From 40b99b686d8064d39818825f92afcd7eb3728ed2 Mon Sep 17 00:00:00 2001 From: Julien Van Roy Date: Wed, 14 Feb 2024 09:37:16 +0000 Subject: [PATCH] [FIX] account_edi_ubl_cii: round PriceAmount (repr. error) We no longer round the PriceAmount since 0fd7284158483bce3308e7c5ba42e3c6ee5abd10. But then, we may encounter a representation error if the PriceAmount is not exactly representable as a binary fraction (see: https://docs.python.org/3/tutorial/floatingpoint.html#representation-error). For instance: having a line with `price_subtotal` = 306.45 and `quantity` = 3, we will compute the PriceAmount as 306.45 / 3 which yields 102.14999999999999. To avoid such a case we round "reasonably" the PriceAmount. opw-3729369 closes odoo/odoo#154361 X-original-commit: f27818e7bc62c548e9bd76d47594d3dcdec85d3d Signed-off-by: Laurent Smet (las) Signed-off-by: Julien Van Roy (juvr) --- .../models/account_edi_xml_ubl_20.py | 3 ++- .../tests/test_xml_ubl_be.py | 20 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py b/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py index 11c507457cb..686704fd370 100644 --- a/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py +++ b/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py @@ -4,6 +4,7 @@ from lxml import etree from odoo import models, _ from odoo.tools import html2plaintext, cleanup_xml_node +from odoo.tools.float_utils import float_round class AccountEdiXmlUBL20(models.AbstractModel): @@ -338,7 +339,7 @@ class AccountEdiXmlUBL20(models.AbstractModel): 'currency_dp': self._get_currency_decimal_places(line.currency_id), # The price of an item, exclusive of VAT, after subtracting item price discount. - 'price_amount': gross_price_unit, + 'price_amount': float_round(gross_price_unit, 10), 'product_price_dp': self.env['decimal.precision'].precision_get('Product Price'), # The number of item units to which the price applies. diff --git a/addons/l10n_account_edi_ubl_cii_tests/tests/test_xml_ubl_be.py b/addons/l10n_account_edi_ubl_cii_tests/tests/test_xml_ubl_be.py index e390310b6d3..37ae1837e05 100644 --- a/addons/l10n_account_edi_ubl_cii_tests/tests/test_xml_ubl_be.py +++ b/addons/l10n_account_edi_ubl_cii_tests/tests/test_xml_ubl_be.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- +import base64 +from lxml import etree + from odoo import Command from odoo.addons.l10n_account_edi_ubl_cii_tests.tests.common import TestUBLCommon from odoo.addons.account.tests.test_account_move_send import TestAccountMoveSendCommon from odoo.tests import tagged -import base64 + @tagged('post_install_l10n', 'post_install', '-at_install') class TestUBLBE(TestUBLCommon, TestAccountMoveSendCommon): @@ -486,6 +489,21 @@ class TestUBLBE(TestUBLCommon, TestAccountMoveSendCommon): self._assert_invoice_attachment(invoice.ubl_cii_xml_id, None, 'from_odoo/bis3_export_with_changed_taxes.xml') + def test_export_rounding_price_amount(self): + invoice = self._generate_move( + self.partner_1, + self.partner_2, + move_type='out_invoice', + invoice_line_ids=[{ + 'product_id': self.product_a.id, + 'quantity': 3, + 'price_unit': 102.15, + 'tax_ids': [Command.set([self.tax_12.id])] + }], + ) + price_amount = etree.fromstring(invoice.ubl_cii_xml_id.raw).find('.//{*}InvoiceLine/{*}Price/{*}PriceAmount') + self.assertEqual(price_amount.text, '102.15') + #################################################### # Test import ####################################################