mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 16:34:46 +00:00
Bank reconciliation wip
This commit is contained in:
@@ -495,6 +495,134 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 1
|
"unique": 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 1,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "payment_entries",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Payment Entries",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Bank Transaction Payments",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "column_break_17",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "allocated_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Allocated Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "unallocated_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Unallocated Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@@ -526,39 +654,6 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "payment_entry",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Payment Entry",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Payment Entry",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"has_web_view": 0,
|
||||||
@@ -571,7 +666,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-11-27 13:26:53.794350",
|
"modified": "2018-11-28 11:05:05.087606",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Transaction",
|
"name": "Bank Transaction",
|
||||||
@@ -640,7 +735,7 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
"show_name_in_global_search": 0,
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "date",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "bank_account",
|
"title_field": "bank_account",
|
||||||
"track_changes": 0,
|
"track_changes": 0,
|
||||||
|
|||||||
@@ -4,7 +4,25 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe.utils import flt
|
||||||
|
|
||||||
class BankTransaction(Document):
|
class BankTransaction(Document):
|
||||||
pass
|
def after_insert(self):
|
||||||
|
self.unallocated_amount = abs(flt(self.credit) - flt(self.debit))
|
||||||
|
|
||||||
|
def on_update_after_submit(self):
|
||||||
|
linked_payments = [x.payment_entry for x in self.payment_entries]
|
||||||
|
|
||||||
|
if linked_payments:
|
||||||
|
allocated_amount = frappe.get_all("Payment Entry", filters=[["name", "in", linked_payments]], fields=["sum(paid_amount) as total"])
|
||||||
|
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "allocated_amount", flt(allocated_amount[0].total))
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)) - flt(allocated_amount[0].total))
|
||||||
|
|
||||||
|
else:
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "allocated_amount", 0)
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)))
|
||||||
|
|
||||||
|
self.reload()
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
frappe.listview_settings['Bank Transaction'] = {
|
||||||
|
add_fields: ["unallocated_amount"],
|
||||||
|
get_indicator: function(doc) {
|
||||||
|
if(flt(doc.unallocated_amount)>0) {
|
||||||
|
return [__("Unreconciled"), "orange", "unallocated_amount,>,0"]
|
||||||
|
} else if(flt(doc.unallocated_amount)==0) {
|
||||||
|
return [__("Reconciled"), "green", "unallocated_amount,=,0"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-11-28 08:55:40.815355",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "payment_document",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Payment Document",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "DocType",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "payment_entry",
|
||||||
|
"fieldtype": "Dynamic Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Payment Entry",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "payment_document",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 1,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-11-28 12:34:41.685571",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Bank Transaction Payments",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class BankTransactionPayments(Document):
|
||||||
|
pass
|
||||||
@@ -43,7 +43,7 @@ erpnext.accounts.bankReconciliation = class BankReconciliation {
|
|||||||
add_plaid_btn() {
|
add_plaid_btn() {
|
||||||
const me = this;
|
const me = this;
|
||||||
frappe.db.get_value("Plaid Settings", "Plaid Settings", "enabled", (r) => {
|
frappe.db.get_value("Plaid Settings", "Plaid Settings", "enabled", (r) => {
|
||||||
if (r.enabled == "1") {
|
if (r && r.enabled == "1") {
|
||||||
me.parent.page.add_inner_button(__('Link a new bank account'), function() {
|
me.parent.page.add_inner_button(__('Link a new bank account'), function() {
|
||||||
new erpnext.accounts.plaidLink(this)
|
new erpnext.accounts.plaidLink(this)
|
||||||
})
|
})
|
||||||
@@ -116,6 +116,7 @@ erpnext.accounts.bankTransactionUpload = class bankTransactionUpload {
|
|||||||
no_socketio: true,
|
no_socketio: true,
|
||||||
sample_url: "e.g. http://example.com/somefile.csv",
|
sample_url: "e.g. http://example.com/somefile.csv",
|
||||||
callback: function(attachment, r) {
|
callback: function(attachment, r) {
|
||||||
|
console.log(r)
|
||||||
if (!r.exc && r.message) {
|
if (!r.exc && r.message) {
|
||||||
me.data = r.message;
|
me.data = r.message;
|
||||||
me.setup_transactions_dom();
|
me.setup_transactions_dom();
|
||||||
@@ -132,10 +133,19 @@ erpnext.accounts.bankTransactionUpload = class bankTransactionUpload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
create_datatable() {
|
create_datatable() {
|
||||||
this.datatable = new DataTable('.transactions-table', {
|
try {
|
||||||
columns: this.data.columns,
|
this.datatable = new DataTable('.transactions-table', {
|
||||||
data: this.data.data
|
columns: this.data.columns,
|
||||||
})
|
data: this.data.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
let msg = __(`Your file could not be processed by ERPNext.
|
||||||
|
<br>It should be a standard CSV or XLSX file.
|
||||||
|
<br>The headers should be in the first row.`)
|
||||||
|
frappe.throw(msg)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_primary_action() {
|
add_primary_action() {
|
||||||
@@ -333,7 +343,7 @@ erpnext.accounts.ReconciliationTool = class ReconciliationTool extends frappe.vi
|
|||||||
|
|
||||||
return Object.assign({}, args, {
|
return Object.assign({}, args, {
|
||||||
...args.filters.push(["Bank Transaction", "docstatus", "=", 1],
|
...args.filters.push(["Bank Transaction", "docstatus", "=", 1],
|
||||||
["Bank Transaction", "payment_entry", "=", ""])
|
["Bank Transaction", "unallocated_amount", ">", 0])
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -366,6 +376,11 @@ erpnext.accounts.ReconciliationTool = class ReconciliationTool extends frappe.vi
|
|||||||
me.$result.append(frappe.render_template("bank_transaction_header"));
|
me.$result.append(frappe.render_template("bank_transaction_header"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static trigger_list_update() {
|
||||||
|
const reconciliation_list = erpnext.accounts.ReconciliationTool;
|
||||||
|
reconciliation_list && reconciliation_list.on_update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
||||||
@@ -446,7 +461,15 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
|||||||
fieldtype: 'Link',
|
fieldtype: 'Link',
|
||||||
fieldname: 'payment_entry',
|
fieldname: 'payment_entry',
|
||||||
options: 'Payment Entry',
|
options: 'Payment Entry',
|
||||||
label: 'Payment Entry'
|
label: 'Payment Entry',
|
||||||
|
get_query: () => {
|
||||||
|
return {
|
||||||
|
filters : [
|
||||||
|
["Payment Entry", "ifnull(clearance_date, '')", "=", ""],
|
||||||
|
["Payment Entry", "docstatus", "=", 1]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
@@ -473,17 +496,22 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
|||||||
const payment_entry = $(e.target).attr('data-name');
|
const payment_entry = $(e.target).attr('data-name');
|
||||||
frappe.xcall('erpnext.accounts.page.bank_reconciliation.bank_reconciliation.reconcile',
|
frappe.xcall('erpnext.accounts.page.bank_reconciliation.bank_reconciliation.reconcile',
|
||||||
{bank_transaction: me.bank_entry, payment_entry: payment_entry})
|
{bank_transaction: me.bank_entry, payment_entry: payment_entry})
|
||||||
.then((result) => console.log(result))
|
.then((result) => {
|
||||||
|
erpnext.accounts.ReconciliationTool.trigger_list_update();
|
||||||
|
me.dialog.hide();
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
$(me.dialog.body).on('blur', '.input-with-feedback', (e) => {
|
$(me.dialog.body).on('blur', '.input-with-feedback', (e) => {
|
||||||
e.preventDefault();
|
if (e.target.value) {
|
||||||
me.dialog.fields_dict['payment_details'].$wrapper.empty();
|
e.preventDefault();
|
||||||
frappe.db.get_doc("Payment Entry", e.target.value)
|
me.dialog.fields_dict['payment_details'].$wrapper.empty();
|
||||||
.then(doc => {
|
frappe.db.get_doc("Payment Entry", e.target.value)
|
||||||
const details_wrapper = me.dialog.fields_dict.payment_details.$wrapper;
|
.then(doc => {
|
||||||
details_wrapper.append(frappe.render_template("linked_payment_row", doc));
|
const details_wrapper = me.dialog.fields_dict.payment_details.$wrapper;
|
||||||
})
|
details_wrapper.append(frappe.render_template("linked_payment_row", doc));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
me.dialog.show();
|
me.dialog.show();
|
||||||
|
|||||||
@@ -7,25 +7,7 @@ import frappe
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
import difflib
|
import difflib
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
from frappe.utils import flt
|
||||||
@frappe.whitelist()
|
|
||||||
def get_linked_payments(bank_transaction):
|
|
||||||
|
|
||||||
transaction = frappe.get_doc("Bank Transaction", bank_transaction)
|
|
||||||
|
|
||||||
amount_matching = check_matching_amount(transaction)
|
|
||||||
description_matching = check_matching_descriptions(transaction)
|
|
||||||
|
|
||||||
if amount_matching:
|
|
||||||
match = check_amount_vs_description(amount_matching, description_matching)
|
|
||||||
if match:
|
|
||||||
return match
|
|
||||||
else:
|
|
||||||
return merge_matching_lists(amount_matching, description_matching)
|
|
||||||
|
|
||||||
else:
|
|
||||||
linked_payments = get_matching_transactions_payments(description_matching)
|
|
||||||
return linked_payments
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def reconcile(bank_transaction, payment_entry):
|
def reconcile(bank_transaction, payment_entry):
|
||||||
@@ -41,13 +23,49 @@ def reconcile(bank_transaction, payment_entry):
|
|||||||
if transaction.debit > 0 and payment_entry.payment_type == "Receive":
|
if transaction.debit > 0 and payment_entry.payment_type == "Receive":
|
||||||
frappe.throw(_("The selected payment entry should be linked with a creditor bank transaction"))
|
frappe.throw(_("The selected payment entry should be linked with a creditor bank transaction"))
|
||||||
|
|
||||||
frappe.db.set_value("Bank Transaction", bank_transaction, "payment_entry", payment_entry)
|
add_payment_to_transaction(transaction, payment_entry)
|
||||||
|
clear_payment_entry(transaction, payment_entry)
|
||||||
|
|
||||||
|
return 'reconciled'
|
||||||
|
|
||||||
|
def add_payment_to_transaction(transaction, payment_entry):
|
||||||
|
transaction.append("payment_entries", {"payment_entry": payment_entry.name})
|
||||||
|
transaction.save()
|
||||||
|
|
||||||
|
def clear_payment_entry(transaction, payment_entry):
|
||||||
linked_bank_transactions = frappe.get_all("Bank Transaction", filters={"payment_entry": payment_entry, "docstatus": 1},
|
linked_bank_transactions = frappe.get_all("Bank Transaction", filters={"payment_entry": payment_entry, "docstatus": 1},
|
||||||
fields=["sum(debit) as debit", "sum(credit) as credit"])
|
fields=["sum(debit) as debit", "sum(credit) as credit"])
|
||||||
cleared_amount = (linked_bank_transactions[0].credit - linked_bank_transactions[0].debit)
|
|
||||||
|
|
||||||
if cleared_amount == payment_entry.total_allocated_amount:
|
cleared_amount = (flt(linked_bank_transactions[0].credit) - flt(linked_bank_transactions[0].debit))
|
||||||
frappe.db.set_value("Payment Entry", payment_entry, "clearance_date", transaction.date)
|
|
||||||
|
if cleared_amount == payment_entry.paid_amount:
|
||||||
|
frappe.db.set_value("Payment Entry", payment_entry.name, "clearance_date", transaction.date)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_linked_payments(bank_transaction):
|
||||||
|
|
||||||
|
transaction = frappe.get_doc("Bank Transaction", bank_transaction)
|
||||||
|
|
||||||
|
# Get all payment entries with a matching amount
|
||||||
|
amount_matching = check_matching_amount(transaction)
|
||||||
|
print(amount_matching)
|
||||||
|
|
||||||
|
# Get some data from payment entries linked to a corresponding bank transaction
|
||||||
|
description_matching = check_matching_descriptions(transaction)
|
||||||
|
print(description_matching)
|
||||||
|
|
||||||
|
"""
|
||||||
|
if amount_matching:
|
||||||
|
match = check_amount_vs_description(amount_matching, description_matching)
|
||||||
|
if match:
|
||||||
|
return match
|
||||||
|
else:
|
||||||
|
return merge_matching_lists(amount_matching, description_matching)
|
||||||
|
|
||||||
|
else:
|
||||||
|
linked_payments = get_matching_transactions_payments(description_matching)
|
||||||
|
return linked_payments
|
||||||
|
"""
|
||||||
|
|
||||||
def check_matching_amount(transaction):
|
def check_matching_amount(transaction):
|
||||||
amount = transaction.credit if transaction.credit > 0 else transaction.debit
|
amount = transaction.credit if transaction.credit > 0 else transaction.debit
|
||||||
@@ -55,32 +73,52 @@ def check_matching_amount(transaction):
|
|||||||
|
|
||||||
payments = frappe.get_all("Payment Entry", fields=["name", "paid_amount", "payment_type", "reference_no", "reference_date",
|
payments = frappe.get_all("Payment Entry", fields=["name", "paid_amount", "payment_type", "reference_no", "reference_date",
|
||||||
"party", "party_type", "posting_date", "paid_to_account_currency"], filters=[["paid_amount", "like", "{0}%".format(amount)],
|
"party", "party_type", "posting_date", "paid_to_account_currency"], filters=[["paid_amount", "like", "{0}%".format(amount)],
|
||||||
["docstatus", "=", "1"], ["payment_type", "=", payment_type], ["clearance_date", "=", ""]])
|
["docstatus", "=", "1"], ["payment_type", "=", payment_type], ["ifnull(clearance_date, '')", "=", ""]])
|
||||||
|
|
||||||
return payments
|
return payments
|
||||||
|
|
||||||
|
|
||||||
def check_matching_descriptions(transaction):
|
def check_matching_descriptions(transaction):
|
||||||
bank_transactions = frappe.get_all("Bank Transaction", fields=["name", "description", "payment_entry", "date"],
|
bank_transactions = frappe.db.sql("""
|
||||||
filters=[["docstatus", "=", "1"], ["payment_entry", "!=", ""]])
|
SELECT
|
||||||
|
bt.name, bt.description, bt.date, btp.payment_document, btp.payment_entry
|
||||||
|
FROM
|
||||||
|
`tabBank Transaction` as bt
|
||||||
|
LEFT JOIN
|
||||||
|
`tabBank Transaction Payments` as btp
|
||||||
|
ON
|
||||||
|
bt.name = btp.parent
|
||||||
|
WHERE
|
||||||
|
bt.allocated_amount > 0
|
||||||
|
AND
|
||||||
|
bt.docstatus = 1
|
||||||
|
""", as_dict=True)
|
||||||
|
|
||||||
result = []
|
selection = []
|
||||||
for bank_transaction in bank_transactions:
|
for bank_transaction in bank_transactions:
|
||||||
if bank_transaction.description:
|
if bank_transaction.description:
|
||||||
seq=difflib.SequenceMatcher(lambda x: x == " ", transaction.description, bank_transaction.description)
|
seq=difflib.SequenceMatcher(lambda x: x == " ", transaction.description, bank_transaction.description)
|
||||||
|
|
||||||
if seq.ratio() > 0.5:
|
if seq.ratio() > 0.5:
|
||||||
bank_transaction["ratio"] = seq.ratio()
|
bank_transaction["ratio"] = seq.ratio()
|
||||||
result.append(bank_transaction)
|
selection.append(bank_transaction)
|
||||||
|
|
||||||
return result
|
document_types = set([x["payment_document"] for x in selection])
|
||||||
|
|
||||||
|
for document_type in document_types:
|
||||||
|
print(document_type)
|
||||||
|
|
||||||
|
|
||||||
|
return selection
|
||||||
|
|
||||||
def check_amount_vs_description(amount_matching, description_matching):
|
def check_amount_vs_description(amount_matching, description_matching):
|
||||||
result = []
|
result = []
|
||||||
|
print(description_matching)
|
||||||
|
print(amount_matching)
|
||||||
for match in amount_matching:
|
for match in amount_matching:
|
||||||
result.append([match for x in description_matching if match["name"]==x["payment_entry"]])
|
m = [match for x in description_matching.payment_entries if match["name"]==x["payment_entry"]]
|
||||||
|
result.append(m)
|
||||||
return match
|
print(result)
|
||||||
|
return result
|
||||||
|
|
||||||
def merge_matching_lists(amount_matching, description_matching):
|
def merge_matching_lists(amount_matching, description_matching):
|
||||||
|
|
||||||
@@ -100,10 +138,10 @@ def get_matching_transactions_payments(description_matching):
|
|||||||
payment_by_ratio = {x["payment_entry"]: x["ratio"] for x in description_matching}
|
payment_by_ratio = {x["payment_entry"]: x["ratio"] for x in description_matching}
|
||||||
|
|
||||||
if payments:
|
if payments:
|
||||||
payment_list = frappe.get_all("Payment Entry", fields=["name", "paid_amount", "payment_type", "reference_no", "reference_date",
|
reference_payment_list = frappe.get_all("Payment Entry", fields=["name", "paid_amount", "payment_type", "reference_no", "reference_date",
|
||||||
"party", "party_type", "posting_date", "paid_to_account_currency"], filters=[["name", "in", payments]])
|
"party", "party_type", "posting_date", "paid_to_account_currency"], filters=[["name", "in", payments]])
|
||||||
|
|
||||||
return sorted(payment_list, key=lambda x: payment_by_ratio[x["name"]])
|
return sorted(reference_payment_list, key=lambda x: payment_by_ratio[x["name"]])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
Reference in New Issue
Block a user