Monday, September 28, 2026
17 changes · saas-19.2
Resolved issues and error corrections
The Indian payroll payment report now shows the payment date when the ENET payment option is selected. This helps payroll users review and process payment information consistently without missing a required date field.
Original PR description
Bug reproduction - Install l10n_in_hr_payroll, payslips, validate, pay, Payment Date is not there if you select enet option Bug cause - It is made invisible if the option is enet before Bug solution - Remove the block that made it invisible task-6584795
Shared project users with editing rights can now create tasks without running into a customer access error. The customer field is correctly protected from edits when users are not allowed to change it, preventing task creation from failing.
Original PR description
Steps to Reproduce: - Install Project. - Share a project with a project sharing user having Edit or Edit with limited access permissions. - Log in as that shared user. - Open the shared project and create a task from the list or kanban view. - Observe that creating the task fails with an AccessError on Contact. Issue - Creating the task fails with an AccessError on the Customer (`partner_id`). Cause - The customer field is editable for project sharing users who should not be allowed to modify it. As a result, `partner_id` is included during task creation and triggers an access error. Solution - Correct the readonly condition on the customer field so unauthorized users cannot modify it. task-5075150 Forward-Port-Of: odoo/enterprise#123052
This change removes an inappropriate default value from an internal method parameter in Odoo's core test framework. It follows best-practice checks to reduce the risk of confusing behavior or runtime errors during automated testing, with no expected impact on regular users.
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 fixes the loyalty promotion setup so minimum purchase details are fully hidden for buy X, get Y programs. It prevents users from accidentally setting a minimum purchase rule that does not apply to that promotion type.
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
The Belgian payroll time off calendar now correctly greys out days covered by Parental Time Off or Time Credit schedules. This helps employees and HR teams see unavailable days accurately and avoid confusion when reviewing leave calendars.
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
This fix prevents users from being shown a misleading “Pick From” option when splitting dropship operations that should only create new lots. As a result, the lot number and expiration date entered by the user are now correctly applied, reducing delivery errors for tracked products.
Original PR description
Steps to reproduce 1. In Inventory Settings, enable Lots & Serial Numbers and Expiration Dates. 2. Create a storable product tracked by lot with Expiration Date enabled. 3. Create and confirm a…
Steps to reproduce 1. In Inventory Settings, enable Lots & Serial Numbers and Expiration Dates. 2. Create a storable product tracked by lot with Expiration Date enabled. 3. Create and confirm a dropship of it, then open the move's Detailed Operations. 4. The pre-filled line works: typing a batch and an expiration date creates exactly that lot at validation. 5. To split the quantity, click "Add a line": it opens the "Pick From" popup, and choosing "Create" there creates the lot and attaches it to the line. 6. On that line, edit "Lot/Serial Number" and "Expiration Date", then Validate. -> Expected: the values entered on the line are used. -> Actual: they are ignored; the lot created through "Pick From" is delivered with its own expiration date, the name and date typed on the line have no effect. Issue --- On a create-lots-only non-incoming operation like `Dropship`, `show_quant` is derived from `picking_code` alone, so the "Pick From" quant picker is shown even though the operation only creates lots. Adding a line goes through "Pick From", which creates the lot and attaches its `lot_id` to the move line; from then on the line's `lot_name` and `expiration_date` stay editable but do nothing, since a set `lot_id` is used as-is at validation and the `expiration_date` is recomputed from the lot, so anything typed there is silently dropped. Such an operation has no existing stock to pick from, so `show_quant` is now gated on the lot settings too: "Pick From" is hidden and the line's `lot_name` and `expiration_date` become the only inputs, created into the lot at validation like receipts already do. https://github.com/odoo/odoo/blob/68dcb950df83d70ff2aea0e05c96cc9b57c1a8a9/addons/stock/models/stock_move.py#L646-L647 opw-6530563 Forward-Port-Of: odoo/odoo#290071 Forward-Port-Of: odoo/odoo#287474
Fixed an issue in Discuss where a new message could disappear temporarily if it arrived while a channel was still loading. Users now see incoming messages reliably without needing to wait for another refresh or fetch.
Original PR description
Before this commit, a message received while a channel opens in Discuss does not appear, and stays out of the thread until the next fetch. This happens because the channel opens on its last read message through `loadAround`, which replaces the message list with the fetched messages. The bus handler of a new message adds it to that list as long as the thread displays the present, so the replacement drops what arrived during the fetch. This commit fixes the issue by putting those messages back: in the list when it displays the present, in `pendingNewMessages` when it does not, where `fetchMoreMessages` already picks them up. https://runbot.odoo.com/odoo/error/947188 Forward-Port-Of: odoo/odoo#290388 Forward-Port-Of: odoo/odoo#289976
This fixes an error that prevented users from being added to payroll groups from the Groups screen in Australian Payroll API databases. It also ensures both additions and removals are properly audit-logged, improving reliability and compliance tracking without changing existing workflows.
Original PR description
#### Description of the issue/feature this PR addresses:
Adding a user to a group from the Groups form crashes on an Australian Payroll-API database, and removals from that form are never audit-logged.
#### Current behavior before PR:
The audit-logging mixin reads the changed users out of the raw write command with vals.get("user_ids")[0][2], which assumes a 3-element command tuple. The Groups form sends the 2-element (4, id) LINK command, so the write raises an IndexError; UNLINK commands are silently not logged for the same reason.
#### Desired behavior after PR is merged:
Group membership changes made from the Groups form are audit-logged for both additions and removals, regardless of the command used to write user_ids. The mixin reads the members before and after the write instead of interpreting the command. No field, model or method-signature change, so it is safe in stable.
opw-6397011
Forward-Port-Of: odoo/enterprise#132821
Forward-Port-Of: odoo/enterprise#125124Users can now click ticket analysis charts or pivot cells grouped by employee, manager, or department without hitting a server error. The report now correctly opens the related helpdesk tickets, making timesheet and support reporting more reliable.
Original PR description
Currently, an error occurs on clicking on the graph or the pivot cell if the data is grouped by Employee/Manager/Department. ### **Steps to reproduce** 1) Install helpdesk_timesheet with demo data 2)…
Currently, an error occurs on clicking on the graph or the pivot cell if the data is grouped by Employee/Manager/Department.
### **Steps to reproduce**
1) Install helpdesk_timesheet with demo data
2) Go to Timesheet > Reporting > Ticket Analysis
3) Set group by to Employee
4) Click on any graph bar or pivot cell
### **Error:**
`ValueError: Invalid field helpdesk.ticket.employee_id in condition ('employee_id', '=', 1)`
Root Cause:
The `helpdesk.ticket.report.analysis` model includes specific fields such as `employee_id`, `department_id`, and `employee_parent_id` (see [1]) that are defined for reporting purposes but do not exist on the `helpdesk.ticket` model. When a user clicks a data point to view related tickets, the reporting view passes the current domain directly to the ticket list view. Because `helpdesk.ticket` lacks these fields, the ORM fails to validate the domain, resulting in a server error.
[1]- https://github.com/odoo/enterprise/blob/8d16b647431985dd7c216ae39eea6ca050e04b46/helpdesk_timesheet/report/helpdesk_ticket_report_analysis.py#L15-L17
### **Fix:**
This commit introduces a mixin to intercept the openView call. The mixin maps reporting-specific fields to valid relational paths on the ticket model `(for example, employee_id is transformed into user_id.employee_id)`. This ensures that the domain generated from the report model is compatible with the target ticket model.
**opw-5931273**
Forward-Port-Of: odoo/enterprise#108503Kenya eTIMS submissions now exclude taxes that do not have a KRA tax code from the reported tax-inclusive total. This prevents levies owed to other authorities, such as tourism levies, from being incorrectly reported to the Kenya Revenue Authority.
Original PR description
Issue: Non KRA taxes are sent in eTIMS tax total Steps to reproduce: - With l10n_ke_edi_oscu - Create a 2% Tax named CTL with no KRA Tax Code - Create an invoice - Add a line with 16% and CTL taxes - Confirm - Send to eTIMS Current behavior: - eTIMS JSON (unaccessible) is created with 'totAmt' (total_tax_included) including non-KRA Taxes Expected Behavior! - eTIMS JSON 'totAmt' doesn't incldue non-KRA Taxes Note: eTIMS is used to report to Tax Autority, however some "taxes" (e.g. Tourism levy) are paid to other authorities (e.g. Tourism Fund) and shouldn't be included in eTIMS. opw-6456478 Forward-Port-Of: odoo/enterprise#131577
This fixes a visual issue in Sales quotations where optional product tables appeared with a mismatched background in dark mode. The optional products area now blends correctly with its surrounding panel, improving readability and visual consistency for users working in dark mode.
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
KPI summaries now ignore archived returns, so hidden or inactive returns do not appear as pending or distort reporting history. Related tests were adjusted to stay reliable even when other companies already have return data in the database.
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 in this version. This prevents it from appearing in environments that may not have the advanced accounting capabilities it depends on, reducing confusion and setup issues.
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
This change removes unnecessary fallback logic in the account reports download flow. It keeps the behavior clearer and easier to maintain without changing the user-facing reporting experience.
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
Demo data for Belgian payroll-related modules now loads using the correct Belgian company context. This prevents an error when users install or load the demo data through the interface, improving setup reliability.
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#132632 Forward-Port-Of: odoo/enterprise#132358
This fix updates formulas used in the Swiss balance sheet report so figures are calculated and presented correctly. It helps Swiss accounting users rely on more accurate financial statements for review and reporting.
Original PR description
Change some formulas in the Swiss balance sheet task-6379692 Forward-Port-Of: odoo/enterprise#123895
Italian invoices using the Import/Export fiscal position now apply the correct single 0% tax instead of adding two overlapping 0% taxes by default. This prevents incorrect tax setup on invoice lines and helps businesses avoid manual corrections and potential reporting errors.
Original PR description
Upon Import/Export, the 0% EX N7 tax is added by default on each tax excluded line, as it incorrectly shares the same default Import/Export fiscal position with the standard 0% EX tax. This causes both to be applied simultaneously to a single invoice line. 1. Install Accounting and `l10n_it` 2. Switch to IT company 3. Go to Invoices and create a new one 4. Select the Import/Export fiscal position 5. Add a line with a new product (so it's clean of custom product taxes) 6. Both `0% EX` and `0% EX N7` taxes are applied, instead of just `0% EX` Ticket [link](https://www.odoo.com/odoo/project.task/6518926) opw-6518926 Forward-Port-Of: odoo/odoo#285586