Fixes and Validations for nested doctypes
diff --git a/erpnext/selling/page/sales_analytics/sales_analytics.js b/erpnext/selling/page/sales_analytics/sales_analytics.js
index 86ab0eb..b87ead5 100644
--- a/erpnext/selling/page/sales_analytics/sales_analytics.js
+++ b/erpnext/selling/page/sales_analytics/sales_analytics.js
@@ -174,7 +174,7 @@
 			me.parent_map = {};
 			me.item_by_name = {};
 			me.data = [];
-
+			
 			$.each(items, function(i, v) {
 				var d = copy_dict(v);
 
diff --git a/erpnext/setup/doctype/customer_group/customer_group.js b/erpnext/setup/doctype/customer_group/customer_group.js
index 67bc293..531ff96 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.js
+++ b/erpnext/setup/doctype/customer_group/customer_group.js
@@ -23,7 +23,17 @@
 
  
 cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-   
+	cur_frm.cscript.set_root_readonly(doc);
+}
+
+cur_frm.cscript.set_root_readonly = function(doc) {
+	// read-only for root customer group
+	if(doc.name==='All Customer Groups') {
+		cur_frm.perm = [[1,0,0], [1,0,0]];
+		cur_frm.set_intro("This is a root customer group and cannot be edited.");
+	} else {
+		cur_frm.set_intro(null);
+	}
 }
 
 //get query select Customer Group
diff --git a/erpnext/setup/doctype/customer_group/customer_group.py b/erpnext/setup/doctype/customer_group/customer_group.py
index 9831024..6eb52b5 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.py
+++ b/erpnext/setup/doctype/customer_group/customer_group.py
@@ -32,32 +32,18 @@
 convert_to_lists = webnotes.conn.convert_to_lists
 	
 # -----------------------------------------------------------------------------------------
-
-
-class DocType:
+from webnotes.utils.nestedset import DocTypeNestedSet
+class DocType(DocTypeNestedSet):
 	def __init__(self, doc, doclist=[]):
 		self.doc = doc
 		self.doclist = doclist
 		self.nsm_parent_field = 'parent_customer_group';
 
-
-	# update Node Set Model
-	def update_nsm_model(self):
-		import webnotes
-		import webnotes.utils.nestedset
-		webnotes.utils.nestedset.update_nsm(self)
-
-	# ON UPDATE
-	#--------------------------------------
-	def on_update(self):
-		# update nsm
-		self.update_nsm_model()   
-
-
 	def validate(self): 
 		if sql("select name from `tabCustomer Group` where name = %s and docstatus = 2", (self.doc.customer_group_name)):
 			msgprint("""Another %s record is trashed. 
 				To untrash please go to Setup & click on Trash."""%(self.doc.customer_group_name), raise_exception = 1)
+		self.validate_root_details("All Customer Groups", "parent_customer_group")
 
 	def on_trash(self):
 		cust = sql("select name from `tabCustomer` where ifnull(customer_group, '') = %s", self.doc.name)
@@ -72,4 +58,4 @@
 
 		# rebuild tree
 		webnotes.conn.set(self.doc,'old_parent', '')
-		self.update_nsm_model()
+		self.update_nsm()
diff --git a/erpnext/setup/doctype/sales_person/sales_person.js b/erpnext/setup/doctype/sales_person/sales_person.js
index a1cac8a..1c7b13f 100644
--- a/erpnext/setup/doctype/sales_person/sales_person.js
+++ b/erpnext/setup/doctype/sales_person/sales_person.js
@@ -22,8 +22,20 @@
 }
 
 cur_frm.cscript.refresh = function(doc, cdt, cdn) {
+	cur_frm.cscript.set_root_readonly(doc);
 }
 
+cur_frm.cscript.set_root_readonly = function(doc) {
+	// read-only for root
+	if(doc.name==='All Sales Persons') {
+		cur_frm.perm = [[1,0,0], [1,0,0]];
+		cur_frm.set_intro("This is a root sales person and cannot be edited.");
+	} else {
+		cur_frm.set_intro(null);
+	}
+}
+
+
 cur_frm.cscript.onload = function(){
 
 }
diff --git a/erpnext/setup/doctype/territory/territory.js b/erpnext/setup/doctype/territory/territory.js
index 9b36d0c..a52bb67 100644
--- a/erpnext/setup/doctype/territory/territory.js
+++ b/erpnext/setup/doctype/territory/territory.js
@@ -23,9 +23,20 @@
 }
 
 cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-   
+	cur_frm.cscript.set_root_readonly(doc);
 }
 
