Thursday, August 13, 2026
40 changes · saas-19.4
Enhancements to existing features
Add account 2284 GBRT Tax Payable and rework the GBRT tax distribution to book to it against 6771 Taxes & dues. Update the Traditional Chinese tax descriptions and remove the 0% Deemed Sales tax. task-6427283 Forward-Port-Of: odoo/odoo#281109
Original PR description
Add account 2284 GBRT Tax Payable and rework the GBRT tax distribution to book to it against 6771 Taxes & dues. Update the Traditional Chinese tax descriptions and remove the 0% Deemed Sales tax. task-6427283 Forward-Port-Of: odoo/odoo#281109
This commit adds a "Reload Data" button to the traceback dialog for PWA applications. When clicked, the user is asked to confirm the action. Once confirmed, all locally stored browser data is cleared, allowing the POS to recover from errors caused by corrupted or outdated local data. task-6388234 Forward-Port-Of: odoo/odoo#282150 Forward-Port-Of: odoo/odoo#276559
Original PR description
This commit adds a "Reload Data" button to the traceback dialog for PWA applications. When clicked, the user is asked to confirm the action. Once confirmed, all locally stored browser data is cleared, allowing the POS to recover from errors caused by corrupted or outdated local data. task-6388234 Forward-Port-Of: odoo/odoo#282150 Forward-Port-Of: odoo/odoo#276559
…h lookup _search_phone_mobile_search previously searched only raw number fields returned by _phone_get_number_fields (e.g. mobile, phone). E164-normalized phone_sanitized was ignored, so searching by a sanitized value could miss records that had no match on the raw fields. This commit: - Extracts _phone_get_searchable_fields() so that both init() and _search_phone_mobile_search build the same searchable field list, appending phone_sanitized alongside mobile/phone when available. - Add
Original PR description
…h lookup _search_phone_mobile_search previously searched only raw number fields returned by _phone_get_number_fields (e.g. mobile, phone). E164-normalized phone_sanitized was ignored, so searching by a sanitized value could miss records that had no match on the raw fields. This commit: - Extracts _phone_get_searchable_fields() so that both init() and _search_phone_mobile_search build the same searchable field list, appending phone_sanitized alongside mobile/phone when available. - Adds expression indexes for phone_sanitized in init() so the REGEXP_REPLACE-based queries hit indexes instead of scanning tables. - Guards init() with self._auto to prevent index creation on AbstractModel subclasses that lack a physical table. Task-6395518 ENTPR: odoo/enterprise#124797 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281598 Forward-Port-Of: odoo/odoo#278018
Resolved issues and error corrections
The Planning menu now appears in the intended order when Field Service is installed. This keeps navigation consistent for users without changing the standard Planning menu setup when Field Service is not installed.
Original PR description
Ensure the Planning menus are displayed in the correct order when Field Service is installed, without affecting the standard Planning menu structure. task-6443397
Documentation and clarification updates
Description of the issue/feature this PR addresses: Signing the Odoo Individual Contributor License Agreement v1.0. Name: Alejandro Martínez GitHub login: alexmbar Email: alexmbar891@gmail.com Country: México Current behavior before PR: I have no CLA signature on file, so my pending l10n_mx contributions (#264576, #264580, #264582, #264583) fail the legal/cla check and cannot be merged. Desired behavior after PR is merged: doc/cla/individual/alexmbar.md is present and the legal/
Original PR description
Description of the issue/feature this PR addresses: Signing the Odoo Individual Contributor License Agreement v1.0. Name: Alejandro Martínez GitHub login: alexmbar Email: alexmbar891@gmail.com Country: México Current behavior before PR: I have no CLA signature on file, so my pending l10n_mx contributions (#264576, #264580, #264582, #264583) fail the legal/cla check and cannot be merged. Desired behavior after PR is merged: doc/cla/individual/alexmbar.md is present and the legal/cla check passes for my contributions. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281391
Miscellaneous changes
- Compute the standard durations for all French leaves in a single `_get_durations()` call instead of recomputing them for each leave. - Reuse the precomputed duration mapping while calculating the French legal duration for each leave. - Keep the existing French-specific duration calculation unchanged, including public holidays, company calendar, date extension, and half-day handling. This avoids repeated ORM computations when processing multiple French leaves in a batch an
Original PR description
- Compute the standard durations for all French leaves in a single `_get_durations()` call instead of recomputing them for each leave. - Reuse the precomputed duration mapping while calculating the…
- Compute the standard durations for all French leaves in a single `_get_durations()` call instead of recomputing them for each leave. - Reuse the precomputed duration mapping while calculating the French legal duration for each leave. - Keep the existing French-specific duration calculation unchanged, including public holidays, company calendar, date extension, and half-day handling. This avoids repeated ORM computations when processing multiple French leaves in a batch and significantly improves the performance of leave duration computation. Performance testing was performed using the `hr.leave.employee.report` introduced in 19.1, which calls `_get_durations()` on a large batch of virtual leaves. Performance testing on a database containing 677 leaves, including 298 French leaves: | Metric | Before | After | |------------------------------------|-----------------|-------------| | Standard duration computations | 298 | 1 | | Total `_get_durations()` | >169s (timeout) | ~24s | not specific to the employee report and benefits any caller that invokes _get_durations() on a larger batch. **opw-6421323** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281914 Forward-Port-Of: odoo/odoo#281165
The Timesheets Assistant now ignores the current user's own contact when matching Gmail email recipients to customers. This prevents unrelated emails from suggesting tasks or projects simply because the user's address appears in the message.
Original PR description
Before this commit, the Timesheets Assistant resolved every address found in a read or composed email to a partner, then matched the event to a task or project having that partner as its customer. The current user is a recipient of every email they receive, so their own address is present in the "To" or "Cc" fields of every `reading_email` event. As a result, any task whose customer was the current user could be suggested for those emails. This commit excludes the current user's partner from that lookup. task-6438374 Forward-Port-Of: odoo/enterprise#127422 Forward-Port-Of: odoo/enterprise#126448
Accounting read-only users can now see the General section on the Accounting tab of contact records when they have the proper access rights. This restores visibility of bank account details that were accidentally hidden by a view configuration issue.
Original PR description
Problem: The General group of the Accounting tab of the partner form view is not visible to some users, even if they have the access rights to see it. Steps to reproduce: 1. Create a user or edit an existing one, giving them Accounting Read-Only access rights. 2. Log in with that user. 3. Go to Contacts and select a partner. 4. Open the Accounting tab 5. Notice how the General group (with the bank account details) is not visible. Cause: In the account_accountant module, the partner form view is inherited in one of the views to add additional groups to the General group of the Accounting tab. However, it doesn't add the new group, but instead replaces the existing groups with the new one. opw-6413683 Forward-Port-Of: odoo/enterprise#126679
This fixes an incorrect value used when reporting Swiss withholding tax changes in payroll declarations. It helps ensure employee payroll data is submitted with the expected official classification, reducing the risk of rejected or inaccurate declarations.
Original PR description
task-6116327 Forward-Port-Of: odoo/enterprise#127745
Fixed an issue in Payroll where saving an employee declaration without selecting an employee caused an error. Users can now create or save these records without being blocked by a traceback, improving reliability in the declaration workflow.
Original PR description
When creating an employee declaration without selecting an employee, a traceback occurs. Steps to reproduce the error: - Install ``l10n_be_hr_payroll`` module with demo data - Switch to Belgian…
When creating an employee declaration without selecting an employee, a traceback occurs. Steps to reproduce the error: - Install ``l10n_be_hr_payroll`` module with demo data - Switch to Belgian company - Go to Payroll > Reporting > Individual Accounts > Create a new Individual Account > Click on Eligible Employees > Create a new employee declaration without employee > Save Traceback: ```py ValueError: Expected singleton: hr.employee() ``` https://github.com/odoo/enterprise/blob/000544c3d5b93e194264e15bb73d9599525106e3/hr_payroll/models/hr_payroll_employee_declaration.py#L71 The ``_compute_version_id()`` method calls ``_get_version()``. When ``employee_id`` is empty, ``_get_version()`` is invoked on an empty ``hr.employee`` record, and its ``ensure_one()`` call raises the above traceback at [1]. [1]: https://github.com/odoo/odoo/blob/3c358ae2badad69b125695a97b4a14e8ab77fccd/addons/hr/models/hr_employee.py#L745-L750 sentry-7625826444 Forward-Port-Of: odoo/enterprise#125175
The Helpdesk Stock flow now shows the Replace button even when no customer is selected. This keeps the ticket interface consistent with related actions and reduces confusion for support teams handling replacements.
Original PR description
Adjust the `invisible` condition to make the button visible even if no customer is selected, for consistency with other buttons --- task-6103996 Forward-Port-Of: odoo/enterprise#124467
### Expected behavior: When an e-invoice is created from POS using SInvoice, existing behavior is to directly submit it ### Current behavior: When a POS order with "Invoice" ticked is confirmed in a VN company, the e-invoice is NOT automatically submitted to SInvoice. Users must manually trigger the send wizard. ### Steps to reproduce: 1. Install l10n_vn_edi_viettel_pos, activate VN company 2. Make an order from POS and check the invoice box 3. Observe SInvoice subsmission error ##
Original PR description
### Expected behavior: When an e-invoice is created from POS using SInvoice, existing behavior is to directly submit it ### Current behavior: When a POS order with "Invoice" ticked is confirmed in a…
### Expected behavior: When an e-invoice is created from POS using SInvoice, existing behavior is to directly submit it ### Current behavior: When a POS order with "Invoice" ticked is confirmed in a VN company, the e-invoice is NOT automatically submitted to SInvoice. Users must manually trigger the send wizard. ### Steps to reproduce: 1. Install l10n_vn_edi_viettel_pos, activate VN company 2. Make an order from POS and check the invoice box 3. Observe SInvoice subsmission error ### Cause of the issue: - caused by commit https://github.com/odoo/odoo/commit/4f30306ccc9ff82911f90ed8b3714b212e4b77dc, which decoupled invoice PDF generation from POS order validation by setting `generate_pdf=False` in context when `use_download_invoice` is False (default) - `_generate_pos_order_invoice()` to skip `_generate_and_send()`, which skips VN SInvoice submission. ### Fix: Override `_generate_pos_order_invoice()` to force generating PDF when auto-send to SInvoice is enabled, restoring `_generate_and_send()` during order validation opw-6427675
Steps to reproduce: ------------------- 1. Install `hr` module 2. Create two employees (e.g., emp1 and emp2) and assign emp1 as the manager of emp2 → emp2 is now a direct subordinate of emp1 3. In the employee list view, apply the custom filter "Direct subordinates is set" (child_ids != False) → emp1 appears in the results as expected 4. Archive emp2 5. Apply the same filter again → emp1 still appears in the results even though it has no active subordinates Issue
Original PR description
Steps to reproduce: ------------------- 1. Install `hr` module 2. Create two employees (e.g., emp1 and emp2) and assign emp1 as the manager of emp2 → emp2 is now a direct subordinate of emp1 3. In…
Steps to reproduce: ------------------- 1. Install `hr` module 2. Create two employees (e.g., emp1 and emp2) and assign emp1 as the manager of emp2 → emp2 is now a direct subordinate of emp1 3. In the employee list view, apply the custom filter "Direct subordinates is set" (child_ids != False) → emp1 appears in the results as expected 4. Archive emp2 5. Apply the same filter again → emp1 still appears in the results even though it has no active subordinates Issue: ------ When an employee (e.g., `emp2`) is archived, their manager (`emp1`) should no longer appear in the "Direct subordinates is set" (child_ids != False) filter — since `emp1` no longer has any active subordinates. However, `emp1` still appears in the search results after `emp2` is archived, because the underlying EXISTS subquery checks all subordinates regardless of their active state. Cause: -------- Before this commit 5ef007a, `osv.expression`, filtering on a One2many field would automatically search against [active co-records ](https://github.com/odoo/odoo/blob/5f65e92d7fa341193df53f5aba1620b596f9a1ec/odoo/osv/expression.py#L1260-L1265)only by default. After that commit, the `condition_to_sql` method in `_RelationalMulti` constructs the comodel with [active_test=False](https://github.com/odoo/odoo/blob/463ca4cf867812890c17d1e1abf7640b04f70ad0/odoo/orm/fields_relational.py#L672-L686) when resolving relational field conditions. This causes the EXISTS subquery generated for `child_ids != False` to compare against all subordinates. (including archived ones rather than active ones only). Solution: --------- Added a callable `domain` attribute on the `child_ids` field definition so that only active subordinates are considered by default. This ensures [get_comodel_domain()](https://github.com/odoo/odoo/blob/2d8b24a791b6fe6bb214c32d4fb58b3d46eca70b/odoo/orm/fields_relational.py#L75-L85) returns a server-side domain that filters out archived subordinates, making the `child_ids != False` filter behave as expected. opw-6193104 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281222 Forward-Port-Of: odoo/odoo#266658
Description of the issue/feature this PR addresses: Installing Odoo via the .deb package continuously causes issues with the asset bundles. This is because of the following daisy chain of behaviors: - `dpkg-buildpackage` parses `SOURCE_DATE_EPOCH` from debian/changelog and then clamps the Modified date of all files to at max that epoch ([src](https://launchpad.net/debian/+source/dpkg/1.18.8)). The relevate date is the one written after the email in the topmost changelog entry - This is pr
Original PR description
Description of the issue/feature this PR addresses: Installing Odoo via the .deb package continuously causes issues with the asset bundles. This is because of the following daisy chain of behaviors:…
Description of the issue/feature this PR addresses: Installing Odoo via the .deb package continuously causes issues with the asset bundles. This is because of the following daisy chain of behaviors: - `dpkg-buildpackage` parses `SOURCE_DATE_EPOCH` from debian/changelog and then clamps the Modified date of all files to at max that epoch ([src](https://launchpad.net/debian/+source/dpkg/1.18.8)). The relevate date is the one written after the email in the topmost changelog entry - This is preserved when unpacking the .deb package, the OS does not change it - The Asset loading logic in ir.qweb and ir.asset relies on the Modified date (via [`os.path.getmtime`](https://github.com/odoo/odoo/blob/17.0/odoo/addons/base/models/ir_asset.py#L49)) to determine the hash that serves a Version for the asset bundles ([src](https://github.com/odoo/odoo/blob/17.0/odoo/addons/base/models/assetsbundle.py#L775), [src](https://github.com/odoo/odoo/blob/17.0/odoo/addons/base/models/assetsbundle.py#L148)) - The controller and ir.qweb compiler rely on this Version hash to correctly invalidate outdated asset bundles and force re-generation of the bundle content as neccessary Current behavior before PR: debian/changelog has not been changed or maintained since 2020 and its timestamp remains `Tue, 15 Dec 2020 10:28:49 +0100` This results in the Modified Date being clamped to 2020, which means the files no matter how much is changed always look like last modified on this date. Therefore the Version hash for the asset bundles never changes, and the asset reload logic does not trigger correctly. This is especially dangerous for setups which use several code sources with different file delivery methods, for example installing Community via .deb but Enterprise via git. This results in only some asset bundles not being updated (those not touched by Enterprise modules) while others are, which then generates an OWL error as it detects the content being different between the bundles ([src](https://github.com/odoo/odoo/blob/17.0/addons/web/static/lib/owl/owl.js#L3333)) For versions 18+, a very common result of this behavior is the portal chatter failing to work. This is because the same files like for example mail/static/src/core/common/thread.xml being loaded into both [`portal.assets_chatter`](https://github.com/odoo/odoo/blob/18.0/addons/portal/__manifest__.py#L69), which is not touched by an Enterprise module, but also into [`web.assets_frontend` ](https://github.com/odoo/odoo/blob/18.0/addons/im_livechat/__manifest__.py#L90) via im_livechat, which is a bundle touched by many modules, including Enterprise modules. Thus, is a file in the mail addon is changed, the changes are correctly applied to `web.assets_frontend`, but not `portal.assets_chatter`, causing an OWL error. This is extremely frustrating to fix, since it not only requires a manual Asset Rebuild, but also for every user to empty their Browser Cache, since the assets bundles are so large as to be guaranteed to be cached, and if the old version of the bundle is loaded from cache, the OWL error persists. A similar error can also happen with website, since the assets for the WYSIWIG editor are loaded as a module-specific bundle, `website.assets_wysiwyg`, which also fails to update, while of course the same assets being loaded to the general website asset bundle will be updated. Desired behavior after PR is merged: The builder for the nightly .deb package of Odoo writes a complete debian/changelog entry instead of merely replacing the first line. This entry includes the current date, thus ensuring the Modified date for the files is not clamped to years in the past. Down the line, this fixes the assets loading issue. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269458
Before this commit: The fullscreen button was displayed on mobile mode and was not working. It should be hidden. "o-dashboard-chart-select" has been renamed to "o-chart-menu" and "o-chart-dashboard-item" to "o-chart-menu-item" in this commit 60a671dc3e5a7fe760c468e8d00abd70204f3281 It should have been updated in all occurrences. Task: 6401639 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confir
Original PR description
Before this commit: The fullscreen button was displayed on mobile mode and was not working. It should be hidden. "o-dashboard-chart-select" has been renamed to "o-chart-menu" and "o-chart-dashboard-item" to "o-chart-menu-item" in this commit 60a671dc3e5a7fe760c468e8d00abd70204f3281 It should have been updated in all occurrences. Task: 6401639 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
The test "Image cropper Enter saves and Escape closes in website builder" fails indeterministically on runbot. The error seems to have appeared just after the merging of [1], which introduced a speed-up in test execution. The failure is caused by an image being "invisible" when queried by `contains()`. The most likely cause is that the image is not yet fetched by the time the test runs. The image source is replaced with a `base64` `data:` URL, so that no fetching is required for this
Original PR description
The test "Image cropper Enter saves and Escape closes in website builder" fails indeterministically on runbot. The error seems to have appeared just after the merging of [1], which introduced a speed-up in test execution. The failure is caused by an image being "invisible" when queried by `contains()`. The most likely cause is that the image is not yet fetched by the time the test runs. The image source is replaced with a `base64` `data:` URL, so that no fetching is required for this test. [1]: https://github.com/odoo/odoo/pull/279584 runbot-944664 Forward-Port-Of: odoo/odoo#281794 Forward-Port-Of: odoo/odoo#280333
We still have cases of people being confused by the fact that they send their invoices, reset it to draft, change something, then re-sending. Of course, the re-sending does not send on peppol, as it's already sent. It's more confusing than anything else. Prevent it if they're sent and not in error. task-6459869 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281525
Original PR description
We still have cases of people being confused by the fact that they send their invoices, reset it to draft, change something, then re-sending. Of course, the re-sending does not send on peppol, as it's already sent. It's more confusing than anything else. Prevent it if they're sent and not in error. task-6459869 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281525
Problem: `isVisibleTextNode` fails to check the space visibility in case it is preccedded with a `feff`. Cause: The final check uses `visibleCharRegex` on the preceding node, which excludes zero-width chars like `feff`. But `feff` is not whitespace, so it shouldn't make the adjacent space collapse either. Solution: Check for non-whitespace instead of visibility on the preceding node. task-6397398 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submi
Original PR description
Problem: `isVisibleTextNode` fails to check the space visibility in case it is preccedded with a `feff`. Cause: The final check uses `visibleCharRegex` on the preceding node, which excludes zero-width chars like `feff`. But `feff` is not whitespace, so it shouldn't make the adjacent space collapse either. Solution: Check for non-whitespace instead of visibility on the preceding node. task-6397398 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280331
Posting expenses opens the "Post Entries" wizard. When posting succeeds, the wizard's action redirects to the newly created journal entries, and the framework's action service closes the dialog with `noReload: true` while simultaneously destroying the current list view to mount the new action in its place. `ExpenseListController`'s `onClose` callback ignored this flag and unconditionally reloaded the list via `model.root.load()`. That call goes through `useService`'s `_protectMethod` wrapper, w
Original PR description
Posting expenses opens the "Post Entries" wizard. When posting succeeds, the wizard's action redirects to the newly created journal entries, and the framework's action service closes the dialog with `noReload: true` while simultaneously destroying the current list view to mount the new action in its place. `ExpenseListController`'s `onClose` callback ignored this flag and unconditionally reloaded the list via `model.root.load()`. That call goes through `useService`'s `_protectMethod` wrapper, which swaps in a promise that never resolves once the owning component is destroyed. Since the reload's RPC and the component's teardown race each other, the reload sometimes never resolved, so `onClose` never completed and the wizard dialog stayed open forever. Skip the reload when `noReload` is set: the list is being torn down anyway, and `onClick` already reloads it unconditionally right after the wizard dialog opens, so nothing is lost. opw-6372904 Forward-Port-Of: odoo/odoo#281464
## Steps to reproduce: - Install Employee - Create a 2-week working schedule and set it as the company default - Try to create a new working schedule - Notice when you click save a ValidationErroe arise ## Cause: Two parts where causing this. First when creating a new calendar and we try to fetch default attendances we don't set the sequence in the newly created attendances https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/resource/models/resour
Original PR description
## Steps to reproduce: - Install Employee - Create a 2-week working schedule and set it as the company default - Try to create a new working schedule - Notice when you click save a ValidationErroe…
## Steps to reproduce: - Install Employee - Create a 2-week working schedule and set it as the company default - Try to create a new working schedule - Notice when you click save a ValidationErroe arise ## Cause: Two parts where causing this. First when creating a new calendar and we try to fetch default attendances we don't set the sequence in the newly created attendances https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/resource/models/resource_calendar.py#L735-L749 so it will get the default value which is 10 so when calling onchange for the attendance_ids_1st_week and attendance_ids_2nd_week each attendance will be set to the odd_week_seq https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/resource/models/resource_calendar.py#L184-L200 which will then make this condition fail https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/resource/models/resource_calendar.py#L615-L616 Second part was related to the `two_weeks_calendar` when saving, its value won't be passed to the vals_list in `web_save()` as when we read the values to be changed we ignore readonly fields and since two_weeks_calendar was used in invisible condition but isn't defined in a separate `<field>` the view create a tag for it ` <field name='two_weeks_calendar' invisible='True' readonly='True' data-used-by='invisible='flexible_hours or not two_weeks_calendar' (page,working_hours)' on_change='1'/> ` This tag would be readonly by default so when the ArchParser gets each field's info it puts `two_weeks_calendar` as a readonly field and ignore it in the creation values https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/web/static/src/views/fields/field.js#L276-L279 which then fails this condition and pass all the 2 weeks attendances in the else condition https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/resource/models/resource_calendar.py#L134-L138 After fixing this another bug was found where if you saved the calendar the attendances will disappear. This was happening when we create the resource.calendar.attendance records it will call the inverse method of the attendance_ids_1st_week and attendance_ids_2nd_week where they are still not computed so it will set attendance_ids to empty https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/resource/models/resource_calendar.py#L152-L156 so after when computing the two weeks attendance it will be empty as well and it will disappear. Last bug was if after creating this you tried to switch the calendar type it will call the same validation error mentioned earlier. As when calling _get_default_attendance_ids it will try to create attendances from the company's default working schedule which will have a conflict since the company's schedule is 2-weeks schedule and we are switching our schedule to 1-week schedule so we are gonna have attendances for 2-weeks in 1-week schedule so it will fail the same condition https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/resource/models/resource_calendar.py#L615-L616 ## Fix: To fix those issues we needed to set the sequence values when copying the data of the company's schedule when computing the default values. Also we need to skip the inverse method when we are still upon creating the records and to do so we are passing a context in the create method to skip the inverse. Last we need to check for the difference between the schedule type and the company's schedule when fetching the default attendances. opw-6374237 Forward-Port-Of: odoo/odoo#281716 Forward-Port-Of: odoo/odoo#279182
When LNA support was added for the ETA integration in odoo/odoo#264766, a small oversight was made when using trying to use localhost as the IoT (common for virtual IoT setups). Because the `targetAddressSpace` was always set to `"local"`, requests to localhost would fail with this error: ``` Request had a target IP address space of `local` yet the resource is in address space `loopback`. ``` This commit fixes the issue by setting the value to `loopback` if localhost is being used. o
Original PR description
When LNA support was added for the ETA integration in odoo/odoo#264766, a small oversight was made when using trying to use localhost as the IoT (common for virtual IoT setups). Because the `targetAddressSpace` was always set to `"local"`, requests to localhost would fail with this error: ``` Request had a target IP address space of `local` yet the resource is in address space `loopback`. ``` This commit fixes the issue by setting the value to `loopback` if localhost is being used. opw-6467156 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Steps to reproduce the bug: - Install a localization that overrides invoice_policy defaults for storable products without an explicit company_id (e.g. l10n_ke_edi_oscu_stock, which forces 'delivery' in that case) - Run TestSaleMRPAngloSaxonValuation.test_sale_mrp_kit_bom_cogs (sale_mrp) or TestAngloSaxonValuation.test_anglo_saxon_cogs_partial_down_payment_credit_note (sale_stock) Problem: These tests create their products without setting invoice_policy explicitly, relying on the field's im
Original PR description
Steps to reproduce the bug: - Install a localization that overrides invoice_policy defaults for storable products without an explicit company_id (e.g. l10n_ke_edi_oscu_stock, which forces 'delivery'…
Steps to reproduce the bug: - Install a localization that overrides invoice_policy defaults for storable products without an explicit company_id (e.g. l10n_ke_edi_oscu_stock, which forces 'delivery' in that case) - Run TestSaleMRPAngloSaxonValuation.test_sale_mrp_kit_bom_cogs (sale_mrp) or TestAngloSaxonValuation.test_anglo_saxon_cogs_partial_down_payment_credit_note (sale_stock) Problem: These tests create their products without setting invoice_policy explicitly, relying on the field's implicit default. l10n_ke_edi_oscu_stock's _compute_invoice_policy (https://github.com/odoo/enterprise/blob/4e459417dac809caafea34aa2e487fc3c1f0ce1a/l10n_ke_edi_oscu_stock/models/product.py#L16-L21) forces invoice_policy to 'delivery' for any storable product whose company_id is not set, which is the case for products created in these test fixtures. Once invoice_policy becomes 'delivery', invoiced quantities are driven by qty_delivered instead of the ordered quantity, which the affected tests never account for (some deliver an arbitrary quantity instead of the exact BoM demand, others never validate a delivery at all), causing wrong COGS amounts or wrongly invoiced quantities as soon as such a localization is installed alongside these modules. Solution: Pin invoice_policy to 'order' explicitly wherever these test fixtures create their products, so the test outcome no longer depends on which other modules happen to be installed. runbot-243633 Forward-Port-Of: odoo/odoo#279277 Forward-Port-Of: odoo/odoo#278346
`test_orderpoint_activity_portal_context_leak` assumes that running the orderpoint will trigger a procurement exception. However, depending on which modules are installed (e.g., when `purchase_stock` is absent), standard stock rules for the test warehouse destination location can succeed in generating stock moves rather than raising an error. Deactivate all matching destination stock rules on the test warehouse prior to running procurement so the orderpoint is guaranteed to fail. runbot-94
Original PR description
`test_orderpoint_activity_portal_context_leak` assumes that running the orderpoint will trigger a procurement exception. However, depending on which modules are installed (e.g., when `purchase_stock` is absent), standard stock rules for the test warehouse destination location can succeed in generating stock moves rather than raising an error. Deactivate all matching destination stock rules on the test warehouse prior to running procurement so the orderpoint is guaranteed to fail. runbot-941316 Forward-Port-Of: odoo/odoo#279781
Before this commit, marking several manufacturing orders as done at once crashed or could post labour costs on the wrong account, because the labour posting loop read the product and the company from the whole recordset instead of the manufacturing order being processed. Steps to reproduce: - activate a second company, e.g. My Company (Chicago) - create a manufacturing order in each company and confirm them - in the Manufacturing Orders list view, select both orders and mark them as done
Original PR description
Before this commit, marking several manufacturing orders as done at once crashed or could post labour costs on the wrong account, because the labour posting loop read the product and the company from…
Before this commit, marking several manufacturing orders as done at once crashed or could post labour costs on the wrong account, because the labour posting loop read the product and the company from the whole recordset instead of the manufacturing order being processed. Steps to reproduce: - activate a second company, e.g. My Company (Chicago) - create a manufacturing order in each company and confirm them - in the Manufacturing Orders list view, select both orders and mark them as done A "ValueError: Expected singleton: res.company(...)" traceback is raised and none of the orders can be closed, even though each one can be marked as done individually. With same-company orders of different products, the production location resolved from the union of products, so the labour entry could be posted against another product's WIP account. Use the manufacturing order of the current loop iteration to resolve the production location, as the rest of the loop already does. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276586
In saas-19.1, `purchase_cdnur_regular` was renamed to `purchase_cdnur_overseas`. However, commit https://github.com/odoo/odoo/commit/c4b0911e061ff0619bd3d6a411701fc898dad258 still used the old section name. This commit updates `purchase_cdnur_regular` to `purchase_cdnur_overseas`. Forward-Port-Of: odoo/odoo#281895
Original PR description
In saas-19.1, `purchase_cdnur_regular` was renamed to `purchase_cdnur_overseas`. However, commit https://github.com/odoo/odoo/commit/c4b0911e061ff0619bd3d6a411701fc898dad258 still used the old section name. This commit updates `purchase_cdnur_regular` to `purchase_cdnur_overseas`. Forward-Port-Of: odoo/odoo#281895
A POS session could not be closed if there were draft orders planned for later the same day. The backend check was only filtering out orders with a date strictly in the future, ignoring the time part for same-day orders. task-id: 6000698 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272241 Forward-Port-Of: odoo/odoo#251935
Original PR description
A POS session could not be closed if there were draft orders planned for later the same day. The backend check was only filtering out orders with a date strictly in the future, ignoring the time part for same-day orders. task-id: 6000698 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272241 Forward-Port-Of: odoo/odoo#251935
Issue: ```python In [14]: receiver._get_peppol_proxy_endpoint('/2/get_services') Out[14]: '/api/peppol//2/get_services' In [15]: receiver._get_peppol_proxy_endpoint('2/get_services') Out[15]: '/api/peppol/2/get_services' ``` this raises: ```bash [ERROR] odoo.addons.account_peppol_response.models.account_edi_proxy_user Auto registration of peppol services for module: account_peppol_response failed on the user: ***, with exception: Invalid signature for request. This might be due to
Original PR description
Issue:
```python
In [14]: receiver._get_peppol_proxy_endpoint('/2/get_services')
Out[14]: '/api/peppol//2/get_services'
In [15]: receiver._get_peppol_proxy_endpoint('2/get_services')
Out[15]: '/api/peppol/2/get_services'
```
this raises:
```bash
[ERROR] odoo.addons.account_peppol_response.models.account_edi_proxy_user
Auto registration of peppol services for module: account_peppol_response failed on the user: ***, with exception: Invalid signature for request. This might be due to another connection to odoo Access Point server. It can occur if you have duplicated your database
```
OPW-6431279
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#281783Steps to reproduce: 1. Refund an order using a Glory Cash payment method 2. The machine refunds the cash correctly **Expected behaviour:** Odoo validates the refund **Actual behaviour:** Odoo sets the line amount to zero, refund incomplete The fix is to correctly remove the money dispensed from the payment total, resulting in a negative payment amount rather than zero. In addition, we remove similar logic for Cashdro machines that was also broken as the code path was never executed.
Original PR description
Steps to reproduce: 1. Refund an order using a Glory Cash payment method 2. The machine refunds the cash correctly **Expected behaviour:** Odoo validates the refund **Actual behaviour:** Odoo sets the line amount to zero, refund incomplete The fix is to correctly remove the money dispensed from the payment total, resulting in a negative payment amount rather than zero. In addition, we remove similar logic for Cashdro machines that was also broken as the code path was never executed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281938
Before this commit, the html composer variant of "Opening thread with needaction messages should mark all messages of thread as read" failed at random on runbot: 11. [verifySteps] expected the following steps > Expected: [ "mark-all-messages-as-read", ] > Received: [] This happens because the channel of that variant holds no message, so the test goes to the inbox before the channel is loaded and it keeps scrollUnread set. Opening the channel again then loads its m
Original PR description
Before this commit, the html composer variant of "Opening thread with needaction messages should mark all messages of thread as read" failed at random on runbot: 11. [verifySteps] expected the…
Before this commit, the html composer variant of "Opening thread with needaction messages should mark all messages of thread as read" failed at random on runbot:
11. [verifySteps] expected the following steps
> Expected: [
"mark-all-messages-as-read",
]
> Received: []
This happens because the channel of that variant holds no message, so the test goes to the inbox before the channel is loaded and it keeps scrollUnread set. Opening the channel again then loads its messages around the 0 separator, and that fetch calls set_message_done, which marks the needaction message as read and leaves nothing for mark_all_as_read to mark.
This commit fixes the issue by giving the channel two messages, pointing the separator at the first one and waiting for their display: loading messages around the separator is skipped when that message is already loaded, so opening the channel again fetches nothing, which the closing assertion checks as well.
The text composer variant gets the same fixture, so that both variants read as master does, from commit 8cd330e3e2d5b1d857d3effb80aa8176d60b38f9. It does not fail: it already waits for a message of its own, and a fetch around its non-zero separator leaves the messages alone in the mock.
https://runbot.odoo.com/odoo/error/945744
Forward-Port-Of: odoo/odoo#282038
Forward-Port-Of: odoo/odoo#281714Reduce idletimeout task id: 6374370 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275081
Original PR description
Reduce idletimeout task id: 6374370 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275081
Before this commit, the test "Shows warning badge on mic/camera on non-granted permission in meeting conversations" failed on runbot, on 19.0: Failed to find 1 of "button[title='Turn camera on']" (Timeout of 10 seconds). Found 0 instead. This happens because the mock server numbers a new record with the highest id of the model plus one, so a record created right after the last one is deleted takes its id back. Joining another call leaves the meeting call first, and the session of the new c
Original PR description
Before this commit, the test "Shows warning badge on mic/camera on non-granted permission in meeting conversations" failed on runbot, on 19.0: Failed to find 1 of "button[title='Turn camera on']"…
Before this commit, the test "Shows warning badge on mic/camera on non-granted permission in meeting conversations" failed on runbot, on 19.0: Failed to find 1 of "button[title='Turn camera on']" (Timeout of 10 seconds). Found 0 instead. This happens because the mock server numbers a new record with the highest id of the model plus one, so a record created right after the last one is deleted takes its id back. Joining another call leaves the meeting call first, and the session of the new call carries the id of the one just left. Leaving broadcasts "discuss.channel.rtc.session/ended" for that id, and under load it lands after the join: the client reads it as its own session being closed and ends the call it has just joined. This commit numbers the records of a model with a counter, started above the ids its definition gives, as a database sequence does, so a notification about a deleted record can no longer name a live one. https://runbot.odoo.com/odoo/error/945965 Forward-Port-Of: odoo/odoo#282244
**Steps to Reproduce:** 1. Configure a main product and its optional product as service products, both with a non-default Unit of Measure (e.g. m²). 2. Add the main product to a quotation. **Issue:** - The main product line's UoM is set to the generic "Units" default instead of the product's own m² UoM. Only reproduces when the product has optional products (which routes it through the product configurator dialog) **Why this happens:** - `_compute_product_uom_id` in `sale.order.line` w
Original PR description
**Steps to Reproduce:** 1. Configure a main product and its optional product as service products, both with a non-default Unit of Measure (e.g. m²). 2. Add the main product to a quotation. **Issue:**…
**Steps to Reproduce:** 1. Configure a main product and its optional product as service products, both with a non-default Unit of Measure (e.g. m²). 2. Add the main product to a quotation. **Issue:** - The main product line's UoM is set to the generic "Units" default instead of the product's own m² UoM. Only reproduces when the product has optional products (which routes it through the product configurator dialog) **Why this happens:** - `_compute_product_uom_id` in `sale.order.line` was updated to return `Units` as UoM in the commit d069ce59e28fda2bc25fb89fd01ee7b988a30fa0 which now defaults a line's `product_uom_id` to the generic reference unit as soon as the line exists, before any product is selected - When a product with optional products is picked, `_openProductConfigurator` reads that placeholder value and forwards it to `/sale/product_configurator/get_values` as `product_uom_id`. - `_get_product_information` finds the `product_uom_id` already set in `uom = (product_uom_id and browse(product_uom_id)) or product_template._get_main_uom()`, so the placeholder "Units" overrides the product's own UoM. **Fix:** - Only forward `productUOMId` to the configurator when actually editing an existing line (`edit=True`), where `product_uom_id` reflects a product-derived value. On a fresh add, no product has been chosen yet, so the line's current `product_uom_id` is just a placeholder default and should not be sent opw-6439473
[FIX] mail: attach dropped files to the message in edition Root cause: When editing a message in the chatter, the composer shown inside the message does not get the dropzoneRef prop, so it does not create its own dropzone: https://github.com/odoo/odoo/blob/5ca10578a2fd1b40cd371ed5ad20c1654dfe54d3/addons/mail/static/src/core/common/composer.js#L197-L209 The chatter creates a dropzone covering the whole chatter that saves dropped files as attachments of the record: https://github.com/odoo/odoo/b
Original PR description
[FIX] mail: attach dropped files to the message in edition Root cause: When editing a message in the chatter, the composer shown inside the message does not get the dropzoneRef prop, so it does not…
[FIX] mail: attach dropped files to the message in edition Root cause: When editing a message in the chatter, the composer shown inside the message does not get the dropzoneRef prop, so it does not create its own dropzone: https://github.com/odoo/odoo/blob/5ca10578a2fd1b40cd371ed5ad20c1654dfe54d3/addons/mail/static/src/core/common/composer.js#L197-L209 The chatter creates a dropzone covering the whole chatter that saves dropped files as attachments of the record: https://github.com/odoo/odoo/blob/5ca10578a2fd1b40cd371ed5ad20c1654dfe54d3/addons/mail/static/src/chatter/web/chatter_patch.js#L106-L138 Since the composer of the message in edition has no dropzone, a file dropped on it is caught by the chatter dropzone and ends up attached to the record instead of the message. Fix: Pass the message body as dropzoneRef to the composer in message.xml. The composer then creates its own dropzone over the message, the same way the chatter composer gets one from chatter.xml, and the dropped file is added to the message in edition. The chatter dropzone and the thread composer dropzone cover that same area and would show at the same time, so both are turned off while a message is in edition. The thread already knows which message that is through messageInEdition, so neither of them has anything to keep track of. Steps to reproduce: 1. Open the Contacts app and open any contact 2. Click Log note, type some text and click Log 3. Hover the note and click the pencil icon to edit it 4. Drag a file from the file explorer and drop it on the note => the file is added to the attachments of the contact instead of the note Ticket [link](https://www.odoo.com/odoo/project.task/6385377) opw-6385377 Forward-Port-Of: odoo/odoo#281580 Forward-Port-Of: odoo/odoo#278373
An old refactor left some data around that are in conflict with other records for the same model. 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#281710 Forward-Port-Of: odoo/odoo#281276
Original PR description
An old refactor left some data around that are in conflict with other records for the same model. 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#281710 Forward-Port-Of: odoo/odoo#281276
Steps: - Install `account_peppol` module. - Set `Peppol` compatible country and related details - Go to my/account page. Issue: - Peppol related details always displayed on `my/account` page even though user select different invoice sending method like: `By Email`. Casue: - selector to manage visibility of Peppol related details in `my/account` is wrong and because of that those fields always display. Probably because https://github.com/odoo/odoo/pull/195764 and backport of this https
Original PR description
Steps: - Install `account_peppol` module. - Set `Peppol` compatible country and related details - Go to my/account page. Issue: - Peppol related details always displayed on `my/account` page even…
Steps: - Install `account_peppol` module. - Set `Peppol` compatible country and related details - Go to my/account page. Issue: - Peppol related details always displayed on `my/account` page even though user select different invoice sending method like: `By Email`. Casue: - selector to manage visibility of Peppol related details in `my/account` is wrong and because of that those fields always display. Probably because https://github.com/odoo/odoo/pull/195764 and backport of this https://github.com/odoo/odoo/pull/198327 merged at same time. Fix: - Update selector to fix this ### [FIX] account_peppol: fix error when setting wrong endpoint Steps: - Install `account_peppol` module. - Set `Peppol` compatible country and related details. - Go to my/account page. - Set some wrong Peppol value for `Peppol e-Address (EAS)` or `Peppol Endpoint` or `Electronic format`. Issue: - Not able to save those details without any error message on address page and getting error on console `Cannot read properties of undefined (reading 'classList')`. Casue: - In this PR https://github.com/odoo/odoo/pull/190312 when adapting portal page we set not existing fields in `invalid_fields` details and because of that it can't find related fields on address page and don't allow to save details without raising proper error message. Fix: - Updated `invalid_fields` values to properly target them ### [FIX] account_peppol: fix display issue for peppol related fields in address Forward-Port-Of: odoo/odoo#281718
Steps to reproduce the bug: - Install repair and accounting - Create a user and grant them only Inventory / User access - Log in as that user and open any Repair Order Problem: Opening the repair order raised: "Failed to read field repair.order.invoice_ids You are not allowed to access 'Journal Entry' (account.move) records." `invoice_count` and `can_create_sale_or_invoice` are computed fields that read `invoice_ids`, a One2many to `account.move` Reading a One2many always queries the
Original PR description
Steps to reproduce the bug: - Install repair and accounting - Create a user and grant them only Inventory / User access - Log in as that user and open any Repair Order Problem: Opening the repair…
Steps to reproduce the bug: - Install repair and accounting - Create a user and grant them only Inventory / User access - Log in as that user and open any Repair Order Problem: Opening the repair order raised: "Failed to read field repair.order.invoice_ids You are not allowed to access 'Journal Entry' (account.move) records." `invoice_count` and `can_create_sale_or_invoice` are computed fields that read `invoice_ids`, a One2many to `account.move` Reading a One2many always queries the comodel, so this triggers an ACL check on `account.move` for the current user, even though the repair order has no invoice and the field is only used to display a count/boolean. A user with `stock.group_stock_user` but no accounting/sales rights has no access to `account.move`, so simply opening the form crashes. Solution: Read `invoice_ids` with `sudo()` inside `_compute_invoice_count` and `_compute_can_create_sale_or_invoice`, since only a derived count/boolean is exposed to the user, not the invoice records themselves. opw-6447829 Forward-Port-Of: odoo/odoo#281692
- Some clients does not know that they can skip the feedback screen timeout by clicking on the screen. So we decrease the timeout to 1.5 seconds to avoid that they wait too much time. - This timeout was already reduced in version `saas-19.1` to 1 second (see PR: github.com/odoo/odoo/issues/235316) - We now set it to 1.5 seconds (because 1 second is not enough for the paid animation to finish on the feedback screen). task-id: 6425204 --- I confirm I have signed the CLA and read the PR gu
Original PR description
- Some clients does not know that they can skip the feedback screen timeout by clicking on the screen. So we decrease the timeout to 1.5 seconds to avoid that they wait too much time. - This timeout was already reduced in version `saas-19.1` to 1 second (see PR: github.com/odoo/odoo/issues/235316) - We now set it to 1.5 seconds (because 1 second is not enough for the paid animation to finish on the feedback screen). task-id: 6425204 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280728 Forward-Port-Of: odoo/odoo#278841
Making sure that during the race condition between the save triggered by closing the widget and the one triggered by the ’ NEED_LOCAL_CHANGES’ bus doesn’t lead to the re-opening of the widget itself and subsequently the list mass edit pop up. Forward-Port-Of: odoo/odoo#281013
Original PR description
Making sure that during the race condition between the save triggered by closing the widget and the one triggered by the ’ NEED_LOCAL_CHANGES’ bus doesn’t lead to the re-opening of the widget itself and subsequently the list mass edit pop up. Forward-Port-Of: odoo/odoo#281013
…tour Scope kanban selection triggers to the active modal to avoid a race with Owl's async modal state, and make Many2XAutocomplete's onClose null-safe against a crash the race was masking. runbot-error-id~939488 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
…tour Scope kanban selection triggers to the active modal to avoid a race with Owl's async modal state, and make Many2XAutocomplete's onClose null-safe against a crash the race was masking. runbot-error-id~939488 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
Previously, refreshing the PoS caused categories with sequence = 0 to fall back to ID-based sorting from IndexedDB. Sequence-based ordering was already fixed in this [pr](https://github.com/odoo/odoo/pull/207172), but the fallback for sequence 0 still sorted by ID. This change ensures categories with sequence = 0 follow the expected ordering when refreshing. Task-6185359 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merge
Original PR description
Previously, refreshing the PoS caused categories with sequence = 0 to fall back to ID-based sorting from IndexedDB. Sequence-based ordering was already fixed in this [pr](https://github.com/odoo/odoo/pull/207172), but the fallback for sequence 0 still sorted by ID. This change ensures categories with sequence = 0 follow the expected ordering when refreshing. Task-6185359 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#281248 Forward-Port-Of: odoo/odoo#273954