Merge branch '4.0.0-wip' of github.com:webnotes/erpnext into 4.0-hotfix
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index f7aeecd..30998e4 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -79,13 +79,13 @@
 	supplier: function() {
 		if(this.frm.updating_party_details)
 			return;
-		erpnext.selling.get_party_details(this.frm, 
+		erpnext.utils.get_party_details(this.frm, 
 			"erpnext.accounts.party.get_party_details", {
 				posting_date: this.frm.doc.posting_date,
-				company: this.frm.doc.company,
 				party: this.frm.doc.supplier,
 				party_type: "Supplier",
-				account: this.frm.doc.debit_to
+				account: this.frm.doc.debit_to,
+				price_list: this.frm.doc.buying_price_list,
 			})
 	},
 	
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index fdf2265..2b33bf0 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -158,13 +158,13 @@
 	customer: function() {
 		if(this.frm.updating_party_details)
 			return;
-		erpnext.selling.get_party_details(this.frm, 
+		erpnext.utils.get_party_details(this.frm, 
 			"erpnext.accounts.party.get_party_details", {
 				posting_date: this.frm.doc.posting_date,
-				company: this.frm.doc.company,
 				party: this.frm.doc.customer,
 				party_type: "Customer",
-				account: this.frm.doc.debit_to
+				account: this.frm.doc.debit_to,
+				price_list: this.frm.doc.selling_price_list,
 			})
 	},
 	
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 0eedd99..c9ffd0e 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -5,17 +5,98 @@
 
 import webnotes
 from webnotes import _
+from webnotes.defaults import get_restrictions
+from erpnext.utilities.doctype.address.address import get_address_display
+from erpnext.utilities.doctype.contact.contact import get_contact_details
 
 @webnotes.whitelist()
-def get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None):
-	if not webnotes.has_permission(party_type, "read", party):
-		webnotes.throw("No Permission")
+def get_party_details(party=None, account=None, party_type="Customer", company=None, 
+	posting_date=None, price_list=None, currency=None):
+	out = webnotes._dict(set_account_and_due_date(party, account, party_type, company, posting_date))
 	
+	party = out[party_type.lower()]
+
+	if not webnotes.has_permission(party_type, "read", party):
+		webnotes.throw("Not Permitted", webnotes.PermissionError)
+
+	party_bean = webnotes.bean(party_type, party)
+	party = party_bean.doc
+
+	set_address_and_contact(out, party, party_type)
+	set_other_values(out, party, party_type)
+	set_price_list(out, party, price_list)
+	
+	if not out.get("currency"):
+		out["currency"] = currency
+	
+	# sales team
 	if party_type=="Customer":
-		get_party_details = webnotes.get_attr("erpnext.selling.doctype.customer.customer.get_customer_details")
+		out["sales_team"] = [{
+			"sales_person": d.sales_person, 
+			"sales_designation": d.sales_designation
+		} for d in party_bean.doclist.get({"doctype":"Sales Team"})]
+	
+	return out
+
+def set_address_and_contact(out, party, party_type):
+	out.update({
+		party_type.lower() + "_address": webnotes.conn.get_value("Address", 
+			{party_type.lower(): party.name, "is_primary_address":1}, "name"),
+		"contact_person": webnotes.conn.get_value("Contact", 
+			{party_type.lower(): party.name, "is_primary_contact":1}, "name")
+	})
+	
+	# address display
+	out.address_display = get_address_display(out[party_type.lower() + "_address"])
+	
+	# primary contact details
+	out.update(get_contact_details(out.contact_person))
+	
+
+def set_other_values(out, party, party_type):
+	# copy
+	if party_type=="Customer":
+		to_copy = ["customer_name", "customer_group", "territory"]
 	else:
-		get_party_details = webnotes.get_attr("erpnext.buying.doctype.supplier.supplier.get_supplier_details")
-				
+		to_copy = ["supplier_name", "supplier_type"]
+	for f in to_copy:
+		out[f] = party.get(f)
+	
+	# fields prepended with default in Customer doctype
+	for f in ['currency', 'taxes_and_charges'] \
+		+ (['sales_partner', 'commission_rate'] if party_type=="Customer" else []):
+		if party.get("default_" + f):
+			out[f] = party.get("default_" + f)
+
+def set_price_list(out, party, given_price_list):
+	# price list	
+	price_list = get_restrictions().get("Price List")
+	if isinstance(price_list, list):
+		price_list = None
+
+	if not price_list:
+		price_list = party.default_price_list
+		
+	if not price_list and party.party_type=="Customer":
+		price_list =  webnotes.conn.get_value("Customer Group", 
+			party.customer_group, "default_price_list")
+
+	if not price_list:
+		price_list = given_price_list
+
+	if price_list:
+		out.price_list_currency = webnotes.conn.get_value("Price List", price_list, "currency")
+		
+	out["selling_price_list" if party.doctype=="Customer" else "buying_price_list"] = price_list
+	
+
+def set_account_and_due_date(party, account, party_type, company, posting_date):
+	if not posting_date:
+		# not an invoice
+		return {
+			party_type.lower(): party
+		}
+	
 	if party:
 		account = get_party_account(company, party, party_type)
 	elif account:
@@ -27,8 +108,7 @@
 		party_type.lower(): party,
 		account_fieldname : account,
 		"due_date": get_due_date(posting_date, party, party_type, account, company)
-	}	
-	out.update(get_party_details(party))
+	}
 	return out
 
 def get_party_account(company, party, party_type):
diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py
index 94bc679..9fe52c8 100644
--- a/erpnext/buying/doctype/supplier/supplier.py
+++ b/erpnext/buying/doctype/supplier/supplier.py
@@ -127,27 +127,4 @@
 	out["total_unpaid"] = billing[0][1]
 	
 	return out
-	
-@webnotes.whitelist()
-def get_supplier_details(supplier, price_list=None, currency=None):
-	if not webnotes.has_permission("Supplier", "read", supplier):
-		webnotes.msgprint("No Permission", raise_exception=webnotes.PermissionError)
-
-	supplier = webnotes.doc("Supplier", supplier)
-	
-	out = webnotes._dict({
-		"supplier_address": webnotes.conn.get_value("Address", 
-			{"supplier": supplier.name, "is_primary_address":1}, "name"),
-		"contact_person": webnotes.conn.get_value("Contact", 
-			{"supplier":supplier.name, "is_primary_contact":1}, "name")
-	})
-
-	for f in ['currency', 'taxes_and_charges']:
-		if supplier.fields.get("default_" + f):
-			out[f] = supplier.fields.get("default_" + f)
-	
-	out.supplier_name = supplier.supplier_name
-	out.currency = supplier.default_currency or currency
-	out.buying_price_list = supplier.default_price_list or price_list
-		
-	return out
\ No newline at end of file
+	
\ No newline at end of file
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 5c45c11..00fb05e 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -7,7 +7,7 @@
 from webnotes.utils import flt, _round
 from erpnext.buying.utils import get_item_details
 from erpnext.setup.utils import get_company_currency
-from erpnext.buying.doctype.supplier.supplier import get_supplier_details
+from erpnext.accounts.party import get_party_details
 
 from erpnext.controllers.stock_controller import StockController
 
@@ -33,7 +33,7 @@
 		
 		# set contact and address details for supplier, if they are not mentioned
 		if self.doc.supplier:
-			self.doc.update_if_missing(get_supplier_details(self.doc.supplier))
+			self.doc.update_if_missing(get_party_details(self.doc.supplier, party_type="Supplier"))
 
 		self.set_missing_item_details(get_item_details)
 		if self.doc.fields.get("__islocal"):
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 75b27a5..a075ad4 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -33,9 +33,9 @@
 			self.set_taxes("other_charges", "taxes_and_charges")
 					
 	def set_missing_lead_customer_details(self):
-		from erpnext.selling.doctype.customer.customer import get_customer_details
+		from erpnext.accounts.party import get_party_details
 		if self.doc.customer:
-			self.doc.update_if_missing(get_customer_details(self.doc.customer))
+			self.doc.update_if_missing(get_party_details(self.doc.customer))
 		
 		elif self.doc.lead:
 			self.doc.update_if_missing(self.get_lead_defaults())
diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js
index bda44ce..c01dee6 100644
--- a/erpnext/public/js/utils/party.js
+++ b/erpnext/public/js/utils/party.js
@@ -4,28 +4,25 @@
 wn.provide("erpnext.utils");
 erpnext.utils.get_party_details = function(frm, method, args) {
 	if(!method) {
-		if(frm.doc.customer) {
-			method = "erpnext.selling.doctype.customer.customer.get_customer_details";
-			var price_list_field = "selling_price_list";
-		} else {
-			method = "erpnext.buying.doctype.supplier.supplier.get_supplier_details";
-			var price_list_field = "buying_price_list";
-		}
+		method = "erpnext.accounts.party.get_party_details";
 	}
 	if(!args) {
 		if(frm.doc.customer) {
 			args = { 
-				customer: frm.doc.customer,
+				party: frm.doc.customer,
+				party_type: "Customer",
 				price_list: frm.doc.selling_price_list
 			};
 		} else {
 			args = { 
-				supplier: frm.doc.supplier,
+				party: frm.doc.supplier,
+				party_type: "Supplier",
 				price_list: frm.doc.buying_price_list
 			};
 		}
-		args.currency = frm.doc.currency;
 	}
+	args.currency = frm.doc.currency;
+	args.company = frm.doc.company;
 	wn.call({
 		method: method,
 		args: args,
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index c8c619a..f51cd55 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -163,58 +163,3 @@
 	out["total_unpaid"] = billing[0][1]
 	
 	return out
-
-@webnotes.whitelist()
-def get_customer_details(customer, price_list=None, currency=None):
-	if not webnotes.has_permission("Customer", "read", customer):
-		webnotes.throw("Not Permitted", webnotes.PermissionError)
-		
-	out = {}
-	customer_bean = webnotes.bean("Customer", customer)
-	customer = customer_bean.doc
-
-	out = webnotes._dict({
-		"customer_address": webnotes.conn.get_value("Address", 
-			{"customer": customer.name, "is_primary_address":1}, "name"),
-		"contact_person": webnotes.conn.get_value("Contact", 
-			{"customer":customer.name, "is_primary_contact":1}, "name")
-	})
-
-	# address display
-	out.address_display = get_address_display(out.customer_address)
-	
-	# primary contact details
-	out.update(get_contact_details(out.contact_person))
-
-	# copy
-	for f in ['customer_name', 'customer_group', 'territory']:
-		out[f] = customer.get(f)
-	
-	# fields prepended with default in Customer doctype
-	for f in ['sales_partner', 'commission_rate', 'currency', 'price_list', 'taxes_and_charges']:
-		if customer.get("default_" + f):
-			out[f] = customer.get("default_" + f)
-
-	# price list
-	from webnotes.defaults import get_defaults_for
-	out.selling_price_list = get_defaults_for(webnotes.session.user).get(price_list)
-	if isinstance(out.selling_price_list, list):
-		out.selling_price_list = None
-	
-	out.selling_price_list = out.selling_price_list or customer.price_list \
-		or webnotes.conn.get_value("Customer Group", 
-			customer.customer_group, "default_price_list") or price_list
-	
-	if out.selling_price_list:
-		out.price_list_currency = webnotes.conn.get_value("Price List", out.selling_price_list, "currency")
-	
-	if not out.currency:
-		out.currency = currency
-	
-	# sales team
-	out.sales_team = [{
-		"sales_person": d.sales_person, 
-		"sales_designation": d.sales_designation
-	} for d in customer_bean.doclist.get({"doctype":"Sales Team"})]
-	
-	return out
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py
index b3e0372..abe0329 100644
--- a/erpnext/selling/doctype/customer/test_customer.py
+++ b/erpnext/selling/doctype/customer/test_customer.py
@@ -10,8 +10,8 @@
 
 
 class TestCustomer(unittest.TestCase):
-	def test_get_customer_details(self):
-		from erpnext.selling.doctype.customer.customer import get_customer_details
+	def test_party_details(self):
+		from erpnext.accounts.party import get_party_details
 		
 		to_check = {
 			'address_display': '_Test Address Line 1\n_Test City\nIndia\nPhone: +91 0000000000', 
@@ -22,7 +22,7 @@
 			'contact_department': None, 
 			'contact_email': 'test_contact_customer@example.com', 
 			'contact_mobile': None, 
-			'_sales_team': [], 
+			'sales_team': [], 
 			'contact_display': '_Test Contact For _Test Customer', 
 			'contact_person': '_Test Contact For _Test Customer-_Test Customer', 
 			'territory': u'_Test Territory', 
@@ -32,9 +32,9 @@
 		
 		make_test_records("Address")
 		make_test_records("Contact")
-				
-		details = get_customer_details("_Test Customer")
-
+						
+		details = get_party_details("_Test Customer")
+		
 		for key, value in to_check.iteritems():
 			self.assertEquals(value, details.get(key))
 		
@@ -49,49 +49,7 @@
 		self.assertEqual(webnotes.conn.exists("Customer", "_Test Customer 1"), ())
 		
 		webnotes.rename_doc("Customer", "_Test Customer 1 Renamed", "_Test Customer 1")
-		
-	def test_merge(self):
-		make_test_records("Sales Invoice")
-		
-		# clear transactions for new name
-		webnotes.conn.sql("""delete from `tabSales Invoice` where customer='_Test Customer 1'""")
-		
-		# check if they exist
-		self.assertEqual(webnotes.conn.exists("Customer", "_Test Customer"), 
-			(("_Test Customer",),))
-		self.assertEqual(webnotes.conn.exists("Customer", "_Test Customer 1"), 
-			(("_Test Customer 1",),))
-		self.assertEqual(webnotes.conn.exists("Account", "_Test Customer - _TC"), 
-			(("_Test Customer - _TC",),))
-		self.assertEqual(webnotes.conn.exists("Account", "_Test Customer 1 - _TC"), 
-			(("_Test Customer 1 - _TC",),))
-			
-		# check if transactions exists
-		self.assertNotEquals(webnotes.conn.sql("""select count(*) from `tabSales Invoice` 
-			where customer='_Test Customer'""", )[0][0], 0)
-		self.assertNotEquals(webnotes.conn.sql("""select count(*) from `tabSales Invoice` 
-			where debit_to='_Test Customer - _TC'""", )[0][0], 0)
-		
-		webnotes.rename_doc("Customer", "_Test Customer", "_Test Customer 1", merge=True)
-		
-		# check that no transaction exists for old name
-		self.assertNotEquals(webnotes.conn.sql("""select count(*) from `tabSales Invoice` 
-			where customer='_Test Customer 1'""", )[0][0], 0)
-		self.assertNotEquals(webnotes.conn.sql("""select count(*) from `tabSales Invoice` 
-			where debit_to='_Test Customer 1 - _TC'""", )[0][0], 0)
-		
-		# check that transactions exist for new name
-		self.assertEquals(webnotes.conn.sql("""select count(*) from `tabSales Invoice` 
-			where customer='_Test Customer'""", )[0][0], 0)
-		self.assertEquals(webnotes.conn.sql("""select count(*) from `tabSales Invoice` 
-			where debit_to='_Test Customer - _TC'""", )[0][0], 0)
-			
-		# check that old name doesn't exist
-		self.assertEqual(webnotes.conn.exists("Customer", "_Test Customer"), ())
-		self.assertEqual(webnotes.conn.exists("Account", "_Test Customer - _TC"), ())
-		
-		# create back _Test Customer
-		webnotes.bean(copy=test_records[0]).insert()
+				
 
 test_ignore = ["Price List"]
 			
@@ -111,5 +69,13 @@
 		"customer_group": "_Test Customer Group",
 		"territory": "_Test Territory",
 		"company": "_Test Company"
+	}],
+	[{
+		"doctype": "Customer",
+		"customer_name": "_Test Customer 2",
+		"customer_type": "Individual",
+		"customer_group": "_Test Customer Group",
+		"territory": "_Test Territory",
+		"company": "_Test Company"
 	}]
 ]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 5c7fdef..5df1af8 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -239,15 +239,15 @@
 	
 	customer: function() {
 		return this.frm.call({
-			method: "erpnext.selling.doctype.customer.customer.get_customer_details",
-			args: { customer: this.frm.doc.customer }
+			method: "erpnext.accounts.party.get_party_details",
+			args: { party: this.frm.doc.customer, party_type:"Customer" }
 		});
 	},
 	
 	supplier: function() {
 		return this.frm.call({
-			method: "erpnext.buying.doctype.supplier.supplier.get_supplier_details",
-			args: { supplier: this.frm.doc.supplier }
+			method: "erpnext.accounts.party.get_party_details",
+			args: { party: this.frm.doc.supplier, party_type:"Supplier" }
 		});
 	},