fix: don't allow renaming account while system is actively in use (#46176)
(cherry picked from commit 999f1cf96d)
Co-authored-by: Ankush Menat <ankush@frappe.io>
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _, throw
|
from frappe import _, throw
|
||||||
from frappe.utils import cint, cstr
|
from frappe.utils import add_to_date, cint, cstr, pretty_date
|
||||||
from frappe.utils.nestedset import NestedSet, get_ancestors_of, get_descendants_of
|
from frappe.utils.nestedset import NestedSet, get_ancestors_of, get_descendants_of
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
@@ -481,6 +481,7 @@ def get_account_autoname(account_number, account_name, company):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_account_number(name, account_name, account_number=None, from_descendant=False):
|
def update_account_number(name, account_name, account_number=None, from_descendant=False):
|
||||||
|
_ensure_idle_system()
|
||||||
account = frappe.get_cached_doc("Account", name)
|
account = frappe.get_cached_doc("Account", name)
|
||||||
if not account:
|
if not account:
|
||||||
return
|
return
|
||||||
@@ -542,6 +543,7 @@ def update_account_number(name, account_name, account_number=None, from_descenda
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def merge_account(old, new):
|
def merge_account(old, new):
|
||||||
|
_ensure_idle_system()
|
||||||
# Validate properties before merging
|
# Validate properties before merging
|
||||||
new_account = frappe.get_cached_doc("Account", new)
|
new_account = frappe.get_cached_doc("Account", new)
|
||||||
old_account = frappe.get_cached_doc("Account", old)
|
old_account = frappe.get_cached_doc("Account", old)
|
||||||
@@ -595,3 +597,27 @@ def sync_update_account_number_in_child(
|
|||||||
|
|
||||||
for d in frappe.db.get_values("Account", filters=filters, fieldname=["company", "name"], as_dict=True):
|
for d in frappe.db.get_values("Account", filters=filters, fieldname=["company", "name"], as_dict=True):
|
||||||
update_account_number(d["name"], account_name, account_number, from_descendant=True)
|
update_account_number(d["name"], account_name, account_number, from_descendant=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_idle_system():
|
||||||
|
# Don't allow renaming if accounting entries are actively being updated, there are two main reasons:
|
||||||
|
# 1. Correctness: It's next to impossible to ensure that renamed account is not being used *right now*.
|
||||||
|
# 2. Performance: Renaming requires locking out many tables entirely and severely degrades performance.
|
||||||
|
|
||||||
|
if frappe.flags.in_test:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# We also lock inserts to GL entry table with for_update here.
|
||||||
|
last_gl_update = frappe.db.get_value("GL Entry", {}, "modified", for_update=True, wait=False)
|
||||||
|
except frappe.QueryTimeoutError:
|
||||||
|
# wait=False fails immediately if there's an active transaction.
|
||||||
|
last_gl_update = add_to_date(None, seconds=-1)
|
||||||
|
|
||||||
|
if last_gl_update > add_to_date(None, minutes=-5):
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Last GL Entry update was done {}. This operation is not allowed while system is actively being used. Please wait for 5 minutes before retrying."
|
||||||
|
).format(pretty_date(last_gl_update)),
|
||||||
|
title=_("System In Use"),
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user