Merge branch 'responsive' of git://github.com/webnotes/erpnext into responsive
diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt
index 27a0340..81b0785 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-05-24 19:29:05", 
   "docstatus": 0, 
-  "modified": "2013-06-12 15:14:00", 
+  "modified": "2013-06-27 11:35:29", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -432,7 +432,7 @@
   "doctype": "DocField", 
   "fieldname": "charge", 
   "fieldtype": "Link", 
-  "label": "Taxes and Charges", 
+  "label": "Apply Taxes and Charges Master", 
   "oldfieldname": "charge", 
   "oldfieldtype": "Link", 
   "options": "Sales Taxes and Charges Master", 
@@ -446,10 +446,11 @@
  }, 
  {
   "doctype": "DocField", 
-  "fieldname": "get_charges", 
-  "fieldtype": "Button", 
-  "label": "Get Taxes and Charges", 
+  "fieldname": "shipping_rule", 
+  "fieldtype": "Link", 
+  "label": "Apply Shipping Rule", 
   "oldfieldtype": "Button", 
+  "options": "Shipping Rule", 
   "print_hide": 1, 
   "read_only": 0
  }, 
diff --git a/accounts/doctype/shipping_rule/shipping_rule.py b/accounts/doctype/shipping_rule/shipping_rule.py
index 5ed4ed3..8714865 100644
--- a/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/accounts/doctype/shipping_rule/shipping_rule.py
@@ -3,23 +3,80 @@
 from __future__ import unicode_literals
 import webnotes
 from webnotes import _, msgprint
+from webnotes.utils import flt, fmt_money
+from webnotes.model.controller import DocListController
+from setup.utils import get_company_currency
 
-class DocType:
+class OverlappingConditionError(webnotes.ValidationError): pass
+class FromGreaterThanToError(webnotes.ValidationError): pass
+class ManyBlankToValuesError(webnotes.ValidationError): pass
+
+class DocType(DocListController):
 	def __init__(self, d, dl):
 		self.doc, self.doclist = d, dl
 		
 	def validate(self):
-		self.validate_to_value_of_shipping_rule_conditions()
+		self.shipping_rule_conditions = self.doclist.get({"parentfield": "shipping_rule_conditions"})
+		self.validate_from_to_values()
+		self.sort_shipping_rule_conditions()
 		self.validate_overlapping_shipping_rule_conditions()
 		
+	def validate_from_to_values(self):
+		zero_to_values = []
 		
-	def validate_to_value_of_shipping_rule_conditions(self):
-		"""check if more than two or more rows has To Value = 0"""
-		shipping_rule_conditions_with_0_to_value = self.doclist.get({
-			"parentfield": "shipping_rule_conditions", "to_value": ["in", [0, None]]})
-		if len(shipping_rule_conditions_with_0_to_value) >= 2:
-			msgprint(_('''There can only be one shipping rule with 0 or blank value for "To Value"'''),
-				raise_exception=True)
+		for d in self.shipping_rule_conditions:
+			self.round_floats_in(d)
+			
+			# values cannot be negative
+			self.validate_value("from_value", ">=", 0.0, d)
+			self.validate_value("to_value", ">=", 0.0, d)
+			
+			if d.to_value == 0:
+				zero_to_values.append(d)
+			elif d.from_value >= d.to_value:
+				msgprint(_("Error") + ": " + _("Row") + " # %d: " % d.idx + 
+					_("From Value should be less than To Value"),
+					raise_exception=FromGreaterThanToError)
+		
+		# check if more than two or more rows has To Value = 0
+		if len(zero_to_values) >= 2:
+			msgprint(_('''There can only be one Shipping Rule Condition with 0 or blank value for "To Value"'''),
+				raise_exception=ManyBlankToValuesError)
 				
+	def sort_shipping_rule_conditions(self):
+		"""Sort Shipping Rule Conditions based on increasing From Value"""
+		self.shipping_rules_conditions = sorted(self.shipping_rule_conditions, key=lambda d: flt(d.from_value))
+		for i, d in enumerate(self.shipping_rule_conditions):
+			d.idx = i + 1
+
 	def validate_overlapping_shipping_rule_conditions(self):
-		pass
\ No newline at end of file
+		def overlap_exists_between((x1, x2), (y1, y2)):
+			"""
+				(x1, x2) and (y1, y2) are two ranges
+				if condition x = 100 to 300
+				then condition y can only be like 50 to 99 or 301 to 400
+				hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2)
+			"""
+			separate = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2)
+			return (not separate)
+		
+		overlaps = []
+		for i in xrange(0, len(self.shipping_rule_conditions)):
+			for j in xrange(i+1, len(self.shipping_rule_conditions)):
+				d1, d2 = self.shipping_rule_conditions[i], self.shipping_rule_conditions[j]
+				if d1.fields != d2.fields:
+					# in our case, to_value can be zero, hence pass the from_value if so
+					range_a = (d1.from_value, d1.to_value or d1.from_value)
+					range_b = (d2.from_value, d2.to_value or d2.from_value)
+					if overlap_exists_between(range_a, range_b):
+						overlaps.append([d1, d2])
+		
+		if overlaps:
+			company_currency = get_company_currency(self.doc.company)
+			msgprint(_("Error") + ": " + _("Overlapping Conditions found between") + ":")
+			messages = []
+			for d1, d2 in overlaps:
+				messages.append("%s-%s = %s " % (d1.from_value, d1.to_value, fmt_money(d1.shipping_amount, currency=company_currency)) + 
+					_("and") + " %s-%s = %s" % (d2.from_value, d2.to_value, fmt_money(d2.shipping_amount, currency=company_currency)))
+					  	
+			msgprint("\n".join(messages), raise_exception=OverlappingConditionError)
\ No newline at end of file
diff --git a/accounts/doctype/shipping_rule/test_shipping_rule.py b/accounts/doctype/shipping_rule/test_shipping_rule.py
new file mode 100644
index 0000000..ff217bc
--- /dev/null
+++ b/accounts/doctype/shipping_rule/test_shipping_rule.py
@@ -0,0 +1,66 @@
+import webnotes
+import unittest
+from accounts.doctype.shipping_rule.shipping_rule import FromGreaterThanToError, ManyBlankToValuesError, OverlappingConditionError
+
+class TestShippingRule(unittest.TestCase):
+	def test_from_greater_than_to(self):
+		shipping_rule = webnotes.bean(copy=test_records[0])
+		shipping_rule.doclist[1].from_value = 101
+		self.assertRaises(FromGreaterThanToError, shipping_rule.insert)
+		
+	def test_many_zero_to_values(self):
+		shipping_rule = webnotes.bean(copy=test_records[0])
+		shipping_rule.doclist[1].to_value = 0
+		self.assertRaises(ManyBlankToValuesError, shipping_rule.insert)
+		
+	def test_overlapping_conditions(self):
+		for range_a, range_b in [
+			((50, 150), (0, 100)),
+			((50, 150), (100, 200)),
+			((50, 150), (75, 125)),
+			((50, 150), (25, 175)),
+			((50, 150), (50, 150)),
+		]:
+			shipping_rule = webnotes.bean(copy=test_records[0])
+			shipping_rule.doclist[1].from_value = range_a[0]
+			shipping_rule.doclist[1].to_value = range_a[1]
+			shipping_rule.doclist[2].from_value = range_b[0]
+			shipping_rule.doclist[2].to_value = range_b[1]
+			self.assertRaises(OverlappingConditionError, shipping_rule.insert)
+
+test_records = [
+	[
+		{
+			"doctype": "Shipping Rule",
+			"calculate_based_on": "Amount",
+			"company": "_Test Company",
+			"account": "_Test Account Shipping Charges - _TC",
+			"cost_center": "_Test Cost Center - _TC"
+		},
+		{
+			"doctype": "Shipping Rule Condition",
+			"parentfield": "shipping_rule_conditions",
+			"from_value": 0,
+			"to_value": 100,
+			"shipping_amount": 50.0
+		},
+		{
+			"doctype": "Shipping Rule Condition",
+			"parentfield": "shipping_rule_conditions",
+			"from_value": 101,
+			"to_value": 200,
+			"shipping_amount": 100.0
+		},
+		{
+			"doctype": "Shipping Rule Condition",
+			"parentfield": "shipping_rule_conditions",
+			"from_value": 201,
+			"shipping_amount": 0.0
+		},
+		{
+			"doctype": "For Territory",
+			"parentfield": "valid_for_territories",
+			"territory": "_Test Territory"
+		}
+	]
+]
\ No newline at end of file
diff --git a/accounts/utils.py b/accounts/utils.py
index fa93cb0..4ca1b3a 100644
--- a/accounts/utils.py
+++ b/accounts/utils.py
@@ -351,4 +351,4 @@
 			webnotes.conn.sql("""update `tabGL Entry` set %s = %s + %s
 				where voucher_type = %s and voucher_no = %s and %s > 0 limit 1""" %
 				(dr_or_cr, dr_or_cr, '%s', '%s', '%s', dr_or_cr), 
-				(d.diff, d.voucher_type, d.voucher_no), debug=1)
\ No newline at end of file
+				(d.diff, d.voucher_type, d.voucher_no))
\ No newline at end of file
diff --git a/buying/doctype/buying_settings/buying_settings.py b/buying/doctype/buying_settings/buying_settings.py
index 7a97349..b00bcef 100644
--- a/buying/doctype/buying_settings/buying_settings.py
+++ b/buying/doctype/buying_settings/buying_settings.py
@@ -8,6 +8,6 @@
 		self.doc, self.doclist = d, dl
 		
 	def validate(self):
-		for key in ["supplier_type", "maintain_same_rate"]:
+		for key in ["supplier_type", "supp_master_name", "maintain_same_rate"]:
 			webnotes.conn.set_default(key, self.doc.fields.get(key, ""))
 	
\ No newline at end of file
diff --git a/controllers/js/contact_address_common.js b/controllers/js/contact_address_common.js
index ca9e084..de1ab34 100644
--- a/controllers/js/contact_address_common.js
+++ b/controllers/js/contact_address_common.js
@@ -5,6 +5,11 @@
 	cur_frm.fields_dict.customer.get_query = erpnext.utils.customer_query;
 	cur_frm.fields_dict.supplier.get_query = erpnext.utils.supplier_query;
 	
+	if(cur_frm.fields_dict.lead) {
+		cur_frm.fields_dict.lead.get_query = erpnext.utils.lead_query;
+		cur_frm.add_fetch('lead', 'lead_name', 'lead_name');
+	}
+	
 	if(doc.__islocal) {
 		var last_route = wn.route_history.slice(-2, -1)[0];
 		if(last_route && last_route[0]==="Form") {
@@ -13,14 +18,32 @@
 				"Maintenance Schedule"]
 				.indexOf(last_route[1])!==-1) {
 				var refdoc = wn.model.get_doc(last_route[1], last_route[2]);
-				cur_frm.set_value("customer", refdoc.customer || refdoc.name);
-				cur_frm.set_value("customer_name", refdoc.customer_name);
+
+				if(refdoc.doctype == "Quotation" ? refdoc.quotation_to=="Customer" : true) {
+					cur_frm.set_value("customer", refdoc.customer || refdoc.name);
+					cur_frm.set_value("customer_name", refdoc.customer_name);
+					if(cur_frm.doc.doctype==="Address")
+						cur_frm.set_value("address_title", cur_frm.doc.customer_name);
+				}
 			}
 			if(["Supplier", "Supplier Quotation", "Purchase Order", "Purchase Invoice", "Purchase Receipt"]
 				.indexOf(last_route[1])!==-1) {
-				var customer = wn.model.get_doc(last_route[1], last_route[2]);
+				var refdoc = wn.model.get_doc(last_route[1], last_route[2]);
 				cur_frm.set_value("supplier", refdoc.supplier || refdoc.name);
 				cur_frm.set_value("supplier_name", refdoc.supplier_name);
+				if(cur_frm.doc.doctype==="Address")
+					cur_frm.set_value("address_title", cur_frm.doc.supplier_name);
+			}
+			if(["Lead", "Quotation"]
+				.indexOf(last_route[1])!==-1) {
+				var refdoc = wn.model.get_doc(last_route[1], last_route[2]);
+				
+				if(refdoc.doctype == "Quotation" ? refdoc.quotation_to=="Lead" : true) {
+					cur_frm.set_value("lead", refdoc.lead || refdoc.name);
+					cur_frm.set_value("lead_name", refdoc.customer_name || refdoc.company_name || refdoc.lead_name);
+					if(cur_frm.doc.doctype==="Address")
+						cur_frm.set_value("address_title", cur_frm.doc.lead_name);
+				}
 			}
 		}
 	}
