Monday, September 21, 2026
15 changes · saas-19.3
Enhancements to existing features
French partner records now show both VAT and SIREN identifiers by default. This makes key business identification information easier to see and manage for companies operating in France.
Original PR description
Added siren to the default taxes for France countries so now both vat and siren are shown in the partners view by default. task-6193373
Resolved issues and error corrections
The accounting tests now use a proper PDF file instead of invalid sample content. This helps prevent false test failures and keeps quality checks stable without changing user-facing behavior.
Original PR description
Use PDF_RAW from base.tests.files instead of fake (and invalid) PDF content, like the other tests needing a PDF attachment. runbot-946577
Documentation and clarification updates
Joris Debonnet has added their signed contributor agreement confirmation to the project records. This supports Odoo's legal contribution process and helps ensure future contributions can be accepted under the project's licensing rules.
Original PR description
I confirm I have just signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289221
This fix updates an automated inventory workflow test so it works correctly when the Turkish Nilvera e-Dispatch localization is installed. It prevents false test failures caused by a different screen identifier, helping keep stock operations validation reliable for localized deployments.
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
The system now blocks creation of API keys that are already expired. This helps prevent mistakes when users copy example settings or enter past dates, reducing confusion and avoiding unusable keys.
Original PR description
Prevent creating API keys that are already expired. One typical case is when you copy/paste the documentation and end up creating keys that are already expired, without noticing. Forward-Port-Of: odoo/odoo#288154 Forward-Port-Of: odoo/odoo#286548
This fixes an issue where installing Chilean localization demo data alongside other localizations could fail and leave the Chilean demo company without accounting examples. The change ensures only suitable Chilean demo transactions are posted, improving setup reliability for demo and testing environments.
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
Employees without HR access can now see one-off work location entries in the calendar, matching the visibility of recurring work locations. This fixes an inconsistency that could hide important availability or location information from colleagues planning meetings or schedules.
Original PR description
**Steps to reproduce** - With a user having HR rights, create an exceptional work location for a user (click on the top bar of one of the days in the calendar, where work locations are displayed, and do not check "repeat every". - Open the calendar app with a user having no HR rights, in the sidebar, add the user with a non-recurrent work location. Notice that the work location is not visible, unlike recurring ones. **Cause** Recurring work locations are defined on the public employee (`*_location_id` type fields) and are readable by all users. Non-recurring work locations are `hr.employee.location` records and the `homeworking_own_rule` rule restricts read operations for non-HR users. opw-6190464 Forward-Port-Of: odoo/odoo#266380
This fixes an issue where a child contact could show an incorrect VAT validation result when processed before its parent company. Parent companies are now checked first, so related contacts inherit the correct VAT status and business records stay accurate.
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#279927This fix improves French PDP e-invoicing logs when an unsupported lifecycle status is received. Instead of showing a blank or unhelpful value, the system records the actual status code, making troubleshooting easier for support teams.
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 fixes an issue in the website HTML builder where using arrow keys to adjust certain size or slider number fields only changed the preview temporarily. The updated value is now properly saved, preventing settings from reverting after the user clicks 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#283504
This fixes a manufacturing test that could fail depending on the timezone of the system running it. The change makes automated checks more consistent and reduces false failures during quality validation, 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 clear spacing when they wrap onto multiple lines. This improves readability and avoids a cramped layout for products with many attribute choices.
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
Payroll dashboard warnings for starting a new or current payroll now respect a user's choice to hide or archive them. This prevents the same warning from repeatedly appearing after dismissal, reducing confusion for payroll users.
Original PR description
Issue: ---------------------------------------- The "Create New Payroll"/"Current Payroll" warning is always displayed, even when hiding or archiving it. Steps to reproduce: ---------------------------------------- - Go to the Payroll Dashboard - Click "Set Schedule" if the warning is there - Then a new warning appears: "Create New Payroll" - Try hiding it by clicking the cross (with or without "Never show it again") - The warning is always there Cause: ---------------------------------------- The warning is added through `_get_payrun_start_warning()` which ignores the `effective_domain`. It even ignores of the warning is active or not by getting it through its ref. Solution: ---------------------------------------- Only call `_get_payrun_start_warning()` if the warning matches the `effective_domain`. opw-6366294
Creating an onsite event from the Onsite action now uses the current user's employee record when no specific employee is provided. This prevents an error and ensures the new event is visible in the expected kanban view.
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
A redundant internal step was removed from maintenance request creation. The maintenance team is already assigned automatically, so this cleanup has no impact on users or daily workflows.
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