Thursday, October 9, 2025
32 changes · saas-18.4
Resolved issues and error corrections
This fixes a typo in the UAE payroll configuration where a salary rule was incorrectly labeled "Out of version" instead of "Out of Contract". The correction helps payroll users see the intended wording and avoid confusion when reviewing salary rules.
Original PR description
fix an accidental change during a forward port from "Out of Contract" to "Out of version" task-5075058
Stripe payments now handle currencies like the Ugandan shilling that use special decimal rules in Stripe. This prevents valid orders from being sent with the wrong amount and rejected at checkout.
Original PR description
Steps: - Activate the 'UGX' currency. - Make a sale order with amount 100 with 'UGX' currency - Try to pay that order (100 USh) using card Issue: - stripe throws the following error - > 'The Checkout Session's total amount must convert to at least 50 cents. 1.00 USh converts to approximately €0.00.' - Hence 100 USh sent was identified as 1 USh by stripe. This confirms issue with decimals and currency mapping. Cause: - 'UGX' is zero-decimal currency but stripe identify it as two-decimal. Fix: - Update mapping for such special currency cases for stripe that don't follow general rules opw-5075707 Forward-Port-Of: odoo/odoo#227688
This change updates the mail module's automated tests so saving email HTML fields waits until the save action is actually available. This helps reduce false failures in Odoo's runbot test system and improves confidence in build results.
Original PR description
This commit tries to solve runbot issues with mail html fields widget. It seems clicking on the save button manually is not generating a call to the backend. This could be due to the fact the button is not enabled due to the data being invalid. Therefore using the clickSave util could be useful in those situation since waiting that the button becomes enabled. This solution is not 100% sure to fix the issue in all cases but manually disabling the button is creating the issue we can observe in those runbots. There is a good chance it might work. fixes-runbot-231582 fixes-runbot-233049 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227484
Some tests were loading Chart.js using loadJS, without the corresponding bundle. That means that the test that comes after could fail if they required treemap/geo charts, as they weren't loaded in ChartJs. Task: [5003595](https://www.odoo.com/odoo/2328/tasks/5003595) Forward-Port-Of: odoo/enterprise#94769
Original PR description
Some tests were loading Chart.js using loadJS, without the corresponding bundle. That means that the test that comes after could fail if they required treemap/geo charts, as they weren't loaded in ChartJs. Task: [5003595](https://www.odoo.com/odoo/2328/tasks/5003595) Forward-Port-Of: odoo/enterprise#94769
The employee form now displays the private address city, state, and ZIP fields in better horizontal alignment. This makes the Swiss payroll employee form easier to read and use, reducing visual confusion when entering address details.
Original PR description
Wrap private address city, state, and zip fields in a flexbox container to ensure proper horizontal alignment on the employee form view. task-5082714 Forward-Port-Of: odoo/enterprise#94779
The employee form layout now keeps the private address city, state, and zip fields aligned on the same row. This improves readability and reduces visual confusion when viewing or editing employee address details.
Original PR description
Wrap private address city, state, and zip fields in a flexbox container to ensure proper horizontal alignment on the employee form view. task-5082714 Forward-Port-Of: odoo/odoo#226935
This fix prevents an error that could occur when an administrator clears browser data in Chrome while Live Chat is installed. It adds a safeguard so the Live Chat storage cleanup handles Chrome's empty storage notification correctly, improving reliability without changing user-facing features.
Original PR description
**Steps to reproduce:** Install 'Live Chat' Open Chrome Log in as 'Admin' Clear browser data **Current behavior before PR:** Clearing data triggers a storage event where the key parameter is null. An event listener attempts to call a method on this null key, leading to a runtime error. **Desired behavior after PR is merged:** A check has been added to ensure the key is not null, preventing the error. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230298
This fixes an issue where some nested website product description text could not be translated when using multiple languages. Businesses can now maintain complete localized shop content, improving consistency for international customers.
Original PR description
Scenario: - enable second language on website - go to /shop/1 and try to translate description_ecommerce Result: this is not translatable Cause: Since at least…
Scenario:
- enable second language on website
- go to /shop/1 and try to translate description_ecommerce
Result: this is not translatable
Cause:
Since at least b455ea85853dfc19ed01e33986ad270cf80ee5d6 the
contenteditable attribute in ContentEditablePlugin is not set on an
element if it has a contenteditable ancestor.
TranslationPlugin disable all editable nodes containing editable nodes.
So with this combination, if we had a node for example:
```
<div class="oe_editable" data-oe-model="product.template" data-oe-id="1"
data-oe-field="description_ecommerce" data-oe-type="html">
<div>
<span class="oe_editable" data-oe-model="product.template"
data-oe-id="1" data-oe-field="description_ecommerce">
test
</span>
</div>
</div>
```
the contenteditable was added to the parent div.oe_editable, but was
removed by TranslationPlugin so the "test" text was not translatable.
Fix: move the code that adds data-oe-readonly class in the
after_setup_editor_handlers so it is run before contenteditable
attributes are set.
opw-5128618Vendor credit notes created through purchase order matching now show the correct positive quantity when reversing over-billed purchase items. This prevents confusing negative quantities and helps keep purchase billing corrections accurate.
Original PR description
Steps to reproduce:- - Create a Purchase Order with Product A(invoicing policy: received quantities) and Quantity 3. - Create Vendor Bill with Product A and Quantity 3 and match it with the PO. - Receive only 2 on PO. - Now on PO, Quantity: 3, Received:2, Billed:3 - Create a Vendor Credit Note for that partner, add an empty line and save. - Click on PO Matching at the top. - Select line from Vendor Credit Note and line from PO, click match. Problem: In Vendor Credit Note Quantity: -1 (which should be 1) Before this commit: When credit note values are prepared from purchase order, quantity to invoice on purchase order is set as quantity on credit note. After this commit: When credit note values are prepared from purchase order, inverse(-ve) of quantity to invoice on purchase order is set as quantity on credit note. task-4975200 Forward-Port-Of: odoo/odoo#230487 Forward-Port-Of: odoo/odoo#221203
The vendor on-time rate report now shows purchase delivery data even when ordered products do not have a product category. This restores the graph on vendor records and gives purchasing teams a complete view of supplier delivery performance.
Original PR description
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and…
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and validate the generated receipt. 5-In the vendor form view, click the On-time Rate smart button → no graph is visible. **Issue:** https://github.com/odoo/odoo/blob/77b3956ed5635d79ae8dc19423140dc6a10098f1/addons/purchase_stock/report/vendor_delay_report.py#L46-L50 ``` The On-time Rate graph is not displayed in the Vendor Delay report. ``` **Cause:** - From version 18.2, `categ_id` was removed as a required field. The report query still uses an inner join on `categ_id`, which excludes products without a category and prevents data from being generated. - Commit which make `categ_id` non require - https://github.com/odoo/odoo/pull/166323/commits/b039caecbeb04057fbccb1cc88d03a4946f88e8e **Solution:** - Replace the inner join with a left join so that products without a `categ_id` are also included in the report (with null values when the category is not set). **opw** - 4991367 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230388 Forward-Port-Of: odoo/odoo#225557
This update ensures the right domestic fiscal position is selected for companies in the UAE, Italy, Mexico, and Cambodia. This helps apply the correct domestic taxes and removes a duplicate Italian setup that could cause confusion or incorrect tax behavior.
Original PR description
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the…
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the following localizations: **AE** Sequences are added making Dubai the domestic fiscal position. However this needs to be improved to automatically prioritize the fiscal position based on the company's state. **IT** (l10n_it_edi_doi) An additional domestic fiscal position was mistakenly added. The correct domestic FP is defined in it's dependency module l10n_it. The duplicate FP is removed. **MX** Sequences are added **KH** Sequences are added No Task - l10n's identified by the fiscal position checks in `test_all_l10n` 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#230654
Spreadsheet-related tests now load the full chart library setup they depend on. This prevents later tests from failing unpredictably when they need specialized chart types such as treemap or geographic charts, improving reliability without changing user-facing behavior.
Original PR description
Some tests were loading Chart.js using loadJS, without the corresponding bundle. That means that the test that comes after could fail if they required treemap/geo charts, as they weren't loaded in ChartJs. Task: [5003595](https://www.odoo.com/web#id=5003595&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form)
The restaurant appointment feature has been updated so its floor screen stays compatible with recent core point-of-sale changes. This helps prevent display or navigation issues for businesses using restaurant tables together with appointments.
Original PR description
This commit adapts an overriding method to reflect changes in the base method done in this pr https://github.com/odoo/odoo/pull/176016. Forward-Port-Of: odoo/enterprise#91334
This fixes several display issues when opening a single bank statement line from a reconciled entry. The reconciliation screen now restores the summary when filters are cleared, avoids expanding unrelated lines, hides an irrelevant Statement button for single-line views, and opens the ledger using the correct journal context.
Original PR description
When you open a statement line from a reconciled move, it opens the bank reconciliation widget with only the selected statement line, which is unfolded by default. However, there are a few issues with this behavior, which are fixed in this commit: 1 - When entering the bank reconciliation widget, the initial line is unfolded. If you remove the filter, all the other lines become unfolded as well. This should not be the case; only the original line should remain unfolded. 2 - By default, the statement summary line is hidden. When the filter is removed, the summary remains hidden. We now ensure the summary is displayed again when the filter is cleared. 3 - The Statement button on the statement line (which is meant to create a new statement) doesn't make any sense when there is only one line. It is now hidden in this case. task-5108118 Forward-Port-Of: odoo/enterprise#95558
Odoo Studio now identifies custom fields using their stored status rather than relying on naming rules. This keeps custom field behavior reliable as older name-based checks are phased out and reduces duplicate configuration work in related apps.
Original PR description
With the fields method `_is_manual_name` being deprecated, checking whether a field is manual can be done through the state instead of the field name. This avoids the need to override the definition of a custom field name in another place in the applications that need to do it. Related https://github.com/odoo/odoo/pull/224524
Test data for Hong Kong payroll accounting now includes required leave allocation records. This prevents validation errors in automated checks, helping keep payroll-related releases stable.
Original PR description
Issue: Unit tests are failing because test data was created without leave allocations, leading to validation errors. Fix: Added leave allocation data for time off types which requiring allocation in some tests. build_error-230409 Forward-Port-Of: odoo/enterprise#96060 Forward-Port-Of: odoo/enterprise#93160
The sales timesheet invoicing wizard now uses a safer format for a setting in its screen definition. This prevents errors for customers with custom tools that read these views outside the browser, while keeping the user experience unchanged.
Original PR description
Versions -------- - 17.0+ Issue ----- Some customizations may parse XML views using Python, in which case the `date_start_invoice_timesheet` field could return an error, as the `options` attribute uses a Javascript boolean `true`. Solution -------- Use `'true'`, which will get parsed as `true` in JS via `archParseBoolean`. Forward-Port-Of: odoo/odoo#230278
This fixes an issue where custom hour or half-day options could be unintentionally cleared when an employee changed the time off type. It helps preserve the user's leave request choices and reduces the need to re-enter information.
Original PR description
- made the value of checkboxes for `request_unit_half` and `request_unit_hours` stay the same when switching between timeoffs that can have hourly type task-id: 5085389 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228981
Gantt group headers now keep their sticky behavior even when the timeline has many or wide columns. This improves usability, especially on mobile screens, by preventing headers from stretching beyond the visible page area.
Original PR description
Gantt group headers could stop being sticky because their width was fixed based on the number and size of columns. Even though they were set to position: sticky, oversized headers could no longer remain aligned when scrolling, as they extended beyond the viewport and were constrained by the document width. This was especially noticeable on mobile, where group headers are often wider than the screen. The fix applies a max-width style to these headers, capping their size to the available space so they remain sticky without overflowing the document. task-4970992 Forward-Port-Of: odoo/enterprise#96612 Forward-Port-Of: odoo/enterprise#96015
This fix ensures multiple quote carousels on the same website page each receive a unique identifier. As a result, visitors can use carousel arrows without accidentally controlling a different carousel on the page.
Original PR description
The selector used to target the carousel, to generate unique ID, did not include some carousels (s_quotes[...]). This led to issues with the controllers that would not be linked to the correct carousel. Steps to reproduce the issue: - Go to Edit - Drop two "s_quotes_carousel" - Save - Click on the "next" arrow of the second carousel => The second carousel does not slide, but the first one does.
The appraisal skills list now scrolls properly on mobile devices, so users can access the justification field and add or remove skill entries. This fixes a mobile usability issue that could prevent completing appraisal skill information smoothly.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 Forward-Port-Of: odoo/enterprise#96527 Forward-Port-Of: odoo/enterprise#91882
This fixes a small issue in the HTML editor that could trigger an unexpected JavaScript error when inserting content. The change helps keep editing actions stable and prevents interruptions for users working with rich text fields.
Original PR description
In `dom.insert`, the variable `container` was being redefined to a constant within a `while` loop, making it impossible to use the original variable within the loop. This caused an `Uncaught Javascript Error` ("Cannot access 'container' before initialization") whenever trying to access it within the loop but above the redefinition. This commit renames the constant to a previously unused name.
opw-5053872
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe color picker in the website and HTML editing tools now reopens on the tab that matches the user's last color choice, such as custom colors or gradients. This makes styling pages smoother by avoiding extra clicks and reducing confusion when adjusting colors repeatedly.
Original PR description
*web, website Before this commit, `BuilderColorPicker` had no memory of the last used tab and always opened on the first tab, regardless of whether the user had previously selected a color. After this commit, if the user has done a selection, the color picker opens on the tab of that selection. How to reproduce the problem: 1. Drop a new snippet, e.g. `s_text_block`, 2. Click on the snippet, then open the "Background" color picker 3. Pick a custom color or a gradient 4. If the color picker is stil open, press ESC 5. Open the color picker again 6. PROBLEM: the color picker is opened on the "theme" tab task-4367641
The appraisal skills list now allows horizontal scrolling again on mobile devices. This makes the justification field and add/remove buttons accessible, so employees and managers can complete appraisal skill updates from smaller screens.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230310 Forward-Port-Of: odoo/odoo#222161
This fix ensures nested website content, such as product eCommerce descriptions, can be translated correctly when multiple languages are enabled. It prevents editable translation areas from being disabled too late, improving the translation experience for website managers.
Original PR description
Scenario: - enable second language on website - go to /shop/1 and try to translate description_ecommerce Result: this is not translatable Cause: Since at least…
Scenario:
- enable second language on website
- go to /shop/1 and try to translate description_ecommerce
Result: this is not translatable
Cause:
Since at least https://github.com/odoo/odoo/commit/b455ea85853dfc19ed01e33986ad270cf80ee5d6 the
contenteditable attribute in ContentEditablePlugin is not set on an
element if it has a contenteditable ancestor.
TranslationPlugin disable all editable nodes containing editable nodes.
So with this combination, if we had a node for example:
```
<div class="oe_editable" data-oe-model="product.template" data-oe-id="1"
data-oe-field="description_ecommerce" data-oe-type="html">
<div>
<span class="oe_editable" data-oe-model="product.template"
data-oe-id="1" data-oe-field="description_ecommerce">
test
</span>
</div>
</div>
```
the contenteditable was added to the parent div.oe_editable, but was
removed by TranslationPlugin so the "test" text was not translatable.
Fix: move the code that adds data-oe-readonly class in the
after_setup_editor_handlers so it is run before contenteditable
attributes are set.
opw-5128618