Monday, April 20, 2026
36 changes · saas-19.1
Resolved issues and error corrections
This update corrects a problem with the message right-click menu so it behaves as expected again. It helps users quickly access message options without interruptions or unexpected behavior.
The Dutch ICP report now uses the same downward integer rounding as the tax export. This keeps the reported amounts consistent and avoids confusing differences between the report and the exported figures.
Original PR description
Description of the issue this commit addresses: The Dutch tax authority lets ICP amounts be rounded down which is the behavior of the exports but not of the report itself meaning the values to not match and is quite confusing. --- Desired habevior after this commit is merged: The integer rounding DOWN is added on the ICP report to restore matching values --- task-6065382 Forward-Port-Of: odoo/enterprise#112953
This fix allows Belgian companies to change their fiscal localization from Companies to Associations and Foundations without failing during the chart update. It removes hidden links to old accounting settings first, so the change completes successfully and existing cash rounding remains intact.
Original PR description
### Issue before this commit: Switching the fiscal localization of a Belgian company from "Companies" to "Associations and Foundations" caused a traceback during the chart reload process. The…
### Issue before this commit:
Switching the fiscal localization of a Belgian company from "Companies" to "Associations and Foundations" caused a traceback during the chart reload process. The operation failed because some accounts from the previous localization could not be deleted.
### Steps to reproduce the issue:
1. Download Accounting
2. Create a new Belgian company
3. Switch to that company
4. Go into Settings -> Fiscal Localization
5. Switch to Associations and Foundations
6. Traceback: The operation cannot be completed: Another model is using the record you are trying to delete. The troublemaker is: 'Account Cash Rounding' (account.cash.rounding). Thanks to the following constraint: 'Profit Account' (profit_account_id). How about archiving the record instead?
### Cause of the issue:
The Belgian localization creates a default cash rounding method ("Round to 0.05") linked to specific profit and loss accounts. When switching localization, it was tried to delete the old chart of accounts, but these accounts are still referenced by account.cash.rounding through profit_account_id and loss_account_id, which use ondelete='restrict'. This prevents account deletion and blocks the localization change. Commit that caused the issue: https://github.com/odoo/odoo/commit/412fc9bed36645dd950c9a60d9b6ffdd9b4bce67
### Reason to introduce the fix:
Before reloading the Belgian chart template, the fix clears the profit_account_id and loss_account_id on the existing cash rounding records. This removes the blocking references, allows the old accounts to be deleted safely, and lets the fiscal localization switch complete successfully without affecting existing cash rounding configurations.
opw-6050537
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fix prevents Mercado Pago webhook calls from failing when the linked invoice reference contains slashes, such as INV/2026/00001. As a result, payments and invoice updates can be processed correctly instead of being rejected with a 404 error.
Original PR description
Currently, the mercado_pago_webhook http route only takes into consideration 1 url segment. This means that invoices with references like INV/2026/00001 don't match any defined route and the server returns a 404. /payment/mercado_pago/webhook/S00001 => OK /payment/mercado_pago/webhook/INV/2026/00001 => KO This commit allows references with slashes to be matched by the route by capturing the entire remaining url path including the slashes. /payment/mercado_pago/webhook/S00001 => OK /payment/mercado_pago/webhook/INV/2026/00001 => OK opw-6035161 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259530 Forward-Port-Of: odoo/odoo#259378
This update corrects the appearance of contract-related buttons on the employee form so they display consistently with the rest of the interface. It also prevents the “New Contract” label from wrapping awkwardly on smaller screens, improving readability and usability.
Original PR description
- Add `text-nowrap` to the "New Contract" button to prevent text from splitting at narrow viewport widths - Fix contract template button styling: remove incorrect classes and align font-size and border with the surrounding UI task-6068488 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 prevents a checkout failure that could happen when buying an event booth using a company account. If one of the company’s contacts already has an active user, Odoo now avoids archiving that partner incorrectly, so payment can complete normally.
Original PR description
Use case: - considering a database where `website_event_booth_sale` is installed - considering a company (ACME Corp., email: info@acme.example.net) and it's contact `Roger` (which have a valid user). then: - As an anonymous user, go to an event with some booth to register - register a booth and enter the company information (important: use the company email: info@acme.example.net, this way the cart is created the company as the `partner_id` !!!) - you are redirected to the cart - try to pay it, and upon payment you have the following error: ``` You cannot archive contacts linked to an active user. You first need to archive their associated user. ``` This commit ensure we also check if any contact of the commercial partner have any user before trying to archive them all. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change prevents time off-related calendar events from being shown as suggestions in the Timesheet Assistant. It helps users avoid confusing or incorrect entries when reviewing timesheets for a day with approved time off.
Original PR description
Steps to Reproduce:
---
1. Book a time off for any day via the Time Off app.
2. Open the Timesheets app for that same day.
3. Open the Timesheet Assistant suggestions panel.
Current Behavior:
---
The assistant surfaces the calendar event generated by the Time Off app as a
timesheet suggestion, e.g."Calendar Event - Mitchell Admin on Time Off : 1 days"
Expected Behavior:
---
Calendar events created by time off requests should not appear as
timesheet suggestions.
Issue:
---
The get_calendar_events getter in timesheet_grid_calendar fetched all calendar event
for the user without filtering by res_model, so time off meetings were included.
Fix:
---
Add ("res_model", "!=", "hr.leave") to the calendar.event search
domain.
task-6117932The contract template button on employee forms now matches the surrounding interface better. This fixes an inconsistent appearance by removing incorrect styling classes and aligning the button’s text size and border with the rest of the page.
Original PR description
Fix contract template button styling: remove incorrect classes and align font-size and border with the surrounding UI task-6068488
This fix prevents discounts on optional sales lines from being recalculated unexpectedly when portal users change quantities. It helps preserve the intended pricing shown to customers and avoids discount values being reset during updates.
Original PR description
Issue: --- Discount compute depends on `product_uom_qty`. On optional lines, this recompute will reset the discount on lines, when portal user updates the quanity. Cause: --- `discount` needs to depend on `product_uom_qty` because discount needs to be computed based on the quantity due to pricelist rules. Fix: --- We can prevent this compute if the quantity update comes from portal. opw-6078083 Forward-Port-Of: odoo/odoo#259696
This change prevents an employee payroll field from being calculated too early, before the necessary payslip data exists. As a result, Belgian holiday pay values are now computed at the right time, avoiding incorrect results and test failures.
Original PR description
…ield The computed, non-stored field `l10n_be_holiday_pay_recovered_n1` had tracking enabled. When writing to any field on the employee, the `write` method calls `_track_prepare` for tracked fields if `mail_notrack` is not set in the context. `_track_prepare` reads the current value of tracked fields to store initial values. Because `l10n_be_holiday_pay_recovered_n1` is non-stored with no dependencies, this triggered a computation at the very beginning of the test, before payslips existed. Later, when payslips were created, the field was never recomputed, causing incorrect values and test failures. Previously, the `tracking_disable` context prevented early computation. The fix removes the tracking attribute entirely, so the field is only computed when accessed, avoiding premature reads and fixing the tests. task: 6095445 Forward-Port-Of: odoo/enterprise#114063 Forward-Port-Of: odoo/enterprise#113015
This change corrects a barcode value used in an automated Point of Sale test so it matches the barcode format expected by the scanner. It helps ensure the test accurately reflects real scanning behavior and prevents false failures in the POS test suite.
Original PR description
The test_GS1_pos_barcodes_scan was failing because the "GS1 Variant Product" barcode was defined as a 13-digit string, while the tour scans it using the GS1 AI 01 (GTIN), which expects a 14-digit GTIN-14. By adding a leading zero to the barcode in the test setup, we align it with the GTIN-14 format parsed by the POS barcode parser during the scan, ensuring the product is correctly added to the order. runbot-error: 242323 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258089
The rental report now shows the correct date on each daily line for rental orders. This fixes a display issue where every line was using the same start date, making the report harder to read and less accurate.
Original PR description
The rental report is a daily report with x rows by rental order, with x the days between the start and return dates. With generate_series inside the select, the query was creating x rows with the same id, resulting in the date field not being correctly displayed (one unique date, the start date). This fix corrects the generation of the report to display the real date on each row. opw-5266525 Forward-Port-Of: odoo/enterprise#106088 Forward-Port-Of: odoo/enterprise#104764
This change adds the product unit of measure to the information sent to ECPay, so invoice lines are easier to understand. It helps customers and support teams see what the quantity refers to when reviewing the resulting document.
Original PR description
Issue: -- The documents returned by the ECpay API can be confusing as it does not include the measurement (UOM). The make it clearer a description is provided to ECpay through the json with the Key "ItemRemark" Current behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 Expected behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 商品單位: Units opw-6070269 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259536
The color picker now stays open when users change the color of an inserted icon. This fixes a frustrating issue in the note editor where hovering a color would close the picker immediately instead of applying the selection.
Original PR description
Commit [1] did already fix this problem, but commit [2] broke it again. This commit restores the condition that was removed by [2] but adapts it slightly in order to only take into account the direct children of the node, instead of any sub-node when checking for the presence of icons. Steps to reproduce: - Go to a "To do" note - Insert an icon with /media - Select the icon - Open the color picker - Hover a color => Color picker closed right away [1]: https://github.com/odoo/odoo/commit/1adfd9b9daf09c26ad642faf411574123110b9be [2]: https://github.com/odoo/odoo/commit/85688ffd11a3a988bf32c8c923a4628a89b57f87 task-6128069 Forward-Port-Of: odoo/odoo#259644
The BoM Overview now handles companies that do not yet have a warehouse configured, instead of showing an error. In that case, product availability is shown as not available, which keeps the overview usable and avoids a blocked workflow.
Original PR description
**Steps to Reproduce:** - Install MRP module. - Create a new company and switch to it. - Create a new BoM. - Click on the "BoM Overview" smart button. **Error:** `IndexError - list index out of range` **Cause:** When a new company is created, no warehouse is automatically generated for it. If no warehouse is configured for the company, the list is empty, causing an error. **Fix:** This commit raises a redirection warning if no warehouse is linked with the company. sentry-7286332859 Forward-Port-Of: odoo/odoo#250602
This update prevents duplicate payment instruction IDs in SEPA files when one payslip is split across multiple bank accounts. It helps ensure payment files comply with bank requirements and avoids export issues, while leaving single-account salary payments unchanged.
Original PR description
### Issue: If a payslip is split into multiple bank accounts (Salary Allocation), the generated SEPA file contains duplicate <InstrId> tags ### Cause: The `_get_payments_vals` method, `InstrId` is…
### Issue: If a payslip is split into multiple bank accounts (Salary Allocation), the generated SEPA file contains duplicate <InstrId> tags ### Cause: The `_get_payments_vals` method, `InstrId` is based on the payslip ID When a single payslip generates multiple transaction blocks, this ID is duplicated, violating the ISO 20022 requirement for unique instruction identifiers https://knowledge.xmldation.com/support/iso20022/general_rules/instrid This commit adds a unique suffix (e.g., -1, -2) to the `InstrId` for each transaction generated from the same payslip to ensure technical uniqueness Nothing change when you only have one account This is the part of the code that use the payment name: https://github.com/odoo/enterprise/blob/194a8d35ef3e9b47ff566479b0c35c0f963fb42d/account_iso20022/models/account_journal.py#L294-L299 ### Steps to reproduce: - Install `hr_payroll_account_iso20022` with demo data - On the Bank Journal, set a valid IBAN (e.g. BE04957751619131) for `Bank Account Number` - Open the Employee page for Abigail Peterson - In the Personal tab, add 2 Bank Accounts (Send Money: True, Account Number: any) - Click on Salary Allocation and Save (You'll have a 50/50 ratio) - Create a new Pay Run (for Abigail Peterson) - Open the last PaySlip and Validate - Create Payment Report (Export Format: SEPA) - Download the Payment Report and check the <InstrId> tags opw-6069670 Forward-Port-Of: odoo/enterprise#113113
There were some translation overrides for `fr_BE` and `fr_CA` that were incorrect or unnecessary. We are deleting these files so they use the correct translations in `fr` instead. In the `nl_BE` translation, we are fixing a menu item so it is shorter, but still correct. task-5921458 Forward-Port-Of: odoo/enterprise#114069 Forward-Port-Of: odoo/enterprise#106998
Original PR description
There were some translation overrides for `fr_BE` and `fr_CA` that were incorrect or unnecessary. We are deleting these files so they use the correct translations in `fr` instead. In the `nl_BE` translation, we are fixing a menu item so it is shorter, but still correct. task-5921458 Forward-Port-Of: odoo/enterprise#114069 Forward-Port-Of: odoo/enterprise#106998
LinkedIn account imports now skip image records that do not include a download link instead of crashing. This prevents the connection process from stopping unexpectedly and helps more LinkedIn accounts connect successfully.
Original PR description
When importing a LinkedIn account, Odoo fetches the image metadata of the organization page and expects each returned image to contain `downloadUrl`. For some LinkedIn accounts this key is missing from the image response, which makes the callback crash with `KeyError: 'downloadUrl'` and prevents the account from being connected. LinkedIn's current Images API documentation describes `downloadUrl` as an optional field, so the import flow should not assume it is always present. This patch skips image entries without `downloadUrl` instead of crashing. opw-6099244 Forward-Port-Of: odoo/enterprise#113812
The CRM onboarding tour was adjusted so the extra lead-generation steps run at the end instead of in the middle. This prevents the tour from getting stuck repeating steps, making the guided experience more reliable for users.
Original PR description
The crm_iap_mine module extended the crm tour, by adding steps to introduce the lead generation feature. These steps were inserted in the middle of the tour, which caused the tour to backtrack and…
The crm_iap_mine module extended the crm tour, by adding steps to introduce the lead generation feature. These steps were inserted in the middle of the tour, which caused the tour to backtrack and loop on itself. Why? For the tour to wait for the next step, we specify the selectors it should look for. In this case, because the modal redirects to the same page (with an updated domain), we cannot specify a selector that would be unique to the new page -> the target is found before the redirect -> after the redirect happens, the tour backtracks to try and recover, causing the loop. Moving the steps to the end of the tour fixes the issue. The disadvantage of this is that no the last step of the tour is not deterministic - it can fail if the user selects a combination of countries and industries which have no valid leads (Antarctica...) or if the user doesn't have enough IAP credits. In this case, the 'Congrats' rainbowman is shown even if the generation failed. Task-5386684 Forward-Port-Of: odoo/odoo#249733
Fixed an issue that could stop password reset instructions from being sent when several users were selected at once. This makes the user management flow more reliable and avoids an unexpected error during a common admin action.
Original PR description
Currently, an error occurs when sending the password reset link to multiple users. **Steps to Reproduce:** - Install `auth_signup` module. - Go to `Users` and make sure there are at least two user…
Currently, an error occurs when sending the password reset link to multiple users.
**Steps to Reproduce:**
- Install `auth_signup` module.
- Go to `Users` and make sure there are at least two user records.
- In the `list view`, select both users.
- Go to `Actions` > click `Send Password Reset Instructions`.
`ValueError: ValueError('Expected singleton: res.users(24, 23)') while evaluating 'records.action_reset_password()'`
This error occurs when generating the email body_html [1]. It passes multiple user
records (self) as the context record, but _render_encapsulate expects a single user
record to render the email body. which raise the error here[2].
This commit passes a single user record when rendering body_html.
[1]: https://github.com/odoo/odoo/blob/39c6e3a2578c4f7058dddb6acf12231d8716e7fd/addons/auth_signup/models/res_users.py#L214
[2]: https://github.com/odoo/odoo/blob/39c6e3a2578c4f7058dddb6acf12231d8716e7fd/addons/mail/models/mail_render_mixin.py#L187
sentry-7271437735
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prClicking a partner mention now opens the profile page and closes the avatar preview popover at the same time. This avoids having the preview stay on screen after the user has already moved on to viewing the full profile.
Original PR description
**Current behavior before PR:** Clicking on a partner mention opens the avatar card popover. When the **View Profile** button is clicked, the partner form view opens, but the popover remains visible. This happens because the popover opened via `onClickPartnerMention` uses the popover service directly, instead of the `usePopover` hook, which automatically closes the popover when the component is unmounted. **Desired behavior after PR is merged:** Clicking the **View Profile** button opens the partner form view and closes the avatar card popover. task-[6063906](https://www.odoo.com/odoo/project/1519/tasks/6063906) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256283
The Reference field in Inventory Move History was editable in the interface even though changes were not actually saved. This update makes the field read-only so users no longer see edits that cannot be kept, avoiding confusion and improving data consistency.
Original PR description
### Issue before this commit: Before this commit, the Reference field displayed on stock.move.line was editable in the user interface, even if the modification made by the user was not persisted.…
### Issue before this commit: Before this commit, the Reference field displayed on stock.move.line was editable in the user interface, even if the modification made by the user was not persisted. After saving and reloading the Move History view, the original value was restored. ### Steps to reproduce the issue: 1. Go to Move history in Inventory app 2. Try to change the name of a line and save 3. If you go back to the Move history you can see that the name is not changed ### Cause of the issue: The issue was caused by a mismatch between the stock.move.line.reference field and its target field stock.move.reference. The field on stock.move.line is a related field that appears editable (readonly=False), but the underlying stock.move.reference field was not writable. As a result, user could edit the field but the modifications were ignored, preventing changes from being effectively saved. ### Reason to introduce the fix: The fix ensures that the reference field in stock.move and in stock.move.line are readonly. opw-6055708 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256434
This update stops invoice creation from failing when aggregate withholding is enabled but its period has been cleared. The required period is now enforced so users cannot save an incomplete setup that would later cause an error.
Original PR description
Previously, if `is_aggregate_limit` was set to True while `aggregate_period` was left empty, it would raise a traceback during invoice creation. Although `aggregate_period` has a default value, it can still be manually cleared. With this commit, `aggregate_period` is enforced as mandatory whenever `is_aggregate_limit` is enabled, preventing such errors. Forward-Port-Of: odoo/odoo#259737 Forward-Port-Of: odoo/odoo#259634
This change improves how the “Search More” option works in accounting and tax selection fields. It uses existing search context instead of building filters manually, which makes the search more reliable and easier to maintain.
Original PR description
This commit replaces the use of creating dynamicFilters while doing "Search More" in the account and tax widget. It now simply updates the context to search default name instead of creating a filter domain manually for that. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259835
This update removes extra blank lines at the start and end of messages before they are sent. It helps ensure customer and internal messages look cleaner and more professional.
Original PR description
Trim the leading and trailing empty lines in the message body before sending it to avoid unwanted empty lines at the beginning and end of messages. task-6027013 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259136