Daily updates from Odoo
Thursday, July 16, 2026
12 changes · 17.0
Enhancements to existing features
Test lints should be deterministic so retrying them doesn't make sense. While lints are not the slowest, pylint can take 10~15mn in later branches, and with retrying that's half an hour (and some) to get a failure, which is all that in wasted staging and build time. Forward-Port-Of: odoo/odoo#276600
Original PR description
Test lints should be deterministic so retrying them doesn't make sense. While lints are not the slowest, pylint can take 10~15mn in later branches, and with retrying that's half an hour (and some) to get a failure, which is all that in wasted staging and build time. Forward-Port-Of: odoo/odoo#276600
task-no
Original PR description
task-no
Resolved issues and error corrections
Mobile users can now see and use the “Upload a PDF & sign” button in the Sign app. This fixes a display issue that prevented users on smaller screens from starting a PDF signing flow.
Original PR description
Issue: ---------------------------------------- When opening the Sign app on mobile, the "Upload a PDF & sign" button doesn't appear. Cause: ---------------------------------------- The Sign buttons are in a `<t t-if="!env.isSmall">`. So if the screen has a width smaller than 767.98px, the buttons aren't displayed. Solution: ---------------------------------------- Remove the `t-if`. It works fine without it. Did not remove the `<t>` for stability. opw-6377211
The bank reconciliation report now shows all unreconciled transactions up to the selected date, not just those from the latest bank statement. This helps finance teams get a complete view of pending reconciliation work and avoid missing older transactions.
Original PR description
The reconciliation report lists only the unreconciled transactions from the last statement instead of all of them Steps: - Create 4 statements with one statement line each with different dates - Go to the reconciliation report (via the three dot menu on bank journal kanban card) - select date as Today -> only the line from the last statement is displayed opw-6250370
This fix ensures the barcode app keeps only one delivery line selected when workers switch between packaged and unpackaged products. It prevents confusing double selections during warehouse picking, reducing the risk of operational mistakes.
Original PR description
**Steps to reproduce:** - Enable "Move Entire Packages" setting on deliveries - Make a product A, that has a package P1, on hand qty of 1 - Make product B that don't have a package, but on hand qty…
**Steps to reproduce:** - Enable "Move Entire Packages" setting on deliveries - Make a product A, that has a package P1, on hand qty of 1 - Make product B that don't have a package, but on hand qty of 1 - Make a delivery that has both of those products, requested qty of 1 for both - Mark it as todo - Go to the barcode app, select the delivery - Select the line with product B - Select the line with product A --> The line with product B is not unselected **Why the fix:** When we have a mix of packaged products and products without a package on the same operation, they are handled separately. The products without a package are handled in https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L388-L392 that calls https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L1277-L1284 But as you can see, there are no mention of the selected package line, which is stored in **this.lastScanned.packageId**. As we do not touch this variable, the selected package line stays selected. The same is true for the other way around, when we select a package line we call https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L394-L398 This function does not care for the **selectedLineVirtualId** which represents the selected line without a package. To avoid this and make it so that only one line is selected even if they have different package, we now set the corresponding value to false to unselect the other line in all situation. This is basically how it's done in https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L1202-L1208 to unselect every line regardless of packages. opw-6266203
Delivery guides can now be printed correctly when a kit includes components measured differently from the kit product. The change prevents pricing errors by using the component product price when the delivered component differs from the sale order item.
Original PR description
When a kit is delivered, each component move is linked to the kit's sale order line. Pricing the delivery guide in "sale order" mode converted the component quantity into the kit's sale UoM. For a component sold in a different UoM category than the kit, this cross-category conversion raises a UserError. Steps to reproduce: - Create a BoM for a kit product with a component in a different UoM category - Create a customer with Delivery Guide Price = "From Sale Order" - Sold the kit in a sale order and deliver it - On the delivery, print the delivery guide -> error This fix makes the guide price for a component move to be "product" if the component's product is different from the related sale line product, avoiding the cross-category UoM conversion. opw-6327895
## Short fix summary: Both Nilvera sync crons (`_l10n_tr_nilvera_get_submitted_document_status` and `_cron_nilvera_get_new_documents`) built their API client from the ambient `self.env.company` instead of each invoice's own `company_id`. In a multi-company setup, or whenever the cron's runtime user's default company differs from the invoice's, this silently used the wrong (or no) API key and the sync failed for those invoices. `_l10n_tr_nilvera_get_submitted_document_status` now groups invoice
Original PR description
## Short fix summary: Both Nilvera sync crons (`_l10n_tr_nilvera_get_submitted_document_status` and `_cron_nilvera_get_new_documents`) built their API client from the ambient `self.env.company` instead of each invoice's own `company_id`. In a multi-company setup, or whenever the cron's runtime user's default company differs from the invoice's, this silently used the wrong (or no) API key and the sync failed for those invoices. `_l10n_tr_nilvera_get_submitted_document_status` now groups invoices by `company_id` and opens one Nilvera client per company. `_cron_nilvera_get_new_documents` now goes through a new `_l10n_tr_nilvera_company_get_documents` helper that loops over the Turkish companies with an API key configured and switches into each one's context via `with_company()` before fetching. task-6328589 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Description of the issue/feature this PR addresses: Abandoned cart recovery emails can be sent more than once when the `website_sale` cron runs concurrently (multiple Odoo workers, or overlapping scheduler runs). `_send_abandoned_cart_email` only sets `cart_recovery_email_sent` *after* `send_mail()`, so two workers can both select the same cart while the flag is still unset. This affects 17.0+ (verified on 17.0 and 19.0). Targeting 17.0 as the oldest supported branch so it can be forward-porte
Original PR description
Description of the issue/feature this PR addresses: Abandoned cart recovery emails can be sent more than once when the `website_sale` cron runs concurrently (multiple Odoo workers, or overlapping…
Description of the issue/feature this PR addresses: Abandoned cart recovery emails can be sent more than once when the `website_sale` cron runs concurrently (multiple Odoo workers, or overlapping scheduler runs). `_send_abandoned_cart_email` only sets `cart_recovery_email_sent` *after* `send_mail()`, so two workers can both select the same cart while the flag is still unset. This affects 17.0+ (verified on 17.0 and 19.0). Targeting 17.0 as the oldest supported branch so it can be forward-ported. Current behavior before PR: Two overlapping cron runs both send the recovery email for the same sale order. Customers receive duplicate abandoned-cart messages. Desired behavior after PR is merged: Each cart is claimed with an atomic `UPDATE ... WHERE cart_recovery_email_sent IS NOT TRUE RETURNING id` before sending. Only the worker that successfully claims the row sends the email; others skip it. A regression test re-enters the cron once during `send_mail` and asserts a single send. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share the project with edit access to a portal user belonging to Company A.4 4. Create a task, switch to Company B, and log a timesheet on the task. 5. Log in as the portal user and try to access the project. Issue: ------- An `Access to unauthorized or invalid companies exception` is raised,
Original PR description
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share…
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share the project with edit access to a portal user belonging to Company A.4 4. Create a task, switch to Company B, and log a timesheet on the task. 5. Log in as the portal user and try to access the project. Issue: ------- An `Access to unauthorized or invalid companies exception` is raised, preventing the portal user from accessing a project they are legitimately shared on. Cause: ---------- https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/project/controllers/portal.py#L159-L173 During `_prepare_project_sharing_session_info`, hr_timesheet overrides the company determination logic through `_get_project_sharing_company()`. https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/hr_timesheet/controllers/project.py#L13-L18 For global projects, the company is derived from an existing timesheet if one exists. As a result, creating a timesheet in another company causes that company to be injected into the sharing session as the current company. Since the portal user does not have access to that company, opening the project triggers an access error. Solution: ---------- Remove the `_get_project_sharing_company()` override. The base implementation already falls back to the portal user's own company when the project has no company assigned, ensuring the sharing session only contains companies the portal user is allowed to access. https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/project/controllers/portal.py#L141-L142 This allows portal users from Company A to continue accessing global projects without errors. opw-6253960 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Description of the issue/feature this PR addresses: `_invoice_get_page_view_values` receives `access_token` as a named argument, then calls `_get_extra_payment_form_values(**kwargs)` without forwarding it. When `invoice_id` is also present in kwargs (query string on the portal invoice page, or an extending module injecting it for provider filtering), `_get_extra_payment_form_values` runs `_document_check_access` with `access_token=None` and raises `AccessError`. `payment.PaymentPortal` already
Original PR description
Description of the issue/feature this PR addresses: `_invoice_get_page_view_values` receives `access_token` as a named argument, then calls `_get_extra_payment_form_values(**kwargs)` without…
Description of the issue/feature this PR addresses: `_invoice_get_page_view_values` receives `access_token` as a named argument, then calls `_get_extra_payment_form_values(**kwargs)` without forwarding it. When `invoice_id` is also present in kwargs (query string on the portal invoice page, or an extending module injecting it for provider filtering), `_get_extra_payment_form_values` runs `_document_check_access` with `access_token=None` and raises `AccessError`. `payment.PaymentPortal` already forwards the token via `payment_context` on `/payment/pay`; the invoice portal page did not. Verified on 17.0, 18.0, and 19.0 (18/19: same omission in `_get_common_page_view_values`). Targeting 17.0 as the oldest supported branch for forward-port. Related CLA: https://github.com/odoo/odoo/pull/275749 Current behavior before PR: Public portal invoice page returns AccessError/403 when `invoice_id` is present in the request kwargs without the named `access_token` being forwarded. Desired behavior after PR is merged: `_get_extra_payment_form_values` receives `access_token=access_token` so portal document access checks succeed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Made with [Cursor](https://cursor.com)
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's ty
Original PR description
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when…
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's type to a "URL" or "CC" field. - Save the changes. - The "URL/CC" field is prefilled with the user's name. A field is considered repurposed when: - its type is changed (e.g. from "Phone" to "URL"); - a custom field is converted into an existing field. **Fix:** This commit preserves the prefill only when the field keeps the same name and type. Otherwise, it clears the stale prefill so repurposed fields no longer inherit incorrect values. task-[5976747](https://www.odoo.com/odoo/project/974/tasks/5976747)
opw-4477659
Original PR description
opw-4477659