Daily updates from Odoo
Monday, September 1, 2025
39 changes · saas-18.4
Resolved issues and error corrections
India EDI, e-waybill, and IRN retry actions now leave a log entry on the related document. This helps businesses see which user retried a submission, which is important because too many GST requests can temporarily block access for 24 hours.
Original PR description
Manual fw-port of https://github.com/odoo/odoo/pull/223957, https://github.com/odoo/odoo/pull/223886, https://github.com/odoo/odoo/pull/207184 *=edi,ewaybill,ewaybill_irn Following the implementation of [Black list request by GST](odoo/iap-apps#1039) the users are blocked for 24 hours on generating too many request. When processing through EDI there is no log when clicked on the retry button, Which is more essentially needed now to know by which user the EDI was retried and we logged the same on the move --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224169
This fix avoids checking empty quote PDF documents for encryption, preventing unnecessary errors when those documents are processed. It helps keep sales quote document handling reliable when an uploaded or configured PDF has no content.
Original PR description
If the document is empty we don't need to check for encryption. Otherwise we risk getting an error. ``` Traceback (most recent call last): File "/home/odoo/src/odoo/18.0/odoo/tools/convert.py", line…
If the document is empty we don't need to check for encryption. Otherwise we risk getting an error.
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/tools/convert.py", line 544, in _tag_root
f(rec)
File "/home/odoo/src/odoo/18.0/odoo/tools/convert.py", line 444, in _tag_record
record = model._load_records([data], self.mode == 'update')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5500, in _load_records
data['record']._load_records_write(data['values'])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5418, in _load_records_write
self.write(values)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 4827, in write
real_recs._validate_fields(vals, inverse_fields)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 1631, in _validate_fields
check(self)
File "/home/odoo/src/odoo/18.0/addons/sale_pdf_quote_builder/models/product_document.py", line 46, in _check_attached_on_and_datas_compatibility
utils._ensure_document_not_encrypted(base64.b64decode(doc.datas))
File "/home/odoo/src/odoo/18.0/addons/sale_pdf_quote_builder/utils.py", line 12, in _ensure_document_not_encrypted
if pdf.PdfFileReader(io.BytesIO(document), strict=False).isEncrypted:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/18.0/odoo/tools/pdf/__init__.py", line 91, in __init__
super().__init__(stream, strict)
File "/home/odoo/.local/lib/python3.12/site-packages/PyPDF2/_reader.py", line 317, in __init__
self.read(stream)
File "/home/odoo/.local/lib/python3.12/site-packages/PyPDF2/_reader.py", line 1408, in read
self._basic_validation(stream)
File "/home/odoo/.local/lib/python3.12/site-packages/PyPDF2/_reader.py", line 1449, in _basic_validation
raise EmptyFileError("Cannot read an empty file")
PyPDF2.errors.EmptyFileError: Cannot read an empty file
```
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#224674Hungarian e-invoicing now correctly reports credit notes as modifications when the original invoice had any payment before reversal. This prevents incorrect STORNO submissions to NAV and helps keep tax reporting accurate.
Original PR description
Before this PR: - Previously, a credit note was marked as STORNO if the base invoice's residual amount was zero, regardless of whether any payments had been made. This led to incorrect STORNO reports being sent to NAV in cases where the invoice had been partially or fully paid before reversal. After this PR: - If any payment was made, the credit note is marked as MODIFY instead of STORNO. Example: - Case 1: No payments before reversal Invoice: 1000 Credit Note 1: -100 Credit Note 2: -900 => Credit Note 1 should be sent as a Modification, Credit Note 2 as STORNO. - Case 2: Payments before reversal Invoice: 1000 Payment: -100 Credit Note: -900 => The Credit Note should be sent as a Modification. task-4818762 Forward-Port-Of: odoo/odoo#224861 Forward-Port-Of: odoo/odoo#211831
This fix prevents order tracking numbers from appearing in every Point of Sale setup, limiting them to restaurant or preparation-display flows where they are useful. It also keeps clear prefixes for kiosk and self-order receipts, helping staff distinguish order sources and avoiding confusion.
Original PR description
- Fix issue where `tracking_number` was displayed for all config. We want to display this number only for `pos_restaurant` configurations. We also want to display it for POS config which have a preparation display configured (see enterprise linked PR). - Ensure Kiosk & Self orders correctly contains a prefix (S or K) inside their `tracking_number` to avoid regression. task-id: 4922308 enterprise PR: https://github.com/odoo/enterprise/pull/91833 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224492 Forward-Port-Of: odoo/odoo#222094
Unsupported IoT devices are now checked repeatedly while they remain connected, instead of requiring users to unplug and reconnect them. This makes device setup and recovery smoother when a device becomes supported after initial detection.
Original PR description
Before this commit, in order for an unsupported device to become supported, it would need to be disconnected so that it was removed from the detected devices, and then reconnected at which point the supported method will be checked again. After this commit, the supported method is run on every iteration of the interface for any existing unsupported devices. This way if they can become supported without disconnecting them entirely. task-5055685 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixes an issue where product capacity lines could seem to disappear immediately after saving a new storage category, even though they returned after reloading. This keeps the saved information visible and consistent for users, and includes a CRM test correction so the fix can be safely validated.
Original PR description
_Note: The main fix of this PR (the orm one) raised an error in CRM, a test was working thanks to some cache pollution (cf description of crm commit). The below text only shows the description of the…
_Note: The main fix of this PR (the orm one) raised an error in CRM, a test was working thanks to some cache pollution (cf description of crm commit). The below text only shows the description of the orm commit._ The use of a computed inverse o2m field does not correctly work when creating the record of the main model. To reproduce: (Need stock) 1. In Settings, enable "Storage Locations" 2. Create a new Storage Category - Make sure to have one Capacity by Product Error: on save, the Capacity by Product disappears. Yet, if the user reloads the page, the capacity will be back. First, few details about the Storage Category model. We are dealing with the field `product_capacity_ids`, a computed inverse o2m field: https://github.com/odoo/odoo/blob/e5e3a3f7bf3770fe2bba11b501870d4fb7ef2e51/addons/stock/models/stock_storage_category.py#L15 Its content is a subset of the `capacity_ids` field: https://github.com/odoo/odoo/blob/e5e3a3f7bf3770fe2bba11b501870d4fb7ef2e51/addons/stock/models/stock_storage_category.py#L14 So, its compute simply get a subset of `capacity_ids` and its inverse will write some values on `capacity_ids`: https://github.com/odoo/odoo/blob/e5e3a3f7bf3770fe2bba11b501870d4fb7ef2e51/addons/stock/models/stock_storage_category.py#L39-L41 Now, back to the issue. When we `web_save` the category, at some point in the create process, it leads here https://github.com/odoo/odoo/blob/bdb24afbf85f4d58722db493f725dd95c5780ff7/odoo/orm/models.py#L4389-L4408 Where we want to resolve all the pending inverse. To do so, we first update the cache (L4401) and we then call the inverse methods (L4408). In the above case, it means that we first update the value of `product_capacity_ids` in the cache. The value we are passing is a `Command.CREATE` value. In that case, when converting the value for the cache, we actually create a `NewId` record: https://github.com/odoo/odoo/blob/ae55f5b494005a1e7566c819592f7dd64623c3fd/odoo/orm/fields_relational.py#L513-L516 When running the inverse, we write this record on `capacity_ids` (cf the code quoted above). This will lead to the actual creation of the capacity record. But... Here is where the problems begin: we have updated the cache with a `NewId` value and define `capacity_ids` with an existing record. However, we don't update anything in the cache. As a result, at the end of `web_save`, we do a `web_read`. It will lead here: https://github.com/odoo/odoo/blob/bdb24afbf85f4d58722db493f725dd95c5780ff7/odoo/orm/models.py#L3427 Where we convert the value of `product_capacity_ids`. Since available in the cache, we will use the `NewId` value and convert it, i.e.: we will return the `.ids` of the recordset: https://github.com/odoo/odoo/blob/ae55f5b494005a1e7566c819592f7dd64623c3fd/odoo/orm/fields_relational.py#L569-L570 Which means... The actual IDs, excluding the `NewId` one. This explains why the line suddenly disappears on save. Then, reloading the page will trigger the compute based on `capacity_ids`. This field is correctly defined, so will do the compute -> the line will appear. Since we update the cache to compute the inverse, we should then clear that cache to ensure proper consistency with what happened during the inverse. OPW-4915087 Forward-Port-Of: odoo/odoo#222763
Fixed an issue where users could not open the full list of events on non-working days in the calendar. The “show more” link now responds correctly, preventing accidental creation popovers and making busy off-day schedules easier to review.
Original PR description
**PROBLEM** If you add a lot of daily event on a off-day, the "show more" link to show all events is not clickable. Clicking bring the event creation popover. **REPRO STEPS** 1. install calendar and hr. 2. on a off day (grey background) in the week or day view, add events until the "show more" link shows up. 3. click on it, and notice the event creation popover pops up instead of the event list popover. **CAUSE** FullCalendar css class fc-non-business have a zindex of 1, a div with this class is "above" the link. **FIX** Removing a line that removed the css class fc-daygrid-more-link to the "more-link" element. Modifying css to keep the style consistent even with this new class. opw-4844719 Forward-Port-Of: odoo/odoo#221007
This fix adjusts an internal Discuss test so its expected performance measurements account for routing cache behavior. It helps keep automated validation stable and reduces false failures during release checks, without changing user-facing features.
Original PR description
runbot-231489 Forward-Port-Of: odoo/odoo#224940
This fixes self-order cart lines so they save every selected product attribute value, matching the regular Point of Sale behavior. It helps ensure orders with configurable products are recorded consistently and accurately for staff and downstream processing.
Original PR description
Before this commit, the ptav of attributes configured to create variants was not saved in the order lines. This was inconsistent with the behavior in Point of Sale, where all ptav values are saved in the order lines. opw-5020130 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224699 Forward-Port-Of: odoo/odoo#224080
The Saudi localization no longer shows the "THIS IS NOT A LEGAL DOCUMENT" warning on vendor bills, vendor credit/debit notes, purchase receipts, or sales receipts. This keeps the warning focused on customer invoice documents where it is relevant when the QR code is missing, reducing confusion for users and suppliers.
Original PR description
Before this commit: - The message "THIS IS NOT A LEGAL DOCUMENT" was also displayed on Vendor Debit Notes, Vendor Credit Notes, Purchase Receipt and Sales Receipt. - The warning should only appear on Customer Invoices, Credit Notes, and Debit Notes when the QR code is missing After this commit: - The warning message is no longer displayed on all Vendor Debit Notes, Vendor Credit Notes, Purchase Receipt and Sales Receipt. Task-5044870 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224473
This fix prevents invoices from crashing during Veri*Factu sending when a Spanish company does not have a VAT number set. Users will see a more reliable invoice sending flow instead of an unexpected system error.
Original PR description
The system will crash when user tries to send the invoice.
**Steps to produce:-**
- Install the **Accounting** module and switch to the **ES company** (with demo data).
- Remove the **VAT** from the ES company and save the changes.
- Go to **Accounting** and create any invoice.
- Click on **Send**.
- In the send wizard, ensure that **Veri\*Factu** is checked at the top, then click the **Send** button.
**Error:-**
`KeyError: 'NIF'`
**Cause:-**
- When the company VAT is not set,` _l10n_es_edi_verifactu_get_values()` does not provide an 'NIF' key.
- Accessing 'NIF' directly in such cases raises a `KeyError` when sending an invoice.
**Solution:-**
- In this PR, `.get('NIF')` instead of direct key access to safely handle missing values.
**sentry-6829500308**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prIoT Boxes now allow more time and retry when downloading certificates from Odoo.com. This reduces setup or renewal failures caused by slow networks, high service load, or certificate provider delays.
Original PR description
Certificate download on the IoT Box from Odoo.com can take more time than the currently set 10 seconds. This can be due to the network, to odoo.com's load, or to let's encrypt. We aligned the timeout to let's encrypt library's timeout, and added a retry, as the iot box should always get a certificate. Task: 4948448
Fixed a purchase order display issue where later pages showed only the vendor’s product name instead of both the vendor name and the product’s internal name. This makes multi-page purchase orders consistent and helps users identify products more clearly.
Original PR description
#### Issue: Only the vendor name of a product is displayed on a purchase order on all pages except the first one. #### Step to reproduce: - make sure "Variant grid entries" is disabled in the…
#### Issue: Only the vendor name of a product is displayed on a purchase order on all pages except the first one. #### Step to reproduce: - make sure "Variant grid entries" is disabled in the settings. If you can't disable it, you can disable the view `purchase.order.form.inherit.matrix` to trigger the bug. - Create a product - Go to the purchase sheet - Add a vendor - Add the field "Vendor Product Name" and "Vendor Product Code" and fill them - Create a purchase order - Add your product - Add your product a second time (on a second line) - Confirm the PO - Activate debug mode - Go to the view and add a limit to have only 1 POL per page - Return to your PO - Go to the second page #### Current behavior: - Only the vendor name is displayed #### Expected behavior: - The vendor name should appear at the top, while the db name should be displayed under as in the first page. #### Cause of the issue: On the first page, POLs data are fetch through a `web_read` on the PO, while on other pages data are fetch through `web_read` on the POLs of the page. While fetching POL data with a `web_read` the client ask for several informations including: `name` and `product_id.display_name`. If both return the same, the client show only one, else it shows the `display_name` on top and the `name` below. - `name` return the vendor name - `product_id` is fetch with the context `partner_id` which transform the `display_name` from the db_name to the Vendor name Therefore it fetches twice the vendor name and don't have the name from the db. #### Solution: - remove the `partner_id` from the context. #### Consequence: - When adding a product to the PO, the name of the product displayed in the dropdown list will be the name from the db instead of the name of the vendor. PO confirmed that consequence is OK as long as it's still possible to search for product using vendor code, which is still possible. opw-4737337 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223250
This fixes supplier bills created from foreign-currency purchase orders when tax is already included in the line price. The bill line balances now deduct the included tax before currency conversion, preventing incorrect accounting amounts.
Original PR description
**Steps to reproduce** - Setup a foreign currency [CUR] with rate - Create a purchase order - Add [CUR] as currency - Add an order line with price included tax - Confirm and receive - Create Bill - Check generated lines values **Issue** Balance of the move lines will be off, as if it was computed using the wrong conversion rate **Investigation** It occurs because when preparing the move values, the system add the balance calculated from the product price. This does not work for price included taxes, as the balance of the invoice line need to have the tax amount deducted opw-4954649 Forward-Port-Of: odoo/odoo#224705 Forward-Port-Of: odoo/odoo#221952
Public holidays spanning multiple days now appear as blocked for every day in calendar views when flexible working schedules are used. This gives employees and managers an accurate view of unavailable days and avoids confusion when planning time off.
Original PR description
**Issue**: Multi-day public holidays only display as single days in calendar views when using flexible working schedules. A 3-day holiday appears as only 1 day blocked, though time-off requests are still correctly prevented for all 3 days. **Cause:** In `_get_unusual_days()`, the implementation for flexible schedules only captures the start date of each leave interval https://github.com/odoo/odoo/blob/132938929d46c8248a9e3a7e2972174ae38eacfa/addons/resource/models/resource_calendar.py#L683-L685 **Steps to reproduce:** 1. Configure a flexible working schedule for an employee or company 2. Go to Time Off > Public Holidays 3. Create a 3 day public holiday 4. Check Time Off calendar view Only 1 day appears blocked instead of all 3 days opw-4997757 Forward-Port-Of: odoo/odoo#224845 Forward-Port-Of: odoo/odoo#224668
Fixes an issue where users could not continue typing after choosing a font size in the HTML editor, even though their text selection still appeared active. The editor now correctly returns focus after the font size dropdown is used, reducing confusion and avoiding interrupted editing workflows.
Original PR description
### Steps to reproduce: - Go to the To-Do app and type something in the editor. - Select the typed text. - Click on the Font Size Input and choose a value from the dropdown (e.g.,80). - Try typing…
### Steps to reproduce: - Go to the To-Do app and type something in the editor. - Select the typed text. - Click on the Font Size Input and choose a value from the dropdown (e.g.,80). - Try typing again in the editable area. - Selection is still visible, the focus is no longer in the editable area. ### Description of the issue/feature this PR addresses: - `focusEditable()` skipped restoring focus if the selection was inside the editor, even when the editor itself wasn’t focused. - When the font size input (inside an iframe) is focused, editable loses focus. - Selecting a value from the dropdown blurs the iframe input, but focus is not returned to the editable area. - As a result, the selection is still visible but the user cannot type. ### Desired behavior after PR is merged: - Does nothing if the editor or its descendants have focus. - Focuses the editor if needed. - Restores selection only when it's outside the editor. - When the iframe input is blurred, focus is returned to the editable area. task-4932364 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222360 Forward-Port-Of: odoo/odoo#218774
Product kits now respect quantity-on-hand filters based on their actual computed availability from component stock. This prevents kits from appearing in product lists when they do not truly match the selected stock range, improving inventory search accuracy.
Original PR description
#### Issue: - When filtering products on "Quantity on hand", kits may appear when they shouldn't #### Step to reproduce: - with MRP - create a new product - create a BoM for this product as kit - make sure you have product of the BoM on hand - go to product - add filters: - "Quantity on hand" > 1 - "Quantity on hand" < *less_than_you_have* #### Current behavior: - kit appears #### Expected behavior: - kit doesn't show #### Cause: - kit were filtered has having both 0 quantity (as unstored product) and their quantity (computed from stock of BoM products). Therefore they were compliant with both filter. #### Solution: - remove kits from products compliant with the filter if they don't comply with the filter with their computed quantity opw-4967763 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224681 Forward-Port-Of: odoo/odoo#221224
This fixes an internal test configuration so the Discuss test suite uses the correct test model from its own module. It helps keep automated checks reliable and avoids accidental reliance on another test module.
Original PR description
PR #223438 uses `mail.test.rating` model (which belongs to `test_mail_full` module) as the test model in `test_discuss_full` module. This PR changes the test model to the correct one. runbot-231321 Forward-Port-Of: odoo/odoo#224630
Razorpay payments now check whether the saved access token has expired when a customer pays. If needed, the system automatically generates a new token, reducing failed payments caused by expired authorization.
Original PR description
Version: - saas-18.2 Issue: - The refresh token method was removed in PR https://github.com/odoo/odoo/pull/188774. Because of this, the Razorpay access token expiry was no longer being checked. Fix: - When a user makes a payment, the system now checks if the Razorpay access token has expired. If it has, a new token will be generated automatically. opw-4953953 Forward-Port-Of: odoo/odoo#224233
A website test was adjusted so it no longer fails when the system performs fewer database queries than the maximum allowed. This improves reliability of automated checks without changing customer-facing website behavior.
Original PR description
This test fails in community only as the query count is lower than the maximum allowed. runbot error 226784
This fix prevents Discuss calls from showing an error when someone leaves or crashes at the same time another participant joins. It makes call handling more reliable in a rare timing situation, reducing disruptive errors for users.
Original PR description
Before this commit, since https://github.com/odoo/odoo/pull/200981, a race condition could occur where the call is over when the the rtc session matching a track event is obtained. This could occur if you crash or leave at the moment another user arrives. You could get a track event from the SFU, wait for the rtc session record from Odoo, leave te call, finally get the rtc session from odoo. This would lead to a traceback as this handler expected that the call was still ongoing. Forward-Port-Of: odoo/odoo#224658 Forward-Port-Of: odoo/odoo#224588
The Chilean electronic invoicing demo setup now includes the required certificate serial number. This lets users test sending invoices to the Chilean tax authority without hitting an installation-related error, while leaving real production certificates unchanged.
Original PR description
**Issue** When installing l10n_cl_ed, the `subject_serial_number` field is left empty. This causes an error when attempting to send an invoice to the SII. **Steps to Reproduce** 1. Install Accounting and l10n_cl_edi 2. Create and confirm an invoice 3. Click "Send Now to SII" 4. Error: Invalid Operation **Root Cause** The `subject_serial_number` is not set during installation, and this field is required for electronic document generation. **Fix** Restore the behavior from version 17.0 by setting a default `subject_serial_number` if it's missing and the certificate is available. This ensures the demo data is functional and allows users to test the SII integration out-of-the-box. Opw-4961801 Forward-Port-Of: odoo/enterprise#90636
When an accounting return entry is duplicated, the new copy is no longer incorrectly tied to the original return. This prevents duplicate entries from affecting or appearing as part of the same tax/reporting return, improving data accuracy.
Original PR description
Duplicating some return's move also kept the duplicate linked to the return. This is wrong. task-5046319 Forward-Port-Of: odoo/enterprise#93323
Subscription orders that include one-time products now correctly create deliveries and generate invoices. This ensures one-off items added to subscriptions are fulfilled and billed as expected, avoiding missed shipments and manual follow-up.
Original PR description
**Version:** - saas-18.4 **Steps to reproduce:** - Install the sale_subscription_stock module. - Create a one-time product and save it. - Create a subscription order, add the one-time product to the order line, and confirm the order. **Before this commit:** - When a one-time product was added to a subscription order, no delivery was created. **After this commit:** - A delivery is properly created, and an invoice is automatically generated when the order includes a one-time product. **Solution:** Add a condition to check for one-time products in the order lines and create a delivery if found. **Impact:** - A delivery is now created when a one-time product is in the sale order. Also, an invoice is automatically generated for it. task-4938898
Receipts for point-of-sale setups using preparation displays or preparation printers now show the correct tracking number. This helps staff and customers match orders to receipts more reliably and avoids confusion during order preparation.
Original PR description
- Ensure the `tracking_number` is dipslayed on receipts for config which use a preparation dipslay or a preparation printer. task-id: 4922308 community PR: https://github.com/odoo/odoo/pull/222094 Forward-Port-Of: odoo/enterprise#93318 Forward-Port-Of: odoo/enterprise#91833
The Kenya OSCU e-invoicing checks now ignore cancelled or draft credit notes when validating invoice reversals. This prevents incorrect blocking errors when businesses issue a new credit note after an earlier one was cancelled or reset.
Original PR description
[FIX] l10_ke_edi_edi_oscu: ensure quantity and monetary values checks are performed on reconciled reversals only. Fixes a behavior where the checks performed on the credit notes related to their quantities and monetary values include non reconciled credit notes. Steps to reproduce: 1 - activate `l10n_ke` on some company. 2 - Create an invoice. 3 - Create a partial or full credit note ( this one will be reconciled with the invoice automatically ) 4 - cancel the credit note or reset it to draft. 5 - create another credit note where the quantities and/or monetary values exceed that of the invoice if summed up with the cancelled credit note. Following the steps will result in an error message saying that the monetary value or quantities on the credit notes exceed that of the invoice. The correct behavior is to simply not count any credit note that isn't explicitly reconciled with the invoice. opw-4779976 Forward-Port-Of: odoo/enterprise#92319
Users who belong to a secondary company can now create multi-company tax returns without hitting an access error. This ensures tax reporting works smoothly for companies operating across multiple entities.
Original PR description
When a tax return is created with multi companies and a user member of one of the secondary companies, he would get an access error due to missing sudo() task-5039551
This fixes a regression that caused IoT communication sessions to be opened earlier than needed after a recent internal refactor. Restoring lazy session handling helps keep point-of-sale and self-order IoT interactions efficient without changing user workflows.
Original PR description
* : pos_iot, pos_self_order_iot The refactor introducing the `iot_http` service dropped by mistake the previous lazy_session optimisation [1], this commit reintroduce it. [1]: https://github.com/odoo/enterprise/commit/313bde6feb756c050a20a3459e1e8282d11ffa66
Egypt payroll calculations now handle terminated employees who do not have annual leave allocations. Instead of failing during payslip computation, the system treats their remaining annual leave as zero so payroll can continue reliably.
Original PR description
When computing payslips for terminated employees (archived) with no annual leave allocations, the method `_l10n_eg_get_annual_remaining_leaves` raised a traceback due to missing allocation data. This fix ensures the method safely handles employees without allocations by returning 0 remaining leaves instead of crashing. This guarantees payslip computation works correctly for employees with no leave allocations. task-5026406
A payroll accounting test was updated to use a fixed car acquisition date so it will continue to pass in 2026 and beyond. This is an internal quality fix that helps keep automated validation reliable without changing business features or user workflows.
Original PR description
Some tests will fail in 2026. This adds a freeze time to prevent this failing. Task: 5034173 Forward-Port-Of: odoo/enterprise#92983
Italian POS orders now send only positive payment amounts to the fiscal printer, avoiding unsupported negative change payments. This helps ensure receipts are processed correctly and sales are reported to the authorities as required.
Original PR description
Before this commit, specifying the payment method used to give back the change in a POS order would lead to the fiscal printer receiving a negative payment as input, which is not supported, thus leading to the order not being treated by the fiscal printer (so not reported to the government). Only the payments with is_change=true where filtered out. I am now adding a filter to only keep the positive payments in the receipt, as the fiscal printer is computing the change itself. opw-4931671 Forward-Port-Of: odoo/enterprise#91794
Gantt card popovers now show standard labels such as Name, Start, and Stop in the user's selected language instead of always appearing in English. This improves the experience for non-English users viewing custom Gantt menus created with Studio.
Original PR description
Steps to Reproduce: - Change the language to something other than English. - Create a new menu in the Appointment module using Studio. - Link that menu with the existing model (Resource Time of…
Steps to Reproduce: - Change the language to something other than English. - Create a new menu in the Appointment module using Studio. - Link that menu with the existing model (Resource Time of Detail). - Save the changes and add the Gantt view - Save the changes and close Studio. - View this new menu in the Gantt view Issue: - When clicking onto the kanban popover card for any record, the labels will remain as "Name" , "Start" , and "Stop" in English, and it will not translate. Reason: - [1] changed the rendering of default kanban card templates from XML to JS. This changed the default template to be static. Fix: - Add a call to the translation core tool "_t" on the three labels upon their generation in _getKanbanViewParams(). This ensures that the arch template that is generated is translated correctly into the user's set language. [1] : b2e31239041e6b7850888a3ae070c3f8a40ea5ee [opw-4861899](https://www.odoo.com/odoo/my-tasks/4861899) Forward-Port-Of: odoo/enterprise#90605
Fixes an issue in Mexican sales where a sale order could show zero invoiced quantity after a related electronic invoice was cancelled and replaced. The system now refreshes the invoiced quantity when the electronic invoice status changes, keeping sales records accurate for users.
Original PR description
How to reproduce the issue: In l10n_mx: 1. Create a sale order. 2. Create an invoice from the SO, with yesterday’s date, and send it to the CFDI. 3. Lock the period at yesterday’s date. 4. Request the invoice cancellation with the “01” method. This creates a new invoice — confirm it. 5. Create a credit note for the original invoice. 6. Retry sending the cancel request to the CFDI; the CFDI state is now cancelled for the original invoice. On the original SO, the quantity invoiced is 0 despite the CFDI state of the original invoice being cancelled. This commit forces a recompute of the quantity invoiced when the CFDI state changes. Since _compute_qty_invoiced uses _get_invoice_lines, which filters out invoices in sent state, only lines from invoices in cancelled state will be taken into account. opw-4910139 Forward-Port-Of: odoo/enterprise#93480 Forward-Port-Of: odoo/enterprise#91924
Rental orders paid through Point of Sale now keep the delivered quantity accurate when items are returned. This prevents returned rental products from being counted as delivered again, improving order accuracy and avoiding confusion in rental operations.
Original PR description
**Issue:** Before this commit, the qty_delivered was wrong when using the Return button when a Picking was made in PoS **Cause:** The `_compute_qty_delivered` method in `pos_sale` adds `pos_line.qty`…
**Issue:** Before this commit, the qty_delivered was wrong when using the Return button when a Picking was made in PoS **Cause:** The `_compute_qty_delivered` method in `pos_sale` adds `pos_line.qty` to the related `sale_line` each time it runs When there is no PoS order, the method add 0 to the line, so the expected behavior work But when you have a PoS Picking, a quantity was added to `qty_delivered` each time the `rental.order.wizard` is used The issue also occured earlier when the `flush_all()` is called in `_process_order()` **Fix:** There is already a `_compute_qty_delivered` method in `pos_sale_stock_renting` that override the `qty_delivered` But it's restricted by `_are_rental_pickings_enabled()` That's not necessary because we don't use any `stock.picking` in the `_compute_qty_delivered` function, only `stock.move` so we removed that verification To make the code working, we also need to extend the _get_outgoing_incoming_moves() results Because there were also block by a `_are_rental_pickings_enabled()` condition even if there is only moves here We need all the moves to calculate `qty_delivered` properly **Steps to reproduce:** - Create a New Product "Rental PoS" that Can be Rented - Create and confirm a New Rental Order, with any customer and your product - Open a PoS Session - Click on Quotation/Order - Choose the last Order and Settle the order - Click on Yes (to confirm import to PoS) - Click on Payment, select Cash and Pay - Go in the Backend, and to your RO - Click Return and Validate - Before the fix, the Delivered should be 2.0 opw-4877019 Forward-Port-Of: odoo/enterprise#93358 Forward-Port-Of: odoo/enterprise#90510
Payroll users can now change salary rule colors reliably from both Salary Rules and Salary Structures. This ensures visual styling is applied correctly in the rule form and pop-up, making salary rule setup clearer and less confusing.
Original PR description
Steps to Produce: - open payroll app - Go to Salary Rules or go to Salary Structures and open any salary rule. - try to change color of any rule. issue: - The color does not change in the Salary Rules. - Additionally, styles do not apply in the salary rule pop-up accessed through Salary Structures. Fix: - Instead of changing the color with formrenderer, a custom widget was created to apply styles directly to the field. opw-4716810 task-4774448 Forward-Port-Of: odoo/enterprise#83514
The Timesheets leaderboard now correctly shows the tip of the day when the leaderboard feature is enabled. This restores expected guidance in the leaderboard dialog and helps users see daily tips while tracking timesheet performance.
Original PR description
Steps to Reproduce: -- - Open timesheet module - Go to setting and enabled leaderboard feature - Open leaderboard dialog and there you will be able to see tip of the day is not visible Issue: -- The issue was even after enabling the leaderboard feature the tip of the day was not visible inside the leaderboard dialog which is unexpected behaviour. Cause: -- The root cause was inside the getLeaderboardData method call where we were not fetching tip from the orm call and the issue is caused by this PR https://github.com/odoo/enterprise/pull/78541 Fix: -- To resolve this, I have include tip while making orm call also store that tip value inside leaderboardData task-4981767 Forward-Port-Of: odoo/enterprise#92811
This fix prevents the French VAT report wizard from crashing when required report dates or report details are not yet available during setup or testing. It makes the VAT amount calculation safer by using default values until enough information is present, improving reliability without changing normal user workflows.
Original PR description
steps to reproduce the issue : 1- install l10n_fr_hr_payroll_account without demo data 2- and run this test .test_computed_fields_without_dependencies Added a dependencies using…
steps to reproduce the issue :
1- install l10n_fr_hr_payroll_account without demo data
2- and run this test .test_computed_fields_without_dependencies
Added a dependencies using @api.depends('report_id', 'date_from', 'date_to') on the _compute_vat_amount method to ensure automatic re-evaluation when any of these fields change.
In test_computed_fields_without_dependencies, the record is created using model.new(), which means required fields like report_id, date_from, and date_to may not be set yet. This caused a crash due to ensure_one() on an empty report_id.
Even though these fields are required, they are not automatically filled when using model.new() (unlike saved records).
Also introduced early exits by setting default values (vat_amount = 0.0, is_vat_due = False) and skipping computation when any of the required fields (report_id, date_from, date_to) or result VAT lines are missing because of ensure_one() in options.
These safeguards prevent errors in the test
build_error-115299
Forward-Port-Of: odoo/enterprise#87608The French VAT reporting flow now uses the correct account when creating a reimbursement entry. This helps keep reimbursement accounting accurate and reduces the risk of manual corrections.
Original PR description
This commit will change the account used for the reimbursement move. task-4932427 Forward-Port-Of: odoo/enterprise#91212
Fixed an issue where sorting a grouped Budget Report by description could trigger an error and interrupt users. This improves reliability when reviewing budget information in Accounting reports.
Original PR description
Currently an error occurs when we try to order a grouped list on `budget.report` model. Steps to replicate: - Install `account_budget` with demo data. - Go to `Accounting > Reporting > Budget Report`. - Go to list view and group by Budget. - Click on the Description (table header) to order the list. Error: `AttributeError: 'bool' object has no attribute 'split'` The error occurs due to line [1] in `web_read_group` calling `.split()` on `_order`, which is `False` because the model sets `_order = False` [2]. Solution: - Remove `_order = False` from the model definition. - Since the model is not stored in the database (`_auto = False`), removing `_order` will not cause issues in stable versions. [1]: https://github.com/odoo/odoo/blob/b14da3d3f4465e2bf0125de0484fe9cb1bc79aed/addons/web/models/models.py#L420 [2]: https://github.com/odoo/enterprise/blob/8cc8443dc11c176b55f7eb3efa07db5edb7e6b0c/account_budget/reports/budget_report.py#L11 sentry-6747467261