From d2dc0a4c9aa97bce4c8b3ab332c37d4ff10a231e Mon Sep 17 00:00:00 2001 From: Pandiyan37 Date: Tue, 17 Feb 2026 12:15:33 +0530 Subject: [PATCH] test(manufacturing): add test to validate the sales order references for sub assembly items --- .../production_plan/test_production_plan.py | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py index 25fc4f26247..62aa4f6ea11 100644 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py @@ -565,6 +565,90 @@ class TestProductionPlan(FrappeTestCase): self.assertEqual(po_doc.items[0].fg_item, fg_item) self.assertEqual(po_doc.items[0].item_code, service_item) + def test_sales_order_references_for_sub_assembly_items(self): + """ + Test that Sales Order and Sales Order Item references in Work Order and Purchase Order + are correctly propagated from the Production Plan. + """ + + from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom + + # Setup Test Items & BOM + fg_item = "Test FG Good Item" + sub_assembly_item1 = "Test Sub Assembly Item 1" + sub_assembly_item2 = "Test Sub Assembly Item 2" + + bom_tree = { + fg_item: { + sub_assembly_item1: {"Test Raw Material 1": {}}, + sub_assembly_item2: {"Test Raw Material 2": {}}, + } + } + + create_nested_bom(bom_tree, prefix="") + + # Create Sales Order + so = make_sales_order(item_code=fg_item, qty=10) + so_item_row = so.items[0].name + + # Create Production Plan from Sales Order + production_plan = frappe.new_doc("Production Plan") + production_plan.company = so.company + production_plan.get_items_from = "Sales Order" + production_plan.item_code = fg_item + + production_plan.get_open_sales_orders() + self.assertEqual(production_plan.sales_orders[0].sales_order, so.name) + + production_plan.get_so_items() + + production_plan.skip_available_sub_assembly_item = 0 + production_plan.get_sub_assembly_items() + + self.assertEqual(len(production_plan.sub_assembly_items), 2) + + # Validate Sales Order references in Sub Assembly Items + for row in production_plan.sub_assembly_items: + if row.production_item == sub_assembly_item1: + row.supplier = "_Test Supplier" + row.type_of_manufacturing = "Subcontract" + + self.assertEqual(row.sales_order, so.name) + self.assertEqual(row.sales_order_item, so_item_row) + + # Submit Production Plan + production_plan.save() + production_plan.submit() + production_plan.make_work_order() + + # Validate Purchase Order (Subcontracted Item) + po_items = frappe.get_all( + "Purchase Order Item", + { + "production_plan": production_plan.name, + "fg_item": sub_assembly_item1, + }, + ["sales_order", "sales_order_item"], + ) + + self.assertTrue(po_items) + self.assertEqual(po_items[0].sales_order, so.name) + self.assertEqual(po_items[0].sales_order_item, so_item_row) + + # Validate Work Order (In-house Item) + work_orders = frappe.get_all( + "Work Order", + { + "production_plan": production_plan.name, + "production_item": sub_assembly_item2, + }, + ["sales_order", "sales_order_item"], + ) + + self.assertTrue(work_orders) + self.assertEqual(work_orders[0].sales_order, so.name) + self.assertEqual(work_orders[0].sales_order_item, so_item_row) + def test_production_plan_combine_subassembly(self): """ Test combining Sub assembly items belonging to the same BOM in Prod Plan.