refactor: payment reconciliation tool (#27128)

diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index c71a62d..b1f3e6f 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -2,46 +2,10 @@
 // For license information, please see license.txt
 
 frappe.provide("erpnext.accounts");
-
-frappe.ui.form.on("Payment Reconciliation Payment", {
-	invoice_number: function(frm, cdt, cdn) {
-		var row = locals[cdt][cdn];
-		if(row.invoice_number) {
-			var parts = row.invoice_number.split(' | ');
-			var invoice_type = parts[0];
-			var invoice_number = parts[1];
-
-			var invoice_amount = frm.doc.invoices.filter(function(d) {
-				return d.invoice_type === invoice_type && d.invoice_number === invoice_number;
-			})[0].outstanding_amount;
-
-			frappe.model.set_value(cdt, cdn, "allocated_amount", Math.min(invoice_amount, row.amount));
-
-			frm.call({
-				doc: frm.doc,
-				method: 'get_difference_amount',
-				args: {
-					child_row: row
-				},
-				callback: function(r, rt) {
-					if(r.message) {
-						frappe.model.set_value(cdt, cdn,
-							"difference_amount", r.message);
-					}
-				}
-			});
-		}
-	}
-});
-
 erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationController extends frappe.ui.form.Controller {
 	onload() {
 		var me = this;
 
-		this.frm.set_query("party", function() {
-			check_mandatory(me.frm);
-		});
-
 		this.frm.set_query("party_type", function() {
 			return {
 				"filters": {
@@ -88,15 +52,36 @@
 
 	refresh() {
 		this.frm.disable_save();
-		this.toggle_primary_action();
+
+		if (this.frm.doc.receivable_payable_account) {
+			this.frm.add_custom_button(__('Get Unreconciled Entries'), () =>
+				this.frm.trigger("get_unreconciled_entries")
+			);
+		}
+		if (this.frm.doc.invoices.length && this.frm.doc.payments.length) {
+			this.frm.add_custom_button(__('Allocate'), () =>
+				this.frm.trigger("allocate")
+			);
+		}
+		if (this.frm.doc.allocation.length) {
+			this.frm.add_custom_button(__('Reconcile'), () =>
+				this.frm.trigger("reconcile")
+			);
+		}
 	}
 
-	onload_post_render() {
-		this.toggle_primary_action();
+	company() {
+		var me = this;
+		this.frm.set_value('receivable_payable_account', '');
+		me.frm.clear_table("allocation");
+		me.frm.clear_table("invoices");
+		me.frm.clear_table("payments");
+		me.frm.refresh_fields();
+		me.frm.trigger('party');
 	}
 
 	party() {
-		var me = this
+		var me = this;
 		if (!me.frm.doc.receivable_payable_account && me.frm.doc.party_type && me.frm.doc.party) {
 			return frappe.call({
 				method: "erpnext.accounts.party.get_party_account",
@@ -109,6 +94,7 @@
 					if (!r.exc && r.message) {
 						me.frm.set_value("receivable_payable_account", r.message);
 					}
+					me.frm.refresh();
 				}
 			});
 		}
@@ -120,16 +106,41 @@
 			doc: me.frm.doc,
 			method: 'get_unreconciled_entries',
 			callback: function(r, rt) {
-				me.set_invoice_options();
-				me.toggle_primary_action();
+				if (!(me.frm.doc.payments.length || me.frm.doc.invoices.length)) {
+					frappe.throw({message: __("No invoice and payment records found for this party")});
+				}
+				me.frm.refresh();
 			}
 		});
 
 	}
 
+	allocate() {
+		var me = this;
+		let payments = me.frm.fields_dict.payments.grid.get_selected_children();
+		if (!(payments.length)) {
+			payments = me.frm.doc.payments;
+		}
+		let invoices = me.frm.fields_dict.invoices.grid.get_selected_children();
+		if (!(invoices.length)) {
+			invoices = me.frm.doc.invoices;
+		}
+		return me.frm.call({
+			doc: me.frm.doc,
+			method: 'allocate_entries',
+			args: {
+				payments: payments,
+				invoices: invoices
+			},
+			callback: function() {
+				me.frm.refresh();
+			}
+		});
+	}
+
 	reconcile() {
 		var me = this;
-		var show_dialog = me.frm.doc.payments.filter(d => d.difference_amount && !d.difference_account);
+		var show_dialog = me.frm.doc.allocation.filter(d => d.difference_amount && !d.difference_account);
 
 		if (show_dialog && show_dialog.length) {
 
@@ -138,7 +149,7 @@
 				title: __("Select Difference Account"),
 				fields: [
 					{
-						fieldname: "payments", fieldtype: "Table", label: __("Payments"),
+						fieldname: "allocation", fieldtype: "Table", label: __("Allocation"),
 						data: this.data, in_place_edit: true,
 						get_data: () => {
 							return this.data;
@@ -179,10 +190,10 @@
 					},
 				],
 				primary_action: function() {
-					const args = dialog.get_values()["payments"];
+					const args = dialog.get_values()["allocation"];
 
 					args.forEach(d => {
-						frappe.model.set_value("Payment Reconciliation Payment", d.docname,
+						frappe.model.set_value("Payment Reconciliation Allocation", d.docname,
 							"difference_account", d.difference_account);
 					});
 
@@ -192,9 +203,9 @@
 				primary_action_label: __('Reconcile Entries')
 			});
 
-			this.frm.doc.payments.forEach(d => {
+			this.frm.doc.allocation.forEach(d => {
 				if (d.difference_amount && !d.difference_account) {
-					dialog.fields_dict.payments.df.data.push({
+					dialog.fields_dict.allocation.df.data.push({
 						'docname': d.name,
 						'reference_name': d.reference_name,
 						'difference_amount': d.difference_amount,
@@ -203,8 +214,8 @@
 				}
 			});
 
-			this.data = dialog.fields_dict.payments.df.data;
-			dialog.fields_dict.payments.grid.refresh();
+			this.data = dialog.fields_dict.allocation.df.data;
+			dialog.fields_dict.allocation.grid.refresh();
 			dialog.show();
 		} else {
 			this.reconcile_payment_entries();
@@ -218,48 +229,12 @@
 			doc: me.frm.doc,
 			method: 'reconcile',
 			callback: function(r, rt) {
-				me.set_invoice_options();
-				me.toggle_primary_action();
+				me.frm.clear_table("allocation");
+				me.frm.refresh_fields();
+				me.frm.refresh();
 			}
 		});
 	}
-
-	set_invoice_options() {
-		var me = this;
-		var invoices = [];
-
-		$.each(me.frm.doc.invoices || [], function(i, row) {
-			if (row.invoice_number && !in_list(invoices, row.invoice_number))
-				invoices.push(row.invoice_type + " | " + row.invoice_number);
-		});
-
-		if (invoices) {
-			this.frm.fields_dict.payments.grid.update_docfield_property(
-				'invoice_number', 'options', "\n" + invoices.join("\n")
-			);
-
-			$.each(me.frm.doc.payments || [], function(i, p) {
-				if(!in_list(invoices, cstr(p.invoice_number))) p.invoice_number = null;
-			});
-		}
-
-		refresh_field("payments");
-	}
-
-	toggle_primary_action() {
-		if ((this.frm.doc.payments || []).length) {
-			this.frm.fields_dict.reconcile.$input
-				&& this.frm.fields_dict.reconcile.$input.addClass("btn-primary");
-			this.frm.fields_dict.get_unreconciled_entries.$input
-				&& this.frm.fields_dict.get_unreconciled_entries.$input.removeClass("btn-primary");
-		} else {
-			this.frm.fields_dict.reconcile.$input
-				&& this.frm.fields_dict.reconcile.$input.removeClass("btn-primary");
-			this.frm.fields_dict.get_unreconciled_entries.$input
-				&& this.frm.fields_dict.get_unreconciled_entries.$input.addClass("btn-primary");
-		}
-	}
-
 };
 
 extend_cscript(cur_frm.cscript, new erpnext.accounts.PaymentReconciliationController({frm: cur_frm}));
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
index cfb24c3..9023b36 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
@@ -1,622 +1,206 @@
 {
- "allow_copy": 1, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2014-07-09 12:04:51.681583", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 0, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_copy": 1,
+ "creation": "2014-07-09 12:04:51.681583",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+  "company",
+  "party_type",
+  "column_break_4",
+  "party",
+  "receivable_payable_account",
+  "col_break1",
+  "from_invoice_date",
+  "to_invoice_date",
+  "minimum_invoice_amount",
+  "maximum_invoice_amount",
+  "invoice_limit",
+  "column_break_13",
+  "from_payment_date",
+  "to_payment_date",
+  "minimum_payment_amount",
+  "maximum_payment_amount",
+  "payment_limit",
+  "bank_cash_account",
+  "sec_break1",
+  "invoices",
+  "column_break_15",
+  "payments",
+  "sec_break2",
+  "allocation"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "company", 
-   "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": "Company", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "label": "Company",
+   "options": "Company",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "party_type", 
-   "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": "Party Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "DocType", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "party_type",
+   "fieldtype": "Link",
+   "label": "Party Type",
+   "options": "DocType",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "", 
-   "fieldname": "party", 
-   "fieldtype": "Dynamic 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": "Party", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "party_type", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.party_type",
+   "fieldname": "party",
+   "fieldtype": "Dynamic Link",
+   "label": "Party",
+   "options": "party_type",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "receivable_payable_account", 
-   "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": "Receivable / Payable Account", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Account", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.company && doc.party",
+   "fieldname": "receivable_payable_account",
+   "fieldtype": "Link",
+   "label": "Receivable / Payable Account",
+   "options": "Account",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "bank_cash_account", 
-   "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": "Bank / Cash Account", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Account", 
-   "permlevel": 0, 
-   "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
-  }, 
+   "description": "This filter will be applied to Journal Entry.",
+   "fieldname": "bank_cash_account",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Bank / Cash Account",
+   "options": "Account"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "col_break1", 
-   "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, 
-   "label": "", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "collapsible": 1,
+   "collapsible_depends_on": "eval: doc.invoices.length == 0",
+   "depends_on": "eval:doc.receivable_payable_account",
+   "fieldname": "col_break1",
+   "fieldtype": "Section Break",
+   "label": "Filters"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "from_date", 
-   "fieldtype": "Date", 
-   "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": "From Invoice Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "depends_on": "eval:(doc.payments).length || (doc.invoices).length",
+   "fieldname": "sec_break1",
+   "fieldtype": "Section Break",
+   "label": "Unreconciled Entries"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "to_date", 
-   "fieldtype": "Date", 
-   "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": "To Invoice Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "fieldname": "payments",
+   "fieldtype": "Table",
+   "label": "Payments",
+   "options": "Payment Reconciliation Payment"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "minimum_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": "Minimum Invoice Amount", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "depends_on": "allocation",
+   "fieldname": "sec_break2",
+   "fieldtype": "Section Break",
+   "label": "Allocated Entries"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "maximum_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": "Maximum Invoice Amount", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "fieldname": "invoices",
+   "fieldtype": "Table",
+   "label": "Invoices",
+   "options": "Payment Reconciliation Invoice"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "description": "System will fetch all the entries if limit value is zero.", 
-   "fieldname": "limit", 
-   "fieldtype": "Int", 
-   "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": "Limit", 
-   "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
-  }, 
+   "fieldname": "column_break_15",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "get_unreconciled_entries", 
-   "fieldtype": "Button", 
-   "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": "Get Unreconciled Entries", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "fieldname": "allocation",
+   "fieldtype": "Table",
+   "label": "Allocation",
+   "options": "Payment Reconciliation Allocation"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "sec_break1", 
-   "fieldtype": "Section 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, 
-   "label": "Unreconciled Payment Details", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "payments", 
-   "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": "Payments", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Payment Reconciliation Payment", 
-   "permlevel": 0, 
-   "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
-  }, 
+   "fieldname": "from_invoice_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "From Invoice Date"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "reconcile", 
-   "fieldtype": "Button", 
-   "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": "Reconcile", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "fieldname": "to_invoice_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "To Invoice Date"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "sec_break2", 
-   "fieldtype": "Section 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, 
-   "label": "Invoice/Journal Entry Details", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "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
-  }, 
+   "fieldname": "minimum_invoice_amount",
+   "fieldtype": "Currency",
+   "label": "Minimum Invoice Amount"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "invoices", 
-   "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": "Invoices", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Payment Reconciliation Invoice", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "description": "System will fetch all the entries if limit value is zero.",
+   "fieldname": "invoice_limit",
+   "fieldtype": "Int",
+   "label": "Invoice Limit"
+  },
+  {
+   "fieldname": "column_break_13",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "from_payment_date",
+   "fieldtype": "Date",
+   "label": "From Payment Date"
+  },
+  {
+   "fieldname": "to_payment_date",
+   "fieldtype": "Date",
+   "label": "To Payment Date"
+  },
+  {
+   "fieldname": "minimum_payment_amount",
+   "fieldtype": "Currency",
+   "label": "Minimum Payment Amount"
+  },
+  {
+   "fieldname": "maximum_payment_amount",
+   "fieldtype": "Currency",
+   "label": "Maximum Payment Amount"
+  },
+  {
+   "fieldname": "payment_limit",
+   "fieldtype": "Int",
+   "label": "Payment Limit"
+  },
+  {
+   "fieldname": "maximum_invoice_amount",
+   "fieldtype": "Currency",
+   "label": "Maximum Invoice Amount"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 1, 
- "icon": "icon-resize-horizontal", 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 1, 
- "istable": 0, 
- "max_attachments": 0, 
- "menu_index": 0, 
- "modified": "2019-01-15 17:42:21.135214", 
- "modified_by": "Administrator", 
- "module": "Accounts", 
- "name": "Payment Reconciliation", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "hide_toolbar": 1,
+ "icon": "icon-resize-horizontal",
+ "issingle": 1,
+ "links": [],
+ "modified": "2021-08-30 13:05:51.977861",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Reconciliation",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 0, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 0, 
-   "read": 1, 
-   "report": 0, 
-   "role": "Accounts Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "read": 1,
+   "role": "Accounts Manager",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 0, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 0, 
-   "read": 1, 
-   "report": 0, 
-   "role": "Accounts User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "read": 1,
+   "role": "Accounts User",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "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
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index acfe1fe..1286bf0 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -3,7 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe, erpnext
-from frappe.utils import flt, today
+from frappe.utils import flt, today, getdate, nowdate
 from frappe import msgprint, _
 from frappe.model.document import Document
 from erpnext.accounts.utils import (get_outstanding_invoices,
@@ -27,24 +27,32 @@
 		else:
 			dr_or_cr_notes = []
 
-		self.add_payment_entries(payment_entries + journal_entries + dr_or_cr_notes)
+		non_reconciled_payments = payment_entries + journal_entries + dr_or_cr_notes
+
+		if self.payment_limit:
+			non_reconciled_payments = non_reconciled_payments[:self.payment_limit]
+
+		non_reconciled_payments = sorted(non_reconciled_payments, key=lambda k: k['posting_date'] or getdate(nowdate()))
+
+		self.add_payment_entries(non_reconciled_payments)
 
 	def get_payment_entries(self):
 		order_doctype = "Sales Order" if self.party_type=="Customer" else "Purchase Order"
+		condition = self.get_conditions(get_payments=True)
 		payment_entries = get_advance_payment_entries(self.party_type, self.party,
-			self.receivable_payable_account, order_doctype, against_all_orders=True, limit=self.limit)
+			self.receivable_payable_account, order_doctype, against_all_orders=True, limit=self.payment_limit,
+			condition=condition)
 
 		return payment_entries
 
 	def get_jv_entries(self):
+		condition = self.get_conditions()
 		dr_or_cr = ("credit_in_account_currency" if erpnext.get_party_account_type(self.party_type) == 'Receivable'
 			else "debit_in_account_currency")
 
 		bank_account_condition = "t2.against_account like %(bank_cash_account)s" \
 				if self.bank_cash_account else "1=1"
 
-		limit_cond = "limit %s" % self.limit if self.limit else ""
-
 		journal_entries = frappe.db.sql("""
 			select
 				"Journal Entry" as reference_type, t1.name as reference_name,
@@ -56,7 +64,7 @@
 			where
 				t1.name = t2.parent and t1.docstatus = 1 and t2.docstatus = 1
 				and t2.party_type = %(party_type)s and t2.party = %(party)s
-				and t2.account = %(account)s and {dr_or_cr} > 0
+				and t2.account = %(account)s and {dr_or_cr} > 0 {condition}
 				and (t2.reference_type is null or t2.reference_type = '' or
 					(t2.reference_type in ('Sales Order', 'Purchase Order')
 						and t2.reference_name is not null and t2.reference_name != ''))
@@ -65,11 +73,11 @@
 					THEN 1=1
 					ELSE {bank_account_condition}
 				END)
-			order by t1.posting_date {limit_cond}
+			order by t1.posting_date
 			""".format(**{
 				"dr_or_cr": dr_or_cr,
 				"bank_account_condition": bank_account_condition,
-				"limit_cond": limit_cond
+				"condition": condition
 			}), {
 				"party_type": self.party_type,
 				"party": self.party,
@@ -80,6 +88,7 @@
 		return list(journal_entries)
 
 	def get_dr_or_cr_notes(self):
+		condition = self.get_conditions(get_return_invoices=True)
 		dr_or_cr = ("credit_in_account_currency"
 			if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
 
@@ -90,7 +99,7 @@
 			if self.party_type == 'Customer' else "Purchase Invoice")
 
 		return frappe.db.sql(""" SELECT doc.name as reference_name, %(voucher_type)s as reference_type,
-				(sum(gl.{dr_or_cr}) - sum(gl.{reconciled_dr_or_cr})) as amount,
+				(sum(gl.{dr_or_cr}) - sum(gl.{reconciled_dr_or_cr})) as amount, doc.posting_date,
 				account_currency as currency
 			FROM `tab{doc}` doc, `tabGL Entry` gl
 			WHERE
@@ -100,15 +109,17 @@
 				and gl.against_voucher_type = %(voucher_type)s
 				and doc.docstatus = 1 and gl.party = %(party)s
 				and gl.party_type = %(party_type)s and gl.account = %(account)s
-				and gl.is_cancelled = 0
+				and gl.is_cancelled = 0 {condition}
 			GROUP BY doc.name
 			Having
 				amount > 0
+			ORDER BY doc.posting_date
 		""".format(
 			doc=voucher_type,
 			dr_or_cr=dr_or_cr,
 			reconciled_dr_or_cr=reconciled_dr_or_cr,
-			party_type_field=frappe.scrub(self.party_type)),
+			party_type_field=frappe.scrub(self.party_type),
+			condition=condition or ""),
 			{
 				'party': self.party,
 				'party_type': self.party_type,
@@ -116,22 +127,23 @@
 				'account': self.receivable_payable_account
 			}, as_dict=1)
 
-	def add_payment_entries(self, entries):
+	def add_payment_entries(self, non_reconciled_payments):
 		self.set('payments', [])
-		for e in entries:
+
+		for payment in non_reconciled_payments:
 			row = self.append('payments', {})
-			row.update(e)
+			row.update(payment)
 
 	def get_invoice_entries(self):
 		#Fetch JVs, Sales and Purchase Invoices for 'invoices' to reconcile against
 
-		condition = self.check_condition()
+		condition = self.get_conditions(get_invoices=True)
 
 		non_reconciled_invoices = get_outstanding_invoices(self.party_type, self.party,
 			self.receivable_payable_account, condition=condition)
 
-		if self.limit:
-			non_reconciled_invoices = non_reconciled_invoices[:self.limit]
+		if self.invoice_limit:
+			non_reconciled_invoices = non_reconciled_invoices[:self.invoice_limit]
 
 		self.add_invoice_entries(non_reconciled_invoices)
 
@@ -139,41 +151,78 @@
 		#Populate 'invoices' with JVs and Invoices to reconcile against
 		self.set('invoices', [])
 
-		for e in non_reconciled_invoices:
-			ent = self.append('invoices', {})
-			ent.invoice_type = e.get('voucher_type')
-			ent.invoice_number = e.get('voucher_no')
-			ent.invoice_date = e.get('posting_date')
-			ent.amount = flt(e.get('invoice_amount'))
-			ent.currency = e.get('currency')
-			ent.outstanding_amount = e.get('outstanding_amount')
+		for entry in non_reconciled_invoices:
+			inv = self.append('invoices', {})
+			inv.invoice_type = entry.get('voucher_type')
+			inv.invoice_number = entry.get('voucher_no')
+			inv.invoice_date = entry.get('posting_date')
+			inv.amount = flt(entry.get('invoice_amount'))
+			inv.currency = entry.get('currency')
+			inv.outstanding_amount = flt(entry.get('outstanding_amount'))
 
 	@frappe.whitelist()
-	def reconcile(self, args):
-		for e in self.get('payments'):
-			e.invoice_type = None
-			if e.invoice_number and " | " in e.invoice_number:
-				e.invoice_type, e.invoice_number = e.invoice_number.split(" | ")
+	def allocate_entries(self, args):
+		self.validate_entries()
+		entries = []
+		for pay in args.get('payments'):
+			pay.update({'unreconciled_amount': pay.get('amount')})
+			for inv in args.get('invoices'):
+				if pay.get('amount') >= inv.get('outstanding_amount'):
+					res = self.get_allocated_entry(pay, inv, inv['outstanding_amount'])
+					pay['amount'] = flt(pay.get('amount')) - flt(inv.get('outstanding_amount'))
+					inv['outstanding_amount'] = 0
+				else:
+					res = self.get_allocated_entry(pay, inv, pay['amount'])
+					inv['outstanding_amount'] = flt(inv.get('outstanding_amount')) - flt(pay.get('amount'))
+					pay['amount'] = 0
+				if pay.get('amount') == 0:
+					entries.append(res)
+					break
+				elif inv.get('outstanding_amount') == 0:
+					entries.append(res)
+					continue
+			else:
+				break
 
-		self.get_invoice_entries()
-		self.validate_invoice()
+		self.set('allocation', [])
+		for entry in entries:
+			if entry['allocated_amount'] != 0:
+				row = self.append('allocation', {})
+				row.update(entry)
+
+	def get_allocated_entry(self, pay, inv, allocated_amount):
+		return frappe._dict({
+			'reference_type': pay.get('reference_type'),
+			'reference_name': pay.get('reference_name'),
+			'reference_row': pay.get('reference_row'),
+			'invoice_type': inv.get('invoice_type'),
+			'invoice_number': inv.get('invoice_number'),
+			'unreconciled_amount': pay.get('unreconciled_amount'),
+			'amount': pay.get('amount'),
+			'allocated_amount': allocated_amount,
+			'difference_amount': pay.get('difference_amount')
+		})
+
+	@frappe.whitelist()
+	def reconcile(self):
+		self.validate_allocation()
 		dr_or_cr = ("credit_in_account_currency"
 			if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
 
-		lst = []
+		entry_list = []
 		dr_or_cr_notes = []
-		for e in self.get('payments'):
+		for row in self.get('allocation'):
 			reconciled_entry = []
-			if e.invoice_number and e.allocated_amount:
-				if e.reference_type in ['Sales Invoice', 'Purchase Invoice']:
+			if row.invoice_number and row.allocated_amount:
+				if row.reference_type in ['Sales Invoice', 'Purchase Invoice']:
 					reconciled_entry = dr_or_cr_notes
 				else:
-					reconciled_entry = lst
+					reconciled_entry = entry_list
 
-				reconciled_entry.append(self.get_payment_details(e, dr_or_cr))
+				reconciled_entry.append(self.get_payment_details(row, dr_or_cr))
 
-		if lst:
-			reconcile_against_document(lst)
+		if entry_list:
+			reconcile_against_document(entry_list)
 
 		if dr_or_cr_notes:
 			reconcile_dr_cr_note(dr_or_cr_notes, self.company)
@@ -183,98 +232,104 @@
 
 	def get_payment_details(self, row, dr_or_cr):
 		return frappe._dict({
-			'voucher_type': row.reference_type,
-			'voucher_no' : row.reference_name,
-			'voucher_detail_no' : row.reference_row,
-			'against_voucher_type' : row.invoice_type,
-			'against_voucher'  : row.invoice_number,
+			'voucher_type': row.get('reference_type'),
+			'voucher_no' : row.get('reference_name'),
+			'voucher_detail_no' : row.get('reference_row'),
+			'against_voucher_type' : row.get('invoice_type'),
+			'against_voucher'  : row.get('invoice_number'),
 			'account' : self.receivable_payable_account,
 			'party_type': self.party_type,
 			'party': self.party,
-			'is_advance' : row.is_advance,
+			'is_advance' : row.get('is_advance'),
 			'dr_or_cr' : dr_or_cr,
-			'unadjusted_amount' : flt(row.amount),
-			'allocated_amount' : flt(row.allocated_amount),
-			'difference_amount': row.difference_amount,
-			'difference_account': row.difference_account
+			'unreconciled_amount': flt(row.get('unreconciled_amount')),
+			'unadjusted_amount' : flt(row.get('amount')),
+			'allocated_amount' : flt(row.get('allocated_amount')),
+			'difference_amount': flt(row.get('difference_amount')),
+			'difference_account': row.get('difference_account')
 		})
 
-	@frappe.whitelist()
-	def get_difference_amount(self, child_row):
-		if child_row.get("reference_type") != 'Payment Entry': return
-
-		child_row = frappe._dict(child_row)
-
-		if child_row.invoice_number and " | " in child_row.invoice_number:
-			child_row.invoice_type, child_row.invoice_number = child_row.invoice_number.split(" | ")
-
-		dr_or_cr = ("credit_in_account_currency"
-			if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
-
-		row = self.get_payment_details(child_row, dr_or_cr)
-
-		doc = frappe.get_doc(row.voucher_type, row.voucher_no)
-		update_reference_in_payment_entry(row, doc, do_not_save=True)
-
-		return doc.difference_amount
-
 	def check_mandatory_to_fetch(self):
 		for fieldname in ["company", "party_type", "party", "receivable_payable_account"]:
 			if not self.get(fieldname):
 				frappe.throw(_("Please select {0} first").format(self.meta.get_label(fieldname)))
 
-	def validate_invoice(self):
+	def validate_entries(self):
 		if not self.get("invoices"):
-			frappe.throw(_("No records found in the Invoice table"))
+			frappe.throw(_("No records found in the Invoices table"))
 
 		if not self.get("payments"):
-			frappe.throw(_("No records found in the Payment table"))
+			frappe.throw(_("No records found in the Payments table"))
 
+	def validate_allocation(self):
 		unreconciled_invoices = frappe._dict()
-		for d in self.get("invoices"):
-			unreconciled_invoices.setdefault(d.invoice_type, {}).setdefault(d.invoice_number, d.outstanding_amount)
+
+		for inv in self.get("invoices"):
+			unreconciled_invoices.setdefault(inv.invoice_type, {}).setdefault(inv.invoice_number, inv.outstanding_amount)
 
 		invoices_to_reconcile = []
-		for p in self.get("payments"):
-			if p.invoice_type and p.invoice_number and p.allocated_amount:
-				invoices_to_reconcile.append(p.invoice_number)
+		for row in self.get("allocation"):
+			if row.invoice_type and row.invoice_number and row.allocated_amount:
+				invoices_to_reconcile.append(row.invoice_number)
 
-				if p.invoice_number not in unreconciled_invoices.get(p.invoice_type, {}):
-					frappe.throw(_("{0}: {1} not found in Invoice Details table")
-						.format(p.invoice_type, p.invoice_number))
+				if flt(row.amount) - flt(row.allocated_amount) < 0:
+					frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equal to remaining payment amount {2}")
+						.format(row.idx, row.allocated_amount, row.amount))
 
-				if flt(p.allocated_amount) > flt(p.amount):
-					frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to Payment Entry amount {2}")
-						.format(p.idx, p.allocated_amount, p.amount))
-
-				invoice_outstanding = unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number)
-				if flt(p.allocated_amount) - invoice_outstanding > 0.009:
-					frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to invoice outstanding amount {2}")
-						.format(p.idx, p.allocated_amount, invoice_outstanding))
+				invoice_outstanding = unreconciled_invoices.get(row.invoice_type, {}).get(row.invoice_number)
+				if flt(row.allocated_amount) - invoice_outstanding > 0.009:
+					frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equal to invoice outstanding amount {2}")
+						.format(row.idx, row.allocated_amount, invoice_outstanding))
 
 		if not invoices_to_reconcile:
-			frappe.throw(_("Please select Allocated Amount, Invoice Type and Invoice Number in atleast one row"))
+			frappe.throw(_("No records found in Allocation table"))
 
-	def check_condition(self):
-		cond = " and posting_date >= {0}".format(frappe.db.escape(self.from_date)) if self.from_date else ""
-		cond += " and posting_date <= {0}".format(frappe.db.escape(self.to_date)) if self.to_date else ""
-		dr_or_cr = ("debit_in_account_currency" if erpnext.get_party_account_type(self.party_type) == 'Receivable'
-			else "credit_in_account_currency")
+	def get_conditions(self, get_invoices=False, get_payments=False, get_return_invoices=False):
+		condition = " and company = '{0}' ".format(self.company)
 
-		if self.minimum_amount:
-			cond += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_amount))
-		if self.maximum_amount:
-			cond += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_amount))
+		if get_invoices:
+			condition += " and posting_date >= {0}".format(frappe.db.escape(self.from_invoice_date)) if self.from_invoice_date else ""
+			condition += " and posting_date <= {0}".format(frappe.db.escape(self.to_invoice_date)) if self.to_invoice_date else ""
+			dr_or_cr = ("debit_in_account_currency" if erpnext.get_party_account_type(self.party_type) == 'Receivable'
+				else "credit_in_account_currency")
 
-		return cond
+			if self.minimum_invoice_amount:
+				condition += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_invoice_amount))
+			if self.maximum_invoice_amount:
+				condition += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_invoice_amount))
+
+		elif get_return_invoices:
+			condition = " and doc.company = '{0}' ".format(self.company)
+			condition += " and doc.posting_date >= {0}".format(frappe.db.escape(self.from_payment_date)) if self.from_payment_date else ""
+			condition += " and doc.posting_date <= {0}".format(frappe.db.escape(self.to_payment_date)) if self.to_payment_date else ""
+			dr_or_cr = ("gl.debit_in_account_currency" if erpnext.get_party_account_type(self.party_type) == 'Receivable'
+				else "gl.credit_in_account_currency")
+
+			if self.minimum_invoice_amount:
+				condition += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_payment_amount))
+			if self.maximum_invoice_amount:
+				condition += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_payment_amount))
+
+		else:
+			condition += " and posting_date >= {0}".format(frappe.db.escape(self.from_payment_date)) if self.from_payment_date else ""
+			condition += " and posting_date <= {0}".format(frappe.db.escape(self.to_payment_date)) if self.to_payment_date else ""
+
+			if self.minimum_payment_amount:
+				condition += " and unallocated_amount >= {0}".format(flt(self.minimum_payment_amount)) if get_payments \
+					else " and total_debit >= {0}".format(flt(self.minimum_payment_amount))
+			if self.maximum_payment_amount:
+				condition += " and unallocated_amount <= {0}".format(flt(self.maximum_payment_amount)) if get_payments \
+					else " and total_debit <= {0}".format(flt(self.maximum_payment_amount))
+
+		return condition
 
 def reconcile_dr_cr_note(dr_cr_notes, company):
