fix: BOM replace tool does not update exploded items of root (#39244)

diff --git a/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py b/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
index a2919b7..f013b88 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
@@ -86,10 +86,12 @@
 		if new_bom == d.parent:
 			frappe.throw(_("BOM recursion: {0} cannot be child of {1}").format(new_bom, d.parent))
 
-		bom_list.append(d.parent)
+		if d.parent not in tuple(bom_list):
+			bom_list.append(d.parent)
+
 		get_ancestor_boms(d.parent, bom_list)
 
-	return list(set(bom_list))
+	return bom_list
 
 
 def update_new_bom_in_bom_items(unit_cost: float, current_bom: str, new_bom: str) -> None:
diff --git a/erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py b/erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py
index b38fc89..30e6f5e 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py
@@ -57,6 +57,68 @@
 		log.reload()
 		self.assertEqual(log.status, "Completed")
 
+	def test_bom_replace_for_root_bom(self):
+		"""
+		- B-Item A (Root Item)
+		        - B-Item B
+		                - B-Item C
+		        - B-Item D
+		                - B-Item E
+		                        - B-Item F
+
+		Create New BOM for B-Item E with B-Item G and replace it in the above BOM.
+		"""
+
+		from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
+		from erpnext.stock.doctype.item.test_item import make_item
+
+		items = ["B-Item A", "B-Item B", "B-Item C", "B-Item D", "B-Item E", "B-Item F", "B-Item G"]
+
+		for item_code in items:
+			if not frappe.db.exists("Item", item_code):
+				make_item(item_code)
+
+		for item_code in items:
+			remove_bom(item_code)
+
+		bom_tree = {
+			"B-Item A": {"B-Item B": {"B-Item C": {}}, "B-Item D": {"B-Item E": {"B-Item F": {}}}}
+		}
+
+		root_bom = create_nested_bom(bom_tree, prefix="")
+
+		exploded_items = frappe.get_all(
+			"BOM Explosion Item", filters={"parent": root_bom.name}, fields=["item_code"]
+		)
+
+		exploded_items = [item.item_code for item in exploded_items]
+		expected_exploded_items = ["B-Item C", "B-Item F"]
+		self.assertEqual(sorted(exploded_items), sorted(expected_exploded_items))
+
+		old_bom = frappe.db.get_value("BOM", {"item": "B-Item E"}, "name")
+		bom_tree = {"B-Item E": {"B-Item G": {}}}
+
+		new_bom = create_nested_bom(bom_tree, prefix="")
+		enqueue_replace_bom(boms=frappe._dict(current_bom=old_bom, new_bom=new_bom.name))
+
+		exploded_items = frappe.get_all(
+			"BOM Explosion Item", filters={"parent": root_bom.name}, fields=["item_code"]
+		)
+
+		exploded_items = [item.item_code for item in exploded_items]
+		expected_exploded_items = ["B-Item C", "B-Item G"]
+		self.assertEqual(sorted(exploded_items), sorted(expected_exploded_items))
+
+
+def remove_bom(item_code):
+	boms = frappe.get_all("BOM", fields=["docstatus", "name"], filters={"item": item_code})
+
+	for row in boms:
+		if row.docstatus == 1:
+			frappe.get_doc("BOM", row.name).cancel()
+
+		frappe.delete_doc("BOM", row.name)
+
 
 def update_cost_in_all_boms_in_test():
 	"""