Daily updates from Odoo
Thursday, June 25, 2026
21 changes · 18.0
Enhancements to existing features
The option to send a PDP response is no longer shown as a large button on the invoice/bill screen. It is now available in the settings menu, since canceling and reposting a document already triggers the same result and the interface is less cluttered.
Original PR description
No real need to show a big button for sending a response in PDP as cancelling and posting an invoice/bill would do the same, so we move it to the cog wheel menu task-6274220
The PDP registration flow now allows the contact email to be edited during signup, which avoids blocking users who need to correct it. It also adds an extra verification check to prevent impersonation and resets the KYC status when a participant is deregistered, so the process can be restarted if needed.
Original PR description
It seems the readonly can cause some problem because the user might want to change it during the registration. Also adding the hash signed to the connect route to make sure nobody can impersonate the kyc Also clicking on the button_deregister_pdp_participant action will now reset the kyc status so that you can do it again if needed. task-626574 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update makes French e-invoicing setup clearer and more proactive during invoice sending and registration. It now guides French companies toward the PDP module when needed, updates the wording to better explain local e-invoicing instead of generic Peppol language, and simplifies the registration flow by showing key fields earlier and completing registration automatically after verification.
Original PR description
#### [IMP] account_peppol,l10n_fr_pdp: rework PDP registration If PDP is not installed but Peppol is installed we suggest installing the PDP module for French companies - in the send & print instead…
#### [IMP] account_peppol,l10n_fr_pdp: rework PDP registration
If PDP is not installed but Peppol is installed we suggest
installing the PDP module for French companies
- in the send & print instead of the following warnings
- "You can send this invoice electronically via Peppol." (what is peppol)
- "partner has requested electronic invoices reception on Peppol."
- in the send & print for any French company that is not on PDP
(this warning can be disabled by setting the system parameter
`account_peppol.disable_pdp_warning` to true)
- in the peppol registration wizard by adding a warning
If PDP is installed we make the following changes to the send & print
- change the wording mentioning "Peppol" to mention the French e-invoicing instead
- make a PDP version of the "Peppol Info" (`account_peppol.WhatIsPeppol`)
- it explains what French E-Invoicing is
- it provides a button to open the registration wizard
- in case the company is registered on Peppol it deregisters the
company first (just like the "complete registration" button)
- display the "You can send this electronically via Peppol" warning
also for French companies (with the wording and "Peppol Info" mentioned above)
- It is displayed in case we are opening the Send & Print wizard from a French
company for a partner on peppol but the "Peppol" / "French
E-invoicing" checkbox is not checked
- Change the wording of the French company non-PDP warning to encourage
the user to register
In the PDP registration wizard
- make all the fields visible directly (already at the start of the KYB/KYC)
- make the SIREN part of the identifier readonly
- make the fields readonly after the verification
- automatically "validate" / register to PDP when we receive the KYC success
task-6320246
#### [IMP] l10n_fr_pdp: add system param for kyc siren
After the previous commit it is not really possible anymore
to use a different SIREN for the KYC than the one in the pdp identifier.
This is because:
- We derive the SIREN directly from the
Identifier in the registration wizard.
- The registration will be validated automatically after the KYC
- The values are readonly after the KYC in any case
That is a problem for testing because we have 1 SIREN to test the
KYC and it is independent from the identifiers provided by the French
datasets for the PDP test environment.
task-NoneResolved issues and error corrections
This change prevents in-page anchor links in emails from being converted into tracking redirects. As a result, links like "#section" keep working correctly when recipients open the final sent message, instead of sending them to the website home page.
Original PR description
When a mailing is sent, its body is run through _shorten_links to turn links into /r/ tracking URLs. find_links_with_urls_and_labels in addons/link_tracker/tools/html.py prepends the base URL to any…
When a mailing is sent, its body is run through _shorten_links to turn links into /r/ tracking URLs. find_links_with_urls_and_labels in addons/link_tracker/tools/html.py prepends the base URL to any href starting with /, ? or #, so a fragment only anchor such as #section becomes http://host#section and is shortened into a tracking link. A recipient clicking it lands on the website home instead of the section, so the in-page navigation inside the email no longer works. Send Test does not shorten links, so the anchor still works when sending a test. Only the real send shortens links, which is why the anchor works in the test but breaks once the mailing is actually sent. link.tracker.create already refuses URLs starting with ? or # because they point to the current page, but prepending the base URL first turns them into absolute URLs that get past that check. https://github.com/odoo/odoo/blob/deeecf7cd02e/addons/link_tracker/models/link_tracker.py#L181-L182 find_links_with_urls_and_labels now skips hrefs starting with # or ?, the same set link.tracker.create rejects, so only paths starting with / are made absolute and tracked. The check sits in the shared helper so every caller of the shortener gets it. Anchor links are left as written. Steps to reproduce: 1. Open Email Marketing and create a mailing, set its recipients to a list containing your own address. 2. Add a button in the body, open its link options and set the URL to #section. 3. Send the mailing. 4. Open the received email and check the button link. => the anchor is a /r/ tracking link that redirects to the website home instead of the section Ticket [link](https://www.odoo.com/odoo/project.task/6310081) opw-6310081
Importing certain valid UBL invoice lines with zero quantity and zero value will no longer fail. These empty lines are now skipped automatically, which prevents the invoice import from stopping with an error message.
Original PR description
### Issue: Importing a UBL invoice containing a line with `LineExtensionAmount=0`, `InvoicedQuantity=0` and a non-zero `PriceAmount` failed with a `ZeroDivisionError`, reported in the chatter as an…
### Issue: Importing a UBL invoice containing a line with `LineExtensionAmount=0`, `InvoicedQuantity=0` and a non-zero `PriceAmount` failed with a `ZeroDivisionError`, reported in the chatter as an import error Such lines are valid UBL but carry no meaningful value, so they are silently skipped after the fix ### Cause: After this commit: https://github.com/odoo/odoo/commit/a7f77f3cfc42764328e7da73a60df8d4cafc968f The `line_extension_amount` was able to go in new parts of the code with a 0.0 value When `line_extension_amount` is set and `invoiced_quantity` is 0, `quantity` is computed as `subtotal * price_quantity / (...)` which resolves to 0 since `subtotal` is also 0 `price_unit = subtotal / quantity` then divides by zero ### Steps to reproduce: - Install `l10n_be` - Import a UBL invoice with a line where `LineExtensionAmount=0`, `InvoicedQuantity=0` and `PriceAmount` is non-zero (You can use the xml on the ticket) Before the fix, the import failed with an error in the chatter opw-6234453
This update corrects a test case that used an invalid Belgian VAT number, which started failing after a stricter validation update in a supporting library. The test still checks for a VAT mismatch, but now uses a valid VAT number so it remains reliable across environments.
Original PR description
This commit fixes a Belgian VAT validation check in `test_import_partner_retrieval_bank_account_number` as the provided vat number isn't a valid one. It keeps the spirit of the test by still having vat number mismatch, but with a valid value. The python-stdnum library used for this validation added a stricter check since version 2.2, which is used in Ubuntu Resolute 26.04. References: - https://github.com/arthurdejong/python-stdnum/commit/7ca9b6ce7b1f2b4d1bf164c2af83a8a77bc919d2 runbot-939796
Confirmed purchase orders now let users edit the line description consistently, even when the product column is visible. This fixes an inconsistency that previously blocked edits in one view but not another, improving day-to-day purchase order handling.
Original PR description
Steps to reproduce the bug: - Create and Confirm a purchase order with any product and a description (name) on the order line - Try to edit the description (name) field Problem: The description field…
Steps to reproduce the bug:
- Create and Confirm a purchase order with any product and a description (name) on the order line
- Try to edit the description (name) field
Problem:
The description field was not editable on a confirmed purchase order when the product_id column was visible, but became editable when product_id was hidden.
The `ProductLabelSectionAndNoteField` widget renders both `product_id` and the description (`name`) in a single cell. When `props.readonly` is true (because `product_id` has `readonly="state in ('purchase', 'to approve', 'done', 'cancel')"`) and the order state is not draft (`isProductClickable` is true), the template rendered the description textarea with a hardcoded `readonly="1"` attribute, making it impossible to edit regardless of the actual intended readonly state for the description.
When `product_id` was column-invisible, the `name` field rendered via its own `section_and_note_text` widget, which correctly used `sectionAndNoteIsReadonly` (blocking only `cancel`, `done`, `posted`) hence the inconsistency.
Solution:
Replace `readonly="1"` with `t-att-readonly="sectionAndNoteIsReadonly"` on the description textarea so its editability follows the same logic as the other cases: blocked only for terminal states (`cancel`, `done`, `posted`), not for `purchase` or `to approve`.
opw-5474986The GSTR-1 spreadsheet now reports the invoice value for SEZ invoices in Indian Rupees instead of the foreign invoice currency. This makes the export consistent with company currency and avoids incorrect return figures.
Original PR description
Currently, when generatign GSTR-1 return spreadshee, SEZ invoices issued in a foreign currency are exported with their totals in the foreign currency rather than the company currency (INR) Steps to reproduce: - Create a B2B SEZ invoice in foreign currency - Go to Accounting > Reporting > [India] GST Return periods - Generate the GSTR-1 report for the period Issue: In the resulting spreadsheet, the "Invoice Value" column takes the invoice total in USD rather then INR opw-6292913 Forward-Port-Of: odoo/enterprise#121157
This update enables the automatic sending of a ‘payment_sent’ message (CDV 211) from purchase invoices through the PDP. Previously, this notification was only available for sales invoices. This ensures suppliers are promptly informed of payment status, streamlining the financial process and improving data accuracy.
Original PR description
## Summary - Enable outbound CDV 211 (`payment_sent`) from purchase invoices in `l10n_fr_pdp`. - Wizard exposes `payment_sent` for purchase documents with MPA payload and payment date. - Cron sends…
## Summary - Enable outbound CDV 211 (`payment_sent`) from purchase invoices in `l10n_fr_pdp`. - Wizard exposes `payment_sent` for purchase documents with MPA payload and payment date. - Cron sends PD for sales and `payment_sent` for purchases; lifecycle residual computed separately per type. ## Multi-repo issues - odoo/odoo#268018 — CDV 211 `payment_sent` on purchase bills ## Related PRs - *(Odoo CE only — no Akretion/OCA changes for this campaign)* ## Test plan - [ ] `odoo-bin -d test --test-tags=/l10n_fr_pdp:TestPdpMessages.test_purchase_payment_sent_lifecycle --stop-after-init` ## Merge order 1. Merge this PR on `odoo/odoo` 18.0 when approved. ## Reviewers & code owners - Requested review: @smetl @chklop - PDP / lifecycle context: @malb-odoo @baje @videc @sveaw --- ## Résumé - Émission sortante du CDV 211 (`payment_sent`) depuis les factures fournisseur dans `l10n_fr_pdp`. - Assistant : `payment_sent` sur les achats avec charge MPA et date de paiement. - Cron : PD pour les ventes, `payment_sent` pour les achats ; résidu de cycle de vie calculé séparément. ## Issues multi-dépôts - odoo/odoo#268018 — CDV 211 `payment_sent` sur factures fournisseur ## PR associées - *(Odoo CE uniquement — pas de changement Akretion/OCA)* ## Tests - [ ] `odoo-bin -d test --test-tags=/l10n_fr_pdp:TestPdpMessages.test_purchase_payment_sent_lifecycle --stop-after-init` ## Ordre de fusion 1. Fusionner cette PR sur `odoo/odoo` 18.0 après revue. ## Revue & auteurs du code - Review demandée : @smetl @chklop - Contexte PDP / cycle de vie : @malb-odoo @baje @videc @sveaw Fixes #268018
This update resolves an issue where importing UBL files containing invoice lines with zero quantity and amount would cause a division-by-zero error, leading to import failures. The fix ensures the system handles these zero-value lines correctly, improving the reliability of UBL import processes.
Original PR description
**PROBLEM** When importing a ubl with a line with an invoiced qty of 0 and an amount of 0, there is division by zero. **STEP TO REPRODUCE** 1. upload a ubl file with an empty line as a vendor bill (there is one in the bugfix ticket). 2. notice the import fails because of a division by zero. The division by zero was introduced by https://github.com/odoo/odoo/pull/265261 opw-6260558
This update corrects a test failure within the French invoicing module (l10n_fr_pdp) that occurred when only the basic Invoicing module was installed. The fix adds the necessary 'in_payment' state, which was present in the full 'enterprise' version of the Accounting module. This ensures the test suite runs correctly and avoids potential disruptions.
Original PR description
The `in_payment` state does not exist in community with only the Invoicing module installed. It is added in `enterprise` in the Accounting module. runbot.build.error-939451
This update corrects a previous issue where the GT Document Type field was incorrectly required when creating vendor bills for vendors outside of Guatemala. The change ensures the field is only mandatory for Guatemalan vendors, streamlining the billing process and improving usability for international transactions. This resolves a user experience problem.
Original PR description
Currently, the GT Document Type field is required when creating vendor bills for non-Guatemalan vendors. **Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a GT Company. -…
Currently, the GT Document Type field is required when creating vendor bills for non-Guatemalan vendors. **Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a GT Company. - Create a new vendor bill for a vendor whose country is not Guatemala. **Observation:** The `GT Document Type` field is required even though the selected vendor is not based in Guatemala. **Root Cause:** At [1], `_compute_l10n_gt_edi_available_doc_types` only checks the company country and ignores the vendor's country, causing GT available document types to be computed for foreign vendors as well. As a result, `l10n_gt_edi_available_doc_types` is populated and the view at [2] incorrectly makes `l10n_gt_edi_doc_type` required. **Fix:** This commit ensures the GT Document Type field is only required for Guatemalan vendors. [1]: https://github.com/odoo/enterprise/blob/7a80db5b5550bf75e4ce5337e869c42386c8a71c/l10n_gt_edi/models/account_move.py#L144-L171 [2]: https://github.com/odoo/enterprise/blob/7a80db5b5550bf75e4ce5337e869c42386c8a71c/l10n_gt_edi/views/account_move_views.xml#L27 opw-6315872
This update fixes an issue where closing the NemHandel registration wizard left outdated proxy information, causing problems when reopening it. Now, closing the wizard properly removes the proxy, ensuring a fresh start each time and preventing data inconsistencies. This improves the user experience for NemHandel registration.
Original PR description
Closing the NemHandel registration wizard (via the 'X' button / esc button) previously persisted the IAP proxy user. This caused issues when reopening the wizard, as stale proxy data prevented a clean retry. Now, closing the wizard triggers the same logic as the deregister button: the proxy user is deleted from the IAP/Odoo instance. This ensures that reopening the wizard always starts a fresh registration with editable values. Task-6075214 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where duplicating a purchase order receipt incorrectly inflated the received quantity on the original purchase order. The change ensures that only the quantity of the initial delivery is counted, resolving a discrepancy in how received quantities are calculated. This improves the accuracy of purchase order tracking.
Original PR description
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- *…
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- * Create a PO and confirm it * Open the receipt, validate and duplicate it * Go on the duplicated receipt and change its Operation Type * Confirm the duplicated receipt. -> the Received Qty on the Po counted the duplicated and modified transfer. Observation: ------------- When we duplicate a stock.picking, we will call ```copy``` and copy all its ```move_ids``` (stock.move), and in stock.move we will copy the ```purchase_line_id``` : https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/models.py#L5868 https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/models.py#L5881-L5892 https://github.com/odoo/odoo/blob/3e6d93bef49bb2718e8aa1756f95c2a6117c8d55/addons/purchase_stock/models/stock_move.py#L13-L15 the ```purchase_line_id``` will keep the link with the pol. The fields are copied since they have ```copy=True``` https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/addons/stock/models/stock_picking.py#L614 https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/fields.py#L304 Because new stock moves are linked directly to the Purchase Order Line (POL), the qty_received calculation aggregates all associated move quantities. https://github.com/odoo/odoo/blob/cfc63060926db4cec773c159b8ecf97dc0b36d1a/addons/purchase_stock/models/purchase_order_line.py#L73-L76 opw-6088239
This update resolves an issue where the system incorrectly imported invoice quantities from UBL files. Specifically, it ensures that the 'invoiced_quantity' and 'base_quantity' values in imported invoices accurately reflect the quantities specified in the original UBL document. This prevents discrepancies in order data.
Original PR description
…ase_quantity equal to zero **STEP TO REPRODUCE** 1. Import the 2fact ubl from the bugfix ticket. 2. Notice some line are imported with quantity = 1, but the quantity invoiced in the ubl is 0. opw-6260558
This update fixes a crash that occurred when Odoo's subscription module was run outside of its normal web environment (like in tests or cron jobs). The fix ensures the system correctly handles situations where an active HTTP request isn't present, preventing a runtime error.
Original PR description
When executing code outside of a web thread (such as in unit tests, cron jobs, or CLI commands), an actual HTTP request does not exist, leaving the global `request` proxy unbound. In these scenarios, the unbound proxy evaluates to False. Because of Python's `and` evaluation, the expression `request and request.params...` returned the unbound proxy itself instead of None. This caused a RuntimeError later when the proxy was compared to other values. We now explicitly check `request.env` to verify an active request exists, properly falling back to None when there is no HTTP context. runbot-938513
This update resolves an issue where the HTML editor's paste functionality was unreliable, leading to errors when saving selections. The fix ensures that selections are correctly updated during paste operations and after restoring previous editor states, improving the overall user experience and data integrity.
Original PR description
### Steps to reproduce: - Insert a file using /file command and upload a file. - Type any powerbox command (e.g. /file, /media) - Press Enter to select the command - IndexSizeError: Failed to execute…
### Steps to reproduce: - Insert a file using /file command and upload a file. - Type any powerbox command (e.g. /file, /media) - Press Enter to select the command - IndexSizeError: Failed to execute 'setBaseAndExtent' on 'Selection': There is no child at offset 5. ### Description of the issue/feature this PR addresses: - makeSavePoint() of history_plugin uses preserveSelection() to save current selection. However, preserved selections remain registered in the cursor update mechanism and continue to be updated when the editor adjusts cursors during DOM changes. - During normalization, updateFeffs() updates all preserved cursors. Because the savepoint selection is stored using preserveSelection(), it is updated as well and can become inconsistent with the DOM state that the savepoint later restores, resulting in an IndexSizeError. ### Solution (backport-https://github.com/odoo/odoo/commit/1eb0e6de8f566d260ecb6c0dae3436e87ffe8436): - Update preserved cursors after steps restoration so they stay in sync with the restored DOM state. - Stage the selection in the clipboard plugin after `before_paste_handlers`, ensuring the selection reflects the final adjusted state before pasting. - Fix `selectFullText` to trigger `pointerup` to have a correct staged selection. task-6298761 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where the system incorrectly processed Viettel S-Invoice XML files, specifically when invoices were delivered in a double-zipped format. The fix now correctly handles both single and double-zipped invoices, ensuring seamless integration with the Viettel e-Invoicing platform and preventing errors.
Original PR description
Description of the issue/feature this PR addresses: The actual XML extraction hardcoded the double-zipped case by reading only the first entry of the outer zip (`zip_file.infolist()[0]`), assuming it was always a nested zip containing the XML. This made it fail when: - The XML was directly in the outer zip (single-zipped). - The zip contained multiple files and the first nested zip didn't hold the XML. Current behavior before PR: After sending an Invoice to Viettel S-Invoice, the e-Invoicing platform would return a ZIP containing one XML file. The XML File being double-unzipped, a traceback is raised. Desired behavior after PR is merged: The fix rewrites _recursive_zip_xml_file_data to actually be recursive. Invoices can be sent to Viettel S-Invoice without raising a traceback. opw-[6249929](https://www.odoo.com/odoo/project.task/6249929?debug=1) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures that custom reports attached to invoices display their intended names in email attachments, rather than a default CFDI-based filename. The fix addresses an issue where localization overrides were preventing the correct report name from being used, leading to duplicate attachments. This improves the clarity and usability of invoice attachments.
Original PR description
Steps to reproduce: * Install `l10n_mx_edi` (or `l10n_sa_edi`). * Go to **Accounting → Customers → Invoices**. * Open **Studio** and, from the top bar, go to **Reports**. * Duplicate the standard…
Steps to reproduce: * Install `l10n_mx_edi` (or `l10n_sa_edi`). * Go to **Accounting → Customers → Invoices**. * Open **Studio** and, from the top bar, go to **Reports**. * Duplicate the standard **Invoice PDF** report. * Open the duplicated report and make any modification to it. * Enable **Developer Mode**. * Go to **Settings → Technical → Actions → Reports** and update the custom report's **Printed Report Name**. * Go to **Settings → Technical → Email → Templates** and create a new invoice email template. * Add the custom report to the template's **Dynamic Reports**. * Create and confirm an invoice for a **Mexican company**. * Click **Send** and select the newly created email template. Observed behavior: * The custom report attachment uses the CFDI-based filename instead of its own report name, making it appear as a duplicate of the standard invoice attachment. Cause: * `_get_placeholder_mail_template_dynamic_attachments_data` relied on the `invoice_report` context key to pass the extra report into `_get_invoice_report_filename`. However, localization overrides (e.g. `l10n_mx_edi`, `l10n_sa_edi`) unconditionally return their own filename without checking the context, so the extra report's `print_report_name` was never evaluated. Fix: * Introduce `_get_invoice_mail_template_dynamic_report_filename` on `account.move` that directly evaluates a given report's `print_report_name`, bypassing the localization override chain. * Call this new method in `_get_placeholder_mail_template_dynamic_attachments_data` instead of the context-based `_get_invoice_report_filename` call. This avoids the need to patch every localization override and cleanly separates the concern of naming dynamic report attachments from the main invoice report filename logic. opw-6228268
This update optimizes a key process within our stock management system, specifically the `_compute_forecast_information` function. By removing an inefficient loop, we’ve significantly reduced the time it takes to access Manufacturing Orders, particularly for databases with many stock records. This results in faster response times and a smoother user experience.
Original PR description
Before this commit, database with large amounts of `stock.move` records could face slow downs when trying to access Manufacturing Orders. While this is partially due to very heavy computations being…
Before this commit, database with large amounts of `stock.move` records could face slow downs when trying to access Manufacturing Orders. While this is partially due to very heavy computations being done, another factor was the use of a loop in `_compute_forecast_information`. This loop would iterate over a recordset of `stock.move` records and put them into a dictionary, sorted by location. As the size of the recordset grew, this loop would take longer and longer. Here, we remove this loop and instead use a built in method to speed things up. ## Benchmarks: |Record count|Time before|Queries before|Time after|Queries after| |------------|-----------|--------------|----------|-------------| |6,262 |0.13s |68 |0.12s |68 | |68,882 |0.60s |112 |0.58s |109 | |432,317 |5.49s |398 |3.68s |309 | |757,702 |15.33s |1,141 |5.79s |599 | [opw-6310415](https://www.odoo.com/odoo/action-6450/6310415?debug=assets) Forward-Port-Of: odoo/odoo#271677
This update ensures that partner bank accounts are usable within all child companies, even if the partner is associated with a parent company. Previously, this restriction limited functionality. This change improves efficiency and simplifies processes for users managing multiple company branches.
Original PR description
Even when a partner has the 'company_id' filled with the parent company, his bank account should be usable in the child companies. This was done in odoo/odoo#262173 from 19.2 but we need to backport it in stable task-6309694 Forward-Port-Of: odoo/odoo#271470