Monday, August 25, 2025
24 changes · saas-18.4
Enhancements to existing features
The scale certification screen now displays the Point of Sale version instead of the IoT device version. This gives users the relevant version information when checking certified scale status, reducing confusion during compliance or support checks.
Original PR description
We need to display the PoS Version, not the IoT version. Forward-Port-Of: odoo/enterprise#91682
Resolved issues and error corrections
The Unsplash image picker now handles duplicate images returned in the same search results. This prevents users from seeing an error when searching for images, such as with the term "Inventory", and keeps the media selection flow working smoothly.
Original PR description
This commit fixes an OwlError when we try to render the images received from Unsplash after a search. The issue is that Unsplash can send duplicate images in the same batch of images. When we render those in a `t-foreach` and use the image `id`s as the keys, we get a duplicate key error. This is fixed by expanding on the previous filtering code, which ignored duplicates over multiple batches. We now ignore duplicates within batches as well. At the time of writing, Unsplash is sending us duplicate images on a search for "Inventory". opw-5027032 Forward-Port-Of: odoo/odoo#223789
Miscellaneous changes
It's not rare to have databases with a huge number of svls for some products. For instance, the database of opw-4326597, which is currently on 17.0 and hosted on Odoo.sh, has 166 000 svls for the same product. Because of that, the current code in `svl_empty_stock` is likely to raise a MemoryError in those databases. The reason for that is the `__get__` call on `stock_valuation_layer_ids` along with a call to `filtered`. After expanding the singleton with the `prefetch_ids` and fetching all the
Original PR description
It's not rare to have databases with a huge number of svls for some products. For instance, the database of opw-4326597, which is currently on 17.0 and hosted on Odoo.sh, has 166 000 svls for the…
It's not rare to have databases with a huge number of svls for some products. For instance, the database of opw-4326597, which is currently on 17.0 and hosted on Odoo.sh, has 166 000 svls for the same product. Because of that, the current code in `svl_empty_stock` is likely to raise a MemoryError in those databases. The reason for that is the `__get__` call on `stock_valuation_layer_ids` along with a call to `filtered`. After expanding the singleton with the `prefetch_ids` and fetching all the fields of the related svls, the cache will probably raise a MemoryError. We are preempting this issue by changing this part of the code with a call to `_read_group` to get the correct lots directly. Thanks to @mwath for pointing this out. #### speedup Benchmark of the `_svl_empty_stock` method, with a product with 200 000 svls with a lot. | Before PR | After PR | |:----------:|:---------:| | 15.03s | 198.64ms | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#188285
The time off wizard now opens bulk employee time off and allocation actions in the right navigation context. This prevents confusing breadcrumbs or URLs that made the action look tied to a single leave request.
Original PR description
Task ID: 5004005 **Description of the issue this PR addresses:** When generating time off or allocations for multiple employees using the wizard, the resulting breadcrumb and navigation incorrectly inherit the active_id from the parent view (a specific leave request) appearing as a child of a specific leave record in the breadcrumb and URL. Forward-Port-Of: odoo/odoo#222764
Lead enrichment now stops retrying when a lead has no valid email after the first attempt. This prevents repeated error loops and reduces unnecessary processing for CRM teams.
Original PR description
If a lead has no valid email, try to enrich it only once This will avoid infinite loop of errors of "Enrichment could not be done because…" Forward-Port-Of: odoo/odoo#223967 Forward-Port-Of: odoo/odoo#223874
Approved and partially approved time off entries opened from the calendar now keep the Employee field read-only. This prevents accidental changes to the employee linked to an already validated request and keeps the calendar dialog consistent with the main form.
Original PR description
Issue: - In Management > Time Off > Calendar View clicking on an approved or partially approved time off opens a dialog where the Employee field is currently editable even if it's read-only on the form view Fix: - The employee_id field has been set to read-only, same as the form view. task- 4862383 Forward-Port-Of: odoo/odoo#214332
The website editor now shows only the relevant color options when choosing dot and line colors for timeline image sections. This removes confusing choices and makes it easier for users to style timelines consistently.
Original PR description
The goal of this commit is to display only the ‘solid’ and ‘custom’ tabs for the color pickers used to choose the color of the dots and dot lines for the timelineImages snippet. 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
This update prevents Point of Sale loyalty barcode activation from failing when a customer record has not been loaded yet. It also makes sales testing more reliable by avoiding duplicate customer names that could cause the wrong customer to be selected.
Original PR description
In PoS loyalty when activating a barcode we were not checking if the partner was already loaded in the PoS resulting of an undefined var. Now we check if the partner is loaded before trying to access it. In PoS sale tour, we were creating a partner called "Test Partner" which was already created in the setup, so sometime the tour was selecting the wrong one. Now, the name of this partner is changed to "AAA - Test Partner invoice" Runbot error: 230992, 230995 https://runbot.odoo.com/odoo/runbot.build.error/230992 https://runbot.odoo.com/odoo/runbot.build.error/230995 Forward-Port-Of: odoo/odoo#223785 Forward-Port-Of: odoo/odoo#223618
Default self-order kiosk images and backgrounds no longer appear as suggestions in the website image picker. This keeps the website editor cleaner while still allowing user-uploaded kiosk images to be reused on website pages.
Original PR description
Commit [1] forced kiosk image and background attachments to be public, therefore making them displayed in the website media dialog in edit mode, as a suggestion. Steps to reproduce: 1. Install…
Commit [1] forced kiosk image and background attachments to be public, therefore making them displayed in the website media dialog in edit mode, as a suggestion. Steps to reproduce: 1. Install website and pos_self_order 2. Go to the website, edit a page, add a block with an image 3. Double-click on the image => the media dialog is empty 4. Save, go to "Point of Sale" 5. Create a "bar", configure it to be a self-order kiosk, add products with the right categories, etc. 6. Go back to the website, edit the page, double-click on an image => the media dialog now shows the kiosk images and background images This commit solves the issue by making it so that the *default* ones are not displayed in the website media dialog. To do that, while keeping them public, we use "url" type attachment pointing to Odoo static files, which are excluded from the website media dialog because that's the way default snippet images for the website are defined too. For user-chosen kiosk images, we keep the behavior of suggesting them in the website media dialog. After all, they are user-chosen public images, it make sense for the user to potentially use them in their website. At least, with this commit, the website media dialog is less polluted while demoing on runbot. [1]: https://github.com/odoo/odoo/commit/b12c49bffafaf81e59ec97a3a51d1b4e05726142
This fixes the placement of action buttons on log notes written by the current user. The buttons now appear consistently next to the date, making message threads easier to read and use.
Original PR description
**Purpose of this PR:** Fix the position of message actions on log notes authored by the current user. Messages authored by self appear on the right side of the thread. This PR mirrors the action placement logic so that, like messages from others (which show actions to the right of the date), self-authored messages show actions to the left of the date. Before: <img width="392" height="638" alt="image" src="https://github.com/user-attachments/assets/8b66c98f-3e00-47c8-abf3-ee62169ed499" /> After: <img width="392" height="638" alt="image" src="https://github.com/user-attachments/assets/d1a425da-fb0c-4793-a080-735286bc2bb9" /> task-[4689357](https://www.odoo.com/odoo/project/1519/tasks/4689357) Forward-Port-Of: odoo/odoo#223788 Forward-Port-Of: odoo/odoo#216520
Uploading GIF images in the website or HTML editor no longer causes an error when image size details cannot be calculated. Instead of showing invalid size information, the interface now hides unavailable size details, making image uploads smoother for users.
Original PR description
When uploading a gif image file, no transformation occurs and therefore no data URL is being generated. Because of this, trying to compute the size from the data URL fails. This commit avoids computing the size from non transformed images, and hides the size info when it is unavailable. (vs "NaN kb") task-4367641
The website builder’s automated checks have been updated to match recent page structure changes, allowing a previously disabled scrollbar-related test to run again. This helps maintain confidence that popup and scrolling behavior in website snippets continues to work as expected, while a separate animation issue remains pending.
Original PR description
This PR aligns tour steps with new DOM structure and re-enable related tests. The `snippet_popup_and_scrollbar` tour was broken due to changes in DOM structure from the new website builder. This tour disabled. Split `test_snippet_popup_with_scrollbar_and_animations` into two separate tours: `snippet_popup_and_scrollbar` and snippet_popup_and_animation`. Note that animation behavior remains unfixed as `On Hover` option is missing.
Fixes a website header styling issue where certain active link styles made the sign in button appear larger than intended. This keeps the header layout consistent and avoids a visual glitch for visitors who are not logged in.
Original PR description
Before this commit, using the "outline" or "border bottom" options for the Link Style (active page link in the header) would make the sign in button bigger. This was due to the fact the selector was not precise enough and would also include the button. This commit improves the selector to avoid impacting the sign in button. Steps to reproduce: - Go to Edit mode - Click on the header - Set the Navbar > Links Style option to "Border Bottom" - Save - Log Out Forward-Port-Of: odoo/odoo#223441
The sales order availability indicator is now hidden when a remaining delivery/backorder has been canceled. This avoids showing a red “No future availability” warning when the customer or user has intentionally decided not to deliver the remaining quantity, reducing confusion for sales teams.
Original PR description
Issue ----- The availability widget states "No future availability" when the backorder of a product has been cancelled, despite the product being available in stock. Steps to reproduce ----- - Create…
Issue ----- The availability widget states "No future availability" when the backorder of a product has been cancelled, despite the product being available in stock. Steps to reproduce ----- - Create a stored product with some on hand quantity - Create a SO for the product - Register a partial delivery (or set the move quantity to 0) - Cancel the backorder - Go back to the SO --> The widget is red and states that there is "No future availability". While the logic is sound, this is confusing the user because they have some qty in stock. Solution ----- The user has manually decided not to deliver the (full qty of) product. There is aready some logic to set the `display_qty_widget` field to False when the user deletes the move from the the picking. https://github.com/odoo/odoo/blob/693e1ef2f934f58209a78787404d5c76be550af4/addons/sale_stock/models/sale_order_line.py#L61 Since the user specified that there is nothing left to deliver, we can extend the condition to include our use case. To do so, we can simply check the existence of a move that is not in a 'done' or 'cancel' state. This will make the widget invisible because it is conditionally invisible. https://github.com/odoo/odoo/blob/693e1ef2f934f58209a78787404d5c76be550af4/addons/sale_stock/static/src/widgets/qty_at_date_widget.xml#L7 ----- Ticket: opw-4942277 Forward-Port-Of: odoo/odoo#220796
Editing the Contact Us page could fail in Italian when the form question block contained duplicate translated labels. The update uses a unique internal identifier so the website editor opens reliably for affected pages.
Original PR description
**Steps to reproduce:** -Install the Website module. -Change the language to Italian. -Enable debug mode. -Go to the website. -Navigate to Website → Contact Us page -Click to Edit -Try to edit the Question block. **Issue:** A traceback occurs with the error: Uncaught Promise > Got duplicate key in t-foreach: Contatto **Cause:** https://github.com/odoo/odoo/blob/d69402a13914428fe6e05cc772157f0eec2c5627/addons/website/static/src/builder/plugins/form/form_option.xml#L7-L11 The t-foreach loop was using model.name as the key, which can result in duplicates (e.g., multiple records with the name 'Contatto'), causing the editor to fail. **Solution:** Use model.id as the t-foreach key instead, ensuring uniqueness for all records. **opw**- 4972693
This fix prevents an error screen when users cancel an import from areas like Contacts or Products. Instead of attempting to continue with missing record information, Odoo now returns users to the previous screen as expected.
Original PR description
To reproduce: ============== 1. Go to any import screen in Odoo (e.g., Contacts, Products). 2. Click on *Cancel*. → Traceback occurs. Problem: ======== In the old behavior clicking on cancel will call historyBack function which will call restore. https://github.com/odoo/odoo/blob/93451453deff4b316cb1865055d1817f8290f8ef/addons/web/static/src/webclient/actions/action_service.js#L1668 and now in this version. this PR changed the way the exit works. https://github.com/odoo/odoo/pull/211187 So when you click on `Cancel` it will call doAction with resIds undefined instead of calling restore. Solution: ========== In case the resIds is undefined we can proceed with the old behavior which is calling the historyBack function. opw-5015226 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Installing the Belgium Accounting localization now continues successfully even if a referenced demo account tag was previously deleted. This prevents setup failures in demo or test environments and makes the installation process more reliable.
Original PR description
Currently, installing the Belgium Accounting localization fails with an error, if the user has deleted referenced demo account tags. **Steps to reproduce:** - Install the Accounting app. - Delete the "Demo Capital Account" account tag. - Install the Belgium Accounting localization (`l10n_be`). **Error:** `ValueError - External ID not found in the system: account.demo_capital_account` At [1], if the `account.demo_capital_account` is not found, it raises an error if the external ID is missing. This commit prevents the error by explicitly passing `raise_if_not_found=False` and skipping the tag if not found. [1] - https://github.com/odoo/odoo/blob/71d1c9a4bef1c29485e3b0390713a9301ad6db4f/addons/l10n_be/demo/account_demo.py#L13-L19 sentry-6776341713 Forward-Port-Of: odoo/odoo#221227
This fixes the help link in Timesheets settings so it opens the correct documentation page after a recent documentation structure change. Users clicking the info icon for Time Off settings will no longer be sent to a missing or outdated page.
Original PR description
**Description:** - In a recent documentation commit, the overview section was removed from the timesheets path. commit: odoo/documentation@3bceee836fa8b8edfd8a35c20b21867354f6c078 **Steps to reproduce:** - In a `v18` runbot - open settings > Timesheets settings > under Time off - click on the info icon <img width="1905" height="944" alt="2025-08-21_18-25" src="https://github.com/user-attachments/assets/34ec76ed-46f7-4b08-8c23-10269e105b43" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223711
Fixed an error that prevented users from printing the yearly salary report in Indian Payroll after payslips were paid. The report now uses the correct translated payroll structure name, avoiding the crash and allowing payroll teams to access annual salary details as expected.
Original PR description
Steps to Reproduce:
- Install Indian Payroll Localization
- create a payslip of any employee and mark as paid
- try to print yearly salary report from reporting menu
Issue:
- A traceback error occurs when printing the yearly salary report.
Reason:
- the sturcture name is translatable field, which gives the value in a dict with the key as languages like {'en_US': 'India: Regular Pay'}.
- The error occurs because the code attempts to use this dictionary with setdefault, which expects a string.
Solution:
- Get the structure name corresponding to the appropriate language from the dictionary before passing it to setdefault.
task-5002518
Forward-Port-Of: odoo/enterprise#91901Bank statement creation no longer fails when a bank journal has no outstanding receipt or payment account configured. This prevents an unexpected error and lets accounting users continue creating statements in this valid setup.
Original PR description
**Steps to reproduce:** - Install Accounting - Make sure that no outstanding receipt/payment account is configured on the Bank journal - Go to the Bank journal - Create a new statement **Issue:** A traceback is raised while executing a SQL query. **Cause:** A IN condition is evaluated with an empty tuple: `AND aml.account_id IN ()` This is due to the fact that there is no outstanding account. **Solution:** Only execute the SQL query if there is an outstanding account. opw-5039931 Forward-Port-Of: odoo/enterprise#93091
Belgian payroll users now see a clear message when trying to change an employee working schedule without a contract start date. This prevents an unexpected system error and helps users correct the missing employee information before continuing.
Original PR description
Prevent the apparition of a traceback when changing the schedule through the wizard
Payroll configuration screens now show Python code correctly for salary rules and rule parameters. This helps payroll administrators review and maintain calculation logic more reliably, reducing confusion when checking pay rule settings.
Original PR description
Forward-Port-Of: odoo/enterprise#92960 Forward-Port-Of: odoo/enterprise#91811
Helpdesk ticket portal pages no longer show an unrelated “Timesheets” breadcrumb just because the ticket contains timesheet entries. This keeps customer-facing navigation clearer and avoids confusion when viewing tickets online.
Original PR description
**Steps to reproduce:** 1. Install 'Helpdesk Sale Timesheet' and 'Website' modules. 2. Create a helpdesk ticket and add timesheets to it. 3. Go to the portal view of helpdesk tickets. **Issue:** If the ticket contains timesheets, the "Timesheets" breadcrumb appears in the portal ticket view. **Cause:** The reason the timesheet variable is used in the hr_timesheet portal template is because it makes the condition evaluate to true, which is why the breadcrumb for Timesheets is displayed. **Fix:** Renamed the loop variable in `t-foreach` to avoid shadowing the `timesheet` variable from the outer context. task-4744294 Forward-Port-Of: odoo/enterprise#85411
Manufacturing users can now search for employees to assign without hitting errors caused by records from companies they cannot access. The employee selection is limited to companies available to the current user, making work order assignment more reliable in multi-company setups.
Original PR description
Task ID: 5005753 Prev behavior: when searching for employees to assign (employee_assigned_ids) from the manufacturing page and using "Search More", it was raising an error bc it was fetching data even from employees part of companies he's not part of New behavior: added domain over employee_assigned_ids such that the accessed users are only the ones being part of a company the current user can access