Tuesday, July 7, 2026
19 changes · saas-19.4
Enhancements to existing features
This update adds automated checks to ensure emails can be properly traced when a new coupon is generated from a helpdesk ticket. It helps protect customer service workflows by reducing the risk of unnoticed regressions in coupon-related communication tracking.
Original PR description
Added tests for email traceability when generating a new coupon in a ticket --- task-6341030
Desktop notifications will no longer be forced onto a single line, so longer messages can display more of their content. This makes important alerts, such as style compilation errors, easier to read and understand at a glance.
Original PR description
Before this commit, on screens wider than the medium breakpoint, notification messages were force-clamped to a single line via a `--lines-clamp: 1` override, hiding the rest of the text for longer messages, such as the "Style error" notification shown when SCSS compilation fails. After this commit, the single-line override is removed so notifications fall back to the default 2-line clamp. task-6037796
The mailing form now places the Exclusion List option inline with the Recipients and Dynamic Lists fields for a more consistent layout. It also hides the Dynamic Lists section when no dynamic list has been set, reducing visual clutter and making the form easier to use.
Original PR description
This commit moves the Exclusion List checkbox to be inline with the Recipients and Dynamic Lists fields. This commit also hides the Dynamic Lists div if the mailing is sent while no dynamic list has been set. task-6321624
Odoo now shows cleaner VAT/Tax ID placeholders and a clearer tooltip when editing customer details. When the expected VAT format is known, users will see an example format; otherwise the field stays empty, reducing confusion and making the guidance easier to understand.
Original PR description
In this commit: - Remove 'or not applicable' and '/ if not applicable' from VAT placeholders. - Display the expected VAT format when available (e.g. BE0477472701). - Leave the placeholder empty when no format is known. - Simplify the tooltip to: 'You can use / to indicate that the customer has no Tax ID.' task-[5005896](https://www.odoo.com/odoo/project/967/tasks/5005896) Forward-Port-Of: odoo/odoo#274578 Forward-Port-Of: odoo/odoo#273344
Resolved issues and error corrections
The planning test flow now closes a side panel that could hide split shift items and cause unreliable results. This keeps the weekly planning checks stable, including when they run on Sundays, helping prevent false failures during quality checks.
Studio's XML editor no longer applies website default-language translations when editing non-website views. This prevents business documents and other views from unexpectedly showing translated XML content just because Website is installed.
Original PR description
Problem: When opening the Studio XML editor when Website is installed, the translation terms corresponding to the Default Language of the first website in the database are used. This behavior should…
Problem: When opening the Studio XML editor when Website is installed, the translation terms corresponding to the Default Language of the first website in the database are used. This behavior should only be applied to the HTML/CSS Editor in Website. Purpose: Modify Website's override of get_related_views to only return translated views when called with a specific website in context. This is done here by adding a context flag, as to not interfere with customizations made in stable versions. This will be changed for master. Steps to Reproduce in Runbot: 1. Activate a non-English (US) language. 2. Add this language to the Website with the lowest ID in the database, then set it to the Default Language of the Website. 3. While in debug mode, enter Studio and navigate to a view that has translation terms (ex. Sale Order Form view), then open the XML editor. opw-5136124 Foward Port of https://github.com/odoo/enterprise/pull/110418 Forward-Port-Of: odoo/enterprise#116771
Fixed an error that appeared when users clicked the AI button while sending a signature request. The AI helper now uses the right interaction mode for Sign templates, so users can continue preparing and sending documents without interruption.
Original PR description
Version: saas-19.3 Steps to Reproduce: 1. Open a sign template and click "Send" 2. Click the AI button in the wizard Issue: Clicking the AI button raises ValueError: "The record must inherit from 'mail.thread'". Cause: `sign.template` does not inherit `mail.thread`, but interfaceKey `mail_composer` requires it. Fix: Added `get interfaceKey()` to `MailComposerChatGPT` so subclasses can override it. `SignAIButton` in `sign_ai` overrides interfaceKey to `html_field_record`. Taskid: 6303226 Forward-Port-Of: odoo/enterprise#120659
The outstanding payments widget on invoices now lists payments consistently by the most recent date and related record first. This reduces confusion for accounting users when reviewing open invoices and matching payments.
Original PR description
Before this commit: The invoice outstanding payments widget was not sorted by date globally, which could lead to confusion for users when viewing the widget. After this commit: This commit adds a sorting mechanism to ensure that the payments are displayed in descending order based on their date and ID. opw-6254080 Forward-Port-Of: odoo/enterprise#122964 Forward-Port-Of: odoo/enterprise#121642
IoT device logs sent to the server are now recorded at a lower severity level. This reduces unnecessary alerts and Sentry usage from noisy device connection issues, helping teams focus on meaningful problems.
Original PR description
Each time IoT box sends its logs to the server (route `/iot/log`), we then print them with the same log level. However, IoT box logs can be quite noisy (for instance when there are some connection issues), which affects the logs. Sentry side, it also implies a huge wave of useless events that reach the limits of our subscription. The logs management have been improved on next versions. In the meantime, we should at least decrease the logger level so we can keep working on Sentry Forward-Port-Of: odoo/enterprise#122426
The Journal Audit PDF report no longer adds an empty final page when the global tax summary section is not included. This prevents confusing or unprofessional-looking report output for accounting users.
Original PR description
Steps to reproduce: 1. Set the active company as My Company (san francisco) 2. Navigate to Accounting > Review > Journal Audit 3. Remove all journals from the report except Bank and Misc. 4. Use the PDF action button to print the report. 5. The last page of the report is completely empty. https://drive.google.com/file/d/1otpniJgt1UNCe2hrUBwqIK58dGuXpu8T/view?usp=sharing This commit ensures that the Journal Audit report does not have blank pages when the global tax summary section is not present. It uses some features of QWeb outlined in the following docs article: https://www.odoo.com/documentation/19.0/developer/reference/frontend/qweb.html#loops opw-6224670 Forward-Port-Of: odoo/enterprise#122704 Forward-Port-Of: odoo/enterprise#121068
The webhook URL field is now constrained so it no longer stretches beyond its container in the form view. This prevents the nearby renew button from being covered or difficult to click, improving the usability of the page.
Original PR description
Before this commit, the webhook URL field could overflow in the form view, causing the adjacent renew button to become partially or fully unclickable. This commit fixes the issue by allowing the copy clipboard URL field container to shrink properly within layout, so the URL is truncated as intended and the renew button remains accessible. task:6317827 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272019
The Timesheets kanban cards now keep the year in the date display on a single line, even when the card contains a long project, task, or description. This improves readability and prevents the date from breaking awkwardly on crowded cards.
Original PR description
Steps to reproduce:
-
1. Open the Timesheets app and display "All Timesheets" in kanban view.
2. Use a record whose project, task, or description is long enough to take up most of the card's width.
3. Look at the date shown on the left side of the kanban card.
Issue:
-
The year is split over two lines (e.g. "202" / "6") instead of staying on a single line.
Cause:
-
On the kanban card, the date is rendered in a small left-hand column split into two lines ("MMM d" and "yyyy"). That column has no `flex-shrink-0`, so when the description and the hours/avatar footer compete for space, the flex layout shrinks the date column until the year no longer fits and wraps.
Fix:
-
Add `flex-shrink-0` to the date column so it keeps its natural width.
task-6330852
Forward-Port-Of: odoo/odoo#271992This change fixes an unreliable test in the dropshipping stock flow that could pass or fail for the wrong reason. It makes the validation timing consistent so product cost updates are checked against the intended values, reducing false build failures and improving confidence in stock valuation behavior.
Original PR description
The below test sometimes fail for an incorrect reason and leads to a false positive:…
The below test sometimes fail for an incorrect reason and leads to a false
positive:
https://github.com/odoo/odoo/blob/6dbeac3a42f46b42c638c05aea8285452c944c3f/addons/stock_dropshipping/tests/test_purchase_order.py#L21
Here is another way to reproduce the issue with a higher probability of
false positive (and it is actually easier to read and understand what the
test is doing and what's wrong). It needs to edit the following test:
https://github.com/odoo/odoo/blob/ec58c5e12987401659ea0d75d3be2905ad1d807d/addons/purchase_stock/tests/test_create_picking.py#L953
With the below diff:
```diff
--- a/addons/purchase_stock/tests/test_create_picking.py
+++ b/addons/purchase_stock/tests/test_create_picking.py
@@ -965,6 +965,7 @@ class TestCreatePicking(ProductVariantsCommon):
'price': 500.0,
'discount': 10,
})]
+ self.product_id_1.standard_price = 1.0
po = self.env['purchase.order'].create(self.po_vals) # create a PO for 5 units
po.button_confirm()
with Form(po) as po_form:
```
It will lead to:
```
Traceback (most recent call last):
File ".../test_create_picking.py", line 976, in test_average_cost_updated_after_po_with_discount
self.assertEqual(self.product_id_1.standard_price, 450.0)
AssertionError: 1.0 != 450.0
```
Here are the explanations: when receiving an AVCO product, at some point, we
recompute its standard price. To do so, among several operations, we take
the last manual update, and we ignore all previous SM:
https://github.com/odoo/odoo/blob/2dbd88657395da965125c8f085da93e04c9c8f0a/addons/stock_account/models/product.py#L463-L465
This is an issue when things are done too quickly. See the pattern:
```py
self.product_a.standard_price = 5.0 # -> define valuation_from_date
po.confirm() # with another cost
receipt.button_validate() # -> define move.date
```
In case of a fast execution, both dates will be equal. We therefore ignore
the SM and rely on the manual update to define the standard price, which is
not expected. This explains the above `AssertionError`.
Fixing the codebase is quite tricky since the opposite use case could also
happen, aka first processing a receipt and only then modifiying the standard
price.
Tests side, a more important solution should probably be implemented to ease
their redaction and avoid this basic pattern. Yet, a WIP task is changing
the valo for Odoo 20, so the whole logic may change. Second, the current
issue is impacting a lot of builds, so we need to move forward. For both
reason, the commit only "fixes" the current test.
runbot-939955
Forward-Port-Of: odoo/odoo#273820
Forward-Port-Of: odoo/odoo#273078This change fixes an intermittent test failure in the messaging bus by making the subscription wait logic more reliable. It ensures the test only proceeds once the correct server-side response has been processed, avoiding false matches with unrelated background notifications.
Original PR description
`test_subscribe_to_new_channel_with_higher_id` sometimes fails. This happens because we only have one test cursor, with no lock preventing two threads from fighting over it: - `trigger_notification_dispatching` calls `precommit.run()`, which creates `bus.bus` records. - Processing an incoming `subscribe` message server-side also acquires a cursor. This means the test thread must always wait for those operations to complete before proceeding. `subscribe` already has a guard meant to wait until its own request has been processed. However, it's too naive: any dispatch that happens after we call `subscribe` is treated as the response to our request, while in practice it can be caused by an unrelated `NOTIFY` that was already in flight. runbot-243463 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix corrects how the web profiler reads component data, preventing an error when the profiler is enabled. As a result, users can turn on profiling without the page failing due to missing values.
Original PR description
Enabling the profiler results in an error because the template attempts to access component values without `this`, which resolves to undefined. This commit fixes the issue by updating the problematic cases to use `this`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The work entries export wizard now closes correctly when users click Cancel or Discard. This makes the export flow behave as expected and avoids confusion when backing out of the action.
Original PR description
Version: - saas-19.4 Issue: - The Cancel (Discard) button in the work entries export wizard does not close the wizard as expected. Fix: - Added special="cancel" to ensure the wizard closes correctly when the Cancel button is clicked. Task-6365691
This update fixes a website logout problem that could trigger a session error when users clicked the logout button in the preview. It also adjusts an automated website signup test so it works reliably without requiring manual configuration, improving test stability.
Original PR description
### Commit 1: [FIX] website: prevent CSRF error by blocking duplicate form submission Before this commit: Clicking the logout button from the website preview triggered two simultaneous logout…
### Commit 1:
[FIX] website: prevent CSRF error by blocking duplicate form submission
Before this commit: Clicking the logout button from the website
preview triggered two simultaneous logout requests:
1. The browser performed the default form submission with a valid
`csrf_token`, destroying the session afterward.
2. During the same click event, `setupClickListener()` intercepted
the click using `closest('[action]')`, found the parent
`/web/session/logout` form, and triggered a second POST request
using `odoo.csrf_token`.
Since the session was already destroyed by the first request, the
second request resulted in a "CSRF validation failed" error.
This commit prevents the default form submission before triggering
the manual POST request, ensuring that only one request is sent.
Runbot-940403
--------------------------------------------------------------------------------------------------------------------------------
### Commit 2:
[FIX] website: enable free sign up setting in test_auth_forms_warning
Steps to reproduce:
1. Install any website related module (e.g. `website`, `website_event`).
2. Keep the default configuration and do not manually enable
'Free sign up' in Settings.
3. Run `test_auth_forms_warning`.
Before this commit: The test did not programmatically enable the
'Free sign up' setting. As a result, it failed unless a developer
manually navigated to the setting and enabled it beforehand.
After this commit: This commit explicitly enables the "Free sign up"
configuration during test execution, allowing public access to the
`/web/signup` page and ensuring the test passes without any manual
setup.
runbot-940394
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#274115
Forward-Port-Of: odoo/odoo#272020This update corrects an automated test for the QFpay payment terminal so it matches the current payment flow. It helps keep the test suite reliable and prevents false failures after recent changes to terminal behavior.
Original PR description
In odoo/odoo#270240 we removed the automated "send" call on payment terminals, but the test for pos_qfpay wasn't updated in the fw port. This commit fixes by adding a call to "send" in the test. Forward-Port-Of: odoo/odoo#274316
This update prevents link suggestion boxes from overflowing the screen when users type a URL on mobile devices. It improves the link editing experience by keeping the suggestions within the visible area, making the interface easier to use on smaller screens.
Original PR description
Step to reproduce: - Open Notes - Open the link popover - Type a URL in the URL input field Description of the issue/: - On mobile devices, URL autocomplete suggestions overflow the viewport. Cause: - The autocomplete suggestions container has a max-width of 600px. - On smaller screens, the container does not shrink to fit the available width, causing it to overflow the viewport. Solution: - Add width: 100% to the autocomplete suggestions container so it adapts to the available screen width on smaller devices while still respecting the existing max-width on larger screens. task-6201175 Forward-Port-Of: odoo/odoo#271925 Forward-Port-Of: odoo/odoo#269493