Daily updates from Odoo
Thursday, July 16, 2026
22 changes · master
Enhancements to existing features
The Sendcloud delivery setting previously called "Use Batch Shipping" is now named "Use Multicollo". This aligns the wording in Odoo with Sendcloud terminology, reducing customer confusion without changing the underlying functionality.
Original PR description
In order to avoid confusion for the customer, "Use Batch Shipping" was renamed to "Use Multicollo".This way it is consistent with the terminology used by Sendcloud. task-6048477 Forward-Port-Of: odoo/enterprise#123195 Forward-Port-Of: odoo/enterprise#122133
Timesheet Assistant suggestions can now be selected more quickly by dragging over them while holding the mouse button. This also prevents Ctrl-clicking a suggestion from accidentally opening a new Odoo page, making bulk actions smoother and less disruptive.
Original PR description
Currently when the user uses ctrl + click on a suggestion, a new odoo page is opened. This is an undesirable side effect and it is removed in this commit. Also, users have to manually click on each suggestion when they want to remove them in batch, or create one timesheet for a bunch of suggestion. This commit lets user hover over suggestion with the mouse button pressed to select them. task-6385047
Updates improve the AI-powered website builder workflow, including its configuration data, builder integration, and supporting utilities. This should help users create or adjust website content more smoothly with AI assistance, though the change appears to be work in progress.
The settings pages for Planning and Field Service have been reorganized into clearer sections such as Planning, Operations, Sales & Billing, and Analytics. This makes configuration easier for users as the number of available options has grown, helping teams find the right setup choices faster.
Original PR description
Reorganize the settings view for Planning and Field Service into intuitive sub-categories (Planning, Operations, Sales & Billing, Analytics). As the available options have grown significantly, this restructuring guides the user more effectively through the configuration steps. - Planning: Employee Unavailabilities, Project Planning, Recurring Shifts - Operations: Field Service, Stock by Vehicle, Worksheets, Equipment, Customer Report, Geolocation - Sales & Billing: Billing, Website Form, Products, Quotations, Travel Fees - Analytics: Customer Ratings task:6172495
Accounting users can now open the related budget directly from an account move form using a new smart button. This saves time when reviewing financial entries and makes it easier to trace how entries affect budgets through analytic lines.
Original PR description
On the account move form view, add a smart button that redirects to the linked budget (linked through the analytic lines) task-6307932
Resolved issues and error corrections
Live field service maps no longer recalculate routes when the current user's position changes, because those routes are based on worker pins instead. This reduces unnecessary processing and helps preserve routing service tokens without changing the visible route behavior.
Original PR description
The routing fetching in `updateUserPosition` of the `MapModel` should not be triggered for the live map. Right now, when changing user position, the routes are fetched again. However, for the live map, this should have no effect on routes, as they start from the user pins instead of the current user's position. This will avoid computing all over routes and preserve tokens. task-6307279 Forward-Port-Of: odoo/enterprise#123536 Forward-Port-Of: odoo/enterprise#123294
This fix restores supported flows where portal users need to archive or unarchive documents when the system explicitly grants elevated permission. It also prevents errors in cases where no documents are present, making document handling more reliable.
Original PR description
In #116886, we fixed the blocking of portal users to (un)archive documents, but it appears that some flows did rely on it and we were lacking a way of supporting it. Task-6205627 Forward-Port-Of: odoo/enterprise#123171 Forward-Port-Of: odoo/enterprise#123015
Subscription products that also allow one-time purchases now display the original price with a strikethrough next to the Buy Once price. This makes discounts or price comparisons clearer for shoppers and helps avoid confusion on product pages.
Original PR description
Version - saas-19.1 Steps to reproduce: - Enable 'Accept One Time Sale' on a subscription product - Open the product page on the website Issue: For subscription products with one time sale enabled, the original price was not shown as a strikethrough next to the Buy Once price. Fix: - Captured and exposed the original price to the template before it gets overwritten during subscription price processing - Added the missing strikethrough element to the Buy Once section of the product page Task ID - 6260207 Forward-Port-Of: odoo/enterprise#123977 Forward-Port-Of: odoo/enterprise#119488
Luxembourg payroll now uses the correct official salary index values for contracts starting from May 2025 and June 2026. This prevents incorrect contract signature index values and helps ensure related payroll calculations reflect current legal parameters.
Original PR description
## Issue When creating or browsing an existing contract in a Luxembourgish company, the current index shown is the one from September 2023 (which was up-to-date until Mai 2025). If the contract is…
## Issue
When creating or browsing an existing contract in a Luxembourgish company, the current index shown is the one from September 2023 (which was up-to-date until Mai 2025). If the contract is created after Mai 2025, the "Index on Contract Signature" field is also wrong.
## Steps to reproduce
1. Install *Luxembourg - Payroll* (`l10n_lu_hr_payroll`)
2. Using a Luxembourgish company, create a new contract for an employee
- *Contract Start Date*: Any date after 05/01/2025 (Mai 1st 2025)
3. __The *Index on Contract Signature* shows `944.43`, which is the index from September 2023. It does not match with the most recent indices.__
## Cause
The two most recent indices are missing from the [`rule_parameter_lu_index`](https://github.com/odoo/enterprise/blob/885edbc270a86ab76e0a6eff4acb5767c0fe29d1/l10n_lu_hr_payroll/data/rule_parameters/general_rules_data.xml#L4-L58). These indices are:
- `968.04` from 2025-05-01 (Mai 1st 2025)
- `992.24` from 2026-06-01 (June 1st 2026)
These values were taken from [here](https://salary.lu/en/tools/social-parameters/indexation-of-salaries) and double-checked [here](https://lustat.statec.lu/?lc=en&tm=DF_C1201&pg=0&snb=1).
## Tests modification
Updating the latest index had an impact on the tests from the `l10n_lu_hr_payroll_account` (testing the salary rules). In fact, the current index (`l10n_lu_current_index`) is [used to compute the indexed wage](https://github.com/odoo/enterprise/blob/7892d035ddb968d67a3e8da0daf91292bd8fb499/l10n_lu_hr_payroll/models/hr_contract.py#L24-L33) (`l10n_lu_indexed_wage`), which is then used to compute most lines in the payslip (e.g., the `WAGE_SUPPLEMENT_70`).
https://github.com/odoo/enterprise/blob/7892d035ddb968d67a3e8da0daf91292bd8fb499/l10n_lu_hr_payroll/data/salary_rules/hr_salary_rule_data.xml#L70-L74
Since the latest index is not the same as when those tests were written, the values are not correct anymore. To prevent this, time was frozen to 01/01/2024 to use the expected index (944.43, from September 2023).
opw-6330790
Forward-Port-Of: odoo/enterprise#122147This fixes incorrect invoice statuses for field service sales orders that include zero-price lines. Existing zero-price quotation lines can now remain invoiceable, while zero-price materials added during field service work are correctly treated as included, preventing orders from staying incorrectly marked as still to invoice.
Original PR description
## [FIX] industry_fsm_sale: fix invoice status for zero price lines ### Issue: Without Anglo-Saxon accounting, the system incorrectly sets the invoice status of all zero price sales order lines…
## [FIX] industry_fsm_sale: fix invoice status for zero price lines
### Issue:
Without Anglo-Saxon accounting, the system incorrectly sets the invoice status of all zero price sales order lines linked to an FSM task to 'no'
This includes pre-existing lines that were already present on the quotation before confirmation. If a zero price line is pre-existing, it should follow the standard flow and be marked as 'to invoice'
Only lines added as materials from the field service task at a zero price should be considered included in the price and marked as 'no'
### Cause:
In `SaleOrderLine._compute_invoice_status`, the system forced `invoice_status = 'no'` for all zero price lines when Anglo-Saxon accounting was disabled
It failed to check if the lines were actually materials added via the FSM task or original quotation lines
### Fix:
A new `material_sale_lines` compute field is added to `project.task` to distinctly isolate and track lines added specifically as materials during the task execution
In `SaleOrderLine._compute_invoice_status`, the logic is updated to ensure that only zero price lines identified as FSM materials are set to 'no' when Anglo-Saxon accounting is disabled
Other pre-existing zero price lines properly remain as 'to invoice'
### Steps to reproduce:
- Install `industry_fsm_sale`
- In Settings > Users & Companies > Companies > Any company, add the field Anglo-Saxon using Studio (In 19.0+)
- Disable Anglo-Saxon on the current company
- Create a product Service (Fixed Price, that create a task in a Field Service Project)
- Create and confirm a Sale Order with the Service and one product with unit price 0
Before the fix, the pre-existing SO line with price 0 is
incorrectly considered as not to invoice ('no')
opw-6169802
------------------------------
## [FIX] industry_fsm_sale: sync sale order invoice status
### Issue:
When a sale order contains FSM material lines with a price of zero and Anglo-Saxon accounting is disabled, the overall sale order invoice status remains stuck on 'to invoice' even after all other invoiceable lines are fully invoiced
### Cause:
The standard `SaleOrder._compute_invoice_status` does not handle FSM business rules regarding zero price material lines that are marked as `invoice_status = 'no'`
Because these lines are never technically invoiced, the global order status fails to transition to 'invoiced'
### Fix:
Override `SaleOrder._compute_invoice_status` to recompute the status of confirmed orders linked to FSM tasks
We use the task's `material_sale_lines` to filter out material components
If all lines on the order are either 'invoiced' or are zero price FSM material lines with Anglo-Saxon disabled, the global sale order status is forced to 'invoiced'
### Steps to reproduce:
- Install `industry_fsm_sale`
- In Settings > Users & Companies > Companies > Any company, add the field Anglo-Saxon using Studio (In 19.0+)
- Disable Anglo-Saxon on the current company
- Create a product Service (Fixed Price, that create a task in a Field Service Project)
- Create and confirm a Sale Order with the Service and one product with unit price 0
- Add a Product from the Task (Use a price 0 product, or set the unit price to 0 on the SO)
- Create the invoice for the Sale Order
Before the fix, the Service and Pre-existing product are invoiced, but in the Other Info Tab of the SO, the status stays on 'To Invoice' instead of 'Fully Invoiced'
opw-6169802
Forward-Port-Of: odoo/enterprise#124190
Forward-Port-Of: odoo/enterprise#119238The timesheet activity assistant no longer shows an empty Unmatched section when all items in that section are filtered out as away-from-keyboard events. This keeps the assistant cleaner and avoids confusing users with a header that has no visible content.
Original PR description
The Unmatched group's header renders even when its only entries are afk events, since those are filtered out at display time but still counted when checking if the group has content. With this PR, we first check if a group has visible content before displaying the header Task-6348666 Forward-Port-Of: odoo/enterprise#123286 Forward-Port-Of: odoo/enterprise#122858
Payslip creation now correctly includes employees assigned to branch companies when working from a parent company. This helps Belgian payroll teams select the right employees without manual workarounds or missing staff from payroll processing.
Original PR description
Bug: employees registered on branch companies don't appear in the
employee_id field when creating a payslip from the parent company.
Reason: the domain used ('company_id', '=', company_id) which only
matches the exact company, not its children.
Solution: replaced '=' with 'child_of' to include all descendant
companies in the hierarchy.
task - 6299634
Forward-Port-Of: odoo/enterprise#122381
Forward-Port-Of: odoo/enterprise#120974This fixes several Hong Kong IRD payroll report details found during certification testing. Reports now better match IRD requirements for amendment grouping, assessment year calculation, income totals, and required departure information.
Original PR description
As we now have complete support for IRD reports (in master), we started to try to get our system certified by the IRD. A first submission highlighted a few issues that we are now fixing. - There is only two types of XML. Original and 'adjustment'. The adjustment XML mix all three adjustment type in one file, which isn't what we did until now. - In 56E, RTN_ASS_YR must be based on the contract start date and the tax year - In 56F, RTN_ASS_YR must be based on the contract end date and the tax year. Also, the reason of departure MUST be set if departure type is 'other' - In 56G, RTN_ASS_YR must be based on the contract end date and the tax year. task-6309992
Payroll rule parameters are now safely copied before use, preventing one process from accidentally altering cached values used by another. This reduces the risk of hard-to-trace payroll calculation issues caused by shared internal data.
Original PR description
Cached functions with `@ormcache` should not return immutable values, yet `_get_parameter_from_code()` could return dicts/sets/lists/etc. It could lead to very obscure bugs such as: ```python def…
Cached functions with `@ormcache` should not return immutable values, yet `_get_parameter_from_code()` could return dicts/sets/lists/etc.
It could lead to very obscure bugs such as:
```python
def some_innocent_code():
category_dict = self.env["hr.rule.parameter"]._get_parameter_from_code('l10n_be_work_entry_categories')
incapacity_codes = category_dict['partial_incapacity']
incapacity_codes |= category_dict['total_incapacity']
# ... then use incapacity_codes
def print_rule_param():
print(self.env["hr.rule.parameter"]._get_parameter_from_code('l10n_be_work_entry_categories')['partial_incapacity'])
print_rule_param() # OrderedSet(['LEAVE281'])
some_innocent_code()
print_rule_param() # OrderedSet(['LEAVE281', 'LEAVE264', 'LEAVE266', 'LEAVE217', 'LEAVE218', 'LEAVE219', 'MEDIC01'])
```
The solution was to either deepcopy the returned value each time, or to change all the rule parameters to their frozen equivalent. Since we don't have access to frozen objects in rule parameters's xml definitions, we opted for the deepcopy approach.
task-6329380
Forward-Port-Of: odoo/enterprise#124134
Forward-Port-Of: odoo/enterprise#123058Invoice tax recalculations through Avatax now refresh the pre-tax base amount each time, instead of keeping an older cached value. This helps ensure invoice line totals stay consistent with the latest tax calculation returned by Avatax.
Original PR description
Previously, when recomputing taxes via Avatax, `manual_tax_amounts` was cleared and repopulated from the fresh API response, but `manual_total_excluded_currency` was only set if it was None. This meant that after the first Avatax call, the pre-tax base amount was never refreshed from subsequent API responses, even though the tax amounts were. This inconsistency could cause stale pre-tax base amounts to persist on invoice lines across recomputations, even when Avatax returned a different base amount. By resetting `manual_total_excluded_currency` to `None` at the start of each recomputation, mirroring what is already done for `manual_tax_amounts`, we ensure that the pre-tax base is always taken from the current Avatax response rather than a previously cached value. opw-6235597 Forward-Port-Of: odoo/enterprise#124152 Forward-Port-Of: odoo/enterprise#123802
Users with the Invoicing & Banks accounting role can now open the Accounting app without encountering an access error. The change restores a missing read permission needed to load accounting screens, bringing behavior back in line with previous versions.
Original PR description
**Description of the issue/feature this PR addresses:** Users in the 'Accounting / Invoicing & Banks' group were encountering an access error when attempting to open the Accounting app. This was…
**Description of the issue/feature this PR addresses:** Users in the 'Accounting / Invoicing & Banks' group were encountering an access error when attempting to open the Accounting app. This was caused by a missing read access right for the `account.return.type` model that is present in previous versions (e.g. saas-19.3). Without this permission, the basic accounting group (`account.group_account_basic`) is blocked from loading the necessary accounting views. This commit restores the `access_account_return_type_basic` rule, granting read access to the basic accounting group so they can access the app without errors. opw-6377912 **Steps to reproduce:** - Sign in as Mitchell Admin - Settings > Users & Companies > Users > Mitchell Admin > Access Rights > Accounting > Accounting > change to ‘Invoicing & Banks’ - Attempt to access the Accounting app > observe Access Error **Current behavior before PR:** - Users in the 'Accounting / Invoicing & Banks' group are unable to access the Accounting app due to Access Error **Desired behavior after PR is merged:** - Users in the 'Accounting / Invoicing & Banks' are able to access the Accounting app Forward-Port-Of: odoo/enterprise#124174
A payroll correction action now applies to all relevant payslips when used from the popup, regardless of which option is selected. This helps payroll teams avoid missed payslips and reduces the need for manual follow-up when processing corrections in batches.
Original PR description
**What:** - Corrected the method logic 'action_keep_wrong_version' to make sure that it works for both option in the view popup. task-6356957 Forward-Port-Of: odoo/enterprise#124089 Forward-Port-Of: odoo/enterprise#122625
This fix prevents an error when users remove the start or end date from a Field Service planning shift. The system now checks that required date values are present before recalculating break time, making shift editing more reliable.
Original PR description
before: when removing the start and end date of a shift, a trace back happens in the `_onchange_break_time` cause: it depends on the start and end date values, so it breaks when they are falsy after: apply a guard to the `_onchange_break_time` function to check on those fields to avoid breaking it --- task-6361418 Forward-Port-Of: odoo/enterprise#123926 Forward-Port-Of: odoo/enterprise#123273
This change adjusts internal automated tests for Field Service planning with sales and timesheets so they run at the correct stage and avoid false warnings. It helps keep quality checks stable without changing day-to-day product behavior for users.
Original PR description
Before this commit, the `TestFsmFlowSaleAtInstall.test_fsm_flow` test throws a warning because of chart template in accounting, the reason is because all tests using accounting test class have to be executed in post_install to avoid having unexpected issue. This commit moves the test in post_install and skip the test is `planning_field_service_sale_stock` module is installed because the behavior tested is altered when that module is installed. runbot-error-240998 Forward-Port-Of: odoo/enterprise#123357 Forward-Port-Of: odoo/enterprise#122306
The Documents search panel was updated to stay compatible with a recent platform change. This prevents crashes when users interact with sortable items in the Documents search panel, improving reliability without changing business workflows.
Original PR description
The web `SearchPanel` root is migrated from the OWL2 compat `useRef` to an OWL3 `signal.ref()` (a function). `DocumentsSearchPanel` passes the inherited `this.root` to `useNestedSortable`, whose `draggable_hook_builder` validates `ref` as an object and reads `ref.el` — so the raw signal function crashed with:
```
Error in hook useNestedSortable: invalid type for property "ref" in parameters: expected { object } and got function.
```
Fix: pass an object ref whose `el` getter reads the signal, keeping `.el` reactive.
Companion of odoo/odoo#272029.This update fixes an issue that could prevent users from confirming all signatures in the Sign app. It keeps the signature dialog aligned with a related platform change so the signing flow continues to work reliably.
Original PR description
Companion PR to odoo/odoo#274208. That PR converts `NameAndSignature.signatureRef` from an OWL2 compat `useRef` (`.el` accessor) to a `signal.ref` (callable). The `SignNameAndSignature` subclass here still read `this.signatureRef.el` inside `updateFrame`, which became `undefined` and threw "Cannot read properties of undefined (reading 'width')" on the "Sign all" confirm. Read the canvas element via `this.signatureRef()` instead. Companion PR: odoo/odoo#274208
Code cleanup and technical improvements
Several Point of Sale localization and payment screens were updated to stay compatible with Odoo's next web interface framework. This is an internal modernization that helps maintain stability during the Owl 3 migration without changing day-to-day business workflows.
Original PR description
`* = ["l10n_de_pos_cert", "l10n_mx_edi_pos", "l10n_pe_edi_pos", "pos_tyro"]` As part of the migration from `owl 2` to `owl 3`, this commit replaces uses of `t-custom-model` with `t-model` or `t-model.proxy`. Community: https://github.com/odoo/odoo/pull/271520