Thursday, August 20, 2026
26 changes · saas-19.4
Resolved issues and error corrections
This update brings the spreadsheet component to a newer version with several usability fixes. It improves sorting with header rows, respects local decimal formatting, avoids unwanted dark-mode changes on inserted images, and simplifies chart editing behavior.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/9dd828e429 [REL] 19.4.8 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/9dd828e429 [REL] 19.4.8 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/7c79c67ca0 [FIX] filter_menu: take number of headers into account when sorting [Task: 6471792](https://www.odoo.com/odoo/2328/tasks/6471792) https://github.com/odoo/o-spreadsheet/commit/02ca371616 [IMP] claude: add gitignore for claude local settings [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/0646064cc2 [FIX] toLocaleString : new helper to use the locale's decimal separator [Task: 6232818](https://www.odoo.com/odoo/2328/tasks/6232818) https://github.com/odoo/o-spreadsheet/commit/8df07994f4 [FIX] toLocaleString : new helper to use the locale's decimal separator [Task: 6232818](https://www.odoo.com/odoo/2328/tasks/6232818) https://github.com/odoo/o-spreadsheet/commit/cc5271d66c [FIX] ChartMenu: hide region selection in edit mode [Task: 6441988](https://www.odoo.com/odoo/2328/tasks/6441988) https://github.com/odoo/o-spreadsheet/commit/398bc59d15 [FIX] Image: Do not apply dark mode to inserted images [Task: 6421550](https://www.odoo.com/odoo/2328/tasks/6421550) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
Italian electronic invoicing now better supports simplified invoices, including stamp duty details and the ability to force simplified exports when the invoice type requires it. The update also prevents simplified invoices from being used for public administration or non-domestic partners, reducing compliance errors.
Original PR description
- Added the BolloVirtuale in the Simplified invoice template - Now it's possible to force the Simplified format on exported invoice when the `l10n_it_document_type` is set to a simplified one - Factored the Italian partner recognition (_l10n_it_edi_is_italian) - Added a check on the invoice, no simplified format for non-domestic / PA partners Task [link](https://www.odoo.com/odoo/project.task/6226436) task-6226436 Forward-Port-Of: odoo/odoo#283154 Forward-Port-Of: odoo/odoo#274493
Archiving an accounting journal with draft entries now directs users to a reachable list of those draft entries. This prevents confusion from an empty or misleading list and helps users resolve the blocking entries before archiving.
Original PR description
> Replaces https://github.com/odoo/odoo/pull/282286, which GitHub closed automatically after a bad force-push on my side: the branch was pushed from a shallow clone and its head lost its parent…
> Replaces https://github.com/odoo/odoo/pull/282286, which GitHub closed automatically after a bad force-push on my side: the branch was pushed from a shallow clone and its head lost its parent commit, leaving no common ancestor with 18.0. A PR in that state cannot be reopened, so this one continues from a clean branch with the exact same change. The review discussion is in that PR, and the rename asked for there is included here. ### Steps to reproduce 1. Go to `Accounting > Customers > Invoices` and create an invoice on a given journal, leaving it in draft. For the clearest case, leave it with no invoice line. 2. Go to `Accounting > Configuration > Journals`, open that journal and archive it. 3. `_check_auto_post_draft_entries` raises: *"You can not archive a journal containing draft journal entries. To proceed: 1/ click on the top-right button 'Journal Entries' from this journal form 2/ then filter on 'Draft' entries 3/ select them all and post or delete them through the action menu"*. 4. Follow those steps: click the `Journal Entries` smart button on the journal form. ### Current behaviour The list comes up empty, so the user concludes the error message is wrong, while the draft entries do exist. The instructions cannot be followed: - The smart button opens `action_account_moves_all_a`, which is named **"Journal Items"** and targets **`account.move.line`**, not `account.move`. The label of the button and the name of the action it opens do not match. - That action defaults to `search_default_posted: 1`, so no draft record is listed. - Draft entries with **no line at all** — commonly created through the incoming mail alias of a journal — have no `account.move.line`, so they stay invisible in that view even after switching the filter. - The action menu of a move line list offers no way to post or delete the entries, and the action sets `create: 0`. - The filter is labelled **"Unposted"**, not "Draft". The offending entries are only reachable through `Accounting > Accounting > Journal Entries`, filtering by journal and by "Unposted". ### Expected behaviour The error should point to a view where the records blocking the archiving are actually listed and actionable. ### This PR Two changes, the validation itself is unchanged: - The error message now points to `Accounting > Accounting > Journal Entries` and uses the real filter name, "Unposted". - The smart button of the journal form is renamed to **"Journal Items"**, so its label matches the action it opens and no longer suggests it lists journal entries. This was asked for in the review of the previous PR. Targeted at 18.0 because that is where the misleading message is being hit in practice; it is identical on 19.0 and master. If a translatable string change does not qualify for the stable series, tell me and I will retarget to master. Forward-Port-Of: odoo/odoo#282956
This fix prevents the new Analytic Distribution model dialog from closing unexpectedly when users bulk-edit several journal items. It ensures users can complete and save a new distribution model during multi-edit workflows, avoiding failed or interrupted data entry.
Original PR description
When mass-editing the Analytic Distribution field on several records at once, and creating a new distribution at once, will close the creation dialog before the user could fill it in. Steps to reproduce: - Enable Analytic Accounting - Open Accounting > Journal Items - Enable the Analytic Distribution column - Select 2 journal items and click on the Analytic Distribution - Click on 'Update', fill a distribution, then click "New Model" - Confirm the multi-edit update Issue: The create Analytic Distribution model dialog closes on its own instead of staying open, so the model can never be saved. Analysis: After https://github.com/odoo/odoo/commit/12a61fa5ab7c56a42020c50c683df8ed52f1fb01, in multi-edit, save() ends reloading the list, unmounting the AnalyticDistribution widget, that closes the model dialog it just opened. opw-6405219 Forward-Port-Of: odoo/odoo#281141
Invoices for dropshipped products with serial or lot tracking now show only the items that were actually invoiced after a return. This prevents customers from seeing returned serial or lot numbers on invoice PDFs, improving document accuracy.
Original PR description
**Issue** Printing an invoice for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report. **Steps to reproduce** - Activate "Display Lots & Serial…
**Issue**
Printing an invoice for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report.
**Steps to reproduce**
- Activate "Display Lots & Serial Numbers on Invoices"
- Create a product tracked by serial/lot and enable the dropship route
- Create two lots: "lot1" and "lot2"
- Create and confirm a SO for quantity 2
- Confirm the PO and validate the dropship for both lots
- Create and post an invoice
- Return "lot2" from the dropship picking
- Create and post a credit note for quantity 1
- Click on print on the invoice
-> The generated PDF displays "lot1 & lot2" instead of "lot1"
**Cause**
While rendering `account.report_invoice_with_payments`, the report calls `_get_invoiced_lot_values` to determine which lot/serial numbers should be displayed:
https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L31-L32 `invoiced_qties = 2` since the invoice is on a quantity of 2 https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L44 Three stock move lines are retrieved from the SO:
- the two original dropship deliveries,
- the return move for `lot2`. https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L63 However, none of them are considered as `is_stock_return` because the dropship locations use `supplier` instead of `internal`: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L72-L76 As a consequence:
- The two original delivery move lines each keep quantity `1`: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L69 they never pass through the return handling logic (as they should be): https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L77-L80
- for the last one, `is_stock_return = False` while it should not, thus the quantity is 1 instead of 0. Furthermore, it does not pass by this code:
https://github.com/odoo/odoo/blob/8759429547e42e9f63b15a7c80475be46ef437e2/addons/sale_stock/models/account_move.py#L79 which would make the quantity for lot2 equalled to 0 (1-1) The quantities are therefore accumulated as:
https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L92
resulting in:
`qties_per_lot = {lot1: 1, lot2: 2}`
instead of:
`qties_per_lot = {lot1: 1, lot2: 0}`
The report selects both lots since it starts with lot1 (qty of 1): https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L94-L99
opw-6236855
Forward-Port-Of: odoo/odoo#271282
Forward-Port-Of: odoo/odoo#270599DIN 5008 PDF documents for Germany, Austria, and Switzerland now display dates in the expected day.month.year format, regardless of the user's language settings. This prevents invoices, quotations, purchase orders, and related reports from showing confusing or non-localized date formats.
Original PR description
* = din5008, din5008_purchase, din5008_repair, din5008_sale **Steps to reproduce:** * Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`) * Set the document layout…
This fixes an error that could block French branch companies from saving Electronic Invoicing (PDP) settings when participating in the pilot phase. The change ensures branches correctly use their parent company's accounting setup, preventing a crash during activation.
Original PR description
**Steps to reproduce:** * Create a **French** parent company and a branch. * Activate **Electronic Invoicing (PDP)** for the parent company. * Switch to the branch while keeping both the **parent…
**Steps to reproduce:**
* Create a **French** parent company and a branch.
* Activate **Electronic Invoicing (PDP)** for the parent company.
* Switch to the branch while keeping both the **parent company** and the **branch** selected in the company switcher.
* Go to **Settings → French Localization → Activate Electronic Invoicing**.
* Activate **Electronic Invoicing (PDP)** for the branch.
* Select the **Participate in the pilot phase** checkbox and try to save settings.
**Observed behavior:**
* A traceback occurs with the error: `psycopg2.errors.SyntaxError: syntax error at or near ")"` on `IN ()` in the SQL query inside `_force_update_l10n_fr_f10_moves`.
**Cause:**
* `_force_update_l10n_fr_f10_moves` searches for receivable/payable accounts using `company_ids IN companies.ids`.
* A branch company has no accounts assigned directly to it — accounts belong to the parent company — so the search returns an empty list.
* Passing an empty tuple to `IN %(account_ids)s` generates `IN ()`, which is invalid PostgreSQL syntax.
**Fix:**
* Replace `('company_ids', 'in', companies.ids)` with
`('company_ids', 'parent_of', companies.ids)` in the account search
inside `_force_update_l10n_fr_f10_moves`.
* This ensures that accounts owned by a parent company are correctly
found when the given companies are branches, since branch companies
inherit their parent's chart of accounts.
opw-6394650
Forward-Port-Of: odoo/odoo#282849
Forward-Port-Of: odoo/odoo#277232Fixes checkout address selection so store pickup locations no longer appear as customer delivery addresses. This prevents confusion when customers review or edit contact details after choosing in-store pickup, while keeping normal saved delivery addresses available.
Original PR description
Steps to produce: --- - Install `website_sale_collect` module. - Create and publish a product. - Add it to the cart and proceed to checkout. - Fill in the address and confirm. - Select a `pick-up in…
Steps to produce: --- - Install `website_sale_collect` module. - Create and publish a product. - Add it to the cart and proceed to checkout. - Fill in the address and confirm. - Select a `pick-up in store` delivery method. - Click the edit icon on the contact details. - Confirm without making any changes. Issue: --- - The pick-up point address appears as a selectable delivery address in the contact details list, which it should not. Root cause: --- - When a pick-up point is selected, `set_pickup_location` calls `_address_from_json` ([1]), which creates a child `res.partner` record with `type='delivery'` and sets `pickup_delivery_method_id` to identify it as a pick-up point address. Later, when the user returns to the address page, `_prepare_address_data` calls `_get_delivery_address_domain` ([2]) from `portal`. This method returns all child partners with `type='delivery'` without distinguishing between user-created delivery addresses and the auto-generated pick-up point addresses As a result, the pick-up point address incorrectly appears in the checkout address list. Solution: --- - As specified in [task], partners created through this flow should be archived. However, in the referenced [commit], the `active=False` flag was removed when creating the partner, causing newly created partners to remain active. Override `_get_delivery_address_domain` to exclude pick-up point addresses. Since auto-generated pick-up point addresses always have `pickup_delivery_method_id` set, they are filtered out from the checkout address list, while manually created delivery addresses remain unaffected. [1]https://github.com/odoo/odoo/blob/fb6298e50a7c8ded2800254e8715336eeb37deb5/addons/website_sale_stock/models/res_partner.py#L16-L72 [2]https://github.com/odoo/odoo/blob/fb6298e50a7c8ded2800254e8715336eeb37deb5/addons/portal/models/res_partner.py#L51-L55 [task]: https://www.odoo.com/odoo/project/49/tasks/3645144 [commit]: https://github.com/odoo/odoo/commit/fb74a371407ee19c6b1a3ab9f5a7b314978cb5cb opw-6356778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276148
Payroll employee searches now stay within the companies selected by the user, preventing employees from other companies from appearing in planning views. This avoids access errors in the Gantt view and makes payroll scheduling data more consistent with the active company context.
Original PR description
Before this change, searching on hr.employee could return either employees from the selected company_ids, or employees managed by the current user. This means that sometimes, employees not in the currently selected company_ids could be shown (e.g.: on the gantt view). This caused issues, like, if on the gantt view, it shows employees from outside the company, then the gantt view will try to access the employee's resource (to get their unavailabilities). Since `resource.resource` is scoped only based on the company_ids, then we don't have the right to access them -> this leads to a traceback Since it makes little sense to show employees from outside the companies we selected (it should filter them!), I removed that from the domain in the `ir.access.csv` file Tests (of the gantt bug) have been added in enterprise. task-5502544 Forward-Port-Of: odoo/odoo#280052
French e-invoicing eligibility now checks a customer's valid SIREN or SIRET number instead of relying only on a VAT number. This prevents French business customers without VAT details from being incorrectly treated as consumers, keeping the e-invoicing option available when appropriate.
Original PR description
**Steps to reproduce:** - Install module `l10n_fr_pdp` and configure French e-Invoicing. - Create a customer has a valid SIREN/SIRET (company_registry) but no VAT number. - Create an invoice for the customer and confirm the invoice. - Check the available sending methods. **Observed Behavior:** The French E-Invoicing option is disabled because the customer is identified as a B2C partner when no VAT number is set. **Cause**: The B2C detection relies on the partner's VAT number instead of its SIREN/SIRET. As a result, French companies without a VAT number but with a valid SIREN are classified as B2C. **Fix**: Determine whether a partner is B2C based on the presence of a valid SIREN/SIRET (derived from `company_registry`) instead of the VAT number. This correctly identifies French business partners that are eligible for French e-Invoicing even when they do not have a VAT number configured. opw-6357756 Forward-Port-Of: odoo/odoo#278060
This fixes an inventory issue where reducing a delivery quantity could subtract the wrong amount if the order and detailed operation used different units of measure. Businesses get more accurate reserved and transferred stock quantities, avoiding leftover reservations and incorrect delivery counts.
Original PR description
Before this commit, decreasing the quantity of a move whose move lines are expressed in another unit of measure removed the wrong quantity from the lines, because the two conversions between the move…
Before this commit, decreasing the quantity of a move whose move lines are expressed in another unit of measure removed the wrong quantity from the lines, because the two conversions between the move unit and the line unit converted a value to its own unit, hence did nothing. Steps to reproduce: - create a product in Units with available stock - create a delivery for 2 Dozen of it and mark it as todo - in the detailed operations, change the unit of the move line to Units (24) - lower the move quantity from 2 to 1 Dozen The move line ends up with 23 Units instead of 12: the decrease of 1 Dozen is applied as 1 Unit on the line and considered fully processed. The remaining 11 units stay reserved and counted on the transfer. Convert the remaining decrease from the move unit to the line unit when taking it from a line, and the taken quantity back to the move unit when updating the remaining decrease. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278411 Forward-Port-Of: odoo/odoo#276774
Fixes an error that could stop warehouse transfers from being validated when reception report printing was enabled. The system now uses the correct report process for Stock and Manufacturing, so users can complete validations without the missing-report failure.
Original PR description
Issue before this commit: ======================== Currently, when the reception report option is enabled for the operation type under Print on Validation, validating a transfer with reserved…
Issue before this commit: ======================== Currently, when the reception report option is enabled for the operation type under Print on Validation, validating a transfer with reserved quantities for the next transfer automatically tries to print the reception report. However, the print fails with `External ID not found in the system: stock.stock_reception_report_action`, preventing the transfer from being validated. Steps to Reproduce: ========================= - Install the stock module. - In Inventory → Configuration → Operation Types → Receipts, enable Reception Report under Print on Validation. - Create a delivery and receipt for Product A, both with a quantity of 4. - Open the Allocation smart button on the receipt and reserve the incoming quantity for the created delivery. - Validate the receipt. Observation: The system tries to print the reception report, but validation fails with `External ID not found in the system: stock.stock_reception_report_action`. Cause of the issue: ========================= In this [PR](https://github.com/odoo/odoo/pull/264299/changes#diff-79ba983a362d3fed28458daad5f2902e914fd731308157aa73f350f1597265a6L30-L35), the reception report action was removed, and the reception report is now printed through the Picking Operations report using `do_print_picking()`. However, the auto-print methods in both Stock and MRP still referenced the old reception report action, causing the `External ID not found` error when the reception report auto-print is enabled After This Commit: ========================= - The obsolete reception report reference is replaced with the appropriate reports in Stock and MRP, preventing the traceback and allowing users to complete validation when the reception report is enabled. - The unnecessary context override in `_get_autoprint_done_report_actions()` was removed. It was replacing the context returned by report_action() with the `unnecessary default_production_ids`, which removed the `active_ids` generated by report_action(). These IDs are required by the report renderer to identify the production records, and removing them caused a blank PDF report.
Messages from portal and live chat users now keep their mention information when posted. This ensures mentioned people are notified as expected instead of mentions being silently ignored.
Original PR description
Before this commit, a portal or livechat visitor mentioning someone in a message did not notify them: the mention was silently dropped. This happens because the client cleans up empty recipient fields by checking `postData[field].length`, and `partner_ids_mention_token` is an object, so its `length` is always undefined. The tokens were dropped as empty, and the server then filtered out every partner the sender cannot read. This commit fixes the issue by checking the number of keys instead.
This fixes Malta accounting data so upgraded databases receive the correct tax grid assignments. It helps ensure new journal entries use the updated tax reporting grids after moving to the newer Odoo version.
Original PR description
**Step to Reproduce:** 1. Create a database in 18.0 with `l10n_mt` installed. 2. Select the Malta chart template (COA). 3. Upgrade the database to 19.0. 4. Verify the tax grids. **Issue:** Tax grids…
**Step to Reproduce:** 1. Create a database in 18.0 with `l10n_mt` installed. 2. Select the Malta chart template (COA). 3. Upgrade the database to 19.0. 4. Verify the tax grids. **Issue:** Tax grids remain unchanged after the upgrade and do not reflect the modifications introduced in [1]. The tax definitions are loaded from CSV data and don't happen during upgrade or module update it did through try_loading". Since the account tags already exist in upgraded databases, the changes are not applied during module loading and the updated grid assignments are not assigned to taxes. **Fix:** Apply the grid update directly through SQL during the upgrade or module update. The change is limited to tax grid assignments and does not require a full tax reload using ``try_loading`` or ``load_data``. **Before fix:** <img width="1458" height="724" alt="image" src="https://github.com/user-attachments/assets/eaac5e3f-d551-4ec0-b282-bb39a50438f9" /> **After fix:** <img width="1240" height="583" alt="image" src="https://github.com/user-attachments/assets/74409c53-dce0-45b2-a6b5-e60f5c2d826d" /> Note: why this fix is needed because existing upgrade script do update move line grid but still tax have the old grid which is weird and will cause issue when journal entry will create. [1]: https://github.com/odoo/odoo/pull/254894/changes/8921186850e31c53072d49a5dc760192f3edb902 opw-6325845 upg-4391393 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272038
Fixes the Italian VAT report so debit carryovers from December are no longer reported in the January credit carryover section. This helps businesses avoid incorrect VAT return categorization and supports more accurate tax reporting.
Original PR description
With a l10n_it company: - Create an invoice for december, create the tax return closing entry for this period. On the monthly VAT Report of january the carryover is declared in section VP9 which is supposed to store credit carry over not debit. opw-6354509 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279471
Point of Sale now correctly distinguishes manually paid negative orders from automatic pay-later balances. This prevents valid refunds or negative orders paid by card or similar methods from being wrongly stopped by a customer-account popup.
Original PR description
Validating a negative order manually paid with a standard method (e.g., Card) mistakenly triggers the fast payment fallback. The system wrongly assumed any single negative payment line was an auto-generated unsettled due. As a result, if the first configured payment method is "Customer Account", validation is incorrectly blocked by a popup asking for a customer. This commit restricts the fast payment trigger for negative amounts to only apply when the existing line is specifically a 'pay_later' type. task-6443347 Forward-Port-Of: odoo/odoo#282844 Forward-Port-Of: odoo/odoo#281238
Fixes an issue where the website analytics page incorrectly showed Plausible Analytics as disconnected, even when it was active. Users can again view their analytics reports directly in Odoo without needing to manually reselect a website.
Original PR description
**Description** The website analytics page always appears as if the website is not connected to Plausible Analytics, even when the connection is actually in place. This means that the user can't read…
**Description** The website analytics page always appears as if the website is not connected to Plausible Analytics, even when the connection is actually in place. This means that the user can't read analytics directly from Odoo, and that the free Plausible Analytics offered is Odoo SaaS is not usable. **How to reproduce** Set up Plausible Analytics (it is active by default on SaaS) and visit `/odoo/website-analytics`, or go to "Reporting" -> "Analytics". **Origin** 1. `WebsiteDashboard` component fetches analytics data via an RPC call to `fetch_dashboard_data`. For how the component is built, the first call misses a `website_id` argument. 2. `fetch_dashboard_data` defaults to `self.env.website` when called without `website_id` argument. After [1], `self.env.website` is empty on `jsonrpc` routes, because this protocol should be URL-agnostic. As result, the `WebsiteDashboard` appears empty when first loaded, and data is restored when a website button is clicked on the top right. **Fix** 1. The argument `website_id` in `fetch_dashboard_data` is made optional. 2. `base.default_website` is used instead of `self.env.website`. `base.default_website` is guaranteed to exist and to point to the first website in the website sequence. [1]: https://github.com/odoo/odoo/commit/5eba3e99ebd4f928fc5de620a38ab127e95be890 task-6402001
Operators can now close all open live chat conversations without the chat interface crashing. The fix keeps chat window data consistent when several conversations close at once, improving reliability for support teams.
Original PR description
Before this commit, clicking "Close all conversations" from the chat hub as an operator with several live chat windows open (fresh database with im_livechat demo data, logged in as admin) sometimes…
Before this commit, clicking "Close all conversations" from the chat hub as an operator with several live chat windows open (fresh database with im_livechat demo data, logged in as admin) sometimes crashed:
TypeError: Cannot read properties of undefined (reading
'findIndex')
at Proxy.close (mail/static/src/core/common/chat_window_model)
or with "RangeError: Maximum call stack size exceeded" in the record machinery. The overflow interrupts that machinery anywhere, hence the varying crash.
This happens because closing all windows leaves every live chat channel at once, and the resulting bus payloads reach the store out of their transaction order. Resolving an out-of-order many command derives a REPLACE from the field's history, and applying it updates the inverse field of each removed record. The problem is that these inverse updates are resolved against the same out-of-order revision:
- on the many side, they derive another REPLACE on the field they come from, re-entering the resolution before the field is updated, until the stack overflows;
- when their revision is older than the field's last replace, they are dropped, leaving the two sides of the relation out of sync.
Reminder that inverse updates go through `updateFields()` since "[FIX] mail: no infinite loop on discuss page load", so that the version history records them.
This commit fixes the issue by always applying client-generated updates (inverse echoes, computes, direct field writes): they reflect state the client already changed elsewhere, so only server data is subject to version resolution. They are still recorded in the history.
task-6450249
Forward-Port-Of: odoo/odoo#283204DIN 5008 PDF documents now show dates in the expected German-style format for Germany, Austria, and Switzerland, regardless of the user's language settings. This prevents invoices, quotations, purchase orders, follow-ups, and field service reports from displaying confusing or non-compliant date formats.
Original PR description
* = din5008_account_followup, din5008_industry_fsm **Steps to reproduce:** * Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`) * Set the document layout to **DIN…
Employee-related Gantt views now apply the user's search filters consistently, so employee schedules, leaves, attendances, and appraisals show more predictable results. The update also standardizes these views around employee grouping to avoid unsupported combinations and missing employees in planning displays.
Original PR description
`user_domain` (in the context) is supposed to contain the domain defined by the user (in the search bar). It was not the case for all gantt views, and produced inconsistent results, as that domain is…
`user_domain` (in the context) is supposed to contain the domain defined by the user (in the search bar). It was not the case for all gantt views, and produced inconsistent results, as that domain is used to know when to display the employees without leaves/attendances. The PR fixes that issue by creating the `HrGanttModel` class, that takes care of defining the `user_domain` correctly. This class also disables the *Group By* menu, and defaults to grouping by employees. This was decided for the following reasons: - All gantt views inheriting this class would group by employee - Grouping by other fields would already not work in some cases - It's very difficult to add employees without records if the gantt is grouped by multiple fields at once Affected `_get_gantt_data()` functions have been adapted accordingly The access models (the ones defined in the `access.csv` files) are implied, and thus never passed as a parameter to `get_gantt_data()`, so we need to also manually add them when converting the model to the related field used in `groupby` task-5502544 Forward-Port-Of: odoo/enterprise#124630
This update fixes several issues in the social media feed, including a crash when liking a tweet, likes not refreshing properly, edited comments not showing immediately, and duplicate images appearing in post previews. These fixes make social media management smoother and reduce confusing or broken interactions for users.
Original PR description
Bugs ==== When liking a Tweet in the feed view, a traceback is raised. Since https://github.com/odoo/odoo/commit/c0c82927f2e7 the likes does not update in the comments modal, `record` is now a snapshot of the kanban record (and so the template is not reactive). When editing a comment, we need to close / re-open the modal to see the change. This is because we try to change the prop from inside the component. Since https://github.com/odoo/enterprise/commit/89d87b7177e20ba1d3daee791d5ff55af0fafaf0 we have many records per media, and so the duplication check should have been updated. Task-6425391
This fixes an error that could block DHL return label creation when a sales order included Incoterms. The system now sends the expected Incoterm code to DHL, preventing the traceback and allowing affected deliveries to be confirmed smoothly.
Original PR description
Issue ----- When "return" is enabled, users get a traceback if the SO has incoterms. Steps to reproduce ----- - Set up DHL - enable return labels - Create a SO with incoterms & confirm it - Confirm the delivery > Traceback Cause ----- The request sent for the return label contains the incoterm record instead of its' code like in `dhl_rest_send_shipping` https://github.com/odoo/enterprise/blob/f6c94d4ca3ef4211a5ab00bf0b39f6a7675c8f79/delivery_dhl_rest/models/delivery_dhl.py#L371-L372 Which is not JSON serializable ----- Ticket: opw-6430371 Forward-Port-Of: odoo/enterprise#126459
Swiss payroll now counts full-day absences correctly for employees without a fixed working schedule. This prevents one-day accident leave from being treated as two days, helping avoid incorrect wage reductions or overstated accident salary amounts.
Original PR description
Issue: Swiss payslips count one extra absence day for employees without a working schedule. A one day accident leave can therefore be prorated as two days, reducing the regular wage and overstating…
Issue: Swiss payslips count one extra absence day for employees without a working schedule. A one day accident leave can therefore be prorated as two days, reducing the regular wage and overstating the accident salary. Steps to reproduce: * Install Swiss Payroll. * Configure a monthly employee without a working schedule. * Assign one day of accident time off. * Generate the payslip for that month. Cause: The Swiss wage computation derives absence boundaries from the date portion of the leave's UTC datetimes: https://github.com/odoo/enterprise/blob/16c29e1bab34b5bcb2b001477d928ec5eb294a97/l10n_ch_hr_payroll/models/hr_payslip.py#L313-L330 A fully flexible employee's full day leave starts at local midnight. In timezones ahead of UTC, that start is stored on the previous UTC date, so the inclusive calendar day computation adds an extra day. Solution: We need to use the requested time off dates for both payslip range filtering and absence proration. These fields preserve the calendar days selected by the user independently of timezone conversion, while leaving the UTC datetimes and half-day handling unchanged. opw-6435086 Forward-Port-Of: odoo/enterprise#127849 Forward-Port-Of: odoo/enterprise#127513
This fix prevents completed restaurant POS orders from showing again on customer-facing preparation status screens. It restores the correct order filtering so staff and customers see only orders that are still active or ready, reducing confusion during service.
Original PR description
**Steps to reproduce** * Install the `pos_order_tracking_display` module with demo data. * Open the restaurant POS, preparation display, and status screen in separate tabs. * From the POS, send an…
**Steps to reproduce**
* Install the `pos_order_tracking_display` module with demo data.
* Open the restaurant POS, preparation display, and status screen in separate tabs.
* From the POS, send an order to the kitchen.
* In the preparation display, mark the order as **Ready**.
* Verify that the order moves to the **Ready** stage on the status screen.
* In the preparation display, mark the order as **Completed**.
**Observation**
* The completed order moves back to the **Almost There** stage on the status
screen.
* Completed orders should no longer be displayed.
**Cause**
The order stage shown in the preparation display is determined by `_get_pos_orders`. Previously, order lines were retrieved through `_get_open_orderlines_in_display`, which excluded completed orders.
After the refactor, order lines are fetched using `get_preparation_display_orders_domain`, which returns completed order lines as well.
Orders are then split into two groups:
* Orders in the **Ready** stage are displayed as **Ready**.
* All other orders are displayed as **Almost There**.
As a result, completed orders incorrectly appear under **Almost There**.
Additionally, `get_preparation_display_orders_domain` contains an incorrect domain introduced by commit https://github.com/odoo/enterprise/commit/8491f7a74363f7de4fd542e0de0b2f06f00f01ae:
* `last_stage_id` is treated as a string literal:
`('stage_id', '=', 'last_stage_id')`
which always evaluates to `False`.
* The `todo` condition is also inverted.
**Fix**
This commit fixes two issues:
* Exclude completed order lines from the preparation display.
* Restore the correct domain logic by replacing the faulty condition with the
simpler equivalent:
```
'|', ('todo', '=', True), ('stage_id', '!=', last_stage_id)
```
This restores the original behavior while keeping the domain easier.
opw-6423519The cart no longer tries to show rental dates when a rental product order has been converted into a regular sales order. This prevents customers from seeing an error page after the rental period is removed, keeping checkout accessible.
Original PR description
Currently, an error occurs when a user adds a rental product to the cart, opens the corresponding sales order, removes the rental period, and then opens the cart again. Steps to replicate: - Install…
Currently, an error occurs when a user adds a rental product to the cart, opens the corresponding sales order, removes the rental period, and then opens the cart again. Steps to replicate: - Install `website_sale_renting` with demo. - Open website > shop > add the product named `Projector`. - Click Ecommerce in the menu bar > Orders . - Remove the `Confirmed` filter > Click on the top order (should be containing the projector product.) - Remove the `Rental Period` and go to the cart. Error: ``` QWebError: Error while rendering the template: AttributeError: 'bool' object has no attribute 'time' Template: website_sale.shorter_cart_summary ``` Cause: - When the user removes the rental period (`rental_start_date` and `rental_end_date`), both fields are set to `False`. When the cart is opened again, these values trigger the error in [line]. - Since the rental period has been removed from the order, the order is converted to a regular Sales Order (see [PR] and its [task]). Therefore, the Rental Period should no longer be displayed. Solution: - Use `is_rental_order` to determine whether to render the rental period instead of `has_rentable_lines`, since `has_rentable_lines `only checks whether the product is rentable [1], which is determined by the product's `rental_periodicity` [2]. - `is_rental_order` is a better check here because it indicates whether the rental period is actually defined on the order [3]. [line]: https://github.com/odoo/enterprise/blob/7c80c9ffa9e7812267f2ac285e3a3fc5ca501814/website_sale_renting/views/templates.xml#L207 [task]: https://www.odoo.com/odoo/all-tasks/6003684 [PR]: https://github.com/odoo/enterprise/pull/106381/commits/56ec41d81f7536f047a1586a12ea6f6e8414b844 [1]: https://github.com/odoo/enterprise/blob/f23ef9c604d8ce6be152d5e5bf6f72bd68b31451/sale_renting/models/sale_order.py#L140-L143 [2]: https://github.com/odoo/enterprise/blob/f23ef9c604d8ce6be152d5e5bf6f72bd68b31451/sale_renting/models/sale_order_line.py#L61-L64 [3]: https://github.com/odoo/enterprise/blob/f23ef9c604d8ce6be152d5e5bf6f72bd68b31451/sale_renting/models/sale_order.py#L135-L138 sentry-7663524549 Forward-Port-Of: odoo/enterprise#128084
Fixes an issue where a customer manually set on a planning shift could be removed when the employee signed in or completed the shift. This keeps field service planning records aligned with the user's chosen customer instead of unexpectedly reverting to the sales order customer.
Original PR description
Before this commit, when `sale_planning` module is installed after `planning_field_service` and the user sets a customer onto a shift, the customer could be removed when the user signs in or complete the shift. This issue is because `sale_planning` module defined `partner_id` field as a related field `related="sale_order_id.partner"` and `planning_field_service` module stores the field and so the field will always follows the partner set on the SO linked even if the user sets a customer on the shift. This commit removes the related attribute to replace it by a compute and a search method to have the exact same behavior but the search method will be short-circuited if the partner_id field is stored. task-5264800 Forward-Port-Of: odoo/enterprise#122034
* = din5008, din5008_purchase, din5008_repair, din5008_sale
**Steps to reproduce:**
* Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`)
* Set the document layout to **DIN 5008** and generate any PDF report (invoice, quotation, purchase order, etc.).
**Observed behavior:**
* All dates in the information block (Invoice Date, Due Date, Delivery Date, Order Date, etc.) are rendered in `yyyy-mm-dd` format instead of the expected `dd.MM.yyyy` format used in DE, AT, and CH.
**Cause:**
* All `t-options="{'widget': 'date'}"` directives across the DIN 5008 template family rely on the active user's language locale for date formatting. If the user language is not `de_DE`, dates render in the locale's default format (e.g. `yyyy-mm-dd` for `en_US`).
**Fix:**
* Add `'format': 'dd.MM.yyyy'` explicitly to all `t-options` date widgets across all DIN 5008 report templates (`l10n_din5008`, `l10n_din5008_sale`, `l10n_din5008_purchase`, `l10n_din5008_sale_subscription`, `l10n_din5008_repair`, `l10n_din5008_account_followup`, `l10n_din5008_industry_fsm`).
* This is correct for all three countries using DIN 5008 (DE, AT, CH), which all follow the `dd.MM.yyyy` convention.
opw-6392649
Forward-Port-Of: odoo/odoo#283260
Forward-Port-Of: odoo/odoo#279085* = din5008_account_followup, din5008_industry_fsm
**Steps to reproduce:**
* Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`)
* Set the document layout to **DIN 5008** and generate any PDF report (invoice, quotation, purchase order, etc.).
**Observed behavior (date format):**
* All dates in the information block (Invoice Date, Due Date, Delivery Date, Order Date, etc.) are rendered in `yyyy-mm-dd` format instead of the expected `dd.MM.yyyy` format used in DE, AT, and CH.
**Cause (date format):**
* All `t-options="{'widget': 'date'}"` directives across the DIN 5008 template family rely on the active user's language locale for date formatting. If the user language is not `de_DE`, dates render in the locale's default format (e.g. `yyyy-mm-dd` for `en_US`).
**Fix (date format):**
* Add `'format': 'dd.MM.yyyy'` explicitly to all `t-options` date widgets across all DIN 5008 report templates (`l10n_din5008`, `l10n_din5008_sale`, `l10n_din5008_purchase`, `l10n_din5008_sale_subscription`, `l10n_din5008_repair`, `l10n_din5008_account_followup`, `l10n_din5008_industry_fsm`).
* This is correct for all three countries using DIN 5008 (DE, AT, CH), which all follow the `dd.MM.yyyy` convention.
opw-6392649
Forward-Port-Of: odoo/enterprise#128413
Forward-Port-Of: odoo/enterprise#126006