Monday, September 21, 2026
18 changes · saas-19.4
Resolved issues and error corrections
This fixes an issue where access rights created through Studio were not treated as read-only when they should be. It helps prevent unintended changes to Studio-generated security settings and keeps configuration behavior consistent.
Original PR description
task-6481613
This fixes an issue where access permissions created through Studio were incorrectly treated as read-only. Users managing Studio customizations can now adjust these permissions as expected, reducing friction when configuring roles and access.
Original PR description
task-6481613 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue in the website page editor where using the keyboard arrow keys on certain size or filter number fields showed a preview but did not keep the new value. Editors can now adjust these settings with the keyboard and trust that the change will remain after clicking away.
Original PR description
When a BuilderRange is displayed with its optional number input, using ArrowUp/ArrowDown updates the preview but does not save the new value. The range component passes its handler through onKeydown, while BuilderNumberInputBase only calls onKeydownArrow after handling arrow keys. As a result, the debounced commit is skipped. Steps to reproduce: - Drop a s_social_media inner snippet - Click on the snippet, then click on the "Size" input - Use "ArrowUp" to increase the value of the number input - Click anywhere on the page => The size goes back to the previous one. task-6385984 Forward-Port-Of: odoo/odoo#286809 Forward-Port-Of: odoo/odoo#283504
Vendor bill users can now find purchase order lines by searching for the related purchase order name, not just the line description. This makes matching bill lines to purchases easier and reduces manual lookup when processing supplier invoices.
Original PR description
Issue: ------------------------------------- When creating a vendor bill, the Purchase Order Line field on the bill line allows selecting a purchase order line. However, the search only matches the…
Issue: ------------------------------------- When creating a vendor bill, the Purchase Order Line field on the bill line allows selecting a purchase order line. However, the search only matches the POL name and does not allow searching by the purchase order name. Steps to reproduce: ------------------------------------- 1. Install the `purchase` module. 2. Go to Vendor Bills, click New, and select a vendor. 3. Add the Purchase Order field to the bill line using the optional fields. 4. Click Add a line and open the Purchase Order selection. 5. Try to search for the line using the purchase order name. The purchase order line cannot be found. Cause of the issue: ------------------------------------- The `purchase.order.line` model does not define `_rec_names_search`, so the record search only considers the purchase order line's `name` field. Solution: ------------------------------------- Define `_rec_names_search` with both `name` and `order_id` so that POLs can also be searched using their related purchase order name.
Creating a Saudi Arabia contact and choosing a Tax Identification Number no longer crashes when no VAT number has been entered. The system now leaves the Saudi tax ID blank until VAT information is available, improving contact setup reliability.
Original PR description
## Steps to Reproduce: - Install the `l10n_sa` and `contacts` modules. - Create a new contact and set the country to **Saudi Arabia**. - Click the "**+**" sign next to the TIN field. - Select "**Tax Identification Number**". ## Error: `TypeError: 'NoneType' object is not subscriptable` ## Cause: The onchange method tries to extract the SA TIN from the VAT even when the VAT is not set. This causes an error when slicing the None value. ## Fix: Skip populating the SA TIN when the VAT is not set. sentry-7716910106
This fix prevents Chilean demo accounting setup from trying to post demo entries meant for non-Chilean partners. It helps companies and evaluators install Chilean localization alongside other localizations without demo data setup failures.
Original PR description
When several localization modules are installed at once (with demo data), loading the chilean demo data fails and the chilean demo company ends up without any accounting demo data. Steps to reproduce: - Install `l10n_cl` together with the other localizations and the enterprise addons, with demo data enabled Issue: Error while loading accounting demo data ValidationError: Document types for foreign customers must be export type (codes 110, 111 or 112) or you should define the customer as an end consumer and use receipts (codes 39 or 41) Analysis: Demo methods will posts every move of the chilean company, not only the ones prepared by the module. In combination with other modules loading their own demo data it may raise the said error. Forward-Port-Of: odoo/odoo#288590
This fixes a leftover reference in the self-ordering point of sale IoT flow after the related feature was removed elsewhere. It helps prevent unnecessary or failing calls, improving reliability without changing the customer-facing experience.
Original PR description
Remove last reference to `last_order_preparation_change` that was removed here. https://github.com/odoo/odoo/pull/250692
This update adjusts an automated stock workflow test so it works correctly when the Turkish Nilvera e-Dispatch module is installed. It prevents a false test timeout caused by a different screen identifier, improving reliability without changing user-facing stock behavior.
Original PR description
### Steps to reproduce: - Install `l10n_tr_nilvera_edispatch` (e.g. the `tr` country build) - Run `test_basic_stock_flow_with_minimal_access_rights` > The tour times out on step 6/31, "check that at…
### Steps to reproduce: - Install `l10n_tr_nilvera_edispatch` (e.g. the `tr` country build) - Run `test_basic_stock_flow_with_minimal_access_rights` > The tour times out on step 6/31, "check that at least one picking is present in the view". ### Cause of the issue: The step triggers on `.o_stock_list_view_view`, a class the web client derives from the `js_class` of `stock.vpicktree`: https://github.com/odoo/odoo/blob/71c040ae236c9487afc49559486a588f21ccb37b/addons/stock/views/stock_picking_views.xml#L66-L70 https://github.com/odoo/odoo/blob/71c040ae236c9487afc49559486a588f21ccb37b/addons/web/static/src/views/utils.js#L45-L68 `l10n_tr_nilvera_edispatch` overwrites that attribute to plug in its e-Receipt upload button, so the root carries `o_l10n_tr_edispatch_tree_view` instead and the trigger never matches: https://github.com/odoo/odoo/blob/71c040ae236c9487afc49559486a588f21ccb37b/addons/l10n_tr_nilvera_edispatch/views/stock_picking_views.xml#L4-L13 Only the class name changes: `L10nTrNilveraEdispatchListView` spreads `StockListView`, so the rendered list is identical. runbot-947260 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288404 Forward-Port-Of: odoo/odoo#288255
This update fixes test setup issues affecting the Purchase app and Units of Measure feature. It makes automated purchase walkthroughs more reliable and ensures units of measure are properly enabled or disabled during tests, reducing false failures and improving confidence in the feature.
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. Forward-Port-Of: odoo/odoo#283451
This update corrects outdated Belgian payroll salary test steps after related product and UX changes. It helps keep automated validation reliable by removing checks for a retired feature and aligning expected payroll values with the current configuration.
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-242808
Forward-Port-Of: odoo/enterprise#131958This update prevents an error when editing sale order line list views in Odoo Studio after a sale order is confirmed. Users can now customize the sale order line view without the screen crashing, while normal sales behavior remains unchanged.
Original PR description
Steps to produce: ---- - Install sales and studio module. - Create new product and make sale order using it. - Confirm the sale order and open the studio. - Click on sale order line > Click on edit…
Steps to produce: ---- - Install sales and studio module. - Create new product and make sale order using it. - Confirm the sale order and open the studio. - Click on sale order line > Click on edit list view. Issue: --- - Clicking the `edit list view` button raises a traceback: `TypeError: Cannot read properties of undefined (reading 'locked')` Root cause: --- - The issue was introduced by [commit]. - `saleProductMixin.hasConfigurationButton` reads the parent sale order's `locked` field by walking up the model tree: https://github.com/odoo/odoo/blob/973218b9d60ebe715f0bf5a9bdc54b036b002e9b/addons/sale/static/src/js/sale_product_mixin.js#L68 - This works in a normal form view because `model.root` is the sale order Record, and Record always has a `.data` object containing its field values. - In Studio's list editor, `model.root` is no longer the sale order Record. Studio replaces it with a `StaticList` - the list of order lines itself. so, it can render the `subview` directly: https://github.com/odoo/enterprise/blob/a6c971daad566043e073b2cb6f2fd18794b49fb0/web_studio/static/src/client_action/view_editor/editors/list/list_editor.js#L73-L77 - `StaticList` holds a collection of child records. It has no field values of its own, so it never sets .data. Accessing `model.root.data` returns undefined. Solution: --- - The `locked` check is only meaningful when a full sale order record tree exists above the line, which isn't guaranteed for every rendering context. Falling back to `undefined` when `root.data` is absent keeps the check inert rather than crashing, without changing behavior in the normal runtime path where `root.data` is always a valid `Record`. [commit]: https://github.com/odoo/odoo/commit/84f4c84adfba546ba940175411363a865d8f7c3a opw-6566217 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix makes website editor color options and the shop product comparison bar display correctly when users work in languages such as German. Longer translated labels now fit better, and styling no longer depends on English text, improving consistency for multilingual users.
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#289008 Forward-Port-Of: odoo/odoo#286426
This fixes a VAT validation issue where child contacts could incorrectly show an invalid VAT status when processed before their parent company. Parent company VAT results are now calculated first, so related child records correctly reuse the verified result.
Original PR description
**Description of the issue/feature this PR addresses:** When a batch recompute of `vies_valid` contains both a parent (commercial) partner and a child sharing the same VAT, and the child happens to…
**Description of the issue/feature this PR addresses:**
When a batch recompute of `vies_valid` contains both a parent (commercial) partner and a child sharing the same VAT, and the child happens to be iterated before its parent, the child ends up with `vies_valid=False` instead of the parent's real, freshly-checked value.
**Current behavior before PR:**
`_compute_vies_valid` loops over `self` in whatever order the batch happens to have:
```python
for partner in self:
...
if partner.parent_id and partner.parent_id.vies_vat_to_check == partner.vies_vat_to_check:
partner.vies_valid = partner.parent_id.vies_valid
continue
status = partner._check_vies_iap()
partner._update_vies_status(status)
```
`Field.compute_value()` removes the whole batch from the "to compute" queue *before* running this loop (it does so upfront, in case the method does not assign every record). So when the loop reaches a child and reads `partner.parent_id.vies_valid` to reuse it, that field is no longer marked "to compute" for the parent, and reading it just returns whatever is currently cached/stored — which, if the parent has not been processed yet in this same loop, is still the old/default value. The child copies that stale value and, being a stored field, keeps it forever: nothing re-triggers its computation afterwards.
Example:
```python
parent = env['res.partner'].create({'name': 'Parent Co'})
child = env['res.partner'].create({'name': 'Child Address', 'parent_id': parent.id})
child.vat = 'BE0477472701' # queues the child's compute first
parent.vat = 'BE0477472701' # queues the parent's compute second
child.vies_valid # False, even though the VAT is valid
parent.vies_valid # True
```
**Desired behavior after PR is merged:**
Every partner without a parent is always computed before any child that may reuse its value, regardless of the batch's original order — so the child correctly ends up with the parent's real `vies_valid`.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#287351
Forward-Port-Of: odoo/odoo#279927The French PDP e-invoicing module now records the actual status code when it receives an unsupported lifecycle status. This makes issue investigation easier by replacing unclear blank or `None` log entries with useful information.
Original PR description
Currently we just log `None` in case we receive a lifecycle with an unsupported (on community side) status. After this commit we log the status code at least. task-None before fix <img width="711" height="120" alt="image" src="https://github.com/user-attachments/assets/1f939cf4-17b7-49cb-8b31-5cc594fdeadd" /> after fix <img width="700" height="116" alt="image" src="https://github.com/user-attachments/assets/1b8b3853-f2da-4426-9c49-1d135d1c7824" /> Forward-Port-Of: odoo/odoo#286429
This fix makes a manufacturing test reliable across different time zones when checking date-based serial numbers. It helps avoid false test failures in automated validation, improving confidence in release checks without changing user-facing behavior.
Original PR description
**PROBLEM**
In `test_generate_serial_button_sequence()` we generate a serial number based on the day of the year. In ir_sequence, we use the time based on the environment timezone, but in the test, we don't use any timezone. This can lead the assertion to fail, since the day of the year can differ with the timezone used.
**REPRO STEPS**
1. edit the freeze_time in the test to `freeze_time('2024-01-15T23:00:00')`
If your timezone is UTC+2, then the time according to your timezone will be `2024-01-16T01:00:00`
So, without in UTC+0, it's the 15th day of the year, but in UTC+2 it's already the 16th.
Remove the timezone in the last assertIn() (ie, remove the fix).
(if your timezone is different, adjust the freeze_time accordingly)
2. run the test and see it fails.
runbot-237780
Forward-Port-Of: odoo/odoo#285647Product option pills in the sales configurator now keep consistent spacing when they wrap onto multiple lines. This prevents cramped rows and makes product choices easier to read for users configuring sales orders.
Original PR description
Pill-style attribute values used Bootstrap's list-inline/list-inline-item, which only sets margin-right between items. When pills wrapped onto a new line, the rows touched with no vertical gap. Fix: Switch the pill list to a flex container with gap-2, matching the spacing website_sale already uses for its own attribute-value lists, so wrapping rows get the same gap as pills on the same row. opw-6584507 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289176
Creating an onsite event from the Onsite action now uses the current user's employee record when no employee is provided. This prevents errors and ensures the new event appears in the expected kanban view for users.
Original PR description
The Onsite action only sets the hr_skills_event_add_employee key in its context, without any employee. Reading default_employee_id directly then raised a KeyError. Even before that, no attendee was added, so the new event did not match the domain of the action and stayed hidden in the kanban view. We now fall back on the employee of the current user. taskid-6361432 Forward-Port-Of: odoo/odoo#288241
An unused line in maintenance request creation was removed because it did not change any data. Maintenance teams are already assigned automatically when requests are created, so this cleanup has no impact on day-to-day use.
Original PR description
The create method assigned request.maintenance_team_id to itself, a no-op that reads and writes the same value and has no effect. This line originally set the team from the equipment as a fallback when creating a request. PR #196181, while refactoring mail alias handling from equipment category to team, replaced that assignment with a self-assignment, turning it into dead code. maintenance_team_id is a required field and is already a stored compute depending on equipment_id, so it is computed correctly on create without this line. Removing it has no functional impact. Forward-Port-Of: odoo/odoo#289007 Forward-Port-Of: odoo/odoo#286132