Merge pull request #2413 from Delte/patch-1

Update tr.csv
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 9b473c1..09f303f 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -247,7 +247,7 @@
 	def update_item(obj, target, source_parent):
 		target.amount = flt(obj.amount) - flt(obj.billed_amt)
 		target.base_amount = target.amount * flt(source_parent.conversion_rate)
-		target.qty = target.amount / flt(obj.rate) if flt(obj.rate) else flt(obj.qty)
+		target.qty = target.amount / flt(obj.rate) if (flt(obj.rate) and flt(obj.billed_amt)) else flt(obj.qty)
 
 	doc = get_mapped_doc("Purchase Order", source_name,	{
 		"Purchase Order": {
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index 91ec813..97eef79 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -1,8 +1,6 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-{% include 'setup/doctype/contact_control/contact_control.js' %};
-
 cur_frm.cscript.refresh = function(doc, dt, dn) {
 	cur_frm.cscript.make_dashboard(doc);
 
@@ -17,9 +15,8 @@
 	}
 	else{
 	  	unhide_field(['address_html','contact_html']);
-		// make lists
-		cur_frm.cscript.make_address(doc,dt,dn);
-		cur_frm.cscript.make_contact(doc,dt,dn);
+
+		erpnext.utils.render_address_and_contact(cur_frm)
 
 		cur_frm.communication_view = new frappe.views.CommunicationList({
 			parent: cur_frm.fields_dict.communication_html.wrapper,
@@ -60,45 +57,6 @@
 	})
 }
 
-
-cur_frm.cscript.make_address = function() {
-	if(!cur_frm.address_list) {
-		cur_frm.address_list = new frappe.ui.Listing({
-			parent: cur_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 supplier='" +
-					cur_frm.doc.name.replace(/'/g, "\\'") + "' and docstatus != 2 order by is_primary_address desc"
-			},
-			as_dict: 1,
-			no_results_message: __('No addresses created'),
-			render_row: cur_frm.cscript.render_address_row,
-		});
-		// note: render_address_row is defined in contact_control.js
-	}
-	cur_frm.address_list.run();
-}
-
-cur_frm.cscript.make_contact = function() {
-	if(!cur_frm.contact_list) {
-		cur_frm.contact_list = new frappe.ui.Listing({
-			parent: cur_frm.fields_dict['contact_html'].wrapper,
-			page_length: 5,
-			new_doctype: "Contact",
-			get_query: function() {
-				return "select name, first_name, last_name, email_id, phone, mobile_no, department, designation, is_primary_contact from tabContact where supplier='" +
-					cur_frm.doc.name.replace(/'/g, "\\'") + "' and docstatus != 2 order by is_primary_contact desc"
-			},
-			as_dict: 1,
-			no_results_message: __('No contacts created'),
-			render_row: cur_frm.cscript.render_contact_row,
-		});
-		// note: render_contact_row is defined in contact_control.js
-	}
-	cur_frm.contact_list.run();
-}
-
 cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) {
 	return{
 		filters:{'buying': 1}
diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py
index 240762e..8a0af9c 100644
--- a/erpnext/buying/doctype/supplier/supplier.py
+++ b/erpnext/buying/doctype/supplier/supplier.py
@@ -9,10 +9,14 @@
 from frappe import msgprint, _
 from frappe.model.naming import make_autoname
 from erpnext.accounts.party import create_party_account
+from erpnext.utilities.address_and_contact import load_address_and_contact
 
 from erpnext.utilities.transaction_base import TransactionBase
 
 class Supplier(TransactionBase):
+	def onload(self):
+		"""Load address and contacts in `__onload`"""
+		load_address_and_contact(self, "supplier")
 
 	def autoname(self):
 		supp_master_name = frappe.defaults.get_global_default('supp_master_name')
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 7c905a6..f30fe02 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -156,7 +156,7 @@
 					/ cint(self.total_days_in_month), 2)
 			elif not self.payment_days:
 				d.e_modified_amount = 0
-			else:
+			elif not d.e_modified_amount:
 				d.e_modified_amount = d.e_amount
 			self.gross_pay += flt(d.e_modified_amount)
 
@@ -168,7 +168,7 @@
 					/ cint(self.total_days_in_month), 2)
 			elif not self.payment_days:
 				d.d_modified_amount = 0
-			else:
+			elif not d.d_modified_amount:
 				d.d_modified_amount = d.d_amount
 
 			self.total_deduction += flt(d.d_modified_amount)
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index d9a6b64..4c97581 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -88,3 +88,4 @@
 erpnext.patches.v4_2.recalculate_bom_cost
 erpnext.patches.v4_2.fix_gl_entries_for_stock_transactions
 erpnext.patches.v4_2.update_requested_and_ordered_qty
+execute:frappe.delete_doc("DocType", "Contact Control")
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 0998c53..ac77cfc 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -10,6 +10,8 @@
 		"public/js/feature_setup.js",
 		"public/js/utils.js",
 		"public/js/queries.js",
-		"public/js/utils/party.js"
+		"public/js/utils/party.js",
+		"public/js/templates/address_list.html",
+		"public/js/templates/contact_list.html"
 	]
 }
diff --git a/erpnext/public/js/templates/address_list.html b/erpnext/public/js/templates/address_list.html
new file mode 100644
index 0000000..e85723f
--- /dev/null
+++ b/erpnext/public/js/templates/address_list.html
@@ -0,0 +1,20 @@
+<p><button class="btn btn-sm btn-default btn-address">
+    <i class="icon-plus"></i> New Address</button></p>
+{% for(var i=0, l=addr_list.length; i<l; i++) { %}
+    <hr>
+    <a href="#Form/Address/{%= addr_list[i].name %}" class="btn btn-sm btn-default pull-right">
+        {%= __("Edit") %}</a>
+    <p><b>{%= i+1 %}. {%= addr_list[i].address_type %}</b></p>
+    <div style="padding-left: 15px;">
+        <div>
+            {% if(addr_list[i].is_primary_address) { %}<span class="label label-info">
+                {%= __("Primary") %}</span>{% } %}
+            {% if(addr_list[i].is_shipping_address) { %}<span class="label label-default">
+                {%= __("Shipping") %}</span>{% } %}
+        </div>
+        <p style="margin-top: 5px;">{%= addr_list[i].display %}</p>
+    </div>
+{% } %}
+{% if(!addr_list.length) { %}
+<p class="text-muted">{%= __("No address added yet.") %}</p>
+{% } %}
diff --git a/erpnext/public/js/templates/contact_list.html b/erpnext/public/js/templates/contact_list.html
new file mode 100644
index 0000000..c4c058c
--- /dev/null
+++ b/erpnext/public/js/templates/contact_list.html
@@ -0,0 +1,25 @@
+<p><button class="btn btn-sm btn-default btn-contact">
+    <i class="icon-plus"></i> New Contact</button></p>
+{% for(var i=0, l=contact_list.length; i<l; i++) { %}
+    <hr>
+    <a href="#Form/Contact/{%= contact_list[i].name %}" class="btn btn-sm btn-default pull-right">
+        {%= __("Edit") %}</a>
+    <p><b>{%= i+1 %}. {%= contact_list[i].first_name %} {%= contact_list[i].last_name %}</b></p>
+    <div style="padding-left: 15px;">
+        <div>
+            {% if(contact_list[i].is_primary_contact) { %}<span class="label label-info">
+                {%= __("Primary") %}</span>{% } %}
+        </div>
+        <p style="padding-top: 5px;">
+            {% if(contact_list[i].phone) { %}
+                {%= __("Phone") %}: {%= contact_list[i].phone %}<br>
+            {% } %}
+            {% if(contact_list[i].email_id) { %}
+                {%= __("Email Id") %}: {%= contact_list[i].email_id %}
+            {% } %}
+        </p>
+    </div>
+{% } %}
+{% if(!contact_list.length) { %}
+<p class="text-muted">{%= __("No contacts added yet.") %}</p>
+{% } %}
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index ef7d03e..6a96fac 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -81,5 +81,28 @@
 
 			d.show();
 		});
