Daily updates from Odoo
Friday, October 24, 2025
30 changes · saas-18.4
Resolved issues and error corrections
The China ASBE balance sheet report now includes the correct lines and account mappings so liabilities and totals are balanced accurately. This helps businesses relying on Chinese financial reports get more reliable balance sheet results and reduces the risk of reporting discrepancies.
Original PR description
Fixes the balance_sheet_balanced test for asbe where the wrong line was set as liability. Also fixes the report itself that was ignoring one line, and missing one account. task-5175789 Forward-Port-Of: odoo/enterprise#97720 Forward-Port-Of: odoo/enterprise#97460
Expense users no longer lose selected analytic distributions when they click "Save & Close" on a new expense line. This prevents reporting and allocation errors by ensuring the chosen distribution is retained consistently.
Original PR description
**Issue** When creating an expense line, if the user selects an analytic distribution and clicks "Save & Close", the selected distribution is not saved. However, closing the popup with the "X" icon…
**Issue** When creating an expense line, if the user selects an analytic distribution and clicks "Save & Close", the selected distribution is not saved. However, closing the popup with the "X" icon does trigger the save. **Steps to Reproduce** 1. Go to Expenses > Expense Reports 2. Select an employee (e.g., Ronnie Hart) 3. Add a new expense line 4. Set an Analytic Distribution 5. Click Save & Close 6. Observe that the analytic distribution is not retained **Root Cause** The save behavior is triggered by a window click event, but clicks inside modals (like the analytic distribution popup) do not propagate as expected. Because everything within the popup is modal, the click does not satisfy the criteria to trigger saving the data. **Fix** Refine the modal detection logic in the `onWindowClick` handler. Specifically, allow modals that contain `this.widgetRef.el` to trigger the closing (and thus saving) behavior, ensuring that selections made in such modals are not lost when clicking Save & Close. Opw-4765799 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#213996
This fix updates the Vietnam localization migration so only the required tax records are refreshed. It helps protect company-specific accounting settings from being accidentally overwritten during an upgrade.
Original PR description
Problem The previous implementation used try_loading() which would reload the entire chart template, potentially overwriting user-customized configurations settings. Solution Replaced try_loading() with a more targeted approach usin _load_data for account.tax.group and account.tax 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#229476 Forward-Port-Of: odoo/odoo#227918
Spreadsheet documents now show their proper thumbnail in the Documents kanban view instead of appearing as a text preview. This makes it easier for users to recognize and open the right spreadsheet at a glance.
Original PR description
## Description Spreadsheets (stored as `application/json`) were matched by the textual preview, so the kanban card showed a text iframe instead of the sheet thumbnail. Now the spreadsheet preview is prioritized so the correct thumbnail displays. Task: [4963284](https://www.odoo.com/odoo/project/2328/tasks/4963284)
This fix ensures users working with Brazilian AvaTax errors see the tailored product list again instead of a generic product view. The restored view includes Brazil-specific tax fields, inline editing, and a direct button to open the full product form, helping users resolve issues faster and with the right information.
Original PR description
The actionable_errors widget was changed to ignore views if a view_mode key is present in the action [1]. It caused the standard product.product list view to pop up, which doesn't work in this case. The custom views have the relevant Brazilian fields (SPED type etc), can be edited inline, and have a "View" button allowing the user to go to the product form view. The standard view has none of these. [1] odoo/odoo@3bd833c73ea654d8558e3d9701ad41e4d75ddd6 opw-5154766
Spanish point-of-sale receipts now correctly display the company’s state name instead of empty brackets. This prevents confusing or incomplete receipt details for Spanish businesses using simplified invoices.
Original PR description
**Steps to reproduce:** - Set a spanish company, set the state - Set the "Simplified Invoice" journal in the settings - Go to PoS and make a purchase - On the receipt, empty brackets are shown where the state should be **Why the fix:** Before this commit, we checked that the company had a state set, and if it had, we displayed *state_id[1]* between brackets. Even if the state_id existed, this is not the correct structure for the state_id, so *state_id[1]* did not exist, and we displayed only the brackets. We now display the correct state name, still between brackets. opw-5098212 Forward-Port-Of: odoo/odoo#232689 Forward-Port-Of: odoo/odoo#230141
Failed email campaigns with hundreds of thousands of recipients can now be retried in smaller batches. This prevents memory errors during resend attempts, helping larger customers recover campaign delivery without manual intervention.
Original PR description
Steps to reproduce the issue: 1. Have 100s of thousands of recipients on a campaign 2. Disconnect your outgoing server and send 3. Reconnect the mailing server and retry sending. Current behavior before PR: A `MemoryError` is raised due to the large number of emails processed to `unlink()` Desired behavior after PR is merged: Larger-scale clients would be able to resend 100s of thousands of emails if they fail opw-5091567 Forward-Port-Of: odoo/odoo#228446
The Field Service “To Schedule” view now only shows open tasks that still need scheduling or assignment. This prevents completed or cancelled work from appearing in planning lists, helping teams focus on actionable tasks.
Original PR description
**steps to reproduce:** Go to field service Go to all tasks > to schedule **issue:** The To Schedule filter was also displaying tasks in cancelled or done state, whereas it should only show open tasks that need to be scheduled or assigned. **cause:** The filter domain did not exclude cancelled/done state, causing closed tasks to appear in the filtered view. **fix:** Updated the filter domain to exclude cancelled/done state, to ensure only open tasks are shown under the To Schedule filter. task-5138590 Forward-Port-Of: odoo/enterprise#96600
This fixes an editor issue where typing next to a link inside formatted text could lose the surrounding formatting. Users creating links in rich text content will now get more consistent visual results, reducing accidental formatting errors.
Original PR description
Problem: If we add a link on a slice of formatted text we end up being able to type unformatted content at the link edges. Cause: After https://github.com/odoo/odoo/commit/3bcbd6f34facb9c88290dbd6496cc5103665a0a2 the `span` can be split and `feff`s are placed around the link, precisely between the link and the `span`. This allows writing unformatted content at the caret when placed between them. Solution: Ensure that the link is created inside the `span`. Also prevent the formatting applied by `.btn` when the link is inside a `span`. Steps to reproduce: 1. Add "abc". 2. Format all the text: set font size 48 (or whatever). 3. Select "b". 4. Create a link on "b" only. 5. Put caret before "a". 6. Press Arrow left. 7. Type any character. → The character is not formatted as the link content. task-5092298 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231675 Forward-Port-Of: odoo/odoo#228353
Printing landscape PDF reports through a Virtual IoT Box no longer produces cropped portrait pages. The print process now fits the PDF to the page so the report keeps its intended orientation, reducing wasted paper and reprints.
Original PR description
When printing a landscape report using a Virtual IoT Box, we end up printing a portrait page cropped. This commit adds the "pdf fit page" argument to ensure the page printed follows the report orientation. opw-5051809 Task: 5149706 Forward-Port-Of: odoo/odoo#232866
Fixed a visual issue where global filter suggestion buttons could appear partially styled for dark mode. This keeps the spreadsheet interface consistent and easier to use, even though dark mode is not currently supported there.
Original PR description
When using the global filter suggestions feature in dark mode, the buttons are halfway in dark mode. We don't support the dark mode in spreadsheet ATM. Task: [5089382](https://www.odoo.com/web#id=5089382&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form)
Landed costs now use the quantity from the affected inventory movement rather than the full remaining quantity of the lot. This prevents costs from being overstated when only part of a lot is included, keeping inventory values accurate.
Original PR description
## Issue: When a lot has remaining quantity not included in the landed cost’s moves, the resulting `stock.valuation.layer` amounts are incorrect Even though `compute_landed_cost()` provides the…
## Issue: When a lot has remaining quantity not included in the landed cost’s moves, the resulting `stock.valuation.layer` amounts are incorrect Even though `compute_landed_cost()` provides the correct base values ## Cause: The cost repartition used `lot_id.quantity_svl` that's the total quantity of the lot , which leads to an incorrect ratio when only part of the lot is impacted As a result, the landed cost amount can be overstated, depending on the difference between the lot's total remaining_qty and the move's remaining_qty This logic only works when all `stock.valuation.layer` of the lot are involved, which is not always the case https://github.com/odoo/odoo/blob/e72b25fffc8f07c51e9a72fe6310e8dd046da793/addons/stock_landed_costs/models/stock_landed_cost.py#L125-L142 ## Steps to reproduce: - Enable Lots & Serial Numbers in Settings - Create a product (Tracked by lot + Valuated by Lot + AVCO) - Create and validate two receipts for the same product and lot - Open Inventory > Products > Lots / Serial Numbers page of Inventory and select your lot (The cost should be 0) - Add Landed Costs for the first receipt - Add a line for a cost of 100$ and compute (You’ll see that one line with 100$ should be added) - Confirm the Landed Cost and click Valuation (The value of the line is doubled to 200$) - On the Lot/Serial Number page of your lot, the cost is also double that the expected value opw-5128570 Forward-Port-Of: odoo/odoo#232740 Forward-Port-Of: odoo/odoo#231936
The web test runner now handles cases where someone starts a manual test before all required assets have finished loading. This prevents an early click on Run from causing a crash, improving reliability for teams using Odoo's test tools.
Original PR description
Before this commit, in manual mode, "Run" could be clicked before the assets finished loading (and so, before the test runner was properly "ready"). This caused a crash because it tried to resolve a promise that did not exist yet. Steps to reproduce: - Go to test URL (manual) - Click "Run" as soon as the button is visible (probably via a script to make sure the click is fast enough) This commit fixes that by adding failsafes around that promise, effecitvely allowing to click "Run" early on. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232789
The VoIP call transfer screen now opens with an empty search field instead of keeping the previous contact search. This avoids confusion for users transferring calls and helps them quickly find the correct recipient.
Original PR description
**Purpose:** Previously, when a contact was searched and made a call. During a call, clicking "Transfer" showed the old search term. **Specification:** Now, the search box is explicitly emptied when transferring the call by resetting this.softphone.addressBook.searchInputValue. **Task-** 5087938 Forward-Port-Of: odoo/enterprise#95102
This update improves Odoo's internal Hoot testing tools and related unit tests so errors are easier to diagnose and failed tests are tracked more reliably. These changes are limited to the test ecosystem, reducing risk for day-to-day business features while improving quality assurance for future releases.
Original PR description
## Pull Request HOOT 38 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232536 Forward-Port-Of: odoo/odoo#231263
This update adjusts Odoo’s automated tests to match changes in the Hoot testing framework’s request handling. It helps keep test results reliable while limiting changes to the test suite, reducing risk for business functionality.
Original PR description
## Pull Request HOOT 38 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. Community: https://github.com/odoo/odoo/pull/232536 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#97851
This fixes a Point of Sale issue where the cash drawer would not open if an unreachable IoT box was also configured. Shops using an ePOS printer can now open the cash drawer reliably, even when another connected device is unavailable.
Original PR description
Steps to reproduce: 1. Configure a POS to use an ePOS printer with the cashdrawer enabled. 2. Also configure the POS to use an IoT box with a dummy device, e.g. '[Shop] Scale'. The important thing is that the IoT box is not reachable when the POS opens, so the dummy devices work well for this. 3. Open the POS, make an order and go to payment, then click 'Open cashbox'. Expected behaviour: The cashdrawer opens Actual behaviour: Nothing happens task-5059502 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232852 Forward-Port-Of: odoo/odoo#232797
This fix prevents Saudi electronic invoice generation from crashing when expected tax information is unavailable. It helps businesses continue invoice processing more reliably and avoids disruption from a missing data edge case.
Original PR description
Before this commit, if the tax_data was missing, it would raise a traceback during the electronic invoice generation. opw-5193614 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Online table bookings now correctly copy the customer's phone number from their contact record into the appointment. This helps staff see the right contact details for reservations without changing how customer records are linked.
Original PR description
Task: [#5005216](https://www.odoo.com/odoo/project/1737/tasks/5005216) --- The phone number field was not being populated correctly when booking a table from the website. It is now properly filled using the phone number of the `res.partner` associated with the appointment. The field remains unlinked to the partner, as it is just a copy. Forward-Port-Of: odoo/enterprise#92836
Point of Sale receipts now use the same numbering format whether the sale is made online or while disconnected. This avoids confusing extra wording on offline orders and makes backend order records easier to compare and audit.
Original PR description
**Steps to reproduce:** - Go to PoS, make an order and pay for it - Before clicking next order close your connection with the server - Make a purchase like this - Go back online and check the orders…
**Steps to reproduce:** - Go to PoS, make an order and pay for it - Before clicking next order close your connection with the server - Make a purchase like this - Go back online and check the orders in the backend The order made online only has the receipt number, but the order made offline has *Order* in front of it. **Why the fix:** The receipt number on a PoS order should be consistand and should not be changed depending on if the purchase was made online or offline. With this commit, every order will have only it's receipt number without the *Order* in front of it even if it was made offline. It is still possible to see if an order was made online or offline with the **F** variable, which is the first number of the last part of the receipt number. If it is 1, the order was made offline, if it is 0, it was made online. The *refPrefix* parameter from the *getNextOrderRefsLocal* function is not used anymore, so it has been replaced by an empty string in the function call in stable and could be deleted when in master. opw-4965095 Forward-Port-Of: odoo/odoo#232745 Forward-Port-Of: odoo/odoo#224416
The POS Six payment flow now uses the currently logged-in POS user when starting a terminal payment. This prevents payment startup failures when a different employee uses an already-open POS session.
Original PR description
This commit fixes an undefined `user_id` on the pos session when trying to start a payment with a Six terminal from another user than the one that started the session. Before this commit: - open a pos session with Mitchell Admin, - check the value of `pos.session.user_id` (it will be `2`), - open another tab and connect as Marc Demo, - check the value of `pos.session.user_id` again: it should be `6`, but instead is `undefined`. After this commit: We use `pos.user.id` instead of `pos.session.user_id.id` to get the user ID. opw-5055977 Forward-Port-Of: odoo/enterprise#98021 Forward-Port-Of: odoo/enterprise#97975
This fix prevents shared accounting accounts from being deleted when they are still used by journal entries in another company. It helps multi-company organizations preserve accounting data integrity and avoid accidental loss of financial links.
Original PR description
In a multi-company environment, accounts can be shared. A Python constraint prevents deleting an account if it has journal items in the current company. However, this check was missing when an account only contained journal items belonging to other shared companies. This commit fixes the issue by: 1. Updating the `ondelete` attribute of the `account_id` field on `account.move.line` to cascade the restriction at the database level. 2. Updating the existing Python constraint on `account.account` to enforce this logic in stable versions without a module update (this will be removed in the master branch). task-5158966 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232957 Forward-Port-Of: odoo/odoo#232530
A website blog test was updated so it no longer depends on the English name of a month. This prevents false test failures when the website is used in other languages, improving confidence in multilingual blog behavior.
Original PR description
Before this commit the blog_tags_with_date tour tried to select the October option by label. In other locales the month label differs and the tour could not find it, so the tour aborted at that step. Steps to reproduce: - Change the website language to one where October has another name. - Run the blog_tags_with_date preview tour. The tour now selects the first month option by index, independent of labels. runbot-233321 Forward-Port-Of: odoo/odoo#232961 Forward-Port-Of: odoo/odoo#232610
This fixes an invoice preview issue that could occur when a website page also included embedded content such as a map. Users can now open invoice previews reliably without encountering an error caused by selecting the wrong embedded frame.
Original PR description
Support the possibility of multiple iframes being present on the invoice preview page. Steps to reproduce ----- 1. Add a map block to the nav bar of the website. 2. Go to accounting and find an invoice. 3. Click preview and receive a traceback. Cause ----- The use of querySelector works if there is only one iframe element, but map blocks are also iframe elements so adding one with the website editor can cause the wrong iframe to be selected with querySelector. Solution ----- The iframe element that needs to be selected already has an id, so updating querySelector to getElementById resolves the issue. opw-ticket 5170640 Forward-Port-Of: odoo/odoo#232754
Sales commission achievement reports now return the expected grouped results instead of often appearing empty. This helps teams review commission performance more reliably without missing data caused by incorrect report paging.
Original PR description
Before this commit, grouping achievements would result in empty list most of the time. It happened because offset and limit were switched by mistake in the override. As a result an offset of 80 was applied in the request during group by. Forward-Port-Of: odoo/enterprise#97959
Fixed an accounting issue where fixed taxes on invoices with negative-priced products could appear as positive amounts. This ensures refunds, discounts, or other negative invoice lines show tax totals with the correct sign, improving invoice accuracy.
Original PR description
Steps to reproduce: 1. Create a fixed tax 2. Create a invoice with a product with negative price Problem: The amount of the tax is positive while the line is negative. opw-5128767 Forward-Port-Of: odoo/odoo#232394 Forward-Port-Of: odoo/odoo#232084
This fix corrects how fixed taxes are calculated when an invoice line has a negative price, such as refunds or adjustments. It helps ensure accounting totals remain accurate and avoids incorrect tax amounts in financial records.
Original PR description
opw-5128767 Forward-Port-Of: odoo/enterprise#97980
This fixes how Odoo's web test mock server handles custom responses, so responses prepared by tests are returned exactly as intended. It helps make automated tests more accurate and reduces the chance of misleading test behavior during development.
Original PR description
Before this commit, when an 'onRpc' handler would return a 'Response' object, it would still be wrapped in a JSON-RPC payload (under the 'result' key) if the "content-type" header specified that it was a JSON-RPC. However, if a 'Response' object is returned by the handler, it usually means that the response should be that object as-is, as it was created with the desired final parameters. This commit ensures that 'Response' values are returned as they are, instead of being wrapped in a JSON-RPC payload object. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232731 Forward-Port-Of: odoo/odoo#232614
Payment terminals connected through IoT Boxes now remain compatible after the latest service update, even if the box has not been restarted. This avoids disruption for customers and removes the need for a manual restart to refresh terminal drivers.
Original PR description
We previously backported the `iot_http` service to saas-18.4 in odoo/odoo#232282. This fw port included changes to the payment terminals drivers. For them to work correctly with the update of the database, IoT Boxes would have required a restart, in order to get the new drivers version. To avoid clients to do this, we ensure the service is able to understand the old version.
This update adjusts an internal website module test so it no longer depends on optional demo data being present. It helps keep automated validation stable across different testing environments without changing customer-facing behavior.
Original PR description
runbot-162894 Forward-Port-Of: odoo/odoo#232920 Forward-Port-Of: odoo/odoo#213962