Daily updates from Odoo
Thursday, August 13, 2026
206 changes
24 changes
Resolved issues and error corrections
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
19 changes
Resolved issues and error corrections
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
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
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
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#281783Bug === When notifying by email a tracking change, the arrow and parenthesis are not rendered in the email body. Technical and Constraints ========================= The class `o_track` is only set in the web client template (`mail.Message`). There's no class in the body of the email that is sent. It can be rendered with "notification template" that we cannot change either (and they just do `t-out="message.body"`, so the body field of the mail message has to be properly rendered). We
Original PR description
Bug === When notifying by email a tracking change, the arrow and parenthesis are not rendered in the email body. Technical and Constraints ========================= The class `o_track` is only set in the web client template (`mail.Message`). There's no class in the body of the email that is sent. It can be rendered with "notification template" that we cannot change either (and they just do `t-out="message.body"`, so the body field of the mail message has to be properly rendered). We also need existing mail message to be rendered correctly, and so we need a way to differentiate mail message created before and after the fix to know when to disable the arrow and parenthesis. Task-6424104
Before this commit: ------------ - The order info button was not visible on the ticket screen in the mobile UI. After this commit: ------------ - Display the order info button in both the mobile and desktop views of the ticket screen. Related: - Enterprise: https://github.com/odoo/enterprise/pull/124485 Task-6388045
Original PR description
Before this commit: ------------ - The order info button was not visible on the ticket screen in the mobile UI. After this commit: ------------ - Display the order info button in both the mobile and desktop views of the ticket screen. Related: - Enterprise: https://github.com/odoo/enterprise/pull/124485 Task-6388045
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 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
Before this commit: --- - When a sale order line contained extra attribute addons, those values were not transferred to the POS order line while settling the sales order. After this commit: --- - Preserved extra attribute addons when creating POS order lines from SO. task-6204583 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276143
Original PR description
Before this commit: --- - When a sale order line contained extra attribute addons, those values were not transferred to the POS order line while settling the sales order. After this commit: --- - Preserved extra attribute addons when creating POS order lines from SO. task-6204583 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276143
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: 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
Steps to reproduce the bug: - Enable 2-step delivery (pick + ship) on a warehouse. - Set both rules on the delivery route to "Pull" (instead of the default Pull + Push): - Pick rule (Stock -> Output): action = Pull, procure_method = make_to_stock - Ship rule (Output -> Customers): action = Pull, procure_method = make_to_order - Create a sale order for qty 1 and confirm it. - Validate the Pick transfer. - Return the Pick transfer. - Cancel the sale order. - Set it back to quotati
Original PR description
Steps to reproduce the bug: - Enable 2-step delivery (pick + ship) on a warehouse. - Set both rules on the delivery route to "Pull" (instead of the default Pull + Push): - Pick rule (Stock ->…
Steps to reproduce the bug:
- Enable 2-step delivery (pick + ship) on a warehouse.
- Set both rules on the delivery route to "Pull" (instead of the default Pull + Push):
- Pick rule (Stock -> Output): action = Pull, procure_method = make_to_stock
- Ship rule (Output -> Customers): action = Pull, procure_method = make_to_order
- Create a sale order for qty 1 and confirm it.
- Validate the Pick transfer.
- Return the Pick transfer.
- Cancel the sale order.
- Set it back to quotation and confirm it again.
Problem:
The newly created delivery (ship) move ends up asking for a wrong, inflated quantity instead of the ordered one (e.g. 3 times the ordered qty for the scenario above; the multiplier depends on the number of prior confirm/cancel/return cycles).
`_action_cancel` (addons/sale_stock/models/sale_order.py) only cancels pickings that are not `done`, so after the pick is validated and returned, cancelling the SO only cancels the still-pending ship move. The pick move and its return stay `done` and linked to the sale order line.
`SaleOrderLine._get_outgoing_incoming_moves` determines which rule "started" the pull/push chain by picking the rule of the first surviving (non-cancelled) move, grouped by warehouse: https://github.com/odoo/odoo/blob/d7bad3dc6c068ffe8643ecb01da1865d743bfb8f/addons/sale_stock/models/sale_order_line.py#L338-L347
Once the ship move is cancelled, it is excluded from that computation, so the Pick rule is wrongly identified as the "triggering" rule instead of the Ship rule. The done pick move and its return share that rule, so they both end up wrongly classified as incoming (returned) quantities instead of being excluded from the computation like before the cancellation, corrupting `_get_qty_procurement`. On reconfirm, `_action_launch_stock_rule` computes
`product_qty = product_uom_qty - qty`, inflating the quantity requested on the new ship move.
Solution:
Identify the triggering rule from the sale order line's full move history, including cancelled moves, so cancelling a move later doesn't change which rule is considered to have started the chain.
opw-6364113
Forward-Port-Of: odoo/odoo#280280Steps to reproduce the bug: - Create three storable products C1 ($10), C2 ($20), C3 ($5) - Create a product P1 with a BoM: 1x C1 + 1x C2 - Create a Manufacturing Order for P1 and validate it - Unlock the MO (Settings > Unlock) - Add C3 as an extra component on the unlocked MO - Open the MO overview Problem: The extra move had value=0 after creation, causing the unit_cost in the MO overview to appear as 0. When a move is added to a done picking or MO it is created with state='done' an
Original PR description
Steps to reproduce the bug: - Create three storable products C1 ($10), C2 ($20), C3 ($5) - Create a product P1 with a BoM: 1x C1 + 1x C2 - Create a Manufacturing Order for P1 and validate it - Unlock…
Steps to reproduce the bug: - Create three storable products C1 ($10), C2 ($20), C3 ($5) - Create a product P1 with a BoM: 1x C1 + 1x C2 - Create a Manufacturing Order for P1 and validate it - Unlock the MO (Settings > Unlock) - Add C3 as an extra component on the unlocked MO - Open the MO overview Problem: The extra move had value=0 after creation, causing the unit_cost in the MO overview to appear as 0. When a move is added to a done picking or MO it is created with state='done' and quantity set immediately. This triggers _set_quantity_done, which creates the move line and calls _set_value(correction_quantity=delta). Inside _set_value, for outgoing moves with a correction_quantity, the code computes: previous_qty = move.quantity - correction_quantity Since the move had no prior quantity, previous_qty=0. The original code then computed ratio=0 and applied move.value += 0, leaving value=0 instead of computing it from scratch. Solution: When previous_qty=0, skip the ratio branch and fall through to the existing from-scratch computation (standard_price * _get_valued_qty() for AVCO/standard costing, _run_fifo() for FIFO). opw-6377393 Forward-Port-Of: odoo/odoo#279962 Forward-Port-Of: odoo/odoo#276303
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#281714Steps to reproduce: - 1. In the website editor, open the portal "My Account" page and, in the Customize panel, disable the "Timesheets" option. 2. As a portal user, open My Account > Tasks for a project whose tasks have allocated time and logged timesheets. 3. Look at the task list, then open one of those tasks. Issue: - The task list still shows the per-group "Total: spent / allocated", and the task detail page still shows "Allocated Time", even though timesheets are hidden in the port
Original PR description
Steps to reproduce: - 1. In the website editor, open the portal "My Account" page and, in the Customize panel, disable the "Timesheets" option. 2. As a portal user, open My Account > Tasks for a project whose tasks have allocated time and logged timesheets. 3. Look at the task list, then open one of those tasks. Issue: - The task list still shows the per-group "Total: spent / allocated", and the task detail page still shows "Allocated Time", even though timesheets are hidden in the portal. Fix: - - Add `_show_portal_timesheets()` to the condition of the list "Total" column. - Gate the `portal_my_task_allocated_hours` block on `_show_portal_timesheets()` in the task detail page. task-6140807 Forward-Port-Of: odoo/odoo#272043
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
7 changes
Resolved issues and error corrections
Steps to produce: --- - Install `website_sale` and `stock` modules - Create a product, publish it, and add it to the cart from website. - Go to `Website > eCommerce > Orders > Orders`. - Open the order, click on `Add shipping` > add `Standard Delivery`. - Confirm the order, validate the delivery via the Delivery smart button. - From the list view, click the `To fulfill` button. Issue: --- - The order that was just delivered still appears in the `To fulfill` filter results, even thoug
Original PR description
Steps to produce: --- - Install `website_sale` and `stock` modules - Create a product, publish it, and add it to the cart from website. - Go to `Website > eCommerce > Orders > Orders`. - Open the…
Steps to produce: --- - Install `website_sale` and `stock` modules - Create a product, publish it, and add it to the cart from website. - Go to `Website > eCommerce > Orders > Orders`. - Open the order, click on `Add shipping` > add `Standard Delivery`. - Confirm the order, validate the delivery via the Delivery smart button. - From the list view, click the `To fulfill` button. Issue: --- - The order that was just delivered still appears in the `To fulfill` filter results, even though all actual products have been fully delivered. Root cause: --- - The `_search_is_unfulfilled`[1] method checks whether any order line has `qty_delivered < product_uom_qty`. A delivery/shipping line (with `is_delivery = True`) is a service—it is never physically delivered, so its `qty_delivered` remains 0 while its `product_uom_qty` is typically 1. This means `0 < 1` is always true for delivery lines, causing every order with a shipping cost line to permanently appear as unfulfilled, regardless of whether all actual products have been fully delivered. Solution: --- - Added domain to exclude all service-type products from the unfulfilled orders check. - Now, an order line is considered unfulfilled only when: - `qty_delivered < product_uom_qty` (under-delivered) - `product.type != 'service'` (not a service product — excludes services, delivery lines, etc.) [1]https://github.com/odoo/odoo/blob/e5d6650c542e44441c7087c729b3b74af3c75fe0/addons/website_sale/models/sale_order.py#L171-L183 opw-6420723 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
### Issue before this commit: Before commit f2965048f60fe6c815b3e50fa714c97a93dfb5d3, company_type allowed manually selecting whether a contact was an individual or a company. After the commit, is_company became a stored computed field derived from the VAT number, with no manual override available in the standard UI, and no exception was added for Spanish DNI/NIE formats. ### Steps to reproduce the issue: 1. Download Accounting and l10n_es 2. Set as VAT of ES company 47857909S (or similar
Original PR description
### Issue before this commit: Before commit f2965048f60fe6c815b3e50fa714c97a93dfb5d3, company_type allowed manually selecting whether a contact was an individual or a company. After the commit,…
### Issue before this commit: Before commit f2965048f60fe6c815b3e50fa714c97a93dfb5d3, company_type allowed manually selecting whether a contact was an individual or a company. After the commit, is_company became a stored computed field derived from the VAT number, with no manual override available in the standard UI, and no exception was added for Spanish DNI/NIE formats. ### Steps to reproduce the issue: 1. Download Accounting and l10n_es 2. Set as VAT of ES company 47857909S (or similar but must be a DNI or NIE format) 3. Create an invoice for a Spanish customer 4. Send the invoice with Facturae 5. Check the XML created and see that the tag <PersonTypeCode> of <SellerParty> has a J (legal entity) rather than an F (individual) ### Cause of the issue: The Spanish localization's _compute_is_company override only adds the check for CIF-formatted VAT numbers (for [legal entities](https://sede.agenciatributaria.gob.es/Sede/ayuda/manuales-videos-folletos/manuales-practicos/guia-practica-cumplimentacion-modelo-censal-036/anexos/anexo-01-solicitud-nif-documentacion-aportar/informacion-sobre-numero-identificacion-fiscal/composicion-nif/personas-juridicas-entidades.html)) but it has no corresponding negative check for DNI or NIE formats (for [standalone individuals](https://sede.agenciatributaria.gob.es/Sede/ayuda/manuales-videos-folletos/manuales-practicos/guia-practica-cumplimentacion-modelo-censal-036/anexos/anexo-01-solicitud-nif-documentacion-aportar/informacion-sobre-numero-identificacion-fiscal/composicion-nif/personas-fisicas.html)). Here the [rules](https://factuo.es/herramientas/verificador-nif) for regex. https://github.com/odoo/odoo/blob/f014e0b7bc3ce56a9931e81339a4f8327a400422/addons/l10n_es/models/res_partner.py#L39-L51 As a result, any standalone partner with a valid non-void VAT inherits is_company = True from the base computation. https://github.com/odoo/odoo/blob/f014e0b7bc3ce56a9931e81339a4f8327a400422/odoo/addons/base/models/res_partner.py#L824-L833 ### Reason to introduce the fix: The Facturae 3.2.2 export directly derives PersonTypeCode (F/J) and the LegalEntity/Individual XML structure from partner.is_company. Since a self-employed individual (autónomo) is required to use their personal DNI/NIE as NIF and is their own commercial partner, the current logic misclassifies them as a legal entity (J), producing a Facturae invoice with an incorrect PersonTypeCode and structure. Explicitly setting is_company = False for DNI/NIE-formatted Spanish VAT numbers restores the ability to correctly represent individual entrepreneurs in Facturae exports. opw-6396314 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277228
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
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
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
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#281783When edit_translations is set, convert_to_record wraps translated terms in branding spans. Related (non-stored) fields re-read that already-wrapped value and ran the same wrapping again, producing nested spans. Only wrap terms for stored fields so related Html inherits the source branding unchanged. Also keep data-oe-translation-state in HTML safe_attrs so sanitization does not strip it. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior af
Original PR description
When edit_translations is set, convert_to_record wraps translated terms in branding spans. Related (non-stored) fields re-read that already-wrapped value and ran the same wrapping again, producing nested spans. Only wrap terms for stored fields so related Html inherits the source branding unchanged. Also keep data-oe-translation-state in HTML safe_attrs so sanitization does not strip it. 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#281729 Forward-Port-Of: odoo/odoo#280397
22 changes
Resolved issues and error corrections
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: --- - When a sale order line contained extra attribute addons, those values were not transferred to the POS order line while settling the sales order. After this commit: --- - Preserved extra attribute addons when creating POS order lines from SO. task-6204583 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276143
Original PR description
Before this commit: --- - When a sale order line contained extra attribute addons, those values were not transferred to the POS order line while settling the sales order. After this commit: --- - Preserved extra attribute addons when creating POS order lines from SO. task-6204583 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276143
Steps to reproduce: - 1. In the website editor, open the portal "My Account" page and, in the Customize panel, disable the "Timesheets" option. 2. As a portal user, open My Account > Tasks for a project whose tasks have allocated time and logged timesheets. 3. Look at the task list, then open one of those tasks. Issue: - The task list still shows the per-group "Total: spent / allocated", and the task detail page still shows "Allocated Time", even though timesheets are hidden in the port
Original PR description
Steps to reproduce: - 1. In the website editor, open the portal "My Account" page and, in the Customize panel, disable the "Timesheets" option. 2. As a portal user, open My Account > Tasks for a project whose tasks have allocated time and logged timesheets. 3. Look at the task list, then open one of those tasks. Issue: - The task list still shows the per-group "Total: spent / allocated", and the task detail page still shows "Allocated Time", even though timesheets are hidden in the portal. Fix: - - Add `_show_portal_timesheets()` to the condition of the list "Total" column. - Gate the `portal_my_task_allocated_hours` block on `_show_portal_timesheets()` in the task detail page. task-6140807 Forward-Port-Of: odoo/odoo#272043
Before this commit and since the new read_group (which fetches records from open groups server side), images were loaded as base64, overloading the return payload and potentially triggering overload errors (MemoryError) This was because the bin_size = true context key was forgotten. After this commit, images are not loaded as base64 thanks to that context key Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged:
Original PR description
Before this commit and since the new read_group (which fetches records from open groups server side), images were loaded as base64, overloading the return payload and potentially triggering overload errors (MemoryError) This was because the bin_size = true context key was forgotten. After this commit, images are not loaded as base64 thanks to that context key 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#281911
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
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
Following this commit: ==== - When a combo is broken down, its items are assigned to their respective courses. - Remove a course when all its items are deleted from the cart. task-6121521
Original PR description
Following this commit: ==== - When a combo is broken down, its items are assigned to their respective courses. - Remove a course when all its items are deleted from the cart. task-6121521
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
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#281783When edit_translations is set, convert_to_record wraps translated terms in branding spans. Related (non-stored) fields re-read that already-wrapped value and ran the same wrapping again, producing nested spans. Only wrap terms for stored fields so related Html inherits the source branding unchanged. Also keep data-oe-translation-state in HTML safe_attrs so sanitization does not strip it. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior af
Original PR description
When edit_translations is set, convert_to_record wraps translated terms in branding spans. Related (non-stored) fields re-read that already-wrapped value and ran the same wrapping again, producing nested spans. Only wrap terms for stored fields so related Html inherits the source branding unchanged. Also keep data-oe-translation-state in HTML safe_attrs so sanitization does not strip it. 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#281729 Forward-Port-Of: odoo/odoo#280397
`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
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.
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, 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
Before this commit, the two steps posting "Hello everyone!" were spliced into the meeting view tour at the index of the step clicking on the Chat action, looked up with `steps.find`. That returns the step itself, so `splice` coerced it to NaN and inserted at 0: the message was posted as the very first thing the tour did, and the marker it searched for served no purpose. Reminder that the index it aimed for does not work: the meeting view is fullscreen with the invite panel open there, and the
Original PR description
Before this commit, the two steps posting "Hello everyone!" were spliced into the meeting view tour at the index of the step clicking on the Chat action, looked up with `steps.find`. That returns the step itself, so `splice` coerced it to NaN and inserted at 0: the message was posted as the very first thing the tour did, and the marker it searched for served no purpose. Reminder that the index it aimed for does not work: the meeting view is fullscreen with the invite panel open there, and the only composer belongs to the chat panel, which opens one step later. This commit writes the two steps at the head of the list and drops the marker, so the tour runs in the order it reads. Forward-Port-Of: odoo/odoo#282060
As the `requirements.txt` file path changed from `addons/iot_box_image` to `setup/iot_box_builder` the checkout from 19 to saas-19.4 can't find the file (looking at the former path instead of the new one). As a workaround, we add `sentry_sdk` requirement in v19.0. Forward-Port-Of: odoo/odoo#282001
Original PR description
As the `requirements.txt` file path changed from `addons/iot_box_image` to `setup/iot_box_builder` the checkout from 19 to saas-19.4 can't find the file (looking at the former path instead of the new one). As a workaround, we add `sentry_sdk` requirement in v19.0. Forward-Port-Of: odoo/odoo#282001
Description of the issue/feature this PR addresses: A user without accounting rights cannot open an invoice form when l10n_fr_pdp is installed. The module extends the method _compute_show_reset_to_draft_button which reads l10n_fr_pdp_sent_in_flow_ids. That field is only readable by the accounting groups while show_reset_to_draft_button is declared in the standard invoice form without any groups restriction < field name="show_reset_to_draft_button" invisible="1"/ > in account.view_move
Original PR description
Description of the issue/feature this PR addresses: A user without accounting rights cannot open an invoice form when l10n_fr_pdp is installed. The module extends the method…
Description of the issue/feature this PR addresses: A user without accounting rights cannot open an invoice form when l10n_fr_pdp is installed. The module extends the method _compute_show_reset_to_draft_button which reads l10n_fr_pdp_sent_in_flow_ids. That field is only readable by the accounting groups while show_reset_to_draft_button is declared in the standard invoice form without any groups restriction < field name="show_reset_to_draft_button" invisible="1"/ > in account.view_move_form Every user able to open an invoice therefore reads it. Steps to reproduce: - install `l10n_fr_pdp` - create a salesman user with sales rights but no accounting right (*Own Documents Only* is enough) - create a FR company and a FR customer - give the salesman access to the FR company - activate Peppol in the general settings - log in as the salesman - create a sale order in the FR company for the FR customer - confirm it - click **Create Invoice** - click **Create Draft** Current behavior before PR: An Access Error dialog is raised Failed to read field account.move.l10n_fr_pdp_sent_in_flow_ids You are not allowed to access 'French PDP Flow' (l10n.fr.pdp.reports.flow) records. This operation is allowed for the following groups: - Accounting/Administrator - Accounting/Invoicing - Show Accounting Features - Readonly - Show Full Accounting Features In odoo.sh, the standard test sale_management / TestSaleFlowTourPostInstall.test_basic_sale_flow_with_minimal_access_rights fails for the same reason as soon as l10n_fr_pdp is installed alongside sale_management. Desired behavior after PR is merged: On a database with l10n_fr_pdp installed, a non-accountant user having the possibility to create invoice should not have the error message displayed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280754
Many users were receiving duplicate vendor bills. The issue was that duplicates were never detected in the receiving flow. Every incoming message returned by the proxy was processed and turned into a new `account.move`, even if it had already been imported previously. This commit filters out messages whose UUID already matches an existing `account.move` before processing them, and acknowledges those duplicates on the IAP side so they are not received again on the next run. task-5930116
Original PR description
Many users were receiving duplicate vendor bills. The issue was that duplicates were never detected in the receiving flow. Every incoming message returned by the proxy was processed and turned into a new `account.move`, even if it had already been imported previously. This commit filters out messages whose UUID already matches an existing `account.move` before processing them, and acknowledges those duplicates on the IAP side so they are not received again on the next run. task-5930116 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280445 Forward-Port-Of: odoo/odoo#274963
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
Before this commit, `waitStoreFetch` returns before the answer is in the store: right after `waitStoreFetch("channels_as_member")`, the store holds no record for a channel that answer carries, on a hundred runs out of a hundred. A test that then asserts on the fetched data depends on timing. This happens because `listenStoreFetch` steps from the `onRpc` callback, which runs before the route is served. The `microTick` at the end of `waitStoreFetch` is meant to cover the rest of the round trip,
Original PR description
Before this commit, `waitStoreFetch` returns before the answer is in the store: right after `waitStoreFetch("channels_as_member")`, the store holds no record for a channel that answer carries, on a hundred runs out of a hundred. A test that then asserts on the fetched data depends on timing.
This happens because `listenStoreFetch` steps from the `onRpc` callback, which runs before the route is served. The `microTick` at the end of `waitStoreFetch` is meant to cover the rest of the round trip, but the answer only reaches the store six microtasks later.
This commit steps from `Store.fetchStoreData` instead, whose promise resolves once the answer is in the store, and drops the tick. The `onRpc` option keeps its route hooks, as tests use it to delay a request.
Forward-Port-Of: odoo/odoo#282043
Forward-Port-Of: odoo/odoo#281499Description of the issue/feature this PR addresses: Odoo supports WebP image fields, but `base_import` validates remote images with `PIL.Image.open()`. Odoo intentionally leaves Pillow's WebP decoder unloaded, so a valid WebP URL is rejected as an unidentified image. Current behavior before PR: Importing a valid WebP image URL fails with `cannot identify image file`. Oversized and unsupported WebP files are also rejected by Pillow before the import-specific size policy can be applied. Desire
Original PR description
Description of the issue/feature this PR addresses: Odoo supports WebP image fields, but `base_import` validates remote images with `PIL.Image.open()`. Odoo intentionally leaves Pillow's WebP decoder…
Description of the issue/feature this PR addresses: Odoo supports WebP image fields, but `base_import` validates remote images with `PIL.Image.open()`. Odoo intentionally leaves Pillow's WebP decoder unloaded, so a valid WebP URL is rejected as an unidentified image. Current behavior before PR: Importing a valid WebP image URL fails with `cannot identify image file`. Oversized and unsupported WebP files are also rejected by Pillow before the import-specific size policy can be applied. Desired behavior after PR is merged: Use Odoo's existing WebP header parser for dimension validation. Valid WebP URLs import unchanged, unsupported WebP remains rejected, and the existing 42-million-pixel import limit remains enforced. Tests cover valid, unsupported, and oversized WebP URL payloads. The complete `test_base_import` suite passes (56 tests, 0 failures/errors). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281829 Forward-Port-Of: odoo/odoo#276648
Steps to Reproduce: ------------------------ - Install the Point of Sale module & create an order with a customer (partner). - Scan the QR code on the receipt to retrieve the invoice. Issue: ------- When clicking `Get My Invoice`, the invoice was not being generated. Cause: --------- - The correct partner was not being set. POS customer scanning the QR code is not logged into Odoo, so no partner is associated with the request. We were incorrectly using the logged-in user’s partner,
Original PR description
Steps to Reproduce: ------------------------ - Install the Point of Sale module & create an order with a customer (partner). - Scan the QR code on the receipt to retrieve the invoice. Issue: -------…
Steps to Reproduce: ------------------------ - Install the Point of Sale module & create an order with a customer (partner). - Scan the QR code on the receipt to retrieve the invoice. Issue: ------- When clicking `Get My Invoice`, the invoice was not being generated. Cause: --------- - The correct partner was not being set. POS customer scanning the QR code is not logged into Odoo, so no partner is associated with the request. We were incorrectly using the logged-in user’s partner, which resulted in an empty partner and therefore an empty VAT value. - The customer's country was also incorrect because the partner’s country was fetched but then overwritten by the order’s country due to improper value assignment. Fix: ---- - In most POS scenarios, the customer associated with the order is the one requesting the invoice. Therefore, if no logged-in user is found, we now correctly use the order’s partner to retrieve VAT and other required information. - The partner's country was corrected by ensuring the values are assigned in the proper order and no longer overridden incorrectly. task: 5406951 Forward-Port-Of: odoo/odoo#239811
Steps to reproduce: 1. Install CRM 2. Activate the Arabic language with English 3. Create a lead with a new email, a new company name, and the Arabic language 4. Save and try to send a message from the chatter Issue: - After the message is sent, the language of Lead is changed to EN from Arabic - Contacts created with the English language Cause: - When we send a message from the chatter of a Lead that has an email_from, a partner_name, and the Arabic language, this forces the creati
Original PR description
Steps to reproduce: 1. Install CRM 2. Activate the Arabic language with English 3. Create a lead with a new email, a new company name, and the Arabic language 4. Save and try to send a message from…
Steps to reproduce: 1. Install CRM 2. Activate the Arabic language with English 3. Create a lead with a new email, a new company name, and the Arabic language 4. Save and try to send a message from the chatter Issue: - After the message is sent, the language of Lead is changed to EN from Arabic - Contacts created with the English language Cause: - When we send a message from the chatter of a Lead that has an email_from, a partner_name, and the Arabic language, this forces the creation of a new contact First child contact is created with arabic language, but `parent_name` is present in the creation dictionary, so this triggers `_create_parent_from_name` that builds a dictionary to create the parent company, but it does not pass the language. As a result, the parent company is created with the English language. then `_create_parent_from_name` links the child to this new parent and this linking triggers the `_compute_lang` on the child and overwrites the child's language with the parent's language At last, Lead's own computed field `_compute_lang_id` triggers and sets the language to English Solution: - pass the language in the dictionary to create the parent company opw-6449407
9 changes
Resolved issues and error corrections
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
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
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#281783`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
In the sampel dashboard the figures are half transparent to indicate that they are just sample data, but they are still interactive. This commit disable all the pointer events on them. Task: [6467022](https://www.odoo.com/web#id=6467022&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) 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 rea
Original PR description
In the sampel dashboard the figures are half transparent to indicate that they are just sample data, but they are still interactive. This commit disable all the pointer events on them. Task: [6467022](https://www.odoo.com/web#id=6467022&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) 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
Before this commit, deleting a record leaves its id in the relations of a record deleted before it in the same update, and reading one of those relations hands out an entry for a record that is gone. This happens because an update takes a deleted record out of the relations that hold it, but forgets it as soon as it is deleted. However, deleting a record is what queues the deletion of the records it holds: `channelMembers` carries `onDelete: (r) => r.delete()`, so the members of a thread are
Original PR description
Before this commit, deleting a record leaves its id in the relations of a record deleted before it in the same update, and reading one of those relations hands out an entry for a record that is gone. This happens because an update takes a deleted record out of the relations that hold it, but forgets it as soon as it is deleted. However, deleting a record is what queues the deletion of the records it holds: `channelMembers` carries `onDelete: (r) => r.delete()`, so the members of a thread are deleted once the thread is already forgotten, and their ids stay in its `onlineMembers`. This commit fixes the issue by keeping the records deleted by an update known until it ends. Forward-Port-Of: odoo/odoo#281983
Before this commit, the hoot test "keep banner for messages received while scrolled up" failed at random on runbot: ``` Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 10 seconds). Found 0 instead. ``` This happens because the test waits for the scroll position it sets in the DOM only, while the thread copies that position to the record on the scroll event, one animation frame later. Bob's message can arrive in between, when the record still says "bot
Original PR description
Before this commit, the hoot test "keep banner for messages received while scrolled up" failed at random on runbot:
```
Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))"
(Timeout of 10 seconds). Found 0 instead.
```
This happens because the test waits for the scroll position it sets in the DOM only, while the thread copies that position to the record on the scroll event, one animation frame later. Bob's message can arrive in between, when the record still says "bottom": the counter the banner reads stays frozen at 0 and the message is marked as read on arrival, so the banner never shows.
This commit waits until the record holds that position before posting.
https://runbot.odoo.com/odoo/error/945967Before this commit: ----------- - When a product attribute had only one available value, it was not automatically selected for display types other than multi. After this commit: ------------ - Automatically select the attribute value when an attribute has a single available value and its display type is not multi, allowing the product to be added without any additional user interaction. Task-6327371 Forward-Port-Of: odoo/odoo#272437
Original PR description
Before this commit: ----------- - When a product attribute had only one available value, it was not automatically selected for display types other than multi. After this commit: ------------ - Automatically select the attribute value when an attribute has a single available value and its display type is not multi, allowing the product to be added without any additional user interaction. Task-6327371 Forward-Port-Of: odoo/odoo#272437
# Introduction This PR fixes broken mention links linked to the fact that we replace strings without paying attention to the fact that some strings may contain others that we want to replace later. This affects both id's and names of records. See commit messages for more details. # How to reproduce - Create Contact A and then Contact B and either : - Contact B's id need to contain Contact A's id (e.g. Contact B id = 12; Contact A id = 1) - Contact B's name need to contain Contact
Original PR description
# Introduction This PR fixes broken mention links linked to the fact that we replace strings without paying attention to the fact that some strings may contain others that we want to replace later.…
# Introduction
This PR fixes broken mention links linked to the fact that we replace strings
without paying attention to the fact that some strings may contain others
that we want to replace later. This affects both id's and names of records.
See commit messages for more details.
# How to reproduce
- Create Contact A and then Contact B and either :
- Contact B's id need to contain Contact A's id (e.g. Contact B id = 12; Contact A id = 1)
- Contact B's name need to contain Contact A's name (e.g. Contact B name = ABC; Contact A name = AB)
- In a chatter create a message mentionning first Contact B and then Contact A
> Depending on the version, you might need to reload the page here
- Edit the message and save
# The issue
We see a broken mention in the chatter
# Cause
When saving an edited message, we give the raw body of the message (without the mention links) and the mentionend partners to `generateMentionsLinks` : https://github.com/odoo/odoo/blob/f9f605b1783d252d5e005bec50a2a72dd4ae0e13/addons/mail/static/src/utils/common/format.js#L152
This method's purpose is to replace the text links ("@Contact A") with actual html links. It does so by enumerating each partner given as an argument and replace the text mention with a placeholder :
https://github.com/odoo/odoo/blob/f9f605b1783d252d5e005bec50a2a72dd4ae0e13/addons/mail/static/src/utils/common/format.js#L158
It will then replace the placeholders with actual links : https://github.com/odoo/odoo/blob/f9f605b1783d252d5e005bec50a2a72dd4ae0e13/addons/mail/static/src/utils/common/format.js#L208-L218
The issue is that in both of those steps, we can try to replace a string that is contained
in another string we want to replace.
For exemple :
"string123 some text string12"
If we try to replace "string12" first, then we will select the wrong string :
"[string12]3 some text string12".
opw-6313748
Forward-Port-Of: odoo/odoo#27254913 changes
Resolved issues and error corrections
Current behavior before PR: - `test_hr_leave_after_adding_accrual_plan_levels` creates a time off using `datetime.date.today()` + 2 and + 3, so the test fails whenever it runs on a Thursday: the requested dates fall on Saturday and Sunday, and the employee is not supposed to work on those days. 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
Current behavior before PR: - `test_hr_leave_after_adding_accrual_plan_levels` creates a time off using `datetime.date.today()` + 2 and + 3, so the test fails whenever it runs on a Thursday: the requested dates fall on Saturday and Sunday, and the employee is not supposed to work on those days. Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
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
When this happens, simply delegate to the origin record. opw-6425802 For the record, this is a partial backport of https://github.com/odoo/odoo/pull/195203. Forward-Port-Of: odoo/odoo#281756
Original PR description
When this happens, simply delegate to the origin record. opw-6425802 For the record, this is a partial backport of https://github.com/odoo/odoo/pull/195203. Forward-Port-Of: odoo/odoo#281756
`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
#### Description of the issue: Activity filters using context_today() bucket against the UTC date instead of the user's local date, off by one for part of the day. Partial revert of #265250 (e048bb5), scoped to PyDate: UTC getters are right for PyDateTime, wrong for a calendar day. #### Current behavior before PR: A Perth (UTC+8) user finds an activity due today under "Future Activities" from 00:00 to 08:00 local, while the chatter labels the same activity "Today". #### Desired behavior
Original PR description
#### Description of the issue: Activity filters using context_today() bucket against the UTC date instead of the user's local date, off by one for part of the day. Partial revert of #265250 (e048bb5), scoped to PyDate: UTC getters are right for PyDateTime, wrong for a calendar day. #### Current behavior before PR: A Perth (UTC+8) user finds an activity due today under "Future Activities" from 00:00 to 08:00 local, while the chatter labels the same activity "Today". #### Desired behavior after PR is merged: context_today(), today and current_date return the user's local calendar day, so filters agree with the chatter. PyDateTime and PyTime keep the UTC getters; now and time.strftime() are unchanged. opw-6415985 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278761
### Issue: When a company is not connected to the French Electronic Invoicing PDP proxy, the generated XML is missing required notes: `PMT`, `PMD` and `AAB` These notes are required by Factur-X rule `BR-FR-05/BT-22` and their absence causes validation errors on the FNFE validator ### Cause: `_l10n_fr_pdp_get_default_notes` only added the notes when the company was using a PDP proxy type Non-PDP users sending invoices via other means were excluded, which contradicts the French e-invoicing
Original PR description
### Issue: When a company is not connected to the French Electronic Invoicing PDP proxy, the generated XML is missing required notes: `PMT`, `PMD` and `AAB` These notes are required by Factur-X rule `BR-FR-05/BT-22` and their absence causes validation errors on the FNFE validator ### Cause: `_l10n_fr_pdp_get_default_notes` only added the notes when the company was using a PDP proxy type Non-PDP users sending invoices via other means were excluded, which contradicts the French e-invoicing requirements ### Steps to reproduce: - Install `l10n_fr_pdp` and switch to the FR company - In Settings, ensure French Electronic Invoicing is not activated - Create and confirm an invoice (any line with tax) - Send the invoice and open the generated XML Before the fix, the `PMT`, `PMD` and `AAB` notes are missing Activating French Electronic Invoicing would include them opw-6392262 opw-6377507 Forward-Port-Of: odoo/odoo#279966
This change sanitizes some post data before allowing the post, making sure the data received by `message_post` is clean based on the current user. part of task-6452761
Original PR description
This change sanitizes some post data before allowing the post, making sure the data received by `message_post` is clean based on the current user. part of task-6452761
This change cleans up the requested data from `/mail/thread/data` route, ensuring it aligns with what is actually needed depending on the user and thread. part of task-6452761
Original PR description
This change cleans up the requested data from `/mail/thread/data` route, ensuring it aligns with what is actually needed depending on the user and thread. part of task-6452761
Steps to reproduce ------------------ 1. Configure a product with a subcontracted BoM and a subcontractor. 2. Create a purchase order of 10 units for that product and confirm it. 3. Receive the 10 units. 4. On the receipt, use "Return for Exchange" on 3 units and validate both the return and the exchange receipt. Issue ----- After the exchange, the 3 units stay in the subcontracting location instead of reaching `WH/Stock`, and the received quantity on the purchase order line stays at 7
Original PR description
Steps to reproduce ------------------ 1. Configure a product with a subcontracted BoM and a subcontractor. 2. Create a purchase order of 10 units for that product and confirm it. 3. Receive the 10…
Steps to reproduce ------------------ 1. Configure a product with a subcontracted BoM and a subcontractor. 2. Create a purchase order of 10 units for that product and confirm it. 3. Receive the 10 units. 4. On the receipt, use "Return for Exchange" on 3 units and validate both the return and the exchange receipt. Issue ----- After the exchange, the 3 units stay in the subcontracting location instead of reaching `WH/Stock`, and the received quantity on the purchase order line stays at 7 instead of 10. `mrp_subcontracting` overrides `_prepare_move_default_values` to force the move `location_dest_id` to the subcontractor location for every `is_subcontract` move: https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/addons/mrp_subcontracting/wizard/stock_picking_return.py#L20-L25 That is correct for the return, but the same override also runs for the exchange re-receipt, an `incoming` picking whose destination should be the stock location from `return_type.default_location_dest_id`: https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/addons/stock/wizard/stock_picking_return.py#L137-L153 The exchange move then goes from the subcontracting location back to itself, so validating it nets zero and `WH/Stock` never receives the units. Skipping the override when `new_picking.picking_type_id.code` is `incoming` lets the exchange land in stock. The received quantity must also count that receipt. `_should_count_for_quantity_received` only counts `supplier` or `transit` sources: https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/addons/stock/models/stock_move.py#L330-L331 so the exchange, sourced from the internal subcontracting location, is skipped while the return still subtracts its quantity. Counting subcontracting-sourced moves: https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/addons/mrp_subcontracting/models/stock_move.py#L312-L314 restores `qty_received` to 10. opw-6410978
`Image.Palette.ADAPTIVE` is not available in the Pillow version provided by Ubuntu Jammy, causing the animated GIF test to fail. Use `Image.ADAPTIVE` instead, which is compatible with both older and newer Pillow versions. 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
`Image.Palette.ADAPTIVE` is not available in the Pillow version provided by Ubuntu Jammy, causing the animated GIF test to fail. Use `Image.ADAPTIVE` instead, which is compatible with both older and newer Pillow versions. 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
## Issue When filtering projects using the "Timesheets >100%" filter, some projects with negative remaining hours (and with their `is_project_overtime` field set to True) won't be displayed, even though their expected hours are completed. This happens with projects which have tasks set to the "Done" or "Cancelled" state. The timesheets entries in those tasks are not taken into account when searching using the "Timesheets >100%" filter. ## Steps to reproduce 1. Install *Task Logs* (`hr_ti
Original PR description
## Issue When filtering projects using the "Timesheets >100%" filter, some projects with negative remaining hours (and with their `is_project_overtime` field set to True) won't be displayed, even…
## Issue
When filtering projects using the "Timesheets >100%" filter, some projects with negative remaining hours (and with their `is_project_overtime` field set to True) won't be displayed, even though their expected hours are completed.
This happens with projects which have tasks set to the "Done" or "Cancelled" state. The timesheets entries in those tasks are not taken into account when searching using the "Timesheets >100%" filter.
## Steps to reproduce
1. Install *Task Logs* (`hr_timesheet`)
2. Create a Project P (with Timehseets enabled)
3. Set the allocated hours of the project to 3:00 (3 hours)
4. Create two tasks:
- T1: State "In progress", and one timesheet entry of 2:00 (2 hours)
- T2: State "Done", and one timesheet entry of 2:00 (2 hours)
5. Back to the project view, set the filter to "Timesheets >100%"
6. **Project P is not shown, even though the total time spent on the project is 4 hours, completing the allocated hours set on the project.**
## Cause
The `_search_is_project_overtime` method filters out the tasks in "closed" states (Done/Cancelled) when computing the amount of time spent on the project.
https://github.com/odoo/odoo/blob/126b5bdd1e85771549198976f8570cd2ff167608/addons/hr_timesheet/models/project_project.py#L103-L114
This does not match with the behavior of the `_compute_is_project_overtime`, which does not take into account the state of the tasks to determine the value of the field:
https://github.com/odoo/odoo/blob/126b5bdd1e85771549198976f8570cd2ff167608/addons/hr_timesheet/models/project_project.py#L85-L94
This leads to a confusing behavior, where a project can have its `is_project_overtime` field set to True, but will still not be shown when using the "Timsheets >100%", even though that filter is defined as `[("is_project_overtime", "=", True)]`.
The compute method was updated by https://github.com/odoo/odoo/commit/d4252825f52a3172420dcda0ea394e42da9f8853, but the related search method was left unchanged, leading to this slight incoherence between the two methods.
opw-6422173
Forward-Port-Of: odoo/odoo#281997Before 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']" (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
## Description Law no. 30-26 of June 18, 2026 updates Dominican ISR withholdings effective **July 1, 2026**: - **Professional services, fees, commissions, and rentals paid to individuals:** 10% to 15%. - **Specific foreign-payment categories:** 15% for royalties or rights, software licenses, online advertising, and the use or storage of data. - **General remittances abroad:** remain at 27% when they are outside those specific categories. The DGII's current **IR-17-2026 (July 2026 onward)** al
Original PR description
## Description Law no. 30-26 of June 18, 2026 updates Dominican ISR withholdings effective **July 1, 2026**: - **Professional services, fees, commissions, and rentals paid to individuals:** 10% to…
## Description Law no. 30-26 of June 18, 2026 updates Dominican ISR withholdings effective **July 1, 2026**: - **Professional services, fees, commissions, and rentals paid to individuals:** 10% to 15%. - **Specific foreign-payment categories:** 15% for royalties or rights, software licenses, online advertising, and the use or storage of data. - **General remittances abroad:** remain at 27% when they are outside those specific categories. The DGII's current **IR-17-2026 (July 2026 onward)** also confirms that the concepts discussed in review are three distinct reporting rows: - **Row 4 — Transfers of titles and properties:** 2%. - **Row 17 — Other income under Decree 139-98, Article 70(a)/(b):** 3%. - **Row 18 — Other withholdings under General Rule 07-2007, as amended by Law 30-26:** 3%. The two 3% rows must not be conflated with each other or with the separate 2% transfer withholding. ## Implementation The changed-rate template entries use new, rate-explicit XML IDs, as recommended in review: - `ret_15_income_person`: new -15% fee withholding, replacing `ret_10_income_person` in the template; posts to `21030301`. - `ret_15_income_rent`: new -15% rental withholding, replacing `ret_10_income_rent` in the template; posts to `21030302`. - `ret_3_income_person`: new -3% General Rule 07-2007 withholding, replacing `ret_2_income_person` in the template; posts to `21030308`. - `tax_group_person_services_15`: new grouped tax using `ret_15_income_person`. - `tax_group_person_construction_3`: new grouped tax using `ret_3_income_person`. - `position_person_services_15`: new physical-services fiscal position mapped only to the current 15% grouped tax. The remaining legal concepts stay separate: - `ret_3_income_article_70`: new -3% tax for Decree 139-98, Article 70(a)/(b), posted to `21030309`. - `ret_2_income_transfer`: remains at -2% on `21030306`; its misleading “Materials” source metadata is corrected to transfers of titles and properties. - `ret_27_income_remittance`: remains active at -27% on `21030307`, with the general foreign-services fiscal position unchanged. - `ret_15_income_foreign_royalties_technology`: new -15% tax only for the foreign categories covered by Law 30-26. It posts to the new `21030310` Law 30-26 payable account rather than the L253-12 remittance account. - `position_exterior_royalties_technology`: new fiscal position mapping purchases only to that specific 15% tax. The specific foreign tax keeps the short invoice label `-15% ISR (L30-26)` to avoid wrapping in vendor-bill PDFs. The original manifest author entry is unchanged, as requested. The Git history and corporate CLA record this contribution by Grupo de Consultoria Henca. ### Existing-company reload behavior The superseded 10%/2% tax, grouped-tax, and physical-services fiscal-position rows are removed from the template rather than shipped as obsolete entries to new companies. On an existing company, Odoo's chart reload keeps those historical records and generated XML IDs unchanged, then creates the new current-rate records under the new XML IDs. On a newly loaded chart, only the current template entries are created. The physical-services fiscal position also has a new XML ID intentionally. Reload preserves existing fiscal-position mappings as user-configurable data and only appends mappings involving new taxes; reusing `position_person` could therefore leave both the historical and current destinations on one position. `position_person_services_15` keeps the current mapping isolated while the old position remains available for historical operations. `ret_2_income_transfer` keeps its existing XML ID because its legal rate, concept, and account remain 2% / transfers / `21030306`. The corrected label is present for new charts; backfilling label-only metadata on already-loaded charts would require an explicit upgrade migration because standard chart reload does not rewrite that user-visible metadata. ## Official references - DGII, current IR-17-2026 download page (July 2026 onward): https://dgii.gov.do/herramientas/formularios/formularioDeclaraciones/Paginas/impuestosRetencionesyRetribuciones.aspx - Law 30-26: https://www.consultoria.gov.do/Consulta/Home/FileManagement?documentId=3405887&managementType=1 - DGII implementation calendar, notice 10-26: https://dgii.gov.do/publicacionesOficiales/avisosInformativos/Documents/2026/10-26.pdf - DGII CA59, calculation for professional and technical services: https://ayuda.dgii.gov.do/conversations/retenciones-y-retribuciones-complementarias/ca59-qu-porcentaje-del-isr-deben-retener-las-personas-jurdicas-a-las-personas-fsicas-en-la-prestacin-de-servicios/5f3c175f8cd858ce879a130f - DGII clarification for General Rule 07-2007 and the construction sector: https://ayuda.dgii.gov.do/conversations/discusiones/aplicacin-de-la-ley-nm-3026-respecto-a-la-retencin-prevista-en-el-artculo-3-de-la-norma-general-072007-sector-construccin/6a45792cde3c6003da189ff1 - DGII legal basis for the 2% transfer withholding: https://ayuda.dgii.gov.do/conversations/discusiones/base-legal-retencion-2-transferencia-de-titulos-y-propiedades/5f6355928cd858ce872bb35a - Ministry clarification on the specific foreign technology and royalty categories: https://www.hacienda.gob.do/ley-30-26-no-dispone-impuestos-por-suscripciones-de-ciudadanos-a-plataformas-digitales-reduce-de-27-a-15-la-retencion-a-empresas-que-contratan-servicios-tecnologicos-en-el-exterior/ Legal basis cited by DGII: Law 11-92, article 309, as amended by Law 30-26, article 17; Regulation of Title II of the Tax Code, article 70. ## Validation - The branch is rebased on the current 17.0 head and contains one squashed commit. - The account, tax-template, and fiscal-position CSV files have consistent column counts, unique IDs, and valid child/account references. - A fresh Dominican chart contains only the new current-rate IDs; the superseded template IDs are absent. - The fresh chart was verified with fees/rentals at 15%; General Rule 07-2007 at 3% on `21030308`; Article 70(a)/(b) at 3% on `21030309`; transfers at 2% on `21030306`; general remittances at 27% on `21030307`; and the covered foreign categories at 15% on `21030310`. - The 15% services and 3% construction groups contain exactly the current tax children, and the new services fiscal position maps each purchase tax to only the 15% group. - An existing company loaded from the pre-law template was reloaded twice. Its historical 10%/10%/2% taxes, historical groups, and historical fiscal position retained their original record IDs and configuration; all current records were created once; the old and new positions each retained exactly two isolated mappings; and the second reload was idempotent. - `/account:TestChartTemplate`: 22 tests passed, 0 failures, 0 errors. This is the first contribution by Grupo de Consultoria Henca (https://www.consultoriahenca.com); the corporate CLA signature is included in `doc/cla/corporate/consultoriahenca.md` as instructed by `doc/cla/sign-cla.md`. Forward-Port-Of: odoo/odoo#275986
6 changes
Resolved issues and error corrections
Follow-up to the backport of the response module in commit 9ca317f99ed5acfca0da42b9cb99ffd995a41b8a . Currently (on 17.0) we do not send the supported identifiers when registering. So i.e. not the response service This is fixed in this commit. The IAP side had to be adapted so it was omitted in the original commit (since the main purpose was to backport PDP). IAP PR: https://github.com/odoo/iap-apps/pull/1757 task-None
Original PR description
Follow-up to the backport of the response module in commit 9ca317f99ed5acfca0da42b9cb99ffd995a41b8a . Currently (on 17.0) we do not send the supported identifiers when registering. So i.e. not the response service This is fixed in this commit. The IAP side had to be adapted so it was omitted in the original commit (since the main purpose was to backport PDP). IAP PR: https://github.com/odoo/iap-apps/pull/1757 task-None
#### Description of the issue/feature this PR addresses: Spanish amounts in words render "uno" where the grammar requires the apocopated "un" — on invoice PDFs, CFDI amounts, and anywhere num2words is called with a Spanish language. #### Current behavior before PR: "DOS MILLONES TRESCIENTOS UNO MIL CUATROCIENTOS TREINTA Y NUEVE PESOS 88/100 M.N." num2words applies the apocope only in to_currency(), never in to_cardinal(), and Odoo renders the plain cardinal then appends the currency label i
Original PR description
#### Description of the issue/feature this PR addresses: Spanish amounts in words render "uno" where the grammar requires the apocopated "un" — on invoice PDFs, CFDI amounts, and anywhere num2words…
#### Description of the issue/feature this PR addresses: Spanish amounts in words render "uno" where the grammar requires the apocopated "un" — on invoice PDFs, CFDI amounts, and anywhere num2words is called with a Spanish language. #### Current behavior before PR: "DOS MILLONES TRESCIENTOS UNO MIL CUATROCIENTOS TREINTA Y NUEVE PESOS 88/100 M.N." num2words applies the apocope only in to_currency(), never in to_cardinal(), and Odoo renders the plain cardinal then appends the currency label itself. Present in both versions pinned in requirements.txt (0.5.10, 0.5.13). #### Desired behavior after PR is merged: "DOS MILLONES TRESCIENTOS UN MIL CUATROCIENTOS TREINTA Y NUEVE PESOS 88/100 M.N." The apocope is applied in to_cardinal() through the num2words monkey patches, for es, es_CO and es_VE. Other languages are untouched. Note: the cardinal is now always apocopated, so a standalone count reads "un" rather than "uno". opw-6375677 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
the field l10n_sa_edi_is_production was introduced in 19.0, so it was never supposed to survive the backport to 17.0 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
the field l10n_sa_edi_is_production was introduced in 19.0, so it was never supposed to survive the backport to 17.0 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
Calling `/shop/payment/validate` as a portal user with an empty cart confirms the empty sale order. Steps to reproduce: - Sign in as a portal user. - Add a product to the cart. - Remove the product. - Go to `/shop/payment/validate`. - The empty sale order is confirmed. opw-6430637
Original PR description
Calling `/shop/payment/validate` as a portal user with an empty cart confirms the empty sale order. Steps to reproduce: - Sign in as a portal user. - Add a product to the cart. - Remove the product. - Go to `/shop/payment/validate`. - The empty sale order is confirmed. opw-6430637
When loading the registry, borrow the request to avoid having using the cursor linked to it. Failing use case before the fix: install base odoo, in the web interface, activate and switch to a new language then install website. The installation will hang if the stable cache is invalidated because the installation may call `_` which will fallback to the request's language - reading the table from the request's cursor - while the installation tries to update the same of that same table in anothe
Original PR description
When loading the registry, borrow the request to avoid having using the cursor linked to it. Failing use case before the fix: install base odoo, in the web interface, activate and switch to a new language then install website. The installation will hang if the stable cache is invalidated because the installation may call `_` which will fallback to the request's language - reading the table from the request's cursor - while the installation tries to update the same of that same table in another cursor. Backport of odoo/odoo#281797 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
**Steps to reproduce:** 1. Install Accounting 2. Import a new invoice with more than 1000 lines (xlsx file found in ticket attachments) 3. Test the imported records **Issue:** - `RecursionError: maximum recursion depth exceeded`. **Cause:** - In a previous commit (3e32d7b9eace62dfa7334009707a93967906c726) aimed at fixing stale analytic distribution totals, the assignment loop in `_compute_discount_allocation_needed` was changed from iterating over `self` to `self.move_id.line_ids`. -
Original PR description
**Steps to reproduce:** 1. Install Accounting 2. Import a new invoice with more than 1000 lines (xlsx file found in ticket attachments) 3. Test the imported records **Issue:** - `RecursionError:…
**Steps to reproduce:** 1. Install Accounting 2. Import a new invoice with more than 1000 lines (xlsx file found in ticket attachments) 3. Test the imported records **Issue:** - `RecursionError: maximum recursion depth exceeded`. **Cause:** - In a previous commit (3e32d7b9eace62dfa7334009707a93967906c726) aimed at fixing stale analytic distribution totals, the assignment loop in `_compute_discount_allocation_needed` was changed from iterating over `self` to `self.move_id.line_ids`. - While this ensured all lines generated updated distribution ratios, it violated the compute logic: assigning values to records outside the current compute batch (`self`). - By executing `line.discount_allocation_dirty = True` on external sibling lines, the method forced the ORM to trigger out-of-band `write()` calls. These writes re-triggered dependency checks (`_field_will_change`), which invoked the compute method again, leading to a recursive loop. **Fix:** 1. Revert the assignment iteration back to `for line in self:`. 2. To preserve the intention of the previous commit (ensuring all lines recompute their shared distribution pool when one line changes), modify the method's `@api.depends` to be `move_id.line_ids.discount` and `move_id.line_ids.analytic_distribution`. By declaring these relational dependencies, modifying a single line now batches all sibling lines into `self` from the start. This allows the lines to synchronize properly without triggering new ORM writes, eliminating the recursion. opw-6451854