Le sette regole, con il testo dello Schematron di EN 16931 (validation-1.3.17). Sono tutte fatali:
| Regola | Categoria | Testo |
|---|---|---|
| BR-E-10 | E, esente | A VAT breakdown (BG-23) with VAT Category code (BT-118) "Exempt from VAT" shall have a VAT exemption reason code (BT-121) or a VAT exemption reason text (BT-120). |
| BR-AE-10 | AE, reverse charge | A VAT breakdown (BG-23) with VAT Category code (BT-118) "Reverse charge" shall have a VAT exemption reason code (BT-121), meaning "Reverse charge" or the VAT exemption reason text (BT-120) "Reverse charge" (or the equivalent standard text in another language). |
| BR-IC-10 | K, intracomunitaria | A VAT breakdown (BG-23) with the VAT Category code (BT-118) "Intra-community supply" shall have a VAT exemption reason code (BT-121), meaning "Intra-community supply" or the VAT exemption reason text (BT-120) "Intra-community supply" (or the equivalent standard text in another language). |
| BR-G-10 | G, esportazione | A VAT breakdown (BG-23) with the VAT Category code (BT-118) "Export outside the EU" shall have a VAT exemption reason code (BT-121), meaning "Export outside the EU" or the VAT exemption reason text (BT-120) "Export outside the EU" (or the equivalent standard text in another language). |
| BR-O-10 | O, fuori campo | A VAT breakdown (BG-23) with VAT Category code (BT-118) " Not subject to VAT" shall have a VAT exemption reason code (BT-121), meaning " Not subject to VAT" or a VAT exemption reason text (BT-120) " Not subject to VAT" (or the equivalent standard text in another language). |
| BR-S-10 | S, ordinaria | A VAT breakdown (BG-23) with VAT Category code (BT-118) "Standard rate" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120). |
| BR-Z-10 | Z, aliquota zero | A VAT breakdown (BG-23) with VAT Category code (BT-118) "Zero rated" shall not have a VAT exemption reason code (BT-121) or VAT exemption reason text (BT-120). |
Il motivo può essere indicato come codice (BT-121, dalla lista VATEX) o come testo (BT-120). Per E basta uno dei due; per AE, K, G e O, il codice o il testo devono significare esattamente quello: «Reverse charge», «Intra-community supply»… Le regole delle altre famiglie (BR-E-08, BR-AE-08 e seguenti) riguardano gli importi; qui si parla solo del motivo.

