Friday, May 29, 2026
18 changes · saas-19.3
Enhancements to existing features
This update enhances the analytic reporting feature by adding a 'product category' field to the account.analytic.line model. This allows users to group and analyze expenses by product category within their reports, providing more granular insights into spending patterns.
Original PR description
Add the related (non-stored) 'product_category' field on the account.analytic.line model to make it available in the Analytic Reporting "Group By" task-6219418 Forward-Port-Of: odoo/odoo#266378
Resolved issues and error corrections
This update fixes a previous issue where payment transaction details weren't consistently saved in Odoo, regardless of whether the payment was triggered by a webhook or polling. The change ensures that all relevant payment information, including card details, is now correctly recorded, improving the accuracy of financial reporting and reconciliation. This resolves a critical data capture problem.
Original PR description
After odoo/odoo#236454, a bug was introduced where the transaction details would only be saved if the payment was resolved via webhook, not via polling. This commit fixes the issue by using the same field names in the webhook payload as is received from the polling endpoint. In addition, the card number and card brand fields are now saved too. opw-6244960 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266788 Forward-Port-Of: odoo/odoo#266629
This update corrects a bug where duplicated manufacturing orders automatically linked to their original sales order. The fix prevents this linking, ensuring that duplicated orders are independent and don't incorrectly display a connection to the original sale. This improves data accuracy and simplifies order management.
Original PR description
Version: --------- - 19.0+ Steps to reproduce: -------------------- 1.Install modules `sale_management`, `purchase`, and `mrp`. 2. Go to Settings and enable the MTO (Replenish on Order) route. 3.…
Version:
---------
- 19.0+
Steps to reproduce:
--------------------
1.Install modules `sale_management`, `purchase`, and `mrp`.
2. Go to Settings and enable the MTO (Replenish on Order) route.
3. Create a product with:
i. Configure a Vendor under the Purchase tab.
ii. Set the route to MTO.
iii. Create a Bill of Materials for the product.
5. Create a Sale Order with the configured product and confirm it.
6. Open the generated Manufacturing Order.
7. Duplicate the Manufacturing Order.
Issue:
------
* The duplicated Manufacturing Order shows a smart button
linked with the Sale Order, which is incorrect.
Root Cause:
------------
This issue is coming form this [Commit](https://github.com/odoo/odoo/commit/2713876dbc70d3984e584a9037a2206dcda4e84a#diff-2b9de2e50ff5e1dc0362b825bac2b07623770fb3275b3257ef972f255f3ccb8b)
* During Sale Order confirmation, the flow
`action_confirm` → `_action_confirm` → `_action_launch_stock_rule`
→ `run` → `_run_pull` → `_action_confirm` calls
`_prepare_procurement_values`.
which gather all procurement values.
In sale_stock, the super call adds `sale_line_id` to the
generated Manufacturing Order when using MTO:
https://github.com/odoo/odoo/blob/0352c5e8543b75083cf555c3d5b4f164f949b465/addons/sale_stock/models/stock.py#L138-L140
* So, when the Sale Order is confirmed, the generated
Manufacturing Order contains sale_line_id, and when this
Manufacturing Order is duplicated, the sale_line_id is also
copied.
* In sale_mrp, the smart button uses sale_line_id to compute
the linked Sale Order count:
https://github.com/odoo/odoo/blob/0352c5e8543b75083cf555c3d5b4f164f949b465/addons/sale_mrp/models/mrp_production.py#L19
Solution:
-----------
* Prevent copying of sale_line_id when duplicating a
Manufacturing Order, ensuring duplicated records are not
linked to any Sale Order.
---
opw-6113149
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#259128This update resolves an error that occurred when the Salary Increase wizard was used with a past date for the salary increase. The issue stemmed from how the system identified compatible employee versions, particularly for new employees. The fix ensures the system handles past dates correctly, preventing the error and allowing users to accurately adjust salaries.
Original PR description
Currently, an error will occur when user puts Date of Salary Increase in the past on the salary increase wizard. Steps to replicate: - Install `hr_payroll` and create a new employee. - From the cog…
Currently, an error will occur when user puts Date of Salary Increase in the past on the salary increase wizard.
Steps to replicate:
- Install `hr_payroll` and create a new employee.
- From the cog menu click `Salary Increase`.
- Put any date from the past in the `Date of Salary Increase` field.
Error:
```py
File '/home/odoo/src/enterprise/saas-19.3/hr_payroll/wizard/hr_payroll_salary_increase_wizard.py', line 43, in _get_affected_version_ids
increase_base_version = employee.version_ids.filtered_domain([('date_version', '<=', self.increase_date)])[-1]
File '/home/odoo/src/odoo/saas-19.3/odoo/orm/models.py', line 6135, in __getitem__
ids = (self._ids[key],)
IndexError: tuple index out of range
```
Cause:
- When the user changes the salary increase date, it triggers the [compute], which calls `_get_affected_version_ids()`. In this method, employee versions [1] are filtered to keep only those whose `date_version` is less than or equal to the selected increase date.
- For newly created employees, version_ids typically contain only an initial version with date_version set to today's date. Therefore, when the selected salary increase date is earlier than today, the filter returns an empty recordset, which later causes the crash when accessing the last record of that recordset.
Solution:
- Early returned empty recordsets when no matching employee versions are found for the selected increase date.
[compute]: https://github.com/odoo/enterprise/blob/2a86967c1754f9c703a87c5d9ceb1d5f5d0ec26f/hr_payroll/wizard/hr_payroll_salary_increase_wizard.py#L34-L39
[1]: https://github.com/odoo/enterprise/blob/2a86967c1754f9c703a87c5d9ceb1d5f5d0ec26f/hr_payroll/wizard/hr_payroll_salary_increase_wizard.py#L43
sentry-7498213478This update resolves an issue where the POS restaurant dashboard broke due to inconsistent record IDs between testing and production environments. The change removes reliance on these IDs, adapting the dashboard's data selection to ensure stability across all environments. This improves the reliability of the dashboard for both testing and live operations.
Original PR description
## Description of the issue/feature this PR addresses: Commit 050ecd2 introduced random serial numbers for records, which caused dashboards relying on static record IDs to break. Later, commit 87f0bee restricted this behavior to environments with `ODOO_RUNBOT` or `ODOO_TEST` enabled. As a result, production keeps stable IDs while testing environments still use random ones. Because of this difference, relying on record IDs is no longer safe, As values differ between testing and production. This PR removes the direct use of record IDs in the POS restaurant dashboard and adapts the domain accordingly. Task: [6054252](https://www.odoo.com/odoo/project/2328/tasks/6054252) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures that backorders created during POS sales are correctly linked to the original POS order. Previously, these backorders lacked a connection, making inventory management more complex. This fix improves order traceability and reporting accuracy within the Point of Sale system.
Original PR description
The delivery transfer for a product tracked by serial number is not linked to the POS order when there is no available stock. When validating a POS delivery in real time, stock can split the transfer…
The delivery transfer for a product tracked by serial number is not linked to the POS order when there is no available stock. When validating a POS delivery in real time, stock can split the transfer into a completed picking and a backorder (e.g. one line fully delivered with lots, another serial-tracked line with no stock and no serial number). Steps to reproduce: ------------------- * Setup two products: one tracked by qunatity with some quantity on-hand an other tracked by SN but no quantity on-hand * Open Pos * Sell in one order, both products without providing SN * Validate payment * Open Inventory: two deliveries sould exist under Inventory Overview of PoS Orders > Observation: The first picking shows the POS order as Source Document but the backorder has no source document and is not linked to the POS order. Why the fix: ------------ Pos Origin (Source Document, POS order, session) was only written on the pickings returned by `_create_picking_from_pos_order_lines`, which did not include pickings created during `_action_done()`. Extend the write to the initial pickings and their backorders so every transfer stays tied to the originating `pos.order`. opw-6090606 Forward-Port-Of: odoo/odoo#266509 Forward-Port-Of: odoo/odoo#259370
This update corrects a bug in the overtime calculation process. Previously, overlapping overtime rules were incorrectly combined, leading to inaccurate overtime intervals. This fix ensures overtime is calculated correctly, preventing potential discrepancies in employee pay.
Original PR description
**Issue:** When computing timing overtime rules, overlapping intervals from different rules were accidentally merged before the overlap resolution step. As a result, the overlap generation logic no longer had access to the original rule boundaries and could not correctly create the final overtime intervals. **Solution:** Keep the original intervals from each rule untouched until the final overlap resolution step so overlaps can be properly sliced and resolved when generating the final overtime intervals. Task: 6168492 Forward-Port-Of: odoo/odoo#266096
This update prevents a critical error during bill matching in Odoo when no new purchase order lines need to be added. Previously, attempting to match a posted bill with zero residual lines would trigger a system error. Now, the system gracefully handles this scenario, ensuring the matching process completes successfully and avoids data corruption.
Original PR description
**Description of the issue/feature this PR addresses:** This PR fixes an "Invalid Operation" UserError during the Bill Matching process. The error occurs when Odoo attempts to call the line addition…
**Description of the issue/feature this PR addresses:** This PR fixes an "Invalid Operation" UserError during the Bill Matching process. The error occurs when Odoo attempts to call the line addition method on a Posted Vendor Bill, even when there are no new residual lines to add. This triggers a write attempt on read-only fields (such as invoice_line_ids) of a validated account move, which is prohibited by Odoo’s ORM. Furthermore, this addresses a functional inconsistency: Odoo allows users to select "Posted" bills in the matching view, but the underlying code is not prepared to handle a "zero residual" scenario on a validated move. If Odoo intends to prevent matching on posted bills, they should be filtered out from the view; since they are available to select, the system must be able to process them when no further modifications to the accounting entries are required. **Current behavior before PR:** When performing a match between a posted Vendor Bill and Purchase Order lines where the "residual" (lines left to add) is zero: The system executes _add_purchase_order_lines() regardless of whether the recordset of lines is empty. Odoo's ORM detects an update attempt on a posted record. A UserError is raised: "You cannot modify the following readonly fields on a posted move: invoice_line_ids". This blocks the user from completing the matching process even if the lines are already technically accounted for. **Desired behavior after PR is merged:** The system will check if residual_purchase_order_lines contains any records before attempting to update the bill. If there are no lines to add, the method call is skipped. The matching process completes successfully without attempting an illegal write on a posted move. **Steps to Reproduce** 1) Create a Purchase Order (PO): Add a product (e.g., "Acoustic Bloc Screens") and confirm the order. 2) Create a Vendor Bill manually: Do not use the "Create Bill" button from the PO. Instead, go to Accounting -> Vendors -> Bills and create a new bill for the same vendor and product. 3) Post the Bill: Set a bill date and click Confirm to move it to the "Posted" state. 4) Open Bill Matching: Go back to the Purchase Order and click the Bill Matching button (or navigate to the matching view). 5) Select Lines: Select the PO line and the corresponding Bill line (which are already equal in quantity/price). 6) Trigger the Match: Click on the Match button. Observe Error: An "Invalid Operation" popup appears, preventing the link because Odoo tries to "add" zero lines to a posted invoice. **Video:** https://drive.google.com/file/d/12aeZIx1JRRSKA9TaWfXy0TeSOgMUMQcg/view --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241171
This pull request optimizes the performance of the account report sheet by streamlining CSS styling and reducing unnecessary DOM calculations. By using CSS variables and more direct selectors, the changes minimize visual rendering impacts, particularly on large tables, leading to a smoother user experience. This resolves performance bottlenecks related to hover effects and table styling.
Original PR description
Forward-Port-Of: odoo/enterprise#118674 Forward-Port-Of: odoo/enterprise#118490
This update resolves an issue preventing users from unreconciling SEPA CT payments with a 'pending' online status. Previously, the system incorrectly blocked this process, causing delays in bank statement reconciliation. The fix allows internal unreconciliation flows to bypass validation, ensuring accurate bank statement matching.
Original PR description
**Issue:** The account_online_payment module overrides `action_draft` to raise a UserError for sepa_ct payments belonging to a batch with a `payment_online_status` = 'pending' or 'accepted'. This…
**Issue:** The account_online_payment module overrides `action_draft` to raise a UserError for sepa_ct payments belonging to a batch with a `payment_online_status` = 'pending' or 'accepted'. This blocks the bank statement unreconciliation process. When `delete_reconciled_line` is called, it tries to set payments to draft and re-post them, despite it being an internal process not a manual user modification. **Steps to reproduce:** - Setup a 'sepa_ct' payment method on a bank journal. - Create a bill with a vendor with a trusted bank account. - Create a payment for that bill with a 'sepa_ct' payment method. - Add the payment to a batch. - Manually set the `payment_online_status` = 'pending'. - Create a bank transaction and reconcile it with the batch. - Try to unreconcile the lines on the transaction - Result: UserError 'You cannot modify a payment that has already been sent to the bank.' **Fix:** Pass a context flag to `action_draft` during the unreconciliation flow so that the validation is skipped when the call originates from the internal unreconcile flow. OPW-6080464 Forward-Port-Of: odoo/enterprise#118342 Forward-Port-Of: odoo/enterprise#117921
This update fixes an issue where importing a product with a changed subscription type would bypass a necessary warning. Previously, the system silently processed the import, allowing users to incorrectly re-enable subscription features. This change ensures a warning is displayed when attempting to modify a product that has already been sold as a subscription, maintaining data integrity.
Original PR description
__ ## Short functional explanation of the error When we have a subscription product that has already been sold. If we try to import a product with the same ID but where we change the subscription…
__ ## Short functional explanation of the error When we have a subscription product that has already been sold. If we try to import a product with the same ID but where we change the subscription type of the product, the import is executed without issue. However, this leads to undesired behavior: when we go to the product page and try to manually change the subscription type (set it back to subscription), the change is not applied as a warning is raised. ## Reproduction Steps Make sure you have debug mode enabled. 1. Create a product, and check the Subscription box. 2. Click on Orders and create a Quotation with this product, then confirm. 3. Go to Products > Products. Select the list view and search for the product you just created. Select it, and click Actions > Export. 4. Check the import compatible field. Select the fields to export: name, id and recurring_invoice. Upon exporting, a file is downloaded. 5. Access that file and change the recurring_invoice to FAUX or FALSE if your computer is in English. Save the changes. 6. Unselect the product and click on the cog, top right > Import. Click on Upload Data File and select the file that you have downloaded upon exporting, then import. ### Expected behavior A user warning is raised: we shouldn't be able to change the subscription type of the product when it has already been sold. ### Unexpected behavior The import is processed normally. Then, when we access the product page, and try to check the Subscriptions box again, a warning is raised. ## Origin of the issue Nothing prevents the import from occurring in that case. __ opw-6143789 Forward-Port-Of: odoo/enterprise#117318 Forward-Port-Of: odoo/enterprise#115046
This update corrects a bug in the generation of FA(3) XML files for Polish VAT invoices. Previously, the system incorrectly omitted a key date ('P_6') when the invoice delivery date matched the invoice issue date. This change ensures accurate compliance with Polish tax regulations by comparing the delivery date to the invoice issue date, as required by the VAT Act.
Original PR description
**Steps to reproduce** 1. Create a customer invoice with Invoice Date `2025-05-27` and accounting Date `2026-05-04`. 2. On the *Other Info* tab, set the Delivery Date to `2026-05-04` and post the…
**Steps to reproduce** 1. Create a customer invoice with Invoice Date `2025-05-27` and accounting Date `2026-05-04`. 2. On the *Other Info* tab, set the Delivery Date to `2026-05-04` and post the invoice. 3. Generate the FA(3) XML. **Issue** `P_6` is omitted from the payload even though the delivery date differs from the invoice issue date. The FA(3) information sheet (Warsaw, September 2025, binding from 1 February 2026) defines `P_6` as *"the date of delivery [...] if such date is specified and differs from the date of issue of the invoice"*, where the date of issue is `P_1` (Art. 106e sec. 1 item 1 of the VAT Act). In Odoo `P_1` maps to `invoice_date`, but the template at https://github.com/odoo/odoo/blob/4890b8021af2a5c025944220043d295bb7bbbb9b/addons/l10n_pl_edi/data/fa3_template.xml#L132 compares `delivery_date` against `invoice.date`, the accounting/entry date. When the invoice is posted on the delivery day the accounting date equals the delivery date, the guard evaluates to false, and `P_6` is wrongly dropped. Comparing against `invoice.invoice_date` aligns the guard with `P_1` as the spec requires. Ticket [link](https://www.odoo.com/odoo/project.task/6211119) opw-6211119 Forward-Port-Of: odoo/odoo#266667
This update corrects a bug where the scrap location selected by a user during a scrap move confirmation was being overridden. Previously, the system defaulted to the company's standard scrap location. Now, the user's chosen scrap location is correctly applied when confirming the move.
Original PR description
**Issue** The scrap location provided by the user may be overridden while confirming a scrap move **Steps to reproduce** - In settings, enable the tracking of location in the warehouse - Have two…
**Issue** The scrap location provided by the user may be overridden while confirming a scrap move **Steps to reproduce** - In settings, enable the tracking of location in the warehouse - Have two location of type 'Inventory loss' - Create a scrap move and change the scrap location - confirm the move -> The scrapped move will be created using the scrap location already present before the user changes it **Cause** The regression has been introduce by this refactoring commit: https://github.com/odoo/odoo/commit/1c7d80a10b5d7db1c4163166bf52b3f3c77044ba While confirming the scrap move: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L2726 https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L2731 It needs to access the `stock.move` record: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L2133 Since this is the first access, it triggers the compute method of `location_dest_id`: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L227-L228 Which sets it to the company's scrap location, regardless of the value provided by the user: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L237-L238 This value is compute here: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/res_company.py#L62-L65 This value is computed by taking the first scrap location found for this company opw-6125152 Forward-Port-Of: odoo/odoo#261803
This update ensures that expenses are correctly linked to analytic accounting when required. Previously, users could post expenses without specifying an analytic distribution even when an analytic plan with a mandatory 'Expense' domain was set. This fix prevents incorrect accounting and ensures accurate tracking of expenses against specific budgets or cost centers.
Original PR description
When posting expenses, if the expense domain is set as mandatory in any of the analytic plans, users can still post expenses without entering an analytic distribution. Steps to reproduce: 1. Create an analytic plan with the "Expense" domain and set it as mandatory. 2. Create a new expense and submit it. 3. Don't enter any analytic distribution. 4. Post Journal Entries for the expense. 5. Notice how the expense is posted without any error message. Ticket [link](https://www.odoo.com/odoo/project.task/6187340) opw-6187340 Forward-Port-Of: odoo/odoo#266399
This update corrects a bug where table assignments weren't consistently syncing across different devices within a POS session. Now, when a waiter selects a table without an order, it correctly displays as occupied on all devices, ensuring accurate table management for staff and customers. This improves the overall POS experience and reduces potential errors.
Original PR description
When a waiter selects a table without adding any items and returns to the floor screen, the table appears as occupied (green) on their device but not on other devices in the same POS session. Steps to reproduce: ------------------- * Open POS session on device A * Open same POS session on device B * On device A: click a table, don't add items, go back to floor * On device B: observe the table does not appear as occupied > Observation: Empty table assignments were not being synced to the server, so other devices couldn't detect the table occupancy. Why the fix: ------------ Also treat orders with a table_id as pending so they sync immediately when a table is opened. The backend already supports this: pos.order can be created with just table_id, and pos_restaurant._get_open_order looks orders up by table_id for table-based sync. opw-5236119 Forward-Port-Of: odoo/odoo#259465 Forward-Port-Of: odoo/odoo#241321
This update optimizes a key query used to retrieve reconciliation models, resulting in significantly faster performance. By correcting a technical issue with how the database searches for matching records, the system now responds much quicker, particularly when the database's memory is not fully warmed up. This improves overall system responsiveness.
Original PR description
The CTE `model_fees` is supposed to get the reconciliation models that match conditions that involves a join with the ir.model.data table. One of these conditions is filtering based on the `name`…
The CTE `model_fees` is supposed to get the reconciliation models that match conditions that involves a join with the ir.model.data table. One of these conditions is filtering based on the `name` field with an `LIKE` operator. On databases that has a GIST index on the field `name`, the planner will prefer to filter the records based using the GIST index and add the extra filters as a filtering criteria after the index condition if the index-condition wasn't possible to be switched to a range-query. The condition is supposed to be a prefix-matching, which can be evaluated directly by a B-TREE if the field had an index and the planner can convert the condition to a range-query. Apparently the `_` in `account_reco_models_fees_%%` was evaluated as a wild-card, making the condition a substring-matching rather than direct prefix-matching. In this PR, I have modified the condition to escape the '_' wildcards. The benchmark done below was on a database that has around **10^7** `ir.model.data` records and 1K `account.reconciliation.model` records. I have split the benchmark into two cases, a case where the buffer-pool of postgres warmed-up and a case where it is not. After Worst case -> https://explain.dalibo.com/plan/975geg1f1h109d5c Before Worst case -> https://explain.dalibo.com/plan/0ce9bf3g0ad8f98b After Best Case -> https://explain.dalibo.com/plan/1a77459dadb0gfc4 Definition of ir_model_data_name_idx2 -> CREATE INDEX ir_model_data_name_idx2 ON public.ir_model_data USING gist (name gist_trgm_ops) Definition of ir_model_data_module_name_uniq_index -> CREATE UNIQUE INDEX ir_model_data_module_name_uniq_index ON public.ir_model_data USING btree (module, name) | PostgreSQL Buffer Pool Status | Before | After | | :--- | :--- | :--- | | Not warmed up (Cold) | 11s | 130ms | | Warmed up (Hot) | 0.022ms | 0.097ms | Forward-Port-Of: odoo/enterprise#117746
This update resolves an issue in the Italian annual tax report where incorrect values (both positive and negative) were displayed for tax lines. The fix ensures that only the positive balance for each pair of tax lines (VL3/VL4 and VL32/VL33) is shown, aligning with tax reporting requirements. This improves the accuracy of the report for Italian businesses.
Original PR description
### Issue In the Italian annual tax report, both VL3/VL4 and VL32/VL33 values could be displayed at the same time However, according to the report logic, only the positive balance should be shown for…
### Issue In the Italian annual tax report, both VL3/VL4 and VL32/VL33 values could be displayed at the same time However, according to the report logic, only the positive balance should be shown for each pair: - VL3 (Tax Due) or VL4 (Tax Credit) - VL32 (Tax Due) or VL33 (Tax Credit) The other one should stay 0 If the global balance is null, both can be 0 ### Cause The lines VL3, VL4, VL32, and VL33 were using the shortcut field `aggregation_formula` directly on the `account.report.line` record This shortcut format does not evaluate or support conditional subformulas like `if_above(EUR(0))` As a result, the report computed and displayed both lines of each pair without filtering out the negative or unwanted values ### Steps to reproduce - Install `l10n_it` and `accountant` and switch to IT Company - Create a balanced Journal Entry for any account - Add the Tax Grid v20 on one of the lines to impact the annual report - Open the `Annual Tax Report (IT)` - Go to the `VL` section - Check the value of VL3/VL4 and VL32/VL33 After the fix, only one value can be positive and the other 0 Ticket [link](https://www.odoo.com/odoo/project.task/6212694) opw-6212694 Forward-Port-Of: odoo/odoo#264294
This update fixes issues related to text selection within the website interface, particularly around nested uncrossable elements. It ensures that selections are correctly maintained, even with complex HTML structures, and improves the overall user experience by accurately reflecting user selections.
Original PR description
*: html_editor, html_builder ### Commit 1: [FIX] html_editor, website: improve helper util setSelection and tests **Before this commit**: after the selection restriction commit…
*: html_editor, html_builder ### Commit 1: [FIX] html_editor, website: improve helper util setSelection and tests **Before this commit**: after the selection restriction commit (https://github.com/odoo/odoo/commit/d09c8fd428315b8c3bf08c43d55da50fcd77f2ae), the tests have to dispatch events specifically to mimic the selection made by mouse. **After this commit:** we improve the setSelection helper to include a flag isMouseEventSimulated and simplify the tests. task-6143995 ### Commit 2: [FIX] html_builder*: improve selection correction for nested uncrossable *: website **Before this commit:** correctSelectionOnUncrossable is not exhaustive for complex html snippets. When there are multiple uncrossable elements in the selection, and there's a parent uncrossable element including other uncrossable ones, the selection is only restricted on the parent uncrossable element. We had a fix for the select all behavior but not for mouse selection. Reproduction: - Have a blockquote snippet with some text around it - Select the text from the blockquote to the text after it => it will keep the authors info selected - And then, if I click on the text, the selection will restrict to the text without the author infos **After this commit:** We now always correct the selection on uncrossable in an iterative way, until the selection is not corrected anymore or a maximum of attempts is reached. We didn't use the loop condition like previously done. Because there can still be an uncrossable inside the selection, when the closest uncrossable elements of the focus node and anchor node are the same. Instead, we stop the looping when the selection isn't being corrected anymore. task-6143995 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr