fix(crm): validate party specific items on opportunity from customer

This commit is contained in:
Shllokkk
2026-10-22 14:41:43 +05:30
parent a0da316f54
commit f2fae012eb
2 changed files with 46 additions and 0 deletions
@@ -133,6 +133,7 @@ class Opportunity(TransactionBase, CRMNote):
self.validate_uom_is_integer("uom", "qty")
self.validate_cust_name()
self.validate_party()
self.validate_party_specific_items()
self.map_fields()
self.validate_qty()
self.set_exchange_rate()
@@ -145,6 +146,32 @@ class Opportunity(TransactionBase, CRMNote):
def on_update(self):
self.update_prospect()
def validate_party_specific_items(self):
if self.opportunity_from != "Customer" or not self.party_name:
return
from erpnext.selling.doctype.party_specific_item.party_specific_item import get_party_specific_items
allowed_values = get_party_specific_items(self.party_name)
if not allowed_values:
return
rows = [row for row in self.get("items") if row.item_code]
allowed_items = frappe.get_all(
"Item",
filters=[["name", "in", list({row.item_code for row in rows})]]
+ [[field, "in", values] for field, values in allowed_values.items()],
pluck="name",
)
for row in rows:
if row.item_code not in allowed_items:
frappe.throw(
_("Row {0}: Item {1} is not allowed for {2} {3}.").format(
row.idx, frappe.bold(row.item_code), _("Customer"), frappe.bold(self.party_name)
),
title=_("Item Restricted for Party"),
)
def validate_qty(self):
for item in self.items:
if flt(item.qty) <= 0:
@@ -94,3 +94,22 @@ class TestPartySpecificItem(FrappeTestCase):
standalone_note = frappe.copy_doc(credit_note)
standalone_note.return_against = None
self.assertRaisesRegex(frappe.ValidationError, "is not allowed for", standalone_note.insert)
def test_opportunity_enforces_party_rules(self):
from erpnext.crm.doctype.opportunity.test_opportunity import make_opportunity
create_party_specific_item(
party_type="Customer",
party="_Test Customer 1",
restrict_based_on="Item",
based_on_value="_Test Item Home Desktop 100",
)
make_opportunity(with_items=1, customer="_Test Customer 1", item_code="_Test Item Home Desktop 100")
self.assertRaisesRegex(
frappe.ValidationError,
"is not allowed for Customer",
make_opportunity,
with_items=1,
customer="_Test Customer 1",
item_code="_Test Item",
)