Daily updates from Odoo
Thursday, May 21, 2026
56 changes · saas-19.1
New functionality added to Odoo
This update introduces a new module, 'obox,' to connect with Obox devices – a hardware platform similar to the Odoo FDM for Belgium. The initial step is to allow the system to recognize and view the Obox's IP address and available services, laying the groundwork for future device interaction.
Original PR description
The Obox (same platform as the Odoo FDM for Belgium) will allow interfacing with hardware devices, and is intended to replace the functionality of the IoT box. This commit only adds the ability to pair an Obox to the database, and see its IP and available services. Enterprise https://github.com/odoo/enterprise/pull/110834
This update introduces the 'obox' module, enabling connection with hardware devices similar to the existing Odoo FDM. The initial step allows users to register and view basic information about their Obox devices, including IP addresses and available services – a key step towards broader device connectivity.
Original PR description
The Obox (same platform as the Odoo FDM for Belgium) will allow interfacing with hardware devices, and is intended to replace the functionality of the IoT box. This commit only adds the ability to pair an Obox to the database, and see its IP and available services. Community: https://github.com/odoo/odoo/pull/254208
Enhancements to existing features
This update enables users to reset statement lines directly within the Kanban view, mirroring functionality from previous versions. This prevents the need to manually delete numerous reconciliations associated with a single statement line, streamlining the accounting process.
Original PR description
This commit adds the possibility to reset a statement line in kanban view like in the previous versions. Function is still there but no UI button was tied to it. This is a problem if you have many reconciliations on one statement line, we do not want to delete them one by one. opw-6015838 Forward-Port-Of: odoo/enterprise#111107
This update enables the IoT box to broadcast its IP address via Bluetooth for 5 minutes after startup. This feature simplifies troubleshooting by providing support and clients with the IP address needed to diagnose connectivity issues. It also handles cases where no network is available by advertising 'No network connection'.
Original PR description
This PR allows the iot box to advertise its ip address over Bluetooth for 5 minutes after boot. The format is `IoT Box [S/N] - [ip]` If no network is available it would advertise "No network connection" instead of the ip This can help clients and support to troubleshoot IoT Box issues.
Resolved issues and error corrections
This update resolves an issue that prevented users from initiating replenishment orders when no routes were associated with a product and the company's routes were not active. The fix ensures the system handles empty route lists gracefully, preventing a technical error and ensuring replenishment functionality works correctly for all products.
Original PR description
## Steps to Reproduce: 1. Install the stock module. 2. Activate "Multi-Step Routes" from settings. 3. Activate the "My Company (Chicago)" company. 4. Create a route for the Chicago company. 5. Create a new product and enable the created route on it. 6. Click on the "Replenish" button. ## Error: `IndexError - tuple index out of range` ## Cause: At [1], when none of the product routes belong to the current company or are shared routes, the filtering returns an empty recordset. As a result, trying to access the first route from the empty result raises an index error. ## Fix: This commit only assigns `route_id` when a route matches the given condition. Otherwise, it keeps the value as `False`. [1] - https://github.com/odoo/odoo/blob/13c0e082c260381a332fe1425fe2ba83a1c0c579/addons/stock/wizard/product_replenish.py#L78 sentry-7488075413 Forward-Port-Of: odoo/odoo#265179
This update corrects a bug where users could cause an error when entering spaces in the 'Forecasted Demand' or 'Forecasted Stock' cells within the Master Production Schedule. The fix ensures that blank input is handled correctly, preventing the error and maintaining data integrity. This improves the user experience and prevents potential data issues.
Original PR description
## Steps to Reproduce:
1. Install `mrp_mps` module.
2. Manufacturing > Planning > Master Production Schedule
3. Click on "Forecasted Demand" or "Forecasted Stock" of any product.
4. Click `<SPACE>` and then `<ENTER>`.
## Error:
`ValueError: could not convert string to float: ' '`
## Cause:
When a user enters whitespace(' ') in a **Forecasted Demand** or **Forecasted Stock** cell, the string bypasses the existing `isNaN/empty` checks at [1]. Then the raw whitespace string passes to the ORM call, where `float(' ')` raised a ValueError.
## Fix:
This commit trims the value so that blank input is treated the same as an empty string, and the cell reverts to its original value.
[1] - https://github.com/odoo/enterprise/blob/6ae5d3df6e9305416e4d6f74259cd01753025f42/mrp_mps/static/src/components/line.js#L128
sentry-7473062917
Forward-Port-Of: odoo/enterprise#117052This update fixes a bug that prevented users from creating new helpdesk teams. The issue occurred when the system attempted to use a default email template after deleting all helpdesk stages. The fix ensures the template exists before attempting to use it, preventing an error and allowing team creation to proceed smoothly.
Original PR description
Currently, an error occurs when a user tries to create a helpdesk team record. **Steps to Reproduce:** - Install the `helpdesk` module without demo data. - Go to `Settings` > `Technical` > `Email` >…
Currently, an error occurs when a user tries to create a helpdesk team record. **Steps to Reproduce:** - Install the `helpdesk` module without demo data. - Go to `Settings` > `Technical` > `Email` > `Email Templates` and delete the `Helpdesk: Ticket Received` template record. - Go to `Helpdesk` > `Configuration` > `Stages` and remove all records. - Go to `Helpdesk` > `Configuration` > `Helpdesk Teams` and click `New` to create a record. `AttributeError: 'NoneType' object has no attribute 'id'` When the user deletes all stages, the system attempts to create a new stage and assign the "Helpdesk: Ticket Received" mail template to it [1]. However, if this template record does not exist, accessing its id raises the error. This commit ensures that the template record exists before accessing its id, otherwise, None is passed as the default value. [1]: https://github.com/odoo/enterprise/blob/32187f79fb0a595497a5e77db4b22b417b03b8dd/helpdesk/models/helpdesk_team.py#L34 sentry-7482994877 Forward-Port-Of: odoo/enterprise#117446
This update fixes a bug that prevented order synchronization with Lazada when package information was incomplete. The system now gracefully handles missing package data, preventing errors and ensuring orders are synced correctly. This improves the overall reliability of the Lazada integration.
Original PR description
orders can omit package data in the API payload if the package id doesn't match. When a picking still had a package_extern_id, filtering order_items by that id produced an empty list, and max() on the resulting timestamps raised ValueError and blocked order sync. Return early when no matching package lines exist so sync can continue. taskId - 6195507 Forward-Port-Of: odoo/enterprise#117194
This update fixes a bug that prevented the HTML editor from correctly converting URLs with mixed or uppercase characters into clickable links. The fix now ensures all URLs, including short domains like 'x.com', are automatically recognized and linked. This improves the user experience by making it easier to share and navigate to online resources within Odoo.
Original PR description
### Description of the issue/feature this PR addresses: - URL_REGEX was constructed with the "i" flag, but passing a RegExp object to new RegExp(regex, "g") silently drops the original flags, leaving only "g". This caused uppercase (ODOO.COM) and mixed-case (Odoo.Com) URLs to not be converted to links when pressing space. ### Desired behavior after PR is merged: - URL_REGEX.source with explicit "gi" flags to preserve case-insensitive matching in `prepareConvertToLink`. - Allow automatic URL detection for single-character domains such as `x.com`, `t.co`, and `a.io` by relaxing the minimum domain label length in the URL regex from 2 to 1 characters. task-6199269 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265409 Forward-Port-Of: odoo/odoo#263255
This update resolves a performance issue in the ES VAT Books report where excessive journal entries caused browser crashes. By implementing a 'load more' limit of 4000, the report now handles larger datasets more efficiently, improving user experience and stability.
Original PR description
The ES VAT Books report currently does not limit the number of lines loaded in the browser. This becomes more and more problematic as the volume of journal items listed in the report increases, ultimately leading to the browser being unable to render that many elements without crashing. Inspired by how this situation is handled in other reports and localizations, we now make use of the `load_more_limit` parameter and set a new default value of 4000 for it. Ticket: opw-5962456 Forward-Port-Of: odoo/enterprise#113830
This update fixes a bug where users could still attempt to book rental services even when resources were unavailable during their chosen time periods. The change ensures that the system now correctly blocks users from adding unavailable resources to their cart, preventing booking errors and improving the user experience. This enhancement is part of a broader effort to ensure accurate rental service availability.
Original PR description
Before this commit, when the user goes to the webshop to take a rental service with rental service unavailable at a certain period, the system does not block the user when the resource is not available during 2 hours in the period chosen by the user. The reason is because the hours are not checked when website_sale_renting_stock is not installed. This commit moves the code checking the time of the rental period made in website_sale_renting_stock in website_sale_renting to be able to have that verification for rental service used with planning to make sure the system will prevent the user to add the product in his cart when the resource is unavailable. task-5123239
This update fixes an issue where the bank account currency wasn't correctly reflected in the XML files generated for Polish e-invoices (Ksef). The change ensures that the 'OpisRachunku' field in the XML accurately displays the bank account currency, resolving a potential reporting discrepancy. This improves the accuracy of e-invoice data transmission.
Original PR description
**STEP TO REPRODUCE** 1. Create a partner with a bank account and setup its currency. 2. Create an invoice using a different currency. 3. Send the invoice to Ksef. 4. Notice the generated xml contains the invoice currency in the field OpisRachunku, but it should be the bank account currency instead. opw-6150563 Forward-Port-Of: odoo/odoo#263842
This update resolves an issue where clicking a dropdown on the `/r` page would cause a system crash. The fix ensures the dropdown observer only starts when the menu element is fully rendered, preventing a 'TypeError' and allowing the dropdown to function correctly. This improves the user experience on this specific page.
Original PR description
Steps to reproduce: - Go to the `/r` page. - Click a dropdown. => traceback Before this commit, `Dropdown.onOpened()` always observed `menuRef.el` as soon as the popover reported it was open. In frontend pages such as `/r`, the menu can still be rendering at that moment. The menu appears just after, but `MutationObserver.observe()` already received `undefined` and raised a `TypeError`. After this commit, `Dropdown.onOpened()` only starts the observer when the menu element exists. The dropdown can finish opening normally, so the menu is shown without traceback. Introduced by [1]. [1]: 7aed5b141f06 Forward-Port-Of: odoo/odoo#265224
This update corrects a bug where changing the standard price of a lot-valued product didn't correctly update the product's cost. The fix ensures that the product's cost is accurately recalculated when the standard price is modified, maintaining correct inventory valuation. This resolves a discrepancy in how lot-valued products are tracked.
Original PR description
**Problem:** change of standard price on a product valued by lot and with standard price category does not work **Steps to reproduce:** - create a storable product tracked and valued by lot - set…
**Problem:** change of standard price on a product valued by lot and with standard price category does not work **Steps to reproduce:** - create a storable product tracked and valued by lot - set category as standard price - set a cost of 10 and save - click on the quantity smart button and then "update quantity" - add a quantity of 1 in a new lot - on the product form, change the cost to 12 and save - reload the page **Current behavior:** the cost is back to 10 **Expected behavior:** it should stay 12 **Cause of the issue:** when we change the standard_price of the product, _change_standard_price() is called from the write method https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L293 Inside _change_standard_price(): step 1: a new product.value is created step 2 : we set the standard_price of the lots to be the same as the one of the product https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L319-L323 In the create method for product.value (step 1), we call _set_value() on the moves with a remaining quantity https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product_value.py#L95 At the end of set_value we call _update_standard_price() on our product https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/stock_move.py#L337 Because the product is lot_valuated we update the standard_price based on the avg_cost of the product (this is needed because for instance if the prod is avco we can not simply use _run_average_batch as it is the case for non lot valuated avco product, because then the result won't be a weighted average of each lot, whereas avg_cost does take this into account) https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L633-L634 To compute the avg_cost, inside _compute_value(), we use the total value of each lot https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L226 The lots total value is computed inside the _compute_value() method of stock.lot. In this method, because the product is valued by standard_price we use the standard price of the lot https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/stock_lot.py#L40 But this value hasn't been updated yet (it will be at the time of step 2) so it's still the old value (10 in our case). So the avg_cost of the product will also be the old value and the standard price will be udpated back the old value Then, at the end of _change_standard_price() (at the time of step 2) the standard price of the lots are set based on the standard price of the product (so it stays the old value) **fix:** Inside _update_standard_price(), if the product is valued by standard price we do nothing https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L639-L640 We apply the same logic for the lot_valued product, if it's standard_price there is nothing to update opw-5949146 Forward-Port-Of: odoo/odoo#264991
This update resolves an issue where time off requests with dual approval ('both') weren't sending notifications to the designated responsible parties. The fix ensures that notifications are properly sent to the 'Notified Time Off Officer' when this approval type is selected, improving the accuracy of time off request workflows.
Original PR description
…cer') no fallback for responsible_ids
Issue:
When ('both','By Employee's Approver and Time Off Officer') is selected on a new HR Leave Type it does not fall back to the responsible_ids or “Notify HR”.
Steps:
1) Setup a neutralized outgoing mail server
2) install hr_holidays
3) make a new hr.leave.Type (Approval) with ('both','By Employee's Approver and Time Off Officer') and select a 'Notified Time Off Officer'(responsible_ids) 4) select an emplyee with a reelated user and remove the coach, manager, and responsible 'Time Off'. 5) save
6) Sign in as the employee, make a time off request under the new Type 7) No email
Fix:
Add a conditional with the lowest priority to fall back to responsible_ids
opw-6101637
Forward-Port-Of: odoo/odoo#264332
Forward-Port-Of: odoo/odoo#261853This update fixes an issue where Italian tax data (specifically INPS and Pension Fund) wasn't being properly imported into Odoo. The fix ensures these taxes are correctly configured, allowing the system to accurately process vendor bills and comply with Italian tax regulations. This improves the reliability of tax calculations and reporting.
Original PR description
### Issue before this commit: In the previous implementation, several Italian taxes, specifically the 4% INPS and the 4% Pension Fund (F.Pens), were not correctly initialized. Although the relevant…
### Issue before this commit: In the previous implementation, several Italian taxes, specifically the 4% INPS and the 4% Pension Fund (F.Pens), were not correctly initialized. Although the relevant EDI data was present in the source CSV templates, it was missing from the actual tax records in the database. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi 2. Go to Accounting -> Taxes 3. Open 4% INPS tax and 4% F.Pens and go to Advanced Options tab and see that no Pension Fund Type is associated by default ### Cause of the issue: While moving the witholding data from l10n_it_edi to l10n_it in this commit https://github.com/odoo/odoo/commit/40e09ca01242 the templates were not correcly rendered and set up. ### Reason to introduce the fix: For a tax to be correctly recognized from the XML, it is essential that we have the corresponding tax already configured in Odoo, including the specific type. We should have at least these two taxes fully configured so the system can elaborate them correctly when imported from vendor bills. opw-6093221 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258947
This update ensures that the customer reference field from invoices is correctly included in the fa3 XML file generated for transmission to the Polish KSEF (tax office). Previously, this information was missing, which could cause processing delays. This fix ensures compliance with Polish tax regulations.
Original PR description
**STEP TO REPRODUCE** 1. Create an invoice and fill the customer reference field (other info tab). 2. send the invoice to ksef. 3. Open the generated fa3 file, and notice there is no mention of the customer reference. Ticket [link](https://www.odoo.com/odoo/project.task/6150812) opw-6150812 Forward-Port-Of: odoo/odoo#263797
This update fixes a bug where selecting a table cell would sometimes incorrectly select the entire table. Previously, selection started in a cell and ended outside the cell wasn't properly handled. This change ensures that table selections work consistently, regardless of how the user initiates the selection process.
Original PR description
The previous commit fixes a behavior that is expected when the user makes a selection that starts in any element and ends in a table cell (the whole table gets selected), but the reverse case was never handled, namely when the selection starts in a table cell and ends outside of it. backport-https://github.com/odoo/odoo/pull/239270/changes/68e71fad5bbb0445bb1850bf694235f3235b602f task-5420366 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265464 Forward-Port-Of: odoo/odoo#264722
This update ensures that WhatsApp channel avatars in the sidebar accurately reflect the member who added the channel, rather than defaulting to a generic avatar. Previously, adding a member caused the incorrect avatar to be shown. This fix improves the user experience and visual consistency within the WhatsApp channel interface.
Original PR description
WhatsApp sidebar avatars should be resolved from the channel's whatsapp member, not from an arbitrary non-self member. Before this fix, adding a member to a WhatsApp channel caused the default Discuss avatar to be displayed instead of the actual WhatsApp member's avatar. This happened because the correspondent was not correctly computed for channels of type whatsapp. task-[5879840](https://www.odoo.com/odoo/project/1519/tasks/5879840) Forward-Port-Of: odoo/enterprise#117633 Forward-Port-Of: odoo/enterprise#115745
This update resolves an issue where the Send & Print wizard would fail when proforma PDFs weren't generated for invoices. The change ensures the system handles cases where these PDFs aren't available gracefully, preventing errors and improving the reliability of invoice sending. This primarily affects invoices processed with specific localization modules.
Original PR description
`_generate_and_send_invoices` raises `KeyError: 'proforma_pdf_attachment'` when `_get_invoice_extra_attachments` returns an empty recordset for a move in the `success` dict. The…
`_generate_and_send_invoices` raises `KeyError: 'proforma_pdf_attachment'` when `_get_invoice_extra_attachments` returns an empty recordset for a move in the `success` dict.
The `proforma_pdf_attachment` key is only populated in `_generate_invoice_fallback_documents`, which is called exclusively when `allow_fallback_pdf=True`. However, the code at the return step also triggers when `allow_fallback_pdf=False` (normal wizard path), where the key is never set.
Replace the bare dict access `move_data['proforma_pdf_attachment']` with `move_data.get('proforma_pdf_attachment', self.env['ir.attachment'])` so the flow returns an empty attachment recordset instead of raising a `KeyError` when no fallback proforma PDF was generated.
Fixes: KeyError: 'proforma_pdf_attachment' in account.move.send.wizard Steps to reproduce:
1. Use the Send & Print wizard on a posted invoice
2. Trigger a condition where _get_invoice_extra_attachments returns an empty recordset (e.g. via l10n_vn_edi_viettel with sinvoice files not yet fetched) despite no error being raised
Forward-Port-Of: odoo/odoo#264564This update resolves an issue preventing normal users from canceling approval requests they created. The fix uses 'sudo' to grant the necessary permissions, ensuring users can now successfully cancel their own approvals without errors. This improves user experience and streamlines the approval process.
Original PR description
Issue: - A user who created an approval request could cancel it. But a rights error appeared during the cancellation. Steps to Reproduce: - Create an approval being a normal user. - Try to cancel the approval. - A ValidationError is raised eventhough the approvals can be cancelled by creator of it. Fix: - Changed the cancel action to use the sudo for the user who created the task and can cancel it Impact: - Users can cancel their own approval requests without errors. Task: 6123104 Forward-Port-Of: odoo/enterprise#114189
This update fixes a minor visual issue on the Odoo website's shop page. Specifically, it prevents the 'clear' button from shrinking, ensuring a consistent and professional look for customers. This improves the overall user experience and brand image.
Original PR description
task-6145581 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262183
This update resolves an issue where updating a manufacturing order (MO) with a multi-level BOM would only create MOs for the immediate child components, missing the next level. The fix ensures that all necessary MOs are generated during the update process, preventing incomplete manufacturing workflows. This improves the reliability of production planning.
Original PR description
When updating a mo, if the new component has a multilvl bom, it will only create a mo for the direct child and not the next Steps to reproduce: ------------------- * Create a products "Main",…
When updating a mo, if the new component has a multilvl bom, it will only create a mo for the direct child and not the next Steps to reproduce: ------------------- * Create a products "Main", "Final", "Semi", "Raw" * Create a Bom for "Final" with "Semi" as component * Create a Bom for "Semi" with "Raw as component * Add MTO on Final and Semi * Create a MO for Main with no components and confirm it * Add "Final" to the mo as component as save. -> The MO for "Final" is correctly created with "Semi" as component but there is no MO for "Semi" with "Raw" as component. Observation: ------------- When updating de MO, it will write the new SM (Final) to the production, and we will call ```_autoconfirm_production``` with ```no_procurement```: https://github.com/odoo/odoo/blob/6fb69b5640743d3bc7bb52c73cb27da428f2451c/addons/mrp/models/mrp_production.py#L1051 Where we will directly confirm the sm (```_action_confirm```). From the SM ```_action_confirm``` we will create and run a procurement (manufacture in our case). From the manufacture we will create the new move line for Semi and go through ```action_confirm``` on the manufacturing order: https://github.com/odoo/odoo/blob/9ef76a4d6010191ab7ab1a0d1085972901280dda/addons/mrp/models/stock_rule.py#L116-L118 In the MO ```action_confirm```, we will confirm the move and should create new procurement for the moves that need them, but, since in our case we have ```no_procurement``` in the context, we will set ```create_proc``` to false: https://github.com/odoo/odoo/blob/9ef76a4d6010191ab7ab1a0d1085972901280dda/addons/mrp/models/mrp_production.py#L1635 Since ```create_proc``` is false we will not create a procurement for those move lines: https://github.com/odoo/odoo/blob/6fb69b5640743d3bc7bb52c73cb27da428f2451c/addons/stock/models/stock_move.py#L1557-L1558 https://github.com/odoo/odoo/blob/6fb69b5640743d3bc7bb52c73cb27da428f2451c/addons/stock/models/stock_move.py#L1571-L1580 opw-6005675 Forward-Port-Of: odoo/odoo#258153
This update fixes an issue where service products weren't correctly applying user-defined default units of measure. Previously, the system would override these settings when a product was marked as a service. Now, default units are applied unless a service product is being invoiced with timesheets, ensuring accurate unit tracking for all product types.
Original PR description
A user-defined default on `product.template` Unit is not applied when the product is of type Service 1. Install Sales and Sales Timesheet 2. Go to Settings > Sales > Product Catalog and enable Units of Measure & Packagings 3. Enable debug mode 4. Go to Sales > Products, open a new product form and set unit to Days 5. In the debug menu (bug icon in the top right), select Set Default Values for Unit = Days and save 6. Reload the page 7. Set the type to Service 8. Unit changes from Days to Hours Same issue happens for `product.product` Issue: User default values are overwritten when certain conditions are met by https://github.com/odoo/odoo/blob/6955370fd2d62c83f0ea24247abf7a9e4b4ebed3/addons/sale_timesheet/models/product_template.py#L55-L57 Solution: Use the user defined default on `uom_id` except for service products that are invoiced with timesheets as they need a time unit of measure opw-6139603 Forward-Port-Of: odoo/odoo#262597
This update fixes an issue where Fedex delivery labels were missing a crucial 'REF' field, which is required by the shipping carrier. The fix ensures that all labels now correctly include this reference, preventing potential delivery delays or errors. This improves the accuracy and reliability of our shipping process.
Original PR description
Issue ----- `REF` field of Fedex labels is missing. Steps to reproduce ----- - Setup Fedex - Create a product (set weight) - Create a delivery for the product - Set carrier as Fedex - Validate…
Issue
-----
`REF` field of Fedex labels is missing.
Steps to reproduce
-----
- Setup Fedex
- Create a product (set weight)
- Create a delivery for the product
- Set carrier as Fedex
- Validate delivery
- Opend the label
> REF field is empty
Cause
-----
When filling the `CustomerReferences`, we only specify the SO
https://github.com/odoo/enterprise/blob/aae680f5b86fa87193ba6616e8431eed985b2ee7/delivery_fedex_rest/models/fedex_request.py#L309-L313
The `REF` field is populated using `CUSTOMER_REFERENCE` references, which is not present in this case.
Excerpt of the API DOC
-----
```
"CustomerReference": {
"type": "object",
"properties": {
"customerReferenceType": {
"type": "string",
"description": [...],
"example": "DEPARTMENT_NUMBER",
"enum": [
"CUSTOMER_REFERENCE",
"DEPARTMENT_NUMBER",
"INVOICE_NUMBER",
"P_O_NUMBER",
"INTRACOUNTRY_REGULATORY_REFERENCE",
"RMA_ASSOCIATION"
]
},
"value": {
"type": "string",
"description": [...],
"example": "3686"
}
}
},
```
[...] replaces long description strings, refer to API for full documentation.
Result after fix
-----
<img width="477" height="738" alt="image" src="https://github.com/user-attachments/assets/0d3a0786-5b7d-41cc-8548-2dc7b0f379ab" />
-----
Ticket:
opw-6101620
Forward-Port-Of: odoo/enterprise#116870This update resolves a memory issue that previously prevented users from importing large PDF files into the Documents App. The fix disables a resource-intensive part of the PDF processing library, ensuring smoother and more reliable PDF imports for all users. This improves the overall user experience and prevents data import failures.
Original PR description
### Description: When trying to import a large PDF file into the Documents App, it can sometimes fail because of an Out-of-Memory error (OOM). This is caused by the library `pdfminer.six` and the function `group_textboxes` that helps order the result of the indexing. This function is memory heavy and is not useful for our use case. To avoid it, we can just disable the "advanced layout analysis" by disabling `boxes_flow`. ### Reference: opw-6164752 Forward-Port-Of: odoo/odoo#264301
This update corrects a technical issue causing unnecessary chatter logging when changing employee pay categories. The change prevents Odoo from tracking a specific field, ensuring smoother operation and reducing potential log clutter. This improves system performance and simplifies payroll management.
Original PR description
Steps to reproduce the issue: 1. Ensure Payroll is installed (the other necessary modules will be installed) 2. Create a new employee, and assign them a new pay category 3. In the new pay category,…
Steps to reproduce the issue: 1. Ensure Payroll is installed (the other necessary modules will be installed) 2. Create a new employee, and assign them a new pay category 3. In the new pay category, assign it a new pay structure 4. In the new pay structure, create a new salary rule with the following options a. Based On → Salary Input b. Unit → Monetary (should be checked by default) c. Available on → Employee d. Default Value → > 0 5. Go back to the employee, go in the payroll tab, scroll to the bottom, and add a new input 6. Select the salary rule you made, and give it a value > 0 7. Save the record 8. Try to change the employee's pay category and observe traceback When changing an employee's pay category, Odoo attempts to log this change in the chatter, even though it is not explicitly a tracked field. The reason for this is because when changing the pay category, `payroll_properties` is also changed in some circumstances. For `properties` fields, they are only logged if it's parent field is updated, and if the `tracking` attribute is not set to `False`. Previously, this was not an issue, as `hr_employee.structure_id` (the parent field of `payroll_properties`) was not a tracked field. The same is true for `hr_version.structure_id`. However, as of this commit (https://github.com/odoo/odoo/pull/156236), they are now tracked fields, as they are not explicitly marked as `tracking=False`. This causes `payroll_properties` to be picked up as a tracked field, since the `tracking` attribute is not explicitly set to `False` This commit will ensure that we explicitly do not track this field, as it was not tracked before these changes. [opw-6173051](https://www.odoo.com/odoo/project/49/tasks/6173051?debug=assets)
This pull request addresses a reported error related to the salary configurator within Odoo. The fix removes a problematic code section that was causing the error, ensuring the configurator functions correctly. This resolves a potential disruption for users managing employee compensation.
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
This update fixes a technical error that prevented users from completing orders with the 'Ship Later' option in the Point of Sale (POS) system. The issue stemmed from how the system handled date formatting, specifically when clearing the 'Ship Later' date field. The fix ensures the system correctly processes orders with this feature.
Original PR description
Steps: = - Enable Allow Ship Later in POS configuration. - Open POS and add any product. - Proceed to the Payment screen. - Click Ship Later, clear the date field, and confirm Issue: = - A traceback occurs: `TypeError: this.state.shippingDate.toISODate is not a function` Reason: = - Here, shippingDate is a Luxon DateTime object when provided. when cleared, it becomes null, so converting it to ISO format is casung the error. Fix: = - Removed unnecessary conversion using `.toISODate()`. - Removed unnecessary hoot test. - Added validation on shippingDate to prevent selecting a past date. task-5406969
This update fixes an issue where guests rejoining public discuss meetings would be redirected to a welcome page without their name pre-filled. The change restores the previous behavior, allowing users to quickly rejoin with a single action and improving the meeting experience.
Original PR description
Previously, when a guest joined a discuss meeting, and the page was reloaded, the user was redirected to the welcome page without the guest name being pre-filled in the input. This PR restores the previous behavior by pre-filling the guest name in the input, allowing users to rejoin the meeting quickly with a single action. task-6192285 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where vendor bills were incorrectly using Swiss tax rates when the invoice originated from a Belgian company. The change ensures that the correct tax rate, based on the invoice's fiscal localization, is applied during the import process. This prevents errors and ensures accurate tax calculations for international transactions.
Original PR description
**Steps to reproduce:** - Create a company in Belgium and set the fiscal localisation accordingly. - In the same company, create a fiscal position in Switzerland, set the foreign tax ID and then…
**Steps to reproduce:** - Create a company in Belgium and set the fiscal localisation accordingly. - In the same company, create a fiscal position in Switzerland, set the foreign tax ID and then generate the taxes for it. - Install the module account_edi_ubl_cii. - Create and invoice for a belgian customer, with one product line having a 0% tax. - Export the invoice as XML. - Go to taxes, filter by purchase, and make sure that the 0% switzerland tax has a higher sequence than the belgian 0% tax. - Import the previous invoice XML as a vendor bill. **Issue:** After importing the bill, the switzerland tax is used even though the fiscal localisation is belgian, which is wrong as it violates the constraint _validate_taxes_country **Solution:** Added a more selective domain to _import_fill_invoice_line_taxes opw-5467936 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265200 Forward-Port-Of: odoo/odoo#255848
This update fixes a discrepancy in how contract type IDs are defined within Odoo's payroll modules. Specifically, the definition was standardized across all modules, resolving potential conflicts and ensuring accurate reporting for Belgian payroll calculations. This change is limited to version 17 and will be addressed in a separate update.
Original PR description
[IMP] hr_contract_salary: fix contract_type_id definition The definitions of the contract_type_id in hr_contract_salary_offer and l10n_be_hr_contract_salary/hr_contract_salary_offer should be same I converted the definition of contract_type_id in the base module to the Belgium one. Also, the contract_type_id was inserted to the view in Belgium one as well, I deleted that part to prevent double appearance. This task is only for v.17, after this version I will open a new PR to handle them. Do not forward the task after v.17 (only for v.17) task - 6101717 Forward-Port-Of: odoo/enterprise#117708 Forward-Port-Of: odoo/enterprise#113244
This update optimizes how Odoo searches for records linked to binary attachments. Previously, searching for records with no attachment resulted in a slow query. Switching to a more efficient ‘NOT EXISTS’ approach dramatically speeds up this search, especially when dealing with a large number of attachments.
Original PR description
Description of the issue/feature this PR addresses: Searching for records without a binary attachment (e.g., `('binary_field', '=', False)`) previously generated a query using `NOT IN (SELECT res_id…
Description of the issue/feature this PR addresses:
Searching for records without a binary attachment (e.g., `('binary_field', '=', False)`) previously generated a query using `NOT IN (SELECT res_id FROM ir_attachment...)`. On databases with a large `ir_attachment` table, materializing this entire list of IDs causes a significant performance bottleneck.
Replacing NOT IN with a NOT EXISTS allows PostgreSQL to short-circuit the evaluation as soon as it find a matching document, drastically reducing query execution time.
Current behavior before PR:
Searching for a "false-ish" binary with attachment generates a query with a `NOT IN`, slow when `ir_attachment` is large.
```python
>>> env["ir.ui.menu"].search([("web_icon_data", "!=", False)])
2026-03-06 15:59:51,326 516177 DEBUG odoo19 odoo.sql_db: [1.076 ms] query: SELECT "ir_ui_menu"."id" FROM "ir_ui_menu" WHERE ("ir_ui_menu"."active" IS TRUE AND "ir_ui_menu"."id" IN (SELECT res_id FROM ir_attachment WHERE res_model = 'ir.ui.menu' AND res_field = 'web_icon_data')) ORDER BY "ir_ui_menu"."sequence" , "ir_ui_menu"."id"
ir.ui.menu(15, 1, 16)
>>> env["ir.ui.menu"].search([("web_icon_data", "=", False)])
2026-03-06 15:59:54,439 516177 DEBUG odoo19 odoo.sql_db: [0.665 ms] query: SELECT "ir_ui_menu"."id" FROM "ir_ui_menu" WHERE ("ir_ui_menu"."active" IS TRUE AND "ir_ui_menu"."id" NOT IN (SELECT res_id FROM ir_attachment WHERE res_model = 'ir.ui.menu' AND res_field = 'web_icon_data')) ORDER BY "ir_ui_menu"."sequence" , "ir_ui_menu"."id"
ir.ui.menu(62, 68, 3, 10, 43, 59, 4, 28, 44, 65, 6, 7, 29, 41, 45, 61, 66, 5, 18, 30, 31, 48, 49, 60, 69, 70, 9, 11, 12, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 32, 33, 34, 36, 37, 38, 39, 40, 42, 46, 47, 52, 54, 56, 57, 58, 63, 71, 73, 74, 76, 78, 79, 80, 81, 50, 64, 51, 72, 75, 77, 35, 14, 13, 53, 2, 55, 67, 8)
```
Desired behavior after PR is merged:
Searching for a "false-ish" binary with attachment generates a query with a `NOT EXISTS`
```python
>>> env["ir.ui.menu"].search([("web_icon_data", "!=", False)])
2026-03-06 15:59:04,847 513555 DEBUG odoo19 odoo.sql_db: [0.945 ms] query: SELECT "ir_ui_menu"."id" FROM "ir_ui_menu" WHERE ("ir_ui_menu"."active" IS TRUE AND "ir_ui_menu"."id" IN (SELECT res_id FROM ir_attachment WHERE res_model = 'ir.ui.menu' AND res_field = 'web_icon_data')) ORDER BY "ir_ui_menu"."sequence" , "ir_ui_menu"."id"
ir.ui.menu(15, 1, 16)
>>> env["ir.ui.menu"].search([("web_icon_data", "=", False)])
2026-03-06 15:59:08,323 513555 DEBUG odoo19 odoo.sql_db: [0.628 ms] query: SELECT "ir_ui_menu"."id" FROM "ir_ui_menu" WHERE ("ir_ui_menu"."active" IS TRUE AND NOT EXISTS (SELECT 1 FROM ir_attachment WHERE res_model = 'ir.ui.menu' AND res_field = 'web_icon_data' AND res_id = "ir_ui_menu"."id")) ORDER BY "ir_ui_menu"."sequence" , "ir_ui_menu"."id"
ir.ui.menu(62, 68, 3, 10, 43, 59, 4, 28, 44, 65, 6, 7, 29, 41, 45, 61, 66, 5, 18, 30, 31, 48, 49, 60, 69, 70, 9, 11, 12, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 32, 33, 34, 36, 37, 38, 39, 40, 42, 46, 47, 52, 54, 56, 57, 58, 63, 71, 73, 74, 76, 78, 79, 80, 81, 50, 64, 51, 72, 75, 77, 35, 14, 13, 53, 2, 55, 67, 8)
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#252525This update fixes an issue where recurring plans weren't appearing in quotations generated using the DIN5008 template. The change adds a simple styling rule to ensure recurring plans are consistently displayed in all reports, regardless of the template used. This improves the accuracy of subscription reporting for Swiss customers.
Original PR description
When generating a quotation for a recurring plan, if the quotation uses the DIN5008 template, the recurring plan is not shown in the report. Steps to reproduce: ------------------- * Make sure…
When generating a quotation for a recurring plan, if the quotation uses the DIN5008 template, the recurring plan is not shown in the report. Steps to reproduce: ------------------- * Make sure l10n_din5008 is installed * Create a Swiss company * Go to the subscription app and create an order with a recurring plan * Print the quotation > Observation: The recurring plan is not shown in the report. Why the fix: ------------ We add a new scss rule to make sure the recurring plan is always shown in the report. https://github.com/odoo/enterprise/blob/fb2eb6cfdc4527e102dd22321975ab3f0d24b88b/sale_subscription/views/subscription_templates.xml#L7-L23 Before: <img width="790" height="677" alt="image" src="https://github.com/user-attachments/assets/342753fa-9655-41ac-a958-f94f6ae2b6c7" /> After: <img width="808" height="756" alt="image" src="https://github.com/user-attachments/assets/4ed726c5-0702-48ee-8578-8b0d2c0f4e55" /> opw-5960219 Forward-Port-Of: odoo/odoo#261727
This update optimizes how the Point of Sale system calculates prices when dealing with large product lists. By streamlining the process, the system now responds faster, particularly when managing a significant number of products and pricing rules. This improves the overall user experience and system efficiency.
Original PR description
The getPrice function in product_template_accounting.js was a performance bottleneck when using large pricelists. This commit introduces the following optimizations: 1. Pre-index pricelist rules by product_id and product_tmpl_id at load time in ProductPricelist. 2. Replace the sort() operation with a single-pass scan to find the best matching rule (highest min_quantity that satisfies the current quantity). 3. Apply sequential rule precedence (Variant → Template → General), stopping as soon as a valid rule is found. 4. Move rule mappings from uiState to direct properties in ProductPricelist to avoid useless reactivity. 5. Centralize rule selection logic in ProductPricelist for better responsibility separation. task-id: 5965826 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244268
This update fixes a potential issue where the website incorrectly displayed unavailable unit of measure (UOM) information for products. This change ensures that users receive accurate UOM feedback, preventing confusion and potential errors when placing orders. It’s a minor improvement to the website’s sales functionality.
Original PR description
In some case, the requested uom might not be available (anymore) depending on the product latest changes. Followup on 4ac31e3545f009d0f96462f6a9098d5163ad521b --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265231
This update resolves an issue where the 'is typing' indicator incorrectly appeared in muted conversations. By setting the 'is typing' status to false for muted channels, we ensure a cleaner and more accurate experience for users. This improves the overall usability of the chat feature.
Original PR description
Before this PR, the "is typing" indicator could be shown on a muted conversation. This PR disables this feature for muted conversations by forcing the isTyping field to false when muted. Ideally, we should not even send the is typing notification, but that is not possible since we broadcast them to the entire channel. task-6154090
This update significantly speeds up the process of finding BOMs for product records, resolving a performance bottleneck. By optimizing how BOMs are identified, the system now responds much faster, especially when dealing with large product catalogs. This change improves overall system responsiveness and efficiency.
Original PR description
Before this commit, finding a bom for a recordset of `products` involved looping over all the boms and it will loop over all the `product_variant_ids` of `bom.product_tmpl_id` if the bom's…
Before this commit, finding a bom for a recordset of `products` involved looping over all the boms and it will loop over all the `product_variant_ids` of `bom.product_tmpl_id` if the bom's `product_id` is NULL. This approach might loop over variants which we are not trying to find a bom for. In additon to that, due to the fact that multiple boms might have the same `product_tmpl_id`, this approach might consider the same variants in the inner loop redundantly even though we matched the variant with a bom in a previous itration.
Worst case, this might result in a time complexity of $O(N * M)$ where N is the number of boms and M is the number of variants.
To improve the performance, I only considered the variants given in the paramater `products` and in addition to that, I created a new dictionary mapping a `product_tmpl_id` to its bom if the bom doesn't have a variant set. By doing this, I can loop over the `products` given and if it doesn't have a bom set then it will be set to the one its template had taken from the previos loop.
In a method call with the following constraints
- **2** products the method was finding a bom for
- The 2 products had the same template and the template contained **550** active variants
- The boms were only related to the template rather than the variants themselves.
| Input Size | Before | After |
| :--- | :--- | :--- |
| 100 | 0.78s | 0.03s |
| 1000 | 8.53s | 0.11s |
| 10000 | 80.99s | 0.73s |
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#247465This update corrects a bug where certain quality control test types were incorrectly visible during manufacturing operations. The change ensures that these test types are hidden by default, aligning with the intended functionality. This prevents users from accidentally selecting inappropriate test types, improving data accuracy.
Original PR description
### Issue: The `Print Label`, `Register Production`, `Register By-products`and `Register Consumed Materials` are all available in the test types at control point creation. ### Expected behavior:…
### Issue:
The `Print Label`, `Register Production`, `Register By-products`and `Register Consumed Materials` are all available in the test types at control point creation.
### Expected behavior:
These test types are only meant for manufacturing operations and are supposed to be hidden by the field domain:
https://github.com/odoo/enterprise/blob/f56aa85b4ad32c5d9ad5593df1366d72e88da0e4/mrp_workorder/models/quality.py#L102-L104 https://github.com/odoo/enterprise/blob/00d6cccd75c402378698a6fd11ee2692f2361c7f/mrp_workorder/models/quality.py#L20-L24
### Cause of the issue:
Since saas-18.1: 5ef007a2116e528b796ebe80fb291ba5f1a94c8f domains are optimised into equivalents SQL clause with better sql performances. This optimization results in the following match for boolean fields:
`('field', '=', True)` -> `('field', 'in', OrderedSet([True]))`
`('field', '=', False)` -> `('field', ' not in', OrderedSet([True]))`
Because of these:
https://github.com/odoo/odoo/blob/82b16e8feb3d60a9a3855e3adb3164ae5a6c041d/odoo/orm/domains.py#L1058-L1079 https://github.com/odoo/odoo/blob/82b16e8feb3d60a9a3855e3adb3164ae5a6c041d/odoo/orm/domains.py#L1215-L1236
Now the issue is that the specific `search_method` of the `allow_registration` field is then called with this optimized domain: https://github.com/odoo/odoo/blob/82b16e8feb3d60a9a3855e3adb3164ae5a6c041d/odoo/orm/domains.py#L860-L866 https://github.com/odoo/enterprise/blob/00d6cccd75c402378698a6fd11ee2692f2361c7f/mrp_workorder/models/quality.py#L20-L24
And since `value` is defined as a non empty ordered set in both cases it the search method returns a True leaf as search domain.
opw-5915197
Forward-Port-Of: odoo/enterprise#117068This update resolves a technical issue that prevented invoices with Early Payment Discounts (EPD) and 0% tax from passing schematron validation, a requirement for Peppol compliance. The fix ensures correct VAT breakdown generation, addressing a previous error where duplicate tax categories were created and a hardcoded tax code was used, now guaranteeing accurate invoice generation.
Original PR description
Before this commit, creating an invoice with an Early Payment Discount (EPD) as a payment term could cause the schematron validation of the generated invoice to fail when an invoice line had a 0% tax. The issue was caused by generating two TaxSubtotal nodes for the same TaxCategory (0%, exemption code 'E'): - one for the 0% VAT - one for the EPD discount applied to the total amount However, Peppol requires a single VAT breakdown (TaxSubtotal) per VAT category (in this case: E) Additionally, when VAT was set to 0%, the allowance charge TaxSubtotal incorrectly used 'S' as a hardcoded tax category code. This commit fixes both issues. task-5900496 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264302 Forward-Port-Of: odoo/odoo#254199
This update resolves an issue where PDFs with multiple XML attachments (using the /Kids structure) weren't being correctly processed, leading to empty bills. The change expands the PDF extractor to recognize both common PDF attachment formats, ensuring all XML attachments are now extracted and included.
Original PR description
Steps to reproduce: - From the accounting dashboard, upload a PDF containing intermediate /Kids nodes representing separate xml attachments Issue: No xml will be extracted, as result the bill will be empty. However, in the chatter pdf preview, the js pdf toolkit correctly show the xml attachemnts. Analysis: The PDF spec defines two ways to organize embedded files under /EmbeddedFiles in the document's name dictionary: - /Names: a flat array of pairs located directly under /EmbeddedFiles - /Kids: an array of child nodes, each of which carries its own /Names array. The extractor currently only handled the /Names case, not detecting embedded attachments in case of PDF using a /Kids tree. This change add lookup for both structures. opw-5929274 Forward-Port-Of: odoo/odoo#252523
This update corrects a visual issue where the project sharing notebook was using dark styles, causing a conflict with the standard light mode appearance. The team removed a specific style file to ensure consistent and correct display for all users.
Original PR description
The project sharing notebook previously used dark-themed styles, which conflicted with the light mode .Removing the notebook.dark.scss file from the imported files in the manifest. task-4922564 Forward-Port-Of: odoo/enterprise#99161
This update corrects a previous issue where product manufacturing quantities were incorrectly linked to planned amounts. Now, the system uses the actual quantity produced, providing more accurate inventory and costing data. This ensures better reporting and decision-making related to product availability and production efficiency.
Original PR description
* Before: the manufactured quantity on product use the planned quantity * After: Use actual produced quantity 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#265114 Forward-Port-Of: odoo/odoo#261438
This update resolves an issue where Odoo incorrectly processed only the first business document within an XML file containing multiple invoices. The fix ensures that the system now accurately imports and processes all valid business documents from a single XML file, aligning with Italian tax regulations. This improves the reliability of importing IT invoices.
Original PR description
### Issue before this commit: When importing an XML file containing multiple business documents (multiple bodies with a single header), the system correctly split the file into separate attachments…
### Issue before this commit: When importing an XML file containing multiple business documents (multiple bodies with a single header), the system correctly split the file into separate attachments but failed to process any document beyond the first one. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it 2. Go to Vendor -> Bills 3. Try to upload a xml with multiple bodies and one header 4. See only the first bill is correctly imported ### Cause of the issue: The splitting logic renamed subsequent attachments with numeric suffixes but then this function incorrectly checked the name of the document. https://github.com/odoo/odoo/blob/29805eec2b70144edf9441cffe7e69e39fd4ba0e/addons/l10n_it_edi/models/account_move.py#L297-L305 We can not rely only on the name of the document but we need to check also its content. Refer to the rules for the name of the attachments: https://www.fatturapa.gov.it/export/documenti/Specifiche-tecniche-relative-al-Sistema-di-Interscambio-versione-1.8.4.pdf In summary what we need in the document (page 9): > The unique progressive of the file is represented by an alphanumeric string up to 5 characters long and with allowed values. [az], [AZ], [0-9]. The unique progressive of the file has the sole purpose of differentiating the name of the files transmitted to the Interchange System by the same entity; it does not necessarily have to follow a strict progressive nature and may also present different numbering styles. ### Reason to introduce the fix: This fix ensures that the function not only checks the name but also the content to be sure that the xml or p7m file contains a valid structure to be registered. Ticket [link](https://www.odoo.com/odoo/project.task/6072258) opw-6072258 Forward-Port-Of: odoo/odoo#265079 Forward-Port-Of: odoo/odoo#259887
This update allows users to re-submit invoices that have been previously rejected by the tax authorities (SPV). Previously, rejected invoices were deleted and recreated, losing valuable tracking information. Now, rejected invoices are preserved as part of the history, improving traceability and simplifying the process for users.
Original PR description
Allow users to re-send invoices that were rejected by the SPV. Previously, EDI documents were deleted and recreated on every interaction, losing history in the process. This commit updates existing EDI documents in place instead, preserving failed documents as history for traceability. task-[5976612](https://www.odoo.com/odoo/project/967/tasks/5976612) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254882
This update fixes inconsistencies in how barcode settings are applied to Manufacturing Orders. Previously, mandatory lot/serial scans weren't reliably enforced, allowing users to bypass validation. Now, the system correctly utilizes MRP operation type configurations, ensuring accurate barcode tracking during production.
Original PR description
Before this commit, the "Allow full order validation" were partially ignored in the Barcode app when used for Manufacturing Orders, and the "Mandatory scan" settings didn't work very well. For…
Before this commit, the "Allow full order validation" were partially ignored in the Barcode app when used for Manufacturing Orders, and the "Mandatory scan" settings didn't work very well. For example, setting the scan of lot/serial as mandatory didn't prevent the user to set automatically a SN on consummed component by generating a lot/serial on the produced product or by clicking on "Produce All" button. This commit adds some conditions to avoid to update barcode lines in case they should depending of the config. This commit also fixes a related issue where the MRP operation type's config wasn't used at all when a MO is created directly from the Barcode app. As the config is get from the MO's picking type and no MO exists when a new one is created from the Barcode app, there is no MO's config returned in the data send by the server. To fix that, the config is now updated clientside when the data are fetched after a save. [Task-5420762](https://www.odoo.com/odoo/project/966/tasks/4655907/project.task/5420762) [opw-5223507](https://www.odoo.com/odoo/project/49/tasks/5223507) Forward-Port-Of: odoo/enterprise#113318
This update resolves an issue where UBL invoices would fail to import due to extra spaces in the 'EndpointID' field. The change automatically removes these spaces, ensuring invoices are correctly processed. This prevents import failures and improves the reliability of our UBL billing integration.
Original PR description
**PROBLEM** When importing a ubl that, for some reason, have trailing space on the text of the EndpointID node, we refuse it. This PR strips the trailing spaces on the import. **STEP TO REPRODUCE** 1. Import a ubl as a bill, with a trailing space in the EndpointID of the other party. 2. Notice the import fail, with the error: The Peppol endpoint (50238597645 ) is not valid. It should contain only letters and digit. opw-6227395 Forward-Port-Of: odoo/odoo#265266
This update fixes a bug that caused duplicate vendor creation during EDI import of Swiss VAT documents. The change ensures correct matching of VAT formats, preventing the system from incorrectly creating new partners when importing Peppol files with Swiss VAT numbers. This improves data accuracy and streamlines import processes.
Original PR description
### Issue: When importing EDI documents such as Peppol files, Swiss VAT numbers are often provided in a flat format (e.g., CHE530781296TVA), while existing Odoo partners usually store them in the…
### Issue: When importing EDI documents such as Peppol files, Swiss VAT numbers are often provided in a flat format (e.g., CHE530781296TVA), while existing Odoo partners usually store them in the official formatted version (e.g., CHE-530.781.296 TVA) This mismatch prevents proper partner matching and may create duplicate partners during import ### Cause: `_retrieve_partner` lacks Swiss-specific VAT normalization logic in `_import_retrieve_customer_from_vat()` As a result, the matching process fails to: - match formatted and unformatted Swiss VAT numbers - properly handle language suffixes such as `TVA`, `MWST`, or `IVA` If `base_vat` is installed, and the imported XML VAT is `CHE530781296TVA`, a new partner will be created with the structure format `CHE-530.781.296 TVA` As the match won't be made new partner will be created at each import ### Steps to reproduce: - Install `account` - Create a Vendor (Name: Test CH Vendor, Country: Switzerland, Tax ID: CHE-530.781.296 TVA) - Import the bill [CH_bill_to_import.xml](https://github.com/user-attachments/files/27202997/CH_bill_to_import.xml) from the ticket Before the fix, the existing partner is not matched and a duplicate partner is created opw-6072239 Forward-Port-Of: odoo/odoo#262011
This update resolves an error that occurred when automatically checking out employees with no defined check-out date, specifically when using the hr_attendance and hr_work_entry_attendance modules. The fix corrects a timezone calculation issue that was creating duplicate overtime entries, leading to a system error. This ensures accurate automatic check-out functionality.
Original PR description
__ ## Short functional explanation of the error While investigating for bug reported on ticket 6036064, I found this other bug. It only occurs when hr_attendance and hr_work_entry_attendance are both…
__ ## Short functional explanation of the error While investigating for bug reported on ticket 6036064, I found this other bug. It only occurs when hr_attendance and hr_work_entry_attendance are both installed. When setting an attendance for an employee that has a check-in date but no check-out date, and running the scheduled action `Automatically check-out employees`, an `expected singleton` error occurs. ## Reproduction Steps 1. Install hr_work_entry_attendance. 2. Create an Employee. In the Payroll tab, set a start date for the contract. In the Settings tab, make sure their timezone is set to Brussels, and set the Overtime Ruleset field to Default Ruleset. 3. In Settings, check the Automatic Check-out box. 4. Go to Attendances. Create an attendance for the employee you just created. Set a Check-in date to 8 am on April 17th, for example, and leave the check-out field empty. 5. Open Scheduled Actions. Search the action Automatically check-out employees and click Run Manually. ### Expected behavior The attendance check-out should be set at the end of April 17th. ### Unexpected behavior An error occurs: `Expected singleton: hr.attendance.overtime.line(39, 40)` ## Origin of the issue When the attendance goes over several days, we set the check-out date to: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L618 This is a Naive date. However, it will later be considered as a UTC date. Because the employee's timezone is Brussels, this time will be transformed to 2 am next day when we retrieve attendance intervals. This will result in the creation of overtime entries for both days, causing the Expected Singleton error. https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L687 https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L667-L672 In our case, `self.check_in` = April 17th at 06:00:00 and `self.check_out` = April 17th at 23:59:59. Converted, we will obtain April 17th at 08:00:00 and April 18th at 1:59:59. Because of that, at the return: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L706-L709 We will return a dict containing 2 intervals: one for 17th April and one for 18th April. We will then create overtime entries with such attendances: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L333 leading to the creation of 2 different overtimes for the same attendance. So, when we retrieve the overtime for that attendance: https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/hr_work_entry_attendance/models/hr_version.py#L185, We get the 2. Thus when trying to access their status with: https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/hr_work_entry_attendance/models/hr_version.py#L191 An Expected Singleton Occurs. __ opw-6036064 Forward-Port-Of: odoo/odoo#262257
This update resolves an error that occurred when automatically checking out employees with no defined check-out date, specifically when using the hr_attendance and hr_work_entry_attendance modules. The issue stemmed from incorrect timezone handling, leading to the creation of duplicate overtime entries. This fix ensures accurate automatic check-out calculations based on employee timezone settings.
Original PR description
__ ## Short functional explanation of the error While investigating for bug reported on ticket 6036064, I found this other bug. It only occurs when hr_attendance and hr_work_entry_attendance are both…
__ ## Short functional explanation of the error While investigating for bug reported on ticket 6036064, I found this other bug. It only occurs when hr_attendance and hr_work_entry_attendance are both installed. When setting an attendance for an employee that has a check-in date but no check-out date, and running the scheduled action `Automatically check-out employees`, an `expected singleton` error occurs. ## Reproduction Steps 1. Install hr_work_entry_attendance. 2. Create an Employee. In the Payroll tab, set a start date for the contract. In the Settings tab, make sure their timezone is set to Brussels, and set the Overtime Ruleset field to Default Ruleset. 3. In Settings, check the Automatic Check-out box. 4. Go to Attendances. Create an attendance for the employee you just created. Set a Check-in date to 8 am on April 17th, for example, and leave the check-out field empty. 5. Open Scheduled Actions. Search the action Automatically check-out employees and click Run Manually. ### Expected behavior The attendance check-out should be set at the end of April 17th. ### Unexpected behavior An error occurs: `Expected singleton: hr.attendance.overtime.line(39, 40)` ## Origin of the issue When the attendance goes over several days, we set the check-out date to: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L618 This is a Naive date. However, it will later be considered as a UTC date. Because the employee's timezone is Brussels, this time will be transformed to 2 am next day when we retrieve attendance intervals. This will result in the creation of overtime entries for both days, causing the Expected Singleton error. https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L687 https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L667-L672 In our case, `self.check_in` = April 17th at 06:02:00 and `self.check_out` = April 17th at 23:59:59. Converted, we will obtain April 17th at 08:02:00 and April 18th at 1:59:59. Because of that, at the return: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L706 We will return a dict containing 2 intervals: one for 17th April and one for 18th April. We will then create overtime entries with such attendances: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L333 leading to the creation of 2 different overtimes for the same attendance. So, when we retrieve the overtime for that attendance: https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/hr_work_entry_attendance/models/hr_version.py#L185, We get the 2. Thus when trying to access their status with: https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/hr_work_entry_attendance/models/hr_version.py#L191 An Expected Singleton Occurs. __ opw-6036064 Forward-Port-Of: odoo/enterprise#115828
This update optimizes a key stock query that previously performed very slowly due to complex string comparisons. By replacing these comparisons with a more efficient method of checking location ancestry, the query now runs significantly faster, especially when dealing with large lists of locations. This improves overall system responsiveness.
Original PR description
### Description of the issue/feature this PR addresses: Some stock queries determine whether a location belongs to the subtree of a set of locations by checking the parent_path prefix against…
### Description of the issue/feature this PR addresses:
Some stock queries determine whether a location belongs to the subtree of a set of locations by checking the parent_path prefix against candidate parent locations. This is done using a correlated EXISTS subquery with a LIKE parent.parent_path || '%' condition.
When the list of candidate locations becomes large (for example tens or hundreds of thousands of ids), this approach causes extremely poor performance because the database must repeatedly compare hierarchical path strings for every candidate row.
This PR improves the performance of this ancestry check by replacing the string prefix comparison with a direct check on the ancestor ids contained in parent_path.
### Current behavior before PR:
The query determines whether a location belongs to the subtree of one of the provided locations using:
location.parent_path LIKE parent.parent_path || '%'
For each row, PostgreSQL must evaluate a correlated subquery against all candidate parent locations. Because this relies on string prefix comparisons on parent_path, when the location list is large, this results in extremely slow queries.
### Desired behavior after PR is merged:
Instead of performing string prefix comparisons, the query extracts the ancestor ids directly from parent_path.
The path is:
1. Trimmed to remove leading and trailing /
2. Split into an array of ancestor ids
3. Expanded using unnest
4. Checked for intersection with the provided location ids
This converts the ancestry check from repeated string comparisons into a simple integer membership check.
### Benchmarks
Comparing performance of old subquery:
```
SELECT stock_location_inner.id
FROM stock_location AS stock_location_inner
WHERE EXISTS (
SELECT 1
FROM stock_location parent
WHERE parent.id IN (long list)
AND stock_location_inner.parent_path LIKE parent.parent_path || '%%'
);
```
to new one:
```
SELECT stock_location_inner.id
FROM stock_location AS stock_location_inner
WHERE EXISTS (
SELECT 1
FROM unnest(
string_to_array(trim(both '/' FROM stock_location_inner.parent_path), '/')::int[]
) AS path_id(id)
WHERE path_id.id IN (long list)
);
```
Depending on the number of elements in 'long list'
| # of elements | Before | After |
| --- |---|---|
| 130,000 | 21min | 0.8sec |
| 10,000 | 95sec | 0.5sec |
| 1,000 | 10.5sec | 0.5sec |
In practice, on the reference ticket this causes the "Validate" button on a stock picking to go from timing out to taking 8 seconds.
### Reference
opw-5932436
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#254245This update resolves an issue where contact display names were not correctly reflecting the associated company when the company's country was set to Brazil. The fix ensures that child contacts linked to Brazilian companies maintain their correct display name association, improving data accuracy for Brazilian users.
Original PR description
### Steps to reproduce: - Install Brazilian localization and 'Contacts' app - Create a contact linked to a company - Change company's country to 'Brazil' - Reload the page and check the contact display name > Contact name no longer shows the associated company name ### Cause of Issue: Upon changing the country on the company's contact form, `_compute_is_company()` method is called for this `partner` and all of its children. https://github.com/odoo/odoo/blob/795fc4706ad9d6fa7389996800e642ebbaaf395d/addons/l10n_latam_base/models/res_partner.py#L37-L40 Since all the `partners` (either companies or individuals) that have 'Brazil' as their country have `l10n_latam_identification_type_id.is_vat` by default, the child contact is switched to a company due to the condition above. ### Fix: Ensure the LATAM-specific `is_company` logic only applies to independent partners (root contacts), not to child contacts created from/linked to a company. opw-6213562
This update fixes an issue where multiple attachments to invoices (like timesheets) sometimes used the same filename, leading to confusion. The change ensures that each additional report has a unique filename, preventing attachment conflicts and improving email reliability. This ensures consistent and accurate attachments for users.
Original PR description
Problem: When adding additional dynamic reports to the “Invoice: Send by Email” template, reports without a configured `print_report_name` incorrectly use the invoice filename. This is an issue because multiple attachments can have the same exact filename. Example from related ticket: the user attached timesheets to their template and both the invoice PDF and timesheet attachment used the same filename. Expected: The additional report should use its own fallback filename (ex: `timesheets_INV_XXX.pdf`) or its configured `print_report_name`. Actual: The additional report uses the invoice filename instead. To fix this, reports without `print_report_name` now fallback to: `<report name>_<invoice name>.pdf` as done in v18.0 Related Ticket: 6207518 and 6175376 Forward-Port-Of: odoo/odoo#264841
This update corrects a bug where portal users could inadvertently delete documents they shouldn't have, potentially leading to data loss during automated cleanup. The fix ensures portal users can only delete documents they own, aligning with the intended functionality. This change improves data integrity and reduces the risk of unintended data deletion.
Original PR description
Reproduce: with rpc call as portal user, you can archive documents you have access to. This is not desired as this may lead to records being deleted when the cron collects the trash, but we only wanted to support portal users deleting only records they own. What we did when calling toggle_active should be done for all calls to `write` with `active`. It also removes the need for `_raise_if_unauthorized_archive` and `_unlink_except_unauthorized`. Task-6205627 Forward-Port-Of: odoo/enterprise#117647 Forward-Port-Of: odoo/enterprise#116886
This update fixes a problem where customers placing 'Pick Up In Store' orders didn't receive confirmation emails. The issue stemmed from how the system handled order details, specifically relating to partner subscriptions. The fix ensures that customers receive the expected email notifications when confirming their orders with this delivery method.
Original PR description
Customers placing an order without logging in and with the "Pick up in store" delivery method are not notified when the delivery is confirmed 1. Install eCommerce and Sales 2. Go to Settings >…
Customers placing an order without logging in and with the "Pick up in store" delivery method are not notified when the delivery is confirmed 1. Install eCommerce and Sales 2. Go to Settings > Website > Delivery and enable "Click & Collect" 3. Go to Settings > Inventory > Shipping and enable "Email Confirmation" 4. Go to Website > Configuration > Payment Providers and Install Demo 5. Go to Website > Configuration > Delivery Methods and open "Pick up in store", set YourCompany as warehouse and publish it 6. Go to Sales > Products, open product "Office Lamp", click on "Update Quantity" in the status bar and add 5 units 7. Log out 8. Go to the shop, add product "Office Lamp" to the cart and checkout 9. Fill in the address form and continue checkout 10. Select "Pick up in store" as delivery method and select a location 11. Confirm the order and pay with Demo 12. As user Mitchell Admin, go to Sales, remove the default filter and open the newly created sale order 13. Open the related delivery with the smart button and validate it 14. No delivery order confirmation was sent to the customer (check emails) Issue: Confirming an order with a "Pick up in store" delivery method replaces the `partner_shipping_id` of the sale order with an archived partner https://github.com/odoo/odoo/blob/d73e5662a0af7c549008661f743ba5d51f765339/addons/delivery/models/sale_order.py#L178-L192 which updates the `partner_id` of the related `stock.picking` with the archived partner https://github.com/odoo/odoo/blob/d73e5662a0af7c549008661f743ba5d51f765339/addons/sale_stock/models/sale_order.py#L130-L132 This will unsubscribe the old `partner_id` on the `stock.picking` and try to subscribe the archived partner https://github.com/odoo/odoo/blob/d73e5662a0af7c549008661f743ba5d51f765339/addons/stock/models/stock_picking.py#L1120-L1125 Because the partner we want to subscribe is archived, he will be filtered out and the subscribe action will have no effect, preventing him from receiving the delivery confirmation https://github.com/odoo/odoo/blob/d73e5662a0af7c549008661f743ba5d51f765339/addons/mail/models/mail_thread.py#L4367-L4369 Solution: Subscribe the parent of the archived partner when we write a `partner_id` on pickings with "in_store" `delivery_type`. This ensures the unarchived partner is subscribed to the picking allowing him to receive the mail confirmation. opw-6095396 Forward-Port-Of: odoo/odoo#265392 Forward-Port-Of: odoo/odoo#263005
This update fixes a performance issue in the partner update process. Specifically, it ensures that VAT checks and related updates only happen when a partner's parent ID is actually changed. This prevents unnecessary processing and potential errors, especially when updating partners through the API.
Original PR description
When updating a partner's parent_id, ensure the VAT check and move line updates are only triggered if the parent_id actually changes. This prevents unnecessary validations and side effects when writing the same parent_id value. This fix improves performance and avoids spurious errors when updating partners via the API. task-[6214466](https://www.odoo.com/odoo/project.task/6214466) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264175