Daily updates from Odoo
Friday, November 21, 2025
32 changes · master
Resolved issues and error corrections
Opening the warehouse “To Receive” view could crash when many transfers had many quality checks because too much quality-check data was loaded into memory. This change loads only the needed quality-check information, greatly reducing memory use and improving reliability for high-volume warehouses.
Original PR description
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive"…
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive" button for a warehouse in the inventory app, in case there are many transfers each with many quality checks. The function will default to loading all data associated with quality checks in memory through field prefetching. However, since quality checks have too much data (particularly because of the HTML fields) associated with them, the cache can quickly bloat causing an OOM error and crashing the worker. This PR disables the prefetcher for quality checks before iterating them, preventing this issue from happening since we only need very light fields in the loop. For a specific customer (opw-5025162), this was the case. Benchmarks: | No. stock.picking | avg no. quality checks | peak memory before | peak memory after | | ----------------- | ---------------------- | ------------------ | ----------------- | | 25 | 20 | 2771 mb | 235 mb | opw-5025162 Forward-Port-Of: odoo/enterprise#98304 Forward-Port-Of: odoo/enterprise#95568
Opening the Documents app no longer fails when it contains an upload request linked to a CRM lead that has since been deleted. The document now safely shows no related record name instead of triggering an error, helping users continue working without interruption.
Original PR description
Steps to reproduce: - Install crm and documents - Go to CRM → Activity Types - Set a folder in the Upload Document activity - Create a CRM lead and schedule an upload document activity - Delete the created lead - Open the Documents module Issue: - A traceback occurs because web_read tries to access values_by_id[record.id], as the upload request document remains in the database after its related activity is deleted. Solution: - fix the recompute of res_name and set it to False, avoiding MissingError opw-5080182 Forward-Port-Of: odoo/enterprise#97461
The LinkedIn integration now uses a supported API version after the previous version was discontinued. This helps prevent connection or publishing issues for businesses using LinkedIn social features.
Original PR description
This commit updates the linkedin version header so that we can use the version of the API. Our actual version was recently sunset, needing the change of version to be done. task-5271712 Forward-Port-Of: odoo/enterprise#99759
The Helpdesk timesheet total now displays the correct value when the company uses days or half-days instead of hours. This prevents misleading totals, such as showing 160 days instead of 2.5 days, and helps teams review logged work accurately.
Original PR description
Steps to reproduce: -------------------- 1. Install helpdesk_timesheet 2. Create a new team with timesheets enabled 3. Create a new ticket and add a timesheet line with some time (e.g., 20 hours) 4.…
Steps to reproduce: -------------------- 1. Install helpdesk_timesheet 2. Create a new team with timesheets enabled 3. Create a new ticket and add a timesheet line with some time (e.g., 20 hours) 4. Open the team’s settings and observe the Timesheets stat button 5. Go to Timesheets > Configuration > Settings 6. Set "Encoding method" to "Days/Half-days" 7. Reopen the team’s settings and observe the Timesheets stat button again Issue: ------ Incorrect value displayed in the Timesheets stat button. (e.g., 160 Days instead of 2.5 Days) Cause: ------ After commit d23ca81, the UoM model was restructured, changing how conversions between hours and days are computed. The field `factor_inv`, previously used in the computation of total_timesheet_time, was removed. Earlier, `factor_inv` handled this conversion correctly. After its removal, the computation now directly uses factor, which leads to incorrect values when converting to days. https://github.com/odoo/enterprise/blob/92bb923ffe185b7744adeadcc8f2972f9a64effb/helpdesk_timesheet/models/helpdesk_team.py#L32-L36 For ex: Consider unit_amount = 20 minutes: **Before** Case 1: Encoding method = Hours/Minutes (unit_amount_sum / product_uom.factor) * uom_team.factor (20 / 1) * 1 = 20 Hours --> CORRECT Case 2: Encoding method = Days/Half-days (unit_amount_sum / product_uom.factor) * uom_team.factor (20 / 1) * 8 = 160 Days --> INCORRECT **After** Encoding method = Days/Half-days (unit_amount_sum * (1.0 if helpdesk_ticket.encode_uom_in_days else product_uom_factor)) / uom_team.factor (20 * 1) / 8 = 2.5 Days --> CORRECT Reference: The [UoM’s factor ](https://github.com/odoo/odoo/blob/ca9df34f3a29796596f92e55647f61f95a95af52/addons/uom/data/uom_data.xml#L29-L37)has also been changed. **NOTE:** Before this change, when the user opened the timesheet sublist view in debug mode and clicked the View button, it opened the default form view of the `account.analytic.line` model instead of the intended timesheet form view. This allowed editing of the Unit of Measure (product_uom_id) field also. To prevent this, the form view reference has been explicitly specified, similar to the one used in the [Project module](https://github.com/odoo/odoo/blob/3f23bd9723d9065f17c1960d185d67a0a809a889/addons/hr_timesheet/views/project_task_views.xml#L41). Solution: ---------- This commit ensures accurate conversion of timesheet values between hours and days opw-5184077 Related community PR: https://github.com/odoo/odoo/pull/233803 Forward-Port-Of: odoo/enterprise#98545
This fixes an issue in the Belgian salary contract module where the system tried to use a missing calculation function. It now reads the correct work time rate field, helping salary contract information load reliably.
Original PR description
The function _get_work_time_rate doesn't exist, but the information we need is in the field work_time_rate. Forward-Port-Of: odoo/enterprise#99922
The Sign send wizard no longer tries to read another user's saved signature or initials when it is not needed. This prevents access-rights errors in multi-role signing templates with multiple internal users, making document sending more reliable.
Original PR description
Before this commit, The following traceback was encountered when the sign.send.request wizard was opened in the following conditions: - sign.template with signature/initials fields and more than one…
Before this commit, The following traceback was encountered when the sign.send.request wizard was opened in the following conditions:
- sign.template with signature/initials fields and more than one role
- more than one sign user (internal user)
```
File "/home/user/workspace/odoo/src/19.0/enterprise/sign/wizard/sign_send_request.py", line 341, in _compute_only_autofill_readonly
not (item.type_id.name == 'Signature' and request._get_user_signature(user, 'sign_signature')) and
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/workspace/odoo/src/19.0/enterprise/sign/wizard/sign_send_request.py", line 323, in _get_user_signature
return user[signature_type]
~~~~^^^^^^^^^^^^^^^^
File "/home/user/workspace/odoo/src/19.0/odoo/odoo/orm/models.py", line 6680, in __getitem__
return self._fields[key].__get__(self)
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/home/user/workspace/odoo/src/19.0/odoo/odoo/orm/fields.py", line 1646, in __get__
record._check_field_access(self, 'read')
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
File "/home/user/workspace/odoo/src/19.0/odoo/odoo/orm/models.py", line 3426, in _check_field_access
raise AccessError(error_msg)
odoo.exceptions.AccessError: You do not have enough rights to access the field "sign_signature" on User (res.users). Please contact your system administrator.
```
This commit ensure that we don't try to access the signature/initial field of another user when it is not necessary.
task-5271648
Forward-Port-Of: odoo/enterprise#99940Closing or cancelling helpdesk tickets no longer causes an error when SLA working hours have been cleared or disabled. This keeps ticket workflows running smoothly even when teams do not use working hour policies.
Original PR description
> **The issue:** When you go to a helpdesk's team settings -> SLA Policies -> Working hours, set the working hours to empty and then disable SLA Policies and save. After that if you try to move a ticket in the same team to done or canceled you will receive an exception. **Cause:** The part of the code causing the issue is supposed to only run if a Working Hours policy is set. **Fix:** Changed the section of the code to only run when Working Hours is set. opw-5120962 > Forward-Port-Of: odoo/enterprise#98889 Forward-Port-Of: odoo/enterprise#96546
This fix updates the external tax sales test flow so it stays compatible with recent related changes in the core sales experience. It helps ensure optional product sales scenarios continue to work reliably when external tax calculation is enabled.
Original PR description
See Also: - https://github.com/odoo/odoo/pull/227241 Forward-Port-Of: odoo/enterprise#99188
This fixes an error when signing Mexican electronic invoices through SW Sapiens. A stray space in the request data was removed so the service receives the expected information and no longer rejects the request with a null value error.
Original PR description
On Commit 6c4d07f a space was added to the payload lines in the request to sw sapiens, causing the payload to contain information that it should not have and leading to the error “value cannot be null.” <img width="2914" height="1552" alt="image" src="https://github.com/user-attachments/assets/04047f14-fc21-45fd-ae29-b241dfbbed2a" /> I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Swedish point-of-sale blackbox integration now checks which protocol version a device supports before sending receipt commands. This prevents errors with older supported devices and helps businesses continue registering receipts reliably.
Original PR description
The serial protocol used with the Swedish blackbox has 2 versions, with v2 adding some more commands. Before this commit, we assumed that the blackbox was compatible with v2, causing an 'unknown message type' error if it only supported v1. After this commit, we check the protocol version of the blackbox when we initialise the driver, so that we only send compatible commands when we register a receipt. opw-5077448 Forward-Port-Of: odoo/enterprise#99930 Forward-Port-Of: odoo/enterprise#99008
The point of sale now loads only draft delivery orders when a session starts, avoiding unnecessary loading of already paid orders. This improves startup performance for businesses using Urban Piper delivery integrations and removes a minor console warning.
Original PR description
Before this commit:
---
- The POS loaded all delivery orders (including paid ones) when starting a session, which caused significant slowdowns.
- The delivery button component was missing `static props = {}`, which produced a console warning.
After this commit:
---
- The POS now loads only *draft* delivery orders, improving performance.
- Added `static props = {}` to the DeliveryButton component to remove the console warning.
task-5343700
Forward-Port-Of: odoo/enterprise#99984
Forward-Port-Of: odoo/enterprise#99904This change reverts a previous adjustment that hid section and note lines in journal item tabs because it caused new journal entry lines to calculate debit and credit amounts incorrectly. Restoring the previous behavior helps ensure accounting entries are created accurately during editing.
Original PR description
This reverts commit 17d0e67106a30a46d608331680e5094dbc44e2e0. The commit is reverted because the `journal_line_ids` field is causing issues with onchange methods that rely on cached values. Specifically, the automatic computation of `debit`/`credit` when adding new lines to a journal entry was failing. While `journal_line_ids` (as a subset of `line_ids`) works correctly when the data is stored in the database, its absence during an onchange computation (which relies solely on cache) led to incorrect behavior. no-task Forward-Port-Of: odoo/enterprise#99875
Deferred half-day and hourly leaves now keep their actual duration when moved to the next month. This prevents payroll work entries from incorrectly counting partial leave as a full day, improving payroll accuracy for employees and HR teams.
Original PR description
When deferring half-day or hourly leaves to the next month, the work entry was incorrectly replaced with a full day duration instead of the actual leave duration. Now splits the work entry to match the exact leave hours when necessary. task-5258753 Forward-Port-Of: odoo/enterprise#99415
This fix prevents upgrade failures when creating timesheet entries from helpdesk tickets that do not have their own analytic account set. It preserves the correct project account instead of replacing it with an empty value, helping affected customers complete upgrades successfully.
Original PR description
When creating an analytic line from a helpdesk ticket, we assigned the account_id from the project's account_id during the upgrade. However, in the standard code, the account_id is later overridden and updated from ticket.analytic_account_id, which is null. As a result, the constraint "At least one analytic account must be set" is triggered. see: https://github.com/odoo/enterprise/blob/dcfef2cc462631f376a596a7c85ae483826835ad/helpdesk_timesheet/models/account_analytic_line.py#L119 Multiple upgrade request failed due to this. Forward-Port-Of: odoo/enterprise#99209 Forward-Port-Of: odoo/enterprise#99201
The VoIP test setup was corrected to include complete contact data, preventing a validation error during automated test runs. This improves test reliability without changing the user-facing VoIP experience.
Original PR description
Before this commit, running VoIP tests in HOOT results in this error: > Global OwlError: Invalid props for component 'TabEntry': 'title' is not a string, 'phoneNumber' is not a string This is because one of the test is setup with incomplete data (no phone number). After this commit, test data is correctly set with a phone number, fixing the props validation error. Forward-Port-Of: odoo/enterprise#100057
Fixed an issue where invoices could fail for alternative sales orders created from subscription upsells, even after customer payment succeeded. The alternative order now keeps the correct next invoice date, preventing incorrect deferred date calculations and ensuring invoices are issued as expected.
Original PR description
Version - 17.0 Issue: - When creating and confirming an alternative sale order (SO) from an upsell order, attempting to generate an invoice would raise a deferred end date error - As a result, the…
Version - 17.0 Issue: - When creating and confirming an alternative sale order (SO) from an upsell order, attempting to generate an invoice would raise a deferred end date error - As a result, the invoice was not created, and even though the customer's payment succeeded, no invoice was issued. Steps to reproduce: - Create an upsell order of a subscription. - Click Create Alternative to generate an alternative SO. - Confirm the SO and click on Create Invoice to make the invoice - This will throw an error of defferred end date Cause: - The `next_invoice_date` was not copied from the previous upsell order to the new alternative SO. - Without this value, the deferred end date was incorrectly computed as today’s date - 1, triggering the error. Fix: - Copy the `next_invoice_date` from the previous upsell order to the new alternative SO to ensure proper deferred date computation. Impact: Invoices for alternative upsell sale orders can now be created successfully without errors. task-5241150 Forward-Port-Of: odoo/enterprise#99919 Forward-Port-Of: odoo/enterprise#98983
The approval process now blocks creating a new request for quotation when one is already linked to the approval. This prevents accidental duplicate purchasing and inflated product quantities when users click the action multiple times or work from multiple tabs.
Original PR description
**Problem:** It's possible to click the "Create RFQ's" button more than once, as the user may have multiple tabs open or multiple users are viewing the same record. When this happens, the approval will create or add to an RFQ even if it already did, and this causes double the intended product quantities. **Solution:** The "Create RFQ's" button becomes hidden when purchase_order_count > 0 (i.e. there are linked POs) so we can perform this check within the button's method `action_create_purchase_orders` to prevent RFQ generation (or modification). opw-5227493 Forward-Port-Of: odoo/enterprise#99817 Forward-Port-Of: odoo/enterprise#99706
This update corrects access to car information in the Belgian salary contract flow. Regular users and applicants can now access the car-related details they need, reducing blocked or incomplete contract salary processes.
Original PR description
Normal users and applicant don't have access to car. Forward-Port-Of: odoo/enterprise#99658
Employees who are not HR officers can now request appraisal feedback without running into access errors. The change lets the appraisal feedback flow read the necessary employee information through the public employee mechanism, keeping the process usable for managers and reviewers.
Original PR description
Since we cannot ask a feedback when we are not an HR officer because we don't have acces to employees and we get an access right error when we try to ask feedback. So we use the hr.public.version mecanism to allow too read the employees without rights. Forward-Port-Of: odoo/enterprise#99947
The Documents sharing wizard now properly applies changes when allowing link access. This ensures users' sharing permission updates are retained, reducing confusion and preventing incorrect access settings.
Original PR description
This commit fix the 'action_allow_link_access' method in 'documents.sharing' model by adding the 'WRITE_VALUE_PREFIX' to the updated fields. Otherwise the changes wasn't taken into account. Task-5220965 Forward-Port-Of: odoo/enterprise#98382
VoIP now checks both the main call and transfer call before marking a call as ended unexpectedly. This prevents transferred calls from being incorrectly flagged, improving call history accuracy for users.
Original PR description
Currently, the check for calls that were ended in a wrong way only assumes that there is one call where there might be two calls in case of transfers. This commit fixes this issue by checking for both session, the main session and the transfer session. Task-5208152
IoT boxes now keep their own last received message position when reconnecting, instead of always being moved to the newest message. This helps prevent missed updates after short connection interruptions while still avoiding old stale messages when a device starts fresh.
Original PR description
Community PR: https://github.com/odoo/odoo/pull/236843 Before this commit, if an IoT box subscribed to the websocket we would always force its last message ID to be the latest (so no old messages would be sent). However, in the case of a brief disconnection, this could result in a message being missed. After this commit, we only force the last message ID to be the latest if the IoT box does not provide its own last message ID. This way, we still avoid the issue of stale messages on boot, but allow disconnections to not result in missing a message.
Barcode scans for kit components now update the existing reserved line when a different unreserved serial or lot is scanned, instead of creating a duplicate line. This prevents unnecessary backorder prompts and helps warehouse operators complete deliveries accurately.
Original PR description
### Issue: Scanning an unreserved lot of a kit component creates a new barcode line rather than updating the value of the initially reserved lot. As a result, the backorder porcess considers that…
### Issue:
Scanning an unreserved lot of a kit component creates a new barcode line rather than updating the value of the initially reserved lot. As a result, the backorder porcess considers that every unscanned yet initially reserved quantity is to backorder.
### Steps to reproduce:
- Create a kit product with a kit BOM:
- 1 x COMP (tracked by SN)
- Add two Serial numbers SN001 and SN002 in stock for the COMP product
- Create and confirm a delivery order for 1 unit of oyur kit product
- Go the barcode app to process your delivery
- Scan SN002
> A new line is created instead of updating the initial reservation
- Validate the delivery
#### > A backorder dialog opens proposing to update the unscanned reservation
### Cause of the issue:
Scanning a lot will first try to find a line to update, however, currently a line will only be found if the scanned lot has been reserved or if no particular lot has been reserved:
https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_model.js#L1659-L1661 https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_model.js#L743-L746 In particular, since no line is considered as valid, a new line is created. And, since this new line does not refer to any `move_id` while the existing one does, the move with the initial reservation will be backordered considering none of its demand was fulfilled: https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_picking_model.js#L904-L921
### Fix:
In order to loosen the condition of lot override on barcode lines we add a check on the package and the location of the line in order to avoid use cases where the initial move line already contains info's that are proper to the initial lot.
opw-5100026
Forward-Port-Of: odoo/enterprise#99845
Forward-Port-Of: odoo/enterprise#98589Changing the quantity being produced from the barcode manufacturing flow now correctly updates and consumes the related component quantities. This prevents production orders from leaving required materials unconsumed, improving inventory accuracy for barcode-based manufacturing operations.
Original PR description
Steps to reproduce: 1- Create MO 2- Change the `qty_producing` Issue: `stock.move.lines` are not consumed. Because `qty_producing` is not a computed field therefore it has no inverse. It updates the consumption with an on change method and in Barcode we don't have `move_raw_ids` in the xml, so its not stored or saved. To fix the problem, `set_qty_producing` was called manually to keep the barcode's design clean. Task: 5111357 Forward-Port-Of: odoo/enterprise#98184
The VoIP test setup was adjusted so mobile device behavior is only simulated where it is needed. This prevents unrelated tests from being affected, improving confidence in automated test results without changing customer-facing functionality.
Original PR description
Since [1], mockUserAgent was called at the root of the module. In this case, it applies globally. This commit moves user agent mocking in `keypad.mobile.test.js` into `beforeEach` and switch to the platform-based "android" helper so it only applies to this suite. [1]: https://github.com/odoo/enterprise/commit/b118a5ceb7f0773783ca003c625c9ae3cccdebed
When a stock move quantity is increased, the system now adjusts the existing reserved line instead of creating an extra line without tracking details. This keeps barcode manufacturing stock flows more consistent and reduces confusion in inventory handling.
Original PR description
Increasing the quantity of a stock move will create a move line with the same data as the stock move (location and product), no lot, nor package. This commit correct some tests values because increasing the quantity on a stock move will increase the existing move line quantity instead of creating a new one. Forward-Port-Of: odoo/enterprise#96750
Fixed an issue where rental prices could be calculated from the default start date instead of the customer's selected start date when unavailable days were configured. This prevents customers from being charged for the wrong number of nights after changing rental dates.
Original PR description
**Issue:** Price is wrongly calculated on period Night when we have Unavailability days. **How to reproduce:** Product A with Nightly rental period. Let's say price = 100. If you're testing on a Monday, go to the settings of the Rental app. Select Wednesday as an Unavailable days (= day + 2). The next starting default date will be day +1 but the next ending default date won't be day +2. Default dates: Tuesday -> Thursday (skipping Wednesday) = **2 nights**. Computed price: **200**. OK. Select another day where day + 1 is ok for renting. Example, Thursday. Default dates: Thursday -> Friday = **1 night**. Computed price: **200**. NOK. **Reason:** The price computation is based on the default start date instead of the selected start date. Unavailability days can increase the duration, but from a wrong starting date. Issue introduced in 3e257042a9a0774e297c8fd07e651eda4613b902 Forward-Port-Of: odoo/enterprise#100085
Creating a new salary offer from an employee record no longer fails because required offer information is lost during setup. This prevents an interruption in the HR offer workflow and keeps offer generation reliable for users.
Original PR description
To reproduce: 1-Navigate to an existing employee. 2-Create a new offer for the employee using "Offers" smartbutton. -The issue firstly appeared because of this commit: https://github.com/odoo/enterprise/commit/b251408ddc16f5f76dc0dcf1270bd4a8424c7b3b -The issue appears because the form is not populated with the context data. This is because upon offer generation, the context is overridden by recomputation of payslips that happens in write() in hr.version model. -The issue should have appeared earlier, however it didn't happen by luck because the dependency check in the commit mentioned above was too specific. Proposed solution: -Send a flag in the context to avoid recomputation upon open generation. Task-id:5245134
Updated VoIP test setup to use the browser platform mock in the intended way. This helps keep automated checks reliable and reduces the risk of false test results during future updates.
Original PR description
The `mockUserAgent()` is meant to be used with a "platform" ("mac", "windows", "android"...) as parameter and not a whole user agent string.
In specific cases, a custom string can be used instead, but only to be added to the user agent string.
This commit adapts its usage(s) accordingly.
Forward-Port-Of: odoo/enterprise#100154This update keeps PDF previews working correctly in Documents after a PDF viewer change affected file links. It also keeps Sign form text readable when users or browsers use dark mode.
Original PR description
In the new version of PDF.js (viewer.js) there is these new lines:
```javascript
const queryString = document.location.search.substring(1);
const params = parseQueryString(queryString);
file = params.get("file") ?? AppOptions.get("defaultUrl");
try {
file = new URL(decodeURIComponent(file)).href;
} catch {
file = encodeURIComponent(file).replaceAll("%2F", "/");
}
```
This has an effect in document as the PDF file are not readable anymore
due has URL is not correct anymore.
To avoid malformed URL we removed the options `download=0`.
---
In the Sign app we need tho force the color of cell as now PDF.js
(iframe) enable color scheme:
```css
:root {
color-scheme: light dark;
}
```
So the `fieldtext` value will be white in dark mode, and we don't want
that.
task-5110143Planning analysis reports now only count shifts when they fall within an employee's working hours. This prevents hours from being incorrectly included in a later month when a shift ends after working hours, improving reporting accuracy for timesheets and planning.
Original PR description
### Steps to reproduce: - Create an employee with fixed working schedule from 8 to 5 - Create a Planning shift for this employee that starts in a month and ends in the first day of the next month outside of working hours (e.g. Sept30th 8AM -> Oct1st 2AM) - Navigate to Timesheets / Planning analysis reports - Notice October has been taken into consideration in the report's planned hours ### Cause: The query we are using for the timesheets/planning report doesn't take working hours into consideration it only cares about the date. So if the shift ends in October 1st we are taking it into account whether it is inside working hours or not. ### Fix: Add a condition to the where clause to check the working hours and if the record lays in this period or not. opw-5089052 Forward-Port-Of: odoo/enterprise#96846
This change avoids saving data into a field that is automatically calculated by the system. It helps prevent hidden data inconsistencies that could cause errors during product barcode lookup operations.
Original PR description
The field all_group_ids is computed from other groups, writing on it creates inconsistencies in the cache and may result in errors when invalidating/flushing.