Daily updates from Odoo
Thursday, April 2, 2026
21 changes · saas-18.3
Enhancements to existing features
This update incorporates the latest withholding tax percentages required by Ecuadorian regulations (Resolución N.º NAC-DGERCGC26-00000009). The changes ensure Odoo accurately calculates and reports withholding taxes for Ecuadorian businesses, maintaining historical data and aligning with internal TRESCLOUD guidelines. This update corrects existing naming inconsistencies and improves data accuracy.
Original PR description
Implement the new withholding tax percentages according to "Resolución N.º NAC-DGERCGC26-00000009" for Ecuador, following internal implementation guidelines by TRESCLOUD. SPECIFICATION: - Created the new withholding percentages as new tax records. - Set the previous withholding percentages as inactive to preserve historical data. - Ensured compatibility with existing tax configurations and fiscal mappings. Table with the changes established in "Resolución N.º NAC-DGERCGC26-00000009". <img width="1676" height="303" alt="image" src="https://github.com/user-attachments/assets/79ae91b2-6d31-442f-af3c-74304742c8b6" /> BP: #252917 Forward-Port-Of: odoo/odoo#254240 Forward-Port-Of: odoo/odoo#254018
Resolved issues and error corrections
This update ensures that the total value displayed for stock items remains consistent between versions 18 and 19. The change corrects a calculation error where only internal locations were considered, leading to discrepancies when migrating to the newer version. This update ensures accurate stock valuation reporting.
Original PR description
**Steps to reproduce** - Create a database in v18.0. - Install the stock and sale modules. - Create a storable product. - Add 100 units as on-hand quantity using an inventory adjustment in the…
**Steps to reproduce** - Create a database in v18.0. - Install the stock and sale modules. - Create a storable product. - Add 100 units as on-hand quantity using an inventory adjustment in the internal location (e.g., WH/Stock). - Create a transit location. - Create an internal transfer and move 20 units from the internal location (WH/Stock) to the Transit location. - WH/Stock now contains 80 quantities. - Transit location contains 20 quantities. - See stock valuation of product. **Issue** - In v18, `value_svl` and `quantity_svl` are computed from [Stock Valuation Layers](https://github.com/odoo/odoo/blob/18.0/addons/stock_account/models/product.py#L213) After that, `total_value` is calculated using the formula [`avg_cost * qty_available`](https://github.com/odoo/odoo/blob/18.0/addons/stock_account/models/product.py#L205). However, when calling `qty_available`, no location context is passed to specify which locations should be considered. Because of this, `qty_available` only considers quantities from internal locations. As a result, the final `total_value` is computed based only on the internal location quantity (80). - When the customer migrates the database to v19, the displayed `total_value` changes. In v19, both (100 qty) internal and transit locations are considered when computing the quantity used for valuation. This happens because a valuation [context](https://github.com/odoo/odoo/blob/19.0/addons/stock_account/models/product.py#L203) is passed when selecting the locations for the quantity computation. Due to this change, the quantity used in the calculation includes both internal and transit locations, which can lead to a different `total_value` being displayed compared to v18. **Solution** - To resolve this issue, the valuation context has been passed when computing the value in the function. This context includes both internal and transit locations. As a result, when `qty_available` is computed, it considers these locations, and the resulting `total_value` remains consistent with the valuation logic. opw-5924110 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254120
This update fixes an issue where the customer stock report incorrectly showed lots as unreturned when multiple partial returns were made. The change ensures that returned lots are accurately identified and displayed, preventing duplicate records and improving the reliability of the report. This ensures accurate stock reporting for customers.
Original PR description
### Issues: The customer stock.lot.report is not well behaved with respect to multiple partial returns which can lead to returned lots that are not correctly flagged as returned and to duplicate…
### Issues: The customer stock.lot.report is not well behaved with respect to multiple partial returns which can lead to returned lots that are not correctly flagged as returned and to duplicate records. ### Steps to reproduce: - Create a product tracked by SN and put 3 units in stock SN1, SN2, SN3 - Create, confirm and validate a delivery for these two units for Bob. - Click Return, return 1 unit and validate the return for the SN1 - Click Return, return 1 unit and validate the return for the SN2 - Open the contact form of Bob > Lots serial numbers smart button #### > There are two lines referring to SN2 both are flagged as un-returned ### Cause of the issue: In order to determine if a lot has been returned the `stock.lot.report` joins the stock_move_line table with it self based on picking and returns of these: https://github.com/odoo/odoo/blob/109f829c2b461b14167e9227e42d096d4410a3b3/addons/stock/report/stock_lot_customer.py#L48-L71 Records are then grouped to represent single move lines and a move line is expected to be returned to be returned if it is related to at least one move line on a return of its picking sharing the same lot related data (see the definition of `has_return`): https://github.com/odoo/odoo/blob/109f829c2b461b14167e9227e42d096d4410a3b3/addons/stock/report/stock_lot_customer.py#L22-L34 Now the issue is that the group by close actually group records based on the `sml_return.id`: https://github.com/odoo/odoo/blob/109f829c2b461b14167e9227e42d096d4410a3b3/addons/stock/report/stock_lot_customer.py#L73-L89 which does not make sense since we expect to aggregate `sml_return.id`'s to compute the `has_return` field and since we do not want a move line of the original delivery to appear twice simply because it is linked to two returns one with and one without returned move line. opw-5974155 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256396
This update fixes a flaw in the website's leaderboard that incorrectly ranked users based on their recent activity. The system now accurately calculates and displays user rankings by weekly and monthly karma gains, ensuring a fairer and more relevant leaderboard experience. This improvement ensures users are recognized for their current performance.
Original PR description
[FIX] website_profile, gamification: fix weekly/monthly leaderboards Prior to this commit, the leaderboard pagination logic was flawed when filtering by specific time periods (e.g., "This Week" or…
[FIX] website_profile, gamification: fix weekly/monthly leaderboards Prior to this commit, the leaderboard pagination logic was flawed when filtering by specific time periods (e.g., "This Week" or "This Month"). The system would first retrieve users sorted by their *all-time* global karma, apply pagination (taking the top X users), and only then calculate the karma gain for the specific period for those few users. This caused users with high recent activity but low all-time karma to only be displayed much later in the page order than they should. This commit fixes the issue by introducing a pre-search step that calculates the karma gain for the requested period at the database level. Pagination is now applied to this specific result set, ensuring users are correctly ranked by their actual performance during that week or month. Note: A new method `_get_users_by_tracking_karma_gain` was added to `res.users` to handle this logic. This approach was chosen to strictly preserve the signature of existing methods for the stable version. A distinct refactor to unify these calculation methods is planned for the master branch. Steps to reproduce: - Install the eLearning module. - Create a few users with different karma_points (more than 25 to have 2 pages). - Go to /profile/users. - Group by week. - Paginate, and you will notice that the order is wrong; the first user on the second page might have more points than users on the first page. Also, when the logged-in user is not on that page, they do not appear at the bottom. task-5344657 opw-3979785 Forward-Port-Of: odoo/odoo#256908 Forward-Port-Of: odoo/odoo#176626
This update resolves a minor issue with the HTML editor's color selector, ensuring consistent test results. Because the toolbar is a popover, it's susceptible to unpredictable behavior. This fix improves the reliability of the testing process.
Original PR description
The toolbar is a popover and is therefore affected by [1]. runbot-242071 [1] 54da715 Forward-Port-Of: odoo/odoo#256783
This update fixes an issue where boolean settings linked to configuration parameters were incorrectly interpreted as 'False' in the system. The change ensures that string values like "False" are correctly parsed as boolean values ('False') when setting configuration options, preventing unexpected behavior and ensuring accurate settings are displayed. This improves the reliability of configuration settings.
Original PR description
When a boolean field on `res.config.setting` tied to `ir.config_parameter` via `config_param` attribute, the value is incorrectly parse as param store `False` as `"False"` and later being shown as `True` on the setting form. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257033
This update resolves an issue where deleting certain fields within the website form functionality caused a crash. The problem stemmed from how website fields were incorrectly parsed as XML. The fix ensures that field deletions are handled correctly, preventing unexpected errors and improving website stability.
Original PR description
Steps to reproduce ================== tl;dr: html fields are parsed as xml - Go to Helpdesk > Tickets > Warranty - Open studio - Add a new text field named "TEST" - Remove it from the view - Exit studio - Go to the website - Click on new - Add a new blogpost - Set a title and save - Click on "Contact & Forms" - Click on the first block - Click on the form - Change the form action to "Create a ticket" - Click on "+ Field" - Change the Type selection to "TEST" - Click on save - Enable debug mode - Go to "Settings / Technical / Database Structure / Fields" - Type x_ in the search bar and press enter - Delete the field => lxml.etree.XMLSyntaxError Cause of the issue ================== When deleting a field, `_check_if_used_in_website_form` is called to prevent the deletion if a field is used in an html field. The html fields were parsed with an xml parser.. opw-5946029 Forward-Port-Of: odoo/odoo#256066
This update fixes an issue where the HTML editor toolbar wasn't appearing on macOS when using Cmd+Shift+Arrow to select text. The fix utilizes a secondary event listener to ensure the toolbar activates correctly, even when the Cmd key is held down. This improves the user experience for macOS users.
Original PR description
Problem: The toolbar does not open when using Cmd+Shift+Arrow to select text on macOS. Cause: On macOS, when the Cmd key is held down, the `keyup` event is never fired for other keys. The toolbar…
Problem:
The toolbar does not open when using Cmd+Shift+Arrow to select text on macOS.
Cause:
On macOS, when the Cmd key is held down, the `keyup` event is never fired for other keys. The toolbar relies on `keyup` for Arrow keys to re-enable `onSelectionChangeActive` and trigger the toolbar update, so it never opens.
See section ("Issue 3 - keyup event put on hold for other keys"): https://web.archive.org/web/20160304022453/http://bitspushedaround.com/on-a-few-things-you-may-not-know-about-the-hellish-command-key-and-javascript-events/
Solution:
Track when an Arrow key is pressed while Cmd is held (`pendingArrowKey`) and use a `selectionchange` listener as a fallback to re-enable the toolbar. The `selectionchange` event fires reliably on macOS even when `keyup` is suppressed. A `isMouseDown` guard ensures the listener does not interfere with the existing mousedown/mouseup flow.
Steps to reproduce:
1- Type some text
2- Use Cmd+Shift+Arrow (left or right) to select text 3- Observe the toolbar does not appear
task-6013408
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#253293This update resolves an issue preventing the correct display of amounts in words for Czech users within Odoo. A temporary patch was implemented to utilize the correct language code. Once the system uses Ubuntu 25.10 or later (with Python 3.13 or higher), this patch will be automatically removed as the `num2words` library has been updated with the necessary fix.
Original PR description
The `num2words` library has a bug in the language code they used for Czech (`cz` instead of `cs`). This commit adds a monkey patch to map the correct language code to the existing converter class, allowing the amount in words to work in Czech. The issue was fixed in version 0.5.14 of the library, so this patch can be removed once we use Ubuntu >= 25.10 (Python >= 3.13), that contains the fixed version of the library. [opw-6088697](https://www.odoo.com/odoo/project.task/6088697) Forward-Port-Of: odoo/odoo#257105 Forward-Port-Of: odoo/odoo#257031
This update fixes an issue where email notifications were incorrectly routing external emails as internal aliases. The change enhances the system's ability to accurately filter internal system emails based on allowed domains, preventing potential notification errors and ensuring correct recipient targeting. This improves the reliability of our email communication.
Original PR description
The fix introduced in https://github.com/odoo/odoo/pull/216737 can lead to "over-eager" filtering when an external email address matches a localpart (left part) alias in a input email list contains…
The fix introduced in https://github.com/odoo/odoo/pull/216737 can lead to "over-eager" filtering when an external email address matches a localpart (left part) alias in a input email list contains internal emails (aliases to filter) AND external email addresses (should not be filtered). The `_find_aliases` method is used to identify internal system emails (aliases, bounces, catchalls) to prevent mail loops and ensure correct recipient filtering during notification grouping. Before this fix, when the `mail.catchall.domain.allowed` system parameter was set, the logic for local-part aliases (where `alias_incoming_local` is True) failed to correctly associate the local part with the allowed domains. This resulted in external email addressed being returned by the system, potentially leading to incorrect notification routing. We now use a more robust approach: - Pre-filter local parts based on the allowed domains to reduce DB load. - Utilize Python Sets for O(1) lookups of static and local aliases - Explicitly validate the (local_part, domain) combo during the final filtering. Example Scenario: - Config: mail.catchall.domain.allowed = "test1.com,test2.com" - Alias: "info" (alias_incoming_local=True) - Input: ["info@test1.com", "info@test3.com"] ### Output Before Fix: ["info@test1.com", "info@test3.com"] (The function failed to recognize info@test3.com as an external alias to be ignored based on the `mail.catchall.domain.allowed` config) ### Output After Fix: ["info@test1.com"] (Correctly identifies the internal alias tob filtered while ignoring the external one) OPW-5469264 OPW-5504201 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244272
This update resolves an issue where the default email template body wasn't appearing in the full composer view within the chatter. The fix ensures that the correct default template body is loaded, regardless of whether the user manually enters content in the composer, improving email communication reliability.
Original PR description
**Issue:** - When opening the full composer from the chatter, the body of the default email template is not loaded. Only the subject line from the template appears, while the body remains empty or…
**Issue:** - When opening the full composer from the chatter, the body of the default email template is not loaded. Only the subject line from the template appears, while the body remains empty or contains only the user's signature. **Steps to reproduce:** 1. Install `contact` 2. Open any contact form. 3. In the chatter, click 'Send message' and then expand button 4. Write a something in body, then save this as a new template. 5. Set this new template as the default (using Debug Mode > Set Default Values). 6. Click 'Send message' in the chatter, 7. Click the 'Full composer' (expand) button without typing anything. **Observed behavior:** - The full composer opens with the correct subject from the default template, but the body is empty. **Cause:** - The `onClickFullComposer` method always passes a `default_body` value in the context to the mail.compose.message wizard. Even if the chatter input is empty **Solution:** - Forward isBodyEmpty in the context from onClickFullComposer. If the user typed content, do nothing. If the body is empty and a default template is available, allow the backend to apply the default template by removing default_body. opw-5405056 Forward-Port-Of: odoo/odoo#254735 Forward-Port-Of: odoo/odoo#239851
This update fixes a minor issue where the VAT label in error messages was incorrectly displaying 'VAT' regardless of the country. The change ensures the correct VAT label is shown, improving the clarity and accuracy of error messages for users. This improves the user experience when VAT validation fails.
Original PR description
Before this **PR**, instead of the VAT label of each country, 'VAT' appeared in the error message. This was due to a mismatch in the matching of country codes.
This update fixes an issue where PEPPOL self-billing invoices weren't correctly including the GLN number or delivery address. The change ensures that the delivery address from the company partner is used in the generated XML, improving compliance with PEPPOL standards and accurate invoice data transmission.
Original PR description
**PROBLEM** When selfbilling with peppol, we have no way of providing a GLN number, or modifying the delivery address. Even if we create a delivery address partner on the current company partner, it's not taken into account. **STEP TO REPRODUCE** 1. Create a delivery address on the current company, set up a GLN number. 2. Configure the purchase journal to do selfbilling. 3. Create a vendor bill with this journal and send it using peppol. 4. Download the xml, and look for the Delivery tag, and notice it doesn't have the GLN number. **FIX** We search for a delivery address on the current company. If there is one, we use it for the Delivery tag. opw-6014374 Forward-Port-Of: odoo/odoo#252970
This update fixes an issue where shipping costs were incorrectly calculated when using combo products with delivery methods based on quantity. The fix ensures that shipping costs accurately reflect the quantity of individual components within the combo, preventing inflated shipping charges. This improves the accuracy of shipping calculations for customers using combo products.
Original PR description
**Issue:**
When using a delivery method that has a shipping cost based on the quantity of the product, the shipping cost is incorrect if there is a combo product. The quantity of the combo product was added to the total quantity of its components.
**How to reproduce:**
1. Create a delivery method based on rules.
2. Create a rule that uses the quantity (ex: 0$ + 5$ times the quantity)
3. Create a combo product
4. Create a sale order and add the combo product to it
5. Add the shipping
=> The shipping cost is incorrect
ex: With 1 combo choice, the shipping cost is doubled
**Fix:**
When calculating shipping cost, skip the sale order line of the combo product and only use the sale order lines of the components.
opw-6016209
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#256978
Forward-Port-Of: odoo/odoo#256055This update resolves an issue preventing website users from seeing product ratings due to access restrictions on product data. The change allows dynamic snippets to be accessed without superuser privileges, ensuring public visitors can view and interact with product ratings. This improves the user experience for customers browsing products.
Original PR description
**Steps to produce:** - Install the `Ecommerce` module. - Create a product. - In the Sales tab, set an alternative product and ensure both are published. - Open the product page on the website and enable `reviews` from the editor. - Open the same product page in incognito mode. **Issue:** ``` AccessError: You do not have enough rights to access the field "rating_avg" on Product Variant (product.product). ``` Root cause: --- - Currently, product records in dynamic snippets to be fetched without superuser privileges. Since the `rating_avg` field is restricted to internal users, public visitors encounter an `AccessError` when viewing snippets with ratings enabled. - Similar approach used [here]. [here]: https://github.com/odoo/odoo/commit/12bb994da4c3222e8c7fb2df95c202a6c45a28b0 opw-6065319 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an error in the Mod 347 BOE export for Spanish companies, ensuring the correct indicators ('C' and 'S') are used for substitutive and complementary declarations. This prevents the AEAT from misinterpreting the file, ensuring accurate tax reporting and compliance.
Original PR description
Currently, the BOE export for `Mod 347` uses incorrect indicators for `Substitutive` and `Complementary declarations`. **Steps to reproduce:** - Install the `l10n_es_reports` module and switch to the…
Currently, the BOE export for `Mod 347` uses incorrect indicators for `Substitutive` and `Complementary declarations`. **Steps to reproduce:** - Install the `l10n_es_reports` module and switch to the `ES company` - Navigate to Accounting > Reporting > Tax Report - From the smart button, select `Report: Tax Report (Mod 347) (ES)` - Download the BOE file using the dropdown. - In the wizard: - Enable `Substitutive Declaration` or `Complementary Declaration` - Set `Previous Report Number` (e.g., 123456789) - Click `Generate BOE` - Upload the generated .txt file to the `AEAT portal`. (AEAT credentials are required) **Observation:** AEAT does not recognize 'X' as a valid indicator for substitutive or complementary declarations and interprets the file as a standard return. **Root Cause:** At [1], the BOE Mod 347 generation writes 'X' for both substitute and complementary declarations. **Fix:** This commit ensures the file contains correct indicators: - 'C' for `complementary declarations` - 'S' for `substitute declarations` This aligns Modelo 347 with AEAT specifications and ensures consistency with the implementation of Modelo 349 at [2]. Ref: https://sede.agenciatributaria.gob.es/Sede/en_gb/ayuda/consultas-informaticas/declaraciones-informativas-ayuda-tecnica/modificar-declaracion-informativa-mediante-fichero.html [1]: https://github.com/odoo/enterprise/blob/c5332bef593cc3fa1b5013a0dac56ccd67e4da14/l10n_es_reports/models/aeat_tax_reports.py#L1061-L1062 [2]: https://github.com/odoo/enterprise/blob/c5332bef593cc3fa1b5013a0dac56ccd67e4da14/l10n_es_reports/models/aeat_tax_reports.py#L1490-L1491 opw-6048711 Forward-Port-Of: odoo/enterprise#112566
This update resolves a technical issue where reports were loading indefinitely, consuming excessive memory. The fix ensures reports stop loading when the component is destroyed, preventing memory buildup and improving system performance. This enhances the stability and responsiveness of the reporting feature.
Original PR description
The preloading of sections would never stop, this is an issue since this would prevent the garbage collector from collecting this big class and all it's objects. We fix this by making sure to stop the reploading when the component is destroyed. It's important to do it this way rather than clearing the timeout as the destruction could happened when the report is loading so the timeout would be unset and a new one would be started. Forward-Port-Of: odoo/enterprise#112662 Forward-Port-Of: odoo/enterprise#112628
This update ensures our accounting software accurately reflects the latest Ecuadorian withholding tax regulations (Resolución N.º NAC-DGERCGC26-00000009) for 2026. The changes involve updating internal test procedures to align with these new tax percentages, ensuring accurate reporting and compliance.
Original PR description
In accordance with the implementation of the new withholding tax percentages according to "Resolución N.º NAC-DGERCGC26-00000009" for Ecuador, following internal implementation guidelines by TRESCLOUD. Unit tests are updated to be based on the new withholding percentages. BP #110343 Forward-Port-Of: odoo/enterprise#110879 Forward-Port-Of: odoo/enterprise#110712
This update fixes a confusing issue in Odoo's Web Studio where a purple 'info' pill appeared on action buttons for mobile users. This prevented users from easily clicking the intended buttons, leading to a frustrating experience. The change removes this unnecessary element, streamlining the mobile interface.
Original PR description
Steps: - Install `web_studio` - Add an approval rule to any action in any form view (example preview button) - Open this form view - You will have a purple info pill in every action button in the form view This can be confusing for people wanting to click on the button on mobile but instead, they click on the purple pill + we don't even want this opw-5911667 Forward-Port-Of: odoo/enterprise#111770
Features or functions removed from Odoo
This update removes restrictions on which PEPPOL numbers can be used for registration. Previously, only numbers from the PEPPOL list were accepted. Now, Odoo can accept numbers from a wider range of countries, increasing the potential reach of our accounting integrations.
Original PR description
Before this commit, only numbers on the peppol list were able to be registered. Now is possible to add numbers from other countries. Task-6033336 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254373
Documentation and clarification updates
This update corrects a minor detail in the Optesis documentation by updating the contributor list. Specifically, the name of Ibrahima NIASSE EXT has been added to reflect the most current information. This ensures accurate representation of those involved in the Optesis project.
Original PR description
Replaced Mame Abdoul Aziz SY with Ibrahima NIASSE EXT in the contributors list. 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#256563