[fixes] set warehouse group wise reorder level, validate ledger (leaf warehouse) on sle and bin
diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js
index 12307fb..acc0409 100644
--- a/erpnext/public/js/queries.js
+++ b/erpnext/public/js/queries.js
@@ -71,7 +71,11 @@
 
 	warehouse: function(doc) {
 		return {
-			filters: [["Warehouse", "company", "in", ["", cstr(doc.company)]]]
+			filters: [
+				["Warehouse", "company", "in", ["", cstr(doc.company)]],
+				["Warehouse", "is_group", "=", "No"]
+				
+			]
 		}
 	}
 });
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index a1580d5..c03ceee 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -3,6 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe import _
 from frappe.utils import flt, nowdate
 import frappe.defaults
 from frappe.model.document import Document
@@ -15,13 +16,21 @@
 		self.validate_mandatory()
 
 		self.projected_qty = flt(self.actual_qty) + flt(self.ordered_qty) + \
-		 	flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
+			flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
+		
+		self.validate_leaf_warehouse()
 
 	def validate_mandatory(self):
 		qf = ['actual_qty', 'reserved_qty', 'ordered_qty', 'indented_qty']
 		for f in qf:
 			if (not getattr(self, f, None)) or (not self.get(f)):
 				self.set(f, 0.0)
+	
+	def validate_leaf_warehouse(self):
+		from erpnext.stock.utils import is_leaf_warehouse
+		
+		if not is_leaf_warehouse(self.warehouse):
+			frappe.throw(_("Group node warehouse is not allowed to select for transactions"))
 
 	def update_stock(self, args, allow_negative_stock=False, via_landed_cost_voucher=False):
 		self.update_qty(args)
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index fe7e54e..f35fa58 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -160,6 +160,28 @@
 		frm.fields_dict.supplier_items.grid.get_field("supplier").get_query = function(doc, cdt, cdn) {
 			return { query: "erpnext.controllers.queries.supplier_query" }
 		}
+		
+		frm.fields_dict['default_warehouse'].get_query = function(doc) {
+			return {
+				filters: { "is_group": "No" }
+			}
+		}
+		
+		frm.fields_dict.reorder_levels.grid.get_field("warehouse_group").get_query = function(doc, cdt, cdn) {
+			return {
+				filters: { "is_group": "Yes" }
+			}
+		}
+		
+		frm.fields_dict.reorder_levels.grid.get_field("warehouse").get_query = function(doc, cdt, cdn) {
+			var d = locals[cdt][cdn];
+			return {
+				filters: {
+					"is_group": "No",
+					"parent_warehouse": d.warehouse_group
+				}
+			}
+		}
 
 	},
 
diff --git a/erpnext/stock/doctype/item_reorder/item_reorder.json b/erpnext/stock/doctype/item_reorder/item_reorder.json
index fea8bf0..27a311d 100644
--- a/erpnext/stock/doctype/item_reorder/item_reorder.json
+++ b/erpnext/stock/doctype/item_reorder/item_reorder.json
@@ -3,19 +3,48 @@
  "allow_import": 0, 
  "allow_rename": 0, 
  "autoname": "hash", 
+ "beta": 0, 
  "creation": "2013-03-07 11:42:59", 
  "custom": 0, 
  "docstatus": 0, 
  "doctype": "DocType", 
