Tuesday, June 16, 2026
23 changes · saas-19.3
New functionality added to Odoo
This update adds support for the Hacienda Foral de Navarra tax agency within Odoo's SII invoicing system. It includes necessary configuration changes to handle the agency's specific XML format and endpoint requirements, ensuring accurate invoice submissions to the Navarra tax authorities.
Original PR description
The Hacienda Foral de Navarra uses the same SII XML format as AEAT but sends invoices to a different endpoint. Additionally, Navarra requires explicit XML namespace declarations in the SOAP envelope header, which the standard zeep serializer does not include by default. This adds the Navarra tax agency as a new option in the company SII configuration, defines its production and test endpoints, and injects the required namespaces in the request header when the Navarra agency is selected. task-5946583 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268928 Forward-Port-Of: odoo/odoo#263048
Enhancements to existing features
This update adds a time limit to the Odoo profiler, preventing excessively long query analysis. The system now automatically tracks and commits profiling data at regular intervals, improving performance and reducing the impact on user experience. This ensures the profiler remains responsive and efficient.
Original PR description
Modify the query collector so that it add an entry before the query runs and updates the time after it runs. use the async collector periodic sampling to commit the profiler after a time limit. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268750 Forward-Port-Of: odoo/odoo#215034
Resolved issues and error corrections
This update fixes an issue where multiple taxes on Brazilian sales orders were displayed on a single line, making them difficult to read. The change adds a line break to display each tax detail on its own line, improving clarity and usability for users.
Original PR description
Upon creating a SO in the Brazilian localization and computing taxes, tax details are displayed on the SO lines. However, when multiple taxes are applied, all tax details are shown on a single line, making them difficult to read. Add a line break between tax details so that each tax is displayed on a separate line. Before: https://www.awesomescreenshot.com/image/61178015?key=703ceba935bbf0b97f4b45c649722827 After: https://www.awesomescreenshot.com/image/61178078?key=3b980b91b7657aa48dec9b825549ebeb opw-6234768 Forward-Port-Of: odoo/enterprise#120527
This update corrects a bug that caused errors when date calculations used a missing or `None` offset value. The fix ensures that date movements are avoided when an offset isn't explicitly provided, preventing unexpected behavior in AI-powered features. This improves the reliability of date-based computations.
Original PR description
Currently, an exception is raised when `offset` is `None` and is compared
with `MIN_OFFSET` or `MAX_OFFSET`.
Currently `offset = op.get("offset", 1)` to assign a default value of `1` when
the `offset` key was missing from `op`. However, this does not handle cases
where the `offset` key is present but its value is `None`.
This commit fixes the issue by defaulting `offset` to `0` when it is missing or
`None` in `op`. Using the default value ensures no date movement occurs
when `offset` is not explicitly provided.
Sentry-7448086997
Forward-Port-Of: odoo/enterprise#118466This update corrects a bug where inactive or archived taxes were incorrectly displayed within the bank reconciliation process. The fix ensures that users can only select active taxes, improving data accuracy and preventing potential errors during reconciliation reporting. This resolves issue OPW-6245641.
Original PR description
### Issue:
When editing a line within the bank reconciliation widget, inactive and archived taxes are incorrectly available for selection
### Cause:
The bank reconciliation edit line form view carried the `{'active_test': False}` context on the `tax_ids` field
This context allowed archived taxes to be loaded and selected during creation and manual edition
### Fix:
Explicitly force `active_test: True` in the view context for the tax field to ensure only active taxes can be searched and selected by the user
### Steps to reproduce:
- Install `account_accountant`
- Create a new tax and set it to inactive
- Go to the Bank Reconciliation widget
- Create a bank statement line
- Set the account to 600000 Expenses
- Edit the line by clicking on the pencil icon
- Open the Taxes selection dropdown
Before the fix, the inactive tax is visible and available for selection by default
opw-6245641
Forward-Port-Of: odoo/enterprise#119522This update improves the accuracy of the reconciliation process by ensuring the matching dialog displays both draft and posted journal items. Previously, the dialog was limited, showing fewer items due to a default filter. This change provides a more complete view for users to reconcile transactions.
Original PR description
The reconcile badge counts draft and posted journal items, but the matching dialog forces a posted filter by default, this makes the dialog show fewer lines than count as it discards the draft ones. Remove the default posted search filter so the dialog displays all matching items. task-6234801 Forward-Port-Of: odoo/enterprise#118146
This update adjusts the format of unit prices in Polish tax invoices (FA3) to ensure accurate calculations and alignment with tax regulations. While the current system technically complies with KSEF requirements, this change improves invoice accuracy by using the maximum allowed decimal places. This resolves a potential discrepancy between unit price and total without tax.
Original PR description
**STEP TO REPRODUCE** 1. Create an invoice with a unit price of 10.005 and qty of 2. 2. Send the invoice to ksef. 3. Open the xml and notice P_9A (unit price) is 10.00 and P_11 (total without tax) is 20.01 Which is inconsistent (10.00 * 2 =/= 20.01). This PR increase the decimal places of P_9A to 8 digits which is the maximum allowed by the FA(3) format. Note that Ksef doesn't verify the untaxed unit price * quantity = total without tax, so the invoice we send are technically valid. However, it's best to generate invoice where the numbers add-up. opw-6203896 Forward-Port-Of: odoo/odoo#263812
This update resolves an issue where the VoIP softphone would throw errors when receiving calls from numbers not linked to a contact. The fix ensures that a task can be created from a contactless call and prevents the 'Tasks' button from appearing when no contact is associated with the call, improving usability.
Original PR description
**Problem:** Two linked errors occur in the Phone (VoIP) softphone when a call is made to or received from a number that is not linked to any contact. **Steps to reproduce:** 1. Receive or make a…
**Problem:** Two linked errors occur in the Phone (VoIP) softphone when a call is made to or received from a number that is not linked to any contact. **Steps to reproduce:** 1. Receive or make a call from the softphone using a phone number that is not linked to any existing contact. 2. Open the call's actions and click "Create" > "Task". -> A client error appears and the task is not created. 3. On a voip.call form whose Contact has been removed, click the "Tasks" smart button. -> A server error is raised. **Current behavior:** Step 2 raises "Cannot read properties of undefined (reading 'id')" and step 3 raises "ValueError: not enough values to unpack (expected 1, got 0)". **Expected behavior:** Creating a task from a contactless call should open the task form without a default contact, and the Tasks smart button should not be reachable when the call has no contact. **Cause of the issue:** Both code paths assume a call always has a linked partner. In `action_list_patch.js`, `getCreateTaskAction` only checks `shouldShowTaskButton` in its predicate but reads `this.contact.id` in its `onClick`; for a contactless call `this.contact` is undefined. In `voip_call.py`, `action_view_tasks` delegates to `self.partner_id.action_view_tasks()`, whose `ensure_one()` fails on the empty partner recordset. Unlike the softphone "view tasks" action, which is gated by `this.contact?.task_count`, the form stat button had no visibility guard. **Fix:** The create-task action now mirrors the existing contact and lead actions, which already build their context conditionally on `this.contact`, so a contactless call simply opens the task form with no default partner. The Tasks stat button is hidden when there are no tasks, matching the softphone predicate and ensuring the partner-less code path is never reached. opw-6246641 Forward-Port-Of: odoo/enterprise#119412
This update fixes a technical issue that could cause errors when comparing history differences in the web editor. The fix ensures the system handles empty history data gracefully, preventing a potential error and improving stability. This change ensures the web editor functions reliably for all users.
Original PR description
If, for whatever reason, the history we try to compare is an empty string, we might get a value error thrown. We guard the code to avoid the error. see :https://github.com/odoo/odoo/issues/269149 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269722
This pull request resolves a visual issue where the cursor appeared incorrectly within dropdown input fields in account reports. The change aligns the cursor to the right, improving the user experience and ensuring consistent input behavior within these reports.
Original PR description
Dropdown inputs inside of an account report show the cursor in the center of the input field. The cursor has been changed to be right-aligned. task-6247454
This update resolves a bug that occurred when sorting financial reports by account code, specifically when a value of 'None' was present. The fix ensures the system handles missing account codes gracefully, preventing crashes and improving the reliability of financial data reporting. This ensures accurate reporting for all users.
Original PR description
If you're grouping by account_code on a line using an account_code
engine, and there's a None value, it will crash.
To get that, you can (with demo data):
- install l10n_be
- set "BE Company COA" as the main, keeping "My Company (San Francisco)"
activated
- go to the profit and loss "Profit and Loss (Abbr) (BE)", set the date
as the current year
- set "Consolidation" filter
- Unfold "60/61 - Goods for Resale,..."
```
Traceback (most recent call last):
...
File "... in _compute_formula_batch_with_engine_account_codes
results_list.sort(key=lambda x: math.inf if x[0] is None else x[0])
TypeError: '<' not supported between instances of 'float' and 'str'
```
Because in case of `None`, we compare with `math.inf` but the account
codes are string.
no-task
Forward-Port-Of: odoo/enterprise#120531This update corrects a validation error that occurred when importing Polish VAT (KSeF) invoices. The fix allows invoices without the required `P_9A` and `P_11` fields to be processed correctly, preventing interruption of the invoice workflow. This ensures smoother and more reliable import of Polish VAT invoices.
Original PR description
When importing bills, if `P_9A` and `P_11` are absent or zero, a `UserError` is raised: `No net or gross unit price found in the FA (3) for the line with the product.` **Steps to reproduce:** - Upload the problematic XML file as an attachment via `Settings -> Technical -> Attachments` - Create a `validator` server action with the code provided in the referenced ticket, with the `Add Contextual Action` flag set - Reload the page - Select the attachment in list view - Click the gear icon - Run the newly created server action KSeF FA(3) schema documentation: https://ksef.podatki.gov.pl/media/4u1bmhx4/information-sheet-on-the-fa-3-logical-structure.pdf Ticket [link](https://www.odoo.com/odoo/project.task/6211065) opw-6211065 Forward-Port-Of: odoo/odoo#265228
This update fixes a problem where Google Calendar attendee information wasn't always syncing correctly when some invitations matched existing email aliases. The change ensures that all Google attendees are properly synchronized, preventing missed invitations and improving the reliability of calendar events. This resolves an internal issue (opw-6086240) that impacted event scheduling.
Original PR description
_get_sync_partner excludes partners whose email matches a configured alias, returning a list shorter than the emails/google_attendees lists. zip() stops at the shortest, silently dropping the last Google attendee instead of the alias-matched one. Fix by replacing the positional zip with a by-email dict lookup, so each attendee is resolved independently and only the unresolvable one is skipped. opw-6086240 Forward-Port-Of: odoo/odoo#263787
This update prevents deleting a batch payment once its linked payments have been marked as 'sent' and an XML export file has been generated. Because we cannot modify the 'sent' status for SEPA payments, this change ensures data integrity and allows continued generation of necessary export files. This avoids potential issues with generating updated payment reports.
Original PR description
When you create a batch payment, linked payments are marked as sent, and an export file is generated (XML). But if you delete the batch payment, the payments will remain marked as sent, meaning you won't be able to re-generate a new XML file for those payments. As we don't want to unmarked them as sent (we can't for SEPA payments), we decided to disallow the batch payment deletion in those cases. task-6117210
This update resolves a bug in the Website Builder module that was causing crashes during testing. By removing unnecessary definitions, the code is now more stable and reliable, ensuring a smoother experience for users building their websites. This fix improves the overall quality and stability of the Odoo website platform.
Original PR description
`this.websiteService` is defined in `WebsiteBuilder`. If it's used inside tests, it's useless to define it in `Builder` and it will crash.
This update fixes a display issue where the AI button appeared inconsistently in the Mass Mailing and Website Builders. The fix redirects patching to the Website Builder, ensuring the AI button is only visible when using the website functionality. This improves the user experience for website builders.
Original PR description
__Problem__ When opening the Mass Mailing builder after the Website Builder, the AI button is still shown. Conversely, if we open the Website Builder after the Mass Mailing builder, the AI button is never shown. This happens because Owl mounts the Builder component only once as long as we don't refresh the page. Since we patch the generic HTML Builder to put the AI button in the sidebar, the state of the first time it's mounted is preserved. __Fix__ Patch the Website Builder directly instead, as we only want the AI button to be available in the website. Community PR: odoo/odoo#270266 task-6189057
This update fixes an issue where holiday pay calculations could exceed an employee's regular wage. The system now ensures the base holiday amount is capped at the employee's standard earnings, ensuring accurate payroll processing and compliance. This change improves the reliability of holiday pay calculations.
Original PR description
The base amount should never be more than the employee's wage. Forward-Port-Of: odoo/enterprise#120681
A previous issue prevented users with limited time-off access from viewing leave information in the Attendances Gantt View. This fix ensures that the Gantt View correctly displays leave requests, even when users have specific access restrictions. The change adds a temporary access layer to ensure accurate calculations.
Original PR description
Version: - 19.0 Steps to reproduce: - Install Attendances and Time Off - Create an internal user. - Give the user: Attendances Officer access & No Time Off Officer/Manager rights - Create an employee…
Version: - 19.0 Steps to reproduce: - Install Attendances and Time Off - Create an internal user. - Give the user: Attendances Officer access & No Time Off Officer/Manager rights - Create an employee linked to the user. - Configure the employee with a Flexible Working Schedule. - Create and approve a Time Off request for the employee. - Open: Attendances -> Gantt View - Navigate to the month containing the employee's approved leave. Issue: - An access error is raised when opening a month that contains the employee's approved leave. Cause: - In `_handle_flexible_leave_interval`, the code accesses `leave.holiday_id` to read fields such as `request_unit_half`, `request_unit_hours`, and `request_hour_from/to` on the `hr.leave` model. - When the current user has Attendances Officer rights but no Time Off access(rare cases), the ORM access check on `hr.leave` raises an AccessError, even though this read is purely for internal calendar computation and does not expose leave data to the user interface. Fix: - Added sudo() on holiday_id to access the employee's leave details and compute the work interval as expected. Task-6264510 Forward-Port-Of: odoo/enterprise#120668 Forward-Port-Of: odoo/enterprise#119116
This update resolves an issue where creating payment sequences in the Accounting module would sometimes trigger a technical error. The fix ensures that date sequences are correctly formatted, preventing the traceback and allowing users to create payment sequences without interruption. This improves the stability and usability of the payment process.
Original PR description
## Issue When trying to call `dt.replace` on a `datetime.time`, a TypeError is raised ``` File "/home/odoo/Documents/src/odoo/190/odoo/addons/base/models/ir_sequence.py", line 270, in _next return…
## Issue
When trying to call `dt.replace` on a `datetime.time`, a TypeError is raised
```
File "/home/odoo/Documents/src/odoo/190/odoo/addons/base/models/ir_sequence.py", line 270, in _next
return seq_date.with_context(ir_sequence_date_range=seq_date.date_from, ir_sequence_date=dt.replace(tzinfo=None))._next()
^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'tzinfo' is an invalid keyword argument for replace()
```
## Steps to reproduce
1. Install *Accounting* (`accountant`)
2. Update the `account.payment` sequence:
- Toggle *Use subsequences per date_range* and create a range
3. In Accounting > Customers > Payments, create a payment:
- Payment Type: Receive
- Customer: Any
- Amount: Any
4. **A traceback appears**
## Cause
This error was introduced by https://github.com/odoo/odoo/commit/4b9dd7893f96.
The `AccountPayment._compute_name` method calls `_next_by_code` and passes a date as the `sequence_date`.
https://github.com/odoo/odoo/blob/337efb069f6cf2cb9478a970f075fd139c1e8e0a/addons/account/models/account_payment.py#L420-L422
In the `_next` method, the `dt` variable is set to that date (`datetime.date`), and calling the `.replace` method on that variable raises an error, as there's no tzinfo for `datetime.date`s.
opw-6303885
Forward-Port-Of: odoo/odoo#270283This update fixes a potential instability issue with the PDP registration process. By moving a key function to the company record, we ensure the registration process remains reliable even if the temporary PDP registration object is deleted. This improves the overall robustness of the system.
Original PR description
The aim of this commit is to move _get_iap_url on res.company model instead of pdp.regitration. This move is made for 2 reasons: 1. PDP registration is a transient model which means that the object could be deleted in the time. 2. PDP registration implementation was using the model (api.model) and the record (self.edi_mode) which is a bad implementation. So by moving this function on company, we ensure that we always have a record to call the function and then the function is no longer an api.model. no task id --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270380 Forward-Port-Of: odoo/odoo#270345 Forward-Port-Of: odoo/odoo#270386
This update fixes a potential issue where state deductions exceeding employee income could result in incorrect, negative taxable income calculations on payslips. The change ensures that taxable income defaults to zero in these scenarios, accurately reflecting state tax liabilities and preventing misleading pay statements. This improves payroll accuracy and compliance.
Original PR description
This commit simply defaults the computed taxable income amount to 0 in case the state deductions are greater than their gross income. Otherwise our payslips would imply that these employees are owed money by the state opw-5137280 Forward-Port-Of: odoo/enterprise#119208 Forward-Port-Of: odoo/enterprise#98114
This update resolves an issue where UBL import failed due to a mismatch between the product's and imported unit of measure categories. The fix allows imports to proceed without error, and users can manually correct the UoM after the import is complete. This prevents import failures and improves data accuracy.
Original PR description
The new collected_values UBL import flow sets product_uom_id from the XML unitCode without checking that the resolved UoM category matches the matched product's UoM category. When they diverge, writing the line triggers the incompatible error. Steps to reproduce: - Create a product "XYZ" with UoM "Units" (category "Unit"). - Import a Peppol UBL bill whose line has Item/Name "XYZ" and unitCode="MTK" (uom_square_meter, "Surface"). - Import fails with: "The Unit of Measure (UoM) 'm²' you have selected for product 'XYZ', is incompatible with its category : Unit." This fix will avoid setting the product_uom_id when the UoM category doesn't match the product's UoM category, allowing the line to be imported without error. The user can then manually set the correct UoM after import. opw-6121714 Forward-Port-Of: odoo/odoo#269933 Forward-Port-Of: odoo/odoo#269714
This update enhances the stability of the French PDP (Point of Departure) registration process. By moving a key function to the company record, the system now reliably accesses the necessary data, addressing a previous issue where the registration model could be deleted. This change improves the overall robustness of the PDP integration.
Original PR description
The aim of this commit is to move _get_iap_url on res.company model instead of pdp.regitration. This move is made for 2 reasons: 1. PDP registration is a transient model which means that the object could be deleted in the time. 2. PDP registration implementation was using the model (api.model) and the record (self.edi_mode) which is a bad implementation. So by moving this function on company, we ensure that we always have a record to call the function and then the function is no longer an api.model. no task id --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270382 Forward-Port-Of: odoo/odoo#270345