[ADD] l10n_es_edi_verifactu{,_pos}: Veri*Factu support - #197635
[ADD] l10n_es_edi_verifactu{,_pos}: Veri*Factu support#197635svfu-odoo wants to merge 3 commits into
Conversation
3c4efa2 to
7ea2c91
Compare
fc880c7 to
dc48ce3
Compare
jco-odoo
left a comment
There was a problem hiding this comment.
Still many uncertainties I am afraid, as well because of how strict the regulations should be interpreted...
There was a problem hiding this comment.
Not clear what you mean by that
There was a problem hiding this comment.
On second thought. We should not delete anything because of the chaining.
The issue I am thinking about:
We are waiting to send a record document to register / update the order.
But then we invoice it (from the order form view).
We still need to send everything for the chaining.
I am not sure this flow is possible though. At least I could not find how to do it. I will have to check again
I just throw an error for now.
I still have to check the case that the same record is multiple times in the same batch (e.g. registration + immediate cancellation)
cae2e42 to
35ac635
Compare
jco-odoo
left a comment
There was a problem hiding this comment.
I am probably wrong about some things...
There was a problem hiding this comment.
Everything is just double. It is simple in l10n_es_edi_tbai.
There was a problem hiding this comment.
TODO: I will double check and try to simplify
|
@odoo/rd-security We would like to continue with this asap as it still needs fw-porting, ... and commercially it is important to have it in all versions before August.
|
And it's all wrong. Stop writing layers upon layers of ORM methods which expose zeep objects or worse. |
|
@xmo-odoo So better have the _get_zeep_operations not as a separate method, but embedded in the _send_batch and if we have duplicate code, so be it? Or maybe in a Python class? |
Or free functions, that also works. Just not orm methods, because that's accessible to anyone who creates a database on the saas, and that exposes a massive API surface. If you absolutely need methods, for things, then they have to get the smart / uncontrolled objects as parameters, and never return them. |
Currently we also set the simplified partner directly on pos orders even in case we do not invoice the pos order directly. This is unnecessary; we only need to set a partner in case we invoice. (Since we need a partner to put on the invoice.) After this commit we only set the simplified partner on pos orders that will be invoiced as simplified invoice. (This happens automatically in case a simplified invoice journal is set in the settings; see field `pos_l10n_es_simplified_invoice_journal_id`) part of task-3745982
|
@xmo-odoo Changes for freeing the zeep_operations applied. |
The moved code will also be needed for Veri*Factu - patched http adapter - a function to retrieve partner info part of task-3745982
jco-odoo
left a comment
There was a problem hiding this comment.
From my side this is ok, so for the remaining changes for security, ... I will give the control to @svfu-odoo
Improvements for e.g. PoS and substitution, ... can be done later as we will also gain experience bringing it into production.
|
@robodoo delegate=svfu-odoo |
There was a problem hiding this comment.
Seems redundant with the method above it, and unused.
There was a problem hiding this comment.
Removed (it was used back when we manually signed the stored attachment)
There was a problem hiding this comment.
Might benefit from a comment that registration_xml is not any sort of operation, and only used to validate that a registration request (the XML message content) can be created? Unless I misunderstand the code in _create_for_record? It doesn't seem to use the message for anything except catching creation errors.
There was a problem hiding this comment.
You understood it correctly.
I added an explanatory comment.
Spain introduces a new EDI called "Veri*Factu" to send invoicing records
to the Spanish tax agency (AEAT).
It is mandatory for most tax payers (that cannot use any of the
other Spanish EDIs like SII or TicketBAI).
This commit adds 2 modules to enable Veri*Factu compliance
- `l10n_es_edi_verifactu` for invoicing / accounting
- `l10n_es_edi_verifactu_pos` for Point of Sale (PoS)
Their setup and usage is briefly described in the documentation
(see the related documentation PR).
The main features of the new modules are as follows.
- `l10n_es_edi_verifactu`
- The "Send & Print" wizard can be used to generate and send Veri*Factu documents.
- A QR code is added to the PDF of invoices send with the Veri*Factu option.
It can be used to check whether the invoice is known to the AEAT.
- A "Veri*Factu" tab is added to the account move form view.
It i.e. gives an overview about the send documents and their status.
- `l10n_es_edi_verifactu_pos`
- A Veri*Factu documents is generated and sent when validating each order.
- A QR code is added to the PDF of PoS order receipts.
It can be used to check whether the order is known to the AEAT.
- A "Veri*Factu" tab is added to the pos order form view.
It i.e. gives an overview about the send documents and their status.
I.e. note the following about Veri*Factu documents
- Each document has a fingerprint (hash of some important values) called `Huella`.
- All documents belonging to one company are linked together in a single chain in generation order.
(Each document refers to the previous document including the `Huella` of the previous document)
- There is a waiting time between submissions of documents (usually 60s).
We sent the document immediately if possible.
But due to the waiting time this is not always possible.
- We still generate / store the needed values when the invoice is sent
(mandated by Veri*Factu spec).
- Documents can be sent in batches.
- Due to the waiting time we sent all "waiting" documents at once.
- In case of 1000 documents the waiting time can be / is ignored
- A "Veri*Factu Document" in Odoo only represents a single invoice / PoS order.
- The needed document values mandated by Veri*Factu are stored in JSON format
on each invoice / order.
- The actual "communication" with AEAT is done via SOAP. (So we sent / receive
XML files)
- We do not store the actual batch XML we sent to the AEAT or the received responses.
- For the responses we extract the necessary information and store them
on each of the document
It can happen that the document reached the AEAT but the response
timed out for some reason (Read-Timeout).
- The AEAT has (potentially) registered the document but we have
not received the response they sent.
- The document will be marked with an error starting with `[Read-Timeout] `.
and automatically be sent again as soon as possible
- When the document is resend successfully we receive a response that the document
was rejected with error `[3000] Registro de facturación duplicado.`
(Assuming the AEAT registered / not rejected the document when it was sent originally.)
But the response also contains some information about the state and potential errors
of the record / duplicate.
- Since the duplicate is the document we previously sent we just take the state from there.
There are 2 ways to create a correcting Veri*Factu document for invoices
- Correction by difference: Done via "Reverse" in credit note wizard
We just send a document representing the credit note as "correction by difference".
The document references the corrected invoice.
- Correction by substitution: Done via "Reverse and Create Invoice" in credit note wizard
We first send a document representing the reversing credit note (it does not
reference the original invoice and is send as an "invoice type").
And then we send the new invoice created by the wizard. It is send as a
"correction by substitution" and references the original invoice.
To link the new invoice to the original invoice a new field was added
- We do not support correcting multiple documents with a single new documents
(neither correction by difference nor correction by substitution)
The "Veri*Factu" tab on the invoice form view also gives information
about which invoice was refunded or substituted.
Limitations
- In Veri*Factu there is some dedicated way to handle the substitution of
simplified invoices with "real" invoices.
This is not implemented currently.
- In Veri*Factu multiple tax types (`Impuesto`) and regimen keys (`ClaveRegimen`) can
be indicated (one per `DetalleDesglose` element).
We currently only allow a single tax type and regimen key for the whole
document.
- In Veri*Factu it is possible to send a "Subsanación" in case a change is made
that does not require updating the invoice PDF.
This is currently not supported.
- I.e. we do not support sending new submission documents for already registered
(possibly with errors) records.
- It is not possible to reset registered (possibly with errors) records back to draft.
- In Veri*Factu it is possible to send a cancellation for records that are otherwise
known to the AEAT (not Veri*Factu).
We do not support sending cancellations for records that are not Veri*Factu registered
within Odoo.
- For simplified invoices there are the special keys / fields `FacturaSimplificadaArt7273`
and `FacturaSinIdentifDestinatarioArt61d`. Currently we never set them (so they are assumed
to be `N` by the AEAT).
task-3745982
There was a problem hiding this comment.
You understood it correctly.
I added an explanatory comment.
There was a problem hiding this comment.
Removed (it was used back when we manually signed the stored attachment)
|
Upgrade exception #623 added. Waiting the forward-port of this PR, the exception will be applied on all builds, and create an inconsistent state for migrations. Important Please forward port this PR ASAP up to master without change, preferably before the end of the week. PRs adding fields/models should be merged at the beginning of the week and all the forward ports should be merged in the same week. If you need to apply any change before it reaches master, please notify runbot team. Details: |
|
@robodoo r+ rebase-ff |
|
@svfu-odoo you may want to rebuild or fix this PR as it has failed CI. |
|
Merge method set to rebase and fast-forward. |