+ "document_type": "Setup", 
  "fields": [
   {
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "warehouse_group", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Warehouse Group", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "warehouse", 
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Warehouse", 
@@ -24,6 +53,7 @@
    "options": "Warehouse", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -39,6 +69,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Re-order Level", 
@@ -46,6 +77,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -61,6 +93,7 @@
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Re-order Qty", 
@@ -68,6 +101,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -83,6 +117,7 @@
    "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Material Request Type", 
@@ -91,6 +126,7 @@
    "options": "Purchase\nTransfer", 
    "permlevel": 0, 
    "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 1, 
@@ -102,18 +138,21 @@
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "idx": 1, 
+ "image_view": 0, 
  "in_create": 1, 
  "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2015-11-16 06:29:48.492627", 
+ "modified": "2016-06-20 15:52:01.978593", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Item Reorder", 
  "owner": "Administrator", 
  "permissions": [], 
+ "quick_entry": 0, 
  "read_only": 0, 
- "read_only_onload": 0
+ "read_only_onload": 0, 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 9931ffa..1f446d2 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -25,6 +25,7 @@
 		validate_warehouse_company(self.warehouse, self.company)
 		self.scrub_posting_time()
 		self.validate_and_set_fiscal_year()
+		self.validate_leaf_warehouse()
 
 		from erpnext.accounts.utils import validate_fiscal_year
 		validate_fiscal_year(self.posting_date, self.fiscal_year, self.meta.get_label("posting_date"), self)
@@ -117,6 +118,11 @@
 		if not self.fiscal_year:
 			self.fiscal_year = get_fiscal_year(self.posting_date, company=self.company)[0]
 
+	def validate_leaf_warehouse(self):
+		from erpnext.stock.utils import is_leaf_warehouse
+		
+		if not is_leaf_warehouse(self.warehouse):
+			frappe.throw(_("Group node warehouse is not allowed to select for transactions"))
 
 def on_doctype_update():
 	if not frappe.db.sql("""show index from `tabStock Ledger Entry`
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index 1032fb0..a0b7296 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -196,12 +196,18 @@
 	ctype = frappe.form_dict.get('ctype')
 	parent_field = 'parent_' + ctype.lower().replace(' ', '_')
 	name_field = ctype.lower().replace(' ', '_') + '_name'
-
+	
 	doc = frappe.new_doc(ctype)
+	
+	parent = frappe.form_dict['parent']
+	
+	if cint(frappe.form_dict['is_root']):
+		parent = None
+
 	doc.update({
 		name_field: frappe.form_dict['name_field'],
-		parent_field: frappe.form_dict['parent'],
+		parent_field: parent,
 		"is_group": frappe.form_dict['is_group']
 	})
-
+	
 	doc.save()
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index 4531913..ad810a9 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -37,7 +37,7 @@
 
 	item_warehouse_projected_qty = get_item_warehouse_projected_qty(items_to_consider)
 
-	def add_to_material_request(item_code, warehouse, reorder_level, reorder_qty, material_request_type):
+	def add_to_material_request(item_code, warehouse, reorder_level, reorder_qty, material_request_type, warehouse_group=None):
 		if warehouse not in warehouse_company:
 			# a disabled warehouse
 			return
@@ -46,7 +46,10 @@
 		reorder_qty = flt(reorder_qty)
 
 		# projected_qty will be 0 if Bin does not exist
-		projected_qty = flt(item_warehouse_projected_qty.get(item_code, {}).get(warehouse))
+		if warehouse_group:
+			projected_qty = flt(item_warehouse_projected_qty.get(item_code, {}).get(warehouse_group))
+		else:
+			projected_qty = flt(item_warehouse_projected_qty.get(item_code, {}).get(warehouse))
 
 		if (reorder_level or reorder_qty) and projected_qty < reorder_level:
 			deficiency = reorder_level - projected_qty
@@ -70,7 +73,7 @@
 		if item.get("reorder_levels"):
 			for d in item.get("reorder_levels"):
 				add_to_material_request(item_code, d.warehouse, d.warehouse_reorder_level,
-					d.warehouse_reorder_qty, d.material_request_type)
+					d.warehouse_reorder_qty, d.material_request_type, warehouse_group=d.warehouse_group)
 
 	if material_requests:
 		return create_material_request(material_requests)
@@ -82,9 +85,17 @@
 		from tabBin where item_code in ({0})
 			and (warehouse != "" and warehouse is not null)"""\
 		.format(", ".join(["%s"] * len(items_to_consider))), items_to_consider):
-
+		
 		item_warehouse_projected_qty.setdefault(item_code, {})[warehouse] = flt(projected_qty)
-
+		
+		warehouse_doc = frappe.get_doc("Warehouse", warehouse)
+		
+		if warehouse_doc.parent_warehouse:
+			if not item_warehouse_projected_qty.get(item_code, {}).get(warehouse_doc.parent_warehouse):
+				item_warehouse_projected_qty.setdefault(item_code, {})[warehouse_doc.parent_warehouse] = flt(projected_qty)
+			else:
+				item_warehouse_projected_qty[item_code][warehouse_doc.parent_warehouse] += flt(projected_qty)
+				
 	return item_warehouse_projected_qty
 
 def create_material_request(material_requests):
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index af7dc58..6e56c5c 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -187,3 +187,9 @@
 	if warehouse_company and warehouse_company != company:
 		frappe.throw(_("Warehouse {0} does not belong to company {1}").format(warehouse, company),
 			InvalidWarehouseCompany)
+
+def is_leaf_warehouse(warehouse):
+	if frappe.db.get_value("Warehouse", warehouse, "is_group") == "No":
+		return True
+	return False
+	
\ No newline at end of file