Daily updates from Odoo
Wednesday, August 5, 2026
345 changes
13 changes
Enhancements to existing features
Backport various tests added in Odoo 19.4+ in order to better spot potential regressions. Forward-Port-Of: odoo/odoo#280568 Forward-Port-Of: odoo/odoo#279677
Original PR description
Backport various tests added in Odoo 19.4+ in order to better spot potential regressions. Forward-Port-Of: odoo/odoo#280568 Forward-Port-Of: odoo/odoo#279677
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and /discuss/channel/messages. Measured from openDiscuss resolving to the message being in the DOM: - 250 to 460ms on an idle machine; - 867 to 5258ms over 10 runs with the CPU throttled 4x, which is what a busy runbot looks like, 3 of the 10 over 2 seconds; - 1474 to 6912ms with the CPU throttl
Original PR description
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and…
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and /discuss/channel/messages. Measured from openDiscuss resolving to the message being in the DOM:
- 250 to 460ms on an idle machine;
- 867 to 5258ms over 10 runs with the CPU throttled 4x, which is what a
busy runbot looks like, 3 of the 10 over 2 seconds;
- 1474 to 6912ms with the CPU throttled 6x, 5 of 6 over 3 seconds.
"Reactions are ordered by id" fails 1 run in 60 at 4x for that reason.
Note that a longer timeout costs nothing on a green build: the timer is cleared as soon as the element is there, so it only delays the report of a test that was going to fail anyway.
This commit raises both to 10 seconds, the delay a tour step already gets in macro.js. test_js.py runs the presets with timeout=15000, so hoot fails the test itself at 15 seconds and 10 leaves room for the rest of the test.
This should also close most of the open runbot errors shaped like:
Failed to find x of "..." (Timeout of 3 seconds). Found 0 instead.
The element does show up in those, just after the wait gave up.
https://runbot.odoo.com/odoo/error/944188
web companion https://github.com/odoo/odoo/pull/279984
Forward-Port-Of: odoo/odoo#280586
Forward-Port-Of: odoo/odoo#279983Resolved issues and error corrections
Before this commit, the user's presence was not sent to the server when another device reported this user as away/offline while this device was online. `ImStatusMixin` reacts to `presence_status` and correct the user's presence on the server when needed (e.g. locally online while away was received). Since [1], the check on the presence being the one of the current user is wrong (comparing `store.self` to the presence user record). The tests only pass because of the initial presence upda
Original PR description
Before this commit, the user's presence was not sent to the server when another device reported this user as away/offline while this device was online. `ImStatusMixin` reacts to `presence_status` and correct the user's presence on the server when needed (e.g. locally online while away was received). Since [1], the check on the presence being the one of the current user is wrong (comparing `store.self` to the presence user record). The tests only pass because of the initial presence update. This commit fixes the issue and ensures the initial update is not confused by the correction. [1]: https://github.com/odoo/odoo/pull/248168 runbot-944282 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#280314
- removed traceback when probe fails on `l10n_ke_edi` driver, - filtered logs from custom drivers (not sending them to sentry anymore - fixed session_id request for websocket, failing on 303 - updated exception_logger so that it catches exceptions as a whole instead of line by line. task-6445199
Original PR description
- removed traceback when probe fails on `l10n_ke_edi` driver, - filtered logs from custom drivers (not sending them to sentry anymore - fixed session_id request for websocket, failing on 303 - updated exception_logger so that it catches exceptions as a whole instead of line by line. task-6445199
# How to reproduce - Create a SO - Add a Section with a multi-line description - Add any product - Confirm & Create an invoice - Go to the invoice # The issue The Section's description is squished on a single line # The problem Since [this commit](https://github.com/odoo/odoo/commit/95c36bcd241b30e6e2d4a2915d38118ddb7556e0) it is now possible to add a multi-line description to a SO. They allowed this by changing the corresponding widgets. The issue is that the widget for the Sect
Original PR description
# How to reproduce - Create a SO - Add a Section with a multi-line description - Add any product - Confirm & Create an invoice - Go to the invoice # The issue The Section's description is squished on a single line # The problem Since [this commit](https://github.com/odoo/odoo/commit/95c36bcd241b30e6e2d4a2915d38118ddb7556e0) it is now possible to add a multi-line description to a SO. They allowed this by changing the corresponding widgets. The issue is that the widget for the Section description in the Invoice view does not handle multi-line content opw-6357044
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930 Forward-Port-Of: odoo/odoo#278782
Original PR description
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930 Forward-Port-Of: odoo/odoo#278782
Before this commit, opening a live chat in Discuss crashes as soon as the visitor is a contact with an open lead, and the agent can no longer post in that conversation: TypeError: can't access property "length", ctx.templateParams.info_records is undefined This happens because the "Open leads" block reads the visitor member on the channel to decide whether to show itself, and on the thread, which holds none, to pass the leads. It therefore calls info_links with no record, and info
Original PR description
Before this commit, opening a live chat in Discuss crashes as soon as the visitor is a contact with an open lead, and the agent can no longer post in that conversation:
TypeError: can't access property "length",
ctx.templateParams.info_records is undefined
This happens because the "Open leads" block reads the visitor member on the channel to decide whether to show itself, and on the thread, which holds none, to pass the leads. It therefore calls info_links with no record, and info_links reads their length. The panel opens by default in Discuss, so the crash takes the composer with it.
This commit reads the visitor member on the channel to pass the leads, and drops the condition of the caller, so that info_links alone decides whether it has something to show.
https://github.com/odoo/enterprise/pull/126715
Forward-Port-Of: odoo/odoo#280430When running `ŧest_free_reservation`, it could happen on very rare occasions that both moves would be created at a different second. In such cases, the test would fail. Since we want to test the case with *exact* same dates, we can't use `assertAlmostEqual` which is usually better for dates. Instead, we freeze the time for the duration of the creation / assignation. runbot-944453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of:
Original PR description
When running `ŧest_free_reservation`, it could happen on very rare occasions that both moves would be created at a different second. In such cases, the test would fail. Since we want to test the case with *exact* same dates, we can't use `assertAlmostEqual` which is usually better for dates. Instead, we freeze the time for the duration of the creation / assignation. runbot-944453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279954 Forward-Port-Of: odoo/odoo#278103
Ensure combo prices are computed in the backend. Forward-Port-Of: odoo/odoo#279919 Forward-Port-Of: odoo/odoo#279652
Original PR description
Ensure combo prices are computed in the backend. Forward-Port-Of: odoo/odoo#279919 Forward-Port-Of: odoo/odoo#279652
As of commit 4588e939, transactions are processed asynchronously by a dedicated cron, so they're still in the `draft` state right after a call to `_charge_with_token`. Posting just created `account.payment` records based on the transaction state was no longer relevant, and running their post-processing immediately after made the problem worse: the transactions were flagged as post-processed while still `draft`, so the post-processing cron later skipped them, and the payments were directly cancel
Original PR description
As of commit 4588e939, transactions are processed asynchronously by a dedicated cron, so they're still in the `draft` state right after a call to `_charge_with_token`. Posting just created `account.payment` records based on the transaction state was no longer relevant, and running their post-processing immediately after made the problem worse: the transactions were flagged as post-processed while still `draft`, so the post-processing cron later skipped them, and the payments were directly canceled due to the transaction not being already in the `done` state. This commit defers both the posting and the cancellation of payments to the post-processing step. Just like the post-processing used to cancel payments for `cancel` transactions, it now cancels all those whose transaction didn't reach a "paid" (`authorized` or `done`) state, so that both declined token charges and API request errors now result in a cancellation of the payment.
Before this commit, this test was failing non-deterministically on on some machines: ``` show banner for new message after thread was read from another device ``` With the following error: ``` Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead. ``` This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it c
Original PR description
Before this commit, this test was failing non-deterministically on on some machines:
```
show banner for new message after thread was read from another device
```
With the following error:
```
Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead.
```
This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it can mark as read automatically the conversation. When this happens the banner is removed, thus the last step would fail.
This commit fixes the issue by making each message body bigger, so that this is very unlikely to see the bottom of message list, therefore avoiding the auto-mark as read from reaching the bottom of conversation.
Forward-Port-Of: odoo/odoo#280103Repro steps: 1) Create an invoice 2) Activate auto post (monthly for example) 3) Confirm the invoice, a new draft invoice will be created 4) Reset to draft 5) Confirm again Problem: A second draft would be created, and next period, 2 invoices would be confirmed Fix: This commit deletes the next auto post recurrence of an invoice, if that next recurrence is in draft, and the invoice is being set to draft. It also prevents creating a recurrence at a date if there is already an exi
Original PR description
Repro steps: 1) Create an invoice 2) Activate auto post (monthly for example) 3) Confirm the invoice, a new draft invoice will be created 4) Reset to draft 5) Confirm again Problem: A second draft would be created, and next period, 2 invoices would be confirmed Fix: This commit deletes the next auto post recurrence of an invoice, if that next recurrence is in draft, and the invoice is being set to draft. It also prevents creating a recurrence at a date if there is already an existing recurrent move on that date. task-6311219 Forward-Port-Of: odoo/odoo#280570 Forward-Port-Of: odoo/odoo#279159
Before this commit, turning the camera on during a call could leave the camera off in every member's UI, including the local user's own tile, while the video was already being sent. This happens because toggleVideo awaits network.updateUpload before updateAndBroadcast, and updateUpload waits on the ready promise of every peer. A single member whose handshake never completes holds isCameraOn and isScreenSharingOn for everyone. This commit fixes the issue by broadcasting the state first and
Original PR description
Before this commit, turning the camera on during a call could leave the camera off in every member's UI, including the local user's own tile, while the video was already being sent. This happens because toggleVideo awaits network.updateUpload before updateAndBroadcast, and updateUpload waits on the ready promise of every peer. A single member whose handshake never completes holds isCameraOn and isScreenSharingOn for everyone. This commit fixes the issue by broadcasting the state first and awaiting the upload after. Note that updateUpload sends its info snapshot to the peers synchronously, so they still learn the new track. Back-port of https://github.com/odoo/odoo/pull/279106 Forward-Port-Of: odoo/odoo#280492 Forward-Port-Of: odoo/odoo#280014
10 changes
Enhancements to existing features
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and /discuss/channel/messages. Measured from openDiscuss resolving to the message being in the DOM: - 250 to 460ms on an idle machine; - 867 to 5258ms over 10 runs with the CPU throttled 4x, which is what a busy runbot looks like, 3 of the 10 over 2 seconds; - 1474 to 6912ms with the CPU throttl
Original PR description
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and…
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and /discuss/channel/messages. Measured from openDiscuss resolving to the message being in the DOM:
- 250 to 460ms on an idle machine;
- 867 to 5258ms over 10 runs with the CPU throttled 4x, which is what a
busy runbot looks like, 3 of the 10 over 2 seconds;
- 1474 to 6912ms with the CPU throttled 6x, 5 of 6 over 3 seconds.
"Reactions are ordered by id" fails 1 run in 60 at 4x for that reason.
Note that a longer timeout costs nothing on a green build: the timer is cleared as soon as the element is there, so it only delays the report of a test that was going to fail anyway.
This commit raises both to 10 seconds, the delay a tour step already gets in macro.js. test_js.py runs the presets with timeout=15000, so hoot fails the test itself at 15 seconds and 10 leaves room for the rest of the test.
This should also close most of the open runbot errors shaped like:
Failed to find x of "..." (Timeout of 3 seconds). Found 0 instead.
The element does show up in those, just after the wait gave up.
https://runbot.odoo.com/odoo/error/944188
web companion https://github.com/odoo/odoo/pull/279984
Forward-Port-Of: odoo/odoo#280586
Forward-Port-Of: odoo/odoo#279983Resolved issues and error corrections
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930 Forward-Port-Of: odoo/odoo#278782
Original PR description
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930 Forward-Port-Of: odoo/odoo#278782
Before this commit, this test was failing non-deterministically on on some machines: ``` show banner for new message after thread was read from another device ``` With the following error: ``` Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead. ``` This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it c
Original PR description
Before this commit, this test was failing non-deterministically on on some machines:
```
show banner for new message after thread was read from another device
```
With the following error:
```
Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead.
```
This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it can mark as read automatically the conversation. When this happens the banner is removed, thus the last step would fail.
This commit fixes the issue by making each message body bigger, so that this is very unlikely to see the bottom of message list, therefore avoiding the auto-mark as read from reaching the bottom of conversation.
Forward-Port-Of: odoo/odoo#280103When running `ŧest_free_reservation`, it could happen on very rare occasions that both moves would be created at a different second. In such cases, the test would fail. Since we want to test the case with *exact* same dates, we can't use `assertAlmostEqual` which is usually better for dates. Instead, we freeze the time for the duration of the creation / assignation. runbot-944453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of:
Original PR description
When running `ŧest_free_reservation`, it could happen on very rare occasions that both moves would be created at a different second. In such cases, the test would fail. Since we want to test the case with *exact* same dates, we can't use `assertAlmostEqual` which is usually better for dates. Instead, we freeze the time for the duration of the creation / assignation. runbot-944453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279954 Forward-Port-Of: odoo/odoo#278103
Ensure combo prices are computed in the backend. Forward-Port-Of: odoo/odoo#279919 Forward-Port-Of: odoo/odoo#279652
Original PR description
Ensure combo prices are computed in the backend. Forward-Port-Of: odoo/odoo#279919 Forward-Port-Of: odoo/odoo#279652
If the badge selection widget value is false, you get an error as it cannot includes in false. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
If the badge selection widget value is false, you get an error as it cannot includes in false. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Before this commit, turning the camera on during a call could leave the camera off in every member's UI, including the local user's own tile, while the video was already being sent. This happens because toggleVideo awaits network.updateUpload before updateAndBroadcast, and updateUpload waits on the ready promise of every peer. A single member whose handshake never completes holds isCameraOn and isScreenSharingOn for everyone. This commit fixes the issue by broadcasting the state first and
Original PR description
Before this commit, turning the camera on during a call could leave the camera off in every member's UI, including the local user's own tile, while the video was already being sent. This happens because toggleVideo awaits network.updateUpload before updateAndBroadcast, and updateUpload waits on the ready promise of every peer. A single member whose handshake never completes holds isCameraOn and isScreenSharingOn for everyone. This commit fixes the issue by broadcasting the state first and awaiting the upload after. Note that updateUpload sends its info snapshot to the peers synchronously, so they still learn the new track. Back-port of https://github.com/odoo/odoo/pull/279106 Forward-Port-Of: odoo/odoo#280492 Forward-Port-Of: odoo/odoo#280014
The tracking field was removed from point_of_sale in https://github.com/odoo/odoo/pull/241368 However, forward ports may still keep the field in fixes prior to 19.3 like here in https://github.com/odoo/odoo/pull/279952 This breaks silently because issues only occur when stock is not installed so the forward-port build won't fail but some nightly builds will. runbot-error-944823
Original PR description
The tracking field was removed from point_of_sale in https://github.com/odoo/odoo/pull/241368 However, forward ports may still keep the field in fixes prior to 19.3 like here in https://github.com/odoo/odoo/pull/279952 This breaks silently because issues only occur when stock is not installed so the forward-port build won't fail but some nightly builds will. runbot-error-944823
[FIX] html_builder: prevent crash on legacy image shapes When the Website Editor encounters an image shape that does not exist in the registry, it fatally crashes upon saving (`TypeError: Cannot read properties of undefined`), blocking the user from saving the page. While an upgrade script exists to remap these shapes ([commit https://github.com/odoo/odoo/commit/f348be018f5740a31754494c905ea2b61bb718be](https://github.com/odoo/upgrade/commit/f348be0dcbc63c1f74f742b562509f81767564c0)), ti
Original PR description
[FIX] html_builder: prevent crash on legacy image shapes When the Website Editor encounters an image shape that does not exist in the registry, it fatally crashes upon saving (`TypeError: Cannot read…
[FIX] html_builder: prevent crash on legacy image shapes When the Website Editor encounters an image shape that does not exist in the registry, it fatally crashes upon saving (`TypeError: Cannot read properties of undefined`), blocking the user from saving the page. While an upgrade script exists to remap these shapes ([commit https://github.com/odoo/odoo/commit/f348be018f5740a31754494c905ea2b61bb718be](https://github.com/odoo/upgrade/commit/f348be0dcbc63c1f74f742b562509f81767564c0)), timeline gaps leave SaaS databases vulnerable. For example, if a client upgraded their database to 17.0 in Feb 2024, they bypassed the migration script merged in Dec 2024. This leaves the legacy shape permanently orphaned inside their modern views. This commit adds a `getImageShape` fallback. Instead of crashing,the editor now defaults to standard values and renders "None" in the UI, allowing the user to select a new shape and save their work. Steps to Reproduce: 1. Install Website. 2. Go to Site -> HTML / CSS Editor. 3. Add `data-shape="web_editor/basic/bsc_organic_2"` to an <img> tag. 4. Click "Edit" to open the Website Builder. 5. Click the image, OR click "Save". 6. JS traceback. [opw-6286044](https://www.odoo.com/odoo/my-support-tasks/6286044?debug=assets) [opw-6291591](https://www.odoo.com/odoo/my-support-tasks/6291591?debug=assets) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278686 Forward-Port-Of: odoo/odoo#270356
The `selection` attribute of `fields.Selection` is not generally translated (unless it is a function instead of a list). For user facing strings, we generally need to translate the value displayed. 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#280257 Forward-Port-Of: odoo/odoo#280094
Original PR description
The `selection` attribute of `fields.Selection` is not generally translated (unless it is a function instead of a list). For user facing strings, we generally need to translate the value displayed. 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#280257 Forward-Port-Of: odoo/odoo#280094
3 changes
Resolved issues and error corrections
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930 Forward-Port-Of: odoo/odoo#278782
Original PR description
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930 Forward-Port-Of: odoo/odoo#278782
Before this commit, this test was failing non-deterministically on on some machines: ``` show banner for new message after thread was read from another device ``` With the following error: ``` Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead. ``` This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it c
Original PR description
Before this commit, this test was failing non-deterministically on on some machines:
```
show banner for new message after thread was read from another device
```
With the following error:
```
Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead.
```
This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it can mark as read automatically the conversation. When this happens the banner is removed, thus the last step would fail.
This commit fixes the issue by making each message body bigger, so that this is very unlikely to see the bottom of message list, therefore avoiding the auto-mark as read from reaching the bottom of conversation.
Forward-Port-Of: odoo/odoo#280103**PROBLEM** Before this PR, there was no way to handle invoices sent to clients depending from a JST/LGU (local government unit). This PR add support for it. opw-6095581 Forward-Port-Of: odoo/odoo#280377 Forward-Port-Of: odoo/odoo#260367
Original PR description
**PROBLEM** Before this PR, there was no way to handle invoices sent to clients depending from a JST/LGU (local government unit). This PR add support for it. opw-6095581 Forward-Port-Of: odoo/odoo#280377 Forward-Port-Of: odoo/odoo#260367
5 changes
Enhancements to existing features
Comply with new provincial fiscal transparency regulations (CABA, Entre Ríos, Chubut, and other provinces still not defined) that mandate detailing Perception IIBB taxes on B2C invoices (Factura/Invoice B): - Some jurisdictions mandate a new description for IIBB perception taxes on the invoice, - We need to put the IIBB perception taxes in the special "Fiscal Transparency Regime" table, and exclude them from the standard tax table, task-6367087 Forward-Port-Of: odoo/odoo#278729 Forwar
Original PR description
Comply with new provincial fiscal transparency regulations (CABA, Entre Ríos, Chubut, and other provinces still not defined) that mandate detailing Perception IIBB taxes on B2C invoices (Factura/Invoice B): - Some jurisdictions mandate a new description for IIBB perception taxes on the invoice, - We need to put the IIBB perception taxes in the special "Fiscal Transparency Regime" table, and exclude them from the standard tax table, task-6367087 Forward-Port-Of: odoo/odoo#278729 Forward-Port-Of: odoo/odoo#277673
Resolved issues and error corrections
Before this commit, this test was failing non-deterministically on on some machines: ``` show banner for new message after thread was read from another device ``` With the following error: ``` Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead. ``` This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it c
Original PR description
Before this commit, this test was failing non-deterministically on on some machines:
```
show banner for new message after thread was read from another device
```
With the following error:
```
Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead.
```
This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it can mark as read automatically the conversation. When this happens the banner is removed, thus the last step would fail.
This commit fixes the issue by making each message body bigger, so that this is very unlikely to see the bottom of message list, therefore avoiding the auto-mark as read from reaching the bottom of conversation.
Forward-Port-Of: odoo/odoo#280103**Steps to reproduce:** - Go to any view where you can send mails (eg sale orders) - Send a first mail to multiple recipients so they are added automatically on the next mail. - Open a new mail, confirm that the recipients are present, add a selectable attachment (eg a PDF), then click on it. - Remove any amount of recipients then send the mail. - You will see that the recipients are added back and the mail is sent to them. **Behavior:** Currently whenever a user clicks on an attachment
Original PR description
**Steps to reproduce:** - Go to any view where you can send mails (eg sale orders) - Send a first mail to multiple recipients so they are added automatically on the next mail. - Open a new mail,…
**Steps to reproduce:**
- Go to any view where you can send mails (eg sale orders)
- Send a first mail to multiple recipients so they are added automatically on the next mail.
- Open a new mail, confirm that the recipients are present, add a selectable attachment (eg a PDF), then click on it.
- Remove any amount of recipients then send the mail.
- You will see that the recipients are added back and the mail is sent to them.
**Behavior:**
Currently whenever a user clicks on an attachment in a mail composer, the systems considers that the user might be trying
to leave the page and will trigger an `urgentSave()`, and further down the line a `web_save()`.
The behavior when a web_save() is triggered is to create a record if there isnt currently one, and otherwise to write the modified values onto the record, using commands.
The recipients for the mail are added by default, which is represented by a list of `[4, id]`add commands, that will be written on the record created in the first `web_save`, however this list is not correctly emptied after the first `_save()`.
If the list is present within `this._changes` then it is correctly cleared, but in the case where no changes were made, the within `this._values['partner_ids']` still contains the commands.
So when we later assign `this.data = { ...this._values };`, `this.data['partner_ids']` now contains our uncleared list of commands.
https://github.com/odoo/odoo/blob/f3e407c6a58abd2ddba42f26fcbd1928da63cb63/addons/web/static/src/model/relational_model/record.js#L1222-L1230
And when we compute changes['partner_ids'] in our next iteration, we find ourselves with our command list again.
https://github.com/odoo/odoo/blob/f3e407c6a58abd2ddba42f26fcbd1928da63cb63/addons/web/static/src/model/relational_model/record.js#L1317-L1322
So when we then try to remove a recipient tag, the new delete command `[3, id]`
just gets canceled out with the already present add command.
And the `write()` in `web_save()` only writes add commands of already present partners, which doesn't do anything.
----
This commit adds a line to ensure commands inside `_values` are cleared
opw-6304713
Forward-Port-Of: odoo/odoo#278876### Steps to reproduce: - Create a product with a bom and 2 operations - Create an MO for 1 unit of that product - Confirm the MO - On the bom, delete the second operation and modify the first operation on anything else than the company, name or workcenter - Go back to the MO, click the "Update Bom" button > The second operation is not unlinked and the first operation is not updated ### Cause of the issue: The `action_update_bom` updates the move raws and operations of the MO via t
Original PR description
### Steps to reproduce: - Create a product with a bom and 2 operations - Create an MO for 1 unit of that product - Confirm the MO - On the bom, delete the second operation and modify the first…
### Steps to reproduce: - Create a product with a bom and 2 operations - Create an MO for 1 unit of that product - Confirm the MO - On the bom, delete the second operation and modify the first operation on anything else than the company, name or workcenter - Go back to the MO, click the "Update Bom" button > The second operation is not unlinked and the first operation is not updated ### Cause of the issue: The `action_update_bom` updates the move raws and operations of the MO via the `_link_bom`: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L1214-L1218 For draft MO's all the work of these updates is done via the compute methods and by deleting all the records unrelevant to the new bom: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2603-L2626 And, in that case all the workorders that are not linked to an operation of the bom are expected to be deleted. However, when the MO is not in draft, the update of operations is expected to be performed here: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2647-L2664 However, since the operation of the bom has been deleted, the workorder that is expected to be deleted is not linked to any operation and hence does not satisfy the condition to be deleted: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2663-L2664 Concerning the non update of operations, it happens because the MO's operation are only updated on the three fields: `company_id`, `workcenter_id`, `name`: https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/mrp/models/mrp_production.py#L2647-L2664 https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/mrp/models/mrp_production.py#L2628-L2629 However, many other changes can and are actually relevant. ### Note: Prior to commit 80e6ed658fb43584bc2fad673ca40d9af6cf0ab6 operations were archived on boms rather than deleted: https://github.com/odoo/odoo/blob/4a5270218fe6fd7d30edb6d684b3340dc7423bab/addons/mrp/views/mrp_routing_views.xml#L53-L55 As such they would still be linked to an operation (but unrelated to the present values of the bom) and hence would fall into the condition of being unlinked from the MO. Since the bom operations are no longer archived there is no way to determine if an operation used to be linked to a bom and we therefore need to chose between deleting all operations unrelated to the present bom or to keep them all (when the MO has been confirmed). Starting from saas-19.1, the fix conflict with commit https://github.com/odoo/odoo/commit/5c4cf2e0fcc3ed5bef77380bb65f356c56b5dac4 That is, the `action_update_bom`, now replan's workorders: https://github.com/odoo/odoo/blob/3412253211daf13d50755fdce7edd9ed9c4400df/addons/mrp/models/mrp_production.py#L1207-L1217 However, the `_link_bom` now unlinks the obsolete and re-creates the still valid workorders (possibly unplanned). In particular, both the computation of `is_planned` and of the new `duration_expected` might differ from the expected checked in the `action_update_bom`. Note that to ensure everything goes as planned, we need to unlink the obsolete workorders before creating the new workorders which would be incorrectly replanned. Other than that, the check on the `duration_expected` in the `action_update_bom` needs to be updated accordingly. Enterprise: https://github.com/odoo/enterprise/pull/120709 opw-6285878 opw-6261738 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269747
Microsoft issues a new refresh token on every access token refresh (rolling 90-day sliding window). The previous code discarded it, causing users to be forced to re-authenticate every 90 days once the original token expired. Closes #253543 Forward-Port-Of: odoo/odoo#276595 Forward-Port-Of: odoo/odoo#268284
Original PR description
Microsoft issues a new refresh token on every access token refresh (rolling 90-day sliding window). The previous code discarded it, causing users to be forced to re-authenticate every 90 days once the original token expired. Closes #253543 Forward-Port-Of: odoo/odoo#276595 Forward-Port-Of: odoo/odoo#268284
5 changes
Enhancements to existing features
The checks the Tax Agency performs are always based on the latest version of their XSD (no API versioning), but the XSD URI changes with each new version of the checks. Since it's not functionally used, it's not so important to keep it always updated and yet now: - we now update the export templates to have the latest `schemalocation` URI for once. - we start ignoring namespaces in l10n_it_* XML tests - we start ignoring the root FatturaElettronica tag's namespace attributes so there
Original PR description
The checks the Tax Agency performs are always based on the latest version of their XSD (no API versioning), but the XSD URI changes with each new version of the checks. Since it's not functionally used, it's not so important to keep it always updated and yet now: - we now update the export templates to have the latest `schemalocation` URI for once. - we start ignoring namespaces in l10n_it_* XML tests - we start ignoring the root FatturaElettronica tag's namespace attributes so there won't be a problem in case we change the `schemalocation` again. Forward-Port-Of: odoo/odoo#275345
Resolved issues and error corrections
Steps to reproduce: - Install employees and attendance app - Make sure there are 2 companies - Make user's employee record for Company B, but not A - Make company A the default company for user - Enable "attendances from backend" setting - Click on the attendance dot (systray) Current Behavior: The dot disappears and you can't check in Expected Behavior: You are able to check in Other bug scenario: If you have employee records in both Company A and Company B, you can check in.
Original PR description
Steps to reproduce: - Install employees and attendance app - Make sure there are 2 companies - Make user's employee record for Company B, but not A - Make company A the default company for user - Enable "attendances from backend" setting - Click on the attendance dot (systray) Current Behavior: The dot disappears and you can't check in Expected Behavior: You are able to check in Other bug scenario: If you have employee records in both Company A and Company B, you can check in. However, you can never check in for Company B as the default company is always selected in the server code opw-6392301 Forward-Port-Of: odoo/odoo#279675 Forward-Port-Of: odoo/odoo#278377
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930 Forward-Port-Of: odoo/odoo#278782
Original PR description
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930 Forward-Port-Of: odoo/odoo#278782
Before this commit, this test was failing non-deterministically on on some machines: ``` show banner for new message after thread was read from another device ``` With the following error: ``` Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead. ``` This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it c
Original PR description
Before this commit, this test was failing non-deterministically on on some machines:
```
show banner for new message after thread was read from another device
```
With the following error:
```
Error: Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 3 seconds). Found 0 instead.
```
This happens because while the message list has 20 messages, each message is 1-line long. That means on many monitors the bottom of conversation is visible and thus it can mark as read automatically the conversation. When this happens the banner is removed, thus the last step would fail.
This commit fixes the issue by making each message body bigger, so that this is very unlikely to see the bottom of message list, therefore avoiding the auto-mark as read from reaching the bottom of conversation.
Forward-Port-Of: odoo/odoo#280103**Steps to reproduce:** 1. Install Accounting and l10n_be and switch to the Belgian company 2. In the settings, set the discount account (`708000`) on Customer Invoices under "Default Accounts" and enable analytic accounting 3. Go to [Accounting -> Configuration -> Analytic Accounts] and create 4 new accounts with "Project" plan (i.e 1,2,3,4) 4. Create a new invoice with two lines, each having 2 of the analytic accounts with 50% each. 5. Set the price to 1000 and a 10% discount for each lin
Original PR description
**Steps to reproduce:** 1. Install Accounting and l10n_be and switch to the Belgian company 2. In the settings, set the discount account (`708000`) on Customer Invoices under "Default Accounts" and…
**Steps to reproduce:** 1. Install Accounting and l10n_be and switch to the Belgian company 2. In the settings, set the discount account (`708000`) on Customer Invoices under "Default Accounts" and enable analytic accounting 3. Go to [Accounting -> Configuration -> Analytic Accounts] and create 4 new accounts with "Project" plan (i.e 1,2,3,4) 4. Create a new invoice with two lines, each having 2 of the analytic accounts with 50% each. 5. Set the price to 1000 and a 10% discount for each line then save. 6. Edit the second line and set the discount to 20%. 7. Open the Journal Items tab **Issue:** - When an invoice contains multiple lines with analytic distributions, changing the discount percentage on any line other than the first fails to correctly update the analytic distribution percentages on the corresponding discount journal items. - The analytic account distribution splits the percentage evenly across both accounts event if they are not split 50/50 **Why this happens:** - This occurred because `_compute_discount_allocation_needed` iterated over `self` to populate target changes. When only one line was modified, `self` contains that line only which is correctly updated with the new analytic distribution. Later in the execution in `_sync_dynamic_line`, particularly in https://github.com/odoo/odoo/blob/5a14360705a55f4d91edf39c936d7a5d8573044b/addons/account/models/account_move.py#L2263-L2274 The first line in `computed_needed` is what gets set in res, and subsequent lines only modify the field if it's monetary. So if the second invoice line is the one updated, it will never override the `analytic_distribution` with the updated values, leaving stale values in that field. - The code iterated directly over `line.analytic_distribution` dictionary keys (the account IDs) rather than its `.items()`. This caused it to ignore the individual percentage value splits (e.g. 60/40), accumulating the un-weighted full discount amount to each account ID. https://github.com/odoo/odoo/blob/5a14360705a55f4d91edf39c936d7a5d8573044b/addons/account/models/account_move_line.py#L1044-L1052 **Fix:** - Change the processing loop inside `_compute_discount_allocation_needed` from `self` to `self.move_id.line_ids` to calculate the correct `analytic_distribution` across all records. - Applying the factored weight ratio (`amount * (percentage / 100.0)`) to `distribution_totals` opw-6362084 Forward-Port-Of: odoo/odoo#279977 Forward-Port-Of: odoo/odoo#275070
7 changes
Resolved issues and error corrections
Before this commit, this test sometimes failed because it couldn't find a dialog containing "camera" within 200ms. In the test scenario, we click to open the BarcodeDialog, which uses the BarcodeVideoScanner. The latter, in its `onMounted`, checks whether it has the necessary permission, which isn't the case as the `getUserMedia` function is mocked in the test to return a rejected promise. As a consequence, the `onError` callback given in props is called, which changes the state of the parent
Original PR description
Before this commit, this test sometimes failed because it couldn't find a dialog containing "camera" within 200ms. In the test scenario, we click to open the BarcodeDialog, which uses the BarcodeVideoScanner. The latter, in its `onMounted`, checks whether it has the necessary permission, which isn't the case as the `getUserMedia` function is mocked in the test to return a rejected promise. As a consequence, the `onError` callback given in props is called, which changes the state of the parent component, which re-renders itself so display "Unable to access camera" instead of the BarcodeVideoScanner. To make this test more robust, we do 2 things: 1) load the zxing library before running the test, which avoids the BarcodeVideoScanner component to load it in onWillStart. 2) explicitly wait for the 2 animationFrames, as in the scenario, we must wait for the BarcodeDialog to be rendered twice, and those renderings are now synchronous. runbot error-237933
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930
Original PR description
Previously, we did not prevent FRCTC from registering through Peppol, even though FRCTC is not supported in Peppol. French companies could attempt to register in Peppol with FRCTC, which caused many errors. task-6421930
Steps: - Install sale_management - Make sure you have 100 quotations with 1 activity each - Open activity view - Default pager displays `1-100/100` - Activity count display `To-do 80` ActivityController uses `useModel` which passes the raw `component.props` to `model.load()`, including the limit from `ir.actions.act_window` (default 80). This value ended up in `fetchActivityData` via `params.limit || this.initialLimit`, overriding `ActivityModel.DEFAULT_LIMIT` (100). The records li
Original PR description
Steps: - Install sale_management - Make sure you have 100 quotations with 1 activity each - Open activity view - Default pager displays `1-100/100` - Activity count display `To-do 80`…
Steps: - Install sale_management - Make sure you have 100 quotations with 1 activity each - Open activity view - Default pager displays `1-100/100` - Activity count display `To-do 80` ActivityController uses `useModel` which passes the raw `component.props` to `model.load()`, including the limit from `ir.actions.act_window` (default 80). This value ended up in `fetchActivityData` via `params.limit || this.initialLimit`, overriding `ActivityModel.DEFAULT_LIMIT` (100). The records list was not affected because `RelationalModel._getNextConfig` never reads `params.limit` (limit is not a `SEARCH_KEY`), so it always loaded 100 records correctly. But `fetchActivityData` used 80, causing a mismatch between the records shown and the activity counts in the column headers. ```js export const SEARCH_KEYS = ["comparison", "context", "domain", "groupBy", "orderBy"]; ``` The fix strips `params.limit` in `ActivityModel.load()` before passing params to `fetchActivityData`, so it falls back to `this.initialLimit (100)`. The pager `onUpdate` handler calls `fetchActivityData` directly with its own `params.limit` and is not affected. However, `ActivityController` never forwards `limit` to the model. This is why we always have `ActivityModel.DEFAULT_LIMIT (100)` without taking into account actions's limit. To fix this we have to add the limit via `this.props.limit`, as `ListController`. `useModelWithSampleData` already had the correct behavior by calling `model.load(getSearchParams(props))` which filters out non-search params like limit. In 19.0 useModel was updated to do the same, so the issue does not exist there. Link to 19.0 fix: https://github.com/odoo/odoo/pull/211697 opw-6281125
**Steps to reproduce:** - Install l10n_pl_edi and enable Allow KSeF integration from **Accounting** settings. - Switch to a Polish company. - Create an EU customer with a valid VAT number. - Create a sale order containing a service product taxed with 0% Steel (or any tax that has a tag of K11). - Confirm the sale order and create a down payment invoice. - Send the invoice to KSeF and inspect the generated XML. **Observed behavior:** The generated KSeF XML does not contai
Original PR description
**Steps to reproduce:** - Install l10n_pl_edi and enable Allow KSeF integration from **Accounting** settings. - Switch to a Polish company. - Create an EU customer with a valid VAT number. - Create a…
**Steps to reproduce:** - Install l10n_pl_edi and enable Allow KSeF integration from **Accounting** settings. - Switch to a Polish company. - Create an EU customer with a valid VAT number. - Create a sale order containing a service product taxed with 0% Steel (or any tax that has a tag of K11). - Confirm the sale order and create a down payment invoice. - Send the invoice to KSeF and inspect the generated XML. **Observed behavior:** The generated KSeF XML does not contain the `P_13_8` field. **Cause:** For invoices involving the tax of tag `K11` (mainly these taxes are used for the supplies that are outside the territory of Poland), the value corresponding to `P_13_8` was not being assigned during XML generation, causing the tag to be omitted from the exported KSeF document. **Fix:** Populate the value of `P_13_8` during KSeF XML generation for invoices, ensuring the field is correctly included in the exported XML. This PR updates the computation of tag `P_13_10` with its test case to ensure consistency with the expected reporting logic, where the tag is computed solely from `K_31`. Here is the [Documentation](https://ksef.podatki.gov.pl/media/gtjhkeek/information-sheet-on-the-fa-3-logical-structure-04032026.pdf) link for the reference of the Ksef structure. **opw**-6294181
When a product carrying a multi-select (no_variant) attribute is added to an order by scanning its barcode, the extra price of the selected attribute value was dropped and the product was added at its base price. The order line total is computed from `price_unit` alone. The `price_extra` of a no_variant attribute is never included in the variant price (a "multi" attribute requires create_variant="no_variant"), so it only reaches the total once folded into `price_unit`. `addLineToOrder` did th
Original PR description
When a product carrying a multi-select (no_variant) attribute is added to an order by scanning its barcode, the extra price of the selected attribute value was dropped and the product was added at…
When a product carrying a multi-select (no_variant) attribute is added to an order by scanning its barcode, the extra price of the selected attribute value was dropped and the product was added at its base price. The order line total is computed from `price_unit` alone. The `price_extra` of a no_variant attribute is never included in the variant price (a "multi" attribute requires create_variant="no_variant"), so it only reaches the total once folded into `price_unit`. `addLineToOrder` did that fold-in only when the product was not scanned (`!isScannedProduct`). That guard was added to avoid counting the extra price twice when scanning an "always" variant barcode, whose extra is already part of its price. Since then, the extra price reaching this block is filtered to no_variant values only, both in the configurator and in the direct-variant branch, so an "always" extra can no longer reach it and the guard now only drops legitimate no_variant surcharges. Remove the guard so the no_variant extra price is always applied. Steps to reproduce: - Create a product with a multi-checkbox attribute whose value has an extra price, and give the product a barcode. - Open the PoS and scan the barcode. - Pick the attribute value in the configurator and validate. => The extra price is not added to the order line. opw-6413924 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Steps to reproduce: 1. Run a local SMTP server that responds with a server error. The server file is provided in the task [refuse_smtp.py](https://github.com/user-attachments/files/27166855/refuse_smtp.py) 2. Create an outgoing server for this SMTP server 3. Send an email Issue: The delivery failure reason displays Mail delivery failed via SMTP server 'None' instead of the configured server name. Cause: ir.mail_server.send_email() builds the failure message from the smtp_server argume
Original PR description
Steps to reproduce: 1. Run a local SMTP server that responds with a server error. The server file is provided in the task [refuse_smtp.py](https://github.com/user-attachments/files/27166855/refuse_smtp.py) 2. Create an outgoing server for this SMTP server 3. Send an email Issue: The delivery failure reason displays Mail delivery failed via SMTP server 'None' instead of the configured server name. Cause: ir.mail_server.send_email() builds the failure message from the smtp_server argument, but in the common path the mail is sent via mail_server_id. In that case, the actual SMTP server is resolved in connect(), while smtp_server remains unset, so the error message shows None. Solution: Store the resolved server label on the SMTP connection when opening it, and reuse that value when formatting send failures. opw-6139168
When a customer invoice is digitized through OCR, the salesperson may be set to the "Public User" instead of the internal user who uploaded the document. Steps to reproduce: - Upload a PDF invoice of an existing customer - Send the PDF to OCR - Reload the page Issue: Observe the Salesperson field: it is set to the Public User. Analysis: This occurs because when the partner is filled in, the compute of the salesperson will trigger. On SaaS this happens through the extraction c
Original PR description
When a customer invoice is digitized through OCR, the salesperson may be set to the "Public User" instead of the internal user who uploaded the document. Steps to reproduce: - Upload a PDF invoice of an existing customer - Send the PDF to OCR - Reload the page Issue: Observe the Salesperson field: it is set to the Public User. Analysis: This occurs because when the partner is filled in, the compute of the salesperson will trigger. On SaaS this happens through the extraction completion webhook a public route processed in sudo. that does not change the current user (public user). As self.env.user is the fallback of the compute, it may be set as salesperson. opw-6296330
2 changes
Resolved issues and error corrections
Cannot modfiy depends in stable. 17.0 and 18.0 only https://github.com/odoo/odoo/pull/271901
Original PR description
Cannot modfiy depends in stable. 17.0 and 18.0 only https://github.com/odoo/odoo/pull/271901
We use to have a chatter response for the IAP code "registrations_needed" that gives in plain text the sms account token. However this IAP code doesn't exist anymore. Task-6425300
Original PR description
We use to have a chatter response for the IAP code "registrations_needed" that gives in plain text the sms account token. However this IAP code doesn't exist anymore. Task-6425300