Merge pull request #3609 from rmehta/address-link

[fix] link address via owner, if created in portal #3540
diff --git a/erpnext/__version__.py b/erpnext/__version__.py
index c8b2f49..2c86e6c 100644
--- a/erpnext/__version__.py
+++ b/erpnext/__version__.py
@@ -1,2 +1,2 @@
 from __future__ import unicode_literals
-__version__ = '5.1.3'
+__version__ = '5.1.4'
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json
index ad224f1..0c5a4bb 100644
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.json
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json
@@ -78,6 +78,51 @@
    "reqd": 1
   }, 
   {
+   "fieldname": "warehouse", 
+   "fieldtype": "Link", 
+   "label": "Warehouse", 
+   "oldfieldname": "warehouse", 
+   "oldfieldtype": "Link", 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "read_only": 0, 
+   "reqd": 0
+  }, 
+  {
+   "allow_on_submit": 1, 
+   "fieldname": "letter_head", 
+   "fieldtype": "Link", 
+   "label": "Letter Head", 
+   "oldfieldname": "letter_head", 
+   "oldfieldtype": "Select", 
+   "options": "Letter Head", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "read_only": 0
+  }, 
+  {
+   "fieldname": "tc_name", 
+   "fieldtype": "Link", 
+   "label": "Terms and Conditions", 
+   "oldfieldname": "tc_name", 
+   "oldfieldtype": "Link", 
+   "options": "Terms and Conditions", 
+   "permlevel": 0, 
+   "read_only": 0
+  }, 
+  {
+   "allow_on_submit": 1, 
+   "fieldname": "select_print_heading", 
+   "fieldtype": "Link", 
+   "in_filter": 0, 
+   "label": "Print Heading", 
+   "oldfieldname": "select_print_heading", 
+   "oldfieldtype": "Select", 
+   "options": "Print Heading", 
+   "permlevel": 0, 
+   "read_only": 0
+  }, 
+  {
    "fieldname": "column_break0", 
    "fieldtype": "Column Break", 
    "oldfieldtype": "Column Break", 
@@ -106,6 +151,14 @@
    "reqd": 0
   }, 
   {
+   "fieldname": "mode_of_payment", 
+   "fieldtype": "Link", 
+   "label": "Mode of Payment", 
+   "options": "Mode of Payment", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "cash_bank_account", 
    "fieldtype": "Link", 
    "label": "Cash/Bank Account", 
@@ -140,17 +193,6 @@
    "reqd": 0
   }, 
   {
-   "fieldname": "warehouse", 
-   "fieldtype": "Link", 
-   "label": "Warehouse", 
-   "oldfieldname": "warehouse", 
-   "oldfieldtype": "Link", 
-   "options": "Warehouse", 
-   "permlevel": 0, 
-   "read_only": 0, 
-   "reqd": 0
-  }, 
-  {
    "fieldname": "cost_center", 
    "fieldtype": "Link", 
    "label": "Cost Center", 
@@ -162,16 +204,6 @@
    "reqd": 1
   }, 
   {
-   "fieldname": "taxes_and_charges", 
-   "fieldtype": "Link", 
-   "label": "Taxes and Charges", 
-   "oldfieldname": "charge", 
-   "oldfieldtype": "Link", 
-   "options": "Sales Taxes and Charges Template", 
-   "permlevel": 0, 
-   "read_only": 0
-  }, 
-  {
    "fieldname": "write_off_account", 
    "fieldtype": "Link", 
    "label": "Write Off Account", 
@@ -190,43 +222,19 @@
    "reqd": 1
   }, 
   {
-   "allow_on_submit": 1, 
-   "fieldname": "letter_head", 
+   "fieldname": "taxes_and_charges", 
    "fieldtype": "Link", 
-   "label": "Letter Head", 
-   "oldfieldname": "letter_head", 
-   "oldfieldtype": "Select", 
-   "options": "Letter Head", 
-   "permlevel": 0, 
-   "print_hide": 1, 
-   "read_only": 0
-  }, 
-  {
-   "fieldname": "tc_name", 
-   "fieldtype": "Link", 
-   "label": "Terms and Conditions", 
-   "oldfieldname": "tc_name", 
+   "label": "Taxes and Charges", 
+   "oldfieldname": "charge", 
    "oldfieldtype": "Link", 
-   "options": "Terms and Conditions", 
-   "permlevel": 0, 
-   "read_only": 0
-  }, 
-  {
-   "allow_on_submit": 1, 
-   "fieldname": "select_print_heading", 
-   "fieldtype": "Link", 
-   "in_filter": 0, 
-   "label": "Print Heading", 
-   "oldfieldname": "select_print_heading", 
-   "oldfieldtype": "Select", 
-   "options": "Print Heading", 
+   "options": "Sales Taxes and Charges Template", 
    "permlevel": 0, 
    "read_only": 0
   }
  ], 
  "icon": "icon-cog", 
  "idx": 1, 
- "modified": "2015-05-20 05:38:44.482696", 
+ "modified": "2015-07-07 08:56:04.381471", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "POS Profile", 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 50a79ec..af144cb 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -124,20 +124,11 @@
 			}
 		})
 
-		if cint(frappe.defaults.get_global_default('maintain_same_rate')):
-			super(PurchaseInvoice, self).validate_with_previous_doc({
-				"Purchase Order Item": {
-					"ref_dn_field": "po_detail",
-					"compare_fields": [["rate", "="]],
-					"is_child_table": True,
-					"allow_duplicate_prev_row_id": True
-				},
-				"Purchase Receipt Item": {
-					"ref_dn_field": "pr_detail",
-					"compare_fields": [["rate", "="]],
-					"is_child_table": True
-				}
-			})
+		if cint(frappe.db.get_single_value('Buying Settings', 'maintain_same_rate')):
+			self.validate_rate_with_reference_doc([
+				["Purchase Order", "purchase_order", "po_detail"], 
+				["Purchase Receipt", "purchase_receipt", "pr_detail"]
+			])
 
 	def set_against_expense_account(self):
 		auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 70d5f4a..809e352 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -605,7 +605,7 @@
    "label": "Total Advance", 
    "oldfieldname": "total_advance", 
    "oldfieldtype": "Currency", 
-   "options": "", 
+   "options": "Company:company:default_currency", 
    "permlevel": 0, 
    "print_hide": 1, 
    "read_only": 1
@@ -618,7 +618,7 @@
    "no_copy": 1, 
    "oldfieldname": "outstanding_amount", 
    "oldfieldtype": "Currency", 
-   "options": "currency", 
+   "options": "Company:company:default_currency", 
    "permlevel": 0, 
    "print_hide": 1, 
    "read_only": 1
@@ -671,7 +671,7 @@
    "no_copy": 1, 
    "oldfieldname": "paid_amount", 
    "oldfieldtype": "Currency", 
-   "options": "currency", 
+   "options": "Company:company:default_currency", 
    "permlevel": 0, 
    "print_hide": 1, 
    "read_only": 0
@@ -711,7 +711,7 @@
    "fieldtype": "Currency", 
    "label": "Write Off Amount", 
    "no_copy": 1, 
-   "options": "currency", 
+   "options": "Company:company:default_currency", 
    "permlevel": 0, 
    "print_hide": 1, 
    "read_only": 0
@@ -1253,7 +1253,7 @@
  "icon": "icon-file-text", 
  "idx": 1, 
  "is_submittable": 1, 
- "modified": "2015-07-03 03:25:40.519956", 
+ "modified": "2015-07-09 17:33:28.583808", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Invoice", 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 604370b..f3acc74 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -169,6 +169,7 @@
 		if pos:
 			if not for_validate and not self.customer:
 				self.customer = pos.customer
+				self.mode_of_payment = pos.mode_of_payment
 				# self.set_customer_defaults()
 
 			for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name',
@@ -263,20 +264,11 @@
 			},
 		})
 
-		if cint(frappe.defaults.get_global_default('maintain_same_sales_rate')):
-			super(SalesInvoice, self).validate_with_previous_doc({
-				"Sales Order Item": {
-					"ref_dn_field": "so_detail",
-					"compare_fields": [["rate", "="]],
-					"is_child_table": True,
-					"allow_duplicate_prev_row_id": True
-				},
-				"Delivery Note Item": {
-					"ref_dn_field": "dn_detail",
-					"compare_fields": [["rate", "="]],
-					"is_child_table": True
-				}
-			})
+		if cint(frappe.db.get_single_value('Selling Settings', 'maintain_same_sales_rate')):
+			self.validate_rate_with_reference_doc([
+				["Sales Order", "sales_order", "so_detail"], 
+				["Delivery Note", "delivery_note", "dn_detail"]
+			])
 
 	def set_against_income_account(self):
 		"""Set against account for debit to account"""
diff --git a/erpnext/change_log/v5/v5_1_4.md b/erpnext/change_log/v5/v5_1_4.md
new file mode 100644
index 0000000..c11af81
--- /dev/null
+++ b/erpnext/change_log/v5/v5_1_4.md
@@ -0,0 +1,4 @@
+- Mode of Payment added to POS Profile
+- Expired Batch is not allowed in stock entry of type manufacturing / repack
+- Validate item rate against reference document with tolerance 0.009
+- Set Customer name in opportunity as per company name in lead
\ No newline at end of file
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 4f35fea..801f6f2 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -229,9 +229,10 @@
 			}, { "start": start, "page_len": page_len, "txt": ("%%%s%%" % txt) })
 
 def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
-	if not filters.get("posting_date"):
-		filters["posting_date"] = nowdate()
-
+	cond = ""
+	if filters.get("posting_date"):
+		cond = "and (ifnull(batch.expiry_date, '')='' or batch.expiry_date >= %(posting_date)s)"
+	
 	batch_nos = None
 	args = {
 		'item_code': filters.get("item_code"),
@@ -251,23 +252,23 @@
 					and sle.warehouse = %(warehouse)s
 					and sle.batch_no like %(txt)s
 					and batch.docstatus < 2
-					and (ifnull(batch.expiry_date, '')='' or batch.expiry_date >= %(posting_date)s)
+					{0}
 					{match_conditions}
 				group by batch_no having sum(sle.actual_qty) > 0
 				order by batch.expiry_date, sle.batch_no desc
-				limit %(start)s, %(page_len)s""".format(match_conditions=get_match_cond(doctype)), args)
+				limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args)
 
 	if batch_nos:
 		return batch_nos
 	else:
-		return frappe.db.sql("""select name, expiry_date from `tabBatch`
+		return frappe.db.sql("""select name, expiry_date from `tabBatch` batch
 			where item = %(item_code)s
 			and name like %(txt)s
 			and docstatus < 2
-			and (ifnull(expiry_date, '')='' or expiry_date >= %(posting_date)s)
+			{0}
 			{match_conditions}
 			order by expiry_date, name desc
-			limit %(start)s, %(page_len)s""".format(match_conditions=get_match_cond(doctype)), args)
+			limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args, debug=1)
 
 def get_account_list(doctype, txt, searchfield, start, page_len, filters):
 	filter_list = []
diff --git a/erpnext/crm/doctype/newsletter_list/newsletter_list.py b/erpnext/crm/doctype/newsletter_list/newsletter_list.py
index 3a580d3..bf78676 100644
--- a/erpnext/crm/doctype/newsletter_list/newsletter_list.py
+++ b/erpnext/crm/doctype/newsletter_list/newsletter_list.py
@@ -12,8 +12,8 @@
 class NewsletterList(Document):
 	def onload(self):
 		singles = [d.name for d in frappe.db.get_all("DocType", "name", {"issingle": 1})]
-		self.get("__onload").import_types = [d.parent \
-			for d in frappe.db.get_all("DocField", "parent", {"options": "Email"}) if d.parent not in singles]
+		self.get("__onload").import_types = [{"value": d.parent, "label": "{0} ({1})".format(d.parent, d.label)} \
+			for d in frappe.db.get_all("DocField", ("parent", "label"), {"options": "Email"}) if d.parent not in singles]
 
 	def import_from(self, doctype):
 		"""Extract email ids from given doctype and add them to the current list"""
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 0225398..78729a3 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -79,7 +79,8 @@
 		if self.customer:
 			self.customer_name = frappe.db.get_value("Customer", self.customer, "customer_name")
 		elif self.lead:
