Tuesday, November 4, 2025
17 changes · 18.0
New functionality added to Odoo
This update lets users find journal items by entering a balance amount in search. It makes it easier to locate specific accounting entries faster, especially when reviewing or reconciling records.
Original PR description
Description of the issue/feature this PR addresses: adding a search field by balance of journal item Current behavior before PR: can't search by balance Desired behavior after PR is merged: typing a number can result in a search by balance --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Enhancements to existing features
This update refreshes the QR-code links used for Brazilian NFC-e invoices so they match the latest URLs required by several states. It helps prevent invoice submission errors caused by outdated or invalid links.
Original PR description
In This PR:
- Several states have updated their NFC-e QR-code URLs, which caused errors when issuing invoices due to invalid or outdated links. This commit updates the 'nfceQrCode' parameter in Avalara requests ('calculate-tax' and 'submit-invoice-goods') to ensure the correct QR-code links are used.
task- 5115845Resolved issues and error corrections
Fixed an issue where the image toolbar would not appear if the editor had lost focus first. The editor now correctly checks both the current focus and the text selection, making image editing more reliable for users.
Original PR description
Description of the issue: - The image toolbar failed to open when the editable had lost focus. - Previously, `focusEditable()` exited early if the active element was inside the editable, even when the actual document selection wasn’t. Solution: - Updated the condition in `focusEditable()` to also check whether the document selection is inside the editable. - Now it only returns early when both the active element and the selection are within the editable. task-5117272 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users can now quickly search journal items by entering an amount, making it easier to find the right accounting lines without manual filtering. This improves day-to-day efficiency for accounting teams working with large numbers of entries.
Original PR description
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
This change brings back the Lot/SN column in Detailed Operations. It makes it easier for users to open the related lot or serial number record directly instead of seeing only plain text in the Pick From field.
Original PR description
The Lot/SN column was removed from the Detailed Operations tree view because it was considered redundant with the "Pick From" column in #199630. However, the lot or SN number displayed in the "Pick From" column is plain text and cannot be clicked to navigate to the corresponding `stock.lot` form view, which can be inconvenient. This PR brings back the Lot/SN column to restore direct navigation to the lot or serial number records. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents invoices from being assigned the wrong invoice type when they are linked to a purchase order. It ensures that special cases like refunds keep their original classification, avoiding accounting errors and incorrect document handling.
Original PR description
### Case This PR fixes the case of creating an invoice with a specific move_type(for example in_refund), than this invoice is linked to a purchase order. I discovered the bug while importing an XML Invoice of an in_refund. Importing this Invoice, the move_type become move_type because it is overwritten from the prepare_invoice data ### Before this PR The move_type is overwritten, so the in_refund become in_invoice and it is wrong. ### After this PR: The move_type is preserved. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change prevents a browser error that could appear when a user saves a pop-up form after interacting with a related list. It makes the interface more reliable by stopping background actions from running on screens that are already closed.
Original PR description
Steps to Reproduce: - Open a Repair Order form view in Odoo 17 or 18. - Navigate to the Parts tab. - In the list view of parts, click the Smart Button on any part line. - A pop-up form view opens…
Steps to Reproduce:
- Open a Repair Order form view in Odoo 17 or 18.
- Navigate to the Parts tab.
- In the list view of parts, click the Smart Button on any part line.
- A pop-up form view opens showing detailed operations.
- Click the “Pick From” field value, but don't change its value.
- Click the Save button in the pop-up.
- Observe the browser console for the error: TypeError: Cannot read properties of null (reading 'querySelector') at ListRenderer.focusCell
Traceback:
```py
TypeError: Cannot read properties of null (reading 'querySelector')
at ListRenderer.focusCell (https://91307582-17-0-all.runbot219.odoo.com/web/assets/15b4f47/web.assets_web.min.js:9519:80)
at ListRenderer.<anonymous> (https://91307582-17-0-all.runbot219.odoo.com/web/assets/15b4f47/web.assets_web.min.js:9477:272)
```
Root Cause:
- Asynchronous patching in OWL (onPatched with await Promise.resolve()) continues execution after the next tick, even if the component is destroyed.
- When the component is destroyed, OWL sets status(this) = 3 (DESTROYED).
- focusCell() accesses DOM using querySelector, which fails if the component is destroyed.
- The code did not check the component status before calling focusCell().
Fix:
- Added `if (status(this) === destroyed) return;` to stop focusCell() execution on destroyed components.
- Ensured async patching is handled safely with await Promise.resolve().
- Added `onWillDestroy` to clean up dialog callbacks, preventing memory leaks.
OPW - [5154694](https://www.odoo.com/odoo/project/70/tasks/5154694)
[PAD](https://pad.odoo.com/p/issue_5154694_shku)
Localhost issue reproduction [steps](https://drive.google.com/file/d/1wkglUosOveUseU0mBePZcQAFB_ZWr3uM/view)
17:https://github.com/odoo/odoo/blob/f9726cfe93e8850a38d9de06acfa5d78473b50b0/addons/web/static/src/views/list/list_renderer.js#L223
18:https://github.com/odoo/odoo/blob/1cac54db8634267a780b4011291f1e8a80ac5f5b/addons/web/static/src/views/list/list_renderer.js#L213
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#232097This update corrects how overtime one-time payments are processed in the Swiss payroll transmission flow. It helps ensure overtime amounts are sent with the right values, reducing the risk of payroll reporting errors.
Original PR description
Forward-Port-Of: odoo/enterprise#98670
This update prevents products added through a sales combo from being incorrectly merged into a separate product selection. As a result, the system now creates the correct sales lines and keeps combo extra prices from affecting separately added items.
Original PR description
Steps: - create a product with attributes of create_variant=never - set variant selection to order grid entry - add this product as a combo choice and set extra_price>1 - In sale order form first add the new combo product with the previously created product - add the new product with same selection of attribute values as combo Issue: - The separately added product should create a new line, but since it was added as a part of the combo, the product's price is summed with extra price and added to the combo itself Cause: - the grid field that is responsible for adding product using product matrix does not filter combo lines Fix: - added filter for combo lines when matrix opens and saves opw-5164789 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix removes Chinese Yuan (CNY) from the currencies PayPal can use in Odoo when the PayPal account is not eligible for it. As a result, customers will no longer reach a payment flow that fails or behaves unexpectedly for CNY invoices, making checkout clearer and more reliable.
Original PR description
## Versions 18.0+ ## Issue No payment is possible with PayPal for invoices expressed in Chinese currency. ## Steps to reproduce **`account` app required** - Enable "CNY" currency via `Invoicing /…
## Versions
18.0+
## Issue
No payment is possible with PayPal for invoices expressed in Chinese currency.
## Steps to reproduce
**`account` app required**
- Enable "CNY" currency via `Invoicing / Configuration / Accounting / Currencies`;
- Install, setup and publish PayPal payment provider;
- Move to the Invoice app:
- Create a new invoice in "CNY" currency for any customer with at least 1 product;
- Confirm and click on the preview button:
- Click on the "Pay now" button then "Pay" button of the wizard.
## Cause
"CNY" currency is only supported for Chinese accounts and for transactions occurring in China. PayPal says:
> Please note that Chinese Renminbi (CNY) is supported as a payment currency (buyer currency) or settlement currency (holding currency) only for in-country PayPal accounts. If the settlement account is based outside of China, PayPal will convert the funds into the account’s primary currency using the applicable currency conversion rate, which includes a spread or fee.
opw-5071893This change prevents expense report PDFs from showing the title twice when using the DIN5008 German document format. It does this by providing the correct report title for DIN5008 headers, resulting in cleaner and more professional printed expense reports.
Original PR description
Issue: Expense title is duplicated when printing an expense report for localizations using the DIN5008 standard. Steps to reproduce: - Install German localization - Create a new expense report - Print the expense report PDF -> Title is duplicated Cause: DIN5008 reports tries to load a value `din5008_document_title` in their header and fallbacks to report's name With this commit, we add a bridge module to extend the expense sheet report and set the `din5008_document_title` to `Expenses Report`. opw-4314414
When a mail template is duplicated, its attachments are now copied too instead of being shared between templates. This prevents edits to one template from unintentionally affecting others and helps avoid access issues in future setups with custom rules.
Original PR description
Copying tmeplates should copy their attachments. Otherwise they are
shared, which means
* wrong res_id: ACL check on attachments relies on a specific
template, as res_model / res_id is used in access check;
* propagated changes: changing one attachment changes it on all
duplicated templates;
If custom rules on templates are implemented, this means notably
ACL issues when accessing attachments. It is not the case in standard
Odoo 17 as everyone can read templates but this notably changes in
future versions of Odoo.
While being there, also fix 'default' usage in copy override. User
given values should not be erased by default computation of name.
Task-5128863
Forward-Port-Of: odoo/odoo#232877This change removes a recently added bot-detection filter from website blog and slides. The previous check could be bypassed by crawlers, so it was allowing unwanted indexing of many tag combinations and could overload tag pages; the team is reverting it while a more reliable solution is developed.
Original PR description
This reverts [1] because the `is_a_bot` check is not reliable. Many crawlers spoof user agents or ignore robots rules, so they still index every tag combination and overload tag clouds. We revert while we look for a better protection. [1]: https://github.com/odoo/odoo/commit/4b1c3bfa83af2b1851db62df5aca4d5777a3d88c
A problem that could break quotation previews after customizing a sales report in Studio has been fixed. The preview now works correctly even when a field is added to the report layout, avoiding an error for users viewing quotations in the portal.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Edit the `sale.report_saleorder` report using `web_studio`. 2. Add the `amount_untaxed` field next to the "Untaxed Amount" subtitle. 3. Create or navigate to…
Versions -------- - 17.0+ Steps ----- 1. Edit the `sale.report_saleorder` report using `web_studio`. 2. Add the `amount_untaxed` field next to the "Untaxed Amount" subtitle. 3. Create or navigate to a quotation and click on the "Preview" action. Issue ----- A traceback occurs during the rendering of the `sale.sale_order_portal_template` template. ``` Error while render the template KeyError: 'doc' Template: sale.document_tax_totals Path: /t/t/tr/td[1]/span Node: <span t-field="doc.amount_untaxed"/> The error occurred while rendering the template sale.document_tax_totals and evaluating the following expression: <span t-field="doc.amount_untaxed"/> ``` Cause ----- In the `sale.report_saleorder_document` template, `doc` is used as the variable name for the current sale order. Consequently, the studio edit uses this variable name to modify the `sale.document_tax_totals` template called within `sale.report_saleorder_document`. However, the `sale.sale_order_portal_template` template, used for the portal preview, also calls `sale.document_tax_totals` but uses `sale_order` as the variable name for the current order. Solution -------- Add an alias `doc` for `sale_order` during the rendering of `sale.document_tax_totals` when called in the portal report preview. opw-5136553
This fix ensures employees’ extra hours from attendance are correctly shown in the Time Off dashboard. It matters because managers and employees now see the full available balance, including hours earned through attendance, without missing data.
Original PR description
### Steps to reproduce: - Install Attendance and Time off apps - Create some attendance with extra hours for the employee - Go to the employee's time off dashboard - Notice Extra Hours allocation is not shown ### Cause: When we are getting the allocation data we check for the leave types that require allocation https://github.com/odoo/odoo/blob/5f6d2afa8c09fe72c01d056ebef01214567a4a99/addons/hr_holidays/models/hr_leave_type.py#L473 And then when checking the types that doesn't require allocation we are looping on the res that we got from the super which already excluded those types https://github.com/odoo/odoo/blob/5f6d2afa8c09fe72c01d056ebef01214567a4a99/addons/hr_holidays_attendance/models/hr_leave_type.py#L41-L43 ### Fix: We loop over the self leave types to make sure we are getting all of the employee's leave data whether the type requires allocation or not. opw-5042325
This fix ensures tax closing entries are linked to the right tax report, so generating a closing from a generic report or a national variant no longer creates confusing duplicate draft moves. It also makes sure that when several national variants exist, they all point back to the generic tax report for consistent behavior.
Original PR description
To reproduce the issue, on a Belgian company: 1) From the Generic Tax Report, or any of its two grouped variants (Account>Tax or Tax>Account), click on the closing entry button. It generates a draft…
To reproduce the issue, on a Belgian company: 1) From the Generic Tax Report, or any of its two grouped variants (Account>Tax or Tax>Account), click on the closing entry button. It generates a draft move. Log a note on that move. 2) Open the national tax report of Belgium, for the same period as in 1). Click on the closing entry button again. ==> The draft move generated in 2) is NOT the same as the one generated in 1) (you can check that from the note logged in 1)). This is because tax_closing_report_id is too naively set on the account.move, to always match the report on which the button was clicked. This commit fixes that, ensuring we set the right report in the closing field. Something will be done in the migration script to 19.0 to set the report properly before creating the returns. The problem also occurs when multiple national variants are available : in this case each of those reports creates a distinct closing entry, with the exact same informations, giving the illusion we're doing per-report closings. In such cases, we associate the closing move to the Generic tax Report. opw-4858689
This fix corrects the minimum rental period calculation so it no longer assumes every month has 30 days. Customers can now select valid rental dates in shorter months like February without the system rejecting them incorrectly.
Original PR description
Issue: Currently minimum rental duration uses a hardcoded 30 days. This cause issue for non-30 days month e.g. Feb. which is 28 days. To reproduce: 1- Install `website_sale_renting` 2- From Setting, set `Minimum Rental Duration` to 1 month. 3- Create a rental product and from website, choose the date: - 01/02/2026 - 28/02/2026 4- This fails. The earliest end date it accepts is 03/03/2026. Cause: This is due to hardcoded 30 days: https://github.com/odoo/enterprise/blob/7ffb9f3cb0d818cf3616d6972df424bf0ca251a4/website_sale_renting/static/src/js/renting_mixin.js#L7-L12 https://github.com/odoo/enterprise/blob/7ffb9f3cb0d818cf3616d6972df424bf0ca251a4/website_sale_renting/static/src/js/renting_mixin.js#L47-L53 We can use luxon plus method instead. ```diff + const minEndDate = startDate.plus(Object.fromEntries([[unit, duration]])); ``` In all usages of `msecPerUnit` we can do the same. Also we can keep remove `msecPerUnit` from master. opw-5094534