From ad9e5d41b25bd83b9100e72be2f31c909adb40f8 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 9 Jan 2025 20:02:59 +0530 Subject: [PATCH 01/11] refactor: introduce select fields in company and payment entry (cherry picked from commit 8b2c981fc3241a6cd48663e80089993e02adff76) # Conflicts: # erpnext/accounts/doctype/payment_entry/payment_entry.py --- .../doctype/payment_entry/payment_entry.json | 11 ++- .../doctype/payment_entry/payment_entry.py | 92 +++++++++++++++++++ erpnext/setup/doctype/company/company.json | 10 +- erpnext/setup/doctype/company/company.py | 3 + 4 files changed, 114 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index 69debbec5c7..df9508793a7 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -21,6 +21,7 @@ "party_name", "book_advance_payments_in_separate_party_account", "reconcile_on_advance_payment_date", + "advance_reconciliation_takes_effect_on", "column_break_11", "bank_account", "party_bank_account", @@ -782,6 +783,14 @@ "options": "No\nYes", "print_hide": 1, "search_index": 1 + }, + { + "default": "Oldest Of Invoice Or Advance", + "fetch_from": "company.reconciliation_takes_effect_on", + "fieldname": "advance_reconciliation_takes_effect_on", + "fieldtype": "Select", + "label": "Advance Reconciliation Takes Effect On", + "options": "Advance Payment Date\nOldest Of Invoice Or Advance\nReconciliation Date" } ], "index_web_pages_for_search": 1, @@ -795,7 +804,7 @@ "table_fieldname": "payment_entries" } ], - "modified": "2024-11-07 11:19:19.320883", + "modified": "2025-01-09 20:02:33.402163", "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 7e3d8a5833b..acc0b55b158 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -53,6 +53,98 @@ class InvalidPaymentEntry(ValidationError): class PaymentEntry(AccountsController): +<<<<<<< HEAD +======= + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + from erpnext.accounts.doctype.advance_taxes_and_charges.advance_taxes_and_charges import ( + AdvanceTaxesandCharges, + ) + from erpnext.accounts.doctype.payment_entry_deduction.payment_entry_deduction import ( + PaymentEntryDeduction, + ) + from erpnext.accounts.doctype.payment_entry_reference.payment_entry_reference import ( + PaymentEntryReference, + ) + + advance_reconciliation_takes_effect_on: DF.Literal[ + "Advance Payment Date", "Oldest Of Invoice Or Advance", "Reconciliation Date" + ] + amended_from: DF.Link | None + apply_tax_withholding_amount: DF.Check + auto_repeat: DF.Link | None + bank: DF.ReadOnly | None + bank_account: DF.Link | None + bank_account_no: DF.ReadOnly | None + base_in_words: DF.SmallText | None + base_paid_amount: DF.Currency + base_paid_amount_after_tax: DF.Currency + base_received_amount: DF.Currency + base_received_amount_after_tax: DF.Currency + base_total_allocated_amount: DF.Currency + base_total_taxes_and_charges: DF.Currency + book_advance_payments_in_separate_party_account: DF.Check + clearance_date: DF.Date | None + company: DF.Link + contact_email: DF.Data | None + contact_person: DF.Link | None + cost_center: DF.Link | None + custom_remarks: DF.Check + deductions: DF.Table[PaymentEntryDeduction] + difference_amount: DF.Currency + in_words: DF.SmallText | None + is_opening: DF.Literal["No", "Yes"] + letter_head: DF.Link | None + mode_of_payment: DF.Link | None + naming_series: DF.Literal["ACC-PAY-.YYYY.-"] + paid_amount: DF.Currency + paid_amount_after_tax: DF.Currency + paid_from: DF.Link + paid_from_account_balance: DF.Currency + paid_from_account_currency: DF.Link + paid_from_account_type: DF.Data | None + paid_to: DF.Link + paid_to_account_balance: DF.Currency + paid_to_account_currency: DF.Link + paid_to_account_type: DF.Data | None + party: DF.DynamicLink | None + party_balance: DF.Currency + party_bank_account: DF.Link | None + party_name: DF.Data | None + party_type: DF.Link | None + payment_order: DF.Link | None + payment_order_status: DF.Literal["Initiated", "Payment Ordered"] + payment_type: DF.Literal["Receive", "Pay", "Internal Transfer"] + posting_date: DF.Date + print_heading: DF.Link | None + project: DF.Link | None + purchase_taxes_and_charges_template: DF.Link | None + received_amount: DF.Currency + received_amount_after_tax: DF.Currency + reconcile_on_advance_payment_date: DF.Check + reference_date: DF.Date | None + reference_no: DF.Data | None + references: DF.Table[PaymentEntryReference] + remarks: DF.SmallText | None + sales_taxes_and_charges_template: DF.Link | None + source_exchange_rate: DF.Float + status: DF.Literal["", "Draft", "Submitted", "Cancelled"] + target_exchange_rate: DF.Float + tax_withholding_category: DF.Link | None + taxes: DF.Table[AdvanceTaxesandCharges] + title: DF.Data | None + total_allocated_amount: DF.Currency + total_taxes_and_charges: DF.Currency + unallocated_amount: DF.Currency + # end: auto-generated types + +>>>>>>> 8b2c981fc3 (refactor: introduce select fields in company and payment entry) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if not self.is_new(): diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 271b440fbda..39fae1fcba1 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -75,6 +75,7 @@ "advance_payments_section", "book_advance_payments_in_separate_party_account", "reconcile_on_advance_payment_date", + "reconciliation_takes_effect_on", "column_break_fwcf", "default_advance_received_account", "default_advance_paid_account", @@ -841,6 +842,13 @@ { "fieldname": "column_break_dcdl", "fieldtype": "Column Break" + }, + { + "default": "Oldest Of Invoice Or Advance", + "fieldname": "reconciliation_takes_effect_on", + "fieldtype": "Select", + "label": "Reconciliation Takes Effect On", + "options": "Advance Payment Date\nOldest Of Invoice Or Advance\nReconciliation Date" } ], "icon": "fa fa-building", @@ -848,7 +856,7 @@ "image_field": "company_logo", "is_tree": 1, "links": [], - "modified": "2024-12-02 15:37:32.723176", + "modified": "2025-01-09 20:01:14.818688", "modified_by": "Administrator", "module": "Setup", "name": "Company", diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 27005d99301..8ae843abc24 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -87,6 +87,9 @@ class Company(NestedSet): payment_terms: DF.Link | None phone_no: DF.Data | None reconcile_on_advance_payment_date: DF.Check + reconciliation_takes_effect_on: DF.Literal[ + "Advance Payment Date", "Oldest Of Invoice Or Advance", "Reconciliation Date" + ] registration_details: DF.Code | None rgt: DF.Int round_off_account: DF.Link | None From 55d699ee010c4b1d4a4e5d5d8c863ced4fdb6a59 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 9 Jan 2025 20:05:30 +0530 Subject: [PATCH 02/11] refactor: patch to migrate checkbox to select (cherry picked from commit a8a8ac71b62b14617cb19ef8ca2596c77a56fac9) # Conflicts: # erpnext/patches.txt --- erpnext/patches.txt | 6 ++++++ ...kbox_to_select_for_reconciliation_effect.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 erpnext/patches/v15_0/migrate_checkbox_to_select_for_reconciliation_effect.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index cfc8be90b4b..c1b626502ac 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -386,4 +386,10 @@ erpnext.patches.v14_0.update_stock_uom_in_work_order_item erpnext.patches.v15_0.set_is_exchange_gain_loss_in_payment_entry_deductions erpnext.patches.v15_0.enable_allow_existing_serial_no erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts +<<<<<<< HEAD erpnext.patches.v15_0.update_asset_status_to_work_in_progress +======= +erpnext.patches.v15_0.refactor_closing_stock_balance #5 +erpnext.patches.v15_0.update_asset_status_to_work_in_progress +erpnext.patches.v15_0.migrate_checkbox_to_select_for_reconciliation_effect +>>>>>>> a8a8ac71b6 (refactor: patch to migrate checkbox to select) diff --git a/erpnext/patches/v15_0/migrate_checkbox_to_select_for_reconciliation_effect.py b/erpnext/patches/v15_0/migrate_checkbox_to_select_for_reconciliation_effect.py new file mode 100644 index 00000000000..883921cfdf8 --- /dev/null +++ b/erpnext/patches/v15_0/migrate_checkbox_to_select_for_reconciliation_effect.py @@ -0,0 +1,18 @@ +import frappe + + +def execute(): + """ + A New select field 'reconciliation_takes_effect_on' has been added to control Advance Payment Reconciliation dates. + Migrate old checkbox configuration to new select field on 'Company' and 'Payment Entry' + """ + companies = frappe.db.get_all("Company", fields=["name", "reconciliation_takes_effect_on"]) + for x in companies: + new_value = ( + "Advance Payment Date" if x.reconcile_on_advance_payment_date else "Oldest Of Invoice Or Advance" + ) + frappe.db.set_value("Company", x.name, "reconciliation_takes_effect_on", new_value) + + frappe.db.sql( + """update `tabPayment Entry` set advance_reconciliation_takes_effect_on = if(reconcile_on_advance_payment_date = 0, 'Oldest Of Invoice Or Advance', 'Advance Payment Date')""" + ) From 34b336ca80d1feafe236fafdc605e55661ba117f Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 9 Jan 2025 20:07:13 +0530 Subject: [PATCH 03/11] refactor: test cases updated (cherry picked from commit fb6c72a247432028701048a342cd432ad69730cb) --- .../payment_reconciliation/test_payment_reconciliation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py index 3f0fb29d671..696398c717d 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py @@ -1671,7 +1671,7 @@ class TestPaymentReconciliation(FrappeTestCase): { "book_advance_payments_in_separate_party_account": 1, "default_advance_paid_account": self.advance_payable_account, - "reconcile_on_advance_payment_date": 1, + "reconciliation_takes_effect_on": "Advance Payment Date", }, ) @@ -1720,7 +1720,7 @@ class TestPaymentReconciliation(FrappeTestCase): { "book_advance_payments_in_separate_party_account": 1, "default_advance_received_account": self.advance_receivable_account, - "reconcile_on_advance_payment_date": 0, + "reconciliation_takes_effect_on": "Oldest Of Invoice Or Advance", }, ) amount = 200.0 @@ -1829,7 +1829,7 @@ class TestPaymentReconciliation(FrappeTestCase): { "book_advance_payments_in_separate_party_account": 1, "default_advance_paid_account": self.advance_payable_account, - "reconcile_on_advance_payment_date": 0, + "reconciliation_takes_effect_on": "Oldest Of Invoice Or Advance", }, ) amount = 200.0 From 74f00bb51b9a40fb8b1b4b3879cd56183c940a19 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 9 Jan 2025 20:09:20 +0530 Subject: [PATCH 04/11] refactor: payment entry to handle posting date on configuation (cherry picked from commit bb8d2c994cd445308d7da66f89cca18043cbf793) --- erpnext/accounts/doctype/payment_entry/payment_entry.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index acc0b55b158..48ed975cf37 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1493,9 +1493,9 @@ class PaymentEntry(AccountsController): "voucher_detail_no": invoice.name, } - if self.reconcile_on_advance_payment_date: + if self.advance_reconciliation_takes_effect_on == "Advance Payment Date": posting_date = self.posting_date - else: + elif self.advance_reconciliation_takes_effect_on == "Oldest Of Invoice Or Advance": date_field = "posting_date" if invoice.reference_doctype in ["Sales Order", "Purchase Order"]: date_field = "transaction_date" @@ -1503,6 +1503,8 @@ class PaymentEntry(AccountsController): if getdate(posting_date) < getdate(self.posting_date): posting_date = self.posting_date + elif self.advance_reconciliation_takes_effect_on == "Reconciliation Date": + posting_date = nowdate() dr_or_cr, account = self.get_dr_and_account_for_advances(invoice) args_dict["account"] = account From be8e1c05200332ce2f6c32ed5f00bca4c748455c Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 9 Jan 2025 20:12:51 +0530 Subject: [PATCH 05/11] refactor: hide old checkbox (cherry picked from commit c8e93e7a61ef95ab3735f235784857a2a02ed2a6) --- 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 39fae1fcba1..ae473e15917 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -797,6 +797,7 @@ "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", + "hidden": 1, "label": "Reconcile on Advance Payment Date" }, { @@ -856,7 +857,7 @@ "image_field": "company_logo", "is_tree": 1, "links": [], - "modified": "2025-01-09 20:01:14.818688", + "modified": "2025-01-09 20:12:25.471544", "modified_by": "Administrator", "module": "Setup", "name": "Company", From 2cdfa9172583738eb177627ff82b60289c0f6d78 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 10 Jan 2025 12:17:13 +0530 Subject: [PATCH 06/11] test: ensure reconciliation date config takes effect (cherry picked from commit e0517852bc54cac3363388b0cdd73da3ba38ddf8) --- .../test_payment_reconciliation.py | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py index 696398c717d..061bbf556fc 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py @@ -6,6 +6,7 @@ import frappe from frappe import qb from frappe.tests.utils import FrappeTestCase, change_settings from frappe.utils import add_days, add_years, flt, getdate, nowdate, today +from frappe.utils.data import getdate as convert_to_date from erpnext import get_default_cost_center from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry @@ -2048,6 +2049,102 @@ class TestPaymentReconciliation(FrappeTestCase): self.assertEqual(pr.get("invoices"), []) self.assertEqual(pr.get("payments"), []) + def test_advance_reconciliation_effect_on_same_date(self): + frappe.db.set_value( + "Company", + self.company, + { + "book_advance_payments_in_separate_party_account": 1, + "default_advance_received_account": self.advance_receivable_account, + "reconciliation_takes_effect_on": "Reconciliation Date", + }, + ) + inv_date = convert_to_date(add_days(nowdate(), -1)) + adv_date = convert_to_date(add_days(nowdate(), -2)) + + si = self.create_sales_invoice(posting_date=inv_date, qty=1, rate=200) + pe = self.create_payment_entry(posting_date=adv_date, amount=80).save().submit() + + pr = self.create_payment_reconciliation() + pr.from_invoice_date = add_days(nowdate(), -1) + pr.to_invoice_date = nowdate() + pr.from_payment_date = add_days(nowdate(), -2) + pr.to_payment_date = nowdate() + pr.default_advance_account = self.advance_receivable_account + + # reconcile multiple payments against invoice + pr.get_unreconciled_entries() + invoices = [x.as_dict() for x in pr.get("invoices")] + payments = [x.as_dict() for x in pr.get("payments")] + pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) + + # Difference amount should not be calculated for base currency accounts + for row in pr.allocation: + self.assertEqual(flt(row.get("difference_amount")), 0.0) + + pr.reconcile() + + si.reload() + self.assertEqual(si.status, "Partly Paid") + # check PR tool output post reconciliation + self.assertEqual(len(pr.get("invoices")), 1) + self.assertEqual(pr.get("invoices")[0].get("outstanding_amount"), 120) + self.assertEqual(pr.get("payments"), []) + + # Assert Ledger Entries + gl_entries = frappe.db.get_all( + "GL Entry", + filters={"voucher_no": pe.name}, + fields=["account", "posting_date", "voucher_no", "against_voucher", "debit", "credit"], + order_by="account, against_voucher, debit", + ) + + expected_gl = [ + { + "account": self.advance_receivable_account, + "posting_date": adv_date, + "voucher_no": pe.name, + "against_voucher": pe.name, + "debit": 0.0, + "credit": 80.0, + }, + { + "account": self.advance_receivable_account, + "posting_date": convert_to_date(nowdate()), + "voucher_no": pe.name, + "against_voucher": pe.name, + "debit": 80.0, + "credit": 0.0, + }, + { + "account": self.debit_to, + "posting_date": convert_to_date(nowdate()), + "voucher_no": pe.name, + "against_voucher": si.name, + "debit": 0.0, + "credit": 80.0, + }, + { + "account": self.bank, + "posting_date": adv_date, + "voucher_no": pe.name, + "against_voucher": None, + "debit": 80.0, + "credit": 0.0, + }, + ] + + self.assertEqual(expected_gl, gl_entries) + + # cancel PE + pe.reload() + pe.cancel() + pr.get_unreconciled_entries() + # check PR tool output + self.assertEqual(len(pr.get("invoices")), 1) + self.assertEqual(len(pr.get("payments")), 0) + self.assertEqual(pr.get("invoices")[0].get("outstanding_amount"), 200) + def make_customer(customer_name, currency=None): if not frappe.db.exists("Customer", customer_name): From a43852054975f7c2670e86e26927937b74b0cff5 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 13 Jan 2025 15:56:41 +0530 Subject: [PATCH 07/11] refactor: store reconciliation date in reference Helps with reposting (cherry picked from commit 7e7775aa44b88fd440d157457e22e59ad9d5a1b0) --- .../payment_entry_reference/payment_entry_reference.json | 9 ++++++++- .../payment_entry_reference/payment_entry_reference.py | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json index 361f516b830..57e401275fd 100644 --- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json +++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json @@ -13,6 +13,7 @@ "payment_term_outstanding", "account_type", "payment_type", + "reconcile_effect_on", "column_break_4", "total_amount", "outstanding_amount", @@ -144,12 +145,18 @@ "is_virtual": 1, "label": "Payment Request Outstanding", "read_only": 1 + }, + { + "fieldname": "reconcile_effect_on", + "fieldtype": "Date", + "label": "Reconcile Effect On", + "read_only": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-09-16 18:11:50.019343", + "modified": "2025-01-13 15:56:18.895082", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry Reference", diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py index 2ac92ba4a84..1d869b92715 100644 --- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py +++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py @@ -30,6 +30,7 @@ class PaymentEntryReference(Document): payment_term: DF.Link | None payment_term_outstanding: DF.Float payment_type: DF.Data | None + reconcile_effect_on: DF.Date | None reference_doctype: DF.Link reference_name: DF.DynamicLink total_amount: DF.Float From e7571c1a32b21be1e8094baa82baecc44a108ef2 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 13 Jan 2025 16:20:58 +0530 Subject: [PATCH 08/11] refactor: save reconcile effect on reference table (cherry picked from commit a4271aa5d1b4cc6572ecb5ff083fb9b58d3b0468) --- .../doctype/payment_entry/payment_entry.json | 4 +++- .../doctype/payment_entry/payment_entry.py | 14 +------------- erpnext/accounts/utils.py | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index df9508793a7..5f191e4800a 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -789,7 +789,9 @@ "fetch_from": "company.reconciliation_takes_effect_on", "fieldname": "advance_reconciliation_takes_effect_on", "fieldtype": "Select", + "hidden": 1, "label": "Advance Reconciliation Takes Effect On", + "no_copy": 1, "options": "Advance Payment Date\nOldest Of Invoice Or Advance\nReconciliation Date" } ], @@ -804,7 +806,7 @@ "table_fieldname": "payment_entries" } ], - "modified": "2025-01-09 20:02:33.402163", + "modified": "2025-01-13 16:03:47.169699", "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 48ed975cf37..a7a3aeda84b 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1493,19 +1493,7 @@ class PaymentEntry(AccountsController): "voucher_detail_no": invoice.name, } - if self.advance_reconciliation_takes_effect_on == "Advance Payment Date": - posting_date = self.posting_date - elif self.advance_reconciliation_takes_effect_on == "Oldest Of Invoice Or Advance": - 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 - elif self.advance_reconciliation_takes_effect_on == "Reconciliation Date": - posting_date = nowdate() - + posting_date = invoice.reconcile_effect_on dr_or_cr, account = self.get_dr_and_account_for_advances(invoice) args_dict["account"] = account args_dict[dr_or_cr] = self.calculate_base_allocated_amount_for_reference(invoice) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 51b4ed248ce..bbf911083a9 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -712,6 +712,22 @@ def update_reference_in_payment_entry( } update_advance_paid = [] + # Update Reconciliation effect date in reference + if payment_entry.advance_reconciliation_takes_effect_on == "Advance Payment Date": + reconcile_on = payment_entry.posting_date + elif payment_entry.advance_reconciliation_takes_effect_on == "Oldest Of Invoice Or Advance": + date_field = "posting_date" + if d.against_voucher_type in ["Sales Order", "Purchase Order"]: + date_field = "transaction_date" + reconcile_on = frappe.db.get_value(d.against_voucher_type, d.against_voucher, date_field) + + if getdate(reconcile_on) < getdate(payment_entry.posting_date): + reconcile_on = payment_entry.posting_date + elif payment_entry.advance_reconciliation_takes_effect_on == "Reconciliation Date": + reconcile_on = nowdate() + + reference_details.update({"reconcile_effect_on": reconcile_on}) + if d.voucher_detail_no: existing_row = payment_entry.get("references", {"name": d["voucher_detail_no"]})[0] From 8f431041f84cc600386087adc69de90a376569f2 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 13 Jan 2025 17:17:18 +0530 Subject: [PATCH 09/11] refactor: backwards compatibility (cherry picked from commit 9fa1865cb7864184176e415fb5502d0bf9ed2eaa) --- .../doctype/payment_entry/payment_entry.py | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index a7a3aeda84b..3b8dc5e0ad0 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1493,7 +1493,27 @@ class PaymentEntry(AccountsController): "voucher_detail_no": invoice.name, } - posting_date = invoice.reconcile_effect_on + if invoice.reconcile_effect_on: + posting_date = invoice.reconcile_effect_on + else: + # For backwards compatibility + # Supporting reposting on payment entries reconciled before select field introduction + if self.advance_reconciliation_takes_effect_on == "Advance Payment Date": + posting_date = self.posting_date + elif self.advance_reconciliation_takes_effect_on == "Oldest Of Invoice Or Advance": + 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 + elif self.advance_reconciliation_takes_effect_on == "Reconciliation Date": + posting_date = nowdate() + frappe.db.set_value("Payment Entry Reference", invoice.name, "reconcile_effect_on", posting_date) + dr_or_cr, account = self.get_dr_and_account_for_advances(invoice) args_dict["account"] = account args_dict[dr_or_cr] = self.calculate_base_allocated_amount_for_reference(invoice) From 18946f84955286b89708860e5e4f9884b87477bf Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 14 Jan 2025 13:52:21 +0530 Subject: [PATCH 10/11] refactor: only update `reconcile_effect_on` advance in separate acc (cherry picked from commit 9ee5fcc602f1dae492d06b85220564c889f49c3a) --- erpnext/accounts/utils.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index bbf911083a9..ae90819b409 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -713,20 +713,21 @@ def update_reference_in_payment_entry( update_advance_paid = [] # Update Reconciliation effect date in reference - if payment_entry.advance_reconciliation_takes_effect_on == "Advance Payment Date": - reconcile_on = payment_entry.posting_date - elif payment_entry.advance_reconciliation_takes_effect_on == "Oldest Of Invoice Or Advance": - date_field = "posting_date" - if d.against_voucher_type in ["Sales Order", "Purchase Order"]: - date_field = "transaction_date" - reconcile_on = frappe.db.get_value(d.against_voucher_type, d.against_voucher, date_field) - - if getdate(reconcile_on) < getdate(payment_entry.posting_date): + if payment_entry.book_advance_payments_in_separate_party_account: + if payment_entry.advance_reconciliation_takes_effect_on == "Advance Payment Date": reconcile_on = payment_entry.posting_date - elif payment_entry.advance_reconciliation_takes_effect_on == "Reconciliation Date": - reconcile_on = nowdate() + elif payment_entry.advance_reconciliation_takes_effect_on == "Oldest Of Invoice Or Advance": + date_field = "posting_date" + if d.against_voucher_type in ["Sales Order", "Purchase Order"]: + date_field = "transaction_date" + reconcile_on = frappe.db.get_value(d.against_voucher_type, d.against_voucher, date_field) - reference_details.update({"reconcile_effect_on": reconcile_on}) + if getdate(reconcile_on) < getdate(payment_entry.posting_date): + reconcile_on = payment_entry.posting_date + elif payment_entry.advance_reconciliation_takes_effect_on == "Reconciliation Date": + reconcile_on = nowdate() + + reference_details.update({"reconcile_effect_on": reconcile_on}) if d.voucher_detail_no: existing_row = payment_entry.get("references", {"name": d["voucher_detail_no"]})[0] From 14d1f67ba9f503bcff0960344565996cc018f280 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 14 Jan 2025 15:24:24 +0530 Subject: [PATCH 11/11] chore: resolve conflicts --- .../doctype/payment_entry/payment_entry.py | 92 ------------------- erpnext/patches.txt | 5 - 2 files changed, 97 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 3b8dc5e0ad0..d714df0927b 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -53,98 +53,6 @@ class InvalidPaymentEntry(ValidationError): class PaymentEntry(AccountsController): -<<<<<<< HEAD -======= - # begin: auto-generated types - # This code is auto-generated. Do not modify anything in this block. - - from typing import TYPE_CHECKING - - if TYPE_CHECKING: - from frappe.types import DF - - from erpnext.accounts.doctype.advance_taxes_and_charges.advance_taxes_and_charges import ( - AdvanceTaxesandCharges, - ) - from erpnext.accounts.doctype.payment_entry_deduction.payment_entry_deduction import ( - PaymentEntryDeduction, - ) - from erpnext.accounts.doctype.payment_entry_reference.payment_entry_reference import ( - PaymentEntryReference, - ) - - advance_reconciliation_takes_effect_on: DF.Literal[ - "Advance Payment Date", "Oldest Of Invoice Or Advance", "Reconciliation Date" - ] - amended_from: DF.Link | None - apply_tax_withholding_amount: DF.Check - auto_repeat: DF.Link | None - bank: DF.ReadOnly | None - bank_account: DF.Link | None - bank_account_no: DF.ReadOnly | None - base_in_words: DF.SmallText | None - base_paid_amount: DF.Currency - base_paid_amount_after_tax: DF.Currency - base_received_amount: DF.Currency - base_received_amount_after_tax: DF.Currency - base_total_allocated_amount: DF.Currency - base_total_taxes_and_charges: DF.Currency - book_advance_payments_in_separate_party_account: DF.Check - clearance_date: DF.Date | None - company: DF.Link - contact_email: DF.Data | None - contact_person: DF.Link | None - cost_center: DF.Link | None - custom_remarks: DF.Check - deductions: DF.Table[PaymentEntryDeduction] - difference_amount: DF.Currency - in_words: DF.SmallText | None - is_opening: DF.Literal["No", "Yes"] - letter_head: DF.Link | None - mode_of_payment: DF.Link | None - naming_series: DF.Literal["ACC-PAY-.YYYY.-"] - paid_amount: DF.Currency - paid_amount_after_tax: DF.Currency - paid_from: DF.Link - paid_from_account_balance: DF.Currency - paid_from_account_currency: DF.Link - paid_from_account_type: DF.Data | None - paid_to: DF.Link - paid_to_account_balance: DF.Currency - paid_to_account_currency: DF.Link - paid_to_account_type: DF.Data | None - party: DF.DynamicLink | None - party_balance: DF.Currency - party_bank_account: DF.Link | None - party_name: DF.Data | None - party_type: DF.Link | None - payment_order: DF.Link | None - payment_order_status: DF.Literal["Initiated", "Payment Ordered"] - payment_type: DF.Literal["Receive", "Pay", "Internal Transfer"] - posting_date: DF.Date - print_heading: DF.Link | None - project: DF.Link | None - purchase_taxes_and_charges_template: DF.Link | None - received_amount: DF.Currency - received_amount_after_tax: DF.Currency - reconcile_on_advance_payment_date: DF.Check - reference_date: DF.Date | None - reference_no: DF.Data | None - references: DF.Table[PaymentEntryReference] - remarks: DF.SmallText | None - sales_taxes_and_charges_template: DF.Link | None - source_exchange_rate: DF.Float - status: DF.Literal["", "Draft", "Submitted", "Cancelled"] - target_exchange_rate: DF.Float - tax_withholding_category: DF.Link | None - taxes: DF.Table[AdvanceTaxesandCharges] - title: DF.Data | None - total_allocated_amount: DF.Currency - total_taxes_and_charges: DF.Currency - unallocated_amount: DF.Currency - # end: auto-generated types - ->>>>>>> 8b2c981fc3 (refactor: introduce select fields in company and payment entry) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if not self.is_new(): diff --git a/erpnext/patches.txt b/erpnext/patches.txt index c1b626502ac..a16f87de0dc 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -386,10 +386,5 @@ erpnext.patches.v14_0.update_stock_uom_in_work_order_item erpnext.patches.v15_0.set_is_exchange_gain_loss_in_payment_entry_deductions erpnext.patches.v15_0.enable_allow_existing_serial_no erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts -<<<<<<< HEAD -erpnext.patches.v15_0.update_asset_status_to_work_in_progress -======= -erpnext.patches.v15_0.refactor_closing_stock_balance #5 erpnext.patches.v15_0.update_asset_status_to_work_in_progress erpnext.patches.v15_0.migrate_checkbox_to_select_for_reconciliation_effect ->>>>>>> a8a8ac71b6 (refactor: patch to migrate checkbox to select)