Monday, November 3, 2025
12 changes · 18.0
Resolved issues and error corrections
Versions -------- 18.0+ Issue ----- The `test_website_sale_add_and_remove_main_product_image_no_variant` and `test_website_sale_remove_main_product_image_with_variant` tours fail because the main product image is not removed as expected after the tour completes. Cause ----- Both tours assume that once the product `<img>` element is removed from the DOM, the action is fully completed. The tour then ends, and the remaining Python code verifies the result. However, this assumption can l
Original PR description
Versions -------- 18.0+ Issue ----- The `test_website_sale_add_and_remove_main_product_image_no_variant` and `test_website_sale_remove_main_product_image_with_variant` tours fail because the main…
Versions -------- 18.0+ Issue ----- The `test_website_sale_add_and_remove_main_product_image_no_variant` and `test_website_sale_remove_main_product_image_with_variant` tours fail because the main product image is not removed as expected after the tour completes. Cause ----- Both tours assume that once the product `<img>` element is removed from the DOM, the action is fully completed. The tour then ends, and the remaining Python code verifies the result. However, this assumption can lead to issues. If the save request takes longer than expected, the Python code may execute prematurely and fail. Solution -------- Add a step at the end of both tours to wait for the `<img>` element to be fully saved and updated in the preview DOM. Additionally, during debugging, it was observed that using an alias URL (i.e., a redirect) to an `ir.attachment` could introduce further issues or slow down the test due to the server fetching the image with a remote call. To address this, this commit replaces the alias URL with a simple binary attachment. opw-5159593 runbot-163025 runbot-163615
**PROBLEM** Internal users can access the documents of a private project even when they are not followers of the project. They shouldn't. **STEP TO REPRODUCE** 1. Create a project, and set its visibility to Invited internal users (private), and upload a document to the project folder. 2. Switch to a user that is not a follower of the project, but is a user of the document app. 3. Go to the documents app, and notice you have access to files in the private project folder. **CAUSE** 1. W
Original PR description
**PROBLEM** Internal users can access the documents of a private project even when they are not followers of the project. They shouldn't. **STEP TO REPRODUCE** 1. Create a project, and set its…
**PROBLEM**
Internal users can access the documents of a private project even when they are not followers of the project. They shouldn't.
**STEP TO REPRODUCE**
1. Create a project, and set its visibility to Invited internal users (private), and upload a document to the project folder.
2. Switch to a user that is not a follower of the project, but is a user of the document app.
3. Go to the documents app, and notice you have access to files in the private project folder.
**CAUSE**
1. When creating the project folder, we don't specify `access_ids`, which means it will copy the `access_ids` of the folder above it. If a user have access to the "Project" folder, they will have access to any sub-folder ("Project" folder is the default parent folder of the any project folder).
2. `is_access_via_link_hidden` is by default set to False, which means the project folder is visible to anyone who has access to its parent folder.
**FIX**
1. Don't copy `access_ids` from the parent folder.
2. If project visibility is private, `is_access_via_link_hidden` is set to True.
3. To give access to the folder to the followers of the project, update the `access_ids` of the project folder and documents when add/removing followers.
opw-4791346Problem: Reverting history sometimes restores children in the wrong order (e.g. `acb` instead of `abc`). Cause: In `historyRevert`, node reinsertion relied on `nextId` / `previousId` only if the referenced sibling was connected to the live DOM (`.isConnected`). When that check failed, the fallback was `parent.append()`. On some Firefox versions, mutation events list the parent removal *after* its children’s, meaning the parent is reinserted first while the children’s siblings still exist b
Original PR description
Problem: Reverting history sometimes restores children in the wrong order (e.g. `acb` instead of `abc`). Cause: In `historyRevert`, node reinsertion relied on `nextId` / `previousId` only if the…
Problem:
Reverting history sometimes restores children in the wrong order (e.g. `acb` instead of `abc`).
Cause:
In `historyRevert`, node reinsertion relied on `nextId` / `previousId` only if the referenced sibling was connected to the live DOM (`.isConnected`).
When that check failed, the fallback was `parent.append()`. On some Firefox versions, mutation events list the parent removal *after* its children’s, meaning the parent is reinserted first while the children’s siblings still exist but are detached. Because `.isConnected` returned false, the fallback `append()` misplaced nodes and broke the order.
Example (processed in reverse order):
```js
[
{ type: 'remove', id: 'p', parentId: 'root', node: { tagName: 'P' } },
{ type: 'remove', id: 'b1', parentId: 'p', nextId: 'b2',
node: { textValue: 'b' } },
{ type: 'add', id: 'b1', append: 'x', node: { textValue: 'b' } },
{ type: 'remove', id: 'c1', parentId: 'p', node: { textValue: 'c' } },
{ type: 'add', id: 'c1', append: 'x', node: { textValue: 'c' } },
]
```
During revert:
- Child removals (b1, c1) are processed first.
- Their sibling nodes exist but are detached → .isConnected false.
- Fallback append() used → "b" inserted after "c" → acb.
- `<p>` restored last with children in wrong order.
Solution:
Remove the `.isConnected` condition.
`before()` and `after()` work even on detached nodes, preserving the original child order regardless of browser mutation sequence.
Steps to reproduce:
- Open todo.
- Have this:
```html
<p>a[]</p>
<p>b<br>c</p>
```
- Press Delete.
- Observe "b" and "c" are not in the right order.
opw-5139795
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#233582**Steps to reproduce** 1. Create a subscription SO with both a recurring and a non-recurring line. 2. Add a discount to the non-recurring line. 3. Confirm the SO. 4. Change the "Start date" of the SO. Issue: the discount on the non-recurring line has been removed. **Solution** Remove the order's start date from the dependencies and manually call `_compute_discount` when needed (for upsell sub lines). opw-4822617
Original PR description
**Steps to reproduce** 1. Create a subscription SO with both a recurring and a non-recurring line. 2. Add a discount to the non-recurring line. 3. Confirm the SO. 4. Change the "Start date" of the SO. Issue: the discount on the non-recurring line has been removed. **Solution** Remove the order's start date from the dependencies and manually call `_compute_discount` when needed (for upsell sub lines). opw-4822617
This test was not awaiting each step properly, which becomes visible when the runbot is overloaded and the querySelector calls return null, at which point accessing `click` or `value` would trigger a traceback. runbot-161423 Forward-Port-Of: odoo/odoo#233900
Original PR description
This test was not awaiting each step properly, which becomes visible when the runbot is overloaded and the querySelector calls return null, at which point accessing `click` or `value` would trigger a traceback. runbot-161423 Forward-Port-Of: odoo/odoo#233900
Issue ----- Removing a line using the subcontracting wizard does not delete the line in DB, there is a "phantom" ML. Steps to reproduce ----- - Create a subcontracted product with 2 components - Add one of each component in subcontractor's stock - Create a PO for the finished product and confirm it - Go to the production - Open the "Record components" wizard - Set quantity then remove the second line - Confirm production (don't update consumption) - Go to Inventory > Reporting > Mo
Original PR description
Issue ----- Removing a line using the subcontracting wizard does not delete the line in DB, there is a "phantom" ML. Steps to reproduce ----- - Create a subcontracted product with 2 components - Add…
Issue ----- Removing a line using the subcontracting wizard does not delete the line in DB, there is a "phantom" ML. Steps to reproduce ----- - Create a subcontracted product with 2 components - Add one of each component in subcontractor's stock - Create a PO for the finished product and confirm it - Go to the production - Open the "Record components" wizard - Set quantity then remove the second line - Confirm production (don't update consumption) - Go to Inventory > Reporting > Moves History and remove the "Done" filter > There is a pending move in the report Cause ----- When saving the wizard's changes, we call a write on the production's `move_line_raw_ids` field to remove delete the line. The field is a simple compute, so we go through its' inverse method https://github.com/odoo/odoo/blob/be3a4283c383d187570f5a73f337030e6ae9d05c/addons/mrp_subcontracting/models/mrp_production.py#L34-L46 The problem is that we populate `line_by_product` using the values present in `move_line_raw_ids` from which we just removed the line. This means that when we do `move.move_line_ids = line_by_product.pop(move.product_id, self.env['stock.move.line'])` we replace the value of `move_line_ids` with only the remaining ones, which means we unlink the move line (*from the move*). Because the inverse field (`move_id` of the SML) is not set as `ondelete='cascade'`, the link is broken but the line remains in db. https://github.com/odoo/odoo/blob/f173c738b1adcf85a80eb641ad307b7cccf17294/odoo/fields.py#L4311-L4322 We cannot change the field to `ondelete='cascade'` as such a change would not be stable. Solution ----- Keep reference of the lines to be removed in order to delete them once `move_line_ids` has been updated. ----- Ticket: opw-4817397 Forward-Port-Of: odoo/odoo#229310
Community PR: https://github.com/odoo/odoo/pull/233842 Forward-Port-Of: odoo/enterprise#98492
Original PR description
Community PR: https://github.com/odoo/odoo/pull/233842 Forward-Port-Of: odoo/enterprise#98492
Repro: - Create DDM for a client - Create 4+ invoices for him - Pay with SEPA - Go to batch payment set it with SEPA - Add all the invoices and set the date to any date <5 days from today. - A yellow line will appear along with (View All).. / click it - From the view click on any payment. - Exception arises saying made_sequence_gap not found in account.payment Issue: made_sequence_gap belongs to 'account.move' incompatible with 'account.payment' causing the exception. Solution:
Original PR description
Repro: - Create DDM for a client - Create 4+ invoices for him - Pay with SEPA - Go to batch payment set it with SEPA - Add all the invoices and set the date to any date <5 days from today. - A yellow line will appear along with (View All).. / click it - From the view click on any payment. - Exception arises saying made_sequence_gap not found in account.payment Issue: made_sequence_gap belongs to 'account.move' incompatible with 'account.payment' causing the exception. Solution: Here the view_duplicated_moves_tree_js view is intended for account.move elements not for account.payment ones, So I included it only when the resModel is account.move. opw-5149260
Enterprise PR: https://github.com/odoo/enterprise/pull/98492 Forward-Port-Of: odoo/odoo#233842
Original PR description
Enterprise PR: https://github.com/odoo/enterprise/pull/98492 Forward-Port-Of: odoo/odoo#233842
This change prevents the due date from being shown on invoices and bills that have been canceled. It helps avoid confusion by ensuring canceled documents no longer display a payment due date that is no longer relevant.
Original PR description
Description of the issue/feature this PR addresses: Due date appearing on canceled invoices Current behavior before PR: Due date appears on canceled invoices Desired behavior after PR is merged: Due date doesn't appear on canceled invoices --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change ensures that default values in mocked fields are kept when test models are extended. As a result, date-related fields like creation and last update timestamps are filled in correctly during tests, making them more reliable.
Original PR description
Before this commit, default values in mock fields defined by functions would be lost when extending a model, because by doing so the fields were JSON-copied and the default functions were lost. To fix this, this commit introduces another way to copy field definitions that preserves functions, allowing default values (typically for the 'create_date' and 'write_date' fields) to be applied correctly. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change updates a sales/manufacturing test so it no longer relies on a field that is only available in the Enterprise edition. It helps the test run correctly in more setups and prevents avoidable test failures.
Original PR description
Cause ----- Test introduced in 2da1c78 uses the field `backorder_ids` which is only present when enterprise is installed https://github.com/odoo/enterprise/blob/67fdbc5ae724a184d62d8cfa23403b8c759b9317/stock_barcode_mrp/models/mrp_production.py#L10 ----- Error: 233584