Friday, January 30, 2026
20 changes · saas-19.1
New functionality added to Odoo
This update enables Odoo to automatically generate and send FA(3) XML invoices to Poland's KSeF system, fulfilling regulatory requirements. It adds necessary fields to invoices and company records, streamlines the submission process, and includes safeguards for data security and system stability. This ensures accurate and compliant tax reporting for businesses operating in Poland.
Original PR description
- Added new fields to res.company to handle key, certificates and session numbers - Added new fields to account.move to track KSeF status, session, reference number, attachments, errors. - Updated…
- Added new fields to res.company to handle key, certificates and session numbers - Added new fields to account.move to track KSeF status, session, reference number, attachments, errors. - Updated the frontend view of the move and the settings. Some fields are debug-view only. - Implemented the sending method with `account.move.send`, storing the xml attached to the move. - Implemented the APIs to communicate securely with the KSeF - Implemented the Check Sending and Download UPO functionality - Implemented the rendering of the FA(3)-compliant XML structure. - Implemented a cron to update invoice KSeF statuses. - Implemented locking so cron and manual don't mess up with each other. - Set as `auto-install` for those who have the Polish localization. - Wrote minimal tests for basic use cases (to be expanded). - Added `neutralize.sql` script to avoid leaking sensitive data when copying a database for support - Added module to `.weblate.json` to make this i18n-able Task [link](https://www.odoo.com/odoo/project.task/4728713) task-4728713 Forward-Port-Of: odoo/odoo#230988
Enhancements to existing features
This update ensures Odoo continues to correctly process Danish VAT (Nemhandel) transactions. The previous method for looking up directory information has been discontinued, so the system has been updated to use a new, reliable method (IAP). Additionally, a technical adjustment was made to ensure consistency with Peppol standards.
Original PR description
We need to switch the lookup on the directory to NAPTR, as the CNAME one is discontinued on January. We now go through IAP to do the lookup. It's also ensuring _check_document_type_support has always the same format as the super() coming from Peppol. task-4486039 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#240203
Resolved issues and error corrections
This update corrects a bug where archived journals were still appearing as selectable payment methods when creating company expenses. The fix ensures that only active journals are offered, improving the user experience and preventing incorrect payment selections. This was caused by a previous code change that didn't properly filter inactive journals.
Original PR description
Steps to Reproduce: 1. Go to Accounting > Configuration > Journals 2. Archive a Journal with outgoing payment method 3. Go to Expenses > Create an Expense paid by company 4. Note that payment methods…
Steps to Reproduce:
1. Go to Accounting > Configuration > Journals
2. Archive a Journal with outgoing payment method
3. Go to Expenses > Create an Expense paid by company
4. Note that payment methods from archived journal are still visible and can be selected.
Issue:
- Archived journals with outbound payment methods were still selectable when creating company-paid expenses.
- Due to this [commit](https://github.com/odoo/odoo/commit/5c9a6704dd54bbbde1703850619ddcc1a3552547) The journals can be archived without system prevention as the action_archived method has been removed.
Solution:
- This occurred because selectable_payment_method_line_ids did not filter out inactive journals when falling back to a generic search. -Aligning the search domain with
[company_expense_allowed_payment_method_line_ids]
(https://github.com/odoo/odoo/blob/19.0/addons/hr_expense/models/res_company.py#L20) by excluding payment method lines linked to inactive journals.
Before Fix:
```py
In [1]: expense = self.env['hr.expense'].browse(1639)
In [2]: expense.selectable_payment_method_line_ids
Out[2]: account.payment.method.line(2, 4, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 166, 170, 172, 512, 516)
In [3]: archived_journal_ids = []
In [4]: payment_method_lines = self.env['account.payment.method.line'].search([
...: *self.env['account.journal']._check_company_domain(expense.company_id),
...: ('payment_type', '=', 'outbound'),
...: ])
In [5]: payment_method_lines
Out[5]: account.payment.method.line(2, 4, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 166, 170, 172, 512, 516)
In [6]: for payment_method_line in payment_method_lines:
...: if not payment_method_line.journal_id.active:
...: archived_journal_ids.append(payment_method_line.journal_id.id)
...:
In [7]: archived_journal_ids
Out[7]: [7, 8]
```
After Fix:
```py
In [8]: payment_method_lines_with_fix = self.env['account.payment.method.line'].search([
...: # The journal is the source of the payment method line company
...: *self.env['account.journal']._check_company_domain(expense.company_id),
...: ('payment_type', '=', 'outbound'),
...: ('journal_id.active', '=', True),
...: ])
In [9]: payment_method_lines_with_fix
Out[9]: account.payment.method.line(153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 166, 170, 172, 512, 516)
In [10]: archived_journal_ids_with_fix = []
In [11]: for payment_method_line in payment_method_lines_with_fix:
...: if not payment_method_line.journal_id.active:
...: archived_journal_ids_with_fix.append(payment_method_line.journal_id.id)
In [12]: archived_journal_ids_with_fix
Out[12]: []
```
OPW-5461359
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#242743This update streamlines the user experience by embedding relevant actions, like 'Create Vendor Bill,' directly into the appropriate journal folders (e.g., Purchase, Sales). This ensures users have the necessary tools available where they're working, improving efficiency.
Original PR description
What: Previously, actions like "Create Vendor Bill" were only embedded in the main "Finance" folder. Now, these actions are also embedded directly into the specific subfolders for each journal type…
What: Previously, actions like "Create Vendor Bill" were only embedded in the main "Finance" folder. Now, these actions are also embedded directly into the specific subfolders for each journal type (e.g., "Purchase", "Sales"). All relevant actions are also kept in the parent "Finance" for general accessibility. The purchase actions are also added to the "Inbox" folder. Why: The previous behavior was inefficient. A user uploading a vendor bill to the "Purchase" folder would not see the "Create Vendor Bill" action. He would only see it when he is in the parent "Finance" folder. By embedding it by default this streamlines the process by ensuring the necessary tools are available exactly where the user is working. How: The logic is implemented within the _documents_configure_sync method of the account.journal model. This is the ideal location because it handles the complete setup of a journal for the Documents app. This ensures that actions are embedded correctly both during module installation and dynamically whenever a new journal is created by a user. Notes: - Tests were rewritten to check these embeddings on install. And were refactored to be more maintainable and cover bank statements better. - The test for importing bank statements had to be moved to a separate testing module, as it needs the `account_bank_statement_extract` module, which is not in the dependencies of `account_move`. - The tests for bank statement processing errors was improved to match the tests in later versions Task-5410752 Related Task-5075610 Forward-Port-Of: odoo/enterprise#102039
This update fixes a misclassification of account 649 in the French Profit and Loss report. The change aligns the report with French accounting standards (PCG 2025 & 2026) by correctly categorizing this account within Wages and Salaries and Social Security Charges. This ensures accurate financial reporting for French businesses using the Odoo Enterprise solution.
Original PR description
## Issue In the *Profit and Loss* report for the French localization (`l10n_fr_reports`), the account 649 was mentioned in the *"Reversals of provisions (and depreciation), expense transfers"*…
## Issue
In the *Profit and Loss* report for the French localization (`l10n_fr_reports`), the account 649 was mentioned in the *"Reversals of provisions (and depreciation), expense transfers"* section, instead of *"Wages and salaries"* and *"Social security charges"*. This classification is described in the *"Recueil des normes comptables françaises"* (Versions [2025](https://www.anc.gouv.fr/files/anc/files/1_Normes_fran%C3%A7aises/Reglements/Recueils/PCG_Janvier2025/Recueil-NF-Janvier-2025.pdf) and [2026](https://www.anc.gouv.fr/files/anc/files/1_Normes_fran%C3%A7aises/recueil/RECEUIL-PCG-2026-AVEC-COUVERTURE.pdf)).
## Steps to reproduce
1. Install *France - Accounting Reports* (`l10n_fr_reports`)
2. Go to the *Profit and Loss* report
3. In debug mode, click the information buttons on the following rows:
- *Reversals of provisions (and depreciation), expense tranfers*: **649 is mentioned**
- *Wages and salaries*: **649 is not mentioned**
- *Social security charges*: **649 is not mentioned**
## Note
The account 649 was added at the beginning of the formula for the *"Wages and salaries"* section in order to respect a logical order. In the *"Social security charges"* formula, since no logical order appears to be used, the account was added at the end.
opw-5724559
Forward-Port-Of: odoo/enterprise#105856
Forward-Port-Of: odoo/enterprise#105474This update resolves a frustrating user experience issue where a notification about delayed translations would block access to editing features on multilingual websites. Previously, clicking 'Edit' after a translation update would simply hide the notification, preventing users from making necessary changes. This fix ensures notifications disappear correctly, allowing seamless website editing.
Original PR description
When we have a delayed translation, we get a notification saying that we should edit, or translate to apply the changes made in the default language. However, when we click on edit, the notification is still present, and it blocks the dropdown, so the user doesn't see it until the notification disappears. Steps to see the issue: - In a multilingual websites: - Add a content in the default language, 'A' - Translate the content in your other language 'B' - Come back to 'A', and edit the content, e. g. add some style - Come back to the language 'B' => A toaster notification appears, and if you click on "Edit" button, you cannot see what's below. task-5447519 Forward-Port-Of: odoo/odoo#245260
This update fixes an issue where embedded actions within folders were hidden from the interface, preventing users from managing or deleting them. The change ensures that embedded child actions are now correctly displayed and accessible, streamlining the process of managing actions within documents. This improves usability and reduces potential data management issues.
Original PR description
### ISSUE Certain embedded actions inside a folder may not appear in the folder’s server actions list (accessible via the gear icon), making them impossible to find or delete through the interface. This occurs because documents.document.get_documents_actions applies overly broad filtering that removes all child server actions, regardless of whether they are embedded in the folder. As a result, if two embedded actions are created in a folder and one is later set as a child of the other, the embedded child action disappears from the visible list but remains embedded in the folder, leaving no way to remove it from the UI. ### SOLUTION The method has been updated to exclude only non-embedded child actions. Embedded child actions are now preserved and correctly displayed in the folder’s actions list, allowing them to be managed and deleted as expected. opw-5213881 Forward-Port-Of: odoo/enterprise#105800 Forward-Port-Of: odoo/enterprise#100395
This update enhances the mobile signing experience by addressing layout issues and navigation problems. Specifically, it cleans up the user interface, clarifies empty states, and ensures smoother transitions during the signing process, leading to a more polished and user-friendly experience.
Original PR description
Before: - Several mobile screens had layout issues such as extra white space, misaligned elements, and uneven spacing. - During signing, the "Next" navigation appeared abruptly without a smooth transition. After: - Improved mobile layouts to remove unnecessary white space and keep grid alignment consistent. - Added placeholders on relevant screens (e.g. Documents folder, Authorized Users, redirect link) to clarify empty states. - Fixed transition issues when navigating between fields during the signing flow. Impact: - Provides a cleaner and more polished mobile signing experience. - Improves usability by making empty states clearer and navigation smoother. Task: 5493477 Forward-Port-Of: odoo/enterprise#104606
The Point of Sale system now gracefully handles errors during initialization, preventing the app from getting stuck on a loading screen. Users are presented with an option to clear local data and refresh, particularly beneficial for mobile users who don't want to manually reset their data. This enhances the user experience and improves POS reliability.
Original PR description
Inconsistent data in the localDB or local storage can cause the POS to fail before it can get initialized. When this happens the page just stays showing the loading screen forever. Now when an error happens while initializing the POS the loader will disappear and the app will give the user the option to clear all local data and refresh the page. This should be especially useful for users on mobile where it's a pain to refresh the local data manually. Task-[5420544](https://www.odoo.com/odoo/project/1737/tasks/5420544) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242532
This update fixes a limitation in the document search feature, allowing users to now search across multiple user root folders. The original system missed a key test scenario, resulting in incomplete search results. This change ensures a more comprehensive and accurate search experience for all users.
Original PR description
Introduced with 7994db2c, where we forgot about the click all tests that would enable all filters at once. See runbot error 237504 Task-5893183
This update resolves a technical issue preventing invoices from successfully validating with DIAN, Colombia's tax authority. The fix corrects a naming inconsistency in invoice tags, ensuring proper validation and compliance. This ensures invoices are processed correctly and avoids potential delays or rejections.
Original PR description
Problem: When validating invoices with DIAN, an error is received. Cause: Incorrect tags are being used in the invoices. These tags are checked when invoices are validated with DIAN. Solution: Use the correct tags in the invoices. schemeName should be used instead of scheme_name. Steps to reproduce: - Install l10n_co_dian module - Choose a Colombian company - Activate DIAN service in Settings - Create an invoice and send it while making sure the DIAN checkbox is ticked - Download the generated zip file and uncompress - Open the XML file and check for scheme_name. It should be replaced by schemeName. opw-5829958 Forward-Port-Of: odoo/enterprise#105841 Forward-Port-Of: odoo/enterprise#105659
This update fixes a memory error that occurred when loading website pages, specifically within the page manager. The change optimizes how the system retrieves page information, reducing the risk of performance issues and ensuring a smoother user experience. A new caching system has been implemented for faster page retrieval.
Original PR description
Before this commit, loading the list view of the website pages invoked a method called `_get_most_specific_pages`. This method caused a memory error due to loading the field called `key` for the pages being fetched. This field was related to a field called `key` in the model `ir.ui.view`, so a cache miss in the recordset causes a `SELECT *` query for the ir.ui.view potentially causing a memory error if the size of these views are big. A solution for this is to force the ORM to load only the `key` field by invoking **search_fetch** on the `ir.ui.view` model instead. In order to improve the retrieval of a given page key count, we now use a Counter map (=> constant time instead of linear search). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#245600 Forward-Port-Of: odoo/odoo#240924
This update corrects a previous issue where paid event registrations automatically confirmed after a sale, leading to inaccurate notifications and a less effective attendee editor. Now, registrations remain in 'draft' mode until attendee information is entered, ensuring notifications are sent to the correct recipient and maintaining administrative control.
Original PR description
Problem: - In version 17, event records linked to a sales order can be automatically set to ‘open’ immediately after the sale. This makes the wizard editor less useful (the data provided is not used…
Problem: - In version 17, event records linked to a sales order can be automatically set to ‘open’ immediately after the sale. This makes the wizard editor less useful (the data provided is not used for the record that is already confirmed) and notifications go to the sales partner instead of the actual assistant. Current behaviour: - Confirmed orders automatically confirm attendees, reducing the value of the wizard step and sending emails to the wrong recipient. Expected behaviour: - Paid attendee registrations created from Sales should remain in “draft” until attendee details are provided. Solution: - Do not set ‘state=“open”’ for payment records created from a sale involving the data wizard for records. Ensure they remain in “draft”. - Confirm registrations once attendee details are present. Advantages: - Restores the usefulness of the attendee editor: confirmation occurs after data entry, so notifications are directed to the attendee, not just the sales partner. - Meets functional expectations for administrative control and proper recipient targeting. Tests to reproduce the error: - Create quote with payment entry - Confirm SO - Enter attendee details and confirm - Registrations change to ‘open’ and a confirmation email is sent to the order partner and not to the registered attendee. @Tecnativa TT58160 @pedrobaeza please review --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244525 Forward-Port-Of: odoo/odoo#230500
This update ensures that customers purchasing event tickets through POS are accurately registered as attendees. Previously, the system didn't consistently link customer information to event registrations, leading to inaccurate attendee tracking. This fix aligns the POS registration process with website registration behavior, improving data accuracy and reporting.
Original PR description
Currently, when a customer is set on the order and buys a event ticket, the information is not set as partner on the registration. Steps to reproduce: ------------------- * Create an event that asks…
Currently, when a customer is set on the order and buys a event ticket, the information is not set as partner on the registration. Steps to reproduce: ------------------- * Create an event that asks for name but is not required * Open pos and sell on ticket * Do not put name info * Select a customer for the order * Validate order * Check registrations > Observation: The customer is not registered as the attendee Why the fix: ------------ We compare the scenarios with the same flow but from website registrations. On the website if there is no user registered: - If information is not filled, nothing will be registered on the registration - If information is filled it will be used to populate attendee fields If there is a user registered while on website: - If no information is filled, attendee fields will be populated with the data from the connected user - If information is filled, it will be used for attendee fields - If partial information is filled, it will be used for attendee fields but will also be completed with data coming from the connected user To achieve the same behavior from the pos we first need to register the customer as the partner for the event. During event creation we also remove values regarding attendee name, email, phone and company if they were not provided during the order. From the website they are not used during creation if they were not given by the customer. However, in the pos this information is present anyway (as empty string or False) as they are fields on the model "event.registration" and are still send to the backennd even if we remove the information here https://github.com/odoo/odoo/blob/787621e44a9cef30469849929df267cae9e977f2/addons/pos_event/static/src/app/screens/product_screen/product_screen.js#L127 We do the fix server-side as a fix in the frontend would not be as straightforward. A customer might be on the order before selecting event ticket and it's easy but one might also add the customer after the ticket was selected. opw-5137197 Forward-Port-Of: odoo/odoo#242783 Forward-Port-Of: odoo/odoo#234871
This update fixes a previous issue where audit reports couldn't be created for periods that didn't align with fiscal years. It now supports fiscal year periodicity and custom periods, ensuring that audit reports accurately reflect financial data and provide clearer analysis for users. This enhancement improves the reliability of financial reporting.
Original PR description
It wasn't possible to create audits on a period that didn't match a fiscal period. task-5417418 Forward-Port-Of: odoo/enterprise#103212
This update ensures that search views remain consistent when navigating from pivot or graph reports to detailed views. Previously, the system defaulted to a generic search view, leading to an inconsistent user experience. This fix corrects the process to correctly pass the intended search view, improving report accuracy and usability.
Original PR description
Clicking on a pivot cell or graph bar/pie opens a new view, but the search_view_id was not being passed. As a result, the default search view was used, even when the action defined a specific one. This caused inconsistent search views between the pivot/graph view and the drilled-down view. This PR fixes the issue by correctly passing the current action's search_view_id when opening a new view from pivot/graph. Steps to reproduce: - install website_sale - goto website > reporting > online sales - click pivot cell - the new opened list view does not have same search view as before <img width="1920" height="563" alt="image" src="https://github.com/user-attachments/assets/e54656bb-088f-464b-8de2-a88a3a3ab22d" /> <img width="1920" height="635" alt="image" src="https://github.com/user-attachments/assets/e95ed61b-7573-4d58-9875-827c3124a039" /> task-[5469929](https://www.odoo.com/odoo/project/1519/tasks/5469929) Forward-Port-Of: odoo/odoo#243233
This update streamlines database synchronization by removing outdated XMLRPC support and improving error handling. The system now handles more databases synchronously and presents errors in a user-friendly way, enhancing the overall stability and reliability of the Odoo Enterprise SaaS platform.
Original PR description
### [IMP] databases: remove xmlrpc fallback for odoo.com Since odoo.com migrated to 19.0, it will always support the json2 API, and XMLRPC support will be dropped on the next version. In order to…
### [IMP] databases: remove xmlrpc fallback for odoo.com Since odoo.com migrated to 19.0, it will always support the json2 API, and XMLRPC support will be dropped on the next version. In order to simplify the code and avoid subsequent requests in case of errors on the json2 API, the XMLRPC fallback is stripped off from `databases.api`. In this commit, we only adapt the tests so that they don't test the fallback to XMLRPC when calling odoo.com. In the next commit, we will remove the dead code. The configuration parameter `databases.odoocom_apiuser` is removed, as well as the corresponding field in the Settings page. ### [FIX] databases: disable the KPI-selection wizard With this commit, we disable the wizard displayed at the end of a synchronization to select which KPIs are added to the properties field. Instead, we always store all the KPIs that are provided by the databases, and the users can still select which ones they want to display on the list view. The wizard is still used in the background for stable compliance, but it is not displayed to the user any more. It will be removed in the next stable version (saas~19.2). Task-id: [5868314](https://www.odoo.com/odoo/project.task/5868314) ### [FIX] databases: handle fetch errors better With this commit, fetching errors like 502 Bad Gateway are handled better, as they are reported as an error message in the final summary instead of interrupting the whole synchronization and showing a traceback to the end user. ### [FIX] databases: synchronize up to immediate_sync_limit databases synchronously Previously, if the number of databases to be synchronized exceeded `databases.immediate_sync_limit`, no databases were synchronized synchronously. Instead, all were queued for a triggered scheduled action. With this commit, the synchronization process will handle up to `immediate_sync_limit` databases synchronously, while the remaining databases will be sent to the scheduled action. Forward-Port-Of: odoo/enterprise#105176
This update resolves an issue where scheduled email notifications and related activities continued to run even after records were deleted. The fix prevents errors caused by attempting to process notifications for non-existent records, improving notification reliability and preventing confusing error messages for users. It ensures that notifications are skipped when records are deleted, avoiding unnecessary processing and potential issues.
Original PR description
RATIONALE When a cascade delete occurs in DB, ORM methods are not called. More specifically loosely connected records using res_model / res_id pair are not removed when unlink override exists. SPECIFICATIONS Fix various use case in mail * notifications sent for scheduled messages; * failure notifications management; * activities mark as done; Task-5138556 Forward-Port-Of: odoo/odoo#244248 Forward-Port-Of: odoo/odoo#233071
This update fixes an issue where Stripe account creation could fail intermittently, leading to duplicated accounts. It ensures that a transaction is always created upon account setup, guaranteeing proper Stripe integration even if subsequent steps fail. Additionally, the system now sanitizes URLs to prevent errors when requesting Stripe account links.
Original PR description
## [FIX] hr_expense_stripe: Fix account duplication Add a transaction commit when the account is created, to ensure that even if any further action fails the stripe account is properly set on the company. This will prevent users from creating accounts every time if the account creation part succeeded ## [FIX] hr_expense_stripe: Sanitize values for webhook url Sometimes the web.base_url is the http version of the database url, where the https is properly setup. At account creation we test the https connection, and allow the creation of the account forcing https on IAP side. But when we request the links for the account, the database will still send the http version of the url, refused by stripe. This adds a sanitization of the URLs on the database side Forward-Port-Of: odoo/enterprise#105858
This update resolves a performance issue in the project timesheet report that prevented it from loading with large datasets. The team optimized the query by using a more efficient join method, resulting in a faster loading time of approximately 2 seconds. This improves the user experience for reports with many records.
Original PR description
After this commit https://github.com/odoo-dev/enterprise/commit/6c33bde74342b634d9f6fbda4ef407ffe9bac54f we introduced a new left join which seems that it slowed down the query a lot. So the report…
After this commit https://github.com/odoo-dev/enterprise/commit/6c33bde74342b634d9f6fbda4ef407ffe9bac54f we introduced a new left join which seems that it slowed down the query a lot. So the report doesn't load at all if we have a lot of records. In this PR we are introducing CROSS LATERAL JOIN as we want to generate only the the relevant dates not all dates between the min starting date and max ending date of all slots. Query plan after modification https://explain.dalibo.com/plan/eh5293ba2354f43c The testing cardinality of the tables: `planning.slot` 7178 rows `hr.employee` 332 rows `resource.resource` 332 rows `resource_calendar_leaves` 4061 rows `account_analytic_line` 267376 rows `generate_series()` will produce 206417 rows | Before | After | |-----------------------------------------|-------| | Query keep being active with no results | ~2s | opw-5089052 Forward-Port-Of: odoo/enterprise#105696 Forward-Port-Of: odoo/enterprise#102283