Friday, July 17, 2026
11 changes · saas-19.4
Enhancements to existing features
Peruvian e-invoicing now includes the product classification codes required by SUNAT's upcoming validation rules. This helps businesses avoid rejected e-invoices for affected goods when the new requirements take effect.
Original PR description
SUNAT is updating its validation rules 2026-08-01, adding three mandatory annexes (25.1, 25.2, 25.3) to Product Catalog N25. E-invoices for these goods are rejected when the required UNSPSC code is not available in the database. Most of the required codes already exist and are active. The rest are handled here: two missing UNSPSC codes were added to the shared catalog, while the fourteen codes that exist but are inactive and the SUNAT-only code 11111111 (which is not part of the UNSPSC standard) are activated from the Peru localization instead. Doing the Peru-specific part in the l10n_pe_edi install hook and upgrade script, the way l10n_mx_edi and l10n_ke_edi_oscu do for their own codes, keeps these activations out of databases that do not use the Peruvian localization. Task-6366907 Forward-Port-Of: odoo/enterprise#124200 Forward-Port-Of: odoo/enterprise#123577
Resolved issues and error corrections
Hong Kong IRD payroll reports now use the correct tax year based on employee start or departure dates. The update also enforces required details when an employee departure reason is marked as “other,” helping businesses meet IRD certification and filing requirements.
Original PR description
As we now have complete support for IRD reports (in master), we started to try to get our system certified by the IRD.
A first submission highlighted a few issues that we are now fixing.
From 19.0:
- In IR56F, the RTN_ASS_YR should be the tax year in which the employee left the company. E.g. after april, the next year.
- In the same report, if the code for the cessation reason is 5 (other), the reason MUST be provided.
From 19.2:
- Same change has to be done when setting RTN_ASS_YR for IR56G
- A same change has to also be done for IR56E, based on the date the employee joined the company.
task-6332150
Forward-Port-Of: odoo/enterprise#124456
Forward-Port-Of: odoo/enterprise#121877Colombian POS orders containing combo products now generate electronic documents that DIAN can accept. The system excludes zero-priced combo parent lines from the submitted XML, preventing card-paid combo sales from failing validation.
Original PR description
Issue: When ordering through POS combo items won't be accepted by DIAN. Steps to reproduce: Set company to Colombia and activate the DIAN module. Simulate a sell of an combo item with POS. Pay with card. Error will ensue. Cause: The XML sent to DIAN is not accepted because one of the items has 0 price (the combo item). Solution: Not sending lines that are combo items. opw-6232599 Forward-Port-Of: odoo/enterprise#123928 Forward-Port-Of: odoo/enterprise#119652
This fixes an issue where attendee email previews could show an outdated event start date after an event was rescheduled. Attendees now receive emails with the correct updated event timing, reducing confusion for multi-day events.
Original PR description
Steps to reproduce: ------------------------------------------------ 1. Install Event module 2. Create a multi day event 3. Create one attendee for the event 4. Change the event dates 5. Go to…
Steps to reproduce: ------------------------------------------------ 1. Install Event module 2. Create a multi day event 3. Create one attendee for the event 4. Change the event dates 5. Go to attendee and Click on Send by Email Observation: ------------------------------------------------ The event start date displayed in the email body is not updated after the event dates are modified. Issue: ------------------------------------------------ In `saas-18.2`, `event_begin_date` and `event_end_date` were simple related fields that automatically updated when their source fields changed. https://github.com/odoo/odoo/blob/saas-18.2/addons/event/models/event_registration.py#L57-L58 However, in `saas-18.3`, slots were introduced and these fields were converted to computed fields https://github.com/odoo/odoo/pull/205945/changes/e2bf8a89d6a50bd40f4673bef38176465f83ba0f * `event_begin_date` is made stored for cohort view grouping * However, the base compute method only depends on `event_id` and `event_slot_id` https://github.com/odoo/odoo/blob/ac37b479321dbe9dbf864e833900e043b1cc70df/addons/event/models/event_registration.py#L177-L180 * When you change `event.date_begin` or `event.date_end`, the registration records don't recompute because the dependency is on the `event_id`, not on the related date fields (`event_id.date_begin`, `event_id.date_end`) * Non-stored computed fields recalculate on-the-fly when accessed, so `event_end_date` appeared to work * Stored computed fields only recalculate when their explicit dependencies change Solution: ------------------------------------------------ * Corrected the dependencies of `_compute_event_begin_date` to recompute value on changing the date of the event opw-6284576 Forward-Port-Of: odoo/enterprise#120184
This fixes an issue that prevented exchange rate adjustment entries from appearing in the bank reconciliation widget. Accounting users can now see the expected exchange movements when reconciling bank transactions, reducing confusion and helping reconciliation stay accurate.
Original PR description
Fix a bug where the exchange moves are no more displayed in the bank reco widget. Bug introduced here: https://github.com/odoo/enterprise/pull/119557 no-task Forward-Port-Of: odoo/enterprise#124495
This fixes a crash when downloading or printing German POS receipts that include Fiskaly TSS certification data. Businesses using certified German point-of-sale flows can reliably access receipts from the backend without errors.
Original PR description
With fiskaly in production, when printing the pos receipt, it crashes because the tss values dictionnary is not correctly interacted with. To reproduce: install l10n_de_pos_cert create a DE shop activate fiskaly and the tss in the settings of the POS create an order in the POS and pay it go to the backend, open the pos order and download the receipt it will crash To reproduce without production credentials, you can not activate fiskaly and the tss but still create and pay the pos order. Then, you can change the pos.config to add the l10n_de_fiskaly_tss_id and change the pos.order to add the l10n_de_fiskaly_time_start. Then download the receipt. opw-6356628 Fixes https://github.com/odoo/enterprise/pull/115676 Forward-Port-Of: odoo/enterprise#123473
VoIP call smart buttons now open the same family-wide records that they count, covering the contact and related company contacts. New records created from those actions still default to the original contact person, reducing confusion for sales, CRM, helpdesk, project, and subscription users.
Original PR description
Commit [1] change the smart buttons on voip.call to count records from all family of the partner (count all record from all partners from the partner's company). However, the actions on the buttons stay the same, they will only open records from the partner itself. This is confusing, we change it to also show records from the whole partner family. [1]: 16772c5c1e604d6beb514f9e5b166fc0c2f452a7 Task-6379569
Chilean point-of-sale receipts with SII barcodes now print correctly instead of crashing during receipt generation. This ensures sales can be validated and customers can receive compliant receipts without interruption.
Original PR description
Steps to reproduce: - Have a Chilean company with DTE configured (a resolution number/date and a signed boleta/factura, so the order's move has an SII barcode) - Open a PoS session, pay an order and validate it Issue: The receipt fails to render and printing crashes with: `TypeError: ctx.image.l10n_cl_sii_barcode_image.to_base64 is not a function` Cause: Commit 0b50021bdae adapted this template as part of the BinaryValue migration (odoo/odoo#244421), calling `to_base64()` on the barcode image. However `l10n_cl_sii_barcode_image` is a computed `fields.Char` that already holds a base64 string (`_pdf417_barcode` returns `b64encode(...).decode()`), not a Binary, so it is never wrapped in a `BinaryValue`. Moreover, this template is also rendered client-side by the PoS QWeb engine, where the value loaded from the server is a plain string with no `to_base64` method either. opw-6389718 Forward-Port-Of: odoo/enterprise#124438
Service sale order lines created from field service planning now let Odoo calculate prices automatically. This ensures customer pricelists and product pricing rules are applied correctly instead of being bypassed by a fixed unit price.
Original PR description
Before this commit, in the method `_generate_service_sale_order_lines` the `price_unit` for sale order lines used an explicitly defined unit price. This prevented the pre-computation of the price. It may cause some issues, for example if there was a pricelist defined on the product, we didn't apply the prices from that pricelist. This commit removes explicit definition of the `price_unit` to let the sale order creation process handle it. [error-941068](https://runbot.odoo.com/odoo/error/941068)
Colombian electronic invoice XML imports now treat the listed price as the actual unit price, matching DIAN rules. This prevents incorrect negative discounts from appearing on vendor bills when imported products have quantities greater than one.
Original PR description
Problem: When importing XML files to generate vendor bills, the system uses UBL parser and assumes that the PriceAmount node needs to be divided by the BaseQuantity node to obtain the exact price…
Problem: When importing XML files to generate vendor bills, the system uses UBL parser and assumes that the PriceAmount node needs to be divided by the BaseQuantity node to obtain the exact price unit. However, in Colombia, the DIAN treats the PriceAmount node as the exact price unit. This was not flagged in the system so the parser incorrectly divides the PriceAmount by BaseQuantity, resulting in negative discounts to be added to match the subtotal. Solution: Extract the basis_qty logic into a helper method so other localizations can override when needed. Current behavior: When importing a Colombian XML with a product that has a BaseQuantity greater than 1, the PriceAmount gets incorrectly divided, resulting in negative discounts on the vendor bill. Expected Behavior: When importing a Colombian XML with a product that has a BaseQuantity greater than 1, the PriceAmount gets parses as the exact unit price with no negative discounts applied. task-6215466 Forward-Port-Of: odoo/enterprise#124567 Forward-Port-Of: odoo/enterprise#122313
This fix prevents an accounting dashboard filter from accidentally affecting document creation during Mexican electronic invoicing payment updates. It avoids an error that could block users from updating payments on CFDI invoices after reconciling bank transactions.
Original PR description
Issue: The `default_type` context can leak into documents creation with invalid values (e.g., 'sale' for documents.document.type), causing a ValueError. Steps to reproduce: - Use a Mexican company with CFDI credentials configured. - Install the documents_account module and create a folder for journals where you will place customer payments. - Create an invoice with "payment policy = PPD", and send it to CFDI. - Create a bank transaction and reconcile it with the invoice. - Go to the Accounting Dashboard, remove current filters, and group by "Type" (this injects default_type into the context). - From there, enter the "Sales" journal and open the invoice. - Click on the "Update Payments" button. - Result: `ValueError: Wrong value for documents.document.type: 'sale'` Fix: Clean context from the `default_*` keys when creating the attachment of the document. opw-6141172 Forward-Port-Of: odoo/enterprise#124578 Forward-Port-Of: odoo/enterprise#124074