From a32bca2bdcda82221becc9ae8e6a14c079aca826 Mon Sep 17 00:00:00 2001 From: jbw-odoo Date: Tue, 27 Sep 2022 06:52:35 +0000 Subject: [PATCH] [FIX] l10n_it_edi: handle negative unit price MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this fix negative aml unit prices were systematically set to positive in the edi xml generating inconsistencies. Manual forwardport of d31d562 closes odoo/odoo#101493 Task: opw-2963947 X-original-commit: 0954550e55ce35445a198006872a12298cd77d5b Signed-off-by: Josse Colpaert Signed-off-by: de Wouters de Bouchout Jean-BenoƮt (jbw) --- addons/l10n_it_edi/models/account_invoice.py | 13 ++--- addons/l10n_it_edi/tests/test_edi_export.py | 60 ++++++++++++++++++++ 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/addons/l10n_it_edi/models/account_invoice.py b/addons/l10n_it_edi/models/account_invoice.py index 90509276bcd..7b738830064 100644 --- a/addons/l10n_it_edi/models/account_invoice.py +++ b/addons/l10n_it_edi/models/account_invoice.py @@ -71,14 +71,11 @@ class AccountMove(models.Model): invoice_lines = [] lines = self.invoice_line_ids.filtered(lambda l: not l.display_type in ('line_note', 'line_section')) for num, line in enumerate(lines): - price_subtotal = line.balance if convert_to_euros else line.price_subtotal - # The price_subtotal should be negative when: - # The line has downpayment lines, but is not a downpayment (i.e. the final invoice, from which downpayment lines are subtracted) or, - # the line is a reverse charge refund. - if (line._get_downpayment_lines() and not is_downpayment) or reverse_charge_refund: - price_subtotal = -abs(price_subtotal) - else: - price_subtotal = abs(price_subtotal) + sign = -1 if line.move_id.is_inbound() else 1 + price_subtotal = (line.balance * sign) if convert_to_euros else line.price_subtotal + # The price_subtotal should be inverted when the line is a reverse charge refund. + if reverse_charge_refund: + price_subtotal = -price_subtotal # Unit price price_unit = 0 diff --git a/addons/l10n_it_edi/tests/test_edi_export.py b/addons/l10n_it_edi/tests/test_edi_export.py index 31049d03044..259c2daed20 100644 --- a/addons/l10n_it_edi/tests/test_edi_export.py +++ b/addons/l10n_it_edi/tests/test_edi_export.py @@ -287,6 +287,24 @@ class TestItEdiExport(TestItEdi): ], }) + cls.negative_price_invoice = cls.env['account.move'].with_company(cls.company).create({ + 'move_type': 'out_invoice', + 'invoice_date': datetime.date(2022, 3, 24), + 'invoice_date_due': datetime.date(2022, 3, 24), + 'partner_id': cls.italian_partner_a.id, + 'partner_bank_id': cls.test_bank.id, + 'invoice_line_ids': [ + (0, 0, { + **cls.standard_line, + }), + (0, 0, { + **cls.standard_line, + 'name': 'negative_line', + 'price_unit': -100.0, + }), + ], + }) + # post the invoices cls.price_included_invoice._post() cls.partial_discount_invoice._post() @@ -296,6 +314,7 @@ class TestItEdiExport(TestItEdi): cls.total_400_VAT_simplified_invoice._post() cls.pa_partner_invoice._post() cls.zero_tax_invoice._post() + cls.negative_price_invoice._post() cls.edi_basis_xml = cls._get_test_file_content('IT00470550013_basis.xml') cls.edi_simplified_basis_xml = cls._get_test_file_content('IT00470550013_simpl.xml') @@ -646,3 +665,44 @@ class TestItEdiExport(TestItEdi): ) invoice_etree = self.with_applied_xpath(invoice_etree, "") self.assertXmlTreeEqual(invoice_etree, expected_etree) + + def test_negative_price_invoice(self): + invoice_etree = etree.fromstring(self.edi_format._export_as_xml(self.negative_price_invoice)) + expected_etree = self.with_applied_xpath( + etree.fromstring(self.edi_basis_xml), + ''' + + + + 1 + standard_line + 1.00 + 800.400000 + 800.40 + 22.00 + + + 2 + negative_line + 1.00 + -100.000000 + -100.00 + 22.00 + + + 22.00 + 700.40 + 154.09 + I + + + + + 854.49 + + + 854.49 + + ''') + invoice_etree = self.with_applied_xpath(invoice_etree, "") + self.assertXmlTreeEqual(invoice_etree, expected_etree)