Monday, July 27, 2026
12 changes · saas-19.4
Resolved issues and error corrections
This fixes Peppol settings so companies are only required to choose a purchase journal when it is actually needed. Non-French companies using Documents for Peppol imports are no longer blocked by French PDP-related requirements, and imports go to the selected destination only.
Original PR description
Fixes the settings view for the account_peppol_purchase_journal_id. account_peppol, documents_account_peppol and l10n_fr_pdp all wants to use a specific condition for the required attribute of the view. With PDP especially, once l10n_fr_pdp is installed, the view forces the base condition, even if documents_account_peppol is installed, and even if the company is not even French. On a non-French company registered/registering on Peppol, the journal shouldn't be mandatory if documents_account_peppol_folder_id is set up. To ease things up, it is now using a computed field. task-6304479 Forward-Port-Of: odoo/enterprise#120721 Forward-Port-Of: odoo/enterprise#120717
This fix keeps existing tax returns consistent when their allowed workflow steps are changed, such as during upgrades. It prevents errors in return lists by moving returns out of statuses that are no longer allowed and ensuring required workflow settings are present.
Original PR description
To reproduce the issue: 1) Create a company in Belgium 2) Instantiate its returns and review, submit and pay one of the VAT returns 3) Change the states_worklfow of the VAT return so that it only…
To reproduce the issue: 1) Create a company in Belgium 2) Instantiate its returns and review, submit and pay one of the VAT returns 3) Change the states_worklfow of the VAT return so that it only accepts "review" and "submit" stages, not "paid" anymore 4) Go to the list of returns, remove the TODO filter => traceback The problem is here that the existing returns don't recompute their state when the workflow of the type is modified. In some cases, this is fine, but it others, it's annoying. In our example, the terminal state changed, so all the returns in that terminal stage should change their state to the new terminal one. "paid" is not an accepted value anymore, it should become "submitted". Moreover, when the workflow is changed, the selection field actually containing the state must also change. As it is, it seems to work because "state" of account.return is stored, but the value it's based on (the workflow field) won't be consistent with it. It's not annoying now, but those inconsistencies could become a big source of trouble in the future (we know that from experience ... I'm looking at you, version 8 ! è-é). This issue typically happens at upgrade. We had cases in FR and AE already. We solve that by a generic override of the write to sort things out when such change needs to happen. An upgrade PR will also be done to adapt the script so that we eventually solve the inconsistencies on dbs that have already migrated to 19.0. Forward-Port-Of: odoo/enterprise#124934 Forward-Port-Of: odoo/enterprise#124144
This fix prevents an access error when an authorized manufacturing user edits a manufacturing order linked to a sales order they are not allowed to view. It keeps production work moving while preserving sales document access restrictions.
Original PR description
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a…
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue: Writing on the `move_raw_ids` will trigger a call of the `_autoconfirm_production` in order to confirm the newly created move: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L990-L991 https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L1422-L1423 During this confirmation process, one calls the `_merge_moves` method in order to merge this new move (if relevant) to any already existing one. https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/stock/models/stock_move.py#L1575-L1576 Now, the issue is that, `sale_stock_renting` module overrides the method `_prepare_merge_moves_distinct_fields` determining the fields relevant to the merge by requiring a read access to the `is_rental_order` compute field of the `sale_order` linked to the MO: https://github.com/odoo/enterprise/blob/b66097122ba3a758734ac6fb2b26579c35cb72c2/sale_stock_renting/models/stock_move.py#L34-L40 However, due to the 'Personal Orders' ir.rule, the user does not have a read access to this record: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/sale/security/ir_rules.xml#L44-L49 Community: https://github.com/odoo/odoo/pull/271017 opw-6275658 Forward-Port-Of: odoo/enterprise#121845 Forward-Port-Of: odoo/enterprise#121135
The barcode app now correctly finds manufacturing orders that were split into multiple related orders. This prevents users from seeing a false “not found” error when scanning the original manufacturing order name, keeping shop floor workflows moving smoothly.
Original PR description
### Steps to reproduce: - Create a product FP with a BOM: 1 X COMP (enough units in stock) - Create and confirm an MO for 3 units - Click on the cog wheel icon > Split the MO in 3 - On the barcode app > Operations > Manufacturing - Scan the name of your base MO #### > Error: No product or order found for barcode ... ### Expected behavior: Scanning an existing MO only adds its barcode as a `search_default_name`: https://github.com/odoo/enterprise/blob/598a8e335605fd68e3ceb5c1170864243426f994/stock_barcode_mrp/models/mrp_production.py#L162-L178 However, while this search is performed with an ilike, we only check the existence of an exact match before raising an error, which does not happen since our splitted MOs have a name: barcode-001, barcode-002, barcode-003,... opw-6376937 Forward-Port-Of: odoo/enterprise#123931
French VAT declarations now handle SIRET numbers that include spaces, reducing failed submissions caused by formatting differences. Users are also warned when bank account numbers appear incorrectly formatted, helping prevent submission errors before they happen.
Original PR description
This commit resolves an issue where VAT declarations failed when the provided SIRET number included spaces. Since check_siret verifies the format, we now strip all spaces from the input. Additionally, this commit introduces a validation for bank account numbers, ensuring that we warn the user if the account number is wrongly formatted. task-6253745 Forward-Port-Of: odoo/enterprise#125311 Forward-Port-Of: odoo/enterprise#120689
This fixes a display issue where Avalara tax fields could be hidden on contact and product forms when company and country information included both US and Canada. Businesses using Avalara can now see and manage the relevant tax codes and exemption details more reliably.
Original PR description
**Steps to reproduce:**
- Install Accounting and account_avatax
- Use a US company (by default)
- Create a contact with Canada as country
**Issue:**
In "Sales & Purchase" tab, all the fields from avatax module are not displayed (i.e. "Avalara Code", "Avalara Partner Code", "Avalara Exemption").
**Cause:**
The `invisible` property of those fields is using `fiscal_country_codes` char field.
If no company is set on the record, `fiscal_country_codes` will contain the country code of the selected companies in addition to the country code of the record.
In this case, the value of `fiscal_country_codes` will be `US,CA` string, which triggers `fiscal_country_codes not in ('US', 'CA')` invisible condition.
opw-6328395
Forward-Port-Of: odoo/enterprise#124619This fix restores the validation workflow for Indian GSTR tax returns after a parent view change broke the return screen. Users can continue validating GSTR returns with the expected dedicated process, while the interface now uses the updated shared validation button structure.
Original PR description
Fixed the broken view for indian tax returns due to parent view refactor. Update the Indian GSTR return workflow to: - adapt the kanban button inheritance to the new view structure, - preserve the custom GSTR Validate button independently of unresolved checks, - Keep the GSTR-specific validation workflow unchanged. - remove indian loc specific validate button instead use from parent. - some code cleaning. task-6365198
This fix ensures Saudi GOSI contributions are calculated without being incorrectly prorated. It helps payroll teams produce more accurate payslips and accounting entries for employees covered by Saudi payroll rules.
Original PR description
task-id: 6380239 Forward-Port-Of: odoo/enterprise#124807 Forward-Port-Of: odoo/enterprise#124122
This fix ensures Brazilian Avalara tax requests keep required customer tax settings even when their values are empty or false. It prevents Avalara from assigning the wrong fiscal operation code, helping invoices use the correct Brazilian tax treatment.
Original PR description
## Steps to reproduce: 1. Install `l10n_br`, `l10n_br_avatax`, and `l10n_br_edi_fiscal_reform`. 2. Ensure that Demo mode is activated if not on Runbot. 3. Navigate to Contacts, then click into "BR…
## Steps to reproduce:
1. Install `l10n_br`, `l10n_br_avatax`, and `l10n_br_edi_fiscal_reform`.
2. Ensure that Demo mode is activated if not on Runbot.
3. Navigate to Contacts, then click into "BR Company Customer Estimated Profit".
4. Duplicate this contact, then set the following fields:
1. Tax Regime set to individual
2. ICMS Taxpayer Type set to Non-Taxpayer
5. Swtich to the BR Company and go to Accounting / Configuration / Settings.
6. Set up a Sandbox Avalara account and enable logging payload responses.
7. Navigate to Accounting > Customers > Invoices.
8. Create an invoice with:
1. Customer set to the copy created earlier.
2. Operation Type set to Sale of Goods
3. Document Type set to 55
4. Payment Method Brazil set to Money
5. Presence set to Present
6. One sales order line with:
1. Regular Consumable Product
2. quantity set to 1
3. price set to 100.0
9. Confirm the invoice.
10. Navigate back to Accounting > Configuration > Settings to view the response from Avalara. The customer will have the CFOP 6102 instead of CFOP 6108.
Explanation:
PR #97845 introduced `_l10n_br_deep_clean_dict()` to remove falsy values and empty dictionaries from the payload we send to Avalara. This fix was applied as broadly as possible to prevent excessive if statements.
However, if the falsy values in taxSettings of the customer are not communicated, Avalara will assign the customer to an incorrect CFOP.
opw-6085964
Forward-Port-Of: odoo/enterprise#124730
Forward-Port-Of: odoo/enterprise#120783Users who start an AI chat can still be prompted to reopen their most recent relevant conversation after refreshing the page. This makes it easier to continue prior AI interactions while avoiding duplicate prompts when that chat is already open.
Original PR description
Purpose: -------- When launching an AI chat, users can be suggested to reopen the latest non-empty chat matching the same interface key and record. This suggestion used to rely on chats already present in the frontend store, so it was lost after a page reload. With this commit, the suggested channel is selected by the backend whenever the AI channel is added to the store and included in its channel data. This keeps the suggestion available after a page reload while hiding it when the previous chat is already open, but not when it is minimized. Task-6354153
Export invoices in Uruguay can now correctly show discounts that reduce the invoice total to zero. This helps exporters meet electronic invoicing validation requirements while still declaring the value of goods or services.
Original PR description
## Problem When generating an export CFE (e-Factura Exportación) in the Uruguayan EDI module, invoices that include a discount line equal to the subtotal — resulting in a **total of 0.00** — were not…
## Problem When generating an export CFE (e-Factura Exportación) in the Uruguayan EDI module, invoices that include a discount line equal to the subtotal — resulting in a **total of 0.00** — were not handled correctly by the XML/CFE generation logic. This use case is valid and required by exporters who need to reflect the declared value of goods/services while invoicing at zero (e.g. to comply with customs or incoterm requirements such as FCA). In Uruware's validation portal, the "Descuentos y Recargos" (discounts & surcharges) section of the subtotal block must be correctly populated for the CFE to be accepted. **Example:** An invoice with a line of 648.00 UYU and a global discount of −648.00 UYU → Total: 0.00. The export value is still declared, taxes are zero, but the CFE must reflect the discount amount explicitly. <img width="592" height="679" alt="example_expo_invoice_discount" src="https://github.com/user-attachments/assets/aa83c158-e342-4da5-a251-fc209bbed5c4" /> ## Root Cause The CFE template (`cfe_template.xml`) and the move computation logic (`account_move.py`) did not account for the case where export invoices carry line-level or global discounts that zero out the total. The discount amount was either omitted from the XML nodes or computed incorrectly, causing Uruware validation to fail or the discount block to not render. ## Fix - **`l10n_uy_edi/models/account_move.py`** — Updated the export invoice computation to correctly include discount amounts in the CFE data dict, ensuring the `ValorDR` is filled with the value of the discount per line. - **`l10n_uy_edi/views/cfe_template.xml`** — Adjusted the template condition so `MntExpoyAsim` node accepts 0 as value. ## Steps to Reproduce (before fix) 1. Create an export invoice (e-Factura Exportación) for a foreign partner. 2. Add a product line with a unit price, e.g. 216.00 × 3 = 648.00 UYU. 3. Add a global discount of 648.00 (same amount) so the total is 0.00. 4. Confirm and send to Uruware — the CFE is rejected / discount block is missing. ## Verification After the fix, the same invoice generates a valid CFE accepted by Uruware with the discount correctly reflected in the `DscRcgGlobal` node and the discount line visible on the printed document. Forward-Port-Of: odoo/enterprise#124910 Forward-Port-Of: odoo/enterprise#120130
This fixes where Mexican CFDI invoice fields are placed so they remain visible even when Colombian e-invoicing features are also installed. It prevents important Mexican invoice information, such as CFDI Origin, from disappearing due to module layout conflicts.
Original PR description
The CFDI fields used //sheet/group//group[last()], which targets the last group by position. Once l10n_co_edi adds its group after header_right_group, the fields land in it instead, and it is invisible unless country_code is CO, so CFDI Origen disappears on MX invoices. Use //group[@id='header_right_group'], like l10n_co_edi already does, so placement no longer depends on what modules are installed. Task Adhoc side: 67269 Forward-Port-Of: odoo/enterprise#124545