Monday, February 23, 2026
10 changes · 17.0
Enhancements to existing features
This update modernizes invoice formats for French, German, and Belgian customers, aligning with new regulatory standards for Factur-X and ZUGFeRD. It clarifies invoice types (ZUGFeRD vs. XRechnung) based on business type and customer location, improving clarity and compliance. The changes also update default invoice formats to PDF/A-3 for these regions.
Original PR description
Updating the FacturX format (France)/ ZUGFeRD format (Germany) to respect the new norms: Factur-X 1.07.3 EXTENDED and ZUGFeRD 2.3.3 EXTENDED. Add the differentiation between these two formats in the customer interface, even if they point to the same value in the code. It clarifies things for the customer, things are called by their name. Also, in Germany, for B2B invoices (peppol EAS = 9930), use ZUGFeRD, but for B2G invoices (peppol EAS = 0204), use XRechnung. Adaptation of the default values in the partner form according to this statement. For French and German companies that are sending invoices to French, German or Belgian customers, changed the default format of invoice sent to be compliant to PDF/A-3 norms. task-5266286 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update simplifies the process of downloading attachments from account moves like invoices and vendor bills. Now, all related attachments – including PDFs, XML files, and mail thread attachments – are automatically bundled into a single ZIP file for easy download, eliminating the need to download individual files.
Original PR description
before: - In v17, account moves (invoices, vendor bills, etc.) did not provide any ZIP export. - Users wanting to download move attachments (e.g. for vendor bills) had to download each file individually. after: - Add an Action on account moves to export attachments as a ZIP archive. - The ZIP contains all attachments linked to the move (PDF, XML, and any other files present in the mail thread), not only the report PDF. - The action is available for all move types (customer invoices, vendor bills, journal entries, etc.) task-5232551 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This update fixes an error in how leave balances are calculated when simulating accruals across carry-over dates. Previously, the system incorrectly reported negative balances. The fix precomputes leave consumption to avoid a circular dependency, ensuring accurate balance calculations for employees taking leave.
Original PR description
__Problem:__ When simulating accruals across a carry-over date, the system showed a wrong available balance. 1. Create an accrual plan: - 1 day granted at the beginning of each month - reset at the…
__Problem:__
When simulating accruals across a carry-over date, the system showed a wrong available balance.
1. Create an accrual plan:
- 1 day granted at the beginning of each month
- reset at the start of the year (carry-over reset)
2. Enable _Allow Negative_ on Paid Time Off.
3. Create a validated allocation starting at the beginning of the year.
4. Take 11 days of leave at the end of the year, approve and validate it
5. Cross the carry-over (Jan 1), then check balance on __Feb 1__:
- __Expected:__ available 1
- __Current:__ available −9
__Root cause:__
- Circular dependency between `leaves_taken` compute and future accrual simulation:
`_get_future_leaves_on()` → creates `fake_allocation` → triggers
`leaves_taken` → `_compute_leaves()` →
`employee._get_consumed_leaves()` → `_get_future_leaves_on()` again.
→ Infinite recursion / wrong value injected.
__Fix:__
- Precompute and inject the correct `leaves_taken` value when building the `fake_allocation` before processing accrual plans through a direct helper `_get_leaves_taken_in_period(target_date)` to compute leaves consumed up to a given date for a single allocation, without recursion.
- opw-4918619This update fixes an issue where the payment term for Mexican CFDI exports was sometimes rendered in English instead of Spanish, leading to potential duplicate filings with the SAT. By explicitly setting the Spanish context, this change guarantees consistent and compliant CFDI XML generation, preventing errors and streamlining the export process.
Original PR description
The CFDI 4.0 field CondicionesDePago is derived from the payment term name, but its rendered value depends on the language context active at XML generation time. Even when the user language is…
The CFDI 4.0 field CondicionesDePago is derived from the payment term name, but its rendered value depends on the language context active at XML generation time. Even when the user language is Spanish, this field may still be rendered in English (e.g. "Immediate Payment") due to context loss during the CFDI rendering process or during XML regeneration. This behavior becomes especially problematic in scenarios with PAC intermittency. A stamping request may be successfully processed by the SAT but time out in Odoo, and a subsequent retry can regenerate the CFDI using a different language context. As a result, two CFDIs with identical fiscal data but different textual content (English vs Spanish) can be generated, potentially leading to duplicated CFDIs registered in the SAT. To ensure deterministic and compliant XML generation, the payment term name is now explicitly evaluated under the es_MX context when rendering the CFDI. This guarantees stable Spanish content for Mexican CFDI textual fields, regardless of user language or transient context changes during the EDI flow. This follows the same rationale as odoo/enterprise@f75a04fa954d, where a lost language context during XML rendering caused inconsistencies between the XML and the expected Mexican CFDI content. Forward-Port-Of: odoo/enterprise#105588
This update corrects a discrepancy in the Romanian tax reports to align with the latest government regulations. Specifically, VAT rates and certain tax amounts have been updated to reflect the current 19-21% and 5%/9%/11% structures. Inactive taxes were also adjusted to ensure accurate report generation.
Original PR description
Romanian VAT has increased from 19% to 21% and from 5%/9% to 11%, some taxes were added previously to the module but they were not reflected in the tax report, also other taxes were missing in order for the report to replicate the current up to date version issued by the romanian government.
This update fixes an issue where lot numbers weren't consistently displayed in POS sales orders when products were tracked by lot and stored in multiple locations. The fix ensures that the correct lot number is accurately reflected for all product lines within the order, improving inventory accuracy and order fulfillment. It also addresses a related issue with stock movement processing during POS closure.
Original PR description
When opening an SO in POS that has a product tracked by lot that is split into several location, the lot number will only appear in one of the line and not the others Steps to reproduce:…
When opening an SO in POS that has a product tracked by lot that is split into several location, the lot number will only appear in one of the line and not the others Steps to reproduce: ------------------- 1. Create a Product A tracked by lot, create lot 111 and add 1 unit to location A and another one to location B 1. Create a sales order 2. Add two units of the product to the sale order 3. Confirm the sales order 4. Open the transfer, make the transfer retrieve the product from several location with the same lot. 5. Save the transfer 6. Open the sales order in POS 7. Load the SN/lots -> Two line of qty 1 appear for the product A but only the first one has the lot number Additional Issue: 8. Change the number of the product for the first line to 2 and erase the second line 9. Confirm and Pay 10. Close POS 11. Open move lines for this product (Inventory>product>In/out) -> It moves 2 product from one location (when there is only product) Observation: ------------- When loading the SO in POS, we will retrieve the SO: https://github.com/odoo/odoo/blob/cb1f5d9c6db64b9ace9b7aa46bd6f94e4462176b/addons/pos_sale/static/src/app/order_management_screen/sale_order_management_screen/sale_order_management_screen.js#L104 While retrieving the SO, we will also retrieve the SOL, with additional information: https://github.com/odoo/odoo/blob/d9b2e5ee730a4e79586bfd3f09adfb794d2dc1f3/addons/pos_sale/models/sale_order.py#L79 -> Issue is that when several moves_line have the sale lot_id.name, their quantity will be overwritten. Addition Issue : When closing pos, all the move will be processed, when processing those moves, the origin only check if the quantity is more than 0 and not if there is enought units. https://github.com/odoo/odoo/blob/cb1f5d9c6db64b9ace9b7aa46bd6f94e4462176b/addons/point_of_sale/models/stock_picking.py#L293-L297 opw-5347992
This update allows branch companies to see and select contacts owned by their parent company when creating invoices or vendor bills. Previously, a branch company could only see contacts owned by itself or those without a company assigned. This change resolves a limitation in the multi-company hierarchy functionality.
Original PR description
Currently, when operating in a branch company, contacts belonging to the parent company are not visible in the partner dropdown on Invoices or Vendor Bills. ### **Steps to reproduce:** 1) Create a…
Currently, when operating in a branch company, contacts belonging to the parent company are not visible in the partner dropdown on Invoices or Vendor Bills.
### **Steps to reproduce:**
1) Create a multi-company hierarchy (Company A -> Branch B).
2) Create a contact owned by Company A.
3) Switch the current company to Branch B.
4) Go to Accounting > Customers > Invoices and create a new invoice.
5) Try to select the contact created in step 2.
### **Current/Buggy Behavior:**
The contact does not appear in the search results.
### **Expected Behavior:**
The contact should be selectable.
### **Root Cause:**
since commit https://github.com/odoo/odoo/commit/67169c42061cb51bc68f6c74f0674a670dd04f58,
the partner model supports the standard
`check_company=True` mechanism, and record rules were updated to allow
branches to access partners of their parent company.
However, the `partner_id` field on the `account.move` form view still
retained a explicit domain: `[('company_id', 'in', (False,
company_id))]` as shown at [1].
This domain overrides the standard `check_company` behavior.
due to which it restricts the selection to partners owned by the current company
(the branch) or partners with no company set. It explicitly excludes
partners owned by the parent company.
### **Fix:**
Remove the domain at [1],
This allows the field to rely on the standard `check_company=True`
logic, which correctly handles the multi-company hierarchy and allows
branches to select parent company partners.
[1]- https://github.com/odoo/odoo/blob/6b7b83449739932aa8420ef8fcd888116e3c0f8a/addons/account/views/account_move_views.xml#L896
**opw-5484611**This update ensures that NACHA payment files accurately reflect the actual account holder's name, rather than the customer's name in Odoo. Prioritizing the bank account holder's name improves payment processing accuracy and compliance with NACHA standards.
Original PR description
The NACHA entry detail was using the partner's name (res.partner.name) for the Individual Name field. This should instead prioritize the Account Holder Name (acc_holder_name) from the bank account, as this reflects the actual name on the bank account which may differ from the partner's name in Odoo. The code now uses bank.acc_holder_name if set, and falls back to payment.partner_id.name if not set.
This update resolves an issue where users received a generic error message when attempting to print resumes with invalid templates. The fix adds detailed tracebacks to the error message, providing developers with the necessary context to quickly identify and resolve template problems. This improves the user experience and streamlines troubleshooting.
Original PR description
Currently, when a user tries to print a resume with an invalid template there’s no traceback to show what went wrong. **Steps to produce:** * Install `hr` with demo data * Modify the view…
Currently, when a user tries to print a resume with an invalid template there’s no traceback to show what went wrong. **Steps to produce:** * Install `hr` with demo data * Modify the view `report_employee_cv` by adding `<div t-if=o.no/>` * Print resume of any employee **Observed Behavior:** Currently it only shows the error in [1], with no context or traceback to explain what went wrong. **Root cause:** * This happens because the route doesn’t include the website parameter. Without it, the system treats the route as non–front end [2], so the error handler never reaches [3].That means [4] never loads the templates [5], and the browser just gets a plain response at [6]. **Solution:** * Catching and raising UserError shows appropriate traceback. **Before:** <img width="1606" height="796" alt="image" src="https://github.com/user-attachments/assets/d5432fbf-d016-46a9-bade-8e8408848c66" /> **After:** <img width="1832" height="928" alt="image" src="https://github.com/user-attachments/assets/6f0413ca-a82a-487d-888f-81be6f0fab03" /> [1]: https://drive.google.com/file/d/1qJLkFGw4bEclqKihdUI-4bjJofdFArEc/view?usp=sharing [2]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L386 [3]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L611 [4]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L573-L576 [5]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/views/http_routing_template.xml#L139 [6]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L575 Related: https://github.com/odoo/enterprise/pull/100142 opw-5167898
This update fixes a problem where users received a generic error message when generating PDF payroll reports with invalid templates. Now, the system displays a detailed traceback, making it easier to identify and resolve the underlying template issues. This improves the user experience and streamlines troubleshooting.
Original PR description
Currently, when a user tries to print a PDF report with an invalid document layout template, there’s no traceback to show what went wrong. **Steps to produce:** * Install payroll with demo data. *…
Currently, when a user tries to print a PDF report with an invalid document layout template, there’s no traceback to show what went wrong. **Steps to produce:** * Install payroll with demo data. * Settings > Configure Document Layout then Edit Layout * Add non-existent field `<div t-if='o.no'/>` * Payroll > All payslips > print any payslip **Observed Behavior:** * Currently it only shows the error in [1], with no context or traceback to explain what went wrong. **Root cause:** * This happens because the route doesn’t include the website parameter. Without it, the system treats the route as non–front end [2], so the error handler never reaches [3].That means [4] never loads the templates [5], and the browser just gets a plain response at [6]. **Solution:** * Catching and raising UserError shows appropriate traceback. **Before:** <img width="1601" height="507" alt="image" src="https://github.com/user-attachments/assets/f7f208f0-cdd7-410e-87e7-32a9651df9d8" /> **After:** <img width="1847" height="928" alt="image" src="https://github.com/user-attachments/assets/c73522d6-2632-422b-b1d1-234e6c61ed2e" /> [1]: https://drive.google.com/file/d/1qJLkFGw4bEclqKihdUI-4bjJofdFArEc/view?usp=sharing [2]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L386 [3]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L611 [4]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L573-L576 [5]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/views/http_routing_template.xml#L139 [6]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L575 Related:https://github.com/odoo/odoo/pull/237262 opw-5167898