Skip to content

Commit 6c4905c

Browse files
committed
[IMP] l10n_it_edi_extension: add AltriDatiGestionali (2.2.1.16) export support for XML invoices
1 parent cfe9d35 commit 6c4905c

12 files changed

Lines changed: 982 additions & 422 deletions

l10n_it_edi_extension/README.rst

Lines changed: 357 additions & 333 deletions
Large diffs are not rendered by default.

l10n_it_edi_extension/__manifest__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"security/ir.model.access.csv",
2626
"data/invoice_it_template.xml",
2727
"data/res.city.it.code.csv",
28+
"views/l10n_it_edi_move_line_other_data_view.xml",
2829
"views/l10n_it_view.xml",
2930
"views/res_partner_view.xml",
3031
"views/company_view.xml",

l10n_it_edi_extension/models/account_move.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,24 @@ def _l10n_it_edi_add_base_lines_xml_values(
216216
)
217217
for base_line, _aggregated_values in base_lines_aggregated_values:
218218
line = base_line["record"]
219+
# Build other_data list from l10n_it_edi_other_data_ids
220+
other_data_list = []
221+
for other_data in line.l10n_it_edi_other_data_ids:
222+
other_data_dict = {
223+
"tipo_dato": other_data.name,
224+
"riferimento_testo": other_data.text_ref or False,
225+
"riferimento_numero": other_data.num_ref or False,
226+
# Pass date object directly, format_date() in template handles it
227+
"riferimento_data": other_data.date_ref or False,
228+
}
229+
other_data_list.append(other_data_dict)
230+
231+
# Get existing altri_dati_gestionali_list or initialize empty list
232+
existing_list = base_line["it_values"].get("altri_dati_gestionali_list", [])
219233
base_line["it_values"].update(
220234
{
221235
"admin_ref": line.l10n_it_edi_admin_ref or None,
236+
"altri_dati_gestionali_list": existing_list + other_data_list,
222237
}
223238
)
224239
return res

l10n_it_edi_extension/models/account_move_line.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright 2025 Giuseppe Borruso - Dinamiche Aziendali srl
2+
# Copyright 2026 Nextev Srl
23
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
34

45
from odoo import fields, models
@@ -8,3 +9,26 @@ class AccountMoveLineInherit(models.Model):
89
_inherit = "account.move.line"
910

1011
l10n_it_edi_admin_ref = fields.Char(string="Admin. ref.", size=20, copy=False)
12+
l10n_it_edi_other_data_ids = fields.One2many(
13+
"l10n_it_edi.line_other_data",
14+
"move_line_id",
15+
string="Other Management Data",
16+
copy=True,
17+
help="Additional management data (AltriDatiGestionali) to be exported "
18+
"in the FatturaPA XML.",
19+
)
20+
21+
def action_open_other_data(self):
22+
"""Open a popup to manage Other Management Data for this invoice line."""
23+
self.ensure_one()
24+
return {
25+
"name": "Altri Dati Gestionali",
26+
"type": "ir.actions.act_window",
27+
"res_model": "l10n_it_edi.line_other_data",
28+
"view_mode": "list,form",
29+
"domain": [("move_line_id", "=", self.id)],
30+
"context": {
31+
"default_move_line_id": self.id,
32+
},
33+
"target": "new",
34+
}
Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,90 @@
11
# Copyright 2025 Giuseppe Borruso - Dinamiche Aziendali srl
2+
# Copyright 2025 Nextev Srl
23
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
34

4-
from odoo import fields, models
5+
from odoo import _, api, fields, models
6+
from odoo.exceptions import ValidationError
57

68

79
class EInvoiceLineOtherData(models.Model):
10+
"""Model for storing AltriDatiGestionali (2.2.1.16) on invoice lines.
11+
12+
Used both for read-only import data (linked to l10n_it_edi.line) and for
13+
editable export data (linked to account.move.line).
14+
"""
15+
816
_name = "l10n_it_edi.line_other_data"
917
_description = "E-invoice line other data"
18+
_rec_name = "display_name"
1019

