Saturday, September 26, 2026
9 changes · master
Resolved issues and error corrections
The customer portal now shows quantities for hidden-composition sections in the same format as regular product lines. This removes a small visual inconsistency, making sales documents clearer and more polished for customers.
Original PR description
On the customer portal, a section with Hide Composition shows its quantity as 1.00 Units, while product lines show 1 Units. Add `min_precision: 0` to the collapsed section quantity, the same as product lines, so both display the same way. opw-6592535 Forward-Port-Of: odoo/odoo#290387
This fixes sales orders so individual items inside a combo product can no longer be changed separately from the product catalog. It helps keep combo product quantities consistent by requiring users to update the combo as a whole.
Original PR description
Steps to reproduce: - Create a sales order. - Add a combo product to the sales order. - Open the product catalog. - Try to update the quantity of an individual combo item. Issue: - Individual combo items can be updated from the product catalog, whereas the combo product should be updated as a whole. Cause: - In commit https://github.com/odoo/odoo/commit/d71d7b954ce3fa49b5c9d33129499b4deb0fc30a, the `combo_item_id` condition specific to the `sale` module was mistakenly dropped from the product catalog logic. Fix: - Restore the `combo_item_id` condition to make combo item lines read-only in the product catalog, preventing them from being updated individually. opw-6600702 Forward-Port-Of: odoo/odoo#290603
The Discuss call controls now stay disabled while a disconnect request is still being processed, preventing users from clicking Start Call too early and having the action ignored. This makes call reconnection behavior more reliable and avoids related test failures.
Original PR description
Before this commit, a click on "Start Call" right after "Disconnect" was ignored when the server had not answered the leave request yet. The test "only notified of a call disconnection when the server ends the session" failed on it:
Failed to find 1 of ".o-discuss-Call" (Timeout of 10 seconds).
Found 0 instead.
This happens because `leaveCall` ends the call before sending the leave request, since "[FIX] mail: only notify unexpected server call disconnects". As a result, "Start Call" and "Start Video Call" are back while `hasPendingRequest` is still true, and `toggleCall` ignores a click during a pending request.
This commit fixes the issue by disabling these two buttons during a pending request, as the join actions of a call already do. The test waits for "Start Call" to be enabled before clicking it.
https://runbot.odoo.com/odoo/error/947584
Forward-Port-Of: odoo/odoo#290585This fixes a timing issue in an automated mail test that could fail when the system responded slightly slower than expected. The change makes the test wait for the application to be ready before continuing, reducing false failures and improving confidence in test results.
Original PR description
Before this commit, mail_template_dynamic_placeholder_tour could fail when the server answers the onchange of "Applies to" slowly: Tour mail_template_dynamic_placeholder_tour failed at step Check if…
Before this commit, mail_template_dynamic_placeholder_tour could fail when the server answers the onchange of "Applies to" slowly:
Tour mail_template_dynamic_placeholder_tour failed at step Check if
the dynamic placeholder popover is opened
(trigger: div.o_model_field_selector_popover)
This happens because the tour waits a fixed 200ms after picking "Contact" before typing "#" in the subject. The popover needs the model, and the record only holds the model once the onchange answers. On runbot the answer came after 230ms, so "#" showed the "select a model" notification instead of the popover.
This commit fixes the issue by waiting for the internal link button of the many2one, which only renders once the record holds the model.
Note that this step relies on "[FIX] web: cancel the pending search on autocomplete select": without it, a search still pending on the picked value marks the input as edited, which hides that button.
https://runbot.odoo.com/odoo/error/947209
Ref commit: https://github.com/odoo/odoo/pull/287888
Forward-Port-Of: odoo/odoo#290364
Forward-Port-Of: odoo/odoo#290185Calendar alarm notifications now use the application’s current date handling instead of the database clock, making reminders behave consistently when dates are simulated in tests. This helps prevent missed or unreliable reminder behavior and strengthens test coverage for calendar notifications.
Original PR description
This commit makes alarm notifications compatible with methods used in tests to mimic dates such as mock_datetime_and_now, while also fixing related tests. Before the commit, the method fetching potential alarms (i.e.: _get_next_potential_limit_alarm) relied on Postgres's now() function. The problem is that this function is not compatible with freezegun as they don't work at the same level. The solution is therefore to use python's now() function and then integrate the result into the query's body. Furthermore, it is required in tests to update the partner's calendar_last_notif_ack field as it will be by default set to the db's creation date. Error-947109 Forward-Port-Of: odoo/odoo#288576
The Swiss payroll employee form now shows the work permit expiration date again. This helps HR keep required employee permit information visible and supports automated contract status checks that rely on that date.
Original PR description
…_date in employee form Add work_permit_expiration_date in Personnal Information page field is added in the standard view here: https://github.com/odoo/odoo/blob/18.0/addons/hr/views/hr_employee_views.xml#L184 this module override standard employee form view by making the entire Personal Information page invisible if CH and rewriting it: https://github.com/odoo/enterprise/blob/18.0/l10n_ch_hr_payroll_elm_transmission/views/l10n_ch_hr_payroll_employee_views.xml#L23 standard module hr_contract use this field in method [update_state](https://github.com/odoo/odoo/blob/18.0/addons/hr_contract/models/hr_contract.py#L184) called by cron [ir_cron_data_contract_update_state](https://github.com/odoo/odoo/blob/18.0/addons/hr_contract/data/hr_contract_data.xml#L53) Forward-Port-Of: odoo/enterprise#129875
Code cleanup and technical improvements
The mail app now manages record-related background cleanup through a single shared lifecycle mechanism. This internal simplification reduces duplicated cleanup tracking and helps ensure records are properly cleared when the app shuts down, without changing user-facing behavior.
Original PR description
Before this commit, a record keeps the stop functions of its effects in the `disposeFns` set, while its scope already owns its computeds. There is no need for that set, as `scope.onDestroy` takes a stop function. This commit registers each stop function on the scope of the record and drops the set, so that a record has one owner for its computeds and its effects. Destroying the app destroys the scope of every record still in the store.
Documentation and clarification updates
A contributor has signed the Odoo Individual Contributor License Agreement. This confirms the legal permission needed for their related contribution to be accepted and maintained in the project.
Original PR description
Signature of the Odoo Individual Contributor License Agreement v1.0 for @mmircoli-nexapp, needed for the fix related to #290493. I confirm I have read the [CLA](https://github.com/odoo/odoo/blob/18.0/doc/cla/icla-1.0.md) and that the committer email matches the one used in my contributions. Forward-Port-Of: odoo/odoo#290549
This change simplifies how Discuss channel members are created behind the scenes, removing a special internal shortcut and making the process more explicit. It should preserve the same user experience while reducing maintenance risk in the mail and Discuss area.
Original PR description
Before this commit, the channel create sets `_bypass_create_check` in its context, and discuss.channel.member.create sudoes itself when it finds that key. This is the only way to sudo members that the ORM creates as part of the channel create. This commit creates the members after the channel instead, with an explicit sudo, so the member create has no special case anymore. As the members do not exist yet when the channel is created, this commit also: - sets `member_indices` in the channel create, from the member values, instead of computing it from the members. - drops `is_member` from the create rule of discuss.channel (the write rule keeps it). That check never denied a create, since the current user is always added as member. - counts the members of a chat in the channel create, since `_constraint_partners_chat` only runs when `channel_member_ids` is written on the channel. task-4714913