Friday, March 20, 2026
15 changes · saas-18.2
New functionality added to Odoo
This update adds support for a new Swedish Peppol BIS3 invoice validation rule. It helps ensure electronic invoices meet current Peppol requirements, reducing the risk of rejected or non-compliant invoices.
Original PR description
Rule information: https://docs.peppol.eu/poacc/billing/3.0/2025-Q4/rules/ubl-peppol/SE-R-005/ OPW-5881918 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#250657
Enhancements to existing features
Employee calendar updates now only refresh public holiday timesheets when the employee's calendar actually changes. This reduces unnecessary background work and avoids needless delete-and-recreate activity while keeping real calendar changes handled correctly.
Original PR description
Reference: opw-5938425 …imesheet regen When hr.employee.write receives resource_calendar_id, we now compare old and new calendar IDs per employee and only refresh public-holiday timesheets for employees whose calendar actually changed. This avoids needless delete/recreate churn on no-op writes while preserving the same behavior for real calendar changes. 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#253349
Resolved issues and error corrections
Field Service task imports now keep the recurrence settings provided in the spreadsheet instead of replacing them with default values. This helps teams avoid manual corrections after importing recurring tasks and ensures schedules match the original data.
Original PR description
### Steps to reproduce: - Create a xlsx sheet with some fsm_tasks values with recurrence values - Import the sheet to Field Service > Tasks - Navigate to the created tasks - Notice the recurrence values is the default ones not the ones in the imported sheet ### Cause: If we are importing records without recurrence_id value we will set the recurrence fields' values to the default values while we might already have values for those fields ### Fix: Check if we have values for recurrence fields we don't set the defaults and let the create method create the project.task.recurrence record and set the recurrence_id opw-5925546 Forward-Port-Of: odoo/odoo#249104
Documentation and clarification updates
Henry Backman has been added to Camptocamp's contributor license agreement records. This confirms authorization for contributions under the company's CLA and supports compliant contribution management.
Original PR description
Please add me as a member of the Camptocamp organization. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254367
Presence notifications now report the correct online or offline status when a user presence is removed or when missed presence updates are sent. This helps users see more accurate availability information in messaging and collaboration features.
Original PR description
...and correct im_status when missed presences Before this commit, presence channel notifications for unlinked records were sent before the records were actually removed from the database. This…
...and correct im_status when missed presences Before this commit, presence channel notifications for unlinked records were sent before the records were actually removed from the database. This caused `im_status` to be calculated using stale data, occasionally resulting in statuses other than "offline" being broadcast. This commit ensures notifications are sent only after the presences have been unlinked, guaranteeing an accurate status. Also before this commit, the missed presences flow incorrectly sent the current user's `im_status` for partners whose presences were missed. This happens because, since [1], presence updates send the bus target's `im_status`, which corresponds to the current user in this subscription flow. This commit fixes the issue by always retrieving the `im_status` from the presence record's identity field. [1] https://github.com/odoo/odoo/pull/204485...and correct im_status when missed presences Before this commit, presence channel notifications for unlinked records were sent before the records were actually removed from the database. This caused `im_status` to be calculated using stale data, occasionally resulting in statuses other than "offline" being broadcast. This commit ensures notifications are sent only after the presences have been unlinked, guaranteeing an accurate status. Also before this commit, the missed presences flow incorrectly sent the current user's `im_status` for partners whose presences were missed. This happens because, since [1], presence updates send the bus target's `im_status`, which corresponds to the current user in this subscription flow. This commit fixes the issue by always retrieving the `im_status` from the presence record's identity field. [1] https://github.com/odoo/odoo/pull/204485 Forward-Port-Of: odoo/odoo#253627 Forward-Port-Of: odoo/odoo#249314
When an Italian Public Administration customer refuses an electronic invoice, Odoo now displays the refusal reason directly in the invoice header. This helps users quickly understand why the invoice was rejected without looking into technical XML details.
Original PR description
When a Public Administrator business refuses an invoice, they also give a reason message (EsitoCommittente/Descrizione), which comes through the IAP to Odoo as an XML tag aside the Outcome code (EsitoCommittente/Esito). Before this PR, the message was ignored, now we show it in the invoice's header. ref: https://www.fatturapa.gov.it/export/documenti/messaggi/v1.1/MessaggiTypes_v1.1.xsd <img width="823" height="232" alt="image" src="https://github.com/user-attachments/assets/8f222f6b-1615-4dd2-a5dd-25e0991ea037" /> <img width="942" height="206" alt="image" src="https://github.com/user-attachments/assets/cdf109ff-40d0-4c50-bdc7-51fb4ea15c98" /> Ticket [link](https://www.odoo.com/odoo/project.task/6041276) opw-6041276 Forward-Port-Of: odoo/odoo#254481
This fixes an issue in Odoo's web testing framework where certain hierarchy checks could loop endlessly and freeze the system. The change prevents repeated processing of the same records, making automated tests more reliable.
Original PR description
Problem: Triggering the `child_of` operator in the testing framework caused an infinite loop that froze Odoo. This occurred because the framework attempted to fetch all children of the root operand without accounting for already visited nodes, resulting in children being added indefinitely. Solution: Switched from using an `array` to `set` to prevent duplicate traversal. Task-6023290 Forward-Port-Of: odoo/odoo#254857
This update resolves a visual issue where the map view in the "My Dashboard" sometimes collapsed. The fix removes conflicting height settings and adds a minimum height to ensure the map always displays correctly, regardless of the number of records shown.
Original PR description
This commit fixes rendering height issues when the map view is displayed inside "My Dashboard". * Removed `height: 100%` from the map and pin list containers. This conflicting rule interfered with the flexbox layout, often causing the map to collapse entirely since it couldn't compute its own height. * Added a `min-height` to the map renderer. This ensures the map always occupies a reasonable amount of space in the dashboard, even when there are few or no records to display. task-6022958 Forward-Port-Of: odoo/enterprise#110968 Forward-Port-Of: odoo/enterprise#110790
This update resolves a technical issue that could have caused errors when importing bank statements with multiple journals using different currencies. The fix prevents a redundant process from triggering, ensuring smoother and more reliable import of bank statement data, particularly for businesses operating with diverse currency setups.
Original PR description
When having multiple journals with the same IBAN, but different currencies, we could have a singleton error if they are not all configured the same (besides the currency). This happens in the cron that fetches new CODAs as we first fetch all CODAs. Then, for each, we have to dispatch it in the right journal. To do so, we rely on `_parse_bank_statement_file` which is called on `self`, which itself calls `_get_coda_final_statements` that triggers the singleton error. However, at this point, we don't care about calling `_get_coda_final_statements` since we only want to retrieve the IBAN and the currency of the CODA, we don't care about the other details. Thus, the solution here is to ignore this call if we don't need it while just retrieveing the necessary info to match a journal before even creating the statements. opw-5723017 opw-6036909 Forward-Port-Of: odoo/enterprise#111101
This update corrects a technical issue that caused the Odoo Enterprise system to crash when resetting purchase data fetching settings for a company. The fix ensures that the system correctly handles this scenario, preventing future errors and maintaining reliable data retrieval for Kenyan e-invoicing.
Original PR description
In case the purchase last fetch data is resetted to `False` on the company, the next cron run will crash with: `type object 'datetime.datetime' has no attribute 'datetime'` This commit fix the wrong default date fallback. opw-5220129 Forward-Port-Of: odoo/enterprise#111124
This update resolves a technical issue related to how geographic data (topoJSON) is processed within the Enterprise edition of Odoo. The fix ensures that charts displaying location-based data are now rendered correctly, improving the accuracy and reliability of these visualizations. This primarily impacts users relying on charts that utilize geographical information.
Original PR description
test adaptation Counterpart of github.com/odoo/odoo/pull/248847 Task-5224009
This update corrects a bug where changes to view order within the Documents module's studio interface weren't consistently applied. The fix involved updating the default order setting within the Documents relational model, ensuring that view order changes are correctly reflected. This improves the user experience for managing document views.
Original PR description
Bug === When changing the order of the views using studio, it wasn't applied. The reason is that we add a default order at the wrong place in JS, it should be done with the attribute made for that, `defaultOrderBy` on the relational model. Task-6047024 Forward-Port-Of: odoo/enterprise#111091
This update fixes an issue with the numbering of lines within the Vietnamese balance sheet report. Specifically, the order of items under 'I. Short-term liabilities' was corrected. This ensures the report accurately reflects financial data for Vietnamese businesses using the Odoo Enterprise system.
Original PR description
- Fixed the numbering of report lines under the section "I. Short-term liabilities" in the balance sheet report 6035762 Forward-Port-Of: odoo/enterprise#111234
This update corrects a visual issue where the company header in accounting reports appeared grayed out in dark mode. The change ensures consistent color styling across both light and dark themes by updating the header's color to a standard muted data color, improving the user experience.
Original PR description
Before this pr: - The company header in the accounting reports is grayed out in the light mode only, not in the dark mode. Reason: - Until now, we have been using the hard-coded 'lightgrey' color for the company header. After this pr: - In this pr, we are changing the color of the company header from hard-coded 'lightgrey' color to the standard variable color '--AccountReport-muted-data-color' used for muted data in account reports. Task-5960592 Forward-Port-Of: odoo/enterprise#110108
This update resolves an issue where documents uploaded to the 'All' folder in the Documents app were not viewable through the bridge interface. The fix ensures that 'All' folder uploads now default to the standard bridge folder, restoring full accessibility for users.
Original PR description
Problem: When a user uploads a document through a bridge to the Documents app, if the destination is set to the `All` folder, the file becomes unviewable from the bridge. It can only be accessed directly via the Documents app. Cause: This occurs because `All` is not an actual folder. Uploads directed to it default to the `My Drive` folder instead. Because `My Drive` is restricted and inaccessible via the bridge, the uploaded documents remain hidden. Solution: To solve this problem, this PR ensures that uploads directed to the `All` folder default to the default bridge folder rather than to `My Drive`. task-6023290 Forward-Port-Of: odoo/enterprise#111290