Wednesday, June 17, 2026
11 changes · saas-18.4
Resolved issues and error corrections
Users can now save website job pages after deleting all content from an editable HTML field. The change prevents empty or whitespace-only content from causing a validation error, so editing workflows are not blocked.
Original PR description
Steps to reproduce: =================== 1. Edit a job page. 2. Delete every `s_rating` block. 3. Save. => Validation Error: Document is empty. Cause: ====== Deleting the last snippet inside an…
Steps to reproduce: =================== 1. Edit a job page. 2. Delete every `s_rating` block. 3. Save. => Validation Error: Document is empty. Cause: ====== Deleting the last snippet inside an editable HTML field (e.g. the last `s_rating` block in the `website_rating` field of a job page) leaves the field's editable container with only whitespace text nodes. On save, it writes that whitespace to the record and then calls `_copy_custom_snippet_translations`, which does `html.fromstring(lang_value)` on the whitespace and raises `lxml.etree.ParserError: Document is empty`, re-raised as `ValidationError`. The user sees a "Validation Error" dialog and can't finish saving. The previous fix for the analogous "Document is empty" symptom on product description editing (commit [1]) added a `cleanupEmptyStructures` `on_removed_handlers` that strips whitespace from `.oe_empty` containers after element removal. That selector covers `oe_structure.oe_empty` containers but not editable HTML field savables (`[data-oe-type="html"]`), which don't carry an `oe_empty` class when they originally had content. As a result, fields like `hr.job.website_rating` still hit the failing parse path. Solution: ========= Extend the cleanup selector to also include `[data-oe-type="html"]` so HTML-field editables are normalized to genuinely empty after the last inner snippet is removed. [1]: https://github.com/odoo/odoo/commit/53d5cc7eed635f64038bf0315f6863011879c529 opw-6244892 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267397
The Uruguay accounting localization now uses the correct formula for the VAT balance in the tax report. This ensures businesses see the right VAT amount when reviewing tax reporting figures.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting and l10n_uy 2. Go to tax report and see the formula of the VAT balance that is incorrect ### Reason to introduce the fix: Correct the formula to display the right amount. opw-6261211 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269376 Forward-Port-Of: odoo/odoo#268478
Restaurant point-of-sale order edit history now shows the employee who actually made a change, even when staff switch users during a session. This improves audit accuracy without changing the employee assigned to the order before payment.
Original PR description
**Steps to reproduce:** - Enable "Track orders edits" in the settings - Enable "Log in with Employees" - Go to the Restaurant, log in with employee A - Go to a table, order 3 Sushis - Go back to the…
**Steps to reproduce:** - Enable "Track orders edits" in the settings - Enable "Log in with Employees" - Go to the Restaurant, log in with employee A - Go to a table, order 3 Sushis - Go back to the floor plan and change to employee B - Go back to the table and change the qty of 3 Sushis to 2 Sushis - Go to the order in the backend and check the chatter - It will indicate that employee A did the change, but it was employee B **Why the fix:** We always used the cashier set on the order to determine who should be put in the chatter, regardless of who is actually connected at that point. We now use the session's current employee to write who did the change in the chatter. We do not change the order's employee, because it will be done once the order has been paid. In the case where we are not logged in but pos_hr is installed, the employee_id might be the id of a res.user, and browsing it might return the wrong value. To avoid this, we check if the value exists as a hr.employee before assigning the name. The way we return the value has been changed because the linter wasn't happy about it. opw-6213504 Forward-Port-Of: odoo/odoo#265582
This fix ensures the recruitment module only creates special search indexes when the database is correctly configured to support them. It prevents installation or upgrade failures in databases where accent-insensitive search is available but not suitable for indexing.
Original PR description
PostgreSQL's `unaccent` function must be marked as `IMMUTABLE` before it can be used in a functional index. The ORM usually handles this when the `unaccent` extension is missing and `odoo-bin` is…
PostgreSQL's `unaccent` function must be marked as `IMMUTABLE` before it can be used in a functional index.
The ORM usually handles this when the `unaccent` extension is missing and `odoo-bin` is started with the `--unaccent` flag during database creation.
However, it is also possible to start `odoo-bin` with an existing database where the `unaccent` extension is already installed, but the function was never marked as `IMMUTABLE`.
In that case, `unaccent` can still be used in conditions such as `WHERE` clauses, but it cannot be used in functional indexes.
`has_unaccent()` actually has three possible states:
```py
class FunctionStatus(IntEnum):
MISSING = 0 # function is not present (falsy)
PRESENT = 1 # function is present but not indexable (not immutable)
INDEXABLE = 2 # function is present and indexable (immutable)
```
Therefore, checking only `if has_unaccent()` before creating an index using `unaccent` is not enough. The index should only be created when `has_unaccent()` returns `FunctionStatus.INDEXABLE`.
task-6307060
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#270278This fix stops users from saving email domains with capital letters, which could prevent incoming email replies from being routed correctly. It helps ensure email aliases keep working reliably without changing the underlying routing process.
Original PR description
[FIX] mail_alias_domain: prevent capitalization in domain names to avoid email routing issues Currently, we allow capitalization in the name / display_name field for Email Domains…
[FIX] mail_alias_domain: prevent capitalization in domain names to avoid email routing issues
Currently, we allow capitalization in the name / display_name field for Email Domains (mail.alias.domain), which allows for capitalized domains in email aliases. When the system receives incoming emails via mail_thread.py's message_route,
the reply_to email addresses are sanitized (all lowercase). We then use the case-sensitive 'in' to identify
message routes, which will always fail for capitalized email domains.
This PR applies sanitizing to the name field so that users cannot save capitalized email domains.
Other options are not viable because:
1. we don't have a case-insensitive equivalent of the 'in' operator
2. altering the current logic to be case-insensitive would decrease performance
3. altering the current logic would change the structure of message_route
Fixes #opw-5401633
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#257792The web client now avoids reusing saved page actions when they depend on context that is no longer available. This prevents errors when users move back and forward in the browser after opening records such as project tasks from notifications.
Original PR description
Steps to reproduce: - Open any project task - Click a project notification that opens another task (requires the corresponding notification preference to be enabled) - Use the browser's Back and Forward buttons => Traceback: active_id is undefined When navigating to a form view via a URL (e.g. `/odoo/m-<model>/<id>`), the action service looks up the last action from session storage and reuses it if the model matches. This behavior, introduced in a4b179a7118916aac032ad252c0e421d452e553c, does not discriminate between dynamic and non-dynamic actions. Non-dynamic actions (those with an id) may rely on context values such as active_id that are only valid in their original execution context. Restoring such an action during browser history navigation causes a traceback because active_id is undefined. Fix by only reusing the session-stored action when it is a dynamic action (no id). Forward-Port-Of: odoo/odoo#270076
This update fixes a scheduling issue with semi-monthly payrolls. Previously, payslips started on the 15th, coinciding with the end of the first half of the month. Now, payslips begin on the 16th, ensuring accurate payroll calculations for employees on a second-half monthly schedule.
Original PR description
Issue: ---------------------------------------- The start date of semi-monthly payslips on second half of the month is the 15 which is also the end date of the first half of the month. Steps to reproduce: ---------------------------------------- - Have an employee with a semi-monthly payroll - When in the first half of the month, create a payslip for this employee - The payslip is from 1st to 15th - Do the same when in the second half of the month - The payslip is from 15th to end of the month Cause: ---------------------------------------- In `_schedule_period_start()` we set the start date to th 15th for semi-monthly payslips. Solution: ---------------------------------------- Set it to the 16th. opw-6281556
This update resolves an issue where the Odoo Report Editor would crash when deleting the last column from a table. The fix prevents a technical error caused by a null value, ensuring the editor remains stable and reliable for users creating reports.
Original PR description
Problem: When deleting the last column in a table in studio we get a traceback. Cause: `firstCell` will be null if we delete the last cell in the table. Fix: Added a null check on `firstCell` before calling `setCursorEnd`, so the cursor is only repositioned when the table still has remaining cells. Steps to reproduce: - Edit a report with a table. - Remove all columns. - Traceback will occur when deleting the last one. opw-6263696 Forward-Port-Of: odoo/enterprise#119502
This update ensures that Philippine sales reports exported to XLSX files consistently maintain the correct order of partner VAT values and row sequence. Previously, the order was unpredictable, leading to potential discrepancies in exported data. This fix guarantees data integrity for reporting and reconciliation purposes.
Original PR description
Description of the issue this commit addresses: SLSP XLSX partner rows were emitted in a non-deterministic order, which made the PH sales/purchases export tests sometimes swap partner VAT values. --- Desired behavior after this commit is merged: This commit keeps the SLSP partner rows in a stable order so the XLSX export always matches the expected partner VAT and row sequence. --- runbot-[162182](https://runbot.odoo.com/odoo/error/162182) Forward-Port-Of: odoo/enterprise#120052
This update removes an unnecessary 'external' tag from a key delivery module, preventing errors from being caught only during nightly testing. This change improves the reliability of our Continuous Integration (CI) process by ensuring all tests are executed. A minor adjustment was also made to a test case to accurately reflect package weight calculations.
Original PR description
Test class was tagged as external although calls are mocked. This means errors were only caught in nightly and not by CI. Removing the tag requires fixing some of the tests. For `test_multicollo`, we send the average weight of packages instead of the total since 97f82442c9fee7dcb3e8c5e9bacddcd6bb864e11. Forward-Port-Of: odoo/enterprise#114660 Forward-Port-Of: odoo/enterprise#111660
This update adds a new test to verify the handling of fully settled customer invoices within the POS system. The previous fix related to tracking 'move' statuses has been incorporated into this test, ensuring continued accuracy in settlement calculations. This change improves the reliability of the POS settlement process.
Original PR description
Just keeping the test in this FW. The original issue was fixed in https://github.com/odoo/enterprise/pull/119084 opw-6173760 Forward-Port-Of: odoo/enterprise#116536