fix: auto unlink warehouse from item on delete (#26073) (#26101)

* fix: auto unlink warehouse from item on delete

* fix: sider

* refactor: use delete_doc

* test: add test for unlinking warehouse from item

* refactor: add msgprint to inform user of unlink

* refactor: cleanup and reuse extant functions

* fix: don't delete row, update table

Co-authored-by: Alan <2.alan.tom@gmail.com>
diff --git a/erpnext/stock/doctype/warehouse/test_warehouse.py b/erpnext/stock/doctype/warehouse/test_warehouse.py
index 95478f6..e3981c9 100644
--- a/erpnext/stock/doctype/warehouse/test_warehouse.py
+++ b/erpnext/stock/doctype/warehouse/test_warehouse.py
@@ -11,6 +11,7 @@
 import erpnext
 from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
 from erpnext.accounts.doctype.account.test_account import get_inventory_account, create_account
+from erpnext.stock.doctype.item.test_item import create_item
 
 test_records = frappe.get_test_records('Warehouse')
 
@@ -92,6 +93,39 @@
 		self.assertTrue(frappe.db.get_value("Warehouse",
 			filters={"account": "Test Warehouse for Merging 2 - TCP1"}))
 
+	def test_unlinking_warehouse_from_item_defaults(self):
+		company = "_Test Company"
+
+		warehouse_names = [f'_Test Warehouse {i} for Unlinking' for i in range(2)]
+		warehouse_ids = []
+		for warehouse in warehouse_names:
+			warehouse_id = create_warehouse(warehouse, company=company)
+			warehouse_ids.append(warehouse_id)
+
+		item_names = [f'_Test Item {i} for Unlinking' for i in range(2)]
+		for item, warehouse in zip(item_names, warehouse_ids):
+			create_item(item, warehouse=warehouse, company=company)
+
+		# Delete warehouses
+		for warehouse in warehouse_ids:
+			frappe.delete_doc("Warehouse", warehouse)
+
+		# Check Item existance
+		for item in item_names:
+			self.assertTrue(
+				bool(frappe.db.exists("Item", item)),
+				f"{item} doesn't exist"
+			)
+
+			item_doc = frappe.get_doc("Item", item)
+			for item_default in item_doc.item_defaults:
+				self.assertNotIn(
+					item_default.default_warehouse,
+					warehouse_ids,
+					f"{item} linked to {item_default.default_warehouse} in {warehouse_ids}."
+				)
+
+
 def create_warehouse(warehouse_name, properties=None, company=None):
 	if not company:
 		company = "_Test Company"
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index 2062bdd..3abc139 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -54,6 +54,7 @@
 			throw(_("Child warehouse exists for this warehouse. You can not delete this warehouse."))
 
 		self.update_nsm_model()
+		self.unlink_from_items()
 
 	def check_if_sle_exists(self):
 		return frappe.db.sql("""select name from `tabStock Ledger Entry`
@@ -138,6 +139,12 @@
 			self.save()
 			return 1
 
+	def unlink_from_items(self):
+		frappe.db.sql("""
+				update `tabItem Default`
+				set default_warehouse=NULL
+				where default_warehouse=%s""", self.name)
+
 @frappe.whitelist()
 def get_children(doctype, parent=None, company=None, is_root=False):
 	if is_root: