Merge pull request #7222 from neilLasrado/assessment

Redesign Assessment Module
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 0083ceb..45602f1 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -2,7 +2,7 @@
 from __future__ import unicode_literals
 import frappe
 
-__version__ = '7.2.11'
+__version__ = '7.2.12'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
@@ -24,3 +24,18 @@
 	company = get_default_company()
 	if company:
 		return frappe.db.get_value('Company', company, 'default_currency')
+
+def set_perpetual_inventory(enable=1):
+	accounts_settings = frappe.get_doc("Accounts Settings")
+	accounts_settings.auto_accounting_for_stock = enable
+	accounts_settings.save()
+
+def encode_company_abbr(name, company):
+	'''Returns name encoded with company abbreviation'''
+	company_abbr = frappe.db.get_value("Company", company, "abbr")
+	parts = name.rsplit(" - ", 1)
+
+	if parts[-1].lower() != company_abbr.lower():
+		parts.append(company_abbr)
+
+	return " - ".join([parts[0], company_abbr])
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index cedaf60..11f376d 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -3,11 +3,12 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.utils import cstr, cint
+from frappe.utils import cint, fmt_money
 from frappe import throw, _
 from frappe.model.document import Document
 
 class RootNotEditable(frappe.ValidationError): pass
+class BalanceMismatchError(frappe.ValidationError): pass
 
 class Account(Document):
 	nsm_parent_field = 'parent_account'
@@ -162,23 +163,38 @@
 			throw(_("Report Type is mandatory"))
 
 	def validate_warehouse_account(self):
+		'''If perpetual inventory is set, and warehouse is linked,
+		the account balance and stock balance as of now must always match.
+		'''
+		from erpnext.accounts.utils import get_balance_on
+		from erpnext.stock.utils import get_stock_value_on
 		if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
 			return
-			
-		if self.account_type == "Stock" and not cint(self.is_group):
-			if not self.warehouse:
-				throw(_("Warehouse is mandatory"))
-				
-			old_warehouse = cstr(frappe.db.get_value("Account", self.name, "warehouse"))
-			if old_warehouse != cstr(self.warehouse):
-				if old_warehouse and frappe.db.exists("Warehouse", old_warehouse):
-					self.validate_warehouse(old_warehouse)
-				if self.warehouse:
-					self.validate_warehouse(self.warehouse)
-					
+
+		if self.account_type == "Stock":
+			if self.is_group == 0 and not self.warehouse:
+				frappe.throw(_("Warehouse is mandatory for non group Accounts of type Stock"))
+
+			if self.warehouse:
+				# company must be same
+				if frappe.get_value('Warehouse', self.warehouse, 'company') != self.company:
+					frappe.throw(_("Warehouse company must be same as Account company"))
+
+				# balance must be same
+				stock_balance = get_stock_value_on(self.warehouse)
+				if self.is_new():
+					account_balance = 0.0
+				else:
+					account_balance = get_balance_on(self.name)
+
+				if account_balance != stock_balance:
+					frappe.throw(_('Account balance ({0}) and stock value ({1}) must be same')\
+						.format(fmt_money(account_balance, self.account_currency),
+							fmt_money(stock_balance, self.account_currency)))
+
 		elif self.warehouse:
 			self.warehouse = None
-	
+
 	def validate_warehouse(self, warehouse):
 		lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
 
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index b4bb542..8756ca4 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -171,7 +171,7 @@
 		})
 
 		jv.submit()
-		
+
 	def test_clear_blank_rows(self):
 		je = make_journal_entry("_Test Bank - _TC", "_Test Account Stock Expenses - _TC", 100, save=False)
 		je.append("accounts", {
@@ -180,11 +180,11 @@
 			"credit_in_account_currency": 0,
 			"exchange_rate": 1
 		})
-		
+
 		self.assertEqual(len(je.get("accounts")), 3)
 		je.save()
-		self.assertEqual(len(je.get("accounts")), 2)		
-		
+		self.assertEqual(len(je.get("accounts")), 2)
+
 
 def make_journal_entry(account1, account2, amount, cost_center=None, posting_date=None, exchange_rate=1, save=True, submit=False, project=None):
 	if not cost_center:
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 99fed1e..9fb7ceb 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -43,7 +43,11 @@
 	}
 
 def get_meta():
-	doctype_meta = {'customer': frappe.get_meta('Customer')}
+	doctype_meta = {
+		'customer': frappe.get_meta('Customer'),
+		'invoice': frappe.get_meta('Sales Invoice')
+	}
+
 	for row in frappe.get_all('DocField', fields = ['fieldname', 'options'],
 		filters = {'parent': 'Sales Invoice', 'fieldtype': 'Table'}):
 		doctype_meta[row.fieldname] = frappe.get_meta(row.options)
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index 921c3b5..720a1dc 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -75,7 +75,7 @@
 	},
 
 	refresh: function(doc) {
-		frappe.contact_link = {doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier'};
+		frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier'};
 
 		this.frm.toggle_display("supplier_name",
 			(this.frm.doc.supplier_name && this.frm.doc.supplier_name!==this.frm.doc.supplier));
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index 9808718..ce6f451 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -16,7 +16,7 @@
 		});
 	},
 	refresh: function(frm) {
-		frappe.contact_link = {doc: frm.doc, fieldname: 'name', doctype: 'Supplier'}
+		frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Supplier'}
 
 		if(frappe.defaults.get_default("supp_master_name")!="Naming Series") {
 			frm.toggle_display("naming_series", false);
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index da05911..67d4822 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -113,7 +113,7 @@
 				date_field = "transaction_date"
 
 			if date_field and self.get(date_field):
-				validate_fiscal_year(self.get(date_field), self.fiscal_year, self.company, 
+				validate_fiscal_year(self.get(date_field), self.fiscal_year, self.company,
 					self.meta.get_label(date_field), self)
 
 	def validate_due_date(self):
@@ -131,7 +131,7 @@
 			transaction_date = self.posting_date
 		else:
 			transaction_date = self.transaction_date
-		 
+
 		if self.meta.get_field("currency"):
 			# price list part
 			fieldname = "selling_price_list" if buying_or_selling.lower() == "selling" \
@@ -144,7 +144,7 @@
 					self.plc_conversion_rate = 1.0
 
 				elif not self.plc_conversion_rate:
-					self.plc_conversion_rate = get_exchange_rate(self.price_list_currency, 
+					self.plc_conversion_rate = get_exchange_rate(self.price_list_currency,
 						self.company_currency, transaction_date)
 
 			# currency
@@ -570,7 +570,7 @@
 							elif asset.status in ("Scrapped", "Cancelled", "Sold"):
 								frappe.throw(_("Row #{0}: Asset {1} cannot be submitted, it is already {2}")
 									.format(d.idx, d.asset, asset.status))
-									
+
 	def delink_advance_entries(self, linked_doc_name):
 		total_allocated_amount = 0
 		for adv in self.advances:
@@ -583,7 +583,7 @@
 			if consider_for_total_advance:
 				total_allocated_amount += flt(adv.allocated_amount, adv.precision("allocated_amount"))
 
-		frappe.db.set_value(self.doctype, self.name, "total_advance", 
+		frappe.db.set_value(self.doctype, self.name, "total_advance",
 			total_allocated_amount, update_modified=False)
 
 	def group_similar_items(self):
@@ -711,7 +711,7 @@
 			.format(order_doctype, order_condition))
 
 	reference_condition = " and (" + " or ".join(conditions) + ")" if conditions else ""
-	
+
 	journal_entries = frappe.db.sql("""
 		select
 			"Journal Entry" as reference_type, t1.name as reference_name,
@@ -771,8 +771,8 @@
 def update_invoice_status():
 	# Daily update the status of the invoices
 
-	frappe.db.sql(""" update `tabSales Invoice` set status = 'Overdue' 
+	frappe.db.sql(""" update `tabSales Invoice` set status = 'Overdue'
 		where due_date < CURDATE() and docstatus = 1 and outstanding_amount > 0""")
 
-	frappe.db.sql(""" update `tabPurchase Invoice` set status = 'Overdue' 
+	frappe.db.sql(""" update `tabPurchase Invoice` set status = 'Overdue'
 		where due_date < CURDATE() and docstatus = 1 and outstanding_amount > 0""")
\ No newline at end of file
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 3e900b2..74ea774 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -3,7 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.utils import cint, flt, cstr, now
+from frappe.utils import cint, flt, cstr
 from frappe import msgprint, _
 import frappe.defaults
 from erpnext.accounts.utils import get_fiscal_year
@@ -14,7 +14,7 @@
 	def validate(self):
 		super(StockController, self).validate()
 		self.validate_inspection()
-	
+
 	def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
 		if self.docstatus == 2:
 			delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
@@ -43,16 +43,16 @@
 
 		gl_list = []
 		warehouse_with_no_account = []
-		
+
 		for item_row in voucher_details:
 			sle_list = sle_map.get(item_row.name)
 			if sle_list:
 				for sle in sle_list:
 					if warehouse_account.get(sle.warehouse):
 						# from warehouse account
-						
+
 						self.check_expense_account(item_row)
-						
+
 						if not sle.stock_value_difference:
 							self.validate_negative_stock(sle)
 
@@ -80,16 +80,16 @@
 			for wh in warehouse_with_no_account:
 				if frappe.db.get_value("Warehouse", wh, "company"):
 					frappe.throw(_("Warehouse {0} is not linked to any account, please create/link the corresponding (Asset) account for the warehouse.").format(wh))
-					
+
 			msgprint(_("No accounting entries for the following warehouses") + ": \n" +
 				"\n".join(warehouse_with_no_account))
 
 		return process_gl_map(gl_list)
-		
+
 	def validate_negative_stock(self, sle):
 		if sle.qty_after_transaction < 0 and sle.actual_qty < 0:
 			frappe.throw(_("For the Item {0}, valuation rate not found for warehouse {1}. To be able to do accounting entries (for booking expenses), we need valuation rate for item {2}. Please create an incoming stock transaction, on or before {3} {4}, and then try submiting {5}")
-			.format(sle.item_code, sle.warehouse, 
+			.format(sle.item_code, sle.warehouse,
 				sle.item_code, sle.posting_date, sle.posting_time, self.name))
 
 	def get_voucher_details(self, default_expense_account, default_cost_center, sle_map):
@@ -248,7 +248,7 @@
 			incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
 
 		return incoming_rate
-		
+
 	def validate_warehouse(self):
 		from erpnext.stock.utils import validate_warehouse_company
 
@@ -257,7 +257,7 @@
 
 		for w in warehouses:
 			validate_warehouse_company(w, self.company)
-			
+
 	def update_billing_percentage(self, update_modified=True):
 		self._update_percent_field({
 			"target_dt": self.doctype + " Item",
@@ -271,21 +271,21 @@
 	def validate_inspection(self):
 		'''Checks if quality inspection is set for Items that require inspection.
 		On submit, throw an exception'''
-		
+
 		inspection_required_fieldname = None
 		if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
 			inspection_required_fieldname = "inspection_required_before_purchase"
 		elif self.doctype in ["Delivery Note", "Sales Invoice"]:
 			inspection_required_fieldname = "inspection_required_before_delivery"
-		
+
 		if not inspection_required_fieldname or \
 			(self.doctype in ["Sales Invoice", "Purchase Invoice"] and not self.update_stock):
 				return
-		
+
 		for d in self.get('items'):
-			if (frappe.db.get_value("Item", d.item_code, inspection_required_fieldname) 
+			if (frappe.db.get_value("Item", d.item_code, inspection_required_fieldname)
 				and not d.quality_inspection):
-				
+
 				frappe.msgprint(_("Quality Inspection required for Item {0}").format(d.item_code))
 				if self.docstatus==1:
 					raise frappe.ValidationError
@@ -301,7 +301,7 @@
 
 	future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items)
 	gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date)
-	
+
 	for voucher_type, voucher_no in future_stock_vouchers:
 		existing_gle = gle.get((voucher_type, voucher_no), [])
 		voucher_obj = frappe.get_doc(voucher_type, voucher_no)
@@ -364,14 +364,19 @@
 	return gl_entries
 
 def get_warehouse_account():
-	if not frappe.flags.warehouse_account_map:
+	if not frappe.flags.warehouse_account_map or frappe.flags.in_test:
 		warehouse_account = frappe._dict()
 
-		for d in frappe.db.sql("""select warehouse, name, account_currency from tabAccount
-			where account_type = 'Stock' and (warehouse is not null and warehouse != ''
-			and is_group != 1) and is_group=0 """, as_dict=1):
-				warehouse_account.setdefault(d.warehouse, d)
-		
+		for d in frappe.db.sql("""select
+				warehouse, name, account_currency
+			from
+				tabAccount
+			where
+				account_type = 'Stock'
+				and (warehouse is not null and warehouse != '')
+				and is_group=0 """, as_dict=1):
+			warehouse_account.setdefault(d.warehouse, d)
+
 		frappe.flags.warehouse_account_map = warehouse_account
-		
+
 	return frappe.flags.warehouse_account_map
diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js
index d7d412a..32171b0 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.js
+++ b/erpnext/crm/doctype/opportunity/opportunity.js
@@ -52,9 +52,9 @@
 
 	set_contact_link: function(frm) {
 		if(frm.doc.customer) {
-			frappe.contact_link = {doc: frm.doc, fieldname: 'customer', doctype: 'Customer'}
+			frappe.dynamic_link = {doc: frm.doc, fieldname: 'customer', doctype: 'Customer'}
 		} else if(frm.doc.lead) {
-			frappe.contact_link = {doc: frm.doc, fieldname: 'lead', doctype: 'Lead'}
+			frappe.dynamic_link = {doc: frm.doc, fieldname: 'lead', doctype: 'Lead'}
 		}
 	},
 
diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py
index 21ac648..0c6a9b8 100644
--- a/erpnext/demo/setup/setup_data.py
+++ b/erpnext/demo/setup/setup_data.py
@@ -163,11 +163,10 @@
 	ss.append('deductions', {
 		'salary_component': 'Income Tax',
 		"abbr":'IT',
-		'condition': 'base > 1000',
-		'amount': random.random() * 1000,
+		'condition': 'base > 10000',
+		'formula': 'base*.1',
 		"idx": 1
 	})
-
 	ss.insert()
 
 	return ss
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
index b5d1ad3..9639e7f 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
+++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
@@ -23,7 +23,7 @@
 // TODO commonify this code
 erpnext.maintenance.MaintenanceSchedule = frappe.ui.form.Controller.extend({
 	refresh: function() {
-		frappe.contact_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+		frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
 
 		var me = this;
 
diff --git a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
index 1a3c35c..62cdf86 100644
--- a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
+++ b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
@@ -25,7 +25,7 @@
 // TODO commonify this code
 erpnext.maintenance.MaintenanceVisit = frappe.ui.form.Controller.extend({
 	refresh: function() {
-		frappe.contact_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+		frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
 
 		if (this.frm.doc.docstatus===0) {
 			cur_frm.add_custom_button(__('Maintenance Schedule'),
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index aa69342..f690878 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -304,9 +304,9 @@
 
 	def get_operations_data(self, data):
 		return {
-			'from_time': data.planned_start_time,
+			'from_time': get_datetime(data.planned_start_time),
 			'hours': data.time_in_mins / 60.0,
-			'to_time': data.planned_end_time,
+			'to_time': get_datetime(data.planned_end_time),
 			'project': self.project,
 			'operation': data.operation,
 			'operation_id': data.name,
diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js
index 8236ce7..1141f99 100644
--- a/erpnext/public/js/queries.js
+++ b/erpnext/public/js/queries.js
@@ -43,28 +43,28 @@
 	},
 
 	contact_query: function(doc) {
-		if(frappe.contact_link) {
-			if(!doc[frappe.contact_link.fieldname]) {
+		if(frappe.dynamic_link) {
+			if(!doc[frappe.dynamic_link.fieldname]) {
 				frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype,
-					frappe.contact_link.fieldname, doc.name))));
+					frappe.dynamic_link.fieldname, doc.name))));
 			}
 
 			return {
 				query: 'frappe.email.doctype.contact.contact.contact_query',
-				filters: { link_doctype: frappe.contact_link.doctype, link_name: doc[frappe.contact_link.fieldname] } };
+				filters: { link_doctype: frappe.dynamic_link.doctype, link_name: doc[frappe.dynamic_link.fieldname] } };
 		}
 	},
 
 	address_query: function(doc) {
-		if(frappe.contact_link) {
-			if(!doc[frappe.contact_link.fieldname]) {
+		if(frappe.dynamic_link) {
+			if(!doc[frappe.dynamic_link.fieldname]) {
 				frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype,
-					frappe.contact_link.fieldname, doc.name))));
+					frappe.dynamic_link.fieldname, doc.name))));
 			}
 
 			return {
-				query: 'frappe.email.doctype.address.address_query',
-				filters: { link_doctype: frappe.contact_link.doctype, link_name: doc[frappe.contact_link.fieldname] } };
+				query: 'frappe.geo.doctype.address.address.address_query',
+				filters: { link_doctype: frappe.dynamic_link.doctype, link_name: doc[frappe.dynamic_link.fieldname] } };
 		}
 	},
 
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 975604d..747b31e 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -32,7 +32,7 @@
 			erpnext.toggle_naming_series();
 		}
 
-		frappe.contact_link = {doc: frm.doc, fieldname: 'name', doctype: 'Customer'}
+		frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Customer'}
 
 		frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
 
diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js
index ab1a24a..e06f963 100644
--- a/erpnext/selling/doctype/quotation/quotation.js
+++ b/erpnext/selling/doctype/quotation/quotation.js
@@ -67,12 +67,8 @@
 		this.frm.toggle_reqd("customer", this.frm.doc.quotation_to == "Customer");
 
 		// to overwrite the customer_filter trigger from queries.js
-		$.each(["customer_address", "shipping_address_name"],
-			function(i, opts) {
-				me.frm.set_query(opts, me.frm.doc.quotation_to==="Lead"
-					? erpnext.queries["lead_filter"] : erpnext.queries["customer_filter"]);
-			}
-		);
+		this.frm.set_query('customer_address', erpnext.queries.address_query);
+		this.frm.set_query('shipping_address_name', erpnext.queries.address_query);
 	},
 
 	tc_name: function() {
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 96ce79a..9d9511e 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -106,7 +106,7 @@
 	refresh: function() {
 		this._super();
 
-		frappe.contact_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+		frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
 
 		this.frm.toggle_display("customer_name",
 			(this.frm.doc.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer));
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.js b/erpnext/setup/doctype/sales_partner/sales_partner.js
index 6531630..df8d23f 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.js
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.js
@@ -3,7 +3,7 @@
 
 frappe.ui.form.on('Sales Partner', {
 	refresh: function(frm) {
-		frappe.contact_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Person'}
+		frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Person'}
 
 		if(doc.__islocal){
 			hide_field(['address_html', 'contact_html']);
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index e52ef81..5ca0315 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -375,15 +375,17 @@
 	if not party:
 		return []
 
-	address_docs = frappe.db.sql("""select * from `tabAddress`
-		where `{0}`=%s order by name limit {1}, {2}""".format(party.doctype.lower(),
-			limit_start, limit_page_length), party.name,
-		as_dict=True, update={"doctype": "Address"})
+	address_names = frappe.db.get_all('Dyanamic Link', fields=('parent'),
+		filters=dict(parenttype='Address', link_doctype=party.doctype, link_name=party.name))
 
-	for address in address_docs:
-		address.display = get_address_display(address)
+	out = []
 
-	return address_docs
+	for address_name in address_names:
+		address = frappe.get_doc('Address', address_name)
+		address.display = get_address_display(address.as_dict())
+		out.append(address)
+
+	return out
 
 @frappe.whitelist()
 def apply_shipping_rule(shipping_rule):
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index f961cdd..7421e01 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -8,6 +8,7 @@
 import frappe.defaults
 from frappe.utils import cint, flt, cstr, today
 from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
+from erpnext import set_perpetual_inventory
 
 class TestPurchaseReceipt(unittest.TestCase):
 	def test_make_purchase_invoice(self):
@@ -26,10 +27,10 @@
 
 	def test_purchase_receipt_no_gl_entry(self):
 		set_perpetual_inventory(0)
-		
+
 		existing_bin_stock_value = frappe.db.get_value("Bin", {"item_code": "_Test Item",
 			"warehouse": "_Test Warehouse - _TC"}, "stock_value")
-		
+
 		pr = make_purchase_receipt()
 
 		stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
@@ -78,22 +79,22 @@
 
 	def test_subcontracting(self):
 		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
-		
+
 		make_stock_entry(item_code="_Test Item", target="_Test Warehouse 1 - _TC", qty=100, basic_rate=100)
-		make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse 1 - _TC", 
+		make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse 1 - _TC",
 			qty=100, basic_rate=100)
-		
+
 		pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=500, is_subcontracted="Yes")
 		self.assertEquals(len(pr.get("supplied_items")), 2)
-		
+
 		rm_supp_cost = sum([d.amount for d in pr.get("supplied_items")])
 		self.assertEquals(pr.get("items")[0].rm_supp_cost, flt(rm_supp_cost, 2))
 
 	def test_serial_no_supplier(self):
 		pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1)
-		self.assertEquals(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "supplier"), 
+		self.assertEquals(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "supplier"),
 			pr.supplier)
-		
+
 		pr.cancel()
 		self.assertFalse(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "warehouse"))
 
@@ -118,21 +119,21 @@
 		for serial_no in rejected_serial_nos:
 			self.assertEquals(frappe.db.get_value("Serial No", serial_no, "warehouse"),
 				pr.get("items")[0].rejected_warehouse)
-				
+
 	def test_purchase_return(self):
 		set_perpetual_inventory()
-		
+
 		pr = make_purchase_receipt()
-		
+
 		return_pr = make_purchase_receipt(is_return=1, return_against=pr.name, qty=-2)
 
 		# check sle
-		outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt", 
+		outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
 			"voucher_no": return_pr.name}, "outgoing_rate")
-			
+
 		self.assertEqual(outgoing_rate, 50)
-		
-		
+
+
 		# check gl entries for return
 		gl_entries = get_gl_entries("Purchase Receipt", return_pr.name)
 
@@ -146,7 +147,7 @@
 		for gle in gl_entries:
 			self.assertEquals(expected_values[gle.account][0], gle.debit)
 			self.assertEquals(expected_values[gle.account][1], gle.credit)
-		
+
 		set_perpetual_inventory(0)
 
 	def test_purchase_return_for_rejected_qty(self):
@@ -158,7 +159,7 @@
 
 		actual_qty = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
 			"voucher_no": return_pr.name, 'warehouse': return_pr.items[0].rejected_warehouse}, "actual_qty")
-		
+
 		self.assertEqual(actual_qty, -2)
 
 		set_perpetual_inventory(0)
@@ -168,87 +169,82 @@
 			serial_no = frappe.get_doc("Serial No", serial_no)
 			for field, value in field_values.items():
 				self.assertEquals(cstr(serial_no.get(field)), value)
-		
+
 		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
-		
+
 		pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1)
-		
+
 		serial_no = get_serial_nos(pr.get("items")[0].serial_no)[0]
-		
+
 		_check_serial_no_values(serial_no, {
 			"warehouse": "_Test Warehouse - _TC",
 			"purchase_document_no": pr.name
 		})
-		
-		return_pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=-1, 
+
+		return_pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=-1,
 			is_return=1, return_against=pr.name, serial_no=serial_no)
-			
+
 		_check_serial_no_values(serial_no, {
 			"warehouse": "",
 			"purchase_document_no": pr.name,
 			"delivery_document_no": return_pr.name
 		})
-	
+
 	def test_closed_purchase_receipt(self):
 		from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_purchase_receipt_status
-		
+
 		pr = make_purchase_receipt(do_not_submit=True)
 		pr.submit()
-		
+
 		update_purchase_receipt_status(pr.name, "Closed")
 		self.assertEquals(frappe.db.get_value("Purchase Receipt", pr.name, "status"), "Closed")
-		
+
 	def test_pr_billing_status(self):
 		# PO -> PR1 -> PI and PO -> PI and PO -> PR2
 		from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
 		from erpnext.buying.doctype.purchase_order.purchase_order \
 			import make_purchase_receipt, make_purchase_invoice as make_purchase_invoice_from_po
-		
+
 		po = create_purchase_order()
-		
+
 		pr1 = make_purchase_receipt(po.name)
 		pr1.posting_date = today()
 		pr1.posting_time = "10:00"
 		pr1.get("items")[0].received_qty = 2
 		pr1.get("items")[0].qty = 2
 		pr1.submit()
-		
+
 		pi1 = make_purchase_invoice(pr1.name)
 		pi1.submit()
-		
+
 		pr1.load_from_db()
 		self.assertEqual(pr1.per_billed, 100)
-		
+
 		pi2 = make_purchase_invoice_from_po(po.name)
 		pi2.get("items")[0].qty = 4
 		pi2.submit()
-		
+
 		pr2 = make_purchase_receipt(po.name)
 		pr2.posting_date = today()
 		pr2.posting_time = "08:00"
 		pr2.get("items")[0].received_qty = 5
 		pr2.get("items")[0].qty = 5
 		pr2.submit()
-		
+
 		pr1.load_from_db()
 		self.assertEqual(pr1.get("items")[0].billed_amt, 1000)
 		self.assertEqual(pr1.per_billed, 100)
 		self.assertEqual(pr1.status, "Completed")
-		
+
 		self.assertEqual(pr2.get("items")[0].billed_amt, 2000)
 		self.assertEqual(pr2.per_billed, 80)
 		self.assertEqual(pr2.status, "To Bill")
-		
+
 def get_gl_entries(voucher_type, voucher_no):
 	return frappe.db.sql("""select account, debit, credit
 		from `tabGL Entry` where voucher_type=%s and voucher_no=%s
 		order by account desc""", (voucher_type, voucher_no), as_dict=1)
 
-def set_perpetual_inventory(enable=1):
-	accounts_settings = frappe.get_doc("Accounts Settings")
-	accounts_settings.auto_accounting_for_stock = enable
-	accounts_settings.save()
-	
 def make_purchase_receipt(**args):
 	pr = frappe.new_doc("Purchase Receipt")
 	args = frappe._dict(args)
diff --git a/erpnext/stock/doctype/warehouse/test_warehouse.py b/erpnext/stock/doctype/warehouse/test_warehouse.py
index edc5400..ec64bdd 100644
--- a/erpnext/stock/doctype/warehouse/test_warehouse.py
+++ b/erpnext/stock/doctype/warehouse/test_warehouse.py
@@ -4,59 +4,64 @@
 from frappe.model.rename_doc import rename_doc
 from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
 from frappe.utils import cint
-from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
+from erpnext import set_perpetual_inventory
+from frappe.test_runner import make_test_records
 
 import frappe
 import unittest
 test_records = frappe.get_test_records('Warehouse')
 
 class TestWarehouse(unittest.TestCase):
+	def setUp(self):
+		if not frappe.get_value('Item', '_Test Item'):
+			make_test_records('Item')
+
 	def test_parent_warehouse(self):
 		parent_warehouse = frappe.get_doc("Warehouse", "_Test Warehouse Group - _TC")
 		self.assertEquals(parent_warehouse.is_group, 1)
-		
+
 	def test_warehouse_hierarchy(self):
 		p_warehouse = frappe.get_doc("Warehouse", "_Test Warehouse Group - _TC")
-		
+
 		child_warehouses =  frappe.db.sql("""select name, is_group, parent_warehouse from `tabWarehouse` wh
 			where wh.lft > %s and wh.rgt < %s""", (p_warehouse.lft, p_warehouse.rgt), as_dict=1)
-		
+
 		for child_warehouse in child_warehouses:
 			self.assertEquals(p_warehouse.name, child_warehouse.parent_warehouse)
 			self.assertEquals(child_warehouse.is_group, 0)
-	
+
 	def test_warehouse_renaming(self):
 		set_perpetual_inventory(1)
 		create_warehouse("Test Warehouse for Renaming 1")
-		
+
 		self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 1 - _TC"))
-		self.assertTrue(frappe.db.get_value("Account", 
+		self.assertTrue(frappe.db.get_value("Account",
 			filters={"warehouse": "Test Warehouse for Renaming 1 - _TC"}))
-		
+
 		# Rename with abbr
 		if frappe.db.exists("Warehouse", "Test Warehouse for Renaming 2 - _TC"):
 			frappe.delete_doc("Warehouse", "Test Warehouse for Renaming 2 - _TC")
 		rename_doc("Warehouse", "Test Warehouse for Renaming 1 - _TC", "Test Warehouse for Renaming 2 - _TC")
-		
+
 		self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 2 - _TC"))
-		self.assertTrue(frappe.db.get_value("Account", 
+		self.assertTrue(frappe.db.get_value("Account",
 			filters={"warehouse": "Test Warehouse for Renaming 2 - _TC"}))
-			
+		self.assertFalse(frappe.db.get_value("Account",
+			filters={"warehouse": "Test Warehouse for Renaming 1 - _TC"}))
+
 		# Rename without abbr
 		if frappe.db.exists("Warehouse", "Test Warehouse for Renaming 3 - _TC"):
 			frappe.delete_doc("Warehouse", "Test Warehouse for Renaming 3 - _TC")
-		
+
 		rename_doc("Warehouse", "Test Warehouse for Renaming 2 - _TC", "Test Warehouse for Renaming 3")
-		
+
 		self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 3 - _TC"))
-		self.assertTrue(frappe.db.get_value("Account", 
+		self.assertTrue(frappe.db.get_value("Account",
 			filters={"warehouse": "Test Warehouse for Renaming 3 - _TC"}))
-			
-		set_perpetual_inventory(0)
-		
+
 	def test_warehouse_merging(self):
 		set_perpetual_inventory(1)
-		
+
 		create_warehouse("Test Warehouse for Merging 1")
 		create_warehouse("Test Warehouse for Merging 2")
 
@@ -64,31 +69,29 @@
 			qty=1, rate=100)
 		make_stock_entry(item_code="_Test Item", target="Test Warehouse for Merging 2 - _TC",
 			qty=1, rate=100)
-			
+
 		existing_bin_qty = (
-			cint(frappe.db.get_value("Bin", 
+			cint(frappe.db.get_value("Bin",
 				{"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 1 - _TC"}, "actual_qty"))
-			+ cint(frappe.db.get_value("Bin", 
+			+ cint(frappe.db.get_value("Bin",
 				{"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 2 - _TC"}, "actual_qty"))
 		)
 
-		rename_doc("Warehouse", "Test Warehouse for Merging 1 - _TC", 
+		rename_doc("Warehouse", "Test Warehouse for Merging 1 - _TC",
 			"Test Warehouse for Merging 2 - _TC", merge=True)
 
 		self.assertFalse(frappe.db.exists("Warehouse", "Test Warehouse for Merging 1 - _TC"))
 
 		bin_qty = frappe.db.get_value("Bin",
 			{"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 2 - _TC"}, "actual_qty")
-			
+
 		self.assertEqual(bin_qty, existing_bin_qty)
-		
+
 		self.assertFalse(frappe.db.exists("Account", "Test Warehouse for Merging 1 - _TC"))
 		self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Merging 2 - _TC"))
-		self.assertTrue(frappe.db.get_value("Account", 
+		self.assertTrue(frappe.db.get_value("Account",
 			filters={"warehouse": "Test Warehouse for Merging 2 - _TC"}))
-			
-		set_perpetual_inventory(0)
-		
+
 def create_warehouse(warehouse_name):
 	if not frappe.db.exists("Warehouse", warehouse_name + " - _TC"):
 		w = frappe.new_doc("Warehouse")
@@ -96,5 +99,7 @@
 		w.parent_warehouse = "_Test Warehouse Group - _TC"
 		w.company = "_Test Company"
 		w.save()
-	
-	
\ No newline at end of file
+
+	if not frappe.get_value('Account', dict(warehouse=warehouse_name + ' - _TC')):
+		print 'Warehouse {0} not linked'.format(warehouse_name)
+
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index 4f5f66f..d99cdf6 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -2,7 +2,7 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
 from frappe.utils import cint, validate_email_add
 from frappe import throw, msgprint, _
 from frappe.utils.nestedset import NestedSet
@@ -53,6 +53,8 @@
 		self.update_nsm_model()
 
 	def create_account_head(self):
+		'''Create new account head if there is no account linked to this Warehouse'''
+		from erpnext.accounts.doctype.account.account import BalanceMismatchError
 		if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
 			if not self.get_account():
 				if self.get("__islocal") or not frappe.db.get_value(
@@ -76,10 +78,12 @@
 						ac_doc.insert()
 						msgprint(_("Account head {0} created").format(ac_doc.name), indicator='green', alert=True)
 
-					except frappe.DuplicateEntryError, e:
-						if not (e.args and e.args[0]=='Account'):
-							# if this is not due to creation of Account
-							raise
+					except frappe.DuplicateEntryError:
+						msgprint(_("Please create an Account for this Warehouse and link it. This cannot be done automatically as an account with name {0} already exists").format(frappe.bold(self.name)),
+							indicator='orange')
+
+					except BalanceMismatchError:
+						msgprint(_("Cannot automatically create Account as there is already stock balance in the Account. You must create a matching account before you can make an entry on this warehouse"))
 
 	def validate_parent_account(self):
 		if not self.company:
@@ -111,7 +115,7 @@
 			else:
 				frappe.db.sql("delete from `tabBin` where name = %s", d['name'])
 
-		warehouse_account = self.get_account(self.name)
+		warehouse_account = self.get_account()
 		if warehouse_account:
 			frappe.delete_doc("Account", warehouse_account)
 
@@ -131,10 +135,9 @@
 		return frappe.db.sql("""select name from `tabWarehouse`
 			where parent_warehouse = %s""", self.name)
 
-	def before_rename(self, olddn, newdn, merge=False):
+	def before_rename(self, old_name, new_name, merge=False):
 		# Add company abbr if not provided
-		from erpnext.setup.doctype.company.company import get_name_with_abbr
-		new_warehouse = get_name_with_abbr(newdn, self.company)
+		new_warehouse = erpnext.encode_company_abbr(new_name, self.company)
 
 		if merge:
 			if not frappe.db.exists("Warehouse", new_warehouse):
@@ -143,64 +146,54 @@
 			if self.company != frappe.db.get_value("Warehouse", new_warehouse, "company"):
 				frappe.throw(_("Both Warehouse must belong to same Company"))
 
-		self.rename_account_for(olddn, new_warehouse, merge)
+		self.rename_account_for(old_name, new_warehouse, merge)
 
 		return new_warehouse
 
-	def rename_account_for(self, olddn, newdn, merge):
-		if self.is_group:
-			old_account = self.get_account()
-		else:
-			old_account = self.get_account(olddn)
+	def rename_account_for(self, old_name, new_name, merge):
+		old_account_name = frappe.get_value('Account', dict(warehouse=old_name))
 
-		if old_account:
-			new_account = None
+		if old_account_name:
 			if not merge:
-				if old_account == self.add_abbr_if_missing(olddn):
-					new_account = frappe.rename_doc("Account", old_account, newdn)
+				# old account name is same as old name, so rename the account too
+				if old_account_name == erpnext.encode_company_abbr(old_name, self.company):
+					frappe.rename_doc("Account", old_account_name, new_name)
 			else:
-				existing_new_account = self.get_account(newdn)
-				new_account = frappe.rename_doc("Account", old_account,
-					existing_new_account or newdn, merge=True if existing_new_account else False)
+				# merge
+				target_account = frappe.get_value('Account', dict(warehouse=new_name))
+				if target_account:
+					# target warehouse has account, merge into target account
+					frappe.rename_doc("Account", old_account_name,
+						target_account, merge=True)
+				else:
+					# target warehouse does not have account, use this account
+					frappe.rename_doc("Account", old_account_name,
+						new_name, merge=False)
 
-			frappe.db.set_value("Account", new_account or old_account, "warehouse", newdn)
+					# rename link
+					frappe.db.set_value('Account', new_name, 'warehouse', new_name)
 
-	def add_abbr_if_missing(self, dn):
-		from erpnext.setup.doctype.company.company import get_name_with_abbr
-		return get_name_with_abbr(dn, self.company)
+	def get_account(self):
+		return frappe.get_value('Account', dict(warehouse=self.name))
 
-	def get_account(self, warehouse=None):
-		filters = {
-			"account_type": "Stock",
-			"company": self.company,
-			"is_group": self.is_group
-		}
-
-		if warehouse:
-			filters.update({"warehouse": warehouse})
-		else:
-			filters.update({"account_name": self.warehouse_name})
-
-		return frappe.db.get_value("Account", filters)
-
-	def after_rename(self, olddn, newdn, merge=False):
+	def after_rename(self, old_name, new_name, merge=False):
 		if merge:
-			self.recalculate_bin_qty(newdn)
+			self.recalculate_bin_qty(new_name)
 
-	def recalculate_bin_qty(self, newdn):
+	def recalculate_bin_qty(self, new_name):
 		from erpnext.stock.stock_balance import repost_stock
 		frappe.db.auto_commit_on_many_writes = 1
 		existing_allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock")
 		frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
 
 		repost_stock_for_items = frappe.db.sql_list("""select distinct item_code
-			from tabBin where warehouse=%s""", newdn)
+			from tabBin where warehouse=%s""", new_name)
 
 		# Delete all existing bins to avoid duplicate bins for the same item and warehouse
-		frappe.db.sql("delete from `tabBin` where warehouse=%s", newdn)
+		frappe.db.sql("delete from `tabBin` where warehouse=%s", new_name)
 
 		for item_code in repost_stock_for_items:
-			repost_stock(item_code, newdn)
+			repost_stock(item_code, new_name)
 
 		frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock)
 		frappe.db.auto_commit_on_many_writes = 0
@@ -231,7 +224,7 @@
 		if self.check_if_sle_exists():
 			throw(_("Warehouses with existing transaction can not be converted to group."))
 		else:
-			account_name = self.get_account(self.name)
+			account_name = self.get_account()
 			if account_name:
 				doc = frappe.get_doc("Account", account_name)
 				doc.flags.exclude_account_type_check = True
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.js b/erpnext/support/doctype/warranty_claim/warranty_claim.js
index abd207b..2369a8a 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.js
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.js
@@ -21,7 +21,7 @@
 
 erpnext.support.WarrantyClaim = frappe.ui.form.Controller.extend({
 	refresh: function() {
-		frappe.contact_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+		frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
 
 		if(!cur_frm.doc.__islocal &&
 			(cur_frm.doc.status=='Open' || cur_frm.doc.status == 'Work In Progress')) {
diff --git a/erpnext/utilities/address_and_contact.py b/erpnext/utilities/address_and_contact.py
index eaa71f9..f3435ae 100644
--- a/erpnext/utilities/address_and_contact.py
+++ b/erpnext/utilities/address_and_contact.py
@@ -122,7 +122,7 @@
 def delete_contact_and_address(doctype, name):
 	for parenttype in ('Contact', 'Address'):
 		items = frappe.db.sql("""select parent from `tabDynamic Link`
-			where parenttype=%s and link_type=%s and link_name=%s""",
+			where parenttype=%s and link_doctype=%s and link_name=%s""",
 			(parenttype, doctype, name))
 
 		for name in items: