Tuesday, September 1, 2026
13 changes · saas-18.3
Enhancements to existing features
The mail module now formats warranty communication data in a standard JSON format before sending it to the warranty server. This helps ensure the server can reliably read the information and reduces the risk of processing errors.
Original PR description
Format the publisher warranty message using json.dumps() instead of Python's native str() representation. This ensures serializeid JSON serialization for the payload sent to the warranty server. Forward-Port-Of: odoo/odoo#285632 Forward-Port-Of: odoo/odoo#283139
Resolved issues and error corrections
Mobile invoice line cards now show the line description when no product is selected. This prevents blank cards and makes invoices easier to review on mobile devices.
Original PR description
Invoice lines can be created without a product. However, the mobile kanban view does not handle such lines properly and displays an empty card without a name or image. This commit adapts mobile kanban view to show invoice line's name when `product_id` is not set. Before | After -- | -- <img width="469" height="277" alt="image" src="https://github.com/user-attachments/assets/3b367581-b73d-4b12-a487-1a54c3b88470" /> | <img width="406" height="300" alt="image" src="https://github.com/user-attachments/assets/107d7294-90e8-49c6-826a-9be75c6b799f" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285608 Forward-Port-Of: odoo/odoo#284755
An internal accounting test now uses a currency that already has the required rounding behavior, instead of changing Hungarian forint settings during the test. This prevents false test failures in Hungarian localization scenarios and helps keep accounting releases stable.
Original PR description
The test forced HUF rounding to 1.0, which fails under l10n_hu once HUF has accounting entries. This commit Uses JPY, which already has coarse rounding, instead. [error-946580](https://runbot.odoo.com/odoo/error/946580) Forward-Port-Of: odoo/enterprise#130013
Polish bank account verification no longer crashes when checking several partners where some are missing a VAT number or bank account. This lets users complete checks for valid partners without being blocked by incomplete records in the same batch.
Original PR description
When we check for multiple partners with some valid and some being incomplete (no vat or no bank account), a traceback is raised This was due to a bracket accessor, changed into a get in this commit. no-task Forward-Port-Of: odoo/odoo#285631
The mail reply box now handles Escape key presses more reliably when mention suggestions or the emoji picker are involved. This prevents dismissed suggestion lists from reopening and interfering with closing replies or popups, reducing frustrating interruptions for users.
Original PR description
Two independent causes made "reply: discard on pressing escape" red, one commit each. "[FIX] mail: wait for the mention suggestions before Escape" is the one that fixes the reported failure, and it holds on every branch: the test presses Escape while the mention fetch is in flight, and the suggestions arriving from the server re-open the list that Escape closed, so the re-opened list takes the second Escape and the reply is never discarded. The test now waits for the fetched suggestions before pressing Escape. "[FIX] mail: keep the suggestion list closed on a re-render" backports "[FIX] mail: keep composer suggestion list closed on unrelated re-render", which entered at 19.0 and never came down. Here NavigableList is re-opened on every patch, so opening the emoji picker after Escape brings the dismissed list back, and it then steals the Escape meant for the picker. https://runbot.odoo.com/odoo/error/946314 Forward-Port-Of: odoo/odoo#284725
French PDP invoice responses are now sent through a single appropriate channel instead of duplicating the reply through both PDP and classic Peppol. This reduces duplicate chatter messages and avoids unnecessary confusion while keeping the response process clear.
Original PR description
When responding to an invoice received through PDP, 2 responses were actually sent: one through PDP and the other through the 'classic' Peppol. This was done to allow more reliability, in case one channel is down when trying to respond, but this mainly creates cluttah' in the chattah' (call me busta rhymes yo) task-6522652 Forward-Port-Of: odoo/odoo#285596
This fix prevents slow simulated taps in mobile web tests from being mistaken for long presses. It reduces random test failures around saving HTML mail content, helping keep automated quality checks stable without changing end-user behavior.
Original PR description
Before this commit, MobileWebSuite.test_unit_mobile failed at random on the mail test "HtmlMail add icon and save inline html", which taps the save button of an html_mail field and waits for the…
Before this commit, MobileWebSuite.test_unit_mobile failed at random on the mail test "HtmlMail add icon and save inline html", which taps the save button of an html_mail field and waits for the write:
[verifySteps] expected the following steps
> Expected: [
"web_save",
]
> Received: []
This happens because a tap held longer than `LONG_TAP_DELAY` counts as a long press, and `_pointerUp` then dispatches no click at all. That delay spans the synthetic pointerdown and pointerup of a single `click()`, so the work a listener does during the press counts towards that delay: tapping save blurs the html field, which converts the whole editor content to inline styles, and under the load of a runbot build that conversion alone takes longer than the delay.
One solution could have been to raise `LONG_TAP_DELAY`, but a listener slower than the new value suppresses the click again.
This commit counts a tap as long only when the test releases the pointer itself, with `pointerUp`, so the work a listener does during a `click()` no longer suppresses the click.
https://runbot.odoo.com/odoo/error/946581
Forward-Port-Of: odoo/odoo#284971This fixes an issue where one timed-out mail test could continue running checks and incorrectly cause many later tests to fail. The change keeps automated test results cleaner and helps developers identify the real source of failures faster.
Original PR description
Before this commit, one test contains() reaching its 10 seconds budget made the 129 tests that ran after it fail with its own assertion, over 14 suites:
[HOOT] Test "@mail/message/link_preview/Delete all link previews at
once" failed:
Failed assertion:
3. [toBe] expected values to be strictly equal (Failed to find 1 of ".o-mail-Message-body:text(...)" (Timeout of 87 seconds). Found 0 instead.)
This happens because the tick re-schedules itself on the result of runOnce(), which is undefined on a failure, the crashing one included. The check keeps selecting every 500ms and logs its assertion against whichever test is running, until a tick lands between two suites and getFixture() throws.
This commit re-schedules a tick only while the check is not done, so the crashing one is the last.
https://runbot.odoo.com/odoo/error/946650
Forward-Port-Of: odoo/odoo#285585This fix changes the order of test cleanup reporting so memory information is logged before the final test result is sent. It prevents failed web test runs from showing an additional misleading error, making build failures clearer and easier to diagnose.
Original PR description
Before this commit, a build whose unit tests suite fails collects a second runbot error on top of the real one: odoo.addons.web.tests.test_js.WebSuite.test_unit_desktop.browser: Error received after…
Before this commit, a build whose unit tests suite fails collects a second runbot error on top of the real one:
odoo.addons.web.tests.test_js.WebSuite.test_unit_desktop.browser:
Error received after termination: [MEMINFO] tests done (after GC)
- used: 220535896 - total: 341990868 - limit: 4395630592
Note that the figures themselves are fine (220MB used of a 4.4GB limit): the error is not about memory, only about when the line is logged.
This happens because the runner logs that line after `stop()`, and `stop()` is what reports the suite result: the server settles the test on that report and kills the browser. The final major GC outlasts the report. A passing build escapes because the browser dies within milliseconds; a failing one stays up for the screenshot, long enough for the GC to finish and the line to land after termination.
This commit fixes the issue by moving `stop()` after the final cleanups and their memory log: the [MEMINFO] line is still logged, but before the result report, while the server still waits on the browser.
https://runbot.odoo.com/odoo/error/229655
Forward-Port-Of: odoo/odoo#284957This fix prevents web test runs from hanging until a long timeout when required test dependencies fail to load. Instead, the failure is reported immediately, helping teams get clearer build results and reducing wasted waiting time in automated checks.
Original PR description
Before this commit, a unit test suite could go silent between two test files, and `browser_js` then waited out its whole timeout before failing with:
[ERROR] TypeError: Failed to fetch
at orm (web.assets_unit_tests.min.js)
FAIL: WebSuite.test_unit_desktop
AssertionError: Script timeout exceeded
This happens because `fetchDependencies` gives every addon a `Deferred` that only the success handler of the batched `all_dependencies` call resolves, and a loaded runbot host answers that call with `RuntimeError: can't start new thread`. Nothing then settles those deferreds, so the `Promise.all` waiting on them never returns, `stop()` is never called, and the browser holds the build until the timeout.
This commit rejects the deferreds of a failed batch and reports an error escaping `runTests` on the console, so the build fails on the fetch error instead of running out its timeout.
https://runbot.odoo.com/odoo/error/243504
Forward-Port-Of: odoo/odoo#284980The Kenya e-invoicing form now hides the validation message area when there is no message to show. This removes an unnecessary blank space in the invoice form, making the screen cleaner and easier to read.
Original PR description
When there is no validation message, an empty div causes a whitespace gap between the header and the sheet in the form view. This commit adds `invisible="not l10n_ke_validation_message"` to the div to prevent this issue. Forward-Port-Of: odoo/enterprise#129364 Forward-Port-Of: odoo/enterprise#129318
The Frontdesk app now explicitly includes a required scheduling component so it can install correctly in setups that skip automatic dependencies. This prevents installation failures in more selective deployment configurations.
Original PR description
Installation of this module fails in single-app skip auto-install. Gantt is not a valid root element in views when web_gantt isn't installed. There is no error on other builds because of the auto-install dependency using the following chain; [frontdesk] ──[depends]──> [hr] ──[depends]──> [web] ──⚡[AUTOLOAD]──> [web_gantt] This change needs forward porting to v19. saas-19.1 already has a fix. REF Runbot; https://runbot.odoo.com/odoo/error/237890 Forward-Port-Of: odoo/enterprise#128592
The Mexican point-of-sale self-invoicing test was adjusted to match the updated process where public users can no longer edit existing customer details. This keeps automated checks aligned with the current, safer customer data flow and helps prevent false test failures.
Original PR description
Ref commit: https://github.com/odoo/odoo/commit/cbc572de17c4519f764b411d1e6dc2b407b8479c Before the ref commit: -------- - Public users could update customer data during the self-invoicing flow. - The `test_qr_code_receipt_mx` test relied on this behavior when updating customer data. After the ref commit: -------- - Public users can no longer update customer data during self-invoicing. - Update `test_qr_code_receipt_mx` to create a new partner with the required customer data when the order is not linked to a customer. Related PR: https://github.com/odoo/odoo/pull/283470 Task-6272660