Daily updates from Odoo
Monday, August 10, 2026
14 changes · 17.0
Enhancements to existing features
The point of sale preparation display now retrieves pending orders much faster, especially when many orders are shown. This reduces waiting time for staff and helps busy locations keep their kitchen or preparation screens responsive.
Original PR description
Improve the execution time of _get_stageless_orders_in_display by replacing the OR condition with IN(subquery) by using UNION ALL to improve query performance. Benchmarks: | display orders count | Time Before | Time After | |-------------------------------|---------------------|------------------| | 1k | 84 s | 0.416 s | | 500 | 37.6 s | 0.150 s | | 250 | 19.4 s | 0.110 s | | 100 | 8 s | 0.068 s | opw-6420949
Belgian payroll now includes updated fiscal employment bonus rates scheduled from August 2026 and 2028. This helps payroll calculations stay aligned with upcoming legal changes for low-wage workers and general fiscal bonus treatment.
Original PR description
Starting from August 2026: - The increased fiscal rate for low-wage workers (Volet B) rises from 52.54% to 63% (and to 72% in 2028). - The general fiscal rate (Volet A) rises from 33.14% to 35% starting in 2028. This adds new rule parameters for the fiscal rates and updates computation logic to apply these rates Task-6438319
Resolved issues and error corrections
The Chilean electronic invoicing module now recognizes five new response codes introduced by SII. This prevents supplier electronic tax documents from getting stuck during claim or acceptance status processing after the SII regulatory update.
Original PR description
**Before this PR:** After the implementation of Resolution 161 of November 13th 2025, SII responses included keys not supported by the current l10n_cl_edi implementation. This resulted in supplier DTEs not being processed as they were before the change, because the five new keys were not found in Odoo's current `l10n_cl_claim` field, causing that the documents with these responses, were kept in a loop not solved. **After this PR:** The five new values from the resolution, along with their translations, were added to the selector field, fixing the process flow. **SII Reference:** https://www.sii.cl/normativa_legislacion/resoluciones/2025/reso161.pdf (see Event Code, page 5)
This fix prevents one Dutch Digipoort tax return record with missing accounting information from stopping status updates for all other records. The system now handles the missing closing entry gracefully, improving reliability for Dutch tax reporting workflows.
Original PR description
The `l10n_nl_reports_sbr_status_info` contains the `l10n_nl_reports_sbr.status.service` class. The class is responsible for fetching the status of sent Digipoort tax returns. The status is then posted as a chatter message to the tax return's closing entry. Issues can arise when one of the status service records is, for whatever reason, missing a closing entry. In such case, the message cannot be posted, resulting in an exception being raised. Since the records are processed in a loop without a try-catch, this causes the whole action to fail. This can lead to one broken record effectively shutting down the whole module's functionality. This PR adds some if-else checks to gracefully handle the case where the closing entry is missing. Related tickets: opw-5901446 and opw-6410082
The selection options for l10n_id_coretax_add_info_07/08 and l10n_id_coretax_facility_info_07 were swapped: the "additional information" fields showed facility stamp text and vice versa. Also add the UoM codes and new kode faktur 07 additional info/facility stamp options published by DJP on 2026-01-26. task-6434742
Original PR description
The selection options for l10n_id_coretax_add_info_07/08 and l10n_id_coretax_facility_info_07 were swapped: the "additional information" fields showed facility stamp text and vice versa. Also add the UoM codes and new kode faktur 07 additional info/facility stamp options published by DJP on 2026-01-26. task-6434742
Steps to Reproduce the Error (Odoo SaaS 19.2): 1. Install l10n_gcc_invoice localization & Accounting 2. Activate Arabic language (ar_001) and add Default Terms and Conditions in Settings > Configuration > Customer Invoices > Default Terms and Conditions 3. Create invoice with ar_001 partner 4. Confirm the invoice 5. Try to create credit note → Error: KeyError: 'en_US' Root Cause: The _load_narration_translation() workaround reads raw invoice_terms from DB and injects the entire JSONB di
Original PR description
Steps to Reproduce the Error (Odoo SaaS 19.2): 1. Install l10n_gcc_invoice localization & Accounting 2. Activate Arabic language (ar_001) and add Default Terms and Conditions in Settings >…
Steps to Reproduce the Error (Odoo SaaS 19.2):
1. Install l10n_gcc_invoice localization & Accounting
2. Activate Arabic language (ar_001) and add Default Terms and Conditions in Settings > Configuration > Customer Invoices > Default Terms and Conditions
3. Create invoice with ar_001 partner
4. Confirm the invoice
5. Try to create credit note → Error: KeyError: 'en_US'
Root Cause:
The _load_narration_translation() workaround reads raw invoice_terms from DB and injects the entire JSONB dict directly into cache, bypassing ORM field conversion. When Odoo 19.2's improved ORM conversion runs, it creates nested JSON in narration instead of a flat structure.
Timeline:
- bedf1cb66fbb: Workaround added to prevent T&C duplication in preview
- 75f050b9650d: Root cause fixed in report template (conditional display) → Made _load_narration_translation() redundant
- 4e4156536bc9: Odoo 19.2 improved ORM conversion → Now conflicts with the redundant workaround, causing nested JSON
How It Breaks:
1. Invoice creation: _load_narration_translation() injects raw dict into cache
2. ORM writes: nested JSON stored: {ar_001: {en_US: ., ar_001: Arabic}}
3. Credit note creation: copy_translations() expects flat structure → Crashes: KeyError: 'en_US'
Why It's Safe to Remove:
Report template already prevents T&C duplication (commit 75f050b9650d). Removing the workaround restores proper credit note creation without breaking T&C display.
Changes:
- Remove moves._load_narration_translation() in create()
- Remove out self.filtered('id')._load_narration_translation() in _compute_narration()
opw : 6284943
Forward-Port-Of: odoo/odoo#271037#### Description of the issue: Activity filters using context_today() bucket against the UTC date instead of the user's local date, off by one for part of the day. Partial revert of #265250 (e048bb5), scoped to PyDate: UTC getters are right for PyDateTime, wrong for a calendar day. #### Current behavior before PR: A Perth (UTC+8) user finds an activity due today under "Future Activities" from 00:00 to 08:00 local, while the chatter labels the same activity "Today". #### Desired behavior
Original PR description
#### Description of the issue: Activity filters using context_today() bucket against the UTC date instead of the user's local date, off by one for part of the day. Partial revert of #265250 (e048bb5), scoped to PyDate: UTC getters are right for PyDateTime, wrong for a calendar day. #### Current behavior before PR: A Perth (UTC+8) user finds an activity due today under "Future Activities" from 00:00 to 08:00 local, while the chatter labels the same activity "Today". #### Desired behavior after PR is merged: context_today(), today and current_date return the user's local calendar day, so filters agree with the chatter. PyDateTime and PyTime keep the UTC getters; now and time.strftime() are unchanged. opw-6415985 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
An old refactor left some data around that are in conflict with other records for the same model. 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
Original PR description
An old refactor left some data around that are in conflict with other records for the same model. 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
The right value often comes from the user and the search implementation may not handle 'any' properly, however 'in' is nearly always implemented. For most cases, transform 'any' into a 'in' before calling Field.search. task-6446206 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
The right value often comes from the user and the search implementation may not handle 'any' properly, however 'in' is nearly always implemented. For most cases, transform 'any' into a 'in' before calling Field.search. task-6446206 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
l10n_fr_pdp's settings view inherits account_peppol and uses peppol_use_parent_company in `invisible`s. The node for that field is provided by account_peppol, but it was only added to account_peppol settings view in 0ab1e0323894. On a database whose account_peppol was not updated after this commit, installing l10n_fr_pdp does not upgrade account_peppol, so this invisible references a field that doesn't exist in the view, so tb at install ``` Error while validating view near: <form string=
Original PR description
l10n_fr_pdp's settings view inherits account_peppol and uses peppol_use_parent_company in `invisible`s. The node for that field is provided by account_peppol, but it was only added to account_peppol…
l10n_fr_pdp's settings view inherits account_peppol and uses peppol_use_parent_company in `invisible`s. The node for that field is provided by account_peppol, but it was only added to account_peppol settings view in 0ab1e0323894. On a database whose account_peppol was not updated after this commit, installing l10n_fr_pdp does not upgrade account_peppol, so this invisible references a field that doesn't exist in the view, so tb at install
```
Error while validating view near:
<form string="Settings" class="oe_form_configuration" js_class="base_settings">
<field name="is_root_company" invisible="1"/>
<app data-string="General Settings" string="General Settings" name="general_settings" logo="/base/static/description/settings.png">
Field 'peppol_use_parent_company' used in modifier 'invisible' (peppol_use_parent_company or account_peppol_proxy_state not in ('sender', 'pending', 'active')) must be present in view but is missing.
View error context:
{'file': '/home/odoo/src/odoo/17.0/addons/l10n_fr_pdp/views/res_config_settings_views.xml',
'line': 1,
'name': 'res.config.settings.view.form.inherit.proxy.user',
'view': ir.ui.view(2640,),
'view.model': 'res.config.settings',
'view.parent': ir.ui.view(1604,),
'xmlid': 'res_config_settings_view_form'}
```
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-prWe still have cases of people being confused by the fact that they send their invoices, reset it to draft, change something, then re-sending. Of course, the re-sending does not send on peppol, as it's already sent. It's more confusing than anything else. Prevent it if they're sent and not in error. task-6459869 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
We still have cases of people being confused by the fact that they send their invoices, reset it to draft, change something, then re-sending. Of course, the re-sending does not send on peppol, as it's already sent. It's more confusing than anything else. Prevent it if they're sent and not in error. task-6459869 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Description of the issue/feature this PR addresses: Odoo supports WebP image fields, but `base_import` validates remote images with `PIL.Image.open()`. Odoo intentionally leaves Pillow's WebP decoder unloaded, so a valid WebP URL is rejected as an unidentified image. Current behavior before PR: Importing a valid WebP image URL fails with `cannot identify image file`. Oversized and unsupported WebP files are also rejected by Pillow before the import-specific size policy can be applied. Desire
Original PR description
Description of the issue/feature this PR addresses: Odoo supports WebP image fields, but `base_import` validates remote images with `PIL.Image.open()`. Odoo intentionally leaves Pillow's WebP decoder unloaded, so a valid WebP URL is rejected as an unidentified image. Current behavior before PR: Importing a valid WebP image URL fails with `cannot identify image file`. Oversized and unsupported WebP files are also rejected by Pillow before the import-specific size policy can be applied. Desired behavior after PR is merged: Use Odoo's existing WebP header parser for dimension validation. Valid WebP URLs import unchanged, unsupported WebP remains rejected, and the existing 42-million-pixel import limit remains enforced. Tests cover valid, unsupported, and oversized WebP URL payloads. The complete `test_base_import` suite passes (56 tests, 0 failures/errors). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Documentation and clarification updates
Description of the issue/feature this PR addresses: Signing the Odoo Individual Contributor License Agreement v1.0. Name: Alejandro Martínez GitHub login: alexmbar Email: alexmbar891@gmail.com Country: México Current behavior before PR: I have no CLA signature on file, so my pending l10n_mx contributions (#264576, #264580, #264582, #264583) fail the legal/cla check and cannot be merged. Desired behavior after PR is merged: doc/cla/individual/alexmbar.md is present and the legal/
Original PR description
Description of the issue/feature this PR addresses: Signing the Odoo Individual Contributor License Agreement v1.0. Name: Alejandro Martínez GitHub login: alexmbar Email: alexmbar891@gmail.com Country: México Current behavior before PR: I have no CLA signature on file, so my pending l10n_mx contributions (#264576, #264580, #264582, #264583) fail the legal/cla check and cannot be merged. Desired behavior after PR is merged: doc/cla/individual/alexmbar.md is present and the legal/cla check passes for my contributions. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Miscellaneous changes
**Problem** Opening a location applies the default filter `qty_available > 0 | virtual_available < 0`. Both fields are computed and non-stored, so each leaf goes through `_search_product_quantity`, which ran `search([])` and evaluated the operator in Python over the whole catalog: - `_compute_quantities_dict` `_read_group`s quants **and** incoming/outgoing moves, even when the searched field only needs quants, each scoped with `product_id IN (all_ids)`. - `_compute_quantities` th
Original PR description
**Problem** Opening a location applies the default filter `qty_available > 0 | virtual_available < 0`. Both fields are computed and non-stored, so each leaf goes through `_search_product_quantity`,…
**Problem**
Opening a location applies the default filter `qty_available > 0 | virtual_available < 0`.
Both fields are computed and non-stored, so each leaf goes through
`_search_product_quantity`, which ran `search([])` and evaluated the operator in
Python over the whole catalog:
- `_compute_quantities_dict` `_read_group`s quants **and** incoming/outgoing moves,
even when the searched field only needs quants, each scoped with
`product_id IN (all_ids)`.
- `_compute_quantities` then materialises every product through the ORM: it zeroes
five fields on each one and loops calling `.update` per product.
- `filtered_domain` iterates the full recordset to evaluate the operator.
Nothing is queried per record, but every step scales with the *total* number of
products, so runtime and (batched prefetch) queries grow with the catalog instead of
with the number of products that actually have stock.
**Solution**
Aggregate the underlying quants/moves once and evaluate the operator per product on
plain dicts:
- Only query what the field needs (`need_quant`/`need_in`/`need_out`); a search on
`qty_available` no longer touches moves.
- No `product_id IN (...)`: the `GROUP BY` only returns products that actually have
quants/moves, bounding the work by stock rather than by catalog size.
- Products with neither quant nor move have an implicit value of 0 and are never
loaded: when 0 satisfies the operator the result is returned as
`id not in <aggregated products that failed>`, otherwise as `id in <matches>`.
- `_compute_quantities` is never called, so no full-catalog ORM materialisation.
The context keys that scope or time-shift the quantity (`lot_id`, `owner_id`,
`package_id`, `from_date`, `to_date`) are applied to the aggregation domains exactly
as `_compute_quantities_dict` does. Like that method's raw aggregates, per-UoM
rounding is ignored, and — as the search already did — kit BoMs are not expanded.
Pre-fix:
| Unique products in location | Search Domain | (Moves=Quants) / Product | Run time | Queries |
|---|---|---|---|---|
| 1,000 | [("virtual_available", ">", 0)] | 1 | 0.15 Seconds | 125 |
| 10,000 | [("virtual_available", ">", 0)] | 1 | 1 Second | 420 |
| 100,000 | [("virtual_available", ">", 0)] | 1 | 10.6 Seconds | 3,400 |
| 100,000 | [("virtual_available", ">", 0)] | 10 | 12.0 Seconds | 3,550 |
| 100,000 | [("virtual_available", ">", 0)] | 50 | 14.5 | 3,700 |
| 500,000 | [("virtual_available", ">", 0)] | 1 | 60.4 Seconds | 17,000 |
| 500,000 | [("incoming_qty", ">", 0)] | 1 | 60.5 Seconds | 17,000 |
| 500,000 | ['or', ("incoming_qty", ">", 0), ("virtual_available", ">", 0)] | 1 | 63 Seconds | 17,170 |
Post-fix:
| Unique products in location | Search Domain | (Moves=Quants) / Product | Run time | Queries |
|---|---|---|---|---|
| 1,000 | [("virtual_available", ">", 0)] | 1 | 0.07 Seconds | 100 |
| 10,000 | [("virtual_available", ">", 0)] | 1 | 0.3 Seconds | 110 |
| 100,000 | [("virtual_available", ">", 0)] | 1 | 2.5 Seconds | 150 |
| 100,000 | [("virtual_available", ">", 0)] | 10 | 3.5 Seconds | 150 |
| 100,000 | [("virtual_available", ">", 0)] | 50 | 4.9 Seconds | 150 |
| 500,000 | [("virtual_available", ">", 0)] | 1 | 6.8 Seconds | 250 |
| 500,000 | [("incoming_qty", ">", 0)] | 1 | 3.2 Seconds | 130 |
| 500,000 | ['or', ("incoming_qty", ">", 0), ("virtual_available", ">", 0)] | 1 | 10.3 Seconds | 315 |
opw-6379459