mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-13 10:11:20 +00:00
Merge pull request #23591 from anupamvs/item-attribute
feat: validate if removed item attributes exist in variants
This commit is contained in:
@@ -111,6 +111,7 @@ class Item(WebsiteGenerator):
|
|||||||
self.synced_with_hub = 0
|
self.synced_with_hub = 0
|
||||||
|
|
||||||
self.validate_has_variants()
|
self.validate_has_variants()
|
||||||
|
self.validate_attributes_in_variants()
|
||||||
self.validate_stock_exists_for_template_item()
|
self.validate_stock_exists_for_template_item()
|
||||||
self.validate_attributes()
|
self.validate_attributes()
|
||||||
self.validate_variant_attributes()
|
self.validate_variant_attributes()
|
||||||
@@ -806,6 +807,76 @@ class Item(WebsiteGenerator):
|
|||||||
if frappe.db.exists("Item", {"variant_of": self.name}):
|
if frappe.db.exists("Item", {"variant_of": self.name}):
|
||||||
frappe.throw(_("Item has variants."))
|
frappe.throw(_("Item has variants."))
|
||||||
|
|
||||||
|
def validate_attributes_in_variants(self):
|
||||||
|
if not self.has_variants or self.get("__islocal"):
|
||||||
|
return
|
||||||
|
|
||||||
|
old_doc = self.get_doc_before_save()
|
||||||
|
old_doc_attributes = set([attr.attribute for attr in old_doc.attributes])
|
||||||
|
own_attributes = [attr.attribute for attr in self.attributes]
|
||||||
|
|
||||||
|
# Check if old attributes were removed from the list
|
||||||
|
# Is old_attrs is a subset of new ones
|
||||||
|
# that means we need not check any changes
|
||||||
|
if old_doc_attributes.issubset(set(own_attributes)):
|
||||||
|
return
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
# get all item variants
|
||||||
|
items = [item["name"] for item in frappe.get_all("Item", {"variant_of": self.name})]
|
||||||
|
|
||||||
|
# get all deleted attributes
|
||||||
|
deleted_attribute = list(old_doc_attributes.difference(set(own_attributes)))
|
||||||
|
|
||||||
|
# fetch all attributes of these items
|
||||||
|
item_attributes = frappe.get_all(
|
||||||
|
"Item Variant Attribute",
|
||||||
|
filters={
|
||||||
|
"parent": ["in", items],
|
||||||
|
"attribute": ["in", deleted_attribute]
|
||||||
|
},
|
||||||
|
fields=["attribute", "parent"]
|
||||||
|
)
|
||||||
|
not_included = defaultdict(list)
|
||||||
|
|
||||||
|
for attr in item_attributes:
|
||||||
|
if attr["attribute"] not in own_attributes:
|
||||||
|
not_included[attr["parent"]].append(attr["attribute"])
|
||||||
|
|
||||||
|
if not len(not_included):
|
||||||
|
return
|
||||||
|
|
||||||
|
def body(docnames):
|
||||||
|
docnames.sort()
|
||||||
|
return "<br>".join(docnames)
|
||||||
|
|
||||||
|
def table_row(title, body):
|
||||||
|
return """<tr>
|
||||||
|
<td>{0}</td>
|
||||||
|
<td>{1}</td>
|
||||||
|
</tr>""".format(title, body)
|
||||||
|
|
||||||
|
rows = ''
|
||||||
|
for docname, attr_list in not_included.items():
|
||||||
|
link = "<a href='#Form/Item/{0}'>{0}</a>".format(frappe.bold(_(docname)))
|
||||||
|
rows += table_row(link, body(attr_list))
|
||||||
|
|
||||||
|
error_description = _('The following deleted attributes exist in Variants but not in the Template. You can either delete the Variants or keep the attribute(s) in template.')
|
||||||
|
|
||||||
|
message = """
|
||||||
|
<div>{0}</div><br>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<td>{1}</td>
|
||||||
|
<td>{2}</td>
|
||||||
|
</thead>
|
||||||
|
{3}
|
||||||
|
</table>
|
||||||
|
""".format(error_description, _('Variant Items'), _('Attributes'), rows)
|
||||||
|
|
||||||
|
frappe.throw(message, title=_("Variant Attribute Error"), is_minimizable=True)
|
||||||
|
|
||||||
def validate_stock_exists_for_template_item(self):
|
def validate_stock_exists_for_template_item(self):
|
||||||
if self.stock_ledger_created() and self._doc_before_save:
|
if self.stock_ledger_created() and self._doc_before_save:
|
||||||
if (cint(self._doc_before_save.has_variants) != cint(self.has_variants)
|
if (cint(self._doc_before_save.has_variants) != cint(self.has_variants)
|
||||||
|
|||||||
Reference in New Issue
Block a user