Wednesday, September 16, 2026
5 changes · saas-18.3
Enhancements to existing features
Inventory availability searches now use a more efficient stock-based calculation, reducing delays when working with large product lists. This improves responsiveness for businesses managing high volumes of stock and warehouse activity.
Original PR description
**Problem:** Searching on free_qty can be slow when there are many stock.move and stock.quant. The search method uses _compute_quantities_dict() to compute the free_qty based on stock.move and stock.quant, which is expensive. **Solution:** A similar field, qty_available, has a faster search method based on stock.quant only. This method can be adapted to support fast searching on free_qty by also aggregating the reserved_qty and subtracting it from the qty_available. **Perf Table:** Record: product.template, with ~20k stock.picking and most products w/o moves. |Record count|Time before|Queries before|Time after|Queries after| |------------|-----------|--------------|----------|-------------| |10k |2.14s |214 |370ms |45 | |50k |6.06s |644 |829ms |50 | |100k |11.42s |1196 |1.05s |46 | opw-6266096 Forward-Port-Of: odoo/odoo#270434
Resolved issues and error corrections
This update adjusts an internal automated test for the Events app after a small expected database activity change. It helps keep quality checks accurate so future event-related changes can be validated reliably.
Original PR description
Description of the issue/feature this PR addresses: Updates the queryCount assertion since the amount of queries increased by one. runbot-944484
Fixed an accounting issue where small but valid foreign exchange gains or losses could be ignored when reconciling payments in currencies with no decimals, such as HUF. This ensures paid invoices are balanced correctly and exchange differences go to the proper gain or loss accounts instead of suspense or receivable balances.
Original PR description
Steps to Reproduce: - Set company currency to EUR (or USD). - Configure a bank journal in HUF (or any 0-decimal currency) with Gain/Loss accounts set and Sales journal as well. - Set two HUF exchange…
Steps to Reproduce: - Set company currency to EUR (or USD). - Configure a bank journal in HUF (or any 0-decimal currency) with Gain/Loss accounts set and Sales journal as well. - Set two HUF exchange rates: 1 EUR = 270.6 (invoice date) and 1 EUR = 272.9 (payment date) - giving a ~0.35 difference. - Create and post a customer invoice for 11,480 HUF on the first date. - Register a bank payment for 11,480 HUF on the second date. - Reconcile the payment against the invoice and validate. Issue: No Exchange Gain/Loss line is created for the ~0.35 difference. Instead it's posted to the Suspense account, or left as an open balance on Receivable, even though a real exchange difference exists. Differences of 0.50 or more are handled correctly, confirming the failure is tied to a fixed 0.50 threshold. Root Cause: `_lines_get_account_balance_exchange_diff` correctly computes `exchange_diff_balance` in company currency and correctly checks it for zero using `company_currency_id.is_zero()`. Immediately after, `_lines_get_exchange_diff_values` performs a second zero-check on the same value, but against `line.currency_id` (the transaction currency, e.g. HUF) instead of company_currency_id. Since HUF's rounding=1.0 gives an `is_zero()` threshold of 0.5 (half the rounding unit), any real company-currency difference below 0.50 passes the first (correct) check but is wrongly discarded by the second (wrong-currency) check. Solution: Corrected the second zero-check to use self.company_currency_id instead of line.currency_id, matching the value's actual currency. Result: Exchange differences now post correctly to Gain/Loss regardless of the transaction currency's rounding precision. opw - 6421574 Forward-Port-Of: odoo/enterprise#127540
Fixed an accounting issue where batch payments could remain marked as sent even after the related bill and payment were paid. This helps keep payment statuses accurate and avoids confusion in vendor payment tracking.
Original PR description
A payment on a journal without outstanding account has no journal entry, so it is matched as soon as it is paid. When the bill it pays is reconciled later on, _compute_state turns it to 'paid', but assigning a field from within a compute doesn't notify the fields depending on it: is_matched stays False and any batch payment holding that payment stays in 'sent' state. Mark is_matched for recomputation explicitly, as 18.0 already does since d8de23495009. Steps to reproduce: - on the Bank journal, leave the outstanding account empty on the outbound payment method line - Post a vendor bill - Register a payment on it - Put that payment in a batch payment and validate the batch - Create a MISC entry and reconcile the bill with it Issue: bill and payment are 'Paid' but the batch stays 'Sent'.
Fixed an issue where Belgian certified POS sales reports could fail in databases with multiple Belgian companies selected. The report now uses the correct company context for tax lookup, helping users generate sales details reliably.
Original PR description
Before this commit, generating the "Sales Details" report of a Belgian certified POS can raise "Expected singleton: account.tax.group(...)" on amulti-company database.…
Before this commit, generating the "Sales Details" report of a Belgian certified POS can raise "Expected singleton: account.tax.group(...)" on amulti-company database. _set_default_belgian_taxes_if_empty() resolves each tax by name only, and the Belgian chart of accounts duplicates "21%", "12%", "6%" and "0%" in every company. Only the ir.rule "Tax multi-company" kept that search sane, and it filters on the allowed companies: it breaks with several companies ticked in the switcher, and from any sudo() flow (automation, cron, mail), which ignores record rules. Pass the session company explicitly with with_company(). This fix is similar to #69402 (17 and 18 only). Steps to reproduce (can be hard to reproduce, but here is a recap): - install Point of Sale and pos_blackbox_be - Setup 2 Belgian companies - configure a certified POS on the first company, sell a product taxed at 21%, close the POS Session - tick both companies in the switcher and print "Sales Details" => ValueError: Expected singleton: account.tax.group(...) opw-6385151