Thursday, May 21, 2026
3 changes · saas-18.4
Enhancements to existing features
Users can now resend Romanian e-invoices that were rejected by the SPV, instead of losing the failed attempt when trying again. The system keeps rejected EDI documents as history, improving traceability and audit confidence while allowing correction and resubmission.
Original PR description
Allow users to re-send invoices that were rejected by the SPV. Previously, EDI documents were deleted and recreated on every interaction, losing history in the process. This commit updates existing EDI documents in place instead, preserving failed documents as history for traceability. task-[5976612](https://www.odoo.com/odoo/project/967/tasks/5976612) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254882
Invoice and bill imports now search for similar products in smaller batches, avoiding memory spikes in databases with very large product catalogs. This reduces the risk of import failures while preserving accurate product matching.
Original PR description
Before this commit, for DBs with a very large number of products it was possible for the thread to run out of memory when importing an invoice or a bill. The reason is that the name on…
Before this commit, for DBs with a very large number of products it was possible for the thread to run out of memory when importing an invoice or a bill. The reason is that the name on product.product is non stored and computed. This leads to tons of recomputes, which in turn leads to reads and stores in cache of the underlying `product.product`, which down the line uses up all of the available memory for the thread. The proposed method uses batches instead of a `search_fetch` as the latter would not solve the recompute problem and hence the underlying memory problem. Another alternative approach could be going straight for the `product.template.name`, but that approach might introduce a loss of precision or functionality when searching for products at invoice import. Here is the memory graph from memray before the fix: <img width="1106" height="450" alt="opw-6168737-memray-pre-fix" src="https://github.com/user-attachments/assets/f971dc4d-aa09-41e3-a8c5-e5ca53f9786d" /> And here is the same graph after the fix: <img width="1106" height="450" alt="opw-6168737-memray-post-fix" src="https://github.com/user-attachments/assets/0a784cdc-9b40-498b-bbcb-89114eec1ec9" /> We can see a much lower peak memory usage after the fix. We an also observe that the memory complexity shifts from `O(n)` to `O(1)`, with `n` being the number of `product.product` records stored in the DB. For both presented graphs, the same, unaltered database was tested. The database contains 389 467 `product.product` records. opw-6168737 Forward-Port-Of: odoo/odoo#264948 Forward-Port-Of: odoo/odoo#262591
Manufacturing now finds the right bill of materials much faster when products have many variants. This reduces delays in production-related operations and improves responsiveness for large product catalogs.
Original PR description
Before this commit, finding a bom for a recordset of `products` involved looping over all the boms and it will loop over all the `product_variant_ids` of `bom.product_tmpl_id` if the bom's…
Before this commit, finding a bom for a recordset of `products` involved looping over all the boms and it will loop over all the `product_variant_ids` of `bom.product_tmpl_id` if the bom's `product_id` is NULL. This approach might loop over variants which we are not trying to find a bom for. In additon to that, due to the fact that multiple boms might have the same `product_tmpl_id`, this approach might consider the same variants in the inner loop redundantly even though we matched the variant with a bom in a previous itration.
Worst case, this might result in a time complexity of $O(N * M)$ where N is the number of boms and M is the number of variants.
To improve the performance, I only considered the variants given in the paramater `products` and in addition to that, I created a new dictionary mapping a `product_tmpl_id` to its bom if the bom doesn't have a variant set. By doing this, I can loop over the `products` given and if it doesn't have a bom set then it will be set to the one its template had taken from the previos loop.
In a method call with the following constraints
- **2** products the method was finding a bom for
- The 2 products had the same template and the template contained **550** active variants
- The boms were only related to the template rather than the variants themselves.
| Input Size | Before | After |
| :--- | :--- | :--- |
| 100 | 0.78s | 0.03s |
| 1000 | 8.53s | 0.11s |
| 10000 | 80.99s | 0.73s |
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#247465