Merge branch 'hotfix'
diff --git a/erpnext/__version__.py b/erpnext/__version__.py
index 56face8..e927343 100644
--- a/erpnext/__version__.py
+++ b/erpnext/__version__.py
@@ -1,2 +1,2 @@
 from __future__ import unicode_literals
-__version__ = '6.27.12'
+__version__ = '6.27.13'
diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
index f1e706e..0eda1db 100644
--- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
+++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
@@ -14,7 +14,7 @@
 	item_list = get_items(filters)
 	aii_account_map = get_aii_accounts()
 	if item_list:
-		item_tax, tax_accounts = get_tax_accounts(item_list, columns)
+		item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
 
 	columns.append({
 		"fieldname": "currency",
@@ -23,7 +23,7 @@
 		"width": 80
 	})
 	company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
-	print company_currency
+	
 	data = []
 	for d in item_list:
 		purchase_receipt = None
@@ -39,7 +39,7 @@
 			purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount]
 
 		for tax in tax_accounts:
-			row.append(item_tax.get(d.parent, {}).get(d.item_code, {}).get(tax, 0))
+			row.append(item_row_tax.get(d.name, {}).get(tax, 0))
 
 		total_tax = sum(row[last_col:])
 		row += [total_tax, d.base_net_amount + total_tax, company_currency]
@@ -76,29 +76,40 @@
 	conditions = get_conditions(filters)
 	match_conditions = frappe.build_match_conditions("Purchase Invoice")
 
-	return frappe.db.sql("""select pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
-		pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name, pi_item.item_group,
-		pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt, pi_item.po_detail,
-		pi_item.expense_account, pi_item.qty, pi_item.base_net_rate, pi_item.base_net_amount, pi.supplier_name
+	return frappe.db.sql("""
+		select 
+			pi_item.name, pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
+			pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name, 
+			pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt, 
+			pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate, 
+			pi_item.base_net_amount, pi.supplier_name
 		from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item
 		where pi.name = pi_item.parent and pi.docstatus = 1 %s %s
-		order by pi.posting_date desc, pi_item.item_code desc""" % (conditions, match_conditions), filters, as_dict=1)
+		order by pi.posting_date desc, pi_item.item_code desc
+	""" % (conditions, match_conditions), filters, as_dict=1)
 
 def get_aii_accounts():
 	return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
 
 def get_tax_accounts(item_list, columns):
 	import json
-	item_tax = {}
+	item_row_tax = {}
 	tax_accounts = []
-	invoice_wise_items = {}
+	invoice_item_row = {}
+	item_row_map = {}
 	for d in item_list:
-		invoice_wise_items.setdefault(d.parent, []).append(d)
+		invoice_item_row.setdefault(d.parent, []).append(d)
+		item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
 
