From 466bf998354b7452fbbebb62b751a93c41aa2f8f Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 1 Jul 2022 19:01:17 +0530 Subject: [PATCH] fix: Remove Expense Claim from Bank Reconciliation - add hooks `get_matching_queries` and `bank_reconciliation_doctypes` to extend the functionality in other apps --- .../bank_reconciliation_tool.py | 60 +++++------- .../bank_transaction/bank_transaction.js | 29 +++--- .../bank_transaction/bank_transaction.py | 20 ++-- erpnext/hooks.py | 14 +++ .../dialog_manager.js | 92 +++++++------------ .../authorization_rule/authorization_rule.js | 8 +- 6 files changed, 98 insertions(+), 125 deletions(-) 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 4cc6bf7fe5..cc3727ce83 100644 --- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py +++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py @@ -10,7 +10,6 @@ from frappe.model.document import Document from frappe.query_builder.custom import ConstantColumn from frappe.utils import flt -from erpnext import get_company_currency from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_paid_amount from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import ( get_amounts_not_reflected_in_system, @@ -368,6 +367,27 @@ def get_queries(bank_account, company, transaction, document_types): account_from_to = "paid_to" if transaction.deposit > 0 else "paid_from" queries = [] + # get matching queries from all the apps + for method_name in frappe.get_hooks("get_matching_queries"): + queries.extend( + frappe.get_attr(method_name)( + bank_account, + company, + transaction, + document_types, + amount_condition, + account_from_to, + ) + or [] + ) + + return queries + + +def get_matching_queries( + bank_account, company, transaction, document_types, amount_condition, account_from_to +): + queries = [] if "payment_entry" in document_types: pe_amount_matching = get_pe_matching_query(amount_condition, account_from_to, transaction) queries.extend([pe_amount_matching]) @@ -385,10 +405,6 @@ def get_queries(bank_account, company, transaction, document_types): pi_amount_matching = get_pi_matching_query(amount_condition) queries.extend([pi_amount_matching]) - if "expense_claim" in document_types: - ec_amount_matching = get_ec_matching_query(bank_account, company, amount_condition) - queries.extend([ec_amount_matching]) - return queries @@ -604,37 +620,3 @@ def get_pi_matching_query(amount_condition): AND ifnull(clearance_date, '') = "" AND cash_bank_account = %(bank_account)s """ - - -def get_ec_matching_query(bank_account, company, amount_condition): - # get matching Expense Claim query - mode_of_payments = [ - x["parent"] - for x in frappe.db.get_all( - "Mode of Payment Account", filters={"default_account": bank_account}, fields=["parent"] - ) - ] - mode_of_payments = "('" + "', '".join(mode_of_payments) + "' )" - company_currency = get_company_currency(company) - return f""" - SELECT - ( CASE WHEN employee = %(party)s THEN 1 ELSE 0 END - + 1 ) AS rank, - 'Expense Claim' as doctype, - name, - total_sanctioned_amount as paid_amount, - '' as reference_no, - '' as reference_date, - employee as party, - 'Employee' as party_type, - posting_date, - '{company_currency}' as currency - FROM - `tabExpense Claim` - WHERE - total_sanctioned_amount {amount_condition} %(amount)s - AND docstatus = 1 - AND is_paid = 1 - AND ifnull(clearance_date, '') = "" - AND mode_of_payment in {mode_of_payments} - """ diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.js b/erpnext/accounts/doctype/bank_transaction/bank_transaction.js index 3758b524da..6f2900a680 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.js +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.js @@ -3,28 +3,21 @@ frappe.ui.form.on("Bank Transaction", { onload(frm) { - frm.set_query("payment_document", "payment_entries", function () { + frm.set_query("payment_document", "payment_entries", function() { + const payment_doctypes = frm.events.get_payment_doctypes(frm); return { filters: { - name: [ - "in", - [ - "Payment Entry", - "Journal Entry", - "Sales Invoice", - "Purchase Invoice", - "Expense Claim", - ], - ], + name: ["in", payment_doctypes], }, }; }); }, - bank_account: function (frm) { + + bank_account: function(frm) { set_bank_statement_filter(frm); }, - setup: function (frm) { + setup: function(frm) { frm.set_query("party_type", function () { return { filters: { @@ -33,6 +26,16 @@ frappe.ui.form.on("Bank Transaction", { }; }); }, + + get_payment_doctypes: function() { + // get payment doctypes from all the apps + return [ + "Payment Entry", + "Journal Entry", + "Sales Invoice", + "Purchase Invoice", + ]; + } }); frappe.ui.form.on("Bank Transaction Payments", { diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 9a0891f147..a788514335 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -58,18 +58,10 @@ class BankTransaction(StatusUpdater): def clear_linked_payment_entries(self, for_cancel=False): for payment_entry in self.payment_entries: - if payment_entry.payment_document in [ - "Payment Entry", - "Journal Entry", - "Purchase Invoice", - "Expense Claim", - "Loan Repayment", - "Loan Disbursement", - ]: - self.clear_simple_entry(payment_entry, for_cancel=for_cancel) - - elif payment_entry.payment_document == "Sales Invoice": + if payment_entry.payment_document == "Sales Invoice": self.clear_sales_invoice(payment_entry, for_cancel=for_cancel) + elif payment_entry.payment_document in get_doctypes_for_bank_reconciliation(): + self.clear_simple_entry(payment_entry, for_cancel=for_cancel) def clear_simple_entry(self, payment_entry, for_cancel=False): if payment_entry.payment_document == "Payment Entry": @@ -95,6 +87,12 @@ class BankTransaction(StatusUpdater): ) +@frappe.whitelist() +def get_doctypes_for_bank_reconciliation(): + """Get Bank Reconciliation doctypes from all the apps""" + return frappe.get_hooks("bank_reconciliation_doctypes") + + def get_reconciled_bank_transactions(payment_entry): reconciled_bank_transactions = frappe.get_all( "Bank Transaction Payments", diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 453579f458..691ba3cd42 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -498,6 +498,15 @@ period_closing_doctypes = [ "Stock Entry", ] +bank_reconciliation_doctypes = [ + "Payment Entry", + "Journal Entry", + "Purchase Invoice", + "Sales Invoice", + "Loan Repayment", + "Loan Disbursement", +] + accounting_dimension_doctypes = [ "GL Entry", "Payment Ledger Entry", @@ -536,6 +545,11 @@ accounting_dimension_doctypes = [ "Sales Order", ] +# get matching queries for Bank Reconciliation +get_matching_queries = ( + "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_matching_queries" +) + regional_overrides = { "France": { "erpnext.tests.test_regional.test_method": "erpnext.regional.france.utils.test_method" diff --git a/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js b/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js index 214a1be134..cb34c9b4c7 100644 --- a/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js +++ b/erpnext/public/js/bank_reconciliation_tool/dialog_manager.js @@ -169,62 +169,46 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager { label: __("Filters"), depends_on: "eval:doc.action=='Match Against Voucher'", }, - { - fieldtype: "Check", - label: "Payment Entry", - fieldname: "payment_entry", - onchange: () => this.update_options(), - }, - { - fieldtype: "Check", - label: "Journal Entry", - fieldname: "journal_entry", - onchange: () => this.update_options(), - }, - { - fieldtype: "Check", - label: "Loan Repayment", - fieldname: "loan_repayment", - onchange: () => this.update_options(), - }, - { - fieldname: "column_break_5", - fieldtype: "Column Break", - }, - { - fieldtype: "Check", - label: "Sales Invoice", - fieldname: "sales_invoice", - onchange: () => this.update_options(), - }, - { - fieldtype: "Check", - label: "Purchase Invoice", - fieldname: "purchase_invoice", - onchange: () => this.update_options(), - }, + ]; + + frappe.call({ + method: "erpnext.accounts.doctype.bank_transaction.bank_transaction.get_doctypes_for_bank_reconciliation", + callback: (r) => { + $.each(r.message, (_i, entry) => { + if (_i % 3 == 0) { + fields.push({ + fieldtype: "Column Break", + }); + } + fields.push({ + fieldtype: "Check", + label: entry, + fieldname: frappe.scrub(entry), + onchange: () => this.update_options(), + }); + }); + + fields.push(...this.get_voucher_fields()); + + me.dialog = new frappe.ui.Dialog({ + title: __("Reconcile the Bank Transaction"), + fields: fields, + size: "large", + primary_action: (values) => + this.reconciliation_dialog_primary_action(values), + }); + } + }); + } + + get_voucher_fields() { + return [ { fieldtype: "Check", label: "Show Only Exact Amount", fieldname: "exact_match", onchange: () => this.update_options(), }, - { - fieldname: "column_break_5", - fieldtype: "Column Break", - }, - { - fieldtype: "Check", - label: "Expense Claim", - fieldname: "expense_claim", - onchange: () => this.update_options(), - }, - { - fieldtype: "Check", - label: "Loan Disbursement", - fieldname: "loan_disbursement", - onchange: () => this.update_options(), - }, { fieldtype: "Section Break", fieldname: "section_break_1", @@ -404,14 +388,6 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager { read_only: 1, }, ]; - - me.dialog = new frappe.ui.Dialog({ - title: __("Reconcile the Bank Transaction"), - fields: fields, - size: "large", - primary_action: (values) => - this.reconciliation_dialog_primary_action(values), - }); } get_selected_attributes() { diff --git a/erpnext/setup/doctype/authorization_rule/authorization_rule.js b/erpnext/setup/doctype/authorization_rule/authorization_rule.js index 4a6c4201c6..3f6afcae7f 100644 --- a/erpnext/setup/doctype/authorization_rule/authorization_rule.js +++ b/erpnext/setup/doctype/authorization_rule/authorization_rule.js @@ -28,8 +28,8 @@ frappe.ui.form.on("Authorization Rule", { } }, transaction: function(frm) { - unhide_field(['system_role', 'system_user','value', 'based_on']); - hide_field(['to_emp','to_designation']); + unhide_field(['system_role', 'system_user', 'value', 'based_on']); + hide_field(['to_emp', 'to_designation']); } }) @@ -41,8 +41,8 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) { else unhide_field('value'); - unhide_field(['system_role', 'system_user','value']); - hide_field(['to_emp','to_designation']); + unhide_field(['system_role', 'system_user', 'value']); + hide_field(['to_emp', 'to_designation']); } cur_frm.fields_dict.system_user.get_query = function(doc, cdt, cdn) {