From 5769c8639175e4b16f38358db1bf8e5480a80bbb Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 3 Jul 2026 14:13:49 +0530 Subject: [PATCH] fix: reject negative tax rate in Item Tax Template --- .../doctype/item_tax_template/item_tax_template.py | 7 +++++++ .../doctype/item_tax_template/test_item_tax_template.py | 7 ++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/item_tax_template/item_tax_template.py b/erpnext/accounts/doctype/item_tax_template/item_tax_template.py index 8a23331b3f6..6985537d52a 100644 --- a/erpnext/accounts/doctype/item_tax_template/item_tax_template.py +++ b/erpnext/accounts/doctype/item_tax_template/item_tax_template.py @@ -5,6 +5,7 @@ import frappe from frappe import _ from frappe.model.document import Document +from frappe.utils import flt class ItemTaxTemplate(Document): @@ -29,6 +30,12 @@ class ItemTaxTemplate(Document): def validate(self): self.set_zero_rate_for_not_applicable_tax() self.validate_tax_accounts() + self.validate_tax_rates() + + def validate_tax_rates(self): + for row in self.get("taxes"): + if flt(row.tax_rate) < 0: + frappe.throw(_("Row {0}: Tax Rate cannot be negative").format(row.idx)) def set_zero_rate_for_not_applicable_tax(self): """Ensure tax_rate is 0 for any row marked as not applicable.""" diff --git a/erpnext/accounts/doctype/item_tax_template/test_item_tax_template.py b/erpnext/accounts/doctype/item_tax_template/test_item_tax_template.py index bf1a2fa07b2..b790e674022 100644 --- a/erpnext/accounts/doctype/item_tax_template/test_item_tax_template.py +++ b/erpnext/accounts/doctype/item_tax_template/test_item_tax_template.py @@ -54,9 +54,6 @@ class TestItemTaxTemplate(ERPNextTestSuite): doc.insert() self.assertEqual(doc.taxes[0].tax_rate, 0) - def test_negative_tax_rate_is_accepted(self): - # SUSPECTED BUG: validate never bounds tax_rate, so a negative (or >100) rate - # saves silently. Locking the current (wrong) behaviour. + def test_negative_tax_rate_is_rejected(self): doc = self.make_template([(TAX_ACCOUNT, -5, 0)]) - doc.insert() - self.assertEqual(doc.taxes[0].tax_rate, -5) + self.assertRaises(frappe.ValidationError, doc.insert)