diff --git a/manufacturing/doctype/bom/bom.js b/manufacturing/doctype/bom/bom.js
index b1f43f7..d14590c 100644
--- a/manufacturing/doctype/bom/bom.js
+++ b/manufacturing/doctype/bom/bom.js
@@ -44,9 +44,9 @@
 		var op = op_table[i].operation_no;
 		if (op && !inList(operations, op)) operations.push(op);
 	}
-	
-	cur_frm.fields_dict["bom_materials"].grid.get_field("operation_no")
-		.df.options = operations.join("\n");
+		
+	wn.meta.get_docfield("BOM Item", "operation_no", 
+		cur_frm.docname).options = operations.join("\n");
 	
 	$.each(getchildren("BOM Item", doc.name, "bom_materials"), function(i, v) {
 		if(!inList(operations, cstr(v.operation_no))) v.operation_no = null;
diff --git a/manufacturing/doctype/bom/bom.txt b/manufacturing/doctype/bom/bom.txt
index 922fd80..d539ad0 100644
--- a/manufacturing/doctype/bom/bom.txt
+++ b/manufacturing/doctype/bom/bom.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-01-22 15:11:38", 
   "docstatus": 0, 
-  "modified": "2013-01-29 17:32:53", 
+  "modified": "2013-06-27 11:08:28", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -112,6 +112,7 @@
   "options": "Specify the operations, operating cost and give a unique Operation no to your operations."
  }, 
  {
+  "depends_on": "with_operations", 
   "doctype": "DocField", 
   "fieldname": "bom_operations", 
   "fieldtype": "Table", 
diff --git a/manufacturing/doctype/bom_item/bom_item.txt b/manufacturing/doctype/bom_item/bom_item.txt
index 14be95a..2554adf 100644
--- a/manufacturing/doctype/bom_item/bom_item.txt
+++ b/manufacturing/doctype/bom_item/bom_item.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-02-22 01:27:49", 
   "docstatus": 0, 
-  "modified": "2013-03-07 07:03:18", 
+  "modified": "2013-06-27 11:30:07", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -92,6 +92,7 @@
   "reqd": 1
  }, 
  {
+  "description": "See \"Rate Of Materials Based On\" in Costing Section", 
   "doctype": "DocField", 
   "fieldname": "rate", 
   "fieldtype": "Float", 
diff --git a/patches/february_2013/p09_timesheets.py b/patches/february_2013/p09_timesheets.py
index 2242d6b..609dba3 100644
--- a/patches/february_2013/p09_timesheets.py
+++ b/patches/february_2013/p09_timesheets.py
@@ -49,7 +49,7 @@
 			for key in custom_map["Timesheet Detail"]:
 				tl.doc.fields[key] = tsd.fields.get(key)
 			
-			tl.make_obj()
+			tl.make_controller()
 			tl.controller.set_status()
 			tl.controller.calculate_total_hours()
 			tl.doc.insert()
diff --git a/patches/june_2013/p07_taxes_price_list_for_territory.py b/patches/june_2013/p07_taxes_price_list_for_territory.py
index fbce115..9204866 100644
--- a/patches/june_2013/p07_taxes_price_list_for_territory.py
+++ b/patches/june_2013/p07_taxes_price_list_for_territory.py
@@ -4,11 +4,12 @@
 	webnotes.reload_doc("setup", "doctype", "for_territory")
 	webnotes.reload_doc("setup", "doctype", "price_list")
 	webnotes.reload_doc("accounts", "doctype", "sales_taxes_and_charges_master")
+	webnotes.reload_doc("accounts", "doctype", "shipping_rule")
 	
 	from setup.utils import get_root_of
 	root_territory = get_root_of("Territory")
 	
-	for parenttype in ["Sales Taxes and Charges Master", "Price List"]:
+	for parenttype in ["Sales Taxes and Charges Master", "Price List", "Shipping Rule"]:
 		for name in webnotes.conn.sql_list("""select name from `tab%s` main
 			where not exists (select parent from `tabFor Territory` territory
 				where territory.parenttype=%s and territory.parent=main.name)""" % \
diff --git a/patches/june_2013/p10_lead_address.py b/patches/june_2013/p10_lead_address.py
new file mode 100644
index 0000000..516e2a6
--- /dev/null
+++ b/patches/june_2013/p10_lead_address.py
@@ -0,0 +1,50 @@
+import webnotes
+
+def execute():
+	webnotes.reload_doc("utilities", "doctype", "address")
+	
+	webnotes.conn.auto_commit_on_many_writes = True
+	
+	for lead in webnotes.conn.sql("""select name as lead, lead_name, address_line1, address_line2, city, country,
+		state, pincode, status, company_name from `tabLead` where not exists 
+		(select name from `tabAddress` where `tabAddress`.lead=`tabLead`.name) and 
+			(ifnull(address_line1, '')!='' or ifnull(city, '')!='' or ifnull(country, '')!='' or ifnull(pincode, '')!='')""", as_dict=True):
+			if set_in_customer(lead):
+				continue
+
+			create_address_for(lead)
+			
+	webnotes.conn.auto_commit_on_many_writes = False
+			
+def set_in_customer(lead):
+	customer = webnotes.conn.get_value("Customer", {"lead_name": lead.lead})
+	if customer:
+		customer_address = webnotes.conn.sql("""select name from `tabAddress`
+			where customer=%s and (address_line1=%s or address_line2=%s or pincode=%s)""", 
+			(customer, lead.address_line1, lead.address_line2, lead.pincode))
+		if customer_address:
+			webnotes.conn.sql("""update `tabAddress` set lead=%s, lead_name=%s
+				where name=%s""", (lead.lead, lead.company_name or lead.lead_name, customer_address[0][0]))
+			return True
+			
+	return False
+			
+def create_address_for(lead):
+	address_title = lead.company_name or lead.lead_name or lead.lead
+	
+	for c in ['%', "'", '"', '#', '*', '?', '`']:
+		address_title = address_title.replace(c, "")
+	
+	if webnotes.conn.get_value("Address", address_title.strip() + "-" + "Billing"):
+		address_title += " " + lead.lead 
+	
+	lead.update({
+		"doctype": "Address", 
+		"address_type": "Billing", 
+		"address_title": address_title
+	})
+	
+	del lead["company_name"]
+	del lead["status"]
+	
+	webnotes.bean(lead).insert()
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index 8979f43..aaf5102 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -247,5 +247,8 @@
 	"patches.june_2013.p06_drop_unused_tables",
 	"patches.june_2013.p08_shopping_cart_settings",
 	"patches.june_2013.p05_remove_search_criteria_reports",
+	"patches.june_2013.p07_taxes_price_list_for_territory",
+	"patches.june_2013.p08_shopping_cart_settings",
 	"patches.june_2013.p09_update_global_defaults",
+	"patches.june_2013.p10_lead_address",
 ]
\ No newline at end of file
diff --git a/public/js/startup.js b/public/js/startup.js
index 96953ad..26e5219 100644
--- a/public/js/startup.js
+++ b/public/js/startup.js
@@ -36,11 +36,18 @@
 		erpnext.toolbar.setup();
 		
 		// complete registration
-		if(in_list(user_roles,'System Manager') && (wn.boot.setup_complete=='No')) { 
+		if(in_list(user_roles,'System Manager') && (wn.boot.setup_complete==='No')) { 
 			wn.require("app/js/complete_setup.js");
 			erpnext.complete_setup.show(); 
-		}
-		if(wn.boot.expires_on && in_list(user_roles, 'System Manager')) {
+		} else if(!wn.boot.customer_count) {
+			if(wn.get_route()[0]!=="Setup") {
+				msgprint("<a class='btn btn-success' href='#Setup'>" 
+					+ wn._("Proceed to Setup") + "</a>\
+					<br><br><p class='text-muted'>"+
+					wn._("This message goes away after you create your first customer.")+
+					"</p>", wn._("Welcome"));
+			}
+		} else if(wn.boot.expires_on && in_list(user_roles, 'System Manager')) {
 			var today = dateutil.str_to_obj(wn.boot.server_date);
 			var expires_on = dateutil.str_to_obj(wn.boot.expires_on);
 			var diff = dateutil.get_diff(expires_on, today);
diff --git a/selling/doctype/customer/customer.py b/selling/doctype/customer/customer.py
index 65ac865..10d2ce5 100644
--- a/selling/doctype/customer/customer.py
+++ b/selling/doctype/customer/customer.py
@@ -62,49 +62,6 @@
 	def validate(self):
 		self.validate_values()
 
-	def create_customer_address(self):
-		addr_flds = [self.doc.address_line1, self.doc.address_line2, self.doc.city, self.doc.state, self.doc.country, self.doc.pincode]
-		address_line = "\n".join(filter(lambda x : (x!='' and x!=None),addr_flds))
-
-		if self.doc.phone_1:
-			address_line = address_line + "\n" + "Phone: " + cstr(self.doc.phone_1)
-		if self.doc.email_id:
-			address_line = address_line + "\n" + "E-mail: " + cstr(self.doc.email_id)
-		webnotes.conn.set(self.doc,'address', address_line)
-		
-		telephone = "(O): " + cstr(self.doc.phone_1) +"\n"+ cstr(self.doc.phone_2) + "\n" + "(M): " +	"\n" + "(fax): " + cstr(self.doc.fax_1)
-		webnotes.conn.set(self.doc,'telephone',telephone)
-
-	def create_p_contact(self,nm,phn_no,email_id,mob_no,fax,cont_addr):
-		c1 = Document('Contact')
-		c1.first_name = nm
-		c1.contact_name = nm
-		c1.contact_no = phn_no
-		c1.email_id = email_id
-		c1.mobile_no = mob_no
-		c1.fax = fax
-		c1.contact_address = cont_addr
-		c1.is_primary_contact = 'Yes'
-		c1.is_customer =1
-		c1.customer = self.doc.name
-		c1.customer_name = self.doc.customer_name
-		c1.customer_address = self.doc.address
-		c1.customer_group = self.doc.customer_group
-		c1.save(1)
-
-	def create_customer_contact(self):
-		contact = sql("select distinct name from `tabContact` where customer_name=%s", (self.doc.customer_name))
-		contact = contact and contact[0][0] or ''
-		if not contact:
-			# create primary contact for individual customer 
-			if self.doc.customer_type == 'Individual':
-				self.create_p_contact(self.doc.customer_name,self.doc.phone_1,self.doc.email_id,'',self.doc.fax_1,self.doc.address)
-		
-			# create primary contact for lead
-			elif self.doc.lead_name:
-				c_detail = sql("select lead_name, company_name, contact_no, mobile_no, email_id, fax, address from `tabLead` where name =%s", self.doc.lead_name, as_dict=1)
-				self.create_p_contact(c_detail and c_detail[0]['lead_name'] or '', c_detail and c_detail[0]['contact_no'] or '', c_detail and c_detail[0]['email_id'] or '', c_detail and c_detail[0]['mobile_no'] or '', c_detail and c_detail[0]['fax'] or '', c_detail and c_detail[0]['address'] or '')
-
 	def update_lead_status(self):
 		if self.doc.lead_name:
 			sql("update `tabLead` set status='Converted' where name = %s", self.doc.lead_name)
@@ -139,31 +96,16 @@
 
 	def create_lead_address_contact(self):
 		if self.doc.lead_name:
-			details = sql("select name, lead_name, address_line1, address_line2, city, country, state, pincode, phone, mobile_no, fax, email_id from `tabLead` where name = '%s'" %(self.doc.lead_name), as_dict = 1)
-			d = Document('Address') 
-			d.address_line1 = details[0]['address_line1'] 
-			d.address_line2 = details[0]['address_line2']
-			d.city = details[0]['city']
-			d.country = details[0]['country']
-			d.pincode = details[0]['pincode']
-			d.state = details[0]['state']
-			d.fax = details[0]['fax']
-			d.email_id = details[0]['email_id']
-			d.phone = details[0]['phone']
-			d.customer = self.doc.name
-			d.customer_name = self.doc.customer_name
-			d.is_primary_address = 1
-			d.address_type = 'Office'
-			try:
-				d.save(1)
-			except NameError, e:
-				pass
-				
+			if not webnotes.conn.get_value("Address", {"lead": self.doc.lead_name, "customer": self.doc.customer}):
+				webnotes.conn.sql("""update `tabAddress` set customer=%s, customer_name=%s where lead=%s""", 
+					(self.doc.name, self.doc.customer_name, self.doc.lead_name))
+
+			lead = webnotes.conn.get_value("Lead", self.doc.lead_name, ["lead_name", "email_id", "phone", "mobile_no"], as_dict=True)
 			c = Document('Contact') 
-			c.first_name = details[0]['lead_name'] 
-			c.email_id = details[0]['email_id']
-			c.phone = details[0]['phone']
-			c.mobile_no = details[0]['mobile_no']
+			c.first_name = lead.lead_name 
+			c.email_id = lead.email_id
+			c.phone = lead.phone
+			c.mobile_no = lead.mobile_no
 			c.customer = self.doc.name
 			c.customer_name = self.doc.customer_name
 			c.is_primary_contact = 1
diff --git a/selling/doctype/lead/lead.js b/selling/doctype/lead/lead.js
index c94aafa..8fb26c5 100644
--- a/selling/doctype/lead/lead.js
+++ b/selling/doctype/lead/lead.js
@@ -14,78 +14,79 @@
 // You should have received a copy of the GNU General Public License
 // along with this program.	If not, see <http://www.gnu.org/licenses/>.
 
-// Module CRM
-
 wn.require('app/utilities/doctype/sms_control/sms_control.js');
+wn.require('app/setup/doctype/contact_control/contact_control.js');
 
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
-	if(user =='Guest'){
-		hide_field(['status', 'naming_series', 'order_lost_reason',
-	'customer', 'rating', 'fax', 'website', 'territory',
-	'address_line1', 'address_line2', 'city', 'state',
-	'country', 'pincode', 'address', 'lead_owner', 'market_segment',
-	'industry', 'campaign_name', 'interested_in', 'company',
-	'fiscal_year', 'contact_by', 'contact_date', 'last_contact_date',
-	'contact_date_ref', 'to_discuss', 'more_info', 'follow_up',
-	'communication_history', 'cc_to', 'subject', 'message', 'lead_attachment_detail',
-	'Create Customer', 'Create Opportunity', 'transaction_date', 'type', 'source']);
-		doc.source = 'Website';
-	}
-	if(!doc.status) set_multiple(dt,dn,{status:'Open'});
-
-	if (!doc.date){ 
-		doc.date = date.obj_to_str(new Date());
-	}
-	// set naming series
-	if(user=='Guest') doc.naming_series = 'WebLead';
+wn.provide("erpnext");
+erpnext.LeadController = wn.ui.form.Controller.extend({
+	setup: function() {
+		this.frm.fields_dict.customer.get_query = erpnext.utils.customer_query;
+	},
 	
-	cur_frm.add_fetch('customer', 'customer_name', 'company_name');
-	
-	if(cur_frm.fields_dict.lead_owner.df.options.match(/^Profile/)) {
-		cur_frm.fields_dict.lead_owner.get_query = erpnext.utils.profile_query;
-	}
-
-	if(cur_frm.fields_dict.contact_by.df.options.match(/^Profile/)) {
-		cur_frm.fields_dict.contact_by.get_query = erpnext.utils.profile_query;
-	}
-
-	if(in_list(user_roles,'System Manager')) {
-		cur_frm.footer.help_area.innerHTML = '<hr>\
-			<p><a href="#Form/Sales Email Settings">Sales Email Settings</a><br>\
-			<span class="help">Automatically extract Leads from a mail box e.g. "sales@example.com"</span></p>';
-	}
-}
-
-cur_frm.cscript.refresh_custom_buttons = function(doc) {
-	cur_frm.clear_custom_buttons();
-	if(!doc.__islocal && !in_list(['Converted', 'Lead Lost'], doc.status)) {
-		if (doc.source != 'Existing Customer') {
-			cur_frm.add_custom_button('Create Customer',
-				cur_frm.cscript['Create Customer']);
+	onload: function() {
+		if(cur_frm.fields_dict.lead_owner.df.options.match(/^Profile/)) {
+			cur_frm.fields_dict.lead_owner.get_query = erpnext.utils.profile_query;
 		}
-		cur_frm.add_custom_button('Create Opportunity',
-			cur_frm.cscript['Create Opportunity']);
-		cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
+
+		if(cur_frm.fields_dict.contact_by.df.options.match(/^Profile/)) {
+			cur_frm.fields_dict.contact_by.get_query = erpnext.utils.profile_query;
+		}
+
+		if(in_list(user_roles,'System Manager')) {
+			cur_frm.footer.help_area.innerHTML = '<hr>\
+				<p><a href="#Form/Sales Email Settings">Sales Email Settings</a><br>\
+				<span class="help">Automatically extract Leads from a mail box e.g. "sales@example.com"</span></p>';
+		}
+	},
+	
+	refresh: function() {
+		erpnext.hide_naming_series();
+		this.frm.clear_custom_buttons();
+		
+		this.frm.__is_customer = this.frm.__is_customer || this.frm.doc.__is_customer;
+		if(!this.frm.doc.__islocal && !this.frm.__is_customer) {
+			this.frm.add_custom_button("Create Customer", this.frm.cscript['Create Customer']);
+			this.frm.add_custom_button("Create Opportunity", this.frm.cscript['Create Opportunity']);
+			this.frm.add_custom_button("Send SMS", this.frm.cscript.send_sms);
+		}
+		
+		cur_frm.communication_view = new wn.views.CommunicationList({
+			list: wn.model.get("Communication", {"lead": this.frm.doc.name}),
+			parent: this.frm.fields_dict.communication_html.wrapper,
+			doc: this.frm.doc,
+			recipients: this.frm.doc.email_id
+		});
+		
+		if(!this.frm.doc.__islocal) {
+			this.make_address_list();
+		}
+	},
+	
+	make_address_list: function() {
+		var me = this;
+		if(!this.frm.address_list) {
+			this.frm.address_list = new wn.ui.Listing({
+				parent: this.frm.fields_dict['address_html'].wrapper,
+				page_length: 5,
+				new_doctype: "Address",
+				get_query: function() {
+					return 'select name, address_type, address_line1, address_line2, \
+					city, state, country, pincode, fax, email_id, phone, \
+					is_primary_address, is_shipping_address from tabAddress \
+					where lead="'+me.frm.doc.name+'" and docstatus != 2 \
+					order by is_primary_address, is_shipping_address desc'
+				},
+				as_dict: 1,
+				no_results_message: 'No addresses created',
+				render_row: this.render_address_row,
+			});
+			// note: render_address_row is defined in contact_control.js
+		}
+		this.frm.address_list.run();
 	}
-}
+});
 
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-	cur_frm.cscript.refresh_custom_buttons(doc);
-	erpnext.hide_naming_series();
-
-	cur_frm.communication_view = new wn.views.CommunicationList({
-		list: wn.model.get("Communication", {"lead": doc.name}),
-		parent: cur_frm.fields_dict.communication_html.wrapper,
-		doc: doc,
-		recipients: doc.email_id
-	})
-}
-
-
-
-cur_frm.cscript.status = function(doc, cdt, cdn){
-	cur_frm.cscript.refresh(doc, cdt, cdn);
-}
+$.extend(cur_frm.cscript, new erpnext.LeadController({frm: cur_frm}));
 
 cur_frm.cscript['Create Customer'] = function(){
 	var doc = cur_frm.doc;
@@ -147,11 +148,4 @@
 			}
 		}
 	);
-}
-
-//get query select Territory
-cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
-	return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY	`tabTerritory`.`name` ASC LIMIT 50';
-}
-
-cur_frm.fields_dict.customer.get_query = erpnext.utils.customer_query;
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py
index a54343a..928eda7 100644
--- a/selling/doctype/lead/lead.py
+++ b/selling/doctype/lead/lead.py
@@ -38,6 +38,9 @@
 
 	def onload(self):
 		self.add_communication_list()