[ADD] l10n_es_edi_verifactu{,_pos}: Veri*Factu support
Spain introduces a new EDI called "Veri*Factu" to send invoicing records
to the Spanish tax agency (AEAT).
It is mandatory for most tax payers (that cannot use any of the
other Spanish EDIs like SII or TicketBAI).
This commit adds 2 modules to enable Veri*Factu compliance
l10n_es_edi_verifactufor invoicing / accountingl10n_es_edi_verifactu_posfor Point of Sale (PoS)Their setup and usage is briefly described in the documentation
(see the related documentation PR).
The main features of the new modules are as follows.
l10n_es_edi_verifactuIt can be used to check whether the invoice is known to the AEAT.
It i.e. gives an overview about the send documents and their status.
l10n_es_edi_verifactu_posIt can be used to check whether the order is known to the AEAT.
It i.e. gives an overview about the send documents and their status.
I.e. note the following about Veri*Factu documents
Huella.(Each document refers to the previous document including the
Huellaof the previous document)We sent the document immediately if possible.
But due to the waiting time this is not always possible.
(mandated by Veri*Factu spec).
on each invoice / order.
XML files)
on each of the document
It can happen that the document reached the AEAT but the response
timed out for some reason (Read-Timeout).
not received the response they sent.
[Read-Timeout].and automatically be sent again as soon as possible
was rejected with error
[3000] Registro de facturación duplicado.(Assuming the AEAT registered / not rejected the document when it was sent originally.)
But the response also contains some information about the state and potential errors
of the record / duplicate.
There are 2 ways to create a correcting Veri*Factu document for invoices
We just send a document representing the credit note as "correction by difference".
The document references the corrected invoice.
We first send a document representing the reversing credit note (it does not
reference the original invoice and is send as an "invoice type").
And then we send the new invoice created by the wizard. It is send as a
"correction by substitution" and references the original invoice.
To link the new invoice to the original invoice a new field was added
(neither correction by difference nor correction by substitution)
The "Veri*Factu" tab on the invoice form view also gives information
about which invoice was refunded or substituted.
Limitations
simplified invoices with "real" invoices.
This is not implemented currently.
Impuesto) and regimen keys (ClaveRegimen) canbe indicated (one per
DetalleDesgloseelement).We currently only allow a single tax type and regimen key for the whole
document.
that does not require updating the invoice PDF.
This is currently not supported.
(possibly with errors) records.
known to the AEAT (not VeriFactu).
We do not support sending cancellations for records that are not Veri*Factu registered
within Odoo.
FacturaSimplificadaArt7273and
FacturaSinIdentifDestinatarioArt61d. Currently we never set them (so they are assumedto be
Nby the AEAT).[IMP] l10n_es{,edi_sii,edi_tbai}: move some code to l10n_es
The moved code will also be needed for Veri*Factu
[FIX] l10n_es_pos: set simplifed partner only when we will invoice
Currently we also set the simplified partner directly on pos orders even
in case we do not invoice the pos order directly.
This is unnecessary; we only need to set a partner in case we invoice.
(Since we need a partner to put on the invoice.)
After this commit we only set the simplified partner on pos orders
that will be invoiced as simplified invoice.
(This happens automatically in case a simplified invoice journal is
set in the settings; see field
pos_l10n_es_simplified_invoice_journal_id)References
documentation PR: odoo/documentation#12068
task-3745982