diff --git a/erpnext/patches.txt b/erpnext/patches.txt index b578ac2cca..b9f8efb303 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -350,4 +350,5 @@ erpnext.patches.v7_1.update_invoice_status 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 0000000000..5c63c007ad --- /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 3d248d1c28..98d0ebcfac 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -532,8 +532,6 @@ class Item(WebsiteGenerator): 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 @@ class Item(WebsiteGenerator): 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 8e7941cdea..e01cc0b6fe 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -143,9 +143,7 @@ class Warehouse(NestedSet): 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 @@ class Warehouse(NestedSet): 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