Daily updates from Odoo
Thursday, June 11, 2026
8 changes · 18.0
Resolved issues and error corrections
This update corrects a previous error that prevented the delivery service from functioning correctly in certain Colombian cities, particularly Antioquia. The fix ensures that all Colombian postal codes, including 4-digit codes, are properly recognized and utilized, improving delivery accuracy and reliability.
Original PR description
Issue ----- Delivery does not always work from/to some cities in Colombia, like Antioquia. Cause ----- There was an oversight in fix 7654c55 where only 5 digit postal codes taken from the colombian localisation were padded in https://github.com/odoo/enterprise/blob/390acf532e8932fd9b9a708382a5e36cdbb35754/delivery_envia/models/envia_request.py#L726-L727 However, some of the colombian cities listed in `l10n_co_edi/data/res.city.csv` have 4 digit codes (like `SANTA FÉ DE ANTIOQUIA`, code `5042`). https://github.com/odoo/enterprise/blob/7cceddaf086d849b8e2121e1023ef3479397534f/l10n_co_edi/data/res.city.csv#L12 ----- Ticket: opw-6248252
This update resolves a problem where importing Peppol/UBL XML files with multiple embedded PDFs resulted in some PDFs being incorrectly separated into separate invoices. The fix adjusts a sorting mechanism to ensure all PDFs are correctly included within the primary invoice, improving data accuracy for imported documents.
Original PR description
When importing a Peppol/UBL XML file containing multiple embedded PDFs the first PDFs is extracted in the same invoice, all the other in separate documents. Steps to reproduce: - Set up a BE Company - Import a Peppol XML with multiple embedded PDF - Check the created Bills Issue: First embedded PDF is extracted in the bill along with the source XML. Other documents are expanded in separate Bills. This occurs because the sort weight of the additional embedded document is the same, causing the system to separate them from the main invoice. opw-6231265 Forward-Port-Of: odoo/odoo#266963
This update resolves an issue where marketing automation campaigns could fail when attempting to reschedule activity traces, specifically when a trace lacked a parent activity. The fix prevents modifications to trace hierarchies during campaign execution, improving campaign stability and preventing user errors. This ensures campaigns run reliably.
Original PR description
### Note: **THIS IS A BACKPORT OF** https://github.com/odoo/enterprise/pull/107556 Some edits were made to the tests so that they match Odoo v18.0 ### Steps to reproduce: - Create a new marketing…
### Note: **THIS IS A BACKPORT OF** https://github.com/odoo/enterprise/pull/107556 Some edits were made to the tests so that they match Odoo v18.0 ### Steps to reproduce: - Create a new marketing campaign with two activities - Set them to occur some number of days after the beginning - Save the campaign and start it - Modify one of the activities to occur some number of days after the other activity and save - Modify the child activity by changing the number of days after its parent that it should run and save > IndexError: tuple index out of range ### Issue: The trace related to the child activity has no parent when trying to reschedule it in `_update_schedule_date`. This causes an issue when trying to get the first mailing_trace_ids using index 0 in this line: https://github.com/odoo/enterprise/blob/3e788e28dc76c928935d874e4e5a18d467c65539/marketing_automation/models/marketing_trace.py#L149 ### Fix: Prevent the activity hierarchy to be modified on started campaigns. We also change the indexing to avoid further out of range issue and properly default on the participant create value. Trying to match existing traces to their parents has too many edge cases when trying to avoid duplicates, and might often need to reset the whole trace chain to work properly. This approach avoids user mistakes on running campaigns, but if a user tries to launch a test (even on draft campaign) he won't be able to modify the hierarchy further without deleting/recreating some activities/traces. So we should ignore this for test traces, but it could impact the behavior between test and actual executions. opw-6251614
This update corrects a technical issue preventing Polish companies from correctly reporting EU transactions to KSeF (the Polish tax authority). The fix ensures the required 'PrefiksPodatnika' field is included in KSeF invoices, aligning with official regulations and preventing non-compliance. This ensures accurate tax reporting for EU sales and services.
Original PR description
Steps to reproduce 1. Configure a Polish company with KSeF enabled. 2. Create a customer invoice using a tax tagged with K_21 (0% EU G, intra-Community supply of goods), K_12 (0% EU S, services taxed…
Steps to reproduce 1. Configure a Polish company with KSeF enabled. 2. Create a customer invoice using a tax tagged with K_21 (0% EU G, intra-Community supply of goods), K_12 (0% EU S, services taxed in the buyer's EU country) or Triangular Sale. 3. Send the invoice to KSeF and download the generated FA(3) XML. Issue The Podmiot1 (seller) block in the rendered FA(3) XML omits the PrefiksPodatnika element, see https://github.com/odoo/odoo/blob/89219a843545d8bb0cad6ea806a1167cee6289da/addons/l10n_pl_edi/data/fa3_template.xml#L34-L42. According to the official Ministry of Finance documentation (https://ksef.podatki.gov.pl/media/4u1bmhx4/information-sheet-on-the-fa-3-logical-structure.pdf, page 11), this conditional field must carry the value "PL" when the invoice documents: - the intra-Community supply of goods, - the provision of services referred to in Article 100 sec. 1 item 1 of the Act for EU VAT taxpayers, - the supply carried out under a simplified triangular transaction by the second taxpayer (Article 135 sec. 1 item 4 (b) and (c)). The XSD marks the element as optional (minOccurs="0", fixed="PL") so KSeF accepts the XML, but the seller's tax reporting is still legally non-compliant for the three cases above, and the field is missing from the KSeF PDF viewer rendering. opw-6213178
This update resolves a bug that occurred when reloading a chart of accounts, specifically when an account's XMLID still referenced its original company. The fix ensures the system correctly verifies the account belongs to the target company before reloading, preventing errors and ensuring accurate account data.
Original PR description
When reloading a chart of accounts, `_pre_reload_data` resolves an account via its xmlid and then evaluates: ```py re.match(f'^{values["code"]}0*$', account.code) ``` `account.code` is a non-stored…
When reloading a chart of accounts, `_pre_reload_data` resolves an account via its xmlid and then evaluates:
```py
re.match(f'^{values["code"]}0*$', account.code)
```
`account.code` is a non-stored computed field that reads from the company-dependent field `code_store`. If the resolved account has no `code_store` entry for the target company (e.g. the account was originally set up under a different company but its xmlid was prefixed with the current company id), `_compute_code` returns False instead of a string, causing a TypeError in re.match.
```py
File "/home/odoo/src/odoo/19.0/addons/account/models/chart_template.py", line 442, in _pre_reload_data
if not account or not re.match(f'^{values["code"]}0*$', account.code):
File "/usr/lib/python3.10/re.py", line 190, in match
return _compile(pattern, flags).match(string)
TypeError: expected string or bytes-like object
```
```sql
apan_4342860=> SELECT
aa.id,
aa.code_store,
imd.module,
imd.name
FROM account_account aa
JOIN ir_model_data imd
ON imd.res_id = aa.id
AND imd.model = 'account.account'
WHERE aa.id = 1056;
id | code_store | module | name
------+-----------------+---------+-----------------
1056 | {"2": "510500"} | account | 1_co_puc_510500
(1 row)
```
This situation arises when a customer moves or reassigns an account between companies but the xmlid retains the original company prefix.
**Fix:**
After resolving the account via xmlid, check whether it actually belongs to the target company using filtered_domain with _check_company_domain. If it does not pass the check, unlink the stale ir.model.data entry and treat the account as not found, allowing the reload to re-establish the correct xmlid linkage via the code-based lookup that follows.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update corrects a restriction in the Odoo accounting module that prevented valid vendor bills from being created. The system previously blocked certain document types based on company VAT affiliation, which was incorrect for purchase invoices. Now, all legally valid document types are supported for purchase invoices, ensuring accurate recording of vendor bills.
Original PR description
Currently, the system restricts fiscal document types for both sales and purchases based on the company’s VAT affiliation, which prevents valid vendor bills from being recorded. **Steps to…
Currently, the system restricts fiscal document types for both sales and purchases based on the company’s VAT affiliation, which prevents valid vendor bills from being recorded. **Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT company`. - Navigate to Accounting > Vendors > Bills. - Create a vendor bill. - Try to select a document type such as `FPEQ` or `FCAP`. **Observation:** The system hides valid vendor document types (e.g., `FPEQ`, `FCAP`) if they do not match the company’s VAT affiliation. **Root Cause:** At [1], the method `_compute_l10n_gt_edi_available_doc_types` filters document types using the company’s VAT affiliation (`l10n_gt_edi_vat_affiliation`) for all move types. This logic is correct for sales (where the company is the issuer), but incorrect for purchases (where the vendor determines the document type). As a result, valid purchase document types are wrongly excluded. **Fix:** This commit updates the computation logic to: - Apply affiliation-based filtering only for sales (`out_*`). - Bypass the restriction for purchases (`in_*`), allowing all valid document types. This ensures that vendor bills can include any legally valid document type regardless of the company’s affiliation, while preserving the existing restrictions for sales workflows. [1]: https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_gt_edi/models/account_move.py#L162-L166 opw-6099863
This update resolves a technical issue where VoIP registration would fail with an error message when a user left a session open and inactive. The fix ensures that the registration process is reliably restarted and handled, preventing frustrating error dialogs and maintaining consistent VoIP functionality. This improves the user experience by ensuring stable call connectivity.
Original PR description
Leaving a session open and idle (page open, no activity at all) eventually pops an error dialog: UncaughtPromiseError > RequestPendingError REGISTER request already in progress, waiting for final…
Leaving a session open and idle (page open, no activity at all) eventually pops an error dialog:
UncaughtPromiseError > RequestPendingError
REGISTER request already in progress, waiting for final response
at Registerer.register (sip.js)
at Registerer.register (registerer.js)
at UserAgent.attemptReconnection (user_agent_service.js)
When the WebSocket transport drops while a REGISTER is in flight (which happens on an idle tab: SIP.js sends a periodic re-REGISTER before the registration expires, and the socket may be closed by an idle timeout or by the machine going to sleep in the meantime), the final response never comes back. SIP.js only clears its internal `waiting` flag from the REGISTER response callbacks (onAccept/onReject/onRedirect); it is never reset on transport loss or request timeout. The Registerer is then stuck `waiting` forever, and every subsequent register() rejects with a RequestPendingError.
On top of that, our wrapper's register() did not return the SIP.js promise, and attemptReconnection() called it without awaiting, so the rejection escaped the surrounding try/catch and surfaced as an unhandled promise rejection. Worse, the WebSocket error was resolved right after, so the user appeared reconnected while VoIP registration was actually dead until the page was reloaded.
This commit makes register() recreate the underlying SIP.js Registerer when it is stuck `waiting` (a clean instance starts with waiting=false), and return the promise so callers can await it. attemptReconnection() now awaits it, so any rejection goes through the existing retry/back-off logic instead of bubbling up as an uncaught error.
The recreation is intentionally conditional: disposing a healthy registerer would send an unregister (REGISTER expires=0) racing with the fresh register (expires=600) and could leave us unregistered, so we only recreate when a request is actually stuck.
Forward-Port-Of: odoo/enterprise#119701This update resolves an issue where the Chilean DTE module incorrectly marked invoices as rejected when the SII (tax authority) reported a server error (status 99). Previously, status 99 always triggered a rejection, leading to duplicate invoices and manual correction. Now, status 99 is handled specifically, allowing for safe retries and clear communication to the user about the SII response.
Original PR description
**Description of the issue/feature this PR addresses:** When sending a Chilean DTE to SII, if SII returns status code 99 (internal server error), the invoice is incorrectly marked as rejected.…
**Description of the issue/feature this PR addresses:**
When sending a Chilean DTE to SII, if SII returns status code 99 (internal server error), the invoice is incorrectly marked as rejected. According to the SII specification, code 99 means the server had an internal error and it is unknown whether the DTE was actually received — it is not a rejection.
This causes fiscal issues: the DTE may have been validly registered at SII, but Odoo marks it as rejected. If the user retries the send, SII rejects it as a duplicate. If the user creates a new invoice for the same document, a duplicate fiscal document is generated. Recovery requires manual intervention.
_This issue is also tracked in the following Odoo task: https://www.odoo.com/es_ES/my/tasks/5374459_
**Current behavior before PR:**
Any `STATUS` code other than 0 or 5 falls through to:
```
else:
self.l10n_cl_dte_status = 'rejected'
```
This includes code 99, which does not mean the DTE was rejected — it means the outcome is unknown.
**Desired behavior after PR is merged:**
Status 99 is handled explicitly: the invoice keeps its not_sent status so it can be safely retried. The chatter still logs the SII response so the user is informed.