-			self.customer_name = frappe.db.get_value("Lead", self.lead, "lead_name")
+			lead_name, company_name = frappe.db.get_value("Lead", self.lead, ["lead_name", "company_name"])
+			self.customer_name = company_name or lead_name
 
 	def get_cust_address(self,name):
 		details = frappe.db.sql("""select customer_name, address, territory, customer_group
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 15d663c..ef1afa3 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -5,7 +5,7 @@
 app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
 app_icon = "icon-th"
 app_color = "#e74c3c"
-app_version = "5.1.3"
+app_version = "5.1.4"
 
 error_report_email = "support@erpnext.com"
 
diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json
index 7dfc0b8..710f4e2 100644
--- a/erpnext/hr/doctype/employee/employee.json
+++ b/erpnext/hr/doctype/employee/employee.json
@@ -290,6 +290,7 @@
    "label": "Company Email", 
    "oldfieldname": "company_email", 
    "oldfieldtype": "Data", 
+   "options": "Email", 
    "permlevel": 0, 
    "reqd": 0
   }, 
@@ -385,6 +386,7 @@
    "fieldname": "personal_email", 
    "fieldtype": "Data", 
    "label": "Personal Email", 
+   "options": "Email", 
    "permlevel": 0
   }, 
   {
@@ -674,7 +676,7 @@
  ], 
  "icon": "icon-user", 
  "idx": 1, 
- "modified": "2015-02-20 05:02:14.205144", 
+ "modified": "2015-07-09 02:25:20.987412", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Employee", 
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.js b/erpnext/hr/doctype/salary_manager/salary_manager.js
index 240547c..ca70226 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.js
+++ b/erpnext/hr/doctype/salary_manager/salary_manager.js
@@ -1,30 +1,44 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-var display_activity_log = function(msg) {
+cur_frm.cscript.display_activity_log = function(msg) {
 	if(!cur_frm.ss_html)
 		cur_frm.ss_html = $a(cur_frm.fields_dict['activity_log'].wrapper,'div');
-	cur_frm.ss_html.innerHTML =
-		'<div class="padding"><h4>'+__("Activity Log:")+'</h4>'+msg+'</div>';
+	if(msg) {
+		cur_frm.ss_html.innerHTML =
+			'<div class="padding"><h4>'+__("Activity Log:")+'</h4>'+msg+'</div>';
+	} else {
+		cur_frm.ss_html.innerHTML = "";
+	}
 }
 
 //Create salary slip
 //-----------------------
 cur_frm.cscript.create_salary_slip = function(doc, cdt, cdn) {
+	cur_frm.cscript.display_activity_log("");
 	var callback = function(r, rt){
 		if (r.message)
-			display_activity_log(r.message);
+			cur_frm.cscript.display_activity_log(r.message);
 	}
 	return $c('runserverobj', args={'method':'create_sal_slip','docs':doc},callback);
 }
 
 cur_frm.cscript.submit_salary_slip = function(doc, cdt, cdn) {
+	cur_frm.cscript.display_activity_log("");
 	var check = confirm(__("Do you really want to Submit all Salary Slip for month {0} and year {1}", [doc.month, doc.fiscal_year]));
 	if(check){
+		// clear all in locals
+		if(locals["Salary Slip"]) {
+			$.each(locals["Salary Slip"], function(name, d) {
+				frappe.model.remove_from_locals("Salary Slip", name);
+			});
+		}
+
 		var callback = function(r, rt){
 			if (r.message)
-				display_activity_log(r.message);
+				cur_frm.cscript.display_activity_log(r.message);
 		}
+
 		return $c('runserverobj', args={'method':'submit_salary_slip','docs':doc},callback);
 	}
 }
@@ -47,4 +61,4 @@
 
 frappe.ui.form.on("Salary Manager", "refresh", function(frm) {
 	frm.disable_save();
-});
\ No newline at end of file
+});
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.py b/erpnext/hr/doctype/salary_manager/salary_manager.py
index eeb6ac0..3e0b53e 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.py
+++ b/erpnext/hr/doctype/salary_manager/salary_manager.py
@@ -101,7 +101,7 @@
 		log = "<p>No employee for the above selected criteria OR salary slip already created</p>"
 		if ss_list:
 			log = "<b>Salary Slip Created For</b>\
-			<br><br>%s" % '<br>'.join(ss_list)
+			<br><br>%s" % '<br>'.join(self.format_as_links(ss_list))
 		return log
 
 
@@ -144,7 +144,7 @@
 		else:
 			all_ss = [d[0] for d in all_ss]
 
-		submitted_ss = list(set(all_ss) - set(not_submitted_ss))
+		submitted_ss = self.format_as_links(list(set(all_ss) - set(not_submitted_ss)))
 		if submitted_ss:
 			mail_sent_msg = self.send_email and " (Mail has been sent to the employee)" or ""
 			log = """
@@ -164,6 +164,9 @@
 			"""% ('<br>'.join(not_submitted_ss))
 		return log
 
+	def format_as_links(self, ss_list):
+		return ['<a href="#Form/Salary Slip/{0}">{0}</a>'.format(s) for s in ss_list]
+
 
 	def get_total_salary(self):
 		"""
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index 17fbc5e..6d16cd4 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -250,7 +250,8 @@
 cur_frm.fields_dict['production_item'].get_query = function(doc) {
 	return {
 		filters:[
-			['Item', 'is_pro_applicable', '=', 'Yes']
+			['Item', 'is_pro_applicable', '=', 'Yes'],
+			['Item', 'has_variants', '=', 'No']
 		]
 	}
 }
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 0274b7e..0f805d0 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -30,6 +30,7 @@
 		validate_status(self.status, ["Draft", "Submitted", "Stopped",
 			"In Process", "Completed", "Cancelled"])
 
+		self.validate_production_item()
 		if self.bom_no:
 			validate_bom_no(self.production_item, self.bom_no)
 
@@ -319,6 +320,13 @@
 	def delete_time_logs(self):
 		for time_log in frappe.get_all("Time Log", ["name"], {"production_order": self.name}):
 			frappe.delete_doc("Time Log", time_log.name)
+	
+	def validate_production_item(self):
+		if frappe.db.get_value("Item", self.production_item, "is_pro_applicable")=='No':
+			frappe.throw(_("Item is not allowed to have Production Order."))
+		
+		if frappe.db.get_value("Item", self.production_item, "has_variants"):
+			frappe.throw(_("Production Order cannot be raised against a Item Template"))
 
 @frappe.whitelist()
 def get_item_details(item):
diff --git a/erpnext/public/js/pos/pos.js b/erpnext/public/js/pos/pos.js
index 164e883..70f3023 100644
--- a/erpnext/public/js/pos/pos.js
+++ b/erpnext/public/js/pos/pos.js
@@ -401,7 +401,8 @@
 
 			this.with_modes_of_payment(function() {
 				// prefer cash payment!
-				var default_mode = me.modes_of_payment.indexOf(__("Cash"))!==-1 ? __("Cash") : undefined;
+				var default_mode = me.frm.doc.mode_of_payment ? me.frm.doc.mode_of_payment : 
+					me.modes_of_payment.indexOf(__("Cash"))!==-1 ? __("Cash") : undefined;
 
 				// show payment wizard
 				var dialog = new frappe.ui.Dialog({
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 775eb41..cd65d18 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -71,7 +71,7 @@
 				} else {
 					filters = {
 						'item_code': item.item_code,
-						'posting_date': me.frm.doc.posting_date,
+						'posting_date': me.frm.doc.posting_date || nowdate(),
 					}
 					if(item.warehouse) filters["warehouse"] = item.warehouse
 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index f52f7e5..90a8a6c 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -108,11 +108,9 @@
 		if not self.installation_status: self.installation_status = 'Not Installed'
 
 	def validate_with_previous_doc(self):
-		items = self.get("items")
-
 		for fn in (("Sales Order", "against_sales_order", "so_detail"), 
 				("Sales Invoice", "against_sales_invoice", "si_detail")):
-			if filter(None, [getattr(d, fn[1], None) for d in items]):
+			if filter(None, [getattr(d, fn[1], None) for d in self.get("items")]):
 				super(DeliveryNote, self).validate_with_previous_doc({
 					fn[0]: {
 						"ref_dn_field": fn[1],
@@ -120,15 +118,10 @@
 							["currency", "="]],
 					},
 				})
-
-				if cint(frappe.defaults.get_global_default('maintain_same_sales_rate')):
-					super(DeliveryNote, self).validate_with_previous_doc({
-						fn[0] + " Item": {
-							"ref_dn_field": fn[2],
-							"compare_fields": [["rate", "="]],
-							"is_child_table": True
-						}
-					})
+				
+		if cint(frappe.db.get_single_value('Selling Settings', 'maintain_same_sales_rate')):
+			self.validate_rate_with_reference_doc([["Sales Order", "sales_order", "so_detail"], 
+				["Sales Invoice", "sales_invoice", "si_detail"]])
 
 	def validate_proj_cust(self):
 		"""check for does customer belong to same project as entered.."""
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index acf2764..45606b0 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -216,7 +216,7 @@
    "options": "Variant Attribute", 
    "permlevel": 0, 
    "precision": "", 
-   "read_only": 0
+   "read_only": 1
   }, 
   {
    "fieldname": "inventory", 
@@ -900,9 +900,9 @@
   }
  ], 
  "icon": "icon-tag", 
- "idx": 1,
+ "idx": 1, 
  "max_attachments": 1, 
- "modified": "2015-07-01 17:20:18.204558", 
+ "modified": "2015-07-09 02:23:47.669199", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Item", 
diff --git a/erpnext/stock/doctype/manage_variants/manage_variants.js b/erpnext/stock/doctype/manage_variants/manage_variants.js
index e8b7ade..edbfcd2 100644
--- a/erpnext/stock/doctype/manage_variants/manage_variants.js
+++ b/erpnext/stock/doctype/manage_variants/manage_variants.js
@@ -42,6 +42,10 @@
 			})
 		});
 	},
