From 4436585aa07a82ab3704d8091fd99482854aa854 Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Mon, 25 May 2026 21:39:54 +0530 Subject: [PATCH 1/6] 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` From b8b2141e20eeadf4b06f29f944e0da7567e40acf Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Tue, 26 May 2026 14:19:04 +0530 Subject: [PATCH 2/6] test: update testcase (cherry picked from commit 9c39b01f1c838e88cec373bb320fc53332e47df7) --- .../test_period_closing_voucher.py | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) 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 15f2025e669..c5b20ea395f 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 @@ -375,16 +375,6 @@ class TestPeriodClosingVoucher(unittest.TestCase): 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", @@ -402,14 +392,7 @@ class TestPeriodClosingVoucher(unittest.TestCase): 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, - ) + self.assertEqual(totals_after_cancel.total_debit, totals_after_cancel.total_credit) def create_company(): From 76078a7fb941ba2b820e1af9ac8c040f6a774654 Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Tue, 26 May 2026 15:48:41 +0530 Subject: [PATCH 3/6] fix: ERPNextTestSuite to change_settings --- .../period_closing_voucher/test_period_closing_voucher.py | 2 +- 1 file changed, 1 insertion(+), 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 c5b20ea395f..e5098b0bfbc 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 @@ -352,7 +352,7 @@ class TestPeriodClosingVoucher(unittest.TestCase): return pcv - @ERPNextTestSuite.change_settings( + @change_settings( "Accounts Settings", {"enable_immutable_ledger": 1}, ) From 9d211990c3a3782a938fb2ad7c24d2941783a73e Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Tue, 26 May 2026 15:56:38 +0530 Subject: [PATCH 4/6] fix: import change_settings --- .../period_closing_voucher/test_period_closing_voucher.py | 1 + 1 file changed, 1 insertion(+) 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 e5098b0bfbc..68c6364e88c 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 @@ -12,6 +12,7 @@ from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journ 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 +from erpnext.tests.utils import change_settings class TestPeriodClosingVoucher(unittest.TestCase): From 31c251d9561d8149bc8d79e0e2c4a41bec18e7f6 Mon Sep 17 00:00:00 2001 From: "Nihantra C. Patel" <141945075+Nihantra-Patel@users.noreply.github.com> Date: Tue, 26 May 2026 16:24:31 +0530 Subject: [PATCH 5/6] fix: update import --- .../period_closing_voucher/test_period_closing_voucher.py | 2 +- 1 file changed, 1 insertion(+), 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 68c6364e88c..5b42bc0f210 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 @@ -5,6 +5,7 @@ import unittest import frappe +from frappe.tests.utils import change_settings from frappe.utils import today from erpnext.accounts.doctype.finance_book.test_finance_book import create_finance_book @@ -12,7 +13,6 @@ from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journ 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 -from erpnext.tests.utils import change_settings class TestPeriodClosingVoucher(unittest.TestCase): From 8f164cff1d450470b05e0da6cbaaa2a9e92e3470 Mon Sep 17 00:00:00 2001 From: Nihantra Patel Date: Tue, 26 May 2026 22:53:14 +0530 Subject: [PATCH 6/6] test: immutable ledger reverse entry --- .../period_closing_voucher/test_period_closing_voucher.py | 3 +++ 1 file changed, 3 insertions(+) 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 5b42bc0f210..e4e31a9adf4 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 @@ -358,6 +358,9 @@ class TestPeriodClosingVoucher(unittest.TestCase): {"enable_immutable_ledger": 1}, ) def test_immutable_ledger_reverse_entry_uses_passed_posting_date_after_pcv(self): + frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") + frappe.db.sql("delete from `tabPeriod Closing Voucher` where company='Test PCV Company'") + company = create_company() cost_center = create_cost_center("Test Cost Center 1")