Monday, September 15, 2025
18 changes · saas-18.4
Enhancements to existing features
Invoices created from sales orders now keep the sales order name as the customer reference when no customer reference already exists. This helps businesses match invoices and prepayments more reliably while reducing incorrect payment matches caused by customer names in payment memos.
Original PR description
Unless there's already a customer reference, we need the SO name to be able to match any prepayment --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224999
Point of Sale users can now reopen combo and configurable items directly from the order, adjust their choices, and discard changes if needed. Matching edited items are automatically combined to keep orders cleaner, while custom text and combo pricing are preserved more reliably after edits or page refreshes.
Original PR description
Task: [#4890396](https://www.odoo.com/odoo/my-tasks/4890396) Community PR: [#221924](https://github.com/odoo/odoo/pull/221924) --- Improves the POS experience by allowing users to reopen and edit…
Task: [#4890396](https://www.odoo.com/odoo/my-tasks/4890396) Community PR: [#221924](https://github.com/odoo/odoo/pull/221924) --- Improves the POS experience by allowing users to reopen and edit configurable and combo products directly from their orderlines. When a product is edited to match another existing line, the lines are automatically merged to avoid duplicates. - Introduced `useTimedPress` to support both click and long press interactions. - Reopening a configurator now pre-fills default attributes, custom values, and combo selections. - Removed click delay when selecting an orderline, improving responsiveness. - Extracted logic for configurator, combo choice, unit price computation, and orderline merging from `addProductToOrder` into dedicated functions (`tryMergeOrderline`, etc.) for reuse across the codebase. --- The Combo/Product Configurator popups no longer receive default values directly. Instead, they now work with the orderline passed as a prop. ** Combo Configurator Popup ** - Use `props.line.selectedComboIds` as the source for default values. - Save the initial `state.combo` so it can be restored on discard. - Add a **Discard** button in the popup footer. ** Product Configurator Popup ** - Use `props.line.selectedAttributes` for the default values. - If there is no orderline like new combo item, fall back to `props.comboItem?.saveStateAttributes`. - Save the initial `state.selectedAttributes` so it can be restored on discard. - Expose `selectedAttributes` on `pos.orderline` as a function so it can be recomputed at any time. ** Bug Fix: Price ** - Fixed a bug where updating a combo item directly from the Order Summary used the wrong price (ignoring the combo). - We now open the **Combo Configurator** instead of the **Product Configurator** when editing a combo item from the Order Summary. --- When refreshing the page, we also lose the `free text` of the `custom_attribute_value`. By adding the model `product.attribute.custom.value` to the `get databaseTable()` from `DataServiceOptions`, we ensure that the records are saved in IndexedDB Forward-Port-Of: odoo/odoo#227097 Forward-Port-Of: odoo/odoo#221924
Resolved issues and error corrections
Imported sales orders now keep the original price when a product from a purchase request cannot be matched in the sales database. This prevents affected order lines from incorrectly showing a zero price, helping sales teams avoid underbilling and manual corrections.
Original PR description
Steps: - Install Purchase in first db and sale in second db. - Ensure RFQ contain product which does not exist in second db. - Export RFQ and import it in sale order view. Issue: - Price is always 0 on sol if it didn't find related product. Cause: - In [this] PR we always recompute price on all sol instead sol with product Fix: - Recompute price and discount only on sol with product. [this]: https://github.com/odoo/odoo/pull/190310
This fixes an issue in Odoo Studio where choosing a measure for a cohort view could trigger an error because the list showed incompatible fields. It also removes an unnecessary request parameter that caused warning messages when creating new views.
Original PR description
Currently, an error occurs when user tries to select any measure in cohort view. Steps to replicate: - Install `sale_management` and `web_studio`. - Open the Sales app and turn on studio mode. -…
Currently, an error occurs when user tries to select any measure in cohort view. Steps to replicate: - Install `sale_management` and `web_studio`. - Open the Sales app and turn on studio mode. - Under the Views tab, turn on cohort view. - Under the Measures field, select any value and observe the error appearing in the terminal. Error: `ValueError: Invalid aggregate method 'None' for 'create_date:None'` Cause: - The Measure field dropdown in the Cohort Editor was mistakenly assigned the choices of `dateFields` [1] instead of `measureFields`. - This allowed users to select incompatible field types (e.g., date/datetime), which lead to error in aggregation behavior in the cohort view. Solution: - Corrected the choices of Measure field to `measureFields`. - Also added a condition to allow only those fields that have an aggregator (for some fields like `sequence` that dont have an aggregator). - Also removed context field from arguments [2] in the rpc call as function doesnt need it [3] (This shows warning on runbot as well). [1]: https://github.com/odoo/enterprise/blob/d8539dff5f3dcecfeb99fd7fc22a6915aaa02c4b/web_studio/static/src/client_action/view_editor/editors/cohort/cohort_editor_sidebar.xml#L30 [2]: https://github.com/odoo/enterprise/blob/bf9510e152279418200cb0becb6b637c19b02d4e/web_studio/static/src/client_action/editor/new_view_dialogs/new_view_dialog.js#L87 [3]: https://github.com/odoo/enterprise/blob/bf9510e152279418200cb0becb6b637c19b02d4e/web_studio/controllers/main.py#L805 sentry-6781792463 Forward-Port-Of: odoo/enterprise#94450 Forward-Port-Of: odoo/enterprise#91599
Changing an expense product's policy no longer recalculates and overwrites the analytic distribution on existing expenses. This preserves previously entered expense analytics while still applying the correct default analytics to newly created expenses.
Original PR description
When changing the expense policy of an expense product, the compute of analytic distribution of all expenses linked to the product is triggered. Steps: - Have an expense product X with expense policy…
When changing the expense policy of an expense product, the compute of analytic distribution of all expenses linked to the product is triggered. Steps: - Have an expense product X with expense policy 'at_sales' - Create several expenses with an expense product X and any analytic account - Create an analytic distribution model that link the expense account of X with a specific analytic account AA - Create a new expense for product X, the analytic account AA should be set from the distribution model - Go to the form view of product x and change the expense policy to 'cost' - Go back to the expense list view -> All expenses having the product X have the AA account Cause: `sale_order_id` has been added to the `depends` of `hr_expense._compute_analytic_distribution` by 2b3bf5e0fe31d4b4ef6b487da493657f695b14e1 but this wrong since we have the `sale_expense._onchange_sale_order_id` that add the `analytic_dostribution` field to the fields to be computed. The compute is triggered since we change `product_id.expense_policy`, which triggers the `_compute_can_be_reinvoiced` which triggers the `_compute_sale_order_id` Fix: With this commit, we emove the depends on the compute and we also adapt `test_compute_analytic_distribution_expense` in a way that it triggers the onchange as we do in the original flow. opw-4998899 Forward-Port-Of: odoo/odoo#226864 Forward-Port-Of: odoo/odoo#224226
Indonesian e-Faktur downloads no longer fail when an invoice line has multiple non-luxury taxes. This prevents a crash during document export and helps users complete compliant invoicing without manual workarounds.
Original PR description
The system crashes with an error when a user tries to `download the e-Faktur` document. **Steps to produce:-** - Install `Accounting` and switch to `ID Company`(with demo data). - Create a `new…
The system crashes with an error when a user tries to `download the e-Faktur` document.
**Steps to produce:-**
- Install `Accounting` and switch to `ID Company`(with demo data).
- Create a `new invoice` and select customer as `ID Company`.
- Add the product and in `taxes add 11% and 0% (2 non-luxury taxes)` and confirm the invoice.
- Click on gear icon and click on `Download e-Faktur` button.
**Error:-**
`ValueError: ValueError('Expected singleton: account.tax(5, 15)') while
evaluating 'action = records.download_efaktur()'`
**Root cause:-**
- When more than one non-luxury tax is applied and the e-Faktur document is downloading, the code at [1] expects a single tax record, but multiple non-luxury taxes are found.
**Solution:-**
- Since luxury tax is already excluded from the regular tax computation at [2], I think we can directly sum all non-luxury taxes.
[1]: https://github.com/odoo/odoo/blob/52aa6231130ea165fdb44e6370ec3e396b7603cc/addons/l10n_id_efaktur_coretax/models/account_move_line.py#L52
[2]: https://github.com/odoo/odoo/blob/52aa6231130ea165fdb44e6370ec3e396b7603cc/addons/l10n_id_efaktur_coretax/models/account_move_line.py#L24-L25
**sentry-6837559933**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#224419Appointment booking notification emails are now limited to the staff followers who need to know a new appointment was created. This prevents appointment attendees from receiving an internal “Appointment Booked” email that was not meant for them, reducing confusion and improving communication accuracy.
Original PR description
[1] introduces the new paradigm of always sending emails to "relevant recipients" which fetches emails and partners linked to the relevant record to send a message.
In appointment the "Appointment Booked" template is only meant to be sent to followers of `mt{_calendar,_appointment}_event_booked` to inform users that a new appointment was created even if they are not personally assigned to it.
`test_request_meeting_message_for_manual_confirmation` is also updated to represent the case of some visitor creating booking an appointment instead of using internal users for everything to better represent real use cases. Additionally each mail.mail record is extracted and checked individually to make sure we send the right contents to the right recipients.
[1]: 1dd6070ecaab385446cc2df7cad444f046812061
task-5075513
task-4711415
Forward-Port-Of: odoo/enterprise#94456This fix restores fast processing when Odoo determines who should receive mail notifications. It removes a slowdown introduced by a previous change, helping messaging-related actions respond more quickly without adding extra database load.
Original PR description
The commit 2e63fe11624b8abd9205ae94b6721fce660751db introduced a severe performance regression in some SQL query, going from 1.2ms to 450ms! Instead of computing the transitive closure of collected groups in pure SQL with a "WITH RECURSIVE", we use the computed field all_implied_ids. As the latter is based on ormcache'd data, the new solution has no marginal cost in terms of SQL queries.
This fix makes the Send button in Odoo's messaging composer respond reliably when used from the iOS progressive web app. It prevents the message box from shifting at the moment of tapping Send, reducing missed sends in Discuss and chatter conversations.
Original PR description
Before this commit, when using IOS PWA, pressing 'Send' button of in composer in discuss or chatter would sometimes not register the send. This happens because in IOS PWA, the composer has a bottom margin as this is close to iOS persistent swipe bar. However, the margin should not be present when there's the soft-keyboard. Because of this dynamic margin based on input focus, when composing textual message and pressing "Send" button, the textarea looses focus and a fraction of second the margin-bottom is increased and moves the "Send" button. This leads to mis-clicking the "Send" button. This commit removes the margin-bottom rule on non-focusin of textarea with iOS PWA. The composer is close to swipe bar so that's not as elegant as before, but at least this doesn't add the problem of non- working "Send" button. opw-5028809 Forward-Port-Of: odoo/odoo#226881 Forward-Port-Of: odoo/odoo#226546
This fixes an issue where embedded Odoo pages, such as livechat, could fail because the web client tried to access browser window information that may be restricted. The change helps avoid access violations in cross-origin or sandboxed contexts, improving reliability for embedded experiences.
Original PR description
This [commit] introduced a cross-origin/sandbox access violation. `window.top` properties must never be accessed without guarding. Known issue: embedded livechat. [commit]: https://github.com/odoo/odoo/commit/27a85d650dee8345a4ec701bf7456eec07851718 task-5083154
The Time Off request dialog now shows the Submit Request button when there is no dashboard warning message available. This prevents employees or HR users from being blocked when creating absence requests in the Swiss payroll transmission setup, while keeping the usual validation after submission.
Original PR description
**Steps to reproduce** 1. Install l10n_ch_hr_payroll_elm_transmission 2. Go to an employee's profile 3. Click on "Absences" smart button 4. Create a new Time Off request Issue: the form view dialog is missing a button to confirm the request. Cause: the dashboard warning message is not part of the l10n_ch_hr_payroll_elm_transmission view. Solution: display the "Submit Request" button if we don't have any dashboard warning message. There will still be a validation after the request is submitted. opw-4972467 Forward-Port-Of: odoo/odoo#221427
This fixes an issue where a point of sale order could remain stuck when a cashier refreshed the browser before cancelling a Worldline terminal payment. The POS now continues to receive the terminal cancellation confirmation, reducing checkout interruptions and manual recovery work.
Original PR description
This PR fixes a bug where the point of sale didn't receive notifications from the Worldline payment terminal for the cancellations if the browser webpage was refreshed How to reproduce: 1. Open a POS session with Worldline terminal 2. Send a transaction to the terminal 3. Refresh the browser webpage before paying 4. Click on "Cancel" on the POS screen --> your order will be stuck and never receive the confirmation This PR removes the check for the iot longpolling action identifier which changes on refresh of the webpage + adds more error messages for Worldline terminals Related PR in v17 -> saas-18.2: https://github.com/odoo/enterprise/pull/94635 task-5075860 Forward-Port-Of: odoo/enterprise#94629
Bank reconciliation can now match payments to shorter sales order references such as SO0001. This helps reduce missed matches and manual reconciliation work for accounting teams.
Original PR description
Matching on references was limited to matching words > 8, to increase reliability, but the default sequence for sale orders is 6 characters (SO0001), so they would never be found unless we reach SO1000000 -_- Forward-Port-Of: odoo/enterprise#93640
Reloading a page now keeps users in the correct app menu instead of switching to another menu that uses the same underlying action. This prevents confusion when navigating shared customer or partner screens across Sales, Invoicing, and Purchase.
Original PR description
* STEP TO REPRODUCE: install sale management module, go to sale app -> customer menu -> Then reloading the page using F5 -> the menu is change to invoice which is not correct * Also Multiple modules (Sale, Account, Purchase) share same actions (e.g. partner action) * SOLUTION: Modified webclient.js action-to-menu mapping to handle multiple menus sharing same action 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#226391 Forward-Port-Of: odoo/odoo#225984
Reloading a page could show the wrong application menu when several apps shared the same customer or partner screen. This fix keeps users in the correct menu context, reducing confusion when navigating Sales, Accounting, or Purchasing pages.
Original PR description
* STEP TO REPRODUCE: install sale management module, go to sale app -> customer menu -> Then reloading the page using F5 -> the menu is change to invoice which is not correct * Also Multiple modules (Sale, Account, Purchase) share same actions (e.g. partner action) * SOLUTION: - Modified webclient.js action-to-menu mapping to handle multiple menus sharing same action Forward-Port-Of: odoo/enterprise#94485
Moving documents to a previously visited folder no longer accidentally removes access for existing members. This helps ensure authorized users keep the document permissions they were given, avoiding unnecessary access issues after organizing files.
Original PR description
When moving documents with members to a folder which has been visited by those same members (or some of them) they are removed from those documents access. This is caused by the document.access which has an entry for the members but with a null role. Task-5075196 Forward-Port-Of: odoo/enterprise#94684 Forward-Port-Of: odoo/enterprise#94149
This fixes a problem where a manually opened Kanban column could fail to reopen after users left and returned to the view, causing an error. Users can now resume their work without crashes, even when many grouped columns are already open.
Original PR description
[FIX] web: Fix opened groups of web_read_group This commit fixes an issue where groups manually opened by the user were not correctly restored, leading to a traceback. Steps to reproduce: In a kanban views, when we have already 10 columns opened automatically and others closed ones: - Manually open a closed group after the first 10 opened groups. - Navigate to another view. - Return to the kanban view. We got a traceback: `TypeError: can't access property "map", data.records is undefined` The `web_read_group` function does not reopen the manually opened group when the `MAX_NUMBER_OPENED_GROUPS` limit has been reached. The web client does not handle this case gracefully, as it expects the manually opened group to still be opened. Solution: Manually opened groups should remain open regardless of the `MAX_NUMBER_OPENED_GROUPS` limit. This approach is more functionally sound and aligns with the behavior the web client expects.
The workcenter planning view now shows the actual working hours defined for each workcenter instead of always displaying a full 24-hour day. This gives manufacturing teams a clearer view of available capacity and helps them schedule work orders more reliably.
Original PR description
## **Issue Before This Commit:** In the workcenter planning view, the total hours displayed were misleading, as they always showed 24 hours of the day instead of the workcenter’s defined working…
## **Issue Before This Commit:** In the workcenter planning view, the total hours displayed were misleading, as they always showed 24 hours of the day instead of the workcenter’s defined working hours. This caused confusion for users since the displayed total hours did not match the actual available working time of the workcenter. ## **Steps to Reproduce:** - Create a Manufacturing Order (MO). - Add "Drawer" as the product. - Add a "SEC-ASSEM: [FURN_8855] Drawer" BOM. - Set the quantity to produce as 10. - Confirm the MO and plan it. - Open the planning view and notice that the total hours count incorrectly shows 24 hours instead of the defined working hours. ## **Cause of the issue:** The bug was introduced by this PR (https://github.com/odoo/odoo/pull/205486), as the related changes were not adapted here. Because of that, pill.record.workcenter_id[0] returns an undefined value. ## **With This Commit:** The calculation of total hours has been corrected to consider only the workcenter’s defined working hours. Users now see accurate hours in the planning view, making it easier to plan and schedule work orders reliably. task - 4900885