From 4556c36736cf79e9861c2feb5e022961e738bbf5 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 3 May 2023 20:45:12 +0530 Subject: [PATCH 1/7] refactor: limit output to 50 in reconciliation tool (cherry picked from commit 7a381affce02e5aea2c5a9a38ebf2638e8128f9a) # Conflicts: # erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json --- .../payment_reconciliation.json | 29 +++++++++++++++++++ .../payment_reconciliation.py | 2 ++ erpnext/accounts/utils.py | 23 +++++++++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json index 18d34850850..c988b36cb01 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json @@ -26,8 +26,10 @@ "bank_cash_account", "cost_center", "sec_break1", + "invoice_name", "invoices", "column_break_15", + "payment_name", "payments", "sec_break2", "allocation" @@ -136,6 +138,7 @@ "label": "Minimum Invoice Amount" }, { + "default": "50", "description": "System will fetch all the entries if limit value is zero.", "fieldname": "invoice_limit", "fieldtype": "Int", @@ -166,6 +169,7 @@ "label": "Maximum Payment Amount" }, { + "default": "50", "description": "System will fetch all the entries if limit value is zero.", "fieldname": "payment_limit", "fieldtype": "Int", @@ -185,13 +189,38 @@ "fieldtype": "Link", "label": "Cost Center", "options": "Cost Center" +<<<<<<< HEAD +======= + }, + { + "depends_on": "eval:doc.party", + "fieldname": "default_advance_account", + "fieldtype": "Link", + "label": "Default Advance Account", + "mandatory_depends_on": "doc.party_type", + "options": "Account" + }, + { + "fieldname": "invoice_name", + "fieldtype": "Data", + "label": "Filter on Invoice" + }, + { + "fieldname": "payment_name", + "fieldtype": "Data", + "label": "Filter on Payment" +>>>>>>> 7a381affce (refactor: limit output to 50 in reconciliation tool) } ], "hide_toolbar": 1, "icon": "icon-resize-horizontal", "issingle": 1, "links": [], +<<<<<<< HEAD "modified": "2022-04-29 15:37:10.246831", +======= + "modified": "2023-08-15 05:35:50.109290", +>>>>>>> 7a381affce (refactor: limit output to 50 in reconciliation tool) "modified_by": "Administrator", "module": "Accounts", "name": "Payment Reconciliation", diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index cc3ec26066f..6db39cc9991 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -210,6 +210,8 @@ class PaymentReconciliation(Document): min_outstanding=self.minimum_invoice_amount if self.minimum_invoice_amount else None, max_outstanding=self.maximum_invoice_amount if self.maximum_invoice_amount else None, accounting_dimensions=self.accounting_dimension_filter_conditions, + limit=self.invoice_limit, + voucher_no=self.invoice_name, ) cr_dr_notes = ( diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 2df3387b83e..a089a856c04 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -884,7 +884,9 @@ def get_outstanding_invoices( min_outstanding=None, max_outstanding=None, accounting_dimensions=None, - vouchers=None, + vouchers=None, # list of dicts [{'voucher_type': '', 'voucher_no': ''}] for filtering + limit=None, # passed by reconciliation tool + voucher_no=None, # filter passed by reconciliation tool ): ple = qb.DocType("Payment Ledger Entry") @@ -917,6 +919,8 @@ def get_outstanding_invoices( max_outstanding=max_outstanding, get_invoices=True, accounting_dimensions=accounting_dimensions or [], + limit=limit, + voucher_no=voucher_no, ) for d in invoice_list: @@ -1648,12 +1652,13 @@ class QueryPaymentLedger(object): self.voucher_posting_date = [] self.min_outstanding = None self.max_outstanding = None + self.limit = self.voucher_no = None def reset(self): # clear filters self.vouchers.clear() self.common_filter.clear() - self.min_outstanding = self.max_outstanding = None + self.min_outstanding = self.max_outstanding = self.limit = None # clear result self.voucher_outstandings.clear() @@ -1667,6 +1672,7 @@ class QueryPaymentLedger(object): filter_on_voucher_no = [] filter_on_against_voucher_no = [] + if self.vouchers: voucher_types = set([x.voucher_type for x in self.vouchers]) voucher_nos = set([x.voucher_no for x in self.vouchers]) @@ -1677,6 +1683,10 @@ class QueryPaymentLedger(object): filter_on_against_voucher_no.append(ple.against_voucher_type.isin(voucher_types)) filter_on_against_voucher_no.append(ple.against_voucher_no.isin(voucher_nos)) + if self.voucher_no: + filter_on_voucher_no.append(ple.voucher_no.like(f"%{self.voucher_no}%")) + filter_on_against_voucher_no.append(ple.against_voucher_no.like(f"%{self.voucher_no}%")) + # build outstanding amount filter filter_on_outstanding_amount = [] if self.min_outstanding: @@ -1792,6 +1802,11 @@ class QueryPaymentLedger(object): ) ) + if self.limit: + self.cte_query_voucher_amount_and_outstanding = ( + self.cte_query_voucher_amount_and_outstanding.limit(self.limit) + ) + # execute SQL self.voucher_outstandings = self.cte_query_voucher_amount_and_outstanding.run(as_dict=True) @@ -1805,6 +1820,8 @@ class QueryPaymentLedger(object): get_payments=False, get_invoices=False, accounting_dimensions=None, + limit=None, + voucher_no=None, ): """ Fetch voucher amount and outstanding amount from Payment Ledger using Database CTE @@ -1826,6 +1843,8 @@ class QueryPaymentLedger(object): self.max_outstanding = max_outstanding self.get_payments = get_payments self.get_invoices = get_invoices + self.limit = limit + self.voucher_no = voucher_no self.query_for_outstanding() return self.voucher_outstandings From d727a13562d3585e0522071b9e25dfd2e8ca7294 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 4 Jul 2023 08:40:47 +0530 Subject: [PATCH 2/7] refactor: trigger on value change (cherry picked from commit e48f8139ebdd5aa64e3b9139157948a7a17afb61) --- .../payment_reconciliation/payment_reconciliation.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js index 07f35c9fe11..6f1f34bc9f3 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js @@ -151,6 +151,15 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo this.frm.refresh(); } + invoice_name() { + this.frm.trigger("get_unreconciled_entries"); + } + + payment_name() { + this.frm.trigger("get_unreconciled_entries"); + } + + clear_child_tables() { this.frm.clear_table("invoices"); this.frm.clear_table("payments"); From a8c53eeb931c2fe15bdfe3072c88539be7aeed4b Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 4 Jul 2023 08:49:30 +0530 Subject: [PATCH 3/7] refactor: filter on cr/dr notes (cherry picked from commit 52f609e67a30988e498cf03bc0da7fa946ab3f5d) --- .../payment_reconciliation.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index 6db39cc9991..258587b9999 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -5,6 +5,7 @@ import frappe from frappe import _, msgprint, qb from frappe.model.document import Document +from frappe.query_builder import Criterion from frappe.query_builder.custom import ConstantColumn from frappe.utils import flt, fmt_money, get_link_to_form, getdate, nowdate, today @@ -130,6 +131,15 @@ class PaymentReconciliation(Document): def get_return_invoices(self): voucher_type = "Sales Invoice" if self.party_type == "Customer" else "Purchase Invoice" doc = qb.DocType(voucher_type) + + conditions = [] + conditions.append(doc.docstatus == 1) + conditions.append(doc[frappe.scrub(self.party_type)] == self.party) + conditions.append(doc.is_return == 1) + + if self.payment_name: + conditions.append(doc.name.like(f"%{self.payment_name}%")) + self.return_invoices = ( qb.from_(doc) .select( @@ -137,11 +147,7 @@ class PaymentReconciliation(Document): doc.name.as_("voucher_no"), doc.return_against, ) - .where( - (doc.docstatus == 1) - & (doc[frappe.scrub(self.party_type)] == self.party) - & (doc.is_return == 1) - ) + .where(Criterion.all(conditions)) .run(as_dict=True) ) From c5080abd4648bd03c062bf62ccaf95a6a69d35ce Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 4 Jul 2023 09:02:05 +0530 Subject: [PATCH 4/7] refactor: filter on advance payments (cherry picked from commit 86bac2cf52e6094755e8f21df871a7f56a4d53a5) # Conflicts: # erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py # erpnext/controllers/accounts_controller.py --- .../payment_reconciliation.py | 18 +++++++++ erpnext/controllers/accounts_controller.py | 38 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index 258587b9999..051f769fb24 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -58,7 +58,25 @@ class PaymentReconciliation(Document): def get_payment_entries(self): order_doctype = "Sales Order" if self.party_type == "Customer" else "Purchase Order" +<<<<<<< HEAD condition = self.get_conditions(get_payments=True) +======= + condition = frappe._dict( + { + "company": self.get("company"), + "get_payments": True, + "cost_center": self.get("cost_center"), + "from_payment_date": self.get("from_payment_date"), + "to_payment_date": self.get("to_payment_date"), + "maximum_payment_amount": self.get("maximum_payment_amount"), + "minimum_payment_amount": self.get("minimum_payment_amount"), + } + ) + + if self.payment_name: + condition.update({"name": self.payment_name}) + +>>>>>>> 86bac2cf52 (refactor: filter on advance payments) payment_entries = get_advance_payment_entries( self.party_type, self.party, diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 76fe6a91182..8b88599c4d1 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -2320,10 +2320,48 @@ def get_advance_payment_entries( payment_entries_against_order, unallocated_payment_entries = [], [] limit_cond = "limit %s" % limit if limit else "" +<<<<<<< HEAD if order_list or against_all_orders: if order_list: reference_condition = " and t2.reference_name in ({0})".format( ", ".join(["%s"] * len(order_list)) +======= + if payment_type == "Receive": + q = q.select((payment_entry.source_exchange_rate).as_("exchange_rate")) + else: + q = q.select((payment_entry.target_exchange_rate).as_("exchange_rate")) + + if condition: + if condition.get("name", None): + q = q.where(payment_entry.name.like(f"%{condition.get('name')}%")) + + q = q.where(payment_entry.company == condition["company"]) + q = ( + q.where(payment_entry.posting_date >= condition["from_payment_date"]) + if condition.get("from_payment_date") + else q + ) + q = ( + q.where(payment_entry.posting_date <= condition["to_payment_date"]) + if condition.get("to_payment_date") + else q + ) + if condition.get("get_payments") == True: + q = ( + q.where(payment_entry.cost_center == condition["cost_center"]) + if condition.get("cost_center") + else q + ) + q = ( + q.where(payment_entry.unallocated_amount >= condition["minimum_payment_amount"]) + if condition.get("minimum_payment_amount") + else q + ) + q = ( + q.where(payment_entry.unallocated_amount <= condition["maximum_payment_amount"]) + if condition.get("maximum_payment_amount") + else q +>>>>>>> 86bac2cf52 (refactor: filter on advance payments) ) else: reference_condition = "" From ab9da5281e338611f6bb3dcceb19eb9949e21501 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 4 Jul 2023 09:06:08 +0530 Subject: [PATCH 5/7] refactor: filter for journal entries (cherry picked from commit d01f0f2e965d776b9b142e33559efe012b4734e5) --- .../doctype/payment_reconciliation/payment_reconciliation.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index 051f769fb24..27b5af600b6 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -92,6 +92,9 @@ class PaymentReconciliation(Document): def get_jv_entries(self): condition = self.get_conditions() + if self.payment_name: + condition += f" and t1.name like '%%{self.payment_name}%%'" + if self.get("cost_center"): condition += f" and t2.cost_center = '{self.cost_center}' " From 4a4cba071542ef14786abf220bbde5477d036399 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 23 Aug 2023 12:57:00 +0530 Subject: [PATCH 6/7] chore: resolve conflict --- .../payment_reconciliation.json | 17 +-------- .../payment_reconciliation.py | 17 +-------- erpnext/controllers/accounts_controller.py | 38 ------------------- 3 files changed, 2 insertions(+), 70 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json index c988b36cb01..0dc9c135b8c 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json @@ -189,16 +189,6 @@ "fieldtype": "Link", "label": "Cost Center", "options": "Cost Center" -<<<<<<< HEAD -======= - }, - { - "depends_on": "eval:doc.party", - "fieldname": "default_advance_account", - "fieldtype": "Link", - "label": "Default Advance Account", - "mandatory_depends_on": "doc.party_type", - "options": "Account" }, { "fieldname": "invoice_name", @@ -209,18 +199,13 @@ "fieldname": "payment_name", "fieldtype": "Data", "label": "Filter on Payment" ->>>>>>> 7a381affce (refactor: limit output to 50 in reconciliation tool) } ], "hide_toolbar": 1, "icon": "icon-resize-horizontal", "issingle": 1, "links": [], -<<<<<<< HEAD - "modified": "2022-04-29 15:37:10.246831", -======= "modified": "2023-08-15 05:35:50.109290", ->>>>>>> 7a381affce (refactor: limit output to 50 in reconciliation tool) "modified_by": "Administrator", "module": "Accounts", "name": "Payment Reconciliation", @@ -247,4 +232,4 @@ "sort_order": "DESC", "states": [], "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 27b5af600b6..abffd262961 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -58,25 +58,10 @@ class PaymentReconciliation(Document): def get_payment_entries(self): order_doctype = "Sales Order" if self.party_type == "Customer" else "Purchase Order" -<<<<<<< HEAD condition = self.get_conditions(get_payments=True) -======= - condition = frappe._dict( - { - "company": self.get("company"), - "get_payments": True, - "cost_center": self.get("cost_center"), - "from_payment_date": self.get("from_payment_date"), - "to_payment_date": self.get("to_payment_date"), - "maximum_payment_amount": self.get("maximum_payment_amount"), - "minimum_payment_amount": self.get("minimum_payment_amount"), - } - ) - if self.payment_name: - condition.update({"name": self.payment_name}) + condition += "name like '%%{0}%%'".format(self.payment_name) ->>>>>>> 86bac2cf52 (refactor: filter on advance payments) payment_entries = get_advance_payment_entries( self.party_type, self.party, diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 8b88599c4d1..76fe6a91182 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -2320,48 +2320,10 @@ def get_advance_payment_entries( payment_entries_against_order, unallocated_payment_entries = [], [] limit_cond = "limit %s" % limit if limit else "" -<<<<<<< HEAD if order_list or against_all_orders: if order_list: reference_condition = " and t2.reference_name in ({0})".format( ", ".join(["%s"] * len(order_list)) -======= - if payment_type == "Receive": - q = q.select((payment_entry.source_exchange_rate).as_("exchange_rate")) - else: - q = q.select((payment_entry.target_exchange_rate).as_("exchange_rate")) - - if condition: - if condition.get("name", None): - q = q.where(payment_entry.name.like(f"%{condition.get('name')}%")) - - q = q.where(payment_entry.company == condition["company"]) - q = ( - q.where(payment_entry.posting_date >= condition["from_payment_date"]) - if condition.get("from_payment_date") - else q - ) - q = ( - q.where(payment_entry.posting_date <= condition["to_payment_date"]) - if condition.get("to_payment_date") - else q - ) - if condition.get("get_payments") == True: - q = ( - q.where(payment_entry.cost_center == condition["cost_center"]) - if condition.get("cost_center") - else q - ) - q = ( - q.where(payment_entry.unallocated_amount >= condition["minimum_payment_amount"]) - if condition.get("minimum_payment_amount") - else q - ) - q = ( - q.where(payment_entry.unallocated_amount <= condition["maximum_payment_amount"]) - if condition.get("maximum_payment_amount") - else q ->>>>>>> 86bac2cf52 (refactor: filter on advance payments) ) else: reference_condition = "" From 20c45c79757a6c3d6ece0815973426de58a8a587 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 23 Aug 2023 14:15:35 +0530 Subject: [PATCH 7/7] chore: linter fix --- erpnext/accounts/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index a089a856c04..0c01ff78c8c 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -884,9 +884,9 @@ def get_outstanding_invoices( min_outstanding=None, max_outstanding=None, accounting_dimensions=None, - vouchers=None, # list of dicts [{'voucher_type': '', 'voucher_no': ''}] for filtering - limit=None, # passed by reconciliation tool - voucher_no=None, # filter passed by reconciliation tool + vouchers=None, # list of dicts [{'voucher_type': '', 'voucher_no': ''}] for filtering + limit=None, # passed by reconciliation tool + voucher_no=None, # filter passed by reconciliation tool ): ple = qb.DocType("Payment Ledger Entry")