Skip to content

Commit 5759ced

Browse files
committed
[IMP] l10n_it_edi_extension: add AltriDatiGestionali (2.2.1.16) export support for XML invoices
1 parent 77e3b95 commit 5759ced

12 files changed

Lines changed: 974 additions & 415 deletions

l10n_it_edi_extension/README.rst

Lines changed: 350 additions & 326 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
@@ -244,9 +244,24 @@ def _l10n_it_edi_add_base_lines_xml_values(
244244
)
245245
for base_line, _aggregated_values in base_lines_aggregated_values:
246246
line = base_line["record"]
247+
# Build other_data list from l10n_it_edi_other_data_ids
248+
other_data_list = []
249+
for other_data in line.l10n_it_edi_other_data_ids:
250+
other_data_dict = {
251+
"tipo_dato": other_data.name,
252+
"riferimento_testo": other_data.text_ref or False,
253+
"riferimento_numero": other_data.num_ref or False,
254+
# Pass date object directly, format_date() in template handles it
255+
"riferimento_data": other_data.date_ref or False,
256+
}
257+
other_data_list.append(other_data_dict)
258+
259+
# Get existing altri_dati_gestionali_list or initialize empty list
260+
existing_list = base_line["it_values"].get("altri_dati_gestionali_list", [])
247261
base_line["it_values"].update(
248262
{
249263
"admin_ref": line.l10n_it_edi_admin_ref or None,
264+
"altri_dati_gestionali_list": existing_list + other_data_list,
250265
}
251266
)
252267
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: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,89 @@
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"
1018

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

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)