From 91b08f179a4e29f3b9400190faa50154cc587709 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 17:30:32 +0530 Subject: [PATCH] feat: Date filters on bank reconciliation tool (#33271) * Update bank_reconciliation_tool.py Applying date filter on transactions and all the bank entries and also gives the filter the bank entries as per reference date. Sorted all transactions and entries as per date in ascending order. Also added posting date columns in all bank entries and default checkbox tick of journal entry, hide the sales invoice and purchase invoice checkbox. (cherry picked from commit e5a1189becad071f54c727bc6c0dba16bea2a12f) * Filters on Bank Reconciliation Applying date filter on transactions and all the bank entries and also gives the filter the bank entries as per reference date. Sorted all transactions and entries as per date in ascending order. Also added posting date columns in all bank entries and default checkbox tick of journal entry, hide the sales invoice and purchase invoice checkbox. (cherry picked from commit 447272aa4d1f49428717b1b0ae8e34a21fd0e752) * Update bank_reconciliation_tool.json Adding fields in bank reconciliation tool (cherry picked from commit 8e7c8a648221bdd35b9ecde52a9b56d78b412206) * Feat:Filter on Payment Entries and Journal Entries Applying filters on Payement entries and Journal Entries as per reference date and posting date (cherry picked from commit 408c89df030998fe36df135570c9edd90a522996) * feat:filters on bank reconciliation Added date filters on bank transactions, payment entries and journal entries and sorted list as per date in ascending order. (cherry picked from commit 05b6fce03d58d75df557f5dc5285da30b8baab38) * feat: added arguments of posting date and reference date (cherry picked from commit 645869e6ffec48b605cfdb68d763a7c9f21e3eec) * fix: linters (cherry picked from commit 6b5276398ef90a1a362ce709a92f47f4219f0134) * fix: json issue (cherry picked from commit 81e5f711725e42b25eb84f41790024798f6c535e) * fix: filtered as per reference date On bank reconciliation, transactions will be filtered as per date selected in 'from_date' and 'to_date' fields , In dialog, all the bank entries will be fetched as per the posting date selected and if filtered by reference date checkbox is tick then then there will be two fields 'from_reference_date' and 'to_reference_date' then all bank entries in dialog box came as per reference date, selected. And by default journal entry checkbox is tick. Also sorted the bank transactions and bank entries as per ascending order date wise. (cherry picked from commit 3aaa2f5326b13dbf390d86da9917fbb5def447ae) * fix: pre-commit (cherry picked from commit e2614b8a21117f47c0661f1e0080ed5f95d2e4f8) * fix: passing from_date and to_date filters in test cases passing from_date and to_date filters in test_linked_payments and test_debit_credit_output for unit testing (cherry picked from commit f1810803e1d874a22a49b5bd9b3351fbd2b5b843) * fix: pre-commit (cherry picked from commit 35c29e02267eafade500bdb91fb67a53ec554641) * fix: pre-commit (cherry picked from commit c764f14f53e4b6d87263681be9786166cd7998f9) * feat: consolidated auto bank reconciliation Added a button of Auto Reconcile, to reconcile the bank entries as per the matching reference number with the bank transaction and count of transactions reconciled message will be pop up on clicking the auto reconcile button. (cherry picked from commit d65243eb65fe53d5f5fad0bcb9ffeb1fce7e727a) * fix: data format (cherry picked from commit 12822f7c36fd8a3f5aeea146b0d5e7be46f14a47) * fix: remove comments (cherry picked from commit 917b2190aa25fff735ea3442cee797112147ccb1) * chore: fix fieldnames and order (cherry picked from commit 232726288acb230c49ddb023d453ad055a8b8215) Co-authored-by: sonali Co-authored-by: Deepesh Garg --- .../bank_reconciliation_tool.js | 32 ++- .../bank_reconciliation_tool.json | 35 ++- .../bank_reconciliation_tool.py | 263 +++++++++++++++--- .../bank_transaction/test_bank_transaction.py | 15 +- .../data_table_manager.js | 9 +- .../dialog_manager.js | 21 +- 6 files changed, 324 insertions(+), 51 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.js b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.js index 28e79b5d2c6..c083189eb27 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.js +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.js @@ -21,13 +21,22 @@ frappe.ui.form.on("Bank Reconciliation Tool", { frm.trigger('bank_account'); }, + filter_by_reference_date: function (frm) { + if (frm.doc.filter_by_reference_date) { + frm.set_value("bank_statement_from_date", ""); + frm.set_value("bank_statement_to_date", ""); + } else { + frm.set_value("from_reference_date", ""); + frm.set_value("to_reference_date", ""); + } + }, + refresh: function (frm) { frappe.require("bank-reconciliation-tool.bundle.js", () => frm.trigger("make_reconciliation_tool") ); - frm.upload_statement_button = frm.page.set_secondary_action( - __("Upload Bank Statement"), - () => + + frm.add_custom_button(__("Upload Bank Statement"), () => frappe.call({ method: "erpnext.accounts.doctype.bank_statement_import.bank_statement_import.upload_bank_statement", @@ -49,6 +58,20 @@ frappe.ui.form.on("Bank Reconciliation Tool", { }, }) ); + + frm.add_custom_button(__('Auto Reconcile'), function() { + frappe.call({ + method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.auto_reconcile_vouchers", + args: { + bank_account: frm.doc.bank_account, + from_date: frm.doc.bank_statement_from_date, + to_date: frm.doc.bank_statement_to_date, + filter_by_reference_date: frm.doc.filter_by_reference_date, + from_reference_date: frm.doc.from_reference_date, + to_reference_date: frm.doc.to_reference_date, + }, + }) + }); }, after_save: function (frm) { @@ -160,6 +183,9 @@ frappe.ui.form.on("Bank Reconciliation Tool", { ).$wrapper, bank_statement_from_date: frm.doc.bank_statement_from_date, bank_statement_to_date: frm.doc.bank_statement_to_date, + filter_by_reference_date: frm.doc.filter_by_reference_date, + from_reference_date: frm.doc.from_reference_date, + to_reference_date: frm.doc.to_reference_date, bank_statement_closing_balance: frm.doc.bank_statement_closing_balance, cards_manager: frm.cards_manager, diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.json b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.json index f666101d3fd..80993d6608d 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.json +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.json @@ -10,6 +10,9 @@ "column_break_1", "bank_statement_from_date", "bank_statement_to_date", + "from_reference_date", + "to_reference_date", + "filter_by_reference_date", "column_break_2", "account_opening_balance", "bank_statement_closing_balance", @@ -36,13 +39,13 @@ "fieldtype": "Column Break" }, { - "depends_on": "eval: doc.bank_account", + "depends_on": "eval: doc.bank_account && !doc.filter_by_reference_date", "fieldname": "bank_statement_from_date", "fieldtype": "Date", "label": "From Date" }, { - "depends_on": "eval: doc.bank_statement_from_date", + "depends_on": "eval: doc.bank_account && !doc.filter_by_reference_date", "fieldname": "bank_statement_to_date", "fieldtype": "Date", "label": "To Date" @@ -81,14 +84,33 @@ }, { "fieldname": "no_bank_transactions", - "fieldtype": "HTML" + "fieldtype": "HTML", + "options": "
No Matching Bank Transactions Found
" + }, + { + "depends_on": "eval:doc.filter_by_reference_date", + "fieldname": "from_reference_date", + "fieldtype": "Date", + "label": "From Reference Date" + }, + { + "depends_on": "eval:doc.filter_by_reference_date", + "fieldname": "to_reference_date", + "fieldtype": "Date", + "label": "To Reference Date" + }, + { + "default": "0", + "fieldname": "filter_by_reference_date", + "fieldtype": "Check", + "label": "Filter by Reference Date" } ], "hide_toolbar": 1, "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2021-04-21 11:13:49.831769", + "modified": "2023-01-13 13:00:02.022919", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Reconciliation Tool", @@ -107,5 +129,6 @@ ], "quick_entry": 1, "sort_field": "modified", - "sort_order": "DESC" -} + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py index 8b496e5ea33..57bc351f414 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py @@ -8,7 +8,7 @@ import frappe from frappe import _ from frappe.model.document import Document from frappe.query_builder.custom import ConstantColumn -from frappe.utils import flt +from frappe.utils import cint, flt from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_paid_amount from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import ( @@ -50,6 +50,7 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None): "party", ], filters=filters, + order_by="date", ) return transactions @@ -261,6 +262,80 @@ def create_payment_entry_bts( return reconcile_vouchers(bank_transaction.name, vouchers) +@frappe.whitelist() +def auto_reconcile_vouchers( + bank_account, + from_date=None, + to_date=None, + filter_by_reference_date=None, + from_reference_date=None, + to_reference_date=None, +): + frappe.flags.auto_reconcile_vouchers = True + document_types = ["payment_entry", "journal_entry"] + bank_transactions = get_bank_transactions(bank_account) + matched_transaction = [] + for transaction in bank_transactions: + linked_payments = get_linked_payments( + transaction.name, + document_types, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, + ) + vouchers = [] + for r in linked_payments: + vouchers.append( + { + "payment_doctype": r[1], + "payment_name": r[2], + "amount": r[4], + } + ) + transaction = frappe.get_doc("Bank Transaction", transaction.name) + account = frappe.db.get_value("Bank Account", transaction.bank_account, "account") + matched_trans = 0 + for voucher in vouchers: + gl_entry = frappe.db.get_value( + "GL Entry", + dict( + account=account, voucher_type=voucher["payment_doctype"], voucher_no=voucher["payment_name"] + ), + ["credit", "debit"], + as_dict=1, + ) + gl_amount, transaction_amount = ( + (gl_entry.credit, transaction.deposit) + if gl_entry.credit > 0 + else (gl_entry.debit, transaction.withdrawal) + ) + allocated_amount = gl_amount if gl_amount >= transaction_amount else transaction_amount + transaction.append( + "payment_entries", + { + "payment_document": voucher["payment_doctype"], + "payment_entry": voucher["payment_name"], + "allocated_amount": allocated_amount, + }, + ) + matched_transaction.append(str(transaction.name)) + transaction.save() + transaction.update_allocations() + matched_transaction_len = len(set(matched_transaction)) + if matched_transaction_len == 0: + frappe.msgprint(_("No matching references found for auto reconciliation")) + elif matched_transaction_len == 1: + frappe.msgprint(_("{0} transaction is reconcilied").format(matched_transaction_len)) + else: + frappe.msgprint(_("{0} transactions are reconcilied").format(matched_transaction_len)) + + frappe.flags.auto_reconcile_vouchers = False + + return frappe.get_doc("Bank Transaction", transaction.name) + + @frappe.whitelist() def reconcile_vouchers(bank_transaction_name, vouchers): # updated clear date of all the vouchers based on the bank transaction @@ -323,20 +398,58 @@ def reconcile_vouchers(bank_transaction_name, vouchers): @frappe.whitelist() -def get_linked_payments(bank_transaction_name, document_types=None): +def get_linked_payments( + bank_transaction_name, + document_types=None, + from_date=None, + to_date=None, + filter_by_reference_date=None, + from_reference_date=None, + to_reference_date=None, +): # get all matching payments for a bank transaction transaction = frappe.get_doc("Bank Transaction", bank_transaction_name) bank_account = frappe.db.get_values( "Bank Account", transaction.bank_account, ["account", "company"], as_dict=True )[0] (account, company) = (bank_account.account, bank_account.company) - matching = check_matching(account, company, transaction, document_types) + matching = check_matching( + account, + company, + transaction, + document_types, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, + ) return matching -def check_matching(bank_account, company, transaction, document_types): +def check_matching( + bank_account, + company, + transaction, + document_types, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, +): # combine all types of vouchers - subquery = get_queries(bank_account, company, transaction, document_types) + subquery = get_queries( + bank_account, + company, + transaction, + document_types, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, + ) filters = { "amount": transaction.unallocated_amount, "payment_type": "Receive" if transaction.deposit > 0 else "Pay", @@ -357,11 +470,20 @@ def check_matching(bank_account, company, transaction, document_types): filters, ) ) - return sorted(matching_vouchers, key=lambda x: x[0], reverse=True) if matching_vouchers else [] -def get_queries(bank_account, company, transaction, document_types): +def get_queries( + bank_account, + company, + transaction, + document_types, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, +): # get queries to get matching vouchers amount_condition = "=" if "exact_match" in document_types else "<=" account_from_to = "paid_to" if transaction.deposit > 0 else "paid_from" @@ -377,6 +499,11 @@ def get_queries(bank_account, company, transaction, document_types): document_types, amount_condition, account_from_to, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, ) or [] ) @@ -385,15 +512,42 @@ def get_queries(bank_account, company, transaction, document_types): def get_matching_queries( - bank_account, company, transaction, document_types, amount_condition, account_from_to + bank_account, + company, + transaction, + document_types, + amount_condition, + account_from_to, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, ): queries = [] if "payment_entry" in document_types: - pe_amount_matching = get_pe_matching_query(amount_condition, account_from_to, transaction) + pe_amount_matching = get_pe_matching_query( + amount_condition, + account_from_to, + transaction, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, + ) queries.extend([pe_amount_matching]) if "journal_entry" in document_types: - je_amount_matching = get_je_matching_query(amount_condition, transaction) + je_amount_matching = get_je_matching_query( + amount_condition, + transaction, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, + ) queries.extend([je_amount_matching]) if transaction.deposit > 0 and "sales_invoice" in document_types: @@ -500,47 +654,81 @@ def get_lr_matching_query(bank_account, amount_condition, filters): return vouchers -def get_pe_matching_query(amount_condition, account_from_to, transaction): +def get_pe_matching_query( + amount_condition, + account_from_to, + transaction, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, +): # get matching payment entries query if transaction.deposit > 0: currency_field = "paid_to_account_currency as currency" else: currency_field = "paid_from_account_currency as currency" + filter_by_date = f"AND posting_date between '{from_date}' and '{to_date}'" + order_by = " posting_date" + filter_by_reference_no = "" + if cint(filter_by_reference_date): + filter_by_date = f"AND reference_date between '{from_reference_date}' and '{to_reference_date}'" + order_by = " reference_date" + if frappe.flags.auto_reconcile_vouchers == True: + filter_by_reference_no = f"AND reference_no = '{transaction.reference_number}'" return f""" - SELECT - (CASE WHEN reference_no=%(reference_no)s THEN 1 ELSE 0 END - + CASE WHEN (party_type = %(party_type)s AND party = %(party)s ) THEN 1 ELSE 0 END - + 1 ) AS rank, - 'Payment Entry' as doctype, - name, - paid_amount, - reference_no, - reference_date, - party, - party_type, - posting_date, - {currency_field} - FROM - `tabPayment Entry` - WHERE - paid_amount {amount_condition} %(amount)s - AND docstatus = 1 - AND payment_type IN (%(payment_type)s, 'Internal Transfer') - AND ifnull(clearance_date, '') = "" - AND {account_from_to} = %(bank_account)s + SELECT + (CASE WHEN reference_no=%(reference_no)s THEN 1 ELSE 0 END + + CASE WHEN (party_type = %(party_type)s AND party = %(party)s ) THEN 1 ELSE 0 END + + 1 ) AS rank, + 'Payment Entry' as doctype, + name, + paid_amount, + reference_no, + reference_date, + party, + party_type, + posting_date, + {currency_field} + FROM + `tabPayment Entry` + WHERE + paid_amount {amount_condition} %(amount)s + AND docstatus = 1 + AND payment_type IN (%(payment_type)s, 'Internal Transfer') + AND ifnull(clearance_date, '') = "" + AND {account_from_to} = %(bank_account)s + {filter_by_date} + {filter_by_reference_no} + order by{order_by} + """ -def get_je_matching_query(amount_condition, transaction): +def get_je_matching_query( + amount_condition, + transaction, + from_date, + to_date, + filter_by_reference_date, + from_reference_date, + to_reference_date, +): # get matching journal entry query - # We have mapping at the bank level # So one bank could have both types of bank accounts like asset and liability # So cr_or_dr should be judged only on basis of withdrawal and deposit and not account type cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit" - + filter_by_date = f"AND je.posting_date between '{from_date}' and '{to_date}'" + order_by = " je.posting_date" + filter_by_reference_no = "" + if cint(filter_by_reference_date): + filter_by_date = f"AND je.cheque_date between '{from_reference_date}' and '{to_reference_date}'" + order_by = " je.cheque_date" + if frappe.flags.auto_reconcile_vouchers == True: + filter_by_reference_no = f"AND je.cheque_no = '{transaction.reference_number}'" return f""" - SELECT (CASE WHEN je.cheque_no=%(reference_no)s THEN 1 ELSE 0 END + 1) AS rank , @@ -564,6 +752,9 @@ def get_je_matching_query(amount_condition, transaction): AND jea.account = %(bank_account)s AND jea.{cr_or_dr}_in_account_currency {amount_condition} %(amount)s AND je.docstatus = 1 + {filter_by_date} + {filter_by_reference_no} + order by {order_by} """ diff --git a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py index a5d04137995..f900e0775ce 100644 --- a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py @@ -5,6 +5,7 @@ import json import unittest import frappe +from frappe import utils from frappe.tests.utils import FrappeTestCase from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import ( @@ -40,7 +41,12 @@ class TestBankTransaction(FrappeTestCase): "Bank Transaction", dict(description="Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic"), ) - linked_payments = get_linked_payments(bank_transaction.name, ["payment_entry", "exact_match"]) + linked_payments = get_linked_payments( + bank_transaction.name, + ["payment_entry", "exact_match"], + from_date=bank_transaction.date, + to_date=utils.today(), + ) self.assertTrue(linked_payments[0][6] == "Conrad Electronic") # This test validates a simple reconciliation leading to the clearance of the bank transaction and the payment @@ -81,7 +87,12 @@ class TestBankTransaction(FrappeTestCase): "Bank Transaction", dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"), ) - linked_payments = get_linked_payments(bank_transaction.name, ["payment_entry", "exact_match"]) + linked_payments = get_linked_payments( + bank_transaction.name, + ["payment_entry", "exact_match"], + from_date=bank_transaction.date, + to_date=utils.today(), + ) self.assertTrue(linked_payments[0][3]) # Check error if already reconciled diff --git a/erpnext/public/js/bank_reconciliation_tool/data_table_manager.js b/erpnext/public/js/bank_reconciliation_tool/data_table_manager.js index 9ef8ce6b63e..f7c19a1b7ff 100644 --- a/erpnext/public/js/bank_reconciliation_tool/data_table_manager.js +++ b/erpnext/public/js/bank_reconciliation_tool/data_table_manager.js @@ -5,7 +5,12 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager { Object.assign(this, opts); this.dialog_manager = new erpnext.accounts.bank_reconciliation.DialogManager( this.company, - this.bank_account + this.bank_account, + this.bank_statement_from_date, + this.bank_statement_to_date, + this.filter_by_reference_date, + this.from_reference_date, + this.to_reference_date ); this.make_dt(); } @@ -17,6 +22,8 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager { "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_bank_transactions", args: { bank_account: this.bank_account, + from_date: this.bank_statement_from_date, + to_date: this.bank_statement_to_date }, callback: function (response) { me.format_data(response.message); diff --git a/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js b/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js index b5e6ab871d1..51664f8885e 100644 --- a/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js +++ b/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js @@ -5,8 +5,12 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager { this.bank_account = bank_account; this.company = company; this.make_dialog(); + this.bank_statement_from_date = bank_statement_from_date; + this.bank_statement_to_date = bank_statement_to_date; + this.filter_by_reference_date = filter_by_reference_date; + this.from_reference_date = from_reference_date; + this.to_reference_date = to_reference_date; } - show_dialog(bank_transaction_name, update_dt_cards) { this.bank_transaction_name = bank_transaction_name; this.update_dt_cards = update_dt_cards; @@ -35,13 +39,13 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager { if (r.message) { this.bank_transaction = r.message; r.message.payment_entry = 1; + r.message.journal_entry = 1; this.dialog.set_values(r.message); this.dialog.show(); } }, }); } - get_linked_vouchers(document_types) { frappe.call({ method: @@ -49,6 +53,11 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager { args: { bank_transaction_name: this.bank_transaction_name, document_types: document_types, + from_date: this.bank_statement_from_date, + to_date: this.bank_statement_to_date, + filter_by_reference_date: this.filter_by_reference_date, + from_reference_date:this.from_reference_date, + to_reference_date:this.to_reference_date }, callback: (result) => { @@ -66,6 +75,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager { row[1], row[2], reference_date, + row[8], format_currency(row[3], row[9]), row[6], row[4], @@ -101,6 +111,11 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager { editable: false, width: 120, }, + { + name: "Posting Date", + editable: false, + width: 120, + }, { name: __("Amount"), editable: false, @@ -578,4 +593,4 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager { } } -}; +}; \ No newline at end of file