Daily updates from Odoo
Wednesday, June 17, 2026
18 changes · saas-18.3
Resolved issues and error corrections
This update resolves an issue where Peppol invoices generated with invoice-type contacts were missing the correct buyer reference information. The fix ensures that the configured Leitweg-ID is properly included in the XML invoice data, facilitating compliant Peppol transactions. This improves the accuracy of invoice data for German businesses using Peppol.
Original PR description
**Steps to reproduce:** - Install the `l10n_de` module and switch to a `DE Company`. - Enable `Peppol` in the Invoicing app settings. - Open the `DE Company` customer record. - In the `Invoicing`…
**Steps to reproduce:** - Install the `l10n_de` module and switch to a `DE Company`. - Enable `Peppol` in the Invoicing app settings. - Open the `DE Company` customer record. - In the `Invoicing` tab, change the Peppol ID code from `Germany VAT` to `Germany Leitweg-ID` and set a code (e.g., `13075957-K000-52`). - In the `Contacts & Addresses` tab, create an invoice-type contact named `test`. - Create a new invoice using the `test` contact. - Send the invoice via Peppol. - Download the generated `XML` and inspect the `BuyerReference` field. **Observation:** The `<cbc:BuyerReference>` field is set to `N/A` instead of the configured `Leitweg-ID`. **Root Cause:** At [1], the `BuyerReference` node is populated using `vals['customer']`. For invoices addressed to an invoice-type contact, the contact itself does not contain the Peppol configuration, which is stored on the commercial partner. As a result, the code fails to retrieve the customer's `Leitweg-ID` and leaves the `BuyerReference` field empty. **Fix:** This commit ensures that the configured Leitweg-ID is correctly added to the `BuyerReference` field for child contact. [1]: https://github.com/odoo/odoo/blob/281658e86971687656f3235ac1ff8afcb52f2908/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_xrechnung.py#L87-L97 opw-6269478 Forward-Port-Of: odoo/odoo#269818
This update resolves an issue where saving job page descriptions with all content removed resulted in a 'Document is empty' validation error. The fix ensures that empty, whitespace-only HTML fields are handled correctly during saving, preventing the error and allowing users to successfully update their job postings. This improves the user experience for managing recruitment content.
Original PR description
Steps to reproduce: =================== 1. Edit a job page. 2. Delete every `s_rating` block. 3. Save. => Validation Error: Document is empty. Cause: ====== Deleting the last snippet inside an…
Steps to reproduce: =================== 1. Edit a job page. 2. Delete every `s_rating` block. 3. Save. => Validation Error: Document is empty. Cause: ====== Deleting the last snippet inside an editable HTML field (e.g. the last `s_rating` block in the `website_rating` field of a job page) leaves the field's editable container with only whitespace text nodes. On save, it writes that whitespace to the record and then calls `_copy_custom_snippet_translations`, which does `html.fromstring(lang_value)` on the whitespace and raises `lxml.etree.ParserError: Document is empty`, re-raised as `ValidationError`. The user sees a "Validation Error" dialog and can't finish saving. The previous fix for the analogous "Document is empty" symptom on product description editing (commit [1]) added a `cleanupEmptyStructures` `on_removed_handlers` that strips whitespace from `.oe_empty` containers after element removal. That selector covers `oe_structure.oe_empty` containers but not editable HTML field savables (`[data-oe-type="html"]`), which don't carry an `oe_empty` class when they originally had content. As a result, fields like `hr.job.website_rating` still hit the failing parse path. Solution: ========= Extend the cleanup selector to also include `[data-oe-type="html"]` so HTML-field editables are normalized to genuinely empty after the last inner snippet is removed. [1]: https://github.com/odoo/odoo/commit/53d5cc7eed635f64038bf0315f6863011879c529 opw-6244892 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267397
A bug was causing ewaybill generation to fail when a global discount with a negative amount was applied to an invoice. This update corrects the system to handle these discount lines properly, ensuring ewaybills are generated successfully. This resolves a technical issue impacting invoice processing and ewaybill generation in India.
Original PR description
Issue: Global discount creates negative lines that are refused by the endpoint. Steps to reproduce: - In an Indian company - Create an invoice to "B2B Customer Intrastate" - Add a product - Add a Discount line with a negative amount - Confirm - Generate ewaybill - set - Document Type to "Tax Invoice (supply)" - Transportation mode to "" - Generate ewaybill Current behavior: - When sent, JSON produce a "234 Total Amount Error" (not mocked on runbot) Expected behavior: - JSON is accepted Cause: Discount line is sent as is. However, endpoint refuses negative lines. opw-6130779
A recent issue causing the Documents view to crash when accessed through an activity has been resolved. This was due to a timing problem with how the system processed data, leading to an error when trying to set a key value. This update ensures the Documents view functions reliably for all users.
Original PR description
### Description When navigating to Documents via an activity, the list view crashes with a TypeError on setting 'COMPANY'. ### Root Cause An asynchronous race condition occurs between parent and child `onWillStart` hooks. The child finishes an await before the parent's hook runs `expandDefaultValue()`. Thus, `this.state.expanded[sectionId]` is undefined when the child tries to write to its nested keys. ### Solution Await `sectionsPromise` first in the child hook. opw-6276003 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#120713 Forward-Port-Of: odoo/enterprise#119634
This update fixes an error in the VAT balance calculation within the l10n_uy module for Uruguay. The previous formula was incorrect, leading to inaccurate reporting. This change ensures that VAT reports accurately reflect the correct financial balances, improving the reliability of financial data.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting and l10n_uy 2. Go to tax report and see the formula of the VAT balance that is incorrect ### Reason to introduce the fix: Correct the formula to display the right amount. opw-6261211 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269376 Forward-Port-Of: odoo/odoo#268478
This update resolves an issue in the Odoo Studio report editor where deleting the last column from a table would trigger a technical error (traceback). The fix ensures the editor remains stable by preventing errors when the last column is removed, improving the user experience and preventing report editing disruptions.
Original PR description
Problem: When deleting the last column in a table in studio we get a traceback. Cause: `firstCell` will be null if we delete the last cell in the table. Fix: Added a null check on `firstCell` before calling `setCursorEnd`, so the cursor is only repositioned when the table still has remaining cells. Steps to reproduce: - Edit a report with a table. - Remove all columns. - Traceback will occur when deleting the last one. opw-6263696 Forward-Port-Of: odoo/enterprise#119502
This update significantly speeds up how Odoo groups email messages, particularly when dealing with large volumes of data. The previous method was slow and inefficient, but this change optimizes the process, resulting in a dramatic performance boost. This means faster email processing and improved system responsiveness for our customers.
Original PR description
## The Problem When grouping messages, the code was accumulating recordsets using the `|=` union operator inside a loop. Since each union call internally builds an `OrderedSet` over all previously…
## The Problem When grouping messages, the code was accumulating recordsets using the `|=` union operator inside a loop. Since each union call internally builds an `OrderedSet` over all previously accumulated IDs, the performance degraded quadratically relative to the number of document records. This caused bottlenecks on databases with large message volumes. ## The Solution * Replaced the `|=` recordset accumulation with a plain Python dictionary of ordered sets to store IDs per operation, while keeping same behavior. * Deferred the `browse()` call until after the loop is complete. * Reduced the overall complexity from **$O(N^2)$** to **$O(N)$**. --- ## Benchmarks *Tested on a customer database grouping by "Created By" and "Created On":* | Record Count | Before | After | Improvement | | :--- | :--- | :--- | :--- | | **300k records** | 83.00s | **1.00s** | **-99%** | | **30k records** | 0.60s | 0.25s | (Minor) | **Note:** The performance gains become exponentially more significant as the record count grows. **OPW-6123758** Forward-Port-Of: odoo/odoo#269123 Forward-Port-Of: odoo/odoo#260147
This fix resolves an issue where extra prices were incorrectly applied to products with 'always' attributes when creating combos in Point of Sale. The update ensures that extra prices are now set on the combo creation page for 'always' attributes, aligning with the intended functionality and preventing double-counting.
Original PR description
## Steps to reproduce - Create an attribute A, of type always, with 2 values, one should have an extra price - Create an attribute B, of type never, with 2 values - Create a product that has both…
## Steps to reproduce - Create an attribute A, of type always, with 2 values, one should have an extra price - Create an attribute B, of type never, with 2 values - Create a product that has both those attributes - Create a combo with that product with both values for A - Go to the PoS and order that combo with the value that has an extra price for A - The extra price is added ## Why the fix: For variants of type always, a product is created, meaning we can chose which products of this variants to have in our combo. As we can chose this, it means that we can and should chose the extra price on the combo creation page, not on the attribute page. It does not make sense to take the attribute extra price into account, as we do not take the unit price of combo items into account, so this extra price should be set on the combo page and we should ignore the attribute's extra price if the type is "always". The variants are then considered as different products, as they should in this case. If the type of the attribute is never, we can't chose which one gets an extra price on the combo page, so we should still take the attribute's extra price in this situation, as we have no other way to set it. We need to have both an always and a never attribute in order to reproduce this bug because if we only have "always" values, the configuration of the combo item is bypassed and is undefined, so **attribute_value_ids** will be undefined in this code and we won't get any value for the extra price in this code: https://github.com/odoo/odoo/blob/c09e8b2fc24ee75495fc947924e29cf5c601506f/addons/point_of_sale/static/src/app/models/utils/compute_combo_items.js#L44-L49 We now ignore the attribute's extra price if it's type is always, otherwise, it the behavior stays the same. opw-6262431
This update corrects a visual issue where product images in the grid layout didn't display in the correct left-to-right order. The change adjusts how images are navigated within the product image viewer to match the user's visual perception, ensuring a consistent and intuitive shopping experience.
Original PR description
This commit ensures product images follow their visual order in the product image viewer when using the grid layout. Steps to reproduce: - Open a product page with multiple images (or add Extra Media…
This commit ensures product images follow their visual order in the product image viewer when using the grid layout. Steps to reproduce: - Open a product page with multiple images (or add Extra Media to the product) - Change layout mode to "Grid" and click save - Click any image to open the product image viewer - Navigate between images Images do not follow the visual left-to-right order. This regression was introduced by [commit], which replaced the row-based grid with a column-first layout. As a result, `querySelectorAll` returns images in DOM order, which no longer matches the visual order. To fix this, images are now reordered based on their visual placement in the grid so navigation matches the order seen by the user. Images are traversed in visual left-to-right order while also accounting for varying image heights and multi-column alignment. [commit]: https://github.com/odoo/odoo/commit/9a3628b9735550bf8ecc2252ea1b7338f68ab966 task-[4364143](https://www.odoo.com/odoo/project/974/tasks/4364143) Forward-Port-Of: odoo/odoo#269855 Forward-Port-Of: odoo/odoo#254077
This update resolves an issue where navigating between tasks in Odoo caused errors due to outdated information being restored from the user's browser session. The fix ensures that only dynamic actions are reused, preventing errors related to invalid context data and improving overall task navigation stability. This enhances the user experience by eliminating unexpected application behavior.
Original PR description
Steps to reproduce: - Open any project task - Click a project notification that opens another task (requires the corresponding notification preference to be enabled) - Use the browser's Back and Forward buttons => Traceback: active_id is undefined When navigating to a form view via a URL (e.g. `/odoo/m-<model>/<id>`), the action service looks up the last action from session storage and reuses it if the model matches. This behavior, introduced in a4b179a7118916aac032ad252c0e421d452e553c, does not discriminate between dynamic and non-dynamic actions. Non-dynamic actions (those with an id) may rely on context values such as active_id that are only valid in their original execution context. Restoring such an action during browser history navigation causes a traceback because active_id is undefined. Fix by only reusing the session-stored action when it is a dynamic action (no id). Forward-Port-Of: odoo/odoo#270076
This update fixes an issue where capitalized email domains were causing routing problems. The change prevents users from saving capitalized domain names, ensuring emails are correctly processed and delivered. This resolves a technical limitation impacting email functionality.
Original PR description
[FIX] mail_alias_domain: prevent capitalization in domain names to avoid email routing issues Currently, we allow capitalization in the name / display_name field for Email Domains…
[FIX] mail_alias_domain: prevent capitalization in domain names to avoid email routing issues
Currently, we allow capitalization in the name / display_name field for Email Domains (mail.alias.domain), which allows for capitalized domains in email aliases. When the system receives incoming emails via mail_thread.py's message_route,
the reply_to email addresses are sanitized (all lowercase). We then use the case-sensitive 'in' to identify
message routes, which will always fail for capitalized email domains.
This PR applies sanitizing to the name field so that users cannot save capitalized email domains.
Other options are not viable because:
1. we don't have a case-insensitive equivalent of the 'in' operator
2. altering the current logic to be case-insensitive would decrease performance
3. altering the current logic would change the structure of message_route
Fixes #opw-5401633
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#257792This update corrects an issue where the link editor unexpectedly appeared when creating multiple tracked links. The fix ensures the editor is properly canceled when a new link is generated, preventing confusing behavior and improving the user experience. This resolves a minor usability problem.
Original PR description
Steps to reproduce: - Go to the Link Tracker page - Generate a first tracked link - Click on the button to start editing the code - Click on "create another tracker" - Generate a second tracked link => When you access the screen to see/edit the tracked link url, the buttons "ok" and "cancel" are already present. Clicking on "ok" display a traceback. To fix this issue, this commit also cancels edition when clicking on "create another tracker". task-4531974 Forward-Port-Of: odoo/odoo#268573
This update fixes an issue where the number of comments displayed on course slides wasn't accurately reflecting the actual number of comments due to recent changes in how Odoo handles messages. The fix ensures that comment counts are synchronized with the current number of available comments, improving the user experience.
Original PR description
Steps to reproduce: - Open a slide of a course in non fullscreen mode (website). - Go to the comments tab and add a comment in the chatter. - The comments count does not change in the tab. - The same thing happens when a comment is deleted. - Another way to see the incorrect counter is to add a note in the slide form view (backend). Before this change, `website_slides` used `website_message_ids` to calculate the comments. Since #138233 the old portal chatter has been replaced with the mail chatter and the way messages are displayed on the portal has changed. For example notes are no longer considered portal messages and also deleted messages should not be displayed or counted as such. This change ensures that comments calculations are based on a domain that considers those changes meaning that comments will be synced with the actual number of available comments. Forward-Port-Of: odoo/odoo#263087 Forward-Port-Of: odoo/odoo#260376
This update fixes an issue where sales and purchase reports in the Philippines (SLSP) were sometimes exported with incorrect partner VAT values due to an unpredictable order of rows. The change ensures a consistent and reliable export, guaranteeing the correct partner VAT and row sequence for all reports. This improves data accuracy and reduces potential errors in financial reporting.
Original PR description
Description of the issue this commit addresses: SLSP XLSX partner rows were emitted in a non-deterministic order, which made the PH sales/purchases export tests sometimes swap partner VAT values. --- Desired behavior after this commit is merged: This commit keeps the SLSP partner rows in a stable order so the XLSX export always matches the expected partner VAT and row sequence. --- runbot-[162182](https://runbot.odoo.com/odoo/error/162182) Forward-Port-Of: odoo/enterprise#120052
This update significantly speeds up inventory adjustments when making changes to large delivery orders with reserved packages. Previously, adjustments were slow and could freeze the user interface. Now, inventory adjustments are much faster and more responsive, improving warehouse efficiency.
Original PR description
Behavior before: Adjusting physical inventory quantities for reserved packages takes time when linked to large delivery orders (e.g., 400+ lines). The user interface freezes, causing a poor warehouse…
Behavior before: Adjusting physical inventory quantities for reserved packages takes time when linked to large delivery orders (e.g., 400+ lines). The user interface freezes, causing a poor warehouse user experience during stock counts. Behavior after: Inventory adjustments on reserved packages process faster. The UI remains responsive, and package records are updated instantly without performance degradation. Root Cause: When an inventory adjustment triggers '_free_reservation', it processes move lines sequentially. Inside this loop, Odoo recursively runs '_check_entire_pack()', forcing a full database evaluation of all 400+ delivery lines for every single line adjusted. This results in heavy, redundant processing. Fix: Used a context flag `bypass_entire_pack=True` to silence the '_check_entire_pack()' validation while looping through individual line adjustments. Once the loop completes, the package validation is called exactly once in batch for all affected pickings, preserving data integrity while eliminating redundant database queries. Steps to Reproduce: 1. Have a product tracked by Lot and Package. 2. Have an open delivery order in Ready state (stock reserved) containing 400 or more lines of this product, one package per line. 3. Go to Inventory → Physical Inventory. 4. Set the counted quantity of any reserved bag to 0. 5. Click Apply. 6. Observe that the system takes time to process this single change. 7. Unreserve the delivery order. 8. Perform the same steps as mentioned above. 9. Inventory adjustment is much faster. opw-6234885 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270228
This update ensures the Odoo spreadsheet functionality is running the most recent version, addressing potential bugs and improving performance. It’s a routine maintenance task to keep our spreadsheet tools reliable and up-to-date. This change focuses on internal improvements to the spreadsheet component.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/233f3eafec [REL] 18.3.51 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/3f01c9d938 [FIX] Find and replace : selection after an UPDATE_CELL [Task: 4818132](https://www.odoo.com/odoo/2328/tasks/4818132) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This update resolves a technical issue preventing receipt printing in the Italian POS module. Specifically, a race condition caused printer deadlocks when automatic receipt printing was enabled. Now, printing is tied to the 'Skip Preview Screen' option, ensuring reliable receipt generation.
Original PR description
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview…
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview Screen"; - Disable "ePos Printer"; - Set up an Italian Fiscal Printer; - Open a POS session and process a first order. Issue: After the first receipt, no other messages (price display, receipt, open register) are sent to the fiscal printer. A page reload is required. Issue: After the first receipt, no other messages (price display, receipt, open register) are sent to the fiscal printer. A page reload is required. Cause: When "Automatic Receipt Printing" is true but "Skip Preview Screen" is false, a race condition occurs. `afterOrderValidation` triggers a print job while simultaneously transitioning to the `ReceiptScreen`. When the `ReceiptScreen` mounts, it triggers a second fiscal print job before the first has resolved. This creates a deadlock in `toHtml` of `renderService`, permanently blocking the printer queue. Solution: Since the italian localisation sending the receipt to the fiscal printer is mandatory, the printing route is now tied to the "Skip Preview Screen" option. Enterprise PR: https://github.com/odoo/enterprise/pull/112654 [opw-5979212](https://www.odoo.com/odoo/project/49/tasks/5979212) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270343 Forward-Port-Of: odoo/odoo#256932
This update resolves a bug that prevented receipt printing after the initial order in the Italian POS module. The fix ensures receipts are consistently printed via the payment screen, eliminating a printer deadlock and improving the user experience. The change also simplifies settings for Italian fiscal printers.
Original PR description
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview…
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview Screen"; - Disable "ePos Printer"; - Set up an Italian Fiscal Printer; - Open a POS session and process a first order. Issue: After the first receipt, no other messages (price display, receipt, open register) are sent to the fiscal printer. A page reload is required. Cause: When "Automatic Receipt Printing" is true but "Skip Preview Screen" is false, a race condition occurs. `afterOrderValidation` triggers a print job while simultaneously transitioning to the `ReceiptScreen`. When the `ReceiptScreen` mounts, it triggers a second fiscal print job before the first has resolved. This creates a deadlock in `toHtml` of `renderService`, permanently blocking the printer queue. Solution: Since the italian localisation sending the receipt to the fiscal printer is mandatory, the printing route is now tied to the "Skip Preview Screen" option. UI settings are adjusted to hide the redundant auto-print checkbox when an IT fiscal printer is configured. Community PR: https://github.com/odoo/odoo/pull/256932 [opw-5979212](https://www.odoo.com/odoo/project/49/tasks/5979212) Forward-Port-Of: odoo/enterprise#120747 Forward-Port-Of: odoo/enterprise#112654