From 529bab8f0b729e93dd8db1034263e4a86fc3de1d Mon Sep 17 00:00:00 2001 From: Jigar Vaghela Date: Mon, 9 May 2022 10:14:44 +0000 Subject: [PATCH] [FIX] l10n_in_edi: Fix 100% discount or zero quantity error and value Before this commit: =================== unit price calculation give error ZeroDivisionError: float division by zero for more details https://pad.odoo.com/p/r.c871c2581c415b13b0455a192ad0619d After this commit: ================== No error and set unit price,total amount before discount and discount amount if 100% discount or zero quantity is there closes odoo/odoo#93027 X-original-commit: 60047761e592e9621650d65ac6ac1911f853141a Signed-off-by: Josse Colpaert --- .../l10n_in_edi/models/account_edi_format.py | 20 +++++++---- addons/l10n_in_edi/tests/test_edi_json.py | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/addons/l10n_in_edi/models/account_edi_format.py b/addons/l10n_in_edi/models/account_edi_format.py index 927b462a3ca..6cb7a751406 100644 --- a/addons/l10n_in_edi/models/account_edi_format.py +++ b/addons/l10n_in_edi/models/account_edi_format.py @@ -7,7 +7,7 @@ import pytz import markupsafe from odoo import models, fields, api, _ -from odoo.tools import html_escape +from odoo.tools import html_escape, float_is_zero from odoo.exceptions import AccessError from odoo.addons.iap import jsonrpc import logging @@ -302,6 +302,16 @@ class AccountEdiFormat(models.Model): } """ tax_details_by_code = self._get_l10n_in_tax_details_by_line_code(line_tax_details.get("tax_details", {})) + full_discount_or_zero_quantity = line.discount == 100.00 or float_is_zero(line.quantity, 3) + if full_discount_or_zero_quantity: + unit_price_in_inr = line.currency_id._convert( + line.price_unit, + line.company_currency_id, + line.company_id, + line.date or fields.Date.context_today(self) + ) + else: + unit_price_in_inr = ((line.balance / (1 - (line.discount / 100))) / line.quantity) * sign return { "SlNo": str(index), "PrdDesc": line.name.replace("\n", ""), @@ -310,12 +320,10 @@ class AccountEdiFormat(models.Model): "Qty": self._l10n_in_round_value(line.quantity or 0.0, 3), "Unit": line.product_uom_id.l10n_in_code and line.product_uom_id.l10n_in_code.split("-")[0] or "OTH", # Unit price in company currency and tax excluded so its different then price_unit - "UnitPrice": self._l10n_in_round_value( - ((line.balance / (1 - (line.discount / 100))) / line.quantity) * sign, 3), + "UnitPrice": self._l10n_in_round_value(unit_price_in_inr, 3), # total amount is before discount - "TotAmt": self._l10n_in_round_value((line.balance / (1 - (line.discount / 100))) * sign), - "Discount": self._l10n_in_round_value( - ((line.balance / (1 - (line.discount / 100))) - line.balance) * sign), + "TotAmt": self._l10n_in_round_value(unit_price_in_inr * line.quantity), + "Discount": self._l10n_in_round_value((unit_price_in_inr * line.quantity) * (line.discount / 100)), "AssAmt": self._l10n_in_round_value(line.balance * sign), "GstRt": self._l10n_in_round_value(tax_details_by_code.get("igst_rate", 0.00) or ( tax_details_by_code.get("cgst_rate", 0.00) + tax_details_by_code.get("sgst_rate", 0.00)), 3), diff --git a/addons/l10n_in_edi/tests/test_edi_json.py b/addons/l10n_in_edi/tests/test_edi_json.py index fe7ac0b6edf..4abc1742dd4 100644 --- a/addons/l10n_in_edi/tests/test_edi_json.py +++ b/addons/l10n_in_edi/tests/test_edi_json.py @@ -48,6 +48,14 @@ class TestEdiJson(AccountTestInvoicingCommon): cls.invoice.write({ "invoice_line_ids": [(1, l_id, {"discount": 10}) for l_id in cls.invoice.invoice_line_ids.ids]}) cls.invoice.action_post() + cls.invoice_full_discount = cls.init_invoice("out_invoice", post=False, products=cls.product_a) + cls.invoice_full_discount.write({ + "invoice_line_ids": [(1, l_id, {"discount": 100}) for l_id in cls.invoice_full_discount.invoice_line_ids.ids]}) + cls.invoice_full_discount.action_post() + cls.invoice_zero_qty = cls.init_invoice("out_invoice", post=False, products=cls.product_a) + cls.invoice_zero_qty.write({ + "invoice_line_ids": [(1, l_id, {"quantity": 0}) for l_id in cls.invoice_zero_qty.invoice_line_ids.ids]}) + cls.invoice_zero_qty.action_post() def test_edi_json(self): json_value = self.env["account.edi.format"]._l10n_in_edi_generate_invoice_json(self.invoice) @@ -94,3 +102,31 @@ class TestEdiJson(AccountTestInvoicingCommon): } } self.assertDictEqual(json_value, expected, "Indian EDI send json value is not matched") + + #=================================== Full discount test ===================================== + json_value = self.env["account.edi.format"]._l10n_in_edi_generate_invoice_json(self.invoice_full_discount) + expected.update({ + "DocDtls": {"Typ": "INV", "No": "INV/2019/00002", "Dt": "01/01/2019"}, + "ItemList": [{ + "SlNo": "1", "PrdDesc": "product_a", "IsServc": "N", "HsnCd": "01111", "Qty": 1.0, + "Unit": "UNT", "UnitPrice": 1000.0, "TotAmt": 1000.0, "Discount": 1000.0, "AssAmt": 0.0, + "GstRt": 5.0, "IgstAmt": 0.0, "CgstAmt": 0.0, "SgstAmt": 0.0, "CesRt": 0.0, "CesAmt": 0.0, + "CesNonAdvlAmt": 0.0, "StateCesRt": 0.0, "StateCesAmt": 0.0, "StateCesNonAdvlAmt": 0.0, + "OthChrg": 0.0, "TotItemVal": 0.0}], + "ValDtls": {"AssVal": 0.0, "CgstVal": 0.0, "SgstVal": 0.0, "IgstVal": 0.0, "CesVal": 0.0, + "StCesVal": 0.0, "RndOffAmt": 0.0, "TotInvVal": 0.0} + }) + self.assertDictEqual(json_value, expected, "Indian EDI with 100% discount sent json value is not matched") + + #=================================== Zero quantity test ============================================= + json_value = self.env["account.edi.format"]._l10n_in_edi_generate_invoice_json(self.invoice_zero_qty) + expected.update({ + "DocDtls": {"Typ": "INV", "No": "INV/2019/00003", "Dt": "01/01/2019"}, + "ItemList": [{ + "SlNo": "1", "PrdDesc": "product_a", "IsServc": "N", "HsnCd": "01111", "Qty": 0.0, + "Unit": "UNT", "UnitPrice": 1000.0, "TotAmt": 0.0, "Discount": 0.0, "AssAmt": 0.0, + "GstRt": 5.0, "IgstAmt": 0.0, "CgstAmt": 0.0, "SgstAmt": 0.0, "CesRt": 0.0, "CesAmt": 0.0, + "CesNonAdvlAmt": 0.0, "StateCesRt": 0.0, "StateCesAmt": 0.0, "StateCesNonAdvlAmt": 0.0, + "OthChrg": 0.0, "TotItemVal": 0.0}], + }) + self.assertDictEqual(json_value, expected, "Indian EDI with 0(zero) quantity sent json value is not matched")