Daily updates from Odoo
Monday, November 3, 2025
22 changes · 18.0
Enhancements to existing features
Users who are already registered as Peppol receivers in another Odoo database no longer need to manually deregister and start over. Odoo now detects the existing registration and sends a secure email link so they can transfer the Peppol connection to the current database more smoothly.
Original PR description
### Summary Previously, when a user attempted to **register as a Peppol receiver** while already registered through a different Odoo database, the system would raise a **User Error**. The user had to…
### Summary
Previously, when a user attempted to **register as a Peppol receiver** while already registered through a different Odoo database, the system would raise a **User Error**.
The user had to **manually deregister** and **re-register** from the desired database.
---
### New Behavior (After This Commit)
With this update:
- The system **detects existing Peppol registrations** across databases.
- Instead of raising an error, it now **sends an automated email** to the user with a **secure transfer link**.
- This allows the user to **migrate their Peppol connection** to the current database seamlessly.
---
### Flow Overview
```text
┌────────────────────────────┐
│ User initiates Peppol │
│ registration (becomes │
│ sender) │
└────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ Check existing registration │
└────────────┬─────────────────┘
│
┌──────────────┴──────────────┐
▼ ▼
┌─────────────────────┐ ┌──────────────────────────────┐
│ User NOT registered │ │ User ALREADY registered |
│ in any Odoo DB │
└────────────┬────────┘ └──────────────┬───────────────┘
│ │
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────────┐
│ Proceed with normal │ │ Send email with transfer link│
│ registration flow │ │ to the user │
└──────────────────────────┘ └──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ User clicks transfer link
│
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ Peppol connection migrated
└──────────────────────────────┘
```
---
iap pr- https://github.com/odoo/iap-apps/pull/1236
task- 5023252This update adds quick search in the invoice list so users can find invoices by currency amount. It makes locating specific invoices faster and reduces manual scrolling or filtering.
Original PR description
Description of the issue/feature this PR addresses: Added quick search in invoice search view Current behavior before PR: Can not search invoice by currency amount Desired behavior after PR is merged: User is able to search by currency amount --- 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 ensures website building snippets appear correctly when using Arabic or other right-to-left languages. It helps users edit website pages without missing content options due to layout positioning issues.
Original PR description
Steps to reproduce: =================== - Set arabic as default language for website - Try to add a snippet -> you can't see the snippets Cause: ====== Snippets were fetched correctly but were not visible. In RTL languages (like Arabic), the CSS `transform-origin` was set to 'top right', rendering the snippets off-screen. This is due to the browser's interpretation of positioning in RTL mode. For more details, see MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/ Properties/position Solution: ========= Force the snippet preview's position by setting `left: 0`. This ensures its positioning is always aligned to the left, regardless of the `transform-origin` value dynamically set by the browser in RTL mode. opw-5214703
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 update fixes the way Chilean state names are displayed in customer addresses. It replaces placeholder numeric codes with the official country-standard codes, helping ensure addresses are accurate and consistent for users and integrations.
Original PR description
**Steps to reproduce:** 1. Go to Sales > Create and edit a new customer. 2. Select Chile as the country and choose a state. **Issue:** - State codes appear as numbers (e.g., 01, 02, 03...) which are not ISO-compliant. **Cause**: - State codes in the CSV file were defined as simple numbers instead of proper ISO codes. <img width="601" height="146" alt="image" src="https://github.com/user-attachments/assets/a941c200-467b-4ad5-8f79-ca9e8a92d7b4" /> <img width="443" height="131" alt="image" src="https://github.com/user-attachments/assets/dc1df1b0-2267-499f-ad1d-bb5c9381cd66" /> **Solution**: - Updated all state codes to match the official ISO 3166-2:IQ codes (Reference: https://www.iso.org/obp/ui/#iso:code:3166:CL) **opw-5148562**
This fixes an issue where a sales order line could keep an outdated Delivered Quantity Method after the related product’s service settings were changed. The field now refreshes correctly when product type or service-related settings are updated, helping keep delivery tracking accurate.
Original PR description
To reproduce: ============= - create SO with a product of service type 'manual' - go to product and change its service type to 'milestones' - go back to SO -> the field 'Delivered Quantity Method' is not updated Problem: ======== `qty_delivered_method` is a computed field depending only on `product_id`. When changing the service type of the product, the field is not recomputed. Solution: ========= Add dependencies on `product_id.type` and `product_id.service_type`. P.S: also added `is_expense` as dependency as it is used in the computation. opw-5096446 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
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
When bills are created from QR Vendor Scan or IRN fetching, Odoo now uses the GST treatment provided by Partner Autocomplete instead of defaulting to “regular.” This helps ensure vendor tax treatment is set correctly from the start, reducing manual corrections and tax-related mistakes.
Original PR description
Before this commit: We used to set `regular` treatment when using QR Vendor Scan or Fetching bill with IRN After this commit: We use the GST Treatment received from Partner Autocomplete to set the GST Treatment task-none --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix keeps scrap orders consistent when a user changes the product. If the new product has no valid Bill of Materials, the scrap BOM is cleared; if it does, the appropriate BOM is selected automatically, preventing quantity mismatches at validation.
Original PR description
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the…
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the bom_id field is hidden and remains set. This will cause the scrap quantity to be set to 0 when they validate the scrap. However, the product move actually happens for the correct quantity causing an inconsistency. Purpose: This will either set the bom_id field to False if the new product doesn’t have a valid BoM, or it will update it to the first available BoM. Steps to Reproduce on Runbot: 1. Create a scrap order for a product that has a kit type BoM and set the kit field. 2. Change the product to a product without a kit type BoM. 3. Validate the scrap order. 4. Observe the quantity field is set to 0, but there are product moves for the correct quantity. opw-5122880 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231937
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 fix improves how Swedish bank account numbers are identified when exporting partner bank details. It now correctly recognizes several valid account formats that were previously treated as invalid, reducing errors in exported data and helping ensure payments are handled correctly.
Original PR description
### Issue: Some valid Swedish account numbers are not recognized as Swedish. ### Steps to reproduce: - Install 'l10n_se_bban' and switch to Swedish company - Create a new partner, under the…
### Issue: Some valid Swedish account numbers are not recognized as Swedish. ### Steps to reproduce: - Install 'l10n_se_bban' and switch to Swedish company - Create a new partner, under the 'Accounting' page create a new bank account 1- 62074-0 2- 678653833066 3- 99603406872188 - In the partner list view select this new partner - Click Actions > Export, select "Banks" and "Bank Type" - Check the file 1- 62074-0 not recognized as Plusgiro 2- 678653833066 not recognized as BBAN 3- 99603406872188 not recognized as BBAN ### Cause: These numbers are not recognized by the checks of Odoo but are valid numbers: 1. Plusgiro account numbers can be 2 to 8 digits long, Odoo accepted only 7 to 8 digits account numbers 2. Old Handelsbanken numbers (6000-6999) can have 8 digits instead of 9, Odoo only accepts 9 digits numbers 3. Only clearing numbers starting with 8 are 5 digits long, Odoo also included ranges 9500-9549 and 9960-9969 ### Sources: 1 and 3: https://www.amcbanking.com/kb/swedish-payments-how-to-configure-sender-and-vendor-bank-accounts-in-fo/ 1 and 3: https://github.com/Tobbe/kontonummer.js/blob/04959502d7d2d52938aabda80b8a3464efddfdd1/kontonummer.js 2: https://github.com/barsoom/banktools-se/commit/b964806d5cad0491ea121419520fd5b5d4478c15 opw-5099867
This change fixes an access problem that prevented some Recruitment administrators from sending referral campaigns. Users with the right recruitment permissions can now complete the action without needing extra employee access rights.
Original PR description
STEP TO REPRODUCE:
------------------
1- Give to Marc Demo the right : Recruitment / Administrator (be sure he doesn't have any right on Employees)
2- Log as Marc Demo
3- Go to Recruitment
4- Click on the three dots in kanban card
5- Click on Referral Campaign
6- Click on Send
You will have an access error
This user (with these groups) should be able to send a referral campaign
task-5082344This 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
This update fixes a problem where some appointment pages could fail to load with a 404 error when the assigned staff member has flexible working hours. It ensures availability is checked correctly so customers can view the appointment details without interruption.
Original PR description
This PR fixes the 404 error displayed on the info page of a "Limit to Work Hours" appointment linked to a staff user with flexible hours. The availability of the staff user must not be computed from its work schedules as it has flexible hours. Task-5046134