Daily updates from Odoo
Tuesday, June 2, 2026
115 changes
21 changes
Resolved issues and error corrections
This update addresses a requirement from the Peruvian tax authority (SUNAT) regarding delivery guides. Customers using the older version of our l10n_pe_edi_stock module were receiving errors due to a missing field. We’ve updated the module to include this required date, ensuring compliance and preventing delivery guide rejections. Customers using older versions need to update to this latest module to avoid issues.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662
Forward-Port-Of: odoo/enterprise#119038This update resolves issues related to Philippine taxes and accounting within Odoo. Specifically, it corrects the account type for inventory variations and restructures VAT tax calculations for accurate reporting, aligning with Philippine tax regulations. This ensures correct tax calculations and reporting for Philippine businesses using Odoo.
Original PR description
Update the COA by setting account 502040 (Inventory/Stock Variation) to type `expense`. We also restructure the FWVAT DS/EM tax to use group of taxes design. task-6146238
This update resolves an issue where branch users were unable to create new journal entries due to an access restriction within the accounting module. The fix adds elevated permissions to the query used to identify sequence gaps, allowing branch users to correctly create entries without encountering an error. This ensures branch users can perform standard accounting tasks.
Original PR description
**Steps to reproduce:** * Create a parent company with a branch company (Settings > Companies). * Create a user whose **only** allowed company is the branch. * While logged in as a parent-company…
**Steps to reproduce:** * Create a parent company with a branch company (Settings > Companies). * Create a user whose **only** allowed company is the branch. * While logged in as a parent-company admin, open the Miscellaneous Operations journal, find the first or second posted entry, reset it to draft, clear its name to a digits-only value (e.g. `0001`) and save – leaving it in draft state. This stores `sequence_prefix = ''` and `sequence_number = 1` in the database. * Log in as the branch-company user. * Navigate to Accounting > Journal Entries > New. * Set any date and save the draft entry (or simply write `name = '/'` on it). **Observed behavior:** * Saving fails with: `odoo.exceptions.AccessError: You are not allowed to access 'Journal Entry' (account.move) records.` **Cause:** * `_update_sequence_made_gap`, introduced in 19.0, detects sequence holes by running a raw SQL query that finds the two entries immediately before and after each move in the same journal with the same `sequence_prefix`. The query contains **no `company_id` filter**. * In a branch-company setup the parent's journal (`journal_id`) is shared across companies. When an early entry's `name` is cleared to a digits-only value its `sequence_prefix` becomes `''`. A new entry created by the branch user also starts with `name = '/'`, which gives it `sequence_prefix = ''` and `sequence_number = 0`. The SQL therefore returns the parent company's entry (`sequence_number = 1`, `sequence_prefix = ''`) as the `next_id` neighbour. * The IDs from that query are passed to a local `browse()` closure, which in 19.0 read: https://github.com/odoo/odoo/blob/af37df9bee34fe60c1e51896af23fc7fe9b76cfc/addons/account/models/account_move.py#L5770-L5771 * `self.browse()` inherits the **non-sudo** environment of the branch user. When the method subsequently writes `move_n1.made_sequence_gap = …` on the browsed parent-company record, the ORM record-rule check finds the branch user has no access to that company → **`AccessError`**. * This is a regression from 18.4 where the equivalent `_set_next_made_sequence_gap` explicitly used `.sudo()` when searching for neighbour moves: https://github.com/odoo/odoo/blob/22d84ae99bb79e7b1022367e6bc1b61cc8d9e8b1/addons/account/models/account_move.py#L5453-L5457 **Fix:** * Add `.sudo()` inside the `browse()` closure so that neighbouring moves are always accessed with elevated rights, regardless of the calling user's company context. * `made_sequence_gap` is a UI-only flag that indicates sequence holes; it carries no security or financial significance, making the sudo escalation safe. opw-6231085 Forward-Port-Of: odoo/odoo#266676
This update corrects a problem where the E-Invoice QR code would break when multiple invoices were displayed, and a related issue with the Mydata classification group shrinking. The layout has been adjusted to ensure the QR code displays correctly regardless of the number of invoice lines, improving the E-Invoice generation process.
Original PR description
before this commit: - The QR code on the E-Invoice broke when multiple invoice lines were reduced the available space. - Mydata classification group is shrink. after this commit: - Adjusted the layout to ensure the QR code moves to a new page if there isn't enough space on the current page. - Fix Mydata classification shrink issue. task-6026681 Forward-Port-Of: odoo/odoo#266660
This update fixes an issue where subscription products with one-time purchase options were incorrectly displaying recurring subscription prices in the product configurator. Now, the configurator accurately shows the one-time price when this option is selected, ensuring accurate pricing for customers and improving the subscription ordering process across both the website and backend.
Original PR description
Version 19.1 steps to reproduce: - open sales and open a subscription product. enable accept one time and add another subscription product as an optional product. - open the website product page, select the one time price, and click add to cart. issue: when a subscription product that allows one time purchase is added to the cart or to a subscription order, the product configurator wizard was showing the recurring subscription price instead of the one time price. this issue was present both on the website frontend and in the backend subscription module. fix: the product configurator wizard now correctly shows the one time price when the accept one time option is selected, both on the website frontend and in the backend subscription flow. task: 6126684. Forward-Port-Of: odoo/enterprise#114862
This update resolves an issue where product variants weren't being created properly when a product template used a dynamic attribute with a single value. Previously, the order line would fail to add to the order. This change ensures that product variants are correctly generated, improving the reliability of the Point of Sale functionality.
Original PR description
When a product template has a dynamic attribute with only one value, `isConfigurable()` returns `false` (correctly suppressing the configurator popup), but `create_product_variant_from_pos` was never called, leaving the order line without a proper variant and causing error when trying to add it to the order. opw-6213957 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265589 Forward-Port-Of: odoo/odoo#264134
This update fixes an issue where multiple Mercado Pago terminals were incorrectly linked to a single payment interface, leading to missed webhook responses. The change ensures that each active terminal receives its own webhook notifications, improving the reliability of payment processing. This resolves a potential problem with duplicate payments or incomplete transactions.
Original PR description
Issue Upon initialization of the pos a PaymentInterface is constructed for every pos_payment_method (even archived pos payment methods ?!). [As we allow only one WebSocket subscription per…
Issue Upon initialization of the pos a PaymentInterface is constructed for every pos_payment_method (even archived pos payment methods ?!). [As we allow only one WebSocket subscription per channel](https://github.com/odoo/odoo/blob/4e1c89890c5fd54a79dcf5bf20268e51d8fe6e69/addons/point_of_sale/static/src/app/utils/payment/payment_interface.js#L100) for the PaymentInterface, all webhook responses will be linked to only one PaymentInterface. Meaning that when you have two Mercado Pago pos_payment_method terminals configured, only the first pos_payment_method (id=1) will be subscribed to the WebSocket and all the webhook responses from the second pos_payment_method terminal (id=2) will arrive to the PayementInterface of the first pos_payment_method (id=1). Where payload.payment_method_id (id=2) != this.payment_method_id.id (id=1). Solution - Only iterate and create a PaymentInterface for compatible pos_payment_methods which are active - Check if the webhook response is linked to the PendingPaymentLine opw-6069455 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262184
This update resolves a bug that occurred when using Point of Sale with multiple companies. The issue stemmed from how user assignments were being calculated, leading to a 'singleton' error. The fix ensures employees are correctly associated with each company's POS configuration, improving the functionality for businesses managing multiple locations.
Original PR description
Step to reproduce: - install point_of_sale with demo - have two company and 1 pos in each company - install pos_hr - install pos_sale Observation: - we get a traceback ``` File…
Step to reproduce:
- install point_of_sale with demo
- have two company and 1 pos in each company
- install pos_hr
- install pos_sale
Observation:
- we get a traceback
```
File "/src/saas-19.2/odoo/orm/fields_misc.py", line 115, in __get__
raise ValueError("Expected singleton: %s" % record) from None
ValueError: Expected singleton: res.company(7, 8)
```
- and pos_sale is not installed
Cause:
- when installing `pos_sale` `_ensure_downpayment_product` is called.
- this sets downpayment product on every `pos.config` record.
- this triggers write call from pos_hr, which tries to identify users for pos
- this uses `with_company(self.company)` <----- actual issue
- here self has two config, each from different company, hence `with_company`
raises singleton error
why not in earlier verison:
- before commit [1] we only set downpayment product on only pos_config_main
- now we set it on every pos.config, so now self contain multiple records
[1] https://github.com/odoo/odoo/commit/a3f9114434c7cab8757b0283698662792e6b7946
Fix:
- compute users by first grouping them over company_id
related pr: https://github.com/odoo/odoo/pull/254026
opw-6217135
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#264962This update fixes an issue where invoices weren't sorted correctly on the customer portal based on their payment status. The change updates the system to prioritize sorting by payment status, ensuring customers see invoices in the correct order based on whether they've been paid or not. This improves the user experience and accuracy of invoice management.
Original PR description
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. -…
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. - Navigate to the invoices list and attempt to sort by **Status**. Issue:- --- - Sorting by **Status** does not reflect the actual invoice payment status, resulting in incorrect ordering. Root cause: --- - At [1], the sorting field for Status is set to state, which corresponds to invoice states (Draft, Posted, Cancelled). However, the portal displays and expects sorting based on payment_state. Fix: --- - Update the sorting configuration to use payment_state instead of state, ensuring that invoices are sorted correctly according to their payment status on the portal. [1]https://github.com/odoo/odoo/blob/5b85287ec4ea9f1b51e0f33402900777dfeeb725/addons/account/controllers/portal.py#L46-L52 opw-6128998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262976
This update resolves an issue where the Account PEPPOL response service wasn't correctly activated after registration. The fix ensures that supported services are updated when the `2/connect` route is used, preventing the service from being missing when the module is installed prior to registration. This ensures proper functionality for PEPPOL integration.
Original PR description
To register as receiver we only call the `2/connect` route (and not any of the other `register*` routes). But currently that route does not update the supported services. Thus the response service is missing when the `account_peppol_response` module is installed before registering. We add the supported document identifiers to the `connect` call here. We change the route on IAP to update the services. task-None IAP PR: https://github.com/odoo/iap-apps/pull/1582 Forward-Port-Of: odoo/odoo#263747
This update ensures all Odoo views automatically update when data changes, resolving issues where some views (like the map view) wouldn't refresh. By centralizing subscriptions within the core system, this fix guarantees a consistent and responsive user experience, preventing disruptions to features like coordinate fetching.
Original PR description
This commit centralizes model event subscriptions within the `useModel` hook to ensure all view controllers reactively update by default. Previously, individual controllers were responsible for manually subscribing to the model's "update" events. Views that omitted this wiring (such as the map view) failed to re-render during mid-session `notify()` calls, breaking features like progressive coordinate fetching. Moving the subscription directly into `useModel` guarantees that all consumer views stay in sync automatically. As a result, the now-redundant manual subscription inside `HierarchyController` has been removed. task-6255163
This update resolves an issue that prevented the map's pin list from updating correctly during slow data loading. By creating a fresh copy of the pin data on demand, the map now displays accurate information more reliably, especially with large maps. This enhances the user experience and ensures the map remains responsive.
Original PR description
Fixes a core model issue where `_filterUnlocatedRecords` destructively mutated `data.recordGroups` in place, making it impossible to evaluate subsequent progressive OSM coordinate arrivals. The baseline state is now preserved in `data.allRecordGroups` at load time, and a fresh copy is derived on each call. To support this progressive rendering, `MapPinListPopover` is equipped with a `useBus` subscription. This ensures that while the core controller subtree updates automatically, this isolated popover also stays in sync with the model. task-6255163
This update fixes an issue where UBL files weren't correctly applying tax rates during import. Previously, the system used a simplified cache key that could lead to incorrect tax assignments for similar lines. This change ensures that the imported tax rates from the UBL file are accurately reflected, improving data consistency.
Original PR description
When we import a UBL file, we call the `_import_retrieve_tax` method to fetch taxes to indicate on lines.
During the process, we use cache to avoid performing the search a second time if a new line is the same as a previous one.
https://github.com/odoo/odoo/blob/d0424f2ffcf99ee59befe288150f1643b3fa0112/addons/account/models/account_tax.py#L4459-L4462
The cache_key used is defined as follows: {line's invoice, line's name, line's partner}.
This implies that if two lines from the same invoice share the same name and partner, the same tax will automatically be used even if different taxes were indicated in the file.
This is not desirable as we should match what is indicated in the XML file imported.
opw-6226166
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#266697This update resolves a bug where formatting (bold, italic, underline) applied to inline code selections within the HTML editor wouldn't be consistently removed. The fix ensures that formatting nodes are correctly handled during selection and removal, providing a more reliable editing experience. This improves the usability of the To-Do module and other areas where inline code is used.
Original PR description
Problem: When selecting text containing `o_inline_code` and applying formatting such as bold, italic, or underline, the formatting cannot be removed. Cause: When applying formatting, nodes matching…
Problem: When selecting text containing `o_inline_code` and applying formatting such as bold, italic, or underline, the formatting cannot be removed. Cause: When applying formatting, nodes matching `is_formattable_node_predicates` are ignored. However, when checking whether the selection is already formatted, those nodes are not ignored, so the selection is erroneously considered to be only partially formatted. Solution: Take `is_formattable_node_predicates` into account when checking whether a selection is formatted. Steps to reproduce: - Go to To-Do → Create New. - Type some text and add inline code on the same line. - Select all content using Ctrl + A. - Apply formatting such as bold, italic, or underline using keyboard shortcuts (Ctrl + B / Ctrl + I / Ctrl + U). - Press the same shortcut again to remove the formatting. - Observe that the formatting is not removed. task-6229228 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267455 Forward-Port-Of: odoo/odoo#265183
This update fixes a crash that occurred when purchase matching tried to convert vendor bills with only a description and UoM, without a linked product. The change ensures purchase matching works correctly with bills identified solely by their description, maintaining consistency in quantity calculations. This improves the reliability of importing vendor bills.
Original PR description
### Issue before this commit: Opening the Purchase Matching wizard would crash if the vendor bill contained lines with a description and a Unit of Measure (UoM), but no product selected. ### Steps to…
### Issue before this commit: Opening the Purchase Matching wizard would crash if the vendor bill contained lines with a description and a Unit of Measure (UoM), but no product selected. ### Steps to reproduce the issue: 1. Enable Units of Measure in Settings 2. Create and confirm a Vendor Bill setting a description and a UoM, but leave the Product field empty. 3. Click on "Purchase matching" smart button 4. The system throws a traceback with the error: "The unit of measure Unit defined on the order line doesn't belong to the same category as the unit of measure False defined on the product." ### Cause of the issue: In the purchase.bill.line.match model, the field product_uom_qty was computed by calling _compute_quantity using line.product_uom_id. Since product_uom_id is a related field on product_id.uom_id, it returns False when no product is set. The UoM conversion logic cannot handle a False destination category, leading to the crash. ### Reason to introduce the fix: Make purchase matching robust when imported vendor bills contain lines identified only by their description and not by a product. Note that for `purchase.bill.line.match` corresponding to an account.move.line but not related to any product, the `product_uom_qty` should match the quantity of the `aml_id` instead of attempting a UoM conversion based on a missing product UoM for the behavior to be consistent with the inverse method: https://github.com/odoo/odoo/blob/59d6232979b8499fde6cb700df1870e2e38d0d3e/addons/purchase/models/purchase_bill_line_match.py#L45-L54 opw-5911526 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266899 Forward-Port-Of: odoo/odoo#257827
This update resolves a problem where users authenticating with standard Polish certificates were incorrectly rejected. The change expands the certificate matching logic to correctly identify certificate types, restoring functionality for existing customers and ensuring continued support for new users. This prevents authentication errors related to KSeF compliance.
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 optimizes a key report that calculates historical inventory values. The change adds indexes to a database table, significantly speeding up the report generation process. Previously, the report was extremely slow due to inefficient database searches, but now it completes much faster.
Original PR description
The Inventory Valuation report at a past date rebuilds historical value by tracing stock moves. Two product.value lookups run on the hot path and both hit unindexed columns: -…
The Inventory Valuation report at a past date rebuilds historical value by tracing stock moves. Two product.value lookups run on the hot path and both hit unindexed columns: - stock.move._get_manual_value() searches product.value by move_id for every traced move; - product.product._get_last_product_value() searches product.value by product_id. product.value declares neither column with an index, so each lookup performs a sequential scan of the whole table. This is harmless on small tables but degrades sharply as product.value grows (one row is written per manual standard-price/move revaluation). On a database where product.value held ~9.6M rows, the per-move move_id lookup seq-scans the entire table only to return nothing (no row carries a move_id), repeated for every traced move, so the historical report never completes. Index product_id (dense) and move_id (btree_not_null, since it is null for every manual revaluation row). Each lookup then becomes an index scan. Measured on a ~9.6M-row product.value, historical valuation report, single date: | product.value lookup | without index | with index | | --------------------------- | ------------------------- | ------------------ | | by product_id (DISTINCT ON) | ~0.56s (1.7 GB seq scan) | index scan | | by move_id, per traced move | full seq scan, returns 0 | index scan | | report (~3.1M moves traced) | never completes (>20 min) | completes (~3 min) | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266790
This update resolves an issue where invoices with duplicate product entries would generate an error, preventing proper invoice creation. The fix automatically sums the quantities of the same product across multiple invoice lines, ensuring accurate invoice processing. This improves invoice accuracy and prevents disruptions to the invoicing workflow.
Original PR description
## Steps to Reproduce: 1. Install the **Invoicing** module. 2. Create a new product. 3. Create a new invoice and make the **Product** column visible in invoice lines. 4. Add the same product in two different invoice lines. 5. Click the **Catalog** button on the invoice lines. ## Error: `ValueError - Expected singleton: account.move.line(2, 3)` ## Cause: The method `_get_product_catalog_lines_data()` can receive multiple invoice lines for the same product when it appears more than once in the invoice. In this case, directly accessing quantity [1] on a multi-recordset raises an error. ## Fix: This commit sums up all line quantities for the same product. [1] - https://github.com/odoo/odoo/blob/61765c4ffc385402b02054fd6777c95d02f936e8/addons/account/models/account_move_line.py#L3875-L3884 sentry-7497160662
This update resolves an issue preventing AI Live Chat responses from being correctly delivered when embedded on other websites. The fix changes how the AI stream is accessed, ensuring it adheres to security protocols and receives the necessary data. This enhances the overall reliability and performance of the embedded AI Live Chat feature.
Original PR description
AI livechat embedded on another origin could not receive AI responses. The response stream is requested with fetch(), so it bypassed the livechat CORS routing that only wraps RPC calls. The matching CORS controller was also exposed as JSON-RPC, which cannot return the streamed HTTP response correctly. Expose the CORS endpoint as an HTTP stream, route the embedded fetch call to it, and pass the livechat guest token explicitly. task-id-6201054 Forward-Port-Of: odoo/enterprise#117535
This update fixes an issue where overtime was incorrectly reducing the displayed remaining time in the MO kanban view. The change ensures that the kanban header accurately reflects the actual remaining workload by ignoring previously consumed overtime values. This improves the accuracy of workload reporting.
Original PR description
Issue before this PR:- ======================== Currently, the total remaining time in the MO kanban header is computed by directly summing the `remaining_time` of all manufacturing orders in the…
Issue before this PR:- ======================== Currently, the total remaining time in the MO kanban header is computed by directly summing the `remaining_time` of all manufacturing orders in the column. This also includes overtime (negative remaining time), which incorrectly reduces the actual remaining workload. Steps to reproduce: ======================== 1) Install the `mrp_workorder` module. 2) Create 2 MOs with a work order. 3) Start the work order and wait until the real duration exceeds the expected duration (`real duration > expected duration`). 4) Pause the work order and open the MO kanban view. 5) Observe that the negative remaining time is shown in the column header. Cause of the issue: ======================== The `groupAggregate` method in the `MrpProductionKanbanHeader` component directly sums all `remaining_time` values, including negative ones. Since negative values represent overtime that has already been consumed, they should not reduce the future workload displayed in the kanban header. After this PR: ======================== This PR updates the method to treat negative remaining time as `0` when computing the total remaining time, ensuring that the kanban header correctly reflects the remaining future workload. TaskId:- 6226535
This update fixes an issue where manually added analytic distributions on purchase orders were lost when the line's account was changed. Now, when a purchase order line's account is updated, the associated analytic distribution remains intact, ensuring accurate tracking of costs. This prevents data inconsistencies and simplifies reporting for users managing purchase invoices.
Original PR description
__ ## Short functional explanation of the error When confirming a Purchase Order holding lines with an analytic distribution that has been manually added, and creating a vendor bill out of this PO…
__ ## Short functional explanation of the error When confirming a Purchase Order holding lines with an analytic distribution that has been manually added, and creating a vendor bill out of this PO using the Auto-Complete field. When we change the account of that line, the line loses the manually added Analytic Distribution. ## Reproduction Steps 1. Go to Accounting. Click on the tab Configuration; under the Analytic Accounting section, click on Analytic Distribution Models. 2. Create an Analytic Distribution Model for a product. 3. Go to Purchase. Create a new PO, set a Vendor and select the product you created the Analytic Distribution Model for. On the right side of the form, click on the view menu and check Analytic Distribution to make it appear. 4. Click on the Analytic Distribution of the product and add a new one; for example, select Administrative in the Departments section. 5. Confirm order. 6. Go to Accounting and click on the Vendors tab > Bills. Create a new bill, and in the field Auto-Complete, select the PO you just created. 7. Change the account of the line. ### Expected behavior Only the account should be changed on the line. ### Unexpected behavior The manually added Analytic Distribution has disappeared. ## Origin of the issue When we change the `account_id` field, the compute method `_compute_analytic_distribution` is triggered. This method retrieves the related distributions of the line: https://github.com/odoo/odoo/blob/af32885ec5f07d492f3b8e8fff1785996a739f72/addons/account/models/account_move_line.py#L1154 which, in the context of Purchase, calls this method: https://github.com/odoo/odoo/blob/af32885ec5f07d492f3b8e8fff1785996a739f72/addons/purchase/models/account_invoice.py#L540-L545 We retrieve the distribution of the related line using `self.purchase_line_id.analytic_distribution`. However, this code isn't triggered when the move line has an analytic distribution, even though the related line `purchase_line_id` might have one! Therefore, we need to execute that code whether or not our move line has an analytic distribution. Note: the same behavior is to avoid when creating invoices for quotations. __ opw-6062466 Forward-Port-Of: odoo/odoo#267274 Forward-Port-Of: odoo/odoo#258380
20 changes
Resolved issues and error corrections
This update addresses a requirement from the Peruvian tax authority (SUNAT) regarding delivery guides. Customers using the l10n_pe_edi_stock module now *must* include a 'carrier handover date' field to avoid validation errors. The update automatically handles this by reusing existing data, and provides a helpful message to users on older versions to update the module.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662
Forward-Port-Of: odoo/enterprise#119038This update corrects a problem where the QR code on E-Invoices would break when invoices had multiple lines, and a Mydata classification group was shrinking. The layout has been adjusted to ensure the QR code displays correctly regardless of the number of invoice lines, improving the E-Invoice generation process.
Original PR description
before this commit: - The QR code on the E-Invoice broke when multiple invoice lines were reduced the available space. - Mydata classification group is shrink. after this commit: - Adjusted the layout to ensure the QR code moves to a new page if there isn't enough space on the current page. - Fix Mydata classification shrink issue. task-6026681 Forward-Port-Of: odoo/odoo#266660
This update resolves an issue where branch users were unable to save new journal entries due to access restrictions. The fix adds elevated permissions to the query used to identify sequence gaps, allowing branch users to correctly create entries within their company's journal. This ensures branch users can fully utilize the accounting functionality.
Original PR description
**Steps to reproduce:** * Create a parent company with a branch company (Settings > Companies). * Create a user whose **only** allowed company is the branch. * While logged in as a parent-company…
**Steps to reproduce:** * Create a parent company with a branch company (Settings > Companies). * Create a user whose **only** allowed company is the branch. * While logged in as a parent-company admin, open the Miscellaneous Operations journal, find the first or second posted entry, reset it to draft, clear its name to a digits-only value (e.g. `0001`) and save – leaving it in draft state. This stores `sequence_prefix = ''` and `sequence_number = 1` in the database. * Log in as the branch-company user. * Navigate to Accounting > Journal Entries > New. * Set any date and save the draft entry (or simply write `name = '/'` on it). **Observed behavior:** * Saving fails with: `odoo.exceptions.AccessError: You are not allowed to access 'Journal Entry' (account.move) records.` **Cause:** * `_update_sequence_made_gap`, introduced in 19.0, detects sequence holes by running a raw SQL query that finds the two entries immediately before and after each move in the same journal with the same `sequence_prefix`. The query contains **no `company_id` filter**. * In a branch-company setup the parent's journal (`journal_id`) is shared across companies. When an early entry's `name` is cleared to a digits-only value its `sequence_prefix` becomes `''`. A new entry created by the branch user also starts with `name = '/'`, which gives it `sequence_prefix = ''` and `sequence_number = 0`. The SQL therefore returns the parent company's entry (`sequence_number = 1`, `sequence_prefix = ''`) as the `next_id` neighbour. * The IDs from that query are passed to a local `browse()` closure, which in 19.0 read: https://github.com/odoo/odoo/blob/af37df9bee34fe60c1e51896af23fc7fe9b76cfc/addons/account/models/account_move.py#L5770-L5771 * `self.browse()` inherits the **non-sudo** environment of the branch user. When the method subsequently writes `move_n1.made_sequence_gap = …` on the browsed parent-company record, the ORM record-rule check finds the branch user has no access to that company → **`AccessError`**. * This is a regression from 18.4 where the equivalent `_set_next_made_sequence_gap` explicitly used `.sudo()` when searching for neighbour moves: https://github.com/odoo/odoo/blob/22d84ae99bb79e7b1022367e6bc1b61cc8d9e8b1/addons/account/models/account_move.py#L5453-L5457 **Fix:** * Add `.sudo()` inside the `browse()` closure so that neighbouring moves are always accessed with elevated rights, regardless of the calling user's company context. * `made_sequence_gap` is a UI-only flag that indicates sequence holes; it carries no security or financial significance, making the sudo escalation safe. opw-6231085 Forward-Port-Of: odoo/odoo#266676
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 ensures accurate stock tracking and prevents discrepancies between sales orders, purchase orders, and receipts.
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 fixes an issue where subscription products with one-time purchase options were incorrectly displaying recurring subscription prices in the product configurator. Now, the configurator accurately shows the one-time price when this option is selected, ensuring accurate pricing for subscription orders across the website and backend.
Original PR description
Version 19.1 steps to reproduce: - open sales and open a subscription product. enable accept one time and add another subscription product as an optional product. - open the website product page, select the one time price, and click add to cart. issue: when a subscription product that allows one time purchase is added to the cart or to a subscription order, the product configurator wizard was showing the recurring subscription price instead of the one time price. this issue was present both on the website frontend and in the backend subscription module. fix: the product configurator wizard now correctly shows the one time price when the accept one time option is selected, both on the website frontend and in the backend subscription flow. task: 6126684. Forward-Port-Of: odoo/enterprise#114862
This update resolves an issue where product variants weren't being created when a product template used a dynamic attribute with only one possible value. Previously, the system wouldn't add the variant to the order, leading to errors. This change ensures that all product variants are correctly generated, improving order processing and preventing errors.
Original PR description
When a product template has a dynamic attribute with only one value, `isConfigurable()` returns `false` (correctly suppressing the configurator popup), but `create_product_variant_from_pos` was never called, leaving the order line without a proper variant and causing error when trying to add it to the order. opw-6213957 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265589 Forward-Port-Of: odoo/odoo#264134
This update fixes an issue where invoices weren't sorting correctly on the customer portal based on their payment status. The fix ensures invoices are displayed in the correct order (e.g., In Payment, Not Paid, Paid) as viewed by customers, improving the user experience.
Original PR description
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. -…
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. - Navigate to the invoices list and attempt to sort by **Status**. Issue:- --- - Sorting by **Status** does not reflect the actual invoice payment status, resulting in incorrect ordering. Root cause: --- - At [1], the sorting field for Status is set to state, which corresponds to invoice states (Draft, Posted, Cancelled). However, the portal displays and expects sorting based on payment_state. Fix: --- - Update the sorting configuration to use payment_state instead of state, ensuring that invoices are sorted correctly according to their payment status on the portal. [1]https://github.com/odoo/odoo/blob/5b85287ec4ea9f1b51e0f33402900777dfeeb725/addons/account/controllers/portal.py#L46-L52 opw-6128998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262976
This update fixes an issue where UBL invoices weren't correctly linking to purchase orders. The change now uses a more precise filter based on purchase order sequences, ensuring invoices are accurately matched to related purchase orders during import. This improves the reliability of our UBL invoice processing.
Original PR description
[FIX] *: improve invoice origin keywords selection modules: account_edi_ubl_cii, purchase_edi_ubl_bis3 In UBL when importing a vendor bill, if the purchase order reference is not in the right node (OrderReference), we're used to take every word in the items descriptions as potential reference without applying any filter This commit apply a filter using the ir.sequence related to the purchase.order model With this, we only consider words following the sequence naming pattern to search for a related PO no-task Forward-Port-Of: odoo/odoo#266998 Forward-Port-Of: odoo/odoo#262678
This update resolves a bug where shift calculations incorrectly displayed 0% allocated time for weekend shifts, preventing accurate hour allocation. Additionally, a test was modified to avoid running when demo data is present, ensuring consistent test execution. These changes improve the reliability of shift planning and testing processes.
Original PR description
## [FIX] planning_field_service: avoid division by 0 Before this commit, when the shift is created during the weekend, the allocated_percentage will be 0 percent because the resource assigned is not…
## [FIX] planning_field_service: avoid division by 0 Before this commit, when the shift is created during the weekend, the allocated_percentage will be 0 percent because the resource assigned is not supposed to work at that day and so a division by zero occured in the onchange of break_time field in planning.slot model. This commit checks if allocated_percentage is not equal to 0 before computing the new allocated hours when the user alters break_time field on a planning.slot. ## [FIX] planning_field_service: don't start test with onboarding tour with demo Before this commit, the planning_field_service_tour tour does not work when there is demo data because the tour will select the first slot in the gantt view which will be an open shift instead of a shift assigned to the current user because of that, the sign in button is not displayed as expected. This commit makes sure the test running the planning_field_service_tour tour is skipped when demo data are installed. runbot-error-242483
This update fixes an issue where restaurant order tickets were missing customer names. Previously, a change in the system's receipt printing process resulted in the display of order references instead of customer information. The fix ensures that customer names are now correctly included on direct-sale order tickets for restaurants, improving order clarity and customer experience.
Original PR description
Steps to reproduce ------------------ 1. Configure a kitchen printer for a restaurant 2. Open PoS, don't select a table, but select a customer 3. Select Take Out or Delivery 4. Add products in the kitchen printer's category 5. Send to the kitchen Observation -> the ticket shows the order reference, not the customer name! Why the issue: -------------- Before the receipt printer refactor https://github.com/odoo/odoo/commit/b1f17b6e61191cad6a932f923e76a0c406f91f13, the template was showing `order.getName()`, which returns `floating_order_name` (set to the partner name by `setPartner`). After the refactor, the template shows the raw `pos_reference` directly, hence the partner name is missing. Fix: ---- Show the table label when a table is set, otherwise `floating_order_name` which includes the customer name if it exists. opw-6208965
This update resolves an issue preventing monthly companies from receiving their inventory valuation journal entries. The cron job's domain was incorrectly excluding monthly companies, leading to missed valuations. Now, both daily and monthly companies are processed as intended, ensuring accurate inventory accounting at month-end.
Original PR description
#### Description of the issue/feature this PR addresses: The "Stock Account: Inventory Valuation Closing" cron is meant to post valuation journal entries for companies configured with periodic…
#### Description of the issue/feature this PR addresses: The "Stock Account: Inventory Valuation Closing" cron is meant to post valuation journal entries for companies configured with periodic inventory valuation. Due to a faulty domain in ResCompany._cron_post_stock_valuation, monthly companies are never processed, and on the last day of the month daily companies are also skipped. As a result, no inventory valuation journal entries are ever generated by this cron for periodic-valuation companies. #### Current behavior before PR: The cron's domain requires inventory_period = 'daily', which excludes monthly companies on every non-last day of the month. On the last day of the month, an extra AND clause is added requiring inventory_period = 'monthly'. Combined with the existing 'daily' clause, this produces a contradiction (period = 'daily' AND period = 'monthly') that matches no records, so daily companies are dropped on that day as well. Net effect: monthly companies are never processed, and daily companies are skipped on month-end. #### Desired behavior after PR is merged: On a non-last day of the month, the cron processes companies with inventory_period = 'daily'. On the last day of the month, the cron processes both 'daily' and 'monthly' companies, so monthly valuation entries are posted at month-end without dropping daily companies. opw-6115649 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264782 Forward-Port-Of: odoo/odoo#264298
This update fixes an issue where UBL files weren't correctly applying tax rates during import. Previously, the system used a simplified cache key that could lead to incorrect tax assignments for similar lines. This change ensures that the imported UBL file's tax information is accurately reflected, improving data consistency.
Original PR description
When we import a UBL file, we call the `_import_retrieve_tax` method to fetch taxes to indicate on lines.
During the process, we use cache to avoid performing the search a second time if a new line is the same as a previous one.
https://github.com/odoo/odoo/blob/d0424f2ffcf99ee59befe288150f1643b3fa0112/addons/account/models/account_tax.py#L4459-L4462
The cache_key used is defined as follows: {line's invoice, line's name, line's partner}.
This implies that if two lines from the same invoice share the same name and partner, the same tax will automatically be used even if different taxes were indicated in the file.
This is not desirable as we should match what is indicated in the XML file imported.
opw-6226166
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#266697This update resolves an error that prevented users with standard accounting access from verifying company partners within the Türkiye - Nilvera module. The fix allows users to perform verification without requiring full system administrator privileges, improving usability and workflow efficiency.
Original PR description
**Steps to reproduce:** * Install *Türkiye - Nilvera* (`l10n_tr_nilvera`) module. * Log in as *admin user*. * Create a *partner* for the company. * Set *country* as Turkey. * Configure required…
**Steps to reproduce:** * Install *Türkiye - Nilvera* (`l10n_tr_nilvera`) module. * Log in as *admin user*. * Create a *partner* for the company. * Set *country* as Turkey. * Configure required *taxes*. * Create a *demo user*. * Grant the demo user *Accounting admin access*. * Log in with the *demo user*. * Navigate to *Contacts* → open the *Turkey company partner*. * Navigate to *Nilvera Status* (via Invoicing/Accounting tab) click on *Verify*. **Observed behavior:** * A *company access error* is raised during partner verification. **Cause:** * The field *l10n_tr_nilvera_api_key* is restricted with `groups='base.group_system'`, requiring full system admin rights. * Users with *module-level admin access* (e.g., Accounting) do not have sufficient rights, causing the access error. **Fix:** * Use `sudo()` on `env.company` to bypass the restrictive group access. * This allows users with appropriate *functional admin rights* to perform verification without granting full system privileges. Ticket [link](https://www.odoo.com/odoo/project.task/6106907) opw-6106907 Forward-Port-Of: odoo/odoo#262668
This update resolves an issue where attachments sent via the 'Send by Email' action in Sales Orders were disappearing after refreshing the chatter window. The fix restricts attachment saving to the full composer view, ensuring consistent functionality across different composer types. This improves the reliability of email sending workflows.
Original PR description
**Steps to reproduce:** - Install Sales app - Create a Sales Order - Click on the 'Send by Email' action - Add an attachment and send it - Open the chatter to create a log note - Attachment is…
**Steps to reproduce:** - Install Sales app - Create a Sales Order - Click on the 'Send by Email' action - Add an attachment and send it - Open the chatter to create a log note - Attachment is attached to the new message - It disappears on refresh **Issue:** Attachment upload widget was moved to the toolbar of the composer with [1], which split it into `mail_composer_attachment_selector` and `mail_composer_attachment_list`. Then with [2] the selector logic was changed to use `FileUploader` instead of `FileInput` to get the attachment synced when switching back and forth between full and normal chatter composers. But this should not impact action composers created with `'mail.email_compose_message_wizard_form'`. **Fix:** Restrict the attachment save to the full composer using context. [1] https://github.com/odoo/odoo/commit/cee3c8146863300242f9f2d109743a50c2b91027 [2] https://github.com/odoo/odoo/commit/9f7249a141b618fc8640a65d1f7fc20023156ce3 opw-5164504 Forward-Port-Of: odoo/odoo#266994 Forward-Port-Of: odoo/odoo#265736
This update fixes an issue where flexible employee time off wasn't accurately reflected in the calendar views. Now, time off hours are correctly grayed out from midnight to 11 PM, aligning with expected behavior and ensuring accurate scheduling for flexible employees. This ensures accurate representation of employee availability.
Original PR description
__ ## Short functional explanation of the error When setting a time off for an employee who has a flexible schedule, in the attendance app, on the calendar with the 'days' view. We can see that the…
__ ## Short functional explanation of the error When setting a time off for an employee who has a flexible schedule, in the attendance app, on the calendar with the 'days' view. We can see that the hours are grayed out from 8 hours to 16 hours. However, according to this message: https://www.odoo.com/mail/message/1027495005 "[...] the entire day of absence might not be represented as such, which is an issue (for example if a flexible employee with 8h/day takes a day off, the duration of the leave should be 1 day/8 hours but on the gantt view everything should be gray from midnight to midnight)". Moreover, when we select the Week or Month view on the calendar, the day off isn't grayed out. This comes from the fact that, for a flexible schedule, we consider that any time of the day can be a working hour; and we only grey out days in the calendar where no hour has been worked at all. Hence, the hours considered during a flexible day off should be from midnight to 23:59:59. ## Reproduction Steps 1. Go to an employee's profile and set their schedule to flexible. 2. Create a time off of a one-day duration for this employee. 3. Go to the attendance app and see the calendar. ### Expected behavior When clicking on the Day view, all hours from midnight to 11pm should be grayed out. When clicking on the Week/month view, the day of the time off should be grayed out. ### Unexpected behavior When clicking on the Day view, hours from 8am to 4pm are grayed out. When clicking on the Week/month view, the day of the time off isn't grayed out. ## Origin of the issue First, we only consider the leave if the resource is fully flexible, i.e if the employee has no working calendar set: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L546 However, if the schedule of the employee is flexible, the leave resource isn't considered as fully flexible, thus leading us to a leave from 8 am to 4 pm. Moreover, when processing flexible leaves, we return the unavailable intervals with the timezone of the employee: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L589-L592 Whereas when we process fixed leaves, we return the unavailable intervals under utc: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L597-L601 This leads us to display problems: when the user is under European/ Brussels time in summer, the leave starts at 2 am and ends at 11pm, instead of starting at midnight. Note: after discussion with AJU, it has been agreed that the behavior should be the same on the Planning app. __ opw-6030212 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264154 Forward-Port-Of: odoo/odoo#256636
This update fixes an issue where flexible employee time off wasn't displayed accurately in the attendance calendar. Now, time off durations are correctly grayed out from midnight to 11 PM, aligning with expected behavior and ensuring accurate representation of employee availability. This improves the usability of the attendance app for flexible schedules.
Original PR description
__ ## Short functional explanation of the error When setting a time off for an employee who has a flexible schedule, in the attendance app, on the calendar with the 'days' view. We can see that the…
__ ## Short functional explanation of the error When setting a time off for an employee who has a flexible schedule, in the attendance app, on the calendar with the 'days' view. We can see that the hours are grayed out from 8 hours to 16 hours. However, according to this message: https://www.odoo.com/mail/message/1027495005 "[...] the entire day of absence might not be represented as such, which is an issue (for example if a flexible employee with 8h/day takes a day off, the duration of the leave should be 1 day/8 hours but on the gantt view everything should be gray from midnight to midnight)". Moreover, when we select the Week or Month view on the calendar, the day off isn't grayed out. This comes from the fact that, for a flexible schedule, we consider that any time of the day can be a working hour; and we only grey out days in the calendar where no hour has been worked at all. Hence, the hours considered during a flexible day off should be from midnight to 23:59:59. ## Reproduction Steps 1. Go to an employee's profile and set their schedule to flexible. 2. Create a time off of a one-day duration for this employee. 3. Go to the attendance app and see the calendar. ### Expected behavior When clicking on the Day view, all hours from midnight to 11pm should be grayed out. When clicking on the Week/month view, the day of the time off should be grayed out. ### Unexpected behavior When clicking on the Day view, hours from 8am to 4pm are grayed out. When clicking on the Week/month view, the day of the time off isn't grayed out. ## Origin of the issue First, we only consider the leave if the resource is fully flexible, i.e if the employee has no working calendar set: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L546 However, if the schedule of the employee is flexible, the leave resource isn't considered as fully flexible, thus leading us to a leave from 8 am to 4 pm. Moreover, when processing flexible leaves, we return the unavailable intervals with the timezone of the employee: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L589-L592 Whereas when we process fixed leaves, we return the unavailable intervals under utc: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L597-L601 This leads us to display problems: when the user is under European/ Brussels time in summer, the leave starts at 2 am and ends at 11pm, instead of starting at midnight. Note: after discussion with AJU, it has been agreed that the behavior should be the same on the Planning app. __ opw-6030212 Forward-Port-Of: odoo/enterprise#117112 Forward-Port-Of: odoo/enterprise#112482
This update optimizes a key report that calculates historical stock values. The change adds indexes to a database table, significantly speeding up the report generation process. Previously, the report was extremely slow due to inefficient database searches, but now it completes much faster.
Original PR description
The Inventory Valuation report at a past date rebuilds historical value by tracing stock moves. Two product.value lookups run on the hot path and both hit unindexed columns: -…
The Inventory Valuation report at a past date rebuilds historical value by tracing stock moves. Two product.value lookups run on the hot path and both hit unindexed columns: - stock.move._get_manual_value() searches product.value by move_id for every traced move; - product.product._get_last_product_value() searches product.value by product_id. product.value declares neither column with an index, so each lookup performs a sequential scan of the whole table. This is harmless on small tables but degrades sharply as product.value grows (one row is written per manual standard-price/move revaluation). On a database where product.value held ~9.6M rows, the per-move move_id lookup seq-scans the entire table only to return nothing (no row carries a move_id), repeated for every traced move, so the historical report never completes. Index product_id (dense) and move_id (btree_not_null, since it is null for every manual revaluation row). Each lookup then becomes an index scan. Measured on a ~9.6M-row product.value, historical valuation report, single date: | product.value lookup | without index | with index | | --------------------------- | ------------------------- | ------------------ | | by product_id (DISTINCT ON) | ~0.56s (1.7 GB seq scan) | index scan | | by move_id, per traced move | full seq scan, returns 0 | index scan | | report (~3.1M moves traced) | never completes (>20 min) | completes (~3 min) | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266790
This update fixes an issue where custom text attributes on products weren't correctly displayed in POS order lines. Previously, the POS system showed a placeholder instead of the customer's entered text. The fix ensures that customer-defined attributes are accurately reflected when settling orders from the website through POS.
Original PR description
When a sale order containing a product with a custom (free text) attribute was settled in POS, the order line displayed the placeholder attribute value name (e.g. "Custom") instead of the actual text…
When a sale order containing a product with a custom (free text) attribute was settled in POS, the order line displayed the placeholder attribute value name (e.g. "Custom") instead of the actual text entered by the customer. Steps to reproduce: ------------------- * Create a product with a free text attribute (create_variant='no_variant', is_custom=True) * Go to the website's shop (works best in a new private tab) * Fill the free text attribute and add the product to the cart * Click on checkout * In POS, open Quotation/Order and settle the order > Observation: the order line shows "Custom" instead of the text Why the fix: ------------ `SaleOrderLine._load_pos_data_fields` was not exposing `product_no_variant_attribute_value_ids` nor `product_custom_attribute_value_ids`, so the JS `settleSO` function received no attribute data on the `line` object. As a result, the new POS order line was created with empty `attribute_value_ids` and `custom_attribute_value_ids`, leaving `constructFullProductName` unable to find the custom text. The fix adds both fields to `_load_pos_data_fields` and updates `settleSO` to use them when building the new POS order line. The dynamic fetch path (`_getSaleOrder`) is also updated to explicitly read the `product.attribute.custom.value` records so the data is available for orders loaded at runtime. opw-5958678 Forward-Port-Of: odoo/odoo#266875 Forward-Port-Of: odoo/odoo#251993
This update fixes an issue where orders placed at tables in one POS configuration were sometimes incorrectly matched and merged by other POS configurations sharing the same restaurant floor. This ensures that orders are accurately tracked and processed, preventing duplicate orders and improving the reliability of our restaurant POS system. The fix was verified through task ID 6024012.
Original PR description
When multiple POS configurations share the same restaurant floor, an order placed on a table in one POS could be incorrectly retrieved or merged by another POS selecting the same table. task-id: 6024012 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253116
This update resolves a crash that occurred when creating payslips for Belgian employees with overtime, specifically when using attendance-based work contracts. The issue stemmed from a data structure mismatch within the payroll calculations, which has now been corrected. This ensures accurate payslip generation for all employees.
Original PR description
When creating a payslip for an employee in the Belgian localization with an hourly wage and an attendance-based work entry source contract, a traceback occurs if there is an attendance with overtime. This happens because the overridden `_preprocess_work_hours_data_split_half` method in `l10n_be_hr_payroll_attendance` attempts to unpack `work_entries` assuming it is a list of triplets, but it is passed as a `defaultdict` with composite keys instead. This data structure mismatch results in a `ValueError: not enough values to unpack (expected 3, got 2)`. Even if updated to handle the `defaultdict` structure, `_preprocess_work_hours_data_split_half` would improperly delete the overtime line hours without adding them back elsewhere (the code responsible for adding them back seems to have been removed). Since this function serves no purpose anymore, we omit the call to it. However, because `saas-19.2` is a stable version Task Id: 6253707
15 changes
Resolved issues and error corrections
This update addresses a requirement from the Peruvian tax authority, SUNAT, regarding delivery guides for freight transport. Previously, a 'carrier handover date' field was missing, causing errors when submitting delivery guides. The fix automatically detects this error and prompts users to update to the latest module version to ensure compliance.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662
Forward-Port-Of: odoo/enterprise#119038This update resolves an issue where the E-Invoice QR code would break when multiple invoices were displayed, and a related layout problem with Mydata classification groups shrinking. The changes ensure the QR code displays correctly regardless of the number of invoices and maintain a consistent layout.
Original PR description
before this commit: - The QR code on the E-Invoice broke when multiple invoice lines were reduced the available space. - Mydata classification group is shrink. after this commit: - Adjusted the layout to ensure the QR code moves to a new page if there isn't enough space on the current page. - Fix Mydata classification shrink issue. task-6026681 Forward-Port-Of: odoo/odoo#266660
This update resolves an issue where branch users were unable to save new journal entries due to access restrictions. The fix adds elevated permissions to the query used to identify sequence gaps, allowing branch users to correctly create entries within their company's journal. This ensures branch users can perform standard accounting tasks.
Original PR description
**Steps to reproduce:** * Create a parent company with a branch company (Settings > Companies). * Create a user whose **only** allowed company is the branch. * While logged in as a parent-company…
**Steps to reproduce:** * Create a parent company with a branch company (Settings > Companies). * Create a user whose **only** allowed company is the branch. * While logged in as a parent-company admin, open the Miscellaneous Operations journal, find the first or second posted entry, reset it to draft, clear its name to a digits-only value (e.g. `0001`) and save – leaving it in draft state. This stores `sequence_prefix = ''` and `sequence_number = 1` in the database. * Log in as the branch-company user. * Navigate to Accounting > Journal Entries > New. * Set any date and save the draft entry (or simply write `name = '/'` on it). **Observed behavior:** * Saving fails with: `odoo.exceptions.AccessError: You are not allowed to access 'Journal Entry' (account.move) records.` **Cause:** * `_update_sequence_made_gap`, introduced in 19.0, detects sequence holes by running a raw SQL query that finds the two entries immediately before and after each move in the same journal with the same `sequence_prefix`. The query contains **no `company_id` filter**. * In a branch-company setup the parent's journal (`journal_id`) is shared across companies. When an early entry's `name` is cleared to a digits-only value its `sequence_prefix` becomes `''`. A new entry created by the branch user also starts with `name = '/'`, which gives it `sequence_prefix = ''` and `sequence_number = 0`. The SQL therefore returns the parent company's entry (`sequence_number = 1`, `sequence_prefix = ''`) as the `next_id` neighbour. * The IDs from that query are passed to a local `browse()` closure, which in 19.0 read: https://github.com/odoo/odoo/blob/af37df9bee34fe60c1e51896af23fc7fe9b76cfc/addons/account/models/account_move.py#L5770-L5771 * `self.browse()` inherits the **non-sudo** environment of the branch user. When the method subsequently writes `move_n1.made_sequence_gap = …` on the browsed parent-company record, the ORM record-rule check finds the branch user has no access to that company → **`AccessError`**. * This is a regression from 18.4 where the equivalent `_set_next_made_sequence_gap` explicitly used `.sudo()` when searching for neighbour moves: https://github.com/odoo/odoo/blob/22d84ae99bb79e7b1022367e6bc1b61cc8d9e8b1/addons/account/models/account_move.py#L5453-L5457 **Fix:** * Add `.sudo()` inside the `browse()` closure so that neighbouring moves are always accessed with elevated rights, regardless of the calling user's company context. * `made_sequence_gap` is a UI-only flag that indicates sequence holes; it carries no security or financial significance, making the sudo escalation safe. opw-6231085 Forward-Port-Of: odoo/odoo#266676
The WIP report now displays accurate information when using analytic items tracked only with projects. Previously, demo data was shown, which could mislead users. This fix ensures the report preview correctly reflects the data associated with the analytic item, improving report clarity and user understanding.
Original PR description
Currently, when printing the WIP report, demo data is displayed if no product or references are provided on the analytic item. ## Steps to produce: - Install Manufacturing and Accounting - Go to…
Currently, when printing the WIP report, demo data is displayed if no product or references are provided on the analytic item. ## Steps to produce: - Install Manufacturing and Accounting - Go to settings and Enable Analytic Accounting - Search Analytic items and create a new Analytic Item by providing a description and amount. - Gear Icon > print and open the WIP report ## Observed Behavior: The report displays a product (laptop) with a demo reference. This becomes problematic when an analytic item is tracked only with a project, as it still causes product and reference data to appear on the analytic item. This can mislead the user. ## Root cause: After this [commit](https://github.com/odoo/odoo/commit/967ac550e38bab915180647dea6eccb2ae1b3b31), demo data values were added to the report to support report editor previews in the web studio. This helps users understand how the report will look while they are editing it. However, although an account analytic line is defined at [1], no values for fields such as products and references are specified on the form. As a result, the template falls back to the preview values provided. [1]- https://github.com/odoo/odoo/blob/d66bb0d7b550b11876dbc7b9d87f5b2adc17dd74/addons/mrp_account/report/report_mrp_templates.xml#L32-L53 ## Solution: Using `data-oe-demo` instead of removing the fallback data appears to be the best approach, as it allows the report editor to continue using demo values for the report preview, as shown at [2] **Before:** <img width="871" height="340" alt="image" src="https://github.com/user-attachments/assets/91897dbd-65d8-4f70-8f22-ea38b42ba28d" /> **After:** <img width="815" height="380" alt="image" src="https://github.com/user-attachments/assets/ffcf509b-f534-47a8-be1d-53a798995443" /> [2]: https://github.com/odoo/enterprise/blob/a739c6c03c6629bad80f3fe61b1035ce156d59c6/web_studio/static/src/client_action/report_editor/report_iframe.scss#L65-L75 opw-6151563 Forward-Port-Of: odoo/odoo#262517
This update resolves an issue preventing users from scheduling tasks via drag and drop in the Field Service calendar view. The problem stemmed from a validation rule within the industry_fsm module incorrectly resetting deadlines when date changes were detected. This fix ensures drag-and-drop scheduling functions correctly, improving the usability of the Field Service calendar.
Original PR description
Steps to reproduce: ----------------------------------- 1. Install the Field Service module with demo data 2. Go to Projects > Field service 3. Navigate to Calendar view 4. If there's no task in 'To…
Steps to reproduce: ----------------------------------- 1. Install the Field Service module with demo data 2. Go to Projects > Field service 3. Navigate to Calendar view 4. If there's no task in 'To Schedule' section, Drag and drop some tasks into it 5. Now, Try to drag and drop task from 'To Schedule' to the calendar Observation: ----------------------------------- The task is not scheduled by drag and drop in the calendar view Issue: ------------------------------------ When a user drags a task, the Javascript Calendar Model creates an RPC call to `plan_task_in_calendar(vals)`, where `vals` uses `planned_date_start` as the key instead of the database column name `planned_date_begin`. https://github.com/odoo/odoo/blob/153d6bab23f41f340058b98b7708ed058019f35c/addons/project/static/src/views/project_task_calendar/project_task_calendar_model.js#L44-L58 For standard project tasks, the backend `write()` method accepts `planned_date_start` and triggers its `_inverse` method, effectively redirecting the value to the deadline without complaining https://github.com/odoo/enterprise/blob/2f8121157f6dd2e19e242cf8de93b321d7ae0415/project_enterprise/models/project_task.py#L412-L418 However, the `industry_fsm` module implements strict validation in its own `write()` override: if it detects that dates were changed but `planned_date_begin` is totally missing from the update values, it forcibly resets all deadlines to `False`. Therefore, the FSM task scheduling was silently aborted entirely. https://github.com/odoo/enterprise/blob/2f8121157f6dd2e19e242cf8de93b321d7ae0415/industry_fsm/models/project_task.py#L169-L175 Solution: ------------------------------------ We override `plan_task_in_calendar` inside the `industry_fsm` module. This cleanly resolves the mismatch between the frontend interface and the backend table structure precisely at the RPC entry point. By isolating the fix mapping strictly to the FSM module override, we ensure we satisfy the strict FSM `write()` validations Note ------------------------------------ Alternate Approach: https://github.com/odoo/enterprise/commit/5cd627efdc3b2cf1db99a3532b36f2299b123724 Update the calendar view XML definition to use `planned_date_begin` instead of `planned_date_start` for the `date_start` attribute. As calendar drag-and-drop functionality fails due to field name mismatch. The `scheduleEvent` method uses `fieldMapping` to construct vals with 'planned_date_start' as the `date_start` field. https://github.com/odoo/odoo/blob/01df8267ec14cac4a773f78952a7aa9406e00fd4/addons/project/static/src/views/project_task_calendar/project_task_calendar_model.js#L44-L54 opw-6090448
This update resolves an issue where invoices on the customer portal were not sorted correctly by payment status. The fix changes the sorting field to use the actual payment state, ensuring users see invoices organized by their payment status (e.g., Paid, In Payment).
Original PR description
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. -…
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. - Navigate to the invoices list and attempt to sort by **Status**. Issue:- --- - Sorting by **Status** does not reflect the actual invoice payment status, resulting in incorrect ordering. Root cause: --- - At [1], the sorting field for Status is set to state, which corresponds to invoice states (Draft, Posted, Cancelled). However, the portal displays and expects sorting based on payment_state. Fix: --- - Update the sorting configuration to use payment_state instead of state, ensuring that invoices are sorted correctly according to their payment status on the portal. [1]https://github.com/odoo/odoo/blob/5b85287ec4ea9f1b51e0f33402900777dfeeb725/addons/account/controllers/portal.py#L46-L52 opw-6128998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262976
This update fixes an issue where invoice origin matching was overly broad, leading to potential inaccuracies. The change now uses a more precise filter based on purchase order sequences, ensuring that matching PO references are identified correctly during UBL import. This improves the reliability of vendor bill data integration.
Original PR description
[FIX] *: improve invoice origin keywords selection modules: account_edi_ubl_cii, purchase_edi_ubl_bis3 In UBL when importing a vendor bill, if the purchase order reference is not in the right node (OrderReference), we're used to take every word in the items descriptions as potential reference without applying any filter This commit apply a filter using the ir.sequence related to the purchase.order model With this, we only consider words following the sequence naming pattern to search for a related PO no-task Forward-Port-Of: odoo/odoo#266998 Forward-Port-Of: odoo/odoo#262678
This update fixes an issue where a file upload initiated through the link popover would continue in the background even after the popover was discarded. Now, discarding the popover during an upload immediately stops the upload process, preventing unwanted links from being added to records. This improves the user experience and ensures data integrity.
Original PR description
**Current behavior before PR:** Steps to reproduce the issue: - Go to Todo, In the network tab switch to "Slow 4G" so that file upload can take few seconds to upload. - Upload a file using link popover. - While the file upload is in progress, hit the discard button of the link popover. - Notice that the upload continues in the background and when it completes successfully, link is inserted. **Desired behavior after PR is merged:** Discarding the link popover during file upload should cancel the upload request and prevent inserting the link. task-6199113 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266952 Forward-Port-Of: odoo/odoo#263463
This update resolves a problem where orders placed in one restaurant POS configuration could be incorrectly matched and merged by another configuration sharing the same table. This ensures accurate order tracking and prevents duplicate orders, improving the reliability of our restaurant POS system. The fix was verified through task ID 6024012.
Original PR description
When multiple POS configurations share the same restaurant floor, an order placed on a table in one POS could be incorrectly retrieved or merged by another POS selecting the same table. task-id: 6024012 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253116
This update fixes an issue where UBL files weren't always correctly applying tax rates during import. The system previously used a simplified cache key, leading to inaccurate tax assignments for similar lines. This change ensures that the imported UBL file's tax information is precisely reflected, improving data accuracy.
Original PR description
When we import a UBL file, we call the `_import_retrieve_tax` method to fetch taxes to indicate on lines.
During the process, we use cache to avoid performing the search a second time if a new line is the same as a previous one.
https://github.com/odoo/odoo/blob/d0424f2ffcf99ee59befe288150f1643b3fa0112/addons/account/models/account_tax.py#L4459-L4462
The cache_key used is defined as follows: {line's invoice, line's name, line's partner}.
This implies that if two lines from the same invoice share the same name and partner, the same tax will automatically be used even if different taxes were indicated in the file.
This is not desirable as we should match what is indicated in the XML file imported.
opw-6226166
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#266697This update resolves an error that prevented users with standard accounting access from verifying company partners within the Türkiye - Nilvera module. The fix allows users to perform verification without requiring full system administrator privileges, improving usability and workflow. This ensures smoother partner setup and data verification.
Original PR description
**Steps to reproduce:** * Install *Türkiye - Nilvera* (`l10n_tr_nilvera`) module. * Log in as *admin user*. * Create a *partner* for the company. * Set *country* as Turkey. * Configure required…
**Steps to reproduce:** * Install *Türkiye - Nilvera* (`l10n_tr_nilvera`) module. * Log in as *admin user*. * Create a *partner* for the company. * Set *country* as Turkey. * Configure required *taxes*. * Create a *demo user*. * Grant the demo user *Accounting admin access*. * Log in with the *demo user*. * Navigate to *Contacts* → open the *Turkey company partner*. * Navigate to *Nilvera Status* (via Invoicing/Accounting tab) click on *Verify*. **Observed behavior:** * A *company access error* is raised during partner verification. **Cause:** * The field *l10n_tr_nilvera_api_key* is restricted with `groups='base.group_system'`, requiring full system admin rights. * Users with *module-level admin access* (e.g., Accounting) do not have sufficient rights, causing the access error. **Fix:** * Use `sudo()` on `env.company` to bypass the restrictive group access. * This allows users with appropriate *functional admin rights* to perform verification without granting full system privileges. Ticket [link](https://www.odoo.com/odoo/project.task/6106907) opw-6106907 Forward-Port-Of: odoo/odoo#262668
This update resolves a bug where formatting (bold, italic, underline) applied to selected inline code within the HTML editor wouldn't consistently be removed. The fix ensures that formatting nodes are correctly handled during selection and removal, improving the user experience when working with code snippets.
Original PR description
Problem: When selecting text containing `o_inline_code` and applying formatting such as bold, italic, or underline, the formatting cannot be removed. Cause: When applying formatting, nodes matching…
Problem: When selecting text containing `o_inline_code` and applying formatting such as bold, italic, or underline, the formatting cannot be removed. Cause: When applying formatting, nodes matching `is_formattable_node_predicates` are ignored. However, when checking whether the selection is already formatted, those nodes are not ignored, so the selection is erroneously considered to be only partially formatted. Solution: Take `is_formattable_node_predicates` into account when checking whether a selection is formatted. Steps to reproduce: - Go to To-Do → Create New. - Type some text and add inline code on the same line. - Select all content using Ctrl + A. - Apply formatting such as bold, italic, or underline using keyboard shortcuts (Ctrl + B / Ctrl + I / Ctrl + U). - Press the same shortcut again to remove the formatting. - Observe that the formatting is not removed. task-6229228 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267455 Forward-Port-Of: odoo/odoo#265183
This update resolves an issue where orders with heavy products (over 150kg) triggered errors when using the Sendcloud delivery method in the e-commerce. The fix ensures that the system accurately processes multi-package shipments based on weight, preventing order failures and improving the e-commerce shipping experience.
Original PR description
Issue ----- Traceback when trying to get a rate through the e-commerce if the order has to be split into multiple packages due to weight being too high. Steps to reproduce ----- - Setup Sendcloud…
Issue ----- Traceback when trying to get a rate through the e-commerce if the order has to be split into multiple packages due to weight being too high. Steps to reproduce ----- - Setup Sendcloud delivery method - make it available in e-commerce - Create a 150kg product and publish it - Go to e-commerce - Add the product to cart - Checkout the cart > Traceback Cause ----- We retrieve the order's weight through the context. https://github.com/odoo/enterprise/blob/d9a9339e1f30f1e5cc37ebb88949451a6652f83b/delivery_sendcloud/models/delivery_carrier.py#L108 If the call to `_get_shipping_rate` returns that the delivery requires multiple packages, we go into https://github.com/odoo/enterprise/blob/d9a9339e1f30f1e5cc37ebb88949451a6652f83b/delivery_sendcloud/models/delivery_carrier.py#L126-L128 If `order_weight` was not present in the context, this will cause an error in `sendcloud_convert_weight` since it expects a numerical value but receives the `None` fallback. This context key is only present when going through `choose.delivery.carrier` (so not in the e-commerce flow). https://github.com/odoo/odoo/blob/058e640e6687ed3f709dc846f0fa7a1f45226849/addons/delivery/wizard/choose_delivery_carrier.py#L69 ----- Ticket: opw-6210398 Forward-Port-Of: odoo/enterprise#117028
This update optimizes a key report that calculates historical inventory values. The change adds indexes to a database table, dramatically speeding up the report generation process. Previously, the report was extremely slow due to inefficient database searches, but now it completes much faster.
Original PR description
The Inventory Valuation report at a past date rebuilds historical value by tracing stock moves. Two product.value lookups run on the hot path and both hit unindexed columns: -…
The Inventory Valuation report at a past date rebuilds historical value by tracing stock moves. Two product.value lookups run on the hot path and both hit unindexed columns: - stock.move._get_manual_value() searches product.value by move_id for every traced move; - product.product._get_last_product_value() searches product.value by product_id. product.value declares neither column with an index, so each lookup performs a sequential scan of the whole table. This is harmless on small tables but degrades sharply as product.value grows (one row is written per manual standard-price/move revaluation). On a database where product.value held ~9.6M rows, the per-move move_id lookup seq-scans the entire table only to return nothing (no row carries a move_id), repeated for every traced move, so the historical report never completes. Index product_id (dense) and move_id (btree_not_null, since it is null for every manual revaluation row). Each lookup then becomes an index scan. Measured on a ~9.6M-row product.value, historical valuation report, single date: | product.value lookup | without index | with index | | --------------------------- | ------------------------- | ------------------ | | by product_id (DISTINCT ON) | ~0.56s (1.7 GB seq scan) | index scan | | by move_id, per traced move | full seq scan, returns 0 | index scan | | report (~3.1M moves traced) | never completes (>20 min) | completes (~3 min) | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266790
This update resolves a technical issue preventing Viva payments in the POS kiosk. The Viva payment system requires a unique identifier for the cash register, which was previously missing. This fix ensures the correct 'cashRegisterId' is included in the payment request, preventing errors and allowing successful Viva transactions.
Original PR description
When validating a payment in POS Kiosk with Viva payment method we get a Viva.com error Viva’s card-terminal API validates the JSON body with Pydantic and requires a non-empty ``cashRegisterId``. Steps to reproduce: ------------------- * Open POS in kiosk * Make an order and pay with Viva > Observation: Viva returns a validation error: ``cashRegisterId`` is missing or required in the request body (Pydantic ``missing`` on ``body.cashRegisterId``). Why the fix: ------------ Compute ``cashRegisterId`` in the POS client as cashier name, then ``pos.config.name`` so the value is always a non-empty string sent to ``viva_wallet_send_payment_request``. opw-6091223 Forward-Port-Of: odoo/odoo#266980 Forward-Port-Of: odoo/odoo#258605
2 changes
Resolved issues and error corrections
This update addresses a requirement from the Peruvian tax authority (SUNAT) regarding delivery guides. Customers using the l10n_pe_edi_stock module now need to include a 'carrier handover date' field in their delivery guides to avoid errors. The update automatically handles this by reusing existing data, and provides a helpful message to users on older versions to update their module.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662
Forward-Port-Of: odoo/enterprise#119038This update resolves a crash in the General Ledger report when using prefix groups. The fix addresses an issue caused by incorrect domain generation, ensuring lines can be properly expanded. This improves report functionality for users utilizing prefix group filtering.
Original PR description
If expanding a line in the General Ledger report using a prefix group (defined on `prefix_groups_threshold`) users experience a crash due to a bad domain. This bad domain is caused by a custom…
If expanding a line in the General Ledger report using a prefix group (defined on `prefix_groups_threshold`) users experience a crash due to a bad domain. This bad domain is caused by a custom groupby key that is not a real field name, which causes the invalid domain name to be generated here https://github.com/odoo/enterprise/blob/e9a920d62a5894d8198fdbf2e35032de555d0bd7/account_reports/models/account_report.py#L5895-L5898 The solution adds mapping of the groupby names to the actual field names and adjusts `_report_expand_unfoldable_line_groupby_prefix_group()` to read the custom groupby keys from this mapping, thus creating valid domains. This also changes the `forced_domain` to use `display_name` instead of `name` , allowing the lines to expand properly. https://github.com/odoo/enterprise/blob/da6ab7eedfa1b326cc6e01876dfff30e50a1c578/account_reports/models/account_report.py#L5896 Reproduction steps: Runbot 18.4 Debug/Developer mode Accounting -> General Ledger Report Gear icon in top bar Options -> Lower the prefix_groups_threshold to 1 Go back to the general ledger, try expanding some lines and see crash **Only affects 18.4** opw-6231127
10 changes
Resolved issues and error corrections
This update addresses a requirement from the Peruvian tax authority (SUNAT) regarding delivery guides. Customers using the l10n_pe_edi_stock module were previously receiving errors due to a missing field for the carrier handover date. The fix automatically detects this error and provides a clear message to users to update their module version to comply with the latest regulations.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662
Forward-Port-Of: odoo/enterprise#119038The WIP report now displays accurate information when using analytic items tracked only with projects. Previously, demo data was shown, which could mislead users. This fix ensures the report preview reflects the actual data configured for the analytic item, improving report clarity and usability.
Original PR description
Currently, when printing the WIP report, demo data is displayed if no product or references are provided on the analytic item. ## Steps to produce: - Install Manufacturing and Accounting - Go to…
Currently, when printing the WIP report, demo data is displayed if no product or references are provided on the analytic item. ## Steps to produce: - Install Manufacturing and Accounting - Go to settings and Enable Analytic Accounting - Search Analytic items and create a new Analytic Item by providing a description and amount. - Gear Icon > print and open the WIP report ## Observed Behavior: The report displays a product (laptop) with a demo reference. This becomes problematic when an analytic item is tracked only with a project, as it still causes product and reference data to appear on the analytic item. This can mislead the user. ## Root cause: After this [commit](https://github.com/odoo/odoo/commit/967ac550e38bab915180647dea6eccb2ae1b3b31), demo data values were added to the report to support report editor previews in the web studio. This helps users understand how the report will look while they are editing it. However, although an account analytic line is defined at [1], no values for fields such as products and references are specified on the form. As a result, the template falls back to the preview values provided. [1]- https://github.com/odoo/odoo/blob/d66bb0d7b550b11876dbc7b9d87f5b2adc17dd74/addons/mrp_account/report/report_mrp_templates.xml#L32-L53 ## Solution: Using `data-oe-demo` instead of removing the fallback data appears to be the best approach, as it allows the report editor to continue using demo values for the report preview, as shown at [2] **Before:** <img width="871" height="340" alt="image" src="https://github.com/user-attachments/assets/91897dbd-65d8-4f70-8f22-ea38b42ba28d" /> **After:** <img width="815" height="380" alt="image" src="https://github.com/user-attachments/assets/ffcf509b-f534-47a8-be1d-53a798995443" /> [2]: https://github.com/odoo/enterprise/blob/a739c6c03c6629bad80f3fe61b1035ce156d59c6/web_studio/static/src/client_action/report_editor/report_iframe.scss#L65-L75 opw-6151563 Forward-Port-Of: odoo/odoo#262517
This update resolves an issue preventing attendee imports on events with the default mail scheduler. The fix ensures emails are queued asynchronously, avoiding conflicts with the database savepoint system during import processes. This improves the reliability of attendee data updates.
Original PR description
Importing attendees on an event that has an `after_sub` mail scheduler (the default on every event) fails with `savepoint "..." does not exist` and the import is aborted.…
Importing attendees on an event that has an `after_sub` mail scheduler (the default on every event) fails with `savepoint "..." does not exist` and the import is aborted. [`_update_mail_schedulers`](https://github.com/odoo/odoo/blob/b2f3270271f6/addons/event/models/event_registration.py#L298) runs the attendee scheduler synchronously on every registration create. The scheduler commits after each mail batch, which is fine from cron but problematic during an import: since [29460b723f49](https://github.com/odoo/odoo/commit/29460b723f49) [`load`](https://github.com/odoo/odoo/blob/b2f3270271f6/odoo/orm/models.py#L884) uses a single savepoint for the whole run, and any commit underneath releases it, so the next `ROLLBACK TO` / `RELEASE SAVEPOINT` raises `InvalidSavepointSpecification`. When `import_file` is in context, trigger the cron like the async path already does so the mails are queued instead of running inline. Steps to reproduce: 0. Have Contacts and Events installed 1. Events > Events, create a published event 2. Open the event, Attendees tab > Favorites > Import records 3. Upload a file with new attendees (Name, Email, no external id) 4. Click Import => "savepoint ... does not exist", import fails Ticket [link](https://www.odoo.com/odoo/project.task/6124741) opw-6124741 Forward-Port-Of: odoo/odoo#260648
This update fixes an issue where invoices weren't sorted correctly on the customer portal based on their payment status. The fix ensures that invoices are displayed in the correct order – by whether they've been paid, not paid, or are in payment – improving the user experience and accuracy of invoice lists.
Original PR description
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. -…
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. - Navigate to the invoices list and attempt to sort by **Status**. Issue:- --- - Sorting by **Status** does not reflect the actual invoice payment status, resulting in incorrect ordering. Root cause: --- - At [1], the sorting field for Status is set to state, which corresponds to invoice states (Draft, Posted, Cancelled). However, the portal displays and expects sorting based on payment_state. Fix: --- - Update the sorting configuration to use payment_state instead of state, ensuring that invoices are sorted correctly according to their payment status on the portal. [1]https://github.com/odoo/odoo/blob/5b85287ec4ea9f1b51e0f33402900777dfeeb725/addons/account/controllers/portal.py#L46-L52 opw-6128998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262976
This update fixes an issue where currency amounts in Arabic RTL (right-to-left) user interfaces were incorrectly formatted, appearing with the minus sign positioned to the right of the currency symbol. The fix ensures that currency amounts are displayed correctly, aligning with standard left-to-right formatting in Arabic locales, improving the user experience for Arabic-speaking users.
Original PR description
Steps to reproduce 1. Create a company with Egypt localization, currency EGP 2. On a bank journal, set Outstanding Receipt and Outstanding Payment accounts 3. Register a customer payment so the…
Steps to reproduce 1. Create a company with Egypt localization, currency EGP 2. On a bank journal, set Outstanding Receipt and Outstanding Payment accounts 3. Register a customer payment so the journal dashboard shows the Payments row with a negative amount 4. Switch the user language to Arabic 5. Open the Accounting dashboard Issue The Payments amount renders as "LE 5,000.00-" instead of "-5,000.00 LE". formatCurrency returns the string "-5,000.00 LE". In an Arabic page the leading "-" has no intrinsic direction, so the browser attaches it to the surrounding right-to-left Arabic text and visually moves it past the symbol. Sibling rows on the same dashboard render correctly because they already wrap the amount in dir="ltr", see https://github.com/odoo/odoo/blob/d0424f2ffcf99ee59befe288150f1643b3fa0112/addons/account/views/account_journal_dashboard_view.xml#L252 opw-6183749 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266742
This update resolves an issue where VeriFactu invoices were failing due to a problem with sequence numbers that included letters. The fix prevents errors by gracefully handling sequence values with prefixes/suffixes, guiding users to correct the configuration and ensuring invoices are successfully sent to VeriFactu.
Original PR description
**Steps to reproduce:** 1. Install l10n_es_edi_verifactu. 2. Switch to a ES company. 3. Create a customer invoice and send it to VeriFactu. 4. Enable Developer Mode. 5. Go to Settings > Technical >…
**Steps to reproduce:** 1. Install l10n_es_edi_verifactu. 2. Switch to a ES company. 3. Create a customer invoice and send it to VeriFactu. 4. Enable Developer Mode. 5. Go to Settings > Technical > Sequences & Identifiers > Sequences. 6. Search for the `Sequence Code: l10n_es_edi_verifactu` and open it. 7. Set a prefix or suffix using any alphabetical character. 8. Create a new invoice and send it to VeriFactu **Issue:** Traceback on sending Veri*Factu: `ValueError: invalid literal for int() with base 10: 'F260001'` **Cause:** The value returned by `ir.sequence.next_by_id()` may contain alphabetical characters (due to prefix/suffix), while the field `chain_index` expects an integer. The raw sequence value was directly assigned, causing the conversion to fail. **Fix:** Catch the ValueError raised by int() when the sequence value contains non-numeric characters (e.g. due to a prefix/suffix). Instead of crashing, surface a user-friendly error on the document telling the user to remove the prefix/suffix from the sequence configuration. **opw-6037528** Forward-Port-Of: odoo/odoo#255473
This update resolves an issue where barcode scanning incorrectly displayed delivered quantities on sales orders. The fix ensures that quantities are accurately reflected when using lots, preventing backorders and ensuring order fulfillment is correct. This improves the reliability of the barcode inventory process.
Original PR description
Currently when user adds adds quantity in barcode using lots it leads to incorrect sale order quantities. ## Steps to replicate: - Install Sales and Barcode (no demo data). - Enable Lots & Serial…
Currently when user adds adds quantity in barcode using lots it leads to incorrect sale order quantities.
## Steps to replicate:
- Install Sales and Barcode (no demo data).
- Enable Lots & Serial Numbers in settings.
- Create Test Product with Tracking by Lots.
- Go to Inventory > Products>Lots & Serial Numbers and create 3 lots for the product.
- Update each lot’s on-hand quantity to 10 from the product page.
- Create and confirm a Sales Order for the product (lines: qty 3 and 2 units).
- Open the delivery in the Barcode app:
- Scan lot 2 > increase qty to 3 using +1 button
- Scan lot 3 > increase qty to 2 using +1 button
- Validate and go to the sale order.
## Observed Behavior:
The sale order delivered quantities are flipped and a backorder is created even though the quantity for the product is satisfied.
## Root cause:
The issue occurs because when a sales order is confirmed, the system defaults to
using lot 1 on the delivery receipt. When a user scans lot 2, the `_processBarcode` function is triggered, which calls `_findLine` at [1] to select the appropriate line on the receipt.
As the loop in `_findLine` iterates through `pageLines` with values like:
```
[{display_name: "Test product", quantity: 3, lot_id: { name: 'lot1' }},
{display_name: "Test product", quantity: 2, lot_id: { name: 'lot1' }}]
```
During the first iteration, `foundLine` is set at [2] for the line with quantity 3 . Since the subsequent if condition is not satisfied, the loop hits the continue block at [3].
On the next iteration, the line with quantity 2 causes `foundLine` to be overwritten at [2], and the continue block is executed again at [3].
This results in the line with quantity 2 being selected as the line to update at the end of the function.
When the user manually increases the quantity to 3, the line that originally required quantity 2 is updated and fulfilled.
Later, when lot 3 is scanned, the line that required quantity 3 is selected for update, and manually increasing the quantity to 2 before validating the order leads to a backorder and causes the delivered quantities to be flipped.
[1]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1335-L1337 [2]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1690-L1699 [3]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1727-L1729
## Solution:
Avoid grouping lines from different moves unless using batch transfers. This ensures that backorders are not created when the barcode lines are fulfilled.
opw-5423943
Forward-Port-Of: odoo/enterprise#117722
Forward-Port-Of: odoo/enterprise#109032This update fixes an issue where SII invoices generated with quarterly tax periods were incorrectly using monthly formats. The change ensures that the generated JSON documents accurately reflect the company's quarterly tax periodicity, aligning with Spanish tax regulations. This improves data accuracy for tax reporting.
Original PR description
### Issue: When the company `tax_periodicity` is set to quarterly, the generated SII invoice JSON still uses the monthly period format According to the documentation, the options for Periodo include…
### Issue: When the company `tax_periodicity` is set to quarterly, the generated SII invoice JSON still uses the monthly period format According to the documentation, the options for Periodo include distinction between monthly and trimester (p224 - 225): https://sede.agenciatributaria.gob.es/static_files/Sede/Procedimiento_ayuda/G417/FicherosSuministros/V_1_1/SII-Descripcion-ServicioWeb-v1-1_es_es.pdf ### Cause: The invoice JSON generation does not consider the company's `tax_periodicity` This logic was probably omitted because `account_reports` may not be installed However, when the periodicity is configured, the generated SII document should reflect it correctly ### Steps to reproduce: - Install `l10n_es_edi_sii` and `account_reports` - In Settings, set `Tax Periodicity` to `Quarterly` - In Settings, set `Tax Agency for SII` to `Agencia Tributaria Española` - Change ES Company vat number to `ESA12345674` - Create an invoice (Date: 01/05/2026, Customer: ES Company) - Open the generated JSON document - Check the Periodo value, it should be 2T in May opw-6050587 Forward-Port-Of: odoo/odoo#264063
This update fixes an issue where currency differences were incorrectly aggregated in hierarchical financial reports. Previously, the reports displayed totals that didn't accurately reflect the actual values due to currency conversion. This change ensures that reports now accurately represent financial data, providing more reliable insights for business decisions.
Original PR description
opw-6015098 Forward-Port-Of: odoo/enterprise#118705 Forward-Port-Of: odoo/enterprise#114827
This update fixes an issue where UBL files weren't correctly applying tax rates during import. Previously, the system used a simplified cache key that could lead to incorrect tax assignments for similar lines. Now, the system uses a more precise key based on the invoice, line name, and partner, ensuring imported tax rates align with the UBL file data.
Original PR description
When we import a UBL file, we call the `_import_retrieve_tax` method to fetch taxes to indicate on lines.
During the process, we use cache to avoid performing the search a second time if a new line is the same as a previous one.
https://github.com/odoo/odoo/blob/d0424f2ffcf99ee59befe288150f1643b3fa0112/addons/account/models/account_tax.py#L4459-L4462
The cache_key used is defined as follows: {line's invoice, line's name, line's partner}.
This implies that if two lines from the same invoice share the same name and partner, the same tax will automatically be used even if different taxes were indicated in the file.
This is not desirable as we should match what is indicated in the XML file imported.
opw-6226166
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#2666971 change
Resolved issues and error corrections
This update addresses a requirement from the Peruvian tax authority (SUNAT) regarding delivery guides. Customers using the l10n_pe_edi_stock module now need to include a 'carrier handover date' field, which was previously causing errors. The update automatically handles this by reusing existing data and provides a helpful message to users on older versions to update their module.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662
Forward-Port-Of: odoo/enterprise#11903811 changes
New functionality added to Odoo
This update introduces initial support for Philippine payroll within Odoo. Key employee fields have been added to ensure accurate completion of the mandatory yearly tax declarations. This enhancement supports compliance with Philippine tax regulations.
Original PR description
Add initial support for the Philippines Payroll inside Odoo Note that some fields have been added preemptively on the employee, as we know for sure that we need these to correctly declare the mandatory yearly tax declaration. task-3580086
Enhancements to existing features
This update enhances the planning Gantt view by automatically displaying Bill of Materials (BoM) dependencies. Users can now easily see how work orders relate to materials, improving planning accuracy and efficiency. Hovering over dependencies provides detailed information for customization within the BoM.
Original PR description
Activate work order dependencies in the Gantt planning view by default, so users can customize them on the Bill of Materials when needed. This is now readable thanks to dependency display on hover. Task-6168689
This update enhances the functionality of pivot tables in the Enterprise edition by adding improved filtering options. This allows users to more easily analyze data within their reports, leading to better insights and decision-making. The change is considered an important improvement for usability.
Original PR description
Task: 4273959
This update streamlines the checkout process for enterprise sales modules like appointments, rentals, and subscriptions. By moving validation checks earlier in the process – specifically to the cart overview step – we now identify potential issues like unavailable slots or incorrect tax calculations sooner, leading to a smoother and more reliable customer experience. This change aligns with a recent update to the core website sale architecture.
Original PR description
This PR adapts enterprise modules to the new checkout validation architecture introduced in `website_sale` (see odoo/odoo#192183). #### Key changes - Appointments: booking availability checks are now performed at the cart overview step to catch unavailable slots earlier. - Rentals: rental date validation is now performed early at the cart overview step. - External Tax: tax calculation validation is now performed at the payment step. task-4328322 See also: - https://github.com/odoo/odoo/pull/192183 - https://github.com/odoo/upgrade/pull/8544 - https://github.com/odoo/upgrade-util/pull/410
This update simplifies the French VAT EDI reporting process by removing a complex multi-account setup. The changes streamline the user interface, making it easier to manage VAT submissions. This improves usability and reduces the potential for errors in the French VAT reporting process.
Original PR description
In order to ease the use of the French VAT EDI, we change the UI a bit (simplifying it) by removing the multiple accounts setup for the VAT submission, and moving some elements around. task-5490298
Resolved issues and error corrections
This update resolves a crash that could occur when signing salary contracts with a company car option in the configurator. The fix ensures the system handles different contract simulation settings correctly, preventing errors related to missing context information. This improves the stability of the payroll process for Belgian users.
Original PR description
Before this commit, signing a salary contract in the configurator with a company car selected could crash on the cp200_employees_salary_company_car (ATN.CAR) rule with KeyError('origin_version_id'), because the Belgian _get_period_contracts() accessed self.env.context['origin_version_id'] directly whenever salary_simulation was set, while hr_version_context injects salary_simulation=True without that key.
After this commit, the lookup uses .get() and falls back to the default behavior so the rule evaluates safely.
task-6240418
Forward-Port-Of: odoo/enterprise#118392This update streamlines the calculation of offer fields related to employee contracts, preventing unnecessary recomputations and ensuring data consistency. Additionally, a recent change was corrected to properly handle payroll workflows, restoring expected behavior and preventing hidden fields.
Original PR description
**Problem:** Since this https://github.com/odoo/enterprise/pull/103846, `employee_version_id` depends on `contract_start_date` to adjust the employee state based on the contract date. This introduced…
**Problem:** Since this https://github.com/odoo/enterprise/pull/103846, `employee_version_id` depends on `contract_start_date` to adjust the employee state based on the contract date. This introduced an unnecessary dependency chain: ``` contract_start_date -> employee_version_id -> contract_template_id -> wages and other offer fields ``` As a result, updating `contract_start_date` invalidates and recomputes the whole chain, even when `employee_version_id` does not actually change. In addition, offer fields were coupled in a single compute, causing unrelated fields to be reset to template values when only one field required recomputation. **Fix:** - `contract_template_id` compute now depends on `employee_id` instead of `employee_version_id`, and directly uses the employee's `version_id`, breaking the chain while preserving default behavior. - The offer fields computations were also split to avoid unintended recomputations and field resets. - Simplified `_get_version` by always copying values from the template to the currently active version. --- **Additional fix:** The `is_hr_payroll` context flag is used to distinguish payroll vs recruitment flows when creating an offer with both `employee_id` and `applicant_id` unset. A recent change in [Task #6094737](https://www.odoo.com/odoo/project/1251/tasks/6094737) did not account for this flag, causing both fields to be hidden when opening the form from Payroll (a new feature added in saas-19.3). This is fixed by properly considering `is_hr_payroll`, restoring consistent behavior across all versions. Task: 6158245 Forward-Port-Of: odoo/enterprise#115408
This pull request fixes several issues related to field service notifications, reporting, and Gantt chart functionality. It now automatically sends intervention reports to customers upon completion, improves Gantt chart performance, and ensures accurate reporting of interventions.
Original PR description
## [FIX] web_gantt,planning: apply hasGroup before compute params Before this commit, some actions like drag and drop gantt pills are blocked for planning manager instead of being allowed only for…
## [FIX] web_gantt,planning: apply hasGroup before compute params Before this commit, some actions like drag and drop gantt pills are blocked for planning manager instead of being allowed only for them. The reason is because the compute params is something made before checking if the user is a planning manager and so the system will consider the user is not a planning manager. The compute params is something made before because the methods are executed inside 2 distincts onWillStart hook and so OWL framework cannot know one hook depends on the other one. This commit creates a method `onWillStart` in the main gantt controller to be able to override it and be able to wait a rpc before processing the compute params. ## [FIX] planning_field_service_sale_timesheet: don't count unscheduled intervention This commit filters the interventions counted to display the field service stat button in the form view of Sale Order. Now the intervention unscheduled will no longer be counted and also the one linked to plannable SOL. ## [FIX] planning_field_service: send email to customer when intervention published Before this commit, the template "Field Service Scheduled" was unsused. This commit uses that template to send an email to the customer once the intervention is scheduled. ## [FIX] planning_field_service: send report when intervention completed and signed Before this commit, the customer signs the intervention completed and does not received any email with the intervention report. He has to create an account in the DB as portal user to be able to see his intervention or ask to contact person to send him the report by mail. This commit will automatically send the intervention report by mail to the customer once the intervention is completed and signed by the customer. ## [FIX] planning_field_service: fix label and record_name in email sent for Field service Before this commit, the button sent to the customer to see the intervention is `View Planning Slot` and the record name used inside the same email is the display name which is not useful for the customer. This commit changes the label of the button displayed to see `View Report` and change the record_name to show `Field Service - <intervention date>` as shown in the portal view. ## [FIX] planning_field_service: no login required to access to intervention Before this commit, the customer cannot access to the intervention without begin log in even if he has the access token. This commit changes the route access to let the user access to the intervention completed and he can also sign it. ## [FIX] planning: hide duplicated name field in kanban displayed in gantt This commit hides the duplicated name field displayed in the popover of the gantt view in the planning.slot model. ## [FIX] planning_field_service: rename module name This commit renames the module to call it `Field Service` instead of `Planning - Field Service`. ## [FIX] worksheet: only show property warning message in mobile ## [FIX] planning: define employee_public_ids field in planning.slot Before this commit, when a planning user goes to a shift he will see Assign to me button on a shift assigned to another human resource which is normally not allowed. The reason because the button is visible is because `employee_ids` field is always empty for users who are not HR user. This commit adds `employee_public_ids` field which is also a computed field non stored to get the employee for the user who is not a HR user. ## [FIX] planning_field_service: always compute break_time This commit removes the default value on break_time field to always trigger the compute of that field, the reason is because by default the allocated_hours computed when we create a shift, will not always cover the whole duration of the shift, the allocated hours of the shift is computed based on the working schedule of the shift and so the break_time field has to be computed afterwards to make sure the break time is correctly set instead of having 0 by default when we create a shift. task-6060493 Forward-Port-Of: odoo/enterprise#118780 Forward-Port-Of: odoo/enterprise#112420
This update fixes an issue where the expected hours displayed in the attendance Gantt view didn't accurately reflect flexible work schedules, particularly when users' browsers were set to non-UTC timezones. The fix ensures accurate hour calculations based on the user's local timezone, improving the reliability of attendance reporting.
Original PR description
Steps to reproduce: 1. Ensure your browser is in a non-UTC timezone (e.g. Europe/Zurich) 2. Set an employee to have a flexible working schedule 3. Enter the Attendances app 4. When hovering over the employee in the gantt view, the expected hours do not match their working schedule When we calculate the expected hours for the Gantt view in attendances, we calculate this based on an incorrect number of attendance intervals given from _attendance_intervals_batch(). To ensure that we recieve accurate intervals, we need to ensure that we calculate intervals based on the correct date range with respect to the browsers timezone, instead of the UTC date range. [opw-6175441](https://www.odoo.com/odoo/my-tasks/6175441?debug=assets) Forward-Port-Of: odoo/enterprise#118729 Forward-Port-Of: odoo/enterprise#116807
This update fixes an issue where subscription products with one-time purchase options were incorrectly displaying recurring subscription prices in the product configurator. Now, the configurator accurately shows the one-time price when this option is selected, ensuring accurate pricing for subscription orders across the website and backend.
Original PR description
Version 19.1 steps to reproduce: - open sales and open a subscription product. enable accept one time and add another subscription product as an optional product. - open the website product page, select the one time price, and click add to cart. issue: when a subscription product that allows one time purchase is added to the cart or to a subscription order, the product configurator wizard was showing the recurring subscription price instead of the one time price. this issue was present both on the website frontend and in the backend subscription module. fix: the product configurator wizard now correctly shows the one time price when the accept one time option is selected, both on the website frontend and in the backend subscription flow. task: 6126684. Forward-Port-Of: odoo/enterprise#114862
This update ensures Wijninckx contributions (code 867) are only processed in the final quarter of the year. The system now alerts users with a warning and prevents declarations outside of Q4, improving payroll accuracy and compliance with Belgian regulations. This change addresses a potential issue related to ONSS reporting.
Original PR description
The Wijninckx contribution (code 867) should only be declared on the last quarter of the year. This commit introduces a restriction to ensure this: - Triggers a UserError in the DMFA if the code 867 is used in a declaration outside of Q4. - Adds a python-based payslip warning if the `ONSSWIJNINCKX` salary rule is applied to a payslip from January to September. Task Id: 6267562
3 changes
Resolved issues and error corrections
This update resolves an issue where orders exceeding a weight threshold triggered errors when using the Sendcloud delivery method in e-commerce. The fix ensures that the system accurately processes multi-package orders based on weight, preventing errors and improving order fulfillment. This improves the reliability of the e-commerce shipping process.
Original PR description
Issue ----- Traceback when trying to get a rate through the e-commerce if the order has to be split into multiple packages due to weight being too high. Steps to reproduce ----- - Setup Sendcloud…
Issue ----- Traceback when trying to get a rate through the e-commerce if the order has to be split into multiple packages due to weight being too high. Steps to reproduce ----- - Setup Sendcloud delivery method - make it available in e-commerce - Create a 150kg product and publish it - Go to e-commerce - Add the product to cart - Checkout the cart > Traceback Cause ----- We retrieve the order's weight through the context. https://github.com/odoo/enterprise/blob/d9a9339e1f30f1e5cc37ebb88949451a6652f83b/delivery_sendcloud/models/delivery_carrier.py#L108 If the call to `_get_shipping_rate` returns that the delivery requires multiple packages, we go into https://github.com/odoo/enterprise/blob/d9a9339e1f30f1e5cc37ebb88949451a6652f83b/delivery_sendcloud/models/delivery_carrier.py#L126-L128 If `order_weight` was not present in the context, this will cause an error in `sendcloud_convert_weight` since it expects a numerical value but receives the `None` fallback. This context key is only present when going through `choose.delivery.carrier` (so not in the e-commerce flow). https://github.com/odoo/odoo/blob/058e640e6687ed3f709dc846f0fa7a1f45226849/addons/delivery/wizard/choose_delivery_carrier.py#L69 ----- Ticket: opw-6210398
This update resolves an issue where orders placed via mobile self-order with 'Pay After Meal' and online payment were not being sent to the kitchen for preparation. The fix ensures that all orders, regardless of payment type, are now correctly transmitted to the preparation display, improving order workflow efficiency.
Original PR description
pos* = pos_self_order_preparation_display, pos_online_payment_self_order_preparation_display Configuration: -------------- - Restaurant Mode - Self-Order Mode: "QR + Ordering" - Service At: Table - Pay after meal (Online Payment) Issue: ------ Orders created via mobile self-order using "Pay After Meal" + online payment were not appearing in the Preparation Display. Steps to Reproduce: ------------------- 1. Create an order from mobile self-order. 2. Open the restaurant POS, the order is visible there, but it does not appear on the preparation display. Cause: --------------- - The system only sent paid orders to the kitchen when online payment is set, skipping pay-after-meal case. Fix: ------------ - Updated logic to send all orders to the kitchen when “Pay After Meal” is selected, Task: 5929555 Forward-Port-Of: odoo/enterprise#107129
This update addresses a requirement from the Peruvian tax authority (SUNAT) regarding delivery guides. Customers using the l10n_pe_edi_stock module now *must* include a 'carrier handover date' field to avoid validation errors. The update automatically handles this by reusing the existing departure start date for public transport deliveries, and provides a helpful message to users on older versions to update the module.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662
Forward-Port-Of: odoo/enterprise#11903812 changes
Resolved issues and error corrections
This update addresses a requirement from the Peruvian tax authority (SUNAT) regarding delivery guides. Customers using the l10n_pe_edi_stock module now need to include a 'carrier handover date' field in their delivery guides for public transport shipments. The update automatically handles this by reusing the existing departure start date, and provides a helpful message to users on older module versions to update to the latest version to avoid errors.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662
Forward-Port-Of: odoo/enterprise#119038This update resolves an issue where the Cost of Goods Sold (COGS) reporting feature in the project profitability report didn't display correctly when multiple invoices were associated with a sale order. The fix ensures that COGS reporting accurately reflects all related journal entries, regardless of the number of invoices.
Original PR description
Steps to reproduce: ------------------- 1. Install `sale_project_stock` and Accounting. 2. Create a storable product with **Real-time valuation** and configure the COGS account in the product…
Steps to reproduce: ------------------- 1. Install `sale_project_stock` and Accounting. 2. Create a storable product with **Real-time valuation** and configure the COGS account in the product category expense account. (Ensure you have enabled automatic & analytic accounting from accounting>config.) 3. Create a project with a specific analytic account and ensure the project is billable. 4. Create a sale order with the created product and set the same analytic account in the analytic distribution. 5. Confirm the order, deliver the product, generate the invoice, and post it. 6. Open the project and go to the *Profitability* report. 7. Click on the **Cost of Goods Sold** dashboard item. 8. Repeat steps 4–7 with multiple invoices. Issue: ------ When there is only one invoice, clicking the COGS dashboard item correctly displays the related move lines. However, when there are multiple invoices, the action opens with empty results. Cause: ------ `_get_action_for_profitability_section` sets `res_id` only when a single record exists. When multiple records are present, `res_id` becomes `False`, which causes the action to open without results. https://github.com/odoo/odoo/blob/8f79d407724f40ba8e48f1747b2e87311b7fb49e/addons/project_account/models/project_project.py#L78-L83 Solution: --------- When `res_id` is not set, search `account.move` records using the domain to retrieve the relevant move IDs, then apply a proper domain to display all related COGS journal items. opw-5949261 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253639
This update fixes an issue where SII invoice JSONs weren't correctly reflecting quarterly tax periods. The change ensures that invoices generated with a 'Quarterly' tax periodicity accurately display the correct '2T' period format as required by Spanish tax regulations. This improves compliance with local tax reporting standards.
Original PR description
### Issue: When the company `tax_periodicity` is set to quarterly, the generated SII invoice JSON still uses the monthly period format According to the documentation, the options for Periodo include…
### Issue: When the company `tax_periodicity` is set to quarterly, the generated SII invoice JSON still uses the monthly period format According to the documentation, the options for Periodo include distinction between monthly and trimester (p224 - 225): https://sede.agenciatributaria.gob.es/static_files/Sede/Procedimiento_ayuda/G417/FicherosSuministros/V_1_1/SII-Descripcion-ServicioWeb-v1-1_es_es.pdf ### Cause: The invoice JSON generation does not consider the company's `tax_periodicity` This logic was probably omitted because `account_reports` may not be installed However, when the periodicity is configured, the generated SII document should reflect it correctly ### Steps to reproduce: - Install `l10n_es_edi_sii` and `account_reports` - In Settings, set `Tax Periodicity` to `Quarterly` - In Settings, set `Tax Agency for SII` to `Agencia Tributaria Española` - Change ES Company vat number to `ESA12345674` - Create an invoice (Date: 01/05/2026, Customer: ES Company) - Open the generated JSON document - Check the Periodo value, it should be 2T in May opw-6050587 Forward-Port-Of: odoo/odoo#264063
This update resolves a crash in the Asset Depreciation Schedule report that occurred when generating reports with many assets grouped together. The fix ensures the report handles missing data gracefully, preventing errors and allowing users to accurately analyze their assets, even with large groups.
Original PR description
#### Description of the issue/feature this PR addresses: Opening the Asset Depreciation Schedule report with a period comparison enabled crashes with KeyError: 'no_format' when prefix grouping is…
#### Description of the issue/feature this PR addresses:
Opening the Asset Depreciation Schedule report with a period comparison enabled crashes with KeyError: 'no_format' when prefix grouping is active (large number of assets in one account group). The report becomes unusable for affected customers.
#### Current behavior before PR:
_regroup_lines_by_name_prefix sums each subline column by indexing prefix_subline['columns'][i]['no_format'] directly. Empty columns are built as {} by _build_column_dict (both col_value and col_data are None), so they have no 'no_format' key. With a comparison period enabled, an asset that has no value in the comparison period produces an empty column for that period; once prefix grouping fires (len(lines) >= prefix_groups_threshold, default 4000), the direct lookup hits that empty dict and raises KeyError: 'no_format'.
#### Desired behavior after PR is merged:
The prefix group total treats a missing 'no_format' as 0, matching the sibling caller in account_asset/models/account_assets_report.py that already guards with .get('no_format', 0). The report builds without crashing and the empty comparison column contributes 0 to the prefix group total.
opw-6225639This update fixes an issue where the multi-company balance sheet report incorrectly only displayed data from the first company selected. The fix ensures that balances are accurately calculated and displayed across all companies in a multi-company setup, providing more reliable financial reporting.
Original PR description
***Steps to reproduce*:** - Install the l10n_es module. - Create another company with the country set to Spain. - Create and confirm a customer invoice in the new company. - Navigate to Accounting ->…
***Steps to reproduce*:** - Install the l10n_es module. - Create another company with the country set to Spain. - Create and confirm a customer invoice in the new company. - Navigate to Accounting -> Reporting -> Balance Sheet. - Select both companies in the multi-company selector. - Open the Balance Sheet - SMEs (ES) report. ***Observed behavior*:** The report should display balances as the sum of records from both companies, but the balance details and account matching are only taken from the first selected company. ***Cause*:** - The `code` field on `account.account` is company-dependent and stored using per-company values in `code_store`. - Account prefix queries were generated using a single company context (`env.company`) even when multiple companies were selected. - During domain translation, the ORM resolved `code =like '1613%'` using the current company context only, generating queries such as: `code_store->'96'->>0 LIKE '1613%'` - As a result, account resolution and balance computation only worked correctly for the first/current company context. ***Fix*:** - Generate account prefix queries separately for each root company using `with_company(root_company)`. - This ensures that the ORM resolves company-dependent account codes in the correct company context for every selected company. - As a result, account matching and balance computation are evaluated correctly across all selected companies. opw-6109608
This update resolves an issue where Romanian E-Factura invoices were being rejected due to exceeding character limits for product names, descriptions, and notes. The fix automatically truncates these fields to the required maximum lengths (100, 200, and 300 characters respectively) to ensure compliance with Romanian regulations. This prevents invoice rejection and facilitates successful E-Factura transmission.
Original PR description
**Steps to reproduce:** - Install Accounting and l10n_ro_edi - Switch to a Romanian localization (e.g. RO Company) - Configure Romanian E-Factura - Create an invoice with a product having a name…
**Steps to reproduce:** - Install Accounting and l10n_ro_edi - Switch to a Romanian localization (e.g. RO Company) - Configure Romanian E-Factura - Create an invoice with a product having a name longer than 100 chars - Confirm the invoice - Send E-Factura to SPV - Fetch E-Factura status **Issue:** The invoice is rejected with the following error: "[BR-RO-L100]-The allowed maximum number of characters for the Item name (BT-153) is 100." **Similar issue with the product description:** "[BR-RO-L200]-The allowed maximum number of characters for the Item description (BT-154) is 200." **Similar issue with the note (i.e. Terms and Conditions):** "[BR-RO-L300]-The allowed maximum number of characters for the Invoice note (BT-22) is 300." **Solution:** Truncate the name of the product to 100 chars in the electronic invoice, the description of the product to 200 and the note to 300. opw-5964904 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where invoices weren't sorting correctly on the customer portal based on their payment status. The fix ensures invoices are ordered accurately by whether they are 'In Payment,' 'Not Paid,' or 'Paid,' improving the user experience and providing a clearer view of outstanding balances.
Original PR description
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. -…
Steps to produce: --- - Install the `Accounting` module. - Create several invoices for a portal user with different payment states (e.g., In Payment, Not Paid, Paid). - Log in as the portal user. - Navigate to the invoices list and attempt to sort by **Status**. Issue:- --- - Sorting by **Status** does not reflect the actual invoice payment status, resulting in incorrect ordering. Root cause: --- - At [1], the sorting field for Status is set to state, which corresponds to invoice states (Draft, Posted, Cancelled). However, the portal displays and expects sorting based on payment_state. Fix: --- - Update the sorting configuration to use payment_state instead of state, ensuring that invoices are sorted correctly according to their payment status on the portal. [1]https://github.com/odoo/odoo/blob/5b85287ec4ea9f1b51e0f33402900777dfeeb725/addons/account/controllers/portal.py#L46-L52 opw-6128998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262976
This update resolves an issue where changes made within nested editable areas of the rich text editor were not being saved correctly. The fix replaces a `blur` event listener with a `focusout` event, ensuring that changes are properly saved when the user navigates away from the editable content. This improves the reliability of the rich text editor for users.
Original PR description
Problem: When the selection is inside a `contenteditable="true"` element that is not the root editable, focusing away does not trigger a save. Cause: When the DOM contains a nested contenteditable…
Problem:
When the selection is inside a `contenteditable="true"` element that is not the root editable, focusing away does not trigger a save.
Cause:
When the DOM contains a nested contenteditable structure like:
```html
<div class="odoo-editor-editable" contenteditable="true">
abc
<div contenteditable="false">
ac
<div contenteditable="true">a</div>
</div>
</div>
```
With the selection inside the inner `contenteditable="true"`, the `blur` event is not triggered on `.odoo-editor-editable` when focusing away, because the active element is the inner div and `blur` does not bubble.
Solution:
Replace the `blur` listener with `focusout`, which bubbles from the inner `contenteditable="true"` up to `.odoo-editor-editable`, allowing `onBlur` to be called correctly.
Steps to reproduce:
- Open Project > Task.
- Add a `/column` block in the description.
- Focus inside any column and write some text.
- Click away to change tab.
- Reopen the description tab.
- The latest changes inside the columns were not saved.
opw-6227922
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update resolves an issue where Peppol-compliant invoices were generating invalid XML due to incorrect unit price rounding. The fix ensures accurate calculations for invoice line amounts, preventing validation failures and enabling proper Peppol invoice generation. This improves compliance and avoids potential shipping delays.
Original PR description
**PROBLEM** Previously, we rounded the unit price up to 6 digits in the generated xml for peppol. However, odoo compute the lineExtensionAmount with the raw unit price. The generated xml is invalid because priceAmount*InvoicedQuantity != LineExtensionAmount. **STEP TO REPRODUCE** Create an invoice with unit price of 0.01110515964, and quantity of 278362.5. Generate an XML with peppol, and try validating the invoice. You should have the following error: [PEPPOL-EN16931-R120]-Invoice line net amount MUST equal (Invoiced quantity * (Item net price/item price base quantity) + Sum of invoice line charge amount - sum of invoice line allowance amount opw-6009771
This update ensures that attachments related to invoices are handled as intended, allowing for proper regeneration of XML files for sales. A key exception exists for Italian businesses using EDI imports, where attachment detachment is now correctly applied to ensure accurate bulk XML exports for tax reporting. This resolves an issue preventing the inclusion of necessary attachments.
Original PR description
The feature introduced in odoo/enterprise#78429 allows users to detach attachments from moves, primarily to facilitate the regeneration and re-sending of outgoing XMLs (e.g., sales invoices) without needing to delete the original attachment. However, detaching should not apply to incoming XML attachments on bills that originate from EDI import, as these attachments are the received source document and are never regenerated by the system. Detaching them inadvertently prevents their inclusion in bulk XML exports. An exception exists for Italy: businesses need to send Tax Integration XMLs back to the SdI. In this specific case, detaching the Tax Integration XML is appropriate and ensures the bulk export finds the latest, correct attachment. Ticket [link](https://www.odoo.com/odoo/project.task/5062132) opw-5062132
This update fixes a bug preventing the 'NABN' document type from being selected when reversing vendor credit notes in the GT accounting system. Previously, this option was only available for regular vendor bills. Now, users can correctly utilize 'NABN' for GT vendor credit notes, ensuring accurate electronic payment processing.
Original PR description
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Navigate to Invoicing > Vendors > Bills. - Create a new vendor bill. - Observe that `GT Document Type` includes `NABN - Nota de Pago Electrónica` option. - `Confirm` the bill. - Click `Credit Note`, add a reason, and click `Reverse`. - Observe the available options in the `GT Document Type` field. **Observation:** The `NABN - Nota de Pago Electrónica` option is not available for vendor credit notes (`in_refund`), even though `NABN` is a GT-specific credit note document type. **Root Cause:** At [1], `NABN` is added for vendor bills (`in_invoice`, `in_receipt`) instead of vendor credit notes (`in_refund`). **Fix:** This commit ensures users can correctly select `NABN - Nota de Pago Electrónica` on GT vendor credit notes. [1]: https://github.com/odoo/enterprise/blob/c7fa8c9c6f6830f5702fab4f6efaf3ac33f7fe72/l10n_gt_edi/models/account_move.py#L159-L160 opw-6252256
This update fixes an issue where incorrect tax reason codes were being added when using specific co-contractant fiscal positions. This prevented proper UBL export validation against Peppol standards, ensuring compliance with international tax regulations. The change ensures accurate tax data is exported for e-invoicing.
Original PR description
When a co-contractant fisacl position is selected and the user chooses a tax that does not belong to that fiscal position, a tax exemption reason code is added, which breaks the schematron validation on peppol. related-task-id-5905176 Forward-Port-Of: odoo/odoo#264887
5 changes
Resolved issues and error corrections
This update addresses a requirement from the Peruvian tax authority (SUNAT) regarding delivery guides. Customers using the l10n_pe_edi_stock module now need to include a 'carrier handover date' field, which was previously causing validation errors. The update automatically handles this by reusing existing data and provides a helpful message to users on older module versions to update.
Original PR description
SUNAT R. S. N° 000108-2026/SUNAT and the GRE validation rules published on 2026-06-01 add field 34 "Fecha de entrega de bienes al transportista" (cac:LoadingTransportEvent/cbc:OccurrenceDate). It is required, and rejected with error 3617 when absent, only when the transport modality is '01' (public transport). Enforcement started 2026-06-01, so affected customers can no longer submit their delivery guides.
In our implementation the departure start date is equivalent to this date, so we reuse it instead of adding a new field. The node is gated to public transport to match the validation rule and avoid emitting it on private transport ('02') guides.
Because the new node only ships with this module version, customers on an older version keep hitting error 3617 from SUNAT. Detect that code in the SUNAT response and store an actionable message asking the user to update the module, instead of surfacing the raw rejection.
task-6266662This update resolves a requirement from Luxembourg auditors regarding the classification of partners in SAFT reports. Specifically, it ensures less than 30% of transactions with payable or receivable accounts have missing supplier or customer IDs, aligning with Luxembourg's FAIA reporting standards. The change updates XML reports to accurately reflect partner classifications.
Original PR description
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on…
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on \Transaction\Line elements is determined by a partner's `customer_rank` and `supplier_rank`. This is a binary designation, one or the other. The Luxembourg FAIA report requires that less than 30% of \Transaction\Line elements with payable accounts (class 6) can not have \SupplierID. The same applies for \Transaction\Line elements with receivable accounts (class 7) and the \CustomerID element. TSB clarified that any partner on an receivable or payable line should be added to the Customer list or Supplier list respectively https://github.com/odoo/enterprise/pull/100749#issuecomment-3655127511. In addition, I verified that Luxembourg's analysis of four separate FAIA files (from ticket 5427296) aligns with this expectation. <img width="1322" height="690" alt="image" src="https://github.com/user-attachments/assets/1a82f99e-5b32-4dbb-96e1-1b25bab2629b" /> This commit adds partners to the \Supplier and \Customer lists if they have any payable or receivable lines, respectively. It also picks between the \CustomerID and \SupplierID based on a line's `account_type`. This logic is applied to `account_saft` and updates the other, country-specific SAFT reports where appropriate. It also retains the previous `customer_rank` and `supplier_rank` logic as a fallback for older XML reports and for accounts other than `asset_receivable` or `liability_payable`. opw-6118024
This update fixes an issue where the ICP export generated inconsistent XML reports by potentially mixing data from different company contexts. The change ensures a single, consistent company context is used for identifier values, improving the accuracy and reliability of the exported data for Dutch reporting requirements. This resolves potential confusion and ensures data integrity.
Original PR description
Description of the issue this commit addresses: The ICP export could mix values from different company contexts. In some cases, the main identifier and the fiscal entity division value did not come from the same source, which could create confusing or inconsistent XML output. --- Desired behavior after this commit is merged: This commit makes the ICP export use one consistent company context for identifier values, reuses precomputed values when available, and avoids overwriting them with unrelated defaults. --- task-6065382 Forward-Port-Of: odoo/enterprise#112995
This update resolves an access error that occurred when setting up Argentinian companies with branch companies, specifically when archiving a branch. The fix ensures that archived companies are no longer included in access validation, preventing errors and improving data loading for these configurations.
Original PR description
***Steps to reproduce*:** - Create an Argentinian company and create a branch company under the same company. - Set the same Tax ID for both the main and branch company. - Archive the branch company.…
***Steps to reproduce*:**
- Create an Argentinian company and create a branch company under the same company.
- Set the same Tax ID for both the main and branch company.
- Archive the branch company.
- Go to Settings -> Accounting.
- Select any Argentinian Fiscal Localization for the main company.
***Observed behavior*:**
- An access error is raised: `Access to unauthorized or invalid companies.`
***Cause*:**
- In `_get_branches_with_same_vat`, the following logic: `current.root_id._accessible_branches()` and `self.env['res.company'].sudo(). search([('id', 'child_of', current.root_id.ids)])` was also including archived branch companies.
- These archived companies were later involved in access and company validation flows, causing the access error.
- The same issue also affected demo data loading for such company setups.
***Fix*:**
- Add a filter to include only active companies and branches while fetching related companies.
- This prevents archived branch companies from being included in the validation flow.
- Also fixes the issue preventing demo data from loading correctly for these company configurations.
Related Community PR :- [odoo/community](https://github.com/odoo/odoo/pull/266321)
opw-6197313This update fixes a problem where Fedex labels were missing a crucial reference field (REF) needed for accurate shipping. The change ensures the 'REF' field is populated correctly when creating Fedex labels for stock transfers, aligning with API documentation and preventing potential shipping issues. This ensures proper tracking and delivery confirmation.
Original PR description
Backport of bb4f8bf Original PR #116870 Forward-Port-Of: odoo/enterprise#117873