diff --git a/erpnext/stock/doctype/item/test_records.json b/erpnext/stock/doctype/item/test_records.json index fcf2d0bc14..c05c5f39bf 100644 --- a/erpnext/stock/doctype/item/test_records.json +++ b/erpnext/stock/doctype/item/test_records.json @@ -227,6 +227,35 @@ "warehouse_reorder_qty": 20 } ] + }, + { + "default_warehouse": "_Test Warehouse Group-C1 - _TC", + "description": "_Test Item 1", + "doctype": "Item", + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "cost_center": "_Test Cost Center - _TC", + "has_batch_no": 0, + "has_serial_no": 0, + "income_account": "Sales - _TC", + "inspection_required": 0, + "is_stock_item": 1, + "is_sub_contracted_item": 0, + "item_code": "_Test Item Warehouse Group Wise Reorder", + "item_group": "_Test Item Group", + "item_name": "_Test Item Warehouse Group Wise Reorder", + "apply_warehouse_wise_reorder_level": 1, + "reorder_levels": [ + { + "warehouse_group": "_Test Warehouse Group - _TC", + "material_request_type": "Purchase", + "warehouse": "_Test Warehouse Group-C1 - _TC", + "warehouse_reorder_level": 20, + "warehouse_reorder_qty": 20 + } + ], + "stock_uom": "_Test UOM", + "show_in_website": 1, + "website_warehouse": "_Test Warehouse Group-C1 - _TC" } ] diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 0c33ff7f4f..24d0546224 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -79,8 +79,11 @@ class TestStockEntry(unittest.TestCase): def test_auto_material_request_for_variant(self): self._test_auto_material_request("_Test Variant Item-S") - - def _test_auto_material_request(self, item_code, material_request_type="Purchase"): + + def test_auto_material_request_for_warehouse_group(self): + self._test_auto_material_request("_Test Item Warehouse Group Wise Reorder", warehouse="_Test Warehouse Group-C1 - _TC") + + def _test_auto_material_request(self, item_code, material_request_type="Purchase", warehouse="_Test Warehouse - _TC"): item = frappe.get_doc("Item", item_code) if item.variant_of: @@ -89,14 +92,14 @@ class TestStockEntry(unittest.TestCase): template = item projected_qty, actual_qty = frappe.db.get_value("Bin", {"item_code": item_code, - "warehouse": "_Test Warehouse - _TC"}, ["projected_qty", "actual_qty"]) or [0, 0] + "warehouse": warehouse}, ["projected_qty", "actual_qty"]) or [0, 0] # stock entry reqd for auto-reorder - create_stock_reconciliation(item_code=item_code, warehouse="_Test Warehouse - _TC", + create_stock_reconciliation(item_code=item_code, warehouse=warehouse, qty = actual_qty + abs(projected_qty) + 10, rate=100) projected_qty = frappe.db.get_value("Bin", {"item_code": item_code, - "warehouse": "_Test Warehouse - _TC"}, "projected_qty") or 0 + "warehouse": warehouse}, "projected_qty") or 0 frappe.db.set_value("Stock Settings", None, "auto_indent", 1) diff --git a/erpnext/stock/doctype/warehouse/test_records.json b/erpnext/stock/doctype/warehouse/test_records.json index f57fda36a7..c1dad5cfd0 100644 --- a/erpnext/stock/doctype/warehouse/test_records.json +++ b/erpnext/stock/doctype/warehouse/test_records.json @@ -4,43 +4,67 @@ "create_account_under": "Stock Assets - _TC", "doctype": "Warehouse", "warehouse_name": "_Test Warehouse", - - - } + "is_group": "No" + }, { "company": "_Test Company", "create_account_under": "Stock Assets - _TC", "doctype": "Warehouse", "warehouse_name": "_Test Warehouse", - "" + "is_group": "No" }, { "company": "_Test Company", "create_account_under": "Fixed Assets - _TC", "doctype": "Warehouse", - "warehouse_name": "_Test Warehouse 1" + "warehouse_name": "_Test Warehouse 1", + "is_group": "No" }, { "company": "_Test Company", "create_account_under": "Fixed Assets - _TC", "doctype": "Warehouse", - "warehouse_name": "_Test Warehouse 2" + "warehouse_name": "_Test Warehouse 2", + "is_group": "No" }, { "company": "_Test Company", "create_account_under": "Stock Assets - _TC", "doctype": "Warehouse", - "warehouse_name": "_Test Rejected Warehouse" + "warehouse_name": "_Test Rejected Warehouse", + "is_group": "No" }, { "company": "_Test Company 1", "create_account_under": "Stock Assets - _TC1", "doctype": "Warehouse", - "warehouse_name": "_Test Warehouse 2" + "warehouse_name": "_Test Warehouse 2", + "is_group": "No" }, { "company": "_Test Company", "doctype": "Warehouse", - "warehouse_name": "_Test Warehouse No Account" + "warehouse_name": "_Test Warehouse No Account", + "is_group": "No" + }, + { + "company": "_Test Company", + "doctype": "Warehouse", + "warehouse_name": "_Test Warehouse Group", + "is_group": "Yes" + }, + { + "company": "_Test Company", + "doctype": "Warehouse", + "warehouse_name": "_Test Warehouse Group-C1", + "is_group": "No", + "parent_warehouse": "_Test Warehouse Group - _TC" + }, + { + "company": "_Test Company", + "doctype": "Warehouse", + "warehouse_name": "_Test Warehouse Group-C2", + "is_group": "No", + "parent_warehouse": "_Test Warehouse Group - _TC" } ] diff --git a/erpnext/stock/doctype/warehouse/test_warehouse.py b/erpnext/stock/doctype/warehouse/test_warehouse.py index ca80ca793c..b6eaa13602 100644 --- a/erpnext/stock/doctype/warehouse/test_warehouse.py +++ b/erpnext/stock/doctype/warehouse/test_warehouse.py @@ -4,4 +4,22 @@ from __future__ import unicode_literals import frappe -test_records = frappe.get_test_records('Warehouse') \ No newline at end of file +import unittest +test_records = frappe.get_test_records('Warehouse') + +class TestWarehouse(unittest.TestCase): + def test_parent_warehouse(self): + parent_warehouse = frappe.get_doc("Warehouse", "_Test Warehouse Group - _TC") + self.assertEquals(parent_warehouse.is_group, "Yes") + + def test_warehouse_hierarchy(self): + p_warehouse = frappe.get_doc("Warehouse", "_Test Warehouse Group - _TC") + + child_warehouses = frappe.db.sql("""select name, is_group, parent_warehouse from `tabWarehouse` wh + where wh.lft > %s and wh.rgt < %s""", (p_warehouse.lft, p_warehouse.rgt), as_dict=1) + + for child_warehouse in child_warehouses: + self.assertEquals(p_warehouse.name, child_warehouse.parent_warehouse) + self.assertEquals(child_warehouse.is_group, "No") + + diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js index f1f0b66fcb..debcbfdbb5 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.js +++ b/erpnext/stock/doctype/warehouse/warehouse.js @@ -17,10 +17,20 @@ frappe.ui.form.on("Warehouse", { frappe.set_route("query-report", "General Ledger"); }); } + + frm.fields_dict['parent_warehouse'].get_query = function(doc) { + return { + filters: { + "is_group": "Yes", + } + } + } } }); + + cur_frm.set_query("create_account_under", function() { return { filters: { diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py index 43b6b9a4f3..75200b340d 100644 --- a/erpnext/stock/report/stock_balance/stock_balance.py +++ b/erpnext/stock/report/stock_balance/stock_balance.py @@ -71,7 +71,9 @@ def get_conditions(filters): conditions += " and item_code = '%s'" % frappe.db.escape(filters.get("item_code"), percent=False) if filters.get("warehouse"): - conditions += " and warehouse = '%s'" % frappe.db.escape(filters.get("warehouse"), percent=False) + wh = frappe.get_doc("Warehouse", filters.get("warehouse")) + conditions += "and warehouse in (\ + select name from `tabWarehouse` wh where wh.lft >= %s and wh.rgt <= %s)"%(wh.lft, wh.rgt) return conditions diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py index ac4cbbd2e0..a65be6d8e7 100644 --- a/erpnext/stock/report/stock_ledger/stock_ledger.py +++ b/erpnext/stock/report/stock_ledger/stock_ledger.py @@ -73,7 +73,7 @@ def get_sle_conditions(filters): conditions.append("""item_code in (select name from tabItem {item_conditions})""".format(item_conditions=item_conditions)) if filters.get("warehouse"): - conditions.append("warehouse=%(warehouse)s") + conditions.append(get_warehouse_condition(filters.get("warehouse"))) if filters.get("voucher_no"): conditions.append("voucher_no=%(voucher_no)s") @@ -86,7 +86,7 @@ def get_opening_balance(filters, columns): from erpnext.stock.stock_ledger import get_previous_sle last_entry = get_previous_sle({ "item_code": filters.item_code, - "warehouse": filters.warehouse, + "warehouse": get_warehouse_condition(filters.warehouse), "posting_date": filters.from_date, "posting_time": "00:00:00" }) @@ -96,4 +96,9 @@ def get_opening_balance(filters, columns): for i, v in ((9, 'qty_after_transaction'), (11, 'valuation_rate'), (12, 'stock_value')): row[i] = last_entry.get(v, 0) - return row \ No newline at end of file + return row + +def get_warehouse_condition(warehouse): + wh = frappe.get_doc("Warehouse", warehouse) + return " warehouse in (select name from `tabWarehouse` wh\ + where wh.lft >= %s and wh.rgt <= %s)"%(wh.lft, wh.rgt) \ No newline at end of file diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py index 89963abde3..2fb120a180 100644 --- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py +++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py @@ -57,16 +57,19 @@ def get_data(filters): return data def get_bin_list(filters): - bin_filters = frappe._dict() + conditions = [] + if filters.item_code: - bin_filters.item_code = filters.item_code + conditions.append("item_code = '%s' "%filters.item_code) + if filters.warehouse: - bin_filters.warehouse = filters.warehouse + wh = frappe.get_doc("Warehouse", filters.warehouse) + conditions.append(" warehouse in (select name from `tabWarehouse` wh\ + where wh.lft >= %s and wh.rgt <= %s)"%(wh.lft, wh.rgt)) - bin_list = frappe.get_all("Bin", fields=["item_code", "warehouse", - "actual_qty", "planned_qty", "indented_qty", "ordered_qty", "reserved_qty", - "reserved_qty_for_production", "projected_qty"], - filters=bin_filters, order_by="item_code, warehouse") + bin_list = frappe.db.sql("""select item_code, warehouse, actual_qty, planned_qty, indented_qty, + ordered_qty, reserved_qty, reserved_qty_for_production, projected_qty + from tabBin where %s order by item_code, warehouse """% " and ".join(conditions), as_dict=1,debug=1) return bin_list @@ -101,4 +104,6 @@ def get_item_map(item_code): item["reorder_levels"] = reorder_levels.get(item.name) or [] item_map[item.name] = item + + frappe.errprint(item_map) return item_map