[fixes] warehose group wise stock report and test cases for warehouse hierarchy and warehouse group wise reorder level
diff --git a/erpnext/stock/doctype/item/test_records.json b/erpnext/stock/doctype/item/test_records.json
index fcf2d0b..c05c5f3 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 0c33ff7..24d0546 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 @@
 
 	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 @@
 			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 f57fda3..c1dad5c 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 ca80ca7..b6eaa13 100644
--- a/erpnext/stock/doctype/warehouse/test_warehouse.py
+++ b/erpnext/stock/doctype/warehouse/test_warehouse.py
@@ -4,4 +4,22 @@
 
 
 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 f1f0b66..debcbfd 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.js
+++ b/erpnext/stock/doctype/warehouse/warehouse.js
@@ -17,10 +17,20 @@
 				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 43b6b9a..75200b3 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -71,7 +71,9 @@
 		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 ac4cbbd..a65be6d 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -73,7 +73,7 @@
 		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 @@
 	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 @@
 	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 89963ab..2fb120a 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 @@
 	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 @@
 		item["reorder_levels"] = reorder_levels.get(item.name) or []
 		item_map[item.name] = item
 
+		
+	frappe.errprint(item_map)
 	return item_map