Wednesday, January 7, 2026
28 changes · saas-18.4
Resolved issues and error corrections
The upgrade process for hardware driver images now remains compatible with Tailscale after moving to version 19.1. This prevents upgrade failures caused by the missing Tailscale command, helping keep connected hardware deployments reliable.
Original PR description
This PR adds a compatibility with Tailscale after upgrading 25_06/25_07 images to 19.1. It fixes the error ``` FileNotFoundError: [Errno 2] No such file or directory: 'tailscale' ``` Forward-Port-Of: odoo/odoo#242292
This fixes an issue where analytic distributions could fail when they included non-numeric system markers alongside account IDs. The change makes the process more reliable by only using values that can safely be treated as account numbers, preventing errors for users working with analytic accounting data.
Original PR description
Issue: Before this commit, the analytic distribution field contained a mix of integers (account IDs) and strings (such as '__update__'). When attempting to retrieve the account ID, converting the '__update__' string to an integer caused an error. Fix: As a generic solution, instead of skipping only the '__update__' key—which may not be the only non-numeric string in the future—we now process only the strings that can be safely interpreted as numbers. opw-5450293 Forward-Port-Of: odoo/odoo#242021
This update corrects upgrade script locations so IoT driver upgrades use the right module paths in this Odoo version. It also removes an outdated version 16 upgrade path, reducing the risk of failed or confusing upgrade steps.
Original PR description
The PR https://github.com/odoo/odoo/pull/242110 used paths with "hw_drivers" which don't exist anymore in saas-18.4. This PR adapts the paths and moves the upgrade scripts to the correct modules accordingly It also removes the deprecated v16 upgrade
The HTML editor now handles failed link preview requests gracefully, such as when a website blocks access through browser restrictions. This prevents users from seeing an error traceback when adding certain tracked or external links.
Original PR description
Problem: When a fetch request fails (for example due to CORS restrictions), a traceback occurs in the editor. Solution: Backport 971d88121968c85a86c805458d5d9dbbb305995c and ensure the error handling check is applied for both internal and external metadata fetching. Steps to reproduce: - Create a tracked link. - Copy the tracked link. - Create a link in the editor and use the copied URL. - Apply. - Traceback occurs. task-5394908 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242369 Forward-Port-Of: odoo/odoo#240712
This change increases a very short timeout used in internal email server tests to reduce false failures. It helps keep automated validation runs stable, avoiding unnecessary delays caused by test infrastructure rather than product issues.
Original PR description
There are multiple cases where the SMTPD tests fail due to a timeout error. It is much worse to get a red runbot due to a silly timeout than to sometime wait a bit longer than .1 second. 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 Forward-Port-Of: odoo/odoo#242214
Pivot spreadsheet exports now return a clear validation error when no data is provided instead of causing a server exception. This prevents confusing failures and makes invalid export requests easier to handle.
Original PR description
Currently an exception is generated when controlled `/web/pivot/export_xlsx' tries to export xlsx with empty data. `KeyError: 'title'` This PR resolves the issue by raising an `UnprocessableEntity` exception when empty data is provided. The resulting 422 response indicates that the server understood the request and its syntax, but cannot process it because the data is invalid. sentry-6321555617 Forward-Port-Of: odoo/odoo#242379 Forward-Port-Of: odoo/odoo#241415
Messages posted from the chatter now keep the expected spacing below paragraph blocks. This makes sent messages visually consistent with what users see while composing them and with emailed versions.
Original PR description
Problem: When adding a paragraph in the composer and sending the message, the paragraph posted in the chatter has a `margin-bottom` of 0. Cause: Paragraphs in the chatter rendering override the default bottom margin, resulting in inconsistent spacing compared to the composer and the sent email. Solution: Update selector to only target the last `p`. Steps to reproduce: - Open the chatter composer. - Add a paragraph using "/Paragraph". - Add some text. - Send the message. - Observe that the message posted in the chatter has no bottom margin, unlike in the composer. opw-5378129 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#240082
The website builder now updates gray color options after users change the theme's gray hue or saturation. This keeps the color picker consistent with the customized website palette and avoids confusing mismatches.
Original PR description
Steps to reproduce: - Open Website Builder. - Go to Theme > Advanced. - Change the grays hue or saturation. - Open a color picker and check the gray swatches. Before this commit, gray swatches kept using the default palette after changing the grays hue or saturation. After this commit, gray swatches reflect the customized grays.
Odoo now handles saved hierarchy filters more safely when the referenced record has been deleted. This prevents users from seeing a “Missing Record” crash when returning to views such as Employees after a related department was removed.
Original PR description
Reproduce the crash: 1- Create departement in Employees. 2- Create a default filter with child_of or parent_of on the previously created departement. 3- Delete the departement. 4- Go back to Employees => Crash 'Missing Record' This commit adds a check for record exitence in `child_of_domain` and `parent_of_domain` in the case where `_parent_store` is True. This change prevents the `Missing Record` Error. task-5217722 Forward-Port-Of: odoo/odoo#242336 Forward-Port-Of: odoo/odoo#240013
This update corrects a problem where the system was generating invoices with excessively long exchange rates for USD transactions in Vietnam. The fix rounds the exchange rate to two decimal places, aligning with documentation requirements and preventing errors during invoice creation. This ensures accurate VAT calculations and proper invoice processing.
Original PR description
* STEP TO REPRODUCE: create USD invoice to issue sinvoice, have currency rate like 26337.9186666777 , when issue we will get error because too many decimal * SOLUTION: round exchange rate up to 2 decimal because documentation said that is maximum 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 Forward-Port-Of: odoo/odoo#241061
This update resolves an issue where deleting a specific product (Booking Fees) caused an access error. The fix ensures the system can always access the product's data, regardless of the currently selected company, preventing the error from occurring.
Original PR description
**Steps to produce:** - Install `appointment_account_payment` and `l10n_be` with demo data. - Go to product `Booking Fees` and assign company `YourCompany`. - Switch the current company to `Belgium Company`. - Try to delete any product. **Issue:** - An access error is raised when deleting a product. **Root cause:** - During product deletion, method `_unlink_except_booking_fee_product_template` is executed [1]. - If the 'Booking Fees' product is assigned to another company, the current company cannot access its record, which triggers an access error. **Solution:** - Use `sudo()` when fetching the "Booking Fees" product template so that the record can be accessed regardless of the current company. [1]: https://github.com/odoo/enterprise/blob/0ba44def7fd961e1c17aa218e1a86a48f0918371/appointment_account_payment/models/product_template.py#L9-L15 opw-5255991 --- Forward-Port-Of: odoo/enterprise#101582
This update prevents the creation of duplicate bank accounts when reconciling transactions using the bank reconciliation widget. It focuses solely on the reconciliation flow, reducing confusion and errors caused by duplicate account entries. This change improves data accuracy and simplifies the bank reconciliation process.
Original PR description
When using the bank reconciliation widget, avoid creating a new bank account on the selected partner if the same account number already exists on another active partner. This change is intentionally limited to the reconciliation flow only, to reduce noise caused by duplicate bank accounts, and does not affect other partner or bank account creation use cases. task- 5236503 Forward-Port-Of: odoo/odoo#234531
This update corrects an issue with how invoices are formatted for electronic delivery to ECPay in Taiwan. The change removes the company name from the EDI address and now sends a simplified, comma-separated format. This ensures compliance with ECPay's requirements and improves the accuracy of invoice data transmission.
Original PR description
In this commit: --- Update EDI address formatting to remove the company name and send a comma-separated single-line address. task-5410619 Forward-Port-Of: odoo/odoo#241964 Forward-Port-Of: odoo/odoo#241108
This update ensures that the accounting application doesn't automatically contact our external Odoo Fin server when opened. Previously, displaying favorite institutions in the accounting dashboard triggered a call to production.odoofin.com. This fix uses a mock to prevent unnecessary external communication, improving performance and stability.
Original PR description
The aim of this commit is making sure that the click all won't try to contact our external server odoo fin when the accounting application is opened. Indeed, the accounting application is displaying the favorite institutions for a particular country in the accounting dashboard which is doing a call to production.odoofin.com. This commit adds a mock using _request_handler to patch the call to odoo fin. runbot-error-231151 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223602
This update resolves a bug that prevented users from assigning statements to multiple bank lines within the Bank Reconciliation widget. The fix ensures the system handles multiple selections correctly, preventing a common error. This improves the usability of the accounting module for managing bank statements.
Original PR description
An error occurs when a user tries to assign a Statement to multiple selected lines in the Bank Statement list view. Steps to reproduce: 1) Install Accounting with demo data. 2) Open the Bank…
An error occurs when a user tries to assign a Statement to multiple selected lines in the Bank Statement list view. Steps to reproduce: 1) Install Accounting with demo data. 2) Open the Bank Reconciliation widget. 3) Switch to the List view. 4) Select multiple statement lines. 5) Click on the 'Statement' field to assign a statement to the selected lines. Error: `TypeError: Cannot read properties of undefined (reading 'root')` Root Cause: The `BankRecMany2OneMultiID` component attempts to access `active_ids` through `this.env.model.root` (see [1]). During re-rendering, the value of `this.env.model` becomes undefined, which leads to the error. Fix: Add a check for the existence of `this.env.model` in the getter to avoid accessing `root` on an undefined model. [1]- https://github.com/odoo/enterprise/blob/c194bee0e48db407288e3c402e71840af299568d/account_accountant/static/src/components/bank_reconciliation/list_view/list_view_many2one_multi_edit.js#L14 opw-5403564 Forward-Port-Of: odoo/enterprise#101792
This update fixes a rounding issue that was causing inaccurate time remaining displays on Sales Orders. Previously, the system was rounding intermediate calculations, leading to a slight discrepancy. The fix ensures the remaining time is displayed precisely, reflecting the actual consumed hours without rounding drift.
Original PR description
Steps to reproduce: - Create service product with UoM 'pack of 20 hours' and prepaid policy - Sell the product and confirm the Sales Order - Create a helpdesk ticket/task linked to the Sales Order…
Steps to reproduce: - Create service product with UoM 'pack of 20 hours' and prepaid policy - Sell the product and confirm the Sales Order - Create a helpdesk ticket/task linked to the Sales Order Line - Log 22:00 on timesheets Current behavior: Sales Order Line shows '-2:01 remaining' Expected behavior: Should show '-02:00' to reflect two hours overconsumed without rounding. Root cause: Python's float type follows the IEEE 754 double-precision standard, where only base-2 fractions can be stored precisely. Base-10 fractions cannot be represented exactly, introducing tiny rounding errors. During chained operations such as multiple conversions or subtractions, these small errors accumulate into larger discrepancies. The float_round() function uses a small constant epsilon to correct rounding noise, but as arithmetic chains grow, errors exceed epsilon's tolerance and it can no longer correct them. Since a single global epsilon cannot handle every case (small vs. large values, chained vs. single operations, or regressions), rounding drift is inevitable when rounding happens repeatedly. Fix: To prevent these rounding errors from compounding, the solution is to stop intermediate rounding altogether. By using conversions with round=False, all arithmetic is done in the base unit (hours) with full float precision, and rounding is applied only once when displaying the final value. This eliminates error accumulation and ensures consistent, drift-free results. task-5090240 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241120 Forward-Port-Of: odoo/odoo#229282
This update resolves an issue where requesters didn't see signed documents after the signing process. The fix ensures that both the requester and signer automatically receive 'view' access rights to the signed document, preventing access problems and streamlining the document workflow.
Original PR description
To reproduce: ============= - as a User U with Admin rights on Documents (not Sys Admin) - create a folder at the root of the company - create a Sign Request template using this folder as signed document folder - send the Sign Request to another user O and sign it with that user O - go to Documents app with user U and check the folder where the signed document should be - the signed document is not there Problem: ======== when creating signed documents, the access rights for the requester are not set, causing the requester to not see the signed document Solution: ========= give `view` access right on signed documents to both the requester and the signer if they don't already have `edit` access right on it or ownership opw-[5087233](https://www.odoo.com/web#id=5087233&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#100779 Forward-Port-Of: odoo/enterprise#97132
This update resolves a problem preventing the correct display of KPD category lists within the HR module. The fix aligns the module's functionality with the latest version (19.0), ensuring accurate reporting and data processing for tax and payroll calculations. This improves data reliability and compliance.
Original PR description
Fixing the loading error for KPD category list, consistent with 19.0 version of the module. runbot-237639 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242188
This update corrects a visual issue with the carousel's indicator display, specifically when using 'Numbers' as the indicator style. The previous design resulted in unreadable numbers and misaligned buttons. This change ensures indicators are correctly sized and colored for improved usability.
Original PR description
The css rules for indicators outside the carousel were not adapted for number indicators, and used the button color intended for dots and bar as background of the numbers, making them unreadable and…
The css rules for indicators outside the carousel were not adapted for number indicators, and used the button color intended for dots and bar as background of the numbers, making them unreadable and ugly. The height of the indicators when outside influences the margin needed to align the bottom of the prev/next buttons. That caused the bottom of the next/prev buttons to not reach the bottom of the slide with "Numbers" or "Hidden" as indicators. This commit adds the necessary css rules to correctly size and colors the number indicators (and the hidden one) when positioned outside. Steps to reproduce - Add a carousel - Set "Indicators" to "Numbers" - Set "Style" to "Indicators outside" - Bug: The colors are all wrong, we cannot see the numbers - Bug: The bottom of the previous/next buttons do not reach the bottom of the carousel - Set "Indicators" to "Hidden" - Bug: The bottom of the previous/next buttons is even further from the bottom of the carousel task- 5358507 Forward-Port-Of: odoo/odoo#237397
This update corrects a visual issue where the OCR label for expense documents was incorrectly displayed alongside the data field, causing a misalignment in the expense report grid. The fix ensures that all expense data is presented clearly and accurately, regardless of the user interface mode.
Original PR description
Prerequisites ------------- To test this scenario you need either OCR credits, a free trial or to use the IAP account we have in the spreadsheet. Steps To Reproduce ------------------ 1- Go to Expenses > My Expenses. 2- Upload a receipt to trigger OCR. 3- Open the expense in Normal Mode (It works fine in Debug Mode). Issue ----- "Payment Method" field is misaligned - label appears in the value column and field appears in the label column. Cause ----- The label for "ID of the request to IAP-OCR" (`extract_document_uuid`) is visible when OCR data exists, but its field is only visible in Debug Mode. This orphan label breaks the grid layout. opw-5369619 Forward-Port-Of: odoo/enterprise#103189
A bug preventing users from searching within sign templates has been fixed. Previously, the search function within PDF templates was unresponsive. This update removes a technical issue that blocked users from utilizing the search feature, ensuring proper functionality.
Original PR description
Currently when the user is viewing sign templates, they are unable to search within a PDF. **Steps to replicate:** * Install `sign` with demo data * Sign > Templates > Open a template * Try searching using the magnifying glass button **Observed Behavior:** * User is unable to type anything in the PDF search box. **Root cause:** * This error happens because `preventDefault()` is called during a `keydown` event. At [1], calling `event.preventDefault()` stops the key’s normal behavior, so the typed character is not added to the input field. **Solution:** * Remove the `preventDefault` call which allows the search to work again. [1]: https://github.com/odoo/enterprise/blob/3df585779e6ede664279331c4531043688dadf17/sign/static/src/backend_components/editable_pdf_iframe_mixin.js#L623 opw-5366074 Forward-Port-Of: odoo/enterprise#102749
This update resolves a bug that prevented users from successfully canceling the selection of an employee photo within the Salary Configurator. The fix ensures the system correctly handles image uploads and cancellations, improving the user experience. This prevents errors and ensures data integrity.
Original PR description
**Version:** - 17.0 **Steps to reproduce:** - Install the hr_contract_salary module. - Go to Employee contract and click the Generate Offer. - Click on 'Send By Email' button and open Salary Configurator. - Upload an employee photo the first time. then cancel the image selection the second time. **Issue:** - Error occurs when canceling the image selection on Salary Configurator page. **cause:** - The condition to check whether the file exists properly was missing. **solution:** - Added the missing condition to properly check that file exist. Task-5423390 Forward-Port-Of: odoo/enterprise#102410
This update ensures that image shape colors remain consistent when animation speeds are adjusted. Previously, changing the animation speed would reset the color, causing a frustrating user experience. This fix corrects a technical issue related to how image shape IDs are handled, improving visual consistency.
Original PR description
Before this commit, changing the animation speed would reset the colors applied to the image shape. This was due to the code always considering the shape as new because the current shape id wasn't retrieved. Therefore, the colors would be reset to the default ones. Steps to reproduce the issue: - Drop a snippet with an image - Click on the image - Add an image shape. It should be animated. - Change the image shape color - Change the image shape animation speed => The image shape color was reset. task-5375497
This update resolves an issue where a specific product variant (white) wasn't consistently added to the cart during the subscription setup tour. The fix utilizes a click action instead of a checkbox, ensuring a more reliable and predictable user experience for subscription purchases.
Original PR description
In this commit we fix undeterministic error in tour sale_subscription_add_to_cart. We can see on https://runbot.odoo.com/odoo/error/234505 that variant white can not be always selected. For that we prefer use click action instead of check action.
This update resolves an issue with the 'leitweg-id' field in xRechnung invoices, ensuring accurate data transmission. The fix involved updating a helper function to correctly format this ID, which was previously missed by existing tests. This ensures compliance with invoicing standards.
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 resolves an issue where creating a new spreadsheet template within the Quality Control app would trigger a validation error due to a missing default name. The fix provides a default name, ensuring the template creation process functions correctly and users can easily create new spreadsheets.
Original PR description
**Issue** A validation error is raised when creating a new spreadsheet template from a Quality Control Point. **Steps to reproduce** 1. Open the Quality app. 2. Go to Quality Control > Control…
**Issue** A validation error is raised when creating a new spreadsheet template from a Quality Control Point. **Steps to reproduce** 1. Open the Quality app. 2. Go to Quality Control > Control Points. 3. Click "New". 4. Set the type to "Spreadsheet". 5. Click on Spreadsheet Template > Search More. 6. Click "New". -> A validation error is raised. **Cause** In `quality_view`: https://github.com/odoo/enterprise/blob/f54585f84b0fa7a73efb3f0e14266972d510f0a6/quality_control/views/quality_views.xml#L840C17-L845C19 the `many2one_spreadsheet` widget (see [`many2one_spreadsheet_field.js`](https://github.com/odoo/enterprise/blob/f54585f84b0fa7a73efb3f0e14266972d510f0a6/spreadsheet_edition/static/src/assets/components/many2one_spreadsheet_field.js#L36)) overrides "Create and Edit" to create a new spreadsheet through `Many2XSpreadsheetAutocomplete`: https://github.com/odoo/enterprise/blob/f54585f84b0fa7a73efb3f0e14266972d510f0a6/spreadsheet_edition/static/src/assets/components/many2one_spreadsheet_field.js#L11C9-L14C51 This flow does not set a default value for the required `name` field, nor does `action_open_new_spreadsheet`:https://github.com/odoo/enterprise/blob/8365feab396679f0323e89c2f4e0c825a0b2ee7e/spreadsheet_edition/models/spreadsheet_mixin.py#L348 Since `name` is required: https://github.com/odoo/enterprise/blob/8365feab396679f0323e89c2f4e0c825a0b2ee7e/quality_control/models/quality_spreadsheet_template.py#L12 validation fails. **Solution** Provide a default value for the `name` field, using the same default as in `documents_document.py`: https://github.com/odoo/enterprise/blob/8365feab396679f0323e89c2f4e0c825a0b2ee7e/documents_spreadsheet/models/documents_document.py#L321 opw-5340710 Forward-Port-Of: odoo/enterprise#101671
This update ensures that downpayment accounts are correctly applied when calculating taxes externally (like Avatax). Previously, invoices always used the default income account, even with a downpayment account set. Now, the system prioritizes the downpayment account from the product category or falls back to the company's default if no category is defined, aligning with standard downpayment behavior.
Original PR description
**Problem:** When calculating taxes externally (such as Avatax) and a downpayment is made, the line on the invoice will always use the default income account, regardless of the downpayment account set as a company default. This is inconsistent with the standard behavior of downpayments, which will use the downpayment account set on the product's category instead of the income account (which themselves may come from company defaults). **Solution:** Check if there's a company default for downpayment account on product category and use this account for the downpayment line instead of the income account. opw-5171067 Forward-Port-Of: odoo/enterprise#101570 Forward-Port-Of: odoo/enterprise#101524
Features or functions removed from Odoo
This update removes a redundant step in the website tour process. Previously, the tour included an action to copy a tracker link, which was unnecessary due to a prior code change. This simplifies the tour and improves clarity for users.
Original PR description
Following PR [^1], the step about copying the tracker link doesn't do anything as the only actual "action" made in the custom "run()" function has been removed (sic), leaving only the mocking of the Clipboard API (which isn't called anymore, anyway). This commit removes this unused step to avoid confusion. [^1]: https://github.com/odoo/odoo/pull/170548 Forward-Port-Of: odoo/odoo#241358