Daily updates from Odoo
Monday, November 10, 2025
13 changes · 18.0
Enhancements to existing features
The bank statement validation process was optimized to run faster on large databases. This reduces waiting time for users and lowers database load, helping the system stay more responsive.
Original PR description
Description ----------- Avoid self-join of `account_bank_statement` that is done with a `Nested Loop` due to the `LATERAL`. Even if correlated, it requires two separate accesses to its index. Replaces it with a window function + `LAG` partitioned by the `journal_id`. This leads to a simpler plan (lower cost) and working in-memory instead of accessing disk pages (lower IO contention). Benchmark --------- On a database with 46k `account_bank_statement`, calling `_get_invalid_statement_ids` for all statements took: | [Before](https://explain.dalibo.com/plan/7605a4ddc42afbcf) | [After](https://explain.dalibo.com/plan/88d6ac1gee37aha3) | Speed-up | |--------|-------|----------| | 146ms | 72ms | 2x | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232980
Resolved issues and error corrections
This update fixes two issues that could prevent DHL shipments from being created successfully. It corrects a misspelled field name and adjusts the date/time format to match DHL's requirements, reducing failed shipping and return label requests.
Original PR description
Currently, when creating a DHL shipment with an export declaration that includes a customer reference, there is a misspelling of the field 'recipientReference' as 'recepientReference'. This causes…
Currently, when creating a DHL shipment with an export declaration that includes a customer reference, there is a misspelling of the field 'recipientReference' as 'recepientReference'. This causes validation errors when communicating with the DHL API. In addition, the datetime format used for the planned shipping date and time does not conform to the expected format specified by DHL. Steps to reproduce spelling issue: 1. Create a Sales Order with a customer reference and a deliverable product. 2. Validate the SO. 3. Go to the delivery, select DHL as carrier, and confirm. → Error: Validation error #/content/exportDeclaration: extraneous key [recepientReference] is not permitted. Steps to reproduce datetime issue: 1. Create a delivery using the DHL carrier. 2. Confirm the delivery. 3. Return the delivery. 4. Click "Print Return Label". → Error: Bad request #/plannedShippingDateAndTime is not well formatted (expected format: '2010-02-11T17:10:09 GMT+01:00'). Official DHL documentation: https://developer.dhl.com/sites/default/files/2025-11/dpdhl-express-api-3.1.1_swagger.yaml opw-5024363 Forward-Port-Of: odoo/enterprise#98981
This change fixes a problem where setting a default value could fail if duplicate default records already existed in the system. The update makes the lookup select only one matching record, so users can save defaults reliably without encountering an error.
Original PR description
There’s no constraint preventing duplicate `ir.default` records. When setting a default using `self.env['ir.default'].set()`, it searches for an existing one, but if more than one match is found,…
There’s no constraint preventing duplicate `ir.default` records. When setting a default using `self.env['ir.default'].set()`, it searches for an existing one, but if more than one match is found, accessing `default.json_value` raises a singleton error.
This fix makes sure the search only picks one record, avoiding that crash.
Before fix:
```py
self: res.users(1,)
>>> company = self.company_id
>>> company
res.company(1,)
>>> self.env['ir.default'].create({'field_id': 4540, 'company_id': company.id, 'json_value': 7})
ir.default(9,)
>>> self.env['ir.default'].set('res.partner', 'property_account_receivable_id', 7, company_id=company.id)
Traceback (most recent call last):
File "/home/odoo/odoo/odoo/odoo/orm/models.py", line 5630, in ensure_one
_id, = self._ids
^^^^
ValueError: too many values to unpack (expected 1)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/odoo/odoo/odoo/odoo/addons/base/models/ir_default.py", line 107, in set
if default.json_value != json_value:
^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo/odoo/odoo/orm/fields.py", line 1670, in __get__
record.ensure_one()
File "/home/odoo/odoo/odoo/odoo/orm/models.py", line 5633, in ensure_one
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: ir.default(4, 9)
```
After fix:
```py
self: res.users(1,)
>>> company = self.company_id
>>> company
res.company(1,)
>>> self.env['ir.default'].create({'field_id': 4540, 'company_id': company.id, 'json_value': 7})
ir.default(10,)
>>> self.env['ir.default'].set('res.partner', 'property_account_receivable_id', 7, company_id=company.id)
True
```
opw-5228419
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#234893This update fixes a spelling mistake in the Website Sale module, changing an incorrect word to the intended one. It improves the clarity and professionalism of the customer-facing text without affecting how the feature works.
Original PR description
Description of the issue/feature this PR addresses: This PR fixes a typo that was found in website_sale module. There is a mistake in writing "you" --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Amazon delivery update now includes the carrier code expected by Amazon in the shipment data. This helps prevent shipment updates from failing in countries where that field is required, improving order tracking reliability.
Original PR description
The `POST_ORDER_FULFILLMENT_DATA` feed that is used to push order delivery info to Amazon should follow the `OrderFulfillment` schema (see https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_4_1/OrderFulfillment.xsd), but it was missing the `CarrierCode` element, which is required in some countries. This commit adds the missing element to the payload, with the formatted carrier name as a value. If the carrier name cannot be matched, "Other" is used as a fallback to signal Amazon that they should rely on the `CarrierName` instead. Forward-Port-Of: odoo/enterprise#99026
This update adds automated tests for a sales margin scenario to make sure purchase price is recalculated correctly when a canceled order is reset, then the pricelist currency is changed. It helps prevent pricing errors for products with automated costing methods and improves confidence in future changes.
Original PR description
Description of the issue/feature this PR addresses: Test-only PR to verify `purchase_price` recomputation behavior when changing pricelist currency after order cancellation (per reviewer feedback on https://github.com/odoo/odoo/pull/232553). Current behavior before PR: No test coverage for this scenario. Desired behavior after PR is merged: Test validates correct currency conversion of `purchase_price` for AVCO/FIFO products after cancel → draft → pricelist change workflow. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures the purchase price on sales order lines is recalculated correctly when a cancelled order is returned to quotation and the pricelist currency is changed. It prevents outdated cost values from being kept, which helps maintain accurate margin calculations and reporting.
Original PR description
**Description of the issue/feature this PR addresses:** Issue: The purchase_price field in sale order lines is not recomputed when changing the pricelist to a different currency after a sales order…
**Description of the issue/feature this PR addresses:** Issue: The purchase_price field in sale order lines is not recomputed when changing the pricelist to a different currency after a sales order has been confirmed, cancelled, and set back to quotation state. This causes incorrect cost calculations and margin reporting when users need to modify the currency/pricelist of a previously confirmed order that was later cancelled and reset to draft. Affected modules: sale_stock_margin Versions affected: 16.0, 17.0, 18.0 (confirmed on 18.0) **Current behavior before PR:** When a sales order goes through the following workflow: Create a sales order with a pricelist in USD Add a product line (e.g., purchase_price shows $100.00 USD) Confirm the order (stock moves are created) Cancel the order (stock moves are set to state 'cancel' but remain in move_ids) Set the order back to quotation state Change the pricelist to one with a different currency (e.g., EUR) Result: The purchase_price remains in the original currency (USD) instead of being converted to the new currency (EUR). Root cause: The _compute_purchase_price() method in sale_stock_margin checks if move_ids exist to determine whether to use stock-based costing or fall back to the standard price from sale_margin. However, cancelled moves are still present in move_ids, causing the method to skip the currency conversion that should happen when no valid (non-cancelled) moves exist. **Desired behavior after PR is merged:** After following the same workflow: Create a sales order with a pricelist in USD Add a product line (purchase_price shows $100.00 USD) Confirm the order Cancel the order Set the order back to quotation state Change the pricelist to EUR Expected result: The purchase_price is automatically recomputed and converted to the new currency (e.g., shows €92.00 EUR based on the exchange rate). How it works: The method now filters out cancelled stock moves before checking if valued moves exist. If only cancelled moves are present, the computation is delegated to the parent sale_margin module, which properly handles currency conversion using _convert_to_sol_currency(). Video Demostration From runbot of today (10/21/2025) https://drive.google.com/file/d/1KExSzOYHAmMc10b3u_Xy5B1nWkkYOBqy/view --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When a user deletes a rating message in the portal or related pages, the rating summary now updates right away. This keeps the displayed ratings accurate and avoids showing outdated information after a message is removed.
Original PR description
*: portal, portal_rating, website_slides PR #221050, makes it possible to properly remove a message in the portal and PR #216044 retrieves the rating cards feature. There is an overlap between what these two PRs do. When a user removes a rating message and there is a rating cards feature on the page, it should be updated. Most of the remove method changes are indeed what we did in forward port of #221050 (#222517). task-5106543
When a candidate’s name is changed, any existing follow-up activities now automatically reflect the updated name. This keeps records consistent and avoids confusion for recruiters viewing older tasks.
Original PR description
Issue: When updating an hr recruitement candidate name (stored in hr_applicant after 18.2) the name change is not updated in the name of previously created activities. Cause: The field res_name in mail.activity is computed and stored only at creation of an activity. Solution: Retrigger the compute of an activity when updating a candidates name. Task-4988342
This update adjusts an automated purchase test so it works correctly with PostgreSQL 18. It keeps the test focused on the real business behavior while avoiding a database-specific error name change that caused unnecessary test failures.
Original PR description
Apparently in pg18 a standard-compliance
fix (postgres/postgres@086c84b23d99c2ad268f97508cd840efc1fdfd79) has led to `RESTRICT_VIOLATION` being emitted in cases which formerly emitted `FOREIGN_KEY_VIOLATION`. One such case is specifically being tested for by `test_purchase_order_line_without_uom`, leading to this test failing systematically when running pg18:
psycopg2.errors.RestrictViolation: update or delete on table "uom_uom" violates RESTRICT setting of foreign key constraint "purchase_order_line_product_uom_id_fkey" on table "purchase_order_line"
DETAIL: Key (id)=(29) is referenced from table "purchase_order_line".
Update the test to use the more generic `IntegrityError` as it's probably more than sufficient for our purposes. Technically we could pass a tuple of `(ForeignKeyViolation, RestrictViolation)` but it doesn't really seem necessary. And it would require fixing the `_raisesContext` override as currently it is very much *not* compatible with that.This fix makes drag-and-drop work more reliably on touch devices in the Documents app. It helps users move files or items on mobile devices, where the browser was previously losing the needed drag information before the drop action completed.
Original PR description
For now, touch devices do not work with native drag and drop in browsers. When a datatransfer is set on a dragstart event, it is lost before reaching the drop event, but only when using a touch device. Unfortunately, I still haven't found any sources that clearly explain whether this is a known bug or a limitation. The fact that on mobile (really mobile, not devtools, you need a touch device) drag fails on Chrome but succeeds on Firefox. To fix this issue, this commit manages datatransfers in an external variable, without using the method in the Event. I keep the original behavior as default, I just add a fallback to my global datatransfer variable. opw-5139435
This change makes interval calculations consistently normalize their data before combining results. It helps prevent incorrect overlaps and errors when different interval types are used together, especially in planning-related operations.
Original PR description
## The issue Prior to this commit, the `other` parameter in the `_merge` method could belong to a different class, not necessarily an instance of `Intervals`.…
## The issue Prior to this commit, the `other` parameter in the `_merge` method could belong to a different class, not necessarily an instance of `Intervals`. https://github.com/odoo/odoo/blob/8c737601327acec1d83e1e5e3c6e66c9fd226339/addons/resource/models/utils.py#L158-L165 The comment indicates that normalization should be enforced; however, there is no corresponding reference to it within the `_boundaries` method. https://github.com/odoo/odoo/blob/8c737601327acec1d83e1e5e3c6e66c9fd226339/addons/resource/models/utils.py#L48-L53 That normalization just happens in the `__init__`. https://github.com/odoo/odoo/blob/8c737601327acec1d83e1e5e3c6e66c9fd226339/addons/resource/models/utils.py#L117-L132 ## Example For example, in Planning module, we perform operations between `Intervals` and `WorkIntervals`. The `WorkIntervals` class behaves differently from `Intervals`: while `Intervals` uses disjoint closed intervals, `WorkIntervals` uses disjoint semi-closed intervals. ## Side effects During these operations, the `_merge` method was not normalizing the `_items`, which caused inconsistencies and errors (when we are merging two unormalized intervals `([0, 10], [10, 20])` with an empty `others`). ## The fix This commit ensures that the `other` parameter is normalized before processing the `_merge` operation. The fix ensures that normalized intervals are always produced after `_merge`, even when unnormalized intervals are provided as input. ## Real case That issue has been found in that ticket: 5184291 Forward-Port-Of: odoo/odoo#234352
Live chat visitors on mobile devices will no longer see the message input automatically zoom in when they tap it. This keeps the send button visible and makes chatting smoother on external websites.
Original PR description
Before this commit, when using livechat for visitors on mobile devices, click on input would zoom on input of about 115%. This zoom would hide send button at the very end of composer input, and would…
Before this commit, when using livechat for visitors on mobile devices, click on input would zoom on input of about 115%. This zoom would hide send button at the very end of composer input, and would force users to pinch-to-unzoom, making the UX quite poor. This problem happens because mobile devices have an auto-zoom feature that is triggered when font-size is below 16px. The discuss UI is designed with 14px font size (web client font size), and since 14px < 16px, it zooms on input focus to about 115%. This commit fixes the issue by using a font-size of 16px specifically for livechat visitor on mobile devices, so that this doesn't auto-zoom. Note that this problem doesn't happen on the web client even though this uses a font-size of 14px because it specifically disable the autozoom feature: https://github.com/odoo/odoo/blob/17.0/addons/web/views/webclient_templates.xml#L250 This solution is not practical for livechat, for which it has to work on any external website. opw-5229076 Before <img width="199" height="431" alt="after" src="https://github.com/user-attachments/assets/cc2f8e04-bde7-4eeb-84d5-b2efa2763490" /> After <img width="199" height="431" alt="before" src="https://github.com/user-attachments/assets/6c6679fc-9c16-40e7-ab6f-21540d20d59d" /> Forward-Port-Of: odoo/odoo#234967