Monday, September 28, 2026
12 changes · saas-19.3
Enhancements to existing features
Adds test coverage to ensure appraisal campaigns created by managers without Appraisals access only include the employees they selected. This helps prevent accidentally scheduling appraisals for all reporting employees when only a subset was intended.
Original PR description
The campaign wizard created appraisals for every employee reporting to the user instead of the ones actually selected, whenever the user had no Appraisals access rights. Steps to reproduce: 1. Log in…
The campaign wizard created appraisals for every employee reporting to the user instead of the ones actually selected, whenever the user had no Appraisals access rights. Steps to reproduce: 1. Log in as a user with no Appraisals access rights (e.g. Marc Demo) who has several employees reporting to them 2. Go to Appraisals and click "Launch Campaign" 3. Select one employee in the Employees field 4. Pick an Appraisal Template and a date, then click "Schedule" `employee_ids` is a many2many to `hr.employee`, and `convert_to_record` drops the records a user cannot access, so for a non-HR officer the field read back empty. Both `_compute_warning` and `action_generate_appraisals` then fell through to their `self.employee_ids or ...search(...)` branch, whose domain is every employee below the user in the hierarchy. This was fixed in PR #127391 (task 6452765) by setting `bypass_search_access=True` on the field, but that shipped without a test. This one passes with the fix and fails without it. opw-6448677
Spanish localization reports now include return type support for the Mod 420 tax return. This helps ensure the report can be categorized and processed consistently with other tax returns.
Original PR description
Add the `es_mod420_tax_return_type` record to `account_return_data.xml` to support the Mod 420 tax return, including its association with the `l10n_es.mod_420` report. This change is done so that 420 can have return types, which bedore it didn't. task-6225928 Forward-Port-Of: odoo/enterprise#120613
Resolved issues and error corrections
This change removes an unnecessary default value from an internal test method parameter. It follows coding best practices and helps avoid confusing behavior or future runtime errors in Odoo's core test infrastructure.
Original PR description
[RUF077](https://docs.astral.sh/ruff/rules/method-receiver-default/#method-receiver-default-ruf077) specifies that method receiver parameters, such as `self` and `cls`, should not have default values. The reasoning is because these parameters are usually bound by the method binding protocol, so a default value on a receiver parameter is almost certainly a mistake and can lead to confusing behavior or runtime errors. This method seems to not reference self, and this should not cause errors, but it is best practice to not do this. runbot-[947144](https://runbot.odoo.com/odoo/error/947144) Forward-Port-Of: odoo/odoo#290616
This fix ensures demo data for Belgian payroll-related modules is created using the correct Belgian company context. It prevents an error when users load the demo data through the interface, making setup and testing smoother.
Original PR description
Before the fix, loading the module's demo data through the UI triggered an error. task-6581013 Forward-Port-Of: odoo/enterprise#132843 Forward-Port-Of: odoo/enterprise#132358
Updates the U.S. accounting template so physical asset accounts use “Depreciation” instead of “Amortization,” aligning terminology with standard accounting practice. It also adds a dedicated amortization account for intangible assets, improving clarity in financial reporting.
Original PR description
Amortization is used when it is an intangible asset (loan/ goodwill/ IP). Depreciation would be used for a physical tangible asset (vehicles/ PPE). This commit renames some accounts wrongly using the "Amortization" wording when "Depreciation" should've been used. We also add a new account that can be used for Amortization. task-6578876
Buy X Get Y loyalty programs no longer show or allow editing of the Minimum Purchase section. This prevents users from setting purchase thresholds that should not apply to this promotion type, reducing confusion and configuration mistakes.
Original PR description
I think the point was to hide the entire `Minimum Purchase` section when the program type is `buy_x_get_y`, but only the label is hidden. This commit will also hide the div under the label, so no minimum purchase can be set on `buy_x_get_y` programs --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288281
Spreadsheet list formulas now keep single linked numeric values as real numbers instead of converting them to text. This prevents calculation errors in locales such as French, where decimal separators differ, while leaving multi-value behavior unchanged.
Original PR description
Steps to reproduce:
- insert a sale.order list into a spreadsheet
- change the locale to FR_fr
- add the formula in A1: =ODOO.LIST(1, 1, "invoice_ids.amount_total"
- in A2: =A1+1 => error
The value for the "amount_total" is stringified
to something like "4.5" because of the `[].join(",")` but "4.5" is not interpreted as a number in the FR locale where the decimal separator is "," and it should be "4,5"
With this commit, when there's a single record in the x2many, we fallback on the "normal" case and return the real value.
When there are multiple values, we volontarily keep the current behavior. We can't "just format it" because we join with "," and it wouldn't work if "," is also the decimal separator. This is a known and accepted limitation, especially in stable
Task: 6307092
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#283777
Forward-Port-Of: odoo/odoo#270279Fixed a visual issue in Sales quotations where the optional products table appeared lighter than its surrounding section when using dark mode. This improves the consistency and readability of the quotation product selection experience.
Original PR description
**Steps to reproduce:** - Set preferences to dark mode - Create a quotation and add a product with optional products (e.g customizable desk) -> Background of optional products is lighter than the…
**Steps to reproduce:** - Set preferences to dark mode - Create a quotation and add a product with optional products (e.g customizable desk) -> Background of optional products is lighter than the surrounding div **Behavior:** The `div` showcasing optional products is set to be a bit darker to add contrast in the modal. In light mode, table's background is transparent, which allows it to adapt to a darker container. However, this is not the case in dark mode, which causes a mismatch between table and div backgrounds. By default `$table-bg` follows `$body-bg`: https://github.com/odoo/odoo/blob/3442814d57cd9420d7dc6d022d15cd5d1b3def74/addons/web/static/lib/bootstrap/scss/_variables.scss#L738-L740 And is later set to transparent here: https://github.com/odoo/odoo/blob/3442814d57cd9420d7dc6d022d15cd5d1b3def74/addons/web/static/src/scss/bootstrap_overridden_frontend.scss#L74-L75 However when darkmode is enabled, `$body-bg` is re-assigned, which forces `$table-bg` back to the default dark color, bypassing the transparent override. https://github.com/odoo/odoo/blob/3442814d57cd9420d7dc6d022d15cd5d1b3def74/addons/web/static/lib/bootstrap/scss/_root.scss#L132-L139 --- This commit ensures that `table-bg` is explicitly set to transparent for tables displaying optional products. opw-6569713 Forward-Port-Of: odoo/odoo#288127
This update removes unnecessary logic from the accounting reports download flow. It helps keep the report download code clearer and reduces the chance of confusion in future maintenance, with no expected change for users.
Original PR description
`!something` is never nullish, so `?? true` is dead code. Probably the intention was `if (!(data.no_closing_after_download ?? true))`, but reviewer has the final say and I can change it. Forward-Port-Of: odoo/enterprise#131774
This fix prevents spreadsheet actions from converting multi-record relationship fields into plain text. It helps preserve accurate data handling in document spreadsheets and reduces the risk of incorrect filtering or display behavior.
Original PR description
See community PR task-6307092 Forward-Port-Of: odoo/enterprise#128699 Forward-Port-Of: odoo/enterprise#120701
KPI report summaries now ignore archived returns, so hidden or inactive returns no longer appear in business indicators. This keeps reporting clearer and avoids misleading history without forcing users to mark returns as completed.
Original PR description
[FIX] account_reports: KPI provider: properly ignore inactive returns Returns can be archived (setting the 'active' field to False) from the UI, so that the user can hide them when not needed,…
[FIX] account_reports: KPI provider: properly ignore inactive returns Returns can be archived (setting the 'active' field to False) from the UI, so that the user can hide them when not needed, without risking them being regenerated by the cron, and without havin to mark them as completed, which could give misleading information when browsing the history. The problem was here the KPI provider did not properly ignore such returns. ======================================== [FIX] account_reports: make KPI provider test with existing data in db The KPI provider query completely ignores multi-company. Because of that, the test wasn't properly sandboxed, and could fail if any non-test company of the database contained a return made from any untested return type, as it would add one element to the result of get_account_reports_kpi_summary. We now make sure to archive all existing returns, whatever their company, before running the test. Forward-Port-Of: odoo/enterprise#131438
The Bulgarian SAF-T reporting feature will no longer be installed automatically unless the advanced accounting setup is explicitly present. This avoids making a specialized accounting report available in environments that may not have the required accounting capabilities.
Original PR description
As the Bulgarian SAF-T Report is destined for advanced accounting, it should only be available and auto-installed when the 'accountant' module is as well. As the 'accountant' module is not part of the dependencies yet (it is from 20.0 on), we cannot be sure that it is already installed. It is then better to stop the auto installation altogether. Forward-Port-Of: odoo/enterprise#132761