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 = [