Wednesday, July 16, 2025
28 changes · saas-18.4
Enhancements to existing features
The point of sale payment screen now shows the cash rounding amount aligned to the right with a more subtle text style. This makes the payment details easier to scan and improves the checkout interface without changing how payments work.
Original PR description
We moved the cash rounding value to the right, making it text muted to improve UI.
When an IoT box image is reset to another development branch, it now also installs any newly required system and Python packages. This helps development environments stay consistent and reduces setup issues after branch changes.
Original PR description
When resetting on another branch with aliases `odoo_dev` and `odoo_origin`, we now also install new packages from `requirements.txt` and `packages.txt`. Forward-Port-Of: odoo/odoo#219050
Resolved issues and error corrections
This fix makes hidden bus worker errors and failed background promises appear in the bus logs. It helps support and development teams troubleshoot real-time communication issues more quickly, even when problems happen in background browser workers.
Original PR description
Bus behaviors are not easy to troubleshoot: - Worker devtools not easily available. - Errors are kept in the worker, never logged nor raised client side. - Worker communicates with many tabs. To ease troubleshooting the bus, logs were introduced. It's much better because they can be downloaded from any tab, survive reloads... However, unhandled errors/promises are not logged which is cumbersome. This commit adds unhandled errors/promises to the bus logging. 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#219085
Code cleanup and technical improvements
This update simplifies internal callback handling used by website tour automation and web testing tools. It makes the code easier for developers to read and maintain, with no expected change for everyday users.
Original PR description
In this commit, we're changing the structure of the onStep and onError callback functions in macro.js to make them easier to use. Previously, when using onStep and onError, it was difficult to understand what was being returned in the callback and required declaring variables that might not be used. Now, it's easier to destructure the returned object. 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#218767
Miscellaneous changes
The pot exporter was improved to not export empty pot files by returning a file with `data=False`, so that when users try to export a module without any terms to translate, no file is exported and a warning shows in the wizard/logger based on the data being `False`. At this time, the test to auto-export the pot file wasn't adapted to handle this false data, so we adapt now to make auto-exporting work again. For additional context, see: https://github.com/odoo/odoo/commit/5192edca2166aa2701aa
Original PR description
The pot exporter was improved to not export empty pot files by returning a file with `data=False`, so that when users try to export a module without any terms to translate, no file is exported and a warning shows in the wizard/logger based on the data being `False`. At this time, the test to auto-export the pot file wasn't adapted to handle this false data, so we adapt now to make auto-exporting work again. For additional context, see: https://github.com/odoo/odoo/commit/5192edca2166aa2701aad46d3e6d839c7a7bb12f --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where turning off the general developer tool category could also stop device long-polling updates. Device actions and events now continue working as expected, reducing the risk of interrupted hardware communication during development or troubleshooting.
Original PR description
`devtools disable general` should not disable longpolling actions/events. We updated the `toggleable` wrapper to avoid this. Forward-Port-Of: odoo/odoo#219116
The website color picker now correctly shows when a selected background color is transparent instead of displaying it as solid red. This prevents confusion when configuring header backgrounds in the website builder and makes the picker reflect the actual design setting.
Original PR description
> click on header, "Header Position": "Over the Content", click on the color of the background, it is supposed to be transparent, but the picker shows solid red The changes in 41fec6b94900fa85febbfb0fd748a44747182cc6 causes the picker to show incorrect information when the selected color at the creation of the picker is transparent This commit changes the approach used to achieve the same goal (to get the color clicked on when clicking on the hue bar). Without faking a selected color when it is transparent Steps to reproduce: - Open website builder - Click on the header, and set "Header Position" to "Over the Content" - Click on "Background" - Bug: the color shown as selected by the picker is red, not transparent task-4367641
Refund orders in Point of Sale are now named correctly with the “REFUND” label. This makes it easier for staff and back-office users to identify refunds in order lists and reporting.
Original PR description
Currently, when refunding an order the name of the order does not show "REFUND". Steps to reproduce: ------------------- * Open pos session * Make an order * Refund the order * Go to the backend and see all orders > The refund orders does not show the "REFUND" label Why the fix: ------------ In previous version, when in `sync_from_ui` the state of the order in vals was 'draft'. In this version the state in vals is `paid`. This difference leads to the name being computed in `_complete_values_from_session`. This means that `_compute_order_name` is called before the order is fully created and thus `refunded_order_id` is not yet set and we're always using the next sequence to compute the order name. Now, when we already know the order is a refund we will not compute the name in `complete_values_from_session`. The name will get computed in `write`, which is called by `action_pos_order_paid`, as in previous version. opw-4521070 Forward-Port-Of: odoo/odoo#214542
This fixes inconsistent automated test behavior around the link popover in the HTML editor. The change helps keep quality checks stable and reduces false failures during development and release validation.
Original PR description
In 3145a4ffe2e64737297aab90f382fad9f1a29491, tests were adapted to use absolute urls if they failed because they tried to fetch metadata for relative url. Some tests open the link popover near the end, thus passed sometimes (when the test ended before the fetch error). These tests were also adapted in 06263227eb59ce0e0be2416d794ce50f907e1413. But the indeterminism that lead them to pass was not fixed (because of uncertainty about the correct appraoch) The tests failed sometimes because the metadata fetch is triggered in the `onMounted` of the link popover, which does not happen if the component is cancelled before it is rendered task-4367641
This update fixes an issue in Point of Sale where reducing an unsynced item's quantity to zero used an outdated internal action. Cashiers can now remove such items reliably, helping avoid interruptions during sales.
Original PR description
Before this commit, we were calling _unlinkOrderline on the order when decreasing the quantity of an unsynced line to 0 from the decreaseQuantityPopup. This method does not exists anymore so we replace this call with a call to removeOrderline. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218795
The website editor’s header formatting controls now have clearer spacing, and the text alignment dropdown is easier to use. This makes it simpler for users to choose the right alignment option when editing website headers.
Original PR description
Before this commit, the display of the text alignment dropdown was small, making it harder to select the desired option. There was also no space between the 3 formatting options for the header (font size, text color, alignment). This commit re-adds the spacing and makes the dropdown items the same size as other dropdown items from the edit sidebar. task-4367641
This fix reduces the clickable area of padding controls in the HTML builder so they no longer get in the way when editing button text. Users can now more easily select and update text such as the “Contact Us” button while the padding controls remain usable and accessible.
Original PR description
Before this commit, the handlers for the padding option were too big, which made it really hard to click on the text of the "Contact Us" button (the focus would be on the handlers instead). This commit reduces the size of the clickable area around the handlers icons, enabling to edit the text of the "Contact Us" button, while keeping the handlers large enough to be accessible. task-4367641
Calendar views that support creating multiple records now always show the sidebar, even if a user previously hid it in another calendar. This prevents users from getting stuck without access to required sidebar actions in those views.
Original PR description
The sidebar can be toggled in calendar views where the multi create feature isn't enabled. The toggled status is then stored in the session_storage s.t. when coming back, it is restored. In calendar views with the multi create feature, the sidebar can't be toggled: it is always displayed. Before this commit, if the user first went to a "normal" calendar view, toggled off the sidepanel, and then went to a calendar view with multi_create, the sidepanel wasn't displayed (and there was no way for him to toggle it in that view). This commit fixes the issue: when the multi_create feature is enabled, the sidepanel must always be displayed, no matter the state saved in the session_storage. 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#219040
Pop-up elements such as date pickers now close automatically when users move between pages, including with the browser back or forward buttons. This prevents old popovers from lingering on screen and improves the overall navigation experience.
Original PR description
Before this commit, popovers like the datepicker remained open when navigating between pages, using the browser's previous/next page button for example. In this commit, popovers listen to page changes and are closed when such events are detected. Task 4812869 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217148
This update adjusts some internal message text formatting so Odoo's translation tools work reliably on Ubuntu Jammy. It helps prevent automated build failures without changing business workflows or user-facing features.
Original PR description
On Jammy, babel does *not* cope well with f-strings as values inside `_()` calls: it uses `eval` to try and figure them out, which attempts to execute the f-string, which fails because the evaluation context is empty. This is likely fixed from Babel 2.11 onwards (python-babel/babel#915) but Jammy uses babel 2.8[^1]. https://runbot.odoo.com/odoo/runbot.build.error/97849 [^1]: This doesn't seem to trigger on Noble even though it uses 2.10, but locally it does trigger on 2.10.3 (installed via pip), so ubuntu might have backported the fix or something. Forward-Port-Of: odoo/odoo#218887 Forward-Port-Of: odoo/odoo#218803
Regular users can now filter email templates by category without hitting an access error. This keeps the template selection flow working smoothly when sending emails from documents such as sales or purchase orders.
Original PR description
Since commit 42be7cebc84ac4af36104b6d2eba9d3e5d115005, filtering mail templates on their category triggers a search on `ir.model.data` to avoid a memory error on a database having a lot of mail…
Since commit 42be7cebc84ac4af36104b6d2eba9d3e5d115005, filtering mail templates on their category triggers a search on `ir.model.data` to avoid a memory error on a database having a lot of mail templates. However, regular users don't have a read access to this model, so when a user tries to filter on the template category, they get an `AccessError`. With this commit, we add a `sudo()` on the search on `ir.model.data`, so that this error doesn't occur any more. To reproduce the issue on a runbot, follow these steps: - connect as *demo* on a 18.0 database - open a *Sale Order* or a *Purchase Order*, and click on *Send by email* - in the modal dialog, click on the vertical three dots to select a template - if *Search More...* is not available, save the template several times with different new names until *Search More...* appears on the list - click on *Search More...* - in the *Search...* field, click on one of the *Base Templates* or *Custom Templates* filters - boom! `Access Error, You are not allowed to access 'Model Data' (ir.model.data) records.` Forward-Port-Of: odoo/odoo#219034
Highlighted title text with animation now keeps animating correctly when the page is viewed on smaller screens and the text wraps onto multiple lines. This prevents broken visual effects on published website pages, improving consistency for visitors and editors.
Original PR description
Steps to reproduce: 1. Go to Website (Edit mode) and drop a title block. 2. Select the title and set a highlight effect, then a text animation on it, and save the page. 3. Load the page in a reduced viewport in a way that makes the highlighted text split into multiple lines. 4. The animation won't work. The issue is caused mainly by the highlights being automatically split (and also the animation wrapper inside) when there is no available space for the text content, which destroys the "animation" interaction targeted element without retargeting the new wrappers. The goal of this commit is to fix this behavior by forcing the animation to target the whole highlight when a part of its content is animated. opw-4865891 Forward-Port-Of: odoo/odoo#218445
This update corrects accounting demo data so reconciliation models are linked to the proper suspense account instead of the liquidity account. It helps demo environments better reflect the intended accounting workflow and avoids confusing reconciliation behavior after use.
Original PR description
Correcting some demo data where they added the reconcile model on the liquidity but since the reco model will be added at the creation of the reco model, that's not needed. Also the reco model should be put on the suspense and not on the liquidity task: 4908501 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#216902
This fix stops users from creating recruitment stage email templates without the required linked model. It prevents errors when moving applicants into stages that use those templates, making the hiring workflow more reliable.
Original PR description
An error occurs when a user quickly creates a template for a stage, bypassing the validation of the `Applies to` field. As a result, an error is triggered when the user selects a stage that uses that template. **Steps to reproduce:** * Install `hr_recruitment` * hr_recruitment>Configuration>Stages>stage named `New`>Quick Create a mail template with random name and save. * Applications>All Applications>New application>Set stage to `New` `KeyError:False` **Solution:** * Disable quick create as to prevent creating mail templates with empty model ids. **Sentry-6675399135** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#214195
The asset depreciation schedule now opens correctly when draft assets do not yet have generated journal entries. This prevents an error that could block users from reviewing planned depreciation information.
Original PR description
Issue: https://github.com/odoo/odoo/issues/219112 Steps to reproduce:- - Minimum 1 asset in draft - Computation board not computed yet - Opening the depreciation schedule with draft entries. Cause:- - When asset is in draft and computation board is not computed yet no Journal Entries are created for that asset. - `asset_date` is minimum value among dates of related moves. - In this case there are no moves yet so `asset_date` is 'NoneType' - `asset_date = min([asset_date, move_vals['date']])` - In above line when we try to compare 'datetime.date' and 'NoneType' it gives rpc error. Fix: `min([asset_date, move_vals['date']]) if asset_date else move_vals['date']` Followup on commit: https://github.com/odoo/enterprise/commit/eb57a9bc4066ece08059384742d70705a646bbdc Forward-Port-Of: odoo/enterprise#90308
Deleting a field match in a spreadsheet global filter is now properly saved. This prevents users from seeing removed filter settings reappear after saving, making spreadsheet filter configuration more reliable.
Original PR description
Steps to reproduce: 1. Open a spreadsheet with global filters. 2. Open the global filter editor. 3. Open a global filter. 4. Delete the field matching (and nothing else). 5. Save the global filter. => The field matching is not saved. This was due to the fact that the removal of the field matching makes an early return in the `updateFieldMatching` method, which had for last instruction to set the `draft` property to mark the filter as dirty. This commit fixes the issue by ensuring that the `draft` property is set even when the field matching is removed. Task: 4882261 Forward-Port-Of: odoo/enterprise#89621
Helpdesk reporting now avoids using report-only filters when opening the underlying ticket list from a chart. This prevents errors when users click bars in Ticket Analysis and makes drill-down reporting more reliable.
Original PR description
Step to reproduce - Go to helpdesk - Go to Reporting > Ticket Analysis - Group by `Ticket` - Click on any of the blue bars Issue: since odoo/enterprise@d64db03f we now allow user to drill down to base model from report view, this causes issue when a field which is present in report model but not in base/main model. For now we directly pass the domain created for report view to base model. FIx: we remove such fields from domain and then load the view opw-4798353 related: https://github.com/odoo/odoo/pull/215167 Forward-Port-Of: odoo/enterprise#88356
This update ensures the admin user has an email address during quality control worksheet test runs. It prevents a sender email configuration error, making automated checks more reliable without changing day-to-day product behavior.
Original PR description
Set the admin user's email explicitly to prevent "Please configure the sender's email address" error when running the tour with login='admin'. build_error-226779 Forward-Port-Of: odoo/enterprise#88283
The IoT setup process now updates an existing IoT box record only when the incoming information has actually changed. This reduces needless database writes and helps keep setup activity cleaner without changing user-facing behavior.
Original PR description
Currently when /iot/setup method is called if the iot box record exists we always update the record with the received data, even if the data is the same as the record's data. This PR only updates it if the data changes Forward-Port-Of: odoo/enterprise#88210 Forward-Port-Of: odoo/enterprise#88043
To Reproduce: ============= - add contact with empty street2 - create invoice - generate pdf from invoice --> blank line Problem: ========= -The _compute_display_name method concatenates address fields using newline characters (\n). -When some address components (like street2) are empty, this results in multiple consecutive newlines (\n\n), producing blank lines in the rendered display name and PDF reports. https://github.com/odoo/odoo/blob/saas-18.3/odoo/addons/base/models/res_partne
Original PR description
To Reproduce: ============= - add contact with empty street2 - create invoice - generate pdf from invoice --> blank line Problem: ========= -The _compute_display_name method concatenates address fields using newline characters (\n). -When some address components (like street2) are empty, this results in multiple consecutive newlines (\n\n), producing blank lines in the rendered display name and PDF reports. https://github.com/odoo/odoo/blob/saas-18.3/odoo/addons/base/models/res_partner.py#L990 Solution: ========== filtering out empty or whitespace-only lines, and joining them back properly. opw-4820829 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#213923
**Current behavior before PR:** When the chatbot redirects a visitor to a webpage on mobile, the chat window remains open, covering the redirected page. Making it difficult for the visitor to interact with the redirected page. **Desired behavior after PR is merged:** The conversation is automatically folded when the chatbot redirects a visitor to a webpage on mobile. **Task**-4630719 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward
Original PR description
**Current behavior before PR:** When the chatbot redirects a visitor to a webpage on mobile, the chat window remains open, covering the redirected page. Making it difficult for the visitor to interact with the redirected page. **Desired behavior after PR is merged:** The conversation is automatically folded when the chatbot redirects a visitor to a webpage on mobile. **Task**-4630719 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#201132
Previously, when multiple form snippets were added to the same page or a form snippet was cloned, corresponding fields (e.g., the "Name" field) in each form were assigned the same ID. This issue stemmed from three distinct scenarios: 1. Forms from Static Templates: The default form snippet (with "Send an E-mail" action) used a template with hardcoded field IDs. As a result, inserting the snippet multiple times led to duplicate field IDs. 2. Forms from the registry: For t
Original PR description
Previously, when multiple form snippets were added to the same page or a form snippet was cloned, corresponding fields (e.g., the "Name" field) in each form were assigned the same ID. This issue…
Previously, when multiple form snippets were added to the same page or a form snippet was cloned, corresponding fields (e.g., the "Name" field) in each form were assigned the same ID. This issue stemmed from three distinct scenarios: 1. Forms from Static Templates: The default form snippet (with "Send an E-mail" action) used a template with hardcoded field IDs. As a result, inserting the snippet multiple times led to duplicate field IDs. 2. Forms from the registry: For the form snippet with other actions (e.g., "Apply for a Job", "Create a Customer", "Create a Task", etc.), fields are fetched from `form_editor_actions` registry. For the first form, unique IDs are generated and assigned to the fields but was also mutating the fields stored in the registry. When the second form with the same action was added, the fields it recieved from the registry already had an ID, causing the ID generation logic to skip and the old IDs were reused. 3. Cloning Forms/Fields: When the entire form or just field was cloned, the fields were copied from the original form snippet, which also resulted in duplicate IDs. This commit resolves these issues by: - Generating new ID for the fields when the snippet is inserted on the page. - Additionally, we now create a shallow copy of each field before using it. This prevents the original field definitions in the `form_editor_actions` registry from being modified. - Re-rendering fields when forms or individual fields are cloned, ensuring that newly cloned elements get fresh IDs. These changes ensure that all form fields on a page have unique IDs. [task-4251881](https://www.odoo.com/web#id=4251881&cids=1&menu_id=4720&action=333&active_id=1695&model=project.task&view_type=form) Forward-Port-Of: odoo/odoo#214954 Forward-Port-Of: odoo/odoo#183883
[IMP] industry_fsm: use MockRequest to fake geoip In this commit: - MockRequest is used to fake geoip in industry_fsm tests instead of hard coding it with DotDict and manipulating the _request_stack. - space added before "View on Map". task-4745995 Forward-Port-Of: odoo/enterprise#84322
Original PR description
[IMP] industry_fsm: use MockRequest to fake geoip In this commit: - MockRequest is used to fake geoip in industry_fsm tests instead of hard coding it with DotDict and manipulating the _request_stack. - space added before "View on Map". task-4745995 Forward-Port-Of: odoo/enterprise#84322