Saturday, August 2, 2025
5 changes · master
New functionality added to Odoo
Adds support for Spain's mandatory Veri*Factu tax reporting requirements for companies not using other Spanish e-invoicing systems. Businesses can now generate, send, track, and print invoices and PoS receipts with AEAT-verifiable QR codes, helping them meet compliance obligations.
Original PR description
#### [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…
#### [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_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).
#### [IMP] l10n_es{,edi_sii,edi_tbai}: move some code to l10n_es
The moved code will also be needed for Veri*Factu
- patched http adapter
- a function to retrieve partner info
#### [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: https://github.com/odoo/documentation/pull/12068
task-3745982
Forward-Port-Of: odoo/odoo#221431
Forward-Port-Of: odoo/odoo#197635Livechat channel rules can now use AI Agents instead of only scripted chatbots, giving businesses more flexible automated conversations. The update also makes it easier to hand a conversation over to a human agent, improving the customer support flow across livechat.
Original PR description
- Previously, livechat channel rules could only be configured using scripted chatbots(chatbots that rely on pre-defined steps and answers). This commit gives the ability to configure livechat channel rules using AI Agents (LLMs). - The logic of forwarding a discuss channel to a human is moved from `chatbot.script.step` into `discuss.channel` so that it can be used without a `chatbot.script`. Enterprise PR: https://github.com/odoo/enterprise/pull/91244 task-4825509
Documents can now be automatically sorted into folders using AI, helping teams reduce manual filing work and keep incoming documents organized faster. The update also improves AI prompt handling so files can be included safely and adds safeguards to avoid sorting loops and delayed email processing.
Original PR description
Purpose ======= Allow sorting documents that created / move in a folder with AI. Specification ============= To achieve that result, we need to create a new type of server actions, "AI". This type of…
Purpose
=======
Allow sorting documents that created / move in a folder with AI.
Specification
=============
To achieve that result, we need to create a new type of server actions,
"AI". This type of server action can use other server action marked
as "Use with AI". We call the "Use with AI" server action "tools".
The LLM can ask to execute a tool with some parameter. That allow it
to move documents in a given folder, to rename a document,
log a note, etc.
We also need to be able to add binary file in the prompt,
for that purpose, we stop using QWeb, and we render ourselves the prompt with LXML.
Various fixes were applied along the way.
See underlying commits for more details about each of the changes.
Technical
=========
Mail alias: To not block the email CRON, when documents are sent to a
folder with AI sorting enable, we delay the sorting (they will be
sorted in a different CRON, and a ribbon message will be shown
in the kanban view while they are waiting to be sorted)
Loop: We need to prevent loop in case the target folder is also marked
as "AI sorted".
Prompt injection: The new server action code is vulnerable to prompt injection.
An attacker could try to retrieve the information from the prompt
by fooling the LLM into inserting those information in the result
of the server action.
Most obvious example is writing an unlimited free text into a readable record.
Several measures are available to limit this when creating AI server actions:
- End users should make careful use of the '/record' command to specify the
possible "winner candidates" records of the server action.
- The 'ai_tool_schema' can be used to limit the available outputs of the LLM
(for example by truncating text to a certain limit)
- The LLM can only execute a set of manually selected AI tools, these have to
be carefully chosen to avoid unwanted side-effects as the LLM could be fooled
into executing any of these tools with any arguments
- Dynamic information inside the prompt is added using '/field', those values
should be reviewed to make sure they do not contain sensitive information
The AI server actions & tools provided as data in this PR have been reviewed
by Odoo to make sure they follow these criteria.
Number of API calls: OpenAI always answer `"status": "completed"` after
executing a tool (even if it's not finished) so even if the LLM
will execute one action and stop, it will require 2 API calls
(to be sure it's finished and that nothing else will be executed).
In the last call, to specify it's done, there's no more tool call,
and the LLM send eg `The documents has been moved to...`.
Even if we say `When you are done, sent DONE`, it sends it in the
last call. We could have limited the tools call to 1 for documents,
to improve performance, but then we will restrict the feature.
AI module: The code is done in the `ai` module, because it's meant to
replace `ai.tool`. For now, we keep the `ai_server_actions` module
but it's only used for "update with AI" action, and will be merged
with AI in the future.
Access check: We only check that we can execute the AI action, we skip
all check on the tools. The reason is that it can be executed in a
CRON on most cases anyway, so it's better for it to be explicit
(and to have something consistent). If a tool has a group, then a
warning will be shown to explain to the user that the LLM can skip
the access check for this action.
Default folders: For other models, if we didn't insert records in the
prompt, then we add the most used records. But for documents, they
inherit from the accesses of the parent folder, and so it has
security impact, so we don't insert the most used folders (if the
user does not do /record in the prompt, then the LLM won't be able
to move the documents).
Folders values: When inserting a record in the prompt, by default we
just insert its display name. We want the LLM to have more
information for the auto-sort, for example, if we have a folder
"Belgium" inside "Finance", the LLM should be able to know that
the Belgium folder is related to Finance.
Task-4915266A new Accounting and Knowledge integration lets users create polished audit reports directly in Knowledge, edit them collaboratively, and export them as professional PDFs. The update adds ready-made templates, embedded accounting reports, dynamic audit data, attachments, foldable sections, and electronic signature support to make audit reporting faster and more complete.
Original PR description
This PR introduces a new bridge module that connects the Knowledge and Accounting modules, enabling users to seamlessly create audit reports directly within Knowledge. Thanks to this integration, users can now generate professional-grade audit reports with just a few clicks, and continue editing them inside the Knowledge interface. See underlying commits for more details. COM: https://github.com/odoo/odoo/pull/214712 Task-4840940
Website live chat can now be powered by AI agents instead of only scripted chatbot flows. This lets businesses offer more flexible, question-and-answer style support conversations through a new AI Livechat website snippet.
Original PR description
- Previously, livechat channel rules could only be configured using scripted chatbots(chatbots that rely on pre-defined steps and answers). This commit gives the ability to configure livechat channel rules using AI Agents (LLMs). - Introduce AI Livechat website snippet. Community PR: https://github.com/odoo/odoo/pull/221008 task-4825509