Tuesday, September 9, 2025
26 changes · saas-18.4
New functionality added to Odoo
A new shared KPI provider lets Odoo modules publish business metrics in a consistent way. Accounting now uses it to report draft document counts by type, helping future dashboards or reports collect these figures more easily.
Original PR description
This commit introduces a new abstract model `kpi.provider` that allows different modules to contribute their Key Performance Indicators (KPIs) in a modular and extensible way. The `kpi.provider` model defines a base structure for KPI reporting and includes a `get_kpis_summary` method that should be overridden in inheriting models. This method is responsible for returning a list of KPI data specific to the module. KPI data are identified by a unique name and a type allowing for the caller to know how to present the corresponding value. The `account` module inherits from `kpi.provider` to include the amount of draft `account.move` for each `move_type`. Task-id: 5062431 Forward-Port-Of: odoo/odoo#225153
Enhancements to existing features
Users can now rename online bank synchronization links directly from the form view. This helps businesses distinguish between multiple connections to the same bank and manage them with less confusion.
Original PR description
With some provider, you can have several links to the same bank. This can be confusing for the user. Allowing to edit the sync name from the form view can help the user sort out its links. Not a FIX, but suggestion is from opw-5004182 Forward-Port-Of: odoo/enterprise#93538
Resolved issues and error corrections
This update fixes an issue in the India localization and India sales localization test setup where company context was being changed in a way that could fail after initialization. It improves reliability for maintaining Indian tax and fiscal position behavior without changing business workflows.
Original PR description
In this PR: - Replaced direct assignment `self.env.company = self.default_company` with proper odoo environment switching pattern to avoid AttributeError when company attribute becomes read-only after initialization. Forward-Port-Of: odoo/odoo#224795
Miscellaneous changes
Before this commit: Some of the names in the stock_type list were wrong, causing an invalid type error when validating delivery. After the commit: Added a lookup table to update the incorrect names to match names in FedEx documentation. Fedex docs: https://developer.fedex.com/api/en-is/catalog/ship/docs.html opw-4725488 Forward-Port-Of: odoo/enterprise#84762
Original PR description
Before this commit: Some of the names in the stock_type list were wrong, causing an invalid type error when validating delivery. After the commit: Added a lookup table to update the incorrect names to match names in FedEx documentation. Fedex docs: https://developer.fedex.com/api/en-is/catalog/ship/docs.html opw-4725488 Forward-Port-Of: odoo/enterprise#84762
The website editor preview for floating block sections now applies background positioning consistently across all blocks. This helps users see a more accurate preview while editing, reducing surprises when the page is published.
Original PR description
This commit fixes an issue with the `s_floating_blocks` snippet where some CSS rules were inactive due to the selector. Previously, the snippet applied a `background-position: top` property to the first block. However, this rule was ineffective because the first block does not include a `s_parallax_bg`. This commit resolves the issue by allowing all blocks to receive the `background-position` property, ensuring the behavior is fully WYSIWYG for the user. task-5068688 Forward-Port-Of: odoo/odoo#225918
Fixed an accounting issue where reverse charge taxes with offsetting repartition lines could show both manual tax amounts as positive. This helps ensure tax entries reflect the correct sign, improving accuracy in accounting records and reports.
Original PR description
When a tax is defined using +100, -100 as repartition lines, the tax amount retrieved from manual_tax_amounts where positive for both lines. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225855
Odoo no longer saves an internal browser database version that could become outdated when the same app was opened in multiple tabs. This prevents cache failures and console errors, helping pages load more reliably in fresh browser sessions.
Original PR description
Open Odoo in two tabs, in a fresh browser (or delete the IndexedDB). - Open the Contacts app in the first tab; - Open the Contactc app in the second tab; Before this commit, the second tab will not use the cache, and an error will be displayed in the console : `IndexedDB error: The requested version is less than the existing version`. This issue occurs, because the IndexedDB wrapper stores the database version, which is incremented when a new table is needed in order to execute the `onupgradeneeded` function and create the table. Now, the version is not stored anymore. When a new table is needed, the database is opened with the current version + 1. This will execute the `onupgradeneeded` function and create the table. Forward-Port-Of: odoo/odoo#226015
This fix makes an automated online shop test wait for the expected page element before moving to the next step. It reduces false test failures caused by timing issues, helping keep website sales changes more stable during validation.
Original PR description
Some tour steps executed too quickly and did not wait for the target element to appear, causing race conditions where the next step failed due to missing elements. This commit adds an explicit check step between the failing steps to ensure the element is present before continuing, guaranteeing stable tour execution without premature step execution. runbot-229723 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
This fix prevents accounting setup from trying to use chart templates from localization modules that are not currently installable. It reduces unnecessary errors when custom or inherited localization modules are present but not ready to be installed.
Original PR description
* Problem: if having a custom module that add extra tax to current localization module, ex: l10n_x inherit l10n_vn module, but the l10n_x module is not installable because it hasn't upgraded yet, the _get_chart_template_mapping include it as well, there for will log error in https://github.com/odoo/odoo/blob/18.0/addons/account/models/chart_template.py#L1219 * Solution: only get available template code for module that installable 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#225821
The checkout button now appears in the shopper's selected website language when Cash on Delivery is used. This prevents a mixed-language checkout experience and improves clarity for multilingual customers.
Original PR description
Versions -------- - saas-18.3+ Steps ----- 1. Enable the Cash on Delivery payment method; 2. have a delivery method which allows cash on delivery; 3. active a second language on the website; 4. go to /shop/payment in the other language; 5. select Cash on Delivery payment. Issue ----- The "Place order" button isn't translated. Cause ----- The `delivery` module isn't listed as "front-end module" for translation purposes, making the translated term unavailable there. Solution -------- Add `delivery` as a front-end module via a `_get_translation_frontend_modules_name` override. opw-4971473 Forward-Port-Of: odoo/odoo#225940
Romanian electronic bill imports now ignore invalid PEPPOL endpoint data found in ANAF XML files before creating a new partner. This prevents unnecessary import errors being logged when government-provided data contains an invalid endpoint.
Original PR description
Problem --------- When importing the bill, the XML contains a faulty PEPPOL Endpoint (an address mail). Since the partner in the XML does not yet exist in the client database, we attempt to create it with the name, VAT, address and the faulty endpoint; which, triggers an error that is logged in the chatter. For unknown reasons, the RO government allows for such error to be introduced but since we can't change ANAF itself, we have to make a fix to manage the case. Solution --------- When importing the partner data from the XML, we check if the endpoint is valid before creating the partner. If it is not the case, we simply remove and ignore the endpoint data. opw-5046567 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents Stripe setup from trying to enable payment methods that are not compatible with manual capture. Businesses can activate supported payment options without confusing warnings or failed activation attempts.
Original PR description
Steps to reproduce: 1) Check the manual capture checkbox on Stripe. 2) Try to enable it. 3) See the warning that some payment methods can not be activated. Reason: Commit 25feb5b11c2df401580b65e0108145863fcf8987 disallows activating payment methods that do not support manual capture if their provider supports it. Solution: Filter out incompatible pms. opw-4860912 Forward-Port-Of: odoo/odoo#223038
This fixes a display issue where long live chat conversation names could be clipped in the sidebar after a conversation ended. Users can now read the full relevant channel name more reliably, improving navigation and reducing confusion.
Original PR description
Since PR #217615, when a livechat conversation ends, an italic class is added to the thread name classes in the sidebar. As a result, the thread name may be clipped in the sidebar if it is long enough. This change ensures that the thread name is displayed correctly. Before: <img width="310" height="56" alt="image" src="https://github.com/user-attachments/assets/3b289c01-bf11-4f4e-9555-e45a89641975" /> After: <img width="317" height="56" alt="image" src="https://github.com/user-attachments/assets/676eaa5b-e83d-4f77-b320-a9c525d4dce2" />
Users can now refuse a job application using a reason that has no email template without triggering an error. This prevents an unexpected crash in the recruitment workflow and lets teams continue processing applications normally.
Original PR description
When user tries to select a refuse reason without Email Template in Application, A traceback will appear. Steps to reproduce the error: - Install ``hr_recruitment`` module - Go to Recruitment > Configuration > Refuse Reasons > Create a new Reason without Email Template - Create a Application > Refuse > Select refuse reason without email template Traceback: ``` UnboundLocalError: cannot access local variable 'wizard_field_name' where it is not associated with a value ``` https://github.com/odoo/odoo/blob/f6874befe64daf78dc59fa09a349cad305717bed/addons/hr_recruitment/wizard/applicant_refuse_reason.py#L99-L104 Here, the ``wizard_field_name`` variable is referenced before the assignment, So, It will lead to the above traceback. sentry-6844982581 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
New car requests from the Belgian salary configurator will no longer make an employee's current car appear available too early. This prevents confusion or accidental reassignment while the new car is still only at the request stage.
Original PR description
When a new car is ordered through the belgian salary configurator, a car is created in the stage 'New Request'. At this state, nothing is planned to change the car so we don't want to set the existing employee car as available for someone else. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223589
Livechat agents now see a visitor's recent page visit times in their own timezone instead of UTC. This makes the browsing history banner easier to understand and helps agents respond with the correct context.
Original PR description
Before this PR, when browsing a website livechat in the discuss app, the banner containing the 3 last pages browsed by the user showed the utc time instead of the time in the timezone of the agent. Now, the livechat agent is seeing the visit timings in his timezone. To achieve this, we now construct the visit string in the frontend and receive the page and datetime (utc) info from the backend task-4937769 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225602 Forward-Port-Of: odoo/odoo#219113
This fixes an issue where Romanian e-invoicing synchronization could fail with a technical traceback when a communication error occurred. The system now checks the error information in the correct place, helping users receive proper synchronization feedback instead of an unexpected crash.
Original PR description
Problem
---------
Currently, the 'error' message (in case of communication error) is stored in the 'answer' dict. However, the code verify for the 'error' key in the message dict itself.
Solution
---------
When checking if the 'error' key is present, check in the 'answer' dict rather than the message dict
The code is
```message = {**data, 'answer': {**data, 'error': ""}}```
The verification were
``` 'error' in message ?```
and now they are
``` 'error' in message['answer'] ?```
opw-5046567
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update prevents an error message from appearing in debug mode when translating selection field labels on website forms. It improves the reliability of the website translation workflow without changing visible functionality for regular visitors.
Original PR description
**PROBLEM** In debug mode, props type errors pop up when clicking on a selection field to translate it. **STEP TO REPRODUCE** 1. Create a form with a selection field in a page. 2. Ensure you're in debug mode assets. 3. Go in translate mode, and click on a string of the selection field to translate it. 4. Props type error should pop up. **CAUSE** `node` is actually of type `Object` (its the target of a jquery event), the props validations expect it to be of type `String`. opw-4896491 Forward-Port-Of: odoo/odoo#221876
A flaky website builder animation test is being skipped temporarily to prevent random test failures. This helps keep automated checks reliable while the team investigates a long-term fix.
Original PR description
The test fails non-deterministically. We sip it while looking for a long term fix task-4367641
Switching developer mode on or off now shows the correct Calendar meeting tabs after a single refresh. This prevents users from seeing outdated cached screens and avoids confusion when debug-only options should appear immediately.
Original PR description
**Steps to reproduce:** - Go to Calendar app - Go to any meeting - Invitations tab should be hidden (no debug mode) - Trigger developer mode (`?debug=1`) - Invitations tab should be displayed - The…
**Steps to reproduce:** - Go to Calendar app - Go to any meeting - Invitations tab should be hidden (no debug mode) - Trigger developer mode (`?debug=1`) - Invitations tab should be displayed - The tab only appears after a second refresh **Issue:** The new caching process uses a key based on the RPC parameters. In the case of the 'get_views' function, it produces a different result with the same parameters depending on whether debug mode is enabled. This means that two browser refreshes are needed to have the correct view. The first refresh renders the cached view (without the invitation tab) and updates the cache with the view returned by the RPC (with the invitation tab). The new cached view with the invitation tab will be rendered on the second browser refresh. **Fix:** Add the debug option to the RPC parameters to cache the different views separately (with and without the invitation tab). opw-4986038 related: https://github.com/odoo/odoo/commit/f3d955b3235cb256bda79e834df38da0f6a4ac1a Forward-Port-Of: odoo/odoo#223401
Duplicated automatically created reconciliation models are now treated as regular copies, so they appear in the expected filters right away. Archiving a reconciliation model also cleans up related manual unreconciled statement-line assignments, reducing confusion for accounting teams.
Original PR description
When duplicating an automatically created reco model, the field created automatically was still set to True and so the filter doesn't show the reco model at first. By adding the copy=False it solve the problem Also, this commit will remove any manual reco model of unreconciled statement line when archiving that reco model. no task id
The WhatsApp integration now uses the latest supported Meta Graph API version. This helps avoid service disruptions from older API versions being retired and reduces the need for repeated short-term updates.
Original PR description
As outlines in the version [changelog] v17 of the API which we are currently using will be converted to the next oldest supported version of the API as per [policy] We can migrate directly to the latest version and avoid any issue in the next few years instead of having to worry about potentially breaking changes every few months. [changelog]: https://developers.facebook.com/docs/graph-api/changelog/versions/ [policy]: https://developers.facebook.com/docs/graph-api/guides/versioning task-4971841 Forward-Port-Of: odoo/enterprise#94110 Forward-Port-Of: odoo/enterprise#93170
German accounting reports now correctly assign the required DATEV main account when a POS session includes both sales and refunds with different tax rates. This prevents missing account information in DATEV exports and helps ensure accurate reporting.
Original PR description
In _get_datev_account, the l10n_de_datev_main_account_id is determined by identifying a singular debit or credit account used in the journal entry. If there’s no unique account, it falls back to…
In _get_datev_account, the l10n_de_datev_main_account_id is determined by identifying a singular debit or credit account used in the journal entry. If there’s no unique account, it falls back to searching for a unique non-tax line among debit or credit lines. In POS, however, there is the possibility of generating journal entries that break this flow: - In a single POS session, add product A with tax 19% and product B with tax 7%. - In the same session, refund product A. - Close the session to generate the entries. In the resulting entry, since both sale and refund are present, it is not possible to discriminate using debit and credit amounts alone, and as a result, the field l10n_de_datev_main_account_id is not populated. Since account 1411 is always the one to be used for l10n_de_datev_main_account_id in this specific case, this commit adds a final fallback filter to select the correct line and ensure the field is populated. Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4915272) opw-4915272 Forward-Port-Of: odoo/enterprise#92664
The website appointment editor now correctly applies the guest booking setting when it is turned on or off. This prevents accidental changes to whether customers can add guests to appointments, improving reliability for appointment setup.
Original PR description
Since https://github.com/odoo/enterprise/commit/689a2186fbe3b932b90bef3b64716c8443bad551, The website editor option for allow_guests has an inverted behavior, being toggled when it should not and vice versa. This is only due to a small inversion of values when refactoring the website builder code. Inverse the values when the option is on/off to match expected behavior. Task-4930982
Reinstalling the SEPA Direct Debit module no longer causes an error when pre-notification settings are not yet available. This prevents disruption when managing SEPA payment configurations and keeps batch payment setup reliable.
Original PR description
**Issue** When creating a batch payment with SEPA Direct Debit as payment method, if the user uninstalls the SEPA module and then installs it again, Odoo raises a `TypeError: 'int' object is not…
**Issue**
When creating a batch payment with SEPA Direct Debit as payment method, if the user uninstalls the SEPA module and then installs it again, Odoo raises a `TypeError: 'int' object is not iterable`.
**Steps to Reproduce**
1. Create a batch payment with SEPA Direct Debit.
2. Uninstall the `account_sepa_direct_debit` module.
3. Reinstall the module.
**Root Cause**
During module (re)installation, the compute method `_compute_sdd_required_collection_date` is triggered before any SEPA mandates or their pre-notification periods exist. This makes `mandates.mapped('pre_notification_period')` return an empty list. The code then calls:
max(minimum_offset, *mandates.mapped('pre_notification_period'))
When the list is empty, this reduces to `max(minimum_offset)`, which is invalid since `max()` with a single integer argument expects an iterable and raises a `TypeError`.
**Fix**
Handle the empty case so that there is a valid fallback both during installation and when mandates have no configured pre-notification period.
Opw-5042153
Forward-Port-Of: odoo/enterprise#93598When users open a Bill of Materials from the Master Production Schedule edit pop-up, the pop-up now closes automatically. This prevents an error when returning from the BOM screen and provides a smoother planning workflow.
Original PR description
Before this commit: ------------------------- Clicking the BOM field in the edit production schedule pop-up on the MPS page redirected the user to the BOM form view, but the pop-up remained open in…
Before this commit: ------------------------- Clicking the BOM field in the edit production schedule pop-up on the MPS page redirected the user to the BOM form view, but the pop-up remained open in the background. If the user then clicked Cancel on the pop-up, it created a traceback error. Steps to reproduce: ------------------------- 1. Install 'mrp_mps' module. 2. Go to Planning → Master Production Schedule. 3. Click the pencil icon next to a product. 4. In the pop-up, click the BOM value to navigate to the BOM. 5. Notice that the pop-up stays open even after redirection, and closing the pop-up raises a traceback error. Cause of the issue ------------------------- When your onClose arrow function directly executes this.reload(productionScheduleId) without curly braces, it immediately hands over the outcome of that function call to the dialog system. Since this.reload is an asynchronous operation with multiple sequential return values, its immediate outcome may not be a final value. After this commit: ----------------------- The pop-up is automatically closed when navigating to the BOM form view from the BOM field in the Edit Production Schedule popup, ensuring a cleaner and more intuitive user experience. Task Id: 4886331 Forward-Port-Of: odoo/enterprise#90424