Skip to content

Commit 3fe960b

Browse files
monen17Borruso
authored andcommitted
[IMP] l10n_it_edi_extension: Import detail level
Allow the user to import e-bills with no lines, one line for each tax rate, or all lines (default).
1 parent dc2774e commit 3fe960b

11 files changed

Lines changed: 283 additions & 62 deletions

File tree

l10n_it_edi_extension/README.rst

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ Le funzionalità principali incluse sono:
180180

181181
**English**
182182

183-
his module extends Odoo's standard Italian electronic invoicing
183+
This module extends Odoo's standard Italian electronic invoicing
184184
functionality, introducing useful tools such as XML preview and fiscal
185185
code calculation and improvements in importing and exporting XML
186186
invoices.
@@ -204,7 +204,7 @@ The main features included are:
204204
seller/provider's permanent establishment in Italy if different
205205
from the registered office
206206
- ``<Causale>``: in this case there is no specific field, but it
207-
transcribes the "Terms and conditions" od the invoice.
207+
transcribes the "Terms and conditions" of the invoice.
208208
- ``<Art73>``: indicates if the document was issued according to
209209
methods and terms established by ministerial decree pursuant to
210210
article 73 of DPR 633/72
@@ -381,6 +381,12 @@ necessario che siano installati e configurati i moduli dipendenti:
381381
l'invio diretto tramite Odoo (se supportato dalla configurazione
382382
generale).
383383

384+
In Fatturazione > Configurazione > Impostazioni, valorizzare "Livello di
385+
dettaglio importazione e-fatture" per importare le fatture elettroniche
386+
senza righe, con una riga per ogni aliquota, oppure con tutte le righe
387+
(default). Questa configurazione può essere sovrascritta dal campo
388+
"Livello di dettaglio importazione e-fatture" in ogni fornitore.
389+
384390
**English**
385391

386392
The only available configurations are:
@@ -425,6 +431,11 @@ modules must be installed and configured:
425431
- Optional SDI credentials configuration if direct sending through
426432
Odoo is used (if supported by general configuration).
427433

434+
In Invoicing > Configuration > Settings, fill "E-bills import detail
435+
level" to import e-bills with no lines, one line for each tax rate, or
436+
all lines (default). This setting can be overridden using the "E-bills
437+
import detail level" in each supplier.
438+
428439
Bug Tracker
429440
===========
430441

l10n_it_edi_extension/models/account_move.py

