Wednesday, October 15, 2025
40 changes · saas-18.4
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
The privacy lookup now checks for an invalid email address before starting the search. Instead of showing a technical database error, users receive a clear validation message, making the feature more reliable when contact data is incomplete or incorrect.
Original PR description
Currently, an error occurs when running a privacy lookup on a contact with an invalid email address. **Steps to reproduce:** - Install CRM modules. - Create a new contact with an invalid email…
Currently, an error occurs when running a privacy lookup on a contact with an invalid email address.
**Steps to reproduce:**
- Install CRM modules.
- Create a new contact with an invalid email address (missing @ - e.g; `demo`).
- In the contact form, click the gear icon and select "**Privacy Lookup**".
- Click on "**Lookup**" button.
**Error:**
```
UndefinedFunction
operator does not exist: character varying = boolean
LINE 55: WHERE email_normalized = false
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
```
**Cause:**
Here, Execution of the query fails because `email_normalized` is set to a Boolean value, which is being computed at [1]. And method `tools.email_normalize` returns `False` for invalid email inputs - [2].
**Fix:**
This commit raises an error if the email address is invalid before executing the query.
A similar case is already handled in the mail blacklisting module. ([Ref](https://github.com/odoo/odoo/blob/c7f86c3250c59130ae0b95c6847050d3a6fc7a6d/addons/mail/models/mail_blacklist.py#L29-L31)):
[1] - https://github.com/odoo/odoo/blob/e6c0e963c5379ba7ad8da00ba4ea6c2bb259d95c/addons/privacy_lookup/wizard/privacy_lookup_wizard.py#L49
[2] - https://github.com/odoo/odoo/blob/a729578afb7fed79aac2d622aae4da4c0917f8e5/odoo/tools/mail.py#L734-L735
sentry-6881416673
Forward-Port-Of: odoo/odoo#227697Fixed 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
Changing a user's locale can alter which day is treated as the first day of the week. This fix reloads spreadsheet pivot data after a locale update so day-of-week groupings continue to show accurate values.
Original PR description
Chaning the locale can change the first day of the week. But the normalization of the server value depends on this `locale.weekStart`, se we need to reload the pivot when the locale changes, otherwise we might display wrong values for a "day_of_week" grouping. Task: [5149508](https://www.odoo.com/web#id=5149508&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) 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#231337 Forward-Port-Of: odoo/odoo#230949
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.
This fix ensures that accounting reports stay available only to the appropriate accounting users. It helps preserve the intended access boundaries for financial reporting in the journal dashboard.
Original PR description
Forward-Port-Of: odoo/enterprise#96731
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
This fixes lunch cart behavior so placing a new order for a product only increases the quantity of the matching item still marked "To order". Already ordered items are no longer changed by mistake, keeping order quantities accurate for users and lunch administrators.
Original PR description
**Issue**
When a user has two instances of the same product in their lunch cart, one with state "To order" and one with state "Ordered", and places a new order for that product, both the "To order" and "Ordered" records have their quantity incremented. Only the "To order" record should be updated.
**Steps to Reproduce**
- Add two lunch orders for the same product: one with state "To order" and one with state "Ordered".
- Place a new order for the same product.
- Observe that both records ("To order" and "Ordered") have their quantity incremented.
**Root Cause and Changes Made**
The _find_matching_lines method does not restrict the search to orders with state "new" ("To order"). As a result, it returns all matching records for the product, regardless of their state. When update_quantity is called, it updates the quantity for all these records.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#228712The Shop Floor “Add Operator” action now uses the public employee list instead of private employee records. This prevents access warnings for users who are not allowed to view private employee profiles, keeping operator assignment smoother while respecting employee privacy rules.
Original PR description
The task 4762527 added a warning for users that were not allowed to access private employee profiles. The "Add Operator" button in mrp_workorder (Shop Floor) was relying on it. I had to change their list model from hr.employee to hr.employee.public This issues was raised by Aerospacelab in the following PR: https://github.com/odoo/odoo/pull/228623 task-5156702 Forward-Port-Of: odoo/enterprise#96745
This fix ensures Odoo Studio edits are based on the correct main view instead of accidentally inheriting from a secondary extension view. It helps prevent Studio customizations from being attached to the wrong view structure, reducing unexpected behavior when editing screens.
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 change moves a required payment method field into the core accounting module so SEPA direct debit can install or update reliably even when the separate payment app is not installed. It prevents setup failures for businesses using direct debit features and keeps accounting workflows available.
Original PR description
Odoo 18 have an error, the view `account_sepa_direct_debit.account_payment_register_form_inherit_account_sepa_direct_debit` (Enterprise) references the field `payment_method_code` from…
Odoo 18 have an error, the view `account_sepa_direct_debit.account_payment_register_form_inherit_account_sepa_direct_debit` (Enterprise) references the field `payment_method_code` from `account.payment.register`. This field is added to the model in the `account_payment` module, which is not among the dependencies of `account_sepa_direct_debit`. This means that if the `account_payment` module is not installed, the installation/update of `account_sepa_direct_debit` will also fail. To avoid this error, the field `payment_method_code` in the `account_payment` module needs to be defined instead in the `account` module. I open this PR on the recommendation of @hupo-odoo ([comment](https://github.com/odoo/enterprise/pull/96254#pullrequestreview-3310607477)). Here’s a screenshot of the error (runbot) <img width="1498" height="857" alt="runbot_account_sepa_direct_debit" src="https://github.com/user-attachments/assets/e8d66a96-59a3-4cf3-857b-e07a3337338c" /> Here’s the screenshot after changing to this commit <img width="1594" height="725" alt="image" src="https://github.com/user-attachments/assets/ea2fbe2c-31b8-4d61-8cf2-00e003ec3587" /> [OPW](https://www.odoo.com/es_ES/my/tasks/5139827) [PR enterprise](https://github.com/odoo/enterprise/pull/96254#pullrequestreview-3310607477) @moduon MT-12067 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231052
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
Document upload request emails now greet the person being asked to provide the document, instead of incorrectly using the sender or document owner's name. Invitation and reminder emails are also sent in the requestee's language, making communications clearer and more personal.
Original PR description
Currently, the email template inviting a user to upload a document displays the document owner's name in the greeting instead of the requestee's. This commit updates the template to display the correct name. Steps to reproduce: 1. Log in as Mitchell Admin 2. Go in the Document app 3. Click on the New > Request 4. Enter a document name and select Joel Willis as requestee 5. Send the request by clicking on the "Request" button => The invitation email is correctly sent to Joel Willis but it says "Hello Mitchell Admin" instead of "Hello Joel Willis" Additionally, this PR ensures that the reminders and the invitation emails are sent in the requestee's language rather than the sender's. Task-5130591 Forward-Port-Of: odoo/enterprise#96941 Forward-Port-Of: odoo/enterprise#96161
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
This change removes an unreliable automated test assertion in Discuss call testing that could fail unpredictably depending on mobile detection. It helps keep validation runs stable without changing the actual user experience.
Original PR description
Before this commit ([1]), we were testing the absence of a button for mobile, but the test can lead to undeterministic behavior as `isMobileOS` is not reactive as we do not expect a live transition of userAgent, like from desktop to mobile, so testing for this behavior is not useful. A dedicated test for call mobile was introduced in v19 ([2]) https://runbot.odoo.com/odoo/runbot.build.error/233350 [1]: https://github.com/odoo/odoo/pull/177374 [2]: https://github.com/odoo/odoo/pull/218119 Forward-Port-Of: odoo/odoo#231191
The call participant volume slider is no longer shown to users who are not currently in the call. This avoids confusing controls and keeps the call interface focused on actions that are actually available.
Original PR description
Before this PR, the volume slider for call participants was visible even when the user was not part of the call. This PR fixes the behavior by ensuring the volume slider is only available when the user is in the call. task-[5092826](https://www.odoo.com/odoo/project/1519/tasks/5092826) Forward-Port-Of: odoo/odoo#231235 Forward-Port-Of: odoo/odoo#227803
Odoo Studio no longer crashes when users create a related field that points to a monetary field on the same model. This restores the expected setup flow and helps users configure fields without interruption.
Original PR description
In studio, add a related field to a monetary on the current model (ie without dotnames) Before this commit, it crashed. This because of c57c247490f0f58c8746af47ce035c28137faf97 After this commit, the flow works as expected opw-5147572
This update fixes an unreliable automated test for discarding a mail message edit with the Escape key. It helps keep quality checks stable so future mail changes can be validated with fewer false failures.
Original PR description
Before this commit, test "discard on pressing escape" failed non-deterministically with the following error: ``` Failed to find 0 of ".o-mail-Composer" (Timeout of 3 seconds). Found 1 instead. ``` This happens at the very last step of the test: we click on composer of message to have the focus, so that we can then press ESCAPE and discard the editing of message and thus remove the composer. The issue happens because while we click on composer, we don't await the composer being logically focused, which is necessary for the good working of the ESCAPE feature to discard the message editing. This commit fixes the issue by awaiting the composer is logically focused after click on composer, so that pressing ESCAPE is properly expected to cancel the editing and thus remove the composer. Fix runbot-error-233394 Forward-Port-Of: odoo/odoo#231431
The date picker now clearly shows when date cells are disabled and cannot be selected. This reduces confusion for users by making unavailable dates visually distinct after a recent interface change.
Original PR description
In this commit fa3bfb0a696c20ae51cd0f37f737fcf211007c4a, the o_date_item_cell was changed from a button to a div. This made the style of disabled cells not show that its not unclickable, making it confusing for users. Solution is to add specific style for the disbaled o_date_item_cell component. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231249
Fixed an issue where clicking to zoom a product image could show an error when the product had only one image. This keeps the shopping experience smooth for customers using product pages with zoom enabled.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Enable zoom-on-click on product page; 2. have a product page with only a single image; 3. click on the image. Issue ----- > Odoo Client Error > Caused by: TypeError: can't access property "addEventListener", carousel is null Cause ----- Commit 83b79c198eac added event listeners to make the carousel interactive. Issue is that the carousel element doesn't exist in the DOM if there's no extra media. Solution -------- Check if the carousel element exists before adding event listeners. opw-4937009 Forward-Port-Of: odoo/odoo#230795
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 fix removes leftover sidebar spacing when a website's sidebar-style header is hidden. It prevents page content from appearing incorrectly shifted, keeping edited website layouts consistent for visitors and editors.
Original PR description
Steps to reproduce the issue: - In edit mode, change the header template to use the "Sidebar" header (=> since it is a sidebar, the page content is shifted to the right) - Go to the theme tab and toggle the "Show Header" option so the header is removed => Bug: the page content is still shifted as if the sidebar were still present. This happens because the page still has padding-left for the header, although there's no header. task-5131064 Forward-Port-Of: odoo/odoo#229860
This fix keeps custom field name checks flexible without adding unnecessary processing overhead. It helps preserve expected customization behavior while improving internal efficiency and stability.
Original PR description
The use of IrModelFields method `is_manual_name` was [reverted](https://github.com/odoo/odoo/pull/212579) for the sake of efficiency and avoiding instanciating models when not really needed. The use of an overridable method is still needed ([reference](https://github.com/odoo/odoo/pull/145154)). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website editor now keeps document icons visible when translating pages into another language. This prevents missing file previews and helps editors confidently manage multilingual website content.
Original PR description
This commit permits to keep document icon visible during the translation of a website page. Steps to reproduce the issue: - Have a website in English (main) and French - Edit the website in the main lang (English) - Drop Image text block - Change the image to a document - Save - Edit the translation in French => The document logo becomes invisible. This commit fixes this issue. task-3626918 Forward-Port-Of: odoo/odoo#165109
New timesheets added to helpdesk tickets now appear immediately in the expected newest-to-oldest order. This removes the need to refresh the page to see the correct ordering, making ticket time tracking smoother for users.
Original PR description
In version saas-18.3 and later, when creating new timesheets for helpdesk tickets, they are added to the bottom of the list instead of being sorted from newest to oldest. **Steps to reproduce:** 1.…
In version saas-18.3 and later, when creating new timesheets for helpdesk tickets, they are added to the bottom of the list instead of being sorted from newest to oldest. **Steps to reproduce:** 1. Install helpdesk_sale_timesheet 2. Navigate to Helpdesk > Tickets > Timesheets 3. Create a new timesheet **Issue:** The timesheet is added to the very bottom of the list. It is not sorted from newest to oldest until the form view is refreshed. **Causes:** When helpdesk_sale_timesheet module is installed, an issue occurs. The overridden `write()` method on `helpdesk.ticket` accesses `self.timesheet_ids` too early, before the new timesheet is actually added, resulting in the new entry being appended at the end of the list. **Solution:** Avoid evaluating `self.timesheet_ids` when there is no need to process recompute_so_lines. This prevents premature evaluation and allows the ORM to attach and sort the new timesheet correctly, ensuring it appears in the expected order without requiring a form refresh. [opw-4864981](https://www.odoo.com/odoo/project.task/project.task/4864981) Forward-Port-Of: odoo/enterprise#94369
Project budget totals now use the same color logic as individual budget lines. This prevents expense budgets with positive amounts from showing misleading status colors on dashboards and project cards.
Original PR description
#### Issue: - Color for project budget and total project budgets are inconsistent #### Step to reproduce: - In Settings: - activate Project > Timesheet - activate Accounting > Budget Management - Create a project - Go to Dashboard - Add a budget of type 'Expense' - Add a line with a positive amount #### Current Behavior: - Color for the budget is correct - Color for the total budget is wrong #### Expected behavior: - Color for the budget and total budget are consistent While computing budget color, expense budget are dealt as if they were negative. Therefore having a positive amount for purchase order result in some problem on the color of the total of different budgets. This commit creates temporary variables to compute progress of the global budget. Project cards in kanban view use the `total_budget_progress` field, so it also needed to be updated the same way. opw-4812468 Forward-Port-Of: odoo/enterprise#93221
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
Opening the website editor on the login page no longer incorrectly marks the page as modified. This prevents unnecessary dirty-state warnings and keeps the editing experience clearer, while hiding an already unusable user-switch button during editing.
Original PR description
Before this commit, part of the `/web/login` page was immediately marked as dirty when the editor opened. This happened because `UserSwitch` component used a `t-portal` directive that rendered an element outside the `owl-component` tag, causing it to be tracked by the mutation observer. After this commit, the `t-portal` directive is ignored when in edit mode. A side effect of this solution is that the "Choose a user" button is hidden during editing, but this button was already non-editable and non-clickable during edit. **How to reproduce the problem** 1. Navigate to "/web/login" 2. Activate edit mode 3. The "o_dirty" class is present in the login form
Restaurant point-of-sale orders now keep combo meals intact when staff move an item to another course. This prevents part of a combo from being separated, reducing order mistakes and improving service flow.
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
This change makes web editor test results consistent by explicitly setting a border color instead of relying on environment defaults. It helps prevent false build failures in automated testing, improving release reliability without changing user-facing behavior.
Original PR description
Problem: Runbot build fails due to different resulting `border-color` values. Cause: The default `border-color` can change depending on the environment, leading to non-deterministic behavior. Solution: Specify the `border-color` explicitly to ensure consistent results. runbot-233297 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231003
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
This fix prevents Point of Sale session numbers from being used up when cash posting fails. Businesses will see cleaner, continuous session names, making daily cash control and audit trails easier to follow.
Original PR description
Before this commit, if an issue occurred while posting the cash details, the session sequence would still increment even though the operation failed, leading to gaps in session names. With this commit, the sequence only increments when the operation succeeds, ensuring continuous session naming without gaps. opw-5100163 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229834 Forward-Port-Of: odoo/odoo#229532
This fix prevents the Point of Sale from failing to reload when a previously loaded customer record has been deleted. It helps keep checkout operations running smoothly even when customer data changes in the background.
Original PR description
Before this commit, if a previously loaded partner was deleted from the database, reloading the PoS would trigger an error because the partner record could no longer be found. opw-5137871 Forward-Port-Of: odoo/enterprise#96491
Users assigned to tasks in private projects can now print or export their own timesheets without seeing an access error. This removes an inconsistent blockage while keeping access aligned with information already visible 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 Forward-Port-Of: odoo/odoo#231188