Come Odoo decide la categoria
È qui che le versioni divergono:
- Odoo 17 e 18: di serie, l'imposta non ha un campo categoria e Odoo la deduce: per un cliente spagnolo con codice postale che inizia per 35 o 38 (Canarie), L, e per 51 o 52 (Ceuta e Melilla), M; E se l'imposta è al 0 % e venditore e cliente sono dello stesso paese; AE nell'autoliquidazione del cocontraente belga o nell'autofattura con imposta reverse charge; con partita IVA del venditore e imposta al 0 %, K se entrambi sono nello SEE e G se lo è solo uno; nel resto, S se l'imposta ha una percentuale ed E se è al 0 %. Il modulo standard account_edi_ubl_cii_tax_extension (Tax extension for UBL/CII), che non si installa da solo, aggiunge all'imposta Tax Category Code e Tax Exemption Reason Code: con la categoria impostata, Odoo usa quella invece di dedurla.
- Odoo 19: ogni imposta ha Tax Category Code (AE, E, S, Z, G, O, K, L, M, B) e Tax Exemption Reason Code, con la lista VATEX.
- Odoo 20: gli stessi due campi e, in più, Tax Exemption Reason, un testo libero.
- In tutte e quattro le versioni: se una categoria E resta senza motivo, Odoo scrive il testo «Exempt from tax», che soddisfa BR-E-10.
La trappola tipica di Odoo 17 e 18 senza quel modulo è un'imposta al 0 % per un servizio fuori campo IVA, che la deduzione non contrassegna mai come O, oppure una vendita nazionale con reverse charge: la categoria esce diversa da quella che si aspetterebbe il tuo commercialista.
Con il nostro modulo XRechnung e ZUGFeRD
Il generatore del modulo pubblicato conosce solo due categorie, S e Z. In XRechnung UBL scrive S quando l'imposta ha una percentuale e Z quando è al 0 %. In XRechnung CII, il suo formato predefinito, ogni riga esce come S, anche con un'imposta al 0 %, e il validatore di KoSIT la respinge con BR-S-05 (l'abbiamo verificato). Una fattura in reverse charge, intracomunitaria, di esportazione o esente non esce con AE, K, G o E. Su Odoo 18, 19 e 20, con l'abbonamento a FlexigoTech Cloud, il modulo valida il risultato con le regole di KoSIT e lascia in Validation Errors qualsiasi regola che fallisce. Per quelle fatture, oggi, l'esportazione nativa di Odoo è quella che conosce le categorie. Su Odoo 17, la versione pubblicata non valida.

Come risolverlo
- Individua la categoria nel riepilogo IVA dell'XML (BT-118) e confrontala con l'operazione reale.
- Su Odoo 19 e 20, apri l'imposta e imposta il suo Tax Category Code e, se è E, AE, K, G o O, il suo Tax Exemption Reason Code.
- Su Odoo 17 e 18, installa account_edi_ubl_cii_tax_extension e imposta su ogni imposta la sua categoria e, se quella categoria lo richiede, il suo motivo. Senza quel modulo, controlla il paese del cliente, il suo codice postale, la partita IVA e la posizione fiscale: sono i dati da cui Odoo deduce la categoria.
- Un motivo di esenzione su una riga ad aliquota ordinaria provoca BR-S-10: rimuovilo dall'imposta.
- Genera di nuovo il file.
Continua a leggere
Verificato nel codice del modulo (versione 17.0 e 20.0) e nelle fonti collegate
Fonti
- github.com/odoo/odoo/blob/6f00fdadb875342de2d14a179f25431f93cd63c9/addons/account_edi_ubl_
- github.com/odoo/odoo/blob/2982b5f44af03fae6a9888f20632c1cc19f623ba/addons/account_edi_ubl_
- github.com/odoo/odoo/blob/6f00fdadb875342de2d14a179f25431f93cd63c9/addons/account_edi_ubl_
- Codice del modulo: flexigo_germany_xrechnung 20.0 (446f2f68): lib/generators/cii_generator.py
- Codice del modulo: flexigo_germany_xrechnung 20.0 (446f2f68): models/res_company.py
- github.com/odoo/odoo/blob/6f00fdadb875342de2d14a179f25431f93cd63c9/addons/account_edi_ubl_
- github.com/odoo/odoo/blob/2982b5f44af03fae6a9888f20632c1cc19f623ba/addons/account_edi_ubl_
- github.com/odoo/odoo/blob/4d2d4b5895db70596863df941d9a1f0beeb117f8/addons/account_edi_ubl_
- github.com/odoo/odoo/blob/2fec20391a8a61ea3a3bf15e9f24d59dba910a8d/addons/account_edi_ubl_
- github.com/odoo/odoo/blob/2982b5f44af03fae6a9888f20632c1cc19f623ba/addons/account_edi_ubl_
- github.com/odoo/odoo/blob/4d2d4b5895db70596863df941d9a1f0beeb117f8/addons/account_edi_ubl_
- github.com/odoo/odoo/blob/2fec20391a8a61ea3a3bf15e9f24d59dba910a8d/addons/account_edi_ubl_
- Codice del modulo: flexigo_germany_xrechnung 20.0 (446f2f68): lib/generators/ubl_generator.py
- Codice del modulo: flexigo_germany_xrechnung 20.0 (446f2f68): models/xrechnung_cloud.py
- Codice del modulo: flexigo_germany_xrechnung 17.0 (ad05de8f): __manifest__.py
- github.com/ConnectingEurope/eInvoicing-EN16931/releases/tag/validation-1.3.17
