Rename and merging of Item and Warehouse and patch to fix deleted bins
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index b578ac2..b9f8efb 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -350,4 +350,5 @@
erpnext.patches.v7_0.po_status_issue_for_pr_return
erpnext.patches.v7_1.update_missing_salary_component_type
erpnext.patches.v7_0.update_autoname_field
-erpnext.patches.v7_0.update_status_of_po_so
\ No newline at end of file
+erpnext.patches.v7_0.update_status_of_po_so
+erpnext.patches.v7_1.repost_stock_for_deleted_bins_for_merging_items
\ No newline at end of file
diff --git a/erpnext/patches/v7_1/repost_stock_for_deleted_bins_for_merging_items.py b/erpnext/patches/v7_1/repost_stock_for_deleted_bins_for_merging_items.py
new file mode 100644
index 0000000..5c63c00
--- /dev/null
+++ b/erpnext/patches/v7_1/repost_stock_for_deleted_bins_for_merging_items.py
@@ -0,0 +1,41 @@
+from __future__ import unicode_literals
+import frappe
+from erpnext.stock.stock_balance import repost_stock
+
+def execute():
+ modified_items = frappe.db.sql_list("""
+ select name from `tabItem`
+ where is_stock_item=1 and modified >= '2016-10-31'
+ """)
+
+ if not modified_items:
+ return
+
+ item_warehouses_with_transactions = []
+ transactions = ("Sales Order Item", "Material Request Item", "Purchase Order Item",
+ "Stock Ledger Entry", "Packed Item")
+
+ for doctype in transactions:
+ item_warehouses_with_transactions += list(frappe.db.sql("""
+ select distinct item_code, warehouse
+ from `tab{0}` where docstatus=1 and item_code in ({1})"""
+ .format(doctype, ', '.join(['%s']*len(modified_items))), tuple(modified_items)))
+
+ item_warehouses_with_transactions += list(frappe.db.sql("""
+ select distinct production_item, fg_warehouse
+ from `tabProduction Order` where docstatus=1 and production_item in ({0})"""
+ .format(', '.join(['%s']*len(modified_items))), tuple(modified_items)))
+
+ item_warehouses_with_transactions += list(frappe.db.sql("""
+ select distinct pr_item.item_code, pr.source_warehouse
+ from `tabProduction Order` pr, `tabProduction Order Item` pr_item
+ where pr_item.parent and pr.name and pr.docstatus=1 and pr_item.item_code in ({0})"""
+ .format(', '.join(['%s']*len(modified_items))), tuple(modified_items)))
+
+ item_warehouses_with_bin = list(frappe.db.sql("select distinct item_code, warehouse from `tabBin`"))
+
+ item_warehouses_with_missing_bin = list(
+ set(item_warehouses_with_transactions) - set(item_warehouses_with_bin))
+
+ for item_code, warehouse in item_warehouses_with_missing_bin:
+ repost_stock(item_code, warehouse)
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 3d248d1..98d0ebc 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -532,8 +532,6 @@
frappe.throw(_("To merge, following properties must be same for both items")
+ ": \n" + ", ".join([self.meta.get_label(fld) for fld in field_list]))
- frappe.db.sql("delete from `tabBin` where item_code=%s", old_name)
-
def after_rename(self, old_name, new_name, merge):
if self.route:
invalidate_cache_for_item(self)
@@ -567,8 +565,14 @@
existing_allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock")
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
- for warehouse in frappe.db.sql("select warehouse from `tabBin` where item_code=%s", new_name):
- repost_stock(new_name, warehouse[0])
+ repost_stock_for_warehouses = frappe.db.sql_list("""select distinct warehouse
+ from tabBin where item_code=%s""", new_name)
+
+ # Delete all existing bins to avoid duplicate bins for the same item and warehouse
+ frappe.db.sql("delete from `tabBin` where item_code=%s", new_name)
+
+ for warehouse in repost_stock_for_warehouses:
+ repost_stock(new_name, warehouse)
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock)
frappe.db.auto_commit_on_many_writes = 0
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index 8e7941c..e01cc0b 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -143,9 +143,7 @@
if self.company != frappe.db.get_value("Warehouse", new_warehouse, "company"):
frappe.throw(_("Both Warehouse must belong to same Company"))
- frappe.db.sql("delete from `tabBin` where warehouse=%s", olddn)
-
- self.rename_account_for(olddn, newdn, merge)
+ self.rename_account_for(olddn, new_warehouse, merge)
return new_warehouse
@@ -195,11 +193,14 @@
existing_allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock")
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
- for item in frappe.db.sql("""select distinct item_code from (
- select name as item_code from `tabItem` where is_stock_item=1
- union
- select distinct item_code from tabBin) a"""):
- repost_stock(item[0], newdn)
+ repost_stock_for_items = frappe.db.sql_list("""select distinct item_code
+ from tabBin where warehouse=%s""", newdn)
+
+ # Delete all existing bins to avoid duplicate bins for the same item and warehouse
+ frappe.db.sql("delete from `tabBin` where warehouse=%s", newdn)
+
+ for item_code in repost_stock_for_items:
+ repost_stock(item_code, newdn)
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock)
frappe.db.auto_commit_on_many_writes = 0