Daily updates from Odoo
Friday, July 18, 2025
19 changes · 18.0
Resolved issues and error corrections
This change makes automated website tours more stable when they navigate to another page. It helps reduce inconsistent test behavior, improving confidence in quality checks without changing normal user workflows.
Original PR description
In this commit, we add expectUloadPage to goToUrl util. This util redirect to another page an involves a unload event so we need to add this key to this util to avoid undeterministic behaviors in tours that use it. 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
Italian electronic invoice XML generation now excludes linked accounting documents dated after the document being sent. This prevents SDI rejections caused by references to future invoices or payments in credit note XML files.
Original PR description
In a FatturaElettronica xml document <DatiFattureCollegate> allow us to specify any references to other previously sent documents. However, it is currently possible that the system populate this element with moves dated after the current document, causing the SDI to reject the document. Steps to reproduce: - Create an invoice A and register a full payment via the button - Create a credit note for the invoice, unreconcile the credit note if necessary - Create a new invoice B and add the credit note as payment - Create the XML of the credit note Issue: The XML includes info about invoice B, created after the credit note. If invoice B is dated after the credit note, the SDI will reject the xml Solution: Avoid including reconciled elements with date later than the current document date opw-4795664 Forward-Port-Of: odoo/odoo#219106
Project to-do activity counts now use each user's timezone to decide whether items are late, due today, or planned for the future. This prevents mismatches where dashboard counts and the activity list showed different results during certain hours of the day.
Original PR description
User timezone was not being used for activity states and thus the future, today, and late activities would be inaccurate. They were being computed with CURRENT_DATE through SQL which is based on the timezone that the SQL server is in. This would lead to there being a period of some hours based on the user timezone where the actual activities page that you click into and the systray showing different counts of activity states. For example, on our Odoo production database, activities that SF office members create on projects that were for tomorrow would show today after 5pm and when clicking on the today activities there would be nothing until midnight. Using the user timezone in order to compute what today is for them, then using this in the SQL query fixes this issue. This is the same behavior as the compute_state for the state field in mail.activity. opw-4893182
When a project task or subtask is assigned a milestone, it now uses the sales order item linked to that milestone instead of falling back to a parent task or project value. This prevents incorrect invoicing links after users manually clear and reassign milestones on sales-driven project tasks.
Original PR description
**Step to reprocduce :** 1. Install sale_project module 2. Create a product - type: Service - Invoice policy: based on the milestones - Create on order: Project & Task. 3. Create a sale order with…
**Step to reprocduce :**
1. Install sale_project module
2. Create a product
- type: Service
- Invoice policy: based on the milestones
- Create on order: Project & Task.
3. Create a sale order with that product and add two SO lines with different descriptions.
4. Confirm the sale order.
5. Click on the Tasks smart button in the sale order to open the generated tasks.
6. From one of the tasks (e.g., m1)
7. Manually remove the existing milestone and sales order item from the task.
8. Then assign a different milestone (e.g., m2) to the task.
9. The sale order item set different (e.g., m1) instead of the newly set milestone.
**Issue:**
When a task has its `milestone_id` and `sale_line_id` manually cleared, and a new milestone
is later assigned, the task does not get the correct Sales Order Item.
**Cause:**
In the `_compute_sale_line` method, the logic priority the parent task and project when
computing the `sale_line_id`, and only uses the `milestone_id.sale_line_id` as a fallback.
https://github.com/odoo/odoo/blob/259f7eafb15882807640a00cf6939129f27c8fbb/addons/sale_project/models/project_task.py#L109-L113
**Solution :**
To fix this `_compute_sale_line` method to priority the milestone's `sale_line_id`
when a milestone is explicitly set. This ensures that if the task’s milestone
changes, its sale line reflects the one from the milestone, even for subtasks.
opw-4701106This fix makes an automated mail test more reliable by shortening the simulated reconnect timing so the warning appears within the expected window. It helps prevent false test failures in busy environments without changing the user-facing product behavior.
Original PR description
The "show warning when bus connection encounters issues" test simulates a disconnected WebSocket that fails to reconnect. In this scenario, an alert is shown to warn the user that some features may…
The "show warning when bus connection encounters issues" test simulates a disconnected WebSocket that fails to reconnect. In this scenario, an alert is shown to warn the user that some features may be unavailable or slow. However, the websocket worker’s initial reconnect delay is 1.5s, with an added random jitter up to 1 second which means the first reconnect attempt can take up to 2.5s. The test waits up to 2.5s for the alert to show, which is not always enough. The reconnect attempt alone may be that long, and under high CPU load, processing the resulting event can take even longer. This commit reduces the initial reconnect delay and the jitter during this test, ensuring that the reconnect attempt fails and the alert is shown within the expected time. fixes runbot-226443 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
Electronic invoice exports now include the product barcode in the same field already used when importing invoices. This improves consistency between incoming and outgoing UBL/CII documents and helps partners identify products more reliably.
Original PR description
[FIX] account_edi_ubl_cii: export product barcode too Currently we use the `Item/StandardItemIdentification` as the barcode when importing a product. But we do not export the same information. In 18.0+ the `Item/StandardItemIdentification` was added to the UBL XML (for exporting) in commit 72e312815f372de88388c47c612bb5f44b4d8b4e. But there it is only used in `l10n_co_dian`. After this commit we export and fill the tag "by default". task-4941855 Forward-Port-Of: odoo/odoo#218779
Deleting a customer or address will no longer automatically remove related draft or cancelled sales orders. This prevents users from unknowingly losing orders when removing a partner that was only used as a shipping or invoicing address, and lets them review and handle those orders themselves.
Original PR description
On partner deletion, draft & cancelled orders were automatically deleted as well (to ease the deletion of 'unused' partners). Nevertheless, since both the main customer and the shipping and invoicing addresses were considered, the deletion of a partner might lead to the unexpected deletion of an order where the deleted partner was only the invoicing or shipping address. The user might not even be aware of it if they didn't enable the shipping/invoicing addresses setting. We believe it's better to drop this magical deletion and let the user be aware that there are orders related to the customer, so that they can handle it the way they want to, without the program deciding for them. opw-4866778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When settling a sales order in Point of Sale, the order lines are now reloaded from the server instead of relying on older cached data. This ensures cashiers see the latest quantities and prices after changes made in Sales or previous partial payments, reducing billing mistakes.
Original PR description
Steps to reproduce ------------------ 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTX is X as expected 4. Return to…
Steps to reproduce ------------------ 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTX is X as expected 4. Return to Sales order (in the sales app) 5. Edit QTY from X to Y and save 6. Go back to PoS 7. Delete the laoded Sales Order and load it again -> Notice that QTY is still X and not the updated Y!! Other Flow in frontend ---------------------- 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTY is X as expected 4. Change the quantity manually, to pay for X - 1 5. Validate and pay for the order 6. Load the same Sales order again with "Settle the order" -> The quantity is still X and the price is the unit price times X!! Why the issue ------------- When settling the order, we get its value using _getSaleOrder which basically reads it from the cache. So it will read the old order lines having the old qty, and not the updated one. The fix ------- Instead of reading the lines from the cache, we read them direcly from the backend, to accomodate for cases where the data might have been changed on another device or has not been updated in the cache. opw-4819708 opw-4913397 Co-authored-by: Arthur Nanson <artn@odoo.com>
Odoo now blocks users from archiving a pricelist that is still linked to an active loyalty or promotional program. This prevents coupon codes from being rejected unexpectedly and keeps discount program setup consistent for sales teams.
Original PR description
**Step to Reproduce:** 1. Install `sale_loyalty` and `sale` 2. Enable the `Pricelists` option in the settings. 3. Create a pricelist named demo. 4. Create a Discount & Loyalty named `test program`…
**Step to Reproduce:**
1. Install `sale_loyalty` and `sale`
2. Enable the `Pricelists` option in the settings.
3. Create a pricelist named demo.
4. Create a Discount & Loyalty named `test program` with type `Discount Code`,
5. Assign the demo pricelist to the loyalty program.
6. Copy the discount code from the program’s conditional rules.
7. Archive the demo pricelist.
8. create sale order for any product.
9. Try to apply the copied coupon code.
**Observation:**
- An error is shown: "This code is invalid".
- check loyalty program `test program` pricelist field is empty, that suggesting it's valid for all pricelists, but the coupon still fails.
**Issue:**
- When a linked pricelist is archived, it's hidden in the UI, but the relation still exists in the relational table.
```17_sale=# select id,name,active from product_pricelist;
id | name | active
----+------------------------------------+--------
1 | {"en_US": "Default USD pricelist"} | t
2 | {"en_US": "new"} | f
(2 rows)
17_sale=# select * from loyalty_program_product_pricelist_rel;
loyalty_program_id | product_pricelist_id
--------------------+----------------------
5 | 2
(1 row)
```
- While filtering the domain for coupon, the condition is not satisfied due to the program's pricelist.
https://github.com/odoo/odoo/blob/94d727bd9ba38116d3e14188c730c7566744e9f0/addons/sale_loyalty/models/sale_order.py#L636-L647
**Solution:**
- Display a validation error to the user when trying to archive a pricelist
that is linked to any active promotional programs.
opw-4841678
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#214968Automatic invoice sending now reports its scheduled job progress using the correct number of invoices processed and still pending. This avoids misleading logs that previously suggested no records were processed, making monitoring clearer for administrators.
Original PR description
The scheduled action for the automatic sending of invoices currently does not explictly use the `_notify_progress` method introduced since Odoo 18 to track the progress of CRON jobs. This means that implicitly, by default the CRON will log `processed 0 records, 0 records remaining` at each run. This can be confusing, as the automatic invoice sending CRON is batched, and might run multiple times in sucession, reporting each time that it processed 0 records (which might not be true). ## Proposed fix: We correctly count the total account moves that need to be processed (using a `search_count`) and calculate the number of processed records and the remaining ones. opw-4926541 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Reinstalling the Amazon sales integration on databases with past Amazon sales could previously run out of memory. This change reduces the data loaded during setup, making reinstallations much more reliable and lowering peak memory use significantly.
Original PR description
Description ----------- On databases that had `sale_amazon` installed in the past, were used for sales for a certain period, then had the module uninstalled, and later attempted to re-install it, a…
Description ----------- On databases that had `sale_amazon` installed in the past, were used for sales for a certain period, then had the module uninstalled, and later attempted to re-install it, a memory error will occur. The peak memory usage stems from `sale.order.line._compute_is_service`. The reason the compute is triggered is because of the "re-creation" of the master data products `default_product` & `shipping_product`, which writes `type`, which the compute depends on. So the compute will be triggered for all `sale.order.line` records that had those products. This commit avoids the excessive memory usage by explicitly fetching the fields that are needed for the compute, which avoids fetching large fields like the different products' HTML descriptions. Benchmark --------- On a database with 400k+ `sale.order.line` with an amazon related product, installing `sale_amazon` peak memory usage was: | | Peak Mem. | |--------|-----------| | Before | 3.8 GiB | | After | 580 MiB | Reference --------- opw-4915892 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
French electronic invoices sent through Peppol now use the expected XML identifier field. This prevents Peppol validation errors when companies send BIS Billing 3.0 invoices with French SIRET details.
Original PR description
### Issue: BIS3 XML is not valid for Peppol ### Steps to reproduce: - Install l10n_fr_facturx_chorus_pro and switch to french company - Activate peppol - Create a French customer - Under Sales and…
### Issue: BIS3 XML is not valid for Peppol ### Steps to reproduce: - Install l10n_fr_facturx_chorus_pro and switch to french company - Activate peppol - Create a French customer - Under Sales and Purchase tab, set SIRET to "11000201100044" - Under Accounting tab, set the following: - Invoice sending = Peppol - Einvoice format = BIS Billing 3.0 - peppol_eas = France SIRET - peppol endpoint = 11000201100044 - Use Invoice/Invoiced smart button, then select New to create an invoice for this french customer - Add any non-zero invoice line, then confirm - Send and print, send to peppol - Download the XML. The /PartyIdentification/ID element will have the schemeName attribute set. ### Cause: Previous [commit](https://github.com/odoo/odoo/commit/0f3a9dee5cf15fa978a1857c184413003147c4a6#diff-10c62c279423109c43458eab15a3177ff5592d6570451f890fead74389bc3740) added `schemeName`. But Peppol doesn't want any `schemeName`, see the [doc](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/UBL-DT-08/). ### Solution: The correct attribute here seems to be `schemeID`. See an [example from the docs of Peppol](https://docs.peppol.eu/poacc/billing/3.0/bis/#_parties_2). Change `schemeName` to `schemeID`. opw-4934436
This fix prevents an error that could occur while editing a website header and pressing the Tab key when no text area was selected. It improves editing stability by safely handling cases where the cursor selection is missing.
Original PR description
This PR fixes traceback issue: Steps to Reproduce for 1st traceback: 1. Go to Website in edit mode. 2. Click on the menu in the header such a way that the cursor is not placed inside. 3. Press the tab key. 4. You will receive the traceback. Issue: When the selection is null, the anchorNode also becomes null, resulting in closestUnbreakable being null. Therefore, we should avoid accessing nodeName on a null element to prevent errors. Fix: Safely access elements using optional chaining to prevent errors when elements are not found. task-4577864
This update makes an internal mail suggestion helper available for customizations. It helps partners and developers apply targeted custom patches more reliably without changing the standard mail behavior for everyday users.
Original PR description
Useful for custom patches.
This update prevents referral refusal notifications from being sent just because HR opens the refusal wizard. Notifications are now sent only after the refusal is confirmed and are attached to the correct referrer user records, avoiding unnecessary emails and improving email processing performance.
Original PR description
## [PERF] hr_referral: Send refusal notification to referrer's users Description ----------- Following https://github.com/odoo/enterprise/commit/764f9b6f513c90eb79935d9e8469989ea704b61b,…
## [PERF] hr_referral: Send refusal notification to referrer's users Description ----------- Following https://github.com/odoo/enterprise/commit/764f9b6f513c90eb79935d9e8469989ea704b61b, `_send_notification` will not attach the message on the `hr.applicant` itself, so a `model` was provided. But due to a missing `res_id`, `message_notify` will set both `model` & `res_id` to `False` since both are not specified. This leads to the creation of a `mail.message` with no `res_id` and no `model` (as `self` is an empty `mail.thread` recordset). This leads to a performance regression when mail references need to be computed to attach to the notification in `_notify_by_email_get_base_mail_values`, due to the missing `model` and `res_id` of the message. This commit attaches the notification to the referrer's users instead, providing its `model` and `res_id`. Reference --------- opw-4943488 --- ## [FIX] hr_referral: Do not send notif when opening the refuse wizard Description ----------- Currently, when opening the refusal wizard for an applicant, a call to `archive_applicant` is made. However, there is an override of it in `hr_referral` to send a notification for the applicant's refusal, and closing the `referral_state`, even though the applicant may have not been provided a reason for refusal, and the HR can simply close the wizard instead of confirming it. This commit removes the override of `archive_applicant` and moves its logic into `action_refuse_reason_apply` which is called when the wizard is confirmed. Reference --------- opw-4943488 Forward-Port-Of: odoo/enterprise#90309
This fix removes an incorrect default setting in the Swiss payroll ELM transmission configuration. It helps ensure payroll transmission settings use the proper company configuration instead of applying an unintended preset value.
Original PR description
…lated field Forward-Port-Of: odoo/enterprise#90425
Fixes an error that could prevent users from reconfirming a loan after cancellation when Accounting Audit Trail is enabled. This ensures loan workflows remain usable even when past posted accounting entries must be preserved for compliance.
Original PR description
Steps: - Activate Audit Trail in Accounting configuration - Create and confirm a loan, having some moves posted in the past - Cancel it, reset it to draft the re-confirm it again -> ValueError: Expected singleton This is because posted moves can not be unlinked when canceling/closing the loan if audit trail is activated. Therefore we try to access the `state` field from a recordset instead of a singleton. With this commit, we filter the generated move to get the newly created one. opw-4834361
This fix prevents the Barcode app from storing invalid empty values while scanning lots during receipt operations. It avoids a crash when users scan multiple lots, helping warehouse teams complete incoming shipments reliably.
Original PR description
## How to reproduce: https://github.com/user-attachments/assets/bf44f9fd-0402-4d70-8b55-5baf192d42e8 - Enable Consignment - On Receipt operation type, enable 'Use existing lots' - Create product P,…
## How to reproduce:
https://github.com/user-attachments/assets/bf44f9fd-0402-4d70-8b55-5baf192d42e8
- Enable Consignment
- On Receipt operation type, enable 'Use existing lots'
- Create product P, tracked by lot
- Create lot SN-001 & SN-002
- Add 1 unit on hand with lot SN-001
- Create Receipt for 10 units of P -> Confirm
- Open receipt on Barcode App
- Scan "SN-002" => 'undefined' value added to 'dbQuantCache'
- Scan "SN-001" => Uncaught Promise > quantsByLocation is not iterable (cannot read property undefined)
---
## Test result without fix:
```
2025-07-18 09:30:33,801 20801 ERROR oes_test_18 odoo.addons.stock_barcode.tests.test_barcode_client_action_picking: FAIL: TestPickingBarcodeClientAction.test_barcode_lazy_cache_scan_two_lots
Traceback (most recent call last):
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/enterprise/stock_barcode/tests/test_barcode_client_action_picking.py", line 3508, in test_barcode_lazy_cache_scan_two_lots
self.start_tour(url, 'test_barcode_lazy_cache_scan_two_lots', login='admin')
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/odoo/odoo/tests/common.py", line 2264, in start_tour
return self.browser_js(url_path=url_path, code=code, ready=ready, timeout=timeout, success_signal="tour succeeded", **kwargs)
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/odoo/odoo/tests/common.py", line 2235, in browser_js
self.fail('%s\n\n%s' % (message, error))
AssertionError: The test code "odoo.startTour('test_barcode_lazy_cache_scan_two_lots', {"stepDelay": 0, "keepWatchBrowser": false, "debug": false, "startUrl": "/odoo/147/action-stock_barcode.stock_barcode_picking_client_action", "delayToCheckUndeterminisms": 0})" failed
TypeError: quantsByLocation is not iterable (cannot read property undefined)
at LazyBarcodeCache.getQuants (http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21482:279)
at BarcodePickingModel._processBarcode (http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21748:631)
at async http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21661:75
```
OPW-4942192Project profitability now includes relevant budget lines even when a project’s analytic account is linked through a different analytic plan. This prevents missing budget information after upgrades or account-plan mismatches, giving users a more complete view of project finances.
Original PR description
In version 17.3, the analytic mixin was introduced in budget.line model to allow to link a budget line to multiple analytic accounts belonging to different analytic plans. The issue is that we have…
In version 17.3, the analytic mixin was introduced in budget.line model to allow to link a budget line to multiple analytic accounts belonging to different analytic plans. The issue is that we have not adapted the code in project profitability, to take those changes into account. A problematic situation could be the following: 1. We have a project where the account "X" is set to the main project plan (the first one) "Projects" BUT the account "X" actually belongs to the analytic plan "Departments" (yes, it's possible that there is a mismatch between the project plan and the analytic plan, especially after the 18.0 upgrade where "analytic_account_id" just became "account_id", no matter in which plan it was). 2. We have a budget line linked to the account "X" for the plan "Departments". 3. We want to display the budget lines in project profitability, but this line does not appear. That's because we currently only look for the budget lines belonging to the analytic plan "Projects" aka the main/first plan, that match the account "X" of the project. But as account "X" actually belongs to the analytic plan "Departments", no budget lines are found. task-4901400 version-18.0