fix: Book valuation expense in specified account rather than expense included in valuation account (#19590)

* fix: Book valuation expense in specified accout rather than expense included in valuation account

* fix: Remove undefined variable

* fix: Test cases

* fix: Test Case
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 4fbf9a1..5c53d26 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -714,14 +714,14 @@
 							if account_currency==self.company_currency \
 							else tax.tax_amount_after_discount_amount,
 						"cost_center": tax.cost_center
-					}, account_currency)
+					}, account_currency, item=tax)
 				)
 			# accumulate valuation tax
 			if self.is_opening == "No" and tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount):
 				if self.auto_accounting_for_stock and not tax.cost_center:
 					frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category)))
-				valuation_tax.setdefault(tax.cost_center, 0)
-				valuation_tax[tax.cost_center] += \
+				valuation_tax.setdefault(tax.name, 0)
+				valuation_tax[tax.name] += \
 					(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount)
 
 		if self.is_opening == "No" and self.negative_expense_to_be_booked and valuation_tax:
@@ -731,36 +731,38 @@
 			total_valuation_amount = sum(valuation_tax.values())
 			amount_including_divisional_loss = self.negative_expense_to_be_booked
 			i = 1
-			for cost_center, amount in iteritems(valuation_tax):
-				if i == len(valuation_tax):
-					applicable_amount = amount_including_divisional_loss
-				else:
-					applicable_amount = self.negative_expense_to_be_booked * (amount / total_valuation_amount)
-					amount_including_divisional_loss -= applicable_amount
+			for tax in self.get("taxes"):
+				if valuation_tax.get(tax.name):
+					if i == len(valuation_tax):
+						applicable_amount = amount_including_divisional_loss
+					else:
+						applicable_amount = self.negative_expense_to_be_booked * (valuation_tax[tax.name] / total_valuation_amount)
+						amount_including_divisional_loss -= applicable_amount
 
-				gl_entries.append(
-					self.get_gl_dict({
-						"account": self.expenses_included_in_valuation,
-						"cost_center": cost_center,
-						"against": self.supplier,
-						"credit": applicable_amount,
-						"remarks": self.remarks or "Accounting Entry for Stock"
-					})
-				)
+					gl_entries.append(
+						self.get_gl_dict({
+							"account": tax.account_head,
+							"cost_center": tax.cost_center,
+							"against": self.supplier,
+							"credit": applicable_amount,
+							"remarks": self.remarks or _("Accounting Entry for Stock"),
+						}, item=tax)
+					)
 
-				i += 1
+					i += 1
 
 		if self.auto_accounting_for_stock and self.update_stock and valuation_tax:
-			for cost_center, amount in iteritems(valuation_tax):
-				gl_entries.append(
-					self.get_gl_dict({
-						"account": self.expenses_included_in_valuation,
-						"cost_center": cost_center,
-						"against": self.supplier,
-						"credit": amount,
-						"remarks": self.remarks or "Accounting Entry for Stock"
-					})
-				)
+			for tax in self.get("taxes"):
+				if valuation_tax.get(tax.name):
+					gl_entries.append(
+						self.get_gl_dict({
+							"account": tax.account_head,
+							"cost_center": tax.cost_center,
+							"against": self.supplier,
+							"credit": valuation_tax[tax.name],
+							"remarks": self.remarks or "Accounting Entry for Stock"
+						}, item=tax)
+					)
 
 	def make_payment_gl_entries(self, gl_entries):
 		# Make Cash GL Entries
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index b2ad4f4..85b1166 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -204,19 +204,40 @@
 		pi.insert()
 		pi.submit()
 
-		self.check_gle_for_pi(pi.name)
+		self.check_gle_for_pi_against_pr(pi.name)
 
 	def check_gle_for_pi(self, pi):
-		gl_entries = frappe.db.sql("""select account, debit, credit
+		gl_entries = frappe.db.sql("""select account, sum(debit) as debit, sum(credit) as credit
 			from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
-			order by account asc""", pi, as_dict=1)
+			group by account""", pi, as_dict=1)
+
 		self.assertTrue(gl_entries)
 
 		expected_values = dict((d[0], d) for d in [
 			["Creditors - TCP1", 0, 720],
 			["Stock Received But Not Billed - TCP1", 500.0, 0],
-			["_Test Account Shipping Charges - TCP1", 100.0, 0],
+			["_Test Account Shipping Charges - TCP1", 100.0, 0.0],
+			["_Test Account VAT - TCP1", 120.0, 0]
+		])
+
+		for i, gle in enumerate(gl_entries):
+			self.assertEqual(expected_values[gle.account][0], gle.account)
+			self.assertEqual(expected_values[gle.account][1], gle.debit)
+			self.assertEqual(expected_values[gle.account][2], gle.credit)
+
+	def check_gle_for_pi_against_pr(self, pi):
+		gl_entries = frappe.db.sql("""select account, sum(debit) as debit, sum(credit) as credit
+			from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
+			group by account""", pi, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		expected_values = dict((d[0], d) for d in [
+			["Creditors - TCP1", 0, 720],
+			["Stock Received But Not Billed - TCP1", 750.0, 0],
+			["_Test Account Shipping Charges - TCP1", 100.0, 100.0],
 			["_Test Account VAT - TCP1", 120.0, 0],
+			["_Test Account Customs Duty - TCP1", 0, 150]
 		])
 
 		for i, gle in enumerate(gl_entries):
diff --git a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
index fe5d3ed..988cf52 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
@@ -54,9 +54,10 @@
 			expected_values = {
 				stock_in_hand_account: [800.0, 0.0],
 				"Stock Received But Not Billed - TCP1": [0.0, 500.0],
-				"Expenses Included In Valuation - TCP1": [0.0, 300.0]
+				"Expenses Included In Valuation - TCP1": [0.0, 50.0],
+				"_Test Account Customs Duty - TCP1": [0.0, 150],
+				"_Test Account Shipping Charges - TCP1": [0.0, 100.00]
 			}
-
 		else:
 			expected_values = {
 				stock_in_hand_account: [400.0, 0.0],
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 56fd47e..0cb21d7 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -288,8 +288,8 @@
 			if tax.category in ("Valuation", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount):
 				if not tax.cost_center:
 					frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category)))
