fix(stock): propagate renamed attribute values to variant items

This commit is contained in:
barredterra
2026-06-17 17:04:58 +02:00
parent 5c4220ee77
commit 27d574dad5
3 changed files with 69 additions and 0 deletions

View File

@@ -129,6 +129,49 @@ def validate_is_incremental(numeric_attribute, attribute, value, item):
)
def get_attribute_value_renames(item_attribute):
"""Return old to new attribute value mappings for renamed Item Attribute Value rows."""
if item_attribute.numeric_values:
return {}
db_value = item_attribute.get_doc_before_save()
if not db_value:
return {}
old_values = {d.name: d.attribute_value for d in db_value.item_attribute_values}
renames = {}
for row in item_attribute.item_attribute_values:
if row.name in old_values and old_values[row.name] != row.attribute_value:
renames[old_values[row.name]] = row.attribute_value
return renames
def update_variant_attribute_values(item_attribute):
"""Propagate renamed Item Attribute Values to Item Variant Attribute on variant items."""
value_map = get_attribute_value_renames(item_attribute)
if not value_map:
return
item_variant_table = frappe.qb.DocType("Item Variant Attribute")
item_table = frappe.qb.DocType("Item")
for old_value, new_value in value_map.items():
(
frappe.qb.update(item_variant_table)
.join(item_table)
.on(item_table.name == item_variant_table.parent)
.set(item_variant_table.attribute_value, new_value)
.where(item_table.variant_of.isnotnull())
.where(item_table.variant_of != "")
.where(item_variant_table.attribute == item_attribute.name)
.where(item_variant_table.attribute_value == old_value)
).run()
frappe.flags.attribute_values = None
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item, from_variant=True):
allow_rename_attribute_value = frappe.db.get_single_value(
"Item Variant Settings", "allow_rename_attribute_value"

View File

@@ -360,6 +360,30 @@ class TestItem(FrappeTestCase):
self.assertRaises(InvalidItemAttributeValueError, attribute.save)
frappe.db.rollback()
def test_rename_attribute_value_updates_variants(self):
frappe.delete_doc_if_exists("Item", "_Test Variant Item-L", force=1)
variant = create_variant("_Test Variant Item", {"Test Size": "Large"})
variant.save()
attribute = frappe.get_doc("Item Attribute", "Test Size")
for row in attribute.item_attribute_values:
if row.attribute_value == "Large":
row.attribute_value = "Larger"
break
frappe.flags.attribute_values = None
attribute.save()
self.assertEqual(
frappe.db.get_value(
"Item Variant Attribute",
{"parent": variant.name, "attribute": "Test Size"},
"attribute_value",
),
"Larger",
)
def test_make_item_variant(self):
frappe.delete_doc_if_exists("Item", "_Test Variant Item-L", force=1)

View File

@@ -9,6 +9,7 @@ from frappe.utils import flt
from erpnext.controllers.item_variant import (
InvalidItemAttributeValueError,
update_variant_attribute_values,
validate_is_incremental,
validate_item_attribute_value,
)
@@ -47,6 +48,7 @@ class ItemAttribute(Document):
self.validate_duplication()
def on_update(self):
update_variant_attribute_values(self)
self.validate_exising_items()
self.set_enabled_disabled_in_items()