Tuesday, September 15, 2026
19 changes · 18.0
Resolved issues and error corrections
Updating Colombian contact data now keeps newly created child contacts linked to the same company as the original contact. This prevents contacts from being assigned to the wrong company in multi-company setups, improving data accuracy and reducing manual cleanup.
Original PR description
Problem: When updating a contact's data using the "Update data" feature in a multi-company setup, the newly created child contact does not get assigned to the same company as the original contact. Solution: Set the child contact's company to match the parent contact's company when creating the record, ensuring both contacts belong to the same company. Steps to reproduce (runbot v18): 1. Install l10n_co 2. Set up two companies (Company A and Company B). 3. Create a contact with an email and NIT, and set its company to Company B. 4. Click the "Update data" button. 5. Open the newly created child contact and check its company. The company of the newly created child contact is not the same as the parent contact (Company B). opw-6528295
French e-reporting Flow 10 now accepts valid EU OSS VAT rates instead of limiting invoices to a fixed list of French VAT rates. This prevents legitimate cross-border B2C invoices from being rejected before reporting files are generated, while still blocking invalid rates above 100%.
Original PR description
## Summary - Flow 10 currently rejects any tax percent outside a hardcoded **French** list (`VALID_PDP_TAX_RATES`). - The PPF CDAR XSD (specs v3.2) types `TaxPercent` / `TaxCategory/Percent` as…
## Summary - Flow 10 currently rejects any tax percent outside a hardcoded **French** list (`VALID_PDP_TAX_RATES`). - The PPF CDAR XSD (specs v3.2) types `TaxPercent` / `TaxCategory/Percent` as **`xs:decimal` with no enum**. OSS destination VAT (21% BE, 19% DE, 25.5% FI, …) is legitimate e-reporting. - `l10n_eu_oss` still creates those taxes with `country_id=FR`, so a country_id skip would not help. - **This PR (proposal A, recommended):** replace the FR enum with a **0–100** bound. Invalid garbage rates (150%) still fail. - Alternative (do **not** merge both): proposal B keeps the FR enum for domestic partners — see the sibling PR on `dev_l10n_fr_pdp_oss_tax_skip_domestic`. Fixes https://github.com/odoo/odoo/issues/287797 **Odoo task:** [6573571](https://www.odoo.com/fr_FR/my/tasks/6573571) opw-6573571 Introduced by #286547. ## Multi-repo issues - https://github.com/odoo/odoo/issues/287797 ## Related PRs - Alternative proposal B: https://github.com/odoo/odoo/pull/287802 (open in parallel; pick one) ## Test plan - [x] `odoo-bin -d test_l10n_fr_pdp_262 -u l10n_fr_pdp --test-enable --stop-after-init --test-tags=.test_unsupported_tax_rate_is_rejected_for_flow_reporting,.test_oss_eu_vat_rate_is_accepted_for_flow_reporting` - Local Docker: **2 tests, 0 failed, 0 error** ## Merge order Merge **either** this PR **or** the conservative sibling, not both. ## Reviewers & code owners - Requested review: @smetl @chklop - Prior authors on touched code: @malb-odoo @gawa-odoo @jbw-odoo (and Jérémy Bazin / #286547) --- ## Résumé - Le Flux 10 refuse les taux hors liste TVA française, alors que le XSD PPF accepte n’importe quel décimal. - Les factures OSS (21 % BE, etc.) passent en erreur avant génération XML. - Cette PR remplace l’enum par une borne **0–100** (proposition A, recommandée). - Proposition B conservative en PR sœur : ne merger **qu’une** des deux. **Tâche Odoo :** [6573571](https://www.odoo.com/fr_FR/my/tasks/6573571) ## Issues - https://github.com/odoo/odoo/issues/287797 ## Tests - [x] 2 tests OSS / taux hors borne, 0 failed (Docker local) ## Revue - Revue demandée : @smetl @chklop - Auteurs récents : @malb-odoo @gawa-odoo @jbw-odoo
This fixes French e-invoicing checks so cross-border EU consumer sales can use the correct destination VAT rates, while French domestic sales still keep the stricter French VAT validation. It prevents valid OSS invoices from being rejected and keeps safeguards against impossible tax percentages.
Original PR description
## Summary - Conservative alternative to proposal A on `dev_l10n_fr_pdp_oss_tax_range`. - Keep `VALID_PDP_TAX_RATES` for partners in **French territories** (catches a 21% typo on a FR B2C invoice). -…
## Summary - Conservative alternative to proposal A on `dev_l10n_fr_pdp_oss_tax_range`. - Keep `VALID_PDP_TAX_RATES` for partners in **French territories** (catches a 21% typo on a FR B2C invoice). - Skip that enum when the commercial partner is **outside** French territories (OSS B2C destination VAT). Still reject percents outside **0–100**. - `l10n_eu_oss` stores OSS taxes with `country_id=FR`, so the partner country is the OSS signal — not `tax.country_id`. Fixes https://github.com/odoo/odoo/issues/287797 **Odoo task:** [6573571](https://www.odoo.com/fr_FR/my/tasks/6573571) opw-6573571 **Do not merge together with proposal A.** Pick one. ## Multi-repo issues - https://github.com/odoo/odoo/issues/287797 ## Related PRs - Recommended proposal A: https://github.com/odoo/odoo/pull/287801 ## Test plan - [x] `odoo-bin -d test_l10n_fr_pdp_262 -u l10n_fr_pdp --test-enable --stop-after-init --test-tags=.test_unsupported_tax_rate_is_rejected_for_flow_reporting,.test_oss_eu_vat_rate_is_accepted_for_flow_reporting,.test_out_of_range_oss_tax_rate_is_rejected_for_flow_reporting` - Local Docker: **3 tests, 0 failed, 0 error** ## Merge order Merge **either** this PR **or** proposal A, not both. ## Reviewers & code owners - Requested review: @smetl @chklop - Prior authors on touched code: @malb-odoo @gawa-odoo @jbw-odoo (and Jérémy Bazin / #286547) --- ## Résumé - Variante conservative : whitelist FR conservée pour les partenaires en territoire français. - Taux OSS autorisés si le partenaire est hors FR. Borne 0–100 conservée. - Ne pas merger avec la PR A. **Tâche Odoo :** [6573571](https://www.odoo.com/fr_FR/my/tasks/6573571) ## Issues - https://github.com/odoo/odoo/issues/287797 ## Tests - [x] 3 tests, 0 failed (Docker local) ## Revue - Revue demandée : @smetl @chklop - Auteurs récents : @malb-odoo @gawa-odoo @jbw-odoo
This fixes Mexican electronic invoicing payment complements to again use the maximum allowed decimal precision for currency amounts, following guidance from the certification provider after a government consultation. The change helps reduce validation or rejection issues for Mexican payment documents involving rounding or foreign currencies.
Original PR description
Quadrum reverted their changes because > Derived from a consultation with the government we reverted to our previous behavior, we recommend using the maximum number of decimals allowed Reverts commit https://github.com/odoo-dev/enterprise/commit/f13d204dacf9eae98c78de26e9f2e54387a0eaee as well opw-6561617
Users can now save valid local VAT or national ID numbers for foreign vendors operating in the company’s country. This removes an unnecessary validation blocker and supports common cross-border vendor setups.
Original PR description
Currently, VAT validation strictly restricts the VAT number to the country set on the partner's address. This prevents users from saving valid local VAT numbers (national IDs) for foreign vendors operating locally. This commit modifies the `check_vat` to validate the VAT number against either the partner's country or the active environment's company country. `vat_prefix_to_country_code` is introduced to map the VAT prefix doesn't match the country code (ie 'T'->'jp'). Task-6478505 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The default French electronic invoicing profile has been reverted to a broadly supported option. This fixes an issue that prevented many users from sending or receiving French invoices because the previously selected extended profile was not mandatory and often unsupported.
Original PR description
**PROBLEM** https://github.com/odoo/odoo/pull/281717 changed the pdp default profile to be the french extended profile. However, this profile is not mandatory, so most user can't send/receive it. This prevent user from sending french invoices. opw-6420924
This fixes an issue where users signing in while a live websocket connection was open could be sent back to the login page. The session is now saved during the connection handshake without overwriting the browser's current login cookie, improving login reliability for affected flows such as live chat.
Original PR description
Before this commit, signing in from a page holding a websocket connection could land the user back on the login form. This happens because the websocket handshake marks the session dirty to get it written on disk, and _save_session sends a "session_id" cookie back for every dirty session. A handshake answered between the login response and the request that follows it therefore puts the pre-login session back in the browser. Note that the failure was seen on master, where a livechat tour signs in with the bus connected, but every version since 17.0 answers the handshake the same way. This commit saves the session from the handshake itself, so that the response carries no session cookie. https://runbot.odoo.com/odoo/error/947173 Forward-Port-Of: odoo/odoo#287960
This fix ensures custom product attribute values selected in Point of Sale orders are carried through inter-company purchasing and delivery flows. Delivery slips now show the correct product description, reducing fulfillment mistakes when POS ship-later orders create inter-company documents.
Original PR description
*= sale_purchase_inter_company_rules Step to reproduce: - install `sale_purchase_stock_inter_company_rules` and pos with demo - from setting : - enable Multi-Step Routes - enable all options for…
*= sale_purchase_inter_company_rules
Step to reproduce:
- install `sale_purchase_stock_inter_company_rules` and pos with demo
- from setting :
- enable Multi-Step Routes
- enable all options for Inter-Company Transactions (for both companies)
- go to routes, un-archive MTO route
- create a product "A" with routes "MTO" and "buy"
- make the product available for pos (add into `Misc` category)
- create a attribute with custom attribute value and link it to "A"
- in vendor list, add "My Company (Chicago)" as vendor
- switch to Chicago company, for same product add some other vendor
- switch back to "My Company (San Francisco)"
- for pos, in setting enable "Allow Ship Later"
- open Furniture pos, create a order with Product "A"
- go to payment page and select "Ship Later" and pay
- a RFQ is created for this pos order, open and confirm it
- switch to "My Company (Chicago)"
- open sale order (remove "my quotation" filter)
- notice a quotation created from company 1, confirm it.
- open linked delivery slip
Observation:
- the delivery slip will not have description (custom value for attribute for A
is lost)
Cause:
- when preparing vals for SO for inter-company transaction from
`_prepare_sale_order_line_data` we never considered order from pos
- hence in this case, order lines never had custom attributed linked to them
- the description is computed from the attributes from SO
- SO never had them to begin with
Fix
- we introduced a method `_get_pcavs_from_pos_order` which fetch such attributes from pos order too
- to accomplish this we introduce a new module As there is no dependency with purchase and pos
opw-6213076The Mexico DIOT tax report no longer uses the Load More option that could show duplicate lines or prevent users from viewing expanded report details. This improves reliability when reviewing DIOT reporting data with many entries for the same partner.
Original PR description
Account reports can use "Load More" to paginate the lines generated when expanding a groupby. A report line can contain several expressions, which may return overlapping grouping keys. Problem: The…
Account reports can use "Load More" to paginate the lines generated when expanding a groupby. A report line can contain several expressions, which may return overlapping grouping keys. Problem: The limit and offset are applied while computing each expression, before their results are aggregated by grouping key. As a result, a grouping key from a previous page can be returned again by the next "Load More" request. This results in duplicate report lines. In 17.0, this causes an Owl error because `line.id` is used as the key when rendering the lines, and the lines can’t be viewed. The DIOT report is affected because it contains multiple expressions whose grouping keys can overlap. Solution: Disable "Load More" on the DIOT report by removing its pagination limit. Example steps to reproduce: 1. Create or switch to a Mexican company and install `l10n_mx_reports` so the DIOT report is available. 2. Create a partner and 100 posted journal entries for that partner in the same period. Add the `+DIOT: 16%` tag to all 100 account move lines and the `-DIOT: Retención` tag to the first 90. 3. Open Accounting > Reporting > Tax Reports > DIOT. 4. Unfold the partner and click "Load More". Related ticket: opw-6471063 Forward-Port-Of: odoo/odoo#287833
Employees without HR access can now see one-time work location entries for colleagues in the calendar, matching the behavior for recurring locations. This ensures managers and teammates have a complete view of where people are working on specific days.
Original PR description
**Steps to reproduce** - With a user having HR rights, create an exceptional work location for a user (click on the top bar of one of the days in the calendar, where work locations are displayed, and do not check "repeat every". - Open the calendar app with a user having no HR rights, in the sidebar, add the user with a non-recurrent work location. Notice that the work location is not visible, unlike recurring ones. **Cause** Recurring work locations are defined on the public employee (`*_location_id` type fields) and are readable by all users. Non-recurring work locations are `hr.employee.location` records and the `homeworking_own_rule` rule restricts read operations for non-HR users. opw-6190464
This fix ensures that when a recruitment applicant is linked to a contact, the correct contact details are used when creating the partner record. It helps keep applicant and contact information accurate, reducing data inconsistencies in the hiring process.
Original PR description
The values associated with the applicant's linked partner must be used during creation. Task-6479653 Forward-Port-Of: odoo/odoo#287997
Helpdesk teams linked to multiple community forums now open the forum listing correctly instead of showing an error. This improves the customer support experience by ensuring visitors can ask the community even when a team uses several forums or course-linked forums.
Original PR description
### Steps to Reproduce: 1) Install `website_helpdesk_slides_forum` module 2) On a Helpdesk team, link 2 (or more) forums under `Commnity Forums`. 3) Click on website smart button and then click `Ask…
### Steps to Reproduce: 1) Install `website_helpdesk_slides_forum` module 2) On a Helpdesk team, link 2 (or more) forums under `Commnity Forums`. 3) Click on website smart button and then click `Ask the community` button. ### Error: ``` odoo.addons.base.models.ir_qweb.QWebException: Error while render the template KeyError: '_forums' Template: website_helpdesk_slides_forum.helpdesk_forums ``` ### Root Cause: https://github.com/odoo/enterprise/blob/1bdd673c5fd19e335dc0948d2beed7a282e5e172/website_helpdesk_forum/controllers/website_forum.py#L18-L22 On clicking the "Ask the Community" button calls the `helpdesk_forums` controller. A single forum redirects straight to it. Several forums get rendered through `get_template_xml_id()`, with only `forums` in context. `get_template_xml_id()` is overridden in `WebsiteSlidesForumHelpdesk`, which points to : https://github.com/odoo/enterprise/blob/1bdd673c5fd19e335dc0948d2beed7a282e5e172/website_helpdesk_slides_forum/views/helpdesk_templates.xml#L3-L5 a primary copy of the inner partial `forum_all_all_entries`. That partial needs `_forums` (and, once extended by website_slides_forum, courses_discussions too), both only ever set by the page template's own t-call: [Reference](https://github.com/odoo/odoo/blob/23af2b443735c6d3a2f64e44f9ea5da45638b052/addons/website_forum/views/forum_forum_templates_forum_all.xml#L18-L19) Since `helpdesk_forums` is rendered directly instead of going through `website_forum.forum_all`, `_forums` is never set, hence `KeyError` occurs. The base `website_helpdesk_forum` module has the same root cause one level up, surfacing as a different error: https://github.com/odoo/enterprise/blob/1bdd673c5fd19e335dc0948d2beed7a282e5e172/website_helpdesk_forum/controllers/website_forum.py#L24-L25 `website_helpdesk_forum.forum_all` does not exist anywhere in the codebase. A team with multiple forums, without `website_helpdesk_slides_forum` installed, hits ``` ValueError: View 'website_helpdesk_forum.forum_all' in website 1 not found ``` Instead of a listing page. ### Fix: - Both `get_template_xml_id()` implementations now return the real, working `website_forum.forum_all` page template, which already sets `_forums/courses_discussions` through its own `t-call` and wraps the result in website.layout. - `helpdesk_forums()`'s render values are now built through an overridable `_get_helpdesk_forums_render_values()` hook instead of a hardcoded dict, so subclasses can extend the context. - `website_helpdesk_slides_forum` uses that hook to set `hide_forum_slides_link=True`, and adds one small non-primary view inheriting `website_slides_forum.forum_all_all_entries` that conditions the `/slides` promo link (not the "Course" badge, which doesn't navigate anywhere) on `not` `hide_forum_slides_link`. This targets the link element itself rather than a `t-call` site in `forum_all`, so it correctly applies whether `website_slides_forum` groups a given forum as "regular" or "course-linked". **opw-6332175** Forward-Port-Of: odoo/enterprise#124104
Flexible employee leave is now shown as unavailable for the full duration of the leave, including the first and last days. This prevents planning and attendance views from underreporting time off, helping managers see accurate availability.
Original PR description
### Steps to reproduce: - Create a flexible employee - Create a leave from a Monday to a Friday for this employee - Navigate to Planning gantt view and check the week where the created leave exists - Notice only 3 days are greyed-out ### Cause: This is happening because in planning we normally exclude days that are not fully unavailable and since flexible doesn't have a specific start and end hours for the working days the start and end days for the flexible leaves are excluded from the unavailabiliy. This is also happening in `hr_attendance` for example but in a different way where the start and end days of the leave will be shown half greyed-out ### Fix: For _unavailable_intervals_batch we make flexible leaves cover the whole days of the leave opw-6142094
OSS sales for Spain are now reported in the correct VAT declaration box, moving amounts from box 124 to box 123. This helps ensure Spanish tax reports match the required reporting rules and reduces the risk of incorrect filings.
Original PR description
OSS sales were being mapped to mod_303_casilla_124_balance where it should be mapped to mod_303_casilla_123_balance. These amounts must be reported values in casilla 123. This commit updates es_assec, es_common, es_full and es_pymes tax templates from 124 to 123 and updates test_country_tag_from_spain. task-6360387 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284984
Bank synchronization now keeps the payment options already configured on a bank journal instead of replacing them with only the defaults. This prevents businesses from losing their custom incoming and outgoing payment setup when connecting a bank feed.
Original PR description
**Steps to reproduce:** - Install Accounting - Configure "Bank" journal: * Add several incoming payments * Add several outgoing payments - From Accounting dashboard, connect Bank (e.g. Odoo Bank Sync Demo) **Issue:** After bank sync, all the incoming/outgoing payments added on the Bank journal are removed. Only the default ones are re-created. **Solution:** Keep all the existing incoming/outgoing payments (i.e. payment method lines) and only create the default ones for the payment method types that don't exist. opw-6424407 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Flexible employees' approved leave is now shown as full-day unavailability in planning views, including the first and last day of the leave period. This prevents managers from accidentally scheduling employees who are unavailable for the whole leave period.
Original PR description
### Steps to reproduce: - Create a flexible employee - Create a leave from a Monday to a Friday for this employee - Navigate to Planning gantt view and check the week where the created leave exists - Notice only 3 days are greyed-out ### Cause: This is happening because in planning we normally exclude days that are not fully unavailable and since flexible doesn't have a specific start and end hours for the working days the start and end days for the flexible leaves are excluded from the unavailability. This is also happening in `hr_attendance` for example but in a different way where the start and end days of the leave will be shown half greyed-out ### Fix: For _unavailable_intervals_batch we make flexible leaves cover the whole days of the leave opw-6142094
Fleet Officers now have the intended access to view and update all fleet vehicles, rather than being limited to only their own assigned vehicle. This helps fleet teams manage vehicles consistently without unnecessary permission workarounds.
Original PR description
Backport of [this commit from v19.0](https://github.com/odoo/odoo/commit/efc59084fbd3fe314a686699e42bfdcc4553ad85#diff-2cf7820fca8900d37c164482b97772bc099b342c726b80c66f1490627f267403), which fixes **Fleet Officer** access rights
Fixed an issue that caused an error when opening sale or purchase receipts from Invoice Analysis. Users can now drill down from analysis reports to receipt forms without interruption.
Original PR description
When enabling Sale/Purchase Receipts and trying to open the form view from Invoice Analysis, an error occurs. The issue is caused by the `move_type` used in `_where()`, which includes a type that is not defined in the `move_type` field selection. Steps to reproduce: - Enable Sale/Purchase Receipts. - Create a Sale/Purchase Receipt for partner A and confirm it - Go to Invoice Analysis and open the Pivot view - Click on a cell to open partner A's receipt, then try to open the form view - Error Ticket [link](https://www.odoo.com/odoo/project.task/6462153) opw-6462153 Forward-Port-Of: odoo/odoo#282922
FedEx shipping labels in ZPLII format now download with a printer-friendly .zpl file extension instead of being saved as a text file. This avoids manual renaming and helps warehouse teams print labels without disruption.
Original PR description
TL;DR When downloading a `.zplii` shipping label from the chatter on a Delivery Order (using FedEx), the browser automatically adds .txt to the end of the filename, saving it as `.zplii.txt` Step to…
TL;DR
When downloading a `.zplii` shipping label from the chatter on a Delivery Order
(using FedEx), the browser automatically adds .txt to the end of the filename,
saving it as `.zplii.txt`
Step to reproduce:
- install `delivery_fedex_rest` with demo
- open shipping method menu -> Fedex Us -> label format = `zplii` -> save
- create a SO, click on 'Add Shipping",
- select fedex as shipping method -> get rate -> add -> confirm SO
- go to delivery and validate
- notice, in thread, a attachment with ZPLII extension appears
- download (.txt is appended to file)
Issue:
- `fedex_rest_send_shipping` post message with documents with extension as
`fedex_rest_label_file_type` i.e. `ZPLII`
https://github.com/odoo/enterprise/blob/735490d7ba9bdc6d0df7a0bd07c0d4e36d1ed2d4/delivery_fedex_rest/models/delivery_fedex.py#L193-L195
- when the attachment is created for this document , it's mimetype is computed
to be `text/plain` from [guess_mimetype](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/tools/mimetypes.py#L192) method, as data is plain ASCII code
- moreover, when downloading, [_get_stream_from](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/addons/base/models/ir_binary.py#L89) tries to guess extension
using [get_extension](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/tools/mimetypes.py#L210) which return `None` as len('zplii') > 4, [see](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/tools/mimetypes.py#L221)
- finally, as we got `None`, and mimetype is `text/plain`, `.txt` is appended [here](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/addons/base/models/ir_binary.py#L149)
Fix:
- we use `zpl` as extension for file instead of `zplii` as there is not
difference between them from printing perspective
- as length of 'zpl' is <=4 , `get_extension` will considered it as valid
opw-6410968
Forward-Port-Of: odoo/enterprise#126620