Monday, June 15, 2026
22 changes · saas-19.3
Enhancements to existing features
This update enhances the way quantities are handled in the Point of Sale system, specifically within the 'decrease quantity' popup. It now allows for formatting and parsing of quantities, providing greater flexibility and control, while also ensuring that constraints (like preventing negative quantities) can be enforced by other modules.
Original PR description
We now allow formatting and parsing quantity on an orderline when using the decrease quantity popup. This allows overriding from other modules to add contraints (e.g. `pos_blackbox_be` prevents from setting negative quantities). see odoo/enterprise#119702 task-5942777 Forward-Port-Of: odoo/odoo#269936 Forward-Port-Of: odoo/odoo#269487
This update improves the speed and efficiency of selecting timesheets by prioritizing recently used projects, tasks, and helpdesk tickets within the systray timer. The timer now learns from your activity, surfacing the records you've tracked time on most frequently, reducing the need for manual searches.
Original PR description
Before this PR --- The systray timer used the default search ordering, making users repeatedly search for projects, tasks, and helpdesk tickets they had recently tracked time on. After this PR --- The systray timer now ranks projects, tasks, and helpdesk tickets according to recent timesheet activity. Frequently used records are surfaced first while preserving the existing prefill behavior, making timer selection faster and requiring fewer manual searches. task - 6216535 Forward-Port-Of: odoo/enterprise#118299
This update now automatically logs the reasons why orders are skipped during synchronization with Lazada. Previously, users had to manually investigate order details to understand the cause. This enhanced logging provides clearer insights into synchronization issues, streamlining troubleshooting and improving order processing reliability.
Original PR description
Before this commit, the only way to know why an order was not synchronized was to inspect the order details and infer the reason from the code. This commit now logs those reasons. Forward-Port-Of: odoo/enterprise#120212
Resolved issues and error corrections
This update clarifies bank statements for transactions split into multiple lines. Previously, all split lines received the same message, making it difficult to understand each charge. Now, transaction details are added to the label, aligning with CodaBox's breakdown and improving user clarity.
Original PR description
Currently, when global transaction is split into multiple lines, Odoo assigns the exact same communication text to every single split line. This makes it difficult for users to identify what each specific charge is for. To fix this, this commit introduces the transaction category data. Using this data to append specific transaction details to the end of the communication label. As a result, each split line now has a clear, descriptive label that closely matches the detailed breakdown provided by CodaBox. task-6059709 Forward-Port-Of: odoo/enterprise#113811
This update resolves a crash issue that occurred during pivot table autofill operations, specifically with formulas like `=PIVOT(1)`. By adding a check for simple `=PIVOT(...)` formulas, the system now consistently prevents crashes and maintains predictable behavior, ensuring a smoother user experience.
Original PR description
Current behavior before PR: - Autofill on formulas like `=PIVOT(1)` could crash after the refactor in e34c0a3, the new logic tried to process all pivot formulas. - However, simple `=PIVOT(...)` cases do not require any change in formula during autofill. Desired behavior after PR is merged: - Add an early return for pivot formulas that are not `PIVOT.VALUE` or `PIVOT.HEADER`, avoiding unnecessary processing. - Ensure `=PIVOT(...)` formulas remain unchanged during autofill, preventing crashes and keeping behavior consistent. Task: [6158888](https://www.odoo.com/odoo/project/2328/tasks/6158888) Forward-Port-Of: odoo/enterprise#119390
This update fixes an error in the vehicle contract report that was incorrectly adding recurring costs. The issue stemmed from overlapping database queries, leading to inflated totals. The fix replaces multiple joins with a single, more efficient query, ensuring accurate cost reporting for vehicles.
Original PR description
Steps to reproduce: ------------------- 1. Install Fleet with demo data. 2. Create a contract for a vehicle (A) with a recurring cost of 1000 and "Monthly" frequency. 3. Go to Reporting > Costs and…
Steps to reproduce: ------------------- 1. Install Fleet with demo data. 2. Create a contract for a vehicle (A) with a recurring cost of 1000 and "Monthly" frequency. 3. Go to Reporting > Costs and verify the monthly cost (it shows 1000). 4. Create another contract for the same vehicle (A) with a recurring cost of 50 and "Monthly" frequency. 5. Check the monthly cost again. Issue: ------ The reported cost is incorrect. Instead of 1050 (1000 + 50), it shows 2100. Cause: ------ The query uses multiple LEFT JOINs on the contract table, including: https://github.com/odoo/odoo/blob/9ca36dbe53692309bac84329de3b54a1c510cce0/addons/fleet/report/fleet_report.py#L103 These joins overlap and produce duplicate rows for the same vehicle and month, which results in inflated cost totals. Solution: --------- Replace the multiple LEFT JOINs with a single LATERAL join. This ensures the contract table is processed once per vehicle per month and avoids duplication, resulting in correct totals. **Before:** <img width="940" height="609" alt="image" src="https://github.com/user-attachments/assets/e5b3e747-1135-4674-97c9-4e4fd9986dfd" /> **After:** <img width="1053" height="590" alt="image" src="https://github.com/user-attachments/assets/f0df3819-07fb-4de5-aab3-5b4c6f10d213" /> opw-6024132 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256051
This update fixes an issue where the VAT books report was incorrectly including withholding tax in the total VAT calculation for Spanish companies. The fix excludes 'retencion' (withholding tax) from the VAT calculation, ensuring accurate reporting of VAT liabilities. This ensures compliance and reliable financial reporting.
Original PR description
Step to reproduce - install `l10n_es_reports` and switch to ES company - create a invoice, add a product, set price = 100 - add two taxes (one should be withholding tax) ex: 21%G and 19%whi - confirm it, total payable is now 100 + 21 - 19 = 102 - open vat Books report for ES, see line for this invoice Observation: - for this invoice, in total vat column, we get 102 value - it should be 100+ 21 i.e 121 as we do not include withholding taxes in total vat Cause: - the query for report used to sum up all the taxes for calculating vat Fix: - excluded tax of type "retencion" in tax summation opw-6082329 Forward-Port-Of: odoo/enterprise#120270 Forward-Port-Of: odoo/enterprise#114137
This update resolves an issue where closing and reopening records with x2many fields would cause a crash. The fix ensures that all related lists and records share the same 'fields' object, correctly updating the display of property fields within those lists. This improves stability and user experience when working with complex data structures.
Original PR description
Have an x2many field displayed as a list in a form view. In the arch, the x2many form view **isn't** inlined. In that x2many form view, there's a properties field. When a record is clicked,…
Have an x2many field displayed as a list in a form view. In the arch, the x2many form view **isn't** inlined. In that x2many form view, there's a properties field. When a record is clicked, `extendRecord` is called to add the new fields (those of the form) into `this.fields` and those fields are fetched. If there're properties in the property definition, fake fields are created to represent them (see `_processProperties`). However, because of extendRecord, the static list and the record don't share the same reference to the `fields` object. As a consequence, the `fields` object of the static list isn't updated with the fake property fields. If the user closes the record, and opens/closes it again, there's a crash, because the record is re-updated with the fields of the static list, and thus doesn't know about those property fields anymore. This commit fixes the issue by ensuring that we keep the same `fields` object when extending a record, s.t. the list and all its records always share the same object. Bug originally reported here: https://github.com/odoo/odoo/pull/268312 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269717
This update fixes a bug where purchase order line prices were incorrectly set to zero when using reordering rules with expired vendor price lists. The fix ensures the system uses the correct product cost or a valid fallback price, 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 Forward-Port-Of: odoo/odoo#269971 Forward-Port-Of: odoo/odoo#262396
This update fixes an issue where the Datev export incorrectly displayed currency amounts due to a mismatch between the invoice currency and the company currency. The fix ensures that currency calculations in the Datev export align with the invoice's currency, improving the accuracy of financial reports for German clients.
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 Forward-Port-Of: odoo/enterprise#120293
This update resolves an issue where inventory counts weren't accurately recording products without lot numbers. Previously, scanning these products incorrectly updated existing inventory lines. Now, the system correctly creates new inventory lines for lotless products during counts, ensuring accurate stock tracking.
Original PR description
### Steps to reproduce: 1. Create a product tracked by lot 2. Put 10 units in WH/Stock without lot 3. Inventory > Operations > Adjustments > Physical Inventory 4. Select the line referring to your…
### Steps to reproduce: 1. Create a product tracked by lot 2. Put 10 units in WH/Stock without lot 3. Inventory > Operations > Adjustments > Physical Inventory 4. Select the line referring to your product and request an inventory count + Show Expected Quantity 5. Open the barcode app > Count Inventory 6. Scan your product #### > The line is not selected, in particular, next scans will be re-interpreted as product scans rather than new serial creation for your product. ### Cause of the issue: Scanning your product search a line to select if any: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1432-L1435 https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1630-L1632 However, the `findLine` will fail since this method calls the `_canOverrideTrackingNumber` to determine if the lot of the barcodData matches the one of the line: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1859-L1863 But, the override of the `_canOverrideTrackingNumber` method for the `BarcodeQuantModel` does not handle the absence of lotName in the barcodeData correctly as it does not consider that a line without lot can be overridden by an empty lotName: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_quant_model.js#L729-L731 Note however that the super call does: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L795-L798 ### Issue 2: ### Steps to reproduce: - Steps 1 -> 5 - Click on your product line to select it - Scan a new lot to add one new unit referring to that lot - Confirm (1) - Apply Now #### > User Error: Quant's editing is restricted, you can't do this operation Since the line is selected, you have a currentLine during the `processBarcode` and hence the existing line will be updated using the `lotName``: https://github.com/odoo/enterprise/blob/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52/stock_barcode/static/src/models/barcode_model.js#L1560-L1584 However, writing on the line will then try to write on the related quant during the validation process which will be forbiden since we are not allowed to change the lot of an existing quant: https://github.com/odoo/odoo/blob/e3b0ca11d99b2ef819cdad68b169112cd73668b6/addons/stock/models/stock_quant.py#L351-L360 Now, the issue is that actually due to the nature of the line and of the barcode data, the line lot is not expected to be updated but rather a new line is expected to be created: https://github.com/odoo/enterprise/blob/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52/stock_barcode/static/src/models/barcode_model.js#L795-L798 Additional issue: Fixing issue 1 and 2 highlight and other issue of the validation process: - Steps 1 -> 6 > The line gets selected - Scan a newlot > a new subline is added referring to 1 unit of your new quant - Confirm (1) > Some serials where not counted, set them as missing #### > Check your quants: the 10 unit lotless quant was not updated but a new quant for 1 units was created for your newlot ### Cause of the issue: Applying all quantities is expecting to toggle them as counted before applying to update the existing quants: https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L72-L82 https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L287-L296 However, only line tracked by serial numbers are set as counted: https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L60-L63 opw-6212923 Forward-Port-Of: odoo/enterprise#118373
This update resolves an issue where reloading the Point of Sale while the system was in a specific state caused data loss and errors. The fix prevents a race condition between sending a beacon and initiating a new POS request, ensuring a smoother and more reliable reload experience. This improves overall POS stability for users.
Original PR description
When the user reloads the POS while the session is in opening_control, the beforeunload sendBeacon and the new pos_web request race. If the beacon is processed first it deletes the session and load_data fails. task-6259527 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268668 Forward-Port-Of: odoo/odoo#267190
This update fixes an issue where employee out-of-contract payments weren't being correctly deducted when multiple contract versions existed. The system now accurately calculates deductions based on the contract's start date, ensuring accurate payroll processing for employees with amended contracts.
Original PR description
…rsions on same contract **Steps to reproduce**: - Create a contract version from May 1 to May 14. - Create another contract version starting on May 15, then create an amendment version from May 20. - Generate a payslip for May using the May 20 version. - The employee receives the full monthly wage. The out of contract period (May 1 to May 14) is not deducted. **Reason**: - OUT worked days are linked to the first version of the contract starting on May 15. - When computing the OUT ratio, the system only considers worked days linked to the exact version being processed. - As a result, the May 20 amendment version does not see the OUT worked days and no deduction is applied. **Fix**: - Compute the OUT ratio using the contract start date instead of the current version, ensuring OUT worked days are correctly taken into account across all versions of the same contract. Task: 6259341 Forward-Port-Of: odoo/enterprise#119893
This update corrects a bug where bank statement CSV imports were incorrectly multiplying amounts by 100. The fix ensures that debit and credit values are parsed correctly, regardless of whether the 'account_bank_statement_extract' module is installed. This prevents inaccurate financial data import.
Original PR description
Steps to reproduce --- 1. With Accounting installed, import a bank statement CSV that has separate Debit and Credit columns using number separators (e.g. a line with "1.234,56"). 2. Map the columns…
Steps to reproduce --- 1. With Accounting installed, import a bank statement CSV that has separate Debit and Credit columns using number separators (e.g. a line with "1.234,56"). 2. Map the columns to Debit and Credit and import. The imported amounts are multiplied by 100: "1.234,56" is imported as 123,456.00. Issue --- This only happens when both `account_bank_statement_import_csv` and `account_bank_statement_extract` are installed, which is the default in any Accounting database since both modules are auto-installed. `account_bank_statement_extract` turns debit and credit into real Monetary fields on `account.bank.statement.line`: https://github.com/odoo/enterprise/blob/af863c5a53d0ab50fe67cb9ea910391d4a1979dd/account_bank_statement_extract/models/account_bank_statement_line.py#L7-L8 Because they are now real fields, the generic importer already converts those columns to floats: https://github.com/odoo/odoo/blob/bfa39854e56da4bf23295d62f63d66973ad0d78e/addons/base_import/models/base_import.py#L1281-L1285 The CSV statement wizard then parses the same columns a second time: https://github.com/odoo/enterprise/blob/d7ab7ee1287342638006e290ede20b955aae8370/account_bank_statement_import_csv/wizard/account_bank_statement_import_csv.py#L92-L93 The first pass correctly reads "1.234,56" as "1234.56", but the second pass sees a lone dot, mistakes it for the thousands separator, strips it, and produces 123456. The wizard now parses debit and credit only when they are virtual fields, so when they are real fields the values parsed by the generic importer are reused instead of being parsed twice. Without `account_bank_statement_extract`, debit and credit exist only as virtual import fields, so the generic importer skips them and the wizard parses them once. That is why the regression stays hidden until the extract module is present. opw-6227083 --- Forward-Port-Of: odoo/enterprise#118979
This update corrects a bug in how Odoo imports products from UBL invoices. Specifically, when searching by product name, the system incorrectly linked multiple products to the same line, leading to inaccurate data. This fix ensures that products are correctly associated during import, preventing data inconsistencies.
Original PR description
**PROBLEM** When retrieving a product by name, there is no cache_key for the search_method criteria. This leads to the cache_key frozendict being an frozen dict with None values. This means, once we retrieve a first product with the search_method criteria, all following product will match its cache_key, so we ends up associating a product to all subsequent lines, even if they don't have anything in common. **STEP TO REPRODUCE** 1. Create a product with the name: "CASTELTORRE MERLOT DELLE VENEZIE 75CL 10,5i" (it's important the name is not exactly matching) 2. Import the xml which is attached to the bug fix ticket. 3. Notice the product column on all the lines after a certain point have the CASTELTORRE product, even though the corresponding line in the ubl is for another product. opw-6227280 Forward-Port-Of: odoo/odoo#265987
This update significantly improves the speed of searching for partners (customers and suppliers) within the Point of Sale module. By optimizing the search process and reducing unnecessary sorting, the system now responds much quicker, especially when dealing with large customer databases. This enhances the efficiency of sales staff and improves the overall user experience.
Original PR description
Improve partner search response time on large databases (1M+ rows): - Implement smart field selection based on input type (phone, email, text). - Use prefix search (=ilike) for identifiers and exact match for barcodes. - Remove expensive sorting by complete_name in the backend. - Increase search limit to 500 to reduce network round-trips. task-id: 6143737 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265943 Forward-Port-Of: odoo/odoo#260347
This update corrects a calculation error in the Saudi HR payroll module that impacted GOSI contributions for employees with unpaid leave. The fix prortions contributions based on actual worked days, ensuring accurate deductions for employees taking time off. This improves payroll accuracy and compliance for Saudi operations.
Original PR description
Task: 6279514 Forward-Port-Of: odoo/enterprise#119990
This update fixes an issue where long-term sick leave payments weren't correctly calculated due to an outdated system. The change ensures existing sick leave data is properly processed, guaranteeing accurate unpaid sick leave payments as required by Belgian regulations. This prevents incorrect payroll calculations.
Original PR description
Following this task: https://www.odoo.com/odoo/project/1251/tasks/5942163, sick time offs are automatically split between paid/unpaid when the leave is created. However, existing data was not upgraded, and might result on sick leaves not being unpaid when they should. This commit re-introduces the method to ensure legacy compatibility with existing sick leaves. Upgrading the data by splitting/creating new sick leaves would be too heavy. task-6297274
This update fixes a potential issue where certified point-of-sale configurations could allow users to enter negative quantities on order lines. This restriction has now been implemented across both the backend and frontend of the system, ensuring data accuracy and preventing incorrect inventory calculations. This change improves the reliability of our POS system for certified users.
Original PR description
Certified pos configs should not allow to set negative quantities on order lines. We now prevent it from both backend and frontend. see odoo/odoo#269487 task-5942777 Forward-Port-Of: odoo/enterprise#120513 Forward-Port-Of: odoo/enterprise#119702
This update addresses a missing rule in the calculation of employer costs within the Odoo Enterprise system. Following a review, a crucial rule was identified and added to ensure accurate employer cost reporting. This improves the reliability of payroll and HR data.
Original PR description
In this previous PR https://github.com/odoo/enterprise/pull/106839 the computation of the employer cost was fixed and many rules were flagged as needed in that computation. After a report, we found one of the rules was missing so we add it in this PR. Task: 6088412 Forward-Port-Of: odoo/enterprise#112681
This update ensures that stock reports automatically print when a Point of Sale (POS) order is validated. Previously, the print job wasn't triggered, causing delays in stock reporting. The change adds a system to retrieve and execute report actions, streamlining the process and improving inventory tracking.
Original PR description
Validating a `pos.order` creates a stock move in inventory. However, when configuring reports to automatically print on validation, the print job wasn't triggered from the pos. We added a way to retrieve report actions and execute them. Task: 5392414 Forward-Port-Of: odoo/odoo#269614 Forward-Port-Of: odoo/odoo#239084
This update resolves an issue where the URL used for OAuth authentication with the Romanian tax authority (ANAF) was incorrectly generated. The previous method relied on the user's current session, leading to a mismatch with the registered URL. This change ensures the correct URL is used, allowing for proper authentication and tax reporting.
Original PR description
The `_compute_l10n_ro_edi_callback_url` method was using `request.httprequest.url_root` to build the OAuth callback URL. The URL is derived from the current HTTP request, meaning it reflects however the user accessed the session at that moment (e.g. internal IP, localhost, non-standard port). This produces a callback URL that does not match what was registered with ANAF, breaking the OAuth flow. 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#268974 Forward-Port-Of: odoo/odoo#265000