Tuesday, January 13, 2026
11 changes · saas-18.3
Resolved issues and error corrections
This update resolves an issue where Facturae EDI documents were failing validation due to incorrect issuer generation when certificates contained multiple RDNs of the same type. The fix ensures all RDNs are properly ordered, allowing the documents to pass validation checks with official Spanish tax authorities, improving compliance.
Original PR description
When a certificate contains multiple RDNs of the same type (for example several OU entries), the generated issuer is incorrect. This happens because the current implementation relies on a dictionary to sort the RDNs, causing duplicate keys to be overwritten. Steps to reproduce: - Create a certificate with multiple OU RDNs - Upload the certificate in Odoo - Generate the Facturae EDI document - Validate it using official tools: https://face.gob.es/es/facturas/validar-visualizar-facturas https://valide.redsara.es/valide/ejecutarValidarFirma/ejecutar.html The validation fails because the issuer is incorrect. This commit fixes the issue by sorting RDNs using a priority-based list, ensuring all RDNs are preserved and ordered correctly. opw-5408225 opw-5380996 opw-5253287 Forward-Port-Of: odoo/odoo#243098 Forward-Port-Of: odoo/odoo#241094
This update fixes an issue where discounts applied to repair quotations weren't correctly carried over to the linked sales order lines. The fix removes a faulty process that was resetting the discount calculation, ensuring discounts are accurately reflected in the final sales order. This improves the accuracy of pricing and reporting for repair services.
Original PR description
**Steps to reproduce:** * Install the **Repair** module with demo data. * From Setting -> enable 'Discounts' and 'Pricelists' * From the home screen, search for Pricelist and open it. * Open the…
**Steps to reproduce:** * Install the **Repair** module with demo data. * From Setting -> enable 'Discounts' and 'Pricelists' * From the home screen, search for Pricelist and open it. * Open the default USD pricelist and go to Configuration → `Show public price & discount to the customer` * Open the *Repair* app. * Create a **Repair Order with parts**. * Click **Create Quotation** button from the repair order. * In the quotation, order line and set a **discount**. * Return to the repair order using the **Repairs** smart button. * Confirm the repair order, then **Start repair** and **End repair** order. **Observed behavior:** * The discount added on the quotation line disappears from the linked sale order line. **Cause:** * The `discount` field on `sale.order.line` is computed by `_compute_discount`, which `depends` on `product_id`, `product_uom`, and `product_uom_qty`. When `product_uom_qty` is written during `action_repair_done`, the compute method is triggered and the `discount` is recalculated. https://github.com/odoo/odoo/blob/49169c4c4fec57d78cd82c4c9366de9d69540e6a/addons/repair/models/repair.py#L457 **Fix:** * Remove the for loop that calls `write()` on the sale order lines, as it is functionally incorrect and causes the discount to be reset. --- opw-5352567 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243075 Forward-Port-Of: odoo/odoo#238410
This update optimizes how Odoo handles web sockets, particularly when dealing with a large number of connected clients. By tweaking the delay when acquiring web socket cursors, the system now recovers more effectively from connection bottlenecks, preventing disconnections and improving overall performance. This ensures a smoother experience for users, even under heavy load.
Original PR description
Benchmarking with 4k connected clients, 1 message per second. | | Message dispatching | Cursor analysis | |-- |-- | -- | | Before|<img width="600" alt="image" src="https://github.com/user-attachments/assets/f02e7efc-4611-4356-8bef-386ff2b0a7da" />|<img width="600" alt="2_current_implementation__cursor_analysis" src="https://github.com/user-attachments/assets/04dce96e-74a6-4f1b-9918-a6c61913e7c4" />| |After|<img width="600" alt="image" src="https://github.com/user-attachments/assets/a9463484-7f69-4fcb-a248-5692893a8893" />|<img width="600" height="997" alt="8_tweak_delay_both_sleep__cursor_analysis" src="https://github.com/user-attachments/assets/34a2c233-5c36-4597-a55b-cfb89a41efcf" />| Forward-Port-Of: odoo/odoo#241745 Forward-Port-Of: odoo/odoo#241330
This update resolves an issue where the HTML editor would crash when attempting to remove formatting from a cell with a lingering color after text deletion. Now, users can reliably remove color formatting without encountering errors, improving the overall stability and usability of the editor. This was a critical fix impacting the ability to correctly format and edit content.
Original PR description
**Current behavior before PR:** Steps to reproduce: - Create a m x n table - Write some text in a cell, apply color on text - Delete text and keep empty colored element - Select cell - Trying to remove format throws infinite loop error in removeAllColor **Desired behavior after PR is merged:** Clicking on remove format button should remove color from empty colored element without causing traceback. task-5454993 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241829
This update resolves an issue where failed electronic payments in Point of Sale would block users from canceling the payment. A new 'Force cancel' button has been added, mirroring the 'Force done' button, to allow staff to unblock payments and proceed with cancellation when a payment terminal is temporarily unavailable.
Original PR description
Before this commit, if an electronic payment failed (e.g. due to the payment terminal/IoT box not being reachable) and the user subsequently tried to cancel the payment from the POS, they would reach a blocked state. The payment never cancels but it cannot be deleted. This commit adds a 'Force cancel' button, similar to the 'Force done' button already present, to allow the user to get unblocked in this situation. task-5485237 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243263
This update resolves an issue preventing accurate country-based filtering of payslips and payslip runs. By safely storing the country ID, the system now functions correctly, eliminating errors and ensuring reliable reporting. This improves data accuracy and usability.
Original PR description
Issue: The country_id related field on payslip and payslip run was not stored, causing domain filters and search on this field to fail and triggering client-side errors. Fix: Use search parameter to write function so field can be used safely in search domains and filters. Impact: Country-based filtering now works correctly without triggering module loader errors. Task: 5406904 Forward-Port-Of: odoo/enterprise#103318
This update resolves an issue where a reordering rule could incorrectly update a manufacturing order (MO) that was locked due to a quality check. Previously, the system would attempt to add new quantities to these locked MOs, causing an error. This fix ensures the reordering rule doesn't interfere with MOs that are in a 'locked' state after a quality check, improving manufacturing process stability. The change also incorporates updates related to the new stock reference system.
Original PR description
### Issue: In 18.0-18.2, for product with a Manufacturing BoM containing a Component, a WO and a Quality Point If a Reordering Rule is triggered, odoo try to add the newly ordered quantity to an…
### Issue: In 18.0-18.2, for product with a Manufacturing BoM containing a Component, a WO and a Quality Point If a Reordering Rule is triggered, odoo try to add the newly ordered quantity to an existing MO But if the MO is "locked" because a quality check has been performed, a Error is raised: ``` Odoo Warning You cannot update the quantity to do of an ongoing manufacturing order for which quality checks have been performed. ``` ### Steps to reproduce: - Create a product tracked by quantity - Add a BoM (1 component tracked by Quantity, 1 Operation with 1 Quality Point) - Create a Reordering Rule (Route: Manufacture, Trigger: Manual, Min/Max: 1) - Click on Order - Open the created MO and the Shop Floor (Remove the filters to see the WO) - Complete the Quality Point - Modify the Reordering Rule (Min/Max: 2) - Click on Order - the error should be raised ### Cause: The MO to update is retrieved here: https://github.com/odoo/odoo/blob/45184da06cf7b92a48e3e4e90bf8b285bdd9ad6a/addons/mrp/models/stock_rule.py#L53-L57 Using a domain defined in this function: https://github.com/odoo/odoo/blob/45184da06cf7b92a48e3e4e90bf8b285bdd9ad6a/addons/mrp/models/stock_rule.py#L130-L153 In 18.0-18.2, when validating a `quality check` from the Shop Floor while the WO is in `waiting` state, the MO remains in `confirmed` state This makes the domain match the current WO and MO, triggering `change_prod_qty` even though the MO is locked In 18.3–18.4, a similar issue can occur with multiple WOs when the first blocks the second and a `quality check` is performed on the latter The `blocked` state behaves like `waiting`, but the issue is avoided when using the Shop Floor because this commit ensures that clicking a card starts the timer and changes the state to `progress`: https://github.com/odoo/enterprise/pull/84425/commits/67c2127424ef3a1eb4794edd2c262b94ef186561 However, it could still theoretically be triggered under specific conditions In 19.0, the new stock.reference system (https://github.com/odoo/odoo/pull/212679) ensures the MO is detected as different, so a new one is always created opw-5012588 Forward-Port-Of: odoo/enterprise#101313
This update corrects a security vulnerability where public users could modify department settings within the Employees app. The fix restricts public user access to department configuration fields, ensuring data integrity and preventing unauthorized changes. This resolves a potential issue impacting data accuracy and system stability.
Original PR description
**Steps to reproduce:** - Install Employees app - Login as public user - Go to Employees menu - Press on any employee to open its form view - Press on the department field - Try to edit the department configuration **Issue:** Public users can edit all the fields on the department configuration, except the Department's manager. This is should not be the case. **Solution:** Remove write access on department for public users. Task: 5384463 Forward-Port-Of: odoo/odoo#239027
This update corrects a bug where currency rates were incorrectly applied to the 'cogs' line during invoice creation. Now, the cogs value accurately reflects the cost of goods without being influenced by currency fluctuations, ensuring accurate financial reporting. This resolves an issue impacting invoice calculations.
Original PR description
**Steps to reproduce:** - in settings enable "automatic accounting" and "anglo-saxon accounting" - make sure dollar is the main currency - activate euro as another currency - set a rate for today as…
**Steps to reproduce:**
- in settings enable "automatic accounting" and
"anglo-saxon accounting"
- make sure dollar is the main currency
- activate euro as another currency
- set a rate for today as 1$->10 euros
- set another rate for a week ago 1$->2euros
- create a storable product with standard price/automated
category and a cost of 10
- create a new invoice for 1 unit of your product
- do not set a date on the invoice
- set the currency as euro
- click on the calendar widget to choose the rate and select the
date of yesterday
(- the rate applied should now be 1$->2euros)
- confirm the invoice
**Current behavior:**
the cogs line (credit stock interim delivered and debit expenses)
have a value of 5
**Expected behavior:**
the cogs value should be 10. It shouldn't be impacted by the
currency rate.
**Cause of the issue:**
when the invoice is confirmed, because there is no date,
the date is set at today inside _post()
https://github.com/odoo/odoo/blob/626d06734991bcd3b94a6c9454317f311164e9dc/addons/account/models/account_move.py#L5090
This results in a call to write with invoice_date in the vals.
Inside the override of the write() method of AccountMove,
the call to super is inside a 'with self._sync_dynamic_lines' bloc.
https://github.com/odoo/odoo/blob/626d06734991bcd3b94a6c9454317f311164e9dc/addons/account/models/account_move.py#L3413-L3419
So the first part (up until the yield) of _sync_dynamic_lines is
executed before the call to super.
In _sync_dynamic_lines() the yield is inside a 'with _sync_invoice'
bloc.
https://github.com/odoo/odoo/blob/626d06734991bcd3b94a6c9454317f311164e9dc/addons/account/models/account_move.py#L3239-L3241
As a result, the first part of sync_invoice() (until the yield) is
executed before the call to super method write().
https://github.com/odoo/odoo/blob/626d06734991bcd3b94a6c9454317f311164e9dc/addons/account/models/account_move_line.py#L1513-L1515
And the second part is executed after the call to write() and
after the update of line_container['records'] inside
_sync_dynamic_lines().
Because the change of date, changes the currency_rate,
changed('currency_rate') will return True, and the balance will
be recomputed for each line.
https://github.com/odoo/odoo/blob/0dabb221225fba96c0e55779afadd9f12b369777/addons/account/models/account_move_line.py#L1524-L1530
This causes 2 problems:
1) for the non cogs line, the rate set manually by the user
is replaced by the rate of today
2) for the cogs line, a rate is applied where no currency
rate should be applied at all.
The problem 1) was fixed in this PR https://github.com/odoo/odoo/pull/239012
But this does not fix problem 2) as the fix consists in letting the
recomputation happen for the balance of the account move lines
and then re-recompute their balance in the manually set currency_rate.
Whereas for our cogs line we need no currency_rate based
recomputation at all.
**fix**
prevent balance recomputation based on currency_rate change
for cogs lines.
opw-5266804
Forward-Port-Of: odoo/odoo#240006This update corrects a bug in the purchase stock module that was causing incorrect journal entries when returning a product multiple times. The fix ensures that currency differences are handled properly during returns, preventing erroneous compensation account movements. This improves accounting accuracy and reduces the risk of financial discrepancies.
Original PR description
**Steps to reproduce:** - enable automatic accounting - set dollars as the main currency - activate euro and set a rate of 10 euro -> 1$ - create a storable product with category fifo/ automated -…
**Steps to reproduce:** - enable automatic accounting - set dollars as the main currency - activate euro and set a rate of 10 euro -> 1$ - create a storable product with category fifo/ automated - create and confirm a PO for 1 unit for 10 euros (no tax) - validate the receipt - return the product and validate return - return the return and validate - open journal items and search your product **Current behavior:** - there is 6 correct lines (those with credit or debit of 1$) - there is two incorrect extra lines one with credit 9$ and one with debit 9$ **Expected behavior:** those two extra lines should not be there **Cause of the issue:** those lines are compensation account move lines for the case where the price of the product returned is different than the price of the product initially received, in the cases of: - a return: compensate the difference. - the return of a return (our case): de-compensate the difference. (see PR https://github.com/odoo/odoo/pull/162697 and more specifically test test_fifo_return_twice_and_bill). But in this case, the compensation is wrongly triggered because the difference comes from the fact that the currency is not taken into account. https://github.com/odoo/odoo/blob/c89d109c460d51fc90b6b13d5f6bc114c7316e42/addons/purchase_stock/models/stock_move.py#L208 **Fix:** we use the original svl instead of the PO because it avoids currency problem. If we wanted to convert the currency of the PO, we would need to find the date that was used to convert the value at the creation of the first svl. And that date came from _get_currency_convert-date() https://github.com/odoo/odoo/blob/d3599e70973e27ed17e403cf498f76bd31e9c236/addons/purchase_stock/models/stock_move.py#L97 which can take the date of the last invoice (if product was invoiced before the move was validated). https://github.com/odoo/odoo/blob/57c1c510425dcd491c794a0262063db398348640/addons/purchase_stock/models/stock_move.py#L123-L125 We can not use this method because we're doing the return of a return and if the first return also has an invoice, the return value of the method could be the date of this invoice (which is not the date we're looking for). Furthermore there is no way to know if the date returned by _get_currency_convert_date() at the time of the creation of the first svl is the date of the time of the creation of the svl or the date of an invoice previously confirmed. opw-5179239 Forward-Port-Of: odoo/odoo#238904
This update corrects a bug where preparation timers for courses within a split order were incorrectly shared. Now, each preparation order has its own timer that fires independently when its corresponding course is completed, ensuring accurate timing for restaurant service. This enhances the overall order fulfillment process.
Original PR description
Before this commit: -- - When an order was split into courses, all preparation orders incorrectly shared the same timer, even if fired at different times. After this commit: -- - Each preparation order has its own preparation timer when its course is fired. task-5421616