Friday, September 18, 2026
13 changes · saas-19.2
Enhancements to existing features
The Spanish reports app now includes the required return type setup for Mod 420 tax returns. This helps ensure the report can be handled consistently with other tax returns, supporting smoother filing workflows.
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
Resolved issues and error corrections
Odoo now blocks the creation of API keys that are already expired, helping users avoid mistakes when copying example settings from documentation. This reduces confusion and ensures newly created keys can actually be used as intended.
Original PR description
Prevent creating API keys that are already expired. One typical case is when you copy/paste the documentation and end up creating keys that are already expired, without noticing. Forward-Port-Of: odoo/odoo#286677 Forward-Port-Of: odoo/odoo#286548
Generic demo leave types no longer include a specific country, so they will not interfere when setting a company's country in demo or development databases. This keeps country validation active for real leave data while avoiding unnecessary setup blockers caused by sample data.
Original PR description
_check_country_change_holidays constraint blocks writes to res.company.country_id whenever hr.leave/hr.leave.allocation records exist whose leave type country differs from the new company country. Unset country_id on the generic holiday_status_* demo leave types they are not meant to represent a specific country's holiday policy, so they should not carry a country at all. With country_id set to False, they no longer participate in the country-change constraint. The constraint keeps protecting real country changes on business data, while no longer blocking legitimate demo installs where we configure the main company with our country but rely on demo data for dev instances. Related to https://github.com/odoo/odoo/pull/277346 Forward-Port-Of: odoo/odoo#278749
A redundant internal step was removed from maintenance request creation. This cleanup has no expected impact on users, because the maintenance team is already assigned automatically when needed.
Original PR description
The create method assigned request.maintenance_team_id to itself, a no-op that reads and writes the same value and has no effect. This line originally set the team from the equipment as a fallback when creating a request. PR #196181, while refactoring mail alias handling from equipment category to team, replaced that assignment with a self-assignment, turning it into dead code. maintenance_team_id is a required field and is already a stored compute depending on equipment_id, so it is computed correctly on create without this line. Removing it has no functional impact. Forward-Port-Of: odoo/odoo#286132
Invoices already sent through PEPPOL can no longer have the PEPPOL sending option selected again. This prevents users from accidentally attempting to resend invoices that were already transmitted and makes the disabled status clearer in the interface.
Original PR description
If the invoice is already sent through PEPPOL, the checkbox for sending the invoice should then be readonly and unchecked. Currently is correctly unchecked but not readonly. We fix it by copying what French localization (`l10n_fr_pdp`) does already, giving a reason for disabling. <img width="1359" height="948" alt="immagine" src="https://github.com/user-attachments/assets/6f91ab34-8989-487e-8cd9-96dafee7bcb5" /> . Pad: https://pad.odoo.com/p/accountingv20 pad-accountingv20 Forward-Port-Of: odoo/odoo#288898
The API documentation now opens the correct related model when users middle-click a many-to-one field. This prevents confusion and saves time by taking users directly to the intended reference page without unnecessary reloads.
Original PR description
Steps to reproduce: * open api_doc * select a model (eg: project.task) * middle click on a many2one field (eg: stage_id) Observed behavior: The new tab is opened on the base model (project.task) instead of the comodel (project.task.type). This commit fixes the issue by using `t-att-href` to point to the correct model and `preventDefault` to avoid a full reload when clicking on a m2o. Forward-Port-Of: odoo/odoo#288558
The stock workflow test now recognizes the customized Turkish e-Dispatch stock list view, preventing false test failures when that localization is installed. This keeps quality checks reliable without changing the user-facing stock workflow.
Original PR description
### Steps to reproduce: - Install `l10n_tr_nilvera_edispatch` (e.g. the `tr` country build) - Run `test_basic_stock_flow_with_minimal_access_rights` > The tour times out on step 6/31, "check that at…
### Steps to reproduce: - Install `l10n_tr_nilvera_edispatch` (e.g. the `tr` country build) - Run `test_basic_stock_flow_with_minimal_access_rights` > The tour times out on step 6/31, "check that at least one picking is present in the view". ### Cause of the issue: The step triggers on `.o_stock_list_view_view`, a class the web client derives from the `js_class` of `stock.vpicktree`: https://github.com/odoo/odoo/blob/71c040ae236c9487afc49559486a588f21ccb37b/addons/stock/views/stock_picking_views.xml#L66-L70 https://github.com/odoo/odoo/blob/71c040ae236c9487afc49559486a588f21ccb37b/addons/web/static/src/views/utils.js#L45-L68 `l10n_tr_nilvera_edispatch` overwrites that attribute to plug in its e-Receipt upload button, so the root carries `o_l10n_tr_edispatch_tree_view` instead and the trigger never matches: https://github.com/odoo/odoo/blob/71c040ae236c9487afc49559486a588f21ccb37b/addons/l10n_tr_nilvera_edispatch/views/stock_picking_views.xml#L4-L13 Only the class name changes: `L10nTrNilveraEdispatchListView` spreads `StockListView`, so the rendered list is identical. runbot-947260 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288255
This fixes a case where batch payments could remain marked as sent even after the underlying bill and payment were fully paid. Payment matching is now refreshed correctly, helping finance teams see accurate payment statuses without manual intervention.
Original PR description
A payment on a journal without outstanding account has no journal entry, so it is matched as soon as it is paid. When the bill it pays is reconciled later on, _compute_state turns it to 'paid', but assigning a field from within a compute doesn't notify the fields depending on it: is_matched stays False and any batch payment holding that payment stays in 'sent' state. Mark is_matched for recomputation explicitly, as 18.0 already does since d8de234. Steps to reproduce: - On the Bank journal, leave the outstanding account empty on the outbound payment method line - Post a vendor bill - Register a payment on it - Put that payment in a batch payment and validate the batch - Create a MISC entry and reconcile the bill with it - Issue: bill and payment are 'Paid' but the batch stays 'Sent'. Forward-Port-Of: odoo/odoo#288460
This fixes a small issue where an internal export validation problem could show the wrong type of error. The change helps ensure errors are reported correctly, making diagnosis and maintenance more reliable without changing business workflows.
Original PR description
The format was broken. `'{}:{}' % it` → `TypeError` instead of `AssertionError`.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#288836
Forward-Port-Of: odoo/odoo#288610This update ensures the Turkish Nilvera e-Dispatch module installs reliably by declaring a missing required dependency. It prevents installation failures in test or minimal setup scenarios without changing business workflows.
Original PR description
View 'l10n_tr_nilvera_edispatch.view_picking_form_inherit_l10n_tr_nilvera_edispatch' fails to install in single-module test skip auto_install because it depends on field stock.picking:country_code. That field is provided by module 'stock_account' which is not in the dependency path of the module. In normal install the module 'stock_account' is present through auto_install when both 'account' and 'stock' are installed. Adding the direct dependency on 'stock_account' is not a problem because the view crashes without it. 'stock_account' is available through the chain below. [l10n_tr_nilvera_edispatch] ──[depends]──> [stock] ──⚡[AUTOLOAD]──> [stock_account] [l10n_tr_nilvera_edispatch] ──[depends]──> [l10n_tr_nilvera] ──[depends]──> [l10n_tr] ──[depends]──> [account] ──⚡[AUTOLOAD]──> [stock_account] REF Runbot: https://runbot.odoo.com/odoo/error/946186 Forward-Port-Of: odoo/odoo#288683 Forward-Port-Of: odoo/odoo#285633
When helpdesk tickets are merged, related timesheets now keep the same sales order item as the destination ticket. This prevents inconsistent billing or reporting details after combining tickets that were linked to different sale order items.
Original PR description
Currently when you merge helpdesk tickets with differing sale order items, the sales order item listed on the timesheets of the source ticket is not updated to match the destination ticket's sales order item. This PR ensures uniformity bugfix-6473396 Forward-Port-Of: odoo/enterprise#131155 Forward-Port-Of: odoo/enterprise#129060
Creating an appointment event from the calendar now respects the time slot the user selected instead of automatically using the appointment type's default duration. This helps avoid incorrectly timed bookings and reduces manual corrections for staff managing appointments.
Original PR description
When creating an event from the calendar view of an appointment type, the duration of the event was set to the duration of the appointment, therefore bypassing the slot we drew. This commit fixes this behavior by giving the priority to the end date of the drawed slot. Task-6412432 Forward-Port-Of: odoo/enterprise#130171
This fix ensures AI-generated pivot tables apply column groupings in the format the reporting view expects. It prevents errors or incorrect layouts when date-based grouping options are returned by the AI assistant.
Original PR description
The AI backend returns column groupbys as a list containing both strings and dictionaries with interval information. While this format is used to preserve the interval metadata, the pivot model expects `colGroupBys` to be a flat list of strings. This commit updates the view patch to flatten dictionary entries into their corresponding `<field>:<interval>` strings before assigning them to the pivot model metadata, ensuring the format matches the pivot model's expectations. task-6377810 Forward-Port-Of: odoo/enterprise#129515