+	
+	onload_post_render: function(frm) {
+		frm.get_field("variants").grid.cannot_add_rows = true;
+	},
 
 	item_code:function(frm) {
 		return frappe.call({
diff --git a/erpnext/stock/doctype/manage_variants/manage_variants.py b/erpnext/stock/doctype/manage_variants/manage_variants.py
index b6784d3..4dcfb22 100644
--- a/erpnext/stock/doctype/manage_variants/manage_variants.py
+++ b/erpnext/stock/doctype/manage_variants/manage_variants.py
@@ -36,8 +36,8 @@
 	def get_attributes(self):
 		attributes = {}
 		self.set('attributes', [])
-		for d in frappe.db.sql("""select attribute, attribute_value from `tabVariant Attribute` as attribute, 
-			`tabItem` as item where attribute.parent= item.name and item.variant_of = %s""", self.item_code, as_dict=1):
+		for d in frappe.db.sql("""select attr.attribute, attr.attribute_value from `tabVariant Attribute` as attr, 
+			`tabItem` as item where attr.parent = item.name and item.variant_of = %s""", self.item_code, as_dict=1):
 				attributes.setdefault(d.attribute, []).append(d.attribute_value)
 		for d in attributes:
 			attribute_values = set(attributes[d])
diff --git a/erpnext/stock/doctype/manage_variants/test_manage_variants.py b/erpnext/stock/doctype/manage_variants/test_manage_variants.py
index 9952ba9..6aa7f83 100644
--- a/erpnext/stock/doctype/manage_variants/test_manage_variants.py
+++ b/erpnext/stock/doctype/manage_variants/test_manage_variants.py
@@ -11,7 +11,7 @@
 	def test_variant_item_codes(self):
 		manage_variant = frappe.new_doc("Manage Variants")
 		manage_variant.update({
-			"item": "_Test Variant Item",
+			"item_code": "_Test Variant Item",
 			"attributes": [
 				{
 					"attribute": "Test Size",
@@ -34,7 +34,7 @@
 	def test_attributes_are_unique(self):
 		manage_variant = frappe.new_doc("Manage Variants")
 		manage_variant.update({
-			"item": "_Test Variant Item",
+			"item_code": "_Test Variant Item",
 			"attributes": [
 				{
 					"attribute": "Test Size",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index e56cd1e..e782889 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -104,15 +104,8 @@
 			}
 		})
 
-		if cint(frappe.defaults.get_global_default('maintain_same_rate')):
-			super(PurchaseReceipt, self).validate_with_previous_doc({
-				"Purchase Order Item": {
-					"ref_dn_field": "prevdoc_detail_docname",
-					"compare_fields": [["rate", "="]],
-					"is_child_table": True
-				}
-			})
-
+		if cint(frappe.db.get_single_value('Buying Settings', 'maintain_same_rate')):
+			self.validate_rate_with_reference_doc([["Purchase Order", "prevdoc_docname", "prevdoc_detail_docname"]])
 
 	def po_required(self):
 		if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 1135bc7..465b641 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -411,14 +411,21 @@
 	var item = locals[cdt][cdn];
 	if(!item.item_code) {
 		frappe.throw(__("Please enter Item Code to get batch no"));
-	} else {
-		var filters = {
-			'item_code': item.item_code,
-			'posting_date': me.frm.doc.posting_date,
+	}
+	else {
+		if (in_list(["Material Transfer for Manufacture", "Manufacture", "Repack", "Subcontract"], doc.purpose)) {
+			var filters = {
+				'item_code': item.item_code,
+				'posting_date': me.frm.doc.posting_date || nowdate()
+			}	
+		} else {
+			var filters = {
+				'item_code': item.item_code
+			}
 		}
+		
 
 		if(item.s_warehouse) filters["warehouse"] = item.s_warehouse
-
 		return {
 			query : "erpnext.controllers.queries.get_batch_no",
 			filters: filters
@@ -498,9 +505,9 @@
 }
 
 cur_frm.cscript.validate = function(doc, cdt, cdn) {
-	cur_frm.cscript.validate_items(doc);
 	if($.inArray(cur_frm.doc.purpose, ["Purchase Return", "Sales Return"])!==-1)
 		validated = cur_frm.cscript.get_doctype_docname() ? true : false;
+	cur_frm.cscript.validate_items(doc);
 }
 
 cur_frm.cscript.validate_items = function(doc) {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 813a61b..93fd325 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -727,7 +727,7 @@
 						frappe.MappingMismatchError)
 						
 	def validate_batch(self):
-		if self.purpose == "Material Transfer for Manufacture":
+		if self.purpose in ["Material Transfer for Manufacture", "Manufacture", "Repack", "Subcontract"]:
 			for item in self.get("items"):
 				if item.batch_no:
 					if getdate(self.posting_date) > getdate(frappe.db.get_value("Batch", item.batch_no, "expiry_date")):
@@ -870,8 +870,6 @@
 			"account": r.get("account"),
 			"party_type": r.get("party_type"),
 			"party": r.get("party"),
-			"against_invoice": r.get("against_invoice"),
-			"against_voucher": r.get("against_voucher"),
 			"balance": get_balance_on(r.get("account"), se.posting_date) if r.get("account") else 0
 		})
 
@@ -882,8 +880,7 @@
 	parent = {
 		"account": ref.doc.debit_to,
 		"party_type": "Customer",
-		"party": ref.doc.customer,
-		"against_invoice": ref.doc.name,
+		"party": ref.doc.customer
 	}
 
 	# income account entries
@@ -957,9 +954,6 @@
 
 			break
 
-	if len(invoices_against_delivery) == 1:
-		parent["against_invoice"] = invoices_against_delivery[0]
-
 	result = [parent] + [{"account": account} for account in children]
 
 	return result
@@ -1015,9 +1009,6 @@
 
 			break
 
-	if len(invoice_against_receipt) == 1:
-		parent["against_voucher"] = invoice_against_receipt[0]
-
 	result = [parent] + [{"account": account} for account in children]
 
 	return result
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 8114bef..589f1ed 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -73,8 +73,9 @@
 
 	def test_auto_material_request_for_variant(self):
 		manage_variant = frappe.new_doc("Manage Variants")
+		
 		manage_variant.update({
-			"item": "_Test Variant Item",
+			"item_code": "_Test Variant Item",
 			"attributes": [
 				{
 					"attribute": "Test Size",
@@ -391,7 +392,6 @@
 		self.assertEqual(jv.get("accounts")[0].get("account"), "Debtors - _TC")
 		self.assertEqual(jv.get("accounts")[0].get("party_type"), "Customer")
 		self.assertEqual(jv.get("accounts")[0].get("party"), "_Test Customer")
-		self.assertTrue(jv.get("accounts")[0].get("against_invoice"))
 		self.assertEqual(jv.get("accounts")[1].get("account"), "Sales - _TC")
 
 	def test_make_return_jv_for_sales_invoice_non_packing_item(self):
@@ -496,7 +496,6 @@
 		self.assertEqual(jv.get("accounts")[0].get("account"), "_Test Payable - _TC")
 		self.assertEqual(jv.get("accounts")[0].get("party"), "_Test Supplier")
 		self.assertEqual(jv.get("accounts")[1].get("account"), "_Test Account Cost for Goods Sold - _TC")
-		self.assertTrue(jv.get("accounts")[0].get("against_voucher"))
 
 	def test_make_return_jv_for_purchase_receipt(self):
 		se, pr_name = self.test_purchase_receipt_return()
diff --git a/erpnext/tests/test_client.py b/erpnext/tests/test_client.py
index ef412bf..153ce75 100644
--- a/erpnext/tests/test_client.py
+++ b/erpnext/tests/test_client.py
@@ -8,18 +8,18 @@
 
 selenium_tests = True
 
-class TestLogin(unittest.TestCase):
-	def setUp(self):
-		sel.login()
-
-	def test_material_request(self):
-		sel.new_doc("Stock", "Material Request")
-		sel.set_field("company", "_Test Company")
-		sel.add_child("items")
-		sel.set_field("item_code", "_Test Item")
-		sel.set_field("qty", "1")
-		sel.set_field("warehouse", "_Test Warehouse - _TC")
-		sel.set_field("schedule_date", formatdate())
-		sel.done_add_child("items")
-		sel.primary_action()
-		sel.wait_for_state("clean")
+# class TestLogin(unittest.TestCase):
+# 	def setUp(self):
+# 		sel.login()
+#
+# 	def test_material_request(self):
+# 		sel.new_doc("Stock", "Material Request")
+# 		sel.set_field("company", "_Test Company")
+# 		sel.add_child("items")
+# 		sel.set_field("item_code", "_Test Item")
+# 		sel.set_field("qty", "1")
+# 		sel.set_field("warehouse", "_Test Warehouse - _TC")
+# 		sel.set_field("schedule_date", formatdate())
+# 		sel.done_add_child("items")
+# 		sel.primary_action()
+# 		sel.wait_for_state("clean")
diff --git a/erpnext/utilities/doctype/contact/contact.json b/erpnext/utilities/doctype/contact/contact.json
index c71ed60..d2296ca 100644
--- a/erpnext/utilities/doctype/contact/contact.json
+++ b/erpnext/utilities/doctype/contact/contact.json
@@ -75,7 +75,7 @@
    "permlevel": 0
   }, 
   {
-   "depends_on": "eval:!doc.supplier && !doc.sales_partner", 
+   "depends_on": "", 
    "fieldname": "customer", 
    "fieldtype": "Link", 
    "label": "Customer", 
@@ -86,7 +86,7 @@
    "print_hide": 0
   }, 
   {
-   "depends_on": "eval:!doc.supplier && !doc.sales_partner", 
+   "depends_on": "", 
    "fieldname": "customer_name", 
    "fieldtype": "Data", 
    "in_list_view": 0, 
@@ -102,7 +102,7 @@
    "width": "50%"
   }, 
   {
-   "depends_on": "eval:!doc.customer && !doc.sales_partner", 
+   "depends_on": "", 
    "fieldname": "supplier", 
    "fieldtype": "Link", 
    "label": "Supplier", 
@@ -111,7 +111,7 @@
   }, 
   {
    "allow_on_submit": 0, 
-   "depends_on": "eval:!doc.customer && !doc.sales_partner", 
+   "depends_on": "", 
    "fieldname": "supplier_name", 
    "fieldtype": "Data", 
    "in_list_view": 0, 
@@ -120,7 +120,7 @@
    "read_only": 1
   }, 
   {
-   "depends_on": "eval:!doc.customer && !doc.supplier", 
+   "depends_on": "", 
    "fieldname": "sales_partner", 
    "fieldtype": "Link", 
    "label": "Sales Partner", 
@@ -177,7 +177,7 @@
  "idx": 1, 
  "in_create": 0, 
  "in_dialog": 0, 
- "modified": "2015-03-18 07:06:43.906702", 
+ "modified": "2015-07-09 08:15:29.026935", 
  "modified_by": "Administrator", 
  "module": "Utilities", 
  "name": "Contact", 
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index be74aeb..50b0319 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
-from frappe.utils import cstr, now_datetime, cint
+from frappe.utils import cstr, now_datetime, cint, flt
 import frappe.share
 
 from erpnext.controllers.status_updater import StatusUpdater
@@ -92,6 +92,17 @@
 				for field, condition in fields:
 					if prevdoc_values[field] is not None:
 						self.validate_value(field, condition, prevdoc_values[field], doc)
+						
+						
+	def validate_rate_with_reference_doc(self, ref_details):
+		for ref_dt, ref_dn_field, ref_link_field in ref_details:
+			for d in self.get("items"):
+				if d.get(ref_link_field):
+					ref_rate = frappe.db.get_value(ref_dt + " Item", d.get(ref_link_field), "rate")
+					
+					if abs(flt(d.rate - ref_rate, d.precision("rate"))) >= .01:
+						frappe.throw(_("Row #{0}: Rate must be same as {1}: {2} ({3} / {4}) ")
+							.format(d.idx, ref_dt, d.get(ref_dn_field), d.rate, ref_rate))
 
 
 def delete_events(ref_type, ref_name):
diff --git a/setup.py b/setup.py
index a0e3f14..7154899 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
 from setuptools import setup, find_packages
 
-version = "5.1.3"
+version = "5.1.4"
 
 with open("requirements.txt", "r") as f:
 	install_requires = f.readlines()