From 2b307ff52631183460483ab129d9994b09e8ae01 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 16 May 2024 11:40:50 +0530 Subject: [PATCH 1/4] refactor: advance payments, allow configurable reconciliation date (cherry picked from commit 070e2d4d26cc3154d869bb65669b1776e0d5e454) --- .../doctype/payment_entry/payment_entry.json | 12 +++++++++++- .../doctype/payment_entry/payment_entry.py | 15 +++++++++------ erpnext/setup/doctype/company/company.json | 10 +++++++++- erpnext/setup/doctype/company/company.py | 1 + 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index d6ba193aa0e..cdd83a0edfa 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -20,6 +20,7 @@ "party", "party_name", "book_advance_payments_in_separate_party_account", + "reconcile_on_advance_payment_date", "column_break_11", "bank_account", "party_bank_account", @@ -765,6 +766,15 @@ "label": "In Words", "print_hide": 1, "read_only": 1 + }, + { + "default": "0", + "fetch_from": "company.reconcile_on_advance_payment_date", + "fieldname": "reconcile_on_advance_payment_date", + "fieldtype": "Check", + "hidden": 1, + "label": "Reconcile on Advance Payment Date", + "read_only": 1 } ], "index_web_pages_for_search": 1, @@ -778,7 +788,7 @@ "table_fieldname": "payment_entries" } ], - "modified": "2024-04-11 11:25:07.366347", + "modified": "2024-05-16 11:50:19.394918", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry", diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 9f98649248d..e542ff68176 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1249,13 +1249,16 @@ class PaymentEntry(AccountsController): "voucher_detail_no": invoice.name, } - date_field = "posting_date" - if invoice.reference_doctype in ["Sales Order", "Purchase Order"]: - date_field = "transaction_date" - posting_date = frappe.db.get_value(invoice.reference_doctype, invoice.reference_name, date_field) - - if getdate(posting_date) < getdate(self.posting_date): + if self.reconcile_on_advance_payment_date: posting_date = self.posting_date + else: + date_field = "posting_date" + if invoice.reference_doctype in ["Sales Order", "Purchase Order"]: + date_field = "transaction_date" + posting_date = frappe.db.get_value(invoice.reference_doctype, invoice.reference_name, date_field) + + if getdate(posting_date) < getdate(self.posting_date): + posting_date = self.posting_date dr_or_cr, account = self.get_dr_and_account_for_advances(invoice) args_dict["account"] = account diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index c222d6b96a7..467503b280d 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -67,6 +67,7 @@ "default_finance_book", "advance_payments_section", "book_advance_payments_in_separate_party_account", + "reconcile_on_advance_payment_date", "column_break_fwcf", "default_advance_received_account", "default_advance_paid_account", @@ -779,6 +780,13 @@ "fieldtype": "Tab Break", "label": "Dashboard", "show_dashboard": 1 + }, + { + "default": "0", + "depends_on": "eval: doc.book_advance_payments_in_separate_party_account", + "fieldname": "reconcile_on_advance_payment_date", + "fieldtype": "Check", + "label": "Reconcile on Advance Payment Date" } ], "icon": "fa fa-building", @@ -786,7 +794,7 @@ "image_field": "company_logo", "is_tree": 1, "links": [], - "modified": "2024-04-23 12:38:33.173938", + "modified": "2024-05-16 11:52:13.067003", "modified_by": "Administrator", "module": "Setup", "name": "Company", diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index e330fe95cde..2a0b32ed568 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -85,6 +85,7 @@ class Company(NestedSet): parent_company: DF.Link | None payment_terms: DF.Link | None phone_no: DF.Data | None + reconcile_on_advance_payment_date: DF.Check registration_details: DF.Code | None rgt: DF.Int round_off_account: DF.Link | None From 349caf895bc226306c6a04001adfd558edb283c1 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 16 May 2024 12:33:14 +0530 Subject: [PATCH 2/4] chore: better description (cherry picked from commit 000c1b49dc6182a1b5a2394495e86f3a050dd666) --- erpnext/setup/doctype/company/company.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 467503b280d..674805980f5 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -784,6 +784,7 @@ { "default": "0", "depends_on": "eval: doc.book_advance_payments_in_separate_party_account", + "description": "If Enabled - Reconciliation happens on the Advance Payment posting date
\nIf Disabled - Reconciliation happens on oldest of 2 Dates: Invoice Date or the Advance Payment posting date
\n", "fieldname": "reconcile_on_advance_payment_date", "fieldtype": "Check", "label": "Reconcile on Advance Payment Date" @@ -794,7 +795,7 @@ "image_field": "company_logo", "is_tree": 1, "links": [], - "modified": "2024-05-16 11:52:13.067003", + "modified": "2024-05-16 12:39:54.694232", "modified_by": "Administrator", "module": "Setup", "name": "Company", From 53e5fc16d5019f7a8c7ed1f2ddc2f0bcd19ab9f6 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 17 May 2024 10:21:16 +0530 Subject: [PATCH 3/4] refactor: enable no-copy on advance payment flags (cherry picked from commit cafa2f52e5811cbc973ea01c7a4ab635dc827483) --- erpnext/accounts/doctype/payment_entry/payment_entry.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index cdd83a0edfa..6b0115d3f56 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -751,6 +751,7 @@ "fieldtype": "Check", "hidden": 1, "label": "Book Advance Payments in Separate Party Account", + "no_copy": 1, "read_only": 1 }, { @@ -774,6 +775,7 @@ "fieldtype": "Check", "hidden": 1, "label": "Reconcile on Advance Payment Date", + "no_copy": 1, "read_only": 1 } ], @@ -788,7 +790,7 @@ "table_fieldname": "payment_entries" } ], - "modified": "2024-05-16 11:50:19.394918", + "modified": "2024-05-17 10:21:11.199445", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry", From 6c455be6a7a55ef39788c1d5917d15da5334557c Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 20 May 2024 14:42:41 +0530 Subject: [PATCH 4/4] test: reconciliation date for advance payments (cherry picked from commit 30aa4e031d7da5d0a16e8921acbe7b8861adf773) --- .../test_payment_reconciliation.py | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py index 0a3a0678084..53f69a47e75 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py @@ -1525,6 +1525,55 @@ class TestPaymentReconciliation(FrappeTestCase): ] self.assertEqual(pl_entries, expected_ple) + def test_advance_payment_reconciliation_date(self): + frappe.db.set_value( + "Company", + self.company, + { + "book_advance_payments_in_separate_party_account": 1, + "default_advance_paid_account": self.advance_payable_account, + "reconcile_on_advance_payment_date": 1, + }, + ) + + self.supplier = "_Test Supplier" + amount = 1500 + + pe = self.create_payment_entry(amount=amount) + pe.posting_date = add_days(nowdate(), -1) + pe.party_type = "Supplier" + pe.party = self.supplier + pe.payment_type = "Pay" + pe.paid_from = self.cash + pe.paid_to = self.advance_payable_account + pe.save().submit() + + pi = self.create_purchase_invoice(qty=10, rate=100) + self.assertNotEqual(pe.posting_date, pi.posting_date) + + pr = self.create_payment_reconciliation(party_is_customer=False) + pr.default_advance_account = self.advance_payable_account + pr.from_payment_date = pe.posting_date + pr.get_unreconciled_entries() + self.assertEqual(len(pr.invoices), 1) + self.assertEqual(len(pr.payments), 1) + invoices = [invoice.as_dict() for invoice in pr.invoices] + payments = [payment.as_dict() for payment in pr.payments] + pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) + pr.reconcile() + + # Assert Ledger Entries + gl_entries = frappe.db.get_all( + "GL Entry", + filters={"voucher_no": pe.name, "is_cancelled": 0, "posting_date": pe.posting_date}, + ) + self.assertEqual(len(gl_entries), 4) + pl_entries = frappe.db.get_all( + "Payment Ledger Entry", + filters={"voucher_no": pe.name, "delinked": 0, "posting_date": pe.posting_date}, + ) + self.assertEqual(len(pl_entries), 3) + def make_customer(customer_name, currency=None): if not frappe.db.exists("Customer", customer_name):