Daily updates from Odoo
Friday, July 4, 2025
12 changes · master
Enhancements to existing features
This update adds several state-specific payroll tax rates used in US salary calculations, including Alabama, Colorado, and Washington. It helps payroll teams calculate employee pay and employer obligations more accurately based on current state requirements.
Original PR description
Added salary rules for state: - US: Alabama ESA rate - US: Colorado Support Surcharge rate - US: Colorado Solvency Surcharge rate - US: Washington EAF Rate task-4814709 Forward-Port-Of: odoo/enterprise#89344 Forward-Port-Of: odoo/enterprise#87708
The Belgian payroll Eco-Vouchers wizard now keeps each national identification number on its own line. This helps payroll teams correctly handle employees whose NISS changed during the relevant period, reducing reporting confusion and improving voucher file accuracy.
Original PR description
In the Eco-Vouchers wizard, we should have only 1 NISS per line so if an employee changed NISS, it may need multiple lines. Task: 4866687
Uruguayan electronic invoices now send the invoice line name consistently as the mandatory item name, while placing overflow text, product descriptions, and addenda in the optional description field. This prevents duplicated product names on generated reports and keeps invoice XML aligned with DGI length requirements.
Original PR description
This PR aims to improve the way we create NomItem and DscItem lines on the XML files we send to DGI in order to generate the PDF report. We have two fields to inform to DGI in an electronic invoice,…
This PR aims to improve the way we create NomItem and DscItem lines on the XML files we send to DGI in order to generate the PDF report. We have two fields to inform to DGI in an electronic invoice, NomItem which is mandatory an has a maximum of 80 characters to send, and DscItem that is optional an has a limit of 1000 chars. So we ensure NomItem is always sent, and the description will be filled like this: First, if the product name is longer than 80 chars, DscItem field will contain the characters that didn't fit in the NomItem field (characters from the 80th) Then it will contain the description of the product and the addenda content if it exists. Plus, I refactor the method _l10n_uy_edi_cfe_D_global_discount so it is also aligned with what I mentioned before. Another reason for this improvement is that, as the description of a product contains the product name at the beginning, we faced some issues when a user added a description on the fly in the line of the product, and then confirmed and printed the report. In this case, the name of the product was duplicated in the report. With this change, the description will only contain the the part of the product name that exceeds the 80th character. Example:  Forward-Port-Of: odoo/enterprise#80993
PDF exports for accounting reports now generate report content progressively instead of holding all report pages in memory at once. This reduces memory usage during large exports and uses a cleaner internal mechanism for PDF rendering.
Original PR description
When generating the pdf export, we first generate all the bodies of the reports to export in HTML, then add them to a stream, and finally use it to generate the pdf => doing that, we'll use twice the memory: once for all the html, once for the copy in the stream. We can do better by yielding report by report the HTML it generates :) Use self.allow_pdf_render intead of directly patching wkhtml, since allow_pdf_render is cleaner. task-4823834
Shop floor users can now adjust routing directly from a work order, including adding the next operation or moving work to another work center. This reduces back-and-forth with manufacturing order overview screens and gives teams more flexibility while work is already in progress.
Original PR description
**Desired behavior after PR is merged:**
- Add modify routing button in shopfloor workorders with the ability to create another workorder or move work centers
- Allow moving to another work center while the workorder is still in progress
Task:4850003Odoo AI can now use system-managed agents that stay hidden from regular users and cannot be edited or deleted through the interface. These agents can provide direct AI responses without opening chat channels, enabling smoother background automation and simpler user experiences.
Original PR description
## Purpose - Introduced a new is_system_agent flag to distinguish system agents from user-created agents. System agents are hidden from the UI and are not editable by users. - Added a new method get_direct_response() to allow system agents to generate direct responses without creating chat channels.
Users can now turn off the journal-specific filter directly from the bank statements view. This makes it faster to switch from a focused journal view to all bank statements without returning to the dashboard.
Original PR description
This improves the UX by allowing users to quickly switch off the filter and see all bank statements, rather than having to go back to the dashboard and reselect the journal. Task ID: 4797334
When registering payments with SEPA Direct Debit, users now see a clear banner listing any partners without a valid SEPA mandate. This helps teams quickly identify who needs mandate setup before payments can be processed.
Original PR description
When users try to register one or multiple payments with 'SEPA Direct Debit' method, and one or more partners don't have a valid SEPA mandate, a banner alerts the user and mention the names of the concerned partners. This makes it easier for the user because he directly sees the partners for which he has to set a SEPA mandate. task-4575537 runbot : https://runbot.odoo.com/runbot/bundle/18-0-sepa-missing-links-roto-353391 Forward-Port-Of: odoo/enterprise#81019
Resolved issues and error corrections
The Mexican electronic invoicing flow now saves the invoice sending time before contacting the external certification provider. This helps prevent duplicate CFDI documents with slightly different timestamps when a connection is interrupted and Odoo retries the send.
Original PR description
### Background In https://github.com/odoo/enterprise/pull/85026 we changed the behaviour of `l10n_mx_edi_post_time` so that it gets set during the CFDI sending process, rather than when the invoice…
### Background In https://github.com/odoo/enterprise/pull/85026 we changed the behaviour of `l10n_mx_edi_post_time` so that it gets set during the CFDI sending process, rather than when the invoice is posted. This was needed to ensure that the post time both reflects the sending time and is re-used if the invoice needs to be re-sent. ### Bug description Since then, several Mexican customers have reported that some CFDIs are sent duplicated, with a difference of a few seconds in the CFDI's Fecha. ### Analysis A disconnection might occur during sending of the CFDI. In that case, the PAC will process the CFDI, but in Odoo the transaction will be rolled back, and the `l10n_mx_edi_post_time` will be lost. When Odoo re-sends the CFDI, it will take a new `l10n_mx_edi_post_time`. ### Solution Commit before performing the API call so that the `l10n_mx_edi_post_time` gets committed to DB. opw-4780096 Forward-Port-Of: odoo/enterprise#89263 Forward-Port-Of: odoo/enterprise#89117
This fix prevents the invoice OCR process from creating duplicate supplier records when multiple documents from the same supplier are processed at the same time. It improves data quality and reduces manual cleanup for accounting teams using automated invoice extraction.
Original PR description
When the OCR parses documents from the same supplier concurrently, it can happen that it creates duplicated `res.partner` entry for it. This typically happen when the update of the documents is done…
When the OCR parses documents from the same supplier concurrently, it can happen that it creates duplicated `res.partner` entry for it. This typically happen when the update of the documents is done through the webhook. In that case, the different SQL transactions overlap each other and can't "see" the partner created by another request. In order to prevent this, a new field `is_created_by_ocr` and a unique index are introduced to be able to detect duplicated partners created by the OCR. This solution is quite costly as it requires introducing a new field and an index on `res.partner`... Other alternatives were considered: - Updating the documents through a cron instead -> introduces latency, especially on the SaaS where we can't force a cron to run immediately, even with a cron trigger. - Introducing a new model on which we could add the uniqueness model -> also costly, requires a new model just to fix the issue, and we need a way to frequently clean the records, so probably a cron on top of it (or using autovacuum, but its frequency might be too low). - Adding random delay on OCR side before calling the webhook -> introduces latency and no guarantee, it only reduces the chances of duplicated partners. - Using explicit SQL locks -> no guarantee, we only know what should be locked late in the SQL transaction (after fetching the results from the OCR), it wouldn't be very effective. Locking the whole `res_partner` table from the start of the transaction would be too restrictive and equivalent to serializing the transactions. An attempt was made in #88830, but it was deemed too complicated. task-[4904333](https://www.odoo.com/odoo/project/2068/tasks/4904333)
Fixes an issue where GSTR-2B JSON files were attached to messages but not properly linked to newly created vendor bills. Bookkeepers can now open these attachments without seeing a 404 error, improving reliability during GSTR-2B matching.
Original PR description
**Before this PR:** - The GSTR-2B JSON was attached to the message but not linked to the newly created bills (`res_id` was not set). - As a result, when a Bookkeeper user created a new GSTR-2B bill and tried to open the attachment, it raised a 404 error: `"The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."` **After this PR:** - The issue is resolved. - During GSTR-2B matching, unattached message attachments are now properly linked to the newly created bills by updating their res_model and res_id fields. Task ID : 4831758 Forward-Port-Of: odoo/enterprise#89250 Forward-Port-Of: odoo/enterprise#86785
This fixes inconsistent data loading between the standard Point of Sale and self-ordering flows. Businesses should see fewer errors when shared POS information is needed, including receipt printing in self-ordering scenarios where session data may not always be available.
Original PR description
*: l10n_br_edi_pos, l10n_cl_edi_pos, l10n_ec_edi_pos, l10n_ke_edi_oscu_pos, l10n_mx_edi_pos, l10n_pe_edi_pos, pos_blackbox_be, pos_iot, pos_mobile, pos_preparation_display, pos_restaurant_appointment, pos_self_order_iot, pos_settle_due Before this commit, the loading data behavior between self-ordering and PoS was merged but not consistent. This led to issues when we try to add some data to load for both self-ordering and PoS. At the moment, we need to create two separate method to handle both cases. Now with this commit, we have consistent methods which will load data for both self-ordering and PoS. This will allow us to have a more consistent behavior and avoid issues when adding data to load. An explicit example is about `_server_version` object which is added to the `pos.session` model and used when printing the receipt. Since the session isn't always available in self-ordering, sometimes that object isn't available, leading to issues when printing the receipt.