Monday, September 28, 2026
13 changes · saas-19.3
Resolved issues and error corrections
This fix prevents the restaurant floor plan from showing an error if a background image finishes loading after the user has already left the screen. It improves reliability for restaurant staff using floor layouts, especially with older floor images.
Original PR description
When the selected floor uses an old background image without saved dimensions, ensureBgImageLoaded() loads it asynchronously and then calls ensureBoardFits() to resize the canvas. If FloorPlan unmounts before the image loads, the callback still runs while containerRef.el is unavailable, causing: TypeError: Cannot read properties of undefined (reading 'clientWidth') To fix this issue we check that scrollContainer exists before accessing it.
Fixed an issue where selecting multiple timesheet assistant suggestions could leave the Task field blank when one suggestion had only a project and another had both a project and task. The form now keeps the appropriate task when it matches the selected project, reducing manual correction for users.
Original PR description
- When several suggestions are selected, the timesheet form only took the task from the first suggestion that had a project. Selecting a project-only suggestion and a project/task suggestion left the Task field empty. - Take the first matching task independently of which suggestion provided the project, and only if it belongs to that project. task-6485355
Belgian payroll calendars now correctly mark days covered by Parental Time Off or Time Credit as unavailable in the Time Off view. This helps HR users avoid confusion when reviewing employee availability and leave planning.
Original PR description
Issue: ---------------------------------------- When having calendar attendances with the "Parental Time Off" work entry type, then the time off calendar view doesn't show these days as greyed out…
Issue: ---------------------------------------- When having calendar attendances with the "Parental Time Off" work entry type, then the time off calendar view doesn't show these days as greyed out even though it should. Steps to reproduce: ---------------------------------------- - Install l10n_be_hr_payroll and be on a Belgian company - Have an employee with a contract - In the Payroll tab define a start date and an end date for the contract. - In "Working Hours", create a new working schedule where the Work Entry Type is either Parental Time Off (Belgium) or Time Credit for all five weekdays. - Click the "Time Off" smart button - The days covered by the contract aren't greyed out Cause: ---------------------------------------- `_work_intervals_batch` only subtracted the Parental Time Off/Credit Time attendances when `r and not r._is_flexible()`. `_get_unusual_days` never sets `resources_per_tz`, so `r` is always the empty placeholder resource, which is falsy, so the subtraction never ran. Solution: ---------------------------------------- Subtract unless `r` is an actual flexible resource, instead of only when it is a non-flexible one. Note: ---------------------------------------- Not reproducible as of saas-19.3: hr_work_entry's ResourceCalendar gained its own generic `_work_intervals_batch` override there that subtracts any attendance whose work entry type has `count_as == 'absence'`, with no flexible-resource guard. Parental Time Off/Credit Time already have `count_as == 'absence'`, so that override masks this bug by excluding them first. This fix is still needed to make the l10n_be-specific logic correct in its own right. opw-6397416 Forward-Port-Of: odoo/enterprise#128063
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