Wednesday, December 10, 2025
18 changes · saas-18.4
Resolved issues and error corrections
This update fixes a visual bug where clicking the shape selector caused unwanted scrolling in smaller browser windows. The fix prevents the entire viewport from scrolling, resulting in a cleaner user experience. The change ensures consistent appearance across different screen sizes.
Original PR description
**Description of the problem** If the browser window has a limited height, clicking on a shape category in the shape selector scrolls both the shape selector pager (wanted) and the full viewport (not…
**Description of the problem** If the browser window has a limited height, clicking on a shape category in the shape selector scrolls both the shape selector pager (wanted) and the full viewport (not wanted), leading to white bands appearing at the bottom of the viewport. **How to reproduce** 1. Drop `s_picture` snippet 2. Open the background shape selector 3. Reduce the window height until only ~4 rows of shapes are visible 4. Click on "Linear" or "Creative" category 5. BUG: the viewport scrolled **Why the problem happens** When a shape category in the shape selector is clicked, the function `scrollIntoView` is used to bring the first shape of that category into view. By default, `scrollIntoView` scrolls all ancestor scroll-containers (and possibly the viewport) until the desired element is visible. This means that in specific situations the viewport could scroll too. **Fix** The function `scrollIntoView` should support the option `container: "nearest"`, which would force only the first scroll-container to scroll, avoiding scrolling the viewport. However, at the moment this option is not widely supported across browsers [1]. Thus `scrollIntoView` has been removed and its behaviour has been replicated by changing the `scrollTop` property of the `ShapeSelector` scroll-container. [1]: https://caniuse.com/mdn-api_element_scrollintoview_options_parameter_container_option task-5262945
This update fixes a bug where customers could select past time slots when ordering through the self-order system. Now, the system only displays available time slots for the current day, ensuring accurate order scheduling and preventing confusion for customers. This improves the overall ordering experience.
Original PR description
Task: [#5365003](https://www.odoo.com/odoo/project/1737/tasks/5365003) --- before this commit selecting a time slot in self-order, the customer can still pick time slots that are already in the past. For example, if the current time is 14:05, the system still allows selecting 12:00, 12:20, 13:00, etc. This should not be possible. When choosing a pickup time for today, all time slots earlier than the current time should not be generated Forward-Port-Of: odoo/odoo#238416 Forward-Port-Of: odoo/odoo#237923
This update resolves an issue where freezing a spreadsheet with empty lists didn't accurately represent the data. Specifically, the system incorrectly reported empty lists as containing text. This change ensures that frozen spreadsheets accurately reflect the absence of data, improving spreadsheet reliability and data consistency.
Original PR description
Steps to reproduce: - insert a list - expand the list beyond the number of records in order to have ODOO.LIST with no result - add =ISTEXT( <a reference to an empty ODOO.LIST> ) -> the result is TRUE - Freeze and share the spreadsheet => the result of ISTEXT is FALSE in the frozen version task-5360561 opw-5359100 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#237970 Forward-Port-Of: odoo/odoo#237511
This update resolves an issue where the system incorrectly processed invoice sequences without spaces, leading to errors. The change uses a more flexible method to extract the invoice number, ensuring compatibility with various sequence formats (including those without spaces). This prevents errors and improves the reliability of the CL-EDI functionality.
Original PR description
Before this commit, the method `_get_last_sequence` assumed that the document sequence always contained a space separator (e.g., "INV 12345") It attempted to extract the folio number using `res.split(" ")[-1]`.
If the sequence format did not contain a space, such as the standard Odoo format `INV/2025/01234`, the split would return the entire string. This caused a `ValueError` when trying to cast the non-numeric string to an integer:
ValueError: invalid literal for int() with base 10: 'INV/2025/01234'
This commit fixes the issue by using a regular expression to extract the last group of digits from the sequence string. This ensures the folio number is correctly retrieved regardless of the separator used (slash, space, or hyphen).
opw-5401509
Forward-Port-Of: odoo/enterprise#101665This update fixes an issue where invoice totals weren't updating correctly after changing the product or unit price. The original system had a logic error that prevented the totals from recalculating properly. The fix reorders the calculation process to ensure the product's price is used, leading to accurate totals displayed on invoices.
Original PR description
**Steps to reproduce:** - Install Accounting - Create an invoice with an invoice line - Save the invoice - Change the unit price => The totals should change - Change the product => The unit price and…
**Steps to reproduce:** - Install Accounting - Create an invoice with an invoice line - Save the invoice - Change the unit price => The totals should change - Change the product => The unit price and the totals should change - Change the unit price again **Issue:** After this point, the totals don't change anymore, even if the unit price is changed several times. Only saving the form will adapt the totals correctly. **Cause:** When changing the unit price the first time, a "price_unit "key is added in the onchange values. When changing the product, a "product_id" key is added after the price key. Changing the product triggers an onchange of the price with the price of the new product. However, when the price is changed again, as the "price_unit" key already exists, it's reused and its position is still before "product_id" key even if it should be computed after. This order results in the use of the price of the second product instead of the one entered manually when computing the "tax_totals". **Solution:** If "product_id" and "price_unit" are the values of the onchange method, the list of values is reordered to make sure that "product_id" is computed first. opw-5012125 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#239110 Forward-Port-Of: odoo/odoo#232684
This update corrects a display issue on the Odoo portal where users were seeing outdated document counts. Now, users only see documents that are currently in their signing sequence, ensuring a more accurate and user-friendly experience. This improves clarity and prevents confusion for users managing sequential documents.
Original PR description
Version: - 18.0 Steps to reproduce: - Install sign - Upload document. - Add multiple signers - Set a sequential signing order Issue: - When documents require sequential signing, portal users see a banner saying there’s a new document to sign, even if it’s not yet their turn. Solution: - Update the counter to show only the documents that the user can currently sign. Impact: - Portal users now only see documents when it’s their turn to sign. Task-5226240 Forward-Port-Of: odoo/enterprise#98671
This update resolves an issue where AvaTax processes would fail if orders were created without any associated lines. This prevented correct tax calculations and reporting, often requiring manual intervention. The fix ensures that AvaTax only processes orders with at least one line item.
Original PR description
Calling Avatax without lines results in an error and blocks flows: ``` Odoo could not fetch the taxes related to MXXX - SOXXX/XXX. Please check the status of `Sales Order XXX` in the AvaTax portal.…
Calling Avatax without lines results in an error and blocks flows: ``` Odoo could not fetch the taxes related to MXXX - SOXXX/XXX. Please check the status of `Sales Order XXX` in the AvaTax portal. Transactions must have at least one line. ``` There are various cases this can happen: 1/ if `industry_fsm_stock` is installed, empty orders are confirmed [1], 2/ if you put the `end_date` of a subscription before the `next_invoice_date`, then none of the lines are considered invoiceable [2] and you get the error when viewing the subscription in the portal This commit filters out orders without lines. It's also possible to filter this on the level of the models by doing it in `_get_and_set_external_taxes_on_eligible_records()`. However, this means doing it separately for each model, and requires every implementer do it manually. [1] https://github.com/odoo/enterprise/blob/703e7fd413e93a8287da98286aa93b9699ae3e96/industry_fsm_stock/models/project_task.py#L159 [2] https://github.com/odoo/enterprise/blob/c7bf4367a9bf6757a36a9f34a872a6e35a19a3a5/sale_subscription/models/sale_order_line.py#L475 opw-5214609 opw-5247727 opw-5311132 opw-5385960
A technical issue in the Accounting module prevented users from opening a specific Studio menu item, resulting in a confusing traceback. This fix replaces the error with a clear message, guiding users to properly filter their views and ensuring a smoother user experience. This improves usability and prevents data access problems.
Original PR description
**Steps to reproduce:** * Install **Accounting** and ensure Studio is available. * Using **Studio**, create a new menu item pointing to the model *account.code.mapping*. * Save the menu and click it to open the corresponding view. **Observed behavior:** * Opening the Studio-created menu triggers a full traceback. **Cause:** * The model *account.code.mapping* overrides `_search()` and raises `NotImplementedError` when no `account_ids` can be extracted from the domain, which is the case when opening the view without filters. * The missing `_search` logic for empty domains was never implemented, and the resulting exception propagates to the UI as a traceback. **Fix:** * Replace the `NotImplementedError` with a user-friendly `UserError` explaining that the view cannot be opened without specifying relevant filters, preventing the traceback and improving clarity. opw-5183909 Forward-Port-Of: odoo/odoo#239076 Forward-Port-Of: odoo/odoo#236665
This update resolves an issue where the Envia Shipping module would fail to calculate shipping rates if a customer's address information (country, state, city) was incomplete. The fix ensures that the system handles missing address data gracefully, preventing errors and allowing users to accurately obtain shipping quotes.
Original PR description
Currently, an error is raised when trying to fetch the shipping rate if the partner does not have the required geolocation fields (country, state, and city). **Steps to Reproduce:** 1. Install and…
Currently, an error is raised when trying to fetch the shipping rate if the partner does not have the required geolocation fields (country, state, and city). **Steps to Reproduce:** 1. Install and configure the **Envia Shipping** module. 2. Create a partner without an address (only name + phone). 3. Create quotation for that partner with a deliverable product (e.g; Conference Chair). 4. Click "**Add Shipping**", choose _Envia Shipping_ Method, and then click "**Get Rate**". **Error:** `TypeError - quote_from_bytes() expected bytes` **Cause:** At [1], the system tries to compute Envia shipping rates based on the partner’s country, state, and city. If any of these fields are not set, an error is raised. **Fix:** This commit adds a check for the required fields (country, state, and city). If any are missing, `_geolocate_zip` returns False, leading to a proper validation error instead of a traceback. - [2] [1] - https://github.com/odoo/enterprise/blob/f1a02626a1fbe76add104832e151c647307f3ae7/delivery_envia/models/envia_request.py#L591-L593 [2] - https://github.com/odoo/enterprise/blob/f1a02626a1fbe76add104832e151c647307f3ae7/delivery_envia/models/envia_request.py#L617-L624 sentry-7063870478 Forward-Port-Of: odoo/enterprise#100734
This update adds a new account for 'Salaries & Wages Payable' within the Hong Kong localization (l10n_hk) for Odoo. This resolves a previous accounting error and ensures accurate payroll reporting under Hong Kong's NET rules, improving financial accuracy.
Original PR description
Adds a new Salaries & Wages Payable account of type current liabilities in order to use it in payroll for the NET rules and solve a misconfiguration in the default data. task-5042786 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#237884
This update resolves an issue in the Hong Kong payroll module by changing the default account used for net salary payments. The change ensures accurate payslip generation and payment processing, addressing a previous error that caused payment problems. The new 'Salaries & Wages Payable' account is now used across most payroll structures.
Original PR description
Fixes the default account for NET salary rules in the Hong Kong payroll, which is using the wrong account type and causes issues when trying to pay payslips. It is replaced by a new Salaries & Wages Payable account, and we also set it for the structures other than 'Monthly Pay' task-5042786 Forward-Port-Of: odoo/enterprise#100835
This update corrects a bug in the loyalty program where rewards weren't being applied when using 'not ilike' product domains. The fix ensures that the system correctly interprets and applies reward rules based on product categories, regardless of whether the domain uses 'ilike' or 'not ilike'.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create a loyalty program; 2. Create a reward; 3. Add a Product domain to the reward containing the `not ilike` operator; 4. Load the POS; 5. Try to trigger…
Versions
--------
- 18.0+
Steps
-----
1. Create a loyalty program;
2. Create a reward;
3. Add a Product domain to the reward containing the `not ilike` operator;
4. Load the POS;
5. Try to trigger the Loyalty program;
6. The Reward is not applied when the domain is satisfied
Issue
-----
Loyalty Program rewards containing `not ilike`-based product domains are not applied when they should.
Cause
-----
The `_replace_ilike_with_in` function in loyalty_reward.py converts the `ilike` and `not ilike` operators by first fetching the records that very the domain with the operator used, and then by replacing the domain by `in` or `not in` with the returned records ids. This is problematic as in the case of `not ilike`, it leads to a double negation.
Example
-----
For `ilike`: `['categ_id', 'ilike', 'service']`
-> Search for all categories that contain "service": `_search([('display_name', 'ilike', 'service')])`
-> Return new domain `['categ_id', 'in', matching_ids]`
Which is correct.
For `not ilike`: `['categ_id', 'not ilike', 'service']`
-> Search for all categories that **do not contain** "service": `_search([('display_name', 'not ilike', 'service')])`
-> Return new domain `['categ_id', 'not in', matching_ids]`
Which is incorrect, as the matching_ids are already the ids that are not like "service". (i.e., *categ_id not in the categories that do not contain "service"* <=> *categ_id in the categories that contain "service"*, opposite of what is expected.)
Solution
--------
1. Perform the initial search with `ilike` for both operators
opw-5182818
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#235656This update clarifies the documentation for the HTML Editor's position plugin, ensuring developers have a better understanding of its functionality. The change improves clarity and reduces potential confusion when using this key component of the HTML Editor. This is a routine documentation update.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#239168
This update addresses a change in Facebook's data reporting, specifically the deprecation of the audience trend metric. The team quickly implemented a workaround using total page follows to maintain accurate tracking of page growth. This ensures continued visibility into page performance for our business clients.
Original PR description
Bug === Facebook deprecated some of the endpoints related to statistics https://developers.facebook.com/docs/platforminsights/page/deprecated-metrics We fixed all metric except the audience trend,…
Bug === Facebook deprecated some of the endpoints related to statistics https://developers.facebook.com/docs/platforminsights/page/deprecated-metrics We fixed all metric except the audience trend, because we needed a fix rapidly, and we wasn't sure about unfollow. And indeed, `page_daily_follows` only count for positive value, unlike the old `page_fan_adds` / `page_fan_removes`, and there's no equivalent of `page_fan_removes`... Example of data for a month: ``` page_follows 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 page_daily_follows 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 page_follows 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 page_daily_follows 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ``` So we now use `page_follows`, so the total value at a given time, and we look for the newest and oldest value (note that if we could do the same for `page_post_engagements`, then we could just make 2 APIs calls for the year stat). Task-5353390 Forward-Port-Of: odoo/enterprise#101625 Forward-Port-Of: odoo/enterprise#100275
This update fixes an issue where rental pickup moves didn't properly link to the rental order. The change ensures that pickup moves are correctly associated with the rental order, improving the accuracy of inventory reporting. This prevents discrepancies in rental tracking.
Original PR description
### Steps to reproduce: - Create a rentable, storable product - Create and confirm a rental order for 1 unit of this product - Click on pickup - Inventory > Reporting > Moves History #### > Your…
### Steps to reproduce: - Create a rentable, storable product - Create and confirm a rental order for 1 unit of this product - Click on pickup - Inventory > Reporting > Moves History #### > Your pickup move appears without any reference ### Cause of the issue: The issue has been introduced in d0c1e7845feeee1c2e85a21b5d40570d051458d3 which purpose was to remove the `name` field of the `stock.move` model. However, the `_compute_reference` compute method use to rely on this `move.name` to propagate the info that the move was related to a rental order (since there is no picking). Indeed prior to saas-18.4, the compute method was: https://github.com/odoo/odoo/blob/404cb10283cbc706eae67dd793ced363273f3602/addons/stock/models/stock_move.py#L325-L328 And the reference to the rental order was set on the move at pickup: https://github.com/odoo/enterprise/blob/1466a0139ee64ecd059738bc414f6e7e5a9f4354/sale_stock_renting/models/sale_order_line.py#L303-L313 https://github.com/odoo/enterprise/blob/1466a0139ee64ecd059738bc414f6e7e5a9f4354/sale_stock_renting/models/sale_order_line.py#L248-L257 ### Fix: Since the reference field is a computed and stored fields and since some of its dependencies are set at creation the rental move we can not set the `reference` directly in the creation of the record as we used to do for its name since the compute method will then override and erase or reference. opw-5385004
This update addresses a requirement from the Belgian Peppol Authority. Users can still register with 9925, but a warning has been added to guide them towards the preferred 0208 (BCE/KBO) registration method. This ensures compliance and simplifies the registration process for our Belgian users.
Original PR description
The Belgian Peppol Authority wants us to register belgian users with 0208 (BCE/KBO) and not 9925 (BE VAT). It should still be possible to register with 9925 for some edge case, but let's make it clear to our users that this is not the regular path. task-none (feedback from support + TSB) Forward-Port-Of: odoo/odoo#239208 Forward-Port-Of: odoo/odoo#238737
This update fixes a problem where blog post publishing tests were inconsistent due to timing variations. By freezing time during key test steps, the tests now reliably produce the same results, ensuring accurate performance monitoring. This improves the reliability of our blog performance metrics.
Original PR description
Some blog post are published with a post_date matching the time the test is run meaning that they are not considered published. We have multiple possibilities when _get_url_hot_query is called: - all call to /blog are executed before the publication date: 9 - some call to /blog are executed after the publication date: 11 - only the last call is executed after the publication date: ~40-50 Using freezetime after the publication date ensures a consistent result This can be easily reproduced by freezing the time on the first calls in _get_url_hot_query and not on the last one. Runbot error [55754](https://runbot.odoo.com/odoo/error/55754) Forward-Port-Of: odoo/odoo#239236
This update fixes a potential issue where the system was incorrectly removing outdated sub-channels. The change ensures that the cleanup process only targets actual sub-channels, preventing unintended consequences and maintaining data integrity. This improves the stability and reliability of the channel management feature.
Original PR description
In [1], the `_gc_unpin_outdated_sub_channels` method was updated to avoid unpinning sub-channels multiple times. However, a condition is missing on `parent_channel_id` to restrict this gc to actual sub- channels. [1]: https://github.com/odoo/odoo/pull/238493 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#239248