Wednesday, January 28, 2026
32 changes · saas-19.1
Enhancements to existing features
This update allows tooltips in the Odoo application to now include newlines, improving readability and making them easier to understand for users. This change was driven by a need to better organize information within tooltips, enhancing the overall user experience. It's a minor improvement that addresses a usability concern.
Original PR description
We need to have a new line in tooltips. related task-5367117 Allow to have a new line in tooltips strings --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
A previous bug prevented users from adding attachments when sending emails to large groups of contacts (501+). This update corrects a technical issue related to how the system handles large contact lists, ensuring attachments can now be successfully added during mass email campaigns. This improves the reliability of the email sending process.
Original PR description
Steps to reproduce: 1. Install 'contact' 2. Create 501+ contacts (e.g. by duplicating existing one) 3. Select all contacts in list view and click Send Email (from Action menu) 4. Try to add an attachment Issue: - A traceback is raised in the mail composer: `SyntaxError: Unexpected end of JSON input` Cause: `res_ids` is not set on the composer when more than 500 records are selected. This is expected, as the compute method `_compute_res_ids()` does not write `res_ids` when the number of active_ids exceeds 500 (to avoid storing large payloads on the field). Because of this, the code trying to JSON.parse(res_ids) fails. see: https://github.com/odoo/odoo/blob/abc8417413faf598fb83106de4328571d71888aa/addons/mail/wizard/mail_compose_message.py#L400 Solution: - Fallback to context.active_ids when res_ids is not available opw-5351374 Forward-Port-Of: odoo/odoo#238311
This update resolves an issue where contract templates were incorrectly preventing users from creating them. The system has been adjusted to ignore filing status requirements for contract templates, ensuring they can be created without error. This change aligns with the correct process of determining filing status based on the employee, not the template itself.
Original PR description
1. Set "My US Company" state to California, 2. Go to Employees > Employees > Contract Templates, 3. Click New, 4. Fill in a name and save, 5. Invalid Operation: "The employee state filing status is…
1. Set "My US Company" state to California, 2. Go to Employees > Employees > Contract Templates, 3. Click New, 4. Fill in a name and save, 5. Invalid Operation: "The employee state filing status is empty..." A constraint ensures an l10n_us_state_filing_status is set on `hr.version`. The field is used by the salary rules. This field used to be on `hr.employee` and was moved to `hr.version` [1]. There's two types of `hr.version` records: templates without employee_id and actual contract versions linked to an employee. We don't want to evaluate the constraint for the templates, the only way to set a filing status is through the employee so it will always raise. This is functionally correct as well, contract templates should not have a hardcoded filing status, this should be determined per employee. The constraint will now only raise when loading a contract template on the employee or editing the field through the employee. [1] odoo/enterprise#83136 opw-5458566 Forward-Port-Of: odoo/enterprise#105575 Forward-Port-Of: odoo/enterprise#104990
This update fixes a naming inconsistency in the Spanish reporting module (l10n_es_reports). During a recent system update, the names of some reporting wizards were incorrectly updated. This change ensures consistent and accurate reporting functionality for Spanish businesses.
Original PR description
Problem --------- During the FWP moving the dictionnary definition from in-class to standalone, the naming of the wizards was wrongly updated. Solution --------- Change the naming from `l10n_es_reports_2025` to `l10n_es_reports`. error-237536
This update fixes a problem that occurred when installing new chart of accounts for Odoo's payroll system. Previously, creating a new payroll database with a specific chart of accounts (ZA) would trigger an error. This change ensures that the system correctly handles account deletions during installation, preventing this issue and improving stability.
Original PR description
When installing a chart of account, previous records are deleted to be replaced by the one of the installed chart. Since odoo/odoo@4400130eb32, we need to explicitly check for force_delete flag. Before this commit, creating a new payroll database with the ZA chart of account was raising this constraint. opw-5879978
A recent update to the ESG app within the core Odoo system increased the number of menu items being accessed. This commit adjusts a performance test to reflect this change, ensuring the system continues to load menus efficiently. This improves overall system responsiveness.
Original PR description
Due to changes in the related enterprise PR where we add new menu items in the ESG app, the number of queries has increased. This commit increases the query count in the test. task-5172829 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where editing a delivery order after adding a product (without selecting one) would cause an error. The fix ensures the system handles empty product selections gracefully, preventing disruptions to order management. This improves the reliability of delivery order modifications.
Original PR description
Currently, an error occurs when a user edits a delivery order after adding a product line, but without selecting any product. **Steps to Reproduce:** 1. Install the **Stock** module. 2. Create a new Delivery Order and click **"Mark as To-do"**. 3. Click **"Add a product"**, but do not select any product. 4. Change the 'Scheduled Date' or 'Delivery Address'. Video Ref: [LINK](https://drive.google.com/file/d/1v_MZ0nfNa_lzTjV1gChchCw4g_aKzP-8/view?usp=drive_link) **Error:** `ValueError - Expected singleton: uom.uom()` **Cause:** When a stock move is created without a product, `move.product_id` remains empty, which leads to the singleton error during product availability computation. **Fix:** This commit adds a check before performing the UOM comparison. sentry-7173331233 Forward-Port-Of: odoo/odoo#243561
This update resolves an issue where duplicate order warnings appeared when upselling subscriptions in version 19.0. The fix excludes upsell quotes from the duplicate order check, ensuring that these quotes are created and opened without unnecessary warnings. This improves the user experience and prevents potential disruptions to the sales process.
Original PR description
Version: - 19.0 Steps to reproduce: 1. Create a subscription. 2. Set a customer reference 3. Confirm the subscription and create an invoice. 4. Upsell the subscription to generate a upsell quote (state '7_upsell'). Issue: A duplicate order warning is displayed when upsell a subscription Solution: Exclude upsell quotes (`subscription_state == '7_upsell'`) from the duplicate order check in `_fetch_duplicate_orders`. This prevents incorrect warnings when creating or opening upsell quotes. taskid-5438769 Forward-Port-Of: odoo/enterprise#102795
This update resolves a test failure in the web_studio module caused by a missing dependency. The test was incorrectly reporting an error because a related module, `account_edi`, was installed but not properly accounted for in the test setup. This change ensures the test accurately reflects the installed modules and avoids false failures.
Original PR description
`RELATED_MODELS_TO_EXCLUDE` contains `account.edi.document`, which is installed by `account_edi`, which is neither in the `needed_modules` set nor a dependency of any of them. Therefore the test can fail because `account_edi` is not installed even though every module in the set is. Improve the test by checking that the models or fields we're checking for actually belong to the modules we've listed. Also add the missing module in the list. Forward-Port-Of: odoo/enterprise#105504 Forward-Port-Of: odoo/enterprise#104879
This update resolves a test failure related to how contract end dates are handled in the Enterprise Payroll module. The fix ensures contracts automatically end after two years, aligning with current payroll practices. This change improves the reliability of our payroll testing and reporting.
Original PR description
### Cause: Apparently the contract ends automatically after a period if `contract_date_end == False` ### Solution: Set `contract_end_date` to ` Date.today() + relativedelta(years=2)` like in `hr_payroll/tests/common.py` runbot-237945 runbot-237894 Forward-Port-Of: odoo/enterprise#104627
This update fixes a small visual issue in the canned responses displayed within the Odoo interface. Previously, canned responses were cropped, making the descriptions difficult to read. Now, canned responses take up the full available width, ensuring the descriptions are fully visible and easy to understand.
Original PR description
Canned responses have an arbitrary small width limit in the navigable list panel. Due to this restriction, the description of the canned response is barely readable. This commit makes it take the whole available width. task-5873810 || Before | After| | ------------- | ------------- | -----| |Discuss|<img width="832" height="318" alt="image" src="https://github.com/user-attachments/assets/4671ea44-7687-442a-a14c-1c56c3851930" /> |<img width="839" height="331" alt="image" src="https://github.com/user-attachments/assets/7fde9d8c-9682-43e5-b1b4-9a303331f445" />| |Chat window|<img width="453" height="437" alt="image" src="https://github.com/user-attachments/assets/c2b255f6-2552-4739-9a5d-d22e8c257a07" />|<img width="410" height="610" alt="image" src="https://github.com/user-attachments/assets/b8097f1b-04f4-4a3e-b11f-021bfcb9398e" />| Forward-Port-Of: odoo/odoo#245929
This update resolves a technical issue preventing accurate tracking of timesheet events. The fix corrects a categorization error that was disrupting event generation, ensuring timesheet data is properly recorded. This improves the reliability of timesheet reporting.
Original PR description
Fake events generation was broken since we categorized events by category instead of watcher in https://github.com/odoo/enterprise/pull/105263. Also something else that we shall not mention
This update fixes an issue where the 'Mark as Paid' button wasn't consistently appearing during the pay run tour. The fix ensures the button is always visible and accessible, streamlining the user experience. A related adjustment prevents the option button from being triggered multiple times, improving stability.
Original PR description
The Mark as Paid button doesn't appear in the view right away, but has been moved in the options (the ellipses button). It's enough to just add a click action on the ellipses so that the Mark as Paid button is visible and the tour can continue. Also, the button is secondary and not primary so we have removed that class altogether, since there is only one button with Mark as Paid text. This fix was already present for the hr_payroll_account_iso20022 but is now needed for the hr_payroll_account module too. However, since the iso20022 version doesn't depend on hr_payroll_account, we modify its override to only open the option if they are not already opened. This is to avoid the fact that when the override happens, the options ubtton is triggered twice, closing it and hiding the Mark as Paid button Runbot Error: 234625
This update resolves an issue in Odoo's Web Studio where incorrectly configured related fields could cause warnings and errors. The change ensures that related fields are only created when linked to searchable fields, preventing these technical problems and improving stability for business users.
Original PR description
Before this commit studio allowed to make a related field with a non-searchable field (ie standard computed fields) in the the chain. This triggered a warning at creation (at fields.py:resolve_depends) and errors when using in a business setting. After this commit, the filter to build the relational field is modified to take into account this. opw-5436158 Forward-Port-Of: odoo/enterprise#105668 Forward-Port-Of: odoo/enterprise#105607
This update fixes an issue where applicant stage changes weren't correctly displayed in the Odoo recruitment module's chatter. The fix ensures that stage change messages show the correct 'Stage changed' label and uses the accurate stage name ('Qualification') instead of 'Initial Qualification'.
Original PR description
…records in hr_recruitment_reports demo data Steps to reproduce: 1. Load demo data for hr_recruitment_reports module 2. Check applicant records in chatter 3. Observe that stage change messages don't…
…records in hr_recruitment_reports demo data Steps to reproduce: 1. Load demo data for hr_recruitment_reports module 2. Check applicant records in chatter 3. Observe that stage change messages don't show "Stage changed" label 4. Review mail.tracking.value records for applicant stage changes 5. Observe incorrect stage name "Initial Qualification" instead of "Qualification" Bug cause: mail.message records for applicant stage changes were missing the subtype_id field, which defaults to an incorrect subtype (mt_note instead of mt_applicant_stage_changed). This caused the messages to be treated as internal notes rather than stage change notifications. Additionally, mail.tracking.value records used "Initial Qualification" as the old_value_char or new_value_char, which doesn't match the actual stage name defined in hr_recruitment module. The correct stage name is simply "Qualification" (ref: hr_recruitment.stage_job1). Solution: - Add subtype_id field with reference to hr_recruitment.mt_applicant_stage_changed to all mail.message records that track applicant stage transitions - This ensures stage change events are properly identified and displayed in chatter with the correct "Stage changed" label - Update old_value_char and new_value_char fields in mail.tracking.value records to use the correct stage name "Qualification" instead of "Initial Qualification" - Ensures consistency with actual stage names and proper display in applicant chatter history Affected records: 20 mail.message records in hr_recruitment_reports_demo.xml Task Id:5454691 Forward-Port-Of: odoo/enterprise#105278
A bug was causing the Point of Sale system to unexpectedly close and open a new tab when the 'this device' button was clicked. This was due to an error in how the system generated the URL for redirection. This fix ensures that the correct URL is used, preventing unnecessary tab openings and improving the user experience.
Original PR description
Step to reproduce: - start pos - from top-right menu, click on display icon - a dialog will appear, click on "this device" button Observation: - current session will be closed and open in new tab Cause: - Incorrect url formed for redirection which, as a fallback loads currrent pos - base url is `undefined`, as we try to get it from `pos.session`, which now is attribute of `pos.config`. https://github.com/odoo/odoo/blob/06ddce00115c906a4d8396387dd3332482145d7f/addons/point_of_sale/models/pos_config.py#L288 opw-5502812 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244494
This update resolves an issue where outdated sign requests were incorrectly sending notifications to the wrong users due to missing email addresses. The fix ensures that sign requests are only sent to users with matching email addresses, improving the accuracy and reliability of the sign request process. This prevents unnecessary notifications and streamlines document signing.
Original PR description
This commits fix the problem where the `signer_email` field of old sign items don't have a value defined then showed up as "next documents to be signed" for other users, even when the email doesn't match. task-5487349 Forward-Port-Of: odoo/enterprise#104755
This update resolves a visual discrepancy in email layouts when using Columns blocks. Previously, received emails displayed incorrectly formatted columns with extra spacing. The fix ensures the email's layout accurately reflects the editor preview, improving the overall email marketing experience.
Original PR description
Problem: When adding a Columns block, the received email layout differs from the editor preview and appears broken. Cause: The iframe used for processing the editable content did not have its size properly set before conversion. This leads to incorrect calculations during the conversion to inline styles, resulting in extra spacing and misaligned columns. Solution: Force the iframe to the correct size before running the conversion. This ensures that the inline-styled email matches the editor layout. Steps to reproduce: - Add a Columns block in email marketing. - Send the email. - Observe that the received email shows columns with extra space and misalignment. opw-5490792 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#245867
This update corrects a visual glitch that appeared on mobile devices when scrolling back to the top of the website. Specifically, a horizontal scrollbar briefly appeared due to a timing issue with the header's styling. The fix synchronizes header styles to prevent this momentary display problem, ensuring a consistent and professional user experience.
Original PR description
There was an horizontal scrollbar that would appear for a short time after scrolling back to the top of the page. This would occur because the header would still have the "transform" property but the class "o_header_affixed" was already removed. To fix the issue, the header transform is now applied using dynamicContent, to synchronize the style and class correctly. This requires the standard header to have "transition: none" applied after it is scrolled since "translate(0, -100%)" would trigger an animation when hiding the header. task-5155878 Forward-Port-Of: odoo/odoo#245091 Forward-Port-Of: odoo/odoo#241980
This update resolves an issue preventing non-administrator users from accessing the Stock Valuation report. The fix ensures the report can be opened without errors by securing the data access process, improving usability for all users. This change was made to enhance the overall user experience within the Odoo system.
Original PR description
## Issue before this commit: When opening the Stock Valuation report as a non-admin user, an access error occurred. The report attempted to read `tracking_value_ids` from `mail.message`. Since `mail.tracking.value` is restricted to system administrator users, this caused the stock report to fail for regular users. ## Steps to Reproduce: - Install the stock_account module. - Log in as a non-admin user. - Open Accounting -> Review -> Inventory Valuation Report. ## Cause of the Issue: The system reads `mail.tracking.value` to get the last stock valuation closing date. Without a trusted context, this access fails for non-admin users. ## With This Commit: Tracking values are now accessed in a trusted context, allowing the stock report to open for non-admin users without changing the valuation logic. Steps To Reporduce: [Video Link](https://drive.google.com/file/d/1bFmLgadD7Z3PEntVQVM8flTAWCMDJXxK/view?usp=drive_link) opw-5483352 Forward-Port-Of: odoo/odoo#244697
This update fixes a minor usability issue in the chat window by adding a hover effect to the fold and close buttons. Previously, these buttons lacked visual feedback, making them harder to click. The change improves button visibility and responsiveness.
Original PR description
These 2 buttons had no hover effect, compared to other buttons like the "start a call". The lack of hover effect makes it harder to click on these buttons. This commit reduces slightly the opacity of button when not hovered, so that they are highlighted on hover from change to 100% opacity. The reduced opacity also makes these buttons slightly less visible, which is actually an improvement. Before / After (hover on "x") <img width="383" height="48" alt="Screenshot 2026-01-26 at 17 25 10" src="https://github.com/user-attachments/assets/7d4578cc-fcde-44b6-91e9-e0956e789c54" /> <img width="380" height="49" alt="Screenshot 2026-01-26 at 17 14 40" src="https://github.com/user-attachments/assets/e8f3690e-4202-4afd-85a5-d1459b13946e" /> Forward-Port-Of: odoo/odoo#245773
This update resolves a technical issue that could cause errors when processing Peruvian VAT (PE) invoices within the Odoo Enterprise system. The fix ensures that the system handles cases where invoice data is missing, preventing a traceback and maintaining smooth invoice processing. This improves the reliability of the PE VAT module.
Original PR description
Forward-Port-Of: odoo/enterprise#105610 Forward-Port-Of: odoo/enterprise#105462
This update resolves a technical issue where performing an undo operation after inserting a code block would generate a traceback. Now, undoing actions correctly removes inserted content without errors, ensuring a smoother user experience for the HTML editor.
Original PR description
Current behavior before PR: - Inserting a /code block, then adding text above it and performing an undo would trigger a traceback. Desired behavior after PR is merged: - Undo now correctly removes the inserted character without causing any traceback. task-5445873 Forward-Port-Of: odoo/odoo#241839
This update corrects a previous change that prevented the system from automatically selecting a default shipping method when available. It now allows the system to choose a suitable carrier from the list of options, ensuring a smoother and more efficient order fulfillment process. This resolves an issue where users were restricted from utilizing the system's intelligent shipping suggestions.
Original PR description
https://github.com/odoo/odoo/pull/203955, by wanting to ensure no unallowed carrier was set as default, removed the possibility to set one. This PR puts back the possibility of having a default shipping method if part of the available carriers. opw-5263540 Forward-Port-Of: odoo/odoo#242867
This update resolves an issue where Time-Off Responsibles lacked the ability to refuse fully accepted leaves, resulting in an access error. The fix ensures they can correctly unlink related calendar entries, aligning with existing approval workflows and improving usability.
Original PR description
****Behavior:**** When a user who is Time off Responsible but not Officer or Admin and is marked as responsible for an employee tries to refuse a fully accepted leave an access error occurs. This…
****Behavior:**** When a user who is Time off Responsible but not Officer or Admin and is marked as responsible for an employee tries to refuse a fully accepted leave an access error occurs. This occurs because approving a leave creates a resource.calendar.leave linked to the hr.leave, and when refusing it, the system will try to unlink it. https://github.com/odoo/odoo/blob/72e8a29dd0edb0ca3d464142ce869f38f96c730a/addons/hr_holidays/models/hr_leave.py#L896-L901 According to access rules of r.calendar.leaves, Time-off Responsibles are not allowed any access for entries of other employees. Approving them doesn't cause an error because the create operation uses sudo(), assuming that the user must have had valid rights to access the function. This is not the case for the unlink. **Solution:** This fix checks wether the user has write access to the related hr.leave record, then uses sudo(). The idea is that if they are allowed to modify the state of the leave, they can refuse the leave, and therefore should be able to go through the following operations. This is in a similar fashion as the behavior for approving the leaves. ****Steps to Reproduce:**** - Create a Leave Type that requires validation from a manager, and assign one to an employee. - Remove any access rights to Time-Off for the user, but leave Time off Responsible checked. - Assign the user as time-off responsible for the employee - Log in as the user and approve the leave - When refusing the leave, you should get an access error. opw-5178783 Forward-Port-Of: odoo/odoo#243405 Forward-Port-Of: odoo/odoo#238205
This update resolves an error that occurred when a repair order's scheduled date was updated without a product assigned to a move line. The issue stemmed from incorrect calculations related to unit of measure, preventing the update from completing successfully. This ensures repair orders can be scheduled reliably.
Original PR description
An error occurs when the product is not set in the repair move line, and the Scheduled Date is being updated. **Steps to Reproduce:** - Install the **Repairs** module. - Create a new **Repair Orders**. - Add a product and confirm the repair. - In the **Parts** tab, **add a new line** and change the **demanded** quantity without selecting a product. - Update the **Scheduled Date**. **Error:** `AssertionError: precision_rounding must be positive, got 0.0` `ValueError: Expected singleton: uom.uom()` (v19.0) When the move line has no `product_id`, its Unit of Measure (uom_id) is also empty. Updating the scheduled date triggers a computation, which leads to the error. Forward-Port-Of: odoo/odoo#246011 Forward-Port-Of: odoo/odoo#244179
This update fixes an issue where the tour pointer was appearing in unwanted locations, like above dialogs, creating a confusing user experience. Now, the pointer only appears when the trigger element (like the 'My Profile' menu) is actively visible, ensuring a cleaner and more intuitive tour experience.
Original PR description
POC for task-5490670 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#245949 Forward-Port-Of: odoo/odoo#243852
This update resolves an issue where the Gantt chart's date range controls would overlap with other UI elements, particularly on smaller screens. The fix adjusts the scale selector to prevent this overlap, ensuring a cleaner and more usable Gantt chart experience. This improves usability for all users.
Original PR description
Steps to reproduce ================== - Switch to dutch - Emulate an iPhone SE viewport in the browser settings - Open a project - Switch to the gantt view - Use a custom date range -> The gantt controls are displayed on top due to the daterange format being to long Note ==== The fix is in the ViewScaleSelector component, but only the gantt view uses a custom scale opw-5340869 Forward-Port-Of: odoo/odoo#245552
A recent update to the hr_expense_stripe_demo module caused a problem when users attempted to connect a demo account. This fix corrects an error in how system parameters were updated, ensuring the demo account setup now functions correctly. This resolves a minor disruption for users exploring the demo.
Original PR description
Forward port wasn't done right, and the way to get the system parameter changed. To reproduce: - Install hr_expense_stripe_demo - confirm agreeing to the terms - Save - click on "Connect (Demo)"
This update improves the reliability of the IoT Box upgrade process. Previously, a failed upgrade could cause the box to repeatedly attempt the upgrade on subsequent starts. Now, the system checks if the upgrade command was successful before renaming the branch, preventing unnecessary and potentially disruptive restarts.
Original PR description
If the upgrade fails, the branch name can already be set to the target one. Making the IoT Box not upgrading on next start. We now check `git` method return value, to ensure the command succeeded, before renaming the branch. Forward-Port-Of: odoo/odoo#245875
A recent issue prevented the Point of Sale appointment tour from working correctly when tests were run close to midnight. The fix ensures appointments are scheduled and displayed accurately, regardless of the time of day. This improves the reliability of the appointment booking process for users.
Original PR description
The `test_pos_restaurant_appointment_tour_basic` test was failing when run late in the day. The test creates an appointment 30 minutes in the future and expects a corresponding label to appear underneath the table in the POS floor plan. However, if the test is executed near midnight (e.g. 23:45 UTC), the appointment is scheduled for the following day. Since the Point of Sale frontend only displays appointments for the current day, it filters the booking out, causing the tour to timeout while waiting for the label. runbot-232601 Forward-Port-Of: odoo/enterprise#105738
This update fixes a technical issue preventing users without WhatsApp access from viewing WhatsApp conversations in Discuss. The problem stemmed from a configuration error that caused access issues when retrieving message status. This ensures all users can access and view WhatsApp conversations.
Original PR description
Steps to reproduce: - Open any WhatsApp conversation in Discuss. - post a message. - Invite an internal user who does not have WhatsApp access (e.g., Marc Demo). - Log in as the invited user. - Open the invited WhatsApp conversation. => it shows `An error occured while fetching messages` Since [1], this happens because `sudo()` was accidentally removed while storing `whatsappStatus` on messages, leading to an access error. This commit fixes the issue. [1]: https://github.com/odoo/enterprise/pull/100237 Task-5794783