Merge branch 'master' into develop
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 83c6069..16629d9 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
 from erpnext.hooks import regional_overrides
 from frappe.utils import getdate
 
-__version__ = '10.1.37'
+__version__ = '10.1.38'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 909856c..bb7d55b 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -422,10 +422,10 @@
 	# fetch and append data from Activity Log
 	data += frappe.db.sql("""select {fields}
 		from `tabActivity Log`
-		where reference_doctype='{doctype}' and reference_name='{name}'
+		where reference_doctype="{doctype}" and reference_name="{name}"
 		and status!='Success' and creation > {after}
 		{group_by} order by creation desc
-		""".format(doctype=doctype, name=name, fields=fields,
+		""".format(doctype=frappe.db.escape(doctype), name=frappe.db.escape(name), fields=fields,
 			group_by=group_by, after=after), as_dict=False)
 
 	timeline_items = dict(data)
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index bf906ce..16768b9 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -297,7 +297,10 @@
 
 		if party_type == "Supplier":
 			for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
-				from `tabPurchase Invoice` where docstatus=1""", as_dict=1):
+				from `tabPurchase Invoice` where docstatus = 1
+				union
+				select name, due_date, bill_no, bill_date from `tabJournal Entry`
+				where docstatus = 1 and bill_no is not NULL""", as_dict=1):
 					voucher_details.setdefault(pi.name, pi)
 
 		return voucher_details
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 85c58de..6c0347f 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -608,16 +608,19 @@
 			for item_code, tax_data in item_tax_map.items():
 				itemised_tax.setdefault(item_code, frappe._dict())
 
+				tax_rate = 0.0
+				tax_amount = 0.0
+
 				if isinstance(tax_data, list):
-					itemised_tax[item_code][tax.description] = frappe._dict(dict(
-						tax_rate=flt(tax_data[0]),
-						tax_amount=flt(tax_data[1])
-					))
+					tax_rate = flt(tax_data[0])
+					tax_amount = flt(tax_data[1])
 				else:
-					itemised_tax[item_code][tax.description] = frappe._dict(dict(
-						tax_rate=flt(tax_data),
-						tax_amount=0.0
-					))
+					tax_rate = flt(tax_data)
+
+				itemised_tax[item_code][tax.description] = frappe._dict(dict(
+					tax_rate = tax_rate,
+					tax_amount = tax_amount
+				))
 
 	return itemised_tax
 
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index d6d8b1c..25a42f2 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -56,6 +56,7 @@
 		self.status = "Cancelled"
 		# notify leave applier about cancellation
 		self.notify_employee()
+		self.cancel_attendance()
 
 	def validate_applicable_after(self):
 		if self.leave_type:
@@ -149,6 +150,13 @@
 						doc.insert(ignore_permissions=True)
 						doc.submit()
 
+	def cancel_attendance(self):
+		if self.docstatus == 2:
+			attendance = frappe.db.sql("""select name from `tabAttendance` where employee = %s\
+				and (attendance_date between %s and %s) and docstatus < 2 and status in ('On Leave', 'Half Day')""",(self.employee, self.from_date, self.to_date), as_dict=1)
+			for name in attendance:
+				frappe.db.set_value("Attendance", name, "docstatus", 2)
+
 	def validate_salary_processed_days(self):
 		if not frappe.db.get_value("Leave Type", self.leave_type, "is_lwp"):
 			return
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 09e4925..03f1cd8 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -18,8 +18,12 @@
 from erpnext.hr.doctype.employee_benefit_claim.employee_benefit_claim import get_benefit_claim_amount
 
 class SalarySlip(TransactionBase):
+	def __init__(self, *args, **kwargs):
+		super(SalarySlip, self).__init__(*args, **kwargs)
+		self.series = 'Sal Slip/{0}/.#####'.format(self.employee)
+
 	def autoname(self):
-		self.name = make_autoname('Sal Slip/' +self.employee + '/.#####')
+		self.name = make_autoname(self.series)
 
 	def validate(self):
 		self.status = self.get_status()
@@ -460,6 +464,10 @@
 		self.set_status()
 		self.update_status()
 
+	def on_trash(self):
+		from frappe.model.naming import revert_series_if_last
+		revert_series_if_last(self.series, self.name)
+
 	def email_salary_slip(self):
 		receiver = frappe.db.get_value("Employee", self.employee, "prefered_email")
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index b809eaf..e933f5a 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -162,7 +162,7 @@
 					if not self.buying_price_list:
 						frappe.throw(_("Please select Price List"))
 					rate = frappe.db.get_value("Item Price", {"price_list": self.buying_price_list,
-						"item_code": arg["item_code"]}, "price_list_rate")
+						"item_code": arg["item_code"]}, "price_list_rate") or 0.0
 
 					price_list_currency = frappe.db.get_value("Price List",
 						self.buying_price_list, "currency")
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 0047186..cd32e3e 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -340,12 +340,18 @@
 
 	set_item_wise_tax: function(item, tax, tax_rate, current_tax_amount) {
 		// store tax breakup for each item
-		var key = item.item_code || item.item_name;
-		var item_wise_tax_amount = current_tax_amount * this.frm.doc.conversion_rate;
-		if (tax.item_wise_tax_detail && tax.item_wise_tax_detail[key])
-			item_wise_tax_amount += tax.item_wise_tax_detail[key][1];
+		let tax_detail = tax.item_wise_tax_detail;
 
-		tax.item_wise_tax_detail[key] = [tax_rate, flt(item_wise_tax_amount, precision("base_tax_amount", tax))];
+		let key = item.item_code;
+		if(item.item_name && !Object.keys(tax_detail).includes(item.item_name)) {
+			key = item.item_name;
+		}
+
+		let item_wise_tax_amount = current_tax_amount * this.frm.doc.conversion_rate;
+		if (tax_detail && tax_detail[key])
+			item_wise_tax_amount += tax_detail[key][1];
+
+		tax_detail[key] = [tax_rate, flt(item_wise_tax_amount, precision("base_tax_amount", tax))];
 	},
 
 	round_off_totals: function(tax) {
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 690fbbc..27390d4 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -144,17 +144,10 @@
 		""" % (self.doctype, ', '.join(['%s']*len(self.invoices))), tuple(self.invoices), as_dict=1)
 
 		for d in items:
-			item_details = {}
-			item_details[d.item_code] = d.base_net_amount
-
-			if d.parent in self.invoice_items:
-				parent_dict = self.invoice_items[d.parent]
-				if d.item_code in parent_dict:
-					item_details[d.item_code] += parent_dict[d.item_code]
-				else:
-					item_details.update(parent_dict)
-
-			self.invoice_items[d.parent] = item_details
+			if d.item_code not in self.invoice_items.get(d.parent, {}):
+				self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code,
+					sum(i.get('base_net_amount', 0) for i in items
+					    if i.item_code == d.item_code and i.parent == d.parent))
 
 	def get_items_based_on_tax_rate(self):
 		self.tax_details = frappe.db.sql("""
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index eed4016..7d822a7 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -310,7 +310,7 @@
 			d.actual_qty = previous_sle.get("qty_after_transaction") or 0
 
 			# validate qty during submit
-			if d.docstatus==1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty:
+			if d.docstatus==1 and d.s_warehouse and not allow_negative_stock and flt(d.actual_qty, d.precision("actual_qty")) < flt(d.transfer_qty, d.precision("actual_qty")):
 				frappe.throw(_("Row {0}: Qty not available for {4} in warehouse {1} at posting time of the entry ({2} {3})").format(d.idx,
 					frappe.bold(d.s_warehouse), formatdate(self.posting_date),
 					format_time(self.posting_time), frappe.bold(d.item_code))
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index b5d2e3f..085e87f 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -77,8 +77,8 @@
 				elif not frappe.db.get_value("Batch",{"item": self.item_code, "name": self.batch_no}):
 					frappe.throw(_("{0} is not a valid Batch Number for Item {1}").format(self.batch_no, self.item_code))
 
-			elif item_det.has_batch_no ==0 and self.batch_no:
-					frappe.throw(_("The Item {0} cannot have Batch").format(self.item_code))
+			elif item_det.has_batch_no ==0 and self.batch_no and self.is_cancelled == "No":
+				frappe.throw(_("The Item {0} cannot have Batch").format(self.item_code))
 
 		if item_det.has_variants:
 			frappe.throw(_("Stock cannot exist for Item {0} since has variants").format(self.item_code),