Daily updates from Odoo
Friday, August 14, 2026
51 changes
8 changes
Enhancements to existing features
Belgian payroll is updated to apply new fiscal employment bonus rates starting in August 2026 and future rate changes in 2028. This helps ensure payroll calculations remain aligned with upcoming Belgian tax rules for low-wage workers and general fiscal reductions.
Original PR description
Starting from August 2026: - The increased fiscal rate for low-wage workers (Volet B) rises from 52.54% to 63% (and to 72% in 2028). - The general fiscal rate (Volet A) rises from 33.14% to 35% starting in 2028. This adds new rule parameters for the fiscal rates and updates computation logic to apply these rates Task-6438319 Forward-Port-Of: odoo/enterprise#126713
Budget reports now load much faster for databases with many analytic lines and budget lines. The report matching logic was reorganized to avoid excessive comparisons, reducing a sample load time from nearly a minute to about one second.
Original PR description
**Description:** While loading the budget report, the bad queries are created by ```def _get_aal_query()``` and ```def _get_pol_query()``` function, makes the budget report unusable. **Root cause:**…
**Description:**
While loading the budget report, the bad queries are created by
```def _get_aal_query()``` and ```def _get_pol_query()``` function, makes
the budget report unusable.
**Root cause:**
Instead of doing a hash join while searching the record,
the OR statement in the Left Join in the condition
```(%(bl)s IS NULL OR %(a)s = %(bl)s)```
creates a nested for loop that compares everything single aal to bl,
this causes a significant performance issue as the number of the
number of check will be the the number aal * bl,
if a database has a 70k aal and 20k bl, both numbers are not large
but it will cause a 70k * 20k search which is more than a billion.
**Fix**:
There are some refactors made in this PR.
_First_, separate out the Q1.
In order to find the aal that has no bl connects to it.
Doing a search to find the aals that have bl and then subtract them from all aals.
_Second_, Instead of doing a nested loop for by using
```(%(bl)s IS NULL OR %(a)s = %(bl)s)```,
originally we will have do something like
```
JOIN budget_line bl
ON (bl.x_plan2_id IS NULL OR aal.x_plan2_id = bl.x_plan2_id)
AND (bl.x_plan3_id IS NULL OR aal.x_plan3_id = bl.x_plan3_id)
AND (bl.x_plan4_id IS NULL OR aal.x_plan4_id = bl.x_plan4_id)
```
Assuming each bl has three plans ```x_plan2_id```, ```x_plan3_id```, ```x_plan4_id```
Grouping the bl base on whether a specific plan is set, (i.e. shapes)
we can skip the ```IS NULL OR``` because we already know which plan
is null and do the hash join directly.
For example, the shapes will be a dictionary with a key of a tuple of booleans
based on whether a plan is set or not and the value is a list of bl_id.
```
{
(True, False, False): [1, 2],
(False, True, True): [3, 4],
(False, False, False): [5],
}
```
we can end up doing something like
```
JOIN budget_line bl
ON bl.id = ANY(ARRAY[3,4])
AND aal.x_plan3_id = bl.x_plan3_id AND aal.x_plan4_id = bl.x_plan4_id
```
which is way more faster.
---
The benchmark is made locally from this client's database which contains
69k aal, 23k bl, 6829 pol and 3 plans for aal and bl.
|Record count |Time before|Time after|
|--------------------------------------------------|-----------------|---------------|
|69k aal, 23k bl, 6829 pol, 3 plans |70.04s |4.6s |
Dalibo:
Before:
Month-over-month grand total by company:
https://explain.dalibo.com/plan/8h3d4e89aaf9f3d4
Overall grand total by company:
https://explain.dalibo.com/plan/445g1f9caf4923e2
Month-over-month grand total by plan:
https://explain.dalibo.com/plan/53a138ca50b2a7c4
Overall grand total by plan:
https://explain.dalibo.com/plan/hdbe169ddc7g5785
After:
Month-over-month grand total by company:
https://explain.dalibo.com/plan/hcc86c801e6872bf
Overall grand total by company:
https://explain.dalibo.com/plan/69b2421a3581f98h
Month-over-month grand total by plan:
https://explain.dalibo.com/plan/a88f398bbbch3148
Overall grand total by plan:
https://explain.dalibo.com/plan/1gg749ae7ab1553c
opw-6345552
Forward-Port-Of: odoo/enterprise#127732
Forward-Port-Of: odoo/enterprise#124161Timesheet Assistant suggestions are now easier to select in bulk by dragging across them with the mouse button held down. Ctrl-click no longer opens an unwanted new Odoo page, reducing accidental navigation and making batch actions faster.
Original PR description
Currently when the user uses ctrl + click on a suggestion, a new odoo page is opened. This is an undesirable side effect and it is removed in this commit. Also, users have to manually click on each suggestion when they want to remove them in batch, or create one timesheet for a bunch of suggestion. This commit lets user hover over suggestion with the mouse button pressed to select them. task-6385047 Forward-Port-Of: odoo/enterprise#124642
Only the person who created a signature request can now change a signer's email address. This helps prevent unintended or unauthorized recipient changes and improves trust in the signing process.
Original PR description
Forward-Port-Of: odoo/enterprise#127582 Forward-Port-Of: odoo/enterprise#126675
Spreadsheet pivots can now include SQL-based computed fields, giving users more flexible ways to analyze business data directly in spreadsheets. This improves reporting capabilities while keeping the change focused on the spreadsheet experience.
Original PR description
Task: 6442237 Forward-Port-Of: odoo/enterprise#126645
Currently all of our iot boxes are updated on mondays. This PR adds the dynamic selection of the update day of the week based on the rpi serial number. This allows our iot boxes not to be updated all at the same time, reducing the risk of introducing bugs for our clients all at the same time. Related: https://github.com/odoo/odoo/pull/278914 Forward-Port-Of: odoo/odoo#280317 Forward-Port-Of: odoo/odoo#278661
Original PR description
Currently all of our iot boxes are updated on mondays. This PR adds the dynamic selection of the update day of the week based on the rpi serial number. This allows our iot boxes not to be updated all at the same time, reducing the risk of introducing bugs for our clients all at the same time. Related: https://github.com/odoo/odoo/pull/278914 Forward-Port-Of: odoo/odoo#280317 Forward-Port-Of: odoo/odoo#278661
Steps to reproduce: 0. Link a Stripe terminal to a payment method and add the payment method to a kiosk pos.config 1. Select products and initiate payment 3. Stripe error - TypeError: Cannot set properties of undefined(setting 'stripecardpresentnetwork') Paymentline uiState is never initialized because pos_stripe/static/src/overrides/models/pos_payment.js is missing from the payment_terminals bundles and is therefore never loaded in kiosk mode. This commit ensures that the file is loaded
Original PR description
Steps to reproduce: 0. Link a Stripe terminal to a payment method and add the payment method to a kiosk pos.config 1. Select products and initiate payment 3. Stripe error - TypeError: Cannot set properties of undefined(setting 'stripecardpresentnetwork') Paymentline uiState is never initialized because pos_stripe/static/src/overrides/models/pos_payment.js is missing from the payment_terminals bundles and is therefore never loaded in kiosk mode. This commit ensures that the file is loaded and that the PosPayment setup() is completed. opw-6419140 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282049
Task: 6442237 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280219
Original PR description
Task: 6442237 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280219
12 changes
Enhancements to existing features
The employee payroll review field now defaults to reviewed instead of an empty state. This removes ambiguity in employee records and helps payroll teams work with a clearer, consistent review status.
Original PR description
Default the field to '1_reviewed' task-6470096
The appointment booking view now groups entries by guest automatically. This makes it easier for staff to review bookings per customer and quickly understand guest activity without manually changing the view.
Original PR description
Add default Group By Guest Task-id: 6253719
Belgian payroll calculations now include upcoming fiscal employment bonus rate changes starting in August 2026 and 2028. This helps payroll teams apply the correct tax reductions for low-wage workers and general employment bonus cases as legal rates change.
Original PR description
Starting from August 2026: - The increased fiscal rate for low-wage workers (Volet B) rises from 52.54% to 63% (and to 72% in 2028). - The general fiscal rate (Volet A) rises from 33.14% to 35% starting in 2028. This adds new rule parameters for the fiscal rates and updates computation logic to apply these rates Task-6438319 Forward-Port-Of: odoo/enterprise#126713
Budget report loading has been optimized by changing how budget lines are matched and grouped during report generation. This reduces long waits on larger databases, improving usability for teams reviewing budgets and analytic costs.
Original PR description
**Description:** While loading the budget report, the bad queries are created by ```def _get_aal_query()``` and ```def _get_pol_query()``` function, makes the budget report unusable. **Root cause:**…
**Description:**
While loading the budget report, the bad queries are created by
```def _get_aal_query()``` and ```def _get_pol_query()``` function, makes
the budget report unusable.
**Root cause:**
Instead of doing a hash join while searching the record,
the OR statement in the Left Join in the condition
```(%(bl)s IS NULL OR %(a)s = %(bl)s)```
creates a nested for loop that compares everything single aal to bl,
this causes a significant performance issue as the number of the
number of check will be the the number aal * bl,
if a database has a 70k aal and 20k bl, both numbers are not large
but it will cause a 70k * 20k search which is more than a billion.
**Fix**:
There are some refactors made in this PR.
_First_, separate out the Q1.
In order to find the aal that has no bl connects to it.
Doing a search to find the aals that have bl and then subtract them from all aals.
_Second_, Instead of doing a nested loop for by using
```(%(bl)s IS NULL OR %(a)s = %(bl)s)```,
originally we will have do something like
```
JOIN budget_line bl
ON (bl.x_plan2_id IS NULL OR aal.x_plan2_id = bl.x_plan2_id)
AND (bl.x_plan3_id IS NULL OR aal.x_plan3_id = bl.x_plan3_id)
AND (bl.x_plan4_id IS NULL OR aal.x_plan4_id = bl.x_plan4_id)
```
Assuming each bl has three plans ```x_plan2_id```, ```x_plan3_id```, ```x_plan4_id```
Grouping the bl base on whether a specific plan is set, (i.e. shapes)
we can skip the ```IS NULL OR``` because we already know which plan
is null and do the hash join directly.
For example, the shapes will be a dictionary with a key of a tuple of booleans
based on whether a plan is set or not and the value is a list of bl_id.
```
{
(True, False, False): [1, 2],
(False, True, True): [3, 4],
(False, False, False): [5],
}
```
we can end up doing something like
```
JOIN budget_line bl
ON bl.id = ANY(ARRAY[3,4])
AND aal.x_plan3_id = bl.x_plan3_id AND aal.x_plan4_id = bl.x_plan4_id
```
which is way more faster.
---
The benchmark is made locally from this client's database which contains
69k aal, 23k bl, 6829 pol and 3 plans for aal and bl.
|Record count |Time before|Time after|
|--------------------------------------------------|-----------------|---------------|
|69k aal, 23k bl, 6829 pol, 3 plans |70.04s |4.6s |
Dalibo:
Before:
Month-over-month grand total by company:
https://explain.dalibo.com/plan/8h3d4e89aaf9f3d4
Overall grand total by company:
https://explain.dalibo.com/plan/445g1f9caf4923e2
Month-over-month grand total by plan:
https://explain.dalibo.com/plan/53a138ca50b2a7c4
Overall grand total by plan:
https://explain.dalibo.com/plan/hdbe169ddc7g5785
After:
Month-over-month grand total by company:
https://explain.dalibo.com/plan/hcc86c801e6872bf
Overall grand total by company:
https://explain.dalibo.com/plan/69b2421a3581f98h
Month-over-month grand total by plan:
https://explain.dalibo.com/plan/a88f398bbbch3148
Overall grand total by plan:
https://explain.dalibo.com/plan/1gg749ae7ab1553c
opw-6345552
Forward-Port-Of: odoo/enterprise#127581
Forward-Port-Of: odoo/enterprise#124161The timesheet assistant now shows the specific Odoo record name when ActivityWatch sees a recognizable page URL, instead of only showing the broader app name. This makes suggested work activities easier to understand and select, improving timesheet accuracy with minimal user disruption.
Original PR description
Before this commit, when the ActivityWatch integration encountered unmatched Odoo URLs, it would fallback to displaying the general application name (e.g., "Working on Sales"). With this commit, if the URL path ends with a valid record ID (e.g., /odoo/departments/1) and the corresponding model can be identified, the assistant will attempt to fetch and display the actual record name (e.g., "Working on Research & Development"). task: 6365568 Forward-Port-Of: odoo/enterprise#124138
Meal voucher reports now calculate the total voucher value correctly when vouchers are postponed. This helps Belgian payroll teams produce more accurate reporting and reduces the risk of incorrect employee benefit amounts.
Original PR description
-Adjust the total value for meal voucher report in case of postponed meal vouchers.
Spreadsheet pivot tables can now include calculated fields based on SQL data, making reports more flexible and useful for analysis. This improves spreadsheet reporting by allowing users to work with more derived business metrics directly in pivot views.
Original PR description
Task: 6442237 Forward-Port-Of: odoo/enterprise#126645
Only the person who created a signature request can now change a signer’s email address. This helps prevent unauthorized or accidental recipient changes, improving trust and control in the signing process.
Original PR description
Forward-Port-Of: odoo/enterprise#127582 Forward-Port-Of: odoo/enterprise#126675
Currently all of our iot boxes are updated on mondays. This PR adds the dynamic selection of the update day of the week based on the rpi serial number. This allows our iot boxes not to be updated all at the same time, reducing the risk of introducing bugs for our clients all at the same time. Related: https://github.com/odoo/odoo/pull/278914 Forward-Port-Of: odoo/odoo#280317 Forward-Port-Of: odoo/odoo#278661
Original PR description
Currently all of our iot boxes are updated on mondays. This PR adds the dynamic selection of the update day of the week based on the rpi serial number. This allows our iot boxes not to be updated all at the same time, reducing the risk of introducing bugs for our clients all at the same time. Related: https://github.com/odoo/odoo/pull/278914 Forward-Port-Of: odoo/odoo#280317 Forward-Port-Of: odoo/odoo#278661
### [FIX] website: fix GMaps deprecation console warning for s_google_map Google deprecated the synchronous script loader for initializing the Maps JS API. This caused browser console warnings. The fix adopts Google's official `importLibrary()` bootstrap pattern, which loads map libraries (places, maps, marker) lazily on demand rather than all at once.The version is updated to `v=weekly`, which Google recommends as it receives updates weekly versus quarterly for version numbers(`v=num
Original PR description
### [FIX] website: fix GMaps deprecation console warning for s_google_map Google deprecated the synchronous script loader for initializing the Maps JS API. This caused browser console warnings. The…
### [FIX] website: fix GMaps deprecation console warning for s_google_map Google deprecated the synchronous script loader for initializing the Maps JS API. This caused browser console warnings. The fix adopts Google's official `importLibrary()` bootstrap pattern, which loads map libraries (places, maps, marker) lazily on demand rather than all at once.The version is updated to `v=weekly`, which Google recommends as it receives updates weekly versus quarterly for version numbers(`v=number`). Steps to reproduce: 1. Add the `s_google_map` snippet(not the`s_map`, enable debug mode) 2. Open the browser console and observe the deprecation warning ### [IMP] website: warn user to reload after GMaps config changes Switching from the legacy Google Maps APIs to the new APIs requires enabling additional services in Google Cloud. Existing maps using the legacy API continue to work, but when an admin edits a map without a proper configuration, the `GoogleMapAPIKeyDialog` dialog opens. Google Maps configuration changes (API key update or enabling services) do not take effect during the current editor session because the Maps JavaScript API is loaded at page initialization. Before this commit, such misconfigurations (disabled services or invalid API keys) only triggered a dialog showing a generic Google Maps error. After this commit, a notification informs the user that the page must be reloaded for configuration changes to take effect. The setup instructions are also updated to reference the "Places API (NEW)" service. ### [IMP] website: replace deprecated Places API calls in GPS picker The GPS picker relied on `PlacesService.nearbySearch` and `getDetails`, which are part of the deprecated Places API. The new places API replaces these with `Place.searchNearby` and `fetchFields`. Error handling is consolidated into a single try/catch since the new Places API throws on failure rather than returning a status code, removing the need for `PlacesServiceStatus` checks. ### [IMP] website, *: replace deprecated Google Autocomplete *: website_form_project google.maps.places.Autocomplete is deprecated in the new Places API. The replacement (`AutocompleteSuggestion.fetchAutocompleteSuggestions`) does not fire DOM events, making it incompatible with the old event-listener pattern used in GPSPicker. A new Owl component (`PlacesAutoComplete`) is introduced to wrap the new API, built on top of the existing `AutoCompleteWithPages`. References: https://developers.google.com/maps/documentation/javascript/load-maps-js-api https://developers.google.com/maps/documentation/javascript/advanced-markers/migration https://developers.google.com/maps/documentation/javascript/legacy/places-migration-overview task-[4441041](https://www.odoo.com/odoo/project/974/tasks/4441041) Forward-Port-Of: odoo/odoo#282027 Forward-Port-Of: odoo/odoo#242765
Steps to reproduce: 0. Link a Stripe terminal to a payment method and add the payment method to a kiosk pos.config 1. Select products and initiate payment 3. Stripe error - TypeError: Cannot set properties of undefined(setting 'stripecardpresentnetwork') Paymentline uiState is never initialized because pos_stripe/static/src/overrides/models/pos_payment.js is missing from the payment_terminals bundles and is therefore never loaded in kiosk mode. This commit ensures that the file is loaded
Original PR description
Steps to reproduce: 0. Link a Stripe terminal to a payment method and add the payment method to a kiosk pos.config 1. Select products and initiate payment 3. Stripe error - TypeError: Cannot set properties of undefined(setting 'stripecardpresentnetwork') Paymentline uiState is never initialized because pos_stripe/static/src/overrides/models/pos_payment.js is missing from the payment_terminals bundles and is therefore never loaded in kiosk mode. This commit ensures that the file is loaded and that the PosPayment setup() is completed. opw-6419140 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282049
Task: 6442237 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280219
Original PR description
Task: 6442237 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280219
3 changes
Enhancements to existing features
Before this commit: - Refund orders of scheduled (with shipping date) orders always generated a new picking with negative quantities, even when the original delivery had not been completed. - This could lead to incorrect stock movements and negative quantity computations for undelivered pickings. After this commit: - When processing a refund of a scheduled (with shipping date) order, the behavior now depends on the state of the original picking: - If the picking has already been del
Original PR description
Before this commit:
- Refund orders of scheduled (with shipping date) orders always generated a new picking with negative quantities, even when the original delivery had not been completed.
- This could lead to incorrect stock movements and negative quantity computations for undelivered pickings.
After this commit:
- When processing a refund of a scheduled (with shipping date) order, the behavior now depends on the state of the original picking:
- If the picking has already been delivered, a return picking is created with the corresponding negative quantities.
- If the picking has not been delivered, the original picking is updated instead:
- The picking is cancelled for a full refund.
- Refunded product moves are removed from the picking for a partial refund.
- This prevents unnecessary negative stock movements and ensures stock operations remain consistent with the delivery status.
Task-5902424
Forward-Port-Of: odoo/odoo#271506### [FIX] website: fix GMaps deprecation console warning for s_google_map Google deprecated the synchronous script loader for initializing the Maps JS API. This caused browser console warnings. The fix adopts Google's official `importLibrary()` bootstrap pattern, which loads map libraries (places, maps, marker) lazily on demand rather than all at once.The version is updated to `v=weekly`, which Google recommends as it receives updates weekly versus quarterly for version numbers(`v=num
Original PR description
### [FIX] website: fix GMaps deprecation console warning for s_google_map Google deprecated the synchronous script loader for initializing the Maps JS API. This caused browser console warnings. The…
### [FIX] website: fix GMaps deprecation console warning for s_google_map Google deprecated the synchronous script loader for initializing the Maps JS API. This caused browser console warnings. The fix adopts Google's official `importLibrary()` bootstrap pattern, which loads map libraries (places, maps, marker) lazily on demand rather than all at once.The version is updated to `v=weekly`, which Google recommends as it receives updates weekly versus quarterly for version numbers(`v=number`). Steps to reproduce: 1. Add the `s_google_map` snippet(not the`s_map`, enable debug mode) 2. Open the browser console and observe the deprecation warning ### [IMP] website: warn user to reload after GMaps config changes Switching from the legacy Google Maps APIs to the new APIs requires enabling additional services in Google Cloud. Existing maps using the legacy API continue to work, but when an admin edits a map without a proper configuration, the `GoogleMapAPIKeyDialog` dialog opens. Google Maps configuration changes (API key update or enabling services) do not take effect during the current editor session because the Maps JavaScript API is loaded at page initialization. Before this commit, such misconfigurations (disabled services or invalid API keys) only triggered a dialog showing a generic Google Maps error. After this commit, a notification informs the user that the page must be reloaded for configuration changes to take effect. The setup instructions are also updated to reference the "Places API (NEW)" service. ### [IMP] website: replace deprecated Places API calls in GPS picker The GPS picker relied on `PlacesService.nearbySearch` and `getDetails`, which are part of the deprecated Places API. The new places API replaces these with `Place.searchNearby` and `fetchFields`. Error handling is consolidated into a single try/catch since the new Places API throws on failure rather than returning a status code, removing the need for `PlacesServiceStatus` checks. ### [IMP] website, *: replace deprecated Google Autocomplete *: website_form_project google.maps.places.Autocomplete is deprecated in the new Places API. The replacement (`AutocompleteSuggestion.fetchAutocompleteSuggestions`) does not fire DOM events, making it incompatible with the old event-listener pattern used in GPSPicker. A new Owl component (`PlacesAutoComplete`) is introduced to wrap the new API, built on top of the existing `AutoCompleteWithPages`. References: https://developers.google.com/maps/documentation/javascript/load-maps-js-api https://developers.google.com/maps/documentation/javascript/advanced-markers/migration https://developers.google.com/maps/documentation/javascript/legacy/places-migration-overview task-[4441041](https://www.odoo.com/odoo/project/974/tasks/4441041) Forward-Port-Of: odoo/odoo#282027 Forward-Port-Of: odoo/odoo#242765
Steps to reproduce: 0. Link a Stripe terminal to a payment method and add the payment method to a kiosk pos.config 1. Select products and initiate payment 3. Stripe error - TypeError: Cannot set properties of undefined(setting 'stripecardpresentnetwork') Paymentline uiState is never initialized because pos_stripe/static/src/overrides/models/pos_payment.js is missing from the payment_terminals bundles and is therefore never loaded in kiosk mode. This commit ensures that the file is loaded
Original PR description
Steps to reproduce: 0. Link a Stripe terminal to a payment method and add the payment method to a kiosk pos.config 1. Select products and initiate payment 3. Stripe error - TypeError: Cannot set properties of undefined(setting 'stripecardpresentnetwork') Paymentline uiState is never initialized because pos_stripe/static/src/overrides/models/pos_payment.js is missing from the payment_terminals bundles and is therefore never loaded in kiosk mode. This commit ensures that the file is loaded and that the PosPayment setup() is completed. opw-6419140 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282049
3 changes
Enhancements to existing features
Spreadsheet pivot tables can now include SQL-based computed fields, giving users more ways to build custom analyses directly in spreadsheets. This improves reporting flexibility and helps teams extract more tailored insights without leaving the spreadsheet workflow.
Original PR description
Task: 6442237
Odoo Sign now limits changes to a signer's email address to the person who created the signing request. This helps prevent unintended or unauthorized recipient changes, improving control over who receives and signs documents.
Original PR description
Forward-Port-Of: odoo/enterprise#127582 Forward-Port-Of: odoo/enterprise#126675
Task: 6442237 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
Task: 6442237 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
2 changes
Enhancements to existing features
The Dutch payroll module now includes the 2026 resident income tax rates. This helps businesses calculate employee payroll taxes using the latest published values for the new tax year.
Original PR description
Added 2026 values for the residents' income tax rates rule parameter. task-6462877 Forward-Port-Of: odoo/enterprise#127556
Only the person who created a signature request can now change a signer’s email address. This helps prevent unintended or unauthorized recipient changes, improving control and trust in the signing process.
Original PR description
Forward-Port-Of: odoo/enterprise#127582 Forward-Port-Of: odoo/enterprise#126675
3 changes
Enhancements to existing features
Signer email addresses on signature requests can now only be changed by the person who created the request. This helps prevent unauthorized or unintended changes to recipients, improving trust and control in the signing process.
Original PR description
Forward-Port-Of: odoo/enterprise#126675
The Dutch payroll module now includes the 2026 income tax rates for residents. This helps payroll calculations stay aligned with upcoming Dutch tax requirements.
Original PR description
Added 2026 values for the residents' income tax rates rule parameter. task-6462877 Forward-Port-Of: odoo/enterprise#127556
The `create_calendar_meeting` field on `hr.leave.type` allows users to choose if leave requests created with a given time off type generate a corresponding entry in the Calendar app. However, this field was not displayed on the form view. This commit adds `create_calendar_meeting` to the `hr.leave.type` form view inside the configuration section, along with dedicated help text explaining its behavior. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
The `create_calendar_meeting` field on `hr.leave.type` allows users to choose if leave requests created with a given time off type generate a corresponding entry in the Calendar app. However, this field was not displayed on the form view. This commit adds `create_calendar_meeting` to the `hr.leave.type` form view inside the configuration section, along with dedicated help text explaining its behavior. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282242 Forward-Port-Of: odoo/odoo#280593
18 changes
Enhancements to existing features
The search view editor now hides fields that belong to the search panel from its suggestion list. This reduces confusion for users by only showing relevant fields when configuring search views.
Original PR description
The search view editor displays the fields from the search panel, which can be confusing for the user. This commit filter's out those fields from the autocompletion container. tasl-6366232
Belgian payroll salary rule categories for meal vouchers, representation fees, and private car reimbursements have been renamed to make their purpose clearer. This helps payroll users understand that these categories indicate eligibility, reducing confusion in configuration and reporting.
Original PR description
Meal Voucher, Representation Fees and Private Car Reimbursement categories were renamed from boolean fields and kept awkward, unclear names. Rename them to Meal Voucher Eligible, Representation Fees Eligible and Private Car Reimbursement Eligible. Task 6459956
Studio users can now choose which field is totaled in kanban views directly from the sidebar. This makes it easier to customize dashboards and boards without needing technical changes.
Original PR description
The `sum_field` cannot be set in kanban views through Studio. This commit exposes it as a new property in the sidebar. task-6366141
Spreadsheet dashboards across several business areas have been visually standardized so figures display with consistent sizing, spacing, and backgrounds. A new Employee appraisal dashboard has also been added, and translated dashboard text now displays correctly without being compressed.
Belgian payroll now alerts users when an employee's bank account is invalid. This helps payroll teams catch payment issues before processing salary payments, reducing failed transfers and manual follow-up.
Original PR description
This commit adds a warning message in the Belgian payroll module when an employee's bank account is invalid. task-6458596
Calendar events are now matched to projects or tasks using their direct “linked to” relationship before falling back to customer history. This makes suggested timesheets more accurate, especially when calendar meetings are tied to specific project or helpdesk work.
Original PR description
…ojects via the 'linked to' field Before this commit: - Calendar events are matched based on the most timesheet project of the partners. After this commit: - Calendar events are matched to projects/tasks via the "linked to field" before looking to partners projects. task-6238332
The timesheet Timeline view now displays assistant suggestions in true chronological order instead of sorting them by title. Users can also see each suggestion's start time, making it easier to review and enter work accurately.
Original PR description
Forward-Port-Of: odoo/enterprise#126238 Forward-Port-Of: odoo/enterprise#122862
Standard VAT checks are now available from the start across Odoo, reducing inconsistent behavior between setups. EU online VIES VAT checks are separated into an optional accounting-related module, making configuration cleaner for companies that need them.
Original PR description
Previously, both standard offline VAT validation and VIES VAT validation were implemented within a single module, `base_vat`. This led to several issues: 1. Since VIES depended on `account`, it made…
Previously, both standard offline VAT validation and VIES VAT validation were implemented within a single module, `base_vat`. This led to several issues: 1. Since VIES depended on `account`, it made it difficult to use even the standard VAT validation independently. 2. `base_vat` had to be explicitly added as a dependency in all localization modules (l10n), which was redundant because a single dependent module would install it globally anyway. 3. Standard VAT validation was not available from the start at a global level, leading to inconsistencies in validation behavior before and after module installation. With this PR: 1. The standard offline VAT validation is moved to `base`, making it available globally from the beginning. 2. The VIES VAT validation is separated into a new module, `l10n_eu_account_vies`. This module can be enabled via the `vat_check_vies` option in settings. task-5428948 Community PR - https://github.com/odoo/odoo/pull/259784 Upgrade PR - https://github.com/odoo/upgrade/pull/10014 IAP PR - https://github.com/odoo/iap-apps/pull/1609
The light user role now automatically includes a standard set of permissions for employees, including access to Planning, Appointments, and Referral features. This helps ensure employees receive consistent baseline access without extra manual setup.
Original PR description
Since there is a new light user role (and group) that will be set for each employee, this role must come with a package of privileges. Additional default groups are added to the light user: - Planning: User - Appointment: User - Refferal: User: Referral only See related Community PR for more details. Task-6112938
Payroll dashboard warnings now load through a single continuous request instead of many separate requests. This keeps warnings appearing as they are ready while reducing repeated server work, improving responsiveness and efficiency for users.
Original PR description
The dashboard warnings were loaded with multiple RPC calls (one per warning). The main issue with this behavior is the cache that stays cold => more queries are done for the same result at the end. Here we keep this behavior: see all warnings as soon as they are computed, on the dashboard, without blocking the user. But instead of the N rpc, there is one request, to get a stream of warnings. task-6422228
The time off Gantt view now keeps the full month visible for employees with flexible working schedules, making planning more stable and easier to read. New time off entries also avoid applying default hours that could overwrite an employee’s actual schedule.
Original PR description
- Display the full month for employees with flexible schedules to keep the month view stable. - Remove default hours from the creation payload to avoid overriding the employee's actual schedule. Task: 6346363
Belgian payroll users can now see Dimona information directly on the employee form when a Dimona environment is configured. Internal synchronization controls remain hidden in debug mode, so everyday users get the relevant information without exposing technical settings.
Original PR description
Dimona fields on the employee form were restricted to debug mode. Expose the Dimona group to standard users when a Dimona environment is configured, while keeping internal sync flags restricted to debug mode. Task: 6441891
AI agents now use Odoo's website scraping service to collect content from URL sources instead of relying on basic local page parsing. This should make URL-based knowledge more reliable, avoid duplicate fetching across agents, and better organize how different source types are indexed.
Original PR description
Move URL source content extraction to use the IAP website scraper instead of fetching and parsing pages naively. Introduce two new models to support this: `ai.web.page`, which stores the scraped content of a URL and is shared by every AI agent source pointing to that URL so a given URL is only ever fetched and stored once regardless of how many agents source it, and `ai.web.scraper.batch`, which submits URL batches to the scraper, polls for their results, and dispatches them back to the model that requested them once they reach a terminal state. The change also removes the local HTML extractor, adds the required cron and access rules, and adapts source creation/reprocessing so binary, knowledge, and URL sources each follow their own indexing flow. Knowledge sources' content extraction is now using html2plaintext. task-id-6052079
Financial reports now present company information more clearly, reduce clutter in report headers, and format negative currency amounts correctly. The depreciation schedule and multi-ledger PDF filters were also adjusted so reports are easier to read and avoid duplicate "Local GAAP" labels.
Original PR description
Before this commit: - The depreciation schedule report displayed the currency symbol. - Company details were positioned below the company logo. - Unit options (e.g., Thousands, Millions) were displayed in the top-right options header. - Selecting only "Local GAAP" in the multi-ledger filters caused it to appear twice in the generated PDF. - Negative amounts for currencies with a 'before' position (e.g., '$') were formatted incorrectly as "$ (1)". After this commit: - Removed the currency symbol from the depreciation schedule. - Relocated company details to the right side of the logo. - Removed unit options from the top-right header - Fixed the multi-ledger filter to ensure "Local GAAP" appears only once in the PDF. - corrected the negative amount formatting for 'before' position currencies to "($ 1)". Community PR: odoo/odoo#281909 Task-6113583
The Call Debrief view now makes better use of larger displays by showing video and transcription side by side when both are available. It also adjusts more smoothly in full-screen mode, making call review easier and more comfortable across devices.
Original PR description
This PR improves the Call Debrief experience across screen sizes and adapts the UI by: - Use a two-column layout on larger screens when both video and transcription are available. - Make the layout adapt correctly in full-screen mode. task-6328684 Requires: - https://github.com/odoo/odoo/pull/272719 Forward-Port-Of: odoo/enterprise#122029
Refused time off requests are now hidden from the Time step in payroll runs because they do not affect payroll calculations. This keeps the payroll review screen cleaner and helps payroll teams focus only on relevant absences.
Original PR description
Refused time off has no impact on the pay run, so there is no reason to keep showing it in that step. Exclude it from the action domain instead, so the request simply disappears once it is refused. task-6446029
The appraisal survey setup now shows placeholder text in the “Shared With” field. This small usability improvement helps users understand what information to enter when configuring survey sharing.
Original PR description
. Add a placeholder for Shared With field task-6439149
The Obox status widget now uses simple colored icons to show whether each connection type is available. This makes it easier for users to quickly understand websocket and local network connectivity at a glance.
Original PR description
We update the Obox status widget to only display icons with colors depending on wether the connection type is available. <img width="758" height="92" alt="image" src="https://github.com/user-attachments/assets/069962ee-a2b2-4c23-97d5-807b200e332a" />
1 change
Enhancements to existing features
The Dutch payroll module now includes the 2026 resident income tax rate values. This helps payroll calculations stay aligned with upcoming tax requirements for employees in the Netherlands.
Original PR description
Added 2026 values for the residents' income tax rates rule parameter. task-6462877 Forward-Port-Of: odoo/enterprise#127556
1 change
Enhancements to existing features
Allow resetting sent moves to draft. Ensures a rectificative flow exists or is created. Allow to create an empty rectificative report (if no more invoices to report after being reset to draft). Task: 6273211 Backport of https://github.com/odoo/odoo/commit/801051138621d884ca53324a1befb6de47d83306 This commit also makes minor changes that where done in the 18+ forward ports but not in the 18.0 branch itself (removing 'l10n_fr_pdp_bypass_draft_check' in tests and correcting one comment).
Original PR description
Allow resetting sent moves to draft. Ensures a rectificative flow exists or is created. Allow to create an empty rectificative report (if no more invoices to report after being reset to draft). Task: 6273211 Backport of https://github.com/odoo/odoo/commit/801051138621d884ca53324a1befb6de47d83306 This commit also makes minor changes that where done in the 18+ forward ports but not in the 18.0 branch itself (removing 'l10n_fr_pdp_bypass_draft_check' in tests and correcting one comment).