Wednesday, October 15, 2025
20 changes · saas-18.3
Enhancements to existing features
Opening the analytic distribution popup on invoice lines with many analytic accounts now avoids unnecessary repeated data requests. This improves responsiveness for users working with detailed analytic allocations, especially on larger invoices.
Original PR description
Currently opening the analytic distrubtion popup on an invoice line creates N network requests per account set on the line. Steps to reproduce ----- 1. Edit the analytic distribution on an invoice line and add a lot of accounts 2. Open the popup again 3. A lot of web_read requests are made Issue ----- The display_name for the account and currency is not being passed to the field values in recordProps(), resulting in another fetch when each Field element is rendered. Solution ----- Pass account.accountDisplayName. The display name for the currency is actually not initially loaded by the client, but since that field is invisible, we can safely use an empty string. opw-5106219 Forward-Port-Of: odoo/odoo#231342
Updates point of sale and IoT-related browser requests so local devices such as IoT boxes and customer displays continue to connect as Chrome introduces stricter local network access rules. This helps avoid disruption for businesses using local hardware with Odoo POS after upcoming browser changes.
Original PR description
Enterprise PR: https://github.com/odoo/enterprise/pull/96850 Local Network Access restrictions will start shipping by default in Chrome 142. As part of this change, local requests will be allowed to use HTTP in an HTTPS context (gated by a browser permission prompt). This will work automatically when the IP is provided directly, however in the case of IoT we often use the odoo-iot DNS domain to resolve the IP. In this case, you must specify the option `targetAddressSpace: "local"` in the `fetch` request. This commit simply adds this change where appropriate. task-5157145 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231468 Forward-Port-Of: odoo/odoo#231014
This update prepares Odoo Point of Sale IoT connections for upcoming Chrome Local Network Access restrictions. It helps ensure local IoT devices can still be reached from secure Odoo sessions when using the odoo-iot domain, avoiding disruption for businesses using connected hardware.
Original PR description
Community PR: https://github.com/odoo/odoo/pull/231014 Local Network Access restrictions will start shipping by default in Chrome 142. As part of this change, local requests will be allowed to use HTTP in an HTTPS context (gated by a browser permission prompt). This will work automatically when the IP is provided directly, however in the case of IoT we often use the odoo-iot DNS domain to resolve the IP. In this case, you must specify the option `targetAddressSpace: "local"` in the `fetch` request. This PR simply adds this change where appropriate. As part of this we have also backported the change from jquery -> fetch. task-5157145 Forward-Port-Of: odoo/enterprise#97124 Forward-Port-Of: odoo/enterprise#96850
Belgian point-of-sale blackbox messages are now queued, reducing delays during sales workflows and improving reliability when the device is busy or slow. This especially helps actions like pro forma sales where staff do not need to wait for an immediate blackbox response to continue serving customers.
Original PR description
In this commit, we introduce a queuing mechanism for blackbox messages to make all interactions with the blackbox faster and more reliable. This is particularly useful for messages that do not require the response from the blackbox to continue the workflow such as pro forma sales messages.
Resolved issues and error corrections
Payroll work entry generation no longer fails when a fully flexible employee has overlapping sick leave and a public holiday. This prevents blocking errors during payroll preparation for companies using flexible schedules and overlapping leave scenarios.
Original PR description
**Issue:** Multiple errors occur when processing payroll for "Fully Flexible" employees and overlapping leave scenarios: 1. ValueError "Expected singleton: hr.work.entry.type(7, 8)" during work entry…
**Issue:** Multiple errors occur when processing payroll for "Fully Flexible" employees and overlapping leave scenarios: 1. ValueError "Expected singleton: hr.work.entry.type(7, 8)" during work entry generation when sick leave overlaps with public holiday **Steps to Reproduce:** 1. Go to the **Employees** app and create a new employee. * Set the working hours to **empty (fully flexible)**. 2. Go to **Contracts** and create a new contract. * Set the **Work Entry Source** to *Attendance*. * Save and make the contract **Running**. 3. Go to **Time Off** → **New**, and create a sick time off for the employee. * Example: from **25th to 29th**. * Approve the time off. 4. Go to **Configuration** → **Public Holidays**, and create a new public holiday. * Example: **27th**, which overlaps with the sick time off. * Work Entry Type = **Paid Time Off**. 5. Go to **Payroll** → **Work Entries**. * A **traceback** occurs. **Root Causes:** - In `_get_interval_leave_work_entry_type()`: Direct access to `interval[2].work_entry_type_id.code` causes singleton violation when overlapping leaves create intervals containing multiple work entry types. **Fix:** - Replace direct access to `interval[2].work_entry_type_id.code` with safe recordset slicing `interval[2].work_entry_type_id[:1].code` to prevent singleton violation when interval contains multiple work entry types This resolves payroll blocking issue for deployments using the Fully Flexible employee feature, where employees may have overlapping leave types and no assigned working calendar. Test : [PR](https://github.com/odoo/enterprise/pull/93902) opw-4979974 Forward-Port-Of: odoo/odoo#223448
Accounting users limited to a company branch can now access and select the appropriate accounts from the parent company when creating journal entries. This prevents blocked accounting work caused by accounts appearing unavailable for branch-only users.
Original PR description
**Steps to reproduce:** - Install accountant - Create a company branch for a company - Create a non-admin user with Accounting rights and access to the branch only - Connect with the created user - Go to "Accounting / Accounting / Journal Entries" - Create a journal entry and try to set an account on a line **Issue:** There is no account available. The accounts from the parent company should be selectable. **Cause:** The accounts are searched with a "parent_of" domain on "company_ids" field, which is a many2many field. However, as the user doesn't have access to the parent company, the parent company is excluded from the search when parsing the domain. opw-5096437 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231352 Forward-Port-Of: odoo/odoo#230797
Point of Sale receipts, customer displays, and self-order payment pages now create QR codes directly in the browser instead of relying on the server. This helps stores continue printing receipts with QR codes even when the POS is offline and keeps receipt layouts consistent.
Original PR description
Import the `qrcode` JS library and render QR codes directly in the browser instead of requesting them from the backend. This allows receipts with QR codes to be generated and printed even when the POS is offline. Problem was that we cannot use `ZXing.BrowserQRCodeSvgWriter();` (which is a library already used in the POS that can generate QR code) because it generates an unpredictable padding, which cause some issues in the receipt layout. task-id: 5060246 task-id: 5060246 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Odoo Studio now bases edited views on the correct main view instead of an intermediate inherited view. This prevents incorrect customizations and helps ensure Studio changes behave as expected for users.
Original PR description
…ry view Accidentally pass an inheriting view id to edit view. Before this commit, the studio view thus created inherited from the extension view After this commit, it inherits from the closest primary view. opw-4930800 Forward-Port-Of: odoo/enterprise#96636 Forward-Port-Of: odoo/enterprise#94747
Reverse charge taxes can no longer be configured as included in displayed prices, and the tax calculation engine now consistently treats them as price-excluded. This prevents incorrect tax setup and helps ensure accounting calculations follow the expected reverse charge behavior.
Original PR description
After this commit, you no longer can set a custom "price_include_override" on a tax using the UI. Even if you do, the tax engine forces such tax to be price-excluded. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231384
Odoo now stops sending attendee-specific event emails, such as badge or QR code messages, once an event is finished. This prevents outdated or unnecessary attendee communications while still allowing post-event messages intended for all event participants.
Original PR description
Forward-Port-Of: odoo/odoo#229960 Forward-Port-Of: odoo/odoo#227986
This fixes an issue where adding certain localized financial report variants to Annual Statements could fail. Composite report variants are now expanded into their sections, preventing errors and ensuring the correct localized reports appear automatically.
Original PR description
The "Annual Statements" report comes with additional code at create() and write() of account.report, so that any new localized variant of the Balance Sheet, Trial Balance or Profit & Loss will automatically replace its root report in the Annual Statements report's sections. The idea behind that is to "magically" replace those generic reports by the right variant when it's created. The problem with that came when you tried adding a variant to one of those reports that was itself a composite report. In such case, you got a traceback stating a composite report's sections could not have sections themselves. We indeed only support one level of hierarchy for composite reports. We solve the issue by adding all the sections of such composite variant to the Annual Statements instead of adding the variant itself. Bug originally reported by Upgrade, here https://github.com/odoo/upgrade/pull/8571 .
Mobile users can now tap dashboard charts such as scorecards and gauges to open the related Odoo menu, matching the desktop experience. This fixes a navigation gap that previously made mobile dashboards less useful and harder to act on.
Original PR description
Current behavior before PR: - Clicking on a chart in mobile did nothing, unlike on desktop where it redirects to the linked Odoo menu. Desired behavior after PR is merged: - Clicking on a chart in mobile also redirects to the corresponding Odoo menu. - The test has been refactored to remove duplication and improve readability. Task: [4884509](https://www.odoo.com/odoo/2328/tasks/4884509) Forward-Port-Of: odoo/odoo#231469 Forward-Port-Of: odoo/odoo#225372
Corrects a bug where hierarchy-based filters on related records could miss child records that the current user cannot directly access. This helps ensure searches and business rules return consistent results when using stored parent-child structures.
Original PR description
We introduced a regression in https://github.com/odoo/odoo/pull/170009 for 'child_of'/'parent_of' operators on relational fields: With a domain leaf like `[('X2X', 'child_of', ids)]` where the X2X comodel has `_parent_store=True`, we don't take into account inaccessible children from the current user. That's incorrect, and we already fixed this behavior in ae038904face6766d93695dcaa9b07346d05282a, but the test added targeted 'res.partner' which has `_parent_store=False`.
Fix it by using a `_search()` on the sudoed comodel instead of the 'any' operator. In 19.0 we should use 'any!' operator instead.
Forward-Port-Of: odoo/odoo#231458Restaurant point-of-sale orders now keep combo meals together when staff move an item to another course. This prevents parts of the same combo from being split across courses, reducing order mistakes and improving service accuracy.
Original PR description
Steps to reproduce: ------------------------- - Install POS restaurant & create order with multiple courses - Add a combo product in one of the course - Select a combo child line and try to transfer course Issue: ------- - Only the selected child line is transferred to the new course instead of the entire combo. Cause: --------- - The system currently transfers only the selected order line without checking whether it belongs to a combo. Fix: ---- - Updated the logic to check if the selected order line is part of a combo. If so, the entire combo (parent and child lines) will now be moved to the new course together. task: 5005141 Forward-Port-Of: odoo/odoo#222423
Gift Card and E-Wallet products now appear in the Point of Sale screen even when the PoS is limited to selected product categories. This ensures staff can sell these payment products in-store without needing extra category setup.
Original PR description
Before this commit: =================== If the PoS configuration is restricted to specific categories, but the Gift Card and E-Wallet products do not have any category assigned, these products will not be visible in the PoS UI. After this commit: ==================== Gift Card and E-Wallet products are now always visible in the PoS UI, regardless of whether a PoS category is assigned or not. Purpose: ============ Gift Card and E-Wallet products should always be available for sale in the PoS. This ensures they can be sold physically from the PoS UI without requiring category assignment. Task-5103770 Forward-Port-Of: odoo/odoo#231465 Forward-Port-Of: odoo/odoo#228395
Point of Sale orders marked for later shipping now keep the selected shipping date instead of shifting it due to timezone conversion. This prevents customers and staff from seeing the wrong delivery date on receipts.
Original PR description
PURPOSE: ---------------- - Fix incorrect handling of shipping date in POS . It was treated as a datetime, which led to timezone shifts and wrong dates in receipts. STEPS TO REPRODUCE: ------------------- 1. Open point of sale 2. In Configuration → Settings, enable Allow Ship Later for a POS shop. 3. Open a POS session, add a product, proceed to payment, and select Ship Later. 4. Validate the order. ISSUE: -------------------- - The receipt shows the wrong shipping date. CAUSE: --------------------- - shipping_date was serialized using serializeDateTime, forcing a UTC conversion. - Related models only supported datetime type, so date fields were mishandled. FIX: -------------------- - Introduced proper date handling (convertRawToDate, convertDateToRaw). - Updated serialization/deserialization to handle both `date` and `datetime`. - Changed ShippingDate to use serializeDate instead of serializeDateTime. Task-5055738
Checkout step labels are now correctly translated when customers browse the shop in another language. This fixes an inconsistency in multilingual websites, making the checkout experience clearer for international shoppers.
Original PR description
Versions -------- - saas-18.3+ Steps ----- 1. Have a website; 2. enable a new language (other than English); 3. use website in this language; 4. go to checkout. Issue ----- The checkout steps on the top-left aren't translated. Cause ----- Commit dbd22d93183f2 added the `website.checkout.step` model. Like `website.menu`, they have a default record that gets set on initialization, which is then gets used to create a new record per website. The issue is that when enabling a new language, it only translates the default records. The records that are website-specific remain unchanged. Solution -------- Because they function the same we as `website.menu`, we can use the same approach that was taken to translate website menus, and add a `_load_module_terms` override to `ir.module.module`, constructing a SQL query that copies the translations from the default records to the website-specific records. opw-4985676
Spreadsheet list side panels now handle missing or deleted fields without crashing. This keeps users able to edit lists after migrations or custom field removals, reducing disruption from data model changes.
Original PR description
If a field disappeared from a list following a migration or a deleted custom field, the list could no longer be edited in the sidepanel because we tried to access the missing field info (name & string) Task-4915281 Forward-Port-Of: odoo/enterprise#97179 Forward-Port-Of: odoo/enterprise#96158
Project revenue reporting now continues to include sales linked to products that have been archived. This keeps project profitability and status information accurate after old or discontinued service products are archived.
Original PR description
**Steps to reproduce:** 1. Install the Sale, Project, and Timesheet modules. 2. Create a service-based product with `invoicing policy > Prepaid`, linked to `Create on Order > Project and Task`. Add a project template. 3. Create a sale order with that product. 4. Go to the created project and check the project status. **Observed behavior:** * Revenue is visible in project status while the product is active. * Once the product is archived, its revenue disappears. **Root cause:** Archived products were not considered when calculating revenue. **Solution:** Backport the fix from v18 to include archived products in revenue calculations. v18 pr : https://github.com/odoo/odoo/pull/129089 added test for product archive case. opw-5070289 Forward-Port-Of: odoo/odoo#231503 Forward-Port-Of: odoo/odoo#229485
Users assigned to tasks in private projects can now print or export their own timesheets without encountering an access error. This removes an inconsistent reporting issue and helps employees retrieve timesheet records they are already allowed to work with.
Original PR description
****Behavior:**** **Current:** When a user with only 'User' access to Projects and Timesheets, is assigned to a task in a Private project by an admin user, they can then log timesheets on the task as…
****Behavior:**** **Current:** When a user with only 'User' access to Projects and Timesheets, is assigned to a task in a Private project by an admin user, they can then log timesheets on the task as it appears under "My Tasks". The user might then want to print or export the timesheets form the list view. - If the selected timesheets come from only a single private project : an Access Error is raised - If the selected timesheets come from multiple private projects, or a mix of public and private ones : no Error is raised The issue comes from the need to access to the project's name (since the project is private to the user the code raises the error) as well as the company's name. And it only happens when single projects are selected, in the other cases, the exported pdf shows the project's name at another location without error. **Expected:** Since the information is already accessible through multiple other places in odoo (and even in the exported pdf), we should allow the access here aswell. So now when printing or exporting a timesheet from a single private project, no Access Error is raised. **Steps to reproduce:** - Create 2 different projects - Create a task in each - Assign it to another user (Make sure the other user only has user access to timesheets and projects) - Set each project's visibility setting to private - Log in with the other user - Go to Timesheets --> List View Single projects: - Select one or multiple timesheet entries from one of the private projects - Select Print -> Timesheets - You should see an Access Error Multiple projects: - Select one or multiple timesheet entries from a combination of both private projects - Select Print -> Timesheets - You should not have any Errors opw-5127526 Forward-Port-Of: odoo/odoo#231188