-	tax_details = frappe.db.sql("""select parent, account_head, item_wise_tax_detail, charge_type, base_tax_amount_after_discount_amount
-		from `tabPurchase Taxes and Charges` where parenttype = 'Purchase Invoice'
-		and docstatus = 1 and (account_head is not null and account_head != '') and category in ('Total', 'Valuation and Total')
-		and parent in (%s)""" % ', '.join(['%s']*len(invoice_wise_items)), tuple(invoice_wise_items.keys()))
+	tax_details = frappe.db.sql("""
+		select 
+			parent, account_head, item_wise_tax_detail, charge_type, base_tax_amount_after_discount_amount
+		from `tabPurchase Taxes and Charges` 
+		where parenttype = 'Purchase Invoice' and docstatus = 1 
+			and (account_head is not null and account_head != '') 
+			and category in ('Total', 'Valuation and Total')
+			and parent in (%s)
+		""" % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
 
 	for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
 		if account_head not in tax_accounts:
@@ -107,19 +118,26 @@
 		if item_wise_tax_detail:
 			try:
 				item_wise_tax_detail = json.loads(item_wise_tax_detail)
-				for item, tax_amount in item_wise_tax_detail.items():
-					item_tax.setdefault(parent, {}).setdefault(item, {})[account_head] = \
-						flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
+				
+				for item_code, tax_amount in item_wise_tax_detail.items():
+					tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
+					
+					item_net_amount = sum([flt(d.base_net_amount) 
+						for d in item_row_map.get(parent, {}).get(item_code, [])])
+					
+					for d in item_row_map.get(parent, {}).get(item_code, []):
+						item_row_tax.setdefault(d.name, {})[account_head] = \
+							flt((tax_amount * d.base_net_amount) / item_net_amount)
 
 			except ValueError:
 				continue
 		elif charge_type == "Actual" and tax_amount:
-			for d in invoice_wise_items.get(parent, []):
-				item_tax.setdefault(parent, {}).setdefault(d.item_code, {})[account_head] = \
-					(tax_amount * d.base_net_amount) / d.base_net_total
+			for d in invoice_item_row.get(parent, []):
+				item_row_tax.setdefault(d.name, {})[account_head] = \
+					flt((tax_amount * d.base_net_amount) / d.base_net_total)
 
 	tax_accounts.sort()
 	columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
 	columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
 
-	return item_tax, tax_accounts
+	return item_row_tax, tax_accounts
diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
index 2401202..df71350 100644
--- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
+++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
@@ -13,7 +13,7 @@
 
 	item_list = get_items(filters)
 	if item_list:
-		item_tax, tax_accounts = get_tax_accounts(item_list, columns)
+		item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
 	columns.append({
 		"fieldname": "currency",
 		"label": _("Currency"),
@@ -36,7 +36,7 @@
 			delivery_note, d.income_account, d.qty, d.base_net_rate, d.base_net_amount]
 
 		for tax in tax_accounts:
-			row.append(item_tax.get(d.parent, {}).get(d.item_code, {}).get(tax, 0))
+			row.append(item_row_tax.get(d.name, {}).get(tax, 0))
 
 		total_tax = sum(row[last_col:])
 		row += [total_tax, d.base_net_amount + total_tax, company_currency]
@@ -73,49 +73,66 @@
 
 def get_items(filters):
 	conditions = get_conditions(filters)
-	return frappe.db.sql("""select si_item.parent, si.posting_date, si.debit_to, si.project,
-		si.customer, si.remarks, si.territory, si.company, si.base_net_total, si_item.item_code, si_item.item_name,
-		si_item.item_group, si_item.sales_order, si_item.delivery_note, si_item.income_account,
-		si_item.qty, si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
-		si.customer_group, si_item.so_detail
+	return frappe.db.sql("""
+		select
+			si_item.name, si_item.parent, si.posting_date, si.debit_to, si.project,
+			si.customer, si.remarks, si.territory, si.company, si.base_net_total, 
+			si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order, 
+			si_item.delivery_note, si_item.income_account, si_item.qty, 
+			si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
+			si.customer_group, si_item.so_detail
 		from `tabSales Invoice` si, `tabSales Invoice Item` si_item
 		where si.name = si_item.parent and si.docstatus = 1 %s
 		order by si.posting_date desc, si_item.item_code desc""" % conditions, filters, as_dict=1)
 
 def get_tax_accounts(item_list, columns):
 	import json
-	item_tax = {}
+	item_row_tax = {}
 	tax_accounts = []
-	invoice_wise_items = {}
+	invoice_item_row = {}
+	item_row_map = {}
 	for d in item_list:
-		invoice_wise_items.setdefault(d.parent, []).append(d)
+		invoice_item_row.setdefault(d.parent, []).append(d)
+		item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
 
-	tax_details = frappe.db.sql("""select parent, account_head, item_wise_tax_detail,
-		charge_type, base_tax_amount_after_discount_amount
-		from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice'
-		and docstatus = 1 and (account_head is not null and account_head != '')
-		and parent in (%s)""" % ', '.join(['%s']*len(invoice_wise_items)),
-		tuple(invoice_wise_items.keys()))
+	tax_details = frappe.db.sql("""
+		select 
+			parent, account_head, item_wise_tax_detail,
+			charge_type, base_tax_amount_after_discount_amount
+		from `tabSales Taxes and Charges` 
+		where 
+			parenttype = 'Sales Invoice' and docstatus = 1 
+			and (account_head is not null and account_head != '')
+			and parent in (%s)
+	""" % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
 
 	for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
 		if account_head not in tax_accounts:
 			tax_accounts.append(account_head)
-
+			
 		if item_wise_tax_detail:
 			try:
 				item_wise_tax_detail = json.loads(item_wise_tax_detail)
-				for item, tax_amount in item_wise_tax_detail.items():
-					item_tax.setdefault(parent, {}).setdefault(item, {})[account_head] = \
-						 flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
+
+				for item_code, tax_amount in item_wise_tax_detail.items():
+					tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
+						
+					item_net_amount = sum([flt(d.base_net_amount) 
+						for d in item_row_map.get(parent, {}).get(item_code, [])])
+						
+					for d in item_row_map.get(parent, {}).get(item_code, []):
+						item_row_tax.setdefault(d.name, {})[account_head] = \
+							flt((tax_amount * d.base_net_amount) / item_net_amount)
+
 			except ValueError:
 				continue
 		elif charge_type == "Actual" and tax_amount:
-			for d in invoice_wise_items.get(parent, []):
-				item_tax.setdefault(parent, {}).setdefault(d.item_code, {})[account_head] = \
+			for d in invoice_item_row.get(parent, []):
+				item_row_tax.setdefault(d.name, {})[account_head] = \
 					flt((tax_amount * d.base_net_amount) / d.base_net_total)
 
 	tax_accounts.sort()
 	columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
 	columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
 
-	return item_tax, tax_accounts
+	return item_row_tax, tax_accounts
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py
index 7934bf2..53cb7af66 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.py
+++ b/erpnext/accounts/report/purchase_register/purchase_register.py
@@ -119,16 +119,22 @@
 
 def get_invoices(filters):
 	conditions = get_conditions(filters)
-	return frappe.db.sql("""select name, posting_date, credit_to, supplier, supplier_name,
-		bill_no, bill_date, remarks, base_net_total, base_grand_total, outstanding_amount
-		from `tabPurchase Invoice` where docstatus = 1 %s
+	return frappe.db.sql("""
+		select 
+			name, posting_date, credit_to, supplier, supplier_name,
+			bill_no, bill_date, remarks, base_net_total, base_grand_total, outstanding_amount
+		from `tabPurchase Invoice` 
+		where docstatus = 1 %s
 		order by posting_date desc, name desc""" % conditions, filters, as_dict=1)
 
 
 def get_invoice_expense_map(invoice_list):
-	expense_details = frappe.db.sql("""select parent, expense_account, sum(base_net_amount) as amount
-		from `tabPurchase Invoice Item` where parent in (%s) group by parent, expense_account""" %
-		', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
+	expense_details = frappe.db.sql("""
+		select parent, expense_account, sum(base_net_amount) as amount
+		from `tabPurchase Invoice Item` 
+		where parent in (%s) 
+		group by parent, expense_account
+	""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
 
 	invoice_expense_map = {}
 	for d in expense_details:
@@ -138,9 +144,12 @@
 	return invoice_expense_map
 
 def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
-	tax_details = frappe.db.sql("""select parent, account_head, sum(base_tax_amount_after_discount_amount) as tax_amount
-		from `tabPurchase Taxes and Charges` where parent in (%s) group by parent, account_head""" %
-		', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
+	tax_details = frappe.db.sql("""
+		select parent, account_head, sum(base_tax_amount_after_discount_amount) as tax_amount
+		from `tabPurchase Taxes and Charges` 
+		where parent in (%s) and category in ('Total', 'Valuation and Total')
+		group by parent, account_head
+	""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
 
 	invoice_tax_map = {}
 	for d in tax_details:
@@ -156,10 +165,11 @@
 	return invoice_expense_map, invoice_tax_map
 
 def get_invoice_po_pr_map(invoice_list):
-	pi_items = frappe.db.sql("""select parent, purchase_order, purchase_receipt, po_detail,
-		project from `tabPurchase Invoice Item` where parent in (%s)
-		and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '')""" %
-		', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
+	pi_items = frappe.db.sql("""
+		select parent, purchase_order, purchase_receipt, po_detail, project 
+		from `tabPurchase Invoice Item` 
+		where parent in (%s) and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '')
+	""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
 
 	invoice_po_pr_map = {}
 	for d in pi_items:
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 1cb99c5..d857512 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -7,7 +7,7 @@
 app_description = """ERP made simple"""
 app_icon = "icon-th"
 app_color = "#e74c3c"
-app_version = "6.27.12"
+app_version = "6.27.13"
 app_email = "info@erpnext.com"
 app_license = "GNU General Public License (v3)"
 source_link = "https://github.com/frappe/erpnext"
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index f18bc8b..e26aaa7 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -463,9 +463,22 @@
 			clear_cache(self.page_name)
 
 		frappe.db.set_value("Item", newdn, "item_code", newdn)
+		
 		if merge:
 			self.set_last_purchase_rate(newdn)
 			self.recalculate_bin_qty(newdn)
+			
+		for dt in ("Sales Taxes and Charges", "Purchase Taxes and Charges"):
+			for d in frappe.db.sql("""select name, item_wise_tax_detail from `tab{0}` 
+					where ifnull(item_wise_tax_detail, '') != ''""".format(dt), as_dict=1):
+				
+				item_wise_tax_detail = json.loads(d.item_wise_tax_detail)
+				if olddn in item_wise_tax_detail:
+					item_wise_tax_detail[newdn] = item_wise_tax_detail[olddn]
+					item_wise_tax_detail.pop(olddn)
+					
+					frappe.db.set_value(dt, d.name, "item_wise_tax_detail", 
+						json.dumps(item_wise_tax_detail), update_modified=False)
 
 	def set_last_purchase_rate(self, newdn):
 		last_purchase_rate = get_last_purchase_details(newdn).get("base_rate", 0)
@@ -562,7 +575,8 @@
 			variant = get_variant(self.variant_of, args, self.name)
 			if variant:
 				frappe.throw(_("Item variant {0} exists with same attributes")
-					.format(variant), ItemVariantExistsError)
+					.format(variant), ItemVariantExistsError)			
+			
 
 def validate_end_of_life(item_code, end_of_life=None, disabled=None, verbose=1):
 	if (not end_of_life) or (disabled is None):
diff --git a/setup.py b/setup.py
index 1866b87..41e0ce1 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
 from setuptools import setup, find_packages
 from pip.req import parse_requirements
 
-version = "6.27.12"
+version = "6.27.13"
 requirements = parse_requirements("requirements.txt", session="")
 
 setup(