Wednesday, June 24, 2026
23 changes · 19.0
Enhancements to existing features
This update makes the e-invoice report customization more resilient when other installed apps or customizations adjust the same report templates. It reduces the chance of conflicts during upgrades or deployments, helping accounting-related reports behave more consistently.
Original PR description
**Description of the issue/feature this PR addresses:** As the new `xpath` is expecting a very specific type of `t-if` which is possibly changed in other templates of third parties or even Odoo itself which do not depend on this module, we take a more robust approach to identify the block **Current behavior before PR:** Issues with inherited views outside the dependency tree (because of primary=True) **Desired behavior after PR is merged:** Less friction and smoother identifier of the needed diff Info: @wt-io-it --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270605
Resolved issues and error corrections
Product images with transparent backgrounds now keep their transparency on the online shop. This prevents unwanted white boxes from appearing around products, especially on darker website themes.
Original PR description
Steps to reproduce: =================== 1. Go to /shop and open the Website Builder. 2. Edit theme color, change it to black and save 3. Upload a product image with a transparent background on a…
Steps to reproduce: =================== 1. Go to /shop and open the Website Builder. 2. Edit theme color, change it to black and save 3. Upload a product image with a transparent background on a product. => The transparent background is not preserved. The image is displayed with a white background. Cause: ======= The v19 shop redesign hardcoded a default background of `$gray-100` on the `.oe_product_image` thumbnail wrapper. That solid near-white tile shows up behind product images, so PNG/WebP pictures uploaded with an alpha channel render with a visible white box around them instead of letting the page background bleed through. In lower versions there was no default background on `.oe_product_image`, so transparent product images were rendered as expected; the v19 redesign made the default opaque and lost that behavior. (See [1]) Solution: ========= Switch the fallback of the `--o-wsale-card-thumb-background` CSS variable from `$gray-100` to `transparent`. [1]: https://github.com/odoo/odoo/pull/214744 opw-6224448 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users can now filter chatter content, such as conversations or tracked changes, even when the search box is empty. This makes it easier to review relevant activity on records without needing to type a keyword first.
Original PR description
Steps to reproduce: 1. Install `sale_management` 2. Open any quotation and go to the chatter 3. Add different types of messages (logs, messages, tracked changes like quantity updates) 4. Click on the search icon without entering any input 5. Apply a filter such as Conversations or Tracked Changes Issue: - The chats are not filtered. Cause: - The current implementation blocks the search mechanism when the search term is empty. Solution: - Search filters are now applied even when no search term is provided, ensuring the chatter content updates based on filters alone. Backport https://github.com/odoo/odoo/commit/daa2513fe58da2bb182bbea2e15386d72a7f1eb7 opw-6096055 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue in the mail composer where using the End key after inserting a mention could move the cursor to the wrong paragraph. Users can now navigate text around mentions more reliably when writing messages.
Original PR description
### Purpose of this PR: - Inserting a mention in the composer results in a paragraph ending with a bare `<a>` element and no trailing text node. This causes the browser to mishandle the End key, moving the caret to the start of the next paragraph instead of the end of the current line. - Fix by appending a \uFEFF (zero-width no-break space) text node. task-6295924 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270900 Forward-Port-Of: odoo/odoo#269699
A mail-related automated test was adjusted so it continues to pass with PostgreSQL 18, which reports this database constraint issue differently than earlier versions. This is an internal reliability fix that helps keep Odoo's test suite stable without changing user-facing behavior.
Original PR description
This commit is kind of a follow up of
odoo/odoo@39cd4ea856fe00f5674f8c44b2b66cbf2705426d (in 18.0).
In a nutshell, following a standard-compliance fix (postgres/postgres@086c84b) has led to `RESTRICT_VIOLATION` being emitted in cases which formerly emitted `FOREIGN_KEY_VIOLATION`. One such case is specifically being tested for by `test_alias_domain_setup`, leading to this test failing systematically when running pg18:
psycopg2.errors.RestrictViolation: update or delete on table "mail_alias_domain" violates RESTRICT setting of foreign key constraint "mail_alias_alias_domain_id_fkey" on table "mail_alias"
DETAIL: Key (id)=(191) is referenced from table "mail_alias".
This commit updates the test to use the more generic `IntegrityError` as it's probably more than sufficient for our purposes.
Forward-Port-Of: odoo/odoo#271403
Forward-Port-Of: odoo/odoo#271302Employees on flexible schedules can now request a single day off that falls on a public holiday when that leave type is configured to count public holidays. This prevents valid time off requests from being incorrectly rejected and keeps single-day requests consistent with multi-day leave behavior.
Original PR description
Currently, flexible employees can request a multi-day leave spanning a public holiday when the leave type includes public holidays in duration. However, requesting the public holiday date alone is…
Currently, flexible employees can request a multi-day leave spanning a public holiday when the leave type includes public holidays in duration. However, requesting the public holiday date alone is rejected. ### **Steps to reproduce:** - Create a public holiday. - Create a time off type with "Public Holiday Included" enabled. - Select/create an employee with a flexible work schedule and its time zone must be same as admin. - Request a time off on the public holiday date only. ### **Observed Behavior:** The request is rejected because its duration is computed as 0 days. ### **Expected Behavior:** The request should be allowed and count as 1 day, consistent with the multi-day request behavior. ### **Root Cause:** At [1], a dedicated duration computation path is used for single-day leaves of flexible employees. This logic always retrieves overlapping public holidays and computes the leave duration based on the remaining intervals. As a result, a leave requested entirely on a public holiday is computed as 0 days, even when `include_public_holidays_in_duration` is enabled. [1]- https://github.com/odoo/odoo/blob/242f6d3cf7288853f163ac6986a3b7aa4279efaf/addons/hr_holidays/models/hr_leave.py#L436-L444 ### **Fix:** This commit ensures that the `include_public_holidays_in_duration` setting is taken into account when computing single-day leave durations for flexible employees **opw-6284768** Forward-Port-Of: odoo/odoo#271493 Forward-Port-Of: odoo/odoo#269743
The HTML editor now keeps command shortcuts and automatic markdown formatting disabled while users are typing inside code blocks. This prevents crashes and unexpected formatting changes when entering code-like text, making editing more reliable.
Original PR description
### Steps to reproduce: - Go to ToDo. - Create a code block using `/code`. - Place the cursor inside the code block. - Type `/table` and select the table command. - A traceback occurs. ### Purpose of this PR: - Commands and markdown shorthands should not be available inside code blocks. However, typing `/` inside a `<pre>` opened the command palette, allowing structural commands such as `/table` to be executed and causing a traceback. Similarly, markdown shorthands such as `* ` and `1.` were still active, unexpectedly transforming code content into lists. ### This PR fixes the issue by: - Disabling the command palette when the cursor is inside a `<pre>` element. - Disabling markdown shorthands inside `<pre>` elements by registering an `is_shorthand_available_predicates` predicate. task-6292231 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271511 Forward-Port-Of: odoo/odoo#269430
The Mozambique demo company now uses a valid NUIT tax identification number. This prevents demo data checks from failing with newer validation rules, keeping test and demo environments reliable.
Original PR description
Newer versions of stdnum (2.2) also test the number for MZ We did not have a valid NUIT number in the MZ demo company. Runbot error: https://runbot.odoo.com/runbot/build/114118067 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#271398 Forward-Port-Of: odoo/odoo#271299
Purchase orders with cancelled backorders are no longer incorrectly listed as having late receipts. This keeps purchasing teams focused on receipts that still require action and avoids misleading follow-up work.
Original PR description
Steps to reproduce: ------------------- - Create a Purchase Order with an expected Arrival date in the past - Confirm the Purchase Order - Validate the receipt partially and create a backorder -…
Steps to reproduce: ------------------- - Create a Purchase Order with an expected Arrival date in the past - Confirm the Purchase Order - Validate the receipt partially and create a backorder - Cancel the generated backorder - Open the Purchase Orders list and check the 'Late Receipts' Issue: ------ The Purchase Order still appears in the 'Late Receipts' filter even though there is no remaining receipt to process. Cause: ------ The 'Late Receipts' filter relies on the computed search field `is_late`: https://github.com/odoo/odoo/blob/324df67c099ab18c6fe7c8f77212cf809debf383/addons/purchase/views/purchase_views.xml#L439 The search domain for this field is generated by `purchase.order._search_is_late()`: https://github.com/odoo/odoo/blob/324df67c099ab18c6fe7c8f77212cf809debf383/addons/purchase/models/purchase_order.py#L176 In `purchase_stock`, `_get_domain_is_late()` extends the base domain to identify Purchase Orders that still have receipts pending: https://github.com/odoo/odoo/blob/324df67c099ab18c6fe7c8f77212cf809debf383/addons/purchase_stock/models/purchase_order.py#L264-L267 After a partial receipt: - the original receipt is in state `done`, - a backorder is created and linked to the Purchase Order, - the backorder is later cancelled and moves to state `cancel`, - the Purchase Order line still has `qty_received < product_qty`. The existing domain excludes only `done` pickings when determining whether a receipt is still pending. As a result, a cancelled backorder is still treated as an unfinished receipt, causing the Purchase Order to remain visible in the 'Late Receipts' filter. Fix: ---- Exclude both `done` and `cancel` pickings when determining whether a Purchase Order has pending receipts. A cancelled backorder indicates that the remaining quantity will not be received through that transfer. Therefore, once all related pickings are either completed or cancelled, the Purchase Order should no longer be considered late. --- opw-6266046 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Manufacturing orders are no longer created when a product is set to be manufactured but has no Bill of Materials. This prevents confusing empty draft orders and lets replenishment rules handle the missing setup as expected.
Original PR description
Steps to reproduce: - unarchive the MTO route - Create a storable product "P1" with the MTO + Manufacture routes but set no Bill of Materials on it - Create a sales order with one unit of P1 and confirm it Problem: An empty draft MO is created even though no Bill of Materials exists. When no BoM is available, manufacturing orders should not be created, only replenishment rules are expected to handle this case. Fix: Added an early `continue` in `_run_manufacture` to skip MO creation when no BoM is found. opw-6174886
This update adds a test option that lets Odoo verify spreadsheet behavior when list data is not yet ready. It helps prevent timing-related issues in spreadsheet list features, improving confidence in future fixes without changing day-to-day user workflows.
Original PR description
Added the parameter `skipWaitForDataLoaded` to `createSpreadsheetWithList` to test what happens when the list is not ready yet. Task: [6289944](https://www.odoo.com/odoo/2328/tasks/6289944) 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#271144 Forward-Port-Of: odoo/odoo#269096
The Mauritania country flag image has been updated to the correct version. This ensures users see accurate country branding in Odoo wherever country flags are displayed.
Original PR description
[task-6320443](https://www.odoo.com/odoo/project.task/6320443) Forward-Port-Of: odoo/odoo#271488
This fix ensures Odoo's gevent server performs the same database preloading step used elsewhere, so registry settings are initialized properly. It helps avoid server startup or runtime inconsistencies caused by missing registry size configuration.
Original PR description
The code to set the registry size was moved to `preload_registries`. The gevent server does not preload registries and thus does not set the registries size. Instead of moving the code again, we can preload registries in the gevent server. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271640
This fixes a Danish localization upgrade problem where accounting tag updates could run too early and leave old tags still in use. The change makes the update happen after the required new tags are available, reducing upgrade failures for Danish accounting databases.
Original PR description
The tag remapping was running in pre-migrate, before the module's data files are loaded. This caused the tag swap to be silently skipped for any new tag that didn't exist yet, and the subsequent cleanup to fail with a FK violation on account_account_account_tag.
```py
File "/home/odoo/src/odoo/saas-19.2/odoo/sql_db.py", line 417, in execute
self._obj.execute(query, params)
psycopg2.errors.ForeignKeyViolation: update or delete on table "account_account_tag" violates foreign key constraint "account_account_account_tag_account_account_tag_id_fkey" on table "account_account_account_tag"
DETAIL: Key (id)=(356) is still referenced from table "account_account_account_tag".
```
Moving to post-migrate ensures all new account tags are present in the database before the remapping and cleanup run.
upg-[4341331]
[4341331]: https://upgrade.odoo.com/odoo/upgrade.request/4341331?debug=1
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe automated Clickall test setup now also blocks the newer Odoo Fin favorite institutions endpoint from contacting production servers. This keeps test runs isolated and reduces the risk of unreliable results or unintended external calls.
Original PR description
This commit follows up on [1] by extending the Odoo Fin request mock to cover the new version 2 (v2) favorite institutions endpoint. Previously, a mock was introduced to prevent the Clickall tool from making real external HTTP requests to `production.odoofin.com` when displaying the accounting dashboard. This update ensures that the newly introduced v2 URL is also safely intercepted, keeping the automated tests fully isolated from production servers. runbot-234936 [1] : https://github.com/odoo/odoo/commit/c6451015f1b01c3e1defe4a576989fd4bfdf2cdb
The Spain VeriFactu module now correctly requires the certificate component it relies on. This prevents installation or upgrade failures when the certificate component was not loaded first, making deployments more reliable.
Original PR description
### Issue `l10n_es_edi_verifactu` builds an inheritance on `certificate.certificate` and loads that module's views/demo, but only declares `depends: ['l10n_es']`. With `certificate` not guaranteed to…
### Issue `l10n_es_edi_verifactu` builds an inheritance on `certificate.certificate` and loads that module's views/demo, but only declares `depends: ['l10n_es']`. With `certificate` not guaranteed to load first, building the registry without it already present raises: ``` TypeError: Model 'certificate.certificate' does not exist in registry. ``` ### Cause `models/certificate.py` → `_inherit = 'certificate.certificate'`; manifest `data` loads `views/certificate_certificate_views.xml` and `demo/demo_certificate.xml`. Yet `certificate` is absent from `depends`. Every sibling (`l10n_es_edi_facturae`/`sii`/`tbai`, `l10n_sa_edi`) already depends on `certificate`. Present since the module was added in `02f8d5525eb7`. ### Notes - Opened on **18.0** so it **forward-ports to 19.0** (both stable branches carry the bug). `master` already has the equivalent change via #234729 — the forward-port there should be a no-op. - Surfaced via an 18.0→19.0 OpenUpgrade migration that force-updates `verifactu` before `certificate` loads; also reproducible on a plain install where `certificate` isn't otherwise pulled in first. Forward-Port-Of: odoo/odoo#271496
This update corrects a previous issue where warnings from the IoT device were incorrectly treated as errors. Now, when a warning code is received, a notification is displayed, providing clearer visibility into the status of transactions. This ensures more accurate and timely alerts for Point of Sale operations.
Original PR description
Before this commit, all errors returned by the iot after a call to the blackbox were considered as errors. Actually, the errors are only the ones that do not start with 0 (no error) or 1 (warning). This commit changes the behaviour when handling warning. We now show a notification. task-id: 5062178 Forward-Port-Of: odoo/enterprise#109251 Forward-Port-Of: odoo/enterprise#93896
This update resolves a bug where the 'Suggest Forecasted Demand' button disappeared in the Master Production Schedule when the 'Forecasted Stock' row was hidden. Previously, the button's visibility was dependent on the 'Forecasted Stock' row being enabled, causing confusion for users. Now, the button remains visible regardless of the 'Forecasted Stock' row's status.
Original PR description
Steps to reproduce:
1. Install Manufacturing.
2. Enable 'Master Production Schedule' in the Settings.
3. Go to [Manufacturing -> Planning -> Master Production Schedule].
4. Ensure 'Demand Forecast' and 'Forecasted Stock' rows are enabled from the dropdown.
5. Observe the edit pencil button next to 'Forecasted Demand' is visible.
6. Hide 'Forecasted Stock' using the rows filter dropdown.
Issue:
The edit pencil button ("Suggest Forecasted Demand") next to the 'Forecasted Demand' row disappears when the 'Forecasted Stock' row is hidden.
Expected behavior:
The edit pencil visibility should not be affected by the 'Forecasted Stock' row.
opw-6240596This update resolves several errors in the Blackbox test suite for the Belgian POS system, ensuring accurate order processing and synchronization. Specifically, the tests were failing due to incorrect data setup, mismatched expectations regarding printer types, and issues with cost center assignments. These fixes improve the reliability of the testing process and the overall functionality of the system.
Original PR description
1. The `m160` and `m161` mutations for `sign_copy_sale` test didn't set the `l10n_be_short_signature` field on the order, so the `TicketScreen.print` override would fail the check and the…
1. The `m160` and `m161` mutations for `sign_copy_sale` test didn't set the `l10n_be_short_signature` field on the order, so the `TicketScreen.print` override would fail the check and the `blackbox.signCopy` would not be called, causing the test to fail. 2. The `l10n_be_pos_blackbox_urban_piper` tests would crash on `undefined id` on the prep display path of `pos_enterprise`, where the data service will try to load up the prep display data, but it's not loaded in the test bundle. So I created a special setupEnv method for blackbox with urban piper which unpatches the prep display (same mechanism as pos_enterprise) 3. After removing the path for the tests, they would fail for the `expectGeneralProperties` step. By default it expects the `ticketMedium` to be `PAPER`, but there is no printer configured on the tests, so the actual medium is `DIGITAL`. 4. The tests expect the cost center to be `PLATFORM`. There was a patch on `InputGenerator`, which would return platform if the order has a `delivery_provider_id` set. But the patch never fired. I moved the patch directly on the order model, which is where the cost center value is computed. 5. The `test_l10n_be_pos_blackbox_sign_sale_backend_offline` test would endTour prematurely before the orders finished syncing, then check that all the orders are synced. I added an extra isSynced() step to ensure the orders are synced before ending the tour Task-[6320705](https://www.odoo.com/odoo/1737/tasks/6320705)
This update fixes an issue where non-recurring products were incorrectly included in recurring revenue (MRR/YRR) calculations within subscription reports. This ensured accurate reporting regardless of user-selected filters, preventing misleading revenue figures. The change improves the reliability of subscription performance data.
Original PR description
While investigating a support ticket, we noticed that in subscription reports, recurring revenue values (MRR and YRR) are implicitly calculated for non-recurring products. This doesn't cause a direct problem when using the default search domains applied in Subscription > Reporting > Subscription > Pivot view, because a "Recurring" filter is pre-applied. But if the end user removes said filter, they might accidentally fudge the MRR and YRR numbers because the non-recurring products will contributed to the relevant grouping sums. We fix this by adding a CASE clause to explicitly ignore non-recurring products when calculating the report field for MRR and YRR , i.e. only consider `t.recurring_invoice = TRUE`. OPW-6315091
This update resolves an issue where the tooltip for list autofill features displayed error messages instead of correct information when the list data wasn't yet available. The fix ensures that tooltips display the intended data, improving the user experience and preventing misleading notifications.
Original PR description
The getter `getTooltipListFormula` would return the result of `getListHeaderValue` as the content of the tooltip, but this returned a loading error instead of a string if the list was not ready yet. Task: [6289944](https://www.odoo.com/web#id=6289944&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) Forward-Port-Of: odoo/enterprise#121228 Forward-Port-Of: odoo/enterprise#119876
This update corrects an inconsistency in how completed document rights are managed within the Enterprise system. The change ensures that rights associated with finalized documents are accurately reflected, preventing potential access issues. This improves data integrity and reliability for document-related workflows.
This update resolves an issue in the website studio where switching between multiple form models through the 'More models' feature would cause a crash. The fix ensures both the original and newly selected models are retained in the system's memory, preventing data loss and improving stability.
Original PR description
Selecting a second model through the Action option's "More models" crashed because the current form model was dropped from the models cache while the new model was being applied. This commit keeps both the current form model and the model being applied in the cache. Steps to reproduce: - Add a form snippet - Click on the form - In the `Action` option, select `More models` - Select one model - Open `More models` again and select another model - Traceback appears: `TypeError: Cannot read properties of undefined (reading 'website_form_key')` task-6321878 Forward-Port-Of: odoo/enterprise#121492