Thursday, November 6, 2025
15 changes · 18.0
Resolved issues and error corrections
Boleto payment methods are now treated as one-time payments and cannot be tokenized for later reuse. This avoids inconsistent behavior across payment providers and reduces the chance of payment failures or confusing customer experiences.
Original PR description
## Versions 17.0+ ## Issue Boleto is an offline, one-time-use payment method and cannot be tokenized with most payment providers (e.g., Adyen: https://docs.adyen.com/payment-methods/boleto-bancario/, Nuvei: https://www.nuvei.com/apm/boleto). ## Exception Stripe allows a form of tokenization by storing the customer's billing information and regenerating a new Boleto for each payment (cf. https://docs.stripe.com/payments/boleto). Technically, the Boleto itself is not reusable — Stripe simulates tokenization by associating customer info with new Boleto transactions. ## Fix To maintain consistent behavior and avoid provider-specific edge cases, tokenization is disabled for Boleto payments globally. opw-5156718 Forward-Port-Of: odoo/odoo#234373
This update fixes an issue in Shiprocket delivery label generation when taxes without GST tags are used. It also makes the related test more reliable by forcing a consistent tax rate, reducing the risk of intermittent failures.
Original PR description
Some other test adds a fiscal position with tax mapping. This creates 2 problems 1. The new taxes have a tag, which means we evaluate the right hand of…
Some other test adds a fiscal position with tax mapping. This creates 2 problems
1. The new taxes have a tag, which means we evaluate the right hand of
https://github.com/odoo/enterprise/blob/8d3fe30c627eada1186c15480876fb2e8f7ddb59/delivery_shiprocket/models/shiprocket_request.py#L239
However, since l10n_in is not installed,
`tax.env.ref(f"l10n_in.tax_tag_{gst}gst", False)`
does not return anything (False is not a fallback)
https://github.com/odoo/odoo/blob/1e96a3d127e8f521d3027f7110026ae84e11ed5e/odoo/api.py#L588
So we end up looking for `None` in `tax_tag_ids`, which leads us to compare the `_name` properties, see
https://github.com/odoo/odoo/blob/1e96a3d127e8f521d3027f7110026ae84e11ed5e/odoo/models.py#L6545-L6558
2. The test added in 4d5df93 was assuming the default company 15% tax, which was not always true
Solution
-----
1. Provide a fallback for the `ref` lookup
2. Force a 15% tax in the test
-----
runbot-232692
Forward-Port-Of: odoo/enterprise#97998Quality checks now keep the correct company when they are created from stock movements. This prevents confirmation errors when a user switches to another company, making intercompany receipt handling more reliable.
Original PR description
When creating quality checks per quantity, a multi-company error occurs if the active company differs from the one defined on the control point. Steps to reproduce: - Create a Quality Control Point for Company B and Product Table for the receipt operation with a per-quantity control. - Create a receipt in Company B for this product but leave it in draft. - Switch to Company A and try to confirm → error. Root cause: The company_id was not set when creating the quality check, causing it to default to `env.company` (A) instead of the stock move line’s company (B). opw-86993 Forward-Port-Of: odoo/enterprise#98655
This change adjusts how Swiss ISO20022 payment files are generated so they only include SEPA-specific XML details when explicitly enabled. It helps avoid files being rejected by banks that still expect the older Swiss format, while keeping the earlier fix available for cases that need it.
Original PR description
[REV] account_iso20022: Wrong XML generated for Switzerland This reverts commit https://github.com/odoo/enterprise/commit/a0e981171808d4e475249431424955ab2223f5da. This commit was introduced after…
[REV] account_iso20022: Wrong XML generated for Switzerland This reverts commit https://github.com/odoo/enterprise/commit/a0e981171808d4e475249431424955ab2223f5da. This commit was introduced after this fix https://github.com/odoo/enterprise/commit/c160b2ead711797ca7362649971038cc245c5611. Though that original fix was correct, it had some unwanted side-effects: due to the payment method being forced on some payments in order to use SEPA, the sepa_pain_version field was used to generate the corresponding XML nodes, most of the time keeping its default value of pain.001.001.09. For Swiss banks supporting pain.001.001.09 (which becomes mandatory in November 2026), it was not a problem, and everything worked fine. This was the case of the customer for whom the fix was made (ticket 4535542). For the ones still not supporting it, and expecting pain.001.001.03, the bank refused the file, since the it contained unsupported nodes, like BICFI, or a subnode to ReqdExctnDt. The commit we revert here tried to patch the symptoms without really understanding the cause of the issue, by not forcing the payment method everywhere. It breaks again the case of the original ticket (because ScvLvl is not passed to "SEPA" on EUR payments), and essentially makes no sense. We revert it in favor of a better fix. ticket-4535542 ======================= [FIX] account_iso20022: Swiss variant: introduce config parameter to force SEPA nodes in the file https://github.com/odoo/enterprise/commit/c160b2ead711797ca7362649971038cc245c5611 made it so we now force SEPA payments into Swiss ISO20022 files when they're made in EUR to an IBAN account. Though all in all correct, this fix forgot to consider the fact that the SEPA nodes would be generated using the sepa_pain_version field, with defaults to pain.001.001.09 version of the ISO standard. As it is today, the Swiss file is still generated using pain.001.001.03 in Odoo (some task will change that soon, since the support for that old version will be dropped in November 2026). Having such pain.001.001.09 nodes in the file causes it to be rejected by a lot of Swiss banks, because they don't support that version yet, or simply because of the file mixing both versions of the standard. Since no one had asked us to enforce SEPA nodes within the file before recently, we make the choice to keep the fix behavior only when a config parameter is explicitly set to enable it. In all other cases, the former behavior is restored. We also now display the PAIN version field in the journal's form view when this config parameter is set, to give more control on the format of the generated file. ticket-4535542
This update prevents an access error in Documents when a company is archived and users open the app. It ensures folders are only loaded for companies the user can still access, so the Documents workspace opens normally.
Original PR description
**Steps to reproduce:** - Add some folders - Create a new company - Assign some folders to the new company - Archive the company - Click on Documents app - AccessError is raised when opening it…
**Steps to reproduce:** - Add some folders - Create a new company - Assign some folders to the new company - Archive the company - Click on Documents app - AccessError is raised when opening it **Issue:** The issue seems to be related to caching issue on the field `type` when fetching the documents with `search_panel_select_range` and going through `_compute_display_name`: `folders = accessible_records.filtered(lambda d: d.type == 'folder')` This error was quite inconsistent and might be related to the cache missing some prefetched data on a record it shouldn't have been able to read. There is a need to ensure only the folders available to the user are able to be fetched. **Fix:** Added the `type` field in the `search_panel_fields` but this might not be needed if the issue comes from elsewhere. For now the issue was mitigated by explicitly checking for the user companies in the domain of the searchs, but it needs to be checked as this behavior might break other flows. opw-4931278
This change fixes a validation error that could appear during database migration when a tax distribution total was zero. It makes the validation check handle that case correctly, avoiding an unnecessary traceback and helping migrations complete smoothly.
Original PR description
``` File "/home/odoo/src/odoo/19.0/addons/account/models/account_tax.py", line 611, in _validate_repartition_lines raise ValidationError(_("Invoice and credit note distribution should have a total…
```
File "/home/odoo/src/odoo/19.0/addons/account/models/account_tax.py", line 611, in _validate_repartition_lines
raise ValidationError(_("Invoice and credit note distribution should have a total factor (+) equals to 100."))
odoo.exceptions.ValidationError: Invoice and credit note distribution should have a total factor (+) equals to 100.
```
- During the database migration, a traceback occurs because the [total_pos_factor](https://github.com/odoo/odoo/blob/18.0/addons/account/models/account_tax.py#L558) is being calculated as 0. When this happens, the float_compare [function](https://github.com/odoo/odoo/blob/18.0/addons/account/models/account_tax.py#L559) returns -1, which incorrectly satisfies the validation condition and triggers a ValidationError.
- To resolve this, we need to add an additional condition to check whether total_pos_factor is 0, similar to the condition already implemented [here](https://github.com/odoo/odoo/blob/18.0/addons/account/models/account_tax.py#L562) in the code.
tbg-1970
opw-5228357
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis change fixes an issue where vendor credit notes sent to MyInvois could be rejected if the original bill had a custom reference. Odoo now uses the stored reference from the original e-invoice, helping credit notes validate correctly and avoiding submission errors for users.
Original PR description
Currently, customers get an error when trying to send the vendor credit note to MyInvoise if a reference has been set on the bill. ``` The validation failed with the following errors: The reference document UUID [...] does not exist. The internal ID for DocumentUUID [...] does not match. ``` Steps to reproduce: - With an MY company setup - Create a bill and add a custom reference - Send Bill to MyInvois - Create credit note for the Bill - Send Credit note to MyInvoice Issue: Validation will fail because the reference does not match. In the reverse bill we always send the original bill name as original bill id, but also the reference could have been used. Analysis: A solution would be to send always the reference of the original vendor bill if present. However, the bill reference may be altered after submitting the e-invoice. A safer way is to retrieve the reference from the stored e-invoice. opw-5057050 Forward-Port-Of: odoo/odoo#234199
Sales orders linked to deliveries will now be marked as invoiced once no further picking actions are expected, even if the full quantity was not delivered. This keeps order status more accurate and avoids orders appearing open when they are effectively complete from a billing perspective.
Original PR description
If no other operations are expected on the picking, even if the full quantity wasn't delivered, the order should be marked as invoiced. task-4607401 Fixes #144485 Partial revert of #115871 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218322
This update prevents an error that could appear when opening a partner record after uninstalling an e-invoicing module. It now clears the related e-invoice format reference so users can continue working without seeing a traceback.
Original PR description
Before this fix, if you uninstalled this module and navigated to any partner that had a e-invoice format defined by this module, you'd have a traceback. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr @moduon MT-12168 OPW-5172861
This fix ensures that when a subcontracted product is drop-shipped, its stock valuation does not leave behind leftover values that could distort future costing. It keeps accounting and inventory valuations accurate for FIFO, average cost, and standard cost products.
Original PR description
… correct remaining value when sbc dropship **Problem:** When selling and delivering a subcontracted and dropshipped fifo product, the incoming stock valuation layer has a remaining_qty and a…
… correct remaining value when sbc dropship **Problem:** When selling and delivering a subcontracted and dropshipped fifo product, the incoming stock valuation layer has a remaining_qty and a remaining_value. (This also happens with 'standard price' and 'avco' but it's mostly problematic for fifo products. This being said the fix solves all 3 cases) Some context: When we confirm a SO and validate the delivery of a dropshipped (not sbc) product, two svls are created, - one with a negative quantity and value. - one with positive quantity and value. Both have a zero remaining value and remaining quantity. The outgoing svl does not trigger run_fifo or decrease the remaining_qty and remaining_value on any svl. In other words the fifo logic is not applied. If it was the case, the dropship delivery would impact the fifo valuation and other layers which we don't want as the product never really entered the stock. In the use case of this PR, a subcontracted dropshipped fifo product being delivered, the outgoing svl(s) are linked to the dropship and have the correct values. But the incoming svl is linked to the subcontract order and has a remaining value and remaining quantity which will impact the fifo logic when it shouldn't. **Steps to reproduce:** - enable the subcontracting setting and the dropshipping setting. - create a storable product, with a fifo category and positive cost. - create a subonctracted bom with a consumable component. - in the purchase tab of the product set a vendor which is the same as the subcontractor of the bom. - in the inventory tab select only the dropship route - create and confirm a SO for this product. - on the PO enter a positive unit price and confirm - validate the dropship delivery - click on the valuation smart button **Current behavior:** the stock valuation layer linked to the subcontract picking (the one with a positive quantity) has a positive remaining quantity and remaining value. **Expected behavior:** As the product is dropship remaining quantity and remaining value should be 0 **Cause of the issue:** When action_done is called on the picking: 1) In the super method, action_done is called on the move. There, _create_dropshipped_svl is called. https://github.com/odoo/odoo/blob/3c83171923124c7ea63a4d33262a87cddf004b2b/addons/stock_account/models/stock_move.py#L289 Inside _get_dropshipped_svl_vals only the value for the (first) outgoing svl is returned because the location_id (subcontrating location) is valued. https://github.com/odoo/odoo/blob/3c83171923124c7ea63a4d33262a87cddf004b2b/addons/stock_account/models/stock_move.py#L226 2) In the mrp_subcontracting override, button_mark_done is called on the mrp.production associated with the picking. https://github.com/odoo/odoo/blob/3c83171923124c7ea63a4d33262a87cddf004b2b/addons/mrp_subcontracting/models/stock_picking.py#L90 Therefore action_done is called on the finished products move the mrp.production. https://github.com/odoo/odoo/blob/3c83171923124c7ea63a4d33262a87cddf004b2b/addons/mrp/models/mrp_production.py#L1731 The move is a 'in' move so this lead to the creation of an in svl. https://github.com/odoo/odoo/blob/3c83171923124c7ea63a4d33262a87cddf004b2b/addons/stock_account/models/stock_move.py#L289 The problem is that there is no mechanism to prevent the in svl from having a remaining_value and remaining_qty **fix** The mrp_subcontracting_dropshipping override of _action_done (on stock picking) is where, when needed, the other ougoing layer is created specifically in this subcontracting dropshipping use case. https://github.com/odoo/odoo/blob/3c83171923124c7ea63a4d33262a87cddf004b2b/addons/mrp_subcontracting_dropshipping/models/stock_picking.py#L27-L32 Because the conditions are the same, imo, it's a good place to set the value of remaingin_value and remaining_qty of the incoming svl to 0. opw-5184644 Forward-Port-Of: odoo/odoo#233041
This update makes lot and serial number visibility in the barcode app match the Manufacturing setting for showing reserved lots/SNs. As a result, users only see this information when it is expected, which reduces clutter and lowers the risk of picking or scanning mistakes.
Original PR description
Issue: ------------------------------------- Lots/serial numbers were always displayed in the barcode module during Manufacturing Order operations, regardless of whether the Show Reserved Lots/SNs…
Issue: ------------------------------------- Lots/serial numbers were always displayed in the barcode module during Manufacturing Order operations, regardless of whether the Show Reserved Lots/SNs option was enabled in the Manufacturing settings. Steps to Produce: ------------------------------------- - In Manufacturing settings, disable the Show Reserved Lots/SNs option. - Create a Manufacturing Order and reserve component lots. - Go to the barcode app - Lots/SNs appear even though the Show Reserved Lots/SNs option is disabled. After this Commit: ------------------------------------- A correct value is now passed to the condition controlling the lot and serial number visibility. Lots/SNs are shown only when Show Reserved Lots/SNs is enabled in Manufacturing settings, or when they have been picked or scanned, helping users focus only on relevant information and reducing the chance of picking or scanning mistakes. Task Id: [3908929](https://www.odoo.com/odoo/project/966/tasks/3908929)
Returns for mixed products now go back to the correct supplier location, while subcontracted items still use the subcontracting location. This prevents returned goods from being sent to the wrong place and avoids confusion in supplier handling.
Original PR description
Steps to reproduce the bug: - Create a storable product "P1" and "P2" with vendor "azure interior" - for P2 subcontracting BoM referencing "azure interior" as subcontractor and component "C1" -…
Steps to reproduce the bug: - Create a storable product "P1" and "P2" with vendor "azure interior" - for P2 subcontracting BoM referencing "azure interior" as subcontractor and component "C1" - Create a receipt for partner "azure interior" including 1 unit of P1 and 1 unit of P2 - Validate the receipt - Create a return for both P1 and P2 Problem: A picking is created with destination location set to the subcontracting location for both products, instead of setting the partner location only for subcontracted products. Solution: Ensure only the move line for subcontracted products uses the subcontracting destination location, while other returned products go back to the supplier location. When the `picking_id.partner_id`` is changed, it triggers a write on the picking, which in turn triggers a write on its moves, but only on the ones that are not scrapped. However, since the `scrapped`` field is a stored computed field, and as it hasn't been accessed before, it needs to be computed. And because its computation depends on `location_dest_id`, that field also needs to be recomputed. as a result, the `location_dest_id`` of the moves that we manually set may be changed unexpectedly. Therefore, in the `_create_return`` function, we check that the picking’s `partner_id` is different from the moves’ partner_id before updating it, to avoid unnecessary writes and the chain of recomputations that could alter our values. Resetting the picking’s partner_id based on the move’s partner_id could actually be removed in master, as it serves no real purpose, the move.partner_id itself is already derived from the picking’s partner_id. We just keep it in stable versions to avoid any unexpected behavior changes. opw-5208289
When editing and saving website forms, temporary Turnstile loading elements and disabled states are now removed before the page is saved. This prevents unwanted button changes from being stored and ensures forms still work correctly if the Turnstile module is later removed.
Original PR description
Steps to reproduce: 1. Install the `website_cf_turnstile` module. 2. Enter valid Cloudflare Turnstile credentials in the configuration. 3. Go to the Website Editor. 4. Add or edit a form (e.g. contact form) and save the page. 5. Notice that the form’s submit button temporarily shows a spinner and gets a 'disabled' class while Turnstile is initializing. 6. After saving the page, these temporary elements and classes (e.g. .turnstile-spinner and 'disabled') are incorrectly saved into the form’s HTML. 7. If you later remove or uninstall the website_cf_turnstile module, the submit button remains disabled and the spinner icon still appears, even though Turnstile is no longer active. After this commit: Now, when you save a website form in the editor, any temporary classes or elements added by Cloudflare Turnstile are removed. This prevents unwanted changes from being saved to forms. task-4951470 Forward-Port-Of: odoo/odoo#221841
The search feature now correctly handles words that change length during language normalization, such as in Thai. This prevents search results from being missed or search logic from failing in those cases.
Original PR description
The fuzzy search mechanism (specifically the _match utility) calculates the length of the string before normalizing it (e.g., with `unaccent`). However, `unaccent` can remove non-spacing marks (like Thai tone marks or vowels), which changes the length of the string. This mismatch caused the search loop to iterate past the end of the normalized string, leading to incorrect behavior or potential errors. This commit moves the length calculation to after the string has been unaccented, ensuring the loop has the correct bounds. opw-5189276 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233249
This fixes an issue in the Italian tax export flow that could wrongly block quarterly tax return closings. Quarterly filings can now be posted correctly even when there is no closing entry in the previous month, which restores the expected accounting process for affected companies.
Original PR description
A [previous PR](https://github.com/odoo/enterprise/pull/86642) improved the XML export of tax returns with Italian localization. This introduced a bug if the tax period is set quarterly. Currently, it prevents a tax return move from being posted if it detects previous tax closings, but there are none in the previous month. This should only be the case if the tax period is set monthly. Steps to reproduce on runbot: - Install the l10n_it_xml_export module - Switch to an Italian company and set the tax period to `quarterly` - Create a closing entry for the previous quarter - Try to create a closing entry for the current quarter Related ticket: opw-5156791 Forward-Port-Of: odoo/enterprise#98241