5353 "POS Invoice" ,
5454}
5555
56+ ALLOWED_TAX_DIFFERENCE = 1 # Allowable difference in tax amount due to rounding off
57+
5658
5759def set_gst_breakup (doc ):
5860 gst_breakup_html = frappe .render_template (
@@ -180,7 +182,7 @@ def validate_item_wise_tax_detail(doc):
180182 )
181183 tax_difference = abs (multiplier * tax_rate - tax_amount )
182184
183- if tax_difference > 1 :
185+ if tax_difference > ALLOWED_TAX_DIFFERENCE :
184186 correct_charge_type = (
185187 "On Item Quantity" if is_cess_non_advol else "On Net Total"
186188 )
@@ -1203,6 +1205,8 @@ def update(self, doc):
12031205 else :
12041206 self .set_item_name_wise_tax_details ()
12051207
1208+ self .validate_item_gst_details ()
1209+
12061210 def get_item_defaults (self ):
12071211 item_defaults = frappe ._dict (count = 0 )
12081212
@@ -1221,13 +1225,13 @@ def set_item_name_wise_tax_details(self):
12211225 - Item count added to handle rounding errors
12221226 """
12231227
1224- tax_differences = frappe . _dict (
1225- {
1226- tax_row . gst_tax_type : tax_row . get ( self .tax_amount_field (), 0 )
1227- for tax_row in self . doc . taxes
1228- if self . is_gst_tax_row ( tax_row )
1229- }
1230- )
1228+ tax_differences = defaultdict ( float )
1229+ for tax_row in self . doc . taxes :
1230+ if not self .is_gst_tax_row ( tax_row ):
1231+ continue
1232+ tax_type = tax_row . gst_tax_type
1233+ tax_differences [ tax_type ] += tax_row . get ( self . tax_amount_field (), 0 )
1234+
12311235 last_item_with_tax = None
12321236 last_item_defaults = None
12331237
@@ -1399,6 +1403,39 @@ def get_tax_detail_by_item_code(self, item):
13991403
14001404 return response
14011405
1406+ def validate_item_gst_details (self ):
1407+ invalid_rows = defaultdict (list )
1408+
1409+ for item in self .doc .get ("items" ):
1410+ for tax in GST_TAX_TYPES :
1411+ expected_amt = self .get_item_tax_amount (
1412+ item , item .get (f"{ tax } _rate" ), tax
1413+ )
1414+
1415+ diff = abs (item .get (f"{ tax } _amount" ) - expected_amt )
1416+
1417+ if diff > ALLOWED_TAX_DIFFERENCE :
1418+ invalid_rows [item .idx ].append (tax .upper ())
1419+
1420+ if invalid_rows :
1421+ msg = (
1422+ _ (
1423+ "GST amounts do not match the calculated values based on tax rates for the following Item rows:<br><br>"
1424+ )
1425+ + "<ul>"
1426+ )
1427+ for idx , fields in invalid_rows .items ():
1428+ msg += _ (
1429+ "<li><strong>Row #{0}</strong>: {1} amount mismatch</li>"
1430+ ).format (idx , ", " .join (fields ))
1431+
1432+ msg += "</ul>"
1433+
1434+ frappe .throw (
1435+ msg ,
1436+ title = _ ("Incorrect Item GST Details" ),
1437+ )
1438+
14021439 def set_tax_amount_precisions (self , doctype ):
14031440 item_doctype = frappe .get_meta (doctype ).get_field ("items" ).options
14041441
0 commit comments