Wednesday, September 23, 2026
6 changes · 17.0
Resolved issues and error corrections
Fixed an issue where selecting an autocomplete suggestion could cause the dropdown to reopen and remain visible. This improves reliability when users choose linked records and helps prevent automated workflow failures caused by stuck dropdowns.
Original PR description
Before this commit, the autocomplete dropdown of a many2one could open again right after a suggestion was picked, and stay open. The step of mail_template_dynamic_placeholder_tour waiting for it to…
Before this commit, the autocomplete dropdown of a many2one could open again right after a suggestion was picked, and stay open. The step of mail_template_dynamic_placeholder_tour waiting for it to close then times out:
FAILED: [8/36] Tour mail_template_dynamic_placeholder_tour
Step Wait for the drop down to disappear
(trigger: div[name="model_id"] .o-autocomplete:not(:has(.ui-autocomplete)))
TIMEOUT step failed to complete within 10000 ms.
This happens because the search filling the dropdown runs 250ms after the last keystroke, so a suggestion of the previous search can be picked while the next search is still scheduled. Picking a suggestion only closes the dropdown. The scheduled search then runs, opens the dropdown on the selected value, and nothing closes it after that.
This commit fixes the issue by discarding the scheduled search when the dropdown closes.
https://runbot.odoo.com/odoo/error/233574
https://runbot.odoo.com/odoo/error/237744
https://runbot.odoo.com/odoo/error/944454
https://runbot.odoo.com/odoo/error/945517
https://runbot.odoo.com/odoo/error/947141This fixes an issue where using the chatter on a form could discard unsaved edits if the form could not be saved, such as when a required field was empty. Users now keep their current changes and can correct validation errors without losing their work.
Original PR description
Before this commit, posting a message in the chatter of a form view with `post_refresh` lost the unsaved changes of an invalid record, for instance after emptying a required field. The form showed the invalid field for a moment, then came back with the saved values. The same happens on the other chatter actions that reload the form, such as a follower change. This happens because the chatter reloads the record after it tries to save it, even when the save fails. This commit fixes the issue by reloading the record only when the save succeeds.
This fixes a timing issue in an automated Mail test that could fail when the system responded slightly slower than expected. The change makes the test wait for the relevant field to be ready, improving confidence in test results without changing user-facing behavior.
Original PR description
Before this commit, mail_template_dynamic_placeholder_tour could fail when the server answers the onchange of "Applies to" slowly: Tour mail_template_dynamic_placeholder_tour failed at step Check if…
Before this commit, mail_template_dynamic_placeholder_tour could fail when the server answers the onchange of "Applies to" slowly:
Tour mail_template_dynamic_placeholder_tour failed at step Check if
the dynamic placeholder popover is opened
(trigger: div.o_model_field_selector_popover)
This happens because the tour waits a fixed 200ms after picking "Contact" before typing "#" in the subject. The popover needs the model, and the record only holds the model once the onchange answers. On runbot the answer came after 230ms, so "#" showed the "select a model" notification instead of the popover.
This commit fixes the issue by waiting for the internal link button of the many2one, which only renders once the record holds the model.
Note that this step relies on "[FIX] web: cancel the pending search on autocomplete select": without it, a search still pending on the picked value marks the input as edited, which hides that button.
https://runbot.odoo.com/odoo/error/947209
Ref commit: https://github.com/odoo/odoo/pull/287888This fixes demo timesheet entries that were linked to the wrong project for Kitchen Assembly work. The sample data now keeps tasks, projects, and sale orders aligned, preventing misleading project overtime filters and recorded-timesheet views in demo environments.
Original PR description
## Issues In the `sale_timesheet` demo data, a few `account_analytic_line`s have a project_id that does not match their task_id, as their task does not belong to their project. A side effect of this…
## Issues In the `sale_timesheet` demo data, a few `account_analytic_line`s have a project_id that does not match their task_id, as their task does not belong to their project. A side effect of this incoherence occurs when filtering projects based on `is_project_overtime`, as the computation to determine the value of that field slightly differs from the `_search_is_project_overtime` method. In the field computation, we group the `account.analytic.line`s by their `project_id` (whichis an issue when their project_id is not correct) and sum the `unit_amount`, whereas in the `_search` method, we group the `project_task`s by their `project_id` and sum their `effective_hours`. <img width="1619" height="452" alt="6422173_4" src="https://github.com/user-attachments/assets/baeeaa2c-e25f-4206-be55-dbb04406ae32" /> ## Steps to reproduce 1. Install `sale_timesheet` with demo data 2. Open the Sale Order with two "Kitchen Assembly (Milestones)" order line (should be S00022 in 17.0) 3. Click on the *Recorded* button 4. **Some of the "Kitchen Assembly" timesheet entries have their project set to "ACME - S00023", which is not related to the "S00022" sale order at all. The task "Kitchen Assembly" also does not belong to that project. Creating such an entry manually is not even possible.** ## Cause The project_id set on the "Kitchen Assembly" `account_move_line` is the project of "Senior architect" (`sale_line_32`), which is "ACME - S00023". That project does not match the task. https://github.com/odoo/odoo/blob/4b1570db68eabf75c7fae69f3dbbc61b92c4cee3/addons/sale_timesheet/data/sale_service_demo.xml#L896-L932 We should instead use both the task_id and the project_id of the corresponding sale_order_line: `sale_line_34`. <img width="784" height="254" alt="6422173_3" src="https://github.com/user-attachments/assets/629f7ee0-074f-4191-a535-25e13a629d73" /> opw-6422173
This fixes how Odoo handles related many-to-many fields that are not stored, ensuring they do not keep database relationship links they should not have. It helps prevent data from one field being incorrectly mixed into another, reducing unexpected behavior in custom configurations.
Original PR description
When we setup a many2many field which is not stored, it must not have a relation. This is already done for nonrelated fields, but we must do it also for related fields. Otherwise, we may have…
When we setup a many2many field which is not stored, it must not have a relation. This is already done for nonrelated fields, but we must do it also for related fields. Otherwise, we may have side-effects like finding sibling fields in 20.0: in the code below, reading categories would fill roles.
```py
model_id = self.env["ir.model"]._get("test_new_api.foo")
fields = [{
"name": "x_partner_id",
"ttype": "many2one",
"relation": "res.partner",
}, {
"name": "x_role_ids",
"ttype": "many2many",
"relation": "res.partner.category",
}, {
"name": "x_partner_category_ids",
"ttype": "many2many",
"relation": "res.partner.category",
"related": "x_partner_id.category_id",
"store": False,
"readonly": True
}]
for f in fields:
f["model_id"] = model_id.id
self.env["ir.model.fields"].create(fields)
env['test_new_api.foo']._fields['x_partner_category_ids'].relation # should be None
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prCanadian reports now show QST instead of PST when a Quebec tax number is detected. This avoids contradictory invoice labels and helps Quebec businesses present tax registration details correctly without extra setup.
Original PR description
The Canadian localization prints the provincial tax number on every document header and under the customer address with a hardcoded "PST:" label. Companies and customers registered in Québec store…
The Canadian localization prints the provincial tax number on every document header and under the customer address with a hardcoded "PST:" label. Companies and customers registered in Québec store their Québec Sales Tax (QST) number in the same field, so their invoices show "PST:" in the header while the totals section, which uses the QST tax group, shows "QST". The document contradicts itself and does not match how the number is expected to appear on a Québec invoice. Québec registration numbers always carry the "TQ" marker (for example 1234567890 TQ0001), and no other provincial number does. The label is now derived from the number itself: "QST:" when it contains "TQ", "PST:" otherwise. This keeps the existing PST translation untouched and needs no extra configuration. Steps to reproduce: - Set the company's country to Canada and its PST number to 1234567890 TQ0001. - Print any customer invoice. - The header reads "PST: 1234567890 TQ0001" instead of "QST: ...". --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr