Daily updates from Odoo
Tuesday, August 4, 2026
266 changes
14 changes
Enhancements to existing features
The recurring donation product now has a placeholder image, making it appear more polished and recognizable in the online store. This improves the presentation of donation options for website visitors without changing how donations work.
Original PR description
Added placeholder image for the recurring donation product. task-6361612
Resolved issues and error corrections
The timesheet assistant now keeps the suggestions aligned with the latest date selected, even when users click through dates quickly. This prevents outdated information from appearing and helps users enter timesheets with more confidence.
Original PR description
Before this commit, when the user hits multiple times the arrow button to change the date displayed in timesheet assistant, the suggestions displayed could be the suggestions from another day because a rpc is made each time the user changes the date and amoung all rpcs call, the one which takes more time then the one will be taken but it is not necessary the date shown in the view. This commit uses `KeepLast` class to avoid the concurrency issue with those rpcs to be able to always take the last rpc call to get the data. Forward-Port-Of: odoo/enterprise#126323 Forward-Port-Of: odoo/enterprise#126283
Date and datetime fields are now removed from the column selection popover once they have been added, just like other fields. This prevents users from accidentally adding the same date column multiple times, avoiding duplicate identifiers and inconsistent spreadsheet behavior.
Original PR description
Current behavior before PR: - Date and datetime fields remained visible in the popover after being added as columns, allowing the same field to be added multiple times. - Since column fields do not consider granularity, allowing duplicate date fields could create duplicate IDs and inconsistent behavior. Desired behavior after PR is merged: - Treat date and datetime fields the same as other column fields when determining which fields to display in the popover. - Once a date or datetime field is added as a column, it is no longer shown in the popover to prevent duplicate IDs. Task: [6295794](https://www.odoo.com/odoo/project/2328/tasks/6295794) Forward-Port-Of: odoo/enterprise#123463
Regular invoicing users can now post invoices or reset them to draft when Avalara tax integration is enabled. This prevents an unnecessary admin-only restriction from blocking standard billing workflows.
Original PR description
The field `avalara_connection_method` has a restriction to only admins, but needs to be read by normal invoicing users in order to post or reset invoices to draft. Forward-Port-Of: odoo/enterprise#126464
Fixes an issue in Hong Kong payroll where creating a payslip could fail when the selected employee had no contract start date. Payroll users can now select those employees without interruption, while existing payslip handling covers the missing date case.
Original PR description
Currently, an error occurs when a user sets an employee on a payslip. **Steps to Reproduce:** - Install `l10n_hk_hr_payroll` with demo data. - Switch to the `Hong Kong` company. - Create an…
Currently, an error occurs when a user sets an employee on a payslip. **Steps to Reproduce:** - Install `l10n_hk_hr_payroll` with demo data. - Switch to the `Hong Kong` company. - Create an `employee` and make sure that the employee's version has no `contract start date`. - Go to `Payroll` > `Payslips` > `Payslips`. - Create a `payslip` and set that employee. `TypeError: '<' not supported between instances of 'datetime.date' and 'bool'` When a user sets an employee on a payslip, the system computes the worked day lines [1]. If the salary structure uses worked day lines, it creates the corresponding records [2] and calculates out days and out hours based on the contract dates. During this process, the payslip dates are compared with the version's contract start date. If the version does not have a contract start date, it raises an error [3]. This commit ensures that the payslip dates are compared with the version's contract start date, and that out days and out hours are calculated only when the contract start date exists. Cases where no contract start date is defined are already handled in payslip [4]. [1]: https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1964 [2]: https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1985-L1988 [3]- https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/l10n_hk_hr_payroll/models/hr_payslip.py#L309 [4]- https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1092-L1096 sentry-7632216317 Forward-Port-Of: odoo/enterprise#120234
The Argentina electronic invoicing test setup was adjusted so live currency rate checks no longer run in daily builds that block external web requests. This keeps routine build results stable while still allowing the test to run in nightly checks with the right access.
Original PR description
Description of the issue this commit addresses: The live ARCA currency rate test keeps the inherited `standard` tag. It is therefore selected by daily builds whose HTTP guard blocks the request. The guard also blocks it when selected by the external localization suite. --- Desired behavior after this commit is merged: This commit removes the `standard` tag from the live ARCA test. Daily builds skip the test while nightlies still run it with HTTP access. --- runbot-[238857](https://runbot.odoo.com/odoo/error/238857) Forward-Port-Of: odoo/enterprise#125692
The Documents kanban view now keeps the favorite star aligned correctly after a shared spacing change affected its position. This preserves a polished and consistent visual experience for users managing documents.
Original PR description
The favorite icon in the Documents kanban view became misaligned after the `me-1` spacing class was removed from the generic favorite field widget in PR https://github.com/odoo/odoo/pull/250051. Apply the equivalent spacing in the Documents kanban view styles to preserve the icon alignment. Task-6326435 Forward-Port-Of: odoo/enterprise#124039
A small issue in the accounting journal report was corrected so line actions behave as intended. This helps users avoid confusion when working with journal report details, with no broader workflow changes expected.
Original PR description
Forward-Port-Of: odoo/enterprise#126603 Forward-Port-Of: odoo/enterprise#125266
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user (Set Accounting to No) 2- Open Contacts app 3- Try importing contacts (you can download the available template and use it as the file you are asked to upload) 4- Test the import 5- Notice the error you receive Cause: When importing contacts, the commercial fields (fields related to the co
Original PR description
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user…
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user (Set Accounting to No) 2- Open Contacts app 3- Try importing contacts (you can download the available template and use it as the file you are asked to upload) 4- Test the import 5- Notice the error you receive Cause: When importing contacts, the commercial fields (fields related to the contact's parent) are loaded and then written. Some of these fields may have access rights that the user trying to import doesn't have. As a result, when trying to load/write them, the user may get an error. Solution: Use sudo() when loading them. This shouldn't be an issue since they are only copied from the parent. Also, sudo() is already being used when writing the values, https://github.com/odoo/odoo/blob/bb94f13b38f0bf1ce8886f4630ad42caf6c56325/odoo/addons/base/models/res_partner.py#L996 so sudo() should also be used when loading them. opw-6396086 Forward-Port-Of: odoo/odoo#278638
In POS receipt and invoice during a B2C transaction, if the vat number was not set/ wrong, QR code was generated. This commit removes the qr code generation when the invoice is in rejected state. Also, in 19.2 in POS we displayed errors after pressing the validation button, this commit brings it back. task-6237427 Forward-Port-Of: odoo/odoo#273707
Original PR description
In POS receipt and invoice during a B2C transaction, if the vat number was not set/ wrong, QR code was generated. This commit removes the qr code generation when the invoice is in rejected state. Also, in 19.2 in POS we displayed errors after pressing the validation button, this commit brings it back. task-6237427 Forward-Port-Of: odoo/odoo#273707
When an internal recipient receives an Out of Office (OOO) notification, the resulting `mail.message` record has `partner_ids` populated with the recipient partner ID, while `outgoing_email_to` is set to `False`. When a second internal user emails the OOO user within the 4-day window, `_notify_thread_with_out_of_office` excutes a search domain with an OR condition: `'|', ('partner_ids', 'in', recipient.ids), ('outgoing_email_to', '=', email_to)` Because `email_to` is `False` for internal p
Original PR description
When an internal recipient receives an Out of Office (OOO) notification, the resulting `mail.message` record has `partner_ids` populated with the recipient partner ID, while `outgoing_email_to` is…
When an internal recipient receives an Out of Office (OOO) notification, the resulting `mail.message` record has `partner_ids` populated with the recipient partner ID, while `outgoing_email_to` is set to `False`.
When a second internal user emails the OOO user within the 4-day window, `_notify_thread_with_out_of_office` excutes a search domain with an OR condition: `'|', ('partner_ids', 'in', recipient.ids), ('outgoing_email_to', '=', email_to)`
Because `email_to` is `False` for internal partners, `('outgoing_email_to', '=', False)` evaluated to `True` against the first recipient's message record. Consequently, the search falsely determined that the second recipient was already notified, suppressing OOO replies for all subsequent contacts across the 4-day window.
## Proposed solution:
We resolve this by dynamically constructing recipient sub-domains conditionally depending if `recipient` or `email_to` are set.
We also extend `test_routing_with_out_of_office` with a corresponding test case.
## How to reproduce:
1. Set up a DB with at least 3 users (User A, User B, User C).
2. Configure User A to be out of office (in user preferences)
3. Go to any chatter/mail.thread while logged as User B and tag User A in a log note. -> triggers OOO message
4. Log as User C, tag User A in a log note. -> BUG: no OOO message because the "4 day" check falsely believes that User C already received a OOO from User A
OPW-6110300
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#279881
Forward-Port-Of: odoo/odoo#277880Steps to reproduce ------------------ 1. Set two receipt printers on the PoS and open it. 2. From another tab, remove one of the printers and save. -> the open PoS still shows the old printers. It only updates after "reload data" or reopening the session. Why the issue ------------- The open PoS keeps the printer list it loaded at the start. A normal refresh does not fetch the config again (the PoS reads its local copy), so a printer change from another tab is not seen until the data
Original PR description
Steps to reproduce ------------------ 1. Set two receipt printers on the PoS and open it. 2. From another tab, remove one of the printers and save. -> the open PoS still shows the old printers. It only updates after "reload data" or reopening the session. Why the issue ------------- The open PoS keeps the printer list it loaded at the start. A normal refresh does not fetch the config again (the PoS reads its local copy), so a printer change from another tab is not seen until the data is reloaded. The fix ------- When the receipt or preparation printers change on the config, we send a notification to the open PoS sessions with the new printers. The PoS updates its printer list on the spot, without needing to reloade any ohter data. opw-6351006
Before this commit: ===================== floating orders could show the same order number twice on the POS receipt: once through the floating order name and once through the tracking number. This happened because the floating order name defaults to the tracking number until a cashier manually sets a custom name. After this commit: =================== The receipt only displays the floating order name when it differs from the tracking number. Task-6394222 Forward-Port-Of: odoo/odoo#277
Original PR description
Before this commit: ===================== floating orders could show the same order number twice on the POS receipt: once through the floating order name and once through the tracking number. This happened because the floating order name defaults to the tracking number until a cashier manually sets a custom name. After this commit: =================== The receipt only displays the floating order name when it differs from the tracking number. Task-6394222 Forward-Port-Of: odoo/odoo#277492
Steps to reproduce: ------------------- 1. Install hr_holidays. 2. Create a new Time Off Type with "Duration type" set to Hours. 3. Create a time off request. 4. Change the default hour value (e.g., from 12 AM to 10 AM) and observe the formatted value. 5. Switch the user language to Dutch. 6. Create another time off request and change the hour value to 10 AM. Issue: ------ After changing the value to 10 AM, the displayed formatted value remains 12 a.m. Cause: ------ https://gith
Original PR description
Steps to reproduce: ------------------- 1. Install hr_holidays. 2. Create a new Time Off Type with "Duration type" set to Hours. 3. Create a time off request. 4. Change the default hour value (e.g.,…
Steps to reproduce: ------------------- 1. Install hr_holidays. 2. Create a new Time Off Type with "Duration type" set to Hours. 3. Create a time off request. 4. Change the default hour value (e.g., from 12 AM to 10 AM) and observe the formatted value. 5. Switch the user language to Dutch. 6. Create another time off request and change the hour value to 10 AM. Issue: ------ After changing the value to 10 AM, the displayed formatted value remains 12 a.m. Cause: ------ https://github.com/odoo/odoo/blob/c1acf61ab23f231e416354a3504cc3c18170af2c/addons/hr_holidays/static/src/components/float_time_selection/float_time_selection.js#L45-L56 Here, the code attempts to parse the hours and minutes by splitting the already localized formatted string (super.formattedValue) and checking if the formatted value ended with "h" or "m". In Dutch, the localized string ends with "u" instead of "h", causing the string-matching logic to fail silently and default back to 0 (12 a.m.). Example: If we change the value to 10:30 AM, in Dutch the formatted value becomes "10u 30m". Reference: e80750d Solution: --------- Stop parsing the localized formatted string and instead compute hours and minutes directly from the float value stored in the record using `floatToHoursMinutes`, making the formatting independent of translations. opw-6303884 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271085
13 changes
Resolved issues and error corrections
Fixes an error that could stop users from assigning an employee to a Hong Kong payslip when that employee did not have a contract start date set. Payroll users can now continue creating payslips in this case, with the system only calculating contract-date-based values when the start date is available.
Original PR description
Currently, an error occurs when a user sets an employee on a payslip. **Steps to Reproduce:** - Install `l10n_hk_hr_payroll` with demo data. - Switch to the `Hong Kong` company. - Create an…
Currently, an error occurs when a user sets an employee on a payslip. **Steps to Reproduce:** - Install `l10n_hk_hr_payroll` with demo data. - Switch to the `Hong Kong` company. - Create an `employee` and make sure that the employee's version has no `contract start date`. - Go to `Payroll` > `Payslips` > `Payslips`. - Create a `payslip` and set that employee. `TypeError: '<' not supported between instances of 'datetime.date' and 'bool'` When a user sets an employee on a payslip, the system computes the worked day lines [1]. If the salary structure uses worked day lines, it creates the corresponding records [2] and calculates out days and out hours based on the contract dates. During this process, the payslip dates are compared with the version's contract start date. If the version does not have a contract start date, it raises an error [3]. This commit ensures that the payslip dates are compared with the version's contract start date, and that out days and out hours are calculated only when the contract start date exists. Cases where no contract start date is defined are already handled in payslip [4]. [1]: https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1964 [2]: https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1985-L1988 [3]- https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/l10n_hk_hr_payroll/models/hr_payslip.py#L309 [4]- https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1092-L1096 sentry-7632216317 Forward-Port-Of: odoo/enterprise#120234
This fix changes when Argentina electronic invoicing's live ARCA currency-rate test runs. Daily builds will no longer pick up a test that requires external HTTP access, reducing false build failures while preserving coverage in nightly runs.
Original PR description
Description of the issue this commit addresses: The live ARCA currency rate test keeps the inherited `standard` tag. It is therefore selected by daily builds whose HTTP guard blocks the request. The guard also blocks it when selected by the external localization suite. --- Desired behavior after this commit is merged: This commit removes the `standard` tag from the live ARCA test. Daily builds skip the test while nightlies still run it with HTTP access. --- runbot-[238857](https://runbot.odoo.com/odoo/error/238857) Forward-Port-Of: odoo/enterprise#125692
Preparation ticket printing in Belgian self-order point of sale now uses the OBOX device instead of the PoS terminal. This helps align printing with the certified blackbox flow and reduces issues when handling preparation tickets.
Original PR description
Impression of preparation ticket are now handled via the OBOX instead of the PoS terminal. See https://github.com/odoo/enterprise/pull/125348
Corrected a small issue in journal report line actions by removing outdated date fields that were no longer used. This helps ensure report actions behave consistently and avoids confusion from stale internal data.
Original PR description
Forward-Port-Of: odoo/enterprise#125266
The accrual reports now remember the user’s chosen "As of" date when they open a line and navigate back using breadcrumbs. This prevents reports from unexpectedly switching back to today’s date and helps users continue their review with the intended reporting cutoff.
Original PR description
Issue: In accrual list reports (Billed Not Received / Invoiced Not Delivered), selecting an "As of" date, opening a line, and returning with the breadcrumb resets the date filter to the default value…
Issue: In accrual list reports (Billed Not Received / Invoiced Not Delivered), selecting an "As of" date, opening a line, and returning with the breadcrumb resets the date filter to the default value (today's date) Steps to reproduce: 1) Open an accrual list report ( Accounting > Audit > Purchases > Bill to receive / Billed Not Received OR Invoices to be issues / invoiced Not delivered) 2) Pick any "As of" date 3) Open any row 4) Click breadcrumb to return to the accrual list 5) Observe the "As of" date has been reset to today's date To generate some data you could: create a PO, then upload the bill, validate the receipt, then you'll find it in bills received Cause: `AccrualListController.setup()` always initialized state.date with a fresh default date and did not re-put the previously saved `accrual_entry_date` from restored context https://github.com/odoo/enterprise/blob/899f0d45b2ae1dc4e5e06a2e0acb3d006d12d563/account_reports/static/src/views/accrual_list_controller.js#L10-L16 Although `setDate()` stored the selected date in context, `setup()` overwrote the UI state on controller recreation https://github.com/odoo/enterprise/blob/899f0d45b2ae1dc4e5e06a2e0acb3d006d12d563/account_reports/static/src/views/accrual_list_controller.js#L61-L65 Solution: - Persist `accrual_entry_date` in `AccrualListSearchModel` via `exportState()` / `_importState()`, so the date is restored in search context before the list model loads on breadcrumb navigation. - Initialize the date picker through `setDate()` in `onWillStart()` instead of hardcoding `DateTime.now()` in `setup()`, so restoration and user changes share the same code path. - In `setDate()`, reset grouped list caches (`currentGroups` and `groups`) before `root.load()`, because those caches are not keyed on `accrual_entry_date` and would otherwise show stale vendor groups after a date change or breadcrumb restore. opw-6232263 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#126087 Forward-Port-Of: odoo/enterprise#118669
This fix updates Belgian POS blackbox test setup data so automated checks no longer crash with a stack overflow. It improves test reliability for Belgian fiscal POS features without changing business workflows or user-facing behavior.
Original PR description
### Issue: During RunBot single module tests, some tests caused an error: `Maximum call stack size exceeded` after repeated: `[Owl] Unhandled error. Destroying the root component` ### Affected tests:…
### Issue:
During RunBot single module tests, some tests caused an error: `Maximum call stack size exceeded` after repeated: `[Owl] Unhandled error. Destroying the root component`
### Affected tests:
- `sign_money_in_out.called at right time`
- `sign_drawer_open.called at right time`
- `sign_work_in.called when opening register, setting & resetting cashier`
- `sign_work_in_employee.called from login screen (closed session)`
### Cause:
The tests passed `dialogData: {}` to the component env But `dialogData` must at least define `scrollToOrigin`, which is called automatically in `onWillDestroy`:
https://github.com/odoo/odoo/blob/0042e83fb60353a49d4759a79a3ceb0eee6f74b6/addons/web/static/src/core/dialog/dialog.js#L122-L126
Calling `scrollToOrigin()` on an empty object raises a `TypeError`, which Owl catches and re-throws repeatedly until the call stack is exceeded
The full `dialogData` shape is defined in `makeDialogMockEnv`: https://github.com/odoo/odoo/blob/62c540d96fc49d9e74d8c660019754651cb0e085/addons/web/static/tests/_framework/env_test_helpers.js#L151-L161
### Steps to reproduce:
- Install `l10n_be_pos_blackbox` (fresh `-i`, or `-u` with `web` on an existing db)
- Run the tests in MobileWebSuite
Before the fix, the errors are triggered
runbot-941232This fix prevents appraisal surveys from crashing when the list of allowed survey types is unexpectedly empty or unavailable. It helps keep employee appraisal workflows running smoothly during upgrades or when survey settings are incomplete.
Original PR description
Avoid a TypeError in _compute_allowed_survey_types when allowed_survey_types is False by falling back to an empty list before unpacking and appending the appraisal survey type.
```py
File "/home/odoo/src/enterprise/saas-19.3/hr_appraisal_survey/models/survey_survey.py", line 33, in _compute_allowed_survey_types
survey.allowed_survey_types = [*survey.allowed_survey_types, 'appraisal']
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Value after * must be an iterable, not bool
```
Ref: https://github.com/odoo/odoo/pull/268125
Bug introduced in: https://github.com/odoo/enterprise/commit/896f54532338b07265722cb4a4161131d408f58c
upg-[4458975](https://upgrade.odoo.com/odoo/request/4458975?debug=1)Fixed a display issue where the text cursor appeared in the middle of dropdown input fields in account reports. The cursor now aligns correctly, making these fields easier and more predictable to use.
Original PR description
Dropdown inputs inside of an account report show the cursor in the center of the input field. The cursor has been changed to be right-aligned. task-6247454
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user (Set Accounting to No) 2- Open Contacts app 3- Try importing contacts (you can download the available template and use it as the file you are asked to upload) 4- Test the import 5- Notice the error you receive Cause: When importing contacts, the commercial fields (fields related to the co
Original PR description
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user…
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user (Set Accounting to No) 2- Open Contacts app 3- Try importing contacts (you can download the available template and use it as the file you are asked to upload) 4- Test the import 5- Notice the error you receive Cause: When importing contacts, the commercial fields (fields related to the contact's parent) are loaded and then written. Some of these fields may have access rights that the user trying to import doesn't have. As a result, when trying to load/write them, the user may get an error. Solution: Use sudo() when loading them. This shouldn't be an issue since they are only copied from the parent. Also, sudo() is already being used when writing the values, https://github.com/odoo/odoo/blob/bb94f13b38f0bf1ce8886f4630ad42caf6c56325/odoo/addons/base/models/res_partner.py#L996 so sudo() should also be used when loading them. opw-6396086 Forward-Port-Of: odoo/odoo#278638
When an internal recipient receives an Out of Office (OOO) notification, the resulting `mail.message` record has `partner_ids` populated with the recipient partner ID, while `outgoing_email_to` is set to `False`. When a second internal user emails the OOO user within the 4-day window, `_notify_thread_with_out_of_office` excutes a search domain with an OR condition: `'|', ('partner_ids', 'in', recipient.ids), ('outgoing_email_to', '=', email_to)` Because `email_to` is `False` for internal p
Original PR description
When an internal recipient receives an Out of Office (OOO) notification, the resulting `mail.message` record has `partner_ids` populated with the recipient partner ID, while `outgoing_email_to` is…
When an internal recipient receives an Out of Office (OOO) notification, the resulting `mail.message` record has `partner_ids` populated with the recipient partner ID, while `outgoing_email_to` is set to `False`.
When a second internal user emails the OOO user within the 4-day window, `_notify_thread_with_out_of_office` excutes a search domain with an OR condition: `'|', ('partner_ids', 'in', recipient.ids), ('outgoing_email_to', '=', email_to)`
Because `email_to` is `False` for internal partners, `('outgoing_email_to', '=', False)` evaluated to `True` against the first recipient's message record. Consequently, the search falsely determined that the second recipient was already notified, suppressing OOO replies for all subsequent contacts across the 4-day window.
## Proposed solution:
We resolve this by dynamically constructing recipient sub-domains conditionally depending if `recipient` or `email_to` are set.
We also extend `test_routing_with_out_of_office` with a corresponding test case.
## How to reproduce:
1. Set up a DB with at least 3 users (User A, User B, User C).
2. Configure User A to be out of office (in user preferences)
3. Go to any chatter/mail.thread while logged as User B and tag User A in a log note. -> triggers OOO message
4. Log as User C, tag User A in a log note. -> BUG: no OOO message because the "4 day" check falsely believes that User C already received a OOO from User A
OPW-6110300
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#279881
Forward-Port-Of: odoo/odoo#277880Steps to reproduce: ------------------- 1. Install hr_holidays. 2. Create a new Time Off Type with "Duration type" set to Hours. 3. Create a time off request. 4. Change the default hour value (e.g., from 12 AM to 10 AM) and observe the formatted value. 5. Switch the user language to Dutch. 6. Create another time off request and change the hour value to 10 AM. Issue: ------ After changing the value to 10 AM, the displayed formatted value remains 12 a.m. Cause: ------ https://gith
Original PR description
Steps to reproduce: ------------------- 1. Install hr_holidays. 2. Create a new Time Off Type with "Duration type" set to Hours. 3. Create a time off request. 4. Change the default hour value (e.g.,…
Steps to reproduce: ------------------- 1. Install hr_holidays. 2. Create a new Time Off Type with "Duration type" set to Hours. 3. Create a time off request. 4. Change the default hour value (e.g., from 12 AM to 10 AM) and observe the formatted value. 5. Switch the user language to Dutch. 6. Create another time off request and change the hour value to 10 AM. Issue: ------ After changing the value to 10 AM, the displayed formatted value remains 12 a.m. Cause: ------ https://github.com/odoo/odoo/blob/c1acf61ab23f231e416354a3504cc3c18170af2c/addons/hr_holidays/static/src/components/float_time_selection/float_time_selection.js#L45-L56 Here, the code attempts to parse the hours and minutes by splitting the already localized formatted string (super.formattedValue) and checking if the formatted value ended with "h" or "m". In Dutch, the localized string ends with "u" instead of "h", causing the string-matching logic to fail silently and default back to 0 (12 a.m.). Example: If we change the value to 10:30 AM, in Dutch the formatted value becomes "10u 30m". Reference: e80750d Solution: --------- Stop parsing the localized formatted string and instead compute hours and minutes directly from the float value stored in the record using `floatToHoursMinutes`, making the formatting independent of translations. opw-6303884 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271085
### Issue: When a `stock.move.line` is manually added to a component move of a Manufacturing Order via the debug View button, it is not linked to the MO This causes the line to appear without a `production_id` in Move History (shown in gray in 18.3+ instead of colored) ### Cause: `production_id` is set on move lines in `_action_assign`, overridden in `mrp` to propagate MO-specific data: https://github.com/odoo/odoo/blob/e8d4ea2dc71109e9afc5b894c9359bcfc08295ae/addons/mrp/models/stock_mov
Original PR description
### Issue: When a `stock.move.line` is manually added to a component move of a Manufacturing Order via the debug View button, it is not linked to the MO This causes the line to appear without a…
### Issue: When a `stock.move.line` is manually added to a component move of a Manufacturing Order via the debug View button, it is not linked to the MO This causes the line to appear without a `production_id` in Move History (shown in gray in 18.3+ instead of colored) ### Cause: `production_id` is set on move lines in `_action_assign`, overridden in `mrp` to propagate MO-specific data: https://github.com/odoo/odoo/blob/e8d4ea2dc71109e9afc5b894c9359bcfc08295ae/addons/mrp/models/stock_move.py#L352-L358 In the normal flow, `_action_assign` is called by `_action_confirm` on the `stock.move`: https://github.com/odoo/odoo/blob/737e28b9c8609d488d93ce7ce05941ff93779e04/addons/stock/models/stock_move.py#L1644-L1646 But when a line is added manually, the move is already created with state `assigned`, so `_action_confirm` skips the call and `_action_assign` is never executed ### Fix: Setting `production_id` in `_action_assign` was incorrectly placed — there is no reason to set it during move assignment Moving it to the move line creation avoids the issue entirely and removes the dependency on a code path that may not be triggered ### Steps to reproduce: - Install `mrp` - Create a BoM for a tracked product with 2 tracked components - Enable Developer mode - Create a Manufacturing Order for the product - Unhide the View button on a component move and click it - Add a new line for the first component (qty: 1) - Confirm and Produce All the MO - Go to Inventory > Reporting > Move History - Add `production_id` via Studio (or check line color in 18.3+) Before the fix, the manually added line has no `production_id` (and in 18.3+ the line is gray instead of colored) opw-6250911 Forward-Port-Of: odoo/odoo#279839 Forward-Port-Of: odoo/odoo#272035
Code cleanup and technical improvements
The live chat helpdesk information panel was simplified by removing a repeated check around the Open tickets section. This reduces the chance of display issues and adds test coverage to keep the helpdesk ticket information stable for users.
Original PR description
Enterprise counterpart of "[FIX] crm_livechat, *: prevent crash in the info panel", which explains why the condition of the caller goes away. This commit drops the same condition on the "Open tickets" block, and covers that block with a test. https://github.com/odoo/odoo/pull/280430
22 changes
Resolved issues and error corrections
The Statement of Account option from the Malaysian reports module now appears only for Malaysian companies. This prevents users in other countries from seeing or launching a country-specific report that does not apply to their company.
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#126172
This update corrects how the Stripe expense cardholder selection field is built so it follows the current Odoo standard. It ensures filtering rules from the view are properly applied, helping users see the right cardholder options when managing expenses.
Original PR description
After https://github.com/odoo/odoo/issues/196785; the standard way to build a custom m2o field in JS is to call a method from the Many2one module, instead of extending an object from it. This commit solves issues regarding domain in the view not being passed to the widget opw-6399906 Forward-Port-Of: odoo/enterprise#125346
The restaurant appointment point-of-sale test now waits for the page refresh to complete before continuing. This reduces false test failures and helps keep release checks stable without changing customer-facing behavior.
Original PR description
In a tour of pos_restaurant_appointment, we reload the data and continue the tour. Some steps are too fast in the tour and are checked before the page is realy reloaded. This commit adds checks to ensure that the page is reloaded before continuing the tour. runbot-error: 241213 Community PR: https://github.com/odoo/odoo/pull/253327
The manufacturing planning tests were adjusted to match the latest demand calculation, which now includes the entire current day. This helps ensure replenishment suggestions are validated correctly when same-day supply moves are planned later in the day.
Original PR description
Updated the forecast suggestion test expectations after monthly demand was updated to count the full current day, so same-day orderpoint replenishment moves scheduled later in the day are also included Community PR: odoo/odoo#262435 TaskID-5490137 Forward-Port-Of: odoo/enterprise#126415 Forward-Port-Of: odoo/enterprise#115944
A small typo in the journal report line actions was corrected to keep the report interface behaving as expected. This helps users avoid minor issues when working with journal report lines, with no broader process changes.
Original PR description
Forward-Port-Of: odoo/enterprise#125266
This fixes how Planning filters employees and materials for open shifts, so results better match what users expect. It prevents filters meant for unassigned shifts from incorrectly affecting shifts that already have assigned resources.
Original PR description
Before this commit, the domain wrongly assumes that we always search on shifts having no role or a role containing resources of types 'user' or 'material' (1). Additionally to the basic domain which searches on the shifts having resources of types 'user' or 'material' (2). After this commit, we add a condition on domain (1) to only apply it for open shifts (shifts having no resource_id). no-task Forward-Port-Of: odoo/enterprise#126247
Fixed timesheet assistant rules so suggestions are only created when the expected text is present. This prevents confusing entries such as “Discussing with undefined,” making suggested timesheet descriptions clearer for users.
Original PR description
Several aw.rule regexes use (.*) for the capture groups feeding the suggestion name/description, allowing an empty match and producing incorrect suggestions (e.g. "Discussing with undefined") Task-6377168
Issue: --- If a product template has dynamic attributes, some variants might not exist. For those variants, we are showing wrong stock in the website. To reproduce: 1- Create a product with a dynamic attribute and two values. 2- Publish the product and uncheck sell when out-of-stock and check show product when the qty is less than 5. 3- Create a purchase order with qty = 4 for the first value, so a variant is created for it. 4- Go to the website shop. Open the product. 4 available qty i
Original PR description
Issue: --- If a product template has dynamic attributes, some variants might not exist. For those variants, we are showing wrong stock in the website. To reproduce: 1- Create a product with a dynamic attribute and two values. 2- Publish the product and uncheck sell when out-of-stock and check show product when the qty is less than 5. 3- Create a purchase order with qty = 4 for the first value, so a variant is created for it. 4- Go to the website shop. Open the product. 4 available qty in stock is shown for the first variant which is correct. 5- Select 2nd variant. As you see, still 4 available qty is shown which is wrong. As the out-of-stock sale is unchecked, an out-of-stock warning should be shown. Cause and Fix: --- This is due to `isMainProduct` being always False when `product_id` is not set which makes `free_qty` and `out_of_stock` not to be updated. opw-6237602 Forward-Port-Of: odoo/odoo#279572 Forward-Port-Of: odoo/odoo#273104
### Issue: When a `stock.move.line` is manually added to a component move of a Manufacturing Order via the debug View button, it is not linked to the MO This causes the line to appear without a `production_id` in Move History (shown in gray in 18.3+ instead of colored) ### Cause: `production_id` is set on move lines in `_action_assign`, overridden in `mrp` to propagate MO-specific data: https://github.com/odoo/odoo/blob/e8d4ea2dc71109e9afc5b894c9359bcfc08295ae/addons/mrp/models/stock_mov
Original PR description
### Issue: When a `stock.move.line` is manually added to a component move of a Manufacturing Order via the debug View button, it is not linked to the MO This causes the line to appear without a…
### Issue: When a `stock.move.line` is manually added to a component move of a Manufacturing Order via the debug View button, it is not linked to the MO This causes the line to appear without a `production_id` in Move History (shown in gray in 18.3+ instead of colored) ### Cause: `production_id` is set on move lines in `_action_assign`, overridden in `mrp` to propagate MO-specific data: https://github.com/odoo/odoo/blob/e8d4ea2dc71109e9afc5b894c9359bcfc08295ae/addons/mrp/models/stock_move.py#L352-L358 In the normal flow, `_action_assign` is called by `_action_confirm` on the `stock.move`: https://github.com/odoo/odoo/blob/737e28b9c8609d488d93ce7ce05941ff93779e04/addons/stock/models/stock_move.py#L1644-L1646 But when a line is added manually, the move is already created with state `assigned`, so `_action_confirm` skips the call and `_action_assign` is never executed ### Fix: Setting `production_id` in `_action_assign` was incorrectly placed — there is no reason to set it during move assignment Moving it to the move line creation avoids the issue entirely and removes the dependency on a code path that may not be triggered ### Steps to reproduce: - Install `mrp` - Create a BoM for a tracked product with 2 tracked components - Enable Developer mode - Create a Manufacturing Order for the product - Unhide the View button on a component move and click it - Add a new line for the first component (qty: 1) - Confirm and Produce All the MO - Go to Inventory > Reporting > Move History - Add `production_id` via Studio (or check line color in 18.3+) Before the fix, the manually added line has no `production_id` (and in 18.3+ the line is gray instead of colored) opw-6250911 Forward-Port-Of: odoo/odoo#272035
In a MO for a product tracked by serial number, when changing the serial number after confirming the mo, it will silently assign a serial number. **Steps to reproduce** * Create three products: - "Component" - "Final" with a bom containing "Component" and tracked by Serial number - "Setup" with a bom containing "Final" * Create and confirm a MO for "Setup" - assign the serial number "PROD" to "Final" * Produce "Setup" * Create and confirm a MO for "Final" * Generate a seria
Original PR description
In a MO for a product tracked by serial number, when changing the serial number after confirming the mo, it will silently assign a serial number. **Steps to reproduce** * Create three products: -…
In a MO for a product tracked by serial number, when changing the serial number after confirming the mo, it will silently assign a serial number. **Steps to reproduce** * Create three products: - "Component" - "Final" with a bom containing "Component" and tracked by Serial number - "Setup" with a bom containing "Final" * Create and confirm a MO for "Setup" - assign the serial number "PROD" to "Final" * Produce "Setup" * Create and confirm a MO for "Final" * Generate a serial number * Clear the serial number * Generate a new serial number * Produce "Final" -> In Product Moves you can see that the serial number assign was "PROD" **Observation** First when creating the MO, it will create a stock move for "final" and create a stock move line without assigning any quant. action_confirm -> _action_assign https://github.com/odoo/odoo/blob/ff0dd8fcc8dfbb5e5cb798c90d68be41d56b7b4c/addons/stock/models/stock_move.py#L1643-L1646 In _action_assign it will bypass_reservation since the location is "production": https://github.com/odoo/odoo/blob/ff0dd8fcc8dfbb5e5cb798c90d68be41d56b7b4c/addons/stock/models/stock_move.py#L1948 https://github.com/odoo/odoo/blob/ff0dd8fcc8dfbb5e5cb798c90d68be41d56b7b4c/addons/stock/models/stock_location.py#L411-L413 and create the sml: https://github.com/odoo/odoo/blob/e8aa9219e3c72a987f431e47a1534f9ccb0028b2/addons/stock/models/stock_move.py#L2048 When adding the Serial number it will be added to lot_producing_ids, set qty_producing and call set_qty_producing ->_set_quantity_done -> _set_quantity_done_prepare_vals: https://github.com/odoo/odoo/blob/e8aa9219e3c72a987f431e47a1534f9ccb0028b2/addons/mrp/models/mrp_production.py#L1593-L1597 In set_qty_producing->_set_quantity_done ->_set_quantity_done_prepare_vals nothing will be done since there already is a stock move line with the right quantity: https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/stock/models/stock_move.py#L2368-L2371 Second when clearing the Serial number it will call action_clear_lot_producing_ids, where it will - Erase the lot from lot_producing_ids - Set qty_producing to 0 - and call _set_qty_producing _set_qty_producing -> _set_quantity_done -> _set_quantity_done_prepare_vals: where it will erase the stock move line since it's new quantity is 0: https://github.com/odoo/odoo/blob/e8aa9219e3c72a987f431e47a1534f9ccb0028b2/addons/stock/models/stock_move.py#L2353-L2355 Lastly this means that when add in the new lot, it will not already have a stock move line, and it will create a new stock move line based on available quants: https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/stock/models/stock_move.py#L2392-L2402 The lot_ids on the moves is supposed the get assigned when we produce the product: https://github.com/odoo/odoo/blob/e8aa9219e3c72a987f431e47a1534f9ccb0028b2/addons/mrp/models/mrp_production.py#L1911-L1913 opw-6240857 Forward-Port-Of: odoo/odoo#268542
### Problem When mass updating the “Analytic Distribution” field on the lines on Analytic Items the values are not timely reflected on the lines. Steps to reproduce the issue: 1. Accounting > Accounting > Analytic Items. 2. Select multiple records (lines) from the list view. 3. Click on the "Analytic Distribution" column for one of the selected lines to mass-update it. 4. Add or adjust a specific analytic account/tag and click away to apply. 5. Click "Update" on the confirmation pop-up.
Original PR description
### Problem When mass updating the “Analytic Distribution” field on the lines on Analytic Items the values are not timely reflected on the lines. Steps to reproduce the issue: 1. Accounting > Accounting > Analytic Items. 2. Select multiple records (lines) from the list view. 3. Click on the "Analytic Distribution" column for one of the selected lines to mass-update it. 4. Add or adjust a specific analytic account/tag and click away to apply. 5. Click "Update" on the confirmation pop-up. 6. The previously existing analytic distribution tags of other plans disappear, showing only the newly updated account/tag. 7. Refresh the page. 8. The "missing" tags reappear alongside the newly updated one. ### Solution We need to trigger a read of the updated values after they are saved on the server side. opw-6045687 Forward-Port-Of: odoo/odoo#275497 Forward-Port-Of: odoo/odoo#261068
After https://github.com/odoo/odoo/issues/196785; the standard way to build a custom m2o field in JS is to call a method from the Many2one module, instead of extending an object from it. This commit solves issues regarding domain in the view not being passed to the widget opw-6399906 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.odo
Original PR description
After https://github.com/odoo/odoo/issues/196785; the standard way to build a custom m2o field in JS is to call a method from the Many2one module, instead of extending an object from it. This commit solves issues regarding domain in the view not being passed to the widget opw-6399906 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#278123
## Problem When computing qty_delivered on a sale order line, intercompany 'delieveries' from the other company would count towards the delivery total. ## Solution When retreiving the relevant moves for quantity calculation (_get_outgoing_incoming_moves), we will filter out any moves not belonging to the SOL's company. This will prevent moves from other companies into the interco location from being counted towards qty_delivered. ## Steps to Replicate (runbot v19) 1. Create a route
Original PR description
## Problem When computing qty_delivered on a sale order line, intercompany 'delieveries' from the other company would count towards the delivery total. ## Solution When retreiving the relevant moves…
## Problem
When computing qty_delivered on a sale order line, intercompany 'delieveries' from the other company would count towards the delivery total.
## Solution
When retreiving the relevant moves for quantity calculation (_get_outgoing_incoming_moves), we will filter out any moves not belonging to the SOL's company. This will prevent moves from other companies into the interco location from being counted towards qty_delivered.
## Steps to Replicate (runbot v19)
1. Create a route
- Pull Comp B -> Interco, MTO, Comp B delivery
- Pull Interco -> Comp A, MTS, Comp A receipt
(You can review the test for more info about this route config)
(There is also this video showcasing the issue on runbot: https://drive.google.com/file/d/1YeUie4EhWPyg_RuJkNf40S9zARB4jXWY/view)
2. Attach a product to this new route
3. Create a SO for the product and confirm it
4. You should see 4 pickings, validate the chain
5. The qty_delivered on the sale order is double the demand
opw-6361559
Forward-Port-Of: odoo/odoo#275694**Issue** The height is not correctly computed in the picking form when editing product description. **Steps to reproduce** - Create a delivery for a product - Add a description to it - Click on editing the description -> Observe that the description is partially hidden because the widget height is incorrectly computed **Cause** Since commit https://github.com/odoo/odoo/commit/e4f4171e1bc838840c0bd6111cd78f348b201ac2, `useProductAndLabelAutoresize` no longer assigns a height to the
Original PR description
**Issue** The height is not correctly computed in the picking form when editing product description. **Steps to reproduce** - Create a delivery for a product - Add a description to it - Click on…
**Issue** The height is not correctly computed in the picking form when editing product description. **Steps to reproduce** - Create a delivery for a product - Add a description to it - Click on editing the description -> Observe that the description is partially hidden because the widget height is incorrectly computed **Cause** Since commit https://github.com/odoo/odoo/commit/e4f4171e1bc838840c0bd6111cd78f348b201ac2, `useProductAndLabelAutoresize` no longer assigns a height to the widget root. The corresponding widget is `MoveProductLabelField`, which extends `ProductNameAndDescriptionField`: https://github.com/odoo/odoo/blob/91b59f285248c120fe9e3e5f6b6f086ea7be2837/addons/stock/static/src/views/picking_form/stock_move_product_label.js#L5 It uses `useProductAndLabelAutoresize`: https://github.com/odoo/odoo/blob/91b59f285248c120fe9e3e5f6b6f086ea7be2837/addons/product/static/src/product_name_and_description/product_name_and_description.js#L54-L56 **Solution** Explicitly add a div around the product display and description to still use the `Autoresize` Forward-Port-Of: odoo/odoo#271564
### 1. Prevent tour failure by waiting on the correct loading class Before this PR, the tour introduced in commit [1] and modified in commit [2] 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`, allowing the next tour step to run before the loader was shown. After this commit, the tour waits for `o_loading_screen`, which is added immediately and remains visible until the operation finishes. T
Original PR description
### 1. Prevent tour failure by waiting on the correct loading class Before this PR, the tour introduced in commit [1] and modified in commit [2] could fail non-deterministically because it waited for…
### 1. Prevent tour failure by waiting on the correct loading class Before this PR, the tour introduced in commit [1] and modified in commit [2] 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`, allowing the next tour step to run before the loader was shown. After this commit, the tour waits for `o_loading_screen`, which is added immediately and remains visible until the operation finishes. This ensures that the tour waits correctly before proceeding. [1]: https://github.com/odoo/odoo/commit/091b8dee407fe30a115d4bb2e96d4d [2]: https://github.com/odoo/odoo/commit/544a03775119021442d66486c24711 **runbot:** [941508](https://runbot.odoo.com/odoo/error/941508) --- ### 2. Prevent tour failure by clicking the "Close" button instead of pressing "Escape" Before this PR, the tour step introduced in commit [1], which pressed the <kbd>Escape</kbd> key to close the Insert Snippet dialog, could fail non-deterministically with the error: > It is not allowed to do action on an element that's below a modal. After this PR, instead of pressing <kbd>Escape</kbd>, the tour clicks the **Close** (`X`) button to close the dialog. This is a more reliable way to close the dialog and prevents the non-deterministic failure of the sync color shape tour. [1]: https://github.com/odoo/odoo/commit/544a03775119021442d66486c24711d **runbot:** [944543](https://runbot.odoo.com/odoo/error/944543) --- ### 3. Prevent tour failure by adding steps to open sliding panel for color-related options Before this PR, the tour introduced in commit [1] and modified in commit [2] was breaking, because it expected the color-related options to be directly available under the theme tab. However, after commit [3], the color-related controls were moved into a sliding panel. This PR adds the missing steps to open the sliding panel before accessing the color-related options, allowing the tour to complete successfully. [3]: https://github.com/odoo/odoo/commit/8e104a3a416781a903f3b3b4b77e5f8be24fc7b0 **runbot:** [944587](https://runbot.odoo.com/odoo/error/944587) Forward-Port-Of: odoo/odoo#279395 Forward-Port-Of: odoo/odoo#278743
When selecting a new microphone or camera in the `Voice & Video settings` outside an active meeting, the browser was not asking for permission immediately. This caused Firefox (which enforces per device permissions) to reprompt when the meeting started. This fix pre-authorizes the selected device, so Firefox prompts at selection time rather than when starting a meeting. task-6175062 Forward-Port-Of: odoo/odoo#279624 Forward-Port-Of: odoo/odoo#277730
Original PR description
When selecting a new microphone or camera in the `Voice & Video settings` outside an active meeting, the browser was not asking for permission immediately. This caused Firefox (which enforces per device permissions) to reprompt when the meeting started. This fix pre-authorizes the selected device, so Firefox prompts at selection time rather than when starting a meeting. task-6175062 Forward-Port-Of: odoo/odoo#279624 Forward-Port-Of: odoo/odoo#277730
Issue: Outstanding credits/debits from a branch don't appear on the main company and inversely. Cause : From odoo/odoo#255875 outstanding credits/debits are limited by company to prevent different company issues on validation. However, this error is raised for `account.move` having different root companies. Which allow move from different branches of the same company. Steps to reproduce: - create a company and a branch - in the main company create a customer payment and valid it - in
Original PR description
Issue: Outstanding credits/debits from a branch don't appear on the main company and inversely. Cause : From odoo/odoo#255875 outstanding credits/debits are limited by company to prevent different company issues on validation. However, this error is raised for `account.move` having different root companies. Which allow move from different branches of the same company. Steps to reproduce: - create a company and a branch - in the main company create a customer payment and valid it - in the branch, create an invoice for the same customer and confirm it Current behavior: - the outstanding payment from the main company doesn't appear on the branch invoice, However, it's possible to reconcile it from the Journal entry view Expected behavior: - the outstanding payment from the main company appears on the branch invoice, opw-6140689 Forward-Port-Of: odoo/odoo#262260
Steps to reproduce: - Enable the ZUGFeRD (or Factur-X) e-invoicing format on a German customer. - Create a sale order for that customer, confirm it, create an invoice with a down payment. - Confirm and send the invoice to generate the PDF/XML. - Validate the XML (e.g. on portinvoice.com): it is rejected because the invoice line is missing the mandatory ram:Name field, only ram:Description is present. Cause of the issue: a down payment invoice line created from a sale order no l
Original PR description
Steps to reproduce: - Enable the ZUGFeRD (or Factur-X) e-invoicing format on a German customer. - Create a sale order for that customer, confirm it, create an invoice with a down payment. - Confirm and send the invoice to generate the PDF/XML. - Validate the XML (e.g. on portinvoice.com): it is rejected because the invoice line is missing the mandatory ram:Name field, only ram:Description is present. Cause of the issue: a down payment invoice line created from a sale order no longer carries a product_id: it only has a free-text. The Factur-X/CII export template rendered ram:Name directly from line.product_id.name with no fallback. For a line without a product, this produced an empty ram:Name element, which cleanup_xml_node then stripped entirely from the XML, leaving only ram:Description. Solution: Fall back to the line's name when there is no product opw-6391121 Forward-Port-Of: odoo/odoo#277418
recently in 19.1 a commit adds a warning and disables the button in the signup for if you are alreafy logged in. The issue is that for websites without the header (which is the case for internal, but can happen to customers) there is no way to get to the homepage (except from writing to the url or hiting the back button) This created an issue in internal as an example, since our customers have aparently bookmarked the login page, and they would simply login again before this. For some people,
Original PR description
recently in 19.1 a commit adds a warning and disables the button in the signup for if you are alreafy logged in. The issue is that for websites without the header (which is the case for internal, but…
recently in 19.1 a commit adds a warning and disables the button in the signup for if you are alreafy logged in. The issue is that for websites without the header (which is the case for internal, but can happen to customers) there is no way to get to the homepage (except from writing to the url or hiting the back button) This created an issue in internal as an example, since our customers have aparently bookmarked the login page, and they would simply login again before this. For some people, since they would access the page so often, google automatically fill up the url when they type odoo to odoo/web/login This commit aims to introduce a link to the home page that will be displayed in the warning message. This way cusotmers can get to the home page, and we will hopefully stop the support tickets this has created opw-6331783 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#274999
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user (Set Accounting to No) 2- Open Contacts app 3- Try importing contacts (you can download the available template and use it as the file you are asked to upload) 4- Test the import 5- Notice the error you receive Cause: When importing contacts, the commercial fields (fields related to the co
Original PR description
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user…
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user (Set Accounting to No) 2- Open Contacts app 3- Try importing contacts (you can download the available template and use it as the file you are asked to upload) 4- Test the import 5- Notice the error you receive Cause: When importing contacts, the commercial fields (fields related to the contact's parent) are loaded and then written. Some of these fields may have access rights that the user trying to import doesn't have. As a result, when trying to load/write them, the user may get an error. Solution: Use sudo() when loading them. This shouldn't be an issue since they are only copied from the parent. Also, sudo() is already being used when writing the values, https://github.com/odoo/odoo/blob/bb94f13b38f0bf1ce8886f4630ad42caf6c56325/odoo/addons/base/models/res_partner.py#L996 so sudo() should also be used when loading them. opw-6396086 Forward-Port-Of: odoo/odoo#278638
In the Point of Sale receipt styles, the margin classes ms-* (margin left) and me-* (margin right) were inverted: - me-* was pushing margins to the left. - ms-* was pushing margins to the right. This commit swaps them back to their correct sides to ensure custom tickets layout correctly. task-id: 6250233 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
In the Point of Sale receipt styles, the margin classes ms-* (margin left) and me-* (margin right) were inverted: - me-* was pushing margins to the left. - ms-* was pushing margins to the right. This commit swaps them back to their correct sides to ensure custom tickets layout correctly. task-id: 6250233 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Miscellaneous changes
Simplified version of https://github.com/odoo/odoo/pull/276689 Forward-Port-Of: odoo/odoo#277083 Forward-Port-Of: odoo/odoo#276696
Original PR description
Simplified version of https://github.com/odoo/odoo/pull/276689 Forward-Port-Of: odoo/odoo#277083 Forward-Port-Of: odoo/odoo#276696
8 changes
Resolved issues and error corrections
Payroll reports now calculate default dates consistently using the user's timezone. This prevents late-night automated checks and payroll payment workflows from failing around midnight due to mismatched payment and value dates.
Original PR description
### Steps to reproduce: - Set the environment timezone (`env.tz`) to a timezone ahead of UTC (e.g., Europe/Brussels) - Run the enterprise tests (L10n standalone, Single app, or Multi l10n) during the…
### Steps to reproduce: - Set the environment timezone (`env.tz`) to a timezone ahead of UTC (e.g., Europe/Brussels) - Run the enterprise tests (L10n standalone, Single app, or Multi l10n) during the late evening in UTC (e.g., 23:00 UTC) > UserError: The Payment Date cannot be later than the Value Date, please make sure that the correct dates are set ### Cause of Issue: In the payroll payment report wizards, a race condition occurs around midnight due to mismatched timezone context evaluations between different date fields. The `effective_date` field (defined in the base hr_payroll module) derives its default value using `fields.Date.context_today`, which correctly applies the client's timezone offset to the current server time. https://github.com/odoo/enterprise/blob/54b7035b4cb6b9427092a3eebe73f2bee7f2ae09/hr_payroll/wizard/hr_payroll_payment_report_wizard.py#L23-L26 However, `l10n_sa_wps_value_date` (and similar date fields in other localizations like AU, HK, AE) derives its default value using `fields.Date.today()`, which strictly relies on the server's UTC time. https://github.com/odoo/enterprise/blob/54b7035b4cb6b9427092a3eebe73f2bee7f2ae09/l10n_sa_hr_payroll/wizard/hr_payroll_payment_report_wizard.py#L13-L14 When the nightly Runbot builds execute late at night UTC time, the environment timezone frequently crosses midnight into "tomorrow" while the server time is still on "today". Because of this offset, `effective_date` rolls over to tomorrow, but `l10n_sa_wps_value_date` evaluates as today + 1 day (which is also tomorrow). The validation check `effective_date >= l10n_sa_wps_value_date` evaluates to True. https://github.com/odoo/enterprise/blob/54b7035b4cb6b9427092a3eebe73f2bee7f2ae09/l10n_sa_hr_payroll/wizard/hr_payroll_payment_report_wizard.py#L93-L94 ### Fix: Standardize the default date computations to ensure they are all evaluated within the same timezone context and prevent the midnight timezone rollover discrepancy. runbot-937793
A small typo in the journal report line actions was corrected, and unused date fields were cleaned up. This helps prevent confusing or broken actions when users interact with journal report lines, with no expected change to normal workflows.
Original PR description
Forward-Port-Of: odoo/enterprise#125266
The Malaysian Statement of Account option now appears only for companies based in Malaysia. 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#126172
The Planning app now applies employee and material filtering correctly for open shifts only. This prevents assigned shifts from being incorrectly included or excluded, helping planners find the right shifts and resources more reliably.
Original PR description
Before this commit, the domain wrongly assumes that we always search on shifts having no role or a role containing resources of types 'user' or 'material' (1). Additionally to the basic domain which searches on the shifts having resources of types 'user' or 'material' (2). After this commit, we add a condition on domain (1) to only apply it for open shifts (shifts having no resource_id). no-task Forward-Port-Of: odoo/enterprise#126247
The Helpdesk unanswered ticket filter no longer treats automatic acknowledgement emails as customer replies needing a response. This helps support teams focus on genuinely unanswered customer messages and avoid misleading ticket queues.
Original PR description
Steps to reproduce: --------- - install website_helpdesk - set an email address on the company partner if it is empty ( it is empty in a database without demo data). - generate a ticket from the website. - apply the Unanswered filter. Issue: ------ system generated acknowledgement message is considered an unanswered customer reply. Fix: -------- system generated acknowledgement messages are now considered answered. task-5138678
Users who open a bank statement line from an in-app notification will now see the related discussion panel. This ensures tagged users can immediately view and respond to comments in the expected place, improving collaboration during bank reconciliation.
Original PR description
Problem: When navigating to a bank statement line through a notification, the chatter doesn't appear. Steps to reproduce: 1. Set in app notifications for one of the users 2. Open Accounting > Bank > To Reconcile 3. Select any bank statement line 4. Tag the user from step 1 in a comment 5. Log in as that user 6. Check notifications and click the new notification 7. Notice how the chatter does not appear on the bank statement line after navigating there Cause: The chatter was not enabled on the bank statement line form view. opw-6410186
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user (Set Accounting to No) 2- Open Contacts app 3- Try importing contacts (you can download the available template and use it as the file you are asked to upload) 4- Test the import 5- Notice the error you receive Cause: When importing contacts, the commercial fields (fields related to the co
Original PR description
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user…
Problem: When testing the import of contacts with a user without accounting access rights, the test fails and leads to an error. Steps to reproduce: 1- Remove accounting access rights from your user (Set Accounting to No) 2- Open Contacts app 3- Try importing contacts (you can download the available template and use it as the file you are asked to upload) 4- Test the import 5- Notice the error you receive Cause: When importing contacts, the commercial fields (fields related to the contact's parent) are loaded and then written. Some of these fields may have access rights that the user trying to import doesn't have. As a result, when trying to load/write them, the user may get an error. Solution: Use sudo() when loading them. This shouldn't be an issue since they are only copied from the parent. Also, sudo() is already being used when writing the values, https://github.com/odoo/odoo/blob/bb94f13b38f0bf1ce8886f4630ad42caf6c56325/odoo/addons/base/models/res_partner.py#L996 so sudo() should also be used when loading them. opw-6396086 Forward-Port-Of: odoo/odoo#278638
PoS loads product categories from both the PoS configuration and the preparation printers. Before this commit, if a child category was included in the PoS configuration, but its parent was only included in a preparation printer, the parent category was loaded in the frontend without being visible. As a result, the child category was also hidden, even though its products were still available. How to reproduce: - Create a parent category. - Create a child category containing a product. -
Original PR description
PoS loads product categories from both the PoS configuration and the preparation printers. Before this commit, if a child category was included in the PoS configuration, but its parent was only included in a preparation printer, the parent category was loaded in the frontend without being visible. As a result, the child category was also hidden, even though its products were still available. How to reproduce: - Create a parent category. - Create a child category containing a product. - Limit the PoS categories to the child category. - Create a preparation printer and assign the parent category to it. - Open the PoS. - The products are available, but the child category is not visible. opw-6381119 Forward-Port-Of: odoo/odoo#276782
3 changes
Resolved issues and error corrections
Quotations created from helpdesk repair orders now correctly use the salesperson assigned to the customer. This prevents empty salesperson fields, helping teams keep ownership and follow-up responsibility accurate in the sales process.
Original PR description
Currently, when a quotation is created from a repair order generated from a helpdesk ticket, the salesperson is not set on the quotation even if the customer has a salesperson assigned. **Steps to…
Currently, when a quotation is created from a repair order generated from a helpdesk ticket, the salesperson is not set on the quotation even if the customer has a salesperson assigned. **Steps to Reproduce:** - Install `helpdesk_repair`. - Go to `Helpdesk` > `Configuration` > `Helpdesk Teams`. - Open a team recod and enable `Repairs`. - Create a `contact/customer` with a `salesperson` assigned. - Go to `Helpdesk`, create a ticket for that `customer`, and select the `helpdesk team` configured above. - Click `Repair`, then click `Create Quotation`. - Open the quotation and check the `Salesperson` field in the `Other Info` tab. **Current behavior:** The Salesperson field on the quotation remains empty. **Expected behavior:** The Salesperson field on the quotation should inherit the salesperson assigned to the selected customer/contact. **Cause of the issue:** When a repair order is created from a helpdesk ticket, default_user_id [1] is passed in the context . This value is propagated when creating the repair order [2] . Later, when creating the quotation from the repair order [3], the same context is reused. Because default_user_id is already present in the context, it overrides the precomputation of user_id from the customer. As a result, user_id is initialized with an empty value and remains unset. **Fix:** This commit ensures that default_user_id is removed from the context before creating the sale order. Without a default value for user_id, the field is correctly precomputed from the selected customer, and the salesperson is properly assigned. [1]- https://github.com/odoo/enterprise/blob/2662932c7ac8ebf3ed5a05d44d7ebfaff869fcbd/helpdesk_repair/models/helpdesk_ticket.py#L52 [2]- https://github.com/odoo/enterprise/blob/2662932c7ac8ebf3ed5a05d44d7ebfaff869fcbd/helpdesk_repair/models/helpdesk_ticket.py#L36-L40 [3]: https://github.com/odoo/odoo/blob/29328b8fccff833c14de317b51f3b4e5a8c40f75/addons/repair/models/repair.py#L357 opw-6344939 Forward-Port-Of: odoo/enterprise#126310 Forward-Port-Of: odoo/enterprise#122980
The Planning app now applies employee and material filters more accurately when shifts are still unassigned. This helps managers see the right open shifts and avoid confusing or incomplete planning results.
Original PR description
Before this commit, the domain wrongly assumes that we always search on shifts having no role or a role containing resources of types 'user' or 'material' (1). Additionally to the basic domain which searches on the shifts having resources of types 'user' or 'material' (2). After this commit, we add a condition on domain (1) to only apply it for open shifts (shifts having no resource_id). no-task Forward-Port-Of: odoo/enterprise#126247
This fixes an internal test issue caused by an earlier update being carried forward incorrectly. It helps ensure Hong Kong payroll tests use the right date information, reducing the risk of missed regressions in payroll behavior.
Original PR description
Fixes a wrong forward port where the test were not updated to set the correct date field, which were changed in 18.4
4 changes
Resolved issues and error corrections
The planning filters for employees and materials now apply the extra role-based criteria only to open shifts. This prevents assigned shifts from being incorrectly included or excluded, making planning views more accurate for schedulers.
Original PR description
Before this commit, the domain wrongly assumes that we always search on shifts having no role or a role containing resources of types 'user' or 'material' (1). Additionally to the basic domain which searches on the shifts having resources of types 'user' or 'material' (2). After this commit, we add a condition on domain (1) to only apply it for open shifts (shifts having no resource_id). no-task Forward-Port-Of: odoo/enterprise#126247
This fix ensures the Helpdesk Knowledge website integration includes the required website knowledge dependency during installation. It prevents installation failures in specific setup modes, helping deployments complete successfully without manual dependency workarounds.
Original PR description
Trying to install website_helpdesk_knowledge with the flag --skip-auto-install would fail due to website_helpdesk_knowledge/views/helpdesk_views.xml referencing `is_published` which is only defined in `website` https://github.com/odoo/odoo/blob/4d60d5693f3d0253a28dd38412125b2fc6d6b41f/addons/website/models/mixins.py#L184 Reproduciton steps: odoo/odoo-bin --addons-path odoo/addons,odoo/odoo/addons,enterprise,design-themes -d oes_runbot --stop-after-init --log-level=test --max-cron-threads=0 -i website_helpdesk_knowledge --skip-auto-install Adding `website_knowledge` pulls in the relevant dependencies resulting in the field being found and valid Affects **18.0** and **19.0**, **nothing in between** Forward-Port-Of: odoo/enterprise#126260
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots & Serial Numbers in Settings. - Create two products: Car and Engine. - Configure Engine to use Unique Serial Number tracking (Inventory →Traceability). - Set the on-hand quantity of Engine to 1 with serial number 0001. - Create a BoM for Car using Engine as a component. - Create and confirm a man
Original PR description
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots &…
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots & Serial Numbers in Settings. - Create two products: Car and Engine. - Configure Engine to use Unique Serial Number tracking (Inventory →Traceability). - Set the on-hand quantity of Engine to 1 with serial number 0001. - Create a BoM for Car using Engine as a component. - Create and confirm a manufacturing order for Car. - Click `Consumed` for the component and click Produce All. - Navigate to Lots & Serial Numbers → Engine → 0001 → Traceability. - Click the arrow next to the manufacturing order reference, then click Print. ## Observed Behavior: An `Arbitrary Uncaught Python Exception` traceback is raised, resulting in a 404 error. ## Root Cause: This issue occurs because, when the user clicks the arrow button in the traceability report, the template [1] invokes the `onClickUpDownStream` function. This function adds the URL `/stock/output_format/stock/active_id` to the context , as shown in [2]. Later, when the user clicks the Print button, `onClickPrint()` [3] constructs the print URL using the `controllerUrl` value by replacing the active model and active ID placeholders with values from the context. However, the URL stored in the context contains `/active_id` instead of `:active_id`. As a result, the placeholder replacement does not occur, leaving the URL unchanged. This causes the print action to use an invalid URL, ultimately resulting in a 404 error. As shown in [4], `controllerUrl` is assigned directly from the context. [1]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.xml#L52-L56 [2]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L105-L118 [3]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L120-L131 [4]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L53-L55 ## Solution: Pass the correct URL in the context so that the active ID placeholder can be replaced correctly during the print action. This ensures that the generated print URL is valid, allowing the user to print the report without encountering any errors. opw-6372834 Forward-Port-Of: odoo/odoo#276449
**Summary**: When a user receives products from a Purchase Order and later decreases the ordered quantity below the quantity already received, Odoo currently allows the change to be saved. This leaves the Purchase Order in an inconsistent state, where the received quantity exceeds the ordered quantity. **Steps to reproduce:** - Install the Purchase and Inventory modules. - Create a Purchase Order with one storable product. - Set the ordered quantity to 10. - Confirm the Purchase Order.
Original PR description
**Summary**: When a user receives products from a Purchase Order and later decreases the ordered quantity below the quantity already received, Odoo currently allows the change to be saved. This…
**Summary**: When a user receives products from a Purchase Order and later decreases the ordered quantity below the quantity already received, Odoo currently allows the change to be saved. This leaves the Purchase Order in an inconsistent state, where the received quantity exceeds the ordered quantity. **Steps to reproduce:** - Install the Purchase and Inventory modules. - Create a Purchase Order with one storable product. - Set the ordered quantity to 10. - Confirm the Purchase Order. - Receive all 10 units and validate the receipt. - Return to the Purchase Order. - Change the ordered quantity from 10 to 5. - Save the Purchase Order. **Observed Behavior:** The Purchase Order is saved successfully even though only 5 units are ordered while 10 units have already been received. This results in an inconsistent state because the ordered quantity becomes lower than the quantity already received, breaking the expected business logic and potentially leading to inconsistencies between purchase and stock data. **Previous behavior:** Until v18.0, Odoo prevented users from decreasing the ordered quantity below the quantity already received by raising a validation error. Starting from v18.3, following the introduction of the new purchase quantity update flow (see PR #209110), this validation is no longer applied when updating the ordered quantity, allowing the Purchase Order to be saved in an inconsistent state. **Cause:** The new purchase quantity update flow introduced in v18.3 updates the Purchase Order line without validating that the new ordered quantity remains greater than or equal to the quantity already received. As a result, decreasing the ordered quantity below `qty_received` is accepted, creating an inconsistent Purchase Order where the received quantity exceeds the ordered quantity. This regression was introduced because the validation present in the previous flow is no longer enforced in the new update flow. **Fix:** Restore the missing validation in the new purchase quantity update flow to prevent decreasing the ordered quantity below the already received quantity. If a user attempts to do so, raise a `UserError` instructing them to create a return before reducing the ordered quantity. opw-[6270228](https://www.odoo.com/odoo/project/49/tasks/6270228)
18 changes
Enhancements to existing features
The website builder now shows a proper preview image for the AI live chat snippet, even when live chat is not installed. Users can also preview the fallback contact button on hover, making the editing experience clearer and more consistent.
Original PR description
*:ai_website_livechat Problems: 1) There's no preview of the livechat snippet in the website builder. If ai_website is installed but not livechat, there's no preview image for the snippet resulting in a cluttered and inconsistent UX. 2) There is no preview on hover for the livechat preview button. Unlike other odoo builder options, the user cannot see what the livechat preview button would look like if hovered over. Solutions: 1) An image has been added `ai_livechat.png` which is shown on preview 2) The AI livechat fallback is previewable and defaults to "Contact Us" linking to the /contactus page. Task-5248712
This updates internal tests for the rental website planning feature to match recent Google Analytics 4 tracking behavior. It helps keep automated checks reliable when analytics tracking is enabled, with no expected change for day-to-day users.
Original PR description
`tracking_info` is now only computed when `google_analytics_key` is set, and `item_id` now uses the template id as a string rather than the variant id as an integer. Set the key in `setUpClass` and update assertions accordingly. See : - https://github.com/odoo/odoo/pull/253856
The manufacturing work order display was slightly simplified by moving an internal setting to the main screen component instead of sharing it more broadly. This reduces unnecessary internal complexity without changing how users interact with the feature.
Original PR description
This commit removes localStorageName from env. It was added in the env but never used in child components so it can be set on the root component.
Resolved issues and error corrections
Restored automated checks for online payment flows in self-order and kiosk preparation display scenarios. This helps ensure payment journeys continue to work correctly and reduces the risk of regressions reaching customers.
Original PR description
The four online payment preparation display tests were skipped because their tour never reached the online payment step. - Register the tour, and the `pos_self_order` tour utils it imports, in `web.assets_tests`. The tour leaves the self-order SPA for the `/pos/pay/<id>` payment portal page, where only the frontend bundle is loaded, so without this the tour is gone from the registry as soon as the page is unloaded. - Make the "Pay" step use `expectUnloadPage: true` and wait for the payment portal submit button, so the tour actually reaches the payment page instead of ending on the self-order page. - Use the `test_online_payment_kiosk_qr_code` tour for the two kiosk tests, which stay in the kiosk and check the QR code. - Unskip the four tests and move their duplicated setup into a kiosk and a self-order helper. task-id: 6244255
The Timesheet Assistant no longer suggests calendar events marked as available. This keeps recommendations focused on events that may need timesheet entries and reduces distractions for users.
Original PR description
## Previous Behavior In the Timesheet Assistant view, calendar events marked as *available* were still being suggested. These events are not intended to be timesheeted and should not appear in the assistant’s recommendations. Their presence could also obscure more relevant events that require user attention. ## New Expected Behavior Calendar events marked as *available* are now excluded from Timesheet Assistant suggestions. task-[6431591](https://www.odoo.com/odoo/project/4105/tasks/6431591) Forward-Port-Of: odoo/enterprise#126183
The expense Stripe cardholder field now uses the standard setup for selection fields, ensuring filters defined in the view are applied correctly. This prevents users from seeing or choosing inappropriate cardholder records when managing expense card details.
Original PR description
After https://github.com/odoo/odoo/issues/196785; the standard way to build a custom m2o field in JS is to call a method from the Many2one module, instead of extending an object from it. This commit solves issues regarding domain in the view not being passed to the widget opw-6399906 Forward-Port-Of: odoo/enterprise#125346
This change corrects how Timesheet Grid recognizes Discuss-related rules so notification count badges do not interfere with matching. It helps ensure the intended automation or guidance continues to work reliably when users have unread notifications.
Original PR description
task: 6416889 Forward-Port-Of: odoo/enterprise#125877 Forward-Port-Of: odoo/enterprise#125519
The Field Service planning map now checks assignments more reliably before showing the routing popup. This prevents errors when planning groups contain unassigned work or translated labels, improving stability for schedulers.
Original PR description
This commit fixes an issue where we search the resources' types in a group's records, possibly not having any resource. Prior to this commit, a condition filtered out the "None" group. However, this causes three issues: 1. The condition does not consider translations (so this would fail for the "None" group in French for instance); 2. If there is any other group than Open Shifts not having resources, this would fail. 3. If there is another group that does not belong to a resource or to Open Shifts that has some records without resources, we should not display the popup. Instead, we dynamically check whether the groupId is part of the resource_ids of *every* group's record in order to display the popup. no-task Forward-Port-Of: odoo/enterprise#126394
The printer selection popup now correctly limits choices to printers assigned for the report. This helps users choose the right printer and avoids accidental printing to unrelated devices.
Original PR description
This commit fixes the domain for the printer selection popup when printing a report. The assigned printers were not taken into account. task-6332442 Forward-Port-Of: odoo/enterprise#122404
The timesheet assistant now keeps its suggestions aligned with the date the user most recently selected, even when switching dates quickly. This prevents outdated suggestions from another day appearing due to delayed background requests.
Original PR description
Before this commit, when the user hits multiple times the arrow button to change the date displayed in timesheet assistant, the suggestions displayed could be the suggestions from another day because a rpc is made each time the user changes the date and amoung all rpcs call, the one which takes more time then the one will be taken but it is not necessary the date shown in the view. This commit uses `KeepLast` class to avoid the concurrency issue with those rpcs to be able to always take the last rpc call to get the data. Forward-Port-Of: odoo/enterprise#126323 Forward-Port-Of: odoo/enterprise#126283
This fix prevents an error when creating a Hong Kong payslip for an employee whose contract start date is missing. Payroll users can now select the employee and continue payslip preparation without the system crashing, while existing handling for missing dates remains in place.
Original PR description
Currently, an error occurs when a user sets an employee on a payslip. **Steps to Reproduce:** - Install `l10n_hk_hr_payroll` with demo data. - Switch to the `Hong Kong` company. - Create an…
Currently, an error occurs when a user sets an employee on a payslip. **Steps to Reproduce:** - Install `l10n_hk_hr_payroll` with demo data. - Switch to the `Hong Kong` company. - Create an `employee` and make sure that the employee's version has no `contract start date`. - Go to `Payroll` > `Payslips` > `Payslips`. - Create a `payslip` and set that employee. `TypeError: '<' not supported between instances of 'datetime.date' and 'bool'` When a user sets an employee on a payslip, the system computes the worked day lines [1]. If the salary structure uses worked day lines, it creates the corresponding records [2] and calculates out days and out hours based on the contract dates. During this process, the payslip dates are compared with the version's contract start date. If the version does not have a contract start date, it raises an error [3]. This commit ensures that the payslip dates are compared with the version's contract start date, and that out days and out hours are calculated only when the contract start date exists. Cases where no contract start date is defined are already handled in payslip [4]. [1]: https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1964 [2]: https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1985-L1988 [3]- https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/l10n_hk_hr_payroll/models/hr_payslip.py#L309 [4]- https://github.com/odoo/enterprise/blob/03787659236cbcb46c27acebf410ee3d1e9eb15c/hr_payroll/models/hr_payslip.py#L1092-L1096 sentry-7632216317 Forward-Port-Of: odoo/enterprise#120234
The Argentine electronic invoicing test setup was adjusted so a live currency-rate check is not run during daily builds that block external web requests. This prevents avoidable build failures while still allowing the check to run in nightly testing with the right access.
Original PR description
Description of the issue this commit addresses: The live ARCA currency rate test keeps the inherited `standard` tag. It is therefore selected by daily builds whose HTTP guard blocks the request. The guard also blocks it when selected by the external localization suite. --- Desired behavior after this commit is merged: This commit removes the `standard` tag from the live ARCA test. Daily builds skip the test while nightlies still run it with HTTP access. --- runbot-[238857](https://runbot.odoo.com/odoo/error/238857) Forward-Port-Of: odoo/enterprise#125692
Date and date-time fields are now hidden from the column selection popover once they have already been added, just like other fields. This prevents duplicate columns from being created and avoids inconsistent spreadsheet behavior for users configuring list views.
Original PR description
Current behavior before PR: - Date and datetime fields remained visible in the popover after being added as columns, allowing the same field to be added multiple times. - Since column fields do not consider granularity, allowing duplicate date fields could create duplicate IDs and inconsistent behavior. Desired behavior after PR is merged: - Treat date and datetime fields the same as other column fields when determining which fields to display in the popover. - Once a date or datetime field is added as a column, it is no longer shown in the popover to prevent duplicate IDs. Task: [6295794](https://www.odoo.com/odoo/project/2328/tasks/6295794) Forward-Port-Of: odoo/enterprise#123463
This fix makes automated tests for assigning planning resources more stable by avoiding timing-related selection mistakes. It helps reduce false test failures, supporting smoother validation and delivery of Planning field service changes.
Original PR description
This commit fixes undeterministic failures in the `many2many_avatar_resource` tests. Previously, resources were added by typing its name, waiting for the list to update and clicking on the resource. However, `edit` auto-completes with some delay, thereby resulting in random errors where the first resource from the list was added. Instead, we let the `edit` autocomplete to run in order to add a resource, ensuring the first resource from the list is not added as a consequence. runbot-error-941174 Forward-Port-Of: odoo/enterprise#126482
This fix makes Dominican Republic 606 report tests use a consistent document setup instead of depending on which optional modules happen to be installed. It also stabilizes reversal dates, reducing false test failures and helping keep report behavior reliable for customers using either configuration.
Original PR description
Whether DO journals use LATAM fiscal documents depends on `l10n_do_edi` being installed: it is what supplies the `_localization_use_documents` override for DO. l10n_do_reports doesn't depend on it, so the tests inherited whichever configuration the build happened to install, and only went red on the per-module build. Without the EDI module the reversal's `ecf_34` document type produced the name "E34 B0400000001", which the yearly sequence regex reads as year 34; checked against a 2024 date, the sequence constraint rejects it on post. Pin the flag explicitly instead, and run the assertions against both configurations, since customers run both: the NCF is read off the fiscal document number with e-CF, and off the reference without it. Also pin the reversal's accounting date. Left out, `_get_accounting_date` pushes it to the end of the month once the invoice date is in the past, which made the test depend on the date it ran. runbot-error-944488
Code cleanup and technical improvements
The VOIP audio manager now tracks changes to call and audio settings in a cleaner way, ensuring observers are properly cleaned up when no longer needed. This reduces the risk of hidden background work building up over time without changing the user-facing calling experience.
Original PR description
Enterprise counterpart of "[REF] mail: drop the onChange queue for owl effects", which explains the API. Before this commit, the audio manager observes three fields by name and drops the dispose function each observer returns, so nothing ever stops those observers. This commit turns the three observers into dependency lists on the rtc and settings records, keeping `initialRun: false`: the refresh at the end of setup does the initial sync. The records dispose these observers. The audio manager tests take the real store: a fake store has no record to observe. One of them counted the calls to `enumerateDevices` to know that the status was refreshed, and with the real store there are two audio managers, the one of the voip service and the one the test builds, both enumerating the devices. That test counts the refreshes of its own manager instead. https://github.com/odoo/odoo/pull/279818
This update renames internal enrollment-related campaign fields to make their purpose clearer and easier to maintain. It also adds safeguards around the enrollment uniqueness field so future campaign setup is more reliable, with no intended change to user-facing behavior.
Original PR description
In order to ease understanding, prepare future changes and ease grep through code, rename enroll-specific fields on campaign model * domain -> enroll_domain * unique_field_id -> enroll_unique_field_id No functional change should come with this PR. Task- Prepares Task-
VoIP configuration such as credentials, device number, and do-not-disturb timing is now read from the dedicated user settings record instead of a mixed local settings area. This aligns VoIP with the newer settings structure, making preferences clearer and easier to maintain without changing the visible user experience.
Original PR description
Before this commit, the voip columns of res.users.settings were read off store.settings, the record that mixed the server row with the local preferences of the device. Reminder that the mail counterpart of this commit splits the two: res.users.settings becomes a record of its own, reached from its owner, store.self_user.res_users_settings_id, and store.settings keeps only the local preferences. This commit declares the voip columns on that record, sends them through _store_settings_fields, and reads a credential, the device number and the do-not-disturb time off it. Note that the field declarations sit in core/common, reachable from every bundle, while the behavior stays in core/web. https://github.com/odoo/odoo/pull/279128
11 changes
Enhancements to existing features
This update adds and improves automated checks for marketing automation flows, especially around failed or bounced messages and scheduled synchronization. It helps reduce the risk of regressions in campaign enrollment and message handling, improving confidence that automated campaigns continue to behave correctly.
Original PR description
Backport various tests added in Odoo 19.4+ in order to better spot potential regressions. Add new tests for synchronization cron behavior, notably in case of failure.
Resolved issues and error corrections
The Planning app now applies employee and material filters correctly for open shifts. This prevents shifts with assigned resources from being incorrectly included or excluded, making planning views more reliable for schedulers.
Original PR description
Before this commit, the domain wrongly assumes that we always search on shifts having no role or a role containing resources of types 'user' or 'material' (1). Additionally to the basic domain which searches on the shifts having resources of types 'user' or 'material' (2). After this commit, we add a condition on domain (1) to only apply it for open shifts (shifts having no resource_id). no-task Forward-Port-Of: odoo/enterprise#126247
A small issue in the journal report actions was corrected by removing unused date values that could cause confusing or incorrect behavior. This helps keep the accounting report interface consistent and reliable for users.
The self-order flow test now reflects that takeaway is selected automatically when it is the only available option. This keeps automated checks aligned with the current customer experience and helps avoid false test failures.
Original PR description
In this commit: - The takeaway preset is now automatically selected when it is the only available option. Remove the explicit "Takeaway" selection step from the tour to match the updated behavior. Task:6217791 Community PR : https://github.com/odoo/odoo/pull/274301
The AI chat now works more reliably when users move into areas such as Shopfloor that do not provide view-switching information. Instead of crashing when a message is sent, the system safely continues with no available view options listed.
Original PR description
### Issue
When AI chat is used in views where `config.viewSwitcherEntries` is not initialized, sending a message raises a `TypeError` because the code attempts to call `.map()` on an undefined value.
### Steps to Reproduce
[Video](https://drive.google.com/file/d/1i7kWDnmv4mebGtf1to12BNHCG5omBTXl/view?usp=sharing)
1. Click the **Ask AI** button.
2. Open the AI chat.
3. Keep it open and navigate to the **Shopfloor** app.
4. Send a message in the AI chat.
### Error
```text
TypeError: Cannot read properties of undefined (reading 'map')
at WithSearch.getCurrentViewInfo
```
### Fix
Safely handle cases where `config.viewSwitcherEntries` is undefined by using optional chaining and falling back to an empty array.
**Before**
```js
result.available_view_types = config.viewSwitcherEntries.map((v) => v.type);
```
**After**
```js
result.available_view_types =
config.viewSwitcherEntries?.map((v) => v.type) || [];
```
opw-6414684Bank reconciliation now safely handles imported statement lines whose payment reference contains only spaces. This prevents an unexpected error when assigning accounts, improving reliability for accounting teams working with imported bank data.
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
The Barcode app welcome screen now correctly shows guidance to scan a package when package tracking is enabled. This helps warehouse users find transfers from package scans without missing an available workflow.
Original PR description
When packages are enabled, the barcode scanner welcome screen does not display the instructions for scanning a package. ## Steps to reproduce - Enable `Packages` in Inventory settings. - Open the Barcode application. - Observe the instructions listed on the welcome/landing page. - Notice that the instruction `Scan a package to find a transfer` is missing, even though packages are enabled. ## Issue The MainMenu component has a getter barcodeHomeHelper that checks this.packageEnabled to construct the barcode scanner helper bullet points. However, during setup, the configuration value was incorrectly assigned to this.packagesEnabled. ## Fix Correct the variable name typo in the main menu setup so that the package related instructions are correctly displayed when packaging is enabled. [^1] [^1]: 
This update fixes incorrect Italian field labels in the Balance Sheet reports. It improves clarity for Italian-speaking accounting users by ensuring report wording matches the correct translations.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting and l10n_it 2. Install and switch to italian language 3. Go to Balance Sheets and select Balance Sheet (IT) 4. Some words are not correct [Here]( https://docs.google.com/spreadsheets/d/1-w83oAHTxDRIi-W_VSJiscNclw-yijzQUHOgMnTq7jE/edit?gid=0#gid=0) the wrong fields with their correct translations. opw-6424609
Shipments sent through Sendcloud now avoid including VAT fields when the contact's VAT value becomes empty after cleanup, such as placeholder characters. This prevents valid deliveries from being rejected because of blank tax number data.
Original PR description
Follow up of #124245. There remains an edge case where a contact's vat number might be comprised only of characters removed by `_sanitize_vat_number` (eg just `/` as a placeholder). In such cases, the `if ship_to.vat` condition is True so we end up sending data but with an empty value field. This leads to the delivery being rejected by Sendcloud. Might as well change it for `ship_from` too. ----- Ticket: opw-6384603
The change updates cash basis accounting report tests so they use the account configured in the system instead of assuming a fixed account code. This prevents false test failures when account codes differ between database setups, improving release validation reliability.
Original PR description
Description of the issue this commit addresses: Commit 63f5646cfd75 made the tests use the default outstanding account but hard-coded code 101403. In an all-module database, generated account codes depend on existing accounts, so Outstanding Receipts may use code 101404 and make otherwise correct report assertions fail. --- Desired behavior after this commit is merged: This commit derives the expected report line name from the configured outstanding receipts account, making the assertions independent of its generated code. --- runbot-[231581](https://runbot.odoo.com/odoo/error/231581)
Features or functions removed from Odoo
An outdated automated test for structured references in accounting reconciliation was removed because the related behavior is no longer supported after a previous change. This keeps the test suite aligned with the current, simpler reconciliation setup and avoids misleading failures.
Original PR description
After merging pr #117256 the behavior for creating auto reconcile models for structured reference is no longer working so the test for checking that behavior should be removed. This was an FP request to use contains instead of regex in auto reconcile model creation because it was too complicated for users. no task id
7 changes
Resolved issues and error corrections
This fix corrects how Planning filters employees and materials when dealing with open shifts. It prevents unrelated shifts from being included or excluded incorrectly, making scheduling views more accurate for planners.
Original PR description
Before this commit, the domain wrongly assumes that we always search on shifts having no role or a role containing resources of types 'user' or 'material' (1). Additionally to the basic domain which searches on the shifts having resources of types 'user' or 'material' (2). After this commit, we add a condition on domain (1) to only apply it for open shifts (shifts having no resource_id). no-task Forward-Port-Of: odoo/enterprise#126247
Splitting a multi-page PDF in Documents now keeps the resulting pages in a predictable order. This prevents users from seeing pages appear randomly in the kanban view when the files are created at the same time.
Original PR description
steps: - upload a multi-page pdf - split all the pages -> they now show in a random order The issue is that the current documents are sorted by create_date desc, but the split creates all the different documents at the same time so they are sorted in the order they happen to be on the disk. We now add a sort by id to act as a tie-breaker. opw-6176840
Dietikon is now assigned to the canton of Zurich (ZH) instead of Aargau (AG) in Swiss payroll data. This helps ensure payroll-related Swiss location data is accurate for employees or customers associated with Dietikon.
Original PR description
Hi The Kanton for Dietikon is wrong for the swiss hr_payroll. It should be ZH instead of AG. Source: I lived there and from feedback from a customer. PR changes AG -> ZH for Dietikon. Note that this change should propagate to 19.0, but this file is not present in that branch (yet).
The Helpdesk Knowledge website module now includes the missing dependency needed for installation in a specific setup mode. This prevents installation failures and helps ensure the module can be deployed reliably.
Original PR description
Trying to install website_helpdesk_knowledge with the flag --skip-auto-install would fail due to website_helpdesk_knowledge/views/helpdesk_views.xml referencing `is_published` which is only defined in `website` https://github.com/odoo/odoo/blob/4d60d5693f3d0253a28dd38412125b2fc6d6b41f/addons/website/models/mixins.py#L184 Reproduciton steps: odoo/odoo-bin --addons-path odoo/addons,odoo/odoo/addons,enterprise,design-themes -d oes_runbot --stop-after-init --log-level=test --max-cron-threads=0 -i website_helpdesk_knowledge --skip-auto-install Adding `website_knowledge` pulls in the relevant dependencies resulting in the field being found and valid Affects **18.0** and **19.0**, **nothing in between**
This fixes an automated test for Field Service worksheets by ensuring the setup avoids an unexpected example-template wizard. The change helps keep quality checks reliable across databases with or without demo data, without affecting normal user workflows.
Original PR description
When there is only one worksheet, the ‘Explore Worksheets Using an Example Template’ wizard opens. Because of this, the test fails without demo data. If we add steps for this wizard, it won’t open when there is more than one worksheet, which will again cause the test to fail. Also, we cannot add this conditon on step. Therefore, to ignore this wizard, i created a worksheet before running the tour so that the wizard does not open. backport of https://github.com/odoo/enterprise/commit/5bb2d96087f50f7df1d51bbd4c31bb23b6d313da runbot-242471
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots & Serial Numbers in Settings. - Create two products: Car and Engine. - Configure Engine to use Unique Serial Number tracking (Inventory →Traceability). - Set the on-hand quantity of Engine to 1 with serial number 0001. - Create a BoM for Car using Engine as a component. - Create and confirm a man
Original PR description
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots &…
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots & Serial Numbers in Settings. - Create two products: Car and Engine. - Configure Engine to use Unique Serial Number tracking (Inventory →Traceability). - Set the on-hand quantity of Engine to 1 with serial number 0001. - Create a BoM for Car using Engine as a component. - Create and confirm a manufacturing order for Car. - Click `Consumed` for the component and click Produce All. - Navigate to Lots & Serial Numbers → Engine → 0001 → Traceability. - Click the arrow next to the manufacturing order reference, then click Print. ## Observed Behavior: An `Arbitrary Uncaught Python Exception` traceback is raised, resulting in a 404 error. ## Root Cause: This issue occurs because, when the user clicks the arrow button in the traceability report, the template [1] invokes the `onClickUpDownStream` function. This function adds the URL `/stock/output_format/stock/active_id` to the context , as shown in [2]. Later, when the user clicks the Print button, `onClickPrint()` [3] constructs the print URL using the `controllerUrl` value by replacing the active model and active ID placeholders with values from the context. However, the URL stored in the context contains `/active_id` instead of `:active_id`. As a result, the placeholder replacement does not occur, leaving the URL unchanged. This causes the print action to use an invalid URL, ultimately resulting in a 404 error. As shown in [4], `controllerUrl` is assigned directly from the context. [1]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.xml#L52-L56 [2]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L105-L118 [3]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L120-L131 [4]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L53-L55 ## Solution: Pass the correct URL in the context so that the active ID placeholder can be replaced correctly during the print action. This ensures that the generated print URL is valid, allowing the user to print the report without encountering any errors. opw-6372834 Forward-Port-Of: odoo/odoo#276449
opw-6410368
Original PR description
opw-6410368