From 0be33e4132a5f56669a3cf1c909a80545cb3a92b Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 27 Jul 2026 10:21:53 +0530 Subject: [PATCH 1/2] refactor: configurable date in reverse ERR journals --- .../exchange_rate_revaluation.py | 28 +++++++++++++------ .../doctype/journal_entry/journal_entry.js | 1 + 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py index 84ba411c97f..22c70e6d8cd 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py @@ -623,15 +623,27 @@ class ExchangeRateRevaluation(Document): if journals: from erpnext.accounts.doctype.journal_entry.mapper import make_reverse_journal_entry - for x in journals: - reversal = make_reverse_journal_entry(x) - reversal.posting_date = nowdate() - reversal.submit() - frappe.msgprint( - _("Revaluation journal for {0} has been created: {1}").format( - frappe.bold(x), get_link_to_form("Journal Entry", reversal.name) - ) + if drafts := frappe.db.get_all( + "Journal Entry", + filters={"docstatus": 0, "reversal_of": ["in", journals]}, + pluck="name", + as_list=1, + ): + part = "journals are" if len(drafts) > 1 else "journal is" + doc_links = ", ".join(["{}".format(get_link_to_form("Journal Entry", x)) for x in drafts]) + frappe.throw( + msg=_("Reverse {0} already available in draft status: {1}").format(part, doc_links), ) + else: + for x in journals: + reversal = make_reverse_journal_entry(x) + reversal.posting_date = nowdate() + reversal.save() + frappe.msgprint( + _("A draft reverse journal for {0} has been created: {1}").format( + frappe.bold(x), get_link_to_form("Journal Entry", reversal.name) + ) + ) def calculate_exchange_rate_using_last_gle(company, account, party_type, party): diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index ffe6630c725..d294573eca2 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -235,6 +235,7 @@ Object.assign(erpnext.journal_entry, { lock_reversal_entry(frm) { frm.fields .filter((field) => field.has_input) + .filter((field) => field.df.fieldname != "posting_date") .forEach((field) => frm.set_df_property(field.df.fieldname, "read_only", 1)); frm.set_df_property("accounts", "read_only", 1); }, From 1a558ce6419f5b00c9f50067bd919d3a9a4d46c5 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 27 Jul 2026 11:18:41 +0530 Subject: [PATCH 2/2] refactor(test): manually submit reverse err journal --- .../test_exchange_rate_revaluation.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py index 3e5b08d069d..3f849c1082b 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py @@ -377,6 +377,15 @@ class TestExchangeRateRevaluation(ERPNextTestSuite, AccountsTestMixin): self.assertFalse(ret.get("reversals_posted")) err.make_reverse_journal() + # submit + draft = frappe.db.get_all( + "Journal Entry", + filters={"docstatus": 0, "reversal_of": je.name, "voucher_type": "Exchange Rate Revaluation"}, + pluck="name", + as_list=1, + ) + self.assertIsNotNone(draft) + frappe.get_doc("Journal Entry", draft[0]).submit() ret = err.check_journal_and_reversal() self.assertTrue(ret.get("journals_posted")) self.assertTrue(ret.get("reversals_posted"))