mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-01 12:38:27 +00:00
* fix: don't allow renaming account while system is actively in use (#46176)
(cherry picked from commit 999f1cf96d)
# Conflicts:
# erpnext/accounts/doctype/account/account.py
* chore: conflicts
---------
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
|
||||||
@@ -400,6 +400,7 @@ def validate_account_number(name, account_number, 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.db.get_value("Account", name, "company", as_dict=True)
|
account = frappe.db.get_value("Account", name, "company", as_dict=True)
|
||||||
if not account:
|
if not account:
|
||||||
return
|
return
|
||||||
@@ -461,6 +462,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)
|
||||||
@@ -514,3 +516,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