Daily updates from Odoo
Tuesday, November 18, 2025
42 changes · saas-18.3
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
Bancontact payments that need an extra verification step will now stay in a waiting state instead of being marked as failed too early. This prevents customers from being blocked during the payment process and helps payments complete correctly when additional approval is required.
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#235847This change makes the Swiss payroll transmission tests independent from accounting setup details, so they no longer rely on a specific journal being present on the payroll structure. It helps keep automated tests stable and reduces the risk of unrelated configuration causing failures.
Original PR description
Forward-Port-Of: odoo/enterprise#99264 Forward-Port-Of: odoo/enterprise#98672
This update prevents quality checks from appearing for items that were not actually picked or fully prepared, especially in the barcode app. It ensures users only answer the checks relevant to the goods that will really be validated, reducing confusion and avoiding unnecessary steps during receipts and transfers.
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#99565Imported accounting entries with matching numbers are now handled more reliably during reconciliation. This prevents one account’s reconciliation from accidentally blocking automatic matching on other accounts, improving the accuracy of FEC imports.
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 prevents the voice system from trying to reconnect when a user leaves the page normally. It avoids a conflict between two logout-related network requests, which could otherwise cause errors during sign-out or page unload.
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 failure in the manufacturing work order tour. It removes a search step that could cause timing issues and makes the target product appear first, so the test runs more reliably.
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 fix ensures imported FEC journal items keep their matching numbers correctly so automatic reconciliation can work across all affected accounts. It prevents a reconciliation on one account from accidentally blocking later automatic reconciliations on another account.
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 restores the ability to delete highlighted digits in the VoIP softphone when the selection starts at the beginning of the input. It keeps the safety checks that prevent unwanted cursor issues while making backspace work as expected again.
Original PR description
This commit fixes a regression introduced in commit [1] prevented deleting when a selection began at index 0; extend the guard so the numpad (keypad) backspace still removes the highlighted characters while keeping the cursor-safety logic. [1]: https://github.com/odoo/enterprise/commit/73b01fa5e1f56d4ab71d67760b15942fb2fa0e31 task-5217676 Forward-Port-Of: odoo/enterprise#99515 Forward-Port-Of: odoo/enterprise#99358
This update corrects how cash move actions record their related configuration in the Point of Sale app. As a result, receipts are less likely to run into printing problems after cash movements are created.
Original PR description
Before this commit, the cash move popup created an order that missing the config_id field, leading to potential issues in receipt printing. opw-5251257 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix corrects how pop-up dialogs are layered in mobile chat windows, so they now display on top of the chat instead of being hidden behind it. It improves the user experience by making message actions and confirmations immediately visible and easier to use.
Original PR description
**Purpose of this PR :** - Before this PR, dialogs triggered by message actions were rendered beneath the chat window in mobile view due to incorrect `z-index` hierarchy. This created a confusing UX where users had no visual feedback, only discovering the hidden dialog after minimizing the chat window. - This PR adjusts the `z-index` values to ensure dialogs are properly elevated above the chat window layer, restoring the expected stacking context and enabling direct interaction with modal dialogs. **Current behavior before PR:** [before_z.webm](https://github.com/user-attachments/assets/8063633f-6de7-4874-9884-963f4d223587) **Desired behavior after PR is merged:** [after_z.webm](https://github.com/user-attachments/assets/5674a953-8308-4469-907d-311a0d5a3f94) Backport of https://github.com/odoo/odoo/pull/235852 task-[5208322](https://www.odoo.com/odoo/project/1519/tasks/5208322)
The test suite was updated so a payment-related test only runs when the Accountant module is available. This avoids false failures in setups where that module is not installed and the tested behavior is not supported.
Original PR description
Some new tests weren't checking if the accountant module were installed. Without that module installed, those tests make no sense as the behaviour expected (possibility to create payments without creating an entry) is not present unless `accountant` is installed
Fixed an error that could appear when validating an order containing a gift card in the point of sale. Customers can now complete payment normally and the gift card report is generated as expected.
Original PR description
Current behavior: ----------------- A traceback occurs upon validation of an order that contains a giftcard. Steps to reproduce: ------------------- * Open shop * Add giftcard to the order * Go to pay the order * Select a payment method and validate > Observation: A traceback occurs, giftcard report not downloaded Why the fix: ------------ It seems like when this code was forwarded some uses this.env.services.report and some just this.report. https://github.com/odoo/odoo/commit/246515874e863b72626da11a4f5151599b0fa7b5 18.0 has already been changed to use this.env.services.reports and was not merged forward because 18.2 was already using this.env.services.reports. However we need to fix the version pat 18.2 using this.report. opw-5261898
Offers created from the recruitment screens now always receive a valid access token, whether they are generated from an applicant or created manually from the Offers list. This prevents broken offer links and ensures candidates can open the offer page even outside the normal session, such as in an incognito window.
Original PR description
- Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list view. - From the list…
- Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list view. - From the list view, click "New" to create an offer. - Compare both flows: * With "Generate Offer" button: the generated offer link has a valid token and works even in an incognito window. * With "New" button: the generated offer link has `token=False`, which leads to an invalid link. #### Issue In the first scenario, `action_generate_offer()` generates an `access_token` for the offer's link in `hr.applicant`. In the second scenario, no token was generated in `hr.contract.salary.offer`, so offers created via the "New" button end up with `access_token=False` in their links. #### Fix Add a compute to `access_token` in `hr.contract.salary.offer` to generate a token if there is no employee or if the employee on the offer has no linked user. #### Additional - Mark the field `access_token` as readonly. task-5051394
When a vendor bill line is moved to a different account, the linked non-deductible product line now updates to use the same account. This keeps the accounting entries aligned and avoids inconsistent posting on bills that split deductible and non-deductible amounts.
Original PR description
When you have a vendor bill with an invoice line linked to a journal item with the display type "non_deductible_product", if you modify the account_id of the invoice line, then the account_id of the…
When you have a vendor bill with an invoice line linked to a journal item with the display type "non_deductible_product", if you modify the account_id of the invoice line, then the account_id of the linked line should change to have the same value.
How to reproduce?
1. Create an asset model (Accounting > Configuration > Accounting > Asset Models)
2. Set the asset_model_id on an account (on the tab "Automation", set "Automate Asset" as "Create in draft" then set the "Asset Model" field with the created asset model
3. Duplicate the account having the created asset model
4. Create a vendor bill with an invoice line having:
- A strictly positive price unit
- A deductible_amount (Professional %) lower than 100 (this field is hidden by default)
5. Modify the account_id of the invoice line
6. Observe the journal items: the line with the non- deductible product should have the same account_id than the invoice line but it's not the case.
task-5156256
Forward-Port-Of: odoo/odoo#232121Refunds in Point of Sale now handle serial-numbered products correctly when only part of the original quantity is returned. Cashiers can choose which serial numbers to refund, and only the serials from the original sale are shown, which avoids incorrect refund entries and makes returns easier to process.
Original PR description
When refunding an order that contains a product tracked by serial number if you refund less than the total quantity of the product in the order all the serial numbers of the original order would be set anyway. Also you were not able to select the serial numbers to refund. Steps to reproduce: ------------------- * Create product P1, storable, tracked by serial number * Create 2 Serial Numbers SN1, SN2 for P1 * Create a POS order with 2x P1 (SN1, SN2) * Pay and validate the order * Refund the order, set quantity of P1 to 1 * Validate the refund > Observation: The refund order contains P1 with SN1 and SN2, and you cannot edit the serial numbers. Why the fix: ------------ We now allow to select the serial numbers when doing a refund and only show the serial numbers that were in the original order. We also select by default the same number of serial numbers as the quantity to refund. opw-4965171 Forward-Port-Of: odoo/odoo#230778
When processing deliveries by barcode, scanning an unreserved serial or lot for a kit component now updates the intended reserved line instead of creating an extra one. This prevents incorrect backorder prompts and makes delivery validation behave as expected.
Original PR description
### Issue: Scanning an unreserved lot of a kit component creates a new barcode line rather than updating the value of the initially reserved lot. As a result, the backorder porcess considers that…
### Issue:
Scanning an unreserved lot of a kit component creates a new barcode line rather than updating the value of the initially reserved lot. As a result, the backorder porcess considers that every unscanned yet initially reserved quantity is to backorder.
### Steps to reproduce:
- Create a kit product with a kit BOM:
- 1 x COMP (tracked by SN)
- Add two Serial numbers SN001 and SN002 in stock for the COMP product
- Create and confirm a delivery order for 1 unit of oyur kit product
- Go the barcode app to process your delivery
- Scan SN002
> A new line is created instead of updating the initial reservation
- Validate the delivery
#### > A backorder dialog opens proposing to update the unscanned reservation
### Cause of the issue:
Scanning a lot will first try to find a line to update, however, currently a line will only be found if the scanned lot has been reserved or if no particular lot has been reserved:
https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_model.js#L1659-L1661 https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_model.js#L743-L746 In particular, since no line is considered as valid, a new line is created. And, since this new line does not refer to any `move_id` while the existing one does, the move with the initial reservation will be backordered considering none of its demand was fulfilled: https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_picking_model.js#L904-L921
### Fix:
In order to loosen the condition of lot override on barcode lines we add a check on the package and the location of the line in order to avoid use cases where the initial move line already contains info's that are proper to the initial lot.
opw-5100026
Forward-Port-Of: odoo/enterprise#99129
Forward-Port-Of: odoo/enterprise#98589This fix ensures optional products only appear on the website where they are actually available. It prevents shoppers from seeing products that belong to a different website, making the cart experience more accurate and avoiding confusion in multi-website setups.
Original PR description
Steps to reproduce: =================== 1- Create another website 2- Sales app > Products > Open any product's form 3- In the Optional Products field, select any other product in your database for this field 4- Open the product form of the optional product you selected 5- Set the Website field to only be one of your websites, rather than All 6- Navigate to the Website app > Select the non set website in the other Steps 7- Open your shop > Select your main product > Click the add to cart button -> See the optional product appear in the pop-up. Cause: ====== _should_show_product function doesn't validate if a product is available on the website from which the request originates when handling multiple websites. Solution: ========= Update the function to take multiple websites into consideration opw-5179894 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233170
This update makes sure payment references sent to Flutterwave are always unique, even in testing or reset environments. It helps prevent duplicate payment reference errors and keeps payment processing reliable.
Original PR description
The `/payments` endpoint of the Flutterwave v3.0.0 API expects unique `tx_ref` parameters (matching Odoo's payment transaction `reference` field) to be passed. This is guaranteed by a UNIQUE() SQL constraint in Odoo, but testing sometimes involves dropping the database, leading to transaction references being repeated at the provider level for a given merchant account. This commit singularizes all transaction references by suffixing them with the current timestamp, ensuring that the `tx_ref` API parameter remains unique across transaction reference sequences. Forward-Port-Of: odoo/odoo#235799
This change restores tab switching in module information pages when the index.html file contains multiple tabs. It makes the behavior consistent with the Odoo Apps Store description view, so users can navigate the content as expected.
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 https://github.com/user-attachments/assets/ab7f8213-2112-46e2-bb72-5e01cc1f7883 * After: Make the nav tabs work as it should be https://github.com/user-attachments/assets/12c05abc-84f6-495e-ae5b-b6eca4d81a92 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#186568
Vendor batch payments will now use the correct sequence number when they are created and validated. This prevents vendor batches from being labeled with the wrong incoming-payment number, which could cause confusion and make tracking harder.
Original PR description
Currently when creating a vendor batch payment, the system may incorrectly use the inbound batch payment sequence to generate the batch name Steps to reproduce: - Create a Vendor payment. - Create a Vendor batch payment, add the payment, validate it. Issue: Name has been set using the incoming batch payment sequence This occurs because `batch_type` is set to readonly when a payment is added to the list. As result, the current batch type is never sent to the backend that will use the default 'inbound'. opw-5128426 Forward-Port-Of: odoo/enterprise#99570
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 grouped exports behave normally for affected tasks and similar records.
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#235979
Forward-Port-Of: odoo/odoo#235209This update improves how automated tests handle files, blob URLs, and mocked network responses. It helps prevent false test failures and makes test behavior closer to real browser behavior, which supports more reliable development and releases.
Original PR description
See commit messages for details --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234558
Fixed an issue where the expand/collapse button in email-style messages could appear without its icon. This makes long quoted emails easier to read and interact with inside the chatter and portal views.
Original PR description
Before this commit, when a message is of type "email" and contains parts are in foldable with more/less (like `<quote>`), the icon of the button for fold/unfold is missing. This happens because the icon is `.oi` and requires `odoo_ui_icons`. Message of type "email" have their content inside a shadow DOM, because we want to preserve the style of email inside the web client, at least in white theme. Shadow-DOM prevents the parent document to pass `odoo_ui_icons` thus the Shadow-DOM could not apply expected style on `.oi` icons. This commit fixes the issue by passing the required CSS as stylesheet to the shadow DOM, so that `.oi` icons are working inside the shadow DOM of message content of type "email".
This fix lets users revoke SEPA Direct Debit mandates even when those mandates were used for customer portal payments. It prevents access errors for non-admin billing users by ensuring the related saved payment methods are archived correctly in the background.
Original PR description
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** -…
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** - Enable SEPA Direct Debit payment provider in Test Mode - Create a mandate for a customer w/ valid IBAN - Create an invoice for that customer and post it - Action > Generate a Payment Link, open this in an incognito window - Pay using SEPA Direct Debit - Call `_set_done()` on the payment.transaction - Try to revoke the mandate as a non-admin with "Accounting / Billing" -> Access Error, can't modify payment.token **Cause:** - When SEPA Mandate is revoked, we check for all associated payment tokens (saved payment methods from SEPA Direct Debit payment provider) and deactivate them. - The check in code isn't called with sudo, so it uses the current user access rights, but only admins can modify the payment tokens in any way. **Solution:** - Write to the `linked_tokens` with sudo so we can archive the tokens regardless of user access opw-5136221 Forward-Port-Of: odoo/enterprise#99592 Forward-Port-Of: odoo/enterprise#99232
The activity list now keeps working across multiple pages even when some items are filtered out by access rules. This prevents users from getting stuck on the first page and ensures they can reach all activities they are allowed to see.
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 Forward-Port-Of: odoo/odoo#233585
This fix makes file uploads work correctly after interacting with elements placed inside shadow-root components. It prevents a confusing error and improves reliability in parts of the web interface that use this structure.
Original PR description
Before this commit, using 'setInputFile' after interacting with an element contained in any shadow root would not work ("no input has been interacted with" error).
This commit allows the listeners responsible for detecting clicks/focus on file inputs to handle the shadow root cases properly.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#235961This fix ensures mail records correctly update when they are deleted or restored. It improves the reliability of the messaging interface by keeping record status in sync with the latest changes.
Original PR description
The `exists` function of mail records is not reactive. Indeed, it uses a symbol, stored on the proxy internal field which is not observed. This commit fixes the issue by storing it on the record and ensuring we write on the full proxy when the record is deleted. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236159 Forward-Port-Of: odoo/odoo#236042
Fixed an issue where the “Update extra prices” action could disappear too early when editing product variants. This ensures all affected variant lines stay available for update after saving, so price changes are applied consistently across the product and used correctly in sales.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Have a product with multiple variants; 2. go to one of its attributes; 3. in the form, change the default extra price on multiple lines; 4. click on "Update…
Versions -------- - 18.0+ Steps ----- 1. Have a product with multiple variants; 2. go to one of its attributes; 3. in the form, change the default extra price on multiple lines; 4. click on "Update extra prices"; 5. add the updated variants to a sale order. Issue ----- Only the line on which "Update extra prices" was clicked has been updated, even though the button disappeared on all lines after clicking it. Cause ----- The `_compute_default_extra_price_changed` method only compares the `default_extra_price` of the current record to its `_origin` value. Consequently, after saving the form, it will return `False`, even though only one attribute has been updated. Solution -------- Aside from checking whether the value changed on the form, also check whether any product template attribute value has a `price_extra` that's different from the product attribute value's `default_extra_price`. This way, clicking on "Update extra prices" once won't make the other update buttons disappear. opw-5240236 Forward-Port-Of: odoo/odoo#235088