Wednesday, September 23, 2026
18 changes · master
Enhancements to existing features
Accounting test setup now refreshes database statistics after loading test charts so the system chooses faster queries. This prevents long delays in localization test builds and makes internal validation more reliable without changing user-facing accounting behavior.
Original PR description
The default order of account.account joins an aggregate over the ancestor paths of every account. A company created in a test only exists in the test transaction, so the planner assumes it has a…
The default order of account.account joins an aggregate over the ancestor paths of every account. A company created in a test only exists in the test transaction, so the planner assumes it has a single account and reruns that aggregate for each of its accounts, including the dead rows left by earlier test classes. On runbot this turned 5s L10n class setups into minutes and got buckets killed. Analyzing the account tables after the chart load gives the planner the real counts, as test_balance_sheet_balanced already does. Order changes alone are not enough, and rewriting the query slows down production searches. The journal default account lookup only needs a code length, so it now uses the id order. | Benchmark | without | with | |--------------------------------------------|----------|----------| | Peru TestSequence, 25k dead rows (local) | 120-132s | 4.3-7.2s | | L10n build, slow account path queries | 94 | 0 | | L10n build, TestPosAR setup | 145s | 15s | | L10n build, TestCIIFR setup | 109s | 8s | Forward-Port-Of: odoo/odoo#289782
Recall emails for stock items now use information from the specific affected stock movement line, rather than only the overall transfer. This lets the email include clearer product and lot or serial details, helping recipients identify the recalled items more accurately.
Original PR description
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#288882
Back-office users can now find survey certifications using the certification number shown on generated certificates. This makes it easier to locate and verify completed certification records without relying on other participant details.
Original PR description
Purpose ======= Add the possibility to search by certification number in the back-end. Specification ============= A certification number is displayed on the certification when generated, but there's no way to use it to search for that certification in the back-end. Making a new "certification_number" field only available for user inputs that have succeeded a certification survey. Adding it as a column in the user_input list view and adding a search method so that we can search on it without storing it. Using this new field in the certification templates as well. Task-6344097 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Large reports that reuse the same barcodes or QR codes will generate much faster because identical images are reused during the report run instead of being recreated each time. This reduces waiting time for high-volume documents without changing the report output.
Original PR description
### Description of the issue/feature this PR addresses: Reports with hundreds of pages and repeated barcodes or QR codes (same document number, same lot code on every page) re-run reportlab's…
### Description of the issue/feature this PR addresses: Reports with hundreds of pages and repeated barcodes or QR codes (same document number, same lot code on every page) re-run reportlab's createBarcodeDrawing and PNG encoding on every occurrence, even when type, value and options are identical. ### Current behavior before PR: Every call to ir.actions.report.barcode() re-renders the barcode/QR from scratch, regardless of whether an identical (type, value, options) combination was already rendered earlier in the same report. On a 900-page report with 4 barcodes/page, this dominates generation time. Benchmark, 900 pages x 4 barcodes/page, 4 distinct combos, 3600 calls: 19.131s. ### Desired behavior after PR is merged: The pure rendering step (createBarcodeDrawing + mask + PNG encoding) is extracted to a module-level function keyed on (barcode_type, value, options, mask) and wrapped with functools.lru_cache. Repeated barcodes reuse the cached PNG instead of re-rendering. Same benchmark after the fix: 0.020s (946.7x speedup, cache_info hits=3596 misses=4). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289979 Forward-Port-Of: odoo/odoo#289135
Improves the mail module's internal handling of record lists so common lookups and updates avoid unnecessary copying. This should reduce overhead in mail-related screens, especially where many records are involved, while preserving existing behavior.
Original PR description
Before this commit, relation reads such as map, filter and some copied the entire relation into an array of proxies before starting. Even a search matching the first record paid that cost. This…
Before this commit, relation reads such as map, filter and some copied the entire relation into an array of proxies before starting. Even a search matching the first record paid that cost. This commit fixes the issue by implementing these common methods directly on RecordList and centralize the lazy relation computation. On read this accesses the backing array and exposes record proxies as needed, while preserving the callback arguments the inherited array methods accept, including thisArg. The read snapshots the array, so that any mutation during a traversal never skips or repeats a record: the read finishes on the records the relation held when it started. Add regression coverage for traversal during mutations, completed mutation visibility to immediate observers, and callback binding. Chrome 153, median across 18 batches in two runs, in µs per operation (lower is better): | Operation | Records | Before | This commit | | --- | ---: | ---: | ---: | | `some()`, first match | 5 | 0.597 | 0.204 | | `some()`, first match | 500 | 40.02 | 0.203 | | `map()` | 50 | 6.10 | 5.58 | | `map()` | 500 | 63.35 | 62.45 | | `shift()` + `push()` | 500 | 142.38 | 49.65 | | `pop()` + `unshift()` | 500 | 185.11 | 98.95 | | Indexed replacement (`list[i] = record`) | 500 | 1.13 | 47.13 | These are isolated RecordList/Owl microbenchmarks, not end-to-end Discuss UI timings. Forward-Port-Of: odoo/odoo#287994
Planning now warns users when they try to send a schedule but none of the selected employees have a valid work email address. This prevents users from thinking schedules were sent successfully when no employee could actually receive them.
Original PR description
Before: when all employees in the send wizard lacked a work email, clicking 'Save & Send Schedule' sent the schedule to no one without informing the user. After: a warning notification is shown explaining that the planning cannot be sent until at least one employee has a valid work email address. task-5092438
Point of sale users can now add money to a customer's account even when that customer still has unpaid invoices. This makes it easier to accept deposits without forcing staff to settle existing dues first.
Original PR description
"Deposit money" was only offered in the partner list when the customer had no due, so a customer with open invoices could not put money on their account without settling those invoices. Always offer it when a customer account payment method exists. opw-6514079 Forward-Port-Of: odoo/enterprise#132065 Forward-Port-Of: odoo/enterprise#131268
Deleting a starting activity in a marketing automation flow no longer removes all connected child activities by default. The system now keeps valid follow-up steps and only removes trigger steps that cannot stand alone, reducing the risk of accidental campaign data loss.
Original PR description
When a user deletes a root marketing activity, the system currently performs a cascading delete, removing all of its child marketing activities as well. This behavior can be disruptive and may result in unintended data loss. This PR refines the deletion logic to remove only trigger nodes (e.g., "wait for value" or "mail interaction") that are not allowed at the root of the flow. Other nodes that are valid at the root level will be preserved. Task-6559148 Forward-Port-Of: odoo/enterprise#131453
The Marketing Automation editor has been visually refreshed with more consistent spacing, icons, step labels, and layout details. This makes campaign setup and review easier to use, while also improving the mobile experience for creating steps and removing unused trace view elements.
Original PR description
Improve the editor UI with consistent spacing, icons, step names, and other visual elements across the application. This gives the interface a more modern and cohesive look and improves the overall user experience. It also removes unused templates from the trace view and improve the responsiveness of the creation helper on mobile devices. Task-6559148 Co-authored-by: Chrysanthe <chgo@odoo.com> Forward-Port-Of: odoo/enterprise#131772
The AI website assistant can now allow generated JavaScript for only the current chat session instead of enabling it for the whole website. Generated scripts also wait until the page is ready before running, reducing broken interactions and making AI-created website behavior more reliable.
Original PR description
[IMP] ai_website: propose to allow javascript session-wise Commit [1] added an option to add javascript and to allow it for the whole website. This commit adds an option to allow inserting javascript…
[IMP] ai_website: propose to allow javascript session-wise Commit [1] added an option to add javascript and to allow it for the whole website. This commit adds an option to allow inserting javascript in the current chat only. [1]: https://github.com/odoo-dev/enterprise/commit/ad87d6aac19ad4a2b0fe572fff8931c9c122723d task-6481594 --- [REF] ai_website: rename aiScriptsRuntime to aiScriptsManager aiScriptsRuntime wasn't the best name for it, so we renamed it to the aiScriptsManager. task-6481594 --- [FIX] ai_website: run ai scripts only when the dom is loaded Scripts that are generated by AI run as soon as they are parsed, which might lead to issues if it uses not yet parsed content. Steps to see the issue: - Drop a `splash_intro` snippet and some snippet after it - Ask AI to "scroll the page down to the next section when 'Impact' is hovered" => It might check for the presence of the next section immediately when it runs, exiting the script early. task-6481594 Forward-Port-Of: odoo/enterprise#129834
Customer statement and open items reports now produce clearer, better-formatted PDFs with customer addresses included. PDF exports are organized per customer in one combined file, making reports easier to review and share.
Original PR description
This commit adds the following improvements to the customer statement and open items reports: 1) Adds more space for the company bank account number in the header and avoid line breaks in it 2) When printed in PDF, it prints one PDF per customer concatenated together in a single PDF 3) It includes the customer address in the generated report 4) They have better styling task-6476236
Custom AI agents can now guide users through making the agent available by default on relevant business forms, such as leads or tasks. This makes tailored AI assistance easier to deploy without requiring a separate technical setup or custom server action.
Original PR description
Users create custom AI agents and want them to appear automatically as the default agent when they open the relevant form view (leads, tasks, etc.). Extend the "Self Update" skill instructions so that after the agent writes its own model-specific system_prompt, it walks the user through binding itself to that model's form via the existing generic tools — no dedicated server action needed: 1. Resolve the target ir.model via ai_tool_search. 2. Check for an existing (agent, chatter_ai_button, model) rule and propose to update it rather than duplicate. 3. Ask (in plain text) for 2-4 typical actions. 4. Create/update the ai.composer with interface_key='chatter_ai_button' and ai_agent_id pointing back at the current agent. 5. Create the matching ai.prompt.button rows linked via composer_id. task-6578312 Forward-Port-Of: odoo/enterprise#131952
Subcontracting manufacturing orders now show key actions and status details directly on the form, reducing the need to navigate through inventory menus. The overview also shows component availability at the subcontractor location, helping users better understand shortages and replenishment needs for subcontracted work.
Original PR description
*: mrp_subcontracting_purchase Currently, when a subcontracting MO is opened from the picking view, only limited information is displayed. Users need to navigate to the corresponding MO via…
*: mrp_subcontracting_purchase Currently, when a subcontracting MO is opened from the picking view, only limited information is displayed. Users need to navigate to the corresponding MO via Manufacturing Operations in Inventory to access additional details. In addition, the MO overview displays component information based on the warehouse instead of the subcontracting location, making it difficult to review the actual component availability for the subcontracting process. This commit improves the subcontracting MO by: - Adding Overview and Transfers smart buttons, along with the start date and component status, directly on the subcontracting MO form. - Adding a `Free to Use / On Hand (Subcontractor Location)` column to display the quantities available at the subcontractor location for each component in the MO overview. - Hide free to use/on hand and Reserved for finished product. - Computing the `receipt status and reserved quantities` using the subcontractor location instead of the warehouse. - Allow replenishment of components at the warehouse from subcontracting MO overview. - Show the Source PO smart button only in the resupply picking view. - Renamed the `Subcontracting Productions` smart button to `Subcontracted Productions`. TaskId-6234816 Forward-Port-Of: odoo/odoo#267733
Invoice amount due now updates immediately while editing, reducing confusion from totals temporarily appearing out of sync. Applying outstanding credit also saves the invoice first, preventing newly added invoice lines from being lost.
Original PR description
Before this commit, the account.move amount due field would only update on record saving (as it depended on line_ids). This caused a temporary out of sync situation between the total and the amount due on the move form view. This commit ensures that the amount due is computed even before saving the record so that out-of-sync situation is avoided. It also solves the following bug: Repro steps: 1) Create a new invoice 2) Add a customer and save the record 3) Add some invoice lines 4) without saving, add a payment from the outstanding credit Issue: The added (unsaved) invoice lines are removed Solution: This commit forces a record save before assigning outstanding credit task-6534794
Website editors can now insert videos hosted on their own server or a CDN through the media dialog, instead of being limited to supported third-party platforms. This gives businesses more flexibility and control over video content while keeping the feature enabled only where intended, such as the website builder.
Original PR description
Description of the feature this PR addresses: The video tab of the media dialog only accepted urls from the eight supported third party platforms, so a self-hosted video, or one served from a CDN, could not be inserted at all. Add a `VideoFile` provider, tried once no platform matches the url. A video file url has no recognizable shape, so it is probed rather than matched, it is loaded in a detached `<video>`. The feature is behind the `allowVideoFile` config flag, off by default and currently enabled by the website builder. Removes YoutubePlugin which is dead code. task-6466707 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282438
Inventory screens were simplified by removing redundant detailed stock options and making key physical inventory and wave preparation actions easier to find. Wave transfer wording and navigation are clearer, helping users create and manage waves with fewer interruptions.
Tax return checks now focus on issues that actually need attention, reducing unnecessary warnings once company data is complete. The tax reconciliation and draft review checks also provide more accurate results by using the return period, posted entries, and relevant sales and purchase journal filters.
Original PR description
Before this commit:- - Company Data check was always created, just like other checks. - Company Data check's message was using static 'VAT' word. - Drafts & Reviews check excluded moves with type…
Before this commit:-
- Company Data check was always created, just like other
checks.
- Company Data check's message was using static 'VAT' word.
- Drafts & Reviews check excluded moves with type `entry` for common vat report.
- Tax Reconciliation check action
- Opens pivot view of move lines with row group by tax_tag_ids > account_id.
- Domain used only outgoing moves.
- There was no date filter.
After this commit:-
- Company Data check will be created only when failing, if it is passing then
don't create. Because unlike other checks, once company data is set, this check
will always pass, and creating it every time is useless.
- Company Data check's message uses dynamic vat label.
- Drafts & Reviews check now includes `entry` type moves for the common VAT
report, but only when they carry taxes.
- Tax Reconciliation check action
- Opens pivot view of move lines with row group by tax_ids > account_id.
- Remove domain and apply Sales and Purchase journals in default filters so
user can remove it and see it all if needed.
- Apply current return's date period in default filters.
- Apply only Posted moves in default filters.
- Improved names and messages of some checks.
[task-6486107](https://www.odoo.com/odoo/project/967/tasks/6486107)
Forward-Port-Of: odoo/enterprise#130750Customers who start adding a configured product to their cart will no longer lose that action if they close the configurator without explicitly confirming. When the configuration is valid, the main product and selected optional products are still added, reducing missed sales and checkout friction.
Original PR description
Previously, closing the product configurator dialog without confirming resulted in no products being added to the cart, even if the user had initiated an add-to-cart action. This change ensures that both the main product and optional products are added to the cart when the dialog is closed, provided the configuration is valid. task-6055551