-	}
+	},
 });
+
+erpnext.utils = {
+	render_address_and_contact: function(frm) {
+		// render address
+		$(frm.fields_dict['address_html'].wrapper)
+			.html(frappe.render(frappe.templates.address_list,
+				cur_frm.doc.__onload))
+			.find(".btn-address").on("click", function() {
+				new_doc("Address");
+			});
+
+		// render contact
+		if(frm.fields_dict['contact_html']) {
+			$(frm.fields_dict['contact_html'].wrapper)
+				.html(frappe.render(frappe.templates.contact_list,
+					cur_frm.doc.__onload))
+				.find(".btn-contact").on("click", function() {
+					new_doc("Contact");
+				}
+			);
+		}
+	}
+}
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index e5d2ca9..afde2b0 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -1,8 +1,6 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-{% include 'setup/doctype/contact_control/contact_control.js' %};
-
 cur_frm.cscript.onload = function(doc, dt, dn) {
 	cur_frm.cscript.load_defaults(doc, dt, dn);
 }
@@ -32,8 +30,8 @@
 	}else{
 		unhide_field(['address_html','contact_html']);
 		// make lists
-		cur_frm.cscript.make_address(doc, dt, dn);
-		cur_frm.cscript.make_contact(doc, dt, dn);
+
+		erpnext.utils.render_address_and_contact(cur_frm)
 
 		cur_frm.communication_view = new frappe.views.CommunicationList({
 			parent: cur_frm.fields_dict.communication_html.wrapper,
@@ -79,44 +77,6 @@
 	});
 }
 
