From 4436585aa07a82ab3704d8091fd99482854aa854 Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Mon, 25 May 2026 21:39:54 +0530 Subject: [PATCH] fix: use passed posting date in make_reverse_gl_entries (cherry picked from commit f040bdf1656545362d86bda44c8986274124622a) --- .../test_period_closing_voucher.py | 60 +++++++++++++++++++ erpnext/accounts/general_ledger.py | 7 ++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py index 2aa484d05a1..15f2025e669 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py @@ -10,6 +10,7 @@ from frappe.utils import today from erpnext.accounts.doctype.finance_book.test_finance_book import create_finance_book from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice +from erpnext.accounts.general_ledger import make_reverse_gl_entries from erpnext.accounts.utils import get_fiscal_year @@ -351,6 +352,65 @@ class TestPeriodClosingVoucher(unittest.TestCase): return pcv + @ERPNextTestSuite.change_settings( + "Accounts Settings", + {"enable_immutable_ledger": 1}, + ) + def test_immutable_ledger_reverse_entry_uses_passed_posting_date_after_pcv(self): + company = create_company() + cost_center = create_cost_center("Test Cost Center 1") + + jv = make_journal_entry( + posting_date="2021-03-15", + amount=400, + account1="Cash - TPC", + account2="Sales - TPC", + cost_center=cost_center, + company=company, + save=False, + ) + jv.company = company + jv.save() + jv.submit() + + self.make_period_closing_voucher(posting_date="2021-03-31") + + totals_before_cancel = frappe.db.sql( + """ + select sum(debit) as total_debit, sum(credit) as total_credit + from `tabGL Entry` + where voucher_type=%s and voucher_no=%s and is_cancelled=0 + """, + ("Journal Entry", jv.name), + as_dict=True, + )[0] + + # Passed posting_date is after PCV end date, so cancellation should not fail. + make_reverse_gl_entries( + voucher_type="Journal Entry", + voucher_no=jv.name, + posting_date="2022-01-01", + ) + + totals_after_cancel = frappe.db.sql( + """ + select sum(debit) as total_debit, sum(credit) as total_credit + from `tabGL Entry` + where voucher_type=%s and voucher_no=%s and is_cancelled=0 + """, + ("Journal Entry", jv.name), + as_dict=True, + )[0] + + self.assertEqual( + totals_after_cancel.total_debit, + totals_before_cancel.total_debit * 2, + ) + self.assertEqual( + totals_after_cancel.total_credit, + totals_before_cancel.total_credit * 2, + ) + def create_company(): company = frappe.get_doc( diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index ab86dcfd15c..599173c99f5 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -700,7 +700,12 @@ def make_reverse_gl_entries( check_freezing_date(gl_entries[0]["posting_date"], adv_adj) is_opening = any(d.get("is_opening") == "Yes" for d in gl_entries) - validate_against_pcv(is_opening, gl_entries[0]["posting_date"], gl_entries[0]["company"]) + + # For reverse entries, use the posting_date parameter if provided and valid + # Otherwise fall back to original posting_date + validation_date = posting_date if posting_date else gl_entries[0]["posting_date"] + validate_against_pcv(is_opening, validation_date, gl_entries[0]["company"]) + if partial_cancel: # Partial cancel is only used by `Advance` in separate account feature. # Only cancel GL entries for unlinked reference using `voucher_detail_no`