Thursday, September 24, 2026
60 changes · master
Resolved issues and error corrections
Cancelling accounting entries that were still in draft now deletes them instead of creating reversal entries. This avoids recording financial amounts that were never actually posted, especially when periods have already been locked.
Original PR description
_unlink_or_reverse relies on _can_be_unlinked, which only looks at the hash and the lock dates. A draft entry dated in a locked period thus lands in the reversal branch: it is copied, the copy is posted after the lock date and the draft stays behind. The reversal books amounts that were never posted in the first place. Lock dates protect what has been booked. An entry that was never posted can be deleted whatever its date. Seen with hr_payroll_account when a payslip is cancelled after the accountant locked the period without posting the salary entry. Any caller of _unlink_or_reverse (assets, loans, deferred entries) behaves the same. Forward-Port-Of: odoo/odoo#290210 Forward-Port-Of: odoo/odoo#289980
When a Belgian partner's VAT number is changed, the related BCE/KBO identifier is now updated automatically instead of keeping the old value. This keeps business identity data consistent and helps dependent services, such as electronic invoicing endpoints, use the correct information.
Original PR description
Steps to reproduce: * Install **Accounting** module. * Create a Belgian partner. * Assign a VAT number (e.g. BE0477472701). * The BCE/KBO field in Multi ID is correctly populated. * Modify the VAT…
Steps to reproduce:
* Install **Accounting** module.
* Create a Belgian partner.
* Assign a VAT number (e.g. BE0477472701).
* The BCE/KBO field in Multi ID is correctly populated.
* Modify the VAT number.
Observed behavior:
* The BCE/KBO (BE_EN) in Multi ID keeps the old value.
Cause:
* `_deduce_additional_identifiers_from_vat` skipped any identifier key that already existed in `additional_identifiers`: new_identifiers = {k: v for k, v in deduced.items() if k not in identifiers}
* On the first VAT save, BE_EN is written correctly.
* On subsequent VAT changes, BE_EN already exists, so the condition short-circuits and the old value is preserved.
Fix:
* Replace the key-presence guard with a value-equality check so that deduced identifiers are always overwritten when their value would change: updated = {k: v for k, v in deduced.items() if identifiers.get(k) != v}
* Since BE_EN is fully derived from the VAT (it is the VAT with the country prefix stripped), it must always mirror the current VAT.
* The Peppol endpoint is already declared as depending on `additional_identifiers`, so it recomputes automatically once BE_EN is corrected — no further change needed there.
opw-6545770
Forward-Port-Of: odoo/odoo#290348
Forward-Port-Of: odoo/odoo#288057Discuss calls now return to the expected view after a user leaves the meeting layout. This prevents the call from staying stuck on a spotlighted participant when it should show the pinned person, shared screen, chat focus, or tile view.
Original PR description
In the meeting view, the call layouts pick which participant fills the main window from the recent speakers and store it in activeRtcSession. That choice was kept after going back to Discuss (ESC, minimize, or the Discuss layout), so a call that showed tiles stayed in spotlight. Now, when the meeting view closes, the focus is reset to what Discuss would show on its own: the pinned participant, then a shared screen, then the chat window auto-focus, and otherwise the tile view. View in Discuss app (before opening Meeting view) <img width="685" height="245" alt="Screenshot 2026-09-23 at 21 31 09" src="https://github.com/user-attachments/assets/7a915629-3291-4035-9a67-c8cf4045691a" /> View in Discuss app (after leaving Meeting view) <img width="1920" height="641" alt="Screenshot 2026-09-23 at 21 32 31" src="https://github.com/user-attachments/assets/bda7a386-c7a2-4327-ae5a-9f967c716de7" /> Forward-Port-Of: odoo/odoo#290381
Users will no longer receive both an in-app browser alert and a native push notification for the same mention when their Odoo tab is open but not focused. This reduces notification noise and keeps alerts consistent with the user's notification preferences.
Original PR description
Steps to reproduce: - Grant browser notification permission (subscribes to web push). - Set user A's `notification_type` to `inbox` in preferences and reload. - Keep A's tab open but unfocused. - As user B, post an @-mention on a non-channel chatter record targeting A. A receives two alerts: the JS one from the `mail.message/inbox` bus event and the native notification from web push. `OutOfFocusService.notify()` gated JS skip on `message.thread.model`, but the server never sends `mail.thread`, so chatter fell through. Replace it with a `message_type` + `!isSelfAuthored` filter mirroring the server side `_notify_get_recipients_for_extra_notifications`. Also swap the `isInbox` SW handshake workaround added by [1] when the user is busy. [1]: https://github.com/odoo/odoo/pull/232431 Forward-Port-Of: odoo/odoo#290410 Forward-Port-Of: odoo/odoo#282981
This fix ensures amounts in currencies without decimal places, such as Japanese yen, display the full number instead of dropping meaningful zeroes. It prevents confusing monetary summaries like 100 appearing as 1, improving accuracy in financial information shown to users.
Original PR description
Description of the issue/feature this PR addresses: In Odoo 19.0, format_amount(..., trailing_zeroes=False) removes significant integer zeroes when the currency has no decimal places, such as JPY.…
Description of the issue/feature this PR addresses:
In Odoo 19.0, format_amount(..., trailing_zeroes=False) removes
significant integer zeroes when the currency has no decimal places,
such as JPY. Project update monetary summaries use this formatter
with trailing_zeroes disabled.
Steps to reproduce in an Odoo shell with the default JPY configuration:
```python
from odoo.tools.misc import format_amount
currency = env.ref('base.JPY')
format_amount(env, 100, currency, trailing_zeroes=False)
format_amount(env, 0, currency, trailing_zeroes=False)
```
Current behavior before PR:
The numeric part of 100 becomes 1, and the numeric part of 0
disappears. Grouped amounts can also lose digits and leave an
incomplete thousands group.
Desired behavior after PR is merged:
Preserve all integer digits for currencies without decimal places.
Only strip trailing zeroes when a fractional part is present.
Regression coverage includes zero, positive, negative and grouped
amounts, both currency symbol positions, and languages with distinct
or identical decimal and thousands separators.
Validation:
- Before the fix: the new regression test fails in 20 subcases.
- After the fix: all 9 tests in TestFormatAmountFunction and
TestFormatLangDate pass on an isolated PostgreSQL 16 database.
- git diff --check passes.
Test selection:
--test-tags=/base:TestFormatAmountFunction,/base:TestFormatLangDate
This PR also includes my signed Individual Contributor License
Agreement in doc/cla/individual/ysnkucuker.md.
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290374The messaging menu now visually distinguishes non-chat items from regular chats. Notification prompts use an informational blue background, while failure items use a warning color, making the Chats tab easier to understand at a glance.
Original PR description
Failures and "Turn on notifications" are shown in the "Chats" tab. These items are quite different from usual chat, and it's confusing when they look very similar to chats. This commit fixes the issue by putting a background color on the non-chat items: - info (blue) for the "Turn on notifications" - warning (yellow / orange) for the "Failures" items <img width="1927" height="589" alt="Screenshot 2026-09-23 at 20 45 37" src="https://github.com/user-attachments/assets/8e36f956-d9f0-443c-ae0f-9718e7b21d3f" /> Forward-Port-Of: odoo/odoo#290372
Hungarian electronic invoice XML sent to NAV no longer includes cash rounding as a separate invoice line. This keeps reported invoices aligned with Hungarian legal guidance and prevents rounding differences from being treated like taxable goods or services.
Original PR description
Global cash rounding can be applied to customer invoices. Before this commit, the rounding would be included in the XML file sent to NAV. It would be included as a new invoice line (same as the products lines) and the ATK tax is applied on it. As stated in the legal Hungarian Documentation, an invoice line should always relate to the supply of a good or the service provided. In this case, a cash rounding (which is not a financial advantage or disadvantage) will be considered by the law as a settlement difference, that is not part of the invoice. So, this commit removes cash rounding lines from the NAV XML. Moreover, it uses base_lines for the amounts computation instead of line_ids. task-6527383 Forward-Port-Of: odoo/odoo#290375 Forward-Port-Of: odoo/odoo#286258
This fixes reconciliation cases where no exchange difference is needed by ensuring the company currency is used. It helps prevent small remaining balances from being left in company currency after reconciling foreign-currency entries.
Original PR description
When doing reconciliation with no exchange difference, the currency used should always be the company currency. Using foreign currency in that case could leave residual amounts in company currency. task-6582723 Forward-Port-Of: odoo/odoo#289237
The Sales Spreadsheet Dashboard no longer checks for a subscription-related product field that may not exist in this setup. This prevents an error from being logged when users open or edit the sales dashboard, improving reliability without changing dashboard functionality.
Original PR description
Currently an error occurs in the log when the user tries to open dashboard
Steps to Reproduce:
---
1. Install the `spreadsheet_dashboard_sale` module
2. Navigate to Dashboards > Sales Dashboard.
3. Open or click on Edit for the Sales Spreadsheet Dashboard.
Error:
---
`ValueError: Invalid field product.template.recurring_invoice in condition ('recurring_invoice', '!=', True)`
Cause:
---
The recently added commit [1] adds a domain using the
`product_tmpl_id.recurring_invoice` field. However, this field belongs to
the `sale_subscription` module, which is not a dependency of the current module.
Fix:
---
Remove the non-existing `product_tmpl_id.recurring_invoice` field filter from the domain
[1]: https://github.com/odoo/odoo/commit/10fe64e63987b93e42e28cc6fb8319af326ab8be
sentry-7752145163
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290507The mail call settings dialog was adjusted to remove an unwanted visual separator. This keeps the dialog aligned with the updated Frost design and provides a cleaner, more consistent user experience.
Original PR description
The call settings dialog contains a separator that is not desirable with the frost design.
Remove the separator span altogether to keep the dialog consistent with the updated design.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290477The blog page header spacing has been adjusted so it lines up consistently with other website pages such as Shop and Events. This creates a cleaner, more uniform browsing experience for visitors without changing functionality.
Original PR description
The blogs navbar has a top margin (`mt-3`). It was added so the navbar is not too close to the top of the page (before the title was added with commit [1]), but it made it unaligned to other pages navbar, like /shop and /events. This commit removes this margin so all the pages are aligned. [1]: https://github.com/odoo/odoo/commit/5a4d93901ee9a19fb6bf29fdb46bfa68987850f4 Related to task-3083656 Forward-Port-Of: odoo/odoo#290192
Website cards configured with both a link and a background image now remain clickable as expected. This prevents broken navigation on published pages and helps editors use visual card designs without losing link behavior.
Original PR description
**Problem** Clickable cards do not work if they have an image as background. **How to reproduce** Drop a `s_cards_grid` snippet, select a card, enable "Make it clickable", set a URL, then set a background image on the card. Save. The card is no longer clickable. **Why does it happen** When a background image is set, the card gets the `oe_img_bg` class. This class, through `%o-we-background-layer-parent`, sets `position: relative` on every one of its direct children. This is done to keep the background image behind the snippet's own content, but it interferes with the `a.stretched-link` element, making the card not clickable. **Fix** Exclude `.stretched-link` from the children targeted by `%o-we-background-layer-parent`. task-6462339 Forward-Port-Of: odoo/odoo#289620
The Source PO button now appears only on the subcontractor resupply receipt where it is relevant. This prevents unrelated purchase receipts from showing misleading links, helping users identify the correct purchase order in subcontracting workflows.
Original PR description
After a recent change, the smart button for Source POs uses the reference_ids on a stock.picking. This altered the logic to fetch all orders from any picking that has the same reference. However,…
After a recent change, the smart button for Source POs uses the reference_ids on a stock.picking. This altered the logic to fetch all orders from any picking that has the same reference. However, `subcontracting_source_purchase_count` should specifically relate to the resupply of subcontractor picking to their subcontracted purchase order. **Steps to Reproduce:** 1. Enable multi-step routes and subcontracting 2. Unarchive the MTO route 3. Create 4 products Finished Product, A, B, C, and set MTO on both A and B 4. Put 10 units of C in stock 5. Create a BoM for Finished Product using A and B as components 6. Create a subcontracted BoM for B using C as a component 7. Set the purchase vendor for product A as the vendor 8. Set the purchase vendor for product B as the subcontractor 9. Create and confirm a manufacturing order for Finished Product 10. Confirm the POs The two POs are: 1. Purchase Product A from its vendor 2. Subcontract Product B from its subcontractor and use Product C as a component **Current Functionality:** - Product A's receipt has a **Source PO** smart button pointing to the subcontracting PO for Product B (BUG) - Product B's receipt has a **Source PO** smart button pointing to its own PO (BUG) - Product C's picking has a **Source PO** smart button pointing to its own PO **New functionality:** - Product A's receipt has no **Source PO** smart button - Product B's receipt has no **Source PO** smart button - Product C's receipt has a **Source PO** smart button pointing to its own PO opw-6420168 Forward-Port-Of: odoo/odoo#289710 Forward-Port-Of: odoo/odoo#278908
A missing field was restored in the Project task view. This prevents errors when users assign someone to a task, keeping task management workflows running smoothly.
Original PR description
Commit [1] introduced adaptations to the project kanban card and accidentally removed the `project_sharing_portal_user_ids` field, which causes an error when a user tries to assign someone to a task. This commit reintroduces the missing field. [1]: https://github.com/odoo/odoo/commit/d241bd70fe01b51f9cec6cc8140753d14ccd2af8 task-3462435 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290162
This fixes a mobile display issue in Point of Sale where order search filter options, such as Date or Customer, were hidden behind the order list. Mobile users can now choose the correct search field reliably, making it easier to find past orders on small screens.
Original PR description
Steps to reproduce: - Open a PoS session on a small screen (mobile app or mobile browser) - Register at least one order, so the order list is not empty - Go to the Orders screen and type a term in…
Steps to reproduce: - Open a PoS session on a small screen (mobile app or mobile browser) - Register at least one order, so the order list is not empty - Go to the Orders screen and type a term in the search bar Issue: On a desktop the search bar drops down the list of fields to search on (Reference, Receipt Number, Invoice Number, Date, Customer). On a small screen that list never shows up, so the search silently falls back to the first field and there is no way to search by Date or by Customer. Cause: The list is rendered, but painted behind the order list. Under the media-breakpoint-down(sm) block of ticket_screen.scss the order list becomes `position: sticky; z-index: 1`, so a sibling rule raised `.search .fields` to `z-index: 2` to keep the dropdown on top. The `z-1` utility class put on that dropdown in 07f743843830 compiles to `z-index: 1 !important` and overrides the rule. Both elements end up at `z-index: 1` in the same stacking context, and the order list wins the paint order because it comes later in the DOM. Fix: Drop the `z-1` utility and declare `z-index: 2` on `.fields` in the search bar's own stylesheet, which makes the small-screen override in ticket_screen.scss redundant. The stacking of the dropdown now lives in a single place, next to the rest of its styling, so a utility class added to that element cannot silently disable it again. A tour clicks its target element directly and so cannot see a purely visual overlap, which is why the existing MobileTestUi runs of TicketScreen.search() never caught this. The added assertion checks that a suggestion is the topmost element at its own center. opw-6540466 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289082 Forward-Port-Of: odoo/odoo#286983
Company-paid expenses created from a project now apply the project analytic allocation only to the actual expense line, not to balancing lines. This prevents project expense reporting from incorrectly cancelling itself out and gives businesses more accurate project cost visibility.
Original PR description
### Current behavior: Creating a company-paid expense from the Project overview posts a journal entry with the project analytic on both the expense and outstanding lines, so the analytic balance nets to zero ### Expected behavior: Analytic distribution should only be on the P&L (expense) line ### Steps to reproduce: 1. Open a project overview and create a company-paid expense 2. Submit, approve, and post it 3. Open the journal entry: analytic is on debit and credit lines ### Cause of the issue: `project_id` stays in the context after `clean_context` during `_create_company_paid_moves`. With `sale_project`, AML analytic compute then applies the project distribution to outstanding/tax lines as well ### Fix: Removed `project_id` from the context when creating company-paid moves opw-6368848 Forward-Port-Of: odoo/odoo#287299 Forward-Port-Of: odoo/odoo#280256
This fixes an internal data model issue where a non-stored related many-to-many field could incorrectly keep a database relationship. The change helps prevent one custom field from accidentally affecting another when reading related records, improving data consistency for customized Odoo setups.
Original PR description
When we setup a many2many field which is not stored, it must not have a relation. This is already done for nonrelated fields, but we must do it also for related fields. Otherwise, we may have…
When we setup a many2many field which is not stored, it must not have a relation. This is already done for nonrelated fields, but we must do it also for related fields. Otherwise, we may have side-effects like finding sibling fields in 20.0: in the code below, reading categories would fill roles.
```py
model_id = self.env["ir.model"]._get("test_new_api.foo")
fields = [{
"name": "x_partner_id",
"ttype": "many2one",
"relation": "res.partner",
}, {
"name": "x_role_ids",
"ttype": "many2many",
"relation": "res.partner.category",
}, {
"name": "x_partner_category_ids",
"ttype": "many2many",
"relation": "res.partner.category",
"related": "x_partner_id.category_id",
"store": False,
"readonly": True
}]
for f in fields:
f["model_id"] = model_id.id
self.env["ir.model.fields"].create(fields)
env['test_new_api.foo']._fields['x_partner_category_ids'].relation # should be None
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290286
Forward-Port-Of: odoo/odoo#290067This fixes an issue where product images could disappear when importing or creating several variants of the same product at once. Businesses can now rely on bulk product imports to keep images on the product and its variants, reducing manual cleanup after catalog updates.
Original PR description
Steps to reproduce: - Import a product CSV with one row per attribute value ("Product Values" column) and an image URL on every row, or create several variants of the same template in one `create()`…
Steps to reproduce:
- Import a product CSV with one row per attribute value ("Product Values" column) and an image URL on every row, or create several variants of the same template in one `create()` call with an image.
- Open the product: neither the template nor the variants have an image. Products without attribute values imported in the same file are fine.
The import creates all variants of a template in a single batch. The inverse of `image_1920` is applied record by record: the first variant finds no image on the template and writes its image there. Writing `image_1920` on the template invalidates the image cache of every product.product, including the sibling variants being created, whose `image_1920` is protected during the inverse and therefore reads back as empty. The next variant then takes the "clear the image from the template" branch and writes `False` on the template, undoing the first write. Nothing is stored.
Read the value to inverse for every record before writing anything, so the invalidation triggered by the template write cannot change what the following records write.
opw-6545651
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290171
Forward-Port-Of: odoo/odoo#287419Shipment cancellations now send each delivery carrier only the shipments that belong to it. This prevents duplicate cancellation attempts and reduces the risk of carrier API errors or cancelling the wrong shipment.
Original PR description
When cancelling shipments for multiple pickings with different delivery carriers, passing the entire recordset (self) instead of the individual picking to the carrier's cancel_shipment method causes each carrier to receive tracking references that do not belong to it. This results in API errors or silent wrong cancellations at the carrier level, and each shipment being cancelled N times instead of once, where N is the total number of pickings being processed. Forward-Port-Of: odoo/odoo#289809
Fixes an issue where printing labels from the stock allocation report could produce too few labels after partial allocations. The label count now uses the most up-to-date allocation data, helping warehouse teams print the correct number of product labels.
Original PR description
Issue ===== Sometime, when printing product's labels from the allocation report, some labels are missing, the print file doesn't have the right amount. How to reproduce ================ 1. Create a…
Issue
=====
Sometime, when printing product's labels from the allocation report, some labels are missing, the print file doesn't have the right amount.
How to reproduce
================
1. Create a stored product;
2. For this product, create and confirm 3 deliveries (or sale orders):
- 1 for 4 units;
- 1 for 5 units;
- 1 for 6 units;
3. Create and confirm a receipt for 10 units;
4. From this receipt, click on "Allocation" to open the allocation report;
5. In this order, assign:
- 4 units;
- 5 units;
- 1 / 6 units; (Note that 4 + 5 + 1 = 10 units.)
6. Click on "Print Labels" => Only 9 labels are printed.
Cause of the issue & solution
=============================
In the `AllocationReport` `onClickPrintLabels` method, we compute the amount of label to print but this amount was computed based on not correctly updated values.
This commit changes that to base this compute on `productLinesById` which is correctly up to date.
Also, this commit fixes a minor issue by replacing `is_waiting` by `waiting` (when checking move's state) since `waiting` is the right string.
Issue reported during the v 20.0 logistic testing day by VBOL.
Forward-Port-Of: odoo/odoo#289676Stock move references can no longer be edited from list views. This prevents accidental changes to important inventory identifiers and helps keep stock records consistent.
Original PR description
Reference should not be editable in stock move list views Forward-Port-Of: odoo/odoo#290265
This fixes calendar filtering so empty attendee or calendar selections are ignored when building filters. It helps prevent incorrect or confusing calendar results for users working with attendee calendars.
Original PR description
Adds a check when computing filters domain to avoid partner_ids and calendar_id filter. Task-6591658 Forward-Port-Of: odoo/odoo#290199
Time off requests for fully flexible employees now show the correct number of days when the request spans multiple days. This prevents multi-day leave, such as Monday to Friday, from being incorrectly displayed and processed as only one day, while still accounting for public holidays and half-day boundaries.
Original PR description
Steps to reproduce: ------------------------------------ 1. Install Time off module 2. Create New Fully Flexible Employee 3. Click on the Time off smart button 4. Create time off for multiple days…
Steps to reproduce: ------------------------------------ 1. Install Time off module 2. Create New Fully Flexible Employee 3. Click on the Time off smart button 4. Create time off for multiple days (eg. Mon - Friday) Observation: ------------------------------------ Number of days still shows 1 Days. Issue: ------------------------------------ Issue occurs because `work_time_per_day_mapped` returns one interval per day for standard and flexible schedules in multi-day time off requests, so the interval count correctly matches the number of leave days. https://github.com/odoo/odoo/blob/d73e5662a0af7c549008661f743ba5d51f765339/addons/hr_holidays/models/hr_leave.py#L460-L461 However, for fully flexible schedules, it returns a single interval containing the total hours across all days, causing the leave duration to always be computed as 1 day regardless of the actual number of days requested. Solution: ------------------------------------ For fully flexible employees, count the actual calendar days and subtract public holidays when applicable. opw-6060552 Forward-Port-Of: odoo/odoo#255826
This fix improves how Odoo handles searches that exclude certain values, especially when the search follows linked records. Users should see more complete and accurate results when filtering records across sales, inventory, HR, mail, website, and related areas.
Original PR description
Most of the time, when implementing a search method that resolves a
relation, the search method should not support negative operators.
Instead let the ORM inverse correctly the domain.
A domain `[('a.b', op, val)]` when op is negative, we should searh `b`
with the positive operator and negate the domain to have a complete
result.
https://github.com/odoo/enterprise/pull/132619
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#289955Odoo now shows active calls more consistently across the messaging menu, call menu, and member list. This makes it easier for users to recognize when a conversation is in a call, with improved spacing, clearer icons, and better dark mode visibility.
Original PR description
The messaging menu item, the call menu and the member list each showed that a channel is in a call differently. This commit gives them the same call frame and speaker icon, with a stronger frame in dark mode, tucks the messaging menu badge inside the avatar and evens out their spacing and avatar shapes. The messaging menu call participants can only be collapsed from 2 participants on, keeping the toggle room otherwise, and are expanded when reaching that threshold while in the call. <img width="2872" height="908" alt="in-call-hints-full-before-after" src="https://github.com/user-attachments/assets/069a2251-095e-4967-8ad4-cd96030218e9" /> Forward-Port-Of: odoo/odoo#290099
Message cards in the Mail app no longer show extra spacing inside their borders. This makes conversations look cleaner and keeps message content aligned properly with the card edge.
Original PR description
Message cards incorrectly displayed extra padding inside their borders. This commit removes the unnecessary padding so the content aligns properly with the card boundary. **Before/After:** <img width="396" height="146" alt="image" src="https://github.com/user-attachments/assets/8ee0e5a0-54f7-483d-8c25-aa7618263ceb" /> <img width="393" height="129" alt="image" src="https://github.com/user-attachments/assets/620a229e-443f-408c-935d-eff46226a0b5" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290293
New demo databases will no longer show sample SMS and email failure alerts under the administrator account. These demo failures are now assigned to the demo user, keeping administrator demos cleaner while preserving the example failures for users who need to view them.
Original PR description
Before this commit, a new database with demo data shows "SMS Failure: Contact" and "Email Failure: Contact" in the messaging menu of the administrator, which is the user of most demos. This happens because the sms demo messages with a failed notification are authored by the administrator, and the messaging menu lists the failures of the messages authored by the current user. This commit fixes the issue by giving these messages and their notifications to the demo user, so the failures can still be shown by logging in as that user. Forward-Port-Of: odoo/odoo#290191
Starting or joining a meeting call now shows either the permission dialog or the warning popover, not both at once. This reduces visual clutter and makes it easier for users to respond to microphone or camera permission prompts.
Original PR description
Before this commit, permission dialog and the permission warning popover were displayed at the same time. When starting or joining a meeting call this bloated the UI unnecessarily. Before https://github.com/user-attachments/assets/e4faf5ce-b49a-4fee-a01b-990d0f21ff2b After https://github.com/user-attachments/assets/c6da1e02-e694-4c31-ba0d-b92bf1697877 Forward-Port-Of: odoo/odoo#289865
The file viewer toolbar has been updated with a rounded border and clearer disabled icon styling to better match the current visual design. This improves visibility when users preview files and prevents disabled toolbar items from blending with the document underneath.
Original PR description
- rounded + border on toolbar for improved visibility with viewing file - muted icon look instead of opacity on disabled toolbar item, so that this doesn't show viewing file below <img width="2226" height="690" alt="Screenshot 2026-09-22 at 14 45 34" src="https://github.com/user-attachments/assets/d8a1814e-d227-41d9-964b-1c75316ba205" /> _(icon of Reset Zoom is the same as the "before")_ Forward-Port-Of: odoo/odoo#289917
The Discuss app now keeps the New button available in the channel overview, even after all channels have been deleted. This prevents users from getting stuck when they need to recreate or add channels from the kanban view.
Original PR description
Steps to Reproduce : 1. Install Discuss module. 2. Delete all the existing channels. 3. Try to create new channel from kanban view. Observation : New button is disabled on discuss.channel kanban view only when all records are deleted. With one or more records present the button works fine. List view is unaffected as it has no isNewButtonDisabled logic. Cause: KanbanController.isNewButtonDisabled returns true when the view is grouped by a many2one field, has zero groups, and group_create is enabled (defaults to true). discuss_channel_view_kanban uses discuss_category_id (many2one) as default_group_by, so deleting all records empties all groups and triggers this condition. Fix : Add group_create="0" to the kanban arch tag in discuss_channel_view_kanban to break the isNewButtonDisabled condition, keeping the New button always enabled regardless of group count. Forward-Port-Of: odoo/odoo#290131
Chat bubbles in Mail will no longer bounce just because an existing important message count changes or appears when opened. They now animate only when there is a genuinely new important message, reducing unnecessary visual distractions for users.
Original PR description
Before this commit, chat bubbles were bouncing whenever the important counter changed or they were mounted with an important counter. This made the chat bubbles bounce more often than necessary. This commit limits the bounce when transition from newer important counter. This now limits the bounce to when the chat bubble has actually something important and new right now. https://github.com/user-attachments/assets/a19f3742-3e82-4d4d-880c-e6f08e0d0f2e Forward-Port-Of: odoo/odoo#289958
This update adds missing declarations needed by parts of Discuss, Point of Sale, and Restaurant Point of Sale. It prevents runtime errors that could interrupt users while using these areas of Odoo.
Original PR description
* mail,point_of_sale,pos_restaurant This commit adds missing props declarations which cause runtime errors. Forward-Port-Of: odoo/odoo#290303
Several dropdown menus in the web interface have been adjusted to match the Frost redesign. This improves visual consistency and usability in areas such as autocomplete, navigation, company switching, and tag avatar fields.
Original PR description
This commit adjusts missing dropdowns related to the Frost redesign. task-6589485 | Before | After | |--------|--------| | <img width="258" height="291" alt="Screenshot 2026-09-22 at 10 34 49"…
This commit adjusts missing dropdowns related to the Frost redesign. task-6589485 | Before | After | |--------|--------| | <img width="258" height="291" alt="Screenshot 2026-09-22 at 10 34 49" src="https://github.com/user-attachments/assets/3987f460-11fa-4c15-bebf-1482ad4a6b1e" /> | <img width="244" height="311" alt="Screenshot 2026-09-22 at 10 45 31" src="https://github.com/user-attachments/assets/f86793f9-7dfb-4517-a812-0f7bdd91eefd" /> | | <img width="399" height="213" alt="Screenshot 2026-09-22 at 10 46 00" src="https://github.com/user-attachments/assets/0728dddf-f44f-4c47-946d-30a065b84f6a" /> | <img width="402" height="216" alt="Screenshot 2026-09-22 at 10 45 52" src="https://github.com/user-attachments/assets/9c60190e-1808-466e-badb-413025986e95" /> | | <img width="356" height="339" alt="image" src="https://github.com/user-attachments/assets/40372169-80c2-42df-b527-8b0d5479f936" /> | <img width="396" height="330" alt="Screenshot 2026-09-22 at 15 50 19" src="https://github.com/user-attachments/assets/09eaa1ce-fe42-4e1e-b918-0b0c4c84bece" /> | Requires: - https://github.com/odoo/enterprise/pull/132727 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289833
Discuss calls now switch the main view to a newly joined participant when the user was previously alone in an automatic-layout call. This makes one-to-one calls feel more natural while still showing clear feedback when the user is speaking.
Original PR description
Before this commit, when starting a discuss call and being alone in the call with "auto" call layout, the spotlight stayed on self user rather than move to the new participant. This happens because…
Before this commit, when starting a discuss call and being alone in the call with "auto" call layout, the spotlight stayed on self user rather than move to the new participant. This happens because the spotlight in "Auto" mode relies on speaker, and when no one speaks this defaults to oldest participant which is self. However when in this scenario, the most important is seeing the other person as soon as they join. This commit fixes the issue by having spotlight show the other participant. Note that with this change affects the showing that self is talking and other people can hear us, as the lack of showing of the self card means we don't see the talking bars on ouselves. This commit solves this problem by mixing the mic "^" quick settings button with the self talking bar, similarly to the Call Menu. That way, when in a call in the meeting view, this is made very clear when we are self talking at this is properly registered in the call. <img width="1220" height="996" alt="Screenshot 2026-09-23 at 17 55 46" src="https://github.com/user-attachments/assets/a9c1df9a-0f7c-4bac-83e9-f0b5a6219d3d" /> Forward-Port-Of: odoo/odoo#290334
This fixes an issue where some grid views could appear empty after the page content was recreated while already scrolled. The grid now refreshes its displayed rows and columns immediately, reducing confusion and avoiding the need for users to scroll or resize the window to see data again.
Original PR description
See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289997 Forward-Port-Of: odoo/odoo#281721
Image edit and clear buttons now remain visible over light images and in dark mode. Their round shape is also applied consistently across the standard image, avatar, and editor variants, making image management clearer for users.
Original PR description
Before this commit, the edit and clear buttons overlaying an image field sat on a near-white chip that vanished over pale pictures, and that dark mode turned into the same grey as everything around it. Whether you could see them came down to the picture behind them. They were also slightly oval rather than round, because the sizing they relied on only applied to the plain image widget and never reached the avatar or editor variants. This commit makes them readable over any image in both light and dark mode, and hands the shape to the shared circle button style so every variant gets it. task-6578284 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288746
This fixes portal dashboard cards so counters are not shown on the '/my' page when they are not relevant. Business users see a cleaner, more accurate portal experience without misleading numbers on cards.
Original PR description
Purpose ======= Fix the portal card counters which are displayed on the '/my' page even though they shouldn't. Specification ============= Following odoo/odoo#270066 , the precise discuss count have…
Purpose ======= Fix the portal card counters which are displayed on the '/my' page even though they shouldn't. Specification ============= Following odoo/odoo#270066 , the precise discuss count have been displayed on its portal card in a danger badge. The badge is declared in the template with the 'd-none' class, then the JS interaction calls the '/my/counters' route to get the counters and removes this 'd-none' class if the counter is > 0 and if the counter/card should be displayed. The issue is that this 'd-none' class is removed from the 'documentsCounterEl' element which is not necessarily the expected discuss badge. If the card is not the discuss one, the element selector matches the counter meant to be displayed on the card when the portal entry is an 'alert'. Removing the 'd-none' in this case results in cards having their count displayed on them for no reason (they're not alerts nor discuss badge). => Making sure the 'documentsCounterEl' element is the expected 'badge' before removing its 'd-none' class. Task-6584207 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290238
Maintenance request statuses now show as circular indicators in the card-style request view instead of rounded labels. This restores the intended visual cue, making request states easier to scan and consistent with the app design.
Original PR description
Issue Before this Commit: ======================== The maintenance request state is displayed as a rounded pill in the kanban view instead of a circular indicator. <img width="500" height="150"…
Issue Before this Commit: ======================== The maintenance request state is displayed as a rounded pill in the kanban view instead of a circular indicator. <img width="500" height="150" alt="image" src="https://github.com/user-attachments/assets/84fe84ef-ff58-4873-bb73-1f375774f149" /> Steps to reproduce ======================== 1. Open the Maintenance app. 2. Open Maintenance Requests. 3. Observe the maintenance request state. The state is displayed as a rounded pill instead of a circular indicator. Cause of the issue: ======================== In the [PR](https://github.com/odoo/odoo/pull/260098), the view type of maintenance requests was changed from `kanban` to `cards`, but the `MaintenanceRequestStateSelection` component still checks for `kanban` in its `isKanbanOrMobileView` method. As a result, it uses the `rounded-pill` styling instead of the circular styling. After this Commit: ======================== Update the condition to correctly check `card` as the view type, so the maintenance request state is displayed as a circular indicator. <img width="500" height="150" alt="image" src="https://github.com/user-attachments/assets/e01b5898-2ec3-45b3-aa79-f7ed7c8e9e9f" /> Forward-Port-Of: odoo/odoo#290048 Forward-Port-Of: odoo/odoo#289132
The unread message banner in Discuss is now less visually intense when using dark theme. This reduces distraction for users while keeping the banner visible and useful.
Original PR description
Warning alert are very catchy in dark theme, compared to white theme. This made the unread banner far too present in Discuss app in dark theme. This commit mixes the color of alert-warning with black, so that the color matches more closely to the old color palette and matches well with a dark version of the white theme variant. <img width="1968" height="601" alt="Screenshot 2026-09-22 at 18 03 53" src="https://github.com/user-attachments/assets/f4d8847b-29f9-4252-b915-d8a883e43079" /> Forward-Port-Of: odoo/odoo#289983
This update stabilizes an internal Mail test by freezing the test clock at the right moment. It helps prevent false failures in automated testing, improving confidence in release validation without changing user-facing behavior.
Original PR description
Before this commit, the test "CallDebrief: active call uses the current time" could fail on a loaded runbot: ``` [toBeCloseTo] expected values to be close to the given value > Expected: 50 > Received: 49.760 ``` This happens because the mocked date keeps running with the real clock, from the mockDate call at the start of the test until the widget reads DateTime.now() to compute the call duration. The 0.1 margin on the segment width allows less than half a second between the two. This commit fixes the issue by mocking the date and freezing the time right before opening the view, once start() no longer needs the timers. https://runbot.odoo.com/odoo/error/947256 Forward-Port-Of: odoo/odoo#290183
The channel invitation window in Discuss has been visually adjusted to better match the current Frost design. Users will see a cleaner copy-link button, better grouped search suggestions, clearer hover feedback, aligned search icons, and tighter spacing around the invite link.
Original PR description
To match frost design: - copy link button is circled button - suggested items in search are in a single rounded container - hover effect on selected item is clearer - search icons are now alined with search - reduced spacing between "Invite" button and invitation link <img width="2576" height="1066" alt="master-channel-invitation-copy-button-aku" src="https://github.com/user-attachments/assets/a99adb12-7f36-4530-a0eb-19cc90295f37" /> https://github.com/odoo/enterprise/pull/132692 Forward-Port-Of: odoo/odoo#288961
This fix improves how action buttons are arranged in the Point of Sale product screen modal, especially on tablets and screens with unusual proportions. It prevents buttons such as Cancel from appearing awkwardly on their own row or overflowing, making the interface more reliable and easier to use in both portrait and landscape views.
Original PR description
This PR fixes the issue of the Cancel button floating on the last row when the buttons wrap and other overflowing issues. Before this PR, we were targetting the screen's orientation and max-height,…
This PR fixes the issue of the Cancel button floating on the last row when the buttons wrap and other overflowing issues. Before this PR, we were targetting the screen's orientation and max-height, which worked in general but still let a few layout issues through. On tablets the buttons are large and squarish for better touch usability (which has the double function of leaving plenty of space for translations), this makes fitting them within the modal container without overflowing a bit more complex. Instead, we target ranges of the aspect-ratio of the screen and adjust the buttons squarish aspect-ratio and the number of grid columns accordingly. By controlling the grid's columns we're able to tell the last button (the Cancel button) to stretch to full width when needed as well as having a more balanced layout in both landscape and portrait views. task-6235164 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265711
Search fields in Odoo Mail now look clearer and more consistent, with better spacing, aligned action buttons, and improved labels. This makes conversation search and related mail actions easier to recognize and use without changing core behavior.
Original PR description
- space out the search icon and placeholder; - reserve the clear icon room only when it shows; - align primary buttons with the search input height; - label the messaging menu search "Search Conversation"; - make the messaging menu action icons fixed-width. <img width="1408" height="322" alt="search-primary-button-before-after" src="https://github.com/user-attachments/assets/618d3f2c-7aa9-45c2-a6d4-bb46f43da2bf" /> Forward-Port-Of: odoo/odoo#290092
Mail message and composer action buttons no longer show an extra outline when active. This reduces visual clutter and prevents nearby action buttons from appearing to overlap, making the interface cleaner and easier to read.
Original PR description
Active message and composer actions no longer show a button outline. Their opacity already marks them as active, so the outline was only visual noise, and it made adjacent message actions overlap. <img width="1438" height="638" alt="Screenshot 2026-09-23 at 00 49 39" src="https://github.com/user-attachments/assets/58fd104b-44f4-414d-99c8-f215cc15046c" /> Forward-Port-Of: odoo/odoo#290101
Accounting journal codes are no longer limited to seven characters, preventing errors when translated labels become longer in some languages. This removes an old generic restriction so businesses can use localized accounting setups without unexpected validation failures.
Original PR description
Since 20.0, the ORM will raise if the size of a Char field is not respected [1]. Since Journal's field "code" is translated, it can overflow its size of 7 [2] depending on the language. We decide to remove the size constraint on code, since it seems more like a legacy, unjustified constraint. If a country really has a legal constraint on it, it should be handled in the l10n module, not as a generic random constraint. [1]: https://github.com/odoo/odoo/commit/022578d4d6f7406a01a5af7da063e9813bf2ff9b [2]: https://github.com/odoo/odoo/blob/ba824ab3a22a28212171f402e6a54b19e2f847e5/addons/account/models/account_journal.py#L88 Reported by https://github.com/odoo/odoo/pull/289435. Fixes https://github.com/odoo/odoo/issues/289179. Forward-Port-Of: odoo/odoo#289871
This fix prevents a failed permission check on one editor-related channel from stopping all client subscriptions. Users can continue receiving updates from allowed channels, while channels they cannot access are quietly skipped.
Original PR description
`_build_bus_channel_list` should never raise. Otherwise, the entire request is aborted, meaning the client fails to subscribe to *all* channels, including completely unrelated channels. Instead, if a client do not have permission to subscribe to a channel, the channel should just be skipped. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287142
This fixes how journal item reconciliation behaves when an account is not set up for payment reconciliation. The system now uses the company currency and avoids creating unnecessary exchange difference entries, helping keep accounting records accurate.
Original PR description
When reconciling journal items, if one of them is using an account with no payment reconciliation, then the currency of the reconciliation should be the company currency regardless of which currency was used on the items. Also, in that case, no exchange difference entry should be created. task-6582723 Forward-Port-Of: odoo/enterprise#132199
The timesheet timer now prefills with the most recently visited task instead of being blocked by an untouched draft. This prevents employees from accidentally logging time on the wrong task and also supports non-billable tasks when timesheets are allowed.
Original PR description
1. Open a task and open the timer from the systray -> it is prefilled with that task 2. Close the systray, open another task and open the timer again -> it is still prefilled with the first task 3. Open a task, open the timer and click "Create" -> the empty form taking over is prefilled with the task that was just timesheeted Closing the systray saves the form as a draft even when nothing was typed in it, and a draft takes precedence over the task last visited. With this PR, a form is only kept as a draft once the user has edited it, and creating a timesheet consumes the prefill so that the form taking over starts empty. Reopening the systray still prefills the task last visited. Task-6580476 Forward-Port-Of: odoo/enterprise#132176
Opening the lot or serial number generation window no longer crashes when a product has no numbering sequence configured. This helps warehouse users continue barcode operations smoothly even when product setup is incomplete.
Original PR description
When opening the generate lot dialog, there's a traceback when there is no sequence associated with the product. This commit adds the necessairy checks Forward-Port-Of: odoo/enterprise#131917
This fix ensures Colombian electronic invoice XML notes contain only the invoice Terms and Conditions, not the journal technical control key. This keeps DIAN submissions aligned with expected business content and avoids exposing an internal configuration value in customer-facing invoice data.
Original PR description
**Steps to reproduce:** - Install the `l10n_co_dian` module and switch to the CO Company. - Disable `Test environment` and enable `DIAN Demo Mode` in the invoicing settings. - Set a `Technical…
**Steps to reproduce:** - Install the `l10n_co_dian` module and switch to the CO Company. - Disable `Test environment` and enable `DIAN Demo Mode` in the invoicing settings. - Set a `Technical control key` on the `Customer Invoices` journal. - Create and confirm an invoice with Terms and Conditions. - Send the invoice to `DIAN`. - Open the generated XML file and observe the `cbc:Note` tag. **Observation:** The `Note` tag contains the `technical control key`. **Expected behavior:** The `Note` tag should only contain the Terms and Conditions value from the invoice. (Confirm with PO [1]) **Root Cause:** At [2] and [3], the code includes the `technical key` in the `Note` tag. [1]: https://www.odoo.com/mail/message/1164671931 [2]: https://github.com/odoo/enterprise/blob/a5f4bde1aa33ea7b796d7ee3f9d713a6c8ab8348/l10n_co_dian/models/account_edi_xml_ubl_dian.py#L664 [3]: https://github.com/odoo/enterprise/blob/a5f4bde1aa33ea7b796d7ee3f9d713a6c8ab8348/l10n_co_dian/models/account_edi_xml_ubl_dian.py#L1600-L1603 opw-6513843 Forward-Port-Of: odoo/enterprise#132831 Forward-Port-Of: odoo/enterprise#131495
Employees in Belgium can now choose a company bike even when they use the mobility budget. This fixes an incorrect restriction and aligns the salary package options with legally allowed benefits.
Original PR description
When you take the mobility budget, it doesn't allow you to take a company bike. This should be possible as it is legally possible Forward-Port-Of: odoo/enterprise#132567 Forward-Port-Of: odoo/enterprise#132405
Appointment calendar views now display all appointment bookings, even when the current user is not directly part of them. This restores the previous behavior and prevents teams from seeing empty or incomplete calendars after the multi-calendar update.
Original PR description
With the new multi-calendar feature, calendar views in the appointment app also used the calendar filter to show events. This proved to be a regression compared to the old view where we could see other appointments, even if the user wasn't part of it. This commit brings back this behavior by displaying all appointments. Task-6591658 Forward-Port-Of: odoo/enterprise#132742
This update prevents Odoo Studio from crashing when users create a new app and select the map view from the Views tab. It ensures the view setup opens reliably, helping users continue configuring their app without interruption.
Original PR description
In a new app in studio tab "views" ; click on map view. Before this commit there was a crash because of some props not correctly defined After this commit there is no crash Forward-Port-Of: odoo/enterprise#132783 Forward-Port-Of: odoo/enterprise#132608
This fix improves searches that exclude certain records, so teams get more accurate results when filtering out items in Helpdesk, Planning, Sales-related planning, skills reporting, and Kenyan e-invoicing product data. It helps prevent misleading lists or reports caused by negative search conditions not being applied correctly.
Original PR description
https://github.com/odoo/odoo/pull/289955 Forward-Port-Of: odoo/enterprise#132619
This update fixes several Shop Floor interface inconsistencies and adds easier access to barcode reference sheets. It helps manufacturing teams work more smoothly by making the work order screen clearer and related barcode guidance easier to find.
Original PR description
Fix some Shopfloor UI and had link to barcodes demo and action sheet. Task-6574839 Forward-Port-Of: odoo/enterprise#132566
This update adds missing component settings in Planning Field Service, Social, Social Twitter, and Web Studio. It helps prevent runtime errors that could interrupt users while working with planning views, social posts, or report editing.
Original PR description
* planning_field_service,social,web_studio This commit adds missing props declarations which cause runtime errors. Forward-Port-Of: odoo/enterprise#132795
This update corrects configuration issues that could cause internal component errors in the Knowledge article index and O-Box remote debugging tools. It removes outdated inputs and ensures required settings are provided, helping these features run more reliably without changing user workflows.
Original PR description
See commit messages for details. - Runbot [947332](https://runbot.odoo.com/odoo/runbot.build.error/947332) - Runbot [947371](https://runbot.odoo.com/odoo/runbot.build.error/947371) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#132734
This fix removes an outdated length limit on journal codes in several import and order-processing areas. It prevents errors when translated or localized journal codes are longer than expected, helping accounting imports and platform order handling work reliably across languages and countries.
Original PR description
*: l10n_fr_fec_import, pos_platform_order Since 20.0, the ORM will raise if the size of a Char field is not respected [1]. Since Journal's field "code" is translated, it can overflow its size of 7 [2] depending on the language. We decide to remove the size constraint on code, since it seems more like a legacy, unjustified constraint. If a country really has a legal constraint on it, it should be handled in the l10n module, not as a generic random constraint. [1]: https://github.com/odoo/odoo/commit/022578d4d6f7406a01a5af7da063e9813bf2ff9b [2]: https://github.com/odoo/odoo/blob/ba824ab3a22a28212171f402e6a54b19e2f847e5/addons/account/models/account_journal.py#L88 Reported by https://github.com/odoo/odoo/pull/289435. Fixes https://github.com/odoo/odoo/issues/289179 Forward-Port-Of: odoo/enterprise#132591
A WhatsApp-related automated test was updated to match a small change in the channel invitation button. This helps keep quality checks reliable without changing the user experience.
Original PR description
The "Invite" button of the channel invitation no longer has a title attribute, as it duplicated the button label. Target it by its text instead. https://github.com/odoo/odoo/pull/288961 Forward-Port-Of: odoo/enterprise#132692
The Luxembourg reports module now uses a working download link for the FAIA schema file. This prevents failed or empty downloads when users need the required file for Luxembourg reporting compliance.
Original PR description
The old link points to a file with zero bytes. opw-6344914 Forward-Port-Of: odoo/enterprise#132582