Lines changed: 97 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ def _l10n_it_edi_get_extra_info(
333333
for element_summary in elements_summary:
334334
self.l10n_it_edi_amount_tax += get_float(element_summary, ".//Imposta")
335335

336+
extra_info["l10n_it_edi_ext_body_tree"] = body_tree
336337
return extra_info, message_to_log
337338

338339
def _l10n_it_edi_create_partner(
@@ -506,63 +507,106 @@ def _l10n_it_edi_search_partner(self, company, vat, codice_fiscale, email):
506507

507508
return partner
508509

509-
def _l10n_it_edi_import_line(self, element, move_line, extra_info=None):
510-
# Admin. ref.
511-
if admin_ref := get_text(element, ".//RiferimentoAmministrazione"):
512-
move_line.l10n_it_edi_admin_ref = admin_ref
513-
514-
vals = {
515-
"line_number": int(get_text(element, ".//NumeroLinea")),
516-
"service_type": get_text(element, ".//TipoCessionePrestazione"),
517-
"name": " ".join(get_text(element, ".//Descrizione").split()),
518-
"qty": float(get_text(element, ".//Quantita") or 0),
519-
"uom": get_text(element, ".//UnitaMisura"),
520-
"period_start_date": get_date(element, ".//DataInizioPeriodo"),
521-
"period_end_date": get_date(element, ".//DataFinePeriodo"),
522-
"unit_price": get_float(element, ".//PrezzoUnitario"),
523-
"total_price": get_float(element, ".//PrezzoTotale"),
524-
"tax_amount": get_float(element, ".//AliquotaIVA"),
525-
"wt_amount": get_text(element, ".//Ritenuta"),
526-
"tax_kind": get_text(element, ".//Natura").upper(),
527-
"invoice_line_id": move_line.id,
528-
"invoice_id": move_line.move_id.id,
529-
}
530-
einvoice_line = self.env["l10n_it_edi.line"].create(vals)
531-
532-
if elements_code := element.xpath(".//CodiceArticolo"):
533-
for element_code in elements_code:
534-
self.env["l10n_it_edi.article_code"].create(
535-
{
536-
"name": get_text(element_code, ".//CodiceTipo"),
537-
"code_val": get_text(element_code, ".//CodiceValore"),
538-
"l10n_it_edi_line_id": einvoice_line.id,
539-
}
510+
def _l10n_it_edi_ext_import_summary_line(self, element, extra_info=None):
511+
messages_to_log = []
512+
company = self.company_id
513+
percentage = get_float(element, ".//AliquotaIVA")
514+
extra_domain = extra_info.get(
515+
"type_tax_use_domain", [("type_tax_use", "=", "purchase")]
516+
)
517+
l10n_it_exempt_reason = get_text(element, ".//Natura").upper() or False
518+
tax = self._l10n_it_edi_search_tax_for_import(
519+
company,
520+
percentage,
521+
extra_domain,
522+
l10n_it_exempt_reason=l10n_it_exempt_reason,
523+
)
524+
if tax:
525+
self.invoice_line_ids += self.env["account.move.line"].create(
526+
{
527+
"move_id": self.id,
528+
"name": self.env._(
529+
"Summary for tax amount %(percentage)s",
530+
percentage=percentage,
531+
),
532+
"price_unit": get_float(element, ".//ImponibileImporto"),
533+
"tax_ids": tax.ids,
534+
}
535+
)
536+
else:
537+
messages_to_log.append(
538+
Markup("<br/>").join(
539+
(
540+
self.env._(
541+
"Tax not found for summary line "
542+
"with percentage %(percentage)s.",
543+
percentage=percentage,
544+
),
545+
self._compose_info_message(element, "."),
546+
)
540547
)
548+
)
541549

542-
if elements_discount := element.xpath(".//ScontoMaggiorazione"):
543-
for element_discount in elements_discount:
544-
self.env["l10n_it_edi.discount_rise_price"].create(
545-
{
546-
"name": get_text(element_discount, ".//Tipo"),
547-
"percentage": get_float(element_discount, ".//Percentuale"),
548-
"amount": get_float(element_discount, ".//Importo"),
549-
"l10n_it_edi_line_id": einvoice_line.id,
550-
}
551-
)
550+
return messages_to_log
552551

553-
if elements_other_data := element.xpath(".//AltriDatiGestionali"):
554-
for element_other_data in elements_other_data:
555-
self.env["l10n_it_edi.line_other_data"].create(
556-
{
557-
"name": get_text(element_other_data, ".//TipoDato"),
558-
"text_ref": get_text(element_other_data, ".//RiferimentoTesto"),
559-
"num_ref": get_float(
560-
element_other_data, ".//RiferimentoNumero"
552+
def _l10n_it_edi_import_line(self, element, move_line, extra_info=None):
553+
if extra_info is None:
554+
extra_info = dict()
555+
messages_to_log = []
556+
company = move_line.company_id
557+
import_detail_level = (
558+
move_line.partner_id.l10n_it_edi_import_detail_level
559+
or company.l10n_it_edi_import_detail_level
560+
)
561+
if import_detail_level == "min":
562+
move_line.unlink()
563+
line_description = " ".join(get_text(element, ".//Descrizione").split())
564+
messages_to_log.append(
565+
Markup("<br/>").join(
566+
(
567+
self.env._(
568+
"Line with description %(line_description)s "
569+
"has been skipped "
570+
"because import detail level is minimum.",
571+
line_description=line_description,
561572
),
562-
"date_ref": get_date(element_other_data, ".//RiferimentoData"),
563-
"l10n_it_edi_line_id": einvoice_line.id,
564-
}
573+
self._compose_info_message(element, "."),
574+
)
565575
)
576+
)
577+
elif (
578+
body_tree := extra_info.get("l10n_it_edi_ext_body_tree")
579+
) is not None and import_detail_level == "tax":
580+
move_line.unlink()
581+
tax_level_imported = extra_info.get("l10n_it_edi_ext_tax_level_imported")
582+
if not tax_level_imported:
583+
for summary_line in body_tree.xpath(".//DatiBeniServizi/DatiRiepilogo"):
584+
messages_to_log += self._l10n_it_edi_ext_import_summary_line(
585+
summary_line, extra_info=extra_info
586+
)
587+
extra_info["l10n_it_edi_ext_tax_level_imported"] = True
588+
elif import_detail_level == "max":
589+
# Admin. ref.
590+
if admin_ref := get_text(element, ".//RiferimentoAmministrazione"):
591+
move_line.l10n_it_edi_admin_ref = admin_ref
592+
593+
vals = {
594+
"line_number": int(get_text(element, ".//NumeroLinea")),
595+
"service_type": get_text(element, ".//TipoCessionePrestazione"),
596+
"name": " ".join(get_text(element, ".//Descrizione").split()),
597+
"qty": float(get_text(element, ".//Quantita") or 0),
598+
"uom": get_text(element, ".//UnitaMisura"),
599+
"period_start_date": get_date(element, ".//DataInizioPeriodo"),
600+
"period_end_date": get_date(element, ".//DataFinePeriodo"),
601+
"unit_price": get_float(element, ".//PrezzoUnitario"),
602+
"total_price": get_float(element, ".//PrezzoTotale"),
603+
"tax_amount": get_float(element, ".//AliquotaIVA"),
604+
"wt_amount": get_text(element, ".//Ritenuta"),
605+
"tax_kind": get_text(element, ".//Natura").upper(),
606+
"invoice_line_id": move_line.id,
607+
"invoice_id": move_line.move_id.id,
608+
}
609+
einvoice_line = self.env["l10n_it_edi.line"].create(vals)
566610

567611
if elements_code := element.xpath(".//CodiceArticolo"):
568612
self.env["l10n_it_edi.article_code"].create(
@@ -614,7 +658,7 @@ def _l10n_it_edi_import_line(self, element, move_line, extra_info=None):
614658
)
615659
else:
616660
raise UserError(
617-
_(
661+
self.env._(
618662
"Import detail level %(import_detail_level)s not supported.\n"
619663
"Please set an import detail level in company %(company)s.",
620664
import_detail_level=import_detail_level,

l10n_it_edi_extension/models/res_company.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ class ResCompanyInherit(models.Model):
3333
help="Automatically create the partner if it does not "
3434
"exist during the import of Electronic Invoices.",
3535
)
36+
l10n_it_edi_import_detail_level = fields.Selection(
37+
selection=[
38+
("min", "Minimum"),
39+
("tax", "Tax rate"),
40+
("max", "Maximum"),
41+
],
42+
default="max",
43+
required=True,
44+
string="E-bills import detail level",
45+
help="Minimum: the bill is created with no lines; "
46+
"the user will have to create them, according to what specified in "
47+
"the electronic bill.\n"
48+
"Tax rate: every tax rate present in the electronic bill "
49+
"will create a line in the bill.\n"
50+
"Maximum (default): every line contained in the electronic bill "
51+
"will create a line in the bill.",
52+
)
3653

3754

3855
class AccountConfigSettings(models.TransientModel):
@@ -45,3 +62,7 @@ class AccountConfigSettings(models.TransientModel):
4562
"exist during the import of Electronic Invoices.",
4663
readonly=False,
4764
)
65+
l10n_it_edi_import_detail_level = fields.Selection(
66+
related="company_id.l10n_it_edi_import_detail_level",
67+
readonly=False,
68+
)

l10n_it_edi_extension/models/res_partner.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ class ResPartnerInherit(models.Model):
1919
)
2020
l10n_edi_it_register_code = fields.Char(string="Register Registration Number")
2121
l10n_edi_it_register_regdate = fields.Date(string="Register Registration Date")
22+
l10n_it_edi_import_detail_level = fields.Selection(
23+
selection=[
24+
("min", "Minimum"),
25+
("tax", "Tax rate"),
26+
("max", "Maximum"),
27+
],
28+
string="E-bills import detail level",
29+
help="Override the 'E-bills import detail level' of the company "
30+
"for bills of this supplier.\n"
31+
"Minimum: the bill is created with no lines; "
32+
"the user will have to create them, according to what specified in "
33+
"the electronic bill.\n"
34+
"Tax rate: every tax rate present in the electronic bill "
35+
"will create a line in the bill.\n"
36+
"Maximum: every line contained in the electronic bill "
37+
"will create a line in the bill.",
38+
)
2239

2340
@api.constrains("l10n_it_codice_fiscale", "company_type")
2441
def validate_codice_fiscale(self):

l10n_it_edi_extension/readme/CONFIGURE.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Quindi, affinché le funzionalità di questo modulo siano utilizzabili, è neces
2020
- Configurazione delle sequenze dedicate per la numerazione delle fatture elettroniche.
2121
- Eventuale configurazione delle credenziali SDI se si utilizza l'invio diretto tramite Odoo (se supportato dalla configurazione generale).
2222

23+
In Fatturazione > Configurazione > Impostazioni, valorizzare "Livello di dettaglio importazione e-fatture" per importare le fatture elettroniche senza righe, con una riga per ogni aliquota, oppure con tutte le righe (default).
24+
Questa configurazione può essere sovrascritta dal campo "Livello di dettaglio importazione e-fatture" in ogni fornitore.
2325

2426
**English**
2527

@@ -41,4 +43,7 @@ Therefore, for this module's features to be usable, the dependent modules must b
4143
- Company data configuration (VAT number, fiscal code, tax regime, etc.).
4244
- Configuration of accounting journals for issuing electronic invoices (indicating FatturaPA/Electronic format).
4345
- Configuration of dedicated sequences for electronic invoice numbering.
44-
- Optional SDI credentials configuration if direct sending through Odoo is used (if supported by general configuration).
46+
- Optional SDI credentials configuration if direct sending through Odoo is used (if supported by general configuration).
47+
48+
In Invoicing > Configuration > Settings, fill "E-bills import detail level" to import e-bills with no lines, one line for each tax rate, or all lines (default).
49+
This setting can be overridden using the "E-bills import detail level" in each supplier.

l10n_it_edi_extension/readme/DESCRIPTION.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ Le funzionalità principali incluse sono:
7575

7676
4. Aggiunge di un wizard per calcolare i codici fiscali
7777

78-
7978
\<<https://www.fatturapa.gov.it>\>
8079

8180

@@ -156,5 +155,4 @@ The main features included are:
156155

157156
4. Adds a wizard to calculate fiscal codes
158157

159-
160158
\<<https://www.fatturapa.gov.it>\>

l10n_it_edi_extension/static/description/index.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ <h1 class="title">Italy - E-invoicing - Base Feature</h1>
518518
</ol>
519519
<p>&lt;<a class="reference external" href="https://www.fatturapa.gov.it">https://www.fatturapa.gov.it</a>&gt;</p>
520520
<p><strong>English</strong></p>
521-
<p>his module extends Odoo’s standard Italian electronic invoicing
521+
<p>This module extends Odoo’s standard Italian electronic invoicing
522522
functionality, introducing useful tools such as XML preview and fiscal
523523
code calculation and improvements in importing and exporting XML
524524
invoices.</p>
@@ -540,7 +540,7 @@ <h1 class="title">Italy - E-invoicing - Base Feature</h1>
540540
seller/provider’s permanent establishment in Italy if different
541541
from the registered office</li>
542542
<li><tt class="docutils literal">&lt;Causale&gt;</tt>: in this case there is no specific field, but it
543-
transcribes the “Terms and conditions” od the invoice.</li>
543+
transcribes the “Terms and conditions” of the invoice.</li>
544544
<li><tt class="docutils literal">&lt;Art73&gt;</tt>: indicates if the document was issued according to
545545
methods and terms established by ministerial decree pursuant to
546546
article 73 of DPR 633/72</li>
@@ -724,6 +724,11 @@ <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
724724
</ul>
725725
</li>
726726
</ul>
727+
<p>In Fatturazione &gt; Configurazione &gt; Impostazioni, valorizzare “Livello di
728+
dettaglio importazione e-fatture” per importare le fatture elettroniche
729+
senza righe, con una riga per ogni aliquota, oppure con tutte le righe
730+
(default). Questa configurazione può essere sovrascritta dal campo
731+
“Livello di dettaglio importazione e-fatture” in ogni fornitore.</p>
727732
<p><strong>English</strong></p>
728733
<p>The only available configurations are:</p>
729734
<ul class="simple">
@@ -768,6 +773,10 @@ <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
768773
</ul>
769774
</li>
770775
</ul>
776+
<p>In Invoicing &gt; Configuration &gt; Settings, fill “E-bills import detail
777+
level” to import e-bills with no lines, one line for each tax rate, or
778+
all lines (default). This setting can be overridden using the “E-bills
779+
import detail level” in each supplier.</p>
771780
</div>
772781
<div class="section" id="bug-tracker">
773782
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>

0 commit comments

Comments
 (0)