Monday, September 28, 2026
21 changes · master
Enhancements to existing features
The media dialog now presents icons in clearer themed groups, making it easier for users to browse related options. Icon search is also more reliable across languages, accents, and multi-word searches, while new checks help prevent missing or broken icons in future updates.
Original PR description
[IMP] web, website: add tests for the icon list --- __Before commit__ `icons.py` is generated by `web/tooling/icons/generate_icons.py`, but no tests checked whether it contained all icons from…
[IMP] web, website: add tests for the icon list
---
__Before commit__
`icons.py` is generated by `web/tooling/icons/generate_icons.py`, but
no tests checked whether it contained all icons from
`icons_wishlist.txt` and `odoo_ui_icons_config.json`. This could lead
to missing icons if someone forgets to regenerate the fonts.
__What's added__
- A Python test asserting that `ICONS` in `web/icons.py` matches
`icons_wishlist.txt` and `odoo_ui_icons_config.json`.
- A step in the website `media_dialog` tour that verifies each icon
offered by the media dialog renders properly by measuring its width,
ensuring there were no errors during generation.
[IMP] web: order the icon picker's icons by theme
---
The media dialog lists the icons in the order `web/icons.py` declares
them, and that order was alphabetical: `arrow_back` sat between
`article` and `arrow_circle_down`, `crop_landscape` far from `crop`, the
`cc_*` cards scattered through the brand icons. Browsing the dialog
meant scrolling past unrelated icons to reach a variant of the one
already on screen, which only search made bearable.
Both sources are now ordered by theme -- arrows, layout, text, media,
payments, brands ... -- with the variants of an icon kept side by side,
and the generator hands that order over to `icons.py` as it is instead
of sorting it away. `icons_wishlist.txt` carries `#` headers naming
each group, so a new icon has an obvious place to be added to.
The fonts are unchanged: they are still built from a sorted wishlist and
laid out by codepoint, which is what keeps two builds of the same icon
set byte-identical.
[IMP] web, html_editor: translate the icon search tags
---
Every icon of the media dialog carries a long list of search tags
(`wheelchair`, `basket`, `magnifying glass` …) that never reaches the
browser: the needle is matched against them server-side. Those tags
were English only, so a user searching in their own language found
nothing unless the word happened to be part of the icon name.
The tags are now declared with `_lt` in `web/icons.py`, and
`search_icons()` takes an optional `translate` -- `env._` from the
controller -- to match them in the user's language. They stay lazy
because the dict is built at import, long before any language is known.
The English tags remain searchable whatever the language: the index
built at import is matched first, and only the icons it misses are
translated, so an untranslated database and an English needle cost
nothing.
[IMP] web: match every word of an icon search
---
Searching the media dialog for `shopping cart` looked up that whole
string in the tags, and matched only the icons spelling the two words
in that very order. Anything a user types as two hints -- `arrow left`,
`chart bar` -- was therefore likely to return nothing at all.
The needle is now split on spaces and an icon matches when all of its
words are found, in any order, in the icon name or its tags. A word may
come from either language: only the words the English tags miss are
looked up in the translated ones.
[IMP] web: normalize the icon search needle and tags
---
Searching the media dialog for `Cafe` or `café` found nothing: the
needle and the haystack were only lowercased, so case was handled but
diacritics were not. Translated tags make this worse, since most
languages other than English spell their words with accents -- a French
user typing `marche` missed every icon tagged `marché`.
Both sides now go through `remove_accents(text.casefold())`, applied to
the needle, to the index built at import and to the tags translated on
the fly. `casefold()` also folds the cases `lower()` leaves alone, such
as the German `ß`.
The index is built from `tags._source` rather than from an explicit
`_translate('en_US')`: same string, without pretending a language is
known at import time.AI provider settings can now be turned on or off independently from the saved API key. This makes it easier to temporarily disable a provider while keeping credentials in place, and users will see clearer messages when keys are missing or invalid.
Original PR description
Prior to this PR, user had to delete the API key set in order to disable the corresponding provider option in the AI config view. With this PR, we removed the compute method to allow the enable/disable provider option independently from the API key value. Additionally, reworded error messages when API keys are unable and added custom messages when provided API key is invalid. task: 6331248
This update improves Odoo's internal upgrade tooling so more service-related code is migrated correctly during the Owl 3 transition. It helps reduce manual cleanup and lowers the risk of migration issues for future upgrades.
Original PR description
The owl3-migration is missing some of the service's mapping used to migrate the useService call site into usePlugin. This commits aims at fixing this and fixing the typos.
Payroll users will now see a chatter message whenever the estimated end date of a payslip adjustment is changed. This improves traceability by making important adjustment updates visible in the record history.
Original PR description
Add message in chatter whenever the estimated end date of a payslip adjustment is changed. Task-6588118
Indonesian payroll now includes a non-taxable Meal Allowance (Catering) salary rule. This helps employers record catering benefits correctly as benefits in kind while keeping payroll calculations aligned with local requirements.
Original PR description
Add a new salary rule for a non-taxable Meal Allowance (Catering) benefit, categorized as Benefit in Kind. task-6461730
The Belgian payroll module no longer shows a warning about missing ONSS identification because that warning is no longer relevant. This reduces unnecessary alerts for payroll users and helps them focus on items that still require action.
Original PR description
- Missing ONSS Identificantion warning does not make sense anymore task-6569900
This update makes it easier for developers to build domain filters by allowing model records to be used directly in equality checks instead of manually extracting their IDs. It reduces small implementation friction while keeping validation in place to prevent mismatched model usage.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Salespeople are now notified as soon as a customer schedules their subscription to close at the end of the billing period. This gives teams an earlier opportunity to contact the customer and potentially prevent churn.
Original PR description
Before this PR: When a customer closes their subscription at the end of the billing period, only `end_date` changes `subscription_state` stays `in progress` until the period ends. Since tracking only assigned the "State Change" subtype on `subscription_state` changes, this update was logged silently in the chatter with no notification. The salesperson had no way to know the customer intended to leave, and no chance to retain them. After this PR: `_track_log_get_default_subtype` also returns `mail.mt_comment` when `end_date` changes and `is_closing` becomes `True`. The salesperson, already an auto-subscribed follower of that subtype, is now notified as soon as a closing end date is set, giving them a chance to act before the subscription churns. Impact: Salespersons are alerted the moment a customer schedules closure, instead of finding out after the fact, giving them a real window to reach out and reduce silent churn. Taskid-6366414
The accounting settings text for firms has been reworded to make it clearer for users. This is a small wording improvement that helps businesses better understand the relevant setting without changing functionality.
Original PR description
changing the wording for the account firm settings text. task-6578290
The Belgian payroll setup now combines two spouse fiscal status choices that had the same tax effect into one clearer option. This reduces confusion for HR users while keeping withholding tax calculations unchanged.
Original PR description
The "High Income" and "High Pension" options of the Spouse Fiscal Status field have the exact same impact on an employee's withholding taxes. Keeping them separate creates unnecessary clutter in the interface. This change merges both options into a single "With High Income or Pension" option. task-6570466
Sales orders linked to projects now show the milestone option when selling services that are invoiced based on milestones. This makes it easier for users to create and manage milestones directly from the sales order, supporting smoother project billing workflows.
Original PR description
When a product is configured as follows: ------------------ Product Type: Service Service Tracking: Create on Order - Nothing Invoicing Policy: Based on milestones user creates a sale order linked to a project,the milestone stat button will be visible on the sale order. From there, the user can also create new milestones. task-4648575
The public holiday loading wizard now warns users when holidays for the selected year already exist and will be excluded from the list being imported. This helps HR users understand why some holidays are not shown and prevents confusion or duplicate entries.
Original PR description
Notify users, while loading the public holiday from wizard, when some holidays are already present in the system for the given year and will be removed from the shown list. Task: 6559614 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Click & Collect choices made on the product page are now saved without creating an empty order first. This keeps sales data cleaner and applies the customer's delivery choice only when they actually create a cart.
Original PR description
Selecting a pickup store or the standard delivery method on the product page created an empty sale order just to store the choice, even before the customer added anything to the cart. Keep the selection in the session instead of creating a cart when none exists yet. The choice is applied to the order once a cart is actually created. task-6538541 Forward-Port-Of: odoo/odoo#288321
Support teams can now review report snapshots directly from the advanced report configuration view available in debug mode. This helps them investigate customer issues faster by checking whether reported accounting report problems are linked to saved snapshots.
Original PR description
The form view of account.report is only accessible in debug mode, so we can put more advanced debugging/configuration things in it. This way, it'll be easier for support to investigate and check whether the bug reported in a ticket is connected to the snapshots. Forward-Port-Of: odoo/enterprise#132744
The Belgian payroll process no longer shows a toast notification when ONSS rates are imported by the scheduled background job. This reduces unnecessary alerts for users while keeping the import process running as expected.
Original PR description
task-6586967 Forward-Port-Of: odoo/enterprise#132339
Spanish companies can now use one unified accounting setup instead of choosing between separate SME and Complete plans during installation. This makes it possible to change the accounting chart type later from settings, reducing setup friction and avoiding reinstallation when business needs change.
Original PR description
…ingle dynamic fiscal package The Spanish localization previously had separate fiscal packages for SMEs and Complete plans (es_pymes, es_full), forcing users to choose at installation time with no…
…ingle dynamic fiscal package The Spanish localization previously had separate fiscal packages for SMEs and Complete plans (es_pymes, es_full), forcing users to choose at installation time with no way to switch afterwards. This introduces a new unified es_general template that replaces both, along with a spanish_general_chart_type field on res.company (SMEs, Complete, Abbreviated). When the company setting changes, accounts exclusive to the deselected plan are archived and those of the new plan are activated, allowing companies to switch chart type at any time without reinstalling the localization. - Remove template_es_full.py and template_es_pymes.py - Add template_es_general.py with dynamic account loading based on chart type - Add spanish_general_chart_type field to res.company and res.config.settings - Expose the new field in the accounting configuration view as a radio widget task-6065347 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The messaging panel has been reorganized behind the scenes to make it easier to maintain and extend across Odoo apps. This should help keep chatter-related features more consistent in areas such as leave requests, projects, portals, ratings, and eLearning without introducing major visible changes for users.
Original PR description
Replace the elements stored inside `env.inChatter` by a dedicated plugin. This also convert the proxy to signals PR enterprise: https://github.com/odoo/enterprise/pull/126791
This update adapts WhatsApp and related document, recruitment, and knowledge features to a newer shared chatter framework. It helps keep message and collaboration tools consistent across apps, reducing maintenance risk while preserving existing user workflows.
Original PR description
PR community: https://github.com/odoo/odoo/pull/280602
Messaging and live chat internals were updated to use a more consistent way of understanding where each interface element appears. This should make future improvements easier and reduce the risk of inconsistent behavior, with little direct change for end users.
Original PR description
PR enterprise: https://github.com/odoo/enterprise/pull/126501
This update adapts the Knowledge app's comment handling to recent navigation improvements in the related community code. It helps keep comments working consistently as users browse and manage Knowledge articles.
Original PR description
PR community: https://github.com/odoo/odoo/pull/280035
Followers and recipients are now shown in alphabetical order, making lists easier to scan and use. Loading more entries now retrieves smaller batches of 20 at a time, which can make these requests lighter and more responsive.
Original PR description
Before this PR: Followers and recipients were not sorted. Each request loaded up to 100 followers or recipients. After this PR: Followers and recipients are sorted alphabetically. Additionally, we now load only 20 followers or recipients at a time when making a request to load more. task-id:3293718