Friday, June 12, 2026
11 changes · 18.0
New functionality added to Odoo
This update introduces a system to automatically refresh KYC (Know Your Customer) status updates. Previously, users had to manually refresh the status, which is now handled through a webhook from IAP. This streamlines the process and ensures accurate KYC information within the system.
Original PR description
Before this commit, user needed to manually refresh de kyc status, with this commit, the status will be changed when receiving the notification from IAP task-6271596
Resolved issues and error corrections
This update corrects a display issue in the combo configurator where extra prices weren't being converted to the correct currency, leading to inaccurate totals. The fix ensures that prices shown in the configurator match the calculated prices on the sale order line, regardless of the pricelist currency. This improves the accuracy of pricing and order totals for multi-currency sales.
Original PR description
Description of the issue/feature this PR addresses: In the combo configurator dialog, a combo item's extra_price and the price_extra of no_variant attributes are stored in the company/product…
Description of the issue/feature this PR addresses: In the combo configurator dialog, a combo item's extra_price and the price_extra of no_variant attributes are stored in the company/product currency but were sent to the front-end without conversion. When the order uses a pricelist in a different currency, the popup shows these extras at face value (e.g. an extra of USD 1700 appears as ARS 1700 instead of being converted). The sale order line itself already converts these extras, so the popup price and the actual line price didn't match. Current behavior before PR: _get_combo_item_data and _get_selected_ptavs_data return extra_price / price_extra raw, in the company currency. With a foreign-currency pricelist the combo configurator popup adds them 1-to-1 to the already-converted base price, displaying an incorrect total that doesn't match the resulting sale order line. Desired behavior after PR is merged: The controller converts extra_price and price_extra to the configurator's currency (via currency._convert()) before serializing them, so the popup shows the correct amounts in the pricelist currency and matches the price computed on the sale order line. A test (test_sale_combo_multicurrency.py) covers combo extra-price conversion with a foreign-currency pricelist. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a technical issue in the payroll calculation process for employees with contracts exceeding 35 years. The fix adjusts a key parameter to correctly account for Mexican labor law regulations regarding holiday accrual beyond the initial 35-year limit. This ensures accurate payslip generation for all employees.
Original PR description
**Steps to reproduce:** 1. Install l10n_mx_hr_payroll. 2. Create an employee with a contract date over 35 years ago (e.g., 1985). 3. Create a payslip for this employee. 4. Click on "Compute Sheet".…
**Steps to reproduce:**
1. Install l10n_mx_hr_payroll.
2. Create an employee with a contract date over 35 years ago (e.g., 1985).
3. Create a payslip for this employee.
4. Click on "Compute Sheet".
```Error: KeyError(36) while evaluating```
**Cause:**
The rule parameter [rule_parameter_holiday_table](https://github.com/odoo/enterprise/blob/c02c4571bb7db7197b07539ba390d4d20fdce9fe/l10n_mx_hr_payroll/data/hr_rule_parameters_data.xml#L722-L758) defines values
only up to 35 years. Seniority exceeding this range causes a KeyError.
**Solution:**
Extended the `rule_parameter_holiday_2024` table from 35 to 60 years,
following the Mexican Federal Labor Law (LFT) reform formula
(+2 days every 5-year milestone from year 6 onwards).
**NOTE:**(Alternative approach)
```python
@staticmethod
def _get_mx_holiday_days(years_worked):
if years_worked <= 0:
return 0
if years_worked <= 5:
return 12 + (years_worked - 1) * 2
five_year_periods = (years_worked - 6) // 5
return 22 + five_year_periods * 2
```
This approach removes the need for XML data maintenance and handles
all future seniority values mathematically without any cap issues.
opw-6090590This update corrects an issue where stock relocation incorrectly swapped the order of reservations for deliveries. After moving stock, reservations were reassigned in the wrong order, leading to incorrect quantity tracking. This fix ensures reservations are maintained in the original priority after internal stock movements.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Enable `Storage Locations` from Inventory settings - Create a tracked storable product with on-hand 8…
Version: ---------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Enable `Storage Locations` from Inventory settings - Create a tracked storable product with on-hand 8 units in `Shelf 1` - Create Delivery 1 for 5 units and click `Mark as To Do` - Create Delivery 2 for 5 units and click `Mark as To Do` - Verify reservations: - Delivery 1 reserves 5 units - Delivery 2 reserves remaining 3 units - Relocate all 8 units from `Shelf 1` to `Shelf 2` using the `Relocate` action from `stock quant` - Reopen both deliveries Issue: ------ After relocating stock between internal locations, reservations are reassigned in the wrong order: - Delivery 2 becomes fully reserved with 5 units - Delivery 1 is reduced to 3 reserved units This incorrectly swaps the original reservation priority between deliveries. Cause: ------ The relocation wizard starts from: `stock.quant.relocate.action_relocate_quants()` which calls `move_quants()`: https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/wizard/stock_quant_relocate.py#L70 `move_quants()` validates an internal stock move through `_action_done()`: https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/models/stock_quant.py#L1572 During validation, `_synchronize_quant()` moves the stock quantity from `Shelf 1` to `Shelf 2`. However, the already reserved delivery move lines still reference `Shelf 1`. This temporarily makes the source quant negative (`available_qty < 0`), triggering `_free_reservation()`: https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/models/stock_move_line.py#L695-L700 Inside `_free_reservation()`, move lines are ordered using `current_picking_first`: https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/models/stock_move_line.py#L816-L821 Since both deliveries share the same scheduled date, the fallback ordering uses `-cand.id`, causing Delivery 2 (higher id) to be processed before Delivery 1 (lower id). The reservation cleanup therefore happens in this order: - Remove Delivery 2 reservation (3 qty) - Remove Delivery 1 reservation (5 qty) The corresponding moves are then added to `move_to_reassign` in the same order: `[Delivery 2, Delivery 1]` https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/models/stock_move_line.py#L849 Later, `move_to_reassign._action_assign()` processes the moves in recordset order: - Delivery 2 reserves 5 units first - Delivery 1 only gets the remaining 3 units As a result, reservation priority is unintentionally reversed after relocation. Fix: ---- Before calling `_action_assign()`, reverse `move_to_reassign` This ensures reassignment preserves the original reservation order: - Delivery 1 is reassigned first and recovers 5 units - Delivery 2 receives the remaining 3 units The reservation state therefore remains consistent before and after internal stock relocation. --- opw-6218256 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects an issue in the Datev ledger export, ensuring accurate currency calculations. Previously, the system incorrectly used the company currency instead of the invoice's currency, leading to discrepancies in reported values. This fix ensures Datev exports reflect the correct financial data.
Original PR description
There is an issue in the Datev export functionality. In the current functionality, the code calculates a delta between the taxes in the `tax_totals` and the ones on the journal items. Issue is, the tax amounts from tax_totals were always in company currency, while the entry itself can use a foreign one. This replaces the use of company currency with the use of the invoice's currency and appropriately adjusts the test featuring foreign currency. Steps: Create a foreign currency. Create an invoice with a taxed product using the currency. Export the ledger to Datev. Inspect the resulting csv. Note that neither the final listed price, nor the rate listed for the currency align with the ones in the db. opw-6275889
This update resolves an issue where move records needed to be sent to be properly processed within the French VAT (VAT_PD) flow. The fix also corrects errors related to copied zip files during address validation based on country, ensuring accurate data processing for French businesses.
Original PR description
This fix removes the condition that moves must be sent to be part of a flow 10 and correct copy-pasted zip by country_id in address check.
This update resolves a critical error that prevented French eInvoicing invoices from being sent correctly in demo mode. The issue stemmed from a mismatch in data formats between the demo environment and the actual IAP service, specifically related to invoice message structures. This fix ensures invoices can be successfully processed during testing.
Original PR description
**Steps to reproduce:** * Install `l10n_fr_pdp` module. * Activate French eInvoicing in demo mode and enable "Participate in the pilot phase". * Create an invoice for a French client and send it via…
**Steps to reproduce:**
* Install `l10n_fr_pdp` module.
* Activate French eInvoicing in demo mode and enable "Participate in the pilot phase".
* Create an invoice for a French client and send it via the French E-Invoicing.
**Observed behavior:**
* A traceback is raised with `KeyError: 'messages'` in `_send_peppol_documents`.
**Cause:**
* `DEMO_ENDPOINTS['send_document']` in `l10n_fr_pdp` was returning `{'ppf_messages': [...]}`, missing the `messages` key that `_send_peppol_documents` in `account_peppol` unconditionally reads for flow 2.
* Additionally, the demo mock was returning `uid` instead of `uuid` inside `ppf_messages`, which does not match the real IAP response structure.
* Finally, in `l10n_fr_pdp/models/pdp_flow.py`, after successfully sending a flow 10 batch, the system attempted to log `response['uid']` despite the `_send_to_proxy()` method returning `uuid`. This caused a crash during the chatter logging step.
**Fix:**
* Fix `DEMO_ENDPOINTS['send_document']` to return `{'messages': [...]}` with `message_uuid` entries, matching the real IAP response structure for flow 2.
* Update `ppf_messages` in the demo mock to return `uuid` instead of `uid`.
* Fix `pdp_flow.py` to correctly access `response['uuid']` instead of `response['uid']` when posting the success message.
IAP Response: https://github.com/odoo/iap-apps/blob/b0462b9dded36a4d6dd45d00ddd13cd36e31807e/iap_services/l10n_fr_pdp_proxy/controllers/message_controller.py#L63
opw-6289723This update optimizes how Odoo retrieves related mailings during mass email campaigns. Previously, a slow process scanned all mailings, causing performance issues with large campaigns. This fix significantly improves the speed and efficiency of this process, preventing crashes and ensuring smoother campaign execution.
Original PR description
**Description of the issue/feature this PR addresses:** The method _get_ab_testing_siblings_mailings currently scans all mailings in a campaign to apply a simple filter, which becomes expensive on databases with many large mailings. **Steps to reproduce bug:** 1) Run this script to get [enough sufficiently large mailings](https://gist.github.com/brcut-odoo/bb0d6d334bfe110afe16021d17d1b443) 2) Open one of the mailings and recieve a crash from the _get_ab_testing_siblings_mailings **Current behavior before PR** https://drive.google.com/file/d/19xftvzsGSQ9DxB67LNiLkKApzsD192ax/view?usp=drive_link **Current behavior after PR** https://drive.google.com/file/d/1apTJ0rWTKaATYa67ZmmN-7bKhrw4KuTx/view?usp=drive_link opw-6245908 Forward-Port-Of: odoo/odoo#268283
This update resolves an issue where demo leave allocations wouldn't properly validate during an upgrade from Odoo 17.0 to 18.0. The fix ensures that the approval process is executed correctly, preventing data inconsistencies and allowing for smooth upgrades of the Indian Payroll module. This improves the reliability of the demo data and upgrade process.
Original PR description
Steps: - Install an Odoo 17.0 database with the Indian Payroll module and demo data. - Upgrade the database to 18.0. Issue: - The Indian payroll demo data creates leave allocations and approves them…
Steps: - Install an Odoo 17.0 database with the Indian Payroll module and demo data. - Upgrade the database to 18.0. Issue: - The Indian payroll demo data creates leave allocations and approves them through an XML function call. - During a fresh installation, demo files are loaded in 'init' mode, so the approval function is executed and the allocations move from 'confirm' to 'validate'. - However, during a 17.0 >>> 18.0 upgrade, demo files are loaded in 'update' mode. Odoo automatically loads demo files with 'noupdate=True' from the load_demo() >> load_data() function: - This value is passed to the XML importer and becomes the default noupdate state for the file. Since the demo XML file does not explicitly override this value, the function tag uses 'noupdate=True'. - When the XML parser reaches the approval function, _tag_function() skips its execution because of noupdate = 'True' and mode = 'update' condition. - As a result, the approval function is not executed during the upgrade and the leave allocations remain in 'confirm' state. Subsequent demo payroll data expects validated allocations and fails during loading. Fix: - Explicitly set 'noupdate=0' on the demo XML file. This overrides the default 'noupdate=True' value applied to demo files, making the parser evaluate the section with 'noupdate=False'. - As a result, '_tag_function()' executes the approval method during upgrades, the demo leave allocations are validated in both fresh/new db installations and 17.0 >>> 18.0 upgrade scenarios. runbot error-https://runbot.odoo.com/odoo/error/230430 task-6268381
This update fixes an issue where the unit price on purchase orders was incorrectly reset to zero when using reordering rules. The fix ensures that the product's original cost or a valid fallback price is used, preventing inaccurate purchase order pricing. This improves the reliability of purchase order generation.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ----------------------- 1 - Install the `purchase` and `stock` modules. 2 - Create a storable product with tracking enabled. Set the Cost (standard…
Version: ---------- - 18.0+ Steps to reproduce: ----------------------- 1 - Install the `purchase` and `stock` modules. 2 - Create a storable product with tracking enabled. Set the Cost (standard price) to 50. 3 - Open the product form and go to the Purchase tab. * Add a vendor with: * Quantity: 2 * Price: 10 4 - Create a Reordering Rule for this product: * Route: Buy * Trigger: Manual * To Order Quantity: 2 5 - Click on the Order button to generate a purchase order. 6 - Open the generated Purchase Order and verify the Unit Price on the purchase order line. 7 - Open the same product and go to the Purchase tab. In the existing vendor line, add an End Date lower than today so the vendor pricelist becomes expired. 8 - Reopen the same reordering rule. Change To Order Quantity to 1. 9 - Click on the Order button again Issue: ----- The generated purchase order line gets a Unit Price of 0 instead of keeping the product cost or a valid fallback price. Root Cause: -------------- - When clicking on `Order`, it triggers `action_replenish`, which calls the procurement flow: `_procure_orderpoint_confirm` → `run` → `run` → `_run_buy`. - Inside `_run_buy`, the system checks whether a `purchase.order.line` already exists. In this case, the PO line exists, so it calls `_update_purchase_order_line`. https://github.com/odoo/odoo/blob/47ef8b75d0c90001b9989a95f09b962c5b286c53/addons/purchase_stock/models/stock_rule.py#L137 - In `_update_purchase_order_line`, the system tries to fetch a seller using `_select_seller`, - which internally calls `_get_filtered_sellers`. https://github.com/odoo/odoo/blob/47ef8b75d0c90001b9989a95f09b962c5b286c53/addons/product/models/product_product.py#L759 - However, if the seller's `end_date` is less than `today`, `_get_filtered_sellers` skips that seller and returns no valid seller. https://github.com/odoo/odoo/blob/47ef8b75d0c90001b9989a95f09b962c5b286c53/addons/product/models/product_product.py#L731-L733 - As a result, `_update_purchase_order_line` does not find any seller and falls back to setting `price_unit` to `0`, causing the purchase order line price to be updated incorrectly. https://github.com/odoo/odoo/blob/47ef8b75d0c90001b9989a95f09b962c5b286c53/addons/purchase_stock/models/stock_rule.py#L259 --- opw-6117461 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update significantly speeds up the calculation of future timesheet holidays, particularly when many holidays are defined. The change optimizes how timezone conversions are handled, preventing long processing times and ensuring timesheet creation completes efficiently. This improves user experience and system performance.
Original PR description
**Problem:** When creating a new employee, the future timesheets due to public holidays are computed. If the number of public holidays is large (i.e. if the user creates them for each year, several years in the future), then it takes excessively long and the action may not complete. **Cause:** The pytz method `localize` and comparing times with non-static timezones is done repeatedly and unnecessarily which becomes costly with more records. **Solution:** Only localize the time when absolutely necessary (determining the date of the leave in the calendar timezone). **Performance Stats:** |Record count|Time before|Queries before|Time after|Queries after| |------------|-----------|--------------|----------|-------------| |100 |3.1s |393 |0.8s |117 | |1,000 |22.3s |2,090 |1.5s |183 | |10,000 |Timeout |N/A |6.7s |541 | opw-6087422 Forward-Port-Of: odoo/odoo#263953