Wednesday, March 4, 2026
17 changes · 18.0
Enhancements to existing features
This update enhances the accuracy of loan interest rates within the Enterprise module. Previously, interest rates were displayed with only two decimal places. Now, users can specify up to ten decimal places for greater precision, improving financial reporting and calculations.
Original PR description
Allowing more precision on the interest rate for loans. By default the display uses 2 decimals, but if a user decides to add more precision they can up to 10 decimals. task-5913175
This update adjusts the salary scale parameters used in the Odoo Enterprise's Belgian payroll module. Specifically, the values for the first year of the CP200 salary scale and the overall scale have been updated to reflect changes in Belgian regulations as of January 1, 2026. This ensures accurate payroll calculations for Belgian employees.
Original PR description
. Update cp200_salary_scale_first_year values for 01/01/2026 . Update cp200_salary_scale values for 01/01/2026 task-5485636 Forward-Port-Of: odoo/enterprise#107473
Resolved issues and error corrections
This update prevents mail templates from automatically deleting attachments when they are removed from the mail composer. Previously, deleting an attachment in the composer also removed it from the template, causing confusion. The fix simplifies the process by only removing attachments from the template when explicitly deleted in the composer.
Original PR description
Removing an attachment (coming from a mail template) in the mail composer wrongly removes it from the template. - Edit the "Sales: Send Quotation" mail template, add it an attachment - Go to a draft…
Removing an attachment (coming from a mail template) in the mail composer wrongly removes it from the template. - Edit the "Sales: Send Quotation" mail template, add it an attachment - Go to a draft quotation - Click on "Send", it will open the mail composer which will use the template. You should see the file you added on the template. - Now, remove that file from the composer. For instance, for this client you don't want to send it, or you want to replace it or whatever. - The mail attachment has also been deleted from the template, not only from the current mail. - Note that you don't need to send it, just deleting it in the composer is enough to have it removed on the template. Many refactoring were made in `mail` between Odoo 17 and 18, breaking this flow. Another solution would be to change that in JS side, somehow managing to call `delete()` and not `remove()` in `/mail/[..]/attachment_model.js`. The caller is in `unlink()` in `/mail/[..]/attachment_upload_service.js` which is itself called by `onFileRemove()` from `/mail/[..]/mail_composer_attachment_list.js`. That would've kept using the same attachment record as the one in the template without removing it from the template when it's removed from the composer. The python solution seems more straightforward and since it's creating new attachment no other bugs should arise. Finally, note that "ghost" attachment are garbage collected through the `_gc_lost_attachments()` autovacuum method, looking for attachment having `res_id=0` and `mail.compose.message` as model. task-4748058
This update resolves a problem where CSV reports generated by the l10n_pe_reports module were failing due to incompatible CSV formatting settings. The fix ensures the reports generate correctly with Python 3.13 and removes unnecessary configuration steps, improving stability and efficiency. This prevents errors during report generation, particularly on automated builds.
Original PR description
Revealed when l10n modules got enabled on the "distro builds" nightly: on Trixie, `delimiter="|", lineterminator='|\n'` raises ValueError: bad delimiter or lineterminator value This is due to…
Revealed when l10n modules got enabled on the "distro builds" nightly: on Trixie, `delimiter="|", lineterminator='|\n'` raises
ValueError: bad delimiter or lineterminator value
This is due to python/cpython#113797 which added new validations to dialect definitions. For this issue, that the delimiter can not be in the line terminator. This can be fixed via a different trick, which is documented:
> The optional `restval` parameter specifies the value to be written
> if the dictionary is missing a key in `fieldnames`.
so if we add a trailing fieldname which *can not* be found in the row dicts, then `DictWriter` will always write out an empty trailing cell (the default `restval` is an empty string), which should result in the same output.
Also remove the `csv.register_dialect` calls, that's so subsequent CSV calls can easily refer to a common configuration but here two different dialects are being registered under the same name, and each one is only used for the following `DictWriter` call, so at best this is a complete waste of time and at worst this is a race condition in threaded configurations. Just pass the formatting parameters directly to the `DictWriter`.
https://runbot.odoo.com/odoo/error/240950
Forward-Port-Of: odoo/enterprise#109081A bug was causing a validation error when simultaneously updating the fiscal year's last month and last day for a company and its branches. This fix ensures that all changes are applied before the system checks for constraints, preventing the error and allowing users to correctly configure fiscal year settings. This improves the reliability of accounting configurations.
Original PR description
Having a parent company and a chid company selected, and changing both the last day and the last month of the fiscal year as the same time raises a ValidationError. This is because in this case, in the write we successively modify each changed delegated fields from root company to the branches. Then, when checking the constrains we loop through all delegated fields and check if the value of the branches are the same as the root company. This check triggers the error as all values are not set yet. By using a write on branches for all changed delegated fields instead of a simple assignation, the constrains check occurs once all the value have been updated. Steps: - Have a root company and a branch - Select both in company selector - Go to Accounting configuration - Change fiscalyear last month AND ast day at the same time - Save -> ValidationError in `_check_root_delegated_fields` opw-5431145
This update resolves a runtime error that occurred when generating the stock forecast report. Specifically, the report was failing due to an issue with how stock movements were being processed during delivery transfers. This change ensures the report generates correctly, preventing data inaccuracies.
Original PR description
This reverts commit 2b2d73df420baee4fec1c51c28250666d80b48b8. ## How to reproduce (in runbot): - Create Product P - Create Delivery transfer from 'WH/Stock/Shelf 1' - Open Forecast report: =>…
This reverts commit 2b2d73df420baee4fec1c51c28250666d80b48b8.
## How to reproduce (in runbot):
- Create Product P
- Create Delivery transfer from 'WH/Stock/Shelf 1'
- Open Forecast report:
=> RuntimeError: dictionary changed size during iteration
The original fix will be redone in another commit.
---
## Traceback:
```
File "/data/build/odoo/addons/stock/report/stock_forecasted.py", line 21, in get_report_values
'docs': self._get_report_data(product_ids=docids),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/odoo/addons/stock/report/stock_forecasted.py", line 128, in _get_report_data
res['lines'] = self._get_report_lines(product_template_ids, product_ids, wh_location_ids, wh_stock_location)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/odoo/addons/stock/report/stock_forecasted.py", line 359, in _get_report_lines
for product_id, location_id in currents:
RuntimeError: dictionary changed size during iteration
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#251768This update resolves a problem with the HTML Editor's automated tests. The tests were unreliable due to the toolbar being a popover, making it difficult to wait for the display to fully load. The team has increased timeouts and addressed timing issues to ensure test stability and consistent results.
This update corrects a discrepancy in the Spanish version of the abbreviated balance sheet report. It adds account code 189, required by recent Spanish accounting regulations (PGCE) to ensure accurate reporting and compliance. This ensures the financial reports generated for Spanish businesses align with current legal requirements.
Original PR description
According to last updated of PGCE https://www.boe.es/buscar/act.php?id=BOE-A-2011-18458 <img width="790" height="342" alt="image" src="https://github.com/user-attachments/assets/d5875946-d3b0-480b-bea1-8a7f4202aef7" /> @moduon MT-14017
This update fixes a restriction in the Italian tax processing (l10n_it_edi_doi) module, allowing multiple tax lines to be added to invoices, including those with 0% taxes like Enasarco and RIT. This change aligns with Italian tax regulations that permit combining Dichiarazione d'intento with other tax withholdings on the same invoice.
Original PR description
We should be able to add more taxes with the 0% on the same line, like the Enasarco and 23% RIT. Indeed in italy it is possible to have invoices with Dichiarazione d'intento togheter with a withholding and Enasarco taxes. See also: odoo/odoo#236251 Ticket [link](https://www.odoo.com/odoo/project.task/5933699) opw-5933699 Forward-Port-Of: odoo/odoo#248586
This update resolves a minor technical issue that was preventing the correct processing of account EDI invoices, specifically related to handling country codes. The change ensures the system correctly identifies supported countries, improving the reliability of invoice generation and transmission. This fix was made as part of our ongoing commitment to stability and accuracy.
Original PR description
`('FR, DE')` was a single string instead of a tuple, causing a TypeError when `country_code` is not a string (e.g. falsy value on empty recordset). Changed to `('FR', 'DE')` so membership test is used instead of substring search.
opw-6004910
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update resolves a minor typographical error within the account_edi_ubl_cii module. The fix ensures accurate processing of electronic invoices, preventing potential issues with data import and export. This change has no impact on core Odoo functionality.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue in Safari where pressing the spacebar would incorrectly move the text selection within the HTML editor. The fix manually merges adjacent text nodes to ensure the selection remains accurate, improving the editor's usability in Safari. This change enhances the user experience for Safari users.
Original PR description
Problem: In Safari, pressing space sometimes can move the selection unexpectedly. Cause: `node.normalize()` in Safari doesn't work in the same way as in Chrome or Firefox. When the selection is on a…
Problem: In Safari, pressing space sometimes can move the selection unexpectedly. Cause: `node.normalize()` in Safari doesn't work in the same way as in Chrome or Firefox. When the selection is on a text node adjacent to another and we normalize, the two text nodes will be merged but the selection will move to the parent element instead of the correct position inside the new merged text node. Example: before normalize: `<span>"ab""c[]d"</span>` after normalize: `<span>"ab[]cd"</span>` (expected) vs `<span[]>"abcd"</span>` (Safari) Solution: Instead of using `normalize`, we manually merge adjacent text nodes and properly restore the selection by computing the absolute offset before the merge and restoring it to the correct position in the merged text node. Steps to reproduce: - Have two adjacent text nodes inside a `span`. - Put the selection on the second text node in the middle. - Press space. - The selection will move to the end of the text. opw-5956709 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures that disabled user accounts are no longer incorrectly flagged as blacklisted when checking email communication. This prevents unnecessary blocking and improves the overall reliability of the system. The change was originally reported and addressed in a previous release.
Original PR description
Same as https://github.com/odoo/odoo/pull/249466, but for v17 and with tests. > When computing wether the user is blacklisted, disabled records must be ignored. > > https://www.loom.com/share/41ea437477f8416f8b50f9ef979d82bf > > > --- > I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr > > @moduon MT-13153 OPW-5952301 Forward-Port-Of: odoo/odoo#250361
This update fixes an issue where large company logos in Odoo documents were overlapping with customer address information. The PR adds a maximum width constraint to the small company logo, ensuring a cleaner and more readable document layout. This improves the overall user experience and prevents visual confusion.
Original PR description
**Description of the issue/feature this PR addresses:** Similar issue described in: https://github.com/odoo/odoo/pull/249432 Since there is no `max-width` defined for `o_company_logo_small`, if a user uploads a large logo, the customer address overlaps with the company details. This can be tested by previewing the document with a large logo. <img width="684" height="449" alt="image" src="https://github.com/user-attachments/assets/aa2ac10b-cb0f-448a-ade3-6e7bb8b1fcff" /> **Current behavior before PR:** <img width="681" height="383" alt="image" src="https://github.com/user-attachments/assets/cf7d5740-db51-43e3-b8f6-70325e9e28c0" /> **Desired behavior after PR is merged:** <img width="505" height="307" alt="image" src="https://github.com/user-attachments/assets/b175a06a-cde0-4808-a1fb-276fd96272c3" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr cc @ForgeFlow
This update resolves a technical issue where a test case incorrectly left data in an Odoo model. The fix ensures that test data is properly cleaned up after each test run, preventing persistent data from impacting subsequent tests. This improves the reliability of our testing process.
Original PR description
In a previous PR a test case was added the test if fields added via studio would export correctly, in doing so, the fields were added to the model inside the test case, but when continuing with the test case suite, the registery is not cleaned automatically so the fields were still present and have to be removed. task-none related-task-4963157
A broken link in the Odoo Point of Sale settings was directing users to a 404 error page. This update corrects a typo in the documentation URL, ensuring users can now access the correct online documentation for the Stripe payment provider. This improves usability and support for users utilizing the Stripe payment method.
Original PR description
A link (behind a small '?' icon) to online documentation for the Stripe payment provider is broken, on the `Point of Sale > Settings > Payment Terminals` page section. Versions affected: 18.0  Current behavior before PR: - The user is directed to a 404 error page. Desired behavior after PR is merged: - The Odoo online documentation for the Stripe payment provider should be displayed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update clarifies the behavior of Helpdesk article searches when using non-root articles as the main search source. A previous change limited search results to the specific article, now the documentation has been updated to reflect this. Additionally, a minor UI issue related to dropdowns has been addressed.
Original PR description
*: website_helpdesk_knowledge **Steps to reproduce:** - Install Helpdesk/Knowledge/Website apps - Go to Knowledge - Set up a Knowledge workspace root article with some child articles to it - Go to…
*: website_helpdesk_knowledge
**Steps to reproduce:**
- Install Helpdesk/Knowledge/Website apps
- Go to Knowledge
- Set up a Knowledge workspace root article with some child articles to it
- Go to Helpdesk > Configuration > Helpdesk Teams
- Open a Helpdesk team, and go to its Help Center config
- Check Knowledge and set a non-root article as main Article
- Go to Website > Help
First issue (non-root main article):
- Type a word which is present in both the article and one of its child articles
- Only the given article match the word
- If you use the root article it will match in any descendant
Second issue (in every case):
- Type a word in the search bar
- Wait for the dropdown to appear
- Click elsewhere, dropdown is properly hidden
- Try to change the search > Traceback
**Issue:**
The domain used to find the articles to match the search uses the current id as the `root_article_id`:
`['|', ('id', '=', team_article.id), ('root_article_id', '=', team_article.id)],` which was previously working in every case as it was not possible to set a non-root article in the team setting.
This was later changed to allow any article as the default website page. As a result, when a non-root article is selected, the search domain only applies to that specific article and no longer includes its descendants.
The other issue is related to the added boostrap attribute `data-bs-toggle="dropdown"` which is not properly reset when the dropdown is removed, and triggers the creation of an empty dropdown.
**Fix:**
Doesn't seem easy to fix to allow the search on all the descendants of the given article as we can't use the article `root_article_id` and filter out the unwanted results in a clean way (and it doesn't seem doable with a direct domain). Instead clarify the situation in the help of the article.
Also manually reset the attribute for `_onFocusOut`.
related: https://github.com/odoo/enterprise/commit/ed971d4d02624f8b864ab6c37c6e7db8ba3dfe11
opw-5258607