fix: Taxes aren't discounted on early payment discount

- Deductions in payment entry must be split into income loss and tax loss
- Compute total discount in percentage, makes discounting different amounts proportionately easier
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index cd5b6d5..91d31ab 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -1669,7 +1669,7 @@
 		dt, party_account_currency, bank, outstanding_amount, payment_type, bank_amount, doc
 	)
 
-	paid_amount, received_amount, discount_amount = apply_early_payment_discount(
+	paid_amount, received_amount, discount_amount, valid_discounts = apply_early_payment_discount(
 		paid_amount, received_amount, doc
 	)
 
@@ -1769,7 +1769,9 @@
 	if party_account and bank:
 		pe.set_exchange_rate(ref_doc=reference_doc)
 		pe.set_amounts()
-		if discount_amount:
+
+		discount_amount = set_early_payment_discount_loss(pe, doc, valid_discounts, discount_amount)
+		if discount_amount > 0:
 			pe.set_gain_or_loss(
 				account_details={
 					"account": frappe.get_cached_value("Company", pe.company, "default_discount_account"),
@@ -1891,6 +1893,7 @@
 
 def apply_early_payment_discount(paid_amount, received_amount, doc):
 	total_discount = 0
+	valid_discounts = []
 	eligible_for_payments = ["Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"]
 	has_payment_schedule = hasattr(doc, "payment_schedule") and doc.payment_schedule
 
@@ -1911,13 +1914,96 @@
 					received_amount -= discount_amount
 					paid_amount -= discount_amount_in_foreign_currency
 
+				valid_discounts.append({"type": term.discount_type, "discount": term.discount})
 				total_discount += discount_amount
 
 		if total_discount:
 			money = frappe.utils.fmt_money(total_discount, currency=doc.get("currency"))
 			frappe.msgprint(_("Discount of {} applied as per Payment Term").format(money), alert=1)
 
-	return paid_amount, received_amount, total_discount
+	return paid_amount, received_amount, total_discount, valid_discounts
+
+
+def set_early_payment_discount_loss(pe, doc, valid_discounts, discount_amount):
+	"""Split early bird discount deductions into Income Loss & Tax Loss."""
+	if not (discount_amount and valid_discounts):
+		return discount_amount
+
+	total_discount_percent = get_total_discount_percent(doc, valid_discounts)
+
+	if not total_discount_percent:
+		return discount_amount
+
+	loss_on_income = add_income_discount_loss(pe, doc, total_discount_percent)
+	loss_on_taxes = add_tax_discount_loss(pe, doc, total_discount_percent)
+
+	return flt(discount_amount - (loss_on_income + loss_on_taxes))
+
+
+def get_total_discount_percent(doc, valid_discounts) -> float:
+	"""Get total percentage and amount discount applied as a percentage."""
+	total_discount_percent = (
+		sum(
+			discount.get("discount") for discount in valid_discounts if discount.get("type") == "Percentage"
+		)
+		or 0.0
+	)
+
+	# Operate in percentages only as it makes the income & tax split easier
+	total_discount_amount = (
+		sum(discount.get("discount") for discount in valid_discounts if discount.get("type") == "Amount")
+		or 0.0
+	)
+
+	if total_discount_amount:
+		discount_percentage = (total_discount_amount / doc.get("grand_total")) * 100
+		total_discount_percent += discount_percentage
+		return total_discount_percent
+
+	return total_discount_percent
+
+
+def add_income_discount_loss(pe, doc, total_discount_percent) -> float:
+	loss_on_income = flt(doc.get("total") * (total_discount_percent / 100), doc.precision("total"))
+	pe.append(
+		"deductions",
+		{
+			"account": frappe.get_cached_value("Company", pe.company, "default_discount_account"),
+			"cost_center": pe.cost_center or frappe.get_cached_value("Company", pe.company, "cost_center"),
+			"amount": loss_on_income,
+		},
+	)
+	return loss_on_income
+
+
+def add_tax_discount_loss(pe, doc, total_discount_percenatage) -> float:
+	tax_discount_loss = {}
+	total_tax_loss = 0
+	precision = doc.precision("tax_amount_after_discount_amount", "taxes")
+
+	# The same account head could be used more than once
+	for tax in doc.get("taxes", []):
+		tax_loss = flt(
+			tax.get("tax_amount_after_discount_amount") * (total_discount_percenatage / 100), precision
+		)
+		account = tax.get("account_head")
+		if not tax_discount_loss.get(account):
+			tax_discount_loss[account] = tax_loss
+		else:
+			tax_discount_loss[account] += tax_loss
+
+	for account, loss in tax_discount_loss.items():
+		total_tax_loss += loss
+		pe.append(
+			"deductions",
+			{
+				"account": account,
+				"cost_center": pe.cost_center or frappe.get_cached_value("Company", pe.company, "cost_center"),
+				"amount": loss,
+			},
+		)
+
+	return total_tax_loss
 
 
 def get_reference_as_per_payment_terms(