Merge pull request #58175 from aerele/backport-58092-version-15-hotfix

fix(accounts): disallow reversing a reverse journal entry
This commit is contained in:
Khushi Rawat
2026-08-14 17:43:53 +05:30
committed by GitHub
3 changed files with 38 additions and 2 deletions

View File

@@ -65,7 +65,7 @@ frappe.ui.form.on("Journal Entry", {
);
}
if (frm.doc.docstatus == 1) {
if (frm.doc.docstatus == 1 && !frm.doc.reversal_of) {
frm.add_custom_button(
__("Reverse Journal Entry"),
function () {

View File

@@ -7,6 +7,7 @@ import json
import frappe
from frappe import _, msgprint, scrub
from frappe.core.doctype.submission_queue.submission_queue import queue_submission
from frappe.model.document import Document
from frappe.utils import comma_and, cstr, flt, fmt_money, formatdate, get_link_to_form, getdate, nowdate
import erpnext
@@ -1892,7 +1893,21 @@ def make_inter_company_journal_entry(name, voucher_type, company):
@frappe.whitelist()
def make_reverse_journal_entry(source_name, target_doc=None):
def make_reverse_journal_entry(source_name: str, target_doc: str | dict | Document | None = None) -> Document:
# `get_mapped_doc` checks this as well, but the guard below discloses which entry
# reverses which, so read access has to be settled before it runs
if not frappe.has_permission("Journal Entry", doc=source_name):
frappe.throw(_("Not permitted"), frappe.PermissionError)
reversal_of = frappe.db.get_value("Journal Entry", source_name, "reversal_of")
if reversal_of:
frappe.throw(
_("{0} is already a Reverse Journal Entry of {1}. Cancel it instead of reversing it.").format(
get_link_to_form("Journal Entry", source_name),
get_link_to_form("Journal Entry", reversal_of),
)
)
from frappe.model.mapper import get_mapped_doc
def post_process(source, target):

View File

@@ -249,6 +249,27 @@ class TestJournalEntry(unittest.TestCase):
self.check_gl_entries()
def test_disallow_reversal_of_a_reversal_journal_entry(self):
from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry
jv = make_journal_entry("_Test Bank - _TC", "Sales - _TC", 100, submit=True)
rjv = make_reverse_journal_entry(jv.name)
rjv.posting_date = nowdate()
rjv.submit()
self.assertRaisesRegex(
frappe.ValidationError,
"is already a Reverse Journal Entry",
make_reverse_journal_entry,
rjv.name,
)
# the guard must not disclose the reversal to a user who cannot read the entry
frappe.set_user("Guest")
self.addCleanup(frappe.set_user, "Administrator")
self.assertRaises(frappe.PermissionError, make_reverse_journal_entry, rjv.name)
def test_disallow_change_in_account_currency_for_a_party(self):
# create jv in USD
jv = make_journal_entry("_Test Bank USD - _TC", "_Test Receivable USD - _TC", 100, save=False)