Monday, June 1, 2026
8 changes · saas-18.3
New functionality added to Odoo
This update enables Odoo to comply with new French tax regulations requiring electronic reporting of business transactions. It introduces a system for sending transaction and payment data to the tax authorities in a structured format, specifically for B2C and international B2B sales, ensuring accurate tax reporting and compliance.
Original PR description
France’s electronic invoicing reform : The tax administration needs structured fiscal data for the transactions , either via E-invoicing for the nationals B2B or E-reporting for the international B2B…
France’s electronic invoicing reform : The tax administration needs structured fiscal data for the transactions , either via E-invoicing for the nationals B2B or E-reporting for the international B2B and the B2C. This creates two complementary obligations: - **E-invoicing** for domestic B2B transactions, where the invoice itself is exchanged through the PA/Peppol flow. - **E-reporting** for transactions outside that domestic B2B scope, mainly B2C and international B2B, where transaction and payment data must be reported to the tax administration through Flux 10 (period-based). ## Scope Domestic B2B remains handled by the existing e-invoicing flow, because the invoice exchange already carries the required structured information. Flux 10 is introduced for transactions that must be reported separately: - B2C transactions, where there is no buyer-side e-invoice exchange. - International B2B transactions, where the counterparty is outside the French domestic B2B mandate. - Payment reporting when VAT exigibility depends on collection. The reporting is period-based and keeps transaction reports separated from payment reports, because they answer different legal obligations and follow different timelines. ## Corrections and Lifecycle Flux 10 supports both: - **Initial reports**, for the first declaration of a period. - **Rectificative reports**, when already reported data must be corrected or completed. This distinction is needed so corrections remain traceable instead of silently mutating a report that may already have been transmitted. ## Security and Eligibility This PR also enforces stronger safeguards before using PDP/PA services. - **2FA is required** because PDP/PA actions expose regulated fiscal flows and should not be available from a simple password-only login. Email-based 2FA is available as a fallback when users have not configured an authenticator app. - **KYC is introduced** because a company must be identified and validated before Odoo can transmit documents or reports on its behalf through the PDP/PA infrastructure. Together, these changes make the French PDP/PA flow usable not only for invoice exchange, but also for the wider e-reporting obligations required by the French reform. Task-4603708 Forward-Port-Of: odoo/odoo#239576
Resolved issues and error corrections
This update resolves a problem where users authenticating with Polish PESEL certificates were incorrectly rejected by KSeF. The change expands the matching criteria for certificate identifiers, ensuring existing users with standard certificates continue to function correctly. This prevents authentication errors and maintains seamless operation for our Polish customers.
Original PR description
### Description of the issue/feature this PR addresses: **Issue:** A recent update to support `certificateFingerprint` introduced a regression for existing users authenticating with standard…
### Description of the issue/feature this PR addresses: **Issue:** A recent update to support `certificateFingerprint` introduced a regression for existing users authenticating with standard certificates (AKA `certificateSubject`). Because the matching logic strictly checked for the company NIP within the certificate subject, it failed for users using personal PESEL certificates to act on a company's behalf. **Previous PR:** https://github.com/odoo/odoo/pull/264851 **Solution:** Expanded the string-matching heuristic in the XML signer to strip formatting characters from the NIP and explicitly checks for standard Polish qualified certificate prefixes (VATPL and PNOPL) to accurately get the identifier type. ### Current behavior before PR: When a user logs in via a personal PESEL certificate for a company context, the NIP check fails and miscategorizes the payload as a `certificateFingerprint`. KSeF rejects this mismatch, causing a 400 error for previously working setups. ### Desired behavior after PR is merged: The authentication flow distinguishes between `certificateSubject` and `certificateFingerprint` by checking for valid Polish prefixes or exact cleaned NIP matches. Existing customers are restored to working order natively, and new customers using manual fingerprints are still supported without requiring any database or UI changes. opw-6251153 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267060
This update resolves an issue where dropshipping orders incorrectly displayed a negative delivered quantity. The change introduced a new feature for returns, which caused a default setting to add incoming stock moves to the calculation, leading to a -1 quantity. This fix restores the correct delivery quantity by reverting a previous change.
Original PR description
Currently, an error occurs when the user receives a dropship order instead of delivering it directly to the customer. As a result, the sale order shows a negative delivered quantity. ## Steps to…
Currently, an error occurs when the user receives a dropship order instead of delivering it directly to the customer. As a result, the sale order shows a negative delivered quantity. ## Steps to replicate: - Install Sales, Inventory, and Purchase. - Enable Dropshipping from Inventory settings. - Create a test product with the Dropship route enabled and set a vendor for it in the Purchase tab. - Create and confirm a quotation for a customer. - Go to Purchase > `Deliver To:` and set it to `My Company: Receipts.` - Confirm the Purchase Order and validate the receipt. - Go back to the Sale Order. ## Observed Behavior: The delivered quantity is -1, which is incorrect because the customer has not returned any products, nor has the user created a sale order line with a negative quantity (which would indicate a return). ## Root cause: When computing the delivered quantity at [1], the function `_get_outgoing_incoming_moves` [2] is called to retrieve the incoming and outgoing stock moves associated with the sale order lines. Inside this function, moves are filtered and categorized as incoming or outgoing. At [3], the condition is satisfied because the default value of `to_refund` is `True`, so the move is added to `incoming_move_ids`. Later, during the computation at [1], the code iterates through the incoming moves and subtracts their quantities from the delivered quantity. Since the initial delivered quantity is 0, including such a move in `incoming_move_ids` causes the delivered quantity to become -1. <h3> Why did this behavior not occur in lower versions?:</h3> This issue was introduced by [commit], which added the functionality for users to return products that are not listed in the purchase order. As a result, their quantities appear as negative received quantities on the purchase order. Before this change (in saas-18.2), the field `move.to_refund` had a default value of `False`. Because of this, the condition at [3] was not satisfied, and the move was not included in `incoming_move_ids`. Therefore, it was not subtracted when iterating through incoming moves, and the delivered quantity did not become negative. Starting from 18.3, the default value of `to_refund` was changed to `True`. This causes the condition at [3] to be satisfied, the move to be included in `incoming_move_ids`, and its quantity to be subtracted during the computation, resulting in a delivered quantity of -1. [1]- https://github.com/odoo/odoo/blob/1256875226436a854558a1334ffdc886fa4767a8/addons/sale_stock/models/sale_order_line.py#L193-L209 [2]- https://github.com/odoo/odoo/blob/1256875226436a854558a1334ffdc886fa4767a8/addons/sale_stock/models/sale_order_line.py#L316-L353 [3]- https://github.com/odoo/odoo/blob/1256875226436a854558a1334ffdc886fa4767a8/addons/sale_stock/models/sale_order_line.py#L346-L351 ## Solution: We can make the condition stricter by ensuring that only incoming moves that are actual returns are counted as negative in the quantity delivered on a sale order. Specifically, if an incoming move has no corresponding originating return move and the customer has not created a sale order line with a negative quantity (which could also indicate a return), it should not be considered when calculating the delivered quantity. [commit]: https://github.com/odoo/odoo/pull/209110/changes/c1c86182e4b28e929bf56e79f57f33aaa13e67f1 opw-5933594
This update significantly speeds up partner searches within the Point of Sale (POS) system. Previously, searching through a large number of partners was slow due to rendering all results. Now, the system limits the displayed results to 200 and adjusts the search input's delay to reduce unnecessary calls, resulting in a faster and more responsive user experience.
Original PR description
Before this commit, when high number of partners were loaded in the POS, searching for a partner was slow. The main issue was that all of the filtered partners based on the search query were being rendered, while in reality, if a query returns lots of results, the search query is not refined enough and the user is likely to type more characters to narrow down the search. So in this commit, we limit the number of rendered partners to 200, which is a reasonable number of results to display and does not cause performance issues. Moreover, the debounce time of the search input has been increased from 100ms to 500ms to further reduce the number of times the search function is called while the user is typing. opw-6215958 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265598 Forward-Port-Of: odoo/odoo#264300
This update fixes an issue where credit limit warnings incorrectly flagged customers as exceeding their limits when outstanding bank payments were present. Now, the system accurately considers bank payments in its calculations, ensuring warnings only appear when the total outstanding amount exceeds the credit limit. This improves accuracy and prevents unnecessary alerts for customers.
Original PR description
Before this PR: - The credit limit warning calculation only considered credit notes but ignored outstanding bank payments. For example, if a customer had a credit limit of 100,000 and created an invoice for 200,000, then paid 150,000 via bank payment, the warning would still appear incorrectly showing the customer exceeded their limit (200,000 > 100,000), even though the actual outstanding amount was only 50,000. After this PR: - The credit limit warning now properly includes outstanding bank payments in the calculation. Using the same example, after a 150,000 bank payment, the system correctly recognizes the outstanding amount as 50,000 and does not show a warning since it's within the 100,000 credit limit. task-5427613
This update corrects an error in the Peru - Accounting Reports module that was causing the SUNAT/SIRE system to reject DAM reports. Specifically, the report was incorrectly including too much data in field 8, leading to rejection. The fix ensures that only the required 3-digit customs dependency code is used, aligning with SUNAT regulations.
Original PR description
**Steps to reproduce:** * Install Peru - Accounting Reports (l10n_pe_reports). * Create a vendor bill with Document Type 50 (Declaración Aduanera de Mercancías - DAM) and a document number in the…
**Steps to reproduce:** * Install Peru - Accounting Reports (l10n_pe_reports). * Create a vendor bill with Document Type 50 (Declaración Aduanera de Mercancías - DAM) and a document number in the standard pediment format (e.g. C235202610-38047). * Go to Accounting > Reporting > Purchase Electronic Record (RCE 8.4). * Export the TXT file and open it. **Observed behavior:** * Field 8 contains the full first numeric block of the document name including the year and sequence digits (e.g. 235202610) instead of only the 3-digit customs dependency code. * SUNAT/SIRE rejects the file immediately because 235202610 does not exist in Table 4 (RS 040-2022), which only defines 3-digit codes. **Cause:** * `_get_serie_folio()` splits the document name by taking everything before the last digit group as the serie. For a name like C235202610-38047 this produces serie = "C235202610", and the existing `serie[1:]` logic strips only the leading letter, leaving "235202610" in field 8 instead of the 3-digit customs dependency code "235". * The same incorrect value was also written to field 28 (aduana_code). * ref : https://www.sunat.gob.pe/legislacion/superin/2022/anexo-040-2022.pdf **Fix:** * For document types 50 and 52, extract the first numeric group from the document name using `re.search(r'\d+', move_name)` and slice the first 3 characters to obtain the customs dependency code as defined in SUNAT Table 4 (always a 3-digit value). * Apply the same logic to field 28 (aduana_code) for consistency. opw-6157662 Forward-Port-Of: odoo/enterprise#115406
This update fixes an issue where intercompany sales and purchases with multiple identical products resulted in incorrect stock reservation during receipt picking. Specifically, the system was failing to properly reserve all units of a product when creating intercompany transactions with multiple lines. This change ensures accurate stock tracking and prevents discrepancies in inventory levels between companies.
Original PR description
…lit for same-product lines When doing an intercompany Sale->Purchase with multiple lines having the same products, the receipt picking would be incorrectly assigned: - Enable Inter-Company…
…lit for same-product lines
When doing an intercompany Sale->Purchase with multiple lines having the same products, the receipt picking would be incorrectly assigned:
- Enable Inter-Company Transactions on both companies (Create and validate)
- Create SO in company A to company B with 2 lines having the same product P, Confirm. => Delivery in company A, Purchase and Receipts in company will be created => The SO/PO/Delivery/Receipt will all have 2 lines
- Validate delivery => On the receipt, the 2 units of P are reserved on the 1st move, and the 2nd move is not reserved.
https://github.com/user-attachments/assets/b4816051-120e-4226-9228-fd552649d5ef
---
### Test result without fix:
```
2026-04-23 13:16:44,577 48027 INFO oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: Starting TestInterCompanySaleToPurchaseWithStock.test_02_inter_company_multiple_lines_with_same_product ...
2026-04-23 13:16:44,949 48027 INFO oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: ======================================================================
2026-04-23 13:16:44,949 48027 ERROR oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: FAIL: TestInterCompanySaleToPurchaseWithStock.test_02_inter_company_multiple_lines_with_same_product
Traceback (most recent call last):
File "/home/odoo/Odoo/src/18.0/enterprise/sale_purchase_stock_inter_company_rules/tests/test_inter_company_so_to_po.py", line 109, in test_02_inter_company_multiple_lines_with_same_product
self.assertRecordValues(purchase_from_a.picking_ids.move_ids, [
File "/home/odoo/Odoo/src/18.0/odoo/odoo/tests/common.py", line 709, in assertRecordValues
self.assertSequenceEqual(expected_reformatted, record_reformatted, seq_type=list)
AssertionError: Lists differ: [{'pr[18 chars]0, 'quantity': 1.0}, {'product_uom_qty': 1.0, 'quantity': 1.0}] != [{'pr[18 chars]0, 'quantity': 2.0}, {'product_uom_qty': 1.0, 'quantity': 0.0}]
First differing element 0:
{'product_uom_qty': 1.0, 'quantity': 1.0}
{'product_uom_qty': 1.0, 'quantity': 2.0}
- [{'product_uom_qty': 1.0, 'quantity': 1.0},
? ^
+ [{'product_uom_qty': 1.0, 'quantity': 2.0},
? ^
- {'product_uom_qty': 1.0, 'quantity': 1.0}]
? ^
+ {'product_uom_qty': 1.0, 'quantity': 0.0}]
? ^
```
OPW-6145683
Forward-Port-Of: odoo/enterprise#118548
Forward-Port-Of: odoo/enterprise#114873This update resolves a bug where cancelled journal entries were incorrectly displayed in the reconciliation view, preventing successful reconciliations. The fix removes a previous refactor that inadvertently allowed cancelled entries to appear, ensuring accurate reconciliation processes.
Original PR description
Issue: Cancelled journal entries were visible in the "Journal Items to Reconcile" view (action_move_line_posted_unreconciled) because the action domain had no filter to exclude them. This caused…
Issue: Cancelled journal entries were visible in the "Journal Items to Reconcile" view (action_move_line_posted_unreconciled) because the action domain had no filter to exclude them. This caused reconciliation failures, no reconciliation happened, and the cancelled record remained in the view. This regression was introduced during a refactor to allow draft entries in the reconciliation view, where the posted-state condition was removed from the domain: Enterprise commit: https://github.com/odoo/enterprise/commit/003cffabda7d91a6d10d58942ed972ca5e17366d As a result, cancelled journal items also became visible, causing reconciliation attempts to fail while the records remained in the view. Also, we are not allowed to reconcile cancelled move lines, and we already have the validation for this [here](https://github.com/odoo/odoo/blame/a236f67776616f6facdefb0117a6ffdde9b7c84c/addons/account/models/account_move_line.py#L2627) Issue is reproducible on runbot. Here is the video reference: https://drive.google.com/file/d/1ojIDxHn5Yst8gVFy8JyhwtJoDSSSJsmK/view?usp=sharing - OPW: 6247870 Forward-Port-Of: odoo/enterprise#118773