Monday, January 26, 2026
14 changes · saas-18.2
Enhancements to existing features
This change adds a small extension point for how product price labels are built. It helps implement custom pricing displays more safely without changing core product pricing behavior.
Original PR description
Add `_get_price_label_base_str()` method in order to exend it @Tecnativa --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243861
This update expands Odoo's language support to include Spanish, recognizing the significant number of Spanish speakers. By adding Spanish translations, we improve the usability of Odoo for a wider range of customers and users. This enhancement aligns with our commitment to global accessibility.
Original PR description
The official language is English, but Spanish is spoken by ~41 million. task-5247124 Forward-Port-Of: odoo/enterprise#105246
Resolved issues and error corrections
This fix prevents Odoo from incorrectly marking a customer's default pricelist as manually assigned when it simply matches the normal default for their country or lack of country. It makes customer pricing setup more consistent and avoids misleading saved pricelist values.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Have a way to check the `specific_property_product_pricelist` field; 2. create a pricelist for EU countries; 3. delete all other regional pricelists; 4.…
Versions -------- - 18.0+ Steps ----- 1. Have a way to check the `specific_property_product_pricelist` field; 2. create a pricelist for EU countries; 3. delete all other regional pricelists; 4. create a new partner in a EU country; 5. create a new partner outside a EU country; 6. create a new partner without a country. Issue ----- Inconsistent behavior: - EU partner has no `specific_property_product_pricelist` value set, as it's identical to the default `property_product_pricelist`. - The other partners do have a `specific_property_product_pricelist` value set to the default value, as if a user manually assigned them. Cause ----- In the `_inverse_product_pricelist` method, the `default_for_country` pricelist is an empty recordset if the partner has no `country_id` or none of the pricelists have a country groups with the partner's `country_id` in it. Solution -------- Introduce a `_get_country_pricelist_multi` method that can be used by `_get_partner_pricelist_multi` and `_inverse_product_pricelist` to ensure that they both return the same result for any given country (including none), and use this as the `default_for_country`. > [!Note] > An alternative approach could be to replace the `_inverse_product_pricelist` method with an `onchange` method, as the docstring of the `_get_partner_pricelist_multi` method states: >> First, the pricelist of the specific property (res_id set), this one is created when saving a pricelist on the partner form view. > > This suggests a behavior that more closely resembles the purpose of an `onchange` method, instead of an `inverse`. opw-5385213 Enterprise PR: https://github.com/odoo/enterprise/pull/103116 (only modifies a test) Forward-Port-Of: odoo/odoo#241736
Electronic invoice exports now treat '/' as a marker that a partner has no VAT number, rather than as an actual VAT number. This prevents invalid tax identification data from being included in UBL/Peppol documents and keeps related Saudi compliance test documents aligned with the corrected behavior.
Original PR description
To signify that you know a partner does not have vat, we advise using '/'. But we should take care of that in the UBL export, to not consider it a real vat Also, in the cases where we don't have the vat, the CompanyID is supposed to be mandatory. https://docs.peppol.eu/poacc/billing/3.0/syntax/ubl-invoice/cac-TaxRepresentativeParty/cac-PartyTaxScheme/ So, remove the whole PartyTaxScheme if vat is not present. Zatca does not override that rule (except enforcing that seller must have vat, which raises a constraint), so we modify the tests for the simplified documents. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244598 Forward-Port-Of: odoo/odoo#238499
Fixed an issue where customer reports could crash when a customer had a name like "constructor" that conflicts with internal browser object names. Sales teams can now open customer reporting normally regardless of these customer names.
Original PR description
Steps:
- Have a customer named "constructor" (or any valid json prototype key value)
- Install `sale_management`
- Create a sale order with "constructor"
- Open Reporting -> Customers
- Traceback `Caused by: TypeError: groupedDataPoints[key].push is not a function`
This problem occurs because we use the client name directly in an object, and “constructor” already exists in all objects but is not initialized correctly, which raises a traceback.
One solution is to use `let object = Object.create(null)` instead of `let object = {}`, which prevents inheritance of `Object.prototype` properties.
https://github.com/odoo/odoo/blob/5e74f04ff35ed3efa25be295567be41f42024692/addons/web/static/src/views/graph/graph_model.js#L451-L457
opw-5474691
Forward-Port-Of: odoo/odoo#245369
Forward-Port-Of: odoo/odoo#245206This fixes an issue where activity scheduling could assign the wrong plan when multiple schedulers were involved. It helps ensure users see and use the correct activity plan in multi-scheduler workflows, reducing confusion and manual correction.
Original PR description
Description of the issue/feature this PR addresses: Same pattern as in https://github.com/odoo/odoo/pull/189843 but for _compute_plan_id method --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243307
This fix prevents a confusing system error when users create or edit inherited views with incomplete XPath instructions. Instead, Odoo now shows a clear validation message explaining that the required XPath expression is missing, helping administrators correct the view safely.
Original PR description
Currently, an error occurs when a user creates an inherited view. **Steps to Reproduce:** - Go to `Settings > Technical > User Interface > Views`. - Create a new view by entering `name` and selecting…
Currently, an error occurs when a user creates an inherited view.
**Steps to Reproduce:**
- Go to `Settings > Technical > User Interface > Views`.
- Create a new view by entering `name` and selecting any `inherited view`.
- In the `Architecture`, enter the below code:
```
<xpath position="replace">
<field name="name"/>
</xpath>
```
- Now save the view.
`TypeError: Argument must be bytes or unicode, got 'NoneType'`
Cause:
As we can see, when the user enters an xpath without the expr attribute, and when it goes to find the inherited node [1]. Since the expr is missing, its value becomes None [2]. Passing this None as an argument [3] causes the error.
This commit ensures that when a user creates or edits a view with an xpath that is missing the expr attribute, a ValidationError is raised indicating that the expr attribute is missing in the XPath.
[1]: https://github.com/odoo/odoo/blob/4876a54e8cfb3a115b5423db102fc2b7a40b196a/odoo/tools/template_inheritance.py#L145
[2]: https://github.com/odoo/odoo/blob/4876a54e8cfb3a115b5423db102fc2b7a40b196a/odoo/tools/template_inheritance.py#L76
[3]: https://github.com/odoo/odoo/blob/4876a54e8cfb3a115b5423db102fc2b7a40b196a/odoo/tools/template_inheritance.py#L78
[4]: https://github.com/odoo/odoo/blob/4876a54e8cfb3a115b5423db102fc2b7a40b196a/odoo/addons/base/models/ir_ui_view.py#L377-L384
sentry-7161414430
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#242203This change prevents shared address test data from being accidentally altered while portal address tests run. It helps keep automated test results stable and reduces the chance of false failures during quality checks.
Original PR description
Before this commit, the values passed in to the `res.partner.write()` method were mutated during the call by an override of `l10n_cl`. This in turn caused tests of the `portal.tests.test_addresses.TestPortalAddresses` test class to fail as the `self.default_address_values` dictionary which was used to populate fields on partners was mutated during tests and ended in an unexpected state. After this commit, a copy of `self.default_address_values` is passed instead of the original dictionary. runbot-164163
This fix keeps custom document or report templates working when they display monetary amounts using a float-style format. It prevents an avoidable error introduced by a recent precision-handling change, helping preserve compatibility for existing customizations.
Original PR description
Before 8c199f7783527735b35c9fbda334cbdcd55a004f, it was possible
to use the float widget with a monetary field in qweb (not used in
standard code).
By using something like:
```
<span
t-field="o.amount"
t-options="{
'widget': 'float',
'precision': o.currency_id.decimal_places
}"
/>
```
where `amount` is a monetary field.
It worked as `precision` is defined in the options, which means that
`get_digits` was not called, so no errors were raised (the method only
exists for float fields).
Now that `min_precision` has been added, `get_min_display_digits` is
called if it is not set.
Which causes an error, as the method does not exist for monetary
fields.
As we are in stable, we cannot ask users to add a `min_precision` key
to their options, so the fix is to use `hasattr` to avoid calling a
method that doesn't exists.
Forward-Port-Of: odoo/odoo#245699This update corrects a discrepancy in a sales subscription test. The test previously incorrectly prioritized pricelists based on a default partner setting. The fix ensures consistent pricelist ordering, resolving a minor test issue and maintaining accurate subscription pricing calculations.
Original PR description
Versions -------- - 18.0+ Issue ----- Commit a840e4250666 changed a `sale_subscription` test as pricelist ordering was changed. Before, it was `sequence asc, id desc`, now it is `sequence asc, id asc`. However, in the updated tests, it expects the first pricelist created with sequence 4 to be before the second pricelist with sequence 2. This was only happening due to default pricelists getting set as the `specific_property_product_pricelist` if the partner has no country assigned to them. Solution -------- As the behavior is now identical for partners with or without a country assigned to them, we can resolved the test setup by giving both pricelists an identical sequence, making the ordering fall back on `id` like a840e4250666 intended. opw-5385213 Related: https://github.com/odoo/odoo/pull/241736 Forward-Port-Of: odoo/enterprise#103116
This update fixes an issue where the 19%I tax code (9) was missing from Datev exports for expense journal entries. The problem stemmed from how payment amounts were aggregated during the export process, leading to data loss. This ensures accurate tax reporting in Datev.
Original PR description
Currently, when using 19%I tax in vendor bills, the tax code (9) is shown correctly in the BU-Schlüssel section of the datev export. This however is not the case for expense journal entries. Steps to reproduce: - With DE Company setup - Create an Expense as follows: - Included taxes: 19% I - Paid by: Company - Create report > Submit to Manager > Approve > Post Journal entries - Open General Ledger and export Datev Data Issue: Tax code will be missing from the exported entry. This occurs because, when processing payment move lines, amounts and accounts are aggregated, losing track of the source tax. opw-5388791 Forward-Port-Of: odoo/enterprise#105379 Forward-Port-Of: odoo/enterprise#102548
This update resolves a test failure in Odoo's web_studio module caused by a missing dependency. The fix ensures that tests accurately check for the presence of required modules, preventing false failures when related modules like 'account_edi' are not included in the test setup. This improves test reliability and stability.
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#104879
This update addresses a limitation in the account online synchronization process. Previously, a consent link expired after 30 minutes, preventing users from managing their data permissions. We've implemented a new consent token system, linked to the user, to ensure ongoing control over data synchronization.
Original PR description
In this commit:bf5b7d0 we introduce a message on the account_online_link to be able to manage the consent. (one needed fix in this commit:https://github.com/odoo/enterprise/commit/1c84804fd3f0c0d1d23916b9f6a388616f66ac7e) This commit will change the way we manage the consent since the access token is in fact available only for 30 min, so the link in the chatter would not work. We decided to have a consent token which is a uuid4 encoded in base64 (url safe) and link it to the odoofin user. task-5187621 Forward-Port-Of: odoo/enterprise#105254 Forward-Port-Of: odoo/enterprise#105202
This update removes outdated test code related to exchange rate precision in the l10n_mx_edi module. A previous fix inadvertently left this code in place, and this PR ensures a cleaner and more streamlined testing environment. This resolves a minor technical issue.
Original PR description
The PR #102557 fixed an issue with exchange rate precision for Solution Factible. However, its forward ports for 18 (PR #104195) and saas-18.2 (PR #104673) did not properly delete some of the old test code. This PR deletes that code. [opw-5165200](https://www.odoo.com/odoo/project.task/5165200) Forward-Port-Of: odoo/enterprise#105339