-				valuation_tax.setdefault(tax.cost_center, 0)
-				valuation_tax[tax.cost_center] += \
+				valuation_tax.setdefault(tax.name, 0)
+				valuation_tax[tax.name] += \
 					(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount)
 
 		if negative_expense_to_be_booked and valuation_tax:
@@ -297,37 +297,42 @@
 			# If expenses_included_in_valuation account has been credited in against PI
 			# and charges added via Landed Cost Voucher,
 			# post valuation related charges on "Stock Received But Not Billed"
+			# introduced in 2014 for backward compatibility of expenses already booked in expenses_included_in_valuation account
 
 			negative_expense_booked_in_pi = frappe.db.sql("""select name from `tabPurchase Invoice Item` pi
 				where docstatus = 1 and purchase_receipt=%s
 				and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
 					and voucher_no=pi.parent and account=%s)""", (self.name, expenses_included_in_valuation))
 
-			if negative_expense_booked_in_pi:
-				expenses_included_in_valuation = stock_rbnb
-
 			against_account = ", ".join([d.account for d in gl_entries if flt(d.debit) > 0])
 			total_valuation_amount = sum(valuation_tax.values())
 			amount_including_divisional_loss = negative_expense_to_be_booked
 			i = 1
-			for cost_center, amount in iteritems(valuation_tax):
-				if i == len(valuation_tax):
-					applicable_amount = amount_including_divisional_loss
-				else:
-					applicable_amount = negative_expense_to_be_booked * (amount / total_valuation_amount)
-					amount_including_divisional_loss -= applicable_amount
+			for tax in self.get("taxes"):
+				if valuation_tax.get(tax.name):
 
-				gl_entries.append(
-					self.get_gl_dict({
-						"account": expenses_included_in_valuation,
-						"cost_center": cost_center,
-						"credit": applicable_amount,
-						"remarks": self.remarks or _("Accounting Entry for Stock"),
-						"against": against_account
-					})
-				)
+					if negative_expense_booked_in_pi:
+						account = stock_rbnb
+					else:
+						account = tax.account_head
 
-				i += 1
+					if i == len(valuation_tax):
+						applicable_amount = amount_including_divisional_loss
+					else:
+						applicable_amount = negative_expense_to_be_booked * (valuation_tax[tax.name] / total_valuation_amount)
+						amount_including_divisional_loss -= applicable_amount
+
+					gl_entries.append(
+						self.get_gl_dict({
+							"account": account,
+							"cost_center": tax.cost_center,
+							"credit": applicable_amount,
+							"remarks": self.remarks or _("Accounting Entry for Stock"),
+							"against": against_account
+						}, item=tax)
+					)
+
+					i += 1
 
 		if warehouse_with_no_account:
 			frappe.msgprint(_("No accounting entries for the following warehouses") + ": \n" +
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 2afb693..c80b9bd 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -66,14 +66,15 @@
 			expected_values = {
 				stock_in_hand_account: [750.0, 0.0],
 				"Stock Received But Not Billed - TCP1": [0.0, 500.0],
-				"Expenses Included In Valuation - TCP1": [0.0, 250.0]
+				"_Test Account Shipping Charges - TCP1": [0.0, 100.0],
+				"_Test Account Customs Duty - TCP1": [0.0, 150.0]
 			}
 		else:
 			expected_values = {
 				stock_in_hand_account: [375.0, 0.0],
 				fixed_asset_account: [375.0, 0.0],
 				"Stock Received But Not Billed - TCP1": [0.0, 500.0],
-				"Expenses Included In Valuation - TCP1": [0.0, 250.0]
+				"_Test Account Shipping Charges - TCP1": [0.0, 250.0]
 			}
 		for gle in gl_entries:
 			self.assertEqual(expected_values[gle.account][0], gle.debit)