Daily updates from Odoo
Friday, July 3, 2026
17 changes · saas-18.3
Resolved issues and error corrections
This update resolves a technical problem that could have caused incorrect updates to French tax reporting data. The fix prevents a query from failing when a specific date field was empty, ensuring accurate tax calculations and reporting for French businesses using the Odoo platform. This improves the reliability of our French tax compliance features.
Original PR description
Fixes _force_update_l10n_fr_f10_moves(). It would create a SQL query that compares a date to a bool when _pdp_get_flow_10_start_date() returned None. Forward-Port-Of: odoo/odoo#273006
This update fixes an issue where URL suggestions in the Notes app overflowed on smaller mobile devices. The fix adjusts the layout of the suggestion container to ensure it adapts to different screen sizes, providing a cleaner and more usable experience for users.
Original PR description
Step to reproduce: - Open Notes - Open the link popover - Type a URL in the URL input field Description of the issue/: - On mobile devices, URL autocomplete suggestions overflow the viewport. Cause: - The autocomplete suggestions container has a max-width of 600px. - On smaller screens, the container does not shrink to fit the available width, causing it to overflow the viewport. Solution: - Add width: 100% to the autocomplete suggestions container so it adapts to the available screen width on smaller devices while still respecting the existing max-width on larger screens. task-6201175 Forward-Port-Of: odoo/odoo#269493
This update fixes an issue where customer addresses were excessively long in form view titles and breadcrumbs, making them difficult to read. The change ensures that only the customer's name is displayed, aligning with how other fields are handled, resulting in a cleaner and more user-friendly navigation experience.
Original PR description
- Create a new Invoice; - Assign a Customer with a multiline address; - Click on the internal link (arrow icon) of the Customer field. Before this commit, the form view title and the breadcrumb would contain not only the customer's name but also their full address. This resulted in an excessively large and unreadable breadcrumb. Now, only the name is retained. This commit applies the same behavior already used in many2one fields: the display name is split by line breaks, and only the first line is kept for the title and breadcrumb. task-id 6329662 Forward-Port-Of: odoo/odoo#272550 Forward-Port-Of: odoo/odoo#272059
This update fixes an issue where the Intrastat report was incorrectly cropping the bill name, preventing full visibility of key information like the hyphenated identifier. The fix adjusts a regex pattern to allow hyphens in bill names, ensuring accurate display of all bill details in the report.
Original PR description
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] *…
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] * Intrastat Country: [any] * Intrastat Transport Mode: [any] - Confirm the bill - Make sure that the bill name contains a hyphen character (i.e. "-") For example, "BILL/2026-06/0001". Use the "Resequence" action from the bills list view if needed. - Go to "Accounting / Reporting / Audit Reports / Intrastat Report" - Expand the line to display the bill name **Issue:** The bill name is not fully displayed. It is cropped right before the hyphen character (i.e. BILL/2026). **Cause:** A regex is used to retrieve the bill name from the report line name, but it is only allowing "/" character. **Solution:** Just allow "-" character in addition. No other character is allowed to limit the risk of matching something that should not. opw-6299854 Forward-Port-Of: odoo/enterprise#120979
A technical issue prevented users from previewing the '2Fa New Login' template. This was caused by an assertion error triggered when the preview environment wasn't running with elevated privileges. The fix replaces the assertion with a conditional check that returns placeholder data, allowing the preview to function correctly.
Original PR description
Issue: ---------------------------------------- Clicking "Preview" on the template "2Fa New Login" causes an error. Steps to reproduce: ---------------------------------------- - Search for the mail template "Settings: 2Fa New Login" - Click "Preview" - Error in terminal - From 17.0+ the error shows in UI - From saas-18.3+, a traceback occurs whe resetting the template Cause: ---------------------------------------- There is an assert the method `_get_totp_mail_code()` to ensure it's used during 2FA. But when passing by rendering this template in preview we aren't in sudo and the assert in `_get_totp_mail_code()` raises. Solution: ---------------------------------------- We replace the `assert` by a `if` which will return fake results. opw-6333887 Forward-Port-Of: odoo/odoo#273505 Forward-Port-Of: odoo/odoo#273125
This update fixes an issue where users weren't receiving notifications when a sign request was completed after they selected 'Handle in Odoo' (inbox) for notifications. The change ensures that the sender receives a notification, improving transparency and workflow efficiency for sign requests. This was a bug impacting the sign process.
Original PR description
## Issue When a user sets their notification to "Handle in Odoo" (`inbox`) and a sign requested is completed, they do not receive the expected notification. ## Steps to reproduce 1. Install *Sign*…
## Issue When a user sets their notification to "Handle in Odoo" (`inbox`) and a sign requested is completed, they do not receive the expected notification. ## Steps to reproduce 1. Install *Sign* (`sign`) 2. Sets the current user's notification preference to "Handle in Odoo" (`inbox`) 3. Create a sign request and send it to Marc Demo 4. As Marc Demo, sign the request 5. **The user who sent the sign request did not receive a notification to notify them that the request was signed.** ## Fix This is a partial backport of both https://github.com/odoo/enterprise/commit/463d6a2aae536356e6dee6b902f2e881dbc4fbda (saas-18.2) and a related fix https://github.com/odoo/enterprise/commit/41395dba4fd31222f5fd9fc94a84c977cf9334f9 (19.0). Before the first commit, users would not receive inbox notification when sign requests would be completed. ## Note to reviewer The issue only occurs in 18.0, as it is fixed by https://github.com/odoo/enterprise/commit/463d6a2aae536356e6dee6b902f2e881dbc4fbda in 18.2, but we can backport the fix from https://github.com/odoo/enterprise/commit/41395dba4fd31222f5fd9fc94a84c977cf9334f9 from 18.2 to 18.4 if desired. opw-6251702 Forward-Port-Of: odoo/enterprise#122519 Forward-Port-Of: odoo/enterprise#120740
This update resolves an issue where server reloads triggered by file changes could cause the application to crash. The fix prevents a series of signals from interrupting the server's restart process, ensuring stability and preventing service interruptions during updates. This improves the reliability of the Odoo server.
Original PR description
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP`…
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP` into `KeyboardInterrupt`, which `ThreadedServer.run()`'s wait-loop catches. The catch is too narrow — a reload `SIGHUP` can kill the process through **three** windows that all sit outside the wait-loop's `try/except`, so the exception escapes `run()`/`main()`. Under Docker's default `restart: no`, PID 1 dies and the container stays down. ### The three windows 1. **Teardown duplicate (exit 130).** One file change can emit several FS events; the FSWatcher's `if not odoo.phoenix:` dedup races across threads and fires more than one `SIGHUP`. The first begins the phoenix teardown; the second lands during `stop()` / `watcher.stop()` / `_reexec()` and `KeyboardInterrupt` escapes. 2. **Exec-gap (exit 129).** `os.execve()` resets caught signal handlers to their default disposition (`SIGHUP` terminates) but preserves `SIG_IGN`; a `SIGHUP` arriving after the exec but before the re-exec'd process re-installs its handler kills the process outright. 3. **Startup (exit 130).** In the re-exec'd process, a `SIGHUP` anywhere in the startup section that precedes the wait-loop — `start()`, `preload_registries()` **and** `cron_spawn()` — escapes `run()`. ### Reproducer (deterministic) Boot a `ThreadedServer` (`--workers 0`) on any initialised db, then signal PID 1 a few times in quick succession: ```bash docker exec <container> sh -c 'i=0; while [ $i -lt 8 ]; do kill -HUP 1; sleep 0.1; i=$((i+1)); done' ``` Unpatched the process exits 130 or 129. Patched it stays up after one clean phoenix reload. Verified live on 17.0 and 18.0: stock `server.py` dies; the patched `server.py` survives sustained bursts (20/20 across repeated reload cycles on each version); `SIGINT`/`SIGTERM` still exit 0. ### Fix Minimal, in `signal_handler` + `run()` + `_reexec()`; `SIGINT`/`SIGTERM` untouched; one new instance attribute, no new module globals: - **Teardown duplicate:** ignore a `SIGHUP` once `quit_signals_received` is set (a restart/shutdown is already pending; the re-exec reloads fresh code). - **Startup:** a per-instance `in_preload` flag marks the entire startup section (`start()` + `preload_registries()` + `cron_spawn()`); a `SIGHUP` there sets the phoenix flag + counter and returns instead of raising, so the wait-loop exits right after startup and runs the normal restart. - **Exec-gap:** `signal.signal(signal.SIGHUP, signal.SIG_IGN)` just before `os.execve` so a `SIGHUP` in the gap is dropped rather than terminating the process. ### Related - #21209 (merged) — introduced the phoenix flag; did not guard these windows. - #206898 (merged), #207930 (open) — PreforkServer reload. ### CLA Covered by Codeforward B.V.'s corporate CLA; #269240 adds me to its contributor list (pending merge). Forward-Port-Of: odoo/odoo#269247
This update resolves a rare technical problem within the Odoo web interface that could occasionally cause a test to fail. The fix ensures that popovers are properly closed, preventing errors that arise when components are destroyed during the testing process. This improves the stability of the web application.
Original PR description
Add an extra step to close the popover and prevent the `Component is destroyed` error[1], which can happen during hoots cleanup, similar to the issue we see when some dialogs perform RPCs as they are being destroyed. [1]: https://runbot.odoo.com/runbot/build/115972540 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273396 Forward-Port-Of: odoo/odoo#273085
This update fixes an issue where new time off requests were incorrectly showing a duration of 0 days due to an automation rule. The fix ensures the leave duration is accurately calculated from the requested dates, regardless of automation activity creation. This prevents incorrect time off calculations and reporting.
Original PR description
Current behavior: -- With an active automation rule (base_automation) whose action creates an activity (e.g. a "Time Off Approval" activity) on hr.leave creation, every newly created time off request…
Current behavior: -- With an active automation rule (base_automation) whose action creates an activity (e.g. a "Time Off Approval" activity) on hr.leave creation, every newly created time off request has a duration of 0 days / 0 hours, regardless of the requested dates. Expected behavior: -- The leave duration is computed from the requested dates, unaffected by the presence of an activity-creating automation rule. Steps to reproduce: -- - Create an automation rule on hr.leave, trigger "On Creation & Update". - Add an action that creates an activity (type "Time Off Approval"). - Create any time off request for an employee with a working schedule. - The request shows a duration of "0 days" (or "0 hours"). Cause of the issue: -- date_from/date_to and number_of_days/number_of_hours are stored compute fields the duration (number_of_days/number_of_hours) depends on the dates (date_from/date_to). The rule's action creates a mail.activity whose notification renders the leave's display_name. Computing display_name pulls in dashboard_warning_message, which re-enters _compute_date_from_to. Inside that in-progress compute, _compute_duration is evaluated while date_from/date_to are still False in the ORM cache, so _get_durations returns (0, 0). The dates are correct afterwards, but the duration was already computed and stored as 0, and nothing in the create flow re-triggers its compute, so a stale 0 is persisted to the database (it is only recomputed if a dependency such as the request dates or leave type is later modified). Fix: -- Once date_from/date_to are settled at the end of _compute_date_from_to, add the duration fields (number_of_days, number_of_hours, duration_display) back to the compute queue so they are recomputed against the correct dates. opw-6235902 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue preventing users from modifying a product's Bill of Materials (BOM) type when sales orders are already linked across multiple companies. Previously, the system prevented changes to ensure data integrity. Now, users can safely adjust BOM types, maintaining accurate sales order fulfillment and inventory management within a multi-company environment.
Original PR description
### Steps to reproduce: - Have two companies: company1 and company2 - Create a producct P available in both company1 and company2 - with company1, create a kit bom for a product P - with company2,…
### Steps to reproduce: - Have two companies: company1 and company2 - Create a producct P available in both company1 and company2 - with company1, create a kit bom for a product P - with company2, create and confirm a sale order for 1 unit of P - with company1, change the bom type of P from kit to manufature #### > UserError: As long as there are some sale order lines that must be delivered/invoiced and are related to these bills of materials, you can not remove them. ### Cause of the issue: Changing the bom type from a kit (phantom type) to a non kit will launch a call of the `_ensure_bom_is_free` in order to ensure data integrity if the kit bom was used by a relevant sale order line: https://github.com/odoo/odoo/blob/f4c76be062bec47b68ee42505d7d42fed31ac0f2/addons/sale_mrp/models/mrp_bom.py#L15-L18 https://github.com/odoo/odoo/blob/f4c76be062bec47b68ee42505d7d42fed31ac0f2/addons/sale_mrp/models/mrp_bom.py#L24-L42 However, this check does not take the company of the bom into account and in the present flow, the company of the bom is different from the company of the supposedly problematic sol. opw-6290304 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273486 Forward-Port-Of: odoo/odoo#271119
This update fixes an error in how timesheet revenue is calculated for prepaid services, ensuring accurate reporting. The previous calculation incorrectly accounted for day UoM rounding, leading to inflated revenue figures. This change now uses the correct per-unit rate, reflecting discounts and ensuring accurate revenue reporting for prepaid orders.
Original PR description
Steps to reproduce 1. Create a service product: Invoicing Policy = Prepaid/Fixed Price, Track Service = Timesheets, Unit of Measure = Days 2. Confirm a Sales Order with 2 days of that product at…
Steps to reproduce 1. Create a service product: Invoicing Policy = Prepaid/Fixed Price, Track Service = Timesheets, Unit of Measure = Days 2. Confirm a Sales Order with 2 days of that product at 800/day 3. Register 1 hour on the generated task 4. Open Timesheets > Reporting, add the "Timesheet Revenues" measure Issue `timesheet_revenues` in `timesheets.analysis.report` was computed per analytic line as `(SOL.price_subtotal / SOL.qty_delivered) * (unit_amount * sol_uom.factor / ts_uom.factor)` (https://github.com/odoo/odoo/blob/16f170619d9cc5fd86529a3f17e349da37607f73/addons/sale_timesheet/report/timesheets_analysis_report.py#L42-L44). `SOL.qty_delivered` is a stored float rounded to the day UoM precision (0.01d). For 1 hour timesheeted, qty_delivered = 1/8 = 0.125d rounds to 0.13d, so the formula yields (1600 / 0.13) × (1/8) = 1538.46 instead of the correct 100. Because `qty_delivered` is recomputed each time a timesheet is added, all existing rows shift their revenue figure with every new entry. Additionally, using `price_subtotal / qty_delivered` as the per-unit rate ignores any line discount: the rate derived from a discounted subtotal divided by a delivered quantity that differs from the ordered quantity is not the effective price per day. For prepaid lines, the effective per-unit rate is `price_subtotal / product_uom_qty` — the ordered quantity is stable and the subtotal already reflects any discount — multiplied by the timesheet hours converted to the SO line UoM. opw-6150555 Forward-Port-Of: odoo/odoo#272910 Forward-Port-Of: odoo/odoo#262524
This update fixes a usability issue in the invoice outstanding payments widget by sorting payments in descending order by date. This ensures users can easily see the most recent payments and reduces confusion when reviewing outstanding invoices. The change was driven by a user feedback request (opw-6254080).
Original PR description
Before this commit: The invoice outstanding payments widget was not sorted by date globally, which could lead to confusion for users when viewing the widget. After this commit: This commit adds a sorting mechanism to ensure that the payments are displayed in descending order based on their date and ID. opw-6254080
This update resolves an issue where the Sale Renting module wasn't properly connected to the Gantt view functionality. Previously, the module wouldn't display Gantt views correctly. This fix ensures compatibility and proper functionality for users relying on Gantt views within the Sale Renting module, aligning with recent improvements in Odoo 19 and later versions.
Original PR description
Module was introduced without a dependency on the `web_gantt` module despite using `gantt` views. Already fixed in 19+ runbot error 237883 Forward-Port-Of: odoo/enterprise#122136
This update fixes a technical issue where Odoo wasn't properly handling certificate chains. Now, Odoo correctly loads the full certificate chain, ensuring greater security and compatibility with external systems that require complete certificate validation. This improves the overall reliability of Odoo's secure connections.
Original PR description
Previously, only the leaf certificate was parsed when loading PEM-encoded data, ignoring any additional certificates in the chain. This change updates the loading logic to include the full certificate chain, ensuring proper integrity and compatibility with flows that require it. Useful for this PR: odoo/odoo#254906 Task [link](https://www.odoo.com/odoo/project.task/6053921) task-6053921 Forward-Port-Of: odoo/odoo#255100
This update ensures that several Odoo community add-ons (certificate, l10n_hr_edi, etc.) are correctly licensed under LGPL-3. Previously, these modules incorrectly used the enterprise license. This change aligns with the proper licensing for community-supported add-ons, clarifying legal obligations and ensuring compliance.
Original PR description
Before this commit, the license set on manifest of some modules uses the enterprise license instead of `LGPL-3` license since it is a community module. This commit changes the license to set `LGPL-3`. Fixes #205134 Forward-Port-Of: odoo/odoo#273690 Forward-Port-Of: odoo/odoo#273597
This update fixes an issue where the price of Point of Sale (POS) order lines wasn't correctly recalculated after a refund and quantity change. Specifically, when a refund was processed and the line quantity was adjusted, the price wasn't updated to reflect the fiscal position. This ensures accurate pricing and tax calculations during POS transactions.
Original PR description
When changing the quantity of a pos order line the fiscal position set on the order was not used when recomputing the line price and taxes. Steps to reproduce: ------------------- * Create a tax with 15% rate and another with 10% rate * Create a fiscal position that maps the 15% tax to the 10% tax * Setup a PoS to be able to use that fiscal position * Open the PoS, add a product with the 15% tax, set the fiscal position and validate the order * Refund the order in the backend and change the quantity of the line from -1 to 0 and back to -1. > Observation: The price is not the same as before Why the fix: ------------ The fiscal position was not applied when recomputing the line's price and taxes. opw-6253311 Forward-Port-Of: odoo/odoo#273366 Forward-Port-Of: odoo/odoo#270135
This update optimizes how Odoo forms respond to changes. Previously, opening a form triggered onchange methods multiple times for related field updates. This fix reduces redundant calls, leading to faster form loading and a smoother user experience. It's a small but important improvement for overall performance.
Original PR description
When an onchange method depends on several fields that all change at once (for example two fields that both have a default value), opening the form triggers that method once per field, even though a single call would suffice. This adds a per-pass set of already-applied onchange methods so that, within the same batch of changed fields, each method is invoked only once. Note this does not guarantee a method is called exactly once overall: it may still run again in later onchange passes; we only remove the redundant calls within a single pass. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#251813