Thursday, August 6, 2026
36 changes · saas-19.2
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#279983The feature was never merged on IAP/Internal's side and we now have a new task to move the setting up of the auto-refill from the local db to the IAP server, so the feature is no longer relevant on the client side. Task-6397951 Forward-Port-Of: odoo/odoo#277512
Original PR description
The feature was never merged on IAP/Internal's side and we now have a new task to move the setting up of the auto-refill from the local db to the IAP server, so the feature is no longer relevant on the client side. Task-6397951 Forward-Port-Of: odoo/odoo#277512
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
The decorator `no_retry` can be used on any objects and just sets a flag. When checking if we should retry a test, let's also check the value on the class. This was broken by 2423b460526e9e7dd9ea8a7b3f7e40c93ab708f5. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280641
Original PR description
The decorator `no_retry` can be used on any objects and just sets a flag. When checking if we should retry a test, let's also check the value on the class. This was broken by 2423b460526e9e7dd9ea8a7b3f7e40c93ab708f5. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280641
Resolved issues and error corrections
The Vietnamese financial reports now classify short-term loan balances under held-to-maturity investments, in line with Circular 99/2025. This helps companies using the Vietnam localization produce balance sheets that match current reporting requirements.
Original PR description
### Expected behavior: As per circular 99/2025, short-term loan (12831) balance is required to fall under Held to Maturity Investment (Code 123) instead of 112, translated: ``` Short-term held-to-maturity investments (Code 123): includes held-to-maturity investments with a remaining term of 12 months or less from the end of the accounting period, such as term deposits, bonds, commercial paper, loans, and other debt securities. This item does not include held-to-maturity investments that have been presented in the item “Cash equivalents” ``` ### Steps to reproduce: Install `l10n_vn_reports` module ### Fix: PO validated: Update the Balance Sheet code formula for the 12381 account opw-6413120 Forward-Port-Of: odoo/enterprise#126763
Miscellaneous changes
**Steps to reproduce:** - Install Survey app - Create a survey - Share as e-mail - Add some text in the body/subject - Modify recipients - The added text is automatically reset **Issue:** Behavior was previously introduced to match the content of the composer body/subject to the recipient language. If there was only one language among the recipients it automatically adapted the template and changed the rendered language (which also refreshed the content). This logic was trigge
Original PR description
**Steps to reproduce:** - Install Survey app - Create a survey - Share as e-mail - Add some text in the body/subject - Modify recipients - The added text is automatically reset **Issue:** Behavior…
**Steps to reproduce:** - Install Survey app - Create a survey - Share as e-mail - Add some text in the body/subject - Modify recipients - The added text is automatically reset **Issue:** Behavior was previously introduced to match the content of the composer body/subject to the recipient language. If there was only one language among the recipients it automatically adapted the template and changed the rendered language (which also refreshed the content). This logic was triggered by a depends on `partner_ids` and triggered the compute on every recipient changes which led to the subject/body reset. **Fix:** Revert commit: https://github.com/odoo/odoo/commit/b7bbb7b21f4848323666230b518cad9459726f67 in 18.0+ Also adapt commit: https://github.com/odoo/odoo/commit/c6f19e89cb6019e7dbaadbc7427fbb6ddd5661ed to avoid mixed language in resulting mail when the composer was modified We could also try to prevent the compute when the subject or body is already modified instead of removing its logic. opw-6020245 Forward-Port-Of: odoo/odoo#280162 Forward-Port-Of: odoo/odoo#254090
The Australian payroll update process now includes salary rule category data when refreshing payroll rules. This prevents update failures when new salary categories are introduced, helping payroll maintenance run more reliably.
Original PR description
ir_cron_update_payroll_data updates the payroll data including rules but fails if a new rule category is introduced. This commit adds the hr_salary_rule_category_data file to the list of data files to update. task-6351929 Forward-Port-Of: odoo/enterprise#122392
The Barcode app welcome screen now shows the package scanning instruction when package tracking is enabled. This helps warehouse users understand they can scan a package to find the related transfer, reducing confusion during daily inventory operations.
Original PR description
When packages are enabled, the barcode scanner welcome screen does not display the instructions for scanning a package. ## Steps to reproduce - Enable `Packages` in Inventory settings. - Open the Barcode application. - Observe the instructions listed on the welcome/landing page. - Notice that the instruction `Scan a package to find a transfer` is missing, even though packages are enabled. ## Issue The MainMenu component has a getter barcodeHomeHelper that checks this.packageEnabled to construct the barcode scanner helper bullet points. However, during setup, the configuration value was incorrectly assigned to this.packagesEnabled. ## Fix Correct the variable name typo in the main menu setup so that the package related instructions are correctly displayed when packaging is enabled. [^1] [^1]:  Forward-Port-Of: odoo/enterprise#124658
Users without payroll permissions can now open time off type details without hitting an access error. The payroll-only field is hidden from users who do not have the required access, keeping the Time Off workflow usable for regular employees.
Original PR description
## Steps to reproduce: - Install Payroll and Time off - Create a user with no payroll rights - Log in as this created user - Go to time off and click on one day from the dashboard - Click on the pop-up button next to the time off type - An access error get triggerd that you can't access unpaid_structure_ids ## Cause: As this commit https://github.com/odoo/enterprise/pull/118037/changes/3a66d1405f2fb657c2660db72679e4ac523c3b83 this field have a specific group so when trying to show it in a view for a user that doesn't have this group it will trigger an access error ## Fix: We add the group to the field in the view so if the user doesn't have the group it won't be accessed at all opw-6376005
Appointment cancellation emails are now sent in the language of the customer who booked the appointment, matching the behavior of confirmation emails. This avoids confusing customers with cancellation messages in the staff member's language while preserving the old behavior for non-appointment events.
Original PR description
**Problem:** When an appointment is cancelled, the cancellation email is always sent in the organizer's (staff member's) language, ignoring the booking customer's language. The booking confirmation,…
**Problem:**
When an appointment is cancelled, the cancellation email is always sent in the organizer's (staff member's) language, ignoring the booking customer's language. The booking confirmation, by contrast, is correctly localized.
**Steps to reproduce:**
1. Set a contact's language to a non-default one (e.g. Romanian).
2. Book an appointment for that contact (they are the booker/attendee).
3. Cancel the appointment.
4. The customer received the confirmation in Romanian but the cancellation email arrives in English.
**Current behavior:**
The cancellation email is rendered in the organizer's language.
**Expected behavior:**
The cancellation email is rendered in the booking customer's language, like the confirmation/invitation email.
**Cause of the issue:**
The cancellation uses `appointment_canceled_mail_template`, whose `lang` is `{{ object.partner_id.lang }}`. On `calendar.event`, `partner_id` is `related='user_id.partner_id'`, i.e. the organizer, not the customer. The template is posted once per event (via `_track_template`), so its single rendering language applies to every recipient, including attendees whose own language differs. The confirmation email is unaffected because it is the per-attendee `attendee_invitation_mail_template` (model `calendar.attendee`), rendered once per attendee in that attendee's language.
**Fix:**
Deriving the language from `appointment_booker_id` makes the cancellation consistent with the other appointment mails, which are meant for the person who booked the meeting. It falls back to `partner_id` when there is no booker (e.g. an event not created through the appointment flow), preserving the previous behavior in that case.
opw-6323179
Forward-Port-Of: odoo/enterprise#125927
Forward-Port-Of: odoo/enterprise#124116This fix prevents duplicate report lines from being created when a user clicks to expand the same report line multiple times quickly. As a result, expanded lines can be collapsed reliably, improving the stability of financial report navigation especially on slow connections.
Original PR description
Steps to reproduce:- - Open any report. - Click on a particular line to unfold more than once very fast(or throttle network to 3G) - Once line is unfolded click again to fold that line. - Line is not…
Steps to reproduce:- - Open any report. - Click on a particular line to unfold more than once very fast(or throttle network to 3G) - Once line is unfolded click again to fold that line. - Line is not folding. Cause:- - When we clicked multiple times to unfold line, duplicate child lines were created(as many times as many times we clicked). - Because when first promise was not resolved so `unfolded = false` and we clicked again so new promise also tries to unfold the same line, resulting in unfolding the same line multiple times. - In version 17.0 these duplicate child lines are created but somehow not visible but it breaks `foldLine`. From version 18.0 onwards these duplicate child lines are visible. Solution: In `unfoldLine` set the flag `unfolding`. So in all clicks other than first, we get `unfolding = true` and don't proceed further, preventing unfolding the same line multiple times. task-6260425 Forward-Port-Of: odoo/enterprise#126765 Forward-Port-Of: odoo/enterprise#120392
Portal users editing Knowledge articles can now view and edit existing voice transcription text without seeing the internal-only recording controls. This keeps article editing available while preventing portal users from accessing a feature reserved for internal staff.
Original PR description
Portal users can edit Knowledge articles but should not have access to the voice recording feature, which is reserved for internal users. The readonly component is already used in read-only views, so reusing it in the editor for portal users is safe, it still renders the existing transcription content correctly without exposing any recording controls. Portal users can still edit the text content inside the component thanks to the editable descendants concept, which allows the editor to manage specific editable areas even within a readonly component. Task-6320461 Forward-Port-Of: odoo/enterprise#126606
The cash basis accounting report tests now use the actual configured outstanding receipts account instead of assuming a fixed account code. This prevents false test failures when account codes differ between database setups, improving release reliability without changing user-facing behavior.
Original PR description
Description of the issue this commit addresses: Commit 63f5646cfd75 made the tests use the default outstanding account but hard-coded code 101403. In an all-module database, generated account codes depend on existing accounts, so Outstanding Receipts may use code 101404 and make otherwise correct report assertions fail. --- Desired behavior after this commit is merged: This commit derives the expected report line name from the configured outstanding receipts account, making the assertions independent of its generated code. --- runbot-[231581](https://runbot.odoo.com/odoo/error/231581) Forward-Port-Of: odoo/enterprise#126743 Forward-Port-Of: odoo/enterprise#125652
Uploading a document from a contact now places it in the intended default area instead of reusing the last folder selected in Documents. This prevents files from being accidentally stored in the wrong workspace, reducing confusion and manual cleanup for users.
Original PR description
Steps to reproduce ================== 1. Open Documents. 2. Select Finance. 3. Return to the home page and open the Contacts app. 4. Open any contact. 5. Click the Documents stat button. 6. Upload a document. Issue ===== The document is uploaded to the Finance folder instead of My Drive. Reason ====== When uploading a document using the upload button, we use `currentFolderAccessToken` to determine the destination folder. When opening the Documents view from a contact, `searchpanel_default_folder_id` is set to `False` so that documents are uploaded to the `All` workspace. However, when the search model is loaded, we do not reset `currentFolderAccessToken` when `folder_id` is `False`, causing the previously selected folder (Finance) to be reused. Task-6352242 Forward-Port-Of: odoo/enterprise#123285
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
Steps to reproduce: 1) Install hr_holidays & hr_attendance. 2) Enable "Display Extra Hours" & "Absence Management" in the Attendance app settings. 3) Make a new employee, in the form view click the "+" button to make a new hr version record for this employee. 4) Set the date to be the first of the last month. 5) In the Attendance app -> New -> Select the new employee. 6) Select the check in and out dates to be from last month, edit the times such that the time worked is between 7 and 8 h
Original PR description
Steps to reproduce: 1) Install hr_holidays & hr_attendance. 2) Enable "Display Extra Hours" & "Absence Management" in the Attendance app settings. 3) Make a new employee, in the form view click the…
Steps to reproduce: 1) Install hr_holidays & hr_attendance. 2) Enable "Display Extra Hours" & "Absence Management" in the Attendance app settings. 3) Make a new employee, in the form view click the "+" button to make a new hr version record for this employee. 4) Set the date to be the first of the last month. 5) In the Attendance app -> New -> Select the new employee. 6) Select the check in and out dates to be from last month, edit the times such that the time worked is between 7 and 8 hours (ex 9:00am to 4:55pm). 7) In the Attendance app -> Reporting -> Attendances -> the test employee should have a negative value for "Worked Extra Hours" 8) Create a new time off type, enable "Deduct Extra Hours" & disable "Requires Allocation" use hours as the Unit of measure. 9) Open the time off smart button menu from the test employee's form view. Issue) The value seen in the report from step 7 is not the same as what the user sees in the dashboard. Notes) This issue can occur when an employee scheduled to work for 8 hours a day only clocks in for 7:55 hours leading to a negative extra time. The back-end has the correct value stored and sends it to the browser. The issue occurs because the JavaScript function that converts the decimal number of hours into a string (9.5 -> "9:30") does not work with negative input. This PR resolves that issue. opw-6417543 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280491
Before this commit: Deleting a record that uses a filterable selection field with `whitelist_fname` raises a traceback because the record field data becomes undefined during deletion. Steps to reproduce: 1. Install Belgium Accounting (l10n_be). 2. Create a contact and set a Peppol scheme and endpoint. 3. Delete the contact -> a traceback is raised. After this commit: The selection field safely handles undefined record field data during record deletion without causing an error. no-t
Original PR description
Before this commit: Deleting a record that uses a filterable selection field with `whitelist_fname` raises a traceback because the record field data becomes undefined during deletion. Steps to reproduce: 1. Install Belgium Accounting (l10n_be). 2. Create a contact and set a Peppol scheme and endpoint. 3. Delete the contact -> a traceback is raised. After this commit: The selection field safely handles undefined record field data during record deletion without causing an error. no-task Forward-Port-Of: odoo/odoo#280153 Forward-Port-Of: odoo/odoo#278808
Bug === Since a4efb745e9f4ba24dfa01f1e17e65f1a7cac90a5 , we cannot insert properties. The reason is that we try to get the field definition from the inserted QWeb expression (eg `object.properties.get('property_product', env['product']).name`) which crash. Task-6311655
Original PR description
Bug
===
Since a4efb745e9f4ba24dfa01f1e17e65f1a7cac90a5 , we cannot insert properties. The reason is that we try to get the field definition from the inserted QWeb expression (eg `object.properties.get('property_product', env['product']).name`) which crash.
Task-6311655### Issue: A user who can modify `tax_exigibility` but does not have `account.group_account_readonly` is blocked from switching to `on_payment` There is no way to complete the operation as the account field is not visible and cannot be filled before saving ### Cause: When `tax_exigibility` is set to `on_payment`, the view expects `cash_basis_transition_account_id` to be filled before saving`_constrains_cash_basis_transition_account` then validates that the account is reconcilable `cas
Original PR description
### Issue: A user who can modify `tax_exigibility` but does not have `account.group_account_readonly` is blocked from switching to `on_payment` There is no way to complete the operation as the…
### Issue: A user who can modify `tax_exigibility` but does not have `account.group_account_readonly` is blocked from switching to `on_payment` There is no way to complete the operation as the account field is not visible and cannot be filled before saving ### Cause: When `tax_exigibility` is set to `on_payment`, the view expects `cash_basis_transition_account_id` to be filled before saving`_constrains_cash_basis_transition_account` then validates that the account is reconcilable `cash_basis_transition_account_id` was restricted to `account.group_account_readonly`, hiding it from other users The field is never rendered, so it cannot be filled The `required` constraint is never evaluated client-side and `_constrains_cash_basis_transition_account` raises a `ValidationError` on save because the account is empty There is no reason to restrict `cash_basis_transition_account_id` independently — if a user can modify `tax_exigibility`, they must also be able to set the linked account ### Steps to reproduce: - Install `account` - Enable Cash Basis in Settings (On RunBot ensure no default account is set) - Enable Developer Mode in Settings - Go to Settings > Users & Companies > Users - Open the current user and disable both: `Show Accounting Features - Readonly` and `Show Full Accounting Features` (if set) - Go to Invoicing > Configuration > Taxes - Open any tax and go to Advanced Options - Change Tax Exigibility to Based on Payment Before the fix, the account selector is not displayed and saving raises an error opw-6359173 Forward-Port-Of: odoo/odoo#274728
Before this commit, the `empty a many2one field in list view` test sometimes failed, because the many2one value wasn't correctly unset (`first record` was selected). This happened because we cleared the input and automatically validated (typically with tab). However, it could happen that the validation occurred after the dropdown was opened, so the first value of the dropdown was selected. As a matter of fact, adding `await runAllTimers()` after clearing the input is a way to make the test fail
Original PR description
Before this commit, the `empty a many2one field in list view` test sometimes failed, because the many2one value wasn't correctly unset (`first record` was selected). This happened because we cleared…
Before this commit, the `empty a many2one field in list view` test sometimes failed, because the many2one value wasn't correctly unset (`first record` was selected). This happened because we cleared the input and automatically validated (typically with tab). However, it could happen that the validation occurred after the dropdown was opened, so the first value of the dropdown was selected. As a matter of fact, adding `await runAllTimers()` after clearing the input is a way to make the test fail deterministically. This commit avoids the issue by emptying the many2one without validation, so it basically only set the input value to the empty string, but doesn't tab/enter or anything else, hence it never selects an unwanted value. runbot error-941430 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#280351
**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#280533
Forward-Port-Of: odoo/odoo#278876This is rather an attempt of fix, as we couldn't reproduce the error locally or in a multi build., so we have no guarantee that this strenghtens the test. The test sometimes fails as `.o_crop_icon` can't be found within 200ms. Before that, we wait for the video element to be ready (we rely on a patch of the `isVideoReady` method of the component to know that the video is ready). Once it is, the isReady flag in the state is set to true and the CropOverlay component renders its `o_crop_icon` el
Original PR description
This is rather an attempt of fix, as we couldn't reproduce the error locally or in a multi build., so we have no guarantee that this strenghtens the test. The test sometimes fails as `.o_crop_icon`…
This is rather an attempt of fix, as we couldn't reproduce the error locally or in a multi build., so we have no guarantee that this strenghtens the test. The test sometimes fails as `.o_crop_icon` can't be found within 200ms. Before that, we wait for the video element to be ready (we rely on a patch of the `isVideoReady` method of the component to know that the video is ready). Once it is, the isReady flag in the state is set to true and the CropOverlay component renders its `o_crop_icon` element. Our guess is that we may sometimes early return in `isVideoReady`, because the component has been destroyed (a new rendering might be on the way). To ensure that we don't take that as the ready signal in the test, we now only consider that we're ready if isVideoReady returned true (i.e. no early return). runbot error-241798 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#280329
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 Forward-Port-Of: odoo/odoo#279724
**Issue** Confirming a SO that generates a batch of MOs from a BoM with a batch size could lead to creating an invalid number of pickings: all the MOs end up sharing a single picking instead of getting one each. **Steps to reproduce** - Use 2-step manufacturing - Create a storable product with the MTO + Manufacture routes - Add a BOM that has a batch size of 10 that consumes one component - Create and confirm a SO of 100 units of that product -> 10 MOs are created, but each one points
Original PR description
**Issue** Confirming a SO that generates a batch of MOs from a BoM with a batch size could lead to creating an invalid number of pickings: all the MOs end up sharing a single picking instead of…
**Issue** Confirming a SO that generates a batch of MOs from a BoM with a batch size could lead to creating an invalid number of pickings: all the MOs end up sharing a single picking instead of getting one each. **Steps to reproduce** - Use 2-step manufacturing - Create a storable product with the MTO + Manufacture routes - Add a BOM that has a batch size of 10 that consumes one component - Create and confirm a SO of 100 units of that product -> 10 MOs are created, but each one points to the same "Pick Components" transfer instead of getting its own. **Cause** This commit dd6ee071f949752d31497d9f975ba7fc41ebcd98 batches the confirm of productions: https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/mrp/models/stock_rule.py#L120 thus `assign_picking` is called in batches: https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/mrp/models/mrp_production.py#L1653 https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1736-L1737 https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1550-L1556 since, the `reference_ids` are the same for each MO/stock.move (they all come from the same procurement): https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1712-L1713 Consequently, all the moves end up in the same recordset `moves`: https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1527 Creating only one picking: https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1577 opw-6403427 Forward-Port-Of: odoo/odoo#279179
Issue ----- Branch companies can have quants of a product limited to their parent company, but they don't show in the per location report. Steps to reproduce ----- - Create a branch company - Create a WH for the branch - Create a tracked product - Company set to parent only - Switch to the branch company - Add a quant of the product in branch stock - Open Inventory > Reporting > Locations > The product is not shown although there is a quant in the branch Cause ----- The m
Original PR description
Issue ----- Branch companies can have quants of a product limited to their parent company, but they don't show in the per location report. Steps to reproduce ----- - Create a branch company - Create…
Issue ----- Branch companies can have quants of a product limited to their parent company, but they don't show in the per location report. Steps to reproduce ----- - Create a branch company - Create a WH for the branch - Create a tracked product - Company set to parent only - Switch to the branch company - Add a quant of the product in branch stock - Open Inventory > Reporting > Locations > The product is not shown although there is a quant in the branch Cause ----- The menu button triggers `action_view_quants` https://github.com/odoo/odoo/blob/03a3662212f094158f885ae6545009fd0a74d3cb/addons/stock/views/stock_quant_views.xml#L493-L495 https://github.com/odoo/odoo/blob/03a3662212f094158f885ae6545009fd0a74d3cb/addons/stock/models/stock_quant.py#L399-L402 The problem here comes from the fact that in `_get_quants_action`, we limit the products to those of only the active companies, instead of allowing to view those of parent companies aswell. https://github.com/odoo/odoo/blob/03a3662212f094158f885ae6545009fd0a74d3cb/addons/stock/models/stock_quant.py#L1330 Such a change works because the domain is specifically for the product's (`product_id.company_id`) and not the location's. ----- Ticket: opw-6131525 Forward-Port-Of: odoo/odoo#280083 Forward-Port-Of: odoo/odoo#277531
Version: -------- - 19.0+ Steps to reproduce: ------------------- - Install `purchase` and `stock` - Create a Purchase Order for a storable or consumable product - Set the ordered quantity to a negative value (e.g. `-10`) - Confirm the Purchase Order. - Open the Deliveries and search using the Purchase Order name Issue: ------ An outgoing return picking is correctly created for 10 units, but an additional empty incoming receipt is also generated and linked to the Purchase Order
Original PR description
Version: -------- - 19.0+ Steps to reproduce: ------------------- - Install `purchase` and `stock` - Create a Purchase Order for a storable or consumable product - Set the ordered quantity to a…
Version: -------- - 19.0+ Steps to reproduce: ------------------- - Install `purchase` and `stock` - Create a Purchase Order for a storable or consumable product - Set the ordered quantity to a negative value (e.g. `-10`) - Confirm the Purchase Order. - Open the Deliveries and search using the Purchase Order name Issue: ------ An outgoing return picking is correctly created for 10 units, but an additional empty incoming receipt is also generated and linked to the Purchase Order. Cause: ------ When a Purchase Order is confirmed, `purchase.order.button_approve()` calls `purchase.order._create_picking()`: https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/purchase_stock/models/purchase_order.py#L179 Inside `_create_picking()`, if no open picking exists yet, Then first creates an incoming receipt using `_prepare_picking()`: https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/purchase_stock/models/purchase_order.py#L382 The generated receipt is configured with: - source location: Vendor - destination location: Stock - picking type: Incoming - origin: Purchase Order reference Stock moves are then created on that receipt through: https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/purchase_stock/models/purchase_order.py#L387-L388 For negative PO quantities, the move is initially created with a negative demand: ``` Vendor -> Stock, quantity -10 ```` During `stock.move._action_confirm()`, stock identifies such moves in `neg_r_moves`: [https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/stock/models/stock_move.py#L1604](https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/stock/models/stock_move.py#L1604) Those moves are automatically converted into return moves by: * swapping source and destination locations, * converting the quantity to positive, * assigning the return picking type when available: [https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/stock/models/stock_move.py#L1612-L1614](https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/stock/models/stock_move.py#L1612-L1614) The resulting move becomes: ``` Stock -> Vendor, quantity 10 ``` The converted move is then reassigned through: [https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/stock/models/stock_move.py#L1630](https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/addons/stock/models/stock_move.py#L1630) This correctly creates the outgoing return picking. However, the original incoming receipt created earlier by `purchase_stock` is left without any moves, resulting in an empty ghost receipt linked to the Purchase Order. Solution: --------- - Track whether `_create_picking()` created a new incoming receipt during the current confirmation flow. - After stock move confirmation, if that newly-created receipt no longer contains any moves, unlink it and remove it from the pickings to confirm. - This preserves the valid outgoing return picking while preventing empty incoming receipts from being generated. NOTE: ------ This Issue not reproduce from saas-19.3. Fix in this [commit](https://github.com/odoo-dev/odoo/commit/81caaaa3f7212ad5d9d72cd446b65c5fb0a9bef9) --- opw-6131329 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265704
### Steps to reproduce: - Create 3 AVCO products: Super Kit, Kit, Comp - Super Kit BoM: 2 x Kit - Kit BoM: 1 x Comp - Create and confirm a purchase order for 1 X Super Kit at 100 - Validate the receipt of 2 Comp - Go to the valuation > Both units of Comp are valued at 100 for a total of 200 ### Cause of the issue: The issue has been introduced by: https://github.com/odoo/odoo/pull/158849/changes/713701a5035d342263e3fef2a2819b5696b6d063 To be more precise, the price unit of each u
Original PR description
### Steps to reproduce: - Create 3 AVCO products: Super Kit, Kit, Comp - Super Kit BoM: 2 x Kit - Kit BoM: 1 x Comp - Create and confirm a purchase order for 1 X Super Kit at 100 - Validate the…
### Steps to reproduce: - Create 3 AVCO products: Super Kit, Kit, Comp - Super Kit BoM: 2 x Kit - Kit BoM: 1 x Comp - Create and confirm a purchase order for 1 X Super Kit at 100 - Validate the receipt of 2 Comp - Go to the valuation > Both units of Comp are valued at 100 for a total of 200 ### Cause of the issue: The issue has been introduced by: https://github.com/odoo/odoo/pull/158849/changes/713701a5035d342263e3fef2a2819b5696b6d063 To be more precise, the price unit of each unit of Comp is expected to be computed by the `_get_price_unit`. This method used to rely on the `product_qty` appropriately: https://github.com/odoo/odoo/pull/158849/changes/713701a5035d342263e3fef2a2819b5696b6d063#diff-687527af1723e60816358020c4d83687479df62ca0cfd71079f0a82afb4b3efeL27 However, backorder adapt the move demand and hence did not provide the appropriate demand in this flow that computation logic was changed to rely on the `bom` and `bom_line` quantities: https://github.com/odoo/odoo/blob/29977a6a80442af49ecefa7fef54f085483d8f77/addons/purchase_mrp/models/stock_move.py#L20-L40 This new computation is not correct in case of nested boms since the `bom_line` only carries the unit demand on the last explosion stage. ### Additional issue: If nested kit boms lead to the creation of 2 moves with the same `cost_share` and `bom_line_id`, these moves will be merged without summing their `cost_share` leading to an under pricing of the kit since its related `stock_move`'s `cost_share` will not sum up to 100 percents anymore. This issue is tested in `test_avco_purchase_nested_kit_explode_cost_share_backorder_2` and fixed similarly to demand merging: https://github.com/odoo/odoo/blob/613f3cb7b2f4813ce6c8f53718a6cca841b081ad/addons/stock/models/stock_move.py#L1122-L1134 ### Note: We also modify the test `test_valuation_with_backorder` to be understandable and to make appropriate asserts. opw-6253776 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279890 Forward-Port-Of: odoo/odoo#276242
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' 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#276303
Steps to reproduce the error: (Python Version: 3.14.X) - Install ``accounting_firm`` industry with demo data Code for server action to generate the error: ```py for i in [1]: try: pass except Exception: pass if i: pass ``` Traceback: ```py ValueError: forbidden opcode(s) in'...': JUMP_BACKWARD_NO_INTERRUPT ``` https://github.com/odoo/industry/blob/701f7595453772e42ce72aa75df346a504e5bd82/accounting_firm/demo/ir_actions_server.xml#L105-L10
Original PR description
Steps to reproduce the error: (Python Version: 3.14.X) - Install ``accounting_firm`` industry with demo data Code for server action to generate the error: ```py for i in [1]: try: pass except…
Steps to reproduce the error: (Python Version: 3.14.X)
- Install ``accounting_firm`` industry with demo data
Code for server action to generate the error:
```py
for i in [1]:
try:
pass
except Exception:
pass
if i:
pass
```
Traceback:
```py
ValueError: forbidden opcode(s) in'...': JUMP_BACKWARD_NO_INTERRUPT
```
https://github.com/odoo/industry/blob/701f7595453772e42ce72aa75df346a504e5bd82/accounting_firm/demo/ir_actions_server.xml#L105-L108
The server action contains a ``for`` loop with a ``try/except`` block followed by additional statements in the loop body,
this combination generates the ``JUMP_BACKWARD_NO_INTERRUPT`` opcode, which is not included in ``_SAFE_OPCODES`` at [1].
When the server action is evaluated by ``safe_eval``, it calls the ``assert_valid_codeobj`` method, which validates the compiled bytecode against ``_SAFE_OPCODES``. Since ``JUMP_BACKWARD_NO_INTERRUPT`` is not present in the allowed opcodes, ``assert_valid_codeobj()`` raises a ``ValueError`` at [2] before the server action is executed .
Solution:
``JUMP_BACKWARD_NO_INTERRUPT`` opcode is added in the ``_SAFE_OPCODES`` and it is also added in the ``_SAFE_QWEB_OPCODES``.
It was added in Python 3.11: https://docs.python.org/3/whatsnew/3.11.html#new-opcodes
``JUMP_BACKWARD_NO_INTERRUPT`` is a control-flow opcode that only changes
the interpreter's execution flow by jumping back to a previous instruction.
It is the equivalent to ``JUMP_BACKWARD`` opcode. Its only semantic difference is
that the interpreter does not perform an interrupt check at that instruction.
It does not introduce any new capabilities or perform operations such as
attribute access, imports, function calls, or object creation.
Ref: https://docs.python.org/3.12/library/dis.html#opcode-JUMP_BACKWARD_NO_INTERRUPT
Similar commit that adds some necessary opcodes:
https://github.com/odoo/odoo/commit/86498d24946e510025add5d24ef0d4bcce8ad05f
[1]: https://github.com/odoo/odoo/blob/2ccbc4660077bd48529e9de43d4309fbfafc75ca/odoo/tools/safe_eval.py#L135
[2]: https://github.com/odoo/odoo/blob/2ccbc4660077bd48529e9de43d4309fbfafc75ca/odoo/tools/safe_eval.py#L244-L246
sentry-7614026125
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#277192### Issue: A partner with VAT set to '/' incorrectly matches a fiscal position with `VAT required`, instead of one without The '/' value is the placeholder suggested by the UI to indicate that the partner is known to have no VAT, but it was treated as a valid VAT by the fiscal position matching logic ### Cause: `_get_fpos_ranking_functions` uses `_get_vat_valid` to rank fiscal positions based on VAT presence `_get_vat_valid` returned `True` for any non-empty VAT value, including '/' Th
Original PR description
### Issue: A partner with VAT set to '/' incorrectly matches a fiscal position with `VAT required`, instead of one without The '/' value is the placeholder suggested by the UI to indicate that the…
### Issue: A partner with VAT set to '/' incorrectly matches a fiscal position with `VAT required`, instead of one without The '/' value is the placeholder suggested by the UI to indicate that the partner is known to have no VAT, but it was treated as a valid VAT by the fiscal position matching logic ### Cause: `_get_fpos_ranking_functions` uses `_get_vat_valid` to rank fiscal positions based on VAT presence `_get_vat_valid` returned `True` for any non-empty VAT value, including '/' The '/' case was not excluded, causing it to be treated as a valid VAT number ### Steps to reproduce: - Install `account` - Create two fiscal positions with auto-apply: -- Name: FP VAT, VAT required: True, sequence: 1 -- Name: FP no VAT, VAT required: False, sequence: 2 - Create a partner with VAT: '/' - Create an Invoice for that partner and check the Fiscal Position Before the fix, `FP VAT` is selected instead of `FP no VAT` opw-6204531 Forward-Port-Of: odoo/odoo#280494 Forward-Port-Of: odoo/odoo#280065
## Issue When logging timesheet from the *Recorded* smart button on a Sale Order containing multiple service items, the recorded hours will be added to the first sale order line, regardless of the task ID set on the timesheet entries. ## Steps to reproduce 1. Install *Sales Timesheet* (`sale_timesheet`) 2. Create a Product P: - *Product Type*: Service - *Create on Order*: Task - *Project*: Any 3. Create a SO: - *Customer*: Any - Add the product P on two different
Original PR description
## Issue When logging timesheet from the *Recorded* smart button on a Sale Order containing multiple service items, the recorded hours will be added to the first sale order line, regardless of the…
## Issue
When logging timesheet from the *Recorded* smart button on a Sale Order containing multiple service items, the recorded hours will be added to the first sale order line, regardless of the task ID set on the timesheet entries.
## Steps to reproduce
1. Install *Sales Timesheet* (`sale_timesheet`)
2. Create a Product P:
- *Product Type*: Service
- *Create on Order*: Task
- *Project*: Any
3. Create a SO:
- *Customer*: Any
- Add the product P on two different lines and give them two different descriptions D1 and D2
- Confirm the SO, this will create two tasks with the names D1 and D2
4. On the SO, click the *Recorded* smart button and create two entries:
1. Task D1, 2 hours spent
2. Tsk D2, 3 hours spent
5. **Back on the SO, there are 5 hours registered for the first SOL (with the description D1), which does not match the entries we created from the smart button.**
It is worth noting that when we create the Timesheets entries from the project itself (instead of the SO's smart button), the hours are correctly distributed among the different SOLs.
## Cause
The SOL linked to the timesheet entry (`account.analytic.line`) is computed by `_compute_so_line`:
https://github.com/odoo/odoo/blob/8b102f500f5a122e99b07a08cc43814e7c6f0f75/addons/sale_timesheet/models/hr_timesheet.py#L79-L82
This method sets the correct SOL under the condition that `is_so_line_edited` is False and `_is_no_billed()` returns True.
When opening the *Recorded* smart button from a SO, the `is_so_line_edited` is set to True by default, even if no SOL was modified.
https://github.com/odoo/odoo/blob/8b102f500f5a122e99b07a08cc43814e7c6f0f75/addons/sale_timesheet/models/sale_order.py#L113-L117
As that value is never set to False, when trying to compute the SOL for the timesheet entry, the entry is skipped and the default SOL (which is the first one) is used instead.
opw-6133473
Forward-Port-Of: odoo/odoo#274759Before this commit, in some cases, the order created for printing cash move was saved to the IndexedDB and then later loaded from IndexedDB, which caused the order gets synced to the backend but missing some required fields, like preset or pricelist. opw-5969602 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262248
Original PR description
Before this commit, in some cases, the order created for printing cash move was saved to the IndexedDB and then later loaded from IndexedDB, which caused the order gets synced to the backend but missing some required fields, like preset or pricelist. opw-5969602 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262248
Since https://github.com/odoo/odoo/pull/239898 Opening a livechat session in debug mode as a user without livechat access throws a traceback: `Invalid props for component BadgeTag: onDelete is not a function` This happens because `null` is passed to the `onDelete` prop, while the component validation expects a function. This commit fixes the issue. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280679
Original PR description
Since https://github.com/odoo/odoo/pull/239898 Opening a livechat session in debug mode as a user without livechat access throws a traceback: `Invalid props for component BadgeTag: onDelete is not a function` This happens because `null` is passed to the `onDelete` prop, while the component validation expects a function. This commit fixes the issue. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280679
When we create a database with `-i web --skip-auto-install`, we run into CSS compilation errors due to undefined variables `$black` and `$gray-200`. This commit adds these two definitions. opw-6398398 Forward-Port-Of: odoo/odoo#279753 Forward-Port-Of: odoo/odoo#279287
Original PR description
When we create a database with `-i web --skip-auto-install`, we run into CSS compilation errors due to undefined variables `$black` and `$gray-200`. This commit adds these two definitions. opw-6398398 Forward-Port-Of: odoo/odoo#279753 Forward-Port-Of: odoo/odoo#279287
Steps to reproduce ------------------ 1. Set the company document layout to DIN5008 2. Open a delivery and print the delivery slip The title is missing on the DIN5008 layout, we only have the reference `WH/OUT/00001`. What happens ------------ The DIN5008 layout hides the body title with css and prints its own `h2` instead, from the `din5008_document_title` variable, and uses `o.name` (the picking number) when this variable is not set. The commit 0058d1cf7655 added the title on the
Original PR description
Steps to reproduce ------------------ 1. Set the company document layout to DIN5008 2. Open a delivery and print the delivery slip The title is missing on the DIN5008 layout, we only have the reference `WH/OUT/00001`. What happens ------------ The DIN5008 layout hides the body title with css and prints its own `h2` instead, from the `din5008_document_title` variable, and uses `o.name` (the picking number) when this variable is not set. The commit 0058d1cf7655 added the title on the standard delivery report with `picking_type_id._get_code_report_name()`, but `l10n_din5008_stock` was not updated to set `din5008_document_title`, so on DIN5008 we only get the number. The fix ------- We set it the same way as the other layouts, hence we get back the full title `Delivery Note WH/OUT/00001`. opw-6299248 Forward-Port-Of: odoo/odoo#277444
load_data() reads product.pricelist.item_ids as a field, which applies _base_domain_item_ids()'s dotted active conditions. Since this runs as the cashier, never sudo, the ORM injects ir.rules into those conditions, forcing a non-hashable subquery that Postgres re-scans once per pricelist item. Cost scales with items times catalog size, freezing session opening on large catalogs. product.pricelist.item is already loaded separately via a plain, indexed pricelist_id domain. Reuse it to build ite
Original PR description
load_data() reads product.pricelist.item_ids as a field, which applies _base_domain_item_ids()'s dotted active conditions. Since this runs as the cashier, never sudo, the ORM injects ir.rules into those conditions, forcing a non-hashable subquery that Postgres re-scans once per pricelist item. Cost scales with items times catalog size, freezing session opening on large catalogs.
product.pricelist.item is already loaded separately via a plain, indexed pricelist_id domain. Reuse it to build item_ids instead of reading the field, avoiding the join/subquery entirely.
before after speedup
item_ids read 475.8s 2.44s ~195x
load_data() (full) unbounded 8.7s hang -> ok
opw-6391847
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#277254