Monday, September 28, 2026
11 changes · 19.0
Resolved issues and error corrections
This fixes cases where expanding a form from views such as Gantt opened a generic backend form instead of the intended specialized form. Users, including portal users in project task sharing, now see the right form layout for their context, reducing confusion and incorrect navigation.
Original PR description
When a user expands the form view (e.g., from the Gantt view), a default low-priority form view is opened because the specific form view ID is not passed during dialog initialization. This commit…
When a user expands the form view (e.g., from the Gantt view),
a default low-priority form view is opened because the
specific form view ID is not passed during dialog initialization.
This commit introduces the expandedFormRef props to FormViewDialog,
allowing users to specify the exact form view to be used when expanding.
Use case:
In project task sharing, when a portal user expands a task from
the Gantt view, we want to open the project sharing form view
instead of the default backend view.By passing the expandedFormRef
(form view ID) while opening the dialog, we ensure the correct view
is used.
this.dialogService.add(
FormViewDialog,
{
title,
resModel,
...
context: {
expandedFormRef: formViewId,
}
}
);
backport-https://github.com/odoo/odoo/pull/199912/changes/4f71fbbd26b428e57943d974e8441bef295cdef1
task-6356431
Forward-Port-Of: odoo/odoo#290138Employee records now show the contract and salary structure type that applied to the selected historical timeline version, instead of always showing the current active values. This helps HR users review past employee information accurately without changing the underlying database structure.
Original PR description
### Description of the issue/feature this PR addresses: When navigating through historical employee records on the employee form view timeline, the contract_type_id persistently displays the active…
### Description of the issue/feature this PR addresses: When navigating through historical employee records on the employee form view timeline, the contract_type_id persistently displays the active contract type rather than the correct historical value for the selected version. This behavior is rooted in how the Odoo ORM handles caching for stored related fields. Because contract_type_id is defined with store=True, the ORM optimizes read operations by fetching the data cached in the local hr.employee database column, bypassing the newly selected version_id context. Attempting to fix this by modifying field attributes directly (e.g., setting store=False) breaks native base schema validation tests because it removes the expected physical database column. ### Current behavior before PR: Selecting a historical version on the Employee timeline continues to display the current active contract_type_id. Contract types selected on one version will reflect across all version visually, even if other versions have different contract types. ### Desired behavior after PR is merged: Selecting any timeline version on the Employee form view dynamically and accurately displays that version's specific historical contract_type_id. The field stays reliably populated and reactive when switching back and forth between timeline nodes, as the ORM is forced to recalculate its value upon every context shift. opw-6518153 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixed an issue where commission detail views could appear empty for salespeople assigned to multiple sales teams. The report now uses the sales team linked to the selected commission plan, helping managers see the correct achievement details.
Original PR description
When a salesperson belongs to multiple sales teams, opening the details of a team-based commission plan can show an empty Achievement Details view if the plan's team differs from the salesperson's…
When a salesperson belongs to multiple sales teams, opening the details of a team-based commission plan can show an empty Achievement Details view if the plan's team differs from the salesperson's primary sales team. Steps to reproduce: - Create two sales teams, Team A and Team B, without assigning a team leader. - Add the same salesperson to both teams, with Team B added first, making Team B the salesperson's sale_team_id. - Create separate team-based commission plans for Team A and Team B and add the salesperson to both plans. - Create and confirm a sales order for Team A with the salesperson assigned. - Open the commission report for Team A and click Details. The Achievement Details view is empty, while Team B details load as expected. The action currently sets `commission_team_ids` using the salesperson's sales team instead of the commission plan's team. This causes the Team A sales order to be excluded when the achievement data is generated, resulting in an empty Details view. Solution: Use the commission plan's team when populating 'commission_team_ids' so that the source records are filtered using the team associated with the selected plan. opw-6529552 [Runbot Video](https://drive.google.com/file/d/1VK-YujUPvuJP3bzPeRsJqokPKaWlh0zG/view?usp=sharing)
This fix stops the standard Attendance work entry type from being incorrectly configured as Time Off. It prevents payroll and time-off calculations for flexible employees from showing zero time when attendance records should count as work.
Original PR description
- The standard Attendance work entry type (`WORK100`) can be configured as Time Off by setting `is_work=False`. - In this configuration, the inverse method sets `is_leave=True`, causing `WORK100` to be considered a leave work entry type. - For flexible employees, the generated Attendance intervals are checked by `_is_work_period()`. Since `WORK100` has `is_leave=True`, these intervals are filtered out, resulting in a Time Off duration of 0 days and 0 hours. - Prevent configuring the standard Attendance work entry type as Time Off by raising a validation error when `is_work` is disabled. **opw-6593405** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The online shop now keeps decimal quantities for products sold by weight, volume, length, or other continuous units, so customers can buy amounts like 2.5 kg without the cart reducing it to 2 kg. For products sold as individual units, the product page and configurator now show whole-number quantities upfront, matching what will actually be added to the cart and avoiding pricing confusion.
Original PR description
The eCommerce always casts cart quantities to integers, which prevents selling products in continuous units of measure (kg, L, m, ...), and lets the product page and the product configurator display…
The eCommerce always casts cart quantities to integers, which prevents selling products in continuous units of measure (kg, L, m, ...), and lets the product page and the product configurator display quantities that are silently truncated when added to the cart. Quantities are now rounded according to the unit of measure: continuous UoMs keep the decimals allowed by the "Product Unit" precision, while UoMs based on Units keep integer quantities. Continuous UoMs --------------- Steps to reproduce: 1. Create a product sold in kg and publish it on the website 2. On its product page, set the quantity to 2.5 and add it to the cart Observed: The cart line gets 2 kg. https://github.com/user-attachments/assets/36bc1453-3b89-4009-a7ff-b3f896834b5e Expected: The cart line gets 2.5 kg. Product page, UoMs based on Units --------------------------------- Steps to reproduce: 1. Open the page of a product sold in Units 2. Set the quantity to 2.5 and add it to the cart Observed: The product page keeps showing 2.5, but the cart line gets 2 units. Uploading Screen Recording 2026-09-25 at 11.06.17 AM.mov… Expected: The quantity is truncated to 2 on the product page, showing the user exactly what's going to be added to the cart. Product configurator, UoMs based on Units ----------------------------------------- Steps to reproduce: 1. Open the page of a product sold in Units with optional products 2. Set the quantity to 1.5 and click "Add to cart" 3. In the configurator, change the quantity to 3.7 Observed: The configurator shows 1.5, then 3.7, and its total is computed on those quantities, but the cart line gets 1, then 3 units. https://github.com/user-attachments/assets/05df405d-39ed-449b-81b1-76337b10f57c Expected: The configurator shows 1, then 3, and its total matches the quantity added to the cart. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Portal users with limited edit access can now create and save tasks, subtasks, and nested subtasks in shared projects without permission errors. This keeps project collaboration working as intended while preserving access limits for fields they should not edit.
Original PR description
**[FIX] project: allow portal users with edit-limited access to create tasks** Steps to Reproduce: - As an internal user, share a project with a portal user and assign them `Edit with limited…
**[FIX] project: allow portal users with edit-limited access to create tasks**
Steps to Reproduce:
- As an internal user, share a project with a portal user and assign them `Edit with limited access`.
- Log in as the portal user.
- Open the shared project and navigate to the task list.
- Create a new task or subtask and try to save it.
- Observe that the portal user is unable to create or save the task.
Issue:
- When a project is shared with a portal user and assigned `Edit with limited access`, the portal user is unable to create or save tasks in the shared project.
Cause:
- The security rule project_task_rule_portal_project_sharing was too restrictive and did not grant create access for portal users with `Edit with limited access` rights. As a result, the record creation failed despite being allowed in the UI.
Solution:
- Update the `project_task_rule_portal_project_sharing` rule to properly include create access for portal users with `Edit with limited access`, ensuring they can create and save tasks/subtasks in project sharing.
**[FIX] project: allow portal users to create tasks with subtasks**
Steps to reproduce:
- Share a project with a portal user and give them Edit (limited) access.
- Log in as the portal user.
- Try to create a new task with a subtask in a single operation
Cause:
- When creating a task together with its subtasks, the `parent_id` record rule blocked access. At the moment of creation, the portal user was not yet a follower of the parent task, so they could not read it, leading to an access error.
Solution:
For portal users:
- Temporarily strip `child_ids` from the creation values.
- Create the parent tasks first.
- Subscribe the portal user as a follower of the parent.
- Write back the subtasks (child_ids).
For non-portal users, the flow remains unchanged, and subtasks are created in one go.
**[FIX] project: allow portal users to create subtasks when milestone is in context**
- Share a project with a portal user having Edit or Edit with limited access permissions.
- Log in as that portal user.
- Open the shared project and create a new task with a subtask.
- From the task form, open the subtask by clicking the `View Task` button in the subtask list.
- In that subtask, create another subtask (a subtask of the subtask).
- Click Save and observe that the record cannot be saved.
Cause
- When a portal user creates a subtask of a subtask in a shared project, they do not yet have access to the `milestone_id` field. As a result, even though a milestone is present in the context, it cannot be assigned during record creation, causing the subtask to fail when saving.
Solution:
- In the create method, we extract the milestone_id into `additional_vals_list` and assign the milestone after task creation using `sudo`.
**[FIX] project: fix project sharing warning on task creation**
Steps to Reproduce:
- As an internal user, share a project with a portal user and assign
Edit with limited access.
- Log in as the portal user.
- Open the shared project and go to the task list.
- Create a task, then create its subtask, and open the subtask form.
- Click the parent task stat button and attempt to create a new task.
- Notice the following warning appears in the logs.
`You do not have enough rights to access the field "create_uid" on Task
(project.task)`
Cause:
- The stat button opens the task creation form without a safe context, causing
Odoo to read restricted fields (like create_uid), which portal users cannot
access.
Solution
- Pass a context to the button to avoid reading restricted fields:
`context="{'default_project_id': project_id}"`
**[FIX] project: prevent partner access error for shared users**
Steps to Reproduce:
- Install Project.
- Share a project with a project sharing user having Edit or Edit with limited
access permissions.
- Log in as that shared user.
- Open the shared project and create a task from the list or kanban view.
Issue
- Creating the task fails with an AccessError on the Customer(`partner_id`).
Cause
- The customer field is editable for project sharing users who should not be
allowed to modify it. As a result, `partner_id` is included during task
creation and triggers an access error.
Solution
- Correct the readonly condition on the customer field so unauthorized users
cannot modify it.
task-5075150
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prOdoo now prevents invalid custom One2many relation settings from being saved in Studio and safely handles any existing invalid settings. This keeps the server responsive so users can correct configuration mistakes without triggering a 500 error.
Original PR description
### Current behavior: When a Studio custom One2many field has an invalid relation field (inverse) name, accessing `registry.field_inverses` raises KeyError. On 19.0 this also crashes error-page…
### Current behavior: When a Studio custom One2many field has an invalid relation field (inverse) name, accessing `registry.field_inverses` raises KeyError. On 19.0 this also crashes error-page rendering, leaving the server unusable after closing Studio. On 18.0, it doesn't crash the server. ### Expected behavior: An invalid inverse name must not crash the registry or error handler; the server should stay responsive so the user can fix the field. ### Steps to reproduce: 1. Install sales, project with demo data 2. Create a sale order, use Studio to add a new "Lines" field (e.g. test line) 3. In the sale order, add a product that has Create on Order field (e.g. plumbing services from the demo data) > Confirm 4. Click on the smart button to go to project/task 5. Switch to Studio again, add a related field in the task, point that to Sales Order > test line 6. Activate debug mode, click on More for test line (task) 7. In properties, turn off Read only. Important here: add an invalid key for Relation Field (e.g. 'hehe') 8. Error popup shows key error. Try to close and exit out of Studio mode > Server crashes with 500 Internal Server Error ### Cause of the issue: - When a custom One2many field has an invalid `inverse_name` (set via Studio developer mode), `One2many.setup_inverses` accessed `registry[comodel]._fields[inverse_name]` without checking existence - Building the cached `registry.field_inverses` property then raises an uncaught KeyError and bricks the server with 500 Internal Server Error ### Fix: - When a custom One2many field has an invalid inverse_name (set via Studio developer mode One2many.setup_inverses accessed registry[comodel]._fields[inverse_name] without checking existence - Building the cached registry.field_inverse property then raises an uncaught KeyError and bricks the server with 500 Internal Server Error opw-6479178
Fixed an issue that could block planning shift creation when an employee's approved time off included a public holiday. This keeps scheduling usable for flexible-working employees and avoids an error during planning calendar calculations.
Original PR description
… leaves # **Steps to Reproduce** 1. Create a fresh Odoo 19 database with Time Off, Employees, Payroll, and Planning installed. 2. Create an employee with a Flexible Working Schedule. 3. Go to **Time…
… leaves
# **Steps to Reproduce**
1. Create a fresh Odoo 19 database with Time Off, Employees, Payroll, and Planning installed.
2. Create an employee with a Flexible Working Schedule.
3. Go to **Time Off → Configuration → Time Off Types** and create:
* Name: Test Hourly Time Off
* Request Unit: Hours
4. Go to **Time Off → Configuration → Public Holidays** and create:
* Name: Test Public Holiday
* Date: 14 August 2026
* Time Type: Test Hourly Time Off
5. Create an employee Time Off using Test Hourly Time Off, covering the public holiday:
* 27 July 2026 → 30 August 2026
* Approve the Time Off.
6. Go to Planning → Schedule by Role.
7. Create a new planning shift for this employee.
# **Issue**
During the Planning Gantt computation, *`_get_flexible_resource_valid_work_intervals()`* calls *`_format_leave()`*. When the employee's Time Off includes the Public Holiday, multiple `resource.calendar.leaves` records are merged into the same interval. *`_format_leave()`* expects a single record, resulting in an **Expected singleton** error in `hr_holidays/models/resource.py`.
# **Solution**
```python
leave_record = leave[2].filtered('holiday_id')
```
This ensures that only the employee's actual `hr.leave` record is selected when a public holiday is included in the same interval. As a result, `date_from` and `date_to` are accessed on the correct single record, preventing the `Expected singleton` error while keeping the standard public holiday processing unchanged.
[Runbot v19.0 video](https://drive.google.com/file/d/1qg2VqtoxhBV3dIjxW05oQXaxKU-S9cv6/view?usp=sharing)
opw- 6478752Saudi Arabia and UAE companies will now use GCC tax invoice and POS receipt layouts only when they have a VAT number. This helps prevent VAT-unregistered businesses from issuing tax-style documents that may not be legally appropriate, while other GCC countries remain unchanged.
Original PR description
…tempalts for VAT unregistered Companies In Saudi Arabia (ZATCA), a business's legal authority to issue tax documents is dictated by annual revenue thresholds: registration is mandatory above SAR…
…tempalts for VAT unregistered Companies In Saudi Arabia (ZATCA), a business's legal authority to issue tax documents is dictated by annual revenue thresholds: registration is mandatory above SAR 375,000, voluntary between SAR 187,500 and SAR 375,000, and exempt below SAR 187,500. Per Article 53 of the KSA VAT Implementing Regulations, only a registered "Taxable Person" may issue a Tax Invoice (B2B) or a Simplified Tax Invoice (B2C). In the UAE, the Federal Tax Authority (FTA) imposes the same registration prerequisite. Previously the bilingual GCC tax layout was chosen purely from the company's country, on both the invoice report and the POS receipt. For SA and AE, we now only use the GCC report templates when the company actually has a VAT number; otherwise we fall back to the standard report template. The remaining GCC countries (BH, OM, QA, KW) are unaffected. The POS receipt flag `is_gcc_country` is renamed to `use_gcc_report` to enhance code readability task-6326221 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 Forward-Port-Of: odoo/odoo#286509 Forward-Port-Of: odoo/odoo#279377
Kenyan eTIMS reporting now excludes taxes that do not have a KRA tax code from the reported tax-inclusive total. This prevents levies owed to other authorities, such as tourism levies, from being incorrectly reported to the Kenya Revenue Authority.
Original PR description
Issue: Non KRA taxes are sent in eTIMS tax total Steps to reproduce: - With l10n_ke_edi_oscu - Create a 2% Tax named CTL with no KRA Tax Code - Create an invoice - Add a line with 16% and CTL taxes - Confirm - Send to eTIMS Current behavior: - eTIMS JSON (unaccessible) is created with 'totAmt' (total_tax_included) including non-KRA Taxes Expected Behavior! - eTIMS JSON 'totAmt' doesn't incldue non-KRA Taxes Note: eTIMS is used to report to Tax Autority, however some "taxes" (e.g. Tourism levy) are paid to other authorities (e.g. Tourism Fund) and shouldn't be included in eTIMS. opw-6456478 Forward-Port-Of: odoo/enterprise#131577
This fix ensures mandatory Swiss payroll statistics rules remain usable even if users archive related payroll rules. It prevents reporting failures when calculating monthly, yearly, and master data statistics needed for Swiss payroll reporting.
Original PR description
…ndatory for the statistics You are looping on the STATISTICS_RULE_MAPPING, but they can be archived by the user. It will then make impossible to fetch the amount of this section in -> https://github.com/odoo/enterprise/blob/19.0/l10n_ch_hr_payroll/models/l10n_ch_employee_monthly_values.py#L607 I am currently asking myself one point: - we could either update the code to not look everytime at each section, but I currently don't know if those sections are mandatory - it could also be added an "active" True into the data, so updating the module will reset the states of the records - last solution, update the user's rights to disallow to set them as active False Hello @jugj-odoo , your review is welcome opw-5414075