From f119080eb384a4e8aa49fb6beb7a97c97a0c900b Mon Sep 17 00:00:00 2001 From: pandiyan Date: Mon, 6 Jul 2026 14:15:40 +0530 Subject: [PATCH] test: cover variant item_code/item_name rename on abbreviation change Add regression coverage for the new abbreviation-rename propagation: a simple item_code rename, item_name derived from a template whose item_name differs from its item_code, and a manually customized item_name getting rebuilt rather than left stale. (cherry picked from commit e718a70b2603a19fc6c9f2213be34f313ef68be2) --- erpnext/stock/doctype/item/test_item.py | 94 +++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index a2319ca9488..073c8c8be93 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -443,6 +443,100 @@ class TestItem(FrappeTestCase): "Large", ) + def test_rename_attribute_abbr_updates_variant_item_code(self): + frappe.delete_doc_if_exists("Item", "_Test Variant Item-L", force=1) + frappe.delete_doc_if_exists("Item", "_Test Variant Item-LRG", 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.abbr = "LRG" + break + + def restore_test_size_abbr(): + doc = frappe.get_doc("Item Attribute", "Test Size") + for row in doc.item_attribute_values: + if row.attribute_value == "Large": + row.abbr = "L" + break + frappe.flags.attribute_values = None + doc.save() + + self.addCleanup(restore_test_size_abbr) + self.addCleanup(lambda: frappe.delete_doc_if_exists("Item", "_Test Variant Item-LRG", force=1)) + + frappe.flags.attribute_values = None + attribute.save() + + self.assertFalse(frappe.db.exists("Item", "_Test Variant Item-L")) + self.assertTrue(frappe.db.exists("Item", "_Test Variant Item-LRG")) + self.assertEqual( + frappe.db.get_value("Item", "_Test Variant Item-LRG", "item_name"), + "_Test Variant Item-LRG", + ) + + def test_rename_attribute_abbr_updates_variant_item_name_from_template_name(self): + # item_name can be derived from the template's item_name, which may differ from its + # item_code (e.g. a friendly display name vs. a SKU-style code). The variant's item_name + # must follow the abbreviation rename the same way item_code does. + frappe.delete_doc_if_exists("Item", "_Test Variant Item Diff-L", force=1) + frappe.delete_doc_if_exists("Item", "_Test Variant Item Diff-LRG", force=1) + frappe.delete_doc_if_exists("Item", "_Test Variant Item Diff", force=1) + + template = frappe.get_doc("Item", "_Test Variant Item").as_dict() + template = frappe.get_doc( + { + "doctype": "Item", + "item_code": "_Test Variant Item Diff", + "item_name": "Test Variant Friendly Name", + "item_group": template.item_group, + "stock_uom": template.stock_uom, + "has_variants": 1, + "attributes": [{"attribute": "Test Size"}], + } + ) + template.insert() + self.addCleanup(lambda: frappe.delete_doc_if_exists("Item", "_Test Variant Item Diff", force=1)) + + variant = create_variant("_Test Variant Item Diff", {"Test Size": "Large"}) + variant.save() + self.assertEqual(variant.item_code, "_Test Variant Item Diff-L") + self.assertEqual(variant.item_name, "Test Variant Friendly Name-L") + + # even a manually customized item_name (unrelated to the auto-generated pattern) must be + # rebuilt on abbreviation rename, since item_code and item_name are meant to stay in lockstep. + frappe.db.set_value("Item", variant.name, "item_name", "Custom Friendly Large Shirt Name") + + attribute = frappe.get_doc("Item Attribute", "Test Size") + for row in attribute.item_attribute_values: + if row.attribute_value == "Large": + row.abbr = "LRG" + break + + def restore_test_size_abbr(): + doc = frappe.get_doc("Item Attribute", "Test Size") + for row in doc.item_attribute_values: + if row.attribute_value == "Large": + row.abbr = "L" + break + frappe.flags.attribute_values = None + doc.save() + + self.addCleanup(restore_test_size_abbr) + self.addCleanup(lambda: frappe.delete_doc_if_exists("Item", "_Test Variant Item Diff-LRG", force=1)) + + frappe.flags.attribute_values = None + attribute.save() + + self.assertFalse(frappe.db.exists("Item", "_Test Variant Item Diff-L")) + self.assertEqual( + frappe.db.get_value("Item", "_Test Variant Item Diff-LRG", "item_name"), + "Test Variant Friendly Name-LRG", + ) + def test_make_item_variant(self): frappe.delete_doc_if_exists("Item", "_Test Variant Item-L", force=1)