Daily updates from Odoo
Tuesday, November 4, 2025
155 changes
7 changes
Resolved issues and error corrections
Guests who have not been online for the past 12 hours will no longer receive notifications when a call starts. This reduces unnecessary alerts and helps prevent confusion for people who are no longer actively connected.
Original PR description
With this commit, guests who haven't been online in the last 12 hours will not be notified of a call starting. task-5136330 backport of https://github.com/odoo/odoo/pull/230337 Forward-Port-Of: odoo/odoo#233669 Forward-Port-Of: odoo/odoo#233221
This change keeps scrap orders consistent when the product is changed. If the new product does not use a BoM, the system now clears the BoM value instead of leaving an outdated one behind, preventing the scrap quantity from being set to zero by mistake.
Original PR description
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the…
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the bom_id field is hidden and remains set. This will cause the scrap quantity to be set to 0 when they validate the scrap. However, the product move actually happens for the correct quantity causing an inconsistency. Purpose: This will either set the bom_id field to False if the new product doesn’t have a valid BoM, or it will update it to the first available BoM. Steps to Reproduce on Runbot: 1. Create a scrap order for a product that has a kit type BoM and set the kit field. 2. Change the product to a product without a kit type BoM. 3. Validate the scrap order. 4. Observe the quantity field is set to 0, but there are product moves for the correct quantity. opw-5122880 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234050 Forward-Port-Of: odoo/odoo#231937
This change makes uploaded website videos compatible with content sanitization, so pages can still be edited later by users with restricted permissions. It prevents a situation where a video added by an admin could make the page appear uneditable for other users.
Original PR description
Steps to reproduce the current behaviour: - Update the DEMO user to be a website "restricted editor" and sales "admin" who cannot bypass HTML field sanitization. - As ADMIN, add a YouTube video to a…
Steps to reproduce the current behaviour: - Update the DEMO user to be a website "restricted editor" and sales "admin" who cannot bypass HTML field sanitization. - As ADMIN, add a YouTube video to a product page > Save. - As DEMO, try to update the content on the product page > You cannot (a dialog informs you that you cannot edit the content because an admin edited it previously). Explanation: Starting from [1], an HTML field can be flagged as `sanitize_overridable` which allowed users with the `base.group_sanitize_override` group to skip the HTML field sanitize process. If such users added some content that is not considered "sanitize friendly" (e.g. YouTube iframe), a restricted user won't be allowed to add content in the fields, since the sanitizer will remove the original content from the DOM. For this case, the code from [2] added an implementation to consider the field as none editable and warn the user once he tries to update it. Implementation: The goal of this commit it to fix the current limitation for video upload that currently prevents non admin users to edit a website record once an admin adds a video on it... The idea of the fix is the following: - We already have a technical fallback when uploading a video to save the iframe `src` to an attribute: `data-oe-expression`. - The public widget is now destroying the video iframes so they are never saved in the DOM. - A non-lazy code will build the iframes immediately on page load. - The public widget can always create the iframes if they are not already created (for compatibility). [1]: https://github.com/odoo/odoo/commit/cf844e34dd0ce4830eb99fd0fa5b6b9cb58c867c [2]: https://github.com/odoo/odoo/commit/cb80c15d3db49ede3c93171abcaa9064b88822c6 task-3757205 Forward-Port-Of: odoo/odoo#232871 Forward-Port-Of: odoo/odoo#175717
This update helps the system notice broken browser connections much sooner when the network is slow or unstable. As a result, users are less likely to experience long pauses where messages stop arriving without warning.
Original PR description
When a TCP connection is not closed cleanly, it can take minutes to detect a closed WebSocket connection. During this time, no messages are received. This can happen in slow or unstable network conditions. Browsers do not expose WebSocket ping/pong mechanisms. To detect dead connections quickly, periodic application level messages are sent if no messages were either sent or received within a minute. This approach ensures quicker detection compared to relying on the OS TCP timeout, which is typically set to a high value. X-original-commit: d043e12 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#234275
Fixed an issue where checkout could get stuck loading when external tax checks failed during Brazilian sales. Instead of freezing, the system now captures the problem and shows it in the next checkout step so customers can continue or correct the issue.
Original PR description
**Issue** When buying products in the Brazilian localization, certain errors in external tax calculation were not properly caught by the frontend. This caused the checkout to hang indefinitely with…
**Issue** When buying products in the Brazilian localization, certain errors in external tax calculation were not properly caught by the frontend. This caused the checkout to hang indefinitely with infinite loading. Examples include missing NCM codes or IAP service failures due to invalid addresses. **Steps to Reproduce** 1. Install Brazilian localizations (l10n_br, l10n_br_avatax, l10n_br_edi). 2. Configure Avatax Transfer API credentials (API ID and Key). 3. Create a website with a Brazilian company. 4. Add a product to the cart and proceed to checkout. 5. Choose a delivery method and observe that the UI gets stuck loading. **Root Cause** The `_order_summary_values` method in `website_sale_external_tax` called `_get_and_set_external_taxes_on_eligible_records()`, which could raise exceptions (e.g., IAPServerError). These exceptions were not handled, so they propagated to the frontend as generic RPC errors. The frontend has no built-in mechanism to display these exceptions as user-friendly messages, resulting in infinite loading. **Fix** Wrap the external tax calculation in `_order_summary_values` and catch `UserError`. Instead of letting the exception propagate as a generic RPC error, attach the error message to the result dictionary under `external_tax_error`. This prevents the frontend from hanging while still making the underlying problem visible in the next checkout step, where validation errors are properly handled and shown to the user. Opw-5052078 Forward-Port-Of: odoo/enterprise#96213 Forward-Port-Of: odoo/enterprise#95045
The mail system now checks only real emails when looking for repeated sender loops. This avoids incorrectly blocking a customer’s next email when other non-email messages from the same author had already increased the count.
Original PR description
When detecting loops with _detect_loop_sender if the count of these messages exceeds the LOOP_THRESHOLD, the next email from that user is blocked, even if the number of new emails alone hasn't yet crossed the threshold due to mail messages that are not email triggering the loop detection. This happens because it searches for messages in the mail.message model that share the same model name and author irrespective of the message type. To correct this, the function's search criteria must be modified to explicitly filter for messages where the message_type is set to 'email'. opw-5122962 Forward-Port-Of: odoo/odoo#232026
This update corrects a stock-related automated test that previously appeared to pass even though it had hidden issues. It helps ensure future checks are reliable, reducing the risk of carrying forward broken behavior unnoticed.
Original PR description
Due to an issue in the runbot, the test associated with the PR: odoo#229958 passed despite underlying conflicts and the PR was merged. This PR addresses and resolves those issues to ensure the test functions correctly. Impacted versions: - 18.0 - saas-18.2 - saas-18.3 - saas-18.4 19.0 and master are addressed in odoo#230685 to replace `procurement.group` with `stock.rule` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230687
12 changes
Resolved issues and error corrections
The website now uses the standard redirect utility when sending users to a URL after a rental search action. This makes navigation more reliable and reduces the chance of redirect issues on rental-related pages.
Original PR description
Community PR: https://github.com/odoo/odoo/pull/233842 Forward-Port-Of: odoo/enterprise#98686 Forward-Port-Of: odoo/enterprise#98492
Customers can no longer cancel a self-order once it has been sent to the kitchen display. This avoids mismatches between the backend and the kitchen screen and ensures cancellations follow the proper in-store process.
Original PR description
Currently, it is possible to cancel orders that have been sent to the kitchen display. However when doing so, the kitchen displayd does not receive any information about the cancellation. Steps to reproduce: ------------------- - Modify restaurant and enable self ordering - Open self an place an order (not paid but sent to kitchen) - Go back to "My orders" and cancel it > Order is cancelled in backend but not in the kitchen display Why the fix: ------------ When an order is sent to the kitchen the only way to cancel it should be by going to the register. Therefore now, if an order is present on the kitchen display we will not show the cancel button. opw-5030223 Community: https://github.com/odoo/odoo/pull/229039 Forward-Port-Of: odoo/enterprise#95770
This update fixes how customers are sent to the correct page after certain webshop actions, such as cart updates, product options, wishlist actions, and reorder flows. It helps ensure users consistently land on the intended URL instead of seeing broken or unexpected navigation.
Original PR description
Enterprise PR: https://github.com/odoo/enterprise/pull/98492 Forward-Port-Of: odoo/odoo#234164 Forward-Port-Of: odoo/odoo#233842
Customers can no longer cancel a self-order once it has been sent to the kitchen display. This avoids situations where the order is removed in the system but the kitchen is never informed, helping staff keep orders consistent and reducing confusion.
Original PR description
Currently, it is possible to cancel orders that have been sent to the kitchen display. However when doing so, the kitchen displayd does not receive any information about the cancellation. Steps to reproduce: ------------------- - Modify restaurant and enable self ordering - Open self an place an order (not paid but sent to kitchen) - Go back to "My orders" and cancel it > Order is cancelled in backend but not in the kitchen display Why the fix: ------------ When an order is sent to the kitchen the only way to cancel it should be by going to the register. Therefore now, if an order is present on the kitchen display we will not show the cancel button. opw-5030223 Enterprise: https://github.com/odoo/enterprise/pull/95770 Forward-Port-Of: odoo/odoo#229039
When a user changes the product on a scrap order, the related Bill of Materials is now refreshed automatically. This prevents the scrap quantity from being reset incorrectly and avoids mismatches between what users see and what is actually processed.
Original PR description
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the…
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the bom_id field is hidden and remains set. This will cause the scrap quantity to be set to 0 when they validate the scrap. However, the product move actually happens for the correct quantity causing an inconsistency. Purpose: This will either set the bom_id field to False if the new product doesn’t have a valid BoM, or it will update it to the first available BoM. Steps to Reproduce on Runbot: 1. Create a scrap order for a product that has a kit type BoM and set the kit field. 2. Change the product to a product without a kit type BoM. 3. Validate the scrap order. 4. Observe the quantity field is set to 0, but there are product moves for the correct quantity. opw-5122880 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234050 Forward-Port-Of: odoo/odoo#231937
This fix prevents the system from trying to clean reservations for kit products in situations where that can trigger an error. As a result, users can open and manage inventory quantities normally without being blocked by this issue.
Original PR description
Since this commit: 766ec99 We try to clean reservations because, for some reason, there could be a discrepancy between the sum of “stock.move.line” and the quantity/reserved quantity on…
Since this commit: 766ec99 We try to clean reservations because, for some reason, there could be a discrepancy between the sum of “stock.move.line” and the quantity/reserved quantity on “stock.quant”. However, there are cases where a user creates a storable product, updates its quantity, and then uses it in a “stock.move.line”, confirms it, and later changes the product type to a kit. So, when trying to clean the reservations for these “stock.move.line”, a user error occurs because the system attempts to create a quant for a kit-type product: https://github.com/odoo/odoo/blob/c07778bbce4311c142bd8e2ce3013998d4f126ae/addons/mrp/models/stock_quant.py#L6-L11 As a result, each time users try to access the quant list, clean_reservation is triggered, causing a user error that prevents them from modifying the quantity of any quant. Solution: For kits, we can skip cleaning their quant to avoid unnecessary errors. This is a manual forward-port of #200595 opw-4625002 opw-4624008 opw-4621175 opw-4625465 opw-4621504 opw-4623523 opw-4621508 opw-4623329 opw-4629386 opw-5179369
The chat bubbles on mobile now stay in place when tapped instead of briefly moving down. This makes the chat experience smoother and avoids a distracting visual jump in Discuss and on website pages.
Original PR description
**Description of the issue/feature this PR addresses:** when clicking on chat bubble in mobile, the chat bubbles were moving down temporarily **Current behavior before PR:** when clicking on chat…
**Description of the issue/feature this PR addresses:** when clicking on chat bubble in mobile, the chat bubbles were moving down temporarily **Current behavior before PR:** when clicking on chat bubble in mobile, the chat bubbles were moving down temporarily. this happens because in some contexts, the chat hub bubbles are lift up, like in discuss app and at bottom of website page. This was done with a `transform: translateY()` but when the button was being clicked the chat bubble temporarily resets its unlifted position, as if no `transform: translateY()` was in effect. **Desired behavior after PR is merged:** This fixes the issue by using `bottom` CSS style rule. Chat hub bubbles part has a bottom value, the lift up is now designed to combine with the static bottom value, thus bubbles part stay at the desired position even when being clicked. Backport of #225757 task-[4914438](https://www.odoo.com/odoo/project/1519/tasks/4914438) Before  After  --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change ensures customers receive the expected email when an order status update comes back from Gelato. It helps keep buyers informed automatically and reduces missed notifications in the order process.
Original PR description
Fix not sending the email to customer, when order status update was received from Gelato. opw-4962878 Forward-Port-Of: odoo/odoo#233587
This fixes a stock issue where items with a lot or serial number could be incorrectly balanced against an untracked quantity instead of the correct lot. As a result, inventory remained inconsistent after barcode deliveries and later receipts; the correction keeps stock levels tied to the proper lot, which improves traceability and prevents stock mismatches.
Original PR description
Uecase to reproduce: - Create a quant with a product and 10 lot A - Create a delivery order - Open barcode - In barcode, deliver the product with lot C Current behavior: You have 2 quants: - 10 lot A - -1 without lot Expected behavior: - 10 lot A - -1 lot C It happens because the code try to balance negative quant for lot/sn in a stack of quants without lot/sn for the product. However in this case the barcode create a quant without quantity and without lot. In this case the system wants to update it due to an incorrect condition. It's an issue since in later receit with the correct lot. The quant will never be balanced and it will result with - -1 without - 1 lot C 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#231853
We fixed an issue where checkout could get stuck loading if an external tax check failed during order summary updates. Instead of freezing, the problem is now captured and surfaced so the customer can continue and see a clear message in the next checkout step.
Original PR description
**Issue** When buying products in the Brazilian localization, certain errors in external tax calculation were not properly caught by the frontend. This caused the checkout to hang indefinitely with…
**Issue** When buying products in the Brazilian localization, certain errors in external tax calculation were not properly caught by the frontend. This caused the checkout to hang indefinitely with infinite loading. Examples include missing NCM codes or IAP service failures due to invalid addresses. **Steps to Reproduce** 1. Install Brazilian localizations (l10n_br, l10n_br_avatax, l10n_br_edi). 2. Configure Avatax Transfer API credentials (API ID and Key). 3. Create a website with a Brazilian company. 4. Add a product to the cart and proceed to checkout. 5. Choose a delivery method and observe that the UI gets stuck loading. **Root Cause** The `_order_summary_values` method in `website_sale_external_tax` called `_get_and_set_external_taxes_on_eligible_records()`, which could raise exceptions (e.g., IAPServerError). These exceptions were not handled, so they propagated to the frontend as generic RPC errors. The frontend has no built-in mechanism to display these exceptions as user-friendly messages, resulting in infinite loading. **Fix** Wrap the external tax calculation in `_order_summary_values` and catch `UserError`. Instead of letting the exception propagate as a generic RPC error, attach the error message to the result dictionary under `external_tax_error`. This prevents the frontend from hanging while still making the underlying problem visible in the next checkout step, where validation errors are properly handled and shown to the user. Opw-5052078 Forward-Port-Of: odoo/enterprise#96213 Forward-Port-Of: odoo/enterprise#95045
This change fixes an error in hardware driver certificate checks when comparing certificate expiration dates. It ensures the system uses matching date formats, preventing crashes during certificate validation and keeping connected hardware services working reliably.
Original PR description
Before this commit, datetime.now() was compared to cert.not_valid_after_utc, leading to an error because we compare offset-naive and offset-aware datetimes After this commit, we set an offset-aware datetime.now() if we use not_valid_after_utc Issue introduced in #234005 opw-5237595 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects an automated stock test that had been passing incorrectly due to a runbot issue, despite underlying code conflicts. Fixing the test helps ensure future changes in stock management are validated properly and reduces the risk of unnoticed regressions.
Original PR description
Due to an issue in the runbot, the test associated with the PR: odoo#229958 passed despite underlying conflicts and the PR was merged. This PR addresses and resolves those issues to ensure the test functions correctly. Impacted versions: - 18.0 - saas-18.2 - saas-18.3 - saas-18.4 19.0 and master are addressed in odoo#230685 to replace `procurement.group` with `stock.rule` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230687
17 changes
Resolved issues and error corrections
PDF and spreadsheet attachments are now indexed in a way that keeps text and table structure more readable. This improves the quality of search and AI features that rely on attachment content, such as semantic retrieval and RAG.
Original PR description
### Problem 1. **PDF documents** often produced fragmented or misaligned text, especially in multi-column or tightly formatted layouts. 2. **Tabular files** (`.xlsx`, `.ods`) lost their row–column relationships during extraction, making the indexed text less meaningful for semantic processing. ### Changes #### PDF Attachments - Introduced configurable **`LAParams`** parameters in `pdfminer` to fine-tune text extraction for complex or multi-column layouts. #### Tabular Attachments - Updated **XLSX** and **ODS** indexers to output data in **CSV-like format**, preserving **row–column context** for better AI readability. - Uses **`openpyxl`** (now part of Odoo requirements) to efficiently extract and format spreadsheet data in xlsx files. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr task-id-5045336
This fix ensures the views needed to settle invoices are loaded correctly for users who are allowed to perform the action. As a result, employees without administrator access can now settle invoices as expected, preventing a workflow blockage at the point of payment closing.
Original PR description
Before this commit, a user without the "Role / Administrator" group could not settle invoices because the required views were not loaded. After this commit, the necessary views are properly loaded, allowing all authorized users to settle invoices as expected. opw-5138892
This update keeps the scrap order’s BoM information in sync when the product is changed. It prevents cases where the displayed scrap quantity becomes zero while the actual stock movement still uses the correct amount, avoiding inconsistent results during validation.
Original PR description
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the…
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the bom_id field is hidden and remains set. This will cause the scrap quantity to be set to 0 when they validate the scrap. However, the product move actually happens for the correct quantity causing an inconsistency. Purpose: This will either set the bom_id field to False if the new product doesn’t have a valid BoM, or it will update it to the first available BoM. Steps to Reproduce on Runbot: 1. Create a scrap order for a product that has a kit type BoM and set the kit field. 2. Change the product to a product without a kit type BoM. 3. Validate the scrap order. 4. Observe the quantity field is set to 0, but there are product moves for the correct quantity. opw-5122880 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234050 Forward-Port-Of: odoo/odoo#231937
This update corrects the badge display in list views so colored badges now appear as expected. It improves visual consistency and helps users recognize statuses more easily at a glance.
Original PR description
Purpose ======= Fix the rotting variant of the badge selection field in list views which should properly support the color field option. Specification ============= The 'ListBadgeSelectionRotting' widget was inheriting from the 'BadgeSelectionField' which doesn't support any color in badges. It should inherit from the list variant of the badge selection field called 'ListBadgeSelectionField' which supports the color field option. Task-5186979 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a broken warehouse test so it no longer appears to pass when it should fail. It helps ensure future changes in stock handling are validated properly and reduces the risk of hidden issues reaching users.
Original PR description
Due to an issue in the runbot, the test associated with the PR: odoo#229958 passed despite underlying conflicts and the PR was merged. This PR addresses and resolves those issues to ensure the test functions correctly. Impacted versions: - 18.0 - saas-18.2 - saas-18.3 - saas-18.4 19.0 and master are addressed in odoo#230685 to replace `procurement.group` with `stock.rule` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230687
This change corrects a spelling mistake in the Attendance module, replacing “Beetween” with “Between.” It improves the clarity and professionalism of the interface for users reviewing overtime rules.
Original PR description
This pull request fixes a typo in the hr_attendance module where the word `Beetween` was displayed instead of `Between`. Before Fix: <img width="1920" height="927" alt="before_fix" src="https://github.com/user-attachments/assets/ffe5e7c2-1d87-47fd-ac82-2b7d80f36448" /> After Fix: <img width="1920" height="927" alt="after_fix" src="https://github.com/user-attachments/assets/961f1f9f-9318-4ab0-8c61-56b8e87b9924" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a warning in the Hong Kong payroll localization so the related process can run cleanly again. It does not change business rules; it simply ensures the system uses the proper access check and avoids the build error.
Original PR description
Use `check_access` instead build-error-233453
The company switcher now correctly displays nested companies a user can access, even when an intermediate company in the hierarchy is not available. This prevents missing entries in the company list and makes it easier for users to switch to the right company context.
Original PR description
### Issue: Given a specific configuration, the `SwitchCompanyMenu` will not display all the companies a user can access. Suppose we have a company hierarchy with the following: `Company 1 > Company 2…
### Issue: Given a specific configuration, the `SwitchCompanyMenu` will not display all the companies a user can access. Suppose we have a company hierarchy with the following: `Company 1 > Company 2 > Company 3` (where 2 is a branch of 1, and 3 is a branch of 2). If a user has access to C1 and C3, but not C2, the menu selector will only display C1, rather than a hierarchy of all 3 companies with C2 disabled. This menu has been improved between versions, but the logic behind how we determine which companies to display remains consistent. We loop over each root company from `companyService.allowedCompaniesWithAncestors`, add it, and then add its children. Depending on whether the child company is accessible, it will be disabled (but still displayed) in the hierarchy list. `companyService` pulls its company information from the `session['user_companies']` dict that is created from `session_info`. For each of the `allowed_companies`, we build the `child_ids` from the intersection of each `user.company_id.child_ids` and `user.company_ids`. So we only add the child if it itself is an allowed company, which C2 would not be. C1 is now considered a root company with no children in our loop, so C2 is skipped. C2 isn't a root company either, so it will never be seen, and therefore neither will C3. ### Solution: A similar case was addressed in #138942, where given the same company hierarchy as above, the user instead has access to C2 and C3, but not C1. This PR adjusted how we build the `child_ids` for `disallowed_ancestor_companies` (C1 in this case), properly setting the children for us to loop through. We can use this same logic for the `child_ids` of `allowed_companies`, ensuring we can properly loop through the disallowed children of allowed companies. Additionally, we need to adapt the `CompanySelector` component, which previously grabbed all children even if they were disallowed. opw-4880477 Forward-Port-Of: odoo/odoo#229829 Forward-Port-Of: odoo/odoo#217001
Fixed an issue where checkout could hang indefinitely when external tax calculation failed for Brazilian sales. Instead of freezing, the system now captures the error and continues to show a user-friendly message at the next checkout step, helping customers understand and correct the problem.
Original PR description
**Issue** When buying products in the Brazilian localization, certain errors in external tax calculation were not properly caught by the frontend. This caused the checkout to hang indefinitely with…
**Issue** When buying products in the Brazilian localization, certain errors in external tax calculation were not properly caught by the frontend. This caused the checkout to hang indefinitely with infinite loading. Examples include missing NCM codes or IAP service failures due to invalid addresses. **Steps to Reproduce** 1. Install Brazilian localizations (l10n_br, l10n_br_avatax, l10n_br_edi). 2. Configure Avatax Transfer API credentials (API ID and Key). 3. Create a website with a Brazilian company. 4. Add a product to the cart and proceed to checkout. 5. Choose a delivery method and observe that the UI gets stuck loading. **Root Cause** The `_order_summary_values` method in `website_sale_external_tax` called `_get_and_set_external_taxes_on_eligible_records()`, which could raise exceptions (e.g., IAPServerError). These exceptions were not handled, so they propagated to the frontend as generic RPC errors. The frontend has no built-in mechanism to display these exceptions as user-friendly messages, resulting in infinite loading. **Fix** Wrap the external tax calculation in `_order_summary_values` and catch `UserError`. Instead of letting the exception propagate as a generic RPC error, attach the error message to the result dictionary under `external_tax_error`. This prevents the frontend from hanging while still making the underlying problem visible in the next checkout step, where validation errors are properly handled and shown to the user. Opw-5052078 Forward-Port-Of: odoo/enterprise#96213 Forward-Port-Of: odoo/enterprise#95045
This change corrects permission handling in attendance settings and overtime calculations. It ensures managers can view the ruleset as intended and that overtime lines correctly identify whether a user is the manager, preventing access issues and incorrect behavior for attendance officers.
Original PR description
Problem ---------- Ruleset can't be read if the user is not an attendance manager. The ruleset_id on employee have the group `group_hr_manager`but it doesn't imply attendance manager. Wrong computation of `is_manager` on overtime line if the user has only attendance officer rights and the employee with overtime has this user as attendance manager. Solution ---------- Make the ruleset readonly for hr manager. Fix the is_manager compute task-5180810
The product catalog now shows the right price when discounts are enabled, even if the product was already added to the order. This fixes a mismatch that could make catalog prices appear inconsistent with the order line and improves accuracy for sales users.
Original PR description
Catalog prices do not consider discounts when displayed separately from the unit price on the order line (if any for a given product). It was fixed for the /update_order_line_info route with 5d1837e47c20f04458472658c4f8ea71284fb6ca, but the issue still remained when fetching the original catalog data on opening, through the /order_lines_info route. This only happened when the product was already added to the order, because in this case we avoid recomputing the pricelist price and use the existing sale order line price. This commit makes sure that the sale order line discount field is correctly considered in that case, and also adds tests to cover the catalog more extensively. Fixes #232219 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233098
When an employee does not have a bank account linked, the payslip now displays a clear payment line instead of leaving it blank or showing a placeholder. This makes payslips easier to read and avoids confusion for payroll users and employees.
Original PR description
### Before: - While printing payslip previously if an employee do not have any bank linked we were not printing anything,. ### After: - If no bank account present we will use: Amount to be paid to [employee_name]: [amount] task- 5101235
This fix prevents a permission error when a non-admin user clicks a configurable product in Point of Sale, especially in branch-company setups. The product configurator now opens normally, so staff can continue serving customers without interruption.
Original PR description
**Issue:** In POS, clicking on a tax-free, inventory-tracked, configurable product as a non-admin user can throw an Access Rights error when trying to access it on a branch company's POS config. **Steps to reproduce:** - Configure a branching company on a parent company - Create a new POS restaurant on the child company - Create a configurable product that has no taxes associated with it and add it to a POS category so that it can be chosen from the POS screen - On a non-admin POS user, try to click that product 🐛 **Before this commit:** The user will get an Access Rights error. **After this commit:** The configurator dialog will load successfully. opw-5145176 Forward-Port-Of: odoo/odoo#231343
Self-order preparation printers were missing a needed IoT Box identifier, which could prevent printing through supported connection methods. This update loads the full device information so printing works reliably in self-order, matching the regular point of sale behavior.
Original PR description
Loading IoT preparation printers in self order was not providing the ID of the IoT Box record, required to print using both webrtc/longpolling/websocket. This commit fixes this issue by loading the whole device record, same as we do to load preparation printers in the regular pos.
This fix prevents an error that could appear when manufacturing products tracked by lot and producing more than the requested quantity. It ensures the lot information is kept correctly on the extra output lines, so the production can be completed without a missing lot warning.
Original PR description
For 'By Lots' manufactured products, producing more than requested gives the error "You need to supply a Lot/Serial Number for product...". This occurs from within _post_inventory operations: - update the finished move line with only the producing quantity - create a new finished move line with the exceeding quantity & lot - raise the warning under action_done because one move line has no lot By inverting the updates ( setting the lot before setting the quantity ) we ensure the lot is correctly propagated. task: 5232544 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 prevents an error when checking multiple payslips if some of them have no problems to report. As a result, payroll processing is more reliable and won’t stop unexpectedly in these cases.
Original PR description
When there are multiple payslip on which we call get_error_message, some may have no issues. In this case, it raises a traceback as issues is False. Introduced in https://github.com/odoo/enterprise/pull/94748
This update prevents chat bubbles from shifting down briefly when they are tapped on mobile devices. It keeps the chat widget in the correct position so the interface feels steadier and more polished.
Original PR description
**Description of the issue/feature this PR addresses:** when clicking on chat bubble in mobile, the chat bubbles were moving down temporarily **Current behavior before PR:** when clicking on chat…
**Description of the issue/feature this PR addresses:** when clicking on chat bubble in mobile, the chat bubbles were moving down temporarily **Current behavior before PR:** when clicking on chat bubble in mobile, the chat bubbles were moving down temporarily. this happens because in some contexts, the chat hub bubbles are lift up, like in discuss app and at bottom of website page. This was done with a `transform: translateY()` but when the button was being clicked the chat bubble temporarily resets its unlifted position, as if no `transform: translateY()` was in effect. **Desired behavior after PR is merged:** This fixes the issue by using `bottom` CSS style rule. Chat hub bubbles part has a bottom value, the lift up is now designed to combine with the static bottom value, thus bubbles part stay at the desired position even when being clicked. Backport of #225757 task-[4914438](https://www.odoo.com/odoo/project/1519/tasks/4914438) Before  After  --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234269
7 changes
Resolved issues and error corrections
This change removes a recently added bot-detection filter from website blog and slides. The previous check could be bypassed by crawlers, so it was allowing unwanted indexing of many tag combinations and could overload tag pages; the team is reverting it while a more reliable solution is developed.
Original PR description
This reverts [1] because the `is_a_bot` check is not reliable. Many crawlers spoof user agents or ignore robots rules, so they still index every tag combination and overload tag clouds. We revert while we look for a better protection. [1]: https://github.com/odoo/odoo/commit/4b1c3bfa83af2b1851db62df5aca4d5777a3d88c
A problem that could break quotation previews after customizing a sales report in Studio has been fixed. The preview now works correctly even when a field is added to the report layout, avoiding an error for users viewing quotations in the portal.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Edit the `sale.report_saleorder` report using `web_studio`. 2. Add the `amount_untaxed` field next to the "Untaxed Amount" subtitle. 3. Create or navigate to…
Versions -------- - 17.0+ Steps ----- 1. Edit the `sale.report_saleorder` report using `web_studio`. 2. Add the `amount_untaxed` field next to the "Untaxed Amount" subtitle. 3. Create or navigate to a quotation and click on the "Preview" action. Issue ----- A traceback occurs during the rendering of the `sale.sale_order_portal_template` template. ``` Error while render the template KeyError: 'doc' Template: sale.document_tax_totals Path: /t/t/tr/td[1]/span Node: <span t-field="doc.amount_untaxed"/> The error occurred while rendering the template sale.document_tax_totals and evaluating the following expression: <span t-field="doc.amount_untaxed"/> ``` Cause ----- In the `sale.report_saleorder_document` template, `doc` is used as the variable name for the current sale order. Consequently, the studio edit uses this variable name to modify the `sale.document_tax_totals` template called within `sale.report_saleorder_document`. However, the `sale.sale_order_portal_template` template, used for the portal preview, also calls `sale.document_tax_totals` but uses `sale_order` as the variable name for the current order. Solution -------- Add an alias `doc` for `sale_order` during the rendering of `sale.document_tax_totals` when called in the portal report preview. opw-5136553
This change fixes a mislabeled menu entry in the Recruitment app so the displayed name matches the intended wording. It improves clarity for users navigating the app, with no expected impact on business processes.
Original PR description
used wrong name in this forward-port: 4e847de16a71cb03cb21e05c6d535f6abfae0287 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 ensures employees’ extra hours from attendance are correctly shown in the Time Off dashboard. It matters because managers and employees now see the full available balance, including hours earned through attendance, without missing data.
Original PR description
### Steps to reproduce: - Install Attendance and Time off apps - Create some attendance with extra hours for the employee - Go to the employee's time off dashboard - Notice Extra Hours allocation is not shown ### Cause: When we are getting the allocation data we check for the leave types that require allocation https://github.com/odoo/odoo/blob/5f6d2afa8c09fe72c01d056ebef01214567a4a99/addons/hr_holidays/models/hr_leave_type.py#L473 And then when checking the types that doesn't require allocation we are looping on the res that we got from the super which already excluded those types https://github.com/odoo/odoo/blob/5f6d2afa8c09fe72c01d056ebef01214567a4a99/addons/hr_holidays_attendance/models/hr_leave_type.py#L41-L43 ### Fix: We loop over the self leave types to make sure we are getting all of the employee's leave data whether the type requires allocation or not. opw-5042325
This fix ensures tax closing entries are linked to the right tax report, so generating a closing from a generic report or a national variant no longer creates confusing duplicate draft moves. It also makes sure that when several national variants exist, they all point back to the generic tax report for consistent behavior.
Original PR description
To reproduce the issue, on a Belgian company: 1) From the Generic Tax Report, or any of its two grouped variants (Account>Tax or Tax>Account), click on the closing entry button. It generates a draft…
To reproduce the issue, on a Belgian company: 1) From the Generic Tax Report, or any of its two grouped variants (Account>Tax or Tax>Account), click on the closing entry button. It generates a draft move. Log a note on that move. 2) Open the national tax report of Belgium, for the same period as in 1). Click on the closing entry button again. ==> The draft move generated in 2) is NOT the same as the one generated in 1) (you can check that from the note logged in 1)). This is because tax_closing_report_id is too naively set on the account.move, to always match the report on which the button was clicked. This commit fixes that, ensuring we set the right report in the closing field. Something will be done in the migration script to 19.0 to set the report properly before creating the returns. The problem also occurs when multiple national variants are available : in this case each of those reports creates a distinct closing entry, with the exact same informations, giving the illusion we're doing per-report closings. In such cases, we associate the closing move to the Generic tax Report. opw-4858689
This fix corrects the minimum rental period calculation so it no longer assumes every month has 30 days. Customers can now select valid rental dates in shorter months like February without the system rejecting them incorrectly.
Original PR description
Issue: Currently minimum rental duration uses a hardcoded 30 days. This cause issue for non-30 days month e.g. Feb. which is 28 days. To reproduce: 1- Install `website_sale_renting` 2- From Setting, set `Minimum Rental Duration` to 1 month. 3- Create a rental product and from website, choose the date: - 01/02/2026 - 28/02/2026 4- This fails. The earliest end date it accepts is 03/03/2026. Cause: This is due to hardcoded 30 days: https://github.com/odoo/enterprise/blob/7ffb9f3cb0d818cf3616d6972df424bf0ca251a4/website_sale_renting/static/src/js/renting_mixin.js#L7-L12 https://github.com/odoo/enterprise/blob/7ffb9f3cb0d818cf3616d6972df424bf0ca251a4/website_sale_renting/static/src/js/renting_mixin.js#L47-L53 We can use luxon plus method instead. ```diff + const minEndDate = startDate.plus(Object.fromEntries([[unit, duration]])); ``` In all usages of `msecPerUnit` we can do the same. Also we can keep remove `msecPerUnit` from master. opw-5094534
This fix applies an earlier performance improvement to the spreadsheet version history view, so it no longer makes an unnecessary currency-related server request. It helps the version history action load more efficiently and reduces avoidable delays for users working with spreadsheets.
Original PR description
The perfomance commit added in https://github.com/odoo/odoo/pull/151725 did not account for the version history action that does not inherit from `AbstractSpreadsheetAction`. this missing value trickled down to a bug only detectable in the VersionHistory action and which is addressed in https://github.com/odoo/odoo/pull/232985 This commit adds the same performance to VersionHistory action. Task-5187293 Forward-Port-Of: odoo/enterprise#98038
12 changes
Resolved issues and error corrections
This fix ensures sales orders are marked as invoiced when no further stock operations are expected, even if the full ordered quantity was not delivered. It helps keep order and invoicing status accurate, reducing confusion for sales and accounting teams.
Original PR description
If no other operations are expected on the picking, even if the full quantity wasn't delivered, the order should be marked as invoiced. task-4607401 Fixes #144485 Partial revert of #115871 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an automated test so it can run correctly even when demo data is not installed. It ensures the required accounting setup is available, preventing the test from failing when creating a purchase invoice.
Original PR description
The test `test_dropship_return_backorders_bill_on_order` failed when running without demo data because no chart of accounts was installed, so no Purchase journal existed. As a result, `purchase_order.action_create_invoice()` raised: UserError: No journal could be found in company ... for any of those types: purchase This change inherits from `AccountTestInvoicingCommon` to have the necessary charts. [runbot-231285](https://runbot.odoo.com/odoo/error/231285) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents DHL shipping requests from failing when prices or weights are calculated with very small decimal differences. It improves reliability for delivery validation so shipments can be processed without avoidable errors.
Original PR description
Multiple rounding issues could cause DHL validation errors. Example with product price: - Create a storable product - Create a quotation with quantity 7, price 11.43 - Validate the SO - Go to delivery, use DHL carrier, validate - DHL traceback: 11.429999999999998 not multiple of 0.001 Example with product weight: - Create 3 products, each 0.1 kg - Create a SO with these products - Validate the SO - Go to delivery, use DHL carrier, validate - DHL traceback: 0.30000000000000004 not multiple of 0.001 See official DHL API documentation: https://developer.dhl.com/api-reference/dhl-express-mydhl-api and check the POST /shipments data schema opw-5000193
This change fixes an issue where customer details could be updated in two separate steps, causing inconsistent Peppol verification data and validation errors. It helps ensure partner information is saved consistently, reducing failed verifications for affected users.
Original PR description
In some cases, when doing two consequent writes instead of one batch, the ORM will trigger the dependencies needlessly, and it can end up to discrepancies like: EAS=0208, endpoint=BE... which lead to a validation error. opw-5228670 opw-5225590 opw-5228716 opw-5229057 opw-5232276
This fix improves the export dialog’s search so users can find fields by their visible names, even when those names include parent paths like “Order Lines/Product.” It prevents missed results caused by a mismatch in the search logic, while still keeping technical field IDs usable in debug mode.
Original PR description
The export dialog reverses field.string to prioritize field names over parent paths
in fuzzy search scoring. However, the search pattern was not reversed, causing
mismatches when searching with display names like "Order Lines/Product".
Before: pattern "Order Lines/Product" searched in reversed string "Product/Order Lines"
→ character order mismatch → no results
After: both pattern and string are reversed → proper matching
This fix ensures searching by display names (e.g., "Order Lines/Product") works
as expected, while technical IDs (e.g., "order_line/product_id") continue to work
in debug mode.
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-prThis fix prevents products that have been archived from being included in point of sale combos. It helps avoid accidentally selling items that the business has marked as inactive.
Original PR description
Before this commit, when a product used in a combo was archived, it was still possible to sell it through the combo in the PoS. After this commit, archived products are excluded from combos, preventing them from being sold inadvertently. opw-5180301 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents the delivery date on customer invoices from being unintentionally reset when the invoice is confirmed. It matters because it preserves the correct delivery information for billing and accounting, avoiding confusion and manual corrections.
Original PR description
Versions
--------
- 17.0+
Steps
-----
1. Enable anglo-saxon accounting;
2. have a product category with automated AVCO;
3. assign category to a deliverable product;
4. set product to invoice on delivery;
5. add product to a sales order;
6. confirm order & delivery;
7. create invoice;
8. change the delivery on the invoice;
7. confirm the invoice.
Issue
-----
The delivery date gets reset.
Cause
-----
Commit 818cf04f05767 added `delivery_date` as a permanently protected field when modifying moves or move lines, protecting the records on `write`. With anglo-saxon accounting however, new move lines are created when confirming an invoice, which in turn recalculate the delivery date, as `_get_protected_vals` isn't used for their move on `create`.
Solution
--------
Add `self.env['account.move'].protecting(_get_protected_vals({}, moves))` when creating new lines for a move, to avoid recomputing fields that should always be protected.
opw-4965036Fixed an issue where available stock was not refreshed in Barcode operations after changing the product or source location. This ensures users see the correct quantities when creating or editing internal transfers, reducing confusion and mistakes during warehouse work.
Original PR description
Issue: In this bug, stock quants are not being updated when product_id or location_id is updated. To reproduce: 1- Create a db with demo database and barcode installed 2- Enable storage locations 3- Open barcode -> operations -> Internal transfers -> New 4- Add a product -> e.g. Drawer which there are quants in demo 5- As you see quants are not shown Cause and Fix: This is a partial backport of: #55917 `_compute_product_stock_quant_ids` should depend on `product_id` and `parent_location_id` to be recomputed when product or source location is updated. opw-5065624
Point of Sale now correctly recognizes product packaging when scanned with a GS1 barcode and adds the related quantity automatically. This fixes a checkout issue that could previously require manual quantity adjustment, making barcode scanning faster and more reliable.
Original PR description
Before this commit, scanning a GS1 barcode for a product packaging did not add the quantity. opw-5003035 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update prevents Shiprocket from failing when taxes do not include India GST tags. It also makes the related test more reliable by explicitly using a 15% tax rate, so results are consistent across different company settings.
Original PR description
Some other test adds a fiscal position with tax mapping. This creates 2 problems
1. The new taxes have a tag, which means we evaluate the right hand of
https://github.com/odoo/enterprise/blob/8d3fe30c627eada1186c15480876fb2e8f7ddb59/delivery_shiprocket/models/shiprocket_request.py#L239
However, since l10n_in is not installed,
`tax.env.ref(f"l10n_in.tax_tag_{gst}gst", False)`
does not return anything (False is not a fallback)
https://github.com/odoo/odoo/blob/1e96a3d127e8f521d3027f7110026ae84e11ed5e/odoo/api.py#L588
So we end up looking for `None` in `tax_tag_ids`, which leads us to compare the `_name` properties, see
https://github.com/odoo/odoo/blob/1e96a3d127e8f521d3027f7110026ae84e11ed5e/odoo/models.py#L6545-L6558
2. The test added in 4d5df93 was assuming the default company 15% tax, which was not always true
Solution
-----
1. Provide a fallback for the `ref` lookup
2. Force a 15% tax in the test
-----
runbot-232692This change fixes an issue where users without Employees access could not select an employee in certain forms, especially on mobile. The system now correctly shows the available public employee information instead of incorrectly returning no results.
Original PR description
**Steps to reproduce** - With Studio, create a many2one field in relation to the Employee model. - Have a user with no "Employees" rights. - With this user and in mobile view, click on the field to…
**Steps to reproduce** - With Studio, create a many2one field in relation to the Employee model. - Have a user with no "Employees" rights. - With this user and in mobile view, click on the field to select an employee. -> No records found. Note: the many2one_avatar_employee widget used in HR apps avoid this problem. **Cause** Issue since https://github.com/odoo/odoo/commit/e962860c6f0d8ec9e50bb376e1faab5c7bc69374 The `web_search_read` on the private employee model returns no records when an `image_*` or `avatar_*` field is part of the requested fields. This is because we try to fetch these fields https://github.com/odoo/odoo/blob/188a3fe45fb41463ff86d1fa5e930ab43fb70d0e/addons/hr/models/hr_employee.py#L240 but they are not stored on the public employee model, and will not be put in cache. When performing a read after that, these fields are missing from cache. We try to fetch them from the db https://github.com/odoo/odoo/blob/e962860c6f0d8ec9e50bb376e1faab5c7bc69374/odoo/models.py#L3185 but this fetch is again done using the public employee. This results in missing values and is interpreted as an access error, no data is returned in `web_search_read`. **Solution** Read the problematic fields to make them present in cache when the cache of the public employee is copied to the one of the private employee. opw-4297115
Quality checks created per quantity now use the correct company for the related stock operation. This prevents confirmation errors in multi-company setups when users switch between companies.
Original PR description
When creating quality checks per quantity, a multi-company error occurs if the active company differs from the one defined on the control point. Steps to reproduce: - Create a Quality Control Point for Company B and Product Table for the receipt operation with a per-quantity control. - Create a receipt in Company B for this product but leave it in draft. - Switch to Company A and try to confirm → error. Root cause: The company_id was not set when creating the quality check, causing it to default to `env.company` (A) instead of the stock move line’s company (B). opw-86993