Wednesday, January 7, 2026
11 changes · saas-18.2
Resolved issues and error corrections
This update resolves an issue where database neutralization inadvertently deleted user records due to a broad database truncation command. The fix now only deletes the 'mail.partner.device' records, preventing unintended data loss during testing and upgrades. This ensures a more stable and predictable database environment.
Original PR description
### Step to reproduce: 1. Create db in version 17.0 and create a many2one field with ``mail.partner.device`` 2. neturalize the db. All records of res.users will be vanish due to ``TRUNCATE…
### Step to reproduce:
1. Create db in version 17.0 and create a many2one field
with ``mail.partner.device``
2. neturalize the db. All records of res.users will be vanish due to ``TRUNCATE mail_partner_device CASCADE;``
### Issue:
during neutralize if there is any custom/studio field many2one with ``mail.partner.device`` even if the mail partner device
record won't used it in particular model still it will wipe out all the records of that model on neutrilizing
which can issue during testing on neutrlized db
**To fix it :**
[here](https://github.com/odoo/odoo/pull/133560/files#diff-284b40b100919f9b1d4f7bee50740387fea5f11815210baa5f6de9cbf317ca6dR14) want to delete only partner device. So, adjusted query using ``DELETE FROM mail_partner_device`` instead of truncate.
below traceback will generate due to this during upgrade.
```
Traceback (most recent call last):
File "/home/odoo/bin/misc/update_module_list.py", line 25, in <module>
env["ir.module.module"].update_list()
File "<decorator-gen-87>", line 2, in update_list
File "/home/odoo/src/odoo/17.0/odoo/addons/base/models/ir_module.py", line 71, in check_and_log
log_data = (method.__name__, self.sudo().mapped('display_name'), user.login, user.id, origin)
File "/home/odoo/src/odoo/17.0/odoo/fields.py", line 1188, in __get__
raise MissingError("\n".join([
odoo.exceptions.MissingError: Record does not exist or has been deleted.
(Record: res.users(1,), User: 1)
[ERROR]::Error during the upgrade:
```
opw-5443072
upg-3712726
Forward-Port-Of: odoo/odoo#242081
Forward-Port-Of: odoo/odoo#241535This update corrects a display issue where archived recurring plans continued to show up as pricing options on the website. The fix ensures that inactive plans are no longer considered during product pricing selection, providing a cleaner and more accurate presentation of available plans to customers. This improves the user experience and prevents confusion.
Original PR description
**Steps to produce:** - Install `sale_subscription,website_sale` module. - `Subscription > Configuration > Recurring Plans`. - `Archive` the `Monthly` plan. - Go to website > Shop > Open product `Car…
**Steps to produce:** - Install `sale_subscription,website_sale` module. - `Subscription > Configuration > Recurring Plans`. - `Archive` the `Monthly` plan. - Go to website > Shop > Open product `Car Leasing (SUB)`. **Issue:** - Even after archiving the Monthly recurring plan, its pricing still appears on the website product page. **Root cause:** - At [1], when searching for a suitable recurring price, the system does not filter out pricing records belonging to archived recurring plans. - As a result, inactive plans are still considered during pricing selection. **Solution:** - In this fix, we ensure that recurring plan pricing is included only if the related plan is active. - Archived plans are now ignored, preventing them from appearing on the website. [1]: https://github.com/odoo/enterprise/blob/25edaac85f8fd1699bb78163b01efb966e7fb680/sale_subscription/models/sale_subscription_pricing.py#L78-L79 before <img width="340" height="184" alt="recurring_plan_before" src="https://github.com/user-attachments/assets/abac39fb-5765-4bc4-aec3-87eef7135a18" /> after <img width="337" height="168" alt="recurring_plan_after" src="https://github.com/user-attachments/assets/35ee92e8-e66b-4612-add3-58b277560ea5" /> **opw-5266333** Forward-Port-Of: odoo/enterprise#103223 Forward-Port-Of: odoo/enterprise#100587
This update prevents the loss of Starshipit orders when label creation fails during delivery validation. Previously, a failed label attempt would delete the order, now users can retry validation and fix data in Starshipit without losing existing orders. This enhances the reliability of our delivery process.
Original PR description
## Current behaviour: When validating a delivery, Odoo sends data to Starshipit. If label creation fails, the module deletes the created order. ## Expected behaviour: If label creation fails, the…
## Current behaviour: When validating a delivery, Odoo sends data to Starshipit. If label creation fails, the module deletes the created order. ## Expected behaviour: If label creation fails, the Starshipit order should remain. Users should be able to fix data in Starshipit and retry validation in Odoo without losing the existing order. ## Steps to reproduce: 1. Validate a delivery order integrated with Starshipit. 2. Trigger a label generation failure (e.g., bad address). 3. Observe that the created Starshipit order is deleted. ## Cause of the issue: The integration treats label creation failure as a fatal step and cleans up the previously created Starshipit order. ## Fix: Do not delete the Starshipit order on label failure. When the user retries validation, first check Starshipit for an order matching the unique reference. If found, reuse it and continue with label creation and manifest. If not found, create a new Starshipit order as usual. ## Additional note: The _() wrapper in the error line was removed because the Starshipit service has no env or language context. Since translations cannot be resolved there, Odoo raised a warning. Removing _() avoids this warning and keeps the error clean. opw-5306979 Forward-Port-Of: odoo/enterprise#101174
This update fixes a bug that occurred when push notifications were re-enabled, preventing errors in the service worker. It also addresses a vulnerability where incorrect domain names (specifically those ending in `.invalid`) could cause push notifications to fail, ensuring reliable delivery.
Original PR description
[FIX] mail: avoid error on service worker push subscription change Sometimes, the `pushsubscriptionchange` event is called without an `oldSubscription` defined, which can lead to an error occurring…
[FIX] mail: avoid error on service worker push subscription change Sometimes, the `pushsubscriptionchange` event is called without an `oldSubscription` defined, which can lead to an error occurring inside the service worker. Steps to reproduce: 1. Enable notification in Odoo. 2. Reset the permission in the Chrome interface 3. Re-enable the permission inside the discuss systray by clicking on the Odoobot message. => The pushsubscriptionchange is called without an oldSubscription [FIX] mail: ir_cron_web_push_notification are now more robust With a user having 5 registered devices for push notifications if a browser registers with an endpoint that has a wrong domain such as https://permanently-removed.invalid/fcm/send/XXXXXXXXXXXXX the cron job cannot resolve the invalid domain of the endpoint and ends up disabling it. [FIX] mail: push_to_end_point method to support .invalid TLD if a browser registers with an endpoint that has a TLD `.invalid` such as https://permanently-removed.invalid/fcm/send/XXXXXXXXXXXXX The TLD `.invalid`[1] is intended for use in online construction of domain names that are sure to be invalid and which it is obvious at a glance are invalid. The cron job cannot resolve the invalid domain of the endpoint and ends up disabling it. So we need to unregister a device with an endpoint with a `.invalid` TLD. [1]: https://datatracker.ietf.org/doc/html/rfc2606#section-2 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242013 Forward-Port-Of: odoo/odoo#240502
This update significantly speeds up product searches used in EDI processing, particularly for invoices like those from PEPPOL. By changing how product searches are performed, the system now utilizes indexes more effectively, reducing search times from minutes to seconds, even with a large number of products.
Original PR description
The \_retrieve \_product() function relies on a query with multiple domains OR'ed together. As the search will require a LEFT JOIN with the product_template table, the use of OR in the query prevents…
The \_retrieve \_product() function relies on a query with multiple domains OR'ed together. As the search will require a LEFT JOIN with the product_template table, the use of OR in the query prevents Postgres from utilizing indexes. This becomes a problem in databases with a large number of products since a seq scan would be very slow. This commit changes the way this is done by performing separate queries instead of a single query with multiple conditions within an OR statement. Although this might seem a performance degradation, it actually allows these separate queries to utilize indexes and run much faster compared to the original approach. It also simplifies the priority logic and allows for faster early exits compared to the original one. This function is mainly used with EDI crons (such as PEPPOL where this problem was noticed), which could require hundreds of product searches as it does a search per invoice line. Benchmarks: Importing a peppol document of 173 invoice lines. | Num products | Num invoice lines | Before | After | | ------------ | ----------------- | -------- | ------- | | 864873 | 173 | 868.18 s | 19.43 s | | 397005 | 173 | 468.91 s | 20.68 s | | 8064 | 173 | 125.08 s | 20.1 s | | 564 | 173 | 119.9 s | 20.21 s | opw-5245007 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#240753 Forward-Port-Of: odoo/odoo#238853
This update fixes an issue where the duration of employee time off wasn't accurately calculated after changing their contracts. The fix ensures that the system recomputes time off duration correctly when a contract is updated, preventing discrepancies in reported hours and improving payroll accuracy. This impacts all users who rely on accurate time off calculations.
Original PR description
### Steps to reproduce: - define a time-off type in hours - create working schedules : standard 40h (fixed hours) standard 20h (fixed hours) Flexible 40h (flex hours) Flexible 20h (flex hours) -…
### Steps to reproduce: - define a time-off type in hours - create working schedules : standard 40h (fixed hours) standard 20h (fixed hours) Flexible 40h (flex hours) Flexible 20h (flex hours) - create 2 employees: employee 1 with fixed hours ; employee 2 with flexible hours - create contract 1 Fix 100% (start in 01/01/2025 - standard 40h) and set it to running - create contract 2 Flex 100% (start in 01/01/2025 - Flexible 40h) and set it to running - register a 1st week t-o for each employee (ex: 08/03/2025-08/09/2025) ==> 40h and validate - register a 2nd week t-o for each employee (09/07/2025-09/13/2025) ==> 40h and validate - expire current contract (100%) for each employee and launch a new contract (50%) : - Standard 20h (Fixed hours) for employee 1 ; - Flexible 20h (flex hours) for employee 2 (start on 08/24/2025) ==> set them to running ### Cause: While we are recomputing the duration of the overlapping leaves the resource_calendar for the employee is not yet changed so when getting the work_intervals we are calculating it using the old hours_per_day. Also since we are still writing to the contract and it is not yet in running state so we won't be able to use _get_calendars_validity_within_period ### Fix: We add the number of days and duration display to the compute queue so it will be recomputed after we already change the employee's resource_calendar opw-5010995 Forward-Port-Of: odoo/odoo#227298
This update resolves an issue where the automated PDF generation for payroll wasn't working correctly when multiple payslips were processed. The fix addresses a technical problem with how the system identified the correct partner for PDF creation, ensuring that all payslips generate their corresponding PDF documents as expected.
Original PR description
### Issue: When running the scheduled action "Payroll: Generate pdfs" for several payslips, nothing is generated and a traceback can be seen in the logs. ### Steps to reproduce: - Disable scheduled…
### Issue: When running the scheduled action "Payroll: Generate pdfs" for several payslips, nothing is generated and a traceback can be seen in the logs. ### Steps to reproduce: - Disable scheduled action: "Payroll: Generate pdfs" (to avoid side effect in next step) - Refuse all time off for "Anita Oliver" (to avoid side effect in next step) - Create a user for the employee "Anita Oliver" - Link the employee and the user - Create 2 payslips - 1 for "Mitchell Admin" - 1 for "Anita Oliver" - Compute sheet and confirm both payslips - Run scheduled action: "Payroll: Generate pdfs" - Nothing happens ### Cause: The traceback is raised on the line `self._get_document_partner().id` because `_get_document_partner()` can return a recordset. ### Solution: Call `ids` instead of `id`. ### Note: Calling `_get_document_partner()` on a recordset [here](https://github.com/odoo/enterprise/blob/a0729c8d42ca93016b23e331d8f38c1f4fa88f12/hr_payroll/models/hr_payslip.py#L444) seems unexpected as, if only one payslip in the recordset has `self.employee_id.user_id.partner_id` evaluating to `True`, then it will return only this partner, completely ignoring the other part checking `self.employee_id.work_contact_id`. The final code works fine as `_check_create_documents()` is called again individually [here](https://github.com/odoo/enterprise/blob/a0729c8d42ca93016b23e331d8f38c1f4fa88f12/documents/models/ir_attachment.py#L86). opw-5213979
This update fixes an issue where Odoo incorrectly prioritized the contact name over the legal entity name when creating accounts from XML files. Following discussions with CHKL, the system now correctly prioritizes the legal entity name, ensuring accurate partner identification for accounting and billing processes. This improves data integrity and compliance.
Original PR description
When we create an account.move from an XML file, Odoo first searches for an existing partner via some values fetched with `_import_retrieve_partner_vals()`. Amongst those vals, the name can be fetched from either the `Contact:Name` or the `PartyLegalEntity:RegistrationName`. Currently, the contact name is prioritized over the legal entity name. After discussion with CHKL, this should be the opposite. Discord link: https://discord.com/channels/678381219515465750/694447009679147068/1457691361959608413 Related ticket: opw-5269360 Forward-Port-Of: odoo/odoo#242205 Forward-Port-Of: odoo/odoo#242037
This update corrects a bug where changing a product's type (from goods to service) without a standard update could bypass inventory checks, leading to incorrect stock tracking. The fix ensures that a validation error is raised when a product's type is changed, maintaining accurate inventory management.
Original PR description
## Description of the issue/feature this PR addresses: `compute_is_storable` is called when the `type` value is modified but the `write` function is never called when the value is set using the…
## Description of the issue/feature this PR addresses: `compute_is_storable` is called when the `type` value is modified but the `write` function is never called when the value is set using the `is_storable` attribute. Updating `is_storable` using a `write` ensure that an exception is raised when move line exists. But this fix addresses the symptom, not the underlying issue. So why ? Is it related to the cache or unit test environment ? ## Current behavior before PR: In a Unit test, If you convert a consumable and storable product to a service, no exception is raised, even with existing stock moves. Unlike the previous version of Odoo (<15.0), where an exception was raised when the product type was changed and stock movements existed, detection now occurs if the ‘is_storable’ status is changed. However, this detection is not triggered if the value of ‘is_storable’ is defined by its attribute. ## Desired behavior after PR is merged: An exception must be raised (like Odoo 14.0) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#239284
This update resolves an issue where the 'leitweg-id' field in xRechnung invoices was incorrectly formatted during the forward port. The fix involved updating a helper function to ensure accurate mapping of this identifier, preventing potential invoice processing errors. This ensures compliance with German e-invoice regulations.
Original PR description
Correction of the forward port for the leitweg-id in the 'cbc:BuyerReference' field for the xRechnung invoice. The 'export_invoice_vals' function is an old helper that is not used by default anymore (but used by the tests, that is why the tests did not catch the error). I added the if statement in the corresponding new helper: '_add_invoice_header_nodes' and changed the test for it to catch the error. Related: #236333 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241982
This update fixes an issue where rental transfer dates weren't automatically adjusted when a rental order's period was extended. The fix mirrors the rescheduling behavior of purchase orders, ensuring rental transfers are updated accurately, improving the rental process for customers. This prevents scheduling discrepancies and ensures accurate transfer management.
Original PR description
### Steps to reproduce: - In the settings enable "Rental Transfers" - Create a storable and rentable product P - Create and confirm a rental order for 1 unit of P - Change the rental period to 10 days in the future #### > The rental tranfers were not updated accordingly ### Cause of the issue: Nothing is currently implemented to reschedule the rental transfers. ### Fix: We somewhat mimic the reschedule purchase behavior: https://github.com/odoo/odoo/blob/6ca34a0f5347e0611cde95453119dda8b40fa589/addons/purchase_stock/models/purchase_order_line.py#L98-L101 But we rely on the order itself rather than its order lines since the `start_date` and the `return_date` are related fields so that no `write` is triggered when the order is rescheduled: https://github.com/odoo/enterprise/blob/96a80f583a0ca502ff06bc05d03775c76c6a7537/sale_renting/models/sale_order_line.py#L18-L19 opw-5158508 Forward-Port-Of: odoo/enterprise#101334