+cur_frm.cscript.set_root_readonly = function(doc) {
+	// read-only for root territory
+	if(doc.name==='All Territories') {
+		cur_frm.perm = [[1,0,0], [1,0,0]];
+		cur_frm.set_intro("This is a root territory and cannot be edited.");
+	} else {
+		cur_frm.set_intro(null);
+	}
+}
+
+
 cur_frm.cscript.onload = function(){
 
 }
diff --git a/public/js/all-app.js b/public/js/all-app.js
index 342b51d..c43d8f2 100644
--- a/public/js/all-app.js
+++ b/public/js/all-app.js
@@ -1123,7 +1123,7 @@
 else{$("#"+me.tooltip_id).remove();me.previousPoint=null;}});},get_tooltip_text:function(label,x,y){var date=dateutil.obj_to_user(new Date(x));var value=fmt_money(y);return value+" on "+date;},get_view_data:function(){var res=[];var col_map=$.map(this.columns,function(v){return v.field;});for(var i=0,len=this.dataView.getLength();i<len;i++){var d=this.dataView.getItem(i);var row=[];$.each(col_map,function(i,col){var val=d[col];if(val===null||val===undefined){val=""}
 row.push(val);})
 res.push(row);}
-return res;},get_plot_data:function(){var data=[];var me=this;$.each(this.data,function(i,item){if(item.checked){data.push({label:item.name,data:$.map(me.columns,function(col,idx){if(col.formatter==me.currency_formatter&&!col.hidden&&col.plot!==false){return me.get_plot_points(item,col,idx)}}),points:{show:true},lines:{show:true,fill:true},});data[data.length-1].data=[[dateutil.str_to_obj(me.from_date).getTime(),item.opening]].concat(data[data.length-1].data);}});return data.length?data:false;},get_plot_options:function(){return{grid:{hoverable:true,clickable:true},xaxis:{mode:"time",min:dateutil.str_to_obj(this.from_date).getTime(),max:dateutil.str_to_obj(this.to_date).getTime()}}}});wn.views.TreeGridReport=wn.views.GridReportWithPlot.extend({make_transaction_list:function(parent_doctype,doctype){var me=this;var tmap={};$.each(wn.report_dump.data[doctype],function(i,v){if(!tmap[v.parent])tmap[v.parent]=[];tmap[v.parent].push(v);});this.tl=[];$.each(wn.report_dump.data[parent_doctype],function(i,parent){$.each(tmap[parent.name],function(i,d){me.tl.push($.extend(copy_dict(parent),d));});});},add_tree_grid_events:function(){var me=this;this.grid.onClick.subscribe(function(e,args){if($(e.target).hasClass("toggle")){var item=me.dataView.getItem(args.row);if(item){if(!item._collapsed){item._collapsed=true;}else{item._collapsed=false;}
+return res;},get_plot_data:function(){var data=[];var me=this;$.each(this.data,function(i,item){if(item.checked){data.push({label:item.name,data:$.map(me.columns,function(col,idx){if(col.formatter==me.currency_formatter&&!col.hidden&&col.plot!==false){return me.get_plot_points(item,col,idx)}}),points:{show:true},lines:{show:true,fill:true},});data[data.length-1].data=[[dateutil.str_to_obj(me.from_date).getTime(),item.opening]].concat(data[data.length-1].data);}});return data.length?data:false;},get_plot_options:function(){return{grid:{hoverable:true,clickable:true},xaxis:{mode:"time",min:dateutil.str_to_obj(this.from_date).getTime(),max:dateutil.str_to_obj(this.to_date).getTime()}}}});wn.views.TreeGridReport=wn.views.GridReportWithPlot.extend({make_transaction_list:function(parent_doctype,doctype){var me=this;var tmap={};$.each(wn.report_dump.data[doctype],function(i,v){if(!tmap[v.parent])tmap[v.parent]=[];tmap[v.parent].push(v);});this.tl=[];$.each(wn.report_dump.data[parent_doctype],function(i,parent){if(tmap[parent.name]){$.each(tmap[parent.name],function(i,d){me.tl.push($.extend(copy_dict(parent),d));});}});},add_tree_grid_events:function(){var me=this;this.grid.onClick.subscribe(function(e,args){if($(e.target).hasClass("toggle")){var item=me.dataView.getItem(args.row);if(item){if(!item._collapsed){item._collapsed=true;}else{item._collapsed=false;}
 me.dataView.updateItem(item.id,item);}
 e.stopImmediatePropagation();}});},tree_formatter:function(row,cell,value,columnDef,dataContext){var me=wn.cur_grid_report;value=value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");var data=me.data;var spacer="<span style='display:inline-block;height:1px;width:"+
 (15*dataContext["indent"])+"px'></span>";var idx=me.dataView.getIdxById(dataContext.id);var link=me.tree_grid.formatter(dataContext);if(dataContext.doctype){link+=me.get_link_open_icon(dataContext.doctype,value);}