From 1c40a61d236a6fe2bd4c3dc99714bb95ce7e58f1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 17 Dec 2025 15:26:36 +0530 Subject: [PATCH] fix: validate party's existing transaction currency before merging (cherry picked from commit f48b90c6009a0ad6331fd62e57f57a4dc8d6c73a) --- erpnext/accounts/party.py | 18 ++++++++++++++++++ erpnext/buying/doctype/supplier/supplier.py | 5 +++++ erpnext/selling/doctype/customer/customer.py | 10 +++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index 38dc1e7502d..b8bcc3a4160 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -1056,3 +1056,21 @@ def add_party_account(party_type, party, company, account): def render_address(address, check_permissions=True): return frappe.call(_render_address, address, check_permissions=check_permissions) + + +def validate_party_currency_before_merging(party_type, old_party, new_party): + for company in frappe.get_all("Company"): + old_party_currency = get_party_gle_currency(party_type, old_party, company.name) + new_party_currency = get_party_gle_currency(party_type, new_party, company.name) + + if old_party_currency and new_party_currency and old_party_currency != new_party_currency: + frappe.throw( + _( + "Cannot merge {0} '{1}' into '{2}' as both have existing accounting entries in different currencies for company '{3}'." + ).format( + party_type, + old_party, + new_party, + company.name, + ) + ) diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index 07a2d31166b..f0e85523ea3 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -14,6 +14,7 @@ from frappe.model.naming import set_name_by_naming_series, set_name_from_naming_ from erpnext.accounts.party import ( get_dashboard_info, validate_party_accounts, + validate_party_currency_before_merging, ) from erpnext.controllers.website_list_for_contact import add_role_for_portal_user from erpnext.utilities.transaction_base import TransactionBase @@ -208,6 +209,10 @@ class Supplier(TransactionBase): delete_contact_and_address("Supplier", self.name) + def before_rename(self, olddn, newdn, merge=False): + if merge: + validate_party_currency_before_merging("Supplier", olddn, newdn) + def after_rename(self, olddn, newdn, merge=False): if frappe.defaults.get_global_default("supp_master_name") == "Supplier Name": self.db_set("supplier_name", newdn) diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 449b56de3b4..1c1ae08b280 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -18,7 +18,11 @@ from frappe.utils import cint, cstr, flt, get_formatted_email, today from frappe.utils.deprecations import deprecated from frappe.utils.user import get_users_with_role -from erpnext.accounts.party import get_dashboard_info, validate_party_accounts +from erpnext.accounts.party import ( + get_dashboard_info, + validate_party_accounts, + validate_party_currency_before_merging, +) from erpnext.controllers.website_list_for_contact import add_role_for_portal_user from erpnext.utilities.transaction_base import TransactionBase @@ -367,6 +371,10 @@ class Customer(TransactionBase): if self.lead_name: frappe.db.sql("update `tabLead` set status='Interested' where name=%s", self.lead_name) + def before_rename(self, olddn, newdn, merge=False): + if merge: + validate_party_currency_before_merging("Customer", olddn, newdn) + def after_rename(self, olddn, newdn, merge=False): if frappe.defaults.get_global_default("cust_master_name") == "Customer Name": self.db_set("customer_name", newdn)