Sunday, August 23, 2026
15 changes · master
Enhancements to existing features
Discuss now lets meeting participants convert a meeting into a dedicated group chat so the conversation can continue after the meeting ends. The change also improves notification visibility for important messages and limits who can change certain channel display settings to owners and administrators.
Original PR description
This commit adds an action in Discuss to convert a meeting into a group chat, allowing participants to continue the conversation in a dedicated group chat after the meeting. It also adds a check when writing `default_display_mode`, ensuring that only channel owners and database admins can update it. Task-6470475 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Email invitations to chat channels are now shown immediately as pending members, so users can confirm invites were sent without waiting for guests to join. This makes external email invite behavior more consistent with invitations sent to internal and portal users.
Original PR description
Currently, when a guest is invited via email, they only appear in the members list after they click 'Join Channel' in the invitation email. This can leave users unsure if the invitation was successfully sent. It also differs from internal or portal users, who appear in the list immediately after being invited. This commit adds a pending member entry for each invited email, making invitations visible in the members list as soon as they are sent. The pending member entry is automatically updated with the correct guest and email information once the guest record is created or updated. task-5409239 <img width="245" height="355" alt="image" src="https://github.com/user-attachments/assets/424fbb77-a114-4052-9a9a-dc1185fe151a" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When the field service planning stock module is installed, stock lot information is now calculated for upcoming shifts and shifts in the current week that have a customer. This helps users see the expected stock details on recent schedules right away, avoiding confusion when checking this week's work.
Original PR description
Before this commit, when the module `planning_field_service_stock` is installed, `_compute_lot_ids` in planning.slot model will only be triggered for all shifts in the future with a state in draft and a customer set. That condition is a bit annoying since the user could think the feature does not work if he checks a shift the first day of the week. This commit reviews the condition to compute lot_ids for all shifts in the future or in the current week if those shifts have a customer set to make sure the lot_ids is computed for the most recent shifts. task-6470210
This update adjusts performance test expectations for Knowledge following related Discuss changes around meeting chats, channel settings permissions, and important notification counters. It helps keep automated validation aligned with the expected system behavior while supporting smoother post-meeting collaboration and clearer notifications.
Original PR description
This commit adds an action in Discuss to convert a meeting into a group chat, allowing participants to continue the conversation in a dedicated group chat after the meeting. It also adds a check when writing `default_display_mode`, ensuring that only channel owners and database admins can update it. Additionally, this commit adds a new `important_notification` message subtype to display the notification counter in Discuss when an important notification is received. Task-6470475
Resolved issues and error corrections
This fixes a crash when Odoo converts work-hour values that round up to the next hour, such as 16.9959 becoming 17:00. It helps prevent errors in business processes that rely on computed or aggregated time values, while keeping normal time conversions unchanged.
Original PR description
### Bug `odoo.tools.date_utils.float_to_time` builds the minutes with a rounding step: ```python return time(int(integral), int(float_round(60 * fractional, precision_digits=0)), 0) ``` When the…
### Bug
`odoo.tools.date_utils.float_to_time` builds the minutes with a rounding step:
```python
return time(int(integral), int(float_round(60 * fractional, precision_digits=0)), 0)
```
When the fractional part of the hour is high enough, `round(60 * fractional)`
rounds up to a full **60**, and `time(hour, 60)` is invalid:
```python
>>> float_to_time(16.9959)
ValueError: minute must be in 0..59, not 60
>>> float_to_time(8.999)
ValueError: minute must be in 0..59, not 60
```
Any hours value whose fractional part is ≥ ~0.9917 hits this — which happens
easily with computed/aggregated work-hour floats.
### Fix
Carry the rounded-up minute into the hour, and return `time.max` when that carry
reaches the end of the day (mirroring the existing `hours == 24.0` case):
```python
if minute == 60:
hour += 1
minute = 0
if hour >= 24:
return time.max
```
`float_to_time(16.9959)` now returns `time(17, 0)`, `float_to_time(23.9959)`
returns `time.max`, and regular values are unchanged.
Adds `TestFloatToTime` in `test_date_utils.py` covering the carry, the
end-of-day carry, and regular values.
Forward-Port-Of: odoo/odoo#280807The tooltip for the Sales Order Expiration field was rewritten to fix a grammar issue and make the wording more natural. This improves clarity for sales users when they review or create quotations and sales orders.
Original PR description
Steps to produce: --- - Install the Sales module. - Create a new Sales Order. - Hover over the `Expiration` field. Issue: --- - The help text of the Expiration field contains a grammatical error and the overall sentence is slightly awkward. Improve the help text to make it grammatically correct and more natural. opw-6481226 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283845 Forward-Port-Of: odoo/odoo#283187
Refunded point-of-sale down payments are now handled correctly when a sale order is settled or invoiced. This prevents customers from being invoiced again for an amount that was already refunded, keeping invoice totals and invoiced amounts accurate.
Original PR description
The following commit resets qty_invoiced to zero on sale order lines paid by a POS order when that order is refunded. https://github.com/odoo/odoo/commit/ac39aa4f68dfc77011c39e468e3f60e0338a3c69…
The following commit resets qty_invoiced to zero on sale order lines paid by a POS order when that order is refunded. https://github.com/odoo/odoo/commit/ac39aa4f68dfc77011c39e468e3f60e0338a3c69 However, it does not handle the sale order line created for a refunded POS down payment. That line keeps `qty_invoiced` = -1, which causes the refunded amount to be included again when settling or invoicing the sale order. Steps to reproduce: - Create a sale order. - Pay a down payment through the POS. - Refund the down payment order from the POS. - Settle the remaining amount from the POS or invoice the sale order from the backend. Result: - The generated invoice includes the sale order total plus the refunded down payment. - Sale order `amount_invoiced` will be the down payment amount. Fix: - Delete the refunded downpayment to match the sale flow. - Include refunded down payments in the amount_invoiced computation. opw-6378891 Forward-Port-Of: odoo/odoo#283308 Forward-Port-Of: odoo/odoo#278011
This fixes an issue where customer sale order line lookup could fail when project task billing filters included list-based values. The change preserves existing caching while ensuring the original search criteria are used correctly, improving reliability for timesheet-related sales workflows.
Original PR description
- Avoid converting list values in `_get_last_sol_of_customer_domain` to an invalid domain structure when computing the last sale order line of a customer. - Fix by using `str(domain)` as the cache key instead of the domain itself, while still passing the original `domain` to `search()`. This keeps the per-domain caching behavior intact and works for any domain, regardless of whether it contains list values. task-6425335 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281897
Overtime calculations now avoid counting a shift that ends exactly at midnight as part of the next day. This prevents incorrect overtime adjustments when employees have multiple attendances on the previous day and improves payroll-related accuracy.
Original PR description
When recomputing overtime, attendances overlapping the affected day are retrieved based on their check-in and check-out. An attendance whose check-out is exactly at the start of the following day is…
When recomputing overtime, attendances overlapping the affected day are retrieved based on their check-in and check-out.
An attendance whose check-out is exactly at the start of the following day is currently considered to overlap that day because the domain uses an inclusive lower bound on `check_out`.
This can cause overtime from the previous day to be recomputed using an incomplete set of attendances.
### Steps to reproduce:
* Configure an employee with a daily quantity overtime rule based on the expected hours from the contract.
* On the first day, create multiple attendances, with the last one ending exactly at midnight.
* Ensure the total worked hours on that day result in overtime.
* On the following day, create another attendance.
* Observe that recomputing the second day's overtime also retrieves the attendance ending at midnight.
* The previous day's overtime is then recomputed without the other attendances from that day, resulting in an incorrect overtime value.
* Regenerating the overtime ruleset restores the correct value.
For example, with 8.4 expected hours:
```
Day 1:
09:30 - 11:30
14:30 - 18:19
21:00 - 00:00
Day 2:
create/update an attendance
```
The `21:00 - 00:00` attendance is incorrectly included in Day 2's recomputation because its check-out equals the start of Day 2. The other Day 1 attendances are not included, so Day 1 is recomputed from only 3 hours of work.
To fix the issue we treat `check_out` as an exclusive interval boundary when determining overlap. An attendance ending exactly at the start of a day does not overlap that day, while attendances actually crossing midnight continue to be included.
opw-5474120
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#283894
Forward-Port-Of: odoo/odoo#283226Saudi Arabia POS receipts now embed the ZATCA QR code directly, preventing blank codes on first print from Safari and iPhone browsers. The QR code size was also adjusted so it is easier to scan on printed receipts while keeping the preview appropriately sized.
Original PR description
Fixing the QR code size and Robustness for ZATCA. 1. The QR code is now an embedded image SVG instead of an image fetched from the server, which makes it robust against Webkit quirks. 2. We set the QR size in the preview screen to 200px (back to what it was before https://github.com/odoo/odoo/pull/277813), and we make the QR size on the physical receipt 300px so it's big enough to be scanned easily. More info in the respective commit messages. opw-6399766 Forward-Port-Of: odoo/odoo#282637 Forward-Port-Of: odoo/odoo#282285
The mail composer now safely ignores Escape and arrow-key presses in the “Continue with Full Composer?” popup instead of triggering an error. This prevents a user-facing crash when returning to a draft note in the chatter, improving reliability for everyday communication workflows.
Original PR description
Reproduction steps: - Open a record that has a chatter where you can log notes - Start logging a note in the composer - Close the composer - Click log note again - See "Continue with Full Composer?" popup - Hit escape, up, or down - See traceback This shouldnt really do anything, so this fix makes it do nothing instead of crashing. opw-6476660 Forward-Port-Of: odoo/odoo#283389 Forward-Port-Of: odoo/odoo#282803
Message history now shows tracked date and time changes using the current user's timezone instead of falling back to UTC. The display format is clearer across languages and locations by matching the usual date-time field style and including the timezone.
Original PR description
Although the code was attempting to render the tracking values in the current user's timezone. It did not work. While fixing this, we also wanted to make the time clearer in multi-language/timezone settings: - Date(time) is now formatted in the same way it is for datetime fields in the frontend - The timezone is added after it, so we know exactly what time is meant - Those two fields are reprocessed in the chatter so that we simply show them in the user's locale task-6456370 Forward-Port-Of: odoo/odoo#283819 Forward-Port-Of: odoo/odoo#281769
Mentions in sub-channels now work correctly when a contact is linked to more than one active user. This prevents an error that could block administrators and ensures the contact is invited when at least one linked user allows channel notifications.
Original PR description
Before this commit, mentioning a partner that has two active users in a sub-channel ended on: ValueError: Expected singleton: res.users.settings(77, 80) This happens because the channel notification setting is read through res_users_settings_id, a Many2one on res.users, so two users give two settings records and reading a value on them asks for a singleton. Only an administrator reaches it, as the res.users.settings rule limits everyone else to their own settings. This commit fixes the issue by inviting the partner as soon as one of its users did not turn channel notifications off. Forward-Port-Of: odoo/odoo#283912 Forward-Port-Of: odoo/odoo#283805
This fixes an issue where switching between chatter filters could incorrectly show an empty result even when messages existed. Users will now see the correct messages when changing filters, improving reliability in communication views.
Original PR description
Previously, when a chatter filter returned no messages, the empty search term was kept as the last empty term. As every empty term starts with an empty term, switching to another filter could incorrectly skip the next fetch and leave the filter empty. This PR ensures that empty results are only remembered for non-empty search terms, so switching between chatter filters always fetches the appropriate messages. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281980
Fixed an issue where unselecting a Timesheet Assistant suggestion could leave the previous project or task selected. This prevents timesheets from being created with outdated project details when users switch between suggestions.
Original PR description
Steps to reproduce: ------------ - install timesheet_grid. - activate assistant. - select a suggestion and then unselect it. - select a different project suggestion. Issue: ----------- the project from the previous suggestion remains selected. cause: --------- currentRecord is not reset when a suggestion is unselected, so the previous suggestion's project and task are still reused. Fix: --------- reset currentRecord to null when the suggestion is unselected and showCreateForm is false. Effected pr-https://github.com/odoo/enterprise/pull/126450 task-6482312 Forward-Port-Of: odoo/enterprise#128374