Thursday, August 14, 2025
24 changes · saas-18.3
New functionality added to Odoo
New automated tests were added for the restaurant appointment point-of-sale flow. This helps ensure table, session, and appointment data continue to work reliably when future changes are made.
Original PR description
This commit adds hoot test for the pos_restaurant_appointment module.
Enhancements to existing features
Draft invoices no longer show outstanding credit or debit messages when the related payment widget is already hidden. This keeps the invoice screen consistent and reduces confusion for users reviewing draft accounting documents.
Original PR description
Before this commit: --- Draft invoices can be reconciled with payments via the Bank Reconciliation screen, but the Outstanding Payments widget is hidden to avoid confusion. However, outstanding credits/debits messages were still displayed on draft invoices, leading to inconsistency. In this commit: --- Updated the form to hide outstanding credits/debits messages when the invoice is in draft, making the behavior consistent. Before: --- <img width="1258" height="298" alt="image" src="https://github.com/user-attachments/assets/376b3799-e721-4bd6-bf9c-cb56ca02bb5f" /> After: --- <img width="1258" height="257" alt="image" src="https://github.com/user-attachments/assets/374e33d5-c406-44c1-9309-40c124b45451" /> task-4987833 Forward-Port-Of: odoo/odoo#221680
Resolved issues and error corrections
This fix makes automated checks for live chat session opening more reliable by skipping an unstable navigation step. It helps prevent false test failures while ensuring live chat sessions still open the correct conversation view.
Original PR description
The `test_session_history_open`, in later versions renamed `test_form_view_embed_thread`, ensures that clicking on a live chat session in the list view opens the thread, not the default form view. To do so, we first access the `/web` url, then open the command palette, and finally find the correct live chat view. However, such tests are known to be non-deterministic as the command palette is not always available at the start of the tour. Several live chat tours have been updated to directly access the view, providing the correct URL to `start_tour`: command palette part of the tour is meaningless. fixes runbot-161482 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
Code cleanup and technical improvements
The accounting module was reorganized so tax total rounding is handled in its own reusable part. This makes it easier for localized or custom extensions to adjust rounding behavior without copying larger accounting logic, reducing maintenance risk.
Original PR description
Move the code block responsible for rounding `total_per_tax` aggregates inside `_round_base_lines_tax_details` into a dedicated helper method `_round_total_per_tax`. This refactor allows custom modules to override only the rounding logic without reimplementing the entire `_round_base_lines_tax_details` method, improving maintainability. Related: https://github.com/OCA/l10n-japan/pull/70 @qrtl QT5088 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222759
Adds automated test coverage for the HR-related point of sale flows, including cashier login, navigation, payments, cash movement, and order handling. This helps reduce regressions and improves reliability for businesses using employee-based POS operations.
Original PR description
This commit introduces HOOT test coverage for the pos_hr module: - Added tests for primary model :patched pos.order - Added tests for patched pos_store.js. - Added component tests for Navbar, CashPopup, PaymentScreen, LoginScreen task-4945630
This update improves the Italian electronic invoicing setup by preventing an immediate error when users duplicate a document type. It makes the duplicate action more user-friendly while still helping avoid duplicate document codes.
Original PR description
In https://github.com/odoo/odoo/commit/3e557745f16c33ab3c1b5984d6297913a8849024, we added a contraint to avoid same code. The "issue" with that is that the Duplicate option instantly raises the constraint. It's not really user-friendly. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222611 Forward-Port-Of: odoo/odoo#218933
The follow-up process now checks related accounting entries in a clearer and more precise way. This reduces the risk of internal query confusion and helps keep partner follow-up information reliable without changing the user experience.
Original PR description
Refactored the SQL construction for checking the existence of related account.move records for res.partner entries. The account.move query is now built separately and referenced explicitly, making the code more readable and reducing the chance of ambiguity in field resolution. Using `SQL.identifier(query.table, "id")` ensures that the correct table is referenced in each condition, which is particularly important when dealing with multiple joins or subqueries. Forward-Port-Of: odoo/enterprise#90304 Forward-Port-Of: odoo/enterprise#83770
This fixes an error that occurred when users duplicated several Point of Sale configurations from the list view at the same time. Businesses can now copy multiple POS setups without interruption, making store setup and administration smoother.
Original PR description
### Steps to reproduce the issue: 1) In the Point of Sale app, when trying to duplicate more than two records from the list view, it gives a singleton error. The implementation was added to the master branch from commit [1]. [1]: https://github.com/odoo/odoo/pull/92664/files#diff-4c6e412c7d8f4df2a05831547e7df93d0b91f510d03b7b3ed0d689a18f5dae44R360-R361 opw-4969713 ### Description of the issue/feature this PR addresses: #### Issue Previously, when duplicating more than one pos.config record, it would give a singleton error. #### Solution Added a for loop to iterate over the config records individually. ### Current behavior before PR: https://github.com/user-attachments/assets/ba5a3969-7647-4943-a0b1-12b1961f26cd ### Desired behavior after PR is merged: https://github.com/user-attachments/assets/b952b711-7782-4e9d-b05a-e4019ab79d87 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220452
This fixes unstable automated checks for website live chat ratings by waiting until the chat message is fully saved before verifying it. It helps prevent false test failures and supports more reliable delivery of live chat functionality.
Original PR description
The website live chat rating tours share common steps, among them, the `start` steps. Those steps check if the first message is not duplicated by: - Waiting for the `.o-mail-Thread` selector. -…
The website live chat rating tours share common steps, among them, the `start` steps. Those steps check if the first message is not duplicated by: - Waiting for the `.o-mail-Thread` selector. - Checking if there is only one message. - Adding a class to this message if that is the case. - Adding a step that looks for the added class. This approach is flawed because: - The thread will be persisted once the first message is sent. If the class is added to the transient message but the next assertion runs after persistence, the message with the class is no longer in the DOM. - The class can be overridden if the message re-renders before the next assertion. - There is no guarantee the message is in the DOM when executing `queryAll`. There is no reliable way to check the state before persistence because the thread may change between "trigger" and "run". This commit updates the assertions to ensure the message is sent correctly and no duplicates exist once the thread is fully persisted. fixes runbot-229822 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 fixes an intermittent automated test failure in Point of Sale where product variants could be selected too quickly before the screen refreshed. The change improves confidence in testing for barcode-based product selection without changing day-to-day user behavior.
Original PR description
This fixes a random runbot failure in the barcode search test involving product variants. The issue was caused by timing problems when selecting a second variant of a product with the same template…
This fixes a random runbot failure in the barcode
search test involving product variants.
The issue was caused by timing problems when selecting a second variant of a product with the same template name. Due to UI delays, the wrong variant could be selected.
The issue happened in this sequence:
- The test searched the first barcode (12341357), which correctly
displayed the product template "Product with Attributes" with the
variant (Value 1, 3, 5, 7) preselected.
- The product was added successfully.
- Then the second barcode (12342468) was searched. But before the UI
had time to update
and reflect the new variant (Value 2, 4, 6, 8), the test clicked
again on the same product template — which still had the *first*
variant preselected.
- As a result, the first variant was added twice, and the expected
second variant was missing.
To prevent this, a distinct product template ("Product without Attributes") was introduced between the two variant searches to give the UI enough time to refresh. The tour was also updated to properly wait for the correct product to appear and to avoid triggering the configurator on products without attributes.
runbot-230339
Forward-Port-Of: odoo/odoo#222631
Forward-Port-Of: odoo/odoo#222335This fixes a validation issue where certain legitimate nested view customizations were incorrectly shown as faulty in the interface. It helps prevent false error warnings for valid customizations, reducing confusion for administrators and developers working with Odoo views.
Original PR description
Have an arch that will move a subchild of a parent effectively replacing the parent ```xml <data> <xpath expr="/form/div/div" position="replace"> <xpath expr="/form/div/div/span" position="move" /> </xpath> </data> ``` Before this commit, the move xpath was marked as faulty in the IrUiView's form in the interface. After this commit, the xpath is not marked as invalid, because it is not. read `@def apply_inheritance_specs` to get a grasp on the supported semantics for xpaths arch. opw-4965869 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
Portal users can now open purchase orders even when an ordered product has no image. The purchase order page skips the missing image instead of showing an error, improving reliability for customers and suppliers using the portal.
Original PR description
In the purchase order portal template (`purchase.purchase_order_portal_content`), `image_data_uri(line.product_id.image_128)` was called without checking if the product had an image, leading to a rendering error when `image_128` is False. Steps to reproduce the bug: - create a product without an image - create a purchase order with that product - partner: portal user (e.g joel) - connect as portal user - go to the purchase order - the portal view will raise an error because it tries to render an image Solution: Added a conditional check to only render the `<img>` tag if the product image exists, preventing template evaluation errors. opw-5013230 Forward-Port-Of: odoo/odoo#222769
The website theme switch loader now shows progress correctly every time a user changes themes. This prevents confusion during repeated theme changes by ensuring the loading indicator restarts properly instead of appearing frozen.
Original PR description
__Current behavior before commit:__ When switching a theme, the website loader is displayed with a progress bar. When the operation is finished, the loader is hidden and the progress bar interval is cleared. However, the variable holding the interval ID is not being reset. If the user switch theme a second time, the `initProgressBar` method doesn't start a new interval because its initial guard finds the old interval ID and exit prematurely. This resulted in the progress bar appearing to be stuck. __Description of the fix:__ This commit fixes the issue by removing the initial guard of the `initProgressBar` method. __Steps to reproduce:__ 1. Open the Website builder 2. Click on the "Theme" tab 3. Click on "Switch Theme" 4. Choose a Theme 5. The loader is progressing 6. Do every steps again 7. The loader is stuck at the beginning Forward-Port-Of: odoo/odoo#218356
This fix allows Odoo's template engine to handle longer expressions correctly when running on newer Python versions. It prevents certain pages or reports from failing due to internal expression-size limits, improving reliability without changing user workflows.
Original PR description
Not entirely clear why it was apparently excluded, but apparently in 3.13 some qweb expressions require the use of `EXTENDED_ARG`. Specifically [1] makes the expression long enough that it needs at least one "long jump" which then requires an `EXTENDED_ARGUMENT`, here's the sizes for the expression in question in various Python versions: - 3.10: 102 bytes - 3.11: 188 bytes - 3.12: 214 bytes - 3.13: 272 bytes Thus it makes sense at at some point the earliest jumps in the expression (and `and`/`or` *are* jumps, since they're short-circuiting) would become "long". These increases in size can be due to a multitude of factors e.g. changes in inline cache details (3.11 and above), jumps becoming strictly typed and requiring `TO_BOOL` instructions (3.13), ... [1]: https://github.com/odoo/odoo/commit/cc68a012649f9eb331265deba3197abaf1700d97#diff-92dda03d204cc6ea8b7aacd0c07939843c83b1841f4a3049903844777d83c07bL154-R223 Forward-Port-Of: odoo/odoo#222939
The employee work address section now displays the state, city, and zip fields in a consistent horizontal alignment. This small layout fix makes the form easier to scan and helps users enter address details more clearly.
Original PR description
Task ID: 5002920 Description of the issue/feature this PR addresses: Align state, city, and zip fields horizontally on employee form Current behavior before PR: Not alignment in tab Employee > Work address as per fields state, city, and zip Desired behavior after PR is merged: Fields aligned
This fix updates the Time Off test setup so it archives existing leave types instead of deleting them when demo data is present. This prevents automated nightly builds from failing due to existing linked leave records, improving confidence in test results without changing user-facing behavior.
Original PR description
### Root cause: - We were using .unlink() before, but it throws error if a hr.leave.type is linked with any hr.leave. ### Fix: - Instead of unlink we will archive the record task: 4925370 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an automated test for employee time-off accruals by ensuring all date-sensitive checks run against a fixed date. It helps prevent false test failures caused by the current calendar date, improving release reliability without changing user-facing behavior.
Original PR description
Given that accrual plans are related to dates, all the testcase logic has to be inside 'with freezetime' to avoid date related errors Runbot-error: https://runbot.odoo.com/odoo/runbot.build.error/230722 Forward-Port-Of: odoo/odoo#222854
This fix ensures simulated time settings used in testing are applied only to the selected database. It prevents unintended effects on related databases, such as logging databases, making test behavior more reliable and safer.
Original PR description
Filtering the postgres database was not enough, the log_db was also affected. Since only the order was impacted, this was creating strange side effect in databases like the log-db where it was only modified when the function exists. Checking the -d is more reliable and safer to avoid any side effect when testing with faketime. Forward-Port-Of: odoo/odoo#222805
This change adjusts an automated test for public discussion channels so it no longer depends on a page reload that caused inconsistent failures. It helps keep quality checks stable without changing the experience for end users.
Original PR description
This test suspiciously fails in various ways in all versions before the following PR: https://github.com/odoo/odoo/pull/214358 This seems to indicate an issue with the page reload. Properly wait for the page to reload before proceeding with the next steps in the tour, hoping it will resolve all the related issues. https://runbot.odoo.com/odoo/error/111051 https://runbot.odoo.com/odoo/error/223165 https://runbot.odoo.com/odoo/error/227755 https://runbot.odoo.com/odoo/error/227756 https://runbot.odoo.com/odoo/error/227757 https://runbot.odoo.com/odoo/error/227758 https://runbot.odoo.com/odoo/error/229657 https://runbot.odoo.com/odoo/error/229724 https://runbot.odoo.com/odoo/error/229745 https://runbot.odoo.com/odoo/error/229817 https://runbot.odoo.com/odoo/error/230901 Forward-Port-Of: odoo/odoo#222876 Forward-Port-Of: odoo/odoo#222825
This fix makes an internal automated test for bus notifications run consistently by ensuring the test setup is ready before notifications are triggered. It helps reduce false test failures in the development pipeline without changing user-facing behavior.
Original PR description
This commit fixes the `test_postcommit` that fails in a non deterministic fashion. This test ensures bus notifications created in the post commit hook result in only one batch. To do so, the test listens on the connection with a selector. However, the main thread doesn't wait for the selector to be register before triggering the postcommit hook. This commit ensures the test waits for the selector to register the database connection before going further. runbot-77470 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 Forward-Port-Of: odoo/odoo#222810
Updates internal mail tests so they wait properly for background responses before checking results. This reduces false failures in automated checks, helping keep releases moving without affecting end users.
Original PR description
These tests were failing due to `expect.verifySteps()` being empty rather than the RPC response. The rpc response is asynchronous and awaiting the click doesn't necessarily mean the RPC had time to effectively happen, especially when runbot CPU load is high. Fixes runbot-error-160954 Forward-Port-Of: odoo/odoo#222839
French tax reports now compare totals using proper rounding instead of exact decimal matching. This prevents reports from incorrectly flagging matching amounts as different because of hidden decimal precision differences.
Original PR description
Currently, the code was checking for a strict equality between two sums. However, it may happen that there are many decimals that aren't displayed on the UI, hence the strict equality check fails. For instance `30201.63 != 30201.629999999997`. Instead, we now use the `float_compare` which takes care of rounding issues. opw-5000147 Forward-Port-Of: odoo/enterprise#92356
This fix updates an internal subscription test so it no longer depends on the calendar year in which it runs. It helps keep automated quality checks reliable across time, reducing false failures without changing customer-facing behavior.
Original PR description
Before this commit, when test_uninvoiced_upsell_close_log was launched in a year different than 2025, it would fail with the following error: ``` File…
Before this commit, when test_uninvoiced_upsell_close_log was launched in a year different than 2025, it would fail with the following error:
```
File "/data/build/enterprise/sale_subscription/tests/test_sale_subscription.py", line 2085, in test_uninvoiced_upsell_close_log
action = subscription.prepare_upsell_order()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1042, in prepare_upsell_order
action = self._prepare_renew_upsell_order('7_upsell', upsell_msg_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1012, in _prepare_renew_upsell_order
order = self._create_renew_upsell_order(subscription_state, message_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/test_sale_subscription/models/sale_order.py", line 228, in _create_renew_upsell_order
order = super()._create_renew_upsell_order(subscription_state, message_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 998, in _create_renew_upsell_order
values = self._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/project_sale_subscription/models/sale_order.py", line 40, in _prepare_upsell_renew_order_values
res = super()._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/partner_commission/models/sale_order.py", line 72, in _prepare_upsell_renew_order_values
values = super()._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1182, in _prepare_upsell_renew_order_values
raise UserError(_('You cannot create an upsell for this subscription because it :\n'
odoo.exceptions.UserError: You cannot create an upsell for this subscription because it :
- Has not started yet.
- Has no invoiced period in the future.
```
runbot-task-230716
Forward-Port-Of: odoo/enterprise#92307This fix prevents users from selecting bank reconciliation widget models in places where they cannot work correctly, such as model selectors in Knowledge properties. It avoids errors and tracebacks when those non-stored internal models are used by features that expect regular database-backed records.
Original PR description
To reproduce this issue, just try to perform a name_search/search_count/etc.. on `BankRecWidget` for example: - Example of Steps in Knowledge: - Open knowledge - Create an article - Create another article in the first one (child) - Add a properties - Select `Bank reconciliation widget` in Model - Traceback `BankRecWidget` and `BankRecWidgetLine` use ```py _auto = False _table_query = "0” ``` to avoid being stored in db. This kind of model doesn't work with several methods of the model api, such as `search_count`, `name_search` etc... This commit will add a models blacklist via ir_model._is_valid_for_model_selector opw-4763713 Forward-Port-Of: odoo/enterprise#90060 Forward-Port-Of: odoo/enterprise#88352