Skip to content

Commit 61ac180

Browse files
ljain112mergify[bot]
authored andcommitted
fix: prevent precision errors in discount distribution with inclusive tax
(cherry picked from commit 2068299)
1 parent 3ae5de7 commit 61ac180

3 files changed

Lines changed: 49 additions & 0 deletions

File tree

erpnext/controllers/taxes_and_totals.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,11 @@ def adjust_grand_total_for_inclusive_tax(self):
602602
else:
603603
self.grand_total_diff = 0
604604

605+
# Apply rounding adjustment to grand_total_for_distributing_discount
606+
# to prevent precision errors during discount distribution
607+
if hasattr(self, "grand_total_for_distributing_discount") and not self.discount_amount_applied:
608+
self.grand_total_for_distributing_discount += self.grand_total_diff
609+
605610
def calculate_totals(self):
606611
grand_total_diff = self.grand_total_diff
607612

erpnext/controllers/tests/test_distributed_discount.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,41 @@ def test_distributed_discount_amount_with_taxes(self):
5959
self.assertEqual(so.total, 1500)
6060
self.assertAlmostEqual(so.net_total, 1272.73, places=2)
6161
self.assertEqual(so.grand_total, 1400)
62+
63+
def test_100_percent_discount_with_inclusive_tax(self):
64+
"""Test that 100% discount with inclusive taxes results in zero net_total"""
65+
so = make_sales_order(do_not_save=1)
66+
so.apply_discount_on = "Grand Total"
67+
so.items[0].qty = 2
68+
so.items[0].rate = 1300
69+
so.append(
70+
"taxes",
71+
{
72+
"charge_type": "On Net Total",
73+
"account_head": "_Test Account VAT - _TC",
74+
"cost_center": "_Test Cost Center - _TC",
75+
"description": "Account VAT",
76+
"included_in_print_rate": True,
77+
"rate": 9,
78+
},
79+
)
80+
so.append(
81+
"taxes",
82+
{
83+
"charge_type": "On Net Total",
84+
"account_head": "_Test Account Service Tax - _TC",
85+
"cost_center": "_Test Cost Center - _TC",
86+
"description": "Account Service Tax",
87+
"included_in_print_rate": True,
88+
"rate": 9,
89+
},
90+
)
91+
so.save()
92+
93+
# Apply 100% discount
94+
so.discount_amount = 2600
95+
calculate_taxes_and_totals(so)
96+
97+
# net_total should be exactly 0, not 0.01
98+
self.assertEqual(so.net_total, 0)
99+
self.assertEqual(so.grand_total, 0)

erpnext/public/js/controllers/taxes_and_totals.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,12 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
584584
} else {
585585
me.grand_total_diff = 0;
586586
}
587+
588+
// Apply rounding adjustment to grand_total_for_distributing_discount
589+
// to prevent precision errors during discount distribution
590+
if (me.grand_total_for_distributing_discount && !me.discount_amount_applied) {
591+
me.grand_total_for_distributing_discount += me.grand_total_diff;
592+
}
587593
}
588594
}
589595
}

0 commit comments

Comments
 (0)