Thursday, June 11, 2026
11 changes · saas-18.3
Enhancements to existing features
This update introduces a new 'PINT' layer within the account_edi_ubl_cii module, streamlining the processing of UBL invoices. This layer aligns with European regulations (CEN_EN16931 and PINT-EU) for enhanced compliance and data exchange, particularly for PEPPOL transactions. It improves the handling of invoice data formats.
Original PR description
Add the layer PINT between UBL and BIS3. task: 5890887 Forward-Port-Of: odoo/odoo#260058
Resolved issues and error corrections
This update fixes an issue where invoices for French public entities in DROM regions (like Martinique) were incorrectly formatted when sent through Chorus Pro. The system now correctly includes the SIRET number, ensuring proper invoice routing and compliance. This prevents invoices from being rejected by Chorus Pro.
Original PR description
When invoicing a French public entity through Chorus Pro, the SIRET of the recipient was written in the UBL PartyIdentification only when the partner country was France (country_code == 'FR'). Partners located in a DROM (overseas department/region) have a real French SIRET too, but their ISO country code failed the check, so the SIRET was dropped and replaced by the VAT number. This cause the invoice to not be routed correctly in Chorus Pro. Steps to reproduce: - Setup a french company and connect it to Peppol - Create a customer for a public entity located in Martinique, with its SIRET, Peppol address 0009:11000201100044 (Chorus Pro SIRET) and BIS Billing 3.0 format. - Issue and send an invoice to this customer via Peppol. - Open the generated *_ubl_bis3.xml: AccountingCustomerParty PartyIdentification/ID holds the VAT instead of the SIRET, and Chorus Pro never receives the invoice. opw-6153868 Forward-Port-Of: odoo/odoo#269068 Forward-Port-Of: odoo/odoo#268519
This update fixes an issue where both units flagged as failed during quality control were incorrectly moved to the failure location. The fix ensures that the destination of moved goods is accurately determined based on remaining demand, preventing unintended placement of items in the failure location. This improves the reliability of the quality control process.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ------------------- 1. Install *quality_control* module. 2. Go to *Settings* and enable *Storage Locations*. 3. Open Quality module go to the Quality…
Version:
----------
- 18.0+
Steps to reproduce:
-------------------
1. Install *quality_control* module.
2. Go to *Settings* and enable *Storage Locations*.
3. Open Quality module go to the Quality control -> Quality points
4. Create a *Quality Point* with:
* *Product* set.
* *Control per* set to *Quantity*.
* *Operation* set to *Receipts*.
* *Failure Location* set to *WH/Stock/Shelf1*.
5. Create a *Receipt* with demand of *2 units* for the product used in QP.
6. Mark the quality check as *To Do*.
7. Update the *Done Quantity* to *1*.
8. Open the quality check and click *Fail*.
9. Update the *Done Quantity* back to *2* and save.
10. Open the quality check again, click *Pass*, and validate the receipt.
11. Open the *Detailed Operations* to inspect move lines.
Issue:
------
* Both units (failed and passed) are moved to the *failure location*.
Cause:
------
When a user fails a move line via the QC wizard, the flow is:
do_fail() → show_failure_message() → confirm_fail()
→ check._move_to_failure_location(failure_location_id, failed_qty)
Inside `_move_to_failure_location`, when `failed_qty == move_line.quantity`,
the condition:
https://github.com/odoo/enterprise/blob/a33f580455a54a81d89a848f7b493d9dcc9ba2b2/quality_control/models/quality.py#L458
e.g. 1 == 1
was True even when `move.product_uom_qty = 2` (demand still 2). It only
compared the done quantities, ignoring that unfulfilled demand remained.
As a result, `move.location_dest_id` was set to the failure location.
Later, when the user increases the quantity from 1 to 2 on the move form,
the flow is:
_set_quantity → process_increase → _set_quantity_done → _prepare_move_line_vals
In `_prepare_move_line_vals` :
'location_dest_id': self.location_dest_id.id,
https://github.com/odoo/odoo/blob/47bf284e1e9d8be0d4255418e0a3f67c74fa5114/addons/stock/models/stock_move.py#L1688
The new move line inherits `move.location_dest_id` directly, which at this
point is already the failure location.
When the user then calls `do_pass()` on the second unit, `do_pass()` only
writes `quality_state = 'pass'` and never touches `location_dest_id`. So
the second (passed) move line silently retains the failure location.
Solution:
---------
Add the guard `move.product_uom_qty <= move_line.quantity` to the condition
so the entire move's destination is only redirected when there is genuinely
no remaining unfulfilled demand:
When demand > done qty, the else-branch runs instead: it reduces the
original move's demand and creates a new separate move pointing to the
failure location, leaving the original move's `location_dest_id` pointing
to stock. Any subsequent move lines created on the original move therefore
correctly inherit the stock destination.
---
opw-6080871
Forward-Port-Of: odoo/enterprise#119917
Forward-Port-Of: odoo/enterprise#112859This update corrects a bug that incorrectly handled deductibility percentages on vendor bills, particularly when set to 99%. Previously, changes to deductibility percentages didn't properly update related tax journal entries. This fix ensures accurate synchronization of non-deductible amounts, improving financial reporting accuracy.
Original PR description
### Issue When setting the partial deductibility percentage to 99% on a vendor bill line, the system incorrectly treats it as 100% deductible and completely ignores the non-deductible part…
### Issue When setting the partial deductibility percentage to 99% on a vendor bill line, the system incorrectly treats it as 100% deductible and completely ignores the non-deductible part Additionally, changing the deductibility percentage on a line with taxes does not trigger an update of the non-deductible tax journal items, leaving the private part taxes unchanged ### Cause In the tax recomputation mechanism, `float_compare` was wrongly configured with `precision_rounding=2` instead of `precision_digits=2` when checking the `deductible_amount` field This rounding error caused 99.00 to be evaluated as equal to 100.00, skipping the creation of the non-deductible line Furthermore, `_sync_tax_lines` relies on `get_base_line_tracked_fields` to detect modifications that require a tax recalculation This tracked field list only included price, quantity, and discount. Modifying the deductibility percentage did not trigger any sync, preventing the non-deductible tax lines from adjusting ### Fix To fix the synchronization, `deductible_amount` is added to the tracked fields for invoices This straightforward approach is preferred here for simplicity However, a more restrictive condition may be needed for example only check it on lines with taxes ### Steps to reproduce - Install `account` - Create a Vendor Bill (Price: 1000$, Taxes: 15%, Professional %: 50) - Check the Journal Items tab to see the Private Part line at 500$ debit and Private Part (taxes) line at 75$ debit - Change the Professional % field on the invoice line to 75 Before the fix, the Private Part (taxes) line remains at 75$ debit - Change the Professional % field on the invoice line to 99 Before the fix, the private part lines completely disappear instead of adapting to 1% opw-6245909 Forward-Port-Of: odoo/odoo#267427
This update fixes an issue where overtime hours weren't accurately deducted when an employee's leave allocation was initially approved but then refused. The fix ensures overtime is consistently tracked, preventing discrepancies in hour calculations after a leave request is adjusted. This improves the accuracy of employee time tracking.
Original PR description
**Issue** Employees extra hours were not deducted if an allocation was approved after being refused first. **Steps to reproduce** - Enable "Display Extra Hours" in settings for easier debugging - Have a Time Off type T: - Requires allocation: Yes - Deduct Extra Hours: True - Have an employee with some extra hours (e.g. by creating attendances) - Create an allocation using the time off type T - Expected: extra hours smart button on employee's page is reduced by allocation's duration - Refuse the allocation - Mark it as ready to approve - Expected: extra hours for employee should be the same as before the leave was refused - Actual: the allocation has not reduced the employee's extra hours **Cause** The overtime was unlinked when the allocation was refused. **Fix** Make sure an overtime always exists unless in `refused` state. opw-5959319 Forward-Port-Of: odoo/odoo#254473
This update resolves an error that occurred when creating payment reports for Swiss companies. The issue was triggered when the required module, ‘l10n_ch_hr_payroll’, wasn’t installed. The fix ensures the system handles missing modules gracefully, preventing the report generation process from failing.
Original PR description
*=l10n_ch_hr_payroll,hr_payroll_account_iso20022 When clicking the create payment report button on a payslip for a Swiss company, a traceback occurs if the ``hr_payroll_account_iso20022`` module is…
*=l10n_ch_hr_payroll,hr_payroll_account_iso20022 When clicking the create payment report button on a payslip for a Swiss company, a traceback occurs if the ``hr_payroll_account_iso20022`` module is not installed. Steps to reproduce the error: - Install ``l10n_ch_hr_payroll`` module - Switch to CH Company - Create an Employee and running contract for it - Go to Payroll > Payslip > All payslips > Create a new payslip > Set the employee > Confirm > Create payment report Traceback: ```py ValueError: Wrong value for hr.payroll.payment.report.wizard.export_format: 'iso20022_ch' ``` https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_ch_hr_payroll/models/hr_payslip.py#L383 https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_ch_hr_payroll/models/hr_payslip_run.py#L13 Here, ``iso20022_ch`` is passed as ``export_format``, However, ``iso20022_ch`` is added to the selection field in the ``hr_payroll_account_iso20022`` module at [1]. When that module is not installed, the selection value does not exist, leading to the above error. [1]: https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/hr_payroll_account_iso20022/wizard/hr_payroll_payment_report_wizard.py#L11 sentry-7391832811 Forward-Port-Of: odoo/enterprise#119666 Forward-Port-Of: odoo/enterprise#113277
This update fixes an issue where adding a note to a combo orderline didn't correctly update the quantities of its child lines. The fix ensures that quantities are synchronized across all lines within a combo, regardless of whether a note was added. This improves order accuracy and prevents discrepancies between what's ordered and what's prepared.
Original PR description
**Steps to reproduce:** - Go to the restaurant - Select a table, click on a combo and order it - Add quantity to the ordered combo and add a note to it - Select the desired combo options in the popup - The combos' children lines' qty are not updated and are either too much or 1 **Why the fix:** When we add a note to an orderline that has qty that has not been sent to the kitchen, we split the line in 2 lines, one with everything that has been sent to the kitchen and one with everything that has not been sent and the note we just added. This implementation didn't account for the combos, so the combo_line_ids' qty were never updated and stayed as is in the original line, and were set as 1 in the new line. We now update the children lines' qty at the same time as the parent lines. opw-5164102 Forward-Port-Of: odoo/odoo#237968 Forward-Port-Of: odoo/odoo#232694
This update fixes an issue where the receipt quantity wasn't accurately reflecting changes to the purchase order quantity when using Multi-Step Routes. Specifically, modifying the POL quantity caused the receipt to incorrectly update, leading to discrepancies in inventory tracking. This ensures accurate stock levels are maintained during MTO purchase order processing.
Original PR description
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Inventory > Configuration > Warehouse Management > Routes - Unarchive MTO - Create a storable product P with MTO buy and a set…
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Inventory > Configuration > Warehouse Management > Routes - Unarchive MTO - Create a storable product P with MTO buy and a set vendor - Create and confirm a sale order for 1 unit of P - Confirm the assocaited PO and change the pol quantity from 1 to 10 > the associated receipt is updated from 1 to 10 - Change the pol quantity from 10 to 7 #### > The quantity on the receipt is updated from 10 to 16. ### Cause of the issue: Changing the quantity of the POL will adapt the picking related quantity via these lines: https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/purchase_stock/models/purchase_order_line.py#L115-L117 https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/purchase_stock/models/purchase_order_line.py#L342-L349 by creating new stock moves to be merged: https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/purchase_stock/models/purchase_order_line.py#L220-L251 Now, the issue is that this flows relies both on a negative `qty_to_attach` of `1 - 10 = -9` and a positive `qty_to_push` of `7 - 1 = 6`. However, the `qty_to_attach` is only used if is positive: https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/purchase_stock/models/purchase_order_line.py#L243-L251 The receipt is therefore updated by a `+6` move to push but not by the `-9` move to attach. Leading to a 10 -> 16 rather than 10 -> 7 result. opw-6218307 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269069 Forward-Port-Of: odoo/odoo#264994
This update resolves an issue where purchase order confirmations would fail when a delivery type didn't associate with a warehouse. The fix ensures that the system correctly identifies the final destination location even when a warehouse isn't specified, preventing a type error. This improves the reliability of purchase order processing.
Original PR description
Bug introduced in: https://github.com/odoo/odoo/commit/e2efdf75f67e631ed7622bb01c127120e639f6c5 Steps to reproduce: Clear the Warehouse field (set it to False) Create a purchase order Set "Deliver…
Bug introduced in: https://github.com/odoo/odoo/commit/e2efdf75f67e631ed7622bb01c127120e639f6c5
Steps to reproduce: Clear the Warehouse field (set it to False) Create a
purchase order Set "Deliver To" to the operation type with no warehouse
Add any product Confirm the PO → TypeError is raised
Steps to reproduce the bug:
- Have at least 2 warehouses
- Go to Inventory > Configuration > Operation Types > Receipts
- Clear the Warehouse field (set it to False)
- Create a purchase order:
- Set "Deliver To" to the operation type with no warehouse
- Add any product
- Try to confirm the PO
Problem:
A traceback is triggered:
``` return self.parent_path.startswith(other_location.parent_path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: startswith first arg must be str or a tuple of str, not bool
```
`_get_final_location_record` computes `wh_stock_loc` from
`picking_type_id.warehouse_id.lot_stock_id`. When `warehouse_id`
is False (a valid configuration, operation types can be detached from
any warehouse), `lot_stock_id` short-circuits to False
Solution:
guard the _child_of call with not wh_stock_loc. When the
picking type has no warehouse, wh_stock_loc is falsy and there is
nothing to compare against, so the method falls back to
default_location_dest_id (the only destination available).
opw-6253817
Forward-Port-Of: odoo/odoo#268317This update resolves an issue where negative amounts in Mexican VAT reports weren't consistently including the 'global_discount' field. This fix ensures accurate VAT reporting and compliance with Mexican tax regulations, preventing potential discrepancies and financial errors. The change impacts the l10n_mx_edi module.
This update resolves a requirement from Luxembourg auditors regarding the classification of partners in our SAFT reports. Specifically, it ensures that less than 30% of transactions with payable or receivable accounts have missing supplier or customer IDs. The changes add partners to the relevant lists and prioritize the correct ID based on transaction type, maintaining compatibility with older reports.
Original PR description
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on…
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on \Transaction\Line elements is determined by a partner's `customer_rank` and `supplier_rank`. This is a binary designation, one or the other. The Luxembourg FAIA report requires that less than 30% of \Transaction\Line elements with payable accounts (class 6) can not have \SupplierID. The same applies for \Transaction\Line elements with receivable accounts (class 7) and the \CustomerID element. TSB clarified that any partner on an receivable or payable line should be added to the Customer list or Supplier list respectively https://github.com/odoo/enterprise/pull/100749#issuecomment-3655127511. In addition, I verified that Luxembourg's analysis of four separate FAIA files (from ticket 5427296) aligns with this expectation. <img width="1322" height="690" alt="image" src="https://github.com/user-attachments/assets/1a82f99e-5b32-4dbb-96e1-1b25bab2629b" /> This commit adds partners to the \Supplier and \Customer lists if they have any payable or receivable lines, respectively. It also picks between the \CustomerID and \SupplierID based on a line's `account_type`. This logic is applied to `account_saft` and updates the other, country-specific SAFT reports where appropriate. It also retains the previous `customer_rank` and `supplier_rank` logic as a fallback for older XML reports and for accounts other than `asset_receivable` or `liability_payable`. opw-6118024 Forward-Port-Of: odoo/enterprise#119098 Forward-Port-Of: odoo/enterprise#118714