refactor: hook validate_allowed_companies instead of calling per master

Item, Customer and Supplier each imported and called it in their
validate; register it once in doc_events instead.
This commit is contained in:
Mihir Kandoi
2026-07-22 14:17:32 +05:30
parent 88b8ce3888
commit 01892c2e26
6 changed files with 9 additions and 7 deletions

View File

@@ -20,7 +20,6 @@ from erpnext.controllers.website_list_for_contact import (
add_role_for_portal_user,
link_portal_users_to_contacts,
)
from erpnext.stock.doctype.company_restriction.company_restriction import validate_allowed_companies
from erpnext.utilities.transaction_base import TransactionBase
@@ -154,7 +153,6 @@ class Supplier(TransactionBase):
self.validate_internal_supplier()
self.add_role_for_user()
self.validate_currency_for_receivable_payable_and_advance_account()
validate_allowed_companies(self)
@frappe.whitelist()
def get_supplier_group_details(self):

View File

@@ -400,6 +400,9 @@ doc_events = {
tuple(company_restricted_transaction_doctypes): {
"validate": "erpnext.stock.doctype.company_restriction.company_restriction.validate_transaction_company",
},
("Item", "Customer", "Supplier"): {
"validate": "erpnext.stock.doctype.company_restriction.company_restriction.validate_allowed_companies",
},
"Stock Entry": {
"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",

View File

@@ -28,7 +28,6 @@ from erpnext.controllers.website_list_for_contact import (
add_role_for_portal_user,
link_portal_users_to_contacts,
)
from erpnext.stock.doctype.company_restriction.company_restriction import validate_allowed_companies
from erpnext.utilities.transaction_base import TransactionBase
from .mapper import (
@@ -193,7 +192,6 @@ class Customer(TransactionBase):
self.validate_internal_customer()
self.add_role_for_user()
self.validate_currency_for_receivable_payable_and_advance_account()
validate_allowed_companies(self)
# set loyalty program tier
if not self.is_new() and (customer := self.get_doc_before_save()):

View File

@@ -79,7 +79,7 @@ def has_permission(doc, ptype=None, user=None):
return any(row.company in allowed_companies for row in doc.get("allowed_companies") or [])
def validate_allowed_companies(doc):
def validate_allowed_companies(doc, method=None):
if not doc.get("restrict_to_companies"):
doc.set("allowed_companies", [])
elif not doc.get("allowed_companies") and not doc.flags.ignore_mandatory:

View File

@@ -54,3 +54,8 @@ class TestCompanyRestriction(ERPNextTestSuite):
def test_unrestricted_item_is_not_blocked(self):
item = make_item()
make_material_request(item_code=item.name)
def test_allowed_companies_is_mandatory_when_restricted(self):
item = make_item()
item.restrict_to_companies = 1
self.assertRaises(frappe.MandatoryError, item.save)

View File

@@ -30,7 +30,6 @@ from erpnext.controllers.item_variant import (
make_variant_item_code,
validate_item_variant_attributes,
)
from erpnext.stock.doctype.company_restriction.company_restriction import validate_allowed_companies
from erpnext.stock.doctype.item_default.item_default import ItemDefault
from erpnext.stock.serial_batch_bundle import SerialBatchCreation
from erpnext.stock.utils import get_valuation_method
@@ -246,7 +245,6 @@ class Item(Document):
self.validate_serialized_change_with_bundle()
self.validate_standard_cost_change()
self.validate_item_tax_net_rate_range()
validate_allowed_companies(self)
if not self.is_new():
self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group")