Tuesday, August 25, 2026
30 changes · saas-19.4
Enhancements to existing features
General Ledger reports can now include the invoice date when a report column is configured for it. This gives accounting teams more context directly in ledger exports and reviews, reducing the need to cross-check invoice records separately.
Original PR description
If a column is added with `expression_label` equal to `invoice_date`, include that in results of `_report_custom_engine_general_ledger`. task-5917897 Forward-Port-Of: odoo/enterprise#128938 Forward-Port-Of: odoo/enterprise#113774
Resolved issues and error corrections
This fix improves how product names and descriptions appear on accounting lines. Descriptions now stay italic even when text wraps in narrow columns, preventing product names from being styled incorrectly and making entries easier to read.
Original PR description
This commit removes the CSS hack used to make the description italic when a product is present in an AML. Instead, the product name and description are rendered separately using two spans in the readonly state. The previous `:first-line` approach did not handle line wrapping correctly: when the column was too narrow, part of the product name could wrap onto the next line and incorrectly appear italic. Rendering the two parts separately avoids this issue. Before | After -- | -- <img width="414" height="192" alt="image" src="https://github.com/user-attachments/assets/a178a35c-6d55-4982-a9c3-2fe727c626cc" /> | <img width="399" height="198" alt="image" src="https://github.com/user-attachments/assets/4716f93a-6d47-4631-a982-db43d9d38ef0" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where employee searches could fail or return incorrect results for users without access to private employee details. It helps keep HR searches reliable while maintaining the intended access restrictions.
Original PR description
The hack to search fields as a user that has no access to private employee data and searching on the `current_version_id` instead of the provided field since we force to wrap searchable fields domains in a Query in odoo/odoo#280373. The hack did not support usage of the 'any!' operator on `current_version_id` leading to a query like: "hr_employee.id in (select id from hr_version ...)". task-6468820 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284271 Forward-Port-Of: odoo/odoo#283811
This fix prevents an error when opening the sales product configurator in debug mode for products with optional custom attribute values. Empty custom values are now handled correctly, so users and testers can configure these products without encountering a crash.
Original PR description
This commit prevents a traceback when opening the product configurator in debug mode. Prop validation only happens in debug mode, which exposed an issue with products that allow entering custom attribute values (e.g. Acoustic Bloc Screen). When a custom value is left empty, it is read as `false` when custom attributes are retrieved from the frontend. As a result, the `custom_value` key in the `customPtavs` prop passed to the product configurator contains a boolean, whereas the prop expects a string. This commit ensures that an empty string is passed instead of `false` when opening the configurator for a line with an empty custom attribute value. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Edited chatter messages now keep contact mentions linked correctly when contact names or IDs overlap. This prevents mentions from breaking or pointing to the wrong contact, improving reliability in everyday communication.
Original PR description
# Introduction This PR fixes broken mention links linked to the fact that we replace strings without paying attention to the fact that some strings may contain others that we want to replace later.…
# Introduction
This PR fixes broken mention links linked to the fact that we replace strings
without paying attention to the fact that some strings may contain others
that we want to replace later. This affects both id's and names of records.
See commit messages for more details.
# How to reproduce
- Create Contact A and then Contact B and either :
- Contact B's id need to contain Contact A's id (e.g. Contact B id = 12; Contact A id = 1)
- Contact B's name need to contain Contact A's name (e.g. Contact B name = ABC; Contact A name = AB)
- In a chatter create a message mentionning first Contact B and then Contact A
> Depending on the version, you might need to reload the page here
- Edit the message and save
# The issue
We see a broken mention in the chatter
# Cause
When saving an edited message, we give the raw body of the message (without the mention links) and the mentionend partners to `generateMentionsLinks` : https://github.com/odoo/odoo/blob/f9f605b1783d252d5e005bec50a2a72dd4ae0e13/addons/mail/static/src/utils/common/format.js#L152
This method's purpose is to replace the text links ("@Contact A") with actual html links. It does so by enumerating each partner given as an argument and replace the text mention with a placeholder :
https://github.com/odoo/odoo/blob/f9f605b1783d252d5e005bec50a2a72dd4ae0e13/addons/mail/static/src/utils/common/format.js#L158
It will then replace the placeholders with actual links : https://github.com/odoo/odoo/blob/f9f605b1783d252d5e005bec50a2a72dd4ae0e13/addons/mail/static/src/utils/common/format.js#L208-L218
The issue is that in both of those steps, we can try to replace a string that is contained
in another string we want to replace.
For exemple :
"string123 some text string12"
If we try to replace "string12" first, then we will select the wrong string :
"[string12]3 some text string12".
opw-6313748
Forward-Port-Of: odoo/odoo#283817
Forward-Port-Of: odoo/odoo#272549This change updates website shop testing so inactive products are excluded during test runs. It helps prevent false test failures without changing what customers can see in the online store.
Original PR description
Description of the issue/feature this PR addresses: Addresses an issue causing test failures by ensuring that [inactive products](https://github.com/odoo-dev/odoo/blob/dbc917ddc263a330ff70f5edec716ccafe88d7a6/addons/website_sale/tests/test_product_filters.py#L93-L99) are filtered out rather than leaking from the environment into the test execution. I have verified that this issue does not allow [inactive records to leak to customers](https://www.odoo.com/mail/message/1151343506). runbot-242426 Forward-Port-Of: odoo/odoo#283973
This update fixes automated tests for restaurant appointments in Point of Sale after a storage-clearing behavior changed during data reloads. It keeps production behavior unchanged while ensuring test runs can complete reliably without losing their saved test state.
Original PR description
A recent PR in the community repository introduced a full clear of both `localStorage` and `sessionStorage` when reloading POS data. While this is the intended behavior in production, it breaks the test framework. This commit mocks the `clear` methods directly within the tour steps right before the reload action. This ensures the test survives the page reload and keeps its state, without polluting the core production code with test-specific logic. task-6456447 Forward-Port-Of: odoo/enterprise#128692 Forward-Port-Of: odoo/enterprise#128091
Archiving or deleting one user no longer removes their shared contact from restricted chat channels if another active user for that contact still qualifies. This prevents people from unexpectedly losing access to relevant discussions when accounts are cleaned up.
Original PR description
Before this commit, archiving or deleting a user removed its partner from every group restricted channel, even when another user of that partner was still active and in the group the channel requires. This happens because the members to unsubscribe are searched on partner_id alone, so the search cannot tell whether the partner keeps another user. This commit fixes the issue by unsubscribing a partner only when none of its remaining users has the group the channel requires. Forward-Port-Of: odoo/odoo#283933 Forward-Port-Of: odoo/odoo#283807
Bullet points and lists in generated API documentation now use the proper styling. This makes documentation easier to read and reduces confusion for users consulting technical reference pages.
Original PR description
Bullet points and lists coming from the generated html by docutils were not properly styled. This commit fixes those cases. task-6484990
Fixes a website settings issue where clearing the cookie policy page could leave the cookie banner enabled without a linked policy page and hide the setting needed to restore it. The website now restores the default policy page when needed and prevents deleting a page that is still used as the cookie policy, helping keep cookie notices complete and manageable.
Original PR description
Steps to reproduce: - enable the cookies bar in the website settings and save - clear the "Cookie Policy Page" field and save The website was left without a cookie policy page while the cookies bar was still enabled. Since the settings view only displays the field when it has a value, it disappeared with no way to set it back, other than toggling the cookies bar off and on again. The default policy page was only restored when the `cookies_bar` flag itself changed, so a write clearing only `cookie_policy_id` slipped through. Restore the default page whenever the policy is emptied while the cookies bar remains enabled, so the field reappears with the default page after saving. task-6356766
The accounting dashboard now shows the full invoice or bill amount for documents marked "To Check" instead of only the unpaid balance. This makes the dashboard less misleading when documents have partial payments, because the whole document still needs review.
Original PR description
Currently, the "To Check" links on the dashboard display the residual amount of invoices and bills. Since the entire document needs to be checked regardless of partial payments, showing the remaining balance is misleading. This commit updates the `selects` list in `_get_to_check_payment_query` to use `amount_total` instead of `amount_residual`, ensuring the dashboard reflects the full value of the documents. Task-6478415 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284171
This fixes a problem that could cause user or record avatars to fail loading when an expected update date was missing. Business users should see more reliable avatar display in form and kanban views, with no workflow changes required.
Original PR description
Issue: The `Many2OneAvatarField` and `KanbanMany2OneAvatarField` templates were directly calling `value.write_date?.toMillis()`. Optional chaining does not handle the case where `write_date` is `false`, resulting in a `TypeError` because `toMillis()` is not available on a boolean value. Solution: Added a `uniqueId` getter in both `Many2OneAvatarField` and `KanbanMany2OneAvatarField` to safely handle a missing or false `write_date`. The getter calls `toMillis()` only when `write_date` is available and returns `undefined` otherwise. Both templates now use `uniqueId` for the avatar URL. opw-6464172 Forward-Port-Of: odoo/odoo#282659
This fix removes website editing options that were not useful on link tracking pages, including SEO optimization and related page menus. It helps prevent users from spending time configuring pages that do not contain meaningful visitor-facing content.
Original PR description
Since [this commit][1] you're able to optimize the link tracker page using "optimize seo." This makes no sense as it contains no useful content for visitors to the website. Access to the action is now disabled when the current page is the link tracking page. The page properties and link tracker menu items have also been removed for similar reasons. [1]: https://github.com/odoo/odoo/commit/ac55f2bb113ecf7c774fe6e96d28e716184a97d1 Task-6288891 Forward-Port-Of: odoo/odoo#283954 Forward-Port-Of: odoo/odoo#278132
Clicking a followable field in the HTML editor now selects its display name by default instead of its technical ID. This makes dynamic placeholders more understandable for users while still allowing the ID to be selected when needed.
Original PR description
*: project Before this commit: when clicking a field having sub fields (canFollowRelationFor is true), we just return this field's id, which is not very useful in most cases. After this commit: We created subclass of DynamicPlaceholderPopover, EditorDynamicPlaceholderPopover, which uses EditorModelFieldSelectorPopover. We use the display name of the followable field by default and if the user really want the id, they may choose the id subfield. We also show the followable field's name as the default placeholder instead of "Display name". task-6265223 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283748 Forward-Port-Of: odoo/odoo#272129
Fixed a warning in the Indian localization so the related “View Journal Item(s)” link appears as intended. This helps users quickly open the relevant journal entries directly from the lower TCS tax warning.
Original PR description
The `lower_tcs_tax` warning was using the "actions" key instead of "action". As a result, the warning message was displayed correctly, but the "View Journal Item(s)" action link was not shown. Forward-Port-Of: odoo/odoo#284095
This fixes mailing recipient filtering so temporary wizard screens are no longer treated as valid mailing-enabled models. It helps prevent irrelevant internal setup records from appearing in mass mailing options, keeping campaign setup cleaner and less error-prone.
Original PR description
The search function ` _search_is_mailing_enabled` mistakenly used `model.is_transient()` (where the model is the `ir.model` record itself) to filter the transient models, which always returns `False` since `ir.model` is a regular persistent model. As a result, transient models (wizards) were never filtered out. This commit fixes it by using`self.env[model.model].is_transient()` to call `is_transient` on the actual model. Task-6458883 Forward-Port-Of: odoo/odoo#283781 Forward-Port-Of: odoo/odoo#282783
This fixes a setup problem that could occur when Australian localization was installed without the related Australian reports module. The change keeps specialized report logic with the module that provides it, preventing failures in uncommon installation combinations.
Original PR description
We had a case where l10n_au and account_reports were installed together, but not l10n_au_reports (manually uninstalled ?). Since the custom engine was used on expressions in l10n_au, this failed. Custom engines should always be used and declared within the same module (or a submodule of the one defining the handler) to avoid such issues. opw-6451274 Forward-Port-Of: odoo/odoo#282790
This fix stops Accounting payment terms from crashing when a user enters a zero or negative day value for an end-of-month due date. Users now receive the intended validation message when saving, improving reliability and preventing confusing error screens.
Original PR description
Steps to reproduce: - Install `Accounting` module - Payment Terms > Create NEW - Add a new Due Term line with "Days end of month on the" and a negative amount of days(eg: -1) Traceback: `ValueError: day is out of range for month` When `days_next_month` is set to a negative value, it is passed directly to `relativedelta` as the 'day' value. Since a negative value is not a valid day of the month, the due-date computation raises a `ValueError`. Use the end of the month for the calculation when `days_next_month` is non-positive. This prevents the traceback while computing the payment term and allows the proper validation error to be raised when the record is saved. opw-6453640 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283865 Forward-Port-Of: odoo/odoo#281904
Website editors can now directly edit previously locked sections of mega menu templates, such as footers and logo areas. This makes menu customization smoother and reduces the need for workarounds when building website navigation.
Original PR description
### Issue: Some elements in mega menu templates are not editable inline in the website builder. ### Steps to reproduce: - Go to Website > Site > Menu Editor and add a mega menu item. - Edit the mega menu and set its template (e.g. 'Thumbnails' or 'Logos'). - Try to inline edit certain sections (e.g. footer or logos container). ### Reason: `BuilderContentEditablePlugin` does not apply `contenteditable="true"` to these elements because they do not match any of the selectors defined in `content_editable_selectors`. ### Fix: Add missing element classes to `content_editable_selectors` so that these elements become editable inline. task-[6116253](https://www.odoo.com/odoo/project/974/tasks/6116253) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283975 Forward-Port-Of: odoo/odoo#263021
The Attendance location warning dialog now closes properly when employees choose Discard. This prevents users from getting stuck on the check-in or check-out confirmation popup when browser location access is blocked.
Original PR description
Steps to reproduce: -------------------------------------------- 1. Install Attendance module. 2. Enable `Device & Location Tracking` & `Attendance from Backend` in settings. 3. Block location access…
Steps to reproduce: -------------------------------------------- 1. Install Attendance module. 2. Enable `Device & Location Tracking` & `Attendance from Backend` in settings. 3. Block location access from the browser for this site (Site settings) 4. Try to checkIn/checkOut from the Dot in the systray 5. We'll have one confirmation pop-up asking to Proceed Anyway OR Discard Observation: -------------------------------------------- On clicking the discard button, Nothing happens. Issue: -------------------------------------------- In `confirmChecking()`, the `cancel` callback was defined as an arrow function using an expression body. In JavaScript, an assignment expression returns the assigned value. Since `this._attendanceInProgress` is set to `false`, the callback implicitly returns `false`. `ConfirmationDialog.execButton()` treats a `false` return value as a signal to keep the dialog open (used intentionally to block closing on validation failure) This caused the dialog to never call `this.props.close()`, leaving it permanently open when Discard was clicked. https://github.com/odoo/odoo/blob/5e84fdd99e34836a15cadc4fdf4b6bc449727e58/addons/web/static/src/core/confirmation_dialog/confirmation_dialog.js#L75-L89 Solution: -------------------------------------------- Change the `cancel` callback from an expression body to a block body, A block body arrow function returns `undefined` by default. This ensures `execButton` does not interpret the return value as a 'keep dialog open' signal, and correctly calls `this.props.close()` to dismiss the dialog. opw-6462439 Forward-Port-Of: odoo/odoo#281702
The Sign module now keeps existing rules that hide the "Mark Done" button in the activity scheduling wizard while adding its own condition. This prevents the button from appearing at the wrong time and avoids conflicts with other modules such as Calendar.
Original PR description
Previously, the sign module was completely overwriting the `invisible` attribute on the "Mark Done" (`action_schedule_activities_done`) button in the activity schedule wizard. This inadvertently discarded base conditions (such as hiding the button when `has_error` is true) and caused conflicts with other modules (like `calendar`) that also need to modify this button's visibility. This commit updates the view inheritance to safely append the sign condition using `add` and `separator="or"`, preserving all existing visibility rules. Task-6499751
This update keeps PDF document navigation working with newer and older versions of the PDF library used by Accountant Knowledge. It helps prevent errors when processing PDF outlines, links, and bookmarks after library updates.
Original PR description
On latest versions of PyPDF, the `outlines` attribute was renamed to `outline`, we now handle both attributes to provide compatibility with both versions. A similar issue arises with the `addLink` method, which was renamed to `add_link`, and later replaced by `add_annotation`. Another similar issue arises with the `add_bookmark` method, which was replaced by `add_outline_item`. task-6474715 version-19.4
Fixed an issue in Odoo Sign where declining a signature request with a reason could trigger an error instead of completing smoothly. The decline dialog now closes before the confirmation message appears, preventing duplicate processing and improving the signing experience.
Original PR description
Version: 19.4 Steps to reproduce: - Create a sign request with a signature and send it to a user - Decline the document as administrator with a reason Issue: Opening the thank you dialog before closing the decline dialog caused both actions to be processed together. This made the thank you dialog get built twice and both attempts were already destroyed before orm.call, raising a traceback. Fix: Close the decline signature dialog first, then open the thank you dialog. Task id - 6471923
This fix keeps Australian report calculation rules together with the reporting component that supports them. It prevents errors when Australian localization and accounting reports are installed without the dedicated Australian reports module, improving stability for affected setups.
Original PR description
We had a case where l10n_au and account_reports were installed together, but not l10n_au_reports (manually uninstalled ?). Since the custom engine was used on expressions in l10n_au, this failed. Custom engines should always be used and declared within the same module (or a submodule of the one defining the handler) to avoid such issues. opw-6451274 Forward-Port-Of: odoo/enterprise#128132
This fix prevents a rare crash in the Hungarian Intrastat reporting module when company data is checked in unusual access-right situations. It is mainly a safeguard for future changes or customizations, as the issue is not expected through the standard user interface.
Original PR description
Due to some trouble with tests, we found that in some cases, this function is called on the root company, and if the user does not have the access rights to read data from the company (users with system rights have them by default), it will cause a crash. This situation is not possible with the standard UI, but we fix it in case it becomes possible in a future version or customization. Forward-Port-Of: odoo/enterprise#128218
This update prevents a rare crash when Belgian Intrastat reporting is accessed in unusual company permission scenarios. It makes the process more reliable for future customizations or edge cases, without changing normal user workflows.
Original PR description
Due to some trouble with tests, we found that in some cases, this function is called on the root company, and if the user does not have the access rights to read data from the company (users with system rights have them by default), it will cause a crash. This situation is not possible with the standard UI, but we fix it in case it becomes possible in a future version or customization. Forward-Port-Of: odoo/enterprise#128212
Tax returns can now be submitted without being blocked by incomplete settings on tax groups that have no related transactions. This prevents unnecessary interruptions during tax closing while still checking the configuration that is actually used.
Original PR description
…ax closing Steps to reproduce: - Remove the tax payable and receivable accounts of a tax group for which no move exists. - Open the tax returns view, set the opening date and submit the tax return -> Odoo prevents going further because the tax group configuration isn't fully done, but it's useless to ensure that for tax groups that aren't used. Forward-Port-Of: odoo/enterprise#128197
The AI website livechat snippet now has a preview image again in the website builder. This prevents the uninstalled livechat option from appearing broken, making the page-building experience clearer for users.
Original PR description
Problem: 1) The preview image of the livechat snippet was removed in this [commit][1] and wasn't replaced with another image. As a result, the uninstalled livechat snippet doesn't display properly in the website builder. Solutions: 1) An image has been added `ai_livechat.png` which is shown on preview Note: This fix will change in master to be up to date with current website snippet previews. The location will be moved to `snippet_previews` and the file type will be changed to `.webp` [1]: https://github.com/odoo/enterprise/commit/df05441e469157890253b5550b5f8735723b28fb Task-5248712 Forward-Port-Of: odoo/enterprise#126361
This change updates internal subscription tests so they stay aligned with recent related platform changes. It helps maintain release quality by ensuring subscription flows continue to be validated correctly, with no expected change for end users.
Original PR description
See also: - https://github.com/odoo/odoo/pull/280403 Forward-Port-Of: odoo/enterprise#128610 Forward-Port-Of: odoo/enterprise#127041
This update makes an automated checkout certification test wait for the product screen before continuing. It reduces random test failures in build validation without changing the day-to-day user experience.
Original PR description
we face this error when running tour `FiskalyTour` with linked pr (which is completely independent of this module) and should not fail, but this can be considered as non-deterministic. waiting/confirming that product-screen is shown, before making the next move, solves the issue. build link: https://runbot.odoo.com/runbot/batch/2696526/build/121430872?debug=1 Forward-Port-Of: odoo/enterprise#128733 Forward-Port-Of: odoo/enterprise#127902