Friday, September 18, 2026
19 changes · saas-19.3
Resolved issues and error corrections
Odoo now allows custom modules to choose how language flags are displayed instead of always deriving them from the language code. This helps businesses show flags that better match their regional branding or served markets without extra workarounds.
Original PR description
Which flag stands for a language is a presentation choice, not a property of its code. `_compute_field_flag_image_url` derives the URL from the country part of the locale, and a site that wants a…
Which flag stands for a language is a presentation choice, not a property of its code. `_compute_field_flag_image_url` derives the URL from the country part of the locale, and a site that wants a different flag for a language it offers, a regional one or the flag of the country it actually serves rather than the one the code names, has to compute that URL its own way.
That is not possible today. The field passes the compute as the function object:
flag_image_url = fields.Char(compute=_compute_field_flag_image_url)
`determine()` takes the `callable` branch and calls that object with the recordset. A plain function is not bound, so the implementation of `base` runs whatever class the record has: a module that inherits res.lang and defines `_compute_field_flag_image_url` changes nothing, and nothing says so. No error, no warning, and the field keeps answering the same URL. Getting around it means redeclaring the field only to replace its compute, which is more than the situation calls for.
Passing the method name puts the computation back on the MRO and costs nothing else: `Field.get_depends` resolves a string with `resolve_mro` and collects `_depends` from every implementation it finds, so the `@api.depends('code', 'flag_image')` declared here keeps applying, to this implementation and to an override alike.
This is the same kind of fix as #185419, which made the `domain` of a field reachable by an override for the same reason. Two field declarations in the codebase still pass a function object this way; the other is `website.menu.is_mega_menu`, which passes `inverse` the same way and is left alone here.
Forward-Port-Of: odoo/odoo#288686Attachments added to time off requests will now remain visible even when the time off type does not require supporting documents. This prevents files uploaded by employees or managers from appearing to disappear and keeps leave records complete.
Original PR description
Issue: ---------------------------------------- If the option "Require Supporting Document" on the Time Off Type is unticked, then when adding an attachment on a leave it disappears. Steps to reproduce: ---------------------------------------- - Have a Time Off Type with "Require Supporting Document" unticked - Create a leave with this time off type - On the form view add an attachment through the paperclip icon - It disappears Cause: ---------------------------------------- In `_compute_attachment_is_visible()` if `work_entry_type_support_document` is `False` then `attachment_is_visible` too. `attachment_is_visible` then control whether the attachments of a leave are visible. Solution: ---------------------------------------- Remove the condition on `work_entry_type_support_document`, `attachment_is_visible` purpose is to limit the access to attachments for users unliked to the leave. opw-6542429
This update fixes issues in purchase-related automated tours and ensures unit of measure settings are correctly enabled or disabled during tests. It helps prevent false test failures and keeps purchasing workflows reliable when unit options need to appear.
Original PR description
> ### [FIX] purchase: tour trigger > This commit replaces a trigger which used the button URL because this button's URL can differ if the tour is run in debug mode (eg.: `/odoo/purchase?debug=assets` instead of `/odoo/purchase`). > ### [FIX] uom: correct group > This commit fixes `_enable_uom` and `_disable_uom` `UomCommon` class methods to correctly enable/disable the UoM feature. > > Before that, the user has CRUD accesses to UoM but the feature wasn't enabled as expected, which means `_enable_uom` wasn't enough to display UoM fields in view when this field use the group `uom.group_uom` to be display. > > This issue was spotted while working on the `purchase` test/tour `test_catalog_vendor_uom`. When launch locally on a DB without demo data and only with `purchase` installed, the units of measure weren't visible during the tour, and if the tour is paused and we go in the settings, we can see the UoM setting is unticked.
Project task totals now ignore subtasks that belong to task templates, matching how users see regular tasks in the interface. This makes open, closed, and total task counts more accurate for project reporting and planning.
Original PR description
Before this commit, the task_count and closed_task_count takes into account the subtask inside task template, however, those subtasks are not considered as a basic task in the UI, there are also considered as a template.
This commit adds `('has_template_ancestor', '=', False)` condition to make sure those subtasks are no longer taken into account. The condition inside the compute of `open_task_count` has also been reviewed to have the same conditions in the 3 fields.
task-6483156This fix improves how translated labels display in the website editor color picker and product comparison bar. It prevents long labels from overflowing and ensures styling works consistently across languages such as German.
Original PR description
Steps to reproduce: - Set the user language to German. - Open a color picker with the `Theme` tab in the website editor. - Check the color presets and the reset button. - Open the product comparison bar on the shop page. => Long labels do not fit and some styles are missing. Before this commit, long labels did not fit in the color preset picker. Some CSS selectors also relied on English `title` values, so their styles were not applied in other languages. After this commit, the preset picker adapts to long labels and the CSS selectors use dedicated classes that work in every language. task-6259086 Forward-Port-Of: odoo/odoo#288160 Forward-Port-Of: odoo/odoo#286426
This fixes a missed internal rename so product quantities use the intended unit precision instead of silently defaulting to two decimals. It helps ensure more accurate quantities in Jordanian POS e-invoicing, POS sales details, and stock package handling.
Original PR description
…al.precision The `decimal.precision` "Product Unit of Measure" was renamed "Product Unit" in 18.1. Some occurences called the old name still exist in the code. This is silently fallbacking on the default 2 decimals from the `precision_get`. See: https://github.com/odoo/odoo/pull/193490 task-none Forward-Port-Of: odoo/odoo#288710 Forward-Port-Of: odoo/odoo#288508
Fixed a navigation issue in the API documentation where opening a related field in a new tab could show the original model instead of the related one. This makes browsing model relationships more reliable and avoids unnecessary page reloads.
Original PR description
Steps to reproduce: * open api_doc * select a model (eg: project.task) * middle click on a many2one field (eg: stage_id) Observed behavior: The new tab is opened on the base model (project.task) instead of the comodel (project.task.type). This commit fixes the issue by using `t-att-href` to point to the correct model and `preventDefault` to avoid a full reload when clicking on a m2o. Forward-Port-Of: odoo/odoo#288558
Fixes an issue where clicking “Testing” for a custom recorded tour could do nothing if the tour was only stored in the database. This ensures recorded tours can be tested reliably from the tours list, helping teams validate guided flows without extra technical steps.
Original PR description
Clicking "Testing" on a custom/recorded tour called startTour with mode "auto" and fromDB true, but getTour() only loaded from the database when mode was "manual". For a tour that only exists in the web_tour.tour record (not in the client-side registry), this left `tour` undefined and startTour() silently did nothing. Load from the database whenever fromDB is set, regardless of mode. Task-id: 6575435 Forward-Port-Of: odoo/odoo#288474
Invoices that have already been sent through PEPPOL can no longer have the PEPPOL send option selected again. This avoids accidental duplicate sending and makes the disabled option clearer to users by showing why it is unavailable.
Original PR description
If the invoice is already sent through PEPPOL, the checkbox for sending the invoice should then be readonly and unchecked. Currently is correctly unchecked but not readonly. We fix it by copying what French localization (`l10n_fr_pdp`) does already, giving a reason for disabling. <img width="1359" height="948" alt="immagine" src="https://github.com/user-attachments/assets/6f91ab34-8989-487e-8cd9-96dafee7bcb5" /> . Pad: https://pad.odoo.com/p/accountingv20 pad-accountingv20 Forward-Port-Of: odoo/odoo#288898
This fixes an internal error check so it reports the intended assertion message instead of triggering the wrong type of error. The change helps developers and support teams diagnose export identifier issues more accurately, with no expected impact on day-to-day users.
Original PR description
The format was broken. `'{}:{}' % it` → `TypeError` instead of `AssertionError`.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#288836
Forward-Port-Of: odoo/odoo#288610Removing a lock date now correctly clears related accounting report snapshots. This prevents outdated snapshot data from being kept when a lock date is fully removed, improving data consistency for financial reporting.
Original PR description
Entirely setting the lock date to false did not properly delete the snapshots. Nothing was added to snapshot_deletion_domains, and running Domain.OR on such an empty list returned an always-falsy domain. No snapshot was therefore ever selected for deletion in that case.
Merging helpdesk tickets now keeps the sales order item on related timesheets aligned with the destination ticket. This prevents inconsistent billing or reporting information after support tickets are combined.
Original PR description
Currently when you merge helpdesk tickets with differing sale order items, the sales order item listed on the timesheets of the source ticket is not updated to match the destination ticket's sales order item. This PR ensures uniformity bugfix-6473396 Forward-Port-Of: odoo/enterprise#131155 Forward-Port-Of: odoo/enterprise#129060
This update corrects automated checks for the Belgian payroll salary flow after related feature, display, and configuration changes. It helps keep internal validation reliable so future payroll updates can be tested without false failures.
Original PR description
Error 1:
Drop the automatic extra legal allocation 's test: this feature was remove
in this task 5362345; but the test was not removed
Error 2:
Due to some UX change the IP display change and the test was not up-to-date
Error 3:
Due to a misconfiguration the public transport value was wrong.
runbot_error-242808This fix updates a missed internal reference so quantities use the intended product unit precision instead of falling back to a generic two-decimal default. It helps keep sales, field service planning, and timesheet-related quantities displayed and calculated consistently.
Original PR description
The `decimal.precision` "Product Unit of Measure" was renamed "Product Unit" in 18.1. Some occurences called the old name still exist in the code. This is silently fallbacking on the default 2 decimals from the `precision_get`. See: https://github.com/odoo/odoo/pull/193490 task-none Forward-Port-Of: odoo/enterprise#131811 Forward-Port-Of: odoo/enterprise#131709
When staff create an appointment directly from the calendar, the event now uses the exact time slot they selected instead of defaulting to the standard appointment duration. This prevents incorrect booking lengths and helps calendars reflect the intended availability more accurately.
Original PR description
When creating an event from the calendar view of an appointment type, the duration of the event was set to the duration of the appointment, therefore bypassing the slot we drew. This commit fixes this behavior by giving the priority to the end date of the drawed slot. Task-6412432 Forward-Port-Of: odoo/enterprise#130171
This fix ensures AI-generated pivot reports correctly understand grouped columns, including date or time intervals. It helps prevent reporting errors when users ask the AI to build or update pivot views.
Original PR description
The AI backend returns column groupbys as a list containing both strings and dictionaries with interval information. While this format is used to preserve the interval metadata, the pivot model expects `colGroupBys` to be a flat list of strings. This commit updates the view patch to flatten dictionary entries into their corresponding `<field>:<interval>` strings before assigning them to the pivot model metadata, ensuring the format matches the pivot model's expectations. task-6377810 Forward-Port-Of: odoo/enterprise#129515
This update removes an obsolete reference in the self-ordering IoT area that pointed to functionality already removed elsewhere. It helps keep the point-of-sale self-ordering flow clean and avoids potential errors from calling outdated code.
Original PR description
Remove last reference to `last_order_preparation_change` that was removed here. https://github.com/odoo/odoo/pull/250692
This fix ensures that when users remove a block in Studio that includes text followed by an element, both parts are removed as expected. It prevents leftover text from remaining in customized views, improving accuracy when editing screens.
Original PR description
Have an arch like ``` <div> <br /> TEXT <span /> </div> ``` Now remove the block `TEXT <span />` Before this commit, the resulting inheriting arch was just `<xpath expr="//span" position="replace" />` So the `TEXT` was not removed After this commit, the `TEXT` is removed along with the following span opw-6524957 Forward-Port-Of: odoo/enterprise#131812 Forward-Port-Of: odoo/enterprise#131717
This update adds a test to ensure Avalara tax recalculations stay consistent when only exemption-related tax details change. It helps prevent mismatches between product lines and tax lines after actions such as uploading an exemption certificate and recalculating taxes.
Original PR description
We removed the explicit tax clearing [1]. It ends up triggering a situation where extra_tax_data on the product lines diverges from the tax lines. This happens when the tax integration writes only extra_tax_data without modifying anything else on the lines (if e.g. you first calculate tax, upload the exemption certificate to Avalara, and then recalculate tax). This tests that exact scenario. opw-6547387 [1] https://github.com/odoo/enterprise/pull/107863