Merge pull request #37268 from GursheenK/ar-summary-party-filter

fix: AP AR filters from Party link
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 ee1c9cd..52ae951 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 @@
 	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,
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index 484ff7f..9c73cbb 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -95,18 +95,11 @@
 			"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 @@
 		{
 			"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 @@
 }
 
 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/accounts/report/accounts_payable/test_accounts_payable.py b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py
index 3cf93cc..9f03d92 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 @@
 		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_payable_summary/accounts_payable_summary.js b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
index 8a1725c..9e575e6 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 @@
 			}
 		},
 		{
-			"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 @@
 		{
 			"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 @@
 }
 
 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/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index 67a14e7..1073be0 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 @@
 			}
 		},
 		{
-			"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 @@
 		{
 			"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 @@
 }
 
 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/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 7942402..e3b671f 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -801,7 +801,7 @@
 			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)
diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
index b98916e..4307689 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 @@
 		filters = {
 			"company": self.company,
 			"party_type": "Customer",
-			"party": self.customer,
+			"party": [self.customer],
 			"report_date": today(),
 			"range1": 30,
 			"range2": 60,
@@ -605,3 +605,41 @@
 		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)
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 a78fbeb..5ad10c7 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 @@
 			}
 		},
 		{
-			"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 @@
 		{
 			"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 @@
 }
 
 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
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index 08dc44c..70d2782 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -88,7 +88,7 @@
 			}, __("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 () {
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index e274a52..42932ad 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -138,7 +138,7 @@
 			// 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 () {