summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Lempereur <nle@odoo.com>2025-01-23 20:01:58 +0100
committerNicolas Lempereur <nle@odoo.com>2025-02-06 16:44:15 +0000
commitbe11713fe02aa4f9fbff7528acb1fd408ad725cb (patch)
treefb696d8c4361fe46c6967449fa55dad4550bebca
parent0528b73ae97ef6d19592cc2232556c6acadc652d (diff)
[FIX] l10n_it_edi: post invoice w/ multiple downpayments
Scenario: - create a sale order and confirm it - create two partial down payments for that sale order and confirm them - create a invoice for the remaining amount and confirm it - send and print the invoice (with Send to Tax Agency selected) Result: Traceback error is raised: > ... > File "addons/account/models/account_tax.py", line 2475, in _dispatch_negative_lines > line.setdefault('discount_amount', line['discount_amount_before_dispatching']) > KeyError: 'discount_amount_before_dispatching' Why: bbe04fb62916ae326c830e89b2664dfd32b62b75 was modifying the list base_lines while looping over it, so we would not iterate over all elements, for example: > l = [5, 6, 7, 8] > for i in l: print(i);l.remove(i) shows 5 and 7 Notes: Without the fix, the added test fails with the error given above. The same code is in 17.0 but doesn't cause this error because we have two loops. One that sets 'discount_amount_before_dispatching' and after that one that remove downpayment from base_lines. But the fix should still be backported because it works by chance. opw-4496310 closes odoo/odoo#194949 Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
-rw-r--r--addons/l10n_it_edi/models/account_move.py3
-rw-r--r--addons/l10n_it_edi/tests/export_xmls/test_export_invoice_with_two_downpayments.xml115
-rw-r--r--addons/l10n_it_edi/tests/test_edi_export.py33
3 files changed, 149 insertions, 2 deletions
diff --git a/addons/l10n_it_edi/models/account_move.py b/addons/l10n_it_edi/models/account_move.py
index b74b6e5b9c8..29926a206a4 100644
--- a/addons/l10n_it_edi/models/account_move.py
+++ b/addons/l10n_it_edi/models/account_move.py
@@ -507,7 +507,6 @@ class AccountMove(models.Model):
line = base_line['record']
if line.price_subtotal < 0 and line._get_downpayment_lines():
downpayment_lines.append(base_line)
- base_lines.remove(base_line)
if float_compare(quantity, 0, 2) < 0:
# Negative quantity is refused by SDI, so we invert quantity and price_unit to keep the price_subtotal
@@ -515,6 +514,8 @@ class AccountMove(models.Model):
'quantity': -quantity,
'price_unit': -price_unit,
})
+ for downpayment_line in downpayment_lines:
+ base_lines.remove(downpayment_line)
dispatched_results = self.env['account.tax']._dispatch_negative_lines(base_lines)
base_lines = dispatched_results['result_lines'] + dispatched_results['orphan_negative_lines'] + downpayment_lines
diff --git a/addons/l10n_it_edi/tests/export_xmls/test_export_invoice_with_two_downpayments.xml b/addons/l10n_it_edi/tests/export_xmls/test_export_invoice_with_two_downpayments.xml
new file mode 100644
index 00000000000..c1f41b39115
--- /dev/null
+++ b/addons/l10n_it_edi/tests/export_xmls/test_export_invoice_with_two_downpayments.xml
@@ -0,0 +1,115 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<p:FatturaElettronica xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2" xsi:schemaLocation="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2 http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2/Schema_del_file_xml_FatturaPA_versione_1.2.xsd" versione="FPR12">
+ <FatturaElettronicaHeader>
+ <DatiTrasmissione>
+ <IdTrasmittente>
+ <IdPaese>IT</IdPaese>
+ <IdCodice>01234560157</IdCodice>
+ </IdTrasmittente>
+ <ProgressivoInvio>V202500003</ProgressivoInvio>
+ <FormatoTrasmissione>FPR12</FormatoTrasmissione>
+ <CodiceDestinatario>0000000</CodiceDestinatario>
+ <ContattiTrasmittente>
+ <Telefono>0266766700</Telefono>
+ <Email>test@test.it</Email>
+ </ContattiTrasmittente>
+ </DatiTrasmissione>
+ <CedentePrestatore>
+ <DatiAnagrafici>
+ <IdFiscaleIVA>
+ <IdPaese>IT</IdPaese>
+ <IdCodice>01234560157</IdCodice>
+ </IdFiscaleIVA>
+ <CodiceFiscale>01234560157</CodiceFiscale>
+ <Anagrafica>
+ <Denominazione>company_2_data</Denominazione>
+ </Anagrafica>
+ <RegimeFiscale>RF01</RegimeFiscale>
+ </DatiAnagrafici>
+ <Sede>
+ <Indirizzo>1234 Test Street</Indirizzo>
+ <CAP>12345</CAP>
+ <Comune>Prova</Comune>
+ <Nazione>IT</Nazione>
+ </Sede>
+ </CedentePrestatore>
+ <CessionarioCommittente>
+ <DatiAnagrafici>
+ <IdFiscaleIVA>
+ <IdPaese>IT</IdPaese>
+ <IdCodice>00465840031</IdCodice>
+ </IdFiscaleIVA>
+ <CodiceFiscale>93026890017</CodiceFiscale>
+ <Anagrafica>
+ <Denominazione>Alessi</Denominazione>
+ </Anagrafica>
+ </DatiAnagrafici>
+ <Sede>
+ <Indirizzo>Via Privata Alessi 6</Indirizzo>
+ <CAP>28887</CAP>
+ <Comune>Milan</Comune>
+ <Nazione>IT</Nazione>
+ </Sede>
+ </CessionarioCommittente>
+ </FatturaElettronicaHeader>
+ <FatturaElettronicaBody>
+ <DatiGenerali>
+ <DatiGeneraliDocumento>
+ <TipoDocumento>TD01</TipoDocumento>
+ <Divisa>EUR</Divisa>
+ <Data>2025-02-03</Data>
+ <Numero>INV/2025/00003</Numero>
+ <ImportoTotaleDocumento>94.00</ImportoTotaleDocumento>
+ </DatiGeneraliDocumento>
+ <DatiFattureCollegate>
+ <IdDocumento>INV/2025/00001</IdDocumento>
+ <Data>2025-02-03</Data>
+ </DatiFattureCollegate>
+ <DatiFattureCollegate>
+ <IdDocumento>INV/2025/00002</IdDocumento>
+ <Data>2025-02-03</Data>
+ </DatiFattureCollegate>
+ </DatiGenerali>
+ <DatiBeniServizi>
+ <DettaglioLinee>
+ <NumeroLinea>1</NumeroLinea>
+ <Descrizione>Test Service Product</Descrizione>
+ <Quantita>1.00</Quantita>
+ <PrezzoUnitario>200.00000000</PrezzoUnitario>
+ <PrezzoTotale>200.00000000</PrezzoTotale>
+ <AliquotaIVA>22.00</AliquotaIVA>
+ </DettaglioLinee>
+ <DettaglioLinee>
+ <NumeroLinea>2</NumeroLinea>
+ <Descrizione>Down Payment (ref: INV/2025/00001 on 02/03/2025), INV/2025/00001</Descrizione>
+ <Quantita>1.00</Quantita>
+ <PrezzoUnitario>-40.98000000</PrezzoUnitario>
+ <PrezzoTotale>-40.98000000</PrezzoTotale>
+ <AliquotaIVA>22.00</AliquotaIVA>
+ </DettaglioLinee>
+ <DettaglioLinee>
+ <NumeroLinea>3</NumeroLinea>
+ <Descrizione>Down Payment (ref: INV/2025/00002 on 02/03/2025), INV/2025/00002</Descrizione>
+ <Quantita>1.00</Quantita>
+ <PrezzoUnitario>-81.97000000</PrezzoUnitario>
+ <PrezzoTotale>-81.97000000</PrezzoTotale>
+ <AliquotaIVA>22.00</AliquotaIVA>
+ </DettaglioLinee>
+ <DatiRiepilogo>
+ <AliquotaIVA>22.00</AliquotaIVA>
+ <ImponibileImporto>77.05</ImponibileImporto>
+ <Imposta>16.95</Imposta>
+ <EsigibilitaIVA>I</EsigibilitaIVA>
+ </DatiRiepilogo>
+ </DatiBeniServizi>
+ <DatiPagamento>
+ <CondizioniPagamento>TP02</CondizioniPagamento>
+ <DettaglioPagamento>
+ <ModalitaPagamento>MP05</ModalitaPagamento>
+ <DataScadenzaPagamento>2025-02-03</DataScadenzaPagamento>
+ <ImportoPagamento>94.00</ImportoPagamento>
+ <CodicePagamento>INV/2025/00003</CodicePagamento>
+ </DettaglioPagamento>
+ </DatiPagamento>
+ </FatturaElettronicaBody>
+</p:FatturaElettronica>
diff --git a/addons/l10n_it_edi/tests/test_edi_export.py b/addons/l10n_it_edi/tests/test_edi_export.py
index aa21b9db764..35506cb5bf1 100644
--- a/addons/l10n_it_edi/tests/test_edi_export.py
+++ b/addons/l10n_it_edi/tests/test_edi_export.py
@@ -1,7 +1,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import Command
-from odoo.tests import tagged
+from odoo.tests import freeze_time, tagged
from odoo.addons.l10n_it_edi.tests.common import TestItEdi
@@ -495,3 +495,34 @@ class TestItEdiExport(TestItEdi):
})
invoice.action_post()
self._assert_export_invoice(invoice, 'export_foreign_currency_global_discount.xml')
+
+ @freeze_time("2025-02-03")
+ def test_export_invoice_with_two_downpayments(self):
+ if self.env['ir.module.module']._get('sale').state != 'installed':
+ self.skipTest("sale module is not installed")
+
+ sale_order = self.env['sale.order'].with_company(self.company).create({
+ 'partner_id': self.italian_partner_a.id,
+ 'order_line': [
+ Command.create({'product_id': self.service_product.id, 'price_unit': 200.00}),
+ ],
+ })
+ sale_order.action_confirm()
+
+ for amount in (50, 100):
+ self.env['account.move'].with_company(self.company).browse(
+ self.env['sale.advance.payment.inv'].create([{
+ 'advance_payment_method': 'fixed',
+ 'fixed_amount': amount,
+ 'sale_order_ids': [Command.link(sale_order.id)],
+ }]).create_invoices()['res_id']
+ ).action_post()
+
+ invoice = self.env['account.move'].with_company(self.company).browse(
+ self.env['sale.advance.payment.inv'].create([{
+ 'advance_payment_method': 'delivered',
+ 'sale_order_ids': [Command.link(sale_order.id)],
+ }]).create_invoices()['res_id']
+ )
+ invoice.action_post()
+ self._assert_export_invoice(invoice, 'test_export_invoice_with_two_downpayments.xml')