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 3258a8cbe8a..95ab540d657 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 @@ -8,6 +8,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 from erpnext.tests.utils import ERPNextTestSuite @@ -334,6 +335,48 @@ class TestPeriodClosingVoucher(ERPNextTestSuite): 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") + + # 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_after_cancel.total_credit) + def create_company(): company = frappe.get_doc( diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index e5480fd4244..341488381a0 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -719,7 +719,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`