Tuesday, July 22, 2025
14 changes · saas-18.3
Resolved issues and error corrections
FacturX electronic invoices now include required XML namespace information and correctly identify SEPA Direct Debit payments. This helps invoices pass external validation checks and reduces the risk of rejected or non-compliant e-invoices.
Original PR description
### Issue: There are several issues with the XML of FacturX. ### Steps to reproduce: - Create a partner with a direct debit mandate - In the Accounting tab of the partner select "FacturX" as eInvoice…
### Issue: There are several issues with the XML of FacturX. ### Steps to reproduce: - Create a partner with a direct debit mandate - In the Accounting tab of the partner select "FacturX" as eInvoice format - Create an invoice with this partner, pay with SDD, confirm - Send to FacturX - Verify the PDF with https://www.portinvoice.com/ 1 Missing namespaces 3. In the XML the code for the payment means does not adapt to the payment method: 42 (Payment to bank account) and not 59 (SDD) ### Cause: 1. The namespaces are not there ([doc](https://fnfe-mpe.org/factur-x/factur-x_en/)). 3. We always input "42" as payment mean ### Solution: 1. Added namespaces `xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"` and `xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"` 3. Added the code "59" for SDD, a lot of codes could be added but this commit only handles this one Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4907827) opw-4907827 Forward-Port-Of: odoo/odoo#218686 Forward-Port-Of: odoo/odoo#217763
Sales orders with multiple make-to-order products now continue creating needed purchase orders even if one product has no vendor set. Products without a vendor fall back to available stock handling and notify the responsible person, preventing one setup issue from blocking the rest of the order flow.
Original PR description
Bug introduced in: https://github.com/odoo/odoo/commit/eb26262f17cf0c828e8fdf03a8e2f916e3619d81
Steps to reproduce the bug:
- Create two storable products:
- P1:
- Routes: Make To Order (MTO) + Buy - Vendor: Azure Interior
- P2:
- Routes: Make To Order (MTO) + Buy
- No vendor defined
- Create a sales order with one unit of P1 and one unit of P2
- Confirm the SO
Problem:
The stock move for P2 is created with the procurement method Make To
Stock (MTS), while P1 uses Make To Order. but the purchase order for P1
is not created, because When processing P2 the `run_buy`, a return
occurs and function is stopped instead of continuing to process
the other moves/flow.
Solution:
Ensure that the absence of a vendor for MTO+Buy products only causes a fallback to MTS and notify responsible, without breaking the processing of other moves.
opw-4945468
Forward-Port-Of: odoo/odoo#219302Reinstalling the Amazon sales app could run out of memory on databases with many past Amazon-related sales lines. This change limits the data loaded during that process, reducing peak memory use and making reinstalls more reliable.
Original PR description
Description ----------- On databases that had `sale_amazon` installed in the past, were used for sales for a certain period, then had the module uninstalled, and later attempted to re-install it, a…
Description ----------- On databases that had `sale_amazon` installed in the past, were used for sales for a certain period, then had the module uninstalled, and later attempted to re-install it, a memory error will occur. The peak memory usage stems from `sale.order.line._compute_is_service`. The reason the compute is triggered is because of the "re-creation" of the master data products `default_product` & `shipping_product`, which writes `type`, which the compute depends on. So the compute will be triggered for all `sale.order.line` records that had those products. This commit avoids the excessive memory usage by explicitly fetching the fields that are needed for the compute, which avoids fetching large fields like the different products' HTML descriptions. Benchmark --------- On a database with 400k+ `sale.order.line` with an amazon related product, installing `sale_amazon` peak memory usage was: | | Peak Mem. | |--------|-----------| | Before | 3.8 GiB | | After | 580 MiB | Reference --------- opw-4915892 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219599
Project to-do activity counts now use each user's own timezone when deciding whether items are late, due today, or upcoming. This prevents mismatches where dashboard or systray counts showed activities as due today before they actually appeared in the activity list.
Original PR description
User timezone was not being used for activity states and thus the future, today, and late activities would be inaccurate. They were being computed with CURRENT_DATE through SQL which is based on the timezone that the SQL server is in. This would lead to there being a period of some hours based on the user timezone where the actual activities page that you click into and the systray showing different counts of activity states. For example, on our Odoo production database, activities that SF office members create on projects that were for tomorrow would show today after 5pm and when clicking on the today activities there would be nothing until midnight. Using the user timezone in order to compute what today is for them, then using this in the SQL query fixes this issue. This is the same behavior as the compute_state for the state field in mail.activity. opw-4893182 Forward-Port-Of: odoo/odoo#218713
Point of Sale now calculates lot availability using only stock from the configured PoS source location and its relevant internal child locations. This prevents cashiers from seeing or selling quantities that are available elsewhere but not actually available for that PoS location.
Original PR description
The get_existing_lots function previously returned product_qty based on stock.lot's computed field, which sums quantities from all locations. This led to incorrect available quantities in the PoS, as it should only consider stock in the configured PoS source location and its child internal locations. opw-4865777 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219444 Forward-Port-Of: odoo/odoo#215227
Italian electronic invoice XML generation now excludes linked accounting documents dated after the current document. This prevents tax authority rejections caused by references to invoices or credit notes that should not yet be considered previously issued.
Original PR description
In a FatturaElettronica xml document <DatiFattureCollegate> allow us to specify any references to other previously sent documents. However, it is currently possible that the system populate this element with moves dated after the current document, causing the SDI to reject the document. Steps to reproduce: - Create an invoice A and register a full payment via the button - Create a credit note for the invoice, unreconcile the credit note if necessary - Create a new invoice B and add the credit note as payment - Create the XML of the credit note Issue: The XML includes info about invoice B, created after the credit note. If invoice B is dated after the credit note, the SDI will reject the xml Solution: Avoid including reconciled elements with date later than the current document date opw-4795664 Forward-Port-Of: odoo/odoo#219646 Forward-Port-Of: odoo/odoo#219106
Fixes an issue where changing the quantity of a sales order for a kit with dropshipped components could create incorrect negative purchase quantities. This ensures linked purchase orders reflect the intended customer order quantity, reducing fulfillment and purchasing errors.
Original PR description
…d comp **Problem:** when updating the quantity of a sale order line for a kit whose components are dropshipped, the update of the quantity of the linked Purchase order lines is wrongly computed…
…d comp **Problem:** when updating the quantity of a sale order line for a kit whose components are dropshipped, the update of the quantity of the linked Purchase order lines is wrongly computed **Steps to reproduce:** - enable the dropshipping setting - create a new storable product - in the purchase tab set a vendor - in the inventory tab check only the dropship route - repeat these operations for another product - create a third storable product - create a BOM for this product and set it as "kit" - add the two first products you created in the components - create a new quotation for the kit product, set a quantity of 25 and confirm - modify the quantity to 10 and save - click on the purchase smart button **Current behavior:** the quantities of the two purchase order lines have been updated to -15 **Expected behavior:** it should be 10 **Cause of the issue:** When we change the quantity on the sale order line: The method action_stock_rule from SaleOrderLine is triggered. It will create a procurement: https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/sale_stock/models/sale_order_line.py#L338 To compute the quantity used for this procurement,the computation is : product_qty = line.product_uom_qty - qty where qty is line._get_qty_procurement https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/sale_stock/models/sale_order_line.py#L313 The error comes from the _get_qty_procurement - The "normal" behaviour of _get_qty_procurement is to compute the difference between outgoing moves and incoming moves https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/sale_stock/models/sale_order_line.py#L253-L263 - Basic _get_qty_procurement wouldn't work for a kit as a move is created for each components. So there is an override of the method to handle this case https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/sale_mrp/models/sale_order_line.py#L128-L141 this override calls _compute_kit_quantities on the stock moves linked to the sale order line via its move_ids attribute. _compute_kit_quantities does a computation of the ratios for each component and returns the minimum - Basic _get_qty_procurement wouldn't work either for a dropshipped product as no move is created when confirming the sale order. So there is another override of the method to compute this case https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/stock_dropshipping/models/sale.py#L42-L51 This override uses the purchase order line linked to the sale order line via its purchase_line_ids to compute the quantity. Neither of those two overrides would work for a kit with dropshipped components. The first one would fail because no stock moves are created. The second one would fail because adding the value of each purchase order line created returns a value too high **fix** for this specific case we just take the previous quantity opw-4743482 Forward-Port-Of: odoo/odoo#216633 Forward-Port-Of: odoo/odoo#211726
This change rolls back a previous accounting update that caused problems when validating transactions with required analytic information. It restores the prior behavior to prevent validation errors reported by multiple customers.
Original PR description
This reverts commit 8194c6e2bfedc9437964090b1a498c3e8cff225c. opw-4936028 opw-4933629 opw-4935236 opw-4933456 opw-4933652 opw-4935789 opw-4938570 opw-4938388 opw-4935709 opw-4940233 opw-4938849 Forward-Port-Of: odoo/odoo#218833
The online store cart now avoids showing invalid promotion discount items when a discount product has been removed. This prevents customers from hitting an error when viewing their cart, helping keep checkout flows available.
Original PR description
Currently, an error occurs when the user attempts to go to cart on website with a Promotions program enabled with no discount item attached to it. Steps to replicate: - Install `Sales` and…
Currently, an error occurs when the user attempts to go to cart on website with a Promotions program enabled with no discount item attached to it. Steps to replicate: - Install `Sales` and `Ecommerce`, turn on Discounts and Loyalty from settings. - Go to `Sales > Products > Discounts & Loyalty` and create new with `Program type` as `Promotions`. - Make sure `Reward type` is selected as `Discount` and save. - Now click on rewards and then remove the `Discount Product`. - Now go to Website and add any product with Price > 50 in your cart and go to your cart, you will get your error. Error: `QWebException: Error while render the template AttributeError: 'bool' object has no attribute 'splitlines'` The error occurs because line **[1]** attempts to call `splitlines()` on a `False` value instead of a string, which happens because the product is removed from the `Discount Product` field. This commit resolves the issue by adding a check before rendering an item to prevent it from being passed as empty. [1]-https://github.com/odoo/odoo/blob/35221b9529333410d9a011049788bd6d46635a70/addons/website_sale/models/sale_order_line.py#L26 sentry-6612266221 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixes an issue where loans could fail when being cancelled, reset to draft, and confirmed again while Accounting Audit Trail is enabled. This helps accounting teams manage loan records reliably without encountering an unexpected error from previously posted entries.
Original PR description
Steps: - Activate Audit Trail in Accounting configuration - Create and confirm a loan, having some moves posted in the past - Cancel it, reset it to draft the re-confirm it again -> ValueError: Expected singleton This is because posted moves can not be unlinked when canceling/closing the loan if audit trail is activated. Therefore we try to access the `state` field from a recordset instead of a singleton. With this commit, we filter the generated move to get the newly created one. opw-4834361 Forward-Port-Of: odoo/enterprise#88286
Project profitability now includes budget lines even when a project's analytic account belongs to a different analytic plan than expected. This prevents valid budget information from being hidden after analytic account migrations or plan mismatches, giving users a more complete profitability view.
Original PR description
In version 17.3, the analytic mixin was introduced in budget.line model to allow to link a budget line to multiple analytic accounts belonging to different analytic plans. The issue is that we have…
In version 17.3, the analytic mixin was introduced in budget.line model to allow to link a budget line to multiple analytic accounts belonging to different analytic plans. The issue is that we have not adapted the code in project profitability, to take those changes into account. A problematic situation could be the following: 1. We have a project where the account "X" is set to the main project plan (the first one) "Projects" BUT the account "X" actually belongs to the analytic plan "Departments" (yes, it's possible that there is a mismatch between the project plan and the analytic plan, especially after the 18.0 upgrade where "analytic_account_id" just became "account_id", no matter in which plan it was). 2. We have a budget line linked to the account "X" for the plan "Departments". 3. We want to display the budget lines in project profitability, but this line does not appear. That's because we currently only look for the budget lines belonging to the analytic plan "Projects" aka the main/first plan, that match the account "X" of the project. But as account "X" actually belongs to the analytic plan "Departments", no budget lines are found. task-4901400 version-18.0 Forward-Port-Of: odoo/enterprise#88658
Bank statement reconciliation has been optimized to run much faster on very large accounting databases, reducing the risk of slow imports or timeouts. This improves day-to-day accounting workflows, especially when importing statement files with many lines.
Original PR description
[FIX] account_accountant: refactor and optimize _try_auto_reconcile_statement_lines() In big databases, this method called on large recordsets of statement lines would take too much time, or worse:…
[FIX] account_accountant: refactor and optimize _try_auto_reconcile_statement_lines() In big databases, this method called on large recordsets of statement lines would take too much time, or worse: timeout. This is mainly because the 2 SQL queries are doing too complex searches and hence are badly optimized by the query planner. To solve that, * We search for reconciliable accounts outside the queries to avoid a join * We add a trigram index on statement_line.payment_ref and only use ILIKE operations for reference matching so that it can be used * Instead of using complex and costly regexp_split, we search for matches by splitting account_move_line.ref on ' - ' * We move some logic in python, amount matching, rather than in sql * We don't try anymore to match on amounts found in the payment_ref Additionnally, * The algorithm now treats the statement lines with and without partner the same for reference matching, but lines without partner are just ignored for the amount matching, as it's way too dangerous * Bug of with_prefetch, pre-loading the ids of a wrong object, has been fixed * We revert the patch https://github.com/odoo-dev/enterprise/commit/da52bc70cd745f3e9f7a0539528c84aa47b98cc5 because it was only a temporary measure while the time was back to acceptable * The test_matching_rules_with_empty_aml_ref, irrelevant, was removed Benchmark --------- Importing a csv file of 200 statement lines, on a database of 21M account.move.line, and thus triggering the culprit function, takes (hot timings): | Before | After | Speed-up | |--------|-------|----------| | 185 s | 52 s | ~3.5x | see https://github.com/odoo/odoo/pull/218642
Manufacturing orders created from Barcode now generate all required stock transfers when multi-step manufacturing is enabled, including picking components and storing finished products. This prevents missing warehouse movements and ensures by-products are correctly linked to the manufacturing order.
Original PR description
Task: 4558792 If 3-step manufacturing is enabled, the creation of an MO should also create 2 stock transfers: "Pick Components" and "Store Finished Product". Currently, when an MO is created via Barcode, only SFP is created. The problem boils down to the newly created stock move not having a `warehouse_id` field set, which causes Odoo to miss the required stock rules. This PR fixes the issue by fetching the `warehouse_id` field in XML, from where it is later passed to JS and back to Python's `create` method. Additionally, by-product moves for MOs created via Barcode were not correctly associated with the MO. This issue was solved by passing the missing fields from XML to Python. Forward-Port-Of: odoo/enterprise#90370 Forward-Port-Of: odoo/enterprise#83895
Fixed an issue that could prevent a point-of-sale session from closing after an Urban Piper payment method was used. The closing screen now avoids duplicate payment method entries, so staff can complete end-of-day closing normally.
Original PR description
Currently if setting a urban piper payment method on a shop and using it at checkout will not allow you to close the session. Steps to reproduce: ------------------- * Go in the setting and set up…
Currently if setting a urban piper payment method on a shop and using it at checkout will not allow you to close the session. Steps to reproduce: ------------------- * Go in the setting and set up urban piper (no need for credentials) testing with random keys will do * Go into the payment methods and take one of the urban piper one and assign it to a shop * Open that shop * Place an order and use the urban piper payment method * Validate * Try closing the session > Observation: Nothing happen, we're now unable to select the menu. If doing the same steps but in debug mode, a traceback is shown indicating a duplicate key in a t-foreach Why the fix: ------------ The duplicate key is happening when rendering the closing popup because the function `get_closing_control_data()` was returning twice the information related to the urban piper payment method. Even though urban piper wasn't build with the use case in mind we want to keep it possible. We avoid sending twice the urban piper methods if they were already computed in the super method. opw-4874699 Forward-Port-Of: odoo/enterprise#90427 Forward-Port-Of: odoo/enterprise#88156