Daily updates from Odoo
Friday, August 7, 2026
222 changes
10 changes
Resolved issues and error corrections
The cohort report now calculates average retention based on the size of each cohort instead of treating all cohorts equally. This gives business users a more reliable view of overall retention, especially when comparing groups with very different numbers of records.
Original PR description
Steps to reproduce: - Open a retention cohort with cohorts of different sizes - Compare the average row with the overall retained population Issues: The average row gives every cohort the same weight. A cohort of one record at 0% retention and a cohort of nine records at 100% retention therefore displays 50% instead of 90%. Solution: Weight each cohort percentage by its initial cohort value. Forward-Port-Of: odoo/enterprise#126027
Event badge printing has been corrected so badges that include image fields no longer trigger an error. This helps event staff reliably print ESC/LABEL badges without disruption at registration or check-in.
Original PR description
Before this commit, some faulty logic in the `load_image` function caused a traceback when the ESC/LABEL badge template tried to use an image field. This bug only surfaced recently due to changes in how binary fields are accessed. After this commit, the logic is fixed and the traceback no longer occurs. task-6452486 Forward-Port-Of: odoo/enterprise#127017
Google Reserve availability responses now prevent open spots from exceeding total spots, even when appointment configurations are unusual or inconsistent. This avoids sending confusing availability data to Google and helps keep booking information reliable for customers.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
This fix ensures payroll worked-day calculations consider relevant inactive records instead of accidentally ignoring them. It helps prevent incorrect payslip results in cases where historical or archived payroll data is still needed for accurate computation.
Original PR description
Forward-Port-Of: odoo/enterprise#114877
This fixes an automated barcode batch picking flow so it waits for the first product quantity to update before moving to the next item. It helps prevent incorrect quantity splits in testing, reducing the risk of unreliable validation around warehouse picking workflows.
Original PR description
Problem: When scanning the first product, the second move line is clicked immediately after.…
Problem: When scanning the first product, the second move line is clicked immediately after. https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode_picking_batch/static/tests/tours/tour_test_barcode_batch_flows.js#L1529-L1541 If this happens before the first scan has finished, its quantity is incorrectly applied to the second move line that is clicked. This causes a 0 - 3 split instead of a 1 - 2 split, which results in there only being 6 move lines instead of 7. We updated our quantity on the `currentLine` https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode/static/src/models/barcode_model.js#L1478 When finding `currentLine`, we go through `_findLine` and use `this.selectedLineVirtualId`, which is the one that is currently selected in the UI https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode/static/src/models/barcode_model.js#L1705-L1712 Purpose: By adding this step, we wait until the first line’s quantity to be updated before it moves on and clicks on the second product. runbot-941211 Forward-Port-Of: odoo/enterprise#126847 Forward-Port-Of: odoo/enterprise#124162
The commission report now uses a simpler way to identify grouped report rows. This avoids unnecessary complex identifiers and helps keep commission reporting more reliable internally without changing how users work with the report.
Original PR description
Unlike achievement report ids, commission report ids do not need to identify source records. ROW_NUMBER() is enough to identify the grouped rows and avoids using string ids. Forward-Port-Of: odoo/enterprise#126851
Users can now regain access to shared Documents folders when they are re-invited after a previous invitation expired. This prevents misleading success messages and ensures portal users or groups are correctly restored to the access list.
Original PR description
Sharing a folder with a portal user with an expiration date cannot be done again after the access has expired. The sharing dialog reports success, but the user does not get access and is no longer…
Sharing a folder with a portal user with an expiration date cannot be done again after the access has expired. The sharing dialog reports success, but the user does not get access and is no longer listed. ### Steps to reproduce - In Documents, share a folder with a portal user and set an expiration date. - Wait until the expiration date has passed. - Share the same folder with the same user again from the invite box. => The dialog says the member was added, but the user has no access and does not appear under "People with access". ### Cause The invite box has no expiration field. When re-inviting a user, it updates the existing `documents.access` record and passes `None` for the expiration, which keeps the old `expiration_date`. If that date is already in the past, the user remains expired even though the invite reports success. ### Fix Pass `False` instead of `None` when inviting a member so the existing record's expiration date is cleared. Re-inviting an expired user now restores access. Setting an expiration from the "People with access" list is unchanged. opw-6387559 Forward-Port-Of: odoo/enterprise#127050 Forward-Port-Of: odoo/enterprise#125140
The timesheet leaderboard now correctly shows its helpful tip, which was previously hidden because of an internal argument handling issue. This makes the leaderboard guidance available to users as intended, improving clarity with minimal disruption.
Original PR description
The tip inside the timesheet leaderboard was never visible due to incorrect function arguments assignment. This commit fixes the issue. task-6448478 Forward-Port-Of: odoo/enterprise#126792
Task-6429727 Forward-Port-Of: odoo/odoo#280446 Forward-Port-Of: odoo/odoo#279204
Original PR description
Task-6429727 Forward-Port-Of: odoo/odoo#280446 Forward-Port-Of: odoo/odoo#279204
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens. To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here. runbot er
Original PR description
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens.
To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here.
runbot error-944120
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#28038414 changes
Enhancements to existing features
Receipt printers in Point of Sale IoT now use the same broader printer selection rules as preparation printers. This helps ensure eligible printers are available for receipt printing, reducing configuration friction for businesses using connected POS hardware.
Original PR description
In odoo/enterprise#124306, we removed the subtype from the printer domain, but only for preparation printers. We also update it for receipt printers. Forward-Port-Of: odoo/enterprise#127142 Forward-Port-Of: odoo/enterprise#125648
Resolved issues and error corrections
Google Reserve availability responses now prevent open spots from exceeding total spots, even when appointment settings are configured inconsistently. This avoids sending confusing or invalid availability data in rare edge cases.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
Fixed an issue in the timesheet grid where using Ctrl-click on a suggestion opened a new browser window instead of adding the suggestion to the form. This prevents accidental navigation and makes entering timesheets more reliable for users who use keyboard shortcuts.
Original PR description
Currently, when a user use ctrl + click on a suggestion, instead of adding it to the view form, it opens a new window. This is due to the default behavior when ctrl+click is used on a link. Using a button instead of an a href="#" solves this issue. Forward-Port-Of: odoo/enterprise#126240
The payroll payslip and pay run lists now always show the warnings column instead of hiding it behind an optional menu with a blank label. This removes a confusing interface issue and makes payroll warnings easier for users to notice.
Original PR description
Currently, in the payslip and payrun view, we can see empty label in optional dropdown. Having empty label isn't UX friendly. This empty label is refered to payslip warnings. In this PR expected to change visibility of warning fields, The visibility must be always visible and the field is no longer optional. This condition applies to PayRun and Paylist ListViews. task-6424657 Forward-Port-Of: odoo/enterprise#125860
A display issue in the Timesheet leaderboard has been fixed so users can now see the intended helpful tip. This improves guidance for employees using timesheets without changing their workflow.
Original PR description
The tip inside the timesheet leaderboard was never visible due to incorrect function arguments assignment. This commit fixes the issue. task-6448478 Forward-Port-Of: odoo/enterprise#126792
This update fixes an issue where a specific Swiss payroll value was not being properly recorded during ELM transmission processing. This helps ensure payroll transmission logs are more complete and reliable for audit and troubleshooting purposes.
Original PR description
Forward-Port-Of: odoo/enterprise#127241
Issue: The `shape_color_sync_with_theme_color` tour failed randomly at its last step i.e after changing a theme preset color, the image shapes of the saved (custom) snippet sometimes still had the old color. This happened because `updateContent` called its callback without awaiting it, so the re-processing of the custom snippet images ran in the background after the color change operation had already completed. At normal flow this operation finishes before the previews are looked at, but
Original PR description
Issue: The `shape_color_sync_with_theme_color` tour failed randomly at its last step i.e after changing a theme preset color, the image shapes of the saved (custom) snippet sometimes still had the old color. This happened because `updateContent` called its callback without awaiting it, so the re-processing of the custom snippet images ran in the background after the color change operation had already completed. At normal flow this operation finishes before the previews are looked at, but the tour reaches the `Custom` snippets category within milliseconds and could assert the colors before the re-processing was done - making the outcome depend purely on timing. Fix: Awaiting the callback ensures the custom snippets content is fully updated before the operation completes, so by the time the loading indicator disappears the previews are guaranteed to be in sync. runbot-[944175](https://runbot.odoo.com/odoo/error/944175) Forward-Port-Of: odoo/odoo#276862
Before this PR, the tour could fail non-deterministically because it waited for `o_we_ui_loading` to disappear. However, this class was added with a delay in `operation.js` file, allowing the next tour step to run before the loader was shown. After this PR, the tour waits for `o_loading_screen`, which is added immediately and remains until the operation finishes. This ensures the tour waits correctly before proceeding. runbot-[941508](https://runbot.odoo.com/odoo/error/941508) Forward-Por
Original PR description
Before this PR, the tour could fail non-deterministically because it waited for `o_we_ui_loading` to disappear. However, this class was added with a delay in `operation.js` file, allowing the next tour step to run before the loader was shown. After this PR, the tour waits for `o_loading_screen`, which is added immediately and remains until the operation finishes. This ensures the tour waits correctly before proceeding. runbot-[941508](https://runbot.odoo.com/odoo/error/941508) Forward-Port-Of: odoo/odoo#277869 Forward-Port-Of: odoo/odoo#277651
[*] = html_builder Steps to reproduce: 1. Go to the Website app and drop any snippet. 2. Apply a background or image shape. 3. If a background shape is applied, click the **Flip Shape** option. 4. Go to the **Theme** tab and change the color palette. Issue: The shape color is not updated after changing the color palette. Reason: In the [commit](https://github.com/odoo/odoo/commit/aec8918018b92cbb5cb3dd761824d4), an edge case was left uncovered where applied background/image shap
Original PR description
[*] = html_builder Steps to reproduce: 1. Go to the Website app and drop any snippet. 2. Apply a background or image shape. 3. If a background shape is applied, click the **Flip Shape** option. 4. Go to the **Theme** tab and change the color palette. Issue: The shape color is not updated after changing the color palette. Reason: In the [commit](https://github.com/odoo/odoo/commit/aec8918018b92cbb5cb3dd761824d4), an edge case was left uncovered where applied background/image shapes were not re-rendered after changing the theme color palette, so its color was not refreshed to match newly selected palette. Forward-Port-Of: odoo/odoo#278325 Forward-Port-Of: odoo/odoo#273337
### Current behavior: When exporting a quotation PDF from the Sales Order a multi-word product name, e.g. "Pick Up", is split into 2 lines ### Expected behavior: When exporting a quotation PDF from the Sales Order a multi-word product name, e.g. "Pick Up", should stay on a single line when there is enough horizontal space in the Description column ### Steps to reproduce: 1. Sales > new Sales Order 2. Add a product whose name has at least two words, e.g. "Pick Up" 3. Export the Sales O
Original PR description
### Current behavior: When exporting a quotation PDF from the Sales Order a multi-word product name, e.g. "Pick Up", is split into 2 lines ### Expected behavior: When exporting a quotation PDF from…
### Current behavior: When exporting a quotation PDF from the Sales Order a multi-word product name, e.g. "Pick Up", is split into 2 lines ### Expected behavior: When exporting a quotation PDF from the Sales Order a multi-word product name, e.g. "Pick Up", should stay on a single line when there is enough horizontal space in the Description column ### Steps to reproduce: 1. Sales > new Sales Order 2. Add a product whose name has at least two words, e.g. "Pick Up" 3. Export the Sales Order report to PDF 4. Observe the second word is pushed to a new line, even with free horizontal space ### Cause of the issue: Commit https://github.com/odoo/odoo/commit/6d695e53743a58560a00c163b3ac16ee1f149761 added a `d-flex` in 19.3 to keep product image and name on the same line. The `o_product_name_cell` uses default shrink wrap. Under wkhtmltopdf's old QtWebKit engine the shrink-wrapped width is computed marginally short of the real text width; this margin is font-metric dependent, so with the slightly wider font like Open Sans the last word crosses the boundary and wraps onto a new line, even though the surrounding cell has room. ### Fix: - Add the Bootstrap `flex-grow-1` utility class to the o_product_name_cell div so it grows to fill the remaining width of the flex row - The image keeps its fixed 48px width and stays on the same line - Small UI change, so no unit test. Only manual test: Before: <img width="357" height="211" alt="image" src="https://github.com/user-attachments/assets/29458867-c7d0-4cc8-8397-4c97b7a2b91d" /> After: <img width="342" height="196" alt="image" src="https://github.com/user-attachments/assets/9a1ca99c-916f-4179-b9b9-67879885e9d8" /> opw-6434410
Task-6429727 Forward-Port-Of: odoo/odoo#280446 Forward-Port-Of: odoo/odoo#279204
Original PR description
Task-6429727 Forward-Port-Of: odoo/odoo#280446 Forward-Port-Of: odoo/odoo#279204
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens. To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here. runbot er
Original PR description
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens.
To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here.
runbot error-944120
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#280384Since https://github.com/odoo/odoo/pull/239898 Opening a livechat session in debug mode as a user without livechat access throws a traceback: `Invalid props for component BadgeTag: onDelete is not a function` This happens because `null` is passed to the `onDelete` prop, while the component validation expects a function. This commit fixes the issue. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280910 Forward-Por
Original PR description
Since https://github.com/odoo/odoo/pull/239898 Opening a livechat session in debug mode as a user without livechat access throws a traceback: `Invalid props for component BadgeTag: onDelete is not a function` This happens because `null` is passed to the `onDelete` prop, while the component validation expects a function. This commit fixes the issue. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280910 Forward-Port-Of: odoo/odoo#280679
During the forward port of #278378, the dynamic NSI file path variable was overwritten by an old hardcoded one, breaking the IoT package build. Forward-Port-Of: odoo/odoo#280885
Original PR description
During the forward port of #278378, the dynamic NSI file path variable was overwritten by an old hardcoded one, breaking the IoT package build. Forward-Port-Of: odoo/odoo#280885
12 changes
Enhancements to existing features
This commit adds 3 new `Tax Exemption Reason Code`: - VATEX-FR-F - VATEX-FR-I - VATEX-FR-J task-6333649 Forward-Port-Of: odoo/odoo#280537 Forward-Port-Of: odoo/odoo#278086
Original PR description
This commit adds 3 new `Tax Exemption Reason Code`: - VATEX-FR-F - VATEX-FR-I - VATEX-FR-J task-6333649 Forward-Port-Of: odoo/odoo#280537 Forward-Port-Of: odoo/odoo#278086
Resolved issues and error corrections
A help tip in the timesheet leaderboard was not showing because of an internal setup error. This fix makes the tip visible again, helping users better understand the leaderboard information.
Original PR description
The tip inside the timesheet leaderboard was never visible due to incorrect function arguments assignment. This commit fixes the issue. task-6448478
This fix prevents a barcode batch picking test from moving to the next product before the first scanned quantity has finished updating. It helps ensure batch picking quantities are validated correctly and avoids intermittent failures caused by timing issues.
Original PR description
Problem: When scanning the first product, the second move line is clicked immediately after.…
Problem: When scanning the first product, the second move line is clicked immediately after. https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode_picking_batch/static/tests/tours/tour_test_barcode_batch_flows.js#L1529-L1541 If this happens before the first scan has finished, its quantity is incorrectly applied to the second move line that is clicked. This causes a 0 - 3 split instead of a 1 - 2 split, which results in there only being 6 move lines instead of 7. We updated our quantity on the `currentLine` https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode/static/src/models/barcode_model.js#L1478 When finding `currentLine`, we go through `_findLine` and use `this.selectedLineVirtualId`, which is the one that is currently selected in the UI https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode/static/src/models/barcode_model.js#L1705-L1712 Purpose: By adding this step, we wait until the first line’s quantity to be updated before it moves on and clicks on the second product. runbot-941211 Forward-Port-Of: odoo/enterprise#126847 Forward-Port-Of: odoo/enterprise#124162
Users can now disconnect a Belgian CodaBox connection using either the fidu password or a valid IAP token. This aligns the client with existing server support and reduces friction when revoking access.
Original PR description
The user should be able to revoke the CodaBox connection by either entering the fidu password or by using a valid iap_token. This was implemented in the iap server but not in the client side, after this commit the user should be able to either revoke by using the fidu password or by using the iap_token. task-6348433 Forward-Port-Of: odoo/enterprise#126698
Payroll list views now always show the warning column instead of hiding it behind an optional menu with a blank label. This removes a confusing interface issue and makes payslip or pay run warnings easier for users to notice.
Original PR description
Currently, in the payslip and payrun view, we can see empty label in optional dropdown. Having empty label isn't UX friendly. This empty label is refered to payslip warnings. In this PR expected to change visibility of warning fields, The visibility must be always visible and the field is no longer optional. This condition applies to PayRun and Paylist ListViews. task-6424657
This fixes payroll payslip calculations so worked day lines can correctly consider inactive or archived related records when needed. It helps prevent missing payroll information and supports more accurate payslip results in edge cases involving archived employee or contract data.
Google Reserve availability responses now prevent available spots from exceeding total spots, even when appointment capacity settings are inconsistent. This avoids sending confusing or invalid availability data for rare misconfigured appointment setups.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
Bank reconciliation now safely handles imported statement lines whose payment reference contains only spaces. This prevents an error during account matching and makes reconciliation more reliable for data brought in outside the standard user interface.
Original PR description
When reconciling bank statements with an account, the system will look for past statement lines already reconciled with that account and create a reconciliation model based on common substring in…
When reconciling bank statements with an account, the system will look for past statement lines already reconciled with that account and create a reconciliation model based on common substring in payment_ref. If this payment refs contains only spaces (eg. ' '), it will trigger an index out of range traceback. This is explained by the fact that spaces are striped then '' is considered as False in some filtering leaving the list empty. From the UI, putting ' ' is not supposed to be possible because spaces are striped before write but there is many ways to import statement lines which may lead to this hence the decision of handling this scenario to make the code more robust. Steps to reproduce: 1/ Create two statement lines with payment_ref as ' ' (you can force it using a write) 2/ Click "Set account" on first one and pick 100000 Issued Capital 3/ Do the same for the second statement line => Traceback In this commit, we do not check for common substring if there is less than two labels. opw-6379977 Forward-Port-Of: odoo/enterprise#125779
Task-6429727 Forward-Port-Of: odoo/odoo#279204
Original PR description
Task-6429727 Forward-Port-Of: odoo/odoo#279204
When there is no default confirmation template, An error is raised: AttributeError: 'bool' object has no attribute 'exists'. This happens because default_template is False, So calling default_template.exists() results in the error. The issue occurs during the upgrade process. ``` File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 3142, in _init_column value = field.default(self) File "/home/odoo/src/odoo/19.0/addons/website_sale/models/website.py", line 52, in _default_confi
Original PR description
When there is no default confirmation template,
An error is raised:
AttributeError: 'bool' object has no attribute 'exists'. This happens because default_template is False,
So calling default_template.exists() results in the error. The issue occurs during the upgrade process.
```
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 3142, in _init_column
value = field.default(self)
File "/home/odoo/src/odoo/19.0/addons/website_sale/models/website.py", line 52, in _default_confirmation_email_template
if default_template.exists():
AttributeError: 'bool' object has no attribute 'exists'
```
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#240874
Forward-Port-Of: odoo/odoo#237686After removing sale_order_many2one widget https://github.com/odoo/odoo/commit/0ecaa6e4c359681daf90c1757bcf71ba5e4d305c , there's no need for multiple sale_order_id definitions in the form view. In this commit, cleaning the redundant field definitions and restrict visibility of Sale Order smart button. task-4661781 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280740 Forward-Port-Of: odoo/odoo#255367
Original PR description
After removing sale_order_many2one widget https://github.com/odoo/odoo/commit/0ecaa6e4c359681daf90c1757bcf71ba5e4d305c , there's no need for multiple sale_order_id definitions in the form view. In this commit, cleaning the redundant field definitions and restrict visibility of Sale Order smart button. task-4661781 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280740 Forward-Port-Of: odoo/odoo#255367
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens. To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here. runbot er
Original PR description
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens.
To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here.
runbot error-944120
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#2803845 changes
Enhancements to existing features
Receipt printer setup now uses the same broader printer matching rules already applied to preparation printers. This helps point-of-sale teams select compatible IoT printers more consistently and reduces unnecessary configuration restrictions.
Original PR description
In odoo/enterprise#124306, we removed the subtype from the printer domain, but only for preparation printers. We also update it for receipt printers. Forward-Port-Of: odoo/enterprise#125648
Resolved issues and error corrections
Google Reserve availability responses now avoid reporting more open spots than total spots. This prevents confusing or invalid availability data in rare cases where appointment settings are configured inconsistently.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
Clicking an achievement in a commission plan no longer shows a missing record error. This fix ensures very large achievement identifiers are handled safely, so users can reliably open the related achievement records.
Original PR description
Steps to reproduce: - Open a commission plan - Go to its achievements - Click on an achievement Issues: A missing record error is shown. Achievement ids are sent to the client as strings to avoid truncating ids bigger than the JavaScript limit. When the client sends the string id back, we try to read `id_str` on a recordset whose id is still a string, which results in a missing record. Solution: Use the string id sent by the client directly from `self.id` and convert it to an integer before reading the achievement fields. A test with an id bigger than the JavaScript limit was added to ensure that the id is not truncated and that the related record can be opened.
This fixes an issue where the minimum income value was not being recorded during Swiss payroll ELM transmission processing. The change helps ensure payroll transmission records are complete and easier to audit or troubleshoot.
Original PR description
Forward-Port-Of: odoo/enterprise#127241
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens. To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here. runbot er
Original PR description
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens.
To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here.
runbot error-944120
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#2803844 changes
Enhancements to existing features
Receipt printer selection now follows the same broader matching rules already applied to preparation printers. This helps businesses connect compatible point-of-sale IoT printers more reliably without unnecessary filtering.
Original PR description
In odoo/enterprise#124306, we removed the subtype from the printer domain, but only for preparation printers. We also update it for receipt printers. Forward-Port-Of: odoo/enterprise#125648
Resolved issues and error corrections
Google Reserve availability responses now avoid reporting more open spots than total spots. This prevents confusing or invalid booking information when unusual appointment capacity settings are configured.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
The Shop Floor view now preserves the intended ordering of work orders after refreshes or filter changes. This prevents confusing reordering when teams view work orders by work center, keeping priorities based on status and scheduled start date consistent.
Original PR description
Records already in cache are intended to be sorted by their position in `recordCacheIds` to preserve the previously computed display order. However, `recordCacheIds` stores database record ids (`resId`), and currently the cache lookup incorrectly uses `id` instead. As a result, every lookup returns `-1`, and could lead to inconsistent ordering. Steps to reproduce: 1. Create several manufacturing orders with work orders assigned to the same work center. 2. Give the work orders different states and scheduled start dates. 3. Open Shop Floor and display that work center. 4. Refresh the view or change a filter so the records are recomputed. It should use `resId` so the previously computed display order remains, which is based on state and scheduled start date. Related: odoo/enterprise#74421 opw-6402233 Forward-Port-Of: odoo/enterprise#125928
This update fixes an issue where a required Swiss payroll value was not being recorded during ELM transmission processing. It helps ensure payroll transmission records are complete and easier to audit or troubleshoot.
Original PR description
Forward-Port-Of: odoo/enterprise#127241
5 changes
Enhancements to existing features
Receipt printer selection in Point of Sale now uses the same broader printer matching rules already applied to preparation printers. This helps ensure compatible IoT printers can be selected consistently, reducing setup friction for stores.
Original PR description
In odoo/enterprise#124306, we removed the subtype from the printer domain, but only for preparation printers. We also update it for receipt printers. Forward-Port-Of: odoo/enterprise#125648
Resolved issues and error corrections
The appointment Google Reserve integration now prevents availability responses from showing more open spots than total spots. This avoids misleading booking information in rare cases where appointment capacity settings are inconsistent.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
This fix keeps work orders in the Shop Floor view in the intended sequence after refreshes or filter changes. It prevents confusing reordering by preserving the display order based on work order status and scheduled start date.
Original PR description
Records already in cache are intended to be sorted by their position in `recordCacheIds` to preserve the previously computed display order. However, `recordCacheIds` stores database record ids (`resId`), and currently the cache lookup incorrectly uses `id` instead. As a result, every lookup returns `-1`, and could lead to inconsistent ordering. Steps to reproduce: 1. Create several manufacturing orders with work orders assigned to the same work center. 2. Give the work orders different states and scheduled start dates. 3. Open Shop Floor and display that work center. 4. Refresh the view or change a filter so the records are recomputed. It should use `resId` so the previously computed display order remains, which is based on state and scheduled start date. Related: odoo/enterprise#74421 opw-6402233 Forward-Port-Of: odoo/enterprise#125928
This fixes an issue where minimum income salary rule information was not being properly logged during Swiss payroll ELM transmission. The change improves payroll traceability and helps businesses maintain more complete records for Swiss payroll reporting.
Original PR description
Forward-Port-Of: odoo/enterprise#127241
MyInvois expects the CountrySubentityCode to be fixed as '17' for customers located outside Malaysia, since Malaysian state codes don't apply to them. Set it to '17' instead of the raw state name for non-Malaysian customers. task-6388521 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280556 Forward-Port-Of: odoo/odoo#280550
Original PR description
MyInvois expects the CountrySubentityCode to be fixed as '17' for customers located outside Malaysia, since Malaysian state codes don't apply to them. Set it to '17' instead of the raw state name for non-Malaysian customers. task-6388521 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280556 Forward-Port-Of: odoo/odoo#280550
36 changes
Enhancements to existing features
Belgian payroll now shows a warning when an employee has both private car kilometers and bike kilometers set for the same daily reimbursement context. This helps payroll teams spot combinations that cannot legally be reimbursed together without blocking their workflow.
Original PR description
Problem: Legally, the daily reimbursement of bike travel and private car travel cannot be cumulated. We don't want to prevent the user from doing so, but we still want to warn them. Solution: We added an explicit warning on the employee form using the `hr.payroll.warning` model. Task-6389211
Accounting-related automated tests were updated to match a platform change in how journal entry line descriptions are stored. This helps keep quality checks aligned with the latest accounting data model without changing business workflows.
Original PR description
This commit updates the HOOT tests to reflect the community change where the `account.move.line` `name` field has been converted from `Char` to `Text`. See the corresponding community commit for additional details. See Also: - https://github.com/odoo/odoo/pull/278081 - https://github.com/odoo/upgrade/pull/10909
The Mexico electronic invoicing payment method settings are now placed under the main Accounting menu. This aligns the enterprise menu with recent community changes, making the option easier to find in its expected location.
Original PR description
Move to the accounting root menu where it belongs. See also: - https://github.com/odoo/odoo/pull/280715
The signing app had an unused internal messaging setup removed. This cleanup reduces maintenance overhead without changing how users create or manage signature requests.
Original PR description
This commit removes a `useSubEnv` which defined a bus and is not used anymore.
This update adds automated checks for the POS IoT payment connection logic. It helps reduce the risk of payment terminal issues reaching customers by catching problems earlier during development.
Original PR description
We add tests for the `PaymentInterfaceIot` class.
The map view now uses the clicked item’s intended opening mode instead of guessing whether to open records in the current view, a new window, or a dialog. This makes interactions more consistent, reuses configured list and form views, and supports opening multiple records in a dialog when needed.
Original PR description
This is a follow-up of 75cac501edd, the controller no longer infers by itself whether a record should open in a dialog: the caller now passes an explicit target ('current', 'new_window' or 'dialog'), matching what the template already knows when a click comes from the unlocated records list.
Also reuse the list/form view ids defined on the action (same approach as the pivot view) instead of hardcoding false, and extend the dialog target to support opening several records at once.
task-6378012This update improves the reliability of automated tests by using a shared time-mocking helper across several Odoo Enterprise modules. It helps ensure date- and time-dependent test scenarios behave consistently, reducing false failures and supporting smoother quality checks.
Original PR description
Use the new function so that everything gets patched correctly. https://github.com/odoo/odoo/pull/280810
This update adds a sandbox mode for Belgian DMFA payroll declarations, allowing tests to simulate official reporting flows without affecting real submissions. It helps teams validate payroll accounting behavior more safely and reliably before production use.
Recruiters can now use the AI email composer when refusing an individual applicant, not just when handling multiple applicants. This makes it easier to draft and edit consistent, professional refusal messages in the single-applicant workflow.
Original PR description
…se wizard Refusing a single applicant now opens a dedicated wizard where the email body is rendered and editable. The mail_composer_chatgpt widget was only set up on the multi-applicant wizard, so it was missing there. Inherit the new applicant.refuse.single form to add the widget, mirroring what is already done for applicant.get.refuse.reason. task-6361850
This update adjusts Belgian payroll work entry settings so the right working schedules remain available when new schedule-selection data is used. It also removes a recently added restriction that could unnecessarily limit schedule choices for payroll users.
Original PR description
related PR adds a new field resource_calendar_selectable in the module hr_work_entry this PR updates/sets the value of this filed for some work entry types and reverts Task#6333928 that added a restrictive domain on working schedules. Task#6364149
The subscription portal now hides sections that do not contain any billable lines. This makes customer-facing pages clearer and avoids confusion from empty optional sections that looked like errors.
Original PR description
In portal, a section was always displayed even when it had no billed line. Empty sections (especially optional ones) gave the impression the page was bugged. Only show a section when it contains at least one line to bill. task-6280705
The salary contract update process was adjusted to use a cleaner data format when handling contract changes. This should make the flow more reliable and easier to maintain, including for Belgian payroll-specific handling.
The Belgian payroll rules now include the 2026 night work premium hourly rate for CP 200 employees. This helps payroll calculations stay aligned with the latest required rate for the upcoming year.
Original PR description
. Add cp_200_premium_pay_night_hourly_rate value for 2026 task-6443017
Belgian payroll now includes additional official reasons for ending an employee collaboration. This helps HR teams select the correct standardized reason when processing departures and improves alignment with Belgian reporting requirements.
Original PR description
Before ending the collaboration with employee in Belgium. We should put the reason behind the end of collaboration. There is given official list of end reason that can be used to explain it. Currently, In belgium localization, there are few missing reason. In this PR expected to add the missing reason from the offical form: - (1) end of contract due to notice given by the employer - (2) end of contract due to termination by the employer - (5) Force majeure because of the employee's permanent incapacity for work - (7) End of contract for fix-term employmen - (8) End of contract for specific work task-6396239
This update strengthens the automated checks around scheduled marketing campaign activity processing. It helps ensure background marketing actions run with the right settings and reduces the risk of future regressions as the feature is expanded.
Original PR description
Just quickly cover cron usage when executing activities, aka the other main marketing automation cron. Improve other tests about cron usage. Prepares Task-6425785 [marketing_automation] Incremental sync Prepares Task-3866422 [marketing_automation] Overhaul application
The Indian payroll module now uses clearer tooltip text for ESIC employee and employer contributions. The updated wording explicitly states the wage limits for regular employees and Persons with Disabilities, helping payroll users apply the rules with more confidence.
Original PR description
Clarify the ESIC employee and employer contribution tooltips by using clearer wording and explicitly mentioning the wage limits for regular employees and Persons with Disabilities (PwD). Task-6451829
Appointment pages now provide clearer placement information for floating content snippets. This helps ensure page elements are positioned more appropriately when editing appointment pages, improving consistency for website editors.
Original PR description
Community commit introduces a new plugin responsible for relocating floating snippets. In this commit we provide a scope that adds info of where the snippet can be on an appointment page. Community pr: https://github.com/odoo/odoo/pull/268301 task-6034130, task-5447310
Resolved issues and error corrections
The payroll pay run validation test now confirms the validation prompt before checking the result. This prevents automated checks from getting stuck and improves reliability of payroll quality testing.
Original PR description
The Validate button on the pay run payslip card carries confirm="Are you sure you want to proceed?", so clicking it opens a confirmation dialog instead of validating straight away. That confirm used to live only in hr_payroll_account, which is why only that module's tour patch clicks "Ok". 73a52f1c662 moved the attribute to the base hr_payroll view and dropped the hr_payroll_account override, but left the base tour clicking Validate and immediately asserting the payslip step is green. On builds where hr_payroll_account is not installed the modal stays open, the payslips stay draft, the pay run task-6449105
This update adds a missing module dependency so barcode quality checks work reliably with manufacturing barcode features. It prevents test failures and ensures the related components load together as expected, with no expected change to daily user workflows.
Original PR description
Before this commit, this bridge patches the barcode mrp model of stock_barcode_mrp while not depending on it. This goes unnoticed in the backend, where every installed module lands in the same bundle, but a Hoot test file only loads the modules of the dependency closure of its addon, so the first test suite added here dies on "error while registering suite". This commit adds the missing dependency. stock_barcode_mrp is auto installed on top of stock_barcode and mrp, both already required here, so it comes along with this module anyway.
The quality control spreadsheet tests were adjusted so they work consistently whether or not demo data is installed. This reduces false test failures and helps keep quality control spreadsheet features stable during development.
Original PR description
Commit [1], introduced through PR #122583, added tests for the quality spreadsheet selector and the session info insertion flag. These tests assumed that the template they created was the only quality spreadsheet template. This assumption does not hold when demo data is installed because the demo template remains after the test template is deleted. Consequently, the selector remains available and `can_insert_in_spreadsheet` remains true, causing the final assertions to fail. Remove existing quality spreadsheet templates at the beginning of each test so they fully control the template existence state. This makes the tests independent of demo data. The cleanup runs inside the test savepoint and is rolled back after each test. [1] https://github.com/odoo/enterprise/commit/ef3f2a2e4218d0ec8d83c2df2e8bdd518d41c7ca
Belgian payroll declarations now correctly treat non-equated time credit leave as having no reorganization measure. This prevents invalid ONSS declarations caused by reporting the wrong measure for affected employees.
Original PR description
According to the specifications, time credit not equated (LEAVE14713) should behave similarly to MEDIC01, but with one key exception: it must not trigger a reorganization measure. Previously, it was grouped with MEDIC01 in the DMFAOccupation initialization. This caused it to incorrectly evaluate to True and report a reorganization measure of 3 or 4 to the ONSS. This commit removes LEAVE14713 from that specific condition so it correctly falls through to the default block, assigning -1 (no measure) for the XML output, preventing invalid declarations. task-6431854
The timesheet assistant now highlights total hours correctly against expected working hours. It shows green when recorded time is below expected hours and avoids misleading coloring for flexible-hour schedules, helping users interpret their timesheet status more accurately.
Original PR description
Fix the wrong color selection of total hours on the timesheet assistant page before: green if total time > working hours after: - green if total time < working hours - no color for flexible hours --- task-6409938 Forward-Port-Of: odoo/enterprise#126484 Forward-Port-Of: odoo/enterprise#125177
The Vietnam reporting module now classifies short-term loan balances under held-to-maturity investments in line with Circular 99/2025. This helps businesses produce balance sheets that match current Vietnamese reporting requirements.
Original PR description
### Expected behavior: As per circular 99/2025, short-term loan (12831) balance is required to fall under Held to Maturity Investment (Code 123) instead of 112, translated: ``` Short-term held-to-maturity investments (Code 123): includes held-to-maturity investments with a remaining term of 12 months or less from the end of the accounting period, such as term deposits, bonds, commercial paper, loans, and other debt securities. This item does not include held-to-maturity investments that have been presented in the item “Cash equivalents” ``` ### Steps to reproduce: Install `l10n_vn_reports` module ### Fix: PO validated: Update the Balance Sheet code formula for the 12381 account opw-6413120 Forward-Port-Of: odoo/enterprise#126763
The Statement of Account option from the Malaysian reporting module is now shown and usable only for Malaysian companies. This prevents users in other countries from seeing or running a country-specific report that does not apply to them.
Original PR description
### Current behavior: After installing `l10n_my_reports`, the Malaysian's Statement of Account button appears on Aged Receivable for every company, and the partner Action "Print Statement of Account" can be run from non-MY companies ### Expected behavior: To avoid user confusion, it is advised to restrict its visibility so that it is only accessible to Malaysia-specific companies ### Steps to reproduce: 1. Install `l10n_my_reports` 2. Switch to a non-Malaysian company 3. Open Invoicing > Reporting > Aged Receivable 4. Observe the "Statement of Account" button on partner lines ### Cause of the issue: Missing checks for 'MY' company country code in UI and print report action ### Fix: - show the Aged Receivable SoA button only when `company_country_code === 'MY'` - guard `action_print_report_statement_account` for non-MY companies opw-6340854 Forward-Port-Of: odoo/enterprise#126597 Forward-Port-Of: odoo/enterprise#126172
Portal users editing Knowledge articles can now view and update existing voice transcription text without seeing the voice recording controls. This keeps the recording feature limited to internal users while preserving portal users' ability to work with article content.
Original PR description
Portal users can edit Knowledge articles but should not have access to the voice recording feature, which is reserved for internal users. The readonly component is already used in read-only views, so reusing it in the editor for portal users is safe, it still renders the existing transcription content correctly without exposing any recording controls. Portal users can still edit the text content inside the component thanks to the editable descendants concept, which allows the editor to manage specific editable areas even within a readonly component. Task-6320461 Forward-Port-Of: odoo/enterprise#126606
This fix restores a required loading component for public signing pages. It prevents automated user journeys and related signing interactions from failing, helping maintain a stable document signing experience.
Original PR description
The [linked community PR] retriggers clicks for interaction once they have started, using the existing lazyloader logic. [Commit 407903c] removed the lazyloader from the `sign.assets_public_sign` bundle. This new PR highlighted that removing it there caused several test tours to fail (within `sign` and other modules depending on it). [linked community PR]: https://github.com/odoo/odoo/pull/247404 [Commit 407903c]: https://github.com/odoo/enterprise/commit/407903cedca635a16929634afe41f489d3b56970 task-5221179
This fixes an issue where quickly clicking to expand the same financial report line could create duplicate hidden or visible rows and then stop the line from collapsing properly. Users can now expand and collapse report lines reliably, even on slow connections or with repeated clicks.
Original PR description
Steps to reproduce:- - Open any report. - Click on a particular line to unfold more than once very fast(or throttle network to 3G) - Once line is unfolded click again to fold that line. - Line is not…
Steps to reproduce:- - Open any report. - Click on a particular line to unfold more than once very fast(or throttle network to 3G) - Once line is unfolded click again to fold that line. - Line is not folding. Cause:- - When we clicked multiple times to unfold line, duplicate child lines were created(as many times as many times we clicked). - Because when first promise was not resolved so `unfolded = false` and we clicked again so new promise also tries to unfold the same line, resulting in unfolding the same line multiple times. - In version 17.0 these duplicate child lines are created but somehow not visible but it breaks `foldLine`. From version 18.0 onwards these duplicate child lines are visible. Solution: In `unfoldLine` set the flag `unfolding`. So in all clicks other than first, we get `unfolding = true` and don't proceed further, preventing unfolding the same line multiple times. task-6260425 Forward-Port-Of: odoo/enterprise#126765 Forward-Port-Of: odoo/enterprise#120392
This fixes an error that occurred when updating start or end contract dates for multiple Belgian payroll employees at once. HR teams and automated processes can now apply these date changes in batches without the operation failing.
Original PR description
Currently, attempting to update the `contract_date_start` or `contract_date_end` fields on a recordset containing multiple employees triggers a `ValueError: Expected singleton`.
Steps to reproduce:
1. Ensure the `l10n_be_hr_payroll` module is installed.
2. Attempt to execute `employees.write({'contract_date_start': '2026-01-01'})` where `employees` is a recordset of multiple employees.
3. Observe the `ValueError: Expected singleton` traceback.
task-6442141
task-6409893This fixes incorrect gender values in Belgian payroll demo employee records. It updates 23 employees and fills one missing value, improving the accuracy of payroll test/demo data.
Original PR description
Some records got the gender mixed when adding importing demo data. This fix solves the issue for 23 employees and add a gender for a employee with that field previously empty. related-6364398
Uploading a document from a contact now places it in the intended default area instead of reusing the last folder selected in Documents. This prevents files from being misplaced, such as contact uploads accidentally ending up in Finance.
Original PR description
Steps to reproduce ================== 1. Open Documents. 2. Select Finance. 3. Return to the home page and open the Contacts app. 4. Open any contact. 5. Click the Documents stat button. 6. Upload a document. Issue ===== The document is uploaded to the Finance folder instead of My Drive. Reason ====== When uploading a document using the upload button, we use `currentFolderAccessToken` to determine the destination folder. When opening the Documents view from a contact, `searchpanel_default_folder_id` is set to `False` so that documents are uploaded to the `All` workspace. However, when the search model is loaded, we do not reset `currentFolderAccessToken` when `folder_id` is `False`, causing the previously selected folder (Finance) to be reused. Task-6352242 Forward-Port-Of: odoo/enterprise#123285
Code cleanup and technical improvements
This update refreshes internal timing helper code to remove a deprecated dependency, keeping the system aligned with the newer OWL framework. It should not change day-to-day user behavior, but reduces future maintenance risk across several business apps.
Original PR description
- community: https://github.com/odoo/odoo/pull/279121 See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Knowledge app's properties panel was updated to use the newer interface expected by the platform. This keeps the panel behavior stable during future upgrades while preserving the existing user experience.
Original PR description
Replaced `useLayoutEffect` with `useEffect` (from `@odoo/owl`) because `useLayoutEffect` is deprecated in OWL3. `useEffect` was chosen as the replacement because the original effect reacted to…
Replaced `useLayoutEffect` with `useEffect` (from `@odoo/owl`) because `useLayoutEffect` is deprecated in OWL3. `useEffect` was chosen as the replacement because the original effect reacted to dependency changes (`this.props.record.resId` and `this.hasProperties`) — pattern 3 in the OWL3 migration guide. A `void this.props.record.resId;` statement was added at the top of the callback to subscribe to the plain prop dep that is not auto-tracked. The `useLayoutEffect` refactored in this PR has test coverage — below are some tests that failed when the effect was commented out: - @knowledge/options_dropdown/Toggle Properties Panel (desktop) - @knowledge/options_dropdown/Toggle Properties Panel (Mobile) see commented-out runbot build: https://runbot.odoo.com/runbot/batch/2596677/build/114854261 Note: `useEffect` runs asynchronously after paint, whereas `useLayoutEffect` ran synchronously after DOM mutations. The properties panel visibility logic may require synchronous updates; post-merge monitoring of the knowledge test suite is advised.
The Gantt view was updated as part of Odoo's move to the newer Owl framework. This is an internal modernization that helps keep planning views reliable and ready for future platform changes, with no expected change for day-to-day users.
Original PR description
As part of the Owl 3 migration, replace onWillUpdateProps hook with the appropriate Owl 3 alternatives. `Why use bus ?` Replaces `onWillUpdateProps(this.computeDerivedParams)`. The model isn't reactive, so we recompute the derived state on its synchronous "update" event. This ensures it's ready before the next render. Effects run too late.
This update modernizes how several Odoo screens refresh their interface content, removing an outdated internal mechanism. It helps keep dropdowns and embedded editor components more reliable and easier to maintain without changing day-to-day workflows.
Original PR description
- community: https://github.com/odoo/odoo/pull/276842 See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Web Studio’s automated tests were updated to align with the newer Owl 3 framework. This is an internal maintenance change that helps keep future development and upgrades stable without changing day-to-day user behavior.
Original PR description
As part of the Owl 3 migration, replace deprecated onWillRender hooks with the appropriate Owl 3 alternatives. Community: https://github.com/odoo/odoo/pull/280936
The Knowledge calendar view was updated to use a newer underlying approach that remains compatible with the next version of Odoo's interface framework. A new automated test was added to help ensure this calendar behavior continues to work correctly.
Original PR description
Replaced `useLayoutEffect` with `useEffect` because `useLayoutEffect` is deprecated in OWL3. The useLayoutEffect refactored in this PR had NO test coverage, see commented-out runbot build: https://runbot.odoo.com/runbot/batch/2596755/build/114855786 In this case I wrote a test to make sure the refactoring works (also tested in UI) community PR: https://github.com/odoo/odoo/pull/281002
9 changes
Enhancements to existing features
Receipt printer selection in Point of Sale IoT now matches the broader printer filtering already used for preparation printers. This helps businesses use eligible printers more consistently without being limited by an overly specific printer type setting.
Original PR description
In odoo/enterprise#124306, we removed the subtype from the printer domain, but only for preparation printers. We also update it for receipt printers. Forward-Port-Of: odoo/enterprise#125648
Vendor bill product suggestions based on line labels now respect the setting that enables or disables this feature. This prevents unwanted suggestions for businesses that turned the option off, while keeping the default behavior for community users.
Original PR description
Context: There was an enterprise field `predict_bill_product` allowing users to toggle product prediction based on line label. Before this commit, product prediction by name was running without taking into account the value of this field, which could confuse users who had disabled the feature in settings. This commit makes product prediction by name depend on this field. For community users, the prediction will run by default. no-task --- I confirm I have signed the CLA and read the PR guidelines at [www.odoo.com/submit-pr](http://www.odoo.com/submit-pr)
Resolved issues and error corrections
This fixes an error that could occur in the Kenya OSCU stock integration when a confirmed delivery product was later converted into a kit. Deliveries now continue using the actual component moves, avoiding interruptions during stock processing.
Original PR description
When a stock move's product is turned into a kit after the transfer was confirmed, it explodes it into its component moves and unlinks the original one: https://github.com/odoo/odoo/blob/f59783d43f891fea14d03f67d7c017d7ffbbe5a7/addons/mrp/models/stock_move.py#L358-L363 https://github.com/odoo/odoo/blob/f59783d43f891fea14d03f67d7c017d7ffbbe5a7/addons/mrp/models/stock_move.py#L400 The `_action_done()` override of `l10n_ke_edi_oscu` localisation called `super()` first and then used `self.filtered(...)` on the pre-explosion recordset, which could still reference the now-deleted move, raising a `MissingError`: https://github.com/odoo/enterprise/blob/ee7e6894ed313db844aeff5ba5e19de3ad94898e/l10n_ke_edi_oscu_stock/models/stock_move.py#L96-L99 Use the `super()` return value instead, which reflects the moves that were actually processed. runbot-243291
Australian payroll data updates now include salary rule categories, preventing update jobs from failing when new categories are added. This helps payroll maintenance run more reliably without manual intervention.
Original PR description
ir_cron_update_payroll_data updates the payroll data including rules but fails if a new rule category is introduced. This commit adds the hr_salary_rule_category_data file to the list of data files to update. task-6351929
This update prevents approval requests from trying to send notifications while a temporary form preview is being recalculated. It avoids crashes when approval records are linked through Studio fields, especially for approved or refused requests, making form editing more reliable.
Original PR description
**Before this change** We have the potential to attempt to send a notification email from virtual records created by our `BaseModel.new()` method. This can happen during an `onchange` request, given…
**Before this change** We have the potential to attempt to send a notification email from virtual records created by our `BaseModel.new()` method. This can happen during an `onchange` request, given that we'll be working with a virtual "snapshot" record to recompute potentially changed values for our origin record after a change to one or more values. This issue manifests when using Studio to attach a many2many field to a form view, where the related model is "Approval Request". If an approval request record in either the "Approved" or "Refused" state is attached to our record via this new Studio field, any `onchange` requests will trigger this bug. This is because we can't send messages on a virtual record. **After this change** Prevent the creation and sending of a message if we are computing the request status of a virtual `approval.request()` record. The field `request_status` on this model is computed and stored, but the fact that it is a computed field means that it must be recomputed for a virtual record, even if the origin record already has a stored `request_status`. Thus, we may need to compute a `request_status` value for an ephemeral "snapshot" record. Though the issue only manifests for the "Approved" and "Refused" states, this PR expands on a test that covers every approval request state. opw-6390453 Forward-Port-Of: odoo/enterprise#125374
Rejection notification emails now show the name of the person who declined to sign, rather than the email recipient's name. This prevents confusion for teams tracking who rejected a document and keeps signing communications accurate.
Original PR description
**Description of the issue/feature this PR addresses:** When a document is rejected by a signer, the notification email sent to other involved parties incorrectly displays the recipient's name in the…
**Description of the issue/feature this PR addresses:** When a document is rejected by a signer, the notification email sent to other involved parties incorrectly displays the recipient's name in the subject line instead of the person who actually refused to sign. This occurs because the subject string was using `partner.name` (the current email recipient) instead of `refuser.name`. This commit updates the string to reference the refuser, ensuring the subject accurately identifies the individual who rejected the document. **Steps to reproduce:** - Sign > upload any PDF > add signature request for 2 different signers > Send > choose signers, e.g. Abigail Carter and Marc Demo > Send - Settings > Technical > Emails > Emails - Select one of the sent emails > Sign document > sign > Validate & Send Completed Document - Select the other email > Sign document > top-right dropdown arrow > Decline to sign > Decline - Settings > Technical > Emails > Emails - Observe that all emails sent state that the recipient of the email rejected the signing **Current behavior before PR:** - Rejection email subject states that the recipient refused to sign **Desired behavior after PR is merged:** - Rejection email subject states that the refuser refused to sign opw-6421188
Batch picking test steps now wait for the first product quantity to update before moving to the next item. This prevents quantities from being assigned to the wrong line during rapid barcode scanning, helping ensure picking results remain accurate.
Original PR description
Problem: When scanning the first product, the second move line is clicked immediately after.…
Problem: When scanning the first product, the second move line is clicked immediately after. https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode_picking_batch/static/tests/tours/tour_test_barcode_batch_flows.js#L1529-L1541 If this happens before the first scan has finished, its quantity is incorrectly applied to the second move line that is clicked. This causes a 0 - 3 split instead of a 1 - 2 split, which results in there only being 6 move lines instead of 7. We updated our quantity on the `currentLine` https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode/static/src/models/barcode_model.js#L1478 When finding `currentLine`, we go through `_findLine` and use `this.selectedLineVirtualId`, which is the one that is currently selected in the UI https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode/static/src/models/barcode_model.js#L1705-L1712 Purpose: By adding this step, we wait until the first line’s quantity to be updated before it moves on and clicks on the second product. runbot-941211 Forward-Port-Of: odoo/enterprise#126847 Forward-Port-Of: odoo/enterprise#124162
The fix ensures Google Reserve never receives more open booking spots than the total spots available. This avoids confusing availability data in rare cases where appointment resources are configured inconsistently.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
The IoT device list now opens device details using the standard navigation behavior, which restores pagination after it was disrupted by a previous change. This helps users browse and manage longer device lists reliably without getting stuck or seeing incorrect page behavior.
Original PR description
Since #72351, the pagination on IoT devices was broken due to how we were getting to the full device form when clicking on a record. We now change the override to use the existing method from the framework `switchToForm` which handles it better. opw-6058532 Forward-Port-Of: odoo/enterprise#126486
3 changes
Resolved issues and error corrections
The Romanian National Bank exchange rate feed now uses the new official subdomain required from August 2026. This keeps automatic currency rate updates working without interruption when the old web address stops serving these XML files.
Original PR description
As of 6 August 2026, the XML files used by software applications to retrieve daily exchange rates will no longer be available directly through addresses on the www.bnr.ro domain and will be accessible exclusively via the curs.bnr.ro subdomain. The XML file names will remain unchanged; only the access domain will be modified. no-task
This update corrects an issue in Swiss payroll ELM transmission where the minimum income subject to social insurance was not being recorded properly. It helps ensure payroll transmission logs contain the expected information for review and compliance checks.
Original PR description
Forward-Port-Of: odoo/enterprise#127241
Sometimes the default_state remains in the context from a past action and when the subcontractor fills its components consumptions it will directly modify the quant's quantity. This trigger the automatic rules and generate an unwanted picking opw-6109661 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:
Original PR description
Sometimes the default_state remains in the context from a past action and when the subcontractor fills its components consumptions it will directly modify the quant's quantity. This trigger the automatic rules and generate an unwanted picking opw-6109661 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#280733
2 changes
Resolved issues and error corrections
This update corrects how minimum insured salary information is recorded during Swiss payroll ELM transmissions. It helps ensure payroll transmission logs are complete and accurate for review and compliance purposes.
When stock is installed, the default routes of a warehouse include a rule that does Vendor -> Stock. However, once purchase is installed, that rule is removed and replaced by a 'buy' rule, that requires a vendor set on the product to trigger correctly. So when `test_orderpoint_activity_portal_context_leak` ran without purchase installed, it would find an applicable rule to run the orderpoint and would not trigger a ProcurementException, and thus no activity on the product. runbot-941316
Original PR description
When stock is installed, the default routes of a warehouse include a rule that does Vendor -> Stock. However, once purchase is installed, that rule is removed and replaced by a 'buy' rule, that requires a vendor set on the product to trigger correctly. So when `test_orderpoint_activity_portal_context_leak` ran without purchase installed, it would find an applicable rule to run the orderpoint and would not trigger a ProcurementException, and thus no activity on the product. runbot-941316 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr