fix: patch and validation message to fix target warehouse issue (#21371)

diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 2b21ee8..90ba8b3 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -46,6 +46,7 @@
 		set_default_income_account_for_item(self)
 		self.set_customer_address()
 		self.validate_for_duplicate_items()
+		self.validate_target_warehouse()
 
 	def set_missing_values(self, for_validate=False):
 
@@ -403,6 +404,14 @@
 				else:
 					chk_dupl_itm.append(f)
 
+	def validate_target_warehouse(self):
+		items = self.get("items") + (self.get("packed_items") or [])
+
+		for d in items:
+			if d.get("target_warehouse") and d.get("warehouse") == d.get("target_warehouse"):
+				warehouse = frappe.bold(d.get("target_warehouse"))
+				frappe.throw(_("Row {0}: Delivery Warehouse ({1}) and Customer Warehouse ({2}) can not be same")
+					.format(d.idx, warehouse, warehouse))
 
 	def validate_items(self):
 		# validate items to see if they have is_sales_item enabled
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 9ef0b8d..8478c10 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -667,3 +667,4 @@
 erpnext.patches.v12_0.set_total_batch_quantity
 erpnext.patches.v12_0.rename_mws_settings_fields
 erpnext.patches.v12_0.set_updated_purpose_in_pick_list
+erpnext.patches.v12_0.repost_stock_ledger_entries_for_target_warehouse
diff --git a/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py b/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py
new file mode 100644
index 0000000..13e935b
--- /dev/null
+++ b/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py
@@ -0,0 +1,71 @@
+# Copyright (c) 2020, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	warehouse_perm = frappe.get_all("User Permission",
+		fields=["count(*) as p_count", "is_default", "user"], filters={"allow": "Warehouse"}, group_by="user")
+
+	if not warehouse_perm:
+		return
+
+	execute_patch = False
+	for perm_data in warehouse_perm:
+		if perm_data.p_count == 1 or (perm_data.p_count > 1 and frappe.get_all("User Permission",
+			filters = {"user": perm_data.user, "allow": "warehouse", "is_default": 1}, limit=1)):
+			execute_patch = True
+			break
+
+	if not execute_patch: return
+
+	for doctype in ["Sales Invoice", "Delivery Note"]:
+		if not frappe.get_meta(doctype + ' Item').get_field("target_warehouse").hidden: continue
+
+		cond = ""
+		if doctype == "Sales Invoice":
+			cond = " AND parent_doc.update_stock = 1"
+
+		data = frappe.db.sql(""" SELECT parent_doc.name as name, child_doc.name as child_name
+			FROM
+				`tab{doctype}` parent_doc, `tab{doctype} Item` child_doc
+			WHERE
+				parent_doc.name = child_doc.parent AND parent_doc.docstatus < 2
+				AND child_doc.target_warehouse is not null AND child_doc.target_warehouse != ''
+				AND child_doc.creation > '2020-04-16' {cond}
+		""".format(doctype=doctype, cond=cond), as_dict=1)
+
+		if data:
+			names = [d.child_name for d in data]
+			frappe.db.sql(""" UPDATE `tab{0} Item` set target_warehouse = null
+				WHERE name in ({1}) """.format(doctype, ','.join(["%s"] * len(names) )), tuple(names))
+
+			frappe.db.sql(""" UPDATE `tabPacked Item` set target_warehouse = null
+				WHERE parenttype = '{0}' and parent_detail_docname in ({1})
+			""".format(doctype, ','.join(["%s"] * len(names) )), tuple(names))
+
+			parent_names = list(set([d.name for d in data]))
+
+			for d in parent_names:
+				doc = frappe.get_doc(doctype, d)
+				if doc.docstatus != 1: continue
+
+				doc.docstatus = 2
+				doc.update_stock_ledger()
+				doc.make_gl_entries_on_cancel(repost_future_gle=False)
+
+				# update stock & gl entries for submit state of PR
+				doc.docstatus = 1
+				doc.update_stock_ledger()
+				doc.make_gl_entries()
+
+	if frappe.get_meta('Sales Order Item').get_field("target_warehouse").hidden:
+		frappe.db.sql(""" UPDATE `tabSales Order Item` set target_warehouse = null
+			WHERE creation > '2020-04-16' and docstatus < 2 """)
+
+		frappe.db.sql(""" UPDATE `tabPacked Item` set target_warehouse = null
+			WHERE creation > '2020-04-16' and docstatus < 2 and parenttype = 'Sales Order' """)
+
+
+