fix: prevent double rounding in inclusive tax calculations (#52512)

Co-authored-by: Diptanil Saha <diptanil@frappe.io>
This commit is contained in:
Luis Mendoza
2026-06-03 02:39:42 -03:00
committed by GitHub
parent da82ac86b5
commit 36dc196a1d
3 changed files with 283 additions and 5 deletions

View File

@@ -304,6 +304,7 @@ class calculate_taxes_and_totals:
return
for item in self.doc.items:
item._unrounded_net_amount = None
item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
cumulated_tax_fraction = 0
total_inclusive_tax_amount_per_qty = 0
@@ -331,7 +332,8 @@ class calculate_taxes_and_totals:
):
amount = flt(item.amount) - total_inclusive_tax_amount_per_qty
item.net_amount = flt(amount / (1 + cumulated_tax_fraction), item.precision("net_amount"))
item._unrounded_net_amount = amount / (1 + cumulated_tax_fraction)
item.net_amount = flt(item._unrounded_net_amount, item.precision("net_amount"))
item.net_rate = flt(item.net_amount / item.qty, item.precision("net_rate"))
item.discount_percentage = flt(
item.discount_percentage, item.precision("discount_percentage")
@@ -541,7 +543,9 @@ class calculate_taxes_and_totals:
actual_breakup = tax._total_tax_breakup
diff = flt(expected_amount - actual_breakup, 5)
if abs(diff) <= 0.5:
# TODO: fix rounding difference issues
# Allow up to 1 for zero-precision currencies (e.g. JPY, KRW)
if abs(diff) <= (1 if tax.precision("tax_amount") == 0 else 0.5):
detail_row = self.doc._item_wise_tax_details[last_idx]
detail_row["amount"] = flt(detail_row["amount"] + diff, 5)
@@ -600,7 +604,16 @@ class calculate_taxes_and_totals:
elif tax.charge_type == "On Net Total":
if tax.account_head in item_tax_map:
current_net_amount = item.net_amount
current_tax_amount = (tax_rate / 100.0) * item.net_amount
# Use unrounded net for inclusive taxes to avoid double rounding
if (
cint(tax.included_in_print_rate)
and not self.discount_amount_applied
and item._unrounded_net_amount is not None
):
current_tax_amount = (tax_rate / 100.0) * item._unrounded_net_amount
else:
current_tax_amount = (tax_rate / 100.0) * item.net_amount
elif tax.charge_type == "On Previous Row Amount":
current_net_amount = self.doc.get("taxes")[cint(tax.row_id) - 1].tax_amount_for_current_item
current_tax_amount = (tax_rate / 100.0) * current_net_amount