Daily updates from Odoo
Wednesday, October 15, 2025
78 changes
15 changes
Resolved issues and error corrections
Combo products now print correctly when a point of sale uses separate preparation printers by product category. Each printer shows the combo title and only the relevant child items for its category, reducing preparation mistakes and duplicate kitchen/bar tickets.
Original PR description
Before this commit: =================== - When using separate printers for product categories, combo products were not printed correctly. - All child products of a combo were sent to every printer, regardless of their category. After this commit: ================== - Combo products are now handled properly in preparation tickets. - Each printer will print the combo product title along with only the child products that belong to its assigned category. Task: 5056115 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230982 Forward-Port-Of: odoo/odoo#225658
Fixed an issue where the point of sale screen could keep showing a QR payment prompt after the customer had already paid. Staff can now close the payment popup and continue without running into order finalization errors.
Original PR description
*: pos_online_payment_self_order Before this commit: =============== - When paying with a QR code, the screen kept showing the QR code even after the payment was completed. - Closing the QR popup…
*: pos_online_payment_self_order Before this commit: =============== - When paying with a QR code, the screen kept showing the QR code even after the payment was completed. - Closing the QR popup manually and performing another action resulted in a `Finalize order` error. - This happened because the WebSocket handler flow were not updating the order state properly. After this commit: =============== - Ensure the frontend refreshes payment status directly from the server when the current order is updated. - Remove unnecessary synchronization calls to prevent stale state. - The order is now correctly marked as paid, and no finalize error occurs after closing the QR popup. Issue: =============== - The frontend WebSocket handler for `ONLINE_PAYMENTS_NOTIFICATION` was fetching the full `pos.order` unnecessarily, because the order state is already updated by another WebSocket flow. - `notify_synchronisation` in the self order flow was redundant, as updates are already handled in the `pos_self_order` module’s `pos.order` file. Task - 5107009 Forward-Port-Of: odoo/odoo#229847
Accounting users limited to a company branch can now use accounts from the parent company when creating journal entries. This prevents blocked accounting workflows where no accounts appeared available despite the user having the appropriate branch accounting access.
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
Fixed an issue in Point of Sale where quick-add payment buttons like +10 or +50 could calculate dramatically incorrect amounts for users whose language uses a comma as the decimal separator. This prevents overcharged payment entries and makes checkout totals reliable across localized databases.
Original PR description
**Steps to reproduce:** - Set your database in a language with a "," as a decimal separator, such as French - Make a purchase, chose a payment method - Before paying, click any +10/20/50 button - The…
**Steps to reproduce:** - Set your database in a language with a "," as a decimal separator, such as French - Make a purchase, chose a payment method - Before paying, click any +10/20/50 button - The price will be multiplied by 100, then add the desired amount **Why the fix:** There were two places where the decimal separator was causing issues. First when we try to get the current price, *currentBufferValue*, we try to get it when it's in float state, but as we have a language with a decimal separator set as "," the "." in this float will be ignored, and we will take the decimal as units as well, explaining the *100 amount, because the decimals become whole numbers. Secondly, when we try to make the addition of the two and convert it to string again, the *toString* method will convert it with a default "." not taking the current decimal separator into account. Once again, the "." will be ignored later on, leading to an even more over the top number. We now convert the numbers and the strings using the correct decimal separator. opw-5126224 Forward-Port-Of: odoo/odoo#229735
This fix makes reconciliation models accessible when using Invoicing, preventing accounting workflows from getting stuck. It also cleans up confusing views related to creating reconciliation model lines, making the experience smoother for users.
Original PR description
Currently flows are stuck if you don't have the models. And some views are really weird (create a reconciliation model line). 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#230775
IoT users and administrators can now open IoT screens without needing Point of Sale access when the POS IoT module is installed. POS-related options are only shown or used for users with the right POS permissions, preventing unnecessary access errors.
Original PR description
Before this commit, if an IoT user/admin attempted to access any IoT view while `pos_iot` was installed, they would get a permission error if they were not also a POS user. After this commit, we check if the user is in a POS group before showing any POS related fields. We also check the group when autoconfiguring a new IoT box with a POS, this feature will simply be skipped if the user cannot access POS.
Odoo now handles auto-forwarded emails more accurately when matching email aliases. This prevents unrelated recipients from being automatically added as followers, reducing notification noise and keeping follower lists cleaner.
Original PR description
Sending an email that was auto-forwarded would lead to the recipient line having two different emails which would cause any emails that were not set up as aliases to be added as followers even if…
Sending an email that was auto-forwarded would lead to the recipient line having two different emails which would cause any emails that were not set up as aliases to be added as followers even if local part detection was enabled in the alias settings. This was due to the fact that partner detection was changed in 18.2 and now looked for exact email to alias matches. Ban emails were passed to the _find_or_create_from_emails and then directly matched to the emails in the list of recipient emails. When a match was not found for emails that did not have an exact matching alias_full_name, we would then look for or create a partner for that email. This caused erroneous followers to be added. Changing the functionality to also look for matching local parts in order to skip partner finding and creation reverts this functionality to how it previously worked where extra recipients with matching local parts when local part detection was enabled would not add those partners as followers. opw-4896074 Forward-Port-Of: odoo/odoo#230004 Forward-Port-Of: odoo/odoo#216737
Point of Sale loyalty rewards now only grant points when an order meets the program's minimum item requirements. This prevents customers from receiving points incorrectly or losing excessive points when redeeming a free product.
Original PR description
Loyalty points were not being awarded correctly for some orders. The system granted points even when the minimum required quantity of items was not reached. In some cases, it also added negative…
Loyalty points were not being awarded correctly for some orders. The system granted points even when the minimum required quantity of items was not reached. In some cases, it also added negative loyalty points, which led to an excessive deduction for the customer —sometimes just for claiming a single free product. > Setup of the Loyalty Program (Discount & Loyalty): Program Type : Loyalty Card Rule : minimum 5 items => 10 Loyalty Points per $ Reward : Free product (Simple Pen) => in exchange of 5 Loyalty Points Steps to reproduce: ------------------- * Open the pos Shop * Select a customer with loyalty points * Add a Simple Pen * Click on * Reward > Free Product - Loyalty Program > Observation: Customer shouldn't 'win' points here New Total is mathematically correct but not logic Why the fix: ------------ We need to verify that the order is eligible to generate reward points based on the configured rules, before adding the won points. opw-4914774 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231056 Forward-Port-Of: odoo/odoo#221570
This fixes a point display issue in the point-of-sale loyalty flow. When staff refresh the receipt screen, loyalty points are recalculated so customers see consistent and accurate balances.
Original PR description
Before this commit: --------- - Loyalty points are not recalculated when the receipt screen is refreshed. After this commit: ---------- - Ensures that loyalty points are properly recalculated when the receipt screen is refreshed, preventing inconsistencies in displayed points. task-5106892
Reverse charge taxes can no longer be configured as included in displayed prices, and the tax calculation will always treat them as excluded. This prevents incorrect tax handling and keeps accounting results consistent for affected transactions.
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
Attendee-specific event emails are no longer scheduled once an event has finished. This prevents outdated messages such as badge or QR code emails from being sent after the event, while still allowing post-event communications meant for all attendees.
Original PR description
Forward-Port-Of: odoo/odoo#229960 Forward-Port-Of: odoo/odoo#227986
This fixes an issue where hierarchy-based searches could miss child or parent records that the current user could not directly access. The change helps keep business data relationships accurate when filtering records by organizational or category hierarchies.
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#231458The General Ledger now consistently shows the Initial Balance line first when users expand accounts and use the Load more option. This prevents missing or duplicated ledger lines, improving accuracy and clarity when reviewing account activity.
Original PR description
### Issue: The "Initial Balance" line in the General Ledger is not the first line with the "Load more" option ### Steps to reproduce: - Accounting > Configuration > Accounting Reports > General…
### Issue: The "Initial Balance" line in the General Ledger is not the first line with the "Load more" option ### Steps to reproduce: - Accounting > Configuration > Accounting Reports > General Ledger - Change the Load more limit in the options to a small number, i.e. 4 - Open the General Ledger and unfold an account with more than 10 lines - There is no Initial Balance line, it appears when clicking "Load more" ### Cause: The General Ledger query have this line `ORDER BY 2, move_name, 1`. Here 2 refers to the date and 1to the `account_move_line.id`. But the initial balance line has these columns equal to `NULL` so this ORDER BY will place it at the end of the results. When the limit is smaller than the total number of lines, the initial balance is not fetched by the query. **Additional issue** The limit is incremented several times. In our case, we set the option at 4. It gets incremented [here](https://github.com/odoo/enterprise/blob/edb4ba5b98be9f9ae3617cc6e66c5e3376a1b56c/account_reports/models/account_report.py#L7172) because the load more option is triggered, and also [here](https://github.com/odoo/enterprise/blob/edb4ba5b98be9f9ae3617cc6e66c5e3376a1b56c/account_reports/models/account_general_ledger.py#L239) for no apparent reason (it is not needed "for the Initial balance"). So the query is called with `limit=6`, six lines are retrieved when clicking on "Load more". Considering a scenario where there are 10 lines for the account (with the initial balance) and "Load more limit" set to 4: - The first query gets the lines 1-6 but only 1-4 are displayed. - Clicking "Load more", the offset is 4, the query gets the lines 5-10. 10 being the initial balance, it is put in first position by [this piece of code](https://github.com/odoo/enterprise/blob/edb4ba5b98be9f9ae3617cc6e66c5e3376a1b56c/account_reports/models/account_general_ledger.py#L79-L91). So the lines displayed are 10, 5, 6, 7 - Last click on "Load more", offset is 8, query gets 9 and 10, displays 10, 9. In the end, one line is not displayed, and the initial balance is displayed twice. ### Solution: Add `NULLS FIRST` in `ORDER BY` to always have the Initial Balance as the first line returned by the query. Also remove the unnecessary `limit+1`. opw-5105652
Spreadsheet list editing now handles cases where a field was removed after a migration or custom field deletion. This prevents the side panel from crashing, so users can continue editing affected spreadsheet lists without interruption.
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 totals now continue to include sales of service products even after those products are archived. This keeps project status and profitability information accurate for teams reviewing historical or ongoing project performance.
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
16 changes
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
3 changes
Resolved issues and error corrections
This fix ensures that views created or edited in Odoo Studio inherit from the correct primary view instead of an intermediate extension view. This helps prevent unexpected Studio customization behavior and makes view editing more reliable 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
This fix prevents spreadsheet list editing from breaking when a field was removed after a migration or custom field deletion. Business users can continue editing affected lists in the side panel instead of encountering a crash.
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#96158
Installing the POS due settlement module now applies its required products to every POS setup, including those with open sessions. This prevents checkout or settlement issues caused by missing settlement, deposit, or invoice products.
Original PR description
Backport of https://github.com/odoo/enterprise/pull/95789 Before this commit, when the module pos_settle_due was installed, the special products (settle due, deposit, settle invoice) were only set on the POS configurations that did not have any open session. This could lead to issues when trying to use these products in a POS session of a configuration that did not have them set. Now, the special products are set on all POS configurations when installing the module. Community PR: https://github.com/odoo/odoo/pull/230939 Task id: 5080126
2 changes
Resolved issues and error corrections
IoT users and administrators can now open IoT screens even when they do not have Point of Sale access. POS-specific options are only shown or used for users with the right permissions, preventing unnecessary access errors.
Original PR description
Before this commit, if an IoT user/admin attempted to access any IoT view while `pos_iot` was installed, they would get a permission error if they were not also a POS user. After this commit, we check if the user is in a POS group before showing any POS related fields. We also check the group when autoconfiguring a new IoT box with a POS, this feature will simply be skipped if the user cannot access POS. Forward-Port-Of: odoo/enterprise#97133
This fix prevents spreadsheet list editing from crashing when a referenced field was removed during migration or after deleting a custom field. Business users can continue editing affected lists from the side panel instead of being blocked by an error.
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
24 changes
Resolved issues and error corrections
Preparation tickets in Point of Sale now handle combo products correctly when different printers are assigned to different product categories. Each printer receives the combo name plus only the relevant items for its category, reducing kitchen or service confusion.
Original PR description
Before this commit: =================== - When using separate printers for product categories, combo products were not printed correctly. - All child products of a combo were sent to every printer, regardless of their category. After this commit: ================== - Combo products are now handled properly in preparation tickets. - Each printer will print the combo product title along with only the child products that belong to its assigned category. Task: 5056115 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230982 Forward-Port-Of: odoo/odoo#225658
Accounting users limited to a branch can now access the appropriate accounts from the parent company when creating journal entries. This prevents blocked or incomplete journal entry creation for branch-only accounting 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
This fixes an issue where country-specific point-of-sale fields could disappear when multiple devices were connected to the same session. Businesses using Chilean or Peruvian electronic invoicing in PoS will now keep required session information consistent across devices.
Original PR description
Before this commit, the special fields were added to the PoS session in the `_load_pos_data` function. However, they were not included when sending synchronization notifications to other devices. As a result, in multi-device setups, these fields would be removed after a WebSocket notification. related: https://github.com/odoo/odoo/pull/228419 opw-5073848 Forward-Port-Of: odoo/enterprise#95455
This fix ensures Spain-specific Point of Sale session information stays present when updates are synchronized between multiple devices. It prevents important localization data from being accidentally removed after real-time notifications, improving reliability for multi-device PoS setups.
Original PR description
Before this commit, the special fields were added to the PoS session in the `_load_pos_data` function. However, they were not included when sending synchronization notifications to other devices. As a result, in multi-device setups, these fields would be removed after a WebSocket notification. related: https://github.com/odoo/enterprise/pull/95455 opw-5073848 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228419
AI attachment handling now better supports tabular files such as CSV and spreadsheet formats by organizing rows in a way that can be processed more reliably. This helps users add spreadsheet-like documents as AI sources and improves the quality of information retrieval from those files.
Original PR description
This PR aims to properly support and chunk tabular attachments including csv, xls, xlsx, and ods attachments. task-id-5045336
Shipping labels can now be sent to a selected printer based on the warehouse operation type instead of automatically using the first compatible printer. This helps businesses route labels to the correct location and avoid printing mistakes in multi-printer setups.
Original PR description
Printing shipping labels is performed from the backend, once the shipping info are received in the chatter. The printing command is sent to the frontend via the user bus, then though longpolling to the iot box. This commit adds the possibility to select a printer instead of choosing automatically the first (with the right report associated) on the list. As the change is made on a stable version, we are using system parameters to store the selected printer without adding a new field. We associate a printer with the picking type, in order for to be able to have different printers by default on different picking types. Task: 4792491 Forward-Port-Of: odoo/enterprise#97034 Forward-Port-Of: odoo/enterprise#86818
Returning a non-rental product from a rental order now correctly reduces the delivered quantity on the sale order. This prevents inaccurate order status and invoicing information after rental-related returns.
Original PR description
**Issue**: Returning a non-rental product in a rental order does not correctly update the delivered quantity. **Steps to reproduce**: - Enable rental transfers via Settings > Rental. - Create a…
**Issue**: Returning a non-rental product in a rental order does not correctly update the delivered quantity. **Steps to reproduce**: - Enable rental transfers via Settings > Rental. - Create a rental order with (in that order!): - A rental product - A non-rental product - Confirm the rental order. - Open the related sale order. - Go to the delivery and validate it. - Return the delivery and validate the return. - Observe that the delivered quantity in the sale order is incorrect. **Cause**: The [_get_outgoing_incoming_moves](https://github.com/odoo/odoo/blob/ea6776f095d556e3429d2b847a66f78f2e866380/addons/sale_stock/models/sale_order_line.py#L200C17-L200C85) method fails to detect incoming moves when the destination location has `usage='internal'` (as in rental flows), instead of `customer` (see [_is_outgoing()](https://github.com/odoo/odoo/blob/ea6776f095d556e3429d2b847a66f78f2e866380/addons/stock/models/stock_location.py#L464)). This causes the delivery quantity not to be decremented on return. **Solution**: Relax `_is_incoming()` logic to consider moves as incoming if they come from a rental and go to an internal location. opw-4894358 Forward-Port-Of: odoo/odoo#224714 Forward-Port-Of: odoo/odoo#222093
Fixes several issues in the document extraction manual correction interface, including crashes, disappearing selection boxes, and inaccurate line matching. This makes it easier and more reliable for users to correct extracted data from images and documents.
Original PR description
**[FIX] iap_extract: fix crash when clicking on another column of x2many** When a x2many field is filled using the rectangular selection tool, a crash could occur when the component is busy filling…
**[FIX] iap_extract: fix crash when clicking on another column of x2many** When a x2many field is filled using the rectangular selection tool, a crash could occur when the component is busy filling the values for a field and the user clicks on another column. This happened because the `getNewRecordValues` function was using the current value of `this.activeBoxType` to get the value for the new record. This is incorrect as `this.activeBoxType` can change when the user clicks on another column of the x2many. --- **[FIX] iap_extract: fix line matching in manual correction component** In the logic that handles the matching of selected boxes with existing lines, it was assumed that the existing lines were sorted from top to bottom, but that wasn't guaranteed. When it's not sorted, the out-of-order existing lines couldn't be match to the selected boxes. --- **[FIX] iap_extract: fix loss of focus when clicking on image viewer** When the attachment showed by the viewer is an image and the selected field is a date, a click on the image (to start a rectangular selection or to click a box) would cause a loss of focus on the field which caused the boxes to disappear, making it unusable. This happened because the date fields are displaying a calendar popup which listens on the `pointerdown` event to hide itself when the click occurs outside of it. This causes the loss of focus of the field which hides the boxes. On top of this, we also need to prevent the propagation of the click event when it occurs on the box layers, as it also causes the loss of focus on x2many fields (there is a global click event listener that exits the edit mode when the click occurs on another element). These issues weren't noticed before as they only occur on image attachments. On PDFs, the viewer is embedded in an iframe that prevents the `pointerdown` and `click` events to be visible to the main document. --- **[FIX] iap_extract: fix rectangular selection on scrollable images** The rectangular selection needs to be adjusted when the user scrolls while selecting boxes. This was already properly handled for PDFs, but not for image attachments.
The website builder’s AI command now works correctly when used on product pages. This prevents a “Missing Record” error and lets users continue editing product descriptions without interruption.
Original PR description
__Current behavior before commit:__ Using `/ai` in the website builder sends the record id as a string leading to an error in the backend because `browse` expects an integer as input. __Description of the fix:__ Use `search` instead of `browse` to support id sent as string as well as to validate ACL and existence of the record. __Steps to reproduce the issue on runbot:__ 1. Go to `/shop`. 2. Click on a product. 3. Open the website builder. 4. Enter `/ai` in the description below the product title. => A "Missing Record" error appears.
Fixes delivered quantities when customers return non-rental items that were sold on the same order as rental products. This keeps sales orders accurate after returns, reducing billing and fulfillment confusion for rental workflows.
Original PR description
**Issue**: Returning a non-rental product in a rental order does not correctly update the delivered quantity. **Steps to reproduce**: - Enable rental transfers via Settings > Rental. - Create a…
**Issue**: Returning a non-rental product in a rental order does not correctly update the delivered quantity. **Steps to reproduce**: - Enable rental transfers via Settings > Rental. - Create a rental order with (in that order!): - A rental product - A non-rental product - Confirm the rental order. - Open the related sale order. - Go to the delivery and validate it. - Return the delivery and validate the return. - Observe that the delivered quantity in the sale order is incorrect. **Cause**: The [_get_outgoing_incoming_moves](https://github.com/odoo/odoo/blob/ea6776f095d556e3429d2b847a66f78f2e866380/addons/sale_stock/models/sale_order_line.py#L200C17-L200C85) method fails to detect incoming moves when the destination location has `usage='internal'` (as in rental flows), instead of `customer` (see [_is_outgoing()](https://github.com/odoo/odoo/blob/ea6776f095d556e3429d2b847a66f78f2e866380/addons/stock/models/stock_location.py#L464)). This causes the delivery quantity not to be decremented on return. **Solution**: Relax `_is_incoming()` logic to consider moves as incoming if they come from a rental and go to an internal location. opw-4894358 Forward-Port-Of: odoo/enterprise#93442 Forward-Port-Of: odoo/enterprise#91825
This fix makes reconciliation models accessible in the invoicing app so accounting workflows no longer get blocked when those models are needed. It also cleans up awkward related views, making the invoicing experience smoother for users managing payments and reconciliation.
Original PR description
Currently flows are stuck if you don't have the models. And some views are really weird (create a reconciliation model line). 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#230775
This fix ensures Odoo Studio edits are based on the correct main view rather than a nearby extension view. This helps prevent customization issues and keeps Studio changes applied in the expected place.
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
Auto-forwarded emails with multiple recipient addresses no longer cause unrelated email addresses to be added as followers when alias local-part matching is enabled. This keeps follower lists accurate and avoids unnecessary notifications to unintended contacts.
Original PR description
Sending an email that was auto-forwarded would lead to the recipient line having two different emails which would cause any emails that were not set up as aliases to be added as followers even if…
Sending an email that was auto-forwarded would lead to the recipient line having two different emails which would cause any emails that were not set up as aliases to be added as followers even if local part detection was enabled in the alias settings. This was due to the fact that partner detection was changed in 18.2 and now looked for exact email to alias matches. Ban emails were passed to the _find_or_create_from_emails and then directly matched to the emails in the list of recipient emails. When a match was not found for emails that did not have an exact matching alias_full_name, we would then look for or create a partner for that email. This caused erroneous followers to be added. Changing the functionality to also look for matching local parts in order to skip partner finding and creation reverts this functionality to how it previously worked where extra recipients with matching local parts when local part detection was enabled would not add those partners as followers. opw-4896074 Forward-Port-Of: odoo/odoo#230004 Forward-Port-Of: odoo/odoo#216737
This fixes a formatting issue in the HTML editor where colored or gradient text inside lists could lose its color, become invisible, or create invalid nested formatting when users changed text styles. It helps keep list formatting, checklist strikethroughs, and text entered after a list visually consistent.
Original PR description
Steps to Reproduce: - Create a list in the editor. - Apply a text color to an item. - Change the font type of the text inside the list (e.g., to H1–H6). - Apply a gradient color to text inside a list…
Steps to Reproduce: - Create a list in the editor. - Apply a text color to an item. - Change the font type of the text inside the list (e.g., to H1–H6). - Apply a gradient color to text inside a list item. - Move the cursor outside the list by pressing Enter twice and start typing in the new container. Current behavior before PR: - When changing the font type (H1–H6) after applying a color, the text color turns to default color. also when applying a gradient color and then changing the font type, the text becomes transparent. - This happens because the gradient style was incorrectly applied both on the `<li>` and its child `<font>` element. As a result, Checklist items lose their line-through when checked. Also new base container outside the list ends up with a `<font>` wrapping another `<font>`. Desired behavior after PR is merged: - All child elements inside the list item inherit the color and Gradient styles are applied only to the `<font>` element. - Checklist items correctly show the line-through when checked and No invalid nested `<font class="text-gradient">` tags are created when writing outside the list after pressing Enter twice. task-5039499 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231390 Forward-Port-Of: odoo/odoo#224262
Point of Sale loyalty rewards now check whether an order meets the configured earning rules before adding new points. This prevents customers from receiving points when minimum item quantities are not met and avoids incorrect negative point adjustments when claiming free products.
Original PR description
Loyalty points were not being awarded correctly for some orders. The system granted points even when the minimum required quantity of items was not reached. In some cases, it also added negative…
Loyalty points were not being awarded correctly for some orders. The system granted points even when the minimum required quantity of items was not reached. In some cases, it also added negative loyalty points, which led to an excessive deduction for the customer —sometimes just for claiming a single free product. > Setup of the Loyalty Program (Discount & Loyalty): Program Type : Loyalty Card Rule : minimum 5 items => 10 Loyalty Points per $ Reward : Free product (Simple Pen) => in exchange of 5 Loyalty Points Steps to reproduce: ------------------- * Open the pos Shop * Select a customer with loyalty points * Add a Simple Pen * Click on * Reward > Free Product - Loyalty Program > Observation: Customer shouldn't 'win' points here New Total is mathematically correct but not logic Why the fix: ------------ We need to verify that the order is eligible to generate reward points based on the configured rules, before adding the won points. opw-4914774 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231056 Forward-Port-Of: odoo/odoo#221570
Reverse charge taxes can no longer be configured as included in product prices through the interface. This prevents incorrect tax handling by ensuring these taxes are consistently treated as added separately, improving accounting accuracy and compliance.
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
This fixes how Odoo decides whether expense reports can be edited, reset, or approved. It ensures those actions reflect the actual user's permissions instead of treating every check as if it had elevated access, reducing the risk of incorrect actions being available.
Original PR description
The field is_editable which used the compute method _compute_is_editable and the field can_reset which used the compute method _compute_can_reset, where called with the argument compute_sudo=True. Those 2 method then used the self.env.su which was always True. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224573
Live chat agents marked as busy will now still be considered available to answer chats, while agents marked away remain unavailable. This prevents customers from being routed away from active support staff who only wanted to suppress notifications or show they are busy.
Original PR description
Before this commit, when a human agent had the IM status "busy", the agent was not considered available for live chat. The "busy" feature is intended only to not receive notification and to show to others we are busy, but is not meant to disable availabily as a live chat operator. The issue happens because availability of the operator required the "online" IM status, which ignored "busy" that was added recently. Note that "away" is considered as not available for operator: the "away" IM status can be set manually by user but also can be triggered automatically when agent is away for a long time, and in these cases users already expect to not be considered as available live chat agents. This behavior is kept in this commit. opw-5150332 Forward-Port-Of: odoo/odoo#231475
QR code payments in Point of Sale now update the payment screen once the payment is completed. This prevents staff or customers from seeing an outdated QR code and avoids errors when finalizing the order.
Original PR description
*: pos_online_payment_self_order Before this commit: =============== - When paying with a QR code, the screen kept showing the QR code even after the payment was completed. - Closing the QR popup…
*: pos_online_payment_self_order Before this commit: =============== - When paying with a QR code, the screen kept showing the QR code even after the payment was completed. - Closing the QR popup manually and performing another action resulted in a `Finalize order` error. - This happened because the WebSocket handler flow were not updating the order state properly. After this commit: =============== - Ensure the frontend refreshes payment status directly from the server when the current order is updated. - Remove unnecessary synchronization calls to prevent stale state. - The order is now correctly marked as paid, and no finalize error occurs after closing the QR popup. Issue: =============== - The frontend WebSocket handler for `ONLINE_PAYMENTS_NOTIFICATION` was fetching the full `pos.order` unnecessarily, because the order state is already updated by another WebSocket flow. - `notify_synchronisation` in the self order flow was redundant, as updates are already handled in the `pos_self_order` module’s `pos.order` file. Task - 5107009 Forward-Port-Of: odoo/odoo#231444 Forward-Port-Of: odoo/odoo#229847
The website HTML editor now avoids creating invalid page structure when users change text formatting inside elements that visually behave like blocks. This helps preserve content layout correctly in browsers and reduces unexpected editing results.
Original PR description
Before this commit we would insert a block inside of a phrasing content if it's displayed as a block and we change its font style. For example, if we tried to modify text inside of a `<small>` that has `display: block` style, it would insert a new block inside of it. Steps to see the issue: - Have an open editor with `<small>Text</small>` content, that has `display: block` style - Select "Text" and change the font style to paragraph => It will be `<small><p>Text</p></small>` which is not valid HTML, and it will be parsed by a browser as `<small></small><p>Text</p>`, which is not the expected behavior. task-5123274 Forward-Port-Of: odoo/odoo#230682 Forward-Port-Of: odoo/odoo#229043
Project revenue totals now continue to include prepaid service products even after those products are archived. This keeps project status and profitability reports accurate when older or discontinued products are no longer active.
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
Spreadsheet list side panels now handle missing or deleted fields gracefully. This prevents editing from being blocked after migrations or custom field removals, improving reliability for users managing spreadsheet-based lists.
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
This fix prevents access errors when branch users create Point of Sale orders for products owned by a parent company while real-time inventory valuation is enabled. It helps sales operations continue smoothly across company branches without blocking order creation.
Original PR description
Before this commit, if a product was assigned to company A and a user from one of its branches tried to create an order with real-time inventory valuation enabled, the system would raise an access error when reading the product's cost_currency_id field. opw-4969390 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229825 Forward-Port-Of: odoo/odoo#223951
Users can now print or export their own timesheets from a single private project without hitting an access error. This removes an inconsistent reporting issue for employees who are assigned work on private projects and need to share or keep timesheet records.
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
13 changes
Resolved issues and error corrections
This fixes a problem where users without the right access could trigger repeated reconnection attempts and excessive log messages in the web editor. The system now avoids subscribing to notification channels when access checks fail, keeping the service stable and reducing unnecessary noise for administrators.
Original PR description
Description of the issue/feature this PR addresses: When an exception is raised on the access check, the OutdatedPageWatcherService runs into a reconnect loop, resulting in lots of log entries. <img…
Description of the issue/feature this PR addresses: When an exception is raised on the access check, the OutdatedPageWatcherService runs into a reconnect loop, resulting in lots of log entries. <img width="1190" height="435" alt="image" src="https://github.com/user-attachments/assets/8634e254-344f-4f4f-a46e-c0b3674de303" /> Each reconnect attempt causes a log entry: ``` 2025-08-22 11:30:17,770 4 INFO db18_test_access odoo.addons.base.models.ir_rule: Access Denied by record rules for operation: write on record ids: [25], uid: 6, model: crm.lead 2025-08-22 11:30:17,779 4 WARNING db18_test_access odoo.http: Uh-oh! Looks like you have stumbled upon some top-secret records. Sorry, Marc Demo (id=6) doesn't have 'write' access to: - Lead/Opportunity, Modern Open Space (crm.lead: 25) Blame the following rules: - Personal Leads If you really, really need access, perhaps you can win over your friendly administrator with a batch of freshly baked cookies. ``` Current behavior before PR: Reconnect loop. Desired behavior after PR is merged: Do not add channels without sufficient rights. Related to: https://www.odoo.com/de_DE/my/tasks/5026412 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Contacts can no longer be deleted when they are already linked to Point of Sale orders. This prevents past sales records from losing customer information, helping keep order history accurate and traceable.
Original PR description
Before this commit, it was possible to delete a contact record even if it was linked to PoS orders, which would cause it to be unlinked from those orders. opw-5164368 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Argentina VAT report exports now correctly generate both required AFIP text files for type C vendor bills and invoices without taxes. This helps businesses meet AFIP reporting requirements and avoids incomplete tax return submissions.
Original PR description
…afip code '0' **Description of the issue/feature this PR addresses:** This PR addresses an issue identified in the generation of .txt files for invoices that utilize AFIP tax code '0' **Current behavior before PR:** The system is only generating one of the two .txt files required by AFIP for specific invoice types. Affected Cases: - Invoices of type 'C'. - Invoices that have no taxes. **Desired behavior after PR is merged:** Two .txt files should be generated for all invoice types, as per AFIP requirements. [HERE](https://app.screencastify.com/watch/2mtioGVxEOwW0rAHJS2v) is a video replicating the issue: 1. In localization Argentina, create a vendor bill type 'C' 2. In 'Tax Return' report, filter by date and 'Tax Type: Purchase' 3. Download .ZIP file and see only one .txt
Uruguayan electronic invoices now include invoice lines that have a zero total value, such as free delivery or fully discounted items. This ensures these lines are correctly reported to the tax authority as free delivery, improving compliance and invoice completeness.
Original PR description
## Description of the issue The client wants to register 0.0 line to the CFE (delivery line with price 0.0): based on our findings, the only way to report lines with 0 values to the DGI is by…
## Description of the issue The client wants to register 0.0 line to the CFE (delivery line with price 0.0): based on our findings, the only way to report lines with 0 values to the DGI is by configuring the line as a "free delivery." (invoice indicator 5). But this lines is not been reported as part of the CFE xml (neither as a Free Delivery line or discount ## Steps to reproduce 1. Create a Uruguayan electronic invoice (sales default journal on a UY company) 2. Add a line with quantity 1. price 0 3. Add a second line with quantity 1, price 500 and discount 100% ## Before this PR 1. if we have a line with price unit != 0.0 but with total price of the line 0.0 (as the second line), then we are reporting the invoice line as Free Delivery. 4. But, If we have an invoice with line with price unit 0.0 (example first line) then is not being informed in the CFE at all ## After this PR Both lines are informed to DGI using the invoice indicator 5 (Free Delivery) You can check this on to generate CFE XML in demo mode (not need to connect to UCFE) If you want more visual example please connect to UCFE in testing enviroment and check the generated PDF file. References [Odoo task](https://www.odoo.com/odoo/project/967/tasks/5015691) LATAM 1350 / ADHOC task 53445
This fixes rounding issues where price-included taxes could make invoice or sales line totals differ by a cent from the displayed price. It also simplifies the tax calculation logic and updates country-specific handling for Mexico and Portugal to keep totals consistent.
Original PR description
== Fix bug price-included == Suppose a line of 24.99 with a 20% tax price-included. base: 24.99 / 1.2 = 20.825 tax: 20.825 * 0.2 = 4.165 If we round both, we get 20.83 + 4.17 = 25.0 != 24.99 == Split and simplify round_base_line_tax_details == Easier implementation of this method to be easier to understand and easier to be customized (see PT override). Also, we now use the aggregate methods to aggregate the amounts instead of doing that by hand. opw-4505888 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixed an issue where one-day time off requests could appear as multi-day events in the Calendar app for users in certain time zones. This keeps employee leave calendars accurate and avoids confusion when planning absences.
Original PR description
**Issue:** Single-day time off requests appear as multi-day events in the Calendar app when using certain tim> **Cause:** The `_compute_date_from_to()` method converts user-specified dates to UTC.…
**Issue:** Single-day time off requests appear as multi-day events in the Calendar app when using certain tim> **Cause:** The `_compute_date_from_to()` method converts user-specified dates to UTC. https://github.com/odoo/odoo/blob/028e7228cb830e47a9726bef4c82793ba4590cd5/addons/hr_holidays/models/hr_leave.py#L316-L317 The `_prepare_holidays_meeting_values()` method then uses these UTC datetime values (`holiday.date_from`, `holiday.date_to`) In Los Angeles timezone, and for a one day leave on september 17 2025 this leads to: - holiday.date_from: September 17, 2025 at 03:00 UTC - holiday.date_to: September 18, 2025 at 12:00 UTC causing a single-day leave to be displayed as a two-day event. **After fix:** - start_value: September 17, 2025 at 12:00 - stop_value: September 17, 2025 at 11:59 **Steps to Reproduce:** 1. Set the user timezone to "America/Los_Angeles" 2. Set the browser timezone to the same timezone 3. Create a one-day time off request (e.g., September 17, 2025) 4. Open the Calendar app: the event spans across two days opw-4744817 Forward-Port-Of: odoo/odoo#224298
Project revenue calculations now include products that have been archived, so revenue no longer disappears from project status after a product is archived. This keeps project profitability views accurate for service products sold through Sales, Project, and Timesheets.
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#229485
Fixed an issue where using keyboard navigation in the Helpdesk knowledge base search suggestions could trigger an error page. This improves the reliability of self-service support by allowing customers to search help articles without interruption.
Original PR description
Steps to Reproduce: 1. Navigate to '/helpdesk/customer-care-1/knowledgebase'. 2. Enter any text in the search bar to trigger suggestions. 3. Press the down arrow key twice. 4. A traceback error occurs, indicating an Odoo Client Error. Before this commit, we had a crash when a user types something in a searchbar in the website helpdesk and do keydowns: "Cannot read properties of undefined (reading 'nextElementSibling')" To fix this, we need to add the 'data-bs-toggle' attribute to let BS find it to set '_element' (which must be the previous sibling of the dropdown-menu). This data attribute was probably not set before because in this case the BS dropdown is not used on a button or a link as documented; we use it as an autocomplete functionnality. task-4752497 Forward-Port-Of: odoo/enterprise#90228
Updating the production quantity for subcontracted manufacturing orders no longer creates extra component lines without lot or serial numbers when existing reserved stock already covers the need. This reduces manual rework and prevents validation errors during receipt processing.
Original PR description
Issue Before This Commit: ======================= When a user updates `qty_producing` in a subcontracting MO, it creates new move lines with empty lots or serials, even though the required quantity…
Issue Before This Commit: ======================= When a user updates `qty_producing` in a subcontracting MO, it creates new move lines with empty lots or serials, even though the required quantity is already available in existing `reserved move lines`. This requires the user to manually reassign lots/serials; otherwise, validating the picking raises a UserError of `missing Lot/Serial numbers`. Steps to Reproduce: ======================= - Install the `mrp_subcontracting` and `Purchase` module. - Create product1 with Vendor1. Create product2 with lot tracking and set it `Resupply Subcontractor on order` in Inventory. - Create a BOM for product1, with product2 as a component (quantity 10) and subcontractor Vendor1. - Create and confirm a purchase order for product1 (quantity 10) with Vendor1. - Go to Resupply → Supply Product2, deliver 100 units of Product2 to Vendor1 using lot-01, then validate the picking. - Go to the source PO → Receipt → Record Component. Observe that the move line is created with 100 units from lot-01 - Set qty_producing to 2 → the current component line updates to 20 quantity. - Increase qty_producing by 1 → a new line is created with empty lot, even though the existing line already has 100 quantity of the same lot. Cause of the issue: ======================= When `qty_producing` is updated in the subcontracting MO wizard, the `_set_quantity_done_prepare_vals` method recalculates quantities based on the already modified move line quantity instead of referencing its original `reserved quantity`.This causes incorrect comparisons on subsequent updates, leading to the creation of new move lines with empty lots even when sufficient quantity already exists in the existing move line. With This Commit: ======================= `_set_quantity_done_prepare_vals` method now uses `ml._origin.quantity or ml.quantity`. ` _origin.quantity` ensures the reserved quantity of existing move lines is counted, while `ml.quantity` handles newly created lines without an origin. This prevents unnecessary move lines with empty lots when sufficient quantity already exists in existing reserved lines, eliminating manual reassignment and avoiding UserError on picking validation. opw-5116273
Fixed an issue where using "Select All" in Documents only downloaded the records currently visible on screen, even though the interface indicated that all matching documents were selected. Downloads now include the full selected set, helping users reliably export the documents they intended.
Original PR description
When using "Select All" in the documents list view, only the visible records were downloaded, despite the UI indicating that all matching records were selected. This happened because the original onDownload method relied on targetRecords, which only includes in-memory records. To fix this, onDownload was converted to an async function. We now use getResIds(true) to retrieve all selected record IDs. These IDs are then used in a backend read call to fetch the documents, before proceeding with the download logic. This ensures that downloads reflect the user's full selection, not just the currently loaded subset. opw-4735723
The sales product configurator now fits better on mobile screens when products include custom attribute fields. This prevents oversized input fields and keeps key actions like the cart button visible and easier to use.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create a product attribute with a single custom value; 2. add the attribute to a product A; 3. set product A as an optional product of product B; 4. go to product B's product page in mobile view; 5. click on the cart button. Issue ----- The custom text field takes up way too much real estate. Cause ----- The template isn't fully adapted for mobile view. Solution -------- Change `d-flex` to `d-lg-flex` on the `ptal` element, making the attribute name & input online display in-line on large screens. Additionally, change some bootstrap classes to also have the cart button button displayed within the screen. opw-5114495
This fix improves how Odoo updates large session log tables when checking whether old user sessions still exist. It processes updates in smaller batches, reducing the risk of long-running database operations and improving system stability during maintenance.
Original PR description
The commit: https://github.com/odoo/odoo/commit/6fb676a4e3566c781ddd57480a200cddc88d99ae adds the model `res.device.log` which will hold a lot of data. In order to use this data efficiently, we decide to process data with the boolean field `revoked` equal to `True` (via the indexes). This boolean field indicates whether the session that generated the log is still present on the disk. The commit: https://github.com/odoo/odoo/commit/e4c9d1794f2d4873755a8692f4861ba043fac943 adds an automatic verification mechanism to change this value if necessary. Between the time the model was created and the time the verification mechanism was implemented, the table may have become too large. This will result in a very long write within a transaction. The purpose of this commit is to introduce a method for performing the batch writing.
Reverse charge taxes are now reported with the actual payable tax amount in SAF-T exports instead of showing zero. This helps ensure Romanian SAF-T tax reports match tax authority expectations and reduces compliance reporting errors.
Original PR description
When a reverse charge tax is used, we export a `TaxInformation` with a zero amount instead of the real amount of the tax. The tax authority requires to show the tax to pay and doesn't care about the tax to receive... In order to fix this, we only sum the tax details of lines having positive repartition lines. opw-5125678 Forward-Port-Of: odoo/enterprise#97117
5 changes
Resolved issues and error corrections
This fixes issues in the Social app when commenting on Twitter posts. Images now upload with the correct file type, and comment text is no longer lost when adding files or emojis.
Original PR description
Issue 1 ======= Steps to reproduce ----------------------- 1. Go to the Social app. 2. Create or Select any twitter post. 3. Add a comment to that post with an image. 4. Press Enter. ---> An error…
Issue 1
=======
Steps to reproduce
-----------------------
1. Go to the Social app.
2. Create or Select any twitter post.
3. Add a comment to that post with an image.
4. Press Enter.
---> An error notification will be shown.
When adding an image in a post comment to Twitter, the image was not uploaded properly because the MIME type was not set, and it defaulted to `application/octet-stream`.
This caused the following error:
```
{"errors": [{"parameters": {"$.media_type": ["'application/octet-stream'"]},
"message": "$.media_type: does not have a value in the enumeration
[video/mp4, video/webm, video/mp2t, video/quicktime, text/srt, text/vtt,
model/gltf-binary, model/vnd.usdz+zip, image/jpeg, image/gif, image/bmp,
image/png, image/webp, image/pjpeg, image/tiff]"}], "title": "Invalid Request",
"detail": "One or more parameters to your request was invalid.",
"type": "https://api.twitter.com/2/problems/invalid-request"}
```
From the above error, it's clear that Twitter only accepts specific MIME types.
This fix ensures the image has the correct MIME type so it can be uploaded without issues.
-------------------------------------------------------------------------------------------------------------------------------
Issue 2
=======
Steps to Reproduce
------------------------------
1. Select any post from social feed.
2. Add text comment or edit existing comment.
3. Upload file or add emoji.
=> The comment text is cleared/reset to its initial value.
Technical
------------------------------
With commit [1] we added `t-att-value` which sets the value of the textarea
on every re-render of the component.
After this commit
------------------------------
The initial value is only set once when component is mounted.
Removed `remove image` button for attachment while posting comments.
[1] https://github.com/odoo/enterprise/commit/ced5e88f433b7b9a8e1429259cd8bb6594b34852
Task-4845385Users can now print or export their own timesheets from a single private project without encountering an access error. This removes an inconsistency that blocked valid reporting for assigned users while keeping the same information visibility already available elsewhere in Odoo.
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
Changing the timezone on an appointment page could crash the booking flow when no specific resource filter was selected. The fix ensures the system uses the appropriate available resources automatically, keeping appointment slot refreshes working smoothly.
Original PR description
Changing the timezone on the appointment page triggers a refresh of the available slots. In that flow, the controller computes the maximum possible capacity using `filter_resources`. When no specific…
Changing the timezone on the appointment page triggers a refresh of the available slots. In that flow, the controller computes the maximum possible capacity using `filter_resources`. When no specific resource is selected, `filter_resources` remained falsy and was passed down to `_get_max_capacity_possible`, which then attempted to call a recordset method on a boolean value. Steps to reproduce: 1. Appointments > Dental Care 2. Select a person 3. Change the timezone 4. Observe a traceback Current behavior: `AttributeError: 'bool' object has no attribute '_get_filtered_possible_capacity_combinations'` because `filter_resources` is falsy (boolean) instead of a recordset. this fix: When `filter_resources` is falsy, compute it with `self._get_possible_resources(appointment_type, filter_resource_ids)` before calling `_get_max_capacity_possible(...)`. This guarantees a proper recordset is used and avoids calling recordset methods on a boolean. If a resource is explicitly selected, behavior is unchanged. If not, we now use the same "possible resources" logic already employed by the rest of the route. opw-5152162
Replies to signature request, confirmation, or refusal emails are now shown in the related signing record's chatter. This helps teams keep all signer communication visible in one place and reduces the risk of missed responses.
Original PR description
Previously, when users replied to sign request, signature confirmation, or refusal emails, their responses were not displayed in the corresponding sign request’s chatter. This fix ensures that replies to those emails are now properly routed and shown in the related record’s chatter. task-5105494
This fixes an issue where Mexican electronic invoice XML attachments could be saved with the wrong file type for users with limited permissions. As a result, related Documents records are created correctly when accounting centralization is enabled.
Original PR description
When creating an XML attachment as a user without Write access on the ir.ui.view model, the Mimetype will be set to plain/text. In particular, this causes issues when Accounting centralization is enabled in Documents, as the corresponding Document will only be generated if the Mimetype is application/xml. Creating the XML as Superuser avoids this issue. Similar to https://github.com/odoo/odoo/pull/124507 opw-5057038