Daily updates from Odoo
Friday, July 17, 2026
21 changes · master
Security fixes and vulnerability patches
This change prevents database API keys from being exposed through regular application access or accidentally shown in the user interface. It reduces the risk of sensitive credentials being leaked during normal use, including screen sharing or streaming.
Original PR description
The aim of this commit is to harden the security of the `database_api_key` field. Before this commit: The field could be retrieved through the orm and could be leaked if the access rights were bypassed. A streamer pasting the key in the field could also leak his api key by mistake. After this commit: The only way to access the field is through direct SQL access. The api key isn't shown anymore in the UI: - The UI doesn't receive the key from the backend: it receives dummy **** - The field in the form view display dots instead of any char to prevent leaking the key by mistake. Task-id: None Forward-Port-Of: odoo/enterprise#124277 Forward-Port-Of: odoo/enterprise#122163
Enhancements to existing features
Saudi Arabian currency rate updates now use the Saudi Central Bank as the dedicated source instead of the default xe.com provider. This improves alignment with official SAR exchange rates and avoids duplicate rate entries when several days of data are returned.
Original PR description
Added a new exchange rate provider for the Saudi Central Bank (SAMA) to fetch official SAR exchange rates. Saudi Arabia is removed from the xe.com default and mapped to this dedicated provider instead. Since the API response includes multiple days of data, duplicate currency entries are deduplicated by keeping the first (most recent) occurrence of each currency code. task-4422561
Customer notes now appear as warnings on billable helpdesk tickets and field service shift forms. This helps service teams see important sales or customer information before working on a ticket or scheduled visit.
Original PR description
- When there is a note on a customer, display it as a warning: - in the ticket form view, if the team is billable - shift form view - move `use_helpdesk_sale_timesheet` from `helpdesk_sale_timesheet` into `helpdesk_sale` --- Task-4910696
This improvement creates redirects from old product links to their new Odoo product pages when moving from another ecommerce platform. It helps businesses retain SEO value and avoid broken product links after transferring an old domain.
Original PR description
When switching from an ecommerce platform to another, a major issue is that all the links to your products change and so all of the SEO linked to those product links are lost. One way to mitigate this issue is to create redirects for each products. Once the old domain is transfered, the old product links are restored and redirect to the corresponding odoo products.
Obox remote debugging can now be enabled directly from the Obox form instead of asking customers to visit a special device URL. This makes support sessions easier to start by letting users provide the required Tailscale token in Odoo.
Original PR description
Before this commit, enabling remote debug for an Obox required accessing a specific URL on the Obox, which might be difficult to instruct clients to do. After this commit, there is a Remote Debug toggle in the Obox form view, just like the IoT box. A user simply needs to provide the Tailscale token to enable remote debug. task-6392868
The paid appointments module no longer creates a default booking fee product during installation, keeping databases cleaner for businesses that do not use paid appointments. A booking product is now created only when needed for paid appointment types, and unused unsold booking products can be removed.
Original PR description
# Purpose Installing the module "appointment_account_payment" creates a default product called "booking fees" used in paid appointment type. This auto-creation pollutes the DB of users that never uses such appointment types. Furthermore, the product couldn't be deleted once created. # Specs - Removed the creation of a default booking product upon module installation. - On the creation of a paid appointment type, will create a default product ready for edition by the user. - On manual checkbox activation, a product with a default price can be created through the dropdown menu. - Unused booking product that haven't been sold can be deleted. Task-6167887
Users can now apply common reconciliation actions to multiple selected bank statement lines at once. This reduces repetitive work by letting teams use the main action, assign partners, or set account numbers across several records in one step.
Original PR description
Added actions for multi select of bank statement lines in the list view to: - Use the primary action of all of the selected records - Set the partner for all of the selected records - Set the account number for all of the selected records task-6102308
Deleting an attachment linked to a document now moves the document to the Trash instead of removing it permanently. This protects business documents from being lost when attachments are deleted from related records such as vendor bills or chatter messages.
Original PR description
We replace the `documents.unlink.mixin`, which was previously applied only to specific models, with a generic mechanism that works regardless of the involved models. This new mechanism archives the…
We replace the `documents.unlink.mixin`, which was previously applied only to specific models, with a generic mechanism that works regardless of the involved models. This new mechanism archives the documents when their attachments are deleted, preventing their deletion. It does a little more than the mixin as the mixin was preveting the deletion of the document only when a record sharing a common attachment was deleted. Here, we also preserve the document if the attachment is deleted directly (for example from the chatter of a record). In that case, we also preserve the link between the document and the record (through the res_model and res_id of the document record). This change is motivated by use-cases similar to the following: - In document, click on the action "Create Vendor Bill" - On the chatter of the account.move, delete the attachment - Return to Documents Before, the document was deleted. Now, it has been moved in the Trash. To implement that feature, we remove the "ondelete cascade" on the attachment_id field of document and implement a custom version of it that move the associated documents (if any) in the Trash. Thanks to the api.ondelete decorator, we intercept all attachment deletion and if some of them are linked to a document we copy them and associate their copy with the documents before they are deleted. Note that the copy is cheap as odoo implements a deduplication of the store (see IrAttachment._file_write). Notes that we first have tried to preserve the attachment instead of duplicating it. But it was breaking other flow as they were expecting the attachment to be deleted. For example, when deleting a message with an attachment in the chatter, as the attachment was preserved it was still linked to the message even if it was not anymore directly linked to the model (ex.: lead) through res_model, res_id which caused the attachment to still appear in the chatter. Co-authored-by: Florian Charlier <flch@odoo.com> Task-5155496
Resolved issues and error corrections
Employees can now access and sign signature requests sent to their private email address. The request remains linked to the employee’s existing contact record, avoiding access problems while still delivering the email to the private address.
Original PR description
Before, when a signature request was sent to an employee's private email address, a new partner was created with the private email address and the signature request was linked to that new partner. Since there is a security rule where an employee cannot access a sign request item unless the partner on it matches partner for that employee, the employee is not able to see the sign request as the linked partner to the sign request item is an entirely new partner that is not linked to the employee. To fix the issue, the sign request is now linked to the employee's partner but the email itself is sent to the employee's private email. Task-5358107
Fixes translation-related issues in accounting screens so users see consistent guidance and correctly ordered labels in their chosen language. Bank Matching now keeps the same empty-state help after reloads or language changes, and the fiscal year wizard can use natural wording in languages such as French.
Original PR description
The empty-state message in Bank Matching differs depending on how the view was reloaded. In particular, after changing language from inside the view, the message loses the sentence explaining that users can create or import bank transactions. Ensure the Bank Matching empty-state help remains consistent across all reload flows. --- The fiscal year setup wizard was building the tax periodicity label from two separate translated parts. This produces an incorrect word order in some languages, such as "TVA Périodicité" in French which is supposed to be "Périodicité TVA". Use a single translatable label instead, so translations can place the tax label where it belongs in the sentence. task-6265141
This fix ensures the Avalara tax connection is disabled when a database is neutralized, such as in test or copied environments. It helps prevent those environments from accidentally connecting to the live tax proxy service.
Original PR description
Community: https://github.com/odoo/odoo/pull/272495
This change removes unused template markers from Helpdesk knowledge base search results and eCommerce subscription product pages. It prevents harmless backend warning messages during page rendering, keeping system logs cleaner without changing the customer-facing experience.
Original PR description
When rendering specific server-side pages (Knowledge Base search results and the eCommerce subscription product page), the Python QWeb engine logs the following warning:
"Unknown directives or unused attributes: {'t-key'} from..."
The `t-key` attribute is an OWL-specific directive required for client-side `t-foreach` loops. It is not recognized by the backend Python QWeb engine and serves no purpose in server-rendered templates.
This commit removes the inert `t-key` attributes from these Python-rendered templates.
task-6385543Automatic bank reconciliation now retries failed statement lines once before discarding them. This helps avoid losing reconciliation work when temporary system issues, such as database conflicts, cause a failure.
Original PR description
The auto reconcile cron drops the lines whenever they raise an error which is an issue for things like serialization errors. Now the code retries failed lines once before dropping them to make sure it's an issue with the lines. task-6273202 Forward-Port-Of: odoo/enterprise#119383
This fix ensures Belgian payroll eco vouchers are calculated using the correct start and end date boundaries. It helps avoid incorrect voucher amounts for employees whose eligibility depends on precise payroll period dates.
Original PR description
Forward-Port-Of: odoo/enterprise#124073 Forward-Port-Of: odoo/enterprise#120166
This fix makes map pin popovers open reliably after selecting a record from the pin list. It removes a timing issue that could cause the popover to disappear unexpectedly during automated mobile testing, improving stability without changing user-facing behavior.
Original PR description
Clicking a record in the "PinList" opens a marker popover. Until now this was handled by `centerAndOpenPin`, which closed the pin list popover and then, after two `delay(0)`, centered the map and…
Clicking a record in the "PinList" opens a marker popover. Until now this was handled by `centerAndOpenPin`, which closed the pin list popover and then, after two `delay(0)`, centered the map and opened the marker popover. This was racy. Closing `pinListPopover` triggers a re-render of the view, during which all markers are removed and re-added. If that re-render happened after the popover was opened, the marker element the popover was anchored to no longer existed, and the popover closed itself through `Popover.onTargetMutate()` (which closes the popover when its target element leaves the DOM). Depending on timing, the popover would sometimes be destroyed right after being opened, making the test flaky and leaving no popover open in the browser. To fix this, `centerAndOpenPin` is split in two parts: * it now only closes `pinListPopover` and raises a `shouldOpenMarkerPopover` flag; * on the next `onPatched`, once the markers have been re-rendered, the new `centerAndOpenPinOnPatched` method centers the map on the marker and opens the popover. Opening the popover after the re-render guarantees the marker element is present, removing the race condition. runbot-error-944199
This fixes an issue where opening a Belgian Dimona declaration could fail if an employee's private street information was missing. The change ensures payroll users can continue the declaration process without an unexpected error.
Original PR description
action_open_dimona guards on `self.employee_id.private_street` but then runs re.findall on `self.private_street` Forward-Port-Of: odoo/enterprise#124029
New planning slots now use the company’s working hours in the company timezone, so default start and end times appear correctly. This prevents schedule entries from being shifted by timezone differences when no resource is selected.
Original PR description
Issue: ---------------------------------------- When creating a new slot, no resrouces are set so we use the calendar of the company but the hours are offset because of the timezone. Steps to reproduce: ---------------------------------------- - Have planning Installed - Have an hour based calendar, from 8 to 16 each day for example - Have the company timezone in UTC+2, same for you the user - Go in Planning "Schedule By Resource" view - Click "New" - The default start and end time are 10am and 6pm (2h offset) Cause: ---------------------------------------- `default_get()` calls `_company_working_hours()` to get the company calendar hours. But they are returned in UTC, so when displaying them they are converted to the user timezone and are offsetted. Solution: ---------------------------------------- `_company_working_hours()` should return the compny hours in the company timezone. opw-6333993 Forward-Port-Of: odoo/enterprise#123033
Code cleanup and technical improvements
The grid view was updated to use the newer interface expected by the latest Odoo web framework. This keeps keyboard navigation and time entry behavior working reliably while reducing reliance on outdated internal code.
Original PR description
Replaced `useLayoutEffect` with `signal.ref` + `useEffect` && `onMounted()` + `onPatched()` && `useListener` because `useLayoutEffect` is deprecated in OWL3. The useLayoutEffect refactored in this PR had test coverage — below are some tests that failed when the effect was commented out, and are now passing: - @web_grid/grid_view/grid_view_desktop/Edition navigate with tab/shift+tab and enter key - `@web_grid/grid_view/grid_view_desktop/Edition navigate with tab/shift+tab and enter key` - `@web_grid/grid_cells/float_time_grid_cell/FloatTimeGridCell in grid view` see commented-out runbot build: https://runbot.odoo.com/runbot/batch/2624598/build/116553722 see commented-out runbot build: https://runbot.odoo.com/runbot/batch/2624595/build/116553684
This update simplifies internal test setups for sales and rental flows, making them easier to maintain. It also starts aligning some tests with standard salesperson permissions, helping ensure checks better reflect typical day-to-day usage.
Original PR description
Simplify specs, and start converting some tests to run with standard salesmen rights.
Obox report printing now uses Odoo's shared printer setup for report output, aligning it with other printer types such as ePOS, Zebra, and IoT. This should make printer management more consistent and reduce duplicate Obox-specific printing logic over time.
Original PR description
This commit adapts the Obox report printing to use the new report printing system, the common printer model for ePOS/Zebra/IoT. The Obox is added as a printer type, and the old Obox report logic removed. task-6328971 Community PR: https://github.com/odoo/odoo/pull/272451
This change updates several Odoo Enterprise screens and components to use the supported OWL3 lifecycle approach instead of a deprecated method. It helps keep the platform maintainable and compatible with newer frontend framework versions while preserving existing behavior when screens open and close.
Original PR description
useLayoutEffect is deprecated in OWL3, so replace the calls that used an empty dependency array (run-once-on-mount) with the native OWL3 lifecycle hooks onMounted and onWillUnmount. Effects that returned a cleanup function have their teardown moved into onWillUnmount so the unmount behaviour is preserved. Community PR: https://github.com/odoo/odoo/pull/276619