1120
l10n_it_edi_line_id = fields.Many2one(
1221
"l10n_it_edi.line", string="Related E-bill Line", readonly=True
1322
)
14-
name = fields.Char(string="Data Type", readonly=True)
15-
text_ref = fields.Char(string="Text Reference", readonly=True)
16-
num_ref = fields.Float(string="Number Reference", readonly=True)
17-
date_ref = fields.Char(string="Date Reference", readonly=True)
23+
move_line_id = fields.Many2one(
24+
"account.move.line",
25+
string="Invoice Line",
26+
ondelete="cascade",
27+
index=True,
28+
)
29+
name = fields.Char(
30+
string="Data Type",
31+
required=True,
32+
size=10,
33+
help="TipoDato: Type of additional data (max 10 characters)",
34+
)
35+
text_ref = fields.Char(
36+
string="Text Reference",
37+
size=60,
38+
help="RiferimentoTesto: Text reference (max 60 characters)",
39+
)
40+
num_ref = fields.Float(
41+
string="Number Reference",
42+
digits=(16, 8),
43+
help="RiferimentoNumero: Numeric reference (up to 8 decimal places)",
44+
)
45+
date_ref = fields.Date(
46+
string="Date Reference",
47+
help="RiferimentoData: Date reference",
48+
)
49+
50+
@api.depends("name", "text_ref", "num_ref", "date_ref")
51+
def _compute_display_name(self):
52+
for record in self:
53+
parts = [record.name or ""]
54+
if record.text_ref:
55+
parts.append(record.text_ref)
56+
if record.num_ref:
57+
parts.append(str(record.num_ref))
58+
if record.date_ref:
59+
parts.append(str(record.date_ref))
60+
record.display_name = ": ".join(filter(None, parts))
61+
62+
def action_delete(self):
63+
move_line_id = self.move_line_id.id
64+
self.unlink()
65+
return {
66+
"type": "ir.actions.act_window",
67+
"name": _("Other Management Data"),
68+
"res_model": self._name,
69+
"view_mode": "list,form",
70+
"target": "new",
71+
"domain": [("move_line_id", "=", move_line_id)],
72+
"context": {"default_move_line_id": move_line_id},
73+
}
74+
75+
@api.constrains("name", "text_ref", "num_ref", "date_ref", "move_line_id")
76+
def _check_at_least_one_ref(self):
77+
for record in self:
78+
# Only validate for export records (linked to account.move.line)
79+
if not record.move_line_id:
80+
continue
81+
has_text = bool(record.text_ref)
82+
has_num = bool(record.num_ref)
83+
has_date = bool(record.date_ref)
84+
if not has_text and not has_num and not has_date:
85+
raise ValidationError(
86+
_(
87+
"At least one of Text Reference, Number Reference, "
88+
"or Date Reference must be provided."
89+
)
90+
)

l10n_it_edi_extension/readme/DESCRIPTION.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ Le funzionalità principali incluse sono:
1515
- `<StabileOrganizzazione>`: rappresenta i dati della sede operativa stabile del cedente/prestatore in Italia se diversa dalla sede legale. Da impostare in odoo nell'azienda, tab "Informazioni Generali"
1616
- `<Causale>`: in questo caso non c'è un campo apposito, ma trascrive i "Termini e condizioni" della fattura
1717
- `<Art73>`: indica se il documento è stato emesso secondo modalità e termini stabiliti con decreto ministeriale ai sensi dell'articolo 73 del DPR 633/72. Da impostare in odoo nell'azienda o direttamente in fattura.
18+
- `<AltriDatiGestionali>` (2.2.1.16): dati gestionali aggiuntivi che possono essere inseriti manualmente su ogni riga fattura ed esportati nel file XML FatturaPA. Ogni voce include:
19+
- `<TipoDato>`: tipo di dato (max 10 caratteri, obbligatorio)
20+
- `<RiferimentoTesto>`: riferimento testuale (max 60 caratteri)
21+
- `<RiferimentoNumero>`: riferimento numerico (fino a 8 decimali)
22+
- `<RiferimentoData>`: riferimento data
23+
- Per aggiungere questi dati, aprire la riga fattura e compilare la sezione "Altri Dati Gestionali".
1824
- `<IndirizzoResa>`: rappresenta l'indirizzo di consegna della merce.
1925

2026
3. Miglioramenti nell'import delle fatture XML:
@@ -97,6 +103,12 @@ The main features included are:
97103
- `<StabileOrganizzazione>`: represents the data of the seller/provider's permanent establishment in Italy if different from the registered office
98104
- `<Causale>`: in this case there is no specific field, but it transcribes the "Terms and conditions" of the invoice.
99105
- `<Art73>`: indicates if the document was issued according to methods and terms established by ministerial decree pursuant to article 73 of DPR 633/72
106+
- `<AltriDatiGestionali>` (2.2.1.16): additional management data that can be manually entered on each invoice line and exported to the FatturaPA XML file. Each entry includes:
107+
- `<TipoDato>`: data type (max 10 characters, required)
108+
- `<RiferimentoTesto>`: text reference (max 60 characters)
109+
- `<RiferimentoNumero>`: numeric reference (up to 8 decimal places)
110+
- `<RiferimentoData>`: date reference
111+
- To add this data, open the invoice line and fill in the "Other Management Data" section.
100112
- `<IndirizzoResa>`: represents the shipping address of the goods.
101113

102114
3. Improvements in XML invoice import:

0 commit comments

Comments
 (0)