-	for d in dr_cr_notes:
+	for inv in dr_cr_notes:
 		voucher_type = ('Credit Note'
-			if d.voucher_type == 'Sales Invoice' else 'Debit Note')
+			if inv.voucher_type == 'Sales Invoice' else 'Debit Note')
 
 		reconcile_dr_or_cr = ('debit_in_account_currency'
-			if d.dr_or_cr == 'credit_in_account_currency' else 'credit_in_account_currency')
+			if inv.dr_or_cr == 'credit_in_account_currency' else 'credit_in_account_currency')
 
 		company_currency = erpnext.get_company_currency(company)
 
@@ -283,25 +338,25 @@
 			"voucher_type": voucher_type,
 			"posting_date": today(),
 			"company": company,
-			"multi_currency": 1 if d.currency != company_currency else 0,
+			"multi_currency": 1 if inv.currency != company_currency else 0,
 			"accounts": [
 				{
-					'account': d.account,
-					'party': d.party,
-					'party_type': d.party_type,
-					d.dr_or_cr: abs(d.allocated_amount),
-					'reference_type': d.against_voucher_type,
-					'reference_name': d.against_voucher,
+					'account': inv.account,
+					'party': inv.party,
+					'party_type': inv.party_type,
+					inv.dr_or_cr: abs(inv.allocated_amount),
+					'reference_type': inv.against_voucher_type,
+					'reference_name': inv.against_voucher,
 					'cost_center': erpnext.get_default_cost_center(company)
 				},
 				{
-					'account': d.account,
-					'party': d.party,
-					'party_type': d.party_type,
-					reconcile_dr_or_cr: (abs(d.allocated_amount)
-						if abs(d.unadjusted_amount) > abs(d.allocated_amount) else abs(d.unadjusted_amount)),
-					'reference_type': d.voucher_type,
-					'reference_name': d.voucher_no,
+					'account': inv.account,
+					'party': inv.party,
+					'party_type': inv.party_type,
+					reconcile_dr_or_cr: (abs(inv.allocated_amount)
+						if abs(inv.unadjusted_amount) > abs(inv.allocated_amount) else abs(inv.unadjusted_amount)),
+					'reference_type': inv.voucher_type,
+					'reference_name': inv.voucher_no,
 					'cost_center': erpnext.get_default_cost_center(company)
 				}
 			]
diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
new file mode 100644
index 0000000..87eaaee
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+# import frappe
+import unittest
+
+class TestPaymentReconciliation(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/payment_reconciliation_allocation/__init__.py b/erpnext/accounts/doctype/payment_reconciliation_allocation/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_reconciliation_allocation/__init__.py
diff --git a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
new file mode 100644
index 0000000..3653501
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
@@ -0,0 +1,137 @@
+{
+ "actions": [],
+ "creation": "2021-08-16 17:04:40.185167",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "reference_type",
+  "reference_name",
+  "column_break_3",
+  "invoice_type",
+  "invoice_number",
+  "section_break_6",
+  "allocated_amount",
+  "unreconciled_amount",
+  "amount",
+  "column_break_8",
+  "is_advance",
+  "section_break_5",
+  "difference_amount",
+  "column_break_7",
+  "difference_account"
+ ],
+ "fields": [
+  {
+   "fieldname": "invoice_number",
+   "fieldtype": "Dynamic Link",
+   "in_list_view": 1,
+   "label": "Invoice Number",
+   "options": "invoice_type",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "allocated_amount",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Allocated Amount",
+   "options": "Currency",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_5",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "difference_account",
+   "fieldtype": "Link",
+   "label": "Difference Account",
+   "options": "Account",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_7",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "difference_amount",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Difference Amount",
+   "options": "Currency",
+   "read_only": 1
+  },
+  {
+   "fieldname": "reference_name",
+   "fieldtype": "Dynamic Link",
+   "in_list_view": 1,
+   "label": "Reference Name",
+   "options": "reference_type",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "is_advance",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Is Advance",
+   "read_only": 1
+  },
+  {
+   "fieldname": "reference_type",
+   "fieldtype": "Link",
+   "label": "Reference Type",
+   "options": "DocType",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "invoice_type",
+   "fieldtype": "Link",
+   "label": "Invoice Type",
+   "options": "DocType",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "section_break_6",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_8",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "unreconciled_amount",
+   "fieldtype": "Currency",
+   "hidden": 1,
+   "label": "Unreconciled Amount",
+   "options": "Currency",
+   "read_only": 1
+  },
+  {
+   "fieldname": "amount",
+   "fieldtype": "Currency",
+   "hidden": 1,
+   "label": "Amount",
+   "options": "Currency",
+   "read_only": 1
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2021-08-30 10:58:42.665107",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Reconciliation Allocation",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.py b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.py
new file mode 100644
index 0000000..0fb63b1
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+class PaymentReconciliationAllocation(Document):
+	pass
diff --git a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
index 6a79a85..00c9e12 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
@@ -44,7 +44,6 @@
   {
    "fieldname": "amount",
    "fieldtype": "Currency",
-   "in_list_view": 1,
    "label": "Amount",
    "options": "currency",
    "read_only": 1
@@ -67,7 +66,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2020-07-19 18:12:27.964073",
+ "modified": "2021-08-24 22:42:40.923179",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation Invoice",
diff --git a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
index 925a6f1..add07e8 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
@@ -11,11 +11,7 @@
   "is_advance",
   "reference_row",
   "col_break1",
-  "invoice_number",
   "amount",
-  "allocated_amount",
-  "section_break_10",
-  "difference_account",
   "difference_amount",
   "sec_break1",
   "remark",
@@ -41,6 +37,7 @@
   {
    "fieldname": "posting_date",
    "fieldtype": "Date",
+   "in_list_view": 1,
    "label": "Posting Date",
    "read_only": 1
   },
@@ -64,14 +61,6 @@
   },
   {
    "columns": 2,
-   "fieldname": "invoice_number",
-   "fieldtype": "Select",
-   "in_list_view": 1,
-   "label": "Invoice Number",
-   "reqd": 1
-  },
-  {
-   "columns": 2,
    "fieldname": "amount",
    "fieldtype": "Currency",
    "in_list_view": 1,
@@ -80,56 +69,33 @@
    "read_only": 1
   },
   {
-   "columns": 2,
-   "fieldname": "allocated_amount",
-   "fieldtype": "Currency",
-   "in_list_view": 1,
-   "label": "Allocated amount",
-   "options": "currency",
-   "reqd": 1
-  },
-  {
    "fieldname": "sec_break1",
    "fieldtype": "Section Break"
   },
   {
    "fieldname": "remark",
    "fieldtype": "Small Text",
-   "in_list_view": 1,
    "label": "Remark",
    "read_only": 1
   },
   {
-   "columns": 2,
-   "fieldname": "difference_account",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "Difference Account",
-   "options": "Account"
-  },
-  {
-   "fieldname": "difference_amount",
-   "fieldtype": "Currency",
-   "label": "Difference Amount",
-   "options": "currency",
-   "print_hide": 1,
-   "read_only": 1
-  },
-  {
-   "fieldname": "section_break_10",
-   "fieldtype": "Section Break"
-  },
-  {
    "fieldname": "currency",
    "fieldtype": "Link",
    "hidden": 1,
    "label": "Currency",
    "options": "Currency"
+  },
+  {
+   "fieldname": "difference_amount",
+   "fieldtype": "Currency",
+   "label": "Difference Amount",
+   "options": "currency",
+   "read_only": 1
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2020-07-19 18:12:41.682347",
+ "modified": "2021-08-30 10:51:48.140062",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation Payment",
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 5ed4a19..c46eb7e 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -341,31 +341,42 @@
 
 def reconcile_against_document(args):
 	"""
-		Cancel JV, Update aginst document, split if required and resubmit jv
+		Cancel PE or JV, Update against document, split if required and resubmit
 	"""
-	for d in args:
+	# To optimize making GL Entry for PE or JV with multiple references
+	reconciled_entries = {}
+	for row in args:
+		if not reconciled_entries.get((row.voucher_type, row.voucher_no)):
+			reconciled_entries[(row.voucher_type, row.voucher_no)] = []
 
-		check_if_advance_entry_modified(d)
-		validate_allocated_amount(d)
+		reconciled_entries[(row.voucher_type, row.voucher_no)].append(row)
+
+	for key, entries in reconciled_entries.items():
+		voucher_type = key[0]
+		voucher_no = key[1]
 
 		# cancel advance entry
-		doc = frappe.get_doc(d.voucher_type, d.voucher_no)
-
+		doc = frappe.get_doc(voucher_type, voucher_no)
 		frappe.flags.ignore_party_validation = True
 		doc.make_gl_entries(cancel=1, adv_adj=1)
 
-		# update ref in advance entry
-		if d.voucher_type == "Journal Entry":
-			update_reference_in_journal_entry(d, doc)
-		else:
-			update_reference_in_payment_entry(d, doc)
+		for entry in entries:
+			check_if_advance_entry_modified(entry)
+			validate_allocated_amount(entry)
 
+			# update ref in advance entry
+			if voucher_type == "Journal Entry":
+				update_reference_in_journal_entry(entry, doc, do_not_save=True)
+			else:
+				update_reference_in_payment_entry(entry, doc, do_not_save=True)
+
+		doc.save(ignore_permissions=True)
 		# re-submit advance entry
-		doc = frappe.get_doc(d.voucher_type, d.voucher_no)
+		doc = frappe.get_doc(entry.voucher_type, entry.voucher_no)
 		doc.make_gl_entries(cancel = 0, adv_adj =1)
 		frappe.flags.ignore_party_validation = False
 
-		if d.voucher_type in ('Payment Entry', 'Journal Entry'):
+		if entry.voucher_type in ('Payment Entry', 'Journal Entry'):
 			doc.update_expense_claim()
 
 def check_if_advance_entry_modified(args):
@@ -374,6 +385,9 @@
 		check if amount is same
 		check if jv is submitted
 	"""
+	if not args.get('unreconciled_amount'):
+		args.update({'unreconciled_amount': args.get('unadjusted_amount')})
+
 	ret = None
 	if args.voucher_type == "Journal Entry":
 		ret = frappe.db.sql("""
@@ -395,14 +409,14 @@
 					and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
 					and t1.party_type = %(party_type)s and t1.party = %(party)s and t1.{0} = %(account)s
 					and t2.reference_doctype in ("", "Sales Order", "Purchase Order")
-					and t2.allocated_amount = %(unadjusted_amount)s
+					and t2.allocated_amount = %(unreconciled_amount)s
 			""".format(party_account_field), args)
 		else:
 			ret = frappe.db.sql("""select name from `tabPayment Entry`
 				where
 					name = %(voucher_no)s and docstatus = 1
 					and party_type = %(party_type)s and party = %(party)s and {0} = %(account)s
-					and unallocated_amount = %(unadjusted_amount)s
+					and unallocated_amount = %(unreconciled_amount)s
 			""".format(party_account_field), args)
 
 	if not ret:
@@ -415,58 +429,44 @@
 	elif flt(args.get("allocated_amount"), precision) > flt(args.get("unadjusted_amount"), precision):
 		throw(_("Allocated amount cannot be greater than unadjusted amount"))
 
-def update_reference_in_journal_entry(d, jv_obj):
+def update_reference_in_journal_entry(d, journal_entry, do_not_save=False):
 	"""
 		Updates against document, if partial amount splits into rows
 	"""
-	jv_detail = jv_obj.get("accounts", {"name": d["voucher_detail_no"]})[0]
-	jv_detail.set(d["dr_or_cr"], d["allocated_amount"])
-	jv_detail.set('debit' if d['dr_or_cr']=='debit_in_account_currency' else 'credit',
-		d["allocated_amount"]*flt(jv_detail.exchange_rate))
+	jv_detail = journal_entry.get("accounts", {"name": d["voucher_detail_no"]})[0]
 
-	original_reference_type = jv_detail.reference_type
-	original_reference_name = jv_detail.reference_name
-
-	jv_detail.set("reference_type", d["against_voucher_type"])
-	jv_detail.set("reference_name", d["against_voucher"])
-
-	if d['allocated_amount'] < d['unadjusted_amount']:
-		jvd = frappe.db.sql("""
-			select cost_center, balance, against_account, is_advance,
-				account_type, exchange_rate, account_currency
-			from `tabJournal Entry Account` where name = %s
-		""", d['voucher_detail_no'], as_dict=True)
-
+	if flt(d['unadjusted_amount']) - flt(d['allocated_amount']) != 0:
+		# adjust the unreconciled balance
 		amount_in_account_currency = flt(d['unadjusted_amount']) - flt(d['allocated_amount'])
-		amount_in_company_currency = amount_in_account_currency * flt(jvd[0]['exchange_rate'])
+		amount_in_company_currency = amount_in_account_currency * flt(jv_detail.exchange_rate)
+		jv_detail.set(d['dr_or_cr'], amount_in_account_currency)
+		jv_detail.set('debit' if d['dr_or_cr'] == 'debit_in_account_currency' else 'credit', amount_in_company_currency)
+	else:
+		journal_entry.remove(jv_detail)
 
-		# new entry with balance amount
-		ch = jv_obj.append("accounts")
-		ch.account = d['account']
-		ch.account_type = jvd[0]['account_type']
-		ch.account_currency = jvd[0]['account_currency']
-		ch.exchange_rate = jvd[0]['exchange_rate']
-		ch.party_type = d["party_type"]
-		ch.party = d["party"]
-		ch.cost_center = cstr(jvd[0]["cost_center"])
-		ch.balance = flt(jvd[0]["balance"])
+	# new row with references
+	new_row = journal_entry.append("accounts")
+	new_row.update(jv_detail.as_dict().copy())
 
-		ch.set(d['dr_or_cr'], amount_in_account_currency)
-		ch.set('debit' if d['dr_or_cr']=='debit_in_account_currency' else 'credit', amount_in_company_currency)
+	new_row.set(d["dr_or_cr"], d["allocated_amount"])
+	new_row.set('debit' if d['dr_or_cr'] == 'debit_in_account_currency' else 'credit',
+		d["allocated_amount"] * flt(jv_detail.exchange_rate))
 
-		ch.set('credit_in_account_currency' if d['dr_or_cr']== 'debit_in_account_currency'
-			else 'debit_in_account_currency', 0)
-		ch.set('credit' if d['dr_or_cr']== 'debit_in_account_currency' else 'debit', 0)
+	new_row.set('credit_in_account_currency' if d['dr_or_cr'] == 'debit_in_account_currency'
+		else 'debit_in_account_currency', 0)
+	new_row.set('credit' if d['dr_or_cr'] == 'debit_in_account_currency' else 'debit', 0)
 
-		ch.against_account = cstr(jvd[0]["against_account"])
-		ch.reference_type = original_reference_type
-		ch.reference_name = original_reference_name
-		ch.is_advance = cstr(jvd[0]["is_advance"])
-		ch.docstatus = 1
+	new_row.set("reference_type", d["against_voucher_type"])
+	new_row.set("reference_name", d["against_voucher"])
+
+	new_row.against_account = cstr(jv_detail.against_account)
+	new_row.is_advance = cstr(jv_detail.is_advance)
+	new_row.docstatus = 1
 
 	# will work as update after submit
-	jv_obj.flags.ignore_validate_update_after_submit = True
-	jv_obj.save(ignore_permissions=True)
+	journal_entry.flags.ignore_validate_update_after_submit = True
+	if not do_not_save:
+		journal_entry.save(ignore_permissions=True)
 
 def update_reference_in_payment_entry(d, payment_entry, do_not_save=False):
 	reference_details = {
@@ -576,7 +576,7 @@
 
 @frappe.whitelist()
 def get_company_default(company, fieldname, ignore_validation=False):
-	value = frappe.get_cached_value('Company', company, fieldname)
+	value = frappe.get_cached_value('Company',  company,  fieldname)
 
 	if not ignore_validation and not value:
 		throw(_("Please set default {0} in Company {1}")
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index f4af893..c41f083 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -1587,7 +1587,7 @@
 
 
 def get_advance_payment_entries(party_type, party, party_account, order_doctype,
-		order_list=None, include_unallocated=True, against_all_orders=False, limit=None):
+		order_list=None, include_unallocated=True, against_all_orders=False, limit=None, condition=None):
 	party_account_field = "paid_from" if party_type == "Customer" else "paid_to"
 	currency_field = "paid_from_account_currency" if party_type == "Customer" else "paid_to_account_currency"
 	payment_type = "Receive" if party_type == "Customer" else "Pay"
@@ -1622,14 +1622,14 @@
 
 	if include_unallocated:
 		unallocated_payment_entries = frappe.db.sql("""
-				select "Payment Entry" as reference_type, name as reference_name,
-				remarks, unallocated_amount as amount, {2} as exchange_rate
+				select "Payment Entry" as reference_type, name as reference_name, posting_date,
+				remarks, unallocated_amount as amount, {2} as exchange_rate, {3} as currency
 				from `tabPayment Entry`
 				where
 					{0} = %s and party_type = %s and party = %s and payment_type = %s
-					and docstatus = 1 and unallocated_amount > 0
+					and docstatus = 1 and unallocated_amount > 0 {condition}
 				order by posting_date {1}
-			""".format(party_account_field, limit_cond, exchange_rate_field),
+			""".format(party_account_field, limit_cond, exchange_rate_field, currency_field, condition=condition or ""),
 			(party_account, party_type, party, payment_type), as_dict=1)
 
 	return list(payment_entries_against_order) + list(unallocated_payment_entries)