-cur_frm.cscript.make_address = function() {
-	if(!cur_frm.address_list) {
-		cur_frm.address_list = new frappe.ui.Listing({
-			parent: cur_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 customer='" +
-					cur_frm.doc.name.replace(/'/g, "\\'") + "' and docstatus != 2 order by is_primary_address desc"
-			},
-			as_dict: 1,
-			no_results_message: __('No addresses created'),
-			render_row: cur_frm.cscript.render_address_row,
-		});
-		// note: render_address_row is defined in contact_control.js
-	}
-	cur_frm.address_list.run();
-}
-
-cur_frm.cscript.make_contact = function() {
-	if(!cur_frm.contact_list) {
-		cur_frm.contact_list = new frappe.ui.Listing({
-			parent: cur_frm.fields_dict['contact_html'].wrapper,
-			page_length: 5,
-			new_doctype: "Contact",
-			get_query: function() {
-				return "select name, first_name, last_name, email_id, phone, mobile_no, department, designation, is_primary_contact from tabContact where customer='" +
-					cur_frm.doc.name.replace(/'/g, "\\'") + "' and docstatus != 2 order by is_primary_contact desc"
-			},
-			as_dict: 1,
-			no_results_message: __('No contacts created'),
-			render_row: cur_frm.cscript.render_contact_row,
-		});
-		// note: render_contact_row is defined in contact_control.js
-	}
-	cur_frm.contact_list.run();
-}
-
 cur_frm.fields_dict['customer_group'].get_query = function(doc, dt, dn) {
 	return{
 		filters:{'is_group': 'No'}
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 362542e..36af1f5 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -7,11 +7,14 @@
 from frappe import msgprint, _
 import frappe.defaults
 
-
 from erpnext.utilities.transaction_base import TransactionBase
+from erpnext.utilities.address_and_contact import load_address_and_contact
 from erpnext.accounts.party import create_party_account
 
 class Customer(TransactionBase):
+	def onload(self):
+		"""Load address and contacts in `__onload`"""
+		load_address_and_contact(self, "customer")
 
 	def autoname(self):
 		cust_master_name = frappe.defaults.get_global_default('cust_master_name')
diff --git a/erpnext/selling/doctype/lead/lead.js b/erpnext/selling/doctype/lead/lead.js
index ca6d007..c51892e 100644
--- a/erpnext/selling/doctype/lead/lead.js
+++ b/erpnext/selling/doctype/lead/lead.js
@@ -1,8 +1,6 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-{% include 'setup/doctype/contact_control/contact_control.js' %};
-
 frappe.provide("erpnext");
 erpnext.LeadController = frappe.ui.form.Controller.extend({
 	setup: function() {
@@ -42,33 +40,10 @@
 		});
 
 		if(!this.frm.doc.__islocal) {
-			this.make_address_list();
+			erpnext.utils.render_address_and_contact(cur_frm);
 		}
 	},
 
-	make_address_list: function() {
-		var me = this;
-		if(!this.frm.address_list) {
-			this.frm.address_list = new frappe.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();
-	},
-
 	create_customer: function() {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.selling.doctype.lead.lead.make_customer",
diff --git a/erpnext/selling/doctype/lead/lead.py b/erpnext/selling/doctype/lead/lead.py
index 3c345ef..98bed4d 100644
--- a/erpnext/selling/doctype/lead/lead.py
+++ b/erpnext/selling/doctype/lead/lead.py
@@ -9,11 +9,13 @@
 from frappe.model.mapper import get_mapped_doc
 
 from erpnext.controllers.selling_controller import SellingController
+from erpnext.utilities.address_and_contact import load_address_and_contact
 
 class Lead(SellingController):
 	def onload(self):
 		customer = frappe.db.get_value("Customer", {"lead_name": self.name})
 		self.get("__onload").is_customer = customer
+		load_address_and_contact(self, "lead")
 
 	def validate(self):
 		self._prev = frappe._dict({
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index bffa581..498aec1 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -329,7 +329,7 @@
 	def update_item(source, target, source_parent):
 		target.amount = flt(source.amount) - flt(source.billed_amt)
 		target.base_amount = target.amount * flt(source_parent.conversion_rate)
-		target.qty = source.rate and target.amount / flt(source.rate) or source.qty
+		target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty
 
 	doclist = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
diff --git a/erpnext/setup/doctype/contact_control/README.md b/erpnext/setup/doctype/contact_control/README.md
deleted file mode 100644
index ca98eff..0000000
--- a/erpnext/setup/doctype/contact_control/README.md
+++ /dev/null
@@ -1 +0,0 @@
-[To deprecate] Common scripts for Contacts.
\ No newline at end of file
diff --git a/erpnext/setup/doctype/contact_control/__init__.py b/erpnext/setup/doctype/contact_control/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/setup/doctype/contact_control/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/setup/doctype/contact_control/contact_control.js b/erpnext/setup/doctype/contact_control/contact_control.js
deleted file mode 100755
index 0ca59fc..0000000
--- a/erpnext/setup/doctype/contact_control/contact_control.js
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-if(cur_frm.fields_dict['territory']) {
-	cur_frm.fields_dict['territory'].get_query = function(doc, dt, dn) {
-		return {
-			filters: {
-				'is_group': "No"
-			}
-		}
-	}
-}
-
-cur_frm.cscript.render_contact_row = function(wrapper, data) {
-	// prepare data
-	data.fullname = (data.first_name || '')
-		+ (data.last_name ? ' ' + data.last_name : '');
-	data.primary = data.is_primary_contact ? ' [Primary]' : '';
-
-	// prepare description
-	var description = [];
-	$.each([
-		['phone', 'Tel'],
-		['mobile_no', 'Mobile'],
-		['email_id', 'Email'],
-		['department', 'Department'],
-		['designation', 'Designation']],
-		function(i, v) {
-			if(v[0] && data[v[0]]) {
-				description.push(repl('<h6>%(label)s:</h6> %(value)s', {
-					label: v[1],
-					value: data[v[0]],
-				}));
-			}
-		});
-	data.description = description.join('<br />');
-
-	cur_frm.cscript.render_row_in_wrapper(wrapper, data, 'Contact');
-}
-
-cur_frm.cscript.render_address_row = function(wrapper, data) {
-	// prepare data
-	data.fullname = data.address_type;
-	data.primary = '';
-	if (data.is_primary_address) data.primary += ' [Preferred for Billing]';
-	if (data.is_shipping_address) data.primary += ' [Preferred for Shipping]';
-
-	// prepare address
-	var address = [];
-	$.each(['address_line1', 'address_line2', 'city', 'state', 'country', 'pincode'],
-		function(i, v) {
-			if(data[v]) address.push(data[v]);
-		});
-
-	data.address = address.join('<br />');
-	data.address = "<p class='address-list'>" + data.address + "</p>";
-
-	// prepare description
-	var description = [];
-	$.each([
-		['address', 'Address'],
-		['phone', 'Tel'],
-		['fax', 'Fax'],
-		['email_id', 'Email']],
-		function(i, v) {
-			if(data[v[0]]) {
-				description.push(repl('<h6>%(label)s:</h6> %(value)s', {
-					label: v[1],
-					value: data[v[0]],
-				}));
-			}
-		});
-	data.description = description.join('<br />');
-
-	cur_frm.cscript.render_row_in_wrapper(wrapper, data, 'Address');
-
-	$(wrapper).find('p.address-list').css({
-		'padding-left': '10px',
-		'margin-bottom': '-10px'
-	});
-}
-
-cur_frm.cscript.render_row_in_wrapper = function(wrapper, data, doctype) {
-	// render
-	var $wrapper = $(wrapper);
-
-	data.doctype = doctype.toLowerCase();
-
-	$wrapper.append(repl("\
-		<h4><a class='link_type'>%(fullname)s</a>%(primary)s</h4>\
-		<div class='description'>\
-			<p>%(description)s</p>\
-			<p><a class='delete link_type'>delete this %(doctype)s</a></p>\
-		</div>", data));
-
-	// make link
-	$wrapper.find('h4 a.link_type').click(function() {
-		loaddoc(doctype, data.name);
-	});
-
-	// css
-	$wrapper.css({ 'margin': '0px' });
-	$wrapper.find('div.description').css({
-		'padding': '5px 2px',
-		'line-height': '150%',
-	});
-	$wrapper.find('h6').css({ 'display': 'inline-block' });
-
-	// show delete
-	var $delete_doc = $wrapper.find('a.delete');
-	if (frappe.model.can_delete(doctype))
-		$delete_doc.toggle(true);
-	else
-		$delete_doc.toggle(false);
-
-	$delete_doc.css({ 'padding-left': '0px' });
-
-	$delete_doc.click(function() {
-		cur_frm.cscript.delete_doc(doctype, data.name);
-		return false;
-	});
-}
-
-cur_frm.cscript.delete_doc = function(doctype, name) {
-	// confirm deletion
-	var go_ahead = confirm(__("Delete {0} {1}?", [doctype, name]));
-	if (!go_ahead) return;
-
-	frappe.model.delete_doc(doctype, name, function(r) {
-		if (!r.exc) {
-			var list_name = doctype.toLowerCase() + '_list';
-			cur_frm[list_name].run();
-		}
-	});
-}
-
-// Render List
-cur_frm.cscript.render_list = function(doc, doctype, wrapper, ListView, make_new_doc) {
-	frappe.model.with_doctype(doctype, function(r) {
-		if((r && r['403']) || frappe.boot.user.all_read.indexOf(doctype)===-1) {
-			return;
-		}
-		var RecordListView = frappe.views.RecordListView.extend({
-			default_docstatus: ['0', '1', '2'],
-			default_filters: [
-				[doctype, doc.doctype.toLowerCase().replace(" ", "_"), '=', doc.name],
-			],
-		});
-
-		if (make_new_doc) {
-			RecordListView = RecordListView.extend({
-				make_new_doc: make_new_doc,
-			});
-		}
-
-		var record_list_view = new RecordListView(doctype, wrapper, ListView);
-		if (!cur_frm[doctype.toLowerCase().replace(" ", "_") + "_list"]) {
-			cur_frm[doctype.toLowerCase().replace(" ", "_") + "_list"] = record_list_view;
-		}
-	});
-}
diff --git a/erpnext/setup/doctype/contact_control/contact_control.json b/erpnext/setup/doctype/contact_control/contact_control.json
deleted file mode 100644
index 560aed5..0000000
--- a/erpnext/setup/doctype/contact_control/contact_control.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "creation": "2012-03-27 14:36:19.000000", 
- "docstatus": 0, 
- "doctype": "DocType", 
- "fields": [
-  {
-   "fieldname": "header", 
-   "fieldtype": "Text", 
-   "in_list_view": 1, 
-   "label": "Header", 
-   "permlevel": 0
-  }, 
-  {
-   "fieldname": "customer_intro", 
-   "fieldtype": "Text", 
-   "in_list_view": 1, 
-   "label": "Customer Intro", 
-   "permlevel": 0
-  }, 
-  {
-   "fieldname": "supplier_intro", 
-   "fieldtype": "Text", 
-   "in_list_view": 1, 
-   "label": "Supplier Intro", 
-   "permlevel": 0
-  }
- ], 
- "idx": 1, 
- "in_create": 1, 
- "issingle": 1, 
- "modified": "2013-12-20 19:23:02.000000", 
- "modified_by": "Administrator", 
- "module": "Setup", 
- "name": "Contact Control", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "create": 0, 
-   "email": 1, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "role": "System Manager", 
-   "write": 1
-  }
- ], 
- "read_only": 1
-}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/contact_control/contact_control.py b/erpnext/setup/doctype/contact_control/contact_control.py
deleted file mode 100644
index 96e9551..0000000
--- a/erpnext/setup/doctype/contact_control/contact_control.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-
-from frappe.model.document import Document
-
-class ContactControl(Document):
-	pass
\ No newline at end of file
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.js b/erpnext/setup/doctype/sales_partner/sales_partner.js
index 118d2e2..66e24da 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.js
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.js
@@ -1,12 +1,6 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-{% include 'setup/doctype/contact_control/contact_control.js' %};
-
-cur_frm.cscript.onload = function(doc,dt,dn){
-
-}
-
 cur_frm.cscript.refresh = function(doc,dt,dn){
 
 	if(doc.__islocal){
@@ -15,8 +9,8 @@
 	else{
 		unhide_field(['address_html', 'contact_html']);
 		// make lists
-		cur_frm.cscript.make_address(doc,dt,dn);
-		cur_frm.cscript.make_contact(doc,dt,dn);
+
+		erpnext.utils.render_address_and_contact(cur_frm)
 
 		if (doc.show_in_website) {
 			cur_frm.set_intro(__("Published on website at: {0}",
@@ -25,57 +19,6 @@
 	}
 }
 
-
-cur_frm.cscript.make_address = function() {
-	if(!cur_frm.address_list) {
-		cur_frm.address_list = new frappe.ui.Listing({
-			parent: cur_frm.fields_dict['address_html'].wrapper,
-			page_length: 2,
-			new_doctype: "Address",
-			custom_new_doc: function(doctype) {
-				var address = frappe.model.make_new_doc_and_get_name('Address');
-				address = locals['Address'][address];
-				address.sales_partner = cur_frm.doc.name;
-				address.address_title = cur_frm.doc.name;
-				address.address_type = "Office";
-				frappe.set_route("Form", "Address", address.name);
-			},
-			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 sales_partner='" +
-					cur_frm.doc.name.replace(/'/g, "\\'") + "' and docstatus != 2 order by is_primary_address desc"
-			},
-			as_dict: 1,
-			no_results_message: __('No addresses created'),
-			render_row: cur_frm.cscript.render_address_row,
-		});
-	}
-	cur_frm.address_list.run();
-}
-
-cur_frm.cscript.make_contact = function() {
-	if(!cur_frm.contact_list) {
-		cur_frm.contact_list = new frappe.ui.Listing({
-			parent: cur_frm.fields_dict['contact_html'].wrapper,
-			page_length: 2,
-			new_doctype: "Contact",
-			custom_new_doc: function(doctype) {
-				var contact = frappe.model.make_new_doc_and_get_name('Contact');
-				contact = locals['Contact'][contact];
-				contact.sales_partner = cur_frm.doc.name;
-				frappe.set_route("Form", "Contact", contact.name);
-			},
-			get_query: function() {
-				return "select name, first_name, last_name, email_id, phone, mobile_no, department, designation, is_primary_contact from tabContact where sales_partner='" +
-					cur_frm.doc.name.replace(/'/g, "\\'") + "' and docstatus != 2 order by is_primary_contact desc"
-			},
-			as_dict: 1,
-			no_results_message: __('No contacts created'),
-			render_row: cur_frm.cscript.render_contact_row,
-		});
-	}
-	cur_frm.contact_list.run();
-}
-
 cur_frm.fields_dict['partner_target_details'].grid.get_field("item_group").get_query = function(doc, dt, dn) {
   return{
   	filters:{ 'is_group': "No" }
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.py b/erpnext/setup/doctype/sales_partner/sales_partner.py
index 9031af5..0dfbe4c 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.py
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.py
@@ -5,11 +5,16 @@
 import frappe
 from frappe.utils import cstr, filter_strip_join
 from frappe.website.website_generator import WebsiteGenerator
+from erpnext.utilities.address_and_contact import load_address_and_contact
 
 class SalesPartner(WebsiteGenerator):
 	page_title_field = "partner_name"
 	condition_field = "show_in_website"
 	template = "templates/generators/sales_partner.html"
+	def onload(self):
+		"""Load address and contacts in `__onload`"""
+		load_address_and_contact(self, "sales_partner")
+
 	def autoname(self):
 		self.name = self.partner_name
 
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.js b/erpnext/setup/page/setup_wizard/setup_wizard.js
index 04b917f..939eae6 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.js
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.js
@@ -59,15 +59,18 @@
 				title: __("Select Your Language"),
 				icon: "icon-globe",
 				fields: [
-					{"fieldname": "language", "label": __("Language"), "fieldtype": "Select",
+					{
+						"fieldname": "language", "label": __("Language"), "fieldtype": "Select",
 						options: ["english", "العربية", "deutsch", "ελληνικά", "español", "français", "हिंदी", "hrvatski",
-						"italiano", "nederlands", "polski", "português brasileiro", "português", "српски", "தமிழ்",
-						"ไทย", "中国(简体)", "中國(繁體)"], reqd:1},
+							"italiano", "nederlands", "polski", "português brasileiro", "português", "српски", "தமிழ்",
+							"ไทย", "中国(简体)", "中國(繁體)"],
+						reqd:1, "default": "english"
+					},
 				],
 				help: __("Welcome to ERPNext. Please select your language to begin the Setup Wizard."),
 				onload: function(slide) {
 					slide.get_input("language").on("change", function() {
-						var lang = $(this).val();
+						var lang = $(this).val() || "english";
 						frappe._messages = {};
 						frappe.call({
 							method: "erpnext.setup.page.setup_wizard.setup_wizard.load_messages",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 14c409b..87c3caf 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -253,8 +253,9 @@
 		from frappe.model.naming import make_autoname
 		serial_nos = []
 		for i in xrange(cint(sle.actual_qty)):
-			serial_nos.append(make_autoname(item_det.serial_no_series))
+			serial_nos.append(make_autoname(item_det.serial_no_series, "Serial No"))
 		frappe.db.set(sle, "serial_no", "\n".join(serial_nos))
+		validate_serial_no(sle, item_det)
 
 	if sle.serial_no:
 		serial_nos = get_serial_nos(sle.serial_no)
diff --git a/erpnext/utilities/address_and_contact.py b/erpnext/utilities/address_and_contact.py
new file mode 100644
index 0000000..382c98c
--- /dev/null
+++ b/erpnext/utilities/address_and_contact.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def load_address_and_contact(doc, key):
+	"""Loads address list and contact list in `__onload`"""
+	from erpnext.utilities.doctype.address.address import get_address_display
+
+	doc.get("__onload").addr_list = [a.update({"display": get_address_display(a)}) \
+		for a in frappe.get_all("Address",
+			fields="*", filters={key: doc.name},
+			order_by="is_primary_address desc, modified desc")]
+
+	if doc.doctype != "Lead":
+		doc.get("__onload").contact_list = frappe.get_all("Contact",
+			fields="*", filters={key: doc.name},
+			order_by="is_primary_contact desc, modified desc")
diff --git a/erpnext/utilities/doctype/address/address.js b/erpnext/utilities/doctype/address/address.js
index f56a709..037f663 100644
--- a/erpnext/utilities/doctype/address/address.js
+++ b/erpnext/utilities/doctype/address/address.js
@@ -1,4 +1,13 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-{% include 'controllers/js/contact_address_common.js' %};
\ No newline at end of file
+{% include 'controllers/js/contact_address_common.js' %};
+
+frappe.ui.form.on("Address", "validate", function(frm) {
+	// clear linked customer / supplier / sales partner on saving...
+	$.each(["Customer", "Supplier", "Sales Partner", "Lead"], function(i, doctype) {
+		var name = frm.doc[doctype.toLowerCase().replace(/ /g, "_")];
+		if(name && locals[doctype] && locals[doctype][name])
+			frappe.model.remove_from_locals(doctype, name);
+	});
+});
diff --git a/erpnext/utilities/doctype/contact/contact.js b/erpnext/utilities/doctype/contact/contact.js
index f2a2fdc..ae04d49 100644
--- a/erpnext/utilities/doctype/contact/contact.js
+++ b/erpnext/utilities/doctype/contact/contact.js
@@ -3,6 +3,15 @@
 
 {% include 'controllers/js/contact_address_common.js' %};
 
+frappe.ui.form.on("Contact", "validate", function(frm) {
+	// clear linked customer / supplier / sales partner on saving...
+	$.each(["Customer", "Supplier", "Sales Partner"], function(i, doctype) {
+		var name = frm.doc[doctype.toLowerCase().replace(/ /g, "_")];
+		if(name && locals[doctype] && locals[doctype][name])
+			frappe.model.remove_from_locals(doctype, name);
+	});
+});
+
 cur_frm.cscript.refresh = function(doc) {
 	cur_frm.communication_view = new frappe.views.CommunicationList({
 		list: frappe.get_list("Communication", {"parent": doc.name, "parenttype": "Contact"}),
@@ -15,4 +24,4 @@
 cur_frm.cscript.hide_dialog = function() {
 	if(cur_frm.contact_list)
 		cur_frm.contact_list.run();
-}
\ No newline at end of file
+}