Thursday, June 11, 2026
25 changes · saas-19.2
Resolved issues and error corrections
This update ensures Odoo's financial reports (GSTR-3B and GSTR-2B) accurately reflect new requirements for purchase composition supplies as mandated by Indian tax regulations. The changes align the report formats with government guidelines, improving data accuracy and compliance.
Original PR description
As a new GSTR section for purchase composition supplies has been introduced, the related report domains also need to be updated accordingly. With this commit: GSTR-3B domains are updated to properly include purchase_composition_supplies transactions in the relevant report section. GSTR-2B now includes a separate line for composition supplies, aligned with the government utility format. task-6239870 Forward-Port-Of: odoo/enterprise#118312
This update corrects a bug in the journal report where multi-country tax grids displayed incorrectly, causing countries to disappear when more than two were selected. The fix ensures accurate column spanning and proper display of all selected countries, improving the accuracy of financial reporting.
Original PR description
When more than 2 country are used in the taxes, the colspan of the header is wrong. When more than 2 country are used in tax grids, the country isn't displayed anymore. Forward-Port-Of: odoo/enterprise#120032 Forward-Port-Of: odoo/enterprise#119348
This update fixes an issue where automation rules couldn't correctly assign users to newly created activities when using complex user field paths. The change allows for dynamic user assignment, ensuring activities are properly linked to the intended users within your contacts. This enhancement improves the reliability of automation workflows.
Original PR description
Steps to reproduce: ------------------------------------ 1. Install `ai` and `contacts` modules 2. Create an automation rule on Contact model: * Trigger: On Creation * Action To Do: Execute AI Action…
Steps to reproduce:
------------------------------------
1. Install `ai` and `contacts` modules
2. Create an automation rule on Contact model:
* Trigger: On Creation
* Action To Do: Execute AI Action
* Add a server action tool with 'Create Next Activity' action
* Set Activity User Type to Dynamic
* Set User Field to a dotted path (e.g., user_ids or partner_id.user_id)
3. Create a contact with a linked user
Observation:
------------------------------------
The activity description in the toast message fails to retrieve the user when using dotted field paths
Issue:
------------------------------------
The direct field access `record[self.activity_user_field_name]` in `_ai_get_action_description` method doesn't support dotted paths like 'partner_id.user_id'. This causes the same issue as in the mail module where relational field chains cannot be traversed
Solution:
------------------------------------
Use `record.mapped()` to support dotted paths by traversing the relational chain, consistent with the fix applied to the mail module
opw-6191715
Related Community PR: https://github.com/odoo/odoo/pull/263530
Forward-Port-Of: odoo/enterprise#118921This update fixes an issue where planned dates were lost when converting projects to project templates. The fix ensures that the original planned dates are correctly copied to the new template, improving project tracking accuracy. This change impacts how project templates are created and managed.
Original PR description
****Steps** to reproduce:** - Open a project with a planned date set. - Create Template of that project. - Observe the created project template. **Issue:** The planned dates of the project are lost when converting the project into a template. **Cause:** When we create a project template from a project, the project gets archived. Because a new project template record is created, and the start and expiration fields have copy=False, those dates are not being copied. **Fix:** Explicitly pass the planned date when copying the project, so the project template keeps the original planned date. task-5872500 Forward-Port-Of: odoo/odoo#269257 Forward-Port-Of: odoo/odoo#249411
This update resolves a technical issue that prevented users from correctly accessing certain fields on payslips within the Odoo system. The problem stemmed from an error in how the system retrieves data for these fields, specifically when closing or discarding a payslip. This fix ensures data integrity and prevents errors for users managing payslips.
Original PR description
Steps to reproduce the bug: - open an employee in a belgian company - open End of collaboration in the cog menu - go to the holiday attest tab - click the payslips link - open a payslip then close it or press discard - open the same payslip then close or discard it again - you get a traceback "Cannot read properties of undefined (reading 'relatedPropertyField')" in `_computeDataContext` which happens for some property fields (e.g. seprator) because the `fieldName` is in data but `this.fields[fieldName]` is undefined task-id: 6265648 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update clarifies the status shown when signing documents on behalf of another user. Previously, the display always included the sender's name. Now, it accurately shows 'via [user]' when signing through another user's link, and only the date is displayed when signing directly.
Original PR description
Before this commit, the signer status always displayed "On <date> via <sender>". Now the message only mentions "via <user>" when the document was actually signed by a different user (for example, when an admin is logged in and signs through a signer's link). When the signer uses their own link, only the date is shown. task-6216243
A recent update to Odoo caused an error when generating PDF invoices using the ‘Get ETA Invoice PDF’ button. This fix resolves a technical issue related to how Odoo processes data from external requests, ensuring the button continues to function correctly. This prevents potential disruptions to invoice generation.
Original PR description
Using the “Get ETA Invoice PDF” button located on the form view of invoices can result in a stacktrace error. Since installing requests==2.25.1 with python 3.10, and using: requests.exceptions.JSONDecodeError Will raise the following error: AttributeError: module 'requests.exceptions' has no attribute 'JSONDecodeError' This change fixes the error by using 'JSONDecodeError' from the 'json' package. Related: https://github.com/odoo/odoo/commit/55bddda59b8f9479d515163852fa8cbc718ddbd3 [opw-6275476](https://www.odoo.com/odoo/project/49/tasks/6275476?debug=assets) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268920
This update resolves an issue where the website's main menu would unexpectedly close due to overlapping updates. By closing the extra menu before opening the main menu, the system now provides a more consistent and reliable user experience. This prevents frustrating errors and ensures smooth navigation.
Original PR description
[FIX] website: close the extra menu before opening site menu Update of the extra menu item is done multiple times (cfr `afterFontsloading`). If the extra menu item and the site menu were already open before an update of the extra menu item, the result is a close of the site menu. This can lead to undeterministic error. To solve the problem, the extra menu dropdown is closed before opening the site menu. runbot-240955 Forward-Port-Of: odoo/odoo#269177 Forward-Port-Of: odoo/odoo#266376
This update fixes an issue where purchase order subtotals were incorrectly calculated when some order lines had a quantity of zero. The fix ensures that subtotals are accurately displayed regardless of whether lines with zero quantity are filtered out, improving the accuracy of purchase order reports. This change was made to address a bug impacting order reporting.
Original PR description
Bug introduced in: https://github.com/odoo/odoo/commit/3ac515ab55dd6708e0df283c634e2b99fc4a5561 When order lines with qty=0 are filtered out, `line_index` refers to the filtered list but `order_line[line_index+1]` indexed into the full unfiltered recordset, causing section subtotals to fire at the wrong position with incorrect values. Solution: Pre-store the filtered recordset and use it for the next-element lookup opw-6174429 Forward-Port-Of: odoo/odoo#267924
This update resolves an issue causing excessive logging in Odoo, specifically when handling attachments created by external systems. By returning 'None' when attachment data is missing, the system avoids unnecessary error handling and log spam, improving stability for integrations like EDI connectors. This change primarily impacts third-party integrations.
Original PR description
Return None when datas is empty alongside the existing mimetype check. Avoids unnecessary exception handling leading to logspam for URL type attachments where binary data is unavailable. This issue is only reproducible programmaticaly as the mimetype is not available with url type attachment in Odoo. Thus, it's a problem that only impact third party integrations, EDI connectors or any workflow that creates ir.attachment records directly. opw-6010528 Forward-Port-Of: odoo/enterprise#114160 Forward-Port-Of: odoo/enterprise#113396
This update fixes an issue where invoices were incorrectly labeled as 'proforma' when printed. The print button for posted invoices has been made secondary to emphasize the 'Send' action, aligning with the standard invoicing workflow. This ensures invoices are consistently displayed and processed correctly.
Original PR description
Revert 3ef2c09 which incorrectly added a proforma label when printing posted invoices that had not yet been sent, proforma invoices have an entire feature in the sales app, so an invoice in invoicing should just be an invoice in all cases. --- The Print button on posted invoices was visually styled as a primary action. Make it secondary so the Send action keeps the main visual emphasis, while Print remains available with the same behavior. task-6269645 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269183 Forward-Port-Of: odoo/odoo#268552
This update prevents placeholder images from being sent during menu synchronization, ensuring that only actual product images are transmitted. This improves the efficiency of data transfer and reduces unnecessary data usage, leading to a smoother user experience. The change was driven by a bug affecting menu display.
Original PR description
This commit prevents placeholder images from being included in the menu sync payload and only sends `img_url` when an actual image is configured on the product or category. Task-6251430 Forward-Port-Of: odoo/enterprise#119883 Forward-Port-Of: odoo/enterprise#119482
This update fixes a warning related to how Odoo generates PDFs using the PyPDF library. The change ensures the PDF generation process is compatible with recent PyPDF library updates, preventing potential errors and maintaining stable PDF output. This ensures consistent PDF generation across Odoo versions.
Original PR description
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's…
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's architecture updates (specifically PR #3638 [^1] and PR #3669 [^2]), a reader's page is intended to be read-only. Mutating it directly (e.g., using `mergePage` or `compressContentStreams`) before attaching it to a writer can break internal object references and cause `NullObject` errors. This commit resolves the warning by inverting the order of operations to ensure we only mutate writable objects. The fix implements the following flow: 1. Add the unmodified source page directly to the `PdfFileWriter`. 2. Retrieve the newly created, writable output page. 3. Apply `mergePage` and `compressContentStreams` exclusively to the writer's copy of the page. [^1]: https://github.com/py-pdf/pypdf/pull/3638 [^2]: https://github.com/py-pdf/pypdf/pull/3669 Forward-Port-Of: odoo/odoo#268865 Forward-Port-Of: odoo/odoo#267958
This update fixes a warning related to how Odoo generates PDFs using the PyPDF library. The change ensures the PDF generation process is compatible with newer versions of PyPDF, preventing potential errors and maintaining stable PDF output. This improves the reliability of our PDF generation functionality.
Original PR description
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's…
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's architecture updates (specifically PR #3638 [^1] and PR #3669 [^2]), a reader's page is intended to be read-only. Mutating it directly (e.g., using `mergePage` or `compressContentStreams`) before attaching it to a writer can break internal object references and cause `NullObject` errors. This commit resolves the warning by inverting the order of operations to ensure we only mutate writable objects. The fix implements the following flow: 1. Add the unmodified source page directly to the `PdfFileWriter`. 2. Retrieve the newly created, writable output page. 3. Apply `mergePage` and `compressContentStreams` exclusively to the writer's copy of the page. [^1]: https://github.com/py-pdf/pypdf/pull/3638 [^2]: https://github.com/py-pdf/pypdf/pull/3669 Forward-Port-Of: odoo/enterprise#119694 Forward-Port-Of: odoo/enterprise#119239
This update resolves an issue where calendar events with multiple attendees displayed inconsistent 'Contact Details' information, showing a random attendee's contact info. The fix limits the 'Contact Details' block to events with only one non-organizer attendee, ensuring a consistent and predictable display for 1-on-1 meetings. This improves the user experience and data clarity within the calendar.
Original PR description
When a calendar event has multiple attendees, `_get_contact_details_description` picks the first non-organizer partner from a set-based recordset to render under "Contact Details" in the event…
When a calendar event has multiple attendees, `_get_contact_details_description` picks the first non-organizer partner from a set-based recordset to render under "Contact Details" in the event description. The recordset is built from `partner_ids_from_attendees`, a set whose iteration order depends on Python's hash seed, so the displayed contact is effectively random and not controllable from the UI. Restrict the "Contact Details" block in `_get_contact_details_description` to events with exactly one non-organizer attendee (1-on-1 meetings). For group meetings the block is omitted entirely, since any single attendee picked from a larger group is arbitrary by construction. Steps to reproduce: 1. Go to Calendar > New 2. Add 3+ attendees (e.g. Alice, Bob, Charlie) 3. Save the event 4. Check the Notes tab in the event form => One random attendee's contact info appears under "Contact Details" Ticket [link](https://www.odoo.com/odoo/project.task/6035192) opw-6035192 Forward-Port-Of: odoo/odoo#258901
This update simplifies how spreadsheet documents are handled within Odoo, preventing unnecessary version history creation. By disabling versioning for spreadsheets and frozen spreadsheets, we reduce storage usage and improve performance. This change ensures spreadsheets function efficiently without creating redundant data attachments.
Original PR description
This PR consists of two commits. The first commit hides the Manage Versions action button for spreadsheet and frozen spreadsheet documents, since versioning is disabled for those records. The second commit is a backport of enterprise commit 0e319d0. It disables document versioning for spreadsheet and frozen spreadsheet documents, as spreadsheets already manage their history through spreadsheet revisions. This avoids creating unnecessary document history attachments when spreadsheet data is written or when a spreadsheet is copied. Task: [6236496](https://www.odoo.com/odoo/project/2328/tasks/6236496) Forward-Port-Of: odoo/enterprise#119932 Forward-Port-Of: odoo/enterprise#118484
This update fixes an issue where users could inadvertently edit the cover image, title, and subtitle of a blog post from the 'Next Post' section. The change ensures that this section is fully non-editable, improving the user experience and preventing unintended content modifications. This resolves a potential inconsistency in how the builder handles interactive elements.
Original PR description
[*]: html_builder Issue: When viewing a blog post, the "Next Post" section allows editing the cover image, title, and subtitle of another post. Editing content that belongs to a different post from…
[*]: html_builder
Issue:
When viewing a blog post, the "Next Post" section allows editing the cover image, title, and subtitle of another post. Editing content that belongs to a different post from within the current one is incorrect.
Steps to reproduce:
* Open a blog post that has a "Next Post" section visible.
* Enter edit mode.
* Try to edit the cover image, title, or subtitle of the next post.
* These elements can be interacted with even though they should not be
editable.
Fix:
Make the "Next Post" section fully non-editable. The title and subtitle were already handled via content_not_editable_selectors, but the cover image could still activate builder options, allowing it to be replaced.
Introduce a new `not_activable_element_selectors` resource in the `BuilderOptionsPlugin` so that plugins can declare elements that should not trigger the builder overlay when clicked. Updated the builder to retrieve this selector list from plugin resources instead of using a hardcoded value.
task-5435878
Forward-Port-Of: odoo/odoo#265103
Forward-Port-Of: odoo/odoo#249815This update ensures the LNA button in the POS interface correctly tests functionality for IoT Boxes. Previously, the button wasn't properly sending status updates. Now, the system sends the necessary status action when LNA is enabled on IoT Boxes, improving the reliability of the POS system.
Original PR description
The LNA button in the POS navbar wasn't testing LNA for IoT Boxes. We now send a status action for IoT Boxes with LNA enabled.
This update fixes a discrepancy in how product prices are displayed. Previously, changing the price on a product without variants only updated the variant form, not the main product template. Now, the template price will automatically update when the variant price is changed, ensuring consistent pricing across all product views.
Original PR description
Issue: When the sales price is changed from the product variant form for a product without configured variants, the price is updated only on `product.product.lst_price`. The main product form, opened…
Issue: When the sales price is changed from the product variant form for a product without configured variants, the price is updated only on `product.product.lst_price`. The main product form, opened from Inventory > Products, displays `product.template.list_price`, which remains unchanged. The same issue is visible from Purchase Orders because the product internal link on a purchase order line opens `product.product`, while the product page opens `product.template`. Steps to reproduce: - Create or open a product without configured variants - Open product variant form from the internal link in a purchase order - Change the Sales Price on the product from there - Open the product from Inventory > Products (`product.template`) - The template Sales Price still shows the old value Cause: Since version 19.1, `product.product.lst_price` is an editable stored field, allowing variant-level prices to differ from the template price. This is correct for products with multiple variants, where each variant may have its own sales price. However, for products with only one variant (the product itself), no synchronization was performed from `product.product.lst_price` back to `product.template.list_price`, leaving both product forms inconsistent. Solution: - Add `_inverse_product_lst_price` on `product.product.lst_price` so that When `lst_price` is written and the template has exactly one variant, set `list_price` to `lst_price` (delegates to the template) opw-6260015 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268017
This update ensures that employee avatars are consistently shown in the timesheet kanban view, even for users without HR access rights. Previously, a placeholder image was displayed. The fix addresses a permissions issue, retrieving avatars from a public model when direct access isn't granted.
Original PR description
Steps to reproduce:
- Install the hr_timesheet module
- Create a user without HR access rights
- Create a timesheet
- Log in with the above user
- Open the kanban view
Issue:
Instead of showing the employee's avatar, a placeholder image
is displayed.
Reason:
The user does not have access to the hr.employee model.
Fix:
In this commit, if the user does not have access to hr.employee,
we fetch the image from the hr.employee.public model.
Task: 4461272
X-original-commit: b3018b1ab4bcdfebd8bb83bad38209b96646da3c
Description of the issue/feature this PR addresses:
Current behavior before PR:
Desired behavior after PR is merged:
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#269262This update fixes an issue where purchase transactions were incorrectly identified as intra-state, leading to inaccurate reporting. The change separates sales and purchase transactions during computation, ensuring the correct transaction type is assigned for all transactions, including inter-state vendor bills. A migration update has also been applied to existing databases.
Original PR description
Previously, for purchase journals, `l10n_in_state_id` was always computed using the current company `state_id`. However, in `_compute_l10n_in_transaction_type`, the `l10n_in_state_id` was compared with the company `state_id` for both sales and purchases. As a result, all purchase transactions were always computed as intra-state, including inter-state vendor bills. This commit handles sales and purchase transactions separately while computing `l10n_in_transaction_type` to ensure the correct transaction type is assigned. Migration also added to update it in existing dbs. Forward-Port-Of: odoo/enterprise#118297
This update fixes a problem where tax reports for Moroccan companies were incorrectly including entries with zero balances. The fix filters out these unnecessary entries, ensuring the reports accurately reflect financial data. This improves the reliability and clarity of tax reporting.
Original PR description
When generating the tax report for a Moroccan company, entries with a zero balance were appearing in the report. Steps to reproduce: ------------------- * Create a Moroccan company * Create a bill with a tax to pay * Change the bill date and accounting date to a past date * Make a first payment of the bill, with a date to today * Unreconcile the payment, and make a second payment with a date in the past (the same one as the bill date for example) * Now generate the tax report for the period of today > Observation: The report contains useless entries with a zero balance. Why the fix: ------------ We add `HAVING SUM(account_move_line.balance) != 0` to filter out the line that have a zero balance. opw-5911669 Forward-Port-Of: odoo/enterprise#113956
This update resolves an issue where the website rental planning module would crash when the quantity input field was removed from the product page. The change was due to a shift in how the system handles data evaluation, and this fix ensures the system gracefully handles the absence of the quantity field, preventing errors and maintaining functionality.
Original PR description
Steps to reproduce: 1. Install website_sale_renting_planning 2. In rental module, create a product that is of type service and can be sold 3. Go to the website and remove the quantity selector input…
Steps to reproduce: 1. Install website_sale_renting_planning 2. In rental module, create a product that is of type service and can be sold 3. Go to the website and remove the quantity selector input field from the page and save. Issue: `TypeError: Cannot read properties of null (reading 'dataset')` Why this happens: Following architectural changes in v19.1, the rental data evaluation logic was moved directly into the DaterangePicker component lifecycle. Commit 4e5f71d introduces a new method to where, during initialization (`willStart`), the component triggers `setAddQtyInputMax()` to update the dataset attributes of the quantity selector input box. If the quantity selector has been removed via the website customizer `querySelector` returns `null`, causing the assignment to crash. In v19.0, this logic lived in the `WebsiteSale` interaction, executing only during post-render UI event listener triggers which kept it safe. opw-6268945 Forward-Port-Of: odoo/enterprise#119574
This update resolves a visual glitch in the chatter interface where an empty rectangle appeared next to log notes during editing. The issue stemmed from a system that remembered the last position, causing it to stick to the left even when space was available. This change removes the memorization, ensuring suggestions are displayed correctly regardless of scrolling.
Original PR description
# How to reproduce - Go into any form view of a model with a chatter (e.g. Quotation) - Add multiple long log notes. You need to be able to scroll enough to not see the last log note - Click edit on…
# How to reproduce - Go into any form view of a model with a chatter (e.g. Quotation) - Add multiple long log notes. You need to be able to scroll enough to not see the last log note - Click edit on the last log note - Scroll down to the bottom # The problem An empty rectangle is displayed next to the log note in edit mode. # Cause The rectangle comes from the NavigableList Component, which is the list that displays suggestions when typing things like "@" or "#" : https://github.com/odoo/odoo/blob/1fd44c3bb11a79d5b6aa72bf7de5a83e6c45be46/addons/mail/static/src/core/common/composer.xml#L137 This components uses the `usePostion()` hook, which purpose is to try to find the most appropriate place to put the element. It will try different postions (e.g. on the left, below, above, etc.) and will pick the most appropriate one. It will then adjust the element's style to position it correctly. It is possible to ask for a preferred position using the options given to the hook. This position will be prioritized over the others if it is suitable. In the case of the NavigableList of the chatter, we give it either 'bottom-fit' or the 'top-fit' positions, wich means it will prefer to be displayed above or below the message : https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/mail/static/src/core/common/composer.js#L449-L459 But in our case, when we scroll back up, the position of the rectangle stays on the left, even though the below space is available. That is because of this commit that introduced a memorization of the last solution : https://github.com/odoo/odoo/commit/b2b8d2dbb8396d86492a3089db9b1b1545c8f13b https://github.com/odoo/odoo/blob/f2434aac74324a65ccd81aa18c7b0e8318e59fde/addons/web/static/src/core/position/position_hook.js#L59-L61 This means that when we scroll down, the bottom positions fails and so the left one is defaulted to. Since the position is memorized, it stays on the left. The issue with this left position is that another commit introduced some logic that made it so if the position is not "top" or "bottom", then we set the element's height to some value : https://github.com/odoo/odoo/commit/702748e2c8e895d372d07f9aeff273282d1b1a99 https://github.com/odoo/odoo/blob/f2434aac74324a65ccd81aa18c7b0e8318e59fde/addons/web/static/src/core/position/utils.js#L120-L124 And setting the height of the NavigableList makes it so it displayed even when there are no suggestions inside, because the hiding mechanism of the suggestion list relies on the fact that when there are no suggestions, the div is empty and has no height, so it is hidden. # Propose solution We introduce a settings in the options that will allow to skip the memorization of the last position. Since the left position will never be set in the options, no height will be defined. opw-6172407 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262822
Code cleanup and technical improvements
This update streamlines how 'Activity Done' messages are generated within Odoo. By separating the message creation process, it now allows for easier customization by other modules without impacting core functionality. This enhances flexibility and reduces potential conflicts.
Original PR description
The `_action_done` method in `mail.activity` currently handles multiple responsibilities simultaneously, including permissions, attachments, message posting, and archiving. This commit extracts the chatter message generation logic into a dedicated `_generate_done_message` method. This allows inheriting models to easily override, customize, or completely bypass the generic 'Activity Done' message without duplicating or interfering with the core completion and archiving logic. Task: 6127862 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr