Friday, June 27, 2025
46 changes · saas-18.4
Enhancements to existing features
This change re-enables an automated test for the website image gallery that had been paused after updates to the website builder. It helps ensure image gallery behavior continues to work reliably in future changes, with no direct change for end users.
Original PR description
`test_07_image_gallery` test was disabled after the new website builder changes. This commit re-enables this test. 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
Resolved issues and error corrections
This fix prevents the website builder from failing when a site has no social media links configured. Users can now edit social media snippets normally on new or minimal databases, avoiding an error that interrupted page editing.
Original PR description
Steps to reproduce: - On a database without demo data (and no social links set) - Open website builder in debug - Click on a social media snippet (by default there is one in footer) - Traceback: Validation of props failed because of a `false` value for input text The implementation for the options of snippet `s_social_media` (made in the website builder refactor) did not correctly handle the case where there is no record and the server returns the `false` value instead of a string. Website refactor: 9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2 task-4367641
Code cleanup and technical improvements
This change makes automated tour tests fail when a page reload or redirect is not declared in advance. That reduces flaky test behavior and helps keep customer-facing flows such as point of sale, website sales, events, and blogs more stable during development.
Original PR description
In this commit, we uncomment the listener on beforeUnload to ensure that expectUnloadPage is correctly used in tours. From now on, if a step produces a page unload but didn't declare it, the tour will fail with an Error. This forces step producing page reload/redirect to declare them, s.t. the tour stops after that step, waiting for the next page to be loaded to continue. This is done to remove non determinism in tours. 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
Miscellaneous changes
Current behavior before PR: - The remove icon was visible to all users, even those who not have access rights.  Desired behavior after PR is merged: - Only users with group `im_livechat_group_manager` could remove a livechat operator.  task-id:[4781704](https://www.odoo.com/odoo/project/1519/tasks/47
Original PR description
Current behavior before PR: - The remove icon was visible to all users, even those who not have access rights.  Desired behavior after PR is merged: - Only users with group `im_livechat_group_manager` could remove a livechat operator.  task-id:[4781704](https://www.odoo.com/odoo/project/1519/tasks/4781704) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#213990
The website editor now safely handles rapid repeated clicks on the remove slide button. This prevents a page crash and keeps carousel editing stable for users.
Original PR description
__Current behavior before commit:__ When pressing on Remove slide button twice rapidly the page crashes because it tries to access the closest `.carousel` element on a slide that has already been removed from the DOM. __Description of the fix:__ - Prevent calling `removeSlide` if the slide has already been removed from the DOM. - Add a test to check the remove slide behaviour.
This fix updates the live chat test mock server so it includes the same member type information used by live chat features. This helps prevent test gaps and reduces the risk of live chat behavior breaking when features depend on member roles or types.
Original PR description
Mock server was missing `livechat_member_type`, which can lead to issues when JS features are `livechat_member_type` aware.
This fix stabilizes an automated test for the image cropping feature in the HTML editor that was failing unpredictably. It helps keep quality checks reliable so future changes can be validated with fewer false failures.
Original PR description
After merging the commit [1] the test case is non-deterministically gets failed on runbot. This commit aims to fix the test case. [1]: https://github.com/odoo/odoo/commit/7ab5d4df393e9adf6736c60945197c174149be6a --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Several screens and documents now correctly translate user-visible wording that was previously left in the source language. This improves localization consistency across payment, sales, timesheet, recruitment, loyalty, and settings experiences for users working in other languages.
Original PR description
Content passed to a t-value directive is not translated. This commit redefines as text nodes human-readable content that was incorrectly placed in a t-value, so that it is now translated. *: pos_online_payment, sale_timesheet, web, website_hr_recruitment, website_payment, website_sale_loyalty Enterprise: https://github.com/odoo/enterprise/pull/88666
Spreadsheet dashboard filters now show selected text and boolean values in a more readable way. This makes dashboards easier to understand by displaying choices like “text1 or text2” and “Is set or Is not set” instead of raw comma-separated values.
Original PR description
… boolean filters Steps to reproduce: 1. Configure a spreadsheet dashboard with a text filter and a boolean filter. 2. Set these filters to at least two values. => Boolean filter is displayed as `true,false` instead of `Is set or Is not set` => Text filter is displayed as `text1,text2` instead of `text1 or text2` To ease the testing, the function `getFacetFor` has been moved to a helper (it's already the case in master). This commit also adds a test for the others filters (relation and date). Task: 4900910 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 untranslated wording in the project budget area by placing user-facing text where the translation system can detect it. Business users working in other languages should now see the affected labels or messages translated correctly, improving consistency for multilingual teams.
Original PR description
Content passed to a t-value directive is not translated. This commit redefines as text nodes human-readable content that was incorrectly placed in a t-value, so that it is now translated. Community: https://github.com/odoo/odoo/pull/216136
The website builder's internal action handling was simplified so plugin registration now manages how actions run. This should make the builder easier to maintain and extend, with no expected change for end users aside from improved reliability in related tests.
Original PR description
*: website This refactor centralizes the responsibility of binding BuilderAction methods (`apply`, `prepare`, `isApplied`, etc.) into the builder plugin registration logic, instead of having them bound within the BuilderAction constructor. It simplifies the BuilderAction class and gives the plugin more control over instance behavior, improving flexibility and future extensibility. Minor fix in builder button test included.
This update makes automated website sales and rental checkout tests stricter when a page reload or redirect happens. By requiring those transitions to be declared, the tests become more predictable and reduce flaky validation results for future releases.
Original PR description
In this commit, we uncomment the listener on beforeUnload to ensure that expectUnloadPage is correctly used in tours. From now on, if a step produces a page unload but didn't declare it, the tour will fail with an Error. This forces step producing page reload/redirect to declare them, s.t. the tour stops after that step, waiting for the next page to be loaded to continue. This is done to remove non determinism in tours.
Network scan/analysis tools can be useful when debugging configurations., so we added `arp-scan` and `mtr`. Forward-Port-Of: odoo/odoo#216164 Forward-Port-Of: odoo/odoo#216058
Original PR description
Network scan/analysis tools can be useful when debugging configurations., so we added `arp-scan` and `mtr`. Forward-Port-Of: odoo/odoo#216164 Forward-Port-Of: odoo/odoo#216058
Technically, using `odoo-bin` without `-i` and `-u` for database with `to upgrade` module was wrong before 18.2, which will skip some upgrade processes/checks in `loading.py`. From 18.2 If there are `to upgrade`, `to install` or `to remove` modules in the database `odoo-bin` without `-i` and `-u` will still automatically update these modules. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confir
Original PR description
Technically, using `odoo-bin` without `-i` and `-u` for database with `to upgrade` module was wrong before 18.2, which will skip some upgrade processes/checks in `loading.py`. From 18.2 If there are `to upgrade`, `to install` or `to remove` modules in the database `odoo-bin` without `-i` and `-u` will still automatically update these modules. 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#216025
Since the edited page is within an iframe, the built-in fonts used by the wysiwyg are also loaded inside the page within the iframe, which causes them to replace the one used when viewing the page as a visitor if it happens to be one of the fallback fonts. This commit avoids that by giving a distinct `font-family` to the fonts used by the wysiwyg. task-3080104 Forward-Port-Of: odoo/odoo#214507 Forward-Port-Of: odoo/odoo#112759
Original PR description
Since the edited page is within an iframe, the built-in fonts used by the wysiwyg are also loaded inside the page within the iframe, which causes them to replace the one used when viewing the page as a visitor if it happens to be one of the fallback fonts. This commit avoids that by giving a distinct `font-family` to the fonts used by the wysiwyg. task-3080104 Forward-Port-Of: odoo/odoo#214507 Forward-Port-Of: odoo/odoo#112759
Prior to this commit, when a sale order was created with some service products configured to generate projects at SO confirmation, we would generate an analytic account per project instead of just one for all the generated projects. As a result, we would get redundant analytic accounts, which is not desirable. This is because we were creating the new projects without specifying the analytic account that would be set to it (because we would assume that the project would be first created withou
Original PR description
Prior to this commit, when a sale order was created with some service products configured to generate projects at SO confirmation, we would generate an analytic account per project instead of just one for all the generated projects. As a result, we would get redundant analytic accounts, which is not desirable. This is because we were creating the new projects without specifying the analytic account that would be set to it (because we would assume that the project would be first created without AA, then we would populate it later). The issue is that if `hr_timesheet` is installed, every new project is by default timesheetable, so that it generates an AA automatically at creation of the project (see `create()` method of `hr_timesheet`) To mitigate that, we now specify the analytic account to be used when creating the projects that have to be generated from `_timesheet_create_project()`. version-18.0 task-4854817 Forward-Port-Of: odoo/odoo#215616
Before this commit, when deselecting multiple records in kanban view the focus is set on the searchbar. Like the list view it should take focus on first load but not each time it's displayed. Task-4813624 Forward-Port-Of: odoo/odoo#214979
Original PR description
Before this commit, when deselecting multiple records in kanban view the focus is set on the searchbar. Like the list view it should take focus on first load but not each time it's displayed. Task-4813624 Forward-Port-Of: odoo/odoo#214979
Following this commit: - Empty course are removed on sync and while courses are fired. task-4668552 Enterprise PR - https://github.com/odoo/enterprise/pull/82177 Forward-Port-Of: odoo/odoo#215926 Forward-Port-Of: odoo/odoo#203442
Original PR description
Following this commit: - Empty course are removed on sync and while courses are fired. task-4668552 Enterprise PR - https://github.com/odoo/enterprise/pull/82177 Forward-Port-Of: odoo/odoo#215926 Forward-Port-Of: odoo/odoo#203442
Issue -> For databases with large `account_move_line` tables, running the `_existing_accounting` (when opening Settings) method to check if a company has accounting entries by searching for any `account_move_line` records belonging to the current company is slow. The default search order for this model is `date desc, move_name desc, id`. This causes an index scan on the table using `account_move_line_date_name_id_idx`. The combination of using `date` to order by and the query planner using an
Original PR description
Issue -> For databases with large `account_move_line` tables, running the `_existing_accounting` (when opening Settings) method to check if a company has accounting entries by searching for any `account_move_line` records belonging to the current company is slow. The default search order for this model is `date desc, move_name desc, id`. This causes an index scan on the table using `account_move_line_date_name_id_idx`. The combination of using `date` to order by and the query planner using an unrelated index for the search leads to a long running SELECT query. Solution --> We replace the `search` with a `search_count` where the ordering doesn't matter and the order by clause is skipped. Benchmark --> On customers' database with about 30M move lines and 1 `res.company` record, speedup on the SELECT query is as follows --> 62743.883 ms -> 0.392 ms Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4811622) opw-4811622 Forward-Port-Of: odoo/odoo#215727
The analytic distribution table is not scrollable on mobile devices, resulting in hidden content and an unusable layout when there is horizontal overflow due to many columns. We added style="max-width: 100vw;" to table-responsive wrapper to enable horizontal scrolling on smaller screens. Steps to Reproduce: 1. Install the Expenses and Accounting modules. 2. Go to Settings → Search for Analytic Accounting → Enable it. 3. Add multiple analytic plans with sufficient data to cause horizontal
Original PR description
The analytic distribution table is not scrollable on mobile devices, resulting in hidden content and an unusable layout when there is horizontal overflow due to many columns. We added…
The analytic distribution table is not scrollable on mobile devices, resulting in hidden content and an unusable layout when there is horizontal overflow due to many columns. We added style="max-width: 100vw;" to table-responsive wrapper to enable horizontal scrolling on smaller screens. Steps to Reproduce: 1. Install the Expenses and Accounting modules. 2. Go to Settings → Search for Analytic Accounting → Enable it. 3. Add multiple analytic plans with sufficient data to cause horizontal overflow. 4. Navigate to Expenses → Open any record. 5. Open Inspect in your browser → Switch to mobile view. 6. Click on Analytic Distribution. <details><summary>Images</summary> <p> before FIX:  after FIX:  </p> </details> Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4805590) opw-4805590 Forward-Port-Of: odoo/odoo#212731
Description of the issue/feature this PR addresses: if 2 concurrent requests are generating a sequence number on a sequence that requires a new range odoo will create 2 ranges with the same start and end date. Both request will then return the same sequence number. Current behavior before PR: Duplicated sequence numbers are generated Desired behavior after PR is merged: Raise an error if two date ranges for the same sequence with the same date range are created and avoid sequence number
Original PR description
Description of the issue/feature this PR addresses: if 2 concurrent requests are generating a sequence number on a sequence that requires a new range odoo will create 2 ranges with the same start and…
Description of the issue/feature this PR addresses:
if 2 concurrent requests are generating a sequence number on a sequence that requires a new range odoo will create 2 ranges with the same start and end date. Both request will then return the same sequence number.
Current behavior before PR:
Duplicated sequence numbers are generated
Desired behavior after PR is merged:
Raise an error if two date ranges for the same sequence with the same date range are created and avoid sequence number duplication
Script I used to reproduce the issue:
```python
import threading
import xmlrpc.client
url = 'http://localhost:8069'
db = 'db_name'
username = 'admin'
password = 'admin'
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))
models.execute_kw(db, uid, password, 'ir.sequence', 'unlink', [models.execute_kw(db, uid, password, 'ir.sequence', 'search', [[('code', '=', 'test.sequence')]])])
models.execute_kw(db, uid, password, 'ir.sequence', 'create', [{
'name': 'Test Sequence',
'code': 'test.sequence',
'prefix': 'TEST-',
'suffix': '/%(month)s/%(range_year)s/10001',
'padding': 1,
'number_increment': 1,
'use_date_range': True,
}])
def get_sequence_number():
return models.execute_kw(db, uid, password, 'ir.sequence', 'next_by_code', ['test.sequence'])
for i in range(5):
threading.Thread(target=get_sequence_number).start()
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#215666
Forward-Port-Of: odoo/odoo#210277To Reproduce ------------ - Accounting > Payments (Vendor or Customer) - On the list view, select multiple payment records - Action > Send Receipts by Email Problem ------- The email is sent, but the printed document is not set as the main attachment on the payment, as is the case when Sending a Receipt by Email from the payment's form view. Reason ------ mail does not behave in exactly the same way when sending one PDF report vs when sending a batch of documents ie, The single
Original PR description
To Reproduce ------------ - Accounting > Payments (Vendor or Customer) - On the list view, select multiple payment records - Action > Send Receipts by Email Problem ------- The email is sent, but the printed document is not set as the main attachment on the payment, as is the case when Sending a Receipt by Email from the payment's form view. Reason ------ mail does not behave in exactly the same way when sending one PDF report vs when sending a batch of documents ie, The single record uses `message_post` which calls `_message_set_main_attachment_id`. While in the case of a batch, it is not. Solution -------- Explicitly link `mail.message` attachments to the original `account.payment` record. Similar to what is done for `account.move` attachments that are linked to the `account.move.send` records. OPW-4500389 Forward-Port-Of: odoo/odoo#215899 Forward-Port-Of: odoo/odoo#202345
Description ----------- During bank statement reconciliation, finding matching journal entries generates a complex and resource-intensive query due to elaborate domain. This commit optimizes query performance by introducing a new `search_account_id` field that pre-filters the condition on `account_id` criteria. This allows the domain leaf to be resolved early and the resulting IDs to be re-injected into the main query. The optimization enables Postgres to leverage `pg_stats` directly for
Original PR description
Description ----------- During bank statement reconciliation, finding matching journal entries generates a complex and resource-intensive query due to elaborate domain. This commit optimizes query…
Description ----------- During bank statement reconciliation, finding matching journal entries generates a complex and resource-intensive query due to elaborate domain. This commit optimizes query performance by introducing a new `search_account_id` field that pre-filters the condition on `account_id` criteria. This allows the domain leaf to be resolved early and the resulting IDs to be re-injected into the main query. The optimization enables Postgres to leverage `pg_stats` directly for more accurate cost estimates. It also eliminates the need to join `account.account` with large tables like `account.move.line` and `account.move`. Overall performance improves significantly, given that `account.account` is a relatively small table, making it efficient to reuse the filtered IDs in the main query without impacting performance negatively. Benchmark --------- Clicking on "Reconcile" to open the wizard with the list view of matching Journal Entries (150k matches) from the new reconciliation view, on odoo.com takes (hot timings): | Before | After | Speed-up | |--------|-------|----------| | 14.7s | 5.75s | ~2.5x | Reference --------- task-4863071 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#213809
[FIX] point_of_sale: avoid 500 internal error pos When requesting an invoice from the portal, if an additional required field is left empty, the user gets a 500 Internal server error. (e.g. fields l10n_mx_edi_fiscal_regime, l10n_mx_edi_usage) Steps to reproduce: - Install POS & l10n_mx_reports - Open a POS session and sell a product without invoicing (and print the ticket) - Close the session - Open a new private window and go to \<url\>/pos/ticket - Enter ticket number, date and uniq
Original PR description
[FIX] point_of_sale: avoid 500 internal error pos When requesting an invoice from the portal, if an additional required field is left empty, the user gets a 500 Internal server error. (e.g. fields l10n_mx_edi_fiscal_regime, l10n_mx_edi_usage) Steps to reproduce: - Install POS & l10n_mx_reports - Open a POS session and sell a product without invoicing (and print the ticket) - Close the session - Open a new private window and go to \<url\>/pos/ticket - Enter ticket number, date and unique code and press "Request invoice" - Fill the form in but leave l10n_mx_edi_fiscal_regime & l10n_mx_edi_usage empty - Press "Get my invoice" Runbot: https://runbot.odoo.com/runbot/bundle/saas-18-2-dump-pos-extra-fields-roto-380043 Forward-Port-Of: odoo/odoo#215828
This commit fixes the non-deterministic `connection considered as lost after failed reconnect attempt` test. The monitoring service does not show the connection as lost when the navigator online property is false which makes this test fail when network is not available. This check makes no sense, it doesn't matter if we lost the connection because of a server/client error or because the network is down. This commit removes this check on the "online" navigator property and fixes this test. fix
Original PR description
This commit fixes the non-deterministic `connection considered as lost after failed reconnect attempt` test. The monitoring service does not show the connection as lost when the navigator online property is false which makes this test fail when network is not available. This check makes no sense, it doesn't matter if we lost the connection because of a server/client error or because the network is down. This commit removes this check on the "online" navigator property and fixes this test. fixes runbot-226892 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#216085
This solves a runbot error occuring on the single l10n trigger for Kenya. Cause: l10n_ke_edi_oscu_stock adds a [compute function](https://github.com/odoo/enterprise/blob/18.0/l10n_ke_edi_oscu_stock/models/account_move.py#L166) to the `product_id` field on invoice lines. The ORM triggers computes for all items in the chain - irrespective of whether the value was changed or not. Therefore, when the Kenya modules are installed, the `_compute_product_uom_id` function is triggered - which changes
Original PR description
This solves a runbot error occuring on the single l10n trigger for Kenya. Cause: l10n_ke_edi_oscu_stock adds a [compute…
This solves a runbot error occuring on the single l10n trigger for Kenya. Cause: l10n_ke_edi_oscu_stock adds a [compute function](https://github.com/odoo/enterprise/blob/18.0/l10n_ke_edi_oscu_stock/models/account_move.py#L166) to the `product_id` field on invoice lines. The ORM triggers computes for all items in the chain - irrespective of whether the value was changed or not. Therefore, when the Kenya modules are installed, the `_compute_product_uom_id` function is triggered - which changes the unit of measure. Solution: Improve the account.move.line's `_compute_product_uom_id` to only change the UoM when necessary. Considered Alternatives: - Whilst the l10n_ke_edi compute functions are not ideal - it was done because there was no PO/Bill matching feature at the time. Ideally these computes should be removed - but that would impact the stable policy and may have knock on effects. - changing the tests would simply hide issues arising from uom's and discounts. runbot-75230 Forward-Port-Of: odoo/odoo#215891
This commit fixes the `second tab still receives notifications after main pagehide` test. This test simulates the main tab being closed. As a result, the main tab unregister itself from the worker. Upon message reception, the worker would try to access client's specific data such as channels or debug mode which are supposed to be available. However, since the client was unregistered, an error occurred. runbot-75372 Description of the issue/feature this PR addresses: Current behavior bef
Original PR description
This commit fixes the `second tab still receives notifications after main pagehide` test. This test simulates the main tab being closed. As a result, the main tab unregister itself from the worker. Upon message reception, the worker would try to access client's specific data such as channels or debug mode which are supposed to be available. However, since the client was unregistered, an error occurred. runbot-75372 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#214885 Forward-Port-Of: odoo/odoo#214729
<b>Steps to reproduce:</b> 1. Go to Sales > Configuration > Product Categories 2. Select All / Saleable, and set Costing Method to FIFO 3. Go to Products > New 4. Fill in Name , set Track Inventory True and add Cost, then save the product 5. Change the Category to All / Saleable 6. Navigate to Attributes & Variants, add attribute Leg, and add values Steel and Aluminium <b>Issue :</b> - When modifying a product template with FIFO costing by adding multiple attributes, the system may d
Original PR description
<b>Steps to reproduce:</b> 1. Go to Sales > Configuration > Product Categories 2. Select All / Saleable, and set Costing Method to FIFO 3. Go to Products > New 4. Fill in Name , set Track Inventory True and add Cost, then save the product 5. Change the Category to All / Saleable 6. Navigate to Attributes & Variants, add attribute Leg, and add values Steel and Aluminium <b>Issue :</b> - When modifying a product template with FIFO costing by adding multiple attributes, the system may delete and recreate product variants. This causes "missing record" error during stock valuation replenishment, as the code tries to access deleted product variants. <b>Solution :</b> - After calling super().write(vals), the original products recordset may contain deleted records due to variant regeneration. A check was added to verify if the variants still exist, If not, then continues. <b>opw-4741530</b> Forward-Port-Of: odoo/odoo#215394 Forward-Port-Of: odoo/odoo#209513
Before this commit: ---------------- -The inactive session message was unclear. After this commit: ------------------------- -The message is now clearer and more professional. Task-4797948 Forward-Port-Of: odoo/odoo#210513
Original PR description
Before this commit:
----------------
-The inactive session message was unclear.
After this commit:
-------------------------
-The message is now clearer and more professional.
Task-4797948
Forward-Port-Of: odoo/odoo#210513Before this commit, there could be a race condition where the peer connection gets closed while an offer is being negotiated. This could happen for example when offers are being sent to establish a p2p connection and the fallback to the SFU kicks in and clears the connection. This would lead to a traceback but no functional issue. Forward-Port-Of: odoo/odoo#215995
Original PR description
Before this commit, there could be a race condition where the peer connection gets closed while an offer is being negotiated. This could happen for example when offers are being sent to establish a p2p connection and the fallback to the SFU kicks in and clears the connection. This would lead to a traceback but no functional issue. Forward-Port-Of: odoo/odoo#215995
Prior to this commit, the `_sla_generate_status_values` method in the `helpdesk.ticket` model was using a shared list for storing SLAs per ticket. This could lead to unexpected behavior when multiple tickets are processed simultaneously, as they would share the same list instance. We then removed that logic and replaced it by directly excluding the SLAs of the ticket status having a reached deadline, preventing unnecessary recomputation. Forward-Port-Of: odoo/enterprise#88563 Forward-Port-Of: o
Original PR description
Prior to this commit, the `_sla_generate_status_values` method in the `helpdesk.ticket` model was using a shared list for storing SLAs per ticket. This could lead to unexpected behavior when multiple tickets are processed simultaneously, as they would share the same list instance. We then removed that logic and replaced it by directly excluding the SLAs of the ticket status having a reached deadline, preventing unnecessary recomputation. Forward-Port-Of: odoo/enterprise#88563 Forward-Port-Of: odoo/enterprise#88341
- Before this commit we had a traceback appearing when doing the following steps (`pos_blackbox_be` should be installed): 1. Open a POS session 2. Create a new order 3. Add a product to the order 4. Go to "payments" 5. Close the register -> Traceback occurs This was due becasue just before closing the session when using a blackbox, we create a `Clock out` order and unselected the current order see `removeClockOrder()`, then call `showScreen()`. Now inside `showScreen(
Original PR description
- Before this commit we had a traceback appearing when doing the following steps (`pos_blackbox_be` should be installed):
1. Open a POS session
2. Create a new order
3. Add a product to the order
4. Go to "payments"
5. Close the register -> Traceback occurs
This was due becasue just before closing the session when using a blackbox, we create a `Clock out` order and unselected the current order see `removeClockOrder()`, then call `showScreen()`. Now inside `showScreen()` we make sure the current order exists before accessing its payments.
task-id: 4881969
Forward-Port-Of: odoo/enterprise#88047Before this commit, when selecting all (ctrl-a) in kanban or list views the first document is shown in the detail panel but the focus is not set on it. This commit fix this issue, when no document is focused and we select all the focus is set on the first document, if a document is already selected when selecting all the focus will still be that document. Task-4813624 Forward-Port-Of: odoo/enterprise#88037
Original PR description
Before this commit, when selecting all (ctrl-a) in kanban or list views the first document is shown in the detail panel but the focus is not set on it. This commit fix this issue, when no document is focused and we select all the focus is set on the first document, if a document is already selected when selecting all the focus will still be that document. Task-4813624 Forward-Port-Of: odoo/enterprise#88037
**= pos_restaurant_preparation_display Following this commit: - In preparation display, translation has been introduced which translates the course ( first letter i.e. C ) into user language. - Presets have been made centered in the UI and encapsulated in the pill for better representation. - Preset background color has been added in the preparation display same as set in the backend. - the `I` button in the preparation display is removed. task-4668552 Community PR - https://github.co
Original PR description
**= pos_restaurant_preparation_display Following this commit: - In preparation display, translation has been introduced which translates the course ( first letter i.e. C ) into user language. - Presets have been made centered in the UI and encapsulated in the pill for better representation. - Preset background color has been added in the preparation display same as set in the backend. - the `I` button in the preparation display is removed. task-4668552 Community PR - https://github.com/odoo/odoo/pull/203442 Forward-Port-Of: odoo/enterprise#88567 Forward-Port-Of: odoo/enterprise#82177
When printing a report with an IoT Box, we send a longpolling request from the client. The UI was not blocking doing so, so a fast user could leave the view before the request ended, resulting in a traceback: Component is destroyed. opw-4812421 Forward-Port-Of: odoo/enterprise#88566 Forward-Port-Of: odoo/enterprise#88493
Original PR description
When printing a report with an IoT Box, we send a longpolling request from the client. The UI was not blocking doing so, so a fast user could leave the view before the request ended, resulting in a traceback: Component is destroyed. opw-4812421 Forward-Port-Of: odoo/enterprise#88566 Forward-Port-Of: odoo/enterprise#88493
- Create a sub company from the main company. - On only the sub-company create a new followup level. - While being in both the main company and the sub-company at the same time, try to access the newly created followup level in the followup report view. The following traceback appears: File "/home/odoo/src/odoo/addons/web/models/models.py", line 128, in web_read vals = many2one_data[values[field_name]] KeyError: 9 This commit hide the statusbar for the child company if there is followu
Original PR description
- Create a sub company from the main company. - On only the sub-company create a new followup level. - While being in both the main company and the sub-company at the same time, try to access the newly created followup level in the followup report view. The following traceback appears: File "/home/odoo/src/odoo/addons/web/models/models.py", line 128, in web_read vals = many2one_data[values[field_name]] KeyError: 9 This commit hide the statusbar for the child company if there is followup level in the parent as per the specification of https://github.com/odoo/enterprise/commit/bbcd54519706539d7e2e313118c956200ea70c91 and the implementation of https://github.com/odoo/enterprise/commit/f82ef250560957046be0590f8c2a08039bcc34ca#diff-c502b098cfa2c57bc70c144ae4f0e1fbe1c0116f392ed1a63743f12a51b82084 opw-4669397 Forward-Port-Of: odoo/enterprise#85977 Forward-Port-Of: odoo/enterprise#82324
The tour in `test_worksheet_quality_check` expects the "Select Work Centers" dialog to open automatically on load. This only happens if: - `localStorage` has no previous selection, and - the user has `group_mrp_routings` As seen [Here](https://github.com/odoo-dev/enterprise/blob/df3c6642cae9b40700b0b17e0335cec00ce23d3e/mrp_workorder/static/src/mrp_display/mrp_display.js#L124) in `MrpDisplay.onWillStart()`: `if (localStorage === null && this.group_mrp_routings) { this.to
Original PR description
The tour in `test_worksheet_quality_check` expects the "Select Work Centers" dialog to open automatically on load.
This only happens if:
- `localStorage` has no previous selection, and
- the user has `group_mrp_routings`
As seen [Here](https://github.com/odoo-dev/enterprise/blob/df3c6642cae9b40700b0b17e0335cec00ce23d3e/mrp_workorder/static/src/mrp_display/mrp_display.js#L124) in `MrpDisplay.onWillStart()`:
`if (localStorage === null && this.group_mrp_routings) {
this.toggleWorkcenterDialog(false);
}`
When running with `--without-demo=all`, the admin user does not have this group, so the dialog does not show and the test fails.
We fix this by explicitly assigning the group:
`self.env.ref("base.user_admin").groups_id += self.env.ref('mrp.group_mrp_routings')`
[runbot-161194](https://runbot.odoo.com/odoo/error/161194)
Forward-Port-Of: odoo/enterprise#87891
Forward-Port-Of: odoo/enterprise#87218Description ----------- During bank statement reconciliation, finding matching journal entries generates a complex and resource-intensive query due to elaborate domain. This commit optimizes query performance by introducing a new `search_account_id` field that pre-filters the condition on `account_id` criteria. This allows the domain leaf to be resolved early and the resulting IDs to be re-injected into the main query. The optimization enables Postgres to leverage `pg_stats` directly for
Original PR description
Description ----------- During bank statement reconciliation, finding matching journal entries generates a complex and resource-intensive query due to elaborate domain. This commit optimizes query…
Description ----------- During bank statement reconciliation, finding matching journal entries generates a complex and resource-intensive query due to elaborate domain. This commit optimizes query performance by introducing a new `search_account_id` field that pre-filters the condition on `account_id` criteria. This allows the domain leaf to be resolved early and the resulting IDs to be re-injected into the main query. The optimization enables Postgres to leverage `pg_stats` directly for more accurate cost estimates. It also eliminates the need to join `account.account` with large tables like `account.move.line` and `account.move`. Overall performance improves significantly, given that `account.account` is a relatively small table, making it efficient to reuse the filtered IDs in the main query without impacting performance negatively. Benchmark --------- Clicking on "Reconcile" to open the wizard with the list view of matching Journal Entries (150k matches) from the new reconciliation view, on odoo.com takes (hot timings): | Before | After | Speed-up | |--------|-------|----------| | 14.7s | 5.75s | ~2.5x | Reference --------- task-4863071 Forward-Port-Of: odoo/enterprise#87427
Before when closing agent chat an exception occurred because the `channel_id` was undefined. This happens because when doing an await in the thread is set to `undefined`. This commit introduces a few modifications to the behaviour of the chat with the agent: Firstly, this commit moves the code calling the ORM to delete the chat history when closing the chat window to the `chat_window_model_patch.js`. This allows for the behaviour to also be applied when closing the chat from the chat
Original PR description
Before when closing agent chat an exception occurred because the `channel_id` was undefined. This happens because when doing an await in the thread is set to `undefined`. This commit introduces a few…
Before when closing agent chat an exception occurred because the `channel_id` was undefined. This happens because when doing an await in the thread is set to `undefined`. This commit introduces a few modifications to the behaviour of the chat with the agent: Firstly, this commit moves the code calling the ORM to delete the chat history when closing the chat window to the `chat_window_model_patch.js`. This allows for the behaviour to also be applied when closing the chat from the chat bubble. Additionally, the function has been modified to ensure that the thread is defined when the ORM call is made. The ORM call to close the agent chat was simplified to use the already existing `close_ai_chat` from the `discuss.channel` override. The method now uses a new `channel_type` "ai_chat", to identify channels which contain an `ai.agent`. Along with the new `channel_type`, a new function `_get_or_create_ai_chat` was introduced to properly create the "ai_chat" channels. task-4796898 Forward-Port-Of: odoo/enterprise#85587
the field vat_check_vies on res.company is added in the base_vat module, which is not a required dependency for account_reports. the function _generic_vies_vat_check might therefore result in an error with a missing field. runbot issue: 227603 Forward-Port-Of: odoo/enterprise#88497
Original PR description
the field vat_check_vies on res.company is added in the base_vat module, which is not a required dependency for account_reports. the function _generic_vies_vat_check might therefore result in an error with a missing field. runbot issue: 227603 Forward-Port-Of: odoo/enterprise#88497
Before this commit, when one tries to upload a file to a document request for the first time it does nothing. This is caused by an async memoize call which causes the file to be cleared between the memoize rpc call and the file processing after that call... After that first call the user can upload a new file without issue but it's still annoying. This commit fix this issue by storing the file in a variable before doing the memoize rpc call. Task-4778429 Forward-Port-Of: odoo/enterpri
Original PR description
Before this commit, when one tries to upload a file to a document request for the first time it does nothing.
This is caused by an async memoize call which causes the file to be cleared between the memoize rpc call and the file processing after that call... After that first call the user can upload a new file without issue but it's still annoying.
This commit fix this issue by storing the file in a variable before doing the memoize rpc call.
Task-4778429
Forward-Port-Of: odoo/enterprise#87893
Forward-Port-Of: odoo/enterprise#86002The module `l10n_co_edi_mandate` [inherits](https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_co_edi_mandate/models/account_edi_xml_ubl_dian.py#L5) a model defined in `l10n_co_dian` module, and the workflow in the module also depends[[1]](https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_co_edi_mandate/models/account_invoice.py#L9)[[2]](https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_co
Original PR description
The module `l10n_co_edi_mandate` [inherits](https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_co_edi_mandate/models/account_edi_xml_ubl_dian.py#L5) a model defined…
The module `l10n_co_edi_mandate` [inherits](https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_co_edi_mandate/models/account_edi_xml_ubl_dian.py#L5) a model defined in `l10n_co_dian` module, and the workflow in the module also depends[[1]](https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_co_edi_mandate/models/account_invoice.py#L9)[[2]](https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_co_edi_mandate/models/product_template.py#L8) on DIAN being installed. Both modules have the same dependency `l10n_co_edi` and are autoinstalled. This can easily break if the user chooses to uninstall the dian module. The module will fail to install if dian is not installed. The uninstall of the dian module will also cause an error if this module is installed. The upgrade will fail if the user has dian uninstalled (edi_mandate is a new module and will try to autoinstall) This fix makes the dependency explicit. Forward-Port-Of: odoo/enterprise#88607
steps to reproduce: 1- install l10n_mx_edi_landing 2- without demo data 3 - run test_make_cfdi_report_carry_over_canceled_invoice missing sudo in test case to create sale order in the test build_error-226771 Forward-Port-Of: odoo/enterprise#87946
Original PR description
steps to reproduce: 1- install l10n_mx_edi_landing 2- without demo data 3 - run test_make_cfdi_report_carry_over_canceled_invoice missing sudo in test case to create sale order in the test build_error-226771 Forward-Port-Of: odoo/enterprise#87946
reduce the size of the label that took nearly half the width of the sidepanel. Forward-Port-Of: odoo/enterprise#88331
Original PR description
reduce the size of the label that took nearly half the width of the sidepanel. Forward-Port-Of: odoo/enterprise#88331
Steps to reproduce - install `industry_fsm_sale_subscription` - go to settings -> enable `recurring task` - create product with following configs : * enable `subscription` * product type : `service` * create on order `task` * project `Field service`  - create a SO with this product - go to `Tasks` smart button - select the task and mark it done - ope
Original PR description
Steps to reproduce
- install `industry_fsm_sale_subscription`
- go to settings -> enable `recurring task`
- create product with following configs :
* enable `subscription`
* product type : `service`
* create on order `task`
* project `Field service`

- create a SO with this product
- go to `Tasks` smart button
- select the task and mark it done
- open the second task, from "recurring tasks" smart button
Obervation: in newly created task `Sales Order Item` is not linked
Issue:
- after this commit odoo/enterprise@be201cd ,sale fields are not copied for fsm task. while this is true for simple tasks, we would require such fields to be copied for recurrence tasks
Fix:
- allow sale fields to be copied for recurring tasks
opw-4875830
Forward-Port-Of: odoo/enterprise#88108## Issue When there are heavy (or a lot of) documents in a folder, the user cannot archive this folder as it would trigger a `MemoryError`. ### Analysis The `write` override could unnecessarily fetch the `datas` field (binary file content). This happened because a condition checking `record.datas` was evaluated before checking if `datas` or `url` was actually present in the values being written. This could lead to slowness when e.g. archiving/unarchiving documents, as the ORM would fetch t
Original PR description
## Issue When there are heavy (or a lot of) documents in a folder, the user cannot archive this folder as it would trigger a `MemoryError`. ### Analysis The `write` override could unnecessarily fetch…
## Issue
When there are heavy (or a lot of) documents in a folder, the user cannot archive this folder as it would trigger a `MemoryError`.
### Analysis
The `write` override could unnecessarily fetch the `datas` field (binary file content).
This happened because a condition checking `record.datas` was evaluated before checking if `datas` or `url` was actually present in the values being written. This could lead to slowness when e.g. archiving/unarchiving documents, as the ORM would fetch the binary content even when it was not needed.
## Solution
We leverage Python's boolean short-circuiting to ensure that this behavior is avoided.
### Benchmarks
Profiling peak memory consumption when moving 8 documents (66 Mb each) to the trash:
| Before | After | % |
|------------|------------| --- |
| 1.3 GiB | 96 Mb | - ~93% |
Query count when unlinking account.move (using Runbot data):
| Before | After |
|------------|------------|
| 66 | 72 |
(we may avoid these additional queries by prefetching the fields beforehand, let me know your thoughts)
```
[0.564 ms] query: SELECT "ir_attachment"."id", "ir_attachment"."name", "ir_attachment"."description", "ir_attachment"."res_model", "ir_attachment"."res_field", "ir_attachment"."res_id", "ir_attachment"."company_id", "ir_attachment"."type", "ir_attachment"."url", "ir_attachment"."public", "ir_attachment"."access_token", "ir_attachment"."store_fname", "ir_attachment"."file_size", "ir_attachment"."checksum", "ir_attachment"."mimetype", "ir_attachment"."create_uid", "ir_attachment"."create_date", "ir_attachment"."write_uid", "ir_attachment"."write_date", "ir_attachment"."original_id", "ir_attachment"."key", "ir_attachment"."website_id", "ir_attachment"."theme_template_id" FROM "ir_attachment" WHERE "ir_attachment"."id" IN (3398)
[0.713 ms] query: UPDATE "ir_attachment"
SET "res_id" = "__tmp"."res_id"::int4, "res_model" = "__tmp"."res_model"::VARCHAR, "write_date" = "__tmp"."write_date"::timestamp, "write_uid" = "__tmp"."write_uid"::int4
FROM (VALUES (3398, 117, 'documents.document', '2025-06-17T15:24:12.867699'::timestamp, 22)) AS "__tmp"("id", "res_id", "res_model", "write_date", "write_uid")
WHERE "ir_attachment"."id" = "__tmp"."id"
[0.305 ms] query: SELECT "ir_attachment"."id", "ir_attachment"."res_model", "ir_attachment"."res_id", "ir_attachment"."res_field", "ir_attachment"."public", "ir_attachment"."create_uid" FROM "ir_attachment" WHERE ("ir_attachment"."id" IN (3397))
[0.666 ms] query: SELECT "account_move"."id" FROM "account_move" WHERE ("account_move"."id" IN (255)) AND ("account_move"."company_id" IN (10)) ORDER BY "account_move"."date" DESC , "account_move"."name" DESC , "account_move"."invoice_date" DESC , "account_move"."id" DESC
[0.436 ms] query: SELECT "ir_attachment"."id", "ir_attachment"."name", "ir_attachment"."description", "ir_attachment"."res_model", "ir_attachment"."res_field", "ir_attachment"."res_id", "ir_attachment"."company_id", "ir_attachment"."type", "ir_attachment"."url", "ir_attachment"."public", "ir_attachment"."access_token", "ir_attachment"."store_fname", "ir_attachment"."file_size", "ir_attachment"."checksum", "ir_attachment"."mimetype", "ir_attachment"."create_uid", "ir_attachment"."create_date", "ir_attachment"."write_uid", "ir_attachment"."write_date", "ir_attachment"."original_id", "ir_attachment"."key", "ir_attachment"."website_id", "ir_attachment"."theme_template_id" FROM "ir_attachment" WHERE "ir_attachment"."id" IN (3397)
[0.436 ms] query: SELECT "documents_document"."id", "documents_document"."attachment_id", "documents_document"."active" FROM "documents_document" WHERE ("documents_document"."attachment_id" IN (3397)) ORDER BY "documents_document"."id" DESC
```
### References
opw-4552436
Memory flamegraphs available on the ticket
Forward-Port-Of: odoo/enterprise#88180
Forward-Port-Of: odoo/enterprise#85020