fix: button to make BOMs (#37049)
fix: custom button to make BOMs
diff --git a/erpnext/manufacturing/doctype/bom_creator/bom_creator.js b/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
index 01dc89b..0cf2b51 100644
--- a/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
+++ b/erpnext/manufacturing/doctype/bom_creator/bom_creator.js
@@ -134,6 +134,19 @@
frm.trigger("build_tree");
});
}
+
+ if (frm.doc.docstatus === 1 && frm.doc.status !== "Completed") {
+ frm.add_custom_button(__("Create Multi-level BOM"), () => {
+ frm.trigger("create_multi_level_bom");
+ });
+ }
+ },
+
+ create_multi_level_bom(frm) {
+ frm.call({
+ method: "enqueue_create_boms",
+ doc: frm.doc,
+ })
}
});
diff --git a/erpnext/manufacturing/doctype/bom_creator/bom_creator.py b/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
index 999d610..058caa3 100644
--- a/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
+++ b/erpnext/manufacturing/doctype/bom_creator/bom_creator.py
@@ -161,6 +161,7 @@
def on_submit(self):
self.enqueue_create_boms()
+ @frappe.whitelist()
def enqueue_create_boms(self):
frappe.enqueue(
self.create_boms,
@@ -220,6 +221,18 @@
frappe.msgprint(_("BOMs creation failed"))
def create_bom(self, row, production_item_wise_rm):
+ bom_creator_item = row.name if row.name != self.name else ""
+ if frappe.db.exists(
+ "BOM",
+ {
+ "bom_creator": self.name,
+ "item": row.item_code,
+ "bom_creator_item": bom_creator_item,
+ "docstatus": 1,
+ },
+ ):
+ return
+
bom = frappe.new_doc("BOM")
bom.update(
{
@@ -228,7 +241,7 @@
"quantity": row.qty,
"allow_alternative_item": 1,
"bom_creator": self.name,
- "bom_creator_item": row.name if row.name != self.name else "",
+ "bom_creator_item": bom_creator_item,
"rm_cost_as_per": "Manual",
}
)
diff --git a/erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py b/erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py
index d239d58..d8d9f8f 100644
--- a/erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py
+++ b/erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py
@@ -180,6 +180,73 @@
self.assertEqual(doc.raw_material_cost, fg_valuation_rate)
+ def test_make_boms_from_bom_creator(self):
+ final_product = "Bicycle Test"
+ make_item(
+ final_product,
+ {
+ "item_group": "Raw Material",
+ "stock_uom": "Nos",
+ },
+ )
+
+ doc = make_bom_creator(
+ name="Bicycle BOM",
+ company="_Test Company",
+ item_code=final_product,
+ qty=1,
+ rm_cosy_as_per="Valuation Rate",
+ currency="INR",
+ plc_conversion_rate=1,
+ conversion_rate=1,
+ )
+
+ add_item(
+ parent=doc.name,
+ fg_item=final_product,
+ fg_reference_id=doc.name,
+ item_code="Pedal Assembly",
+ qty=2,
+ )
+
+ doc.reload()
+ self.assertEqual(doc.items[0].is_expandable, 0)
+
+ add_sub_assembly(
+ convert_to_sub_assembly=1,
+ parent=doc.name,
+ fg_item=final_product,
+ fg_reference_id=doc.items[0].name,
+ bom_item={
+ "item_code": "Pedal Assembly",
+ "qty": 2,
+ "items": [
+ {
+ "item_code": "Pedal Body",
+ "qty": 2,
+ },
+ {
+ "item_code": "Pedal Axle",
+ "qty": 2,
+ },
+ ],
+ },
+ )
+
+ doc.reload()
+ self.assertEqual(doc.items[0].is_expandable, 1)
+
+ doc.submit()
+ doc.create_boms()
+ doc.reload()
+
+ data = frappe.get_all("BOM", filters={"bom_creator": doc.name, "docstatus": 1})
+ self.assertEqual(len(data), 2)
+
+ doc.create_boms()
+ data = frappe.get_all("BOM", filters={"bom_creator": doc.name, "docstatus": 1})
+ self.assertEqual(len(data), 2)
+
def create_items():
raw_materials = [