Daily updates from Odoo
Tuesday, November 18, 2025
207 changes
22 changes
Resolved issues and error corrections
This change makes the web client more resilient when a browser no longer exposes the platform information it used to provide. By checking for the feature instead of assuming it is always present, Odoo avoids unnecessary errors and improves compatibility with modern browsers.
Original PR description
This commit uses "Feature detection" to avoid some error when the platform key is not available from navigator. > The platform property indicates the platform/OS the browser is running on. > Theoretically this information is useful for detecting the browser and serving code to work around browser-specific bugs or lack of feature support. However, this is unreliable and is not recommended for the reasons given in User-Agent reduction and Browser detection using the user agent. > Feature detection is a much more reliable strategy. https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Testing/Feature_detection task-4420689 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235958
This fix corrects where the QRIS payment fields are placed on the bank account form so they appear consistently. As a result, users in Indonesia can now see and complete the QRIS API key and MID fields when needed.
Original PR description
**Description of the issue/feature this PR addresses:** This issue occurs because the XPath targeting the `currency_id` field is placed inside a `<div>` that becomes invisible under certain conditions. The `view_partner_bank_form_inherit_hr` view is loaded first due to its sequence, and the `l10n_id` view is applied afterward, causing the QRIS fields to be inserted into that hidden `<div>` from `view_partner_bank_form_inherit_hr`. **Current behavior before PR:** The fields l10n_id_qris_api_key and l10n_id_qris_mid are not visible. **Desired behavior after PR is merged:** The fields l10n_id_qris_api_key and l10n_id_qris_mid are visible by changing XPath target Task: [5247678](https://www.odoo.com/odoo/project.task/5247678) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235949
This update prevents an error when shoppers switch between product variants on subscription-enabled products in the online store. If pricing data is missing, the system now handles it safely instead of triggering a page traceback, improving storefront reliability.
Original PR description
Step to reproduce: - install website_sale_subscription - create a product, add few variants and tick 'Subscriptions' option. - open that product from /shop - toggle between variants Cause: - In case the pricing is not present, 'False' is passed(not an iterable) - `_onChangeCombinationSubscription` expects a iterable, causing traceback Fix: - we pass empty list instead of False opw-5241612 Forward-Port-Of: odoo/enterprise#99160
This update prevents Belgian tax report generation from failing during migration when a company’s fiscal year ends on February 29. It now calculates the start date correctly for any year, so reports continue to generate without errors, including in leap-year-related setups.
Original PR description
``` File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate generate_or_refresh_all_returns(company) File…
```
File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate
generate_or_refresh_all_returns(company)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 228, in _generate_or_refresh_all_returns
self._generate_all_returns(fiscal_country.code, company, domestic_tax_unit)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 24, in _generate_all_returns
super()._generate_all_returns(country_code, main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 281, in _generate_all_returns
report_type._try_create_returns_for_fiscal_year(main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 353, in _try_create_returns_for_fiscal_year
period_date_from, period_date_to = self._get_period_boundaries(main_company, date_pointer)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 530, in _get_period_boundaries
start_day, start_month = self._get_start_date_elements(company_id)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 16, in _get_start_date_elements
fiscal_year_date = date(2025, int(main_company.fiscalyear_last_month), main_company.fiscalyear_last_day)
ValueError: day is out of range for month
```
```
(Pdb) main_company
res.company(3,)
(Pdb) main_company.fiscalyear_last_month
'2'
(Pdb) main_company.fiscalyear_last_day
29
(Pdb) date_from
datetime.date(2025, 3, 1)
```
- During the migration process the system calls [_generate_or_refresh_all_returns](https://github.com/odoo/upgrade/blob/e20a9e2edec4441b2c7aa5858db2a53fb2e9b215/migrations/account_reports/saas~18.3.1.0/end-account-returns.py#L340) which internally uses [_get_start_date_elements](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L14) to compute the fiscal year start date.
- The customer has configured fiscalyear_last_month = February and fiscalyear_last_day = 29 Because of this configuration, the method attempts to construct 29th February 2025, which is invalid since 2025 is not a leap year. The issue occurs because the method uses a hardcoded year [(2025)](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L16) instead of determining the year dynamically.
- I reviewed implementations in other localizations and found that this logic has [1](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_uk_reports/models/account_return.py#L33), [2](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_nz_reports/models/account_return.py#L8) already been corrected there to compute the appropriate start date dynamically.
- I’ve updated this localization to follow the improved implementation used in other countries, so the start-date calculation now works correctly in all cases, including leap years and any fiscal year settings the customer may configure.
opw-5249243
Forward-Port-Of: odoo/enterprise#99353This change prevents an error when portal users open a shared project task and try to use the message box before the task is saved. It keeps the chatter inactive until the task has been created, avoiding a broken experience for collaborators.
Original PR description
Currently, an error occurs when a portal user opens a `shared project` and tries to `mention(@)` someone in the chatter of a `new(unsaved) task`. **Steps to produce:** - Install the `project` module.…
Currently, an error occurs when a portal user opens a `shared project` and tries to `mention(@)` someone in the chatter of a `new(unsaved) task`. **Steps to produce:** - Install the `project` module. - Open the project app and create a new project with at least one task. - From the project’s `dropdown menu(⋮)`, select `Share Project`. - Add a `collaborator: Joel Willis`, with `Edit access` mode, copy the public link, and click `Share Project`. - Open the shared link in an incognito window and sign in as a portal user. - Open the `project folder` > open any task > click `New` > type `'@'` in the chatter. **Error**: `ValueError: Expected singleton: project.task()` **Root cause:** The `composer(message box)` allows typing and mention suggestions even when the task record is not yet saved (`self.thread.id` is `undefined`). At [1], the method is called on an `empty` recordset, causing an `error`. **Fix:** This commit prevents users from writing in the chatter by stopping the composer initialization when the record(thread) is `unsaved`. [1]: https://github.com/odoo/odoo/blob/5cf96828652c2388808b3e49ae67e188c401ec63/addons/project/models/project_task.py#L2051-L2071 sentry-6982269693 Forward-Port-Of: odoo/odoo#235184
The employee org chart button now opens the Hierarchy view on mobile devices instead of the Kanban view. This makes the org chart work as expected on smaller screens and helps users quickly see reporting lines.
Original PR description
Steps to Reproduce: - Open an employee record. - Set managers for the employee. - Open the employee’s form view on mobile. - Click org chart stat button. Before: - On mobile, the org chart button opened the Kanban view by default. After: - On mobile, the org chart button now opens the Hierarchy view by default. task-5245129 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235228
This change prevents long product attribute values from spilling outside the product card in the catalog view. It keeps the layout tidy and consistent, so users can browse and select products without the screen becoming misaligned or harder to use.
Original PR description
Steps to reproduce: 1. Go to Products > Create a new product. 2. Add or create a new attribute with a long text value. 3. Go to Sales > Open any quotation. 4. In the sale order line, click on…
Steps to reproduce: 1. Go to Products > Create a new product. 2. Add or create a new attribute with a long text value. 3. Go to Sales > Open any quotation. 4. In the sale order line, click on "Catalog" and search for the created product. Issue: - The product image and attribute value text overflow outside the product card in the kanban view, causing layout misalignment and breaking the UI design. <img width="647" height="225" alt="image" src="https://github.com/user-attachments/assets/afc592bb-e25a-4d81-882b-0e7cc7ad1064" /> Cause: - The inner div containing the attribute text lacked overflow control, allowing long text to exceed the container width and pushing other elements. Solution: - Added the Bootstrap class `overflow-hidden` to the div element to ensure the image and text remain properly contained within the card layout. <img width="587" height="171" alt="image" src="https://github.com/user-attachments/assets/580ce1e5-42bd-4c2d-b6bf-14315759626d" /> opw-5222002 Forward-Port-Of: odoo/odoo#235680 Forward-Port-Of: odoo/odoo#235214
This update fixes an issue on mobile websites where a hidden mega menu could still block taps on the page. As a result, customers can reopen the menu normally after closing it, improving the browsing experience on mobile devices.
Original PR description
Steps to reproduce: ==================== 1. Add a mega menu. 2. Add effects to the mega menu columns ex (Animation on appearance, Fade, direction from bottom) 3. Switch the website display to mobile view. 4. Click on the mega menu. 5. Go back and try to click again. → The mega menu cannot be opened again. Cause: ====== When the mega menu is hidden, its section remains in the DOM and still captures pointer events. As a result, clicks on the screen (including attempts to reopen the mega menu) are intercepted by the hidden element instead of reaching the intended target. Solution: ========= Disable pointer events on the mega menu section once it is hidden to ensure subsequent clicks behave correctly. opw-5129316 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233636
This change removes an overly strict rule that prevented some tax groups from being copied or edited if their linked payable or receivable accounts had a different type. It makes the system more flexible while still allowing users to adjust account types afterward if needed.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Community PR:** https://github.com/odoo/odoo/pull/235548 opw-5231379 Forward-Port-Of: odoo/enterprise#99421
This update removes an overly strict rule on tax group accounts, so users can again reuse, change, or copy tax groups even if the linked accounts were adjusted before. It makes the system more flexible while still allowing account types to be changed after selection when needed.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Enterprise PR:** https://github.com/odoo/enterprise/pull/99421 opw-5231379 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235548
The salary configurator no longer rewrites the contract template when creating a new version. This prevents missing recalculations and helps ensure contract-related values update correctly.
Original PR description
Writing the contract template on the new version created by the salary configurator is not necessary and caused some computes to not trigger.
This update fixes several Viva Wallet payment issues in Point of Sale, including incorrect payment matching when multiple terminals are used at once, payments affecting the wrong order, and payments getting stuck after a page refresh. It makes confirmations more reliable so customers and staff see the correct payment status.
Original PR description
This commit fixes various issues when using Viva Wallet, including the following: - When two Viva Wallet terminals had a payment in process at the same time in the same POS, one of the payments would…
This commit fixes various issues when using Viva Wallet, including the following: - When two Viva Wallet terminals had a payment in process at the same time in the same POS, one of the payments would fail on Odoo even when it succeeded on the terminal. - When a previous Viva Wallet payment was stuck (never completed or failed), trying to make a new payment would mistakenly affect that previous order instead of the new order. - When refreshing the page during a payment, it becomes stuck and never confirms or fails. To fix these issues, there are two main changes: 1. Stop using the `getPendingPaymentLine` method to retrieve the Viva Wallet payment line. This method is flawed as it assumes there is only one pending payment at a time. 2. Store the Viva session ID for a payment in the payment line's UI state, instead of on the plain JS object. This allows it to persist after a refresh. opw-5226966 opw-5248178 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236004 Forward-Port-Of: odoo/odoo#235695
This update prevents an error that could appear when opening a stock quantity record without a location selected. It makes the Inventory screen more reliable by handling incomplete records safely instead of crashing.
Original PR description
Currently, an error is produced when accessing the stock quant form view without a location set. **Steps to Reproduce:** 1. Install the Inventory module. 2. Create a product with tracking enabled (By Unique Serial Number). 3. Click **"Update Quantity"** (opens list view). 4. Click **New**, click View on the unsaved record (opens form view). 5. Remove the Location field. **Error:** `TypeError - sequence item 0: expected str instance, bool found` **Cause:** In the display name computation at [1], the system attempts to join name parts where one of them can be `False` if the location is not set. **Fix:** Before generating the display name, it now checks whether the record is saved (record.ids). If the record is unsaved (no ID), it sets an empty `display_name` and skips the name-joining logic. [1] - https://github.com/odoo/odoo/blob/16e889bf5885c4d827b8c2c5dce102f98aad689f/addons/stock/models/stock_quant.py#L599 sentry-6717759358 Forward-Port-Of: odoo/odoo#234552
The POS floor plan will now only show booking notifications for the appointment type configured in that POS setup. This prevents incorrect bookings from appearing briefly and disappearing after refresh, making table management more reliable for staff.
Original PR description
Task: [#5005216](https://www.odoo.com/odoo/my-tasks/5005216) Enterprise v17.0: [#93714](https://github.com/odoo/enterprise/pull/93714) --- **Before:** If no appointment type is specified in the POS config and a table is booked via the website, the floor plan is notified of a new booking because the resource used is one of the POS config resources. However, if the page is refreshed, the booking disappears since no appointment type is defined in the POS config **After:** The floor plan is notified of a new booking only if the appointment type of the booking matches the one specified in the POS config. If no appointment type is set in the POS config, no booking notifications are sent. Additionally, when the "Table Booking" field is unchecked in the POS config, the appointment type is automatically unset. Forward-Port-Of: odoo/enterprise#98887 Forward-Port-Of: odoo/enterprise#93636
This update prevents hidden line breaks from being included in Swiss QR code fields. That helps ensure the QR code is formatted correctly and accepted by banks or payment systems.
Original PR description
Swiss QR codes have required information for each line of the QR code. Newline characters present in a field's content shift the content to a different line than intended, causing the QR code to be rejected. This commit removes newline characters from the field elements and alters a unit test to check if this issue occurs again. opw-5095997 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233880
This update fixes the Reviews smart button on employee profiles so it now shows the relevant contract review records instead of an empty page. It restores the expected behavior for both active and inactive records, making it easier to review employee contract history.
Original PR description
Issue:
When an offer is created and signed by the employee, the `Reviews` smart button appears on the employee profile. Although it indicates that there are records, clicking the button redirects to an empty list.
Reason:
After converting contracts to the versioning system, the action for the Reviews button does not properly display contract versions, regardless of whether they are active or inactive, as it did in the previous version.
Fix:
Added a context `{"active_test": False}` to show active or inactive records.
task-5155455This change fixes an issue where imported French accounting entries could stop being automatically reconciled in some accounts after a previous reconciliation. It helps ensure the matching process works consistently, so imported records are reconciled as expected and accounting data stays in sync.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit provides a test to reproduce this issue. opw-5086823 Forward-Port-Of: odoo/enterprise#98855
Odoo now matches Mollie’s actual account setup more closely by no longer enabling iDEAL as a default payment option for new Mollie accounts. It also removes Sofort from the linked payment methods because that payment method has been deprecated by Mollie, helping avoid confusion and unsupported options.
Original PR description
**[FIX] payment_mollie: remove iDEAL from the default payment methods** When a new Mollie account is created, it only accepts card payments out of the box. In Odoo, both the Cards and iDEAL payment methods were activated by default upon enabling the payment provider, while iDEAL required manual activation from Mollie's dashboard. --- **[FIX] payment_mollie: remove Sofort from the linked payment methods** See https://help.mollie.com/hc/en-us/articles/20904206772626-SOFORT-Deprecation-30-September-2024ard. Forward-Port-Of: odoo/odoo#236044
This change prevents imported accounting entries from losing their import-related matching markers too early. As a result, automatic reconciliation now works correctly for all relevant entries, even when similar imported items exist on different accounts.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the…
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit aims to fix that by removing amls imported matching number (starting with "I") from the reconciled amls to consider. opw-5086823 Forward-Port-Of: odoo/odoo#234481
This change fixes an issue where Bancontact payments could be marked as failed when the customer needed to complete an extra verification step. With this update, those payments stay pending during the check, so the customer can finish the payment normally and avoid unnecessary errors.
Original PR description
When paying with Bancontact, in case a 3DS validation is required (challenge flow), Wordline will send a webhook (see below) to indicate that an external (asynchronous) validation was requested.…
When paying with Bancontact, in case a 3DS validation is required (challenge flow), Wordline will send a webhook (see below) to indicate that an external (asynchronous) validation was requested.
Example of recevied webhook:
```
{
'apiFullVersion': 'v1.1',
'apiVersion': 'v1',
...
'payment': {
'status': 'AUTHORIZATION_REQUESTED',
'statusOutput': {
'isAuthorized': False,
'isCancellable': False,
'isRefundable': False,
'statusCategory': 'PENDING_CONNECT_OR_3RD_PARTY',
'statusCode': 51
}
},
'type': 'payment.authorization_requested'
}
```
Since efc2788dfccd, when receiving such webhook we set the transaction as error then force the user flow to `redirect`; this was done to handle payment w/ token (`online_token`) where a 3DS challenge is still required.
But for Bancontact - which is non-tokenizable - we will always be in the "redirect" mode, so we must keep the transaction as `pending`.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#235847The VoIP app now avoids trying to reconnect when a page is being closed normally. This prevents a registration conflict that could cause errors during logout or when leaving the page, improving call service reliability.
Original PR description
On page unload, two conflicting things happen: - A REGISTER request with expires=0 is sent to invalidate the registration - The WebSocket disconnects, triggering the reconnection mechanism that attempts to reissue a registration These two concurrent and conflicting REGISTER requests result in the following error: > RequestPendingError: REGISTER request already in progress, waiting for final response This commit prevents the reconnection mechanism from occurring in the event of a "natural" disconnection, such as one triggered by a page unload. This way, the two conflicting REGISTER requests aren't sent on page unload. [Task-5261940](https://www.odoo.com/odoo/project/5778/tasks/5261940) Forward-Port-Of: odoo/enterprise#99560 Forward-Port-Of: odoo/enterprise#99376
This change fixes an intermittent issue in the manufacturing work order tour by making the “Add Component” flow more stable. It also ensures the intended product appears first, which helps the process run consistently during tests and for users following the same steps.
Original PR description
The search in the "Add Component" dialog caused a re-render race, making the tour ``test_add_component_from_shop_foor_in_multi_step_manufacturing`` fail intermittently. This fix removes the search steps and marks the “Courage” product as favorite so it appears first in the catalog. runbot-227694 Forward-Port-Of: odoo/enterprise#92403
14 changes
Resolved issues and error corrections
This update avoids a browser-side error when the system no longer provides the platform information the app previously checked. It makes the web client more resilient across browsers and devices by using a safer way to detect features instead of relying on browser-identification data.
Original PR description
This commit uses "Feature detection" to avoid some error when the platform key is not available from navigator. > The platform property indicates the platform/OS the browser is running on. > Theoretically this information is useful for detecting the browser and serving code to work around browser-specific bugs or lack of feature support. However, this is unreliable and is not recommended for the reasons given in User-Agent reduction and Browser detection using the user agent. > Feature detection is a much more reliable strategy. https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Testing/Feature_detection task-4420689 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235958
This fix corrects where two Indonesian QRIS configuration fields are inserted in the bank form, so they no longer end up inside a hidden section. As a result, users can now see and fill in the QRIS API key and MID when configuring local payment settings.
Original PR description
**Description of the issue/feature this PR addresses:** This issue occurs because the XPath targeting the `currency_id` field is placed inside a `<div>` that becomes invisible under certain conditions. The `view_partner_bank_form_inherit_hr` view is loaded first due to its sequence, and the `l10n_id` view is applied afterward, causing the QRIS fields to be inserted into that hidden `<div>` from `view_partner_bank_form_inherit_hr`. **Current behavior before PR:** The fields l10n_id_qris_api_key and l10n_id_qris_mid are not visible. **Desired behavior after PR is merged:** The fields l10n_id_qris_api_key and l10n_id_qris_mid are visible by changing XPath target Task: [5247678](https://www.odoo.com/odoo/project.task/5247678) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235949
This update prevents an error when customers switch between product variants on subscription items in the shop. If pricing information is missing, the system now uses an empty list instead of failing, which keeps the product page working smoothly.
Original PR description
Step to reproduce: - install website_sale_subscription - create a product, add few variants and tick 'Subscriptions' option. - open that product from /shop - toggle between variants Cause: - In case the pricing is not present, 'False' is passed(not an iterable) - `_onChangeCombinationSubscription` expects a iterable, causing traceback Fix: - we pass empty list instead of False opw-5241612 Forward-Port-Of: odoo/enterprise#99160
Users opening a shared project in the portal can now view a new task without the chatter causing an error. This change prevents the message box from activating until the task has been saved, avoiding a failed page action and improving stability for portal users.
Original PR description
Currently, an error occurs when a portal user opens a `shared project` and tries to `mention(@)` someone in the chatter of a `new(unsaved) task`. **Steps to produce:** - Install the `project` module.…
Currently, an error occurs when a portal user opens a `shared project` and tries to `mention(@)` someone in the chatter of a `new(unsaved) task`. **Steps to produce:** - Install the `project` module. - Open the project app and create a new project with at least one task. - From the project’s `dropdown menu(⋮)`, select `Share Project`. - Add a `collaborator: Joel Willis`, with `Edit access` mode, copy the public link, and click `Share Project`. - Open the shared link in an incognito window and sign in as a portal user. - Open the `project folder` > open any task > click `New` > type `'@'` in the chatter. **Error**: `ValueError: Expected singleton: project.task()` **Root cause:** The `composer(message box)` allows typing and mention suggestions even when the task record is not yet saved (`self.thread.id` is `undefined`). At [1], the method is called on an `empty` recordset, causing an `error`. **Fix:** This commit prevents users from writing in the chatter by stopping the composer initialization when the record(thread) is `unsaved`. [1]: https://github.com/odoo/odoo/blob/5cf96828652c2388808b3e49ae67e188c401ec63/addons/project/models/project_task.py#L2051-L2071 sentry-6982269693 Forward-Port-Of: odoo/odoo#235184
The employee org chart button now opens the Hierarchy view by default on mobile devices. This fixes an issue where mobile users were taken to the Kanban view instead, making the org chart harder to use.
Original PR description
Steps to Reproduce: - Open an employee record. - Set managers for the employee. - Open the employee’s form view on mobile. - Click org chart stat button. Before: - On mobile, the org chart button opened the Kanban view by default. After: - On mobile, the org chart button now opens the Hierarchy view by default. task-5245129 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235228
The activity counters in the top bar were sometimes counting every reminder on the same record instead of just the most urgent one. This fix restores the expected behavior so users see accurate late, today, and future counts for Tasks, To-dos, and Mailings.
Original PR description
Issue: When multiple activities were created on a single record (e.g., a Task, To-Do, or Mass Mailing), the systray counters for late/today/future activities would incorrectly count *all* of them. The standard behavior is to count only one (the most urgent) per record. Cause: Modules that split activity groups: `project` (for Tasks/To-Dos) and `mass_mailing` (for Email/SMS), used custom counting logic. This logic was outdated and did not follow the "one count per record" rule. Solution: Refactor the custom activity-grouping logic to make the count conform to the general rule again. This aligns all systray counters, ensuring Tasks, To-Dos, and Mailings are now correctly counted only once, based on their most urgent activity. Task-5059640
This update removes hidden line breaks from Swiss QR code fields so each piece of information stays on the correct line. It helps prevent QR codes from being rejected when they are generated, improving reliability for payments in Switzerland.
Original PR description
Swiss QR codes have required information for each line of the QR code. Newline characters present in a field's content shift the content to a different line than intended, causing the QR code to be rejected. This commit removes newline characters from the field elements and alters a unit test to check if this issue occurs again. opw-5095997 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233880
This update removes an overly strict rule on tax group accounts, so users can again reuse, change, or copy tax groups even if the linked accounts have a different type. It makes account setup more flexible while keeping the existing ability to adjust the account type afterward.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Enterprise PR:** https://github.com/odoo/enterprise/pull/99421 opw-5231379 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235548
We fixed an issue on mobile where a hidden mega menu could still block taps on the page. This ensures users can reopen the menu normally after closing it, improving website navigation on phones and tablets.
Original PR description
Steps to reproduce: ==================== 1. Add a mega menu. 2. Add effects to the mega menu columns ex (Animation on appearance, Fade, direction from bottom) 3. Switch the website display to mobile view. 4. Click on the mega menu. 5. Go back and try to click again. → The mega menu cannot be opened again. Cause: ====== When the mega menu is hidden, its section remains in the DOM and still captures pointer events. As a result, clicks on the screen (including attempts to reopen the mega menu) are intercepted by the hidden element instead of reaching the intended target. Solution: ========= Disable pointer events on the mega menu section once it is hidden to ensure subsequent clicks behave correctly. opw-5129316 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233636
This fix removes an overly strict rule on tax group accounts, so users can again reuse, change, or copy tax groups even if the linked accounts had a different type. It makes the tax setup more flexible without blocking normal editing workflows.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Community PR:** https://github.com/odoo/odoo/pull/235548 opw-5231379 Forward-Port-Of: odoo/enterprise#99421
Odoo now only enables the payment methods that a new Mollie account supports by default. It also stops linking Sofort, which Mollie has deprecated, so merchants see fewer setup issues and avoid exposing unavailable payment options.
Original PR description
**[FIX] payment_mollie: remove iDEAL from the default payment methods** When a new Mollie account is created, it only accepts card payments out of the box. In Odoo, both the Cards and iDEAL payment methods were activated by default upon enabling the payment provider, while iDEAL required manual activation from Mollie's dashboard. --- **[FIX] payment_mollie: remove Sofort from the linked payment methods** See https://help.mollie.com/hc/en-us/articles/20904206772626-SOFORT-Deprecation-30-September-2024ard. Forward-Port-Of: odoo/odoo#236044
This change stops the Stock Quantity form from crashing when a location is not set, especially in new or unsaved records. It improves reliability for Inventory users by allowing the form to open and be edited normally instead of showing an error.
Original PR description
Currently, an error is produced when accessing the stock quant form view without a location set. **Steps to Reproduce:** 1. Install the Inventory module. 2. Create a product with tracking enabled (By Unique Serial Number). 3. Click **"Update Quantity"** (opens list view). 4. Click **New**, click View on the unsaved record (opens form view). 5. Remove the Location field. **Error:** `TypeError - sequence item 0: expected str instance, bool found` **Cause:** In the display name computation at [1], the system attempts to join name parts where one of them can be `False` if the location is not set. **Fix:** Before generating the display name, it now checks whether the record is saved (record.ids). If the record is unsaved (no ID), it sets an empty `display_name` and skips the name-joining logic. [1] - https://github.com/odoo/odoo/blob/16e889bf5885c4d827b8c2c5dce102f98aad689f/addons/stock/models/stock_quant.py#L599 sentry-6717759358 Forward-Port-Of: odoo/odoo#234552
When a manufacturing work order is already in progress, adding a product in the component tab now correctly creates the related move line. This ensures the extra component is tracked properly and avoids gaps between what was added on the order and what is recorded for production.
Original PR description
_______________________________________ ## Short functional explanation of the error After starting a work order on a manufacturing order, it is possible to add products in the component tab.…
_______________________________________ ## Short functional explanation of the error After starting a work order on a manufacturing order, it is possible to add products in the component tab. However, the corresponding move line won't be created. ## Reproduction Steps 1. Create a Bom for a product. Set a component and an operation. 2. Create a new Manufacturing order. Select a product and a quantity. The corresponding components and work order should fill automatically. 3. Click on confirm. Click on Work Orders tab and start the timer. 4. Add a new line with a product already in the form. ### Expected behavior When clicking on Product Move, an additional move line should be present. ### Unexpected behavior No new move line is created. ## Origin of the issue In the file stock_move.py, a check is performed to change the state of the move. https://github.com/odoo/odoo/blob/0a1f10929cc6bd20012d2060493b86ee2a20befc/addons/stock/models/stock_move.py#L2158-L2159 However, it doesn't take into account this corner case, as it automatically sets the move at assigned, which prevents the move to be created. Indeed, in order to be created, the code has to go through this: https://github.com/odoo/odoo/blob/0a1f10929cc6bd20012d2060493b86ee2a20befc/addons/mrp/models/mrp_production.py#L1354-L1356 _________________________________________ opw-5034409 --- --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When an activity is created automatically, it will now always be assigned to a user instead of sometimes remaining unassigned. This avoids unclear ownership and helps ensure automated tasks are visible and actionable right away.
Original PR description
**Steps to reproduce:** - Install base_automation, sale_management, and stock. - Create an automation rule for the Transfer model (stock.picking) that creates an activity when the state is set to…
**Steps to reproduce:** - Install base_automation, sale_management, and stock. - Create an automation rule for the Transfer model (stock.picking) that creates an activity when the state is set to Ready. - User type → Dynamic user (based on record) - User field → Responsible - Confirm a Sale Order and open the related delivery. - Move delivery to the Ready state. - Notice that the created activity has no assigned user. **Issue:** - The activity is created without a user_id. **Cause:** - Since user_id is no longer a required field on mail.activity, when creating an activity through automation, if the related record (e.g., stock.picking) does not have a responsible user, and activity type dose not have `default_user_id the user_id` remains unset. https://github.com/odoo/odoo/blob/7ced429ff54c9670f2ff1b1866ecfb01f49ad50d/addons/mail/models/mail_activity_mixin.py#L408-L409 - Previously, the creation logic would fall back to using either a default user from the activity type or the current environment user (env.uid). This fallback no longer occurs in all cases. https://github.com/odoo/odoo/blob/279504268e1c4b57f26543db1c7da9a709fea350/addons/mail/models/mail_activity_mixin.py#L401-L402 **Solution:** - If no user_id is determined (either from the record or activity type), explicitly assign the current logged-in user (env.user) as the activity’s responsible user during creation. - This ensures that every activity created through automation has a valid assignee opw - 5213520 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
9 changes
Resolved issues and error corrections
This change prevents an error that could appear when customers switch between product variants on subscription products in the online shop. If pricing information is missing, the system now handles it safely instead of failing, improving the browsing experience.
Original PR description
Step to reproduce: - install website_sale_subscription - create a product, add few variants and tick 'Subscriptions' option. - open that product from /shop - toggle between variants Cause: - In case the pricing is not present, 'False' is passed(not an iterable) - `_onChangeCombinationSubscription` expects a iterable, causing traceback Fix: - we pass empty list instead of False opw-5241612 Forward-Port-Of: odoo/enterprise#99160
This update removes an overly strict rule that blocked users from changing or copying certain tax groups when the linked accounts had different types. It makes the setup more flexible while still allowing account types to be adjusted later if needed.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Community PR:** https://github.com/odoo/odoo/pull/235548 opw-5231379 Forward-Port-Of: odoo/enterprise#99421
This update makes the Swiss payroll transmission tests independent from accounting-specific configuration, so they can run reliably even when accounting details are not fully set up. It also adjusts payroll validation so payslips can be confirmed without requiring a journal on the payroll structure, reducing test and setup failures.
Original PR description
Forward-Port-Of: odoo/enterprise#99264 Forward-Port-Of: odoo/enterprise#98672
This change fixes an issue where imported French accounting entries could lose their reconciliation marker too early, preventing some journal items from being automatically matched later. As a result, FEC imports should now reconcile more reliably across different accounts, reducing manual follow-up work.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit provides a test to reproduce this issue. opw-5086823 Forward-Port-Of: odoo/enterprise#98855
This change prevents quality checks from appearing for items that were not actually picked or do not yet have the required lot/serial information. It ensures warehouse users only see the checks relevant to the products they are really processing, avoiding extra work and validation confusion.
Original PR description
*: {stock_barcode_,}quality_control #### There are two issues addressed in this PR: 1) In the barcode app, quality checks triggered at validation includes quality checks related to unpicked products.…
*: {stock_barcode_,}quality_control
#### There are two issues addressed in this PR:
1) In the barcode app, quality checks triggered at validation includes quality checks related to unpicked products.
2) Quality check related to product without set lots are triggered.
### Steps to reproduce:
- Create a storable products product A tracked by SN
- Create a control points of type pass/fail on receipts control by
quantity on product A
- Create and confirm a receipt with a move 2 x product A
- Open the receipt in the barcode app
- Scan product A > Scan SN001
- Click on Quality Check
#### > Both QC's are displayed to be processed
### Expected behavior:
Only the QC related to the scanned SN should be processed as it is the only unit that will be moved at validation.
### Cause of the issue:
Only picked move lines are considered to be processed in the barcode app. However, the `check_quality` triggered by clicking on the quality check button only check if the move related to the move line is picked:
https://github.com/odoo/enterprise/blob/9fe45b673c02a98e6dd6b3997f19a2018a76df09/quality_control/models/stock_picking.py#L64-L72
### Fix:
Relying the `barcode_trigger` context key will ensure a uniform behavior between the QC's displayed to be processed directly from the QC button and from these displayed at validation since this context key is already used at validation:
https://github.com/odoo/enterprise/blob/9fe45b673c02a98e6dd6b3997f19a2018a76df09/stock_barcode/static/src/models/barcode_model.js#L581-L590
Note we all changed the default return value of the `check_quality` from `False` to `True` here:
https://github.com/odoo/enterprise/blob/9fe45b673c02a98e6dd6b3997f19a2018a76df09/quality_control/models/stock_picking.py#L71-L73
because this method is called in the `pre_action_done_hook` during the `button_validate` of the picking:
https://github.com/odoo/odoo/blob/a97d3c772001f4f0b9df66d28c1c8f19358898e0/addons/stock/models/stock_picking.py#L1415-L1421
https://github.com/odoo/enterprise/blob/9fe45b673c02a98e6dd6b3997f19a2018a76df09/quality_control/models/stock_picking.py#L91-L96
and since a result that is not `True` is expected to be an action that should be processed prior to validation, returning `False` would make it impossible to proceed with a validation in case the `check_quality` is called and there is no check to process.
Task: 4716252
opw-5010764
Forward-Port-Of: odoo/enterprise#99565This change makes the manufacturing test flow more reliable by removing a search step that could refresh the screen at the wrong moment. It also ensures the intended product appears first in the catalog, reducing intermittent failures in the add-component process.
Original PR description
The search in the "Add Component" dialog caused a re-render race, making the tour ``test_add_component_from_shop_foor_in_multi_step_manufacturing`` fail intermittently. This fix removes the search steps and marks the “Courage” product as favorite so it appears first in the catalog. runbot-227694 Forward-Port-Of: odoo/enterprise#92403
This change prevents the phone system from trying to register twice when a user leaves a page. It avoids an error during page unload, making sign-out and navigation smoother and more reliable.
Original PR description
On page unload, two conflicting things happen: - A REGISTER request with expires=0 is sent to invalidate the registration - The WebSocket disconnects, triggering the reconnection mechanism that attempts to reissue a registration These two concurrent and conflicting REGISTER requests result in the following error: > RequestPendingError: REGISTER request already in progress, waiting for final response This commit prevents the reconnection mechanism from occurring in the event of a "natural" disconnection, such as one triggered by a page unload. This way, the two conflicting REGISTER requests aren't sent on page unload. [Task-5261940](https://www.odoo.com/odoo/project/5778/tasks/5261940) Forward-Port-Of: odoo/enterprise#99560 Forward-Port-Of: odoo/enterprise#99376
Fixes an issue where locking a document in the preview did not refresh the available actions in the menu. Users will now see the correct options right away after changing a document’s lock status, avoiding confusion and inconsistent behavior.
Original PR description
Steps to reproduce =================== - Preview any documents. - Click on the actions menu and lock the document. - Now go to the actions menu again. => The set of options is not updated. Technical =========== - The action menu, which we are using inside the file previewer, is passed explicitly inside the FileViewer component of the document. We were using the `record.load()`, which will not have any effect on the FileViewer component and that's why the action menu was not updating. After this commit ================== - Used the `this._notifyChange()` method, which closes the preview and loads the model to align with the same behaviour as other actions. Task-4988116
This update resolves an error that could interrupt WPS file generation for Saudi payroll. It makes the export process more reliable so payroll teams can complete their work without unexpected tracebacks.
Original PR description
this commit addresses traceback errors occured due to incorrect usage of `_` function. task-5310946
16 changes
Resolved issues and error corrections
This fixes a crash that could happen when certain accounting report screens used manually generated data models. The affected pages now include the required service, helping users access account return and report views reliably.
Original PR description
With this PR: https://github.com/odoo/odoo/pull/229492, comes a new service which is needed on models. Without this service on our manually generated models, this would crash because it was trying to access an undefined variable.
Approved late hours for Saudi employees are now included when generating payslips. This ensures payroll deductions or calculations tied to lateness are reflected correctly and consistently after module installation.
Original PR description
Reproduce 1. create an attencande for SA employee with latehours 2. approve latehours 3. create a payslip for this employee. you will not find the hours reflected to the payslip Issue the property input rule that take the late hours amount was missed Solution add the rule back and make sure it is added to the defention on the module installation Task: 5253150
The Ask AI action now handles cases where a user has multiple AI chat channels without crashing. It also starts a fresh AI chat from the main entry point and removes a duplicate search-view button, making the experience more reliable and less cluttered.
Original PR description
When multiple AI chat channels existed for the same agent/user, `_get_or_create_ai_chat` could return several records. This caused a singleton error when calling `action_ask_ai` because the code expected a single channel record. This commit filters a single record so that only one channel is returned, preventing the crash. And also 'action_ask_ai' will now always opens a new ai chat. Additionally, the redundant 'Ask AI' button in the search view has been removed, as the same functionality is already available from the systray. task-5107276 Forward-Port-Of: odoo/enterprise#95585
The OCR process will no longer automatically change a customer invoice into a sale receipt when the Sale Receipt option is not enabled. This prevents documents from being categorized into a disabled workflow and helps keep invoice processing aligned with company settings.
Original PR description
If the "Sale Receipt" setting isn't enabled, the OCR should never automatically switch a customer invoice to a sale receipt. task-[5265382](https://www.odoo.com/odoo/project.task/5265382) Forward-Port-Of: odoo/enterprise#99522
Payment reminder emails now send any files and dynamic reports configured on the selected email template. This ensures customers receive the complete follow-up information intended by the business, reducing missing-document issues and manual resend work.
Original PR description
### Issue: We can add attachments and dynamic report to the email templates, but they are not sent with follow-ups. ### Steps to reproduce: - Go to the "Payment reminder" email template - Under the…
### Issue: We can add attachments and dynamic report to the email templates, but they are not sent with follow-ups. ### Steps to reproduce: - Go to the "Payment reminder" email template - Under the page "Content", add an attachment by clicking the "Attachments" button - Under the page "Settings", add a dynamic report - Create an overdue invoice for a partner - Go on the form view of the partner, "Accounting" page - Click "Send", make sure the template used is the one with the attachments - Send - The attachments on the template and the dynamic report are not sent ### Cause: The mail template to send the follow-ups is only used to prefill the wizard. ### Solution: Add the template in `_get_wizard_options()` to add the template in the option and later use it to add/generate its attachments. This commit also refactors how the attachments are computed: The previous code was adding the invoices PDFs then removing them. The whole process was confusing. Now `options['attachment_ids']` is appended in `_get_followup_attachments()` with the desired attachments depending on the options. Also `_get_invoices_to_print()` had unnecessary lines. The options are always initiated before calling the method and the condition on "manual_followup" is useless as the invoices are already in options['attachment_ids'] when coming from the wizard. opw-5147736 Forward-Port-Of: odoo/enterprise#99458 Forward-Port-Of: odoo/enterprise#98454
Payroll PDF generation now handles certain report errors without stopping the scheduled process. If one employee declaration cannot be generated, the error is saved on that record and the system continues processing the remaining payroll documents.
Original PR description
When rendering PDF files, `_get_rendering_data` is expected to return a dict with the key `error` when needed. Some localizations respect this correctly, but others will raise an UserError instead. In particular, the `Payroll: Generate pdfs` cron will keep trying to generate the file and the `UserError` will never be caught, so the scheduled action will eventually be deactivated. With this fix, the exception is caught, the message is recorded on the sheet, and the PDF is skipped. The cron will then keep processing the other records. Source: investigation after the cron got disabled on our server Forward-Port-Of: odoo/enterprise#99490
When a cashier tries to sync orders while the Belgian blackbox connection is unavailable, affected orders are now returned to draft instead of remaining stuck. This lets staff retry the sync once the connection is restored, reducing checkout disruption.
Original PR description
When trying to sync orders while being offline, a `ConnectionLostError` is raised. This error was not handled in the pos_blackbox_be module. Now, if an order was not signed correctly by the blackbox, we put its state back to "draft", allowing the cashier to retry later (when the connection to bbox is re-established). Forward-Port-Of: odoo/enterprise#99202 Forward-Port-Of: odoo/enterprise#98778
This fix ensures automated tests properly finish drag-and-drop actions before ending. It helps prevent false test failures and supports more stable quality checks for scheduling-related features.
Original PR description
Since drag sequences are automatically canceled at the end of tests, 'cancel' or 'drop' calls should be properly awaited before the end of a test. This commit ensures that these actions are properly finished before a test ends. Community: https://github.com/odoo/odoo/pull/235359 Forward-Port-Of: odoo/enterprise#99634 Forward-Port-Of: odoo/enterprise#99369
This fix restores the ability to add reactions to messages when using Discuss on a mobile device. It improves day-to-day collaboration by making quick responses work consistently across desktop and mobile.
Original PR description
Task-4607436 Task-5261880 https://github.com/odoo/odoo/pull/235852 Forward-Port-Of: odoo/enterprise#99588
VoIP contact search now avoids checking mobile phone matches until at least three characters are entered. This prevents error messages from appearing while users type the first few digits or letters, making the search experience smoother.
Original PR description
`phone_mobile_search` doesn't allow you to search for less than 3 characters. This commit excludes `phone_mobile_search` from the search domain when there are less than 3 characters. This avoids triggering an UserError on the first characters typed. Forward-Port-Of: odoo/enterprise#99626 Forward-Port-Of: odoo/enterprise#99548
Fixes an issue where switching variants on subscription products in the online shop could trigger an error when no pricing was available. The system now handles missing pricing safely, helping customers browse subscription product options without interruption.
Original PR description
Step to reproduce: - install website_sale_subscription - create a product, add few variants and tick 'Subscriptions' option. - open that product from /shop - toggle between variants Cause: - In case the pricing is not present, 'False' is passed(not an iterable) - `_onChangeCombinationSubscription` expects a iterable, causing traceback Fix: - we pass empty list instead of False opw-5241612 Forward-Port-Of: odoo/enterprise#99160
Studio no longer crashes when users edit JSON-based fields such as analytic distribution. The update lets these fields handle placeholder settings correctly, improving reliability when customizing forms.
Original PR description
When trying to edit the `analytic_distribution` field using Studio, the following traceback occurred: `Caused by: TypeError: Cannot read properties of undefined (reading 'subOptions')` This happened because the new option `placeholder_field` was [introduced](https://github.com/odoo/odoo/commit/6620ebbd184de6f106fceb4427a081b61d97296a) for dynamic placeholders in widget. However, there was no support declared for `placeholder` inside the `FIELD_TYPE_ATTRIBUTES` definition for the `json` field type. This commit adds `EDITABLE_FIELD_ATTRIBUTES.placeholder` to the `json` field type, allowing widgets on JSON fields to correctly handle `placeholder_field` options without causing a Studio crash. opw - 5180896 upg - 3249816 Forward-Port-Of: odoo/enterprise#98526
This fix prevents Belgian tax return generation from crashing when a company’s fiscal year is configured to end on February 29. The date calculation now handles leap-year settings correctly, helping migrations and return generation complete reliably.
Original PR description
``` File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate generate_or_refresh_all_returns(company) File…
```
File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate
generate_or_refresh_all_returns(company)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 228, in _generate_or_refresh_all_returns
self._generate_all_returns(fiscal_country.code, company, domestic_tax_unit)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 24, in _generate_all_returns
super()._generate_all_returns(country_code, main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 281, in _generate_all_returns
report_type._try_create_returns_for_fiscal_year(main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 353, in _try_create_returns_for_fiscal_year
period_date_from, period_date_to = self._get_period_boundaries(main_company, date_pointer)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 530, in _get_period_boundaries
start_day, start_month = self._get_start_date_elements(company_id)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 16, in _get_start_date_elements
fiscal_year_date = date(2025, int(main_company.fiscalyear_last_month), main_company.fiscalyear_last_day)
ValueError: day is out of range for month
```
```
(Pdb) main_company
res.company(3,)
(Pdb) main_company.fiscalyear_last_month
'2'
(Pdb) main_company.fiscalyear_last_day
29
(Pdb) date_from
datetime.date(2025, 3, 1)
```
- During the migration process the system calls [_generate_or_refresh_all_returns](https://github.com/odoo/upgrade/blob/e20a9e2edec4441b2c7aa5858db2a53fb2e9b215/migrations/account_reports/saas~18.3.1.0/end-account-returns.py#L340) which internally uses [_get_start_date_elements](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L14) to compute the fiscal year start date.
- The customer has configured fiscalyear_last_month = February and fiscalyear_last_day = 29 Because of this configuration, the method attempts to construct 29th February 2025, which is invalid since 2025 is not a leap year. The issue occurs because the method uses a hardcoded year [(2025)](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L16) instead of determining the year dynamically.
- I reviewed implementations in other localizations and found that this logic has [1](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_uk_reports/models/account_return.py#L33), [2](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_nz_reports/models/account_return.py#L8) already been corrected there to compute the appropriate start date dynamically.
- I’ve updated this localization to follow the improved implementation used in other countries, so the start-date calculation now works correctly in all cases, including leap years and any fiscal year settings the customer may configure.
opw-5249243
Forward-Port-Of: odoo/enterprise#99353The VoIP keypad now keeps numbers inserted in the intended place when users tap digits after moving the cursor. This prevents dialing errors on Android when the phone keyboard is hidden and the input loses focus.
Original PR description
Keypad input now reads selection from the persisted model whenever the DOM selection isn't trustworthy, particularly on Android where the input blurs to hide the keyboard, so digits typed at any cursor location stay in place. task-5241464
The appointment booking error message now clearly includes the appointment type name when there are not enough seats available. This makes the issue easier for users to understand and resolve when saving appointments without resources.
Original PR description
Currently, when creating a new appointment with a specified number of people but no resources, saving the record triggers a UserError that does not display the appointment type name. Issue: 2 seats are missing to be able to book the appointment.type(1,): Table (30) <img width="1813" height="776" alt="image" src="https://github.com/user-attachments/assets/f87f45de-3552-47bb-b34c-fcc06cea425f" /> Solution: 2 seats are missing to be able to book the Table: Table (30) <img width="1769" height="905" alt="image" src="https://github.com/user-attachments/assets/04188071-be67-4500-b720-039ee7a27c2e" /> Forward-Port-Of: odoo/enterprise#99646
This fixes an issue where portal users could see an error when sending an attachment in a live chat with an agent. The change ensures the user availability field is properly set, helping chats continue smoothly without interruption.
Original PR description
Bug === As portal, open a live chat with an agent, and try to send an attachment. An error will be raised because of `offline_since` (which is not initialized in the compute). Task-4687269
23 changes
Resolved issues and error corrections
DATEV exports now work correctly even when a German company name contains a dot. This prevents the export from failing with an error and ensures accountants can generate the report without interruption.
Original PR description
Currently companies with a dot ('.') in the name cannot export the DATEV report due to a traceback.
Steps to reproduce:
- Select a German (DE) Company having a dot in the name.
- Open Accounting / Reporting / Ledgers / General Ledger
- Click cog > Datev DATA (zip)
Issue:
A Traceback will occur
`Error "ValueError: too many values to unpack (expected 2)"`
This occurs because the system separate the filename from the extension without halting to the first `.`, leading to the error.
opw-5232073This change ensures certain report attachments that start from a remote source are converted into local files before being used. This helps reports that rely on attached images or chatter content work correctly and reliably, especially with cloud storage setups.
Original PR description
During commit #226094, several methods were added to allow fetching remote resources for certain reports. After that commit, we notice that some attachments (like images -> image_src) must need the file localy. To avoid this issue we decided to convert this documents from remote to localy (binary), to be able to manage them. It'll just happen for the reports that need to add attachments from the chatter. OPW-5036638 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235710 Forward-Port-Of: odoo/odoo#235077
This update fixes an issue where kit products were not properly linked during receiving when the process used buy or push steps instead of a pull rule. As a result, delivered quantities and invoice cost calculations for kits are now recorded correctly, preventing incorrect stock and accounting results.
Original PR description
[FIX] purchase_mrp, sale_purchase_stock: track kit bom when receiving without pull rule Problem: If an inventory workflow is completed without any pull rules (only Push or Buy), then `bom_line_id` is…
[FIX] purchase_mrp, sale_purchase_stock: track kit bom when receiving without pull rule Problem: If an inventory workflow is completed without any pull rules (only Push or Buy), then `bom_line_id` is never set on the sale order line. The result has two primary impacts: `qty_received` will not be updated upon final transfer, and the COGS line on the invoice will be calculated using the incorrect method, with an incorrect result. Solution: Upon confirming a Purchase Order, when the picking is being created, we will try to assign the `bom_line_id` on the Sale Order Line if: 1. The PO is attached to a Sale Order 2. The SO line is for the kit 3. The product on the PO line is component of the BOM for that kit With the `bom_line_id` assigned on the SO line, `qty_received` will be calculated correctly for kits, and COGS lines on the generated invoice will also be calculated correctly based on the kit. Steps to Replicate (Runbot 18) - 2-step receipt, 2-step delivery - Cross-Dock enabled - Kit item, fifo auto - No routes enabled on kit - Two components, fifo auto - Enable Buy and Cross-Dock routes - Set a vendor and non-zero price 1. Create a sale order for the kit and sell for non-zero price, confirm 2. Confirm the PO 3. Validate the pickings 1. Receipt 2. Cross-Dock 3. Delivery 4. Go back to the sale order, note the first issue of 0 quantity delivered 5. Create an Invoice 6. Confirm the invoice, note the second issue of the COGS lines being triple the total purchase price opw-5139590 Forward-Port-Of: odoo/odoo#235818 Forward-Port-Of: odoo/odoo#233132
This change makes the web client check browser capabilities before using a browser-specific setting, instead of assuming it is always available. It helps prevent errors on browsers that hide this information, improving reliability for users on affected devices.
Original PR description
This commit uses "Feature detection" to avoid some error when the platform key is not available from navigator. > The platform property indicates the platform/OS the browser is running on. > Theoretically this information is useful for detecting the browser and serving code to work around browser-specific bugs or lack of feature support. However, this is unreliable and is not recommended for the reasons given in User-Agent reduction and Browser detection using the user agent. > Feature detection is a much more reliable strategy. https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Testing/Feature_detection task-4420689 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235958
This fix ensures the QRIS API key and merchant ID fields are shown in the bank account form. The fields were being placed in a hidden part of the page, so users could not see or fill them in.
Original PR description
**Description of the issue/feature this PR addresses:** This issue occurs because the XPath targeting the `currency_id` field is placed inside a `<div>` that becomes invisible under certain conditions. The `view_partner_bank_form_inherit_hr` view is loaded first due to its sequence, and the `l10n_id` view is applied afterward, causing the QRIS fields to be inserted into that hidden `<div>` from `view_partner_bank_form_inherit_hr`. **Current behavior before PR:** The fields l10n_id_qris_api_key and l10n_id_qris_mid are not visible. **Desired behavior after PR is merged:** The fields l10n_id_qris_api_key and l10n_id_qris_mid are visible by changing XPath target Task: [5247678](https://www.odoo.com/odoo/project.task/5247678) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235949
This update prevents an error when customers switch between product variants on subscription products in the shop. If no pricing is available, the system now sends an empty list instead of a missing value, avoiding a traceback and keeping the product page working smoothly.
Original PR description
Step to reproduce: - install website_sale_subscription - create a product, add few variants and tick 'Subscriptions' option. - open that product from /shop - toggle between variants Cause: - In case the pricing is not present, 'False' is passed(not an iterable) - `_onChangeCombinationSubscription` expects a iterable, causing traceback Fix: - we pass empty list instead of False opw-5241612 Forward-Port-Of: odoo/enterprise#99160
This change makes the mobile message reaction test more stable by waiting for the full conversation to finish loading before checking reactions. It also corrects how reaction updates are stored so user reactions are handled consistently instead of being misread as replacements.
Original PR description
Follow-up of https://github.com/odoo/odoo/pull/235852 Test was recently unskipped for test coverage of the fix, but there were non-deterministic failures of this test on runbot: ``` Failed to find 1…
Follow-up of https://github.com/odoo/odoo/pull/235852
Test was recently unskipped for test coverage of the fix, but there were non-deterministic failures of this test on runbot:
```
Failed to find 1 of ".o-mail-MessageReaction:contains('😀')" (Timeout of 3 seconds). Found 0 instead.
```
This happens because conversation has a single message, and the last message is fetched twice: once at init_messaging of the pinned conversation, and another one when loading the message list. The test was awaiting presence of message before adding reactions, but while adding a reaction it's possible to have 2nd fetch of message overwriting the message reactions from a prior `ADD`, leading to failed assertion below that there's no message reactions.
This commit fixes the issue by awaiting the whole message list render thanks to awaiting the 2 messages on UI and not just the 1st one.
Also the to_store format of message reaction was poorly formatted, which lead to "ADD" command being treated as a "REPLACE" instead. This commit also fixes this issue, as the client-side code of message reaction is designed to receive "ADD" commands.This change stops portal users from interacting with the chatter on a task before it has been saved. It prevents a crash when someone tries to mention a user in a new task, improving stability when working in shared projects.
Original PR description
Currently, an error occurs when a portal user opens a `shared project` and tries to `mention(@)` someone in the chatter of a `new(unsaved) task`. **Steps to produce:** - Install the `project` module.…
Currently, an error occurs when a portal user opens a `shared project` and tries to `mention(@)` someone in the chatter of a `new(unsaved) task`. **Steps to produce:** - Install the `project` module. - Open the project app and create a new project with at least one task. - From the project’s `dropdown menu(⋮)`, select `Share Project`. - Add a `collaborator: Joel Willis`, with `Edit access` mode, copy the public link, and click `Share Project`. - Open the shared link in an incognito window and sign in as a portal user. - Open the `project folder` > open any task > click `New` > type `'@'` in the chatter. **Error**: `ValueError: Expected singleton: project.task()` **Root cause:** The `composer(message box)` allows typing and mention suggestions even when the task record is not yet saved (`self.thread.id` is `undefined`). At [1], the method is called on an `empty` recordset, causing an `error`. **Fix:** This commit prevents users from writing in the chatter by stopping the composer initialization when the record(thread) is `unsaved`. [1]: https://github.com/odoo/odoo/blob/5cf96828652c2388808b3e49ae67e188c401ec63/addons/project/models/project_task.py#L2051-L2071 sentry-6982269693 Forward-Port-Of: odoo/odoo#235184
The employee org chart button now opens the Hierarchy view on mobile devices instead of defaulting to the Kanban view. This makes it easier for users to access the correct org chart display when viewing employees on the go.
Original PR description
Steps to Reproduce: - Open an employee record. - Set managers for the employee. - Open the employee’s form view on mobile. - Click org chart stat button. Before: - On mobile, the org chart button opened the Kanban view by default. After: - On mobile, the org chart button now opens the Hierarchy view by default. task-5245129 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235228
This change prevents a crash that could happen when generating Belgian accounting reports during migration. It corrects how the fiscal year start date is calculated so it works properly even for dates like February 29 in non-leap years.
Original PR description
``` File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate generate_or_refresh_all_returns(company) File…
```
File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate
generate_or_refresh_all_returns(company)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 228, in _generate_or_refresh_all_returns
self._generate_all_returns(fiscal_country.code, company, domestic_tax_unit)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 24, in _generate_all_returns
super()._generate_all_returns(country_code, main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 281, in _generate_all_returns
report_type._try_create_returns_for_fiscal_year(main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 353, in _try_create_returns_for_fiscal_year
period_date_from, period_date_to = self._get_period_boundaries(main_company, date_pointer)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 530, in _get_period_boundaries
start_day, start_month = self._get_start_date_elements(company_id)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 16, in _get_start_date_elements
fiscal_year_date = date(2025, int(main_company.fiscalyear_last_month), main_company.fiscalyear_last_day)
ValueError: day is out of range for month
```
```
(Pdb) main_company
res.company(3,)
(Pdb) main_company.fiscalyear_last_month
'2'
(Pdb) main_company.fiscalyear_last_day
29
(Pdb) date_from
datetime.date(2025, 3, 1)
```
- During the migration process the system calls [_generate_or_refresh_all_returns](https://github.com/odoo/upgrade/blob/e20a9e2edec4441b2c7aa5858db2a53fb2e9b215/migrations/account_reports/saas~18.3.1.0/end-account-returns.py#L340) which internally uses [_get_start_date_elements](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L14) to compute the fiscal year start date.
- The customer has configured fiscalyear_last_month = February and fiscalyear_last_day = 29 Because of this configuration, the method attempts to construct 29th February 2025, which is invalid since 2025 is not a leap year. The issue occurs because the method uses a hardcoded year [(2025)](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L16) instead of determining the year dynamically.
- I reviewed implementations in other localizations and found that this logic has [1](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_uk_reports/models/account_return.py#L33), [2](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_nz_reports/models/account_return.py#L8) already been corrected there to compute the appropriate start date dynamically.
- I’ve updated this localization to follow the improved implementation used in other countries, so the start-date calculation now works correctly in all cases, including leap years and any fiscal year settings the customer may configure.
opw-5249243
Forward-Port-Of: odoo/enterprise#99353This update fixes a problem on mobile websites where a hidden mega menu could still block taps on the page. As a result, users can reopen the menu normally after closing it, improving navigation reliability on phones and tablets.
Original PR description
Steps to reproduce: ==================== 1. Add a mega menu. 2. Add effects to the mega menu columns ex (Animation on appearance, Fade, direction from bottom) 3. Switch the website display to mobile view. 4. Click on the mega menu. 5. Go back and try to click again. → The mega menu cannot be opened again. Cause: ====== When the mega menu is hidden, its section remains in the DOM and still captures pointer events. As a result, clicks on the screen (including attempts to reopen the mega menu) are intercepted by the hidden element instead of reaching the intended target. Solution: ========= Disable pointer events on the mega menu section once it is hidden to ensure subsequent clicks behave correctly. opw-5129316 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233636
This change corrects the logic that decides when OSS return reports should be generated. As a result, OSS sales and import returns will only be created when their conditions are actually met, avoiding unnecessary or incorrect report generation.
Original PR description
The OSS Sales returns was generated even when its condition wasn't met since auto_generate was still at True. The OSS Imports didn't have any condition and has one which is similar to the OSS Sales.
This update makes the field selector in spreadsheet pivot side panels respect debug mode. As a result, users can search and see technical field names when working in debug mode, which helps with configuration and troubleshooting.
Original PR description
Steps to reproduce: - Activate debug mode - Insert a pivot in a spreadsheet - In the side panel, click on "Add column" => the component is not in debug mode, so the technical name cannot be searched and is not displayed Task: 5264589
This fix ensures transparent PNG images in the Website image gallery display with a white thumbnail background instead of a black square. It improves the visual appearance of galleries and keeps page editing results consistent and polished.
Original PR description
Steps to reproduce: - Go to Website and click Edit. - Drag and drop an "Image Gallery" snippet onto the page. - Enable the "Squared Miniatures" option. - Add a PNG image with a transparent background to the gallery. Before this commit, thumbnails had a black square background. After this commit, thumbnails have a white background. task-5189020
This fix prevents the Inventory app from crashing when a stock quantity record is opened without a Location set. It improves stability for users editing quantities, especially when working with new or unsaved records.
Original PR description
Currently, an error is produced when accessing the stock quant form view without a location set. **Steps to Reproduce:** 1. Install the Inventory module. 2. Create a product with tracking enabled (By Unique Serial Number). 3. Click **"Update Quantity"** (opens list view). 4. Click **New**, click View on the unsaved record (opens form view). 5. Remove the Location field. **Error:** `TypeError - sequence item 0: expected str instance, bool found` **Cause:** In the display name computation at [1], the system attempts to join name parts where one of them can be `False` if the location is not set. **Fix:** Before generating the display name, it now checks whether the record is saved (record.ids). If the record is unsaved (no ID), it sets an empty `display_name` and skips the name-joining logic. [1] - https://github.com/odoo/odoo/blob/16e889bf5885c4d827b8c2c5dce102f98aad689f/addons/stock/models/stock_quant.py#L599 sentry-6717759358 Forward-Port-Of: odoo/odoo#234552
This update fixes a misleading error shown in Point of Sale when communication with the Blackbox times out. Users will now see a more accurate message, which reduces confusion and helps support teams diagnose the real issue faster.
Original PR description
Before this commit, in the case when there is a timeout communicating with the Blackbox in the POS, an incorrect error message was shown stating that "The IoT Box is connected but the Fiscal Data Module isn't". This message should only be shown when we receive a reply from the IoT box, but it tells us it cannot find the Blackbox. <img width="695" height="240" alt="image" src="https://github.com/user-attachments/assets/ec011f4a-42dd-4ffd-8741-350032897471" /> Forward-Port-Of: odoo/enterprise#99652
This fix ensures imported French FEC entries keep the right matching status so automatic reconciliation works correctly across different accounts. It prevents one reconciliation from unintentionally stopping later ones from being matched, improving import reliability and reducing manual cleanup.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit provides a test to reproduce this issue. opw-5086823 Forward-Port-Of: odoo/enterprise#98855
This update fixes several problems with Viva Wallet payments in Point of Sale, including payments failing incorrectly when multiple terminals are used at the same time. It also prevents stuck payments from being linked to the wrong order and makes payment confirmation more reliable after a page refresh.
Original PR description
This commit fixes various issues when using Viva Wallet, including the following: - When two Viva Wallet terminals had a payment in process at the same time in the same POS, one of the payments would…
This commit fixes various issues when using Viva Wallet, including the following: - When two Viva Wallet terminals had a payment in process at the same time in the same POS, one of the payments would fail on Odoo even when it succeeded on the terminal. - When a previous Viva Wallet payment was stuck (never completed or failed), trying to make a new payment would mistakenly affect that previous order instead of the new order. - When refreshing the page during a payment, it becomes stuck and never confirms or fails. To fix these issues, there are two main changes: 1. Stop using the `getPendingPaymentLine` method to retrieve the Viva Wallet payment line. This method is flawed as it assumes there is only one pending payment at a time. 2. Store the Viva session ID for a payment in the payment line's UI state, instead of on the plain JS object. This allows it to persist after a refresh. opw-5226966 opw-5248178 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236004 Forward-Port-Of: odoo/odoo#235695
This update prevents accidental line breaks from being included in Swiss QR code fields. As a result, QR codes are less likely to be rejected by banks or payment systems due to incorrect formatting.
Original PR description
Swiss QR codes have required information for each line of the QR code. Newline characters present in a field's content shift the content to a different line than intended, causing the QR code to be rejected. This commit removes newline characters from the field elements and alters a unit test to check if this issue occurs again. opw-5095997 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233880
This fix ensures the restaurant floor plan only shows booking notifications for the correct appointment type set in the POS configuration. It also prevents misleading bookings from appearing and then disappearing after a refresh, making the booking experience more reliable for staff.
Original PR description
Task: [#5005216](https://www.odoo.com/odoo/my-tasks/5005216) Enterprise v17.0: [#93714](https://github.com/odoo/enterprise/pull/93714) --- **Before:** If no appointment type is specified in the POS config and a table is booked via the website, the floor plan is notified of a new booking because the resource used is one of the POS config resources. However, if the page is refreshed, the booking disappears since no appointment type is defined in the POS config **After:** The floor plan is notified of a new booking only if the appointment type of the booking matches the one specified in the POS config. If no appointment type is set in the POS config, no booking notifications are sent. Additionally, when the "Table Booking" field is unchecked in the POS config, the appointment type is automatically unset. Forward-Port-Of: odoo/enterprise#98887 Forward-Port-Of: odoo/enterprise#93636
Imported accounting entries that share the same matching number will now be handled more reliably during automatic reconciliation. This prevents one reconciliation from accidentally blocking others on different accounts, helping imported data get matched correctly without manual follow-up.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the…
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit aims to fix that by removing amls imported matching number (starting with "I") from the reconciled amls to consider. opw-5086823 Forward-Port-Of: odoo/odoo#234481
This change makes the manufacturing training/test flow more reliable by removing a step that could cause the screen to refresh at the wrong time. It also ensures the intended product appears first, preventing intermittent failures during the add-component process.
Original PR description
The search in the "Add Component" dialog caused a re-render race, making the tour ``test_add_component_from_shop_foor_in_multi_step_manufacturing`` fail intermittently. This fix removes the search steps and marks the “Courage” product as favorite so it appears first in the catalog. runbot-227694 Forward-Port-Of: odoo/enterprise#92403
Bancontact payments that require an extra verification step are now kept in a pending state instead of being marked as failed. This prevents customers from seeing an error during the normal redirect-based payment flow and helps payments complete correctly.
Original PR description
When paying with Bancontact, in case a 3DS validation is required (challenge flow), Wordline will send a webhook (see below) to indicate that an external (asynchronous) validation was requested.…
When paying with Bancontact, in case a 3DS validation is required (challenge flow), Wordline will send a webhook (see below) to indicate that an external (asynchronous) validation was requested.
Example of recevied webhook:
```
{
'apiFullVersion': 'v1.1',
'apiVersion': 'v1',
...
'payment': {
'status': 'AUTHORIZATION_REQUESTED',
'statusOutput': {
'isAuthorized': False,
'isCancellable': False,
'isRefundable': False,
'statusCategory': 'PENDING_CONNECT_OR_3RD_PARTY',
'statusCode': 51
}
},
'type': 'payment.authorization_requested'
}
```
Since efc2788dfccd, when receiving such webhook we set the transaction as error then force the user flow to `redirect`; this was done to handle payment w/ token (`online_token`) where a 3DS challenge is still required.
But for Bancontact - which is non-tokenizable - we will always be in the "redirect" mode, so we must keep the transaction as `pending`.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#2358479 changes
Resolved issues and error corrections
This change corrects how leave days are calculated for accrual-based allocations when the start date is updated. As a result, employees now receive the full number of accrued days expected from their plan instead of an undercount.
Original PR description
Version: * 17.0 Steps to Reproduce: 1. Create an accrual plan with: * Accrued gain time: At the start of the accrual period * Carry-over time: Other * Carry-over date: 1 January * Add a milestone where the employee accrues 2 days monthly, with a milestone reached = 0 days. 2. Create a new allocation: * Set allocation Type to accrual allocation * Select the accrual plan created above * Set date_from to the 1st of the previous month Issue: * The expected accrued days are 4, but the system only calculates 2. Fix: * When changing the `date_from` value, set `already_accrued` to False. * This ensures `_process_accrual_plans` runs `_add_days_to_allocation` properly and recalculates the correct accrued days. After: * Accrued days now calculate correctly based on the accrual plan. task-5236714 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235229
Users can now export records even when the list view is grouped by a property field. This fixes a crash that occurred during export and makes the export action work reliably in these grouped views.
Original PR description
Step to reproduce
- open a task
- add a property field , say test
- add values for this field in few records
- go to list view and group by test
- select a record from result and export it (from Action btn)
Observation:
- traceback
```
File "/home/odoo/17.0/addons/web/controllers/export.py", line 486, in base
groupby_type = [Model._fields[x.split(':')[0]].type for x in groupby]
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
KeyError: 'task_properties.b60ee9baefee14a8'
```
Cause:
- The issue is caused by splitting, which didn't considered property field
- it tried to look for `task_properties.b60ee9baefee14a8` in _fields which causes KeyError
FIx:
- split the field name properly to bring out actual field name while considering granularity as well as the property fields
opw-5159155
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#235209This pull request fixes several issues that could cause inconsistent behavior or failed operations in everyday Odoo use, including calendar reminders, CRM lead conversion, accounting searches, and external browser requests during testing. It also improves configuration handling and translations, helping make the system more reliable and easier to maintain.
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
The employee org chart button now opens the Hierarchy view on mobile devices instead of defaulting to the Kanban view. This makes the org chart accessible and easier to use on smaller screens.
Original PR description
Steps to Reproduce: - Open an employee record. - Set managers for the employee. - Open the employee’s form view on mobile. - Click org chart stat button. Before: - On mobile, the org chart button opened the Kanban view by default. After: - On mobile, the org chart button now opens the Hierarchy view by default. task-5245129 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235228
This update makes Odoo’s Mollie payment options match what a new Mollie account actually supports by default. It also removes Sofort from the available linked methods because Mollie is discontinuing that payment option, helping prevent unsupported or unavailable payment choices from showing up to users.
Original PR description
**[FIX] payment_mollie: remove iDEAL from the default payment methods** When a new Mollie account is created, it only accepts card payments out of the box. In Odoo, both the Cards and iDEAL payment methods were activated by default upon enabling the payment provider, while iDEAL required manual activation from Mollie's dashboard. --- **[FIX] payment_mollie: remove Sofort from the linked payment methods** See https://help.mollie.com/hc/en-us/articles/20904206772626-SOFORT-Deprecation-30-September-2024ard. Forward-Port-Of: odoo/odoo#236044
The activity list now keeps pagination usable even when some activities are filtered out by access rules. This prevents users from getting stuck on a page that appears complete while additional accessible activities still exist on later pages.
Original PR description
**Steps to reproduce:** - Create some activities which should not be accessible to a specific user (according to the `_search` filtering of `mail.activity`) - Go to Activity Menu > View all…
**Steps to reproduce:** - Create some activities which should not be accessible to a specific user (according to the `_search` filtering of `mail.activity`) - Go to Activity Menu > View all activities as the given user - Ensure that the limit (default: 80) is lower than the total number of activities which should be returned and that the new activities are in the returned elements - On `web_search_read` some records are removed by the `_search` override - The pagination navigation buttons are disabled as the returned number of records is lower than the limit - This means that some activities are not accessible to the user (everything above the given limit) **Issue:** The issue comes from the `_search` override which checks the records available to the user. As it's done after fetching with the limit, the resulting number of records can be lower than expected and this breaks the `_format_web_search_read_results` which considers that we have all the possible records and doesn't try to fetch the total count of records. **Fix:** The main issue can't be directly fixed without modifying the way the access are checked in the `_search` override. This could be mitigated by changing the search limit, making the search as superuser, or adding specific filtering but each has its own limitations. Adding `force_search_count` should allow the user to navigate between pages anyway and see all the available activities. But the number displayed in the pagination will often be incorrect for the current and total count. (e.g. we can have 75 records but 1-80/150 is displayed out of 140 actually readable records) opw-5046389 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures replenishment filters show the right records when users search for items with a to-order value of zero. It removes a mismatch that could incorrectly include products that actually need to be ordered, making inventory filtering more reliable.
Original PR description
**Issue** In replenishment, filtering with `to_order = 0` does not correctly exclude records where `to_order != 0`. **Steps to reproduce** 1. Go to Inventory > Operations > Procurement >…
**Issue** In replenishment, filtering with `to_order = 0` does not correctly exclude records where `to_order != 0`. **Steps to reproduce** 1. Go to Inventory > Operations > Procurement > Replenishment 2. Create a replenishment with a forecast quantity smaller than the min and max quantity (without editing the To Order) 3. Apply a custom filter `to_order = 0` → Records with non-zero `to_order` are incorrectly included **Cause** `qty_to_order` was split into `qty_to_order_computed` and `qty_to_order_manual` in [this commit](https://github.com/odoo/odoo/commit/156bed3f430d706e13822bbd95d91c8dfd3ea42d#diff-0eb18a8d7773b5f99b402392188594178c3ba2004e4bcab26dbc84b1c8d7256a). In the [`_search_qty_to_order` method](https://github.com/odoo/odoo/blob/322c6d0468bf79e9d29e1375c49aa13d4a7b7a67/addons/stock/models/stock_orderpoint.py#L338), all records with `qty_to_order_manual = 0` are included. Since `qty_to_order_manual` defaults to 0 when untouched by the user, this causes incorrect results. Additionally, [`to_order`](https://github.com/odoo/odoo/blob/322c6d0468bf79e9d29e1375c49aa13d4a7b7a67/addons/stock/models/stock_orderpoint.py#L323) displays `qty_to_order_computed` if `qty_to_order_manual = 0`, creating inconsistency. **Solution** Fix the inconsistency by ignoring `qty_to_order_manual` when searching for zero `to_order` values. opw-5150643
This fix makes the event dot easier to see when an event is displayed with a hatched style. It also ensures the correct styling is applied consistently in views like Planning, even when the Calendar app is not installed.
Original PR description
When pills are hatched (unpublished event) in the calendar view (eg. planning) the `o_event_dot` is barely visible. Additionally the styling to display the dot as outlined on hatched event is wrongly scoped in `/calendar` with the calendar status styling. It should be in the view instead. Otherwise, for the planning module which doesn't depend on calendar, the styling is not applied if calendar is not installed, rendering the filled dot. task-3916768 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235286
The import screen now shows the same formatting options for CSV files whether the file extension is written as .csv or .CSV. This removes an inconsistency that could confuse users during file imports, while keeping the import itself working as before.
Original PR description
Before this fix, the import side panel displayed the formatting options only when the uploaded file had a lowercase .csv extension. Files with an uppercase .CSV extension could still be imported but did not show the format selection section, leading to inconsistent behavior. This commit updates the condition to perform a case-insensitive comparison on the file extension. Task-5145031 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235061
7 changes
Resolved issues and error corrections
This fix restores clickable tabs in module information pages, so users can move between sections in an index.html description just like they can in the Odoo Apps Store. It improves the browsing experience and removes a small but frustrating display issue.
Original PR description
* Before: if we have a block contain multiple tab in index.html file we can not click on it to switch between tab, unlike the behiviour in odoo apps store description * After: Make the nav tabs work as it should be 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 fix corrects how amounts are handled when converting an invoice to a credit note, or the other way around, when storno is enabled. It ensures the debit and credit placement stays consistent and only the sign changes, preventing incorrect accounting values.
Original PR description
This commit fixes the amounts of move lines when converting from invoice to credit note and vice versa when storno is enabled. Previously, when converting from invoice/credit note, the amounts remained negative and switches from debit/credit. The quantities should remain in same debit/credit position and only change sign as I switch from invoice/credit note. task-5226311 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Purchase app’s Warnings filter now shows only requests for quotation that actually have warning-level activities. This fixes a mismatch that could previously include records with no activities, making the filter more reliable for users reviewing exceptions.
Original PR description
Steps to reproduce: - Purchases > Requests for Quotation - Ensure you have some POs with: - No activities - Only normal activities - At least one exception activity (type with Decoration Type = Alert…
Steps to reproduce:
- Purchases > Requests for Quotation
- Ensure you have some POs with:
- No activities
- Only normal activities
- At least one exception activity (type with Decoration Type = Alert or Error, unarchive “Exception” in Activity Types if needed)
- Apply the “Warnings” filter
- Before this change:
- POs with no activities incorrectly appear under “Warnings”
- Inverting the filter shows the expected POs with exception activities
Cause of the issue:
- The "Warnings" filter domain relied on a negative operator on the exception decoration field:
https://github.com/odoo/odoo/blob/cebc2acbd0e4d2373e0d1f96bcd291bf70be3a03/addons/purchase/views/purchase_views.xml#L459-L460
- `activity_exception_decoration` is a computed selection set to 'warning' or 'danger' when an exception activity exists:
https://github.com/odoo/odoo/blob/cebc2acbd0e4d2373e0d1f96bcd291bf70be3a03/addons/mail/models/mail_activity_mixin.py#L89-L91
- In 17.0, the search method simply forwards the operator to the decoration type of the linked activities:
https://github.com/odoo/odoo/blob/cebc2acbd0e4d2373e0d1f96bcd291bf70be3a03/addons/mail/models/mail_activity_mixin.py#L120-L121
With ('activity_exception_decoration', '!=', False) this becomes ('activity_ids.activity_type_id.decoration_type', '!=', False), i.e. it relies on a negative operator on the decoration type instead of explicitly matching the exception values. This makes the domain more fragile than an explicit condition on 'warning'/'danger', even though the UI semantics expect “Warning” only when activity_exception_decoration is set.
Why this was not intended:
- The field is truthy only when exception activities exist, a filter named “Warnings” should select exactly those records.
- The negative-operator domain includes records with no activities due to how `!=` works on relational fields, contradicting that semantics.
opw-5177277This update fixes an issue in Studio where adding a new selection option without entering a value could crash the interface. Users can now click Add Selection safely, even if the input is left empty, which makes field setup more reliable.
Original PR description
**Before this commit:** When a user added a new Selection field and clicked the “Add Selection” :white_check_mark: button without entering any value, a `Client Error: (Cannot read properties of undefined (reading 'trim'))` was raised, resulting in a crash of the Studio interface. **After this commit:** Clicking the “Add Selection” :white_check_mark: button with an empty input no longer triggers an error. task-5159376
This update prevents accounting reports from crashing when a saved report points to a handler model that is no longer available. Instead of failing, the system now safely ignores the missing handler and continues to open the report normally, which helps during upgrades or when related modules have been removed or renamed.
Original PR description
In some customer databases, the `custom_handler_model_name` or its fallback `root_report_id.custom_handler_model_name` may point to a model that no longer exists (e.g. `l10n_il.tax.report.handler`).…
In some customer databases, the `custom_handler_model_name` or its fallback `root_report_id.custom_handler_model_name` may point to a model that no longer exists (e.g. `l10n_il.tax.report.handler`). https://github.com/odoo/enterprise/blob/7410249cfdfaca19769e1c9aed813666af8eb19d/account_reports/models/account_report.py#L2578
The previous implementation returned this model name directly without checking if it was registered, which caused a KeyError during report access.
This fix validates the model presence in `self.env` before returning it, and falls back to None if missing. This ensures stable behavior when localization or custom modules are removed or renamed during upgrades.
```python3
Traceback (most recent call last):
File "/home/odoo/src/odoo/17.0/odoo/service/server.py", line 1374, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-16>", line 2, in new
File "/home/odoo/src/odoo/17.0/odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/17.0/odoo/modules/registry.py", line 110, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/17.0/odoo/modules/loading.py", line 519, in load_modules
migrations.migrate_module(package, 'end')
File "/home/odoo/src/odoo/17.0/odoo/modules/migration.py", line 221, in migrate_module
exec_script(self.cr, installed_version, pyfile, pkg.name, stage, stageformat[stage] % version)
File "/home/odoo/src/odoo/17.0/odoo/modules/migration.py", line 239, in exec_script
migrate(cr, installed_version)
File "/home/odoo/src/odoo/17.0/addons/l10n_il/migrations/1.1/end-migrate_update_taxes.py", line 8, in migrate
env['account.chart.template'].try_loading('il', company)
File "/home/odoo/src/odoo/17.0/addons/account/models/chart_template.py", line 155, in try_loading
return self._load(template_code, company, install_demo)
File "/home/odoo/src/odoo/17.0/addons/account/models/chart_template.py", line 214, in _load
self._post_load_data(template_code, company, template_data)
File "/home/odoo/src/enterprise/17.0/account_reports/models/chart_template.py", line 31, in _post_load_data
company._get_and_update_tax_closing_moves(fields.Date.today(), include_domestic=True)
File "/home/odoo/src/enterprise/17.0/account_reports/models/res_company.py", line 163, in _get_and_update_tax_closing_moves
report, tax_closing_options = tax_closing_move._get_report_options_from_tax_closing_entry()
File "/home/odoo/src/enterprise/17.0/account_reports/models/account_move.py", line 272, in _get_report_options_from_tax_closing_entry
report_options = tax_report.with_context(allowed_company_ids=company_ids).get_options(previous_options=options)
File "/home/odoo/src/enterprise/17.0/account_reports/models/account_report.py", line 1670, in get_options
initializer(options, previous_options=previous_options)
File "/home/odoo/src/enterprise/17.0/account_reports/models/account_report.py", line 1619, in _init_options_custom
self.env[custom_handler_model]._custom_options_initializer(self, options, previous_options)
File "/home/odoo/src/odoo/17.0/odoo/api.py", line 550, in __getitem__
return self.registry[model_name](self, (), ())
File "/home/odoo/src/odoo/17.0/odoo/modules/registry.py", line 209, in __getitem__
return self.models[model_name]
KeyError: 'l10n_il.tax.report.handler'
select a.id,a.name,a.custom_handler_model_id,d.name,d.module,d.create_date,d.write_date from account_report a JOIN ir_model_data d on a.id = d.res_id where d.name = 'vat_report' and d.mod
el = 'account.report';
+----+----------------------------------+-------------------------+------------+---------+----------------------------+----------------------------+
| id | name | custom_handler_model_id | name | module | create_date | write_date |
|----+----------------------------------+-------------------------+------------+---------+----------------------------+----------------------------|
| 4 | {"en_US": "VAT Report (PCN874)"} | 770 | vat_report | l10n_il | 2023-02-05 09:42:05.581858 | 2025-06-25 09:19:46.431141 |
+----+----------------------------------+-------------------------+------------+---------+----------------------------+----------------------------+
SELECT 1
Time: 0.106s
select m.id,m.model,m.name,d.name,d.module from ir_model m JOIN ir_model_data d on m.id = d.res_id where d.res_id = 770 and d.model = 'ir.model';
+-----+----------------------------+------------------------------------------------+----------------------------------+-----------------+
| id | model | name | name | module |
|-----+----------------------------+------------------------------------------------+----------------------------------+-----------------|
| 770 | l10n_il.tax.report.handler | {"en_US": "Israely Tax Report Custom Handler"} | model_l10n_il_tax_report_handler | l10n_il_reports |
+-----+----------------------------+------------------------------------------------+----------------------------------+-----------------+
SELECT 1
Time: 0.009s
select id,name,author,latest_version,state,demo from ir_module_module where name='l10n_il_reports';
+-----+-----------------+-----------+----------------+-----------+-------+
| id | name | author | latest_version | state | demo |
|-----+-----------------+-----------+----------------+-----------+-------|
| 997 | l10n_il_reports | Odoo S.A. | 16.0.1.7.2 | installed | False |
+-----+-----------------+-----------+----------------+-----------+-------+
SELECT 1
Time: 0.009s
```
**### There are some upgrade-specific PR**
<img width="1230" height="64" alt="2025-11-12_17-47" src="https://github.com/user-attachments/assets/0f75d3e0-1c95-48bf-adb6-41473f3f1da2" />
opw-5229611
upg-3258991This change removes a unit test that depended on module-specific and Enterprise-only data, which was causing build failures. The test can be reintroduced later in the proper module if needed, but removing it now helps keep the test suite stable.
Original PR description
The unit test `test_can_reset_deferred_invoice()` has several issues. 1. It should be in the `account_audit_trail` module, as the test requires this module. [Unit test documentation: modules](https://www.odoo.com/documentation/19.0/developer/tutorials/unit_tests.html#modules). 2. The test references fields from the Enterprise module `account_accountant`, `account.move.line.deferred_start_date` and `account.move.line.deferred_end_date`. This causes build tests to fail. As such, the test should be removed now and replaced later if necessary. Fixes [PR 235223](https://github.com/odoo/odoo/pull/235223) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change reduces the amount of data loaded when validating tax-related information for multiple invoices at once. It helps avoid memory errors when registering batch payments, making the payment process more reliable for larger invoice sets.
Original PR description
### Description: When trying to register a payment for multiple invoices, it is possible to trigger an Out Of Memory error. This is caused by the constraint `_validate_taxes_country`, calling the compute `_compute_tax_country_id` on all of the moves. To avoid that, we just retrieve the field we need rather than fetching everything. ### Reference: opw-5152687