+		customer = webnotes.conn.get_value("Customer", {"lead_name": self.doc.name})
+		if customer:
+			self.doc.fields["__is_customer"] = customer
 
 	def on_communication_sent(self, comm):
 		webnotes.conn.set(self.doc, 'status', 'Replied')
diff --git a/selling/doctype/lead/lead.txt b/selling/doctype/lead/lead.txt
index 0b602ea..eed87ba 100644
--- a/selling/doctype/lead/lead.txt
+++ b/selling/doctype/lead/lead.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-04-10 11:45:37", 
   "docstatus": 0, 
-  "modified": "2013-06-14 16:20:17", 
+  "modified": "2013-06-28 15:08:26", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -164,10 +164,34 @@
   "doctype": "DocField", 
   "fieldname": "contact_info", 
   "fieldtype": "Section Break", 
-  "label": "Contact Info", 
+  "label": "Address & Contact", 
   "oldfieldtype": "Column Break"
  }, 
  {
+  "depends_on": "eval:doc.__islocal", 
+  "doctype": "DocField", 
+  "fieldname": "address_desc", 
+  "fieldtype": "HTML", 
+  "hidden": 0, 
+  "label": "Address Desc", 
+  "options": "<em>Addresses will appear only when you save the lead</em>", 
+  "print_hide": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "address_html", 
+  "fieldtype": "HTML", 
+  "hidden": 0, 
+  "label": "Address HTML", 
+  "print_hide": 0, 
+  "read_only": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "column_break2", 
+  "fieldtype": "Column Break"
+ }, 
+ {
   "doctype": "DocField", 
   "fieldname": "remark", 
   "fieldtype": "Small Text", 
@@ -221,70 +245,6 @@
  }, 
  {
   "doctype": "DocField", 
-  "fieldname": "column_break2", 
-  "fieldtype": "Column Break"
- }, 
- {
-  "doctype": "DocField", 
-  "fieldname": "address_line1", 
-  "fieldtype": "Data", 
-  "label": "Address Line 1", 
-  "oldfieldname": "address_line1", 
-  "oldfieldtype": "Data", 
-  "print_hide": 1, 
-  "reqd": 0
- }, 
- {
-  "doctype": "DocField", 
-  "fieldname": "address_line2", 
-  "fieldtype": "Data", 
-  "label": "Address Line 2", 
-  "oldfieldname": "address_line2", 
-  "oldfieldtype": "Data", 
-  "print_hide": 1
- }, 
- {
-  "doctype": "DocField", 
-  "fieldname": "city", 
-  "fieldtype": "Data", 
-  "label": "City", 
-  "oldfieldname": "city", 
-  "oldfieldtype": "Select", 
-  "print_hide": 1, 
-  "reqd": 0
- }, 
- {
-  "doctype": "DocField", 
-  "fieldname": "country", 
-  "fieldtype": "Select", 
-  "label": "Country", 
-  "oldfieldname": "country", 
-  "oldfieldtype": "Select", 
-  "options": "link:Country", 
-  "print_hide": 1, 
-  "reqd": 0
- }, 
- {
-  "doctype": "DocField", 
-  "fieldname": "state", 
-  "fieldtype": "Data", 
-  "label": "State", 
-  "oldfieldname": "state", 
-  "oldfieldtype": "Select", 
-  "options": "Suggest", 
-  "print_hide": 1
- }, 
- {
-  "doctype": "DocField", 
-  "fieldname": "pincode", 
-  "fieldtype": "Data", 
-  "label": "Pin Code", 
-  "oldfieldname": "pincode", 
-  "oldfieldtype": "Data", 
-  "print_hide": 1
- }, 
- {
-  "doctype": "DocField", 
   "fieldname": "more_info", 
   "fieldtype": "Section Break", 
   "label": "More Info", 
diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt
index 74a4396..b9772c8 100644
--- a/selling/doctype/quotation/quotation.txt
+++ b/selling/doctype/quotation/quotation.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-05-24 19:29:08", 
   "docstatus": 0, 
-  "modified": "2013-06-19 15:55:15", 
+  "modified": "2013-06-28 12:47:10", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -420,7 +420,7 @@
   "fieldname": "charge", 
   "fieldtype": "Link", 
   "hidden": 0, 
-  "label": "Sales Taxes and Charges", 
+  "label": "Apply Taxes and Charges Master", 
   "oldfieldname": "charge", 
   "oldfieldtype": "Link", 
   "options": "Sales Taxes and Charges Master", 
@@ -434,11 +434,12 @@
  }, 
  {
   "doctype": "DocField", 
-  "fieldname": "get_charges", 
-  "fieldtype": "Button", 
+  "fieldname": "shipping_rule", 
+  "fieldtype": "Link", 
   "hidden": 0, 
-  "label": "Get Taxes and Charges", 
+  "label": "Apply Shipping Rule", 
   "oldfieldtype": "Button", 
+  "options": "Shipping Rule", 
   "print_hide": 1, 
   "read_only": 0
  }, 
