Wednesday, September 23, 2026
23 changes · saas-19.4
Enhancements to existing features
The Vietnamese chart of accounts now includes dedicated accounts for revenue and costs from selling or liquidating investment property. This supports compliance with Circular 99/2025/TT-BTC and helps report related gains or losses separately in Profit & Loss statements.
Original PR description
Circular 99/2025/TT-BTC adds a dedicated Profit & Loss line for gains/losses on the sale and liquidation of investment property, computed from dedicated sub-accounts rather than the main revenue and cost-of-goods-sold accounts. Add the two accounts to the chart of accounts: - 5117 Revenue from sale and liquidation of investment property - 6327 Cost of sale and liquidation of investment property Task-6518304 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290129 Forward-Port-Of: odoo/odoo#287572
Bank statement auto-reconciliation now matches payment references with invoice names even when uppercase and lowercase letters differ. This reduces missed automatic matches and saves accounting teams manual reconciliation work.
Original PR description
Currently, when a payment reference isn't in the same letter case as the invoice name, it wouldn't automatically reconcile. task-6562440 Forward-Port-Of: odoo/enterprise#131418
Resolved issues and error corrections
This fixes an issue where employees could receive repeated chatter messages when they were automatically enrolled in an eLearning course more than once. The enrollment notification now behaves consistently and avoids cluttering employee records with duplicate messages.
Original PR description
Steps to reproduce: - connect with a user with an employee record - recreate a new eLearning course - enable debug mode - add "Role / User" to "Auto Enroll Groups" fields => message is duplicated in the employee's chatter `_action_add_members` in `website_slides` is designed to be idempotent (calling it twice is a no-op if the partner has already joined) but the override in `hr_skills_slides` is not. We have many many duplicated messages on odoo.com (see task) task-6508615 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290032 Forward-Port-Of: odoo/odoo#284483
The website setup flow now keeps upcoming fields unavailable until users reach the right step. This prevents hidden options from reacting to mouse or keyboard input and improves accessibility for people using screen readers or keyboard navigation.
Original PR description
Steps to reproduce: - Start the website configurator and open the description step. - Before choosing a website type, move the pointer over the area where the industry field will appear. - Navigate with Tab before completing the industry selection. => Hidden fields still react to input and can receive keyboard focus. Before this commit, the industry input and positioning dropdown were transparent until the previous step was complete. They could still react to pointer input and be announced by screen readers. After this commit, these fields stay hidden and unavailable until their respective steps are reached, while keeping their layout space.
Removing or reducing column layouts now drops columns that contain no real content, preventing extra blank paragraphs from appearing. Content-filled columns are preserved, and the editor still keeps one empty paragraph when needed so users can continue editing.
Original PR description
#### Description of the issue this PR addresses: - When reducing the number of columns or removing a column layout, empty columns were previously unwrapped like any other column. - As a result, columns containing only placeholder paragraphs contributed empty paragraphs to the resulting content, even though they did not contain any meaningful user content. #### Desired behavior after PR is merged: - Fully empty columns are discarded when they are removed. - Non-empty columns continue to be merged as-is, preserving their content. - A single empty paragraph is still kept when all columns are empty to ensure the editor remains editable. - Rename `Remove columns` to `Remove column layout` and update its description to `Convert columns to regular content` to better reflect the operation. task-6296536 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286125 Forward-Port-Of: odoo/odoo#270220
Website cards configured as clickable links remain clickable after a background image is added. This prevents broken navigation on published pages and helps editors safely combine visual card designs with link behavior.
Original PR description
**Problem** Clickable cards do not work if they have an image as background. **How to reproduce** Drop a `s_cards_grid` snippet, select a card, enable "Make it clickable", set a URL, then set a background image on the card. Save. The card is no longer clickable. **Why does it happen** When a background image is set, the card gets the `oe_img_bg` class. This class, through `%o-we-background-layer-parent`, sets `position: relative` on every one of its direct children. This is done to keep the background image behind the snippet's own content, but it interferes with the `a.stretched-link` element, making the card not clickable. **Fix** Exclude `.stretched-link` from the children targeted by `%o-we-background-layer-parent`. task-6462339
Delivery slip quantities are now rounded correctly when a receipt or delivery is split across multiple stock move lines. This prevents confusing decimal artifacts from appearing on printed documents, improving clarity for warehouse teams and customers.
Original PR description
**Issue** When a move has several move lines, the printed quantities are not rounded, causing floating-point arithmetic artifacts to appear on the report. **Steps to reproduce** - Create and confirm…
**Issue** When a move has several move lines, the printed quantities are not rounded, causing floating-point arithmetic artifacts to appear on the report. **Steps to reproduce** - Create and confirm a PO for 15.6 units of a product. - On the receipt, change the quantity to 17.8 (this splits it into two stock move lines). - Validate the receipt and print the delivery slip. -> The ordered quantity on the generated PDF is not rounded (floating-point arithmetic issue). **Cause** While printing the delivery slip, quantities are aggregated by product: https://github.com/odoo/odoo/blob/189df3538aa07d22f683008522b9143421f411a2/addons/stock/report/report_deliveryslip.xml#L174 No rounding is performed while subtracting quantities from the ordered quantity (resulting in 13.399..): https://github.com/odoo/odoo/blob/189df3538aa07d22f683008522b9143421f411a2/addons/stock/models/stock_move_line.py#L927 Nor while adding the second move line's quantity back to the ordered quantity (resulting in 15.599..): https://github.com/odoo/odoo/blob/189df3538aa07d22f683008522b9143421f411a2/addons/stock/models/stock_move_line.py#L938 **Additional note** Same issues arise for `packaging_qty_ordered`, `quantity` and `packaging_quantity`. opw-6469422 Forward-Port-Of: odoo/odoo#286846 Forward-Port-Of: odoo/odoo#283792
Fixes an issue where changing the gradient angle in the website editor color picker could appear to save but revert afterward. Users can now type a new angle and have it applied immediately, making gradient styling more reliable when editing website building blocks.
Original PR description
Problem: When changing the gradient angle input in the color picker and saving the record, the updated angle is not saved and reverts to the previous value. Cause: `setOnCloseCallback` runs before `onAngleChange` because the angle input fires the `change` event on blur/close. As a result, `onColorGradientChange` is called with the previous angle value, and `onColorGradientPreview` runs afterwards with the new value, causing the applied preview to be reverted later. Solution: Call `onAngleChange` on the `input` event instead of `change` so that state and preview update immediately each time the user types. Steps to reproduce: - Add a gradient to a building block. - Define a value of 180 degrees. - Save - If you open the color picker the value is still 135. task-6522533 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286778 Forward-Port-Of: odoo/odoo#285967
The website project form processing has been cleaned up and reorganized to make it more reliable and easier to update in the future. This helps reduce the risk of errors when visitors submit project-related forms through the website.
Original PR description
Clean up and move some of the form processing logic for future updates opw-6560036 Forward-Port-Of: odoo/odoo#287697
Chatter filters now correctly include field tracking updates in the Tracked Changes view and keep them out of regular conversations. This helps users find audit-related updates in the right place and reduces confusion when reviewing record history.
Original PR description
Previously, the chatter filters only considered notification messages. Since field tracking messages are now stored as tracking messages, they no longer appeared in the 'Tracked Changes' filter and were incorrectly included in the 'Conversations' filter. This PR updates the chatter filters to correctly handle tracking messages, ensuring that each filter displays the appropriate messages. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280981
Project task totals now exclude subtasks that belong to task templates, aligning the counts with what users see as regular tasks in the interface. This prevents template-related items from inflating open, closed, and total task counts, making project reporting clearer and more reliable.
Original PR description
Before this commit, the task_count and closed_task_count takes into account the subtask inside task template, however, those subtasks are not considered as a basic task in the UI, there are also considered as a template.
This commit adds `('has_template_ancestor', '=', False)` condition to make sure those subtasks are no longer taken into account. The condition inside the compute of `open_task_count` has also been reviewed to have the same conditions in the 3 fields.
task-6483156
Forward-Port-Of: odoo/odoo#286910Colombian electronic invoices sent to DIAN no longer include the journal's technical control key in the note field. This keeps the XML note content limited to the invoice Terms and Conditions, avoiding unintended internal information in official documents.
Original PR description
**Steps to reproduce:** - Install the `l10n_co_dian` module and switch to the CO Company. - Disable `Test environment` and enable `DIAN Demo Mode` in the invoicing settings. - Set a `Technical…
**Steps to reproduce:** - Install the `l10n_co_dian` module and switch to the CO Company. - Disable `Test environment` and enable `DIAN Demo Mode` in the invoicing settings. - Set a `Technical control key` on the `Customer Invoices` journal. - Create and confirm an invoice with Terms and Conditions. - Send the invoice to `DIAN`. - Open the generated XML file and observe the `cbc:Note` tag. **Observation:** The `Note` tag contains the `technical control key`. **Expected behavior:** The `Note` tag should only contain the Terms and Conditions value from the invoice. (Confirm with PO [1]) **Root Cause:** At [2] and [3], the code includes the `technical key` in the `Note` tag. [1]: https://www.odoo.com/mail/message/1164671931 [2]: https://github.com/odoo/enterprise/blob/a5f4bde1aa33ea7b796d7ee3f9d713a6c8ab8348/l10n_co_dian/models/account_edi_xml_ubl_dian.py#L664 [3]: https://github.com/odoo/enterprise/blob/a5f4bde1aa33ea7b796d7ee3f9d713a6c8ab8348/l10n_co_dian/models/account_edi_xml_ubl_dian.py#L1600-L1603 opw-6513843 Forward-Port-Of: odoo/enterprise#132606 Forward-Port-Of: odoo/enterprise#131495
The Luxembourg reporting module now uses a working download link for the FAIA XSD file. This prevents failed or empty downloads, helping users access the required reporting schema reliably.
Original PR description
The old link points to a file with zero bytes. opw-6344914 Forward-Port-Of: odoo/enterprise#132582
Australian payroll onboarding now correctly recognizes bank details when a BSB and bank name are provided without a BIC. This prevents users from seeing an incorrect missing bank details warning after completing setup.
Original PR description
Bug reproduction: 1 - Install l10n_au_hr_payroll_api, settings→payroll→AU localization 2 - Start payroll onboarding `2.1 - Next step→fill in BSB and keep BIC empty→Set Bank details` 3 - No BSB or bank set warning continues to appear Bug cause: 1 - For that warning, there is check that checks bic (to not keep empty) Bug solution: 1 - bic check is removed and bank name check is added task-6540863 Forward-Port-Of: odoo/enterprise#130792
This fix hides document actions when no file has been uploaded, preventing users from seeing unusable buttons. It also keeps budget and report amounts properly formatted when a user opens an amount for editing and clicks away without making changes.
Original PR description
Hide Open Document on working files when no attachment Problem: In working files checks with attachment, Open Document button and trash icon are visible even if there is no attachment uploaded yet.…
Hide Open Document on working files when no attachment Problem: In working files checks with attachment, Open Document button and trash icon are visible even if there is no attachment uploaded yet. Cause: We check for existence of attachment by `t-if="record.attachment_ids"`, but `record.attachment_ids`, `record.attachment_ids.value` and `record.attachment_ids.raw_value` are all truthy even if there is no attachment uploaded yet. Fix: Use `invisible="not attachment_ids"` just like before. *** Fix formatting when clicked outside without any change Steps to reproduce:- - Create a budget with a P&L report. - Set a value in a cell. - Then press the edit amount, click somewhere else without changing the amount. - The amount is no longer formatted properly. Cause: When user clicks edit, we populate formatted value for locale format type but when user clicks outside without change, in function `onBlur` we compare populated amount(which is formatted) with cell's no format value. So it mismatches and `focused` is never set `false`. Fix: Make getter `editableValue`, which returns `editableNumericValue` for locale format type and no format value otherwise. Now use this `editableValue` in `onFocus`, `onBlur`(this solves the bug) and `inputValue` to make it more clear. *** [task-6413368](https://www.odoo.com/odoo/project/967/tasks/6413368) Forward-Port-Of: odoo/enterprise#131989
This fix prevents Odoo Studio from crashing when a user creates a new app and opens the Map view option. It improves reliability for users configuring views in Studio, with no expected workflow changes beyond the crash being resolved.
Original PR description
In a new app in studio tab "views" ; click on map view. Before this commit there was a crash because of some props not correctly defined After this commit there is no crash
This fix ensures field service planning tests use a consistent employee time zone instead of inheriting the demo user's location. It prevents false test failures caused by daylight or regional time differences, helping keep release validation reliable.
Original PR description
Employees created in TestPlanningFieldServiceCommon had no explicit tz, so they inherited the acting user's timezone. With --with-demo that user's tz is Europe/Brussels, shifting the resource calendar's work hours by 1h in January and making test_planning_slot_allocated_hours_on_multiple_resources compute 7 allocated hours instead of the expected 8. runbot-946587 Forward-Port-Of: odoo/enterprise#131570
This fix prevents Odoo from running currency translation adjustment calculations when all consolidated companies use the same currency. It avoids unnecessary processing while keeping reporting behavior unchanged for multi-currency consolidations.
Original PR description
The condition used to be options['currency_table']['type'] != 'cta'. In monocurrency, the 'currency_table' option key contained 'monocurrency', so the CTA computation always returned an empty result. However, now that the option key has been removed and we use self.currency_translation, some additional check needs to be added in order to avoid uselessly computing CTA when not consolidating companies in different currencies.
This fix prevents an error when users open the rental schedule from a product that no longer has any variants. The system now skips a missing default product reference, allowing the schedule view to open normally and reducing disruption for rental teams.
Original PR description
Currently, an error occurs when opening the Rental Order Lines Schedule view. **Steps to Reproduce:** - Install the `sale_stock_renting` module. - Go to `Settings` and enable `Variants`. - Go to…
Currently, an error occurs when opening the Rental Order Lines Schedule view. **Steps to Reproduce:** - Install the `sale_stock_renting` module. - Go to `Settings` and enable `Variants`. - Go to `Rental` > `Products` and create a product. - In the `Attributes & Variants` tab, add an attribute with two values and save. - Delete all variants using the `Variants` smart button or from `Inventory` > `Products` > `Product Variants`. - Return to the `Product` and click the `In Renting smart button`. `IndexError: list index out of range` When a product template is created, a product variant is automatically generated if the product has no attributes. Deleting this variant also deletes the product template [1]. By explicitly creating attribute values, a dynamic product variant is generated. Deleting this variant does not delete the product template because of the dynamic attribute [2]. When the In Renting button is clicked, it it going to open the rental order lines Schedule view and adds default_product_id to the action context. Since no product variants exist anymore, accessing the default product variant raises an error [3]. This commit ensures that default_product_id is not added to the context when the product template has no product variants [1]: https://github.com/odoo/odoo/blob/1f70b81eeebcc62b64c18772915e2f4696e189e7/addons/product/models/product_product.py#L486 [2]: https://github.com/odoo/odoo/blob/1f70b81eeebcc62b64c18772915e2f4696e189e7/addons/product/models/product_product.py#L478-L480 [3]- https://github.com/odoo/enterprise/blob/98ec35f3f17a2b706ad4fcc4d6161d12d05eadfd/sale_renting/models/product_product.py#L69 [4]: https://github.com/odoo/odoo/blob/942d3892c33e7ccdcfec260c3da37095069b699e/addons/stock/models/product.py#L635-L643 [5]: https://github.com/odoo/odoo/blob/942d3892c33e7ccdcfec260c3da37095069b699e/addons/stock/models/product.py#L601-L612 sentry-7637715724 Forward-Port-Of: odoo/enterprise#132401 Forward-Port-Of: odoo/enterprise#126356
Selecting a city in an employee's private address now immediately fills the related address details in the form. This avoids confusion by showing the correct address information before saving, matching the data that would already be recorded after save.
Original PR description
Issue: When you select a city in the employee's private address field, the other address fields should be populated accordingly. Even though once you save, the changes are recorded, they don't appear in real-time in the form. This is because the onchange related to the address city field was only in `hr.version`, but not `hr.employee`, so the automatic population upon the change of the city wasn't visible in the employee form view. Fix: Add _onchange_private_city_id() in hr.employee under hr_address_extended module which calls the same-name onchange in the linked version. task-6584206 Forward-Port-Of: odoo/odoo#289837
Link previews in the HTML editor now ignore metadata that contains only spaces. This prevents users from seeing an empty clickable preview area and correctly falls back to showing the link URL when no real title is available.
Original PR description
Problem: When a link's metadata contains whitespace-only strings for `og_title`, `og_description`, or `og_image` (e.g. `og_title: " "`), the link popover displays an empty clickable preview area.…
Problem: When a link's metadata contains whitespace-only strings for `og_title`, `og_description`, or `og_image` (e.g. `og_title: " "`), the link popover displays an empty clickable preview area. Cause: `LinkPopover` assigned raw metadata values directly. Non-empty whitespace strings evaluate to truthy values in JavaScript (`" "` is truthy), preventing fallback to the default URL or empty string. Solution: Trim the metadata values (`og_title`, `og_description`, `og_image`) when populating state so that whitespace-only values evaluate to empty strings and trigger appropriate fallbacks. Steps to reproduce: - Open HTML editor. - Add a link with URL `https://netorg4182089.sharepoint.com/:v:/s/projects/IQD72ajP3WOBT4jcAu_1qLfIAamL9lvrq4ls1Bs9XCyXJvw?e=vQ9wH3`. - Open the link popover. => Observe that the popover title falls back to the URL instead of showing an empty clickable space. opw-6564118 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288188
A timing issue in the rental planning test was corrected so it handles Brussels timezone dates consistently. This prevents false test failures during early-morning runs and helps keep release validation stable without changing customer-facing behavior.
Original PR description
**Issue:** `test_payment_renting_product_available` test is failing when executed between 0:00 AM and 2:00 AM in Brussels timezone (UTC+2): ``` AssertionError: datetime.datetime(2026, 6, 22, 16, 0) != FakeDatetime(2026, 6, 21, 16, 0) : The planning slot should begin at the same time as the picking time. ``` In the database the datetime is stored in UTC, which is the previous day for the example above. In `test_payment_renting_product_available` test, the datetime is passed to `datetime.combine()` function that naively uses the date part, which leads to a one-day delta. The datetime should be converted to the working timezone before being passed to `datetime.combine()`. runbot-940435 Forward-Port-Of: odoo/enterprise#131944
This fixes a display issue in the HTML editor where bullet points could shift too far left when turning large header text into a list. Users creating formatted content will see cleaner, correctly aligned lists without needing manual adjustments.
Original PR description
Problem: Creating a list on a header block with large font size content causes the list marker/bullet to overflow to the left. Cause: `ListPlugin.blockToList()` wrapped block elements into a list without invoking `this.adjustListPadding(list)`, leaving the list padding unadjusted for larger font sizes. Solution: Call `this.adjustListPadding(list)` in `blockToList` so that proper inline padding is set based on the list item content font size. Steps to reproduce: - Create a header block (e.g. Header 4). - Change the font size of the header content to be bigger. - Apply a list on the content. => Observe that the list marker overflows to the left. opw-6542903 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286975