Friday, August 28, 2026
8 changes · master
Code cleanup and technical improvements
This update restructures how mail and chat data is calculated and refreshed behind the scenes, reducing unnecessary recalculations and making state changes more predictable. It also fixes several issues found during the cleanup, including attachment typing, pinned chat behavior, and missing CRM typing declarations.
Original PR description
Commit 1. Before this commit, `Record.onChange` binds its two functions to what `this` is at the call site. A record is only reachable as its proxy once the constructor is over, so a registration has…
Commit 1. Before this commit, `Record.onChange` binds its two functions to what `this` is at the call site. A record is only reachable as its proxy once the constructor is over, so a registration has to wait for `static new`, where `super.new` has returned it, and both models that register one override `static new` for nothing else. This commit resolves the proxy when the functions run rather than when they are registered, so `setup` can register an onChange, and moves both models to it. Commit 2. Before this commit, a value computed from a record can only be a field with a `compute`, and the model guesses whether that value needs storing: `fieldsComputable` picks the lazy plain-valued fields with eight conditions and a regular expression run on the compute's source. This commit adds `fields.computed()`, so the declaration answers instead of the model: the value is computed on the first read and kept in an owl computed of its own, which the model neither stores nor serializes. The 36 fields the detection was picking are declared instead, so `fieldsComputable` lists what the declarations name and the guessing goes. A `compute` left on a field is scheduled and stored. A computed has no `onUpdate`, so the two fields that had one register an `onChange` from `setup`. This also converts four getters that rebuild a collection on every read, so each one runs on a change instead of on every read. This also fixes what the conversion turned up: - `extra_body_attachment_ids` is declared as an `Attr` whose target model lands as its default value, where the compute returns records: the field becomes a `Many`. - three writes to `is_pinned` in `discuss.channel` never reach the member, as its compute owns the value: opening a channel, opening its chat window and undoing an unpin now set `unpin_dt`, what the compute reads and what the server writes to pin. `updateAttr` warns on such a write instead of dropping it in silence. - `crm.lead` has no `models` declaration and no `@crm` path alias, so the `@this` of its compute names the raw class and the computed value stays untyped. The enterprise counterpart declares `helpdesk.ticket` the same way. Commit 3. Before this commit, a value that goes stale on its own is kept by `Record.computedUntilStale`, a per-record store of its own next to the one `fields.computed` uses. The problem is that the same value needs a key repeating its name, a getter to read it through, and a second place to look for a record's computeds. This commit takes the delay as a third argument of `fields.computed`, so the two clock values of the store are declared like any other computed, and `staleComputeds` goes.
This update reorganizes how helpdesk live chat ticket links and display names are calculated behind the scenes. It improves consistency with the broader messaging system and helps keep the related code easier to maintain without changing the user experience.
Original PR description
Counterpart of "[REF] mail, *: declare a computed on a record", which explains the why. `href` is computed from the record, and nothing stores it.
Spreadsheet documents are now stored and identified using the standard JSON format instead of a custom spreadsheet file type. This makes the file handling more accurate and consistent while keeping the spreadsheet experience unchanged for users.
Original PR description
This commit removes the application/o-spreadsheet mimetype in favor of application/json for spreadsheet documents. New mimetype is more correct as spreadsheets are stored as JSON data. Task: 5416850
This update modernizes internal record observation code by replacing a deprecated mechanism with the newer framework approach. It helps keep the platform easier to maintain and ready for future framework changes, with no expected direct change for end users.
Original PR description
- enterprise: https://github.com/odoo/enterprise/pull/127637 See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The mail module now separates the creation of completed activity messages from the rest of the activity completion process. This makes it easier for customizations to change or skip the standard 'Activity Done' message without affecting permissions, attachments, or archiving.
Original PR description
The `_action_done` method in `mail.activity` currently handles multiple responsibilities simultaneously, including permissions, attachments, message posting, and archiving. This commit extracts the chatter message generation logic into a dedicated `_generate_done_message` method. This allows inheriting models to easily override, customize, or completely bypass the generic 'Activity Done' message without duplicating or interfering with the core completion and archiving logic. Task: 6127862 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 Point of Sale app’s internal data and ticket printing services were reorganized into a plugin-based structure. This should make the system easier to maintain and extend across related POS features without changing the day-to-day cashier experience.
Original PR description
Convert the following services to plugins: - pos_data_service - pos_ticket_printer_service
This update reorganizes some point of sale printing and data handling components into a newer plugin structure. It should make future maintenance and country-specific extensions easier without changing day-to-day user workflows.
Original PR description
Convert the following services to plugins: - pos_ticket_printer_service - pos_data_service
This change speeds up manufacturing-related bill of materials checks, especially when confirming large purchase orders with many lines. Businesses using manufacturing, purchasing, sales, point of sale, repairs, or subcontracting should see less slowdown when Odoo needs to evaluate potential kits or components.
Original PR description
Confirming a purchase order of 1000 lines - with only stock & purchase : time is 6.3secs - by adding mrp : time grows to 8.1secs Part of the difference comes from the time it takes to explode the…
Confirming a purchase order of 1000 lines - with only stock & purchase : time is 6.3secs - by adding mrp : time grows to 8.1secs Part of the difference comes from the time it takes to explode the (potential) kits. The refactor of _bom_find consists of: - signature change : company_id -> company_ids to allow searching within multiple companies in one go - return value change : the returned dict's key is now a tuple ( product, company_id or False) Calling _bom_find with no company given : retrieve result with ( product, False) Calling _bom_find with one or more company_id's : retrieve result with ( product, company) -> for _bom_find on record sets having the fields product_id & company_id With this, use case time falls to 6.9secs This will obviously have performance impact on many use cases. 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