@@ -690,6 +691,24 @@
   "search_index": 0
  }, 
  {
+  "doctype": "DocField", 
+  "fieldname": "shipping_address_name", 
+  "fieldtype": "Link", 
+  "hidden": 0, 
+  "label": "Shipping Address Name", 
+  "options": "Address", 
+  "print_hide": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "shipping_address", 
+  "fieldtype": "Small Text", 
+  "hidden": 1, 
+  "label": "Shipping Address", 
+  "print_hide": 1, 
+  "read_only": 1
+ }, 
+ {
   "depends_on": "customer", 
   "doctype": "DocField", 
   "fieldname": "col_break98", 
diff --git a/selling/doctype/sales_common/sales_common.js b/selling/doctype/sales_common/sales_common.js
index 2d30601..77e7759 100644
--- a/selling/doctype/sales_common/sales_common.js
+++ b/selling/doctype/sales_common/sales_common.js
@@ -27,6 +27,9 @@
 erpnext.selling.SellingController = erpnext.TransactionController.extend({
 	setup: function() {
 		this.frm.add_fetch("sales_partner", "commission_rate", "commission_rate");
+		
+		if(this.frm.fields_dict.shipping_address_name && this.frm.fields_dict.customer_address)
+			this.frm.fields_dict.shipping_address_name.get_query = this.frm.fields_dict['customer_address'].get_query;
 	},
 	
 	onload: function() {
@@ -368,7 +371,7 @@
 		}
 	},
 	
-	get_charges: function() {
+	charge: function() {
 		var me = this;
 		if(this.frm.doc.charge) {
 			this.frm.call({
@@ -476,6 +479,27 @@
 		});
 	},
 	
+	shipping_address_name: function () {
+		var me = this;
+		if(this.frm.doc.shipping_address_name) {
+			wn.model.with_doc("Address", this.frm.doc.shipping_address_name, function(name) {
+				var address = wn.model.get_doc("Address", name);
+			
+				var out = $.map(["address_line1", "address_line2", "city"], 
+					function(f) { return address[f]; });
+
+				var state_pincode = $.map(["state", "pincode"], function(f) { return address[f]; }).join(" ");
+				if(state_pincode) out.push(state_pincode);
+			
+				if(address["country"]) out.push(address["country"]);
+			
+				out.concat($.map([["Phone:", address["phone"]], ["Fax:", address["fax"]]], 
+					function(val) { return val[1] ? val.join(" ") : null; }));
+			
+				me.frm.set_value("shipping_address", out.join("\n"));
+			});
+		}
+	}
 });
 
 // to save previous state of cur_frm.cscript
diff --git a/selling/doctype/sales_order/sales_order.js b/selling/doctype/sales_order/sales_order.js
index d8aab21..d9e2d7b 100644
--- a/selling/doctype/sales_order/sales_order.js
+++ b/selling/doctype/sales_order/sales_order.js
@@ -79,29 +79,6 @@
 	if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
 }
 
-cur_frm.fields_dict.shipping_address_name.get_query = cur_frm.fields_dict['customer_address'].get_query;
-
-cur_frm.cscript.shipping_address_name = function() {
-	if(cur_frm.doc.shipping_address_name) {
-		wn.model.with_doc("Address", cur_frm.doc.shipping_address_name, function(name) {
-			var address = wn.model.get_doc("Address", name);
-			
-			var out = $.map(["address_line1", "address_line2", "city"], 
-				function(f) { return address[f]; });
-
-			var state_pincode = $.map(["state", "pincode"], function(f) { return address[f]; }).join(" ");
-			if(state_pincode) out.push(state_pincode);
-			
-			if(address["country"]) out.push(address["country"]);
-			
-			out.concat($.map([["Phone:", address["phone"]], ["Fax:", address["fax"]]], 
-				function(val) { return val[1] ? val.join(" ") : null; }));
-			
-			cur_frm.set_value("shipping_address", out.join("\n"));
-		});
-	}
-};
-
 cur_frm.cscript.pull_quotation_details = function(doc,dt,dn) {
 	var callback = function(r,rt){
 		var doc = locals[cur_frm.doctype][cur_frm.docname];					
diff --git a/selling/doctype/sales_order/sales_order.txt b/selling/doctype/sales_order/sales_order.txt
index dcb0306..6bb1d26 100644
--- a/selling/doctype/sales_order/sales_order.txt
+++ b/selling/doctype/sales_order/sales_order.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-06-18 12:39:59", 
   "docstatus": 0, 
-  "modified": "2013-06-18 17:49:11", 
+  "modified": "2013-06-27 11:31:02", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -450,7 +450,7 @@
   "doctype": "DocField", 
   "fieldname": "charge", 
   "fieldtype": "Link", 
-  "label": "Sales Taxes and Charges", 
+  "label": "Apply Taxes and Charges Master", 
   "oldfieldname": "charge", 
   "oldfieldtype": "Link", 
   "options": "Sales Taxes and Charges Master", 
@@ -463,10 +463,12 @@
  }, 
  {
   "doctype": "DocField", 
-  "fieldname": "get_charges", 
-  "fieldtype": "Button", 
-  "label": "Get Taxes and Charges", 
-  "oldfieldtype": "Button"
+  "fieldname": "shipping_rule", 
+  "fieldtype": "Link", 
+  "label": "Apply Shipping Rule", 
+  "oldfieldtype": "Button", 
+  "options": "Shipping Rule", 
+  "print_hide": 1
  }, 
  {
   "doctype": "DocField", 
diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py
index 64783a0..54a293f 100644
--- a/setup/doctype/company/company.py
+++ b/setup/doctype/company/company.py
@@ -190,33 +190,23 @@
 				self.doc.letter_head = header
 
 	def set_default_accounts(self):
-		if not self.doc.receivables_group and webnotes.conn.exists('Account', 
-			'Accounts Receivable - ' + self.doc.abbr):
-				webnotes.conn.set(self.doc, 'receivables_group', 'Accounts Receivable - ' + 
-					self.doc.abbr)
-					
-		if not self.doc.payables_group and webnotes.conn.exists('Account', 
-			'Accounts Payable - ' + self.doc.abbr):
-				webnotes.conn.set(self.doc, 'payables_group', 'Accounts Payable - ' + self.doc.abbr)
-								
-		if not self.doc.stock_received_but_not_billed and webnotes.conn.exists("Account", 
-			"Stock Received But Not Billed - " + self.doc.abbr):
-				webnotes.conn.set(self.doc, "stock_received_but_not_billed", 
-					"Stock Received But Not Billed - " + self.doc.abbr)
+		accounts = {
+			"receivables_group": "Accounts Receivable",
+			"payables_group": "Accounts Payable",
+			"stock_received_but_not_billed": "Stock Received But Not Billed",
+			"stock_in_hand_account": "Stock In Hand",
+			"stock_adjustment_account": "Stock Adjustment",
+			"expenses_included_in_valuation": "Expenses Included In Valuation"
+		}
 		
-		if not self.doc.stock_adjustment_account and webnotes.conn.exists("Account", 
-			"Stock Adjustment - " + self.doc.abbr):
-				webnotes.conn.set(self.doc, "stock_adjustment_account", "Stock Adjustment - " + 
-					self.doc.abbr)
-					
-		if not self.doc.expenses_included_in_valuation and webnotes.conn.exists("Account", 
-			"Expenses Included In Valuation - " + self.doc.abbr):
-				webnotes.conn.set(self.doc, "expenses_included_in_valuation", 
-					"Expenses Included In Valuation - " + self.doc.abbr)
-		
+		for a in accounts:
+			account_name = accounts[a] + " - " + self.doc.abbr
+			if not self.doc.fields[a] and webnotes.conn.exists("Account", account_name):
+				webnotes.conn.set(self.doc, account_name)
+
 		if not self.doc.stock_adjustment_cost_center:
 				webnotes.conn.set(self.doc, "stock_adjustment_cost_center", self.doc.cost_center)
-	
+
 	# Create default cost center
 	# ---------------------------------------------------
 	def create_default_cost_center(self):
@@ -249,8 +239,7 @@
 			where company=%s and docstatus<2 limit 1""", self.doc.name):
 			self.create_default_accounts()
 		
-		if not webnotes.conn.sql("""select name from `tabCost Center` 
-			where cost_center_name = 'All Units' and company_name = %s""", self.doc.name):
+		if not self.doc.cost_center:
 			self.create_default_cost_center()
 			
 		self.set_default_accounts()
diff --git a/setup/doctype/contact_control/contact_control.js b/setup/doctype/contact_control/contact_control.js
index 79e9de7..c427ec0 100755
--- a/setup/doctype/contact_control/contact_control.js
+++ b/setup/doctype/contact_control/contact_control.js
@@ -59,8 +59,8 @@
 	// prepare data
 	data.fullname = data.address_type;
 	data.primary = '';
-	if (data.is_primary_address) data.primary += ' [Primary]';
-	if (data.is_shipping_address) data.primary += ' [Shipping]';
+	if (data.is_primary_address) data.primary += ' [Preferred for Billing]';
+	if (data.is_shipping_address) data.primary += ' [Preferred for Shipping]';
 	
 	// prepare address
 	var address = [];
diff --git a/setup/doctype/setup_control/setup_control.py b/setup/doctype/setup_control/setup_control.py
index 60d2957..8b44f7e 100644
--- a/setup/doctype/setup_control/setup_control.py
+++ b/setup/doctype/setup_control/setup_control.py
@@ -17,7 +17,7 @@
 from __future__ import unicode_literals
 import webnotes
 
-from webnotes.utils import cint, cstr, getdate, now, nowdate
+from webnotes.utils import cint, cstr, getdate, now, nowdate, get_defaults
 from webnotes.model.doc import Document, addchild
 from webnotes.model.code import get_obj
 from webnotes import session, form, msgprint
@@ -26,16 +26,31 @@
 	def __init__(self, d, dl):
 		self.doc, self.doclist = d, dl
 	
-	# Account Setup
-	# ---------------
 	def setup_account(self, args):
 		import webnotes, json
 		args = json.loads(args)
 		webnotes.conn.begin()
 
-		curr_fiscal_year, fy_start_date, fy_abbr = self.get_fy_details(args.get('fy_start'))
-		#webnotes.msgprint(self.get_fy_details(args.get('fy_start')))
+		self.update_profile_name(args)
+		add_all_roles_to(webnotes.session.user)
+		self.create_fiscal_year_and_company(args)
+		self.set_defaults(args)
+		create_territories()
+		self.create_price_lists(args)
+		self.create_feed_and_todo()
+		self.create_email_digest()
 
+		webnotes.clear_cache()
+		msgprint("Company setup is complete. This page will be refreshed in a moment.")
+		webnotes.conn.commit()
+
+		return {
+			'sys_defaults': get_defaults(), 
+			'user_fullname': (args.get('first_name') or '') + (args.get('last_name')
+					and (" " + args.get('last_name')) or '')
+		}
+	
+	def update_profile_name(self, args):
 		args['name'] = webnotes.session.get('user')
 
 		# Update Profile
@@ -44,39 +59,54 @@
 			UPDATE `tabProfile` SET first_name=%(first_name)s,
 			last_name=%(last_name)s
 			WHERE name=%(name)s AND docstatus<2""", args)
-			
-		
+	
+	def create_fiscal_year_and_company(self, args):
+		curr_fiscal_year, fy_start_date, fy_abbr = self.get_fy_details(args.get('fy_start'))
 		# Fiscal Year
-		master_dict = {'Fiscal Year':{
+		webnotes.bean([{
+			"doctype":"Fiscal Year",
 			'year': curr_fiscal_year,
 			'year_start_date': fy_start_date,
-		}}
-		self.create_records(master_dict)
-		
+		}]).insert()
 		
 		# Company
-		master_dict = {'Company': {
+		webnotes.bean([{
+			"doctype":"Company",
 			'company_name':args.get('company_name'),
 			'abbr':args.get('company_abbr'),
 			'default_currency':args.get('currency')
-		}}
-		self.create_records(master_dict)
-
+		}]).insert()
+		
+		self.curr_fiscal_year = curr_fiscal_year
+	
+	def create_price_lists(self, args):
+		webnotes.bean({
+			'doctype': 'Price List', 
+			'price_list_name': 'Standard Selling',
+			"buying_or_selling": "Selling",
+			"currency": args["currency"]
+		}).insert(),
+		webnotes.bean({
+			'doctype': 'Price List', 
+			'price_list_name': 'Standard Buying',
+			"buying_or_selling": "Buying",
+			"currency": args["currency"]
+		}).insert(),
+	
+	def set_defaults(self, args):
 		# enable default currency
 		webnotes.conn.set_value("Currency", args.get("currency"), "enabled", 1)
 		
-		def_args = {
-			'current_fiscal_year':curr_fiscal_year,
+		global_defaults = webnotes.bean("Global Defaults", "Global Defaults")
+		global_defaults.doc.fields.update({
+			'current_fiscal_year': self.curr_fiscal_year,
 			'default_currency': args.get('currency'),
 			'default_company':args.get('company_name'),
-			'date_format': webnotes.conn.get_value("Country", 
-				args.get("country"), "date_format"),
+			'date_format': webnotes.conn.get_value("Country", args.get("country"), "date_format"),
 			'emp_created_by':'Naming Series',
 			"float_precision": 4
-		}
-
-		# Set 
-		self.set_defaults(def_args)
+		})
+		global_defaults.save()
 		
 		webnotes.conn.set_value("Accounts Settings", None, "auto_inventory_accounting", 1)
 		webnotes.conn.set_default("auto_inventory_accounting", 1)
@@ -89,7 +119,7 @@
 		stock_settings.save()
 		
 		selling_settings = webnotes.bean("Selling Settings")
-		selling_settings.cust_master_name = "Customer Name"
+		selling_settings.doc.cust_master_name = "Customer Name"
 		selling_settings.doc.so_required = "No"
 		selling_settings.doc.dn_required = "No"
 		selling_settings.save()
@@ -100,29 +130,20 @@
 		buying_settings.doc.pr_required = "No"
 		buying_settings.doc.maintain_same_rate = 1
 		buying_settings.save()
-		
-		cp_args = {}
+
+		notification_control = webnotes.bean("Notification Control")
+		notification_control.doc.quotation = 1
+		notification_control.doc.sales_invoice = 1
+		notification_control.doc.purchase_order = 1
+		notification_control.save()
+
+		# control panel
+		cp = webnotes.doc("Control Panel", "Control Panel")
 		for k in ['industry', 'country', 'timezone', 'company_name']:
-			cp_args[k] = args[k]
-		
-		self.set_cp_defaults(**cp_args)
-		
-		create_territories()
-
-		self.create_feed_and_todo()
-		
-		self.create_email_digest()
-
-		webnotes.clear_cache()
-		msgprint("Company setup is complete. This page will be refreshed in a moment.")
-		
-		import webnotes.utils
-		user_fullname = (args.get('first_name') or '') + (args.get('last_name')
-				and (" " + args.get('last_name')) or '')
-				
-		webnotes.conn.commit()
-		return {'sys_defaults': webnotes.utils.get_defaults(), 'user_fullname': user_fullname}
-		
+			cp.fields[k] = args[k]
+			
+		cp.save()
+			
 	def create_feed_and_todo(self):
 		"""update activty feed and create todo for creation of item, customer, vendor"""
 		import home
@@ -131,24 +152,9 @@
 			To Do List</a>' + '"</i>', '#6B24B3')
 
 		d = Document('ToDo')
-		d.description = 'Create your first Customer'
+		d.description = '<a href="#Setup">Complete ERPNext Setup</a>'
 		d.priority = 'High'
 		d.date = nowdate()
-		d.reference_type = 'Customer'
-		d.save(1)
-
-		d = Document('ToDo')
-		d.description = 'Create your first Item'
-		d.priority = 'High'
-		d.date = nowdate()
-		d.reference_type = 'Item'
-		d.save(1)
-
-		d = Document('ToDo')
-		d.description = 'Create your first Supplier'
-		d.priority = 'High'
-		d.date = nowdate()
-		d.reference_type = 'Supplier'
 		d.save(1)
 
 	def create_email_digest(self):
@@ -206,42 +212,7 @@
 			fy = cstr(curr_year) + '-' + cstr(curr_year+1)
 			abbr = cstr(curr_year)[-2:] + '-' + cstr(curr_year+1)[-2:]
 		return fy, stdt, abbr
-
-
-	def create_records(self, master_dict):
-		for d in master_dict.keys():
-			rec = Document(d)
-			for fn in master_dict[d].keys():
-				rec.fields[fn] = master_dict[d][fn]
-				
-			rec_obj = get_obj(doc=rec)
-			rec_obj.doc.save(1)
-			if hasattr(rec_obj, 'on_update'):
-				rec_obj.on_update()
-
-
-	# Set System Defaults
-	# --------------------
-	def set_defaults(self, def_args):
-		ma_obj = get_obj('Global Defaults','Global Defaults')
-		for d in def_args.keys():
-			ma_obj.doc.fields[d] = def_args[d]
-		ma_obj.doc.save()
-		ma_obj.on_update()
-
-
-	# Set Control Panel Defaults
-	# --------------------------
-	def set_cp_defaults(self, industry, country, timezone, company_name):
-		cp = Document('Control Panel','Control Panel')
-		cp.company_name = company_name
-		cp.industry = industry
-		cp.time_zone = timezone
-		cp.country = country
-		cp.save()
 			
-	# Create Profile
-	# --------------
 	def create_profile(self, user_email, user_fname, user_lname, pwd=None):
 		pr = Document('Profile')
 		pr.first_name = user_fname
@@ -261,7 +232,7 @@
 	profile = webnotes.doc("Profile", name)
 	for role in webnotes.conn.sql("""select name from tabRole"""):
 		if role[0] not in ["Administrator", "Guest", "All", "Customer", "Supplier", "Partner"]:
-			d = profile.addchild("userroles", "UserRole")
+			d = profile.addchild("user_roles", "UserRole")
 			d.role = role[0]
 			d.insert()
 			
diff --git a/setup/page/setup/setup.css b/setup/page/setup/setup.css
deleted file mode 100644
index bff44db..0000000
--- a/setup/page/setup/setup.css
+++ /dev/null
@@ -1,6 +0,0 @@
-.setup-column {
-	float: left;
-	width: 45%;
-	margin-right: 5%;
-	margin-bottom: 15px;
-}
\ No newline at end of file
diff --git a/setup/page/setup/setup.js b/setup/page/setup/setup.js
index 788021a..9087188 100644
--- a/setup/page/setup/setup.js
+++ b/setup/page/setup/setup.js
@@ -1,228 +1,180 @@
-// ERPNext: Copyright 2013 Web Notes Technologies Pvt Ltd
-// GNU General Public License. See "license.txt"
+wn.pages['Setup'].onload = function(wrapper) { 
+	if(msg_dialog && msg_dialog.display) msg_dialog.hide();
+	wn.ui.make_app_page({
+		parent: wrapper,
+		title: 'Setup',
+		single_column: true
+	});
 
-wn.module_page["Setup"] = [
-	{
-		title: wn._("Organization"),
-		icon: "icon-building",
-		items: [
-			{
-				"label":wn._("Company"),
-				"doctype":"Company",
-				"description":wn._("List of companies (not customers / suppliers)")
-			},
-			{
-				"doctype":"Fiscal Year",
-				"label": wn._("Fiscal Year"),
-				"description":wn._("Financial Years for books of accounts")
-			},
-			{
-				"doctype":"Currency",
-				"label": wn._("Currency"),
-				"description": wn._("Enable / disable currencies.")
-			},
-		]
-	},
-	{
-		title: wn._("Users"),
-		icon: "icon-group",
-		right: true,
-		items: [
-			{
-				"doctype":"Profile",
-				"label": wn._("Profile"),
-				"description": wn._("Add/remove users, set roles, passwords etc")
-			},
-			{
-				"page":"permission-manager",
-				label: wn._("Permission Manager"),
-				"description": wn._("Set permissions on transactions / masters")
-			},
-			{
-				"page":"user-properties",
-				label: wn._("User Properties"),
-				"description":wn._("Set default values for users (also used for permissions).")
-			},
-			{
-				"doctype":"Workflow",
-				label:wn._("Workflow"),
-				"description":wn._("Set workflow rules.")
-			},
-			{
-				"doctype":"Authorization Rule",
-				label:wn._("Authorization Rule"),
-				"description":wn._("Restrict submission rights based on amount")
-			},
-		]
-	},
-	{
-		title: wn._("Data"),
-		icon: "icon-table",
-		items: [
-			{
-				"page":"data-import-tool",
-				label: wn._("Data Import"),
-				"description":wn._("Import data from spreadsheet (csv) files")
-			},
-			{
-				"route":"Form/Global Defaults",
-				doctype: "Global Defaults",
-				label: wn._("Global Defaults"),
-				"description":wn._("Set default values for entry"),
-			},
-			{
-				"route":"Form/Naming Series/Naming Series",
-				doctype: "Naming Series",
-				label: wn._("Manage Numbering Series"),
-				"description":wn._("Set multiple numbering series for transactions")
-			},
-			{
-				"route":"Form/Rename Tool",
-				doctype: "Rename Tool",
-				label: wn._("Rename Tool"),
-				"description":wn._("Rename multiple items in one go")
-			},
-			{
-				"route":"List/File Data",
-				doctype: "File Data",
-				label: wn._("File Manager"),
-				"description":wn._("List, delete uploaded files.")
-			},
-		]
-	},
-	{
-		title: wn._("Branding and Printing"),
-		icon: "icon-print",
-		right: true,
-		items: [
-			{
-				"doctype":"Letter Head",
-				label:wn._("Letter Head"),
-				"description":wn._("Letter heads for print")
-			},
-			{
-				"doctype":"Print Format",
-				label:wn._("Print Format"),
-				"description":wn._("HTML print formats for quotes, invoices etc")
-			},
-			{
-				"doctype":"Print Heading",
-				label:wn._("Print Heading"),
-				"description":wn._("Add headers for standard print formats")
-			},
-		]
-	},
-	{
-		title: wn._("Email Settings"),
-		icon: "icon-envelope",
-		items: [
-			{
-				"route":"Form/Email Settings/Email Settings",
-				doctype:"Email Settings",
-				label: wn._("Email Settings"),
-				"description":wn._("Out going mail server and support ticket mailbox")
-			},
-			{
-				"route":"Form/Sales Email Settings",
-				doctype:"Sales Email Settings",
-				label: wn._("Sales Email Settings"),
-				"description":wn._("Extract Leads from sales email id e.g. sales@example.com")
-			},
-			{
-				"route":"Form/Jobs Email Settings",
-				doctype:"Jobs Email Settings",
-				label: wn._("Jobs Email Settings"),
-				"description":wn._("Extract Job Applicant from jobs email id e.g. jobs@example.com")
-			},
-			{
-				"route":"Form/Notification Control/Notification Control",
-				doctype:"Notification Control",
-				label: wn._("Notification Control"),
-				"description":wn._("Prompt email sending to customers and suppliers"),
-			},
-			{
-				"doctype":"Email Digest",
-				label: wn._("Email Digest"),
-				"description":wn._("Daily, weekly, monthly email Digests")
-			},
-			{
-				"route":"Form/SMS Settings/SMS Settings",
-				doctype:"SMS Settings",
-				label: wn._("SMS Settings"),
-				"description":wn._("Setup outgoing SMS via your bulk SMS provider")
-			},
-			{
-				"route":"Form/SMS Center/SMS Center",
-				doctype:"SMS Center",
-				label: wn._("SMS Center"),
-				"description":wn._("Send bulk SMS to leads, customers, contacts")
-			},
-		]
-	},
-	{
-		title: wn._("Customize"),
-		icon: "icon-wrench",
-		items: [			
-			{
-				"route":"Form/Customize Form/Customize Form",
-				doctype:"Customize Form",
-				label: wn._("Customize Form"),
-				"description":wn._("Change entry properties (hide fields, make mandatory etc)")
-			},
-			{
-				"doctype":"Custom Field",
-				label: wn._("Custom Field"),
-				"description":wn._("Add fields to forms")
-			},
-			{
-				"doctype":"Custom Script",
-				label: wn._("Custom Script"),
-				"description":wn._("Add custom code to forms")
-			},
-			{
-				"route":"Form/Features Setup/Features Setup",
-				"description":wn._("Simplify entry forms by disabling features"),
-				doctype:"Features Setup",
-				label: wn._("Features Setup"),
-			},
-			{
-				"page":"modules_setup",
-				label: wn._("Show / Hide Modules"),
-				"description":wn._("Show, hide modules")
-			},
-		]
-	},
-	{
-		title: wn._("Administration"),
-		icon: "icon-rocket",
-		right: true,
-		items: [
-			{
-				"page":"update-manager",
-				label: wn._("Update This Application"),
-				"description":wn._("Apply latest updates and patches to this app")
-			},
-			{
-				"route":"Form/Backup Manager",
-				doctype:"Backup Manager",
-				label: wn._("Backup Manager"),
-				"description":wn._("Sync backups with remote tools like Dropbox etc.")
-			},
-			{
-				"route":"List/Scheduler Log",
-				doctype:"Scheduler Log",
-				label: wn._("Scheduler Error Log"),
-				"description":wn._("Get a list of errors encountered by the Scheduler")
-			},
-		]
-	},
-]
+	wrapper.appframe.add_module_icon("Setup");
+	
+	var body = $(wrapper).find(".layout-main"),
+		total = 0,
+		completed = 0;
 
-pscript['onload_Setup'] = function(wrapper) {
-	wn.views.moduleview.make(wrapper, "Setup");
-	if(wn.boot.expires_on) {
-		$(wrapper).find(".main-section")
-			.prepend("<div class='alert'>Your ERPNext account will expire on "
-				+ wn.datetime.global_date_format(wn.boot.expires_on) + "</div>");
+	body.html('<div class="progress progress-striped active">\
+		<div class="progress-bar" style="width: 100%;"></div></div>')
+
+	wn.call({
+		method: "setup.page.setup.setup.get",
+		callback: function(r) {
+			if(r.message) {
+				body.empty();
+				if(wn.boot.expires_on) {
+					$(body).prepend("<div class='text-muted' style='text-align:right'>Account expires on "
+							+ wn.datetime.global_date_format(wn.boot.expires_on) + "</div>");
+				}
+
+				$completed = $('<h4>Setup Completed <span class="completed-percent"></span><h4>\
+					<div class="progress"><div class="progress-bar"></div></div>')
+					.appendTo(body);
+
+				$.each(r.message, function(i, item) {
+					render_item(item)
+				});
+				
+				var completed_percent = cint(flt(completed) / total * 100) + "%";
+				$completed
+					.find(".progress-bar")
+					.css({"width": completed_percent});
+				$(body)
+					.find(".completed-percent")
+					.html("(" + completed_percent + ")");
+			}
+		}
+	});
+	
+	var render_item = function(item, dependency) {		
+		if(item.type==="Section") {
+			$("<h3>")
+				.css({"margin": "20px 0px 15px 0px"})
+				.html('<i class="'+item.icon+'"></i> ' + item.title).appendTo(body);
+			return;
+		}
+		var row = $('<div class="row">')
+			.css({
+				"margin-bottom": "7px",
+				"padding-bottom": "7px",
+				"border-bottom": "1px solid #eee"
+			})
+			.appendTo(body);
+
+		$('<div class="col col-lg-1"></div>').appendTo(row);
+			
+		if(item.type==="Link") {
+			var col = $('<div class="col col-lg-5"><b><a href="#'
+				+item.route+'"><i class="'+item.icon+'"></i> '
+				+item.title+'</a></b></div>').appendTo(row);
+			
+		} else {
+			var col = $('<div class="col col-lg-5">\
+					<span class="badge">'+ item.count +'</span>'+
+					' <b>' + (item.title || item.doctype) + '</b>'
+					+'</div>')
+				.appendTo(row);
+
+			col.find(".badge")
+				.css({
+					"background-color": (item.count ? "green" : "orange"),
+					"display": "inline-block",
+					"min-width": "40px"
+				});
+
+			total += 1;
+			if(item.count)
+				completed += 1;
+		}
+
+		if(dependency) 
+			col.addClass("col-offset-1");
+		else
+			$('<div class="col col-lg-1"></div>').appendTo(row);
+			
+		if(item.doctype) {
+			col.find(".badge")
+				.attr("data-doctype", item.doctype)
+				.css({"cursor": "pointer"})
+				.click(function() {
+					wn.set_route(item.tree || "List", $(this).attr("data-doctype"))
+				})
+		}
+		
+		// tree
+		$links = $('<div class="col col-lg-5">').appendTo(row);
+		
+		if(item.tree) {
+			$('<a class="view-link"><i class="icon-sitemap"></i> Browse</a>\
+				<span class="text-muted">|</span> \
+				<a class="import-link"><i class="icon-upload"></i> Import</a>')
+				.appendTo($links)
+
+			$links.find(".view-link")
+				.attr("data-doctype", item.doctype)
+				.click(function() {
+					wn.set_route(item.tree, item.doctype);
+				})
+		} else if(item.single) {
+			$('<a class="view-link"><i class="icon-edit"></i> Edit</a>')
+				.appendTo($links)
+
+			$links.find(".view-link")
+				.attr("data-doctype", item.doctype)
+				.click(function() {
+					wn.set_route("Form", $(this).attr("data-doctype"));
+				})
+		} else if(item.type !== "Link"){
+			$('<a class="new-link"><i class="icon-plus"></i> New</a> \
+				<span class="text-muted">|</span> \
+				<a class="view-link"><i class="icon-list"></i> View</a> \
+				<span class="text-muted">|</span> \
+				<a class="import-link"><i class="icon-upload"></i> Import</a>')
+				.appendTo($links)
+
+			$links.find(".view-link")
+				.attr("data-doctype", item.doctype)
+				.click(function() {
+					if($(this).attr("data-filter")) {
+						wn.route_options = JSON.parse($(this).attr("data-filter"));
+					}
+					wn.set_route("List", $(this).attr("data-doctype"));
+				})
+
+			if(item.filter)
+				$links.find(".view-link").attr("data-filter", JSON.stringify(item.filter))
+
+			if(wn.model.can_create(item.doctype)) {
+				$links.find(".new-link")
+					.attr("data-doctype", item.doctype)
+					.click(function() {
+						new_doc($(this).attr("data-doctype"))
+					})
+			} else {
+				$links.find(".new-link").remove();
+				$links.find(".text-muted:first").remove();
+			}
+
+		}
+
+		$links.find(".import-link")
+			.attr("data-doctype", item.doctype)
+			.click(function() {
+				wn.route_options = {doctype:$(this).attr("data-doctype")}
+				wn.set_route("data-import-tool");
+			})
+			
+		if(item.links) {
+			$.each(item.links, function(i, link) {
+				var newlinks = $('<span class="text-muted"> |</span> \
+				<a class="import-link" href="#'+link.route
+					+'"><i class="'+link.icon+'"></i> '+link.title+'</a>')
+					.appendTo($links)
+			})
+		}
+			
+		if(item.dependencies) {
+			$.each(item.dependencies, function(i, d) {
+				render_item(d, true);
+			})
+		}
 	}
 }
\ No newline at end of file
diff --git a/setup/page/setup/setup.py b/setup/page/setup/setup.py
new file mode 100644
index 0000000..10fc2a4
--- /dev/null
+++ b/setup/page/setup/setup.py
@@ -0,0 +1,251 @@
+from __future__ import unicode_literals
+import webnotes
+
+items = [
+	{
+		"type": "Section",
+		"title": "Organization",
+		"icon": "icon-building"
+	},
+	{"doctype":"Company"}, 
+	{"doctype":"Fiscal Year"}, 
+	{"doctype":"Currency"}, 
+	{
+		"type": "Section",
+		"title": "Users and Permissions",
+		"icon": "icon-user"
+	},
+	{ 
+		"doctype":"Profile",
+	}, 
+	{ 
+		"doctype":"Role",
+	}, 
+	{ "title": "Permission Manager", 
+		"route": "permission-manager", "type": "Link", "icon": "icon-shield" },
+	{ "title": "User Properties", 
+		"route": "user-properties", "type": "Link", "icon": "icon-user" },
+	{
+		"type": "Section",
+		"title": "Master Data",
+		"icon": "icon-star"
+	},
+	{
+		"doctype": "Item",
+		"dependencies": [
+			{"doctype":"Item Group", "tree": "Sales Browser"}, 
+			{"doctype":"Warehouse"}, 
+			{"doctype":"UOM"}, 
+			{"doctype":"Brand"},
+			{"doctype":"Price List"}, 
+			{ "title": "Stock Settings", 
+				"route": "Form/Stock Settings", "type": "Link", "icon": "icon-cog" },
+		],
+	},
+	{
+		"doctype": "Customer",
+		"dependencies": [
+			{"doctype":"Customer Group", "tree": "Sales Browser"}, 
+			{"doctype":"Territory", "tree": "Sales Browser"}, 
+			{"doctype":"Sales Person", "tree": "Sales Browser"}, 
+			{"doctype":"Contact"}, 
+			{"doctype":"Address"}, 
+			{ "title": "Selling Settings", 
+				"route": "Form/Selling Settings", "type": "Link", "icon": "icon-cog" },
+		]
+	},
+	{
+		"doctype": "Supplier",
+		"dependencies": [
+			{"doctype":"Supplier Type"}, 
+			{"doctype":"Contact"}, 
+			{"doctype":"Address"}, 
+			{ "title": "Buying Settings", 
+				"route": "Form/Buying Settings", "type": "Link", "icon": "icon-cog" },
+		]
+	},
+	{
+		"type": "Section",
+		"title": "Accounts",
+		"icon": "icon-money"
+	},
+	{
+		"doctype": "Account",
+		"tree": "Accounts Browser",
+		"dependencies": [
+			{
+				"title": "Bank Accounts",
+				"doctype":"Account",
+				"filter": {"account_type": "Bank or Cash"}
+			}, 
+			{
+				"title": "Tax Accounts",
+				"doctype":"Account",
+				"filter": {"account_type": "Tax"}
+			},
+		]
+	},
+	{ 
+		"doctype": "Cost Center",
+		"tree": "Accounts Browser",
+	},
+	{ "doctype": "Sales Taxes and Charges Master" },
+	{ "doctype": "Purchase Taxes and Charges Master" },
+	{
+		"type": "Section",
+		"title": "Human Resource",
+		"icon": "icon-group"
+	},
+	{ 
+		"doctype": "Employee",
+		"dependencies": [
+			{ "doctype": "Employment Type" },
+			{ "doctype": "Branch" },
+			{ "doctype": "Department" },
+			{ "doctype": "Designation" },
+			{ "doctype": "Holiday List" },
+			{ "doctype": "Grade" },
+		]
+	 },
+	{ "doctype": "Salary Structure" },
+	{ "doctype": "Leave Allocation" },
+	{ "doctype": "Appraisal Template" },
+	{
+		"type": "Section",
+		"title": "Printing",
+		"icon": "icon-print"
+	},
+	{ "doctype": "Terms and Conditions" },
+	{ "doctype": "Letter Head" },
+	{ "doctype": "Print Heading" },
+	{ "doctype": "Print Format", "filter": {"standard": "No"} },
+	{
+		"type": "Section",
+		"title": "Email",
+		"icon": "icon-envelope-alt"
+	},
+	{ 
+		"title": "Outgoing Email Settings",
+		"doctype": "Email Settings",
+		"single": 1,
+		"query": "select count(*) from tabSingles where doctype='Email Settings' and field='outgoing_mail_server'"
+	},
+	{ 
+		"doctype": "Support Email Settings",
+		"single": 1,
+		"query": "select count(*) from tabSingles where doctype='Email Settings' and field='support_host'"
+	},
+	{ 
+		"doctype": "Sales Email Settings",
+		"single": 1,
+		"query": "select count(*) from tabSingles where doctype='Sales Email Settings' and field='host'"
+	},
+	{ 
+		"doctype": "Jobs Email Settings",
+		"single": 1,
+		"query": "select count(*) from tabSingles where doctype='Jobs Email Settings' and field='host'"
+	},
+	{ 
+		"doctype": "Email Digest",
+	},
+	{
+		"type": "Section",
+		"title": "Opening Accounts and Stock",
+		"icon": "icon-eye-open"
+	},
+	{ "doctype": "Stock Reconciliation" },
+	{ 
+		"doctype": "Journal Voucher",
+		"title": "Opening Accounting Entries",
+		"filter": {
+			"is_opening": "Yes"
+		}
+	},
+	{
+		"type": "Section",
+		"title": "Customization",
+		"icon": "icon-glass"
+	},
+	{ 
+		"doctype": "Customize Form",
+		"single": 1,
+		"query": "select count(distinct doc_type) from `tabProperty Setter`"
+	},
+	{ "doctype": "Workflow" },
+	{ "doctype": "Authorization Rule" },
+	{ "doctype": "Custom Field" },
+	{ "doctype": "Custom Script" },
+	{
+		"type": "Section",
+		"title": "Tools",
+		"icon": "icon-wrench"
+	},
+	{ "title": "Global Settings / Default Values", 
+		"doctype": "Global Defaults", "single": 1,
+	 	"query": """select count(*) from tabSingles where doctype='Global Defaults' 
+		and field not in ('owner', 'creation', 'modified', 'modified_by')"""},
+		
+	{ "title": "Show / Hide Features", 
+		"doctype": "Features Setup", "single": 1,
+	 	"query": """select count(*) from tabSingles where doctype='Features Setup' 
+		and field not in ('owner', 'creation', 'modified', 'modified_by')"""},
+
+	{ "title": "Enable / Disable Email Notifications", 
+		"doctype": "Notification Control", "single": 1,
+	 	"query": """select count(*) from tabSingles where doctype='Notification Control' 
+		and field in ('quotation', 'sales_order', 'sales_invoice', 'purchase_order', 'purchase_receipt', 'expense_claim', 'delivery_note')"""},
+
+	{ "doctype": "File Data", "title": "Uploaded File Attachments" },
+	{ 
+		"doctype": "SMS Settings", 
+		"single": 1,
+	 	"query": "select count(*) from tabSingles where doctype='SMS Settings' and field='sms_gateway_url'"
+	},
+
+	{ "title": "Data Import", 
+		"route": "data-import-tool", "type": "Link", "icon": "icon-upload" },
+	{ "title": "Bulk Rename", 
+		"route": "Form/Rename Tool", "type": "Link", "icon": "icon-upload" },
+	{ "title": "Update Numbering Series", 
+		"route": "Form/Naming Series", "type": "Link", "icon": "icon-sort-by-order" },
+	{ "title": "Show / Hide Modules", 
+		"route": "modules_setup", "type": "Link", "icon": "icon-th" },
+	{ "title": "Send Bulk SMS to Leads / Contacts", 
+		"route": "Form/SMS Center", "type": "Link", "icon": "icon-mobile-phone" },
+	{
+		"type": "Section",
+		"title": "System Administration",
+		"icon": "icon-cog"
+	},
+	{ "title": "Update ERPNext", 
+		"route": "update-manager", "type": "Link", "icon": "icon-rss" },
+	{ "title": "Manage 3rd Party Backups", 
+		"route": "Form/Backup Manager", "type": "Link", "icon": "icon-cloud" },
+	{ "title": "System Scheduler Errors", 
+		"route": "Report/Scheduler Log", "type": "Link", "icon": "icon-exclamation-sign" },
+]
+
+@webnotes.whitelist(allow_roles=["System Manager"])
+def get():
+	for item in items:
+		if item.get("type")=="Section":
+			continue
+		set_count(item)
+		
+		if item.get("dependencies"):
+			for d in item["dependencies"]:
+				set_count(d)
+		
+	return items
+	
+def set_count(item):
+	if "query" in item:
+		item["count"] = webnotes.conn.sql(item["query"])[0][0]
+	elif "filter" in item:
+		key = item["filter"].keys()[0]
+		item["count"] = webnotes.conn.sql("""select count(*) from `tab%s` where
+			%s = %s""" % (item["doctype"], key, "%s"),
+			item["filter"][key])[0][0]
+	elif "doctype" in item:
+		item["count"] = webnotes.conn.sql("select count(*) from `tab%s`" \
+			% item["doctype"])[0][0]
diff --git a/startup/boot.py b/startup/boot.py
index 7d5eb4e..a75c78a 100644
--- a/startup/boot.py
+++ b/startup/boot.py
@@ -22,8 +22,12 @@
 			"Notification Control").get_values()
 				
 		# if no company, show a dialog box to create a new company
-		bootinfo['setup_complete'] = webnotes.conn.sql("""select name from 
-			tabCompany limit 1""") and 'Yes' or 'No'
+		bootinfo["customer_count"] = webnotes.conn.sql("""select count(*) from tabCustomer""")[0][0]
+
+		if not bootinfo["customer_count"]:
+			bootinfo['setup_complete'] = webnotes.conn.sql("""select name from 
+				tabCompany limit 1""") and 'Yes' or 'No'
+		
 		
 		# load subscription info
 		import conf
diff --git a/startup/install.py b/startup/install.py
index 205bee4..89ab290 100644
--- a/startup/install.py
+++ b/startup/install.py
@@ -135,13 +135,7 @@
 			
 		# supplier type
 		{'doctype': 'Supplier Type', 'name': 'Default Supplier Type', 'supplier_type': 'Default Supplier Type'},
-		
-		# Price List
-		{'doctype': 'Price List', 'name': 'Default Price List', 'price_list_name': 'Default Price List',
-			"buying_or_selling": "Selling"},
-		{'doctype': 'Price List', 'name': 'Standard', 'price_list_name': 'Standard',
-			"buying_or_selling": "Selling"},
-				
+
 		# warehouse type
 		{'doctype': 'Warehouse Type', 'name': 'Default Warehouse Type', 'warehouse_type': 'Default Warehouse Type'},
 		{'doctype': 'Warehouse Type', 'name': 'Fixed Asset', 'warehouse_type': 'Fixed Asset'},
diff --git a/stock/doctype/delivery_note/delivery_note.txt b/stock/doctype/delivery_note/delivery_note.txt
index 74a21b3..20e2196 100644
--- a/stock/doctype/delivery_note/delivery_note.txt
+++ b/stock/doctype/delivery_note/delivery_note.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-05-24 19:29:09", 
   "docstatus": 0, 
-  "modified": "2013-06-05 19:22:52", 
+  "modified": "2013-06-27 11:33:53", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -449,7 +449,7 @@
   "doctype": "DocField", 
   "fieldname": "charge", 
   "fieldtype": "Link", 
-  "label": "Taxes and Charges", 
+  "label": "Apply Taxes and Charges Master", 
   "oldfieldname": "charge", 
   "oldfieldtype": "Link", 
   "options": "Sales Taxes and Charges Master", 
@@ -463,10 +463,11 @@
  }, 
  {
   "doctype": "DocField", 
-  "fieldname": "get_charges", 
-  "fieldtype": "Button", 
-  "label": "Get Taxes and Charges", 
+  "fieldname": "shipping_rule", 
+  "fieldtype": "Link", 
+  "label": "Apply Shipping Rule", 
   "oldfieldtype": "Button", 
+  "options": "Shipping Rule", 
   "print_hide": 1, 
   "read_only": 0
  }, 
diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py
index 276f660..d6c1f52 100644
--- a/stock/doctype/item/item.py
+++ b/stock/doctype/item/item.py
@@ -32,7 +32,7 @@
 			from webnotes.model.doc import make_autoname
 			self.doc.item_code = make_autoname(self.doc.naming_series+'.#####')
 		elif not self.doc.item_code:
-			msgprint(_("Item Code is mandatory"), raise_exception=1)
+			msgprint(_("Item Code (item_code) is mandatory because Item naming is not sequential."), raise_exception=1)
 			
 		self.doc.name = self.doc.item_code
 			
@@ -290,4 +290,4 @@
 			from stock.stock_ledger import update_entries_after
 			for wh in webnotes.conn.sql("""select warehouse from `tabBin` 
 				where item_code=%s""", newdn):
-					update_entries_after({"item_code": newdn, "warehouse": wh})
\ No newline at end of file
+					update_entries_after({"item_code": newdn, "warehouse": wh})
diff --git a/stock/doctype/item/item.txt b/stock/doctype/item/item.txt
index e23bbe0..1273b12 100644
--- a/stock/doctype/item/item.txt
+++ b/stock/doctype/item/item.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-05-03 10:45:46", 
   "docstatus": 0, 
-  "modified": "2013-06-13 16:17:42", 
+  "modified": "2013-06-26 21:39:46", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -838,6 +838,7 @@
   "read_only": 0
  }, 
  {
+  "depends_on": "show_in_website", 
   "doctype": "DocField", 
   "fieldname": "copy_from_item_group", 
   "fieldtype": "Button", 
diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 3cde2e2..3492931 100644
--- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -119,4 +119,13 @@
 	def scrub_posting_time(self):
 		if not self.doc.posting_time or self.doc.posting_time == '00:0':
 			self.doc.posting_time = '00:00'
-			
\ No newline at end of file
+			
+	def on_doctype_update(self):
+		webnotes.msgprint(webnotes.conn.sql("""show index from `tabStock Ledger Entry` 
+			where Key_name="posting_sort_index" """))
+		if not webnotes.conn.sql("""show index from `tabStock Ledger Entry` 
+			where Key_name="posting_sort_index" """):
+			webnotes.conn.commit()
+			webnotes.conn.sql("""alter table `tabStock Ledger Entry` 
+				add index posting_sort_index(posting_date, posting_time, name)""")
+			webnotes.conn.begin()
\ No newline at end of file
diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt b/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt
index 6bcd758..674104d 100644
--- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt
+++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-01-29 19:25:42", 
   "docstatus": 0, 
-  "modified": "2013-03-25 16:04:59", 
+  "modified": "2013-06-28 12:39:07", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.py b/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 49e8b15..8e5698c 100644
--- a/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -45,9 +45,12 @@
 			return
 			
 		data = json.loads(self.doc.reconciliation_json)
+		
+		# strip out extra columns (if any)
+		data = [row[:4] for row in data]
+		
 		if self.head_row not in data:
-			msgprint(_("""Hey! You seem to be using the wrong template. \
-				Click on 'Download Template' button to get the correct template."""),
+			msgprint(_("""Wrong Template: Unable to find head row."""),
 				raise_exception=1)
 		
 		# remove the help part and save the json
diff --git a/stock/doctype/warehouse/warehouse.py b/stock/doctype/warehouse/warehouse.py
index 6f32e15..7eb407c 100644
--- a/stock/doctype/warehouse/warehouse.py
+++ b/stock/doctype/warehouse/warehouse.py
@@ -42,7 +42,7 @@
 			bin_wrapper.ignore_permissions = 1
 			bin_wrapper.insert()
 			
-			bin_obj = bin_wrapper.make_obj()
+			bin_obj = bin_wrapper.make_controller()
 		else:
 			bin_obj = get_obj('Bin', bin)
 		return bin_obj
diff --git a/support/doctype/newsletter/newsletter.py b/support/doctype/newsletter/newsletter.py
index 78921f1..e654470 100644
--- a/support/doctype/newsletter/newsletter.py
+++ b/support/doctype/newsletter/newsletter.py
@@ -19,7 +19,6 @@
 import webnotes
 import webnotes.utils
 from webnotes.utils import cstr
-from webnotes.model.doc import Document
 from webnotes import _
 
 class DocType():
@@ -73,8 +72,7 @@
 		elif self.doc.email_list:
 			email_list = [cstr(email).strip() for email in self.doc.email_list.split(",")]
 			for email in email_list:
-				if not webnotes.conn.exists({"doctype": "Lead", "email_id": email}):
-					create_lead(email)
+				create_lead(email)
 					
 			self.send_to_doctype = "Lead"
 			return email_list
@@ -116,15 +114,20 @@
 	"""create a lead if it does not exist"""
 	from email.utils import parseaddr
 	real_name, email_id = parseaddr(email_id)
-	lead = Document("Lead")
-	lead.fields["__islocal"] = 1
-	lead.lead_name = real_name or email_id
-	lead.email_id = email_id
-	lead.status = "Contacted"
-	lead.naming_series = lead_naming_series or get_lead_naming_series()
-	lead.company = webnotes.conn.get_default("company")
-	lead.source = "Email"
-	lead.save()
+	
+	if webnotes.conn.get_value("Lead", {"email_id": email_id}):
+		return
+	
+	lead = webnotes.bean({
+		"doctype": "Lead",
+		"email_id": email_id,
+		"lead_name": real_name or email_id,
+		"status": "Contacted",
+		"naming_series": lead_naming_series or get_lead_naming_series(),
+		"company": webnotes.conn.get_default("company"),
+		"source": "Email"
+	})
+	lead.insert()
 	
 def get_lead_naming_series():
 	"""gets lead's default naming series"""
diff --git a/utilities/doctype/address/address.py b/utilities/doctype/address/address.py
index cfcbea5..c475da1 100644
--- a/utilities/doctype/address/address.py
+++ b/utilities/doctype/address/address.py
@@ -27,7 +27,7 @@
 
 	def autoname(self):
 		if not self.doc.address_title:
-			self.doc.address_title = self.doc.customer or self.doc.supplier or self.doc.sales_partner
+			self.doc.address_title = self.doc.customer or self.doc.supplier or self.doc.sales_partner or self.doc.lead
 			
 		if self.doc.address_title:
 			self.doc.name = cstr(self.doc.address_title).strip() + "-" + cstr(self.doc.address_type).strip()
@@ -35,40 +35,32 @@
 		else:
 			webnotes.msgprint("""Address Title is mandatory.""", raise_exception=True)
 		
-
 	def validate(self):
 		self.validate_primary_address()
 		self.validate_shipping_address()
 	
 	def validate_primary_address(self):
 		"""Validate that there can only be one primary address for particular customer, supplier"""
-		sql = webnotes.conn.sql
 		if self.doc.is_primary_address == 1:
-			if self.doc.customer: 
-				sql("update tabAddress set is_primary_address=0 where customer = '%s'" % (self.doc.customer))
-			elif self.doc.supplier:
-				sql("update tabAddress set is_primary_address=0 where supplier = '%s'" % (self.doc.supplier))
-			elif self.doc.sales_partner:
-				sql("update tabAddress set is_primary_address=0 where sales_partner = '%s'" % (self.doc.sales_partner))
-		elif not self.doc.is_shipping_address:
-			if self.doc.customer: 
-				if not sql("select name from tabAddress where is_primary_address=1 and customer = '%s'" % (self.doc.customer)):
-					self.doc.is_primary_address = 1
-			elif self.doc.supplier:
-				if not sql("select name from tabAddress where is_primary_address=1 and supplier = '%s'" % (self.doc.supplier)):
-					self.doc.is_primary_address = 1
-			elif self.doc.sales_partner:
-				if not sql("select name from tabAddress where is_primary_address=1 and sales_partner = '%s'" % (self.doc.sales_partner)):
-					self.doc.is_primary_address = 1
-
+			self._unset_other("is_primary_address")
+			
+		elif self.doc.is_shipping_address != 1:
+			for fieldname in ["customer", "supplier", "sales_partner", "lead"]:
+				if self.doc.fields.get(fieldname):
+					if not webnotes.conn.sql("""select name from `tabAddress` where is_primary_address=1
+						and `%s`=%s and name!=%s""" % (fieldname, "%s", "%s"), 
+						(self.doc.fields[fieldname], self.doc.name)):
+							self.doc.is_primary_address = 1
+					break
 				
 	def validate_shipping_address(self):
 		"""Validate that there can only be one shipping address for particular customer, supplier"""
-		sql = webnotes.conn.sql
 		if self.doc.is_shipping_address == 1:
-			if self.doc.customer: 
-				sql("update tabAddress set is_shipping_address=0 where customer = '%s'" % (self.doc.customer))
-			elif self.doc.supplier:
-				sql("update tabAddress set is_shipping_address=0 where supplier = '%s'" % (self.doc.supplier))			
-			elif self.doc.sales_partner:
-				sql("update tabAddress set is_shipping_address=0 where sales_partner = '%s'" % (self.doc.sales_partner))			
+			self._unset_other("is_shipping_address")
+			
+	def _unset_other(self, is_address_type):
+		for fieldname in ["customer", "supplier", "sales_partner", "lead"]:
+			if self.doc.fields.get(fieldname):
+				webnotes.conn.sql("""update `tabAddress` set `%s`=0 where `%s`=%s and name!=%s""" %
+					(is_address_type, fieldname, "%s", "%s"), (self.doc.fields[fieldname], self.doc.name))
+				break
\ No newline at end of file
diff --git a/utilities/doctype/address/address.txt b/utilities/doctype/address/address.txt
index 757beb9..ed39c75 100644
--- a/utilities/doctype/address/address.txt
+++ b/utilities/doctype/address/address.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-01-10 16:34:32", 
   "docstatus": 0, 
-  "modified": "2013-01-29 13:24:45", 
+  "modified": "2013-06-28 17:06:32", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -46,11 +46,11 @@
   "label": "Address Details"
  }, 
  {
-  "description": "e.g. Office, Billing, Shipping", 
   "doctype": "DocField", 
   "fieldname": "address_type", 
-  "fieldtype": "Data", 
+  "fieldtype": "Select", 
   "label": "Address Type", 
+  "options": "Billing\nShipping\nOffice\nPersonal\nPlant\nPostal\nShop\nSubsidiary\nWarehouse\nOther", 
   "reqd": 1
  }, 
  {
@@ -145,7 +145,7 @@
   "doctype": "DocField", 
   "fieldname": "is_primary_address", 
   "fieldtype": "Check", 
-  "label": "Is Primary Address"
+  "label": "Preferred Billing Address"
  }, 
  {
   "default": "0", 
@@ -154,7 +154,7 @@
   "fieldname": "is_shipping_address", 
   "fieldtype": "Check", 
   "in_list_view": 1, 
-  "label": "Is Shipping Address"
+  "label": "Preferred Shipping Address"
  }, 
  {
   "doctype": "DocField", 
@@ -208,6 +208,27 @@
   "options": "Sales Partner"
  }, 
  {
+  "doctype": "DocField", 
+  "fieldname": "column_break_22", 
+  "fieldtype": "Column Break"
+ }, 
+ {
+  "depends_on": "eval:!doc.supplier && !doc.sales_partner", 
+  "doctype": "DocField", 
+  "fieldname": "lead", 
+  "fieldtype": "Link", 
+  "label": "Lead", 
+  "options": "Lead"
+ }, 
+ {
+  "depends_on": "eval:!doc.supplier && !doc.sales_partner", 
+  "doctype": "DocField", 
+  "fieldname": "lead_name", 
+  "fieldtype": "Data", 
+  "label": "Lead Name", 
+  "read_only": 1
+ }, 
+ {
   "doctype": "DocPerm", 
   "role": "Sales User"
  }, 
diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py
index c86a50e..2def0ea 100644
--- a/utilities/transaction_base.py
+++ b/utilities/transaction_base.py
@@ -170,21 +170,30 @@
 		
 	# Get Lead Details
 	# -----------------------
-	def get_lead_details(self, name):		
-		details = webnotes.conn.sql("select name, lead_name, address_line1, address_line2, city, country, state, pincode, territory, phone, mobile_no, email_id, company_name from `tabLead` where name = '%s'" %(name), as_dict = 1)		
-		
-		extract = lambda x: details and details[0] and details[0].get(x,'') or ''
-		address_fields = [('','address_line1'),('\n','address_line2'),('\n','city'),(' ','pincode'),('\n','state'),('\n','country'),('\nPhone: ','contact_no')]
-		address_display = ''.join([a[0]+extract(a[1]) for a in address_fields if extract(a[1])])
-		if address_display.startswith('\n'): address_display = address_display[1:]
+	def get_lead_details(self, name):
+		details = webnotes.conn.sql("""select name, lead_name, address_line1, address_line2, city, country, state, pincode
+			from `tabAddress` where lead=%s""", name, as_dict=True)
+		lead = webnotes.conn.get_value("Lead", name, 
+			["territory", "phone", "mobile_no", "email_id", "company_name", "lead_name"], as_dict=True) or {}
+
+		address_display = ""
+		if details:
+			details = details[0]
+			for separator, fieldname in (('','address_line1'), ('\n','address_line2'), ('\n','city'), 
+				(' ','pincode'), ('\n','state'), ('\n','country'), ('\nPhone: ', 'phone')):
+					if details.get(fieldname):
+						address_display += separator + details.get(fieldname)
+
+		if address_display.startswith('\n'):
+			address_display = address_display[1:]
 		
 		ret = {
-			'contact_display' : extract('lead_name'),
+			'contact_display' : lead.get('lead_name'),
 			'address_display' : address_display,
-			'territory' : extract('territory'),
-			'contact_mobile' : extract('mobile_no'),
-			'contact_email' : extract('email_id'),
-			'customer_name' : extract('company_name') or extract('lead_name')
+			'territory' : lead.get('territory'),
+			'contact_mobile' : lead.get('mobile_no'),
+			'contact_email' : lead.get('email_id'),
+			'customer_name' : lead.get('company_name') or lead.get('lead_name')
 		}
 		return ret