Daily updates from Odoo
Thursday, August 20, 2026
23 changes
2 changes
Enhancements to existing features
Portal task searches now avoid a slow lookup pattern that forced the system to scan all tasks. Users should see much quicker results when searching task lists, especially in large databases.
Original PR description
The portal task list searched titles with
['|', ('name', 'ilike', search), ('id', 'ilike', search)]. Applying ilike to the integer id casts it to text, which no index can serve, and OR-ing that branch with the title prevents the trigram index on name from being used at all, so every search fell back to a full scan of project_task. The id branch is now added only when the term is numeric, as an equality on the primary key, keeping the title lookup on its trigram index.
Benchmark on 200k tasks, PostgreSQL EXPLAIN ANALYZE, selective term matching 5 rows, median of 3 runs:
before Parallel Seq Scan on project_task ~150 ms
after Bitmap Index Scan (name gin_trgm_ops) ~0.5 ms
opw-5478903
Forward-Port-Of: odoo/odoo#278548Accounting validation errors now include more useful details, such as the affected account code or journal entry reference. This makes FEC imports and related accounting troubleshooting faster because users can identify the problematic record more easily.
Original PR description
Some generic validation errors raised by core account models lack enough context to identify which record caused the issue, making FEC imports harder to troubleshoot. This commit improves the two…
Some generic validation errors raised by core account models lack enough context to identify which record caused the issue, making FEC imports harder to troubleshoot. This commit improves the two error cases identified for this use case: - `account.account._check_account_code` now includes the invalid account code in the error message. - `account.move.write` now includes the move name/reference and displays human-readable field labels instead of technical field names when attempting to modify read-only fields on posted entries. Although motivated by FEC import, these are generic core validations, so the improvements are implemented at the source to benefit all callers rather than only the FEC import flow. Enrichment is scoped to the two cases above, other constraints/errors across these models are intentionally left unchanged for now, since editing core error messages more broadly should be done deliberately and on a case-by-case basis, not as a blanket rewrite task-5346068 Forward-Port-Of: odoo/odoo#282840 Forward-Port-Of: odoo/odoo#281746
2 changes
Enhancements to existing features
This change gives Odoo's web test helpers more time to detect expected page updates, matching other existing test waits. It reduces false test failures on slower or heavily loaded machines without affecting successful test speed.
Original PR description
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests…
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests give 10 seconds. 430 call sites in addons reach these three helpers and 29 pass an explicit timeout, so 12 frames is what the other 401 get. The problem is that 12 frames is less than what the client needs on a loaded machine. Measured on "should remove file from html editor if removed from attachment list", on the wait that follows the Full composer button: - 5 to 7 frames on an idle machine; - 11 to 18 frames over 8 runs with the machine at load 10 to 20, 5 of the 8 above the 12 frames the default allows. Those 5 are failing runs, and the same test at load 13 to 29 fails 6 runs out of 6 with the 200 milliseconds, 0 out of 6 with 10 seconds. Note that a longer timeout costs nothing on a green build: the wait ends on the frame the DOM matches, so it only delays the report of a test that was going to fail anyway. Hoot fails the test itself after 5 seconds, 15 in test_js.py, which keeps bounding a wait that never resolves. This commit raises the default to 10 seconds, the delay a tour step already gets in macro.js and the one contains() and expect.waitForSteps already have. https://runbot.odoo.com/odoo/error/946094 Forward-Port-Of: odoo/odoo#282702
Accounting validation errors now include more useful details, such as the affected account code or journal entry reference. This makes FEC import issues easier to identify and resolve, while also improving similar accounting errors in other workflows.
Original PR description
Some generic validation errors raised by core account models lack enough context to identify which record caused the issue, making FEC imports harder to troubleshoot. This commit improves the two…
Some generic validation errors raised by core account models lack enough context to identify which record caused the issue, making FEC imports harder to troubleshoot. This commit improves the two error cases identified for this use case: - `account.account._check_account_code` now includes the invalid account code in the error message. - `account.move.write` now includes the move name/reference and displays human-readable field labels instead of technical field names when attempting to modify read-only fields on posted entries. Although motivated by FEC import, these are generic core validations, so the improvements are implemented at the source to benefit all callers rather than only the FEC import flow. Enrichment is scoped to the two cases above, other constraints/errors across these models are intentionally left unchanged for now, since editing core error messages more broadly should be done deliberately and on a case-by-case basis, not as a blanket rewrite task-5346068 Forward-Port-Of: odoo/odoo#282840 Forward-Port-Of: odoo/odoo#281746
1 change
Enhancements to existing features
Portal task searches now handle task numbers more efficiently while keeping title searches fast. This reduces search delays on large project databases, helping customers find tasks much more quickly.
Original PR description
The portal task list searched titles with
['|', ('name', 'ilike', search), ('id', 'ilike', search)]. Applying ilike to the integer id casts it to text, which no index can serve, and OR-ing that branch with the title prevents the trigram index on name from being used at all, so every search fell back to a full scan of project_task. The id branch is now added only when the term is numeric, as an equality on the primary key, keeping the title lookup on its trigram index.
Benchmark on 200k tasks, PostgreSQL EXPLAIN ANALYZE, selective term matching 5 rows, median of 3 runs:
before Parallel Seq Scan on project_task ~150 ms
after Bitmap Index Scan (name gin_trgm_ops) ~0.5 ms
opw-547890315 changes
Enhancements to existing features
Point of Sale configurations now load the required products for due-payment settlement and UrbanPiper delivery integration more reliably. This helps ensure the right products are available when POS sessions are created or loaded, reducing setup friction and operational errors.
Original PR description
*=pos_urban_piper Following this commit: ==== - Load pos_settle_due products when creating or loading a POS config. - Load urbanPiper products when at least one configuration has urbanPiper enabled task-6171250 Related PR : https://github.com/odoo/odoo/pull/262669
Saudi payroll now splits sick leave at the time leave is created, instead of waiting until payslip calculation. This makes leave handling more consistent across countries and improves payroll accuracy by using standardized work-day calculations and rate-based unpaid entries.
Original PR description
Purpose: move the logic of handling SA sick leave split from payslip computation to automatic split during leave creation - refactored the sick leave split logic from `l10n_be_hr_payroll` and `l10n_lu_hr_payroll` to a standardized logic in `hr_holidays` with the ability to split leaves using calendar days or worked days - added the logic for SA sick leave split during leave creation - changed hardcoded unpaid work entries to use amount rate - adapted the use of the method `_number_of_workdays` to use standard `_get_work_days_data_batch` task-id: 6379346
Brazilian shipments sent through Envia.com can now include the required NF-e access key, helping carriers receive the fiscal information they need. The system automatically looks for the linked invoice from packages, pickings, or the sale order, and if none is ready it lets the warehouse validation finish while prompting the user to link and validate an invoice before sending to the shipper.
Original PR description
In Brazil, if you are using Envia.com or other delivery providers you need to make sure you are sending the NF-e Access Key on shipment generation to make sure that the freight company has the right data. In the normal flow: Sale Order -> Invoice -> Picking, the related invoice is automatically attached to the picking so the customer doesn't have to do anything. Priority is invoice on individual package, invoice attached to the picking, invoice attached to the sale order as a final fallback. If all three are missing and not sent to the government yet, the picking will validate fully, but not automatically send to Envia.com. It will instead post to the chatter that an invoice needs to be validated and linked properly to the record before hitting Send to Shipper. task-6120965
Updating a company’s return reminder day now recalculates deadlines only for open account returns that are affected. This preserves the same business behavior while reducing unnecessary processing as the number of returns grows.
Original PR description
In this commit: - Remove the 'company_id.account_return_reminder_day' dependency from the '_compute_deadline' compute method. - Avoid triggering the compute method for all related account returns whenever 'account_return_reminder_day' is updated, as this becomes increasingly expensive when the number of records grows. - Override 'res.company.write()' to detect changes to 'account_return_reminder_day'. - Manually trigger '_compute_deadline()' only for non-completed account returns that are actually affected by the change, reducing unnecessary recomputations while preserving the existing behavior. task-[6296822](https://www.odoo.com/odoo/project/967/tasks/6296822)
Odoo now checks whether a payment or batch payment exceeds the maximum amount allowed by the connected financial institution before initiating it. This helps prevent failed payment attempts and gives users earlier feedback when a bank-imposed limit applies.
Original PR description
Before trying to initiate payments through Odoo/Odoofin, we should check that the total amount for the (batch) payment does not exceed the maximum payment amount allowed by the institution (some Powens institutions introduced that limit). task-6310729 Forward-Port-Of: odoo/enterprise#127110 Forward-Port-Of: odoo/enterprise#121513
Cash journal users can now choose an account directly when quickly creating bank statement lines, reducing extra reconciliation steps. The update also strengthens cash statement posting and deletion rules so records stay consistent and compliant when journals are secured.
Original PR description
This commit will add the possibility to add an account on the quick create view of a bank statement line when being on a cash journal that when selected will do a set account on the statement line created with the account selected no task id
Payroll will no longer automatically set the current driver of a company car based on benefits alone. Instead, employees are marked as future drivers when they choose or receive a car, preventing already reserved cars from being offered again and reducing unnecessary administrative tasks.
Original PR description
. Remove the auto-assignment of the Driver based on the payroll benefits. . If an employee signs a contract and selects the car or the car gets added to the employee's benefits, he should become the car's future driver. . Don't offer in the salary configurator cars for which the future driver is filled. . Don't generate a task every time the payroll officer assigns a new driver to the car . Add the corresponding tests task-6425360 Forward-Port-Of: odoo/enterprise#127390 Forward-Port-Of: odoo/enterprise#126016
Bulgarian companies can now have required monthly VAT reporting files generated automatically when validating a VAT return. The change adds the General Ledger SAF-T file plus purchase and sales reports to the return attachments, reducing manual work and helping with local compliance.
Original PR description
Bulgaria made it mandatory for large companies to present a monthly file
to report their VAT to the administration. To streamline that process,
when the VAT return is validated and PDF is added to the attachments,
the monthly General Ledger SAF-T file, the POKUPKI Purchase Report and
PRODAGBI Sale Report are produced and added as well.
Simplify the report file download error wizard's visuals and descriptions to improve readability.
task-6007963
Forward-Port-Of: odoo/enterprise#127736
Forward-Port-Of: odoo/enterprise#118326Budget report loading has been optimized to avoid inefficient record matching that could make reports unusably slow on larger databases. This should significantly reduce wait times for users opening budget reports, especially when many analytic lines and budget lines are involved.
Original PR description
**Description:** While loading the budget report, the bad queries are created by ```def _get_aal_query()``` and ```def _get_pol_query()``` function, makes the budget report unusable. **Root cause:**…
**Description:**
While loading the budget report, the bad queries are created by
```def _get_aal_query()``` and ```def _get_pol_query()``` function, makes
the budget report unusable.
**Root cause:**
Instead of doing a hash join while searching the record,
the OR statement in the Left Join in the condition
```(%(bl)s IS NULL OR %(a)s = %(bl)s)```
creates a nested for loop that compares everything single aal to bl,
this causes a significant performance issue as the number of the
number of check will be the the number aal * bl,
if a database has a 70k aal and 20k bl, both numbers are not large
but it will cause a 70k * 20k search which is more than a billion.
**Fix**:
There are some refactors made in this PR.
_First_, separate out the Q1.
In order to find the aal that has no bl connects to it.
Doing a search to find the aals that have bl and then subtract them from all aals.
_Second_, Instead of doing a nested loop for by using
```(%(bl)s IS NULL OR %(a)s = %(bl)s)```,
originally we will have do something like
```
JOIN budget_line bl
ON (bl.x_plan2_id IS NULL OR aal.x_plan2_id = bl.x_plan2_id)
AND (bl.x_plan3_id IS NULL OR aal.x_plan3_id = bl.x_plan3_id)
AND (bl.x_plan4_id IS NULL OR aal.x_plan4_id = bl.x_plan4_id)
```
Assuming each bl has three plans ```x_plan2_id```, ```x_plan3_id```, ```x_plan4_id```
Grouping the bl base on whether a specific plan is set, (i.e. shapes)
we can skip the ```IS NULL OR``` because we already know which plan
is null and do the hash join directly.
For example, the shapes will be a dictionary with a key of a tuple of booleans
based on whether a plan is set or not and the value is a list of bl_id.
```
{
(True, False, False): [1, 2],
(False, True, True): [3, 4],
(False, False, False): [5],
}
```
we can end up doing something like
```
JOIN budget_line bl
ON bl.id = ANY(ARRAY[3,4])
AND aal.x_plan3_id = bl.x_plan3_id AND aal.x_plan4_id = bl.x_plan4_id
```
which is way more faster.
---
The benchmark is made locally from this client's database which contains
69k aal, 23k bl, 6829 pol and 3 plans for aal and bl.
|Record count |Time before|Time after|
|--------------------------------------------------|-----------------|---------------|
|69k aal, 23k bl, 6829 pol, 3 plans |70.04s |4.6s |
Dalibo:
Before:
Month-over-month grand total by company:
https://explain.dalibo.com/plan/8h3d4e89aaf9f3d4
Overall grand total by company:
https://explain.dalibo.com/plan/445g1f9caf4923e2
Month-over-month grand total by plan:
https://explain.dalibo.com/plan/53a138ca50b2a7c4
Overall grand total by plan:
https://explain.dalibo.com/plan/hdbe169ddc7g5785
After:
Month-over-month grand total by company:
https://explain.dalibo.com/plan/hcc86c801e6872bf
Overall grand total by company:
https://explain.dalibo.com/plan/69b2421a3581f98h
Month-over-month grand total by plan:
https://explain.dalibo.com/plan/a88f398bbbch3148
Overall grand total by plan:
https://explain.dalibo.com/plan/1gg749ae7ab1553c
opw-6345552
Forward-Port-Of: odoo/enterprise#127732
Forward-Port-Of: odoo/enterprise#124161Shopfloor work orders now handle quantity updates consistently with the backend for continuous production, avoiding unintended changes to the quantity being produced. The work order form layout was also reorganized to make continuous production information clearer for users.
Original PR description
In this commit, shopfloor is modified in order to match the behaviour in the backend; On updating WO's quantity, the quantity producing is not updated if its a continuous production. Workorder form fields were also re-ordered as a part of the ongoing continuous production clean. Task: 6346515 Forward-Port-Of: odoo/enterprise#123215
Payroll warning checks are now grouped so the system avoids repeating the same lookup many times. This should make payslip and employee payroll version processing faster when many warnings are active, without changing the warnings users see.
Kitchen staff can now print preparation tickets on demand directly from the kitchen workflow. Tickets can also print automatically when orders reach configured stages, and added barcodes let staff scan tickets to move orders forward faster.
Original PR description
*: pos_restaurant_preparation_display, pos_urban_piper, pos_self_order_preparation_display In this commit: ------------------- - Introduced functionality to print KOTs on demand from the kitchen. - Added support for automatic printing when an order is moved to a configured stage. - Added barcodes to KOTs printed from the kitchen, allowing kitchen staff to scan them and directly move the order to the next stage. task: 6131467 Related PR: https://github.com/odoo/odoo/pull/273944
Sign managers and the person who sent a signature request can now add or change the linked record at any stage. This helps teams correct or complete request details after the request has moved beyond the sent state, while keeping the field read-only for other users.
Original PR description
Before: - The 'Linked To' field on a Signature Request could only be edited while the request was sent state After: - Sign manager and user who sent SR can now set or change the "Linked To" field at any time. - Other users keep seeing the field as read-only. Impact: - Admins and request senders can correct or add the linked record even after the request has moved past the sent state. Taskid: 6321326
This update refreshes the spreadsheet interface to align with the latest underlying spreadsheet library. Users will see more consistent icons, section styling, and drag-and-drop behavior when working with lists, pivots, and filters in spreadsheet side panels.
The Mexico e-invoicing website sale flow was updated to stay aligned with recent community changes. This helps keep online checkout invoicing behavior consistent and reduces the risk of issues for Mexican localization users.
Original PR description
community PR: https://github.com/odoo/odoo/pull/278561
3 changes
Enhancements to existing features
Users can again use folder action menus when working with document views embedded in spreadsheets or knowledge articles. This makes it easier to share and reuse live folder views while keeping shared access tokens protected from unintended exposure.
Original PR description
Also impacted: test_documents_full It is convenient to export a dynamic view of a folder in both spreadsheet and knowledge links settings. * Care is taken to avoid leaking access folders tokens through the search panel/model's state in knowledge. * We also enable sharing folders shared via link through embedded views as it enables benefitting from the power of them vs. adding the link to the folder in the article. * As with other actions initiated on shortcuts, the "real" operation is done on the target. Sharing the target is simpler than patching a folder "child_of" to return the target children (shortcut as documents_unique_folder_id is not supported). Task-5180137
Turkish payroll settings are updated for 2026, including clearer minimum wage naming and new configurable social security contribution values. This helps payroll teams calculate SSI contributions more accurately within the updated minimum and maximum contribution limits.
Original PR description
- Update the Turkish payroll rule parameters for 2026. - Rename the minimum wage parameter to 'Turkiye Minimum Net Wage'. - Add configurable parameters for the SSI minimum contribution base and employee contribution rate. - Update the SSI contribution computation to account for both the minimum and maximum contribution bases. **task-6397284**
The Dutch payroll localization now includes the 2026 resident income tax rate values. This helps payroll calculations stay aligned with upcoming tax rules for employees residing in the Netherlands.
Original PR description
Added 2026 values for the residents' income tax rates rule parameter. task-6462877 Forward-Port-Of: odoo/enterprise#127556