From 100d0ee784a3716d216ed25e182151248be21a77 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Mon, 3 Aug 2026 00:56:56 +0530 Subject: [PATCH] test(manufacturing): cover the BOM representative-line pick A BOM listing one item on two lines, with descriptions and source warehouses that differ. The second line's description sorts above the first on either engine, so an aggregated value would win; the row must instead carry the first line's description together with that same line's warehouse. --- erpnext/manufacturing/doctype/bom/test_bom.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py index 9ff57dae852..1ac43b992f6 100644 --- a/erpnext/manufacturing/doctype/bom/test_bom.py +++ b/erpnext/manufacturing/doctype/bom/test_bom.py @@ -128,6 +128,43 @@ class TestBOM(ERPNextTestSuite): self.assertEqual(len([row for row in items_dict if row == rm.name]), 1) self.assertAlmostEqual(flt(items_dict[rm.name].amount), expected, places=2) + @timeout + def test_get_items_takes_line_columns_from_one_line(self): + from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict + from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom + from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse + + rm = make_item(properties={"is_stock_item": 1, "valuation_rate": 10}) + fg_item = make_item(properties={"is_stock_item": 1, "valuation_rate": 10}).name + + first_warehouse = create_warehouse("_Test BOM Line A") + second_warehouse = create_warehouse("_Test BOM Line B") + + bom = make_bom(item=fg_item, raw_materials=[rm.name], rm_qty=2, do_not_save=True) + bom.items[0].description = "bbb first line" + bom.items[0].source_warehouse = first_warehouse + bom.append( + "items", + { + "item_code": rm.name, + "qty": 3, + "uom": rm.stock_uom, + "stock_uom": rm.stock_uom, + "description": "ccc second line", + "source_warehouse": second_warehouse, + }, + ) + bom.save() + bom.submit() + + items_dict = get_bom_items_as_dict(bom.name, "_Test Company", qty=1, fetch_exploded=0) + row = items_dict[rm.name] + + # "ccc" sorts above "bbb" on either engine, so an aggregated description would win here; + # the value must instead come from the first line, together with that line's warehouse + self.assertEqual(row.description, "bbb first line") + self.assertEqual(row.source_warehouse, first_warehouse) + @timeout def test_default_bom(self): def _get_default_bom_in_item():