From 888ed36eed9eae73d23de71feeb67425a085e950 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Wed, 27 Sep 2023 13:01:18 +0530 Subject: [PATCH 1/7] fix: set route filter values for AP --- .../accounts_payable/accounts_payable.js | 38 ++++++++++++------- erpnext/buying/doctype/supplier/supplier.js | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js index 484ff7fa2b..9c73cbb344 100644 --- a/erpnext/accounts/report/accounts_payable/accounts_payable.js +++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js @@ -95,18 +95,11 @@ frappe.query_reports["Accounts Payable"] = { "options": "Payment Terms Template" }, { - "fieldname": "party_type", + "fieldname":"party_type", "label": __("Party Type"), - "fieldtype": "Link", - "options": "Party Type", - get_query: () => { - return { - filters: { - 'account_type': 'Payable' - } - }; - }, - on_change: () => { + "fieldtype": "Autocomplete", + options: get_party_type_options(), + on_change: function() { frappe.query_report.set_filter_value('party', ""); frappe.query_report.toggle_filter_display('supplier_group', frappe.query_report.get_filter_value('party_type') !== "Supplier"); } @@ -114,8 +107,15 @@ frappe.query_reports["Accounts Payable"] = { { "fieldname":"party", "label": __("Party"), - "fieldtype": "Dynamic Link", - "options": "party_type", + "fieldtype": "MultiSelectList", + get_data: function(txt) { + if (!frappe.query_report.filters) return; + + let party_type = frappe.query_report.get_filter_value('party_type'); + if (!party_type) return; + + return frappe.db.get_link_options(party_type, txt); + }, }, { "fieldname": "supplier_group", @@ -164,3 +164,15 @@ frappe.query_reports["Accounts Payable"] = { } erpnext.utils.add_dimensions('Accounts Payable', 9); + +function get_party_type_options() { + let options = []; + frappe.db.get_list( + "Party Type", {filters:{"account_type": "Payable"}, fields:['name']} + ).then((res) => { + res.forEach((party_type) => { + options.push(party_type.name); + }); + }); + return options; +} \ No newline at end of file diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js index 08dc44c71b..70d27828b4 100644 --- a/erpnext/buying/doctype/supplier/supplier.js +++ b/erpnext/buying/doctype/supplier/supplier.js @@ -88,7 +88,7 @@ frappe.ui.form.on("Supplier", { }, __("View")); frm.add_custom_button(__('Accounts Payable'), function () { - frappe.set_route('query-report', 'Accounts Payable', { supplier: frm.doc.name }); + frappe.set_route('query-report', 'Accounts Payable', { party_type: "Supplier", party: frm.doc.name }); }, __("View")); frm.add_custom_button(__('Bank Account'), function () { From 9d15124a6a3ad1bacc944f2f62b3999548bd40e8 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Wed, 27 Sep 2023 13:01:48 +0530 Subject: [PATCH 2/7] fix: set route filter values for AR --- .../accounts_receivable.js | 42 ++++++++++++------- erpnext/selling/doctype/customer/customer.js | 2 +- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js index 67a14e7880..1073be0bdc 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js @@ -1,6 +1,8 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt +frappe.provide("erpnext.utils"); + frappe.query_reports["Accounts Receivable"] = { "filters": [ { @@ -38,19 +40,11 @@ frappe.query_reports["Accounts Receivable"] = { } }, { - "fieldname": "party_type", + "fieldname":"party_type", "label": __("Party Type"), - "fieldtype": "Link", - "options": "Party Type", - "Default": "Customer", - get_query: () => { - return { - filters: { - 'account_type': 'Receivable' - } - }; - }, - on_change: () => { + "fieldtype": "Autocomplete", + options: get_party_type_options(), + on_change: function() { frappe.query_report.set_filter_value('party', ""); frappe.query_report.toggle_filter_display('customer_group', frappe.query_report.get_filter_value('party_type') !== "Customer"); } @@ -58,8 +52,15 @@ frappe.query_reports["Accounts Receivable"] = { { "fieldname":"party", "label": __("Party"), - "fieldtype": "Dynamic Link", - "options": "party_type", + "fieldtype": "MultiSelectList", + get_data: function(txt) { + if (!frappe.query_report.filters) return; + + let party_type = frappe.query_report.get_filter_value('party_type'); + if (!party_type) return; + + return frappe.db.get_link_options(party_type, txt); + }, }, { "fieldname": "party_account", @@ -192,3 +193,16 @@ frappe.query_reports["Accounts Receivable"] = { } erpnext.utils.add_dimensions('Accounts Receivable', 9); + + +function get_party_type_options() { + let options = []; + frappe.db.get_list( + "Party Type", {filters:{"account_type": "Receivable"}, fields:['name']} + ).then((res) => { + res.forEach((party_type) => { + options.push(party_type.name); + }); + }); + return options; +} \ No newline at end of file diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index e274a52690..42932ad8bd 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -138,7 +138,7 @@ frappe.ui.form.on("Customer", { // custom buttons frm.add_custom_button(__('Accounts Receivable'), function () { - frappe.set_route('query-report', 'Accounts Receivable', {customer:frm.doc.name}); + frappe.set_route('query-report', 'Accounts Receivable', { party_type: "Customer", party: frm.doc.name }); }, __('View')); frm.add_custom_button(__('Accounting Ledger'), function () { From e7239e02d4ff7ec0338f45aa4264dc65d12d3f36 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Wed, 27 Sep 2023 13:02:52 +0530 Subject: [PATCH 3/7] fix: query for multiselect filter --- .../accounts/report/accounts_receivable/accounts_receivable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 7942402365..e3b671f397 100755 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -801,7 +801,7 @@ class ReceivablePayableReport(object): self.qb_selection_filter.append(self.filters.party_type == self.ple.party_type) if self.filters.get("party"): - self.qb_selection_filter.append(self.filters.party == self.ple.party) + self.qb_selection_filter.append(self.ple.party.isin(self.filters.party)) if self.filters.party_account: self.qb_selection_filter.append(self.ple.account == self.filters.party_account) From f7cb68a45fade2499d51d92a5a096f0640b039f2 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Wed, 27 Sep 2023 13:03:37 +0530 Subject: [PATCH 4/7] fix: summary report filters --- .../accounts_payable_summary.js | 38 +++++++++++------- .../accounts_receivable_summary.js | 39 ++++++++++++------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js index 8a1725c048..9e575e669d 100644 --- a/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js +++ b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js @@ -72,18 +72,11 @@ frappe.query_reports["Accounts Payable Summary"] = { } }, { - "fieldname": "party_type", + "fieldname":"party_type", "label": __("Party Type"), - "fieldtype": "Link", - "options": "Party Type", - get_query: () => { - return { - filters: { - 'account_type': 'Payable' - } - }; - }, - on_change: () => { + "fieldtype": "Autocomplete", + options: get_party_type_options(), + on_change: function() { frappe.query_report.set_filter_value('party', ""); frappe.query_report.toggle_filter_display('supplier_group', frappe.query_report.get_filter_value('party_type') !== "Supplier"); } @@ -91,8 +84,15 @@ frappe.query_reports["Accounts Payable Summary"] = { { "fieldname":"party", "label": __("Party"), - "fieldtype": "Dynamic Link", - "options": "party_type", + "fieldtype": "MultiSelectList", + get_data: function(txt) { + if (!frappe.query_report.filters) return; + + let party_type = frappe.query_report.get_filter_value('party_type'); + if (!party_type) return; + + return frappe.db.get_link_options(party_type, txt); + }, }, { "fieldname":"payment_terms_template", @@ -122,3 +122,15 @@ frappe.query_reports["Accounts Payable Summary"] = { } erpnext.utils.add_dimensions('Accounts Payable Summary', 9); + +function get_party_type_options() { + let options = []; + frappe.db.get_list( + "Party Type", {filters:{"account_type": "Payable"}, fields:['name']} + ).then((res) => { + res.forEach((party_type) => { + options.push(party_type.name); + }); + }); + return options; +} \ No newline at end of file diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js index a78fbeb030..5ad10c7890 100644 --- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js +++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js @@ -72,19 +72,11 @@ frappe.query_reports["Accounts Receivable Summary"] = { } }, { - "fieldname": "party_type", + "fieldname":"party_type", "label": __("Party Type"), - "fieldtype": "Link", - "options": "Party Type", - "Default": "Customer", - get_query: () => { - return { - filters: { - 'account_type': 'Receivable' - } - }; - }, - on_change: () => { + "fieldtype": "Autocomplete", + options: get_party_type_options(), + on_change: function() { frappe.query_report.set_filter_value('party', ""); frappe.query_report.toggle_filter_display('customer_group', frappe.query_report.get_filter_value('party_type') !== "Customer"); } @@ -92,8 +84,15 @@ frappe.query_reports["Accounts Receivable Summary"] = { { "fieldname":"party", "label": __("Party"), - "fieldtype": "Dynamic Link", - "options": "party_type", + "fieldtype": "MultiSelectList", + get_data: function(txt) { + if (!frappe.query_report.filters) return; + + let party_type = frappe.query_report.get_filter_value('party_type'); + if (!party_type) return; + + return frappe.db.get_link_options(party_type, txt); + }, }, { "fieldname":"customer_group", @@ -151,3 +150,15 @@ frappe.query_reports["Accounts Receivable Summary"] = { } erpnext.utils.add_dimensions('Accounts Receivable Summary', 9); + +function get_party_type_options() { + let options = []; + frappe.db.get_list( + "Party Type", {filters:{"account_type": "Receivable"}, fields:['name']} + ).then((res) => { + res.forEach((party_type) => { + options.push(party_type.name); + }); + }); + return options; +} \ No newline at end of file From 4b28154f5ee724d1a2c109f5b9e5b27bc707436b Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Wed, 27 Sep 2023 13:04:13 +0530 Subject: [PATCH 5/7] fix: process soa filter for multiselect --- .../process_statement_of_accounts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py index ee1c9cd208..52ae9513dd 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py +++ b/erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py @@ -146,7 +146,7 @@ def get_ar_filters(doc, entry): return { "report_date": doc.posting_date if doc.posting_date else None, "party_type": "Customer", - "party": entry.customer, + "party": [entry.customer], "customer_name": entry.customer_name if entry.customer_name else None, "payment_terms_template": doc.payment_terms_template if doc.payment_terms_template else None, "sales_partner": doc.sales_partner if doc.sales_partner else None, From 59e8abfd57d85719147129d22e4cc2293a379d71 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Wed, 27 Sep 2023 13:57:49 +0530 Subject: [PATCH 6/7] fix: party format in test --- .../accounts/report/accounts_payable/test_accounts_payable.py | 2 +- .../report/accounts_receivable/test_accounts_receivable.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/accounts_payable/test_accounts_payable.py b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py index 3cf93cc865..9f03d92cd5 100644 --- a/erpnext/accounts/report/accounts_payable/test_accounts_payable.py +++ b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py @@ -34,7 +34,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): filters = { "company": self.company, "party_type": "Supplier", - "party": self.supplier, + "party": [self.supplier], "report_date": today(), "range1": 30, "range2": 60, diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py index b98916ee44..8c13f85a98 100644 --- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py @@ -573,7 +573,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): filters = { "company": self.company, "party_type": "Customer", - "party": self.customer, + "party": [self.customer], "report_date": today(), "range1": 30, "range2": 60, From 2c7d6aec89327330be415b8c624c9272fb3d613b Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 28 Sep 2023 11:16:57 +0530 Subject: [PATCH 7/7] test: multi select party filter in AR report --- .../test_accounts_receivable.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py index 8c13f85a98..4307689158 100644 --- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py @@ -605,3 +605,41 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): for field in expected: with self.subTest(field=field): self.assertEqual(report_output.get(field), expected.get(field)) + + def test_multi_select_party_filter(self): + self.customer1 = self.customer + self.create_customer("_Test Customer 2") + self.customer2 = self.customer + self.create_customer("_Test Customer 3") + self.customer3 = self.customer + + filters = { + "company": self.company, + "party_type": "Customer", + "party": [self.customer1, self.customer3], + "report_date": today(), + "range1": 30, + "range2": 60, + "range3": 90, + "range4": 120, + } + + si1 = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True) + si1.customer = self.customer1 + si1.save().submit() + + si2 = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True) + si2.customer = self.customer2 + si2.save().submit() + + si3 = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True) + si3.customer = self.customer3 + si3.save().submit() + + # check invoice grand total and invoiced column's value for 3 payment terms + report = execute(filters) + + expected_output = {self.customer1, self.customer3} + self.assertEqual(len(report[1]), 2) + output_for = set([x.party for x in report[1]]) + self.assertEqual(output_for, expected_output)