Merge branch 'develop' into contacts-ref
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 4f80b78..95c5dd5 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -206,9 +206,9 @@
 			total_amount_in_payments = 0
 			for payment in self.payments:
 				total_amount_in_payments += payment.amount
-
-			if total_amount_in_payments < self.rounded_total:
-				frappe.throw(_("Total payments amount can't be greater than {}".format(-self.rounded_total)))
+			invoice_total = self.rounded_total or self.grand_total
+			if total_amount_in_payments < invoice_total:
+				frappe.throw(_("Total payments amount can't be greater than {}".format(-invoice_total)))
 
 	def validate_pos_paid_amount(self):
 		if len(self.payments) == 0 and self.is_pos:
@@ -1510,4 +1510,4 @@
 		"outstanding_amount": invoice.outstanding_amount
 	})
 
-	return invoice_discounting
\ No newline at end of file
+	return invoice_discounting
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 2cbe596..52d58dc 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -45,6 +45,7 @@
 		self.set_gross_profit()
 		set_default_income_account_for_item(self)
 		self.set_customer_address()
+		self.validate_for_duplicate_items()
 
 	def set_missing_values(self, for_validate=False):
 
@@ -381,6 +382,34 @@
 			if self.get(address_field):
 				self.set(address_display_field, get_address_display(self.get(address_field)))
 
+	def validate_for_duplicate_items(self):
+		check_list, chk_dupl_itm = [], []
+		if cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
+			return
+
+		for d in self.get('items'):
+			if self.doctype == "Sales Invoice":
+				e = [d.item_code, d.description, d.warehouse, d.sales_order or d.delivery_note, d.batch_no or '']
+				f = [d.item_code, d.description, d.sales_order or d.delivery_note]
+			elif self.doctype == "Delivery Note":
+				e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or '']
+				f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice]
+			elif self.doctype == "Sales Order":
+				e = [d.item_code, d.description, d.warehouse, d.batch_no or '']
+				f = [d.item_code, d.description]
+
+			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
+				if e in check_list:
+					frappe.throw(_("Note: Item {0} entered multiple times").format(d.item_code))
+				else:
+					check_list.append(e)
+			else:
+				if f in chk_dupl_itm:
+					frappe.throw(_("Note: Item {0} entered multiple times").format(d.item_code))
+				else:
+					chk_dupl_itm.append(f)
+
+
 	def validate_items(self):
 		# validate items to see if they have is_sales_item enabled
 		from erpnext.controllers.buying_controller import validate_item_type
diff --git a/erpnext/hr/doctype/leave_application/leave_application_list.js b/erpnext/hr/doctype/leave_application/leave_application_list.js
index f69b182..cbb4b73 100644
--- a/erpnext/hr/doctype/leave_application/leave_application_list.js
+++ b/erpnext/hr/doctype/leave_application/leave_application_list.js
@@ -5,6 +5,8 @@
 			return [__("Approved"), "green", "status,=,Approved"];
 		} else if (doc.status === "Rejected") {
 			return [__("Rejected"), "red", "status,=,Rejected"];
+		} else {
+			return [__("Open"), "red", "status,=,Open"];
 		}
 	}
 };
diff --git a/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
index e2989e2..e5622b7 100644
--- a/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
+++ b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
@@ -23,7 +23,8 @@
 		_("Model") + ":data:50", _("Location") + ":data:100",
 		_("Log") + ":Link/Vehicle Log:100", _("Odometer") + ":Int:80",
 		_("Date") + ":Date:100", _("Fuel Qty") + ":Float:80",
-		_("Fuel Price") + ":Float:100",_("Service Expense") + ":Float:100"
+		_("Fuel Price") + ":Float:100",_("Fuel Expense") + ":Float:100",
+		_("Service Expense") + ":Float:100"
 	]
 	return columns
 
@@ -32,7 +33,8 @@
 	data = frappe.db.sql("""select
 			vhcl.license_plate as "License", vhcl.make as "Make", vhcl.model as "Model",
 			vhcl.location as "Location", log.name as "Log", log.odometer as "Odometer",
-			log.date as "Date", log.fuel_qty as "Fuel Qty", log.price as "Fuel Price"
+			log.date as "Date", log.fuel_qty as "Fuel Qty", log.price as "Fuel Price",
+			log.fuel_qty * log.price as "Fuel Expense"
 		from
 			`tabVehicle` vhcl,`tabVehicle Log` log
 		where
@@ -58,7 +60,7 @@
 		total_ser_exp=0
 		for row in data:
 			if row["Date"] <= period.to_date and row["Date"] >= period.from_date:
-				total_fuel_exp+=flt(row["Fuel Price"])
+				total_fuel_exp+=flt(row["Fuel Expense"])
 				total_ser_exp+=flt(row["Service Expense"])
 		fueldata.append([period.key,total_fuel_exp])
 		servicedata.append([period.key,total_ser_exp])
@@ -84,4 +86,4 @@
 		}
 	}
 	chart["type"] = "line"
-	return chart
\ No newline at end of file
+	return chart
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 09dc9a9..4342af5 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -72,9 +72,7 @@
 				frappe.msgprint(_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(so[0][0], self.po_no))
 
 	def validate_for_items(self):
-		check_list = []
 		for d in self.get('items'):
-			check_list.append(cstr(d.item_code))
 
 			# used for production plan
 			d.transaction_date = self.transaction_date
@@ -83,13 +81,6 @@
 				where item_code = %s and warehouse = %s", (d.item_code, d.warehouse))
 			d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
 
-		# check for same entry multiple times
-		unique_chk_list = set(check_list)
-		if len(unique_chk_list) != len(check_list) and \
-			not cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
-			frappe.msgprint(_("Same item has been entered multiple times"),
-				title=_("Warning"), indicator='orange')
-
 	def product_bundle_has_stock_item(self, product_bundle):
 		"""Returns true if product bundle has stock item"""
 		ret = len(frappe.db.sql("""select i.name from tabItem i, `tabProduct Bundle Item` pbi
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 2de9b97..f79d127 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -166,24 +166,7 @@
 				frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project))
 
 	def validate_for_items(self):
-		check_list, chk_dupl_itm = [], []
-		if cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
-			return
-
 		for d in self.get('items'):
-			e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or '']
-			f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice]
-
-			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
-				if e in check_list:
-					frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
-				else:
-					check_list.append(e)
-			else:
-				if f in chk_dupl_itm:
-					frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
-				else:
-					chk_dupl_itm.append(f)
 			#Customer Provided parts will have zero valuation rate
 			if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
 				d.allow_zero_valuation_rate = 1