diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py index 57ef162b5480bcfd4777e1d1b468a64b65530be6..be156d833039890548698c4da90bd2d661c1b1de 100644 --- a/erpnext/manufacturing/doctype/work_order/test_work_order.py +++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py @@ -2372,6 +2372,59 @@ class TestWorkOrder(IntegrationTestCase): stock_entry.submit() + def test_components_alternate_item_for_bom_based_manufacture_entry(self): + frappe.db.set_single_value("Manufacturing Settings", "backflush_raw_materials_based_on", "BOM") + frappe.db.set_single_value("Manufacturing Settings", "validate_components_quantities_per_bom", 1) + + fg_item = "Test FG Item For Component Validation for alternate item" + source_warehouse = "Stores - _TC" + raw_materials = ["Test Component Validation RM Item 112", "Test Component Validation RM Item 22"] + alternate_item = ["Alternate Test Component Validation RM Item 1"] + + make_item(fg_item, {"is_stock_item": 1}) + for item in raw_materials + alternate_item: + make_item(item, {"is_stock_item": 1, "allow_alternative_item": 1}) + test_stock_entry.make_stock_entry( + item_code=item, + target=source_warehouse, + qty=10, + basic_rate=100, + ) + + frappe.get_doc( + { + "doctype": "Item Alternative", + "item_code": raw_materials[0], + "alternative_item_code": alternate_item[0], + "two_way": 1, + } + ).insert() + + make_bom(item=fg_item, source_warehouse=source_warehouse, raw_materials=raw_materials) + + wo = make_wo_order_test_record( + item=fg_item, + qty=10, + source_warehouse=source_warehouse, + ) + + transfer_entry = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture", 10)) + transfer_entry.save() + transfer_entry.items[0].item_code = alternate_item[0] + transfer_entry.items[0].original_item = raw_materials[0] + transfer_entry.submit() + + self.assertTrue(transfer_entry.docstatus == 1) + + manufacture_entry = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 10)) + manufacture_entry.save() + self.assertTrue(manufacture_entry.items[0].item_code == alternate_item[0]) + self.assertTrue(manufacture_entry.items[0].original_item == raw_materials[0]) + + manufacture_entry.submit() + + frappe.db.set_single_value("Manufacturing Settings", "validate_components_quantities_per_bom", 0) + def test_components_qty_for_bom_based_manufacture_entry(self): frappe.db.set_single_value("Manufacturing Settings", "backflush_raw_materials_based_on", "BOM") frappe.db.set_single_value("Manufacturing Settings", "validate_components_quantities_per_bom", 1) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 0f0b7e3bc32ce67a8f51fcede16c2181f15b3ec8..b16144bbe086beb27e06372576e75435bd7ef493 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -769,7 +769,7 @@ class StockEntry(StockController): def get_matched_items(self, item_code): for row in self.items: - if row.item_code == item_code: + if row.item_code == item_code or row.original_item == item_code: return row return {} @@ -1891,7 +1891,7 @@ class StockEntry(StockController): item_wh = frappe._dict(item_wh) - for item in item_dict.values(): + for original_item, item in item_dict.items(): if self.pro_doc and cint(self.pro_doc.from_wip_warehouse): item["from_warehouse"] = self.pro_doc.wip_warehouse # Get Reserve Warehouse from Subcontract Order @@ -1904,6 +1904,9 @@ class StockEntry(StockController): self.to_warehouse if self.purpose == "Send to Subcontractor" else "" ) + if original_item != item.get("item_code"): + item["original_item"] = original_item + self.add_to_stock_entry_detail(item_dict) # fetch the serial_no of the first stock entry for the second stock entry