Wednesday, September 2, 2026
20 changes · 19.0
Enhancements to existing features
Users with the Invoicing and Banks role can now access tools to find missing or duplicate bank transactions during reconciliation. This makes bank review workflows easier without requiring full accounting permissions.
Ecuadorian electronic documents can now include the RUC of the third-party software provider, as required by SRI rules. Users can enter this provider RUC in the Ecuadorian electronic invoicing settings, and it will be sent electronically and shown on printed documents including delivery guides.
Original PR description
Purpose: SRI Resolution requires taxpayers using 3rd-party billing software in Ecuador to report the software provider's RUC on all electronic documents and printed representations (RIDE). A new system parameter is introduced and displayed in Invoicing > Setting > Ecuadorian Localization > Electronic Invoicing, so users can add their software provider's RUC. This value will be automatically sent to the EDI and displayed on the report. task-6432810 Forward-Port-Of: odoo/enterprise#129456
Large Italian electronic invoices now import much faster by processing invoice lines more efficiently and creating them in one batch. This reduces long waiting times for accounting teams, especially when handling invoices with hundreds or thousands of lines.
Original PR description
### Description: When importing a large invoice, the process can take a lot of time. This is caused by how `l10n_it_edi` handles the creation and writing of each line of the bill. To improve performance, most of the process is now performed in memory and record creation is deferred to a single batch at the end. Additionally, the check related to `account_accountant` is cached to avoid superfluous calls. ### Benchmark: **For `history.limit`[^1] of 50 (= 21002 `account.move.line`):** | Invoice lines | Before | After | Speedup | |---------------|----------|---------|---------| | 33 | 4.75s | 2.23s | 2.1× | | 172 | 2.3min | 45.1s | 3.1× | | 1,934 | 44.4min | 6.8min | 6.6× | [^1]: System parameter `account.bill.predict.history.limit` ### Reference: opw-5937519 Forward-Port-Of: odoo/odoo#282880
Invoice field prediction has been optimized for databases with many accounting entries, especially when processing Peppol documents. This reduces waiting time when matching invoice lines to products, accounts, or taxes, with the biggest gains on large vendor bills.
Original PR description
### Description: Predicting fields can be slow when the database has a large amount of move lines (AML). This is caused by the fact that `_predicted_field` will search on all these AMLs to find the…
### Description: Predicting fields can be slow when the database has a large amount of move lines (AML). This is caused by the fact that `_predicted_field` will search on all these AMLs to find the ones related to the searched fields. It can be an issue when using Peppol since it is used a lot in most localizations to match each line to its product/account/tax. To speed up the queries, the move IDs have been inlined in `_build_predictive_query` to avoid suboptimal execution plans caused by LIMIT and ORDER BY clauses. Additionally, materialization of the `account_move_line` CTE has been removed so the planner can inline filters and stream rows directly, which improves performance in most use cases. ### Benchmark: **For a `history.limit`[^1] of 100:** | Nb of invoice line | Before | After | AMLs scanned | |--------------------|-----------|---------|--------------| | 33 | 7s | 4s | 232 | | 172 | 11.39min | 5min | 99859 | | 1934 | 3h+ [^2] | 1h40min | 102503 | **For a `history.limit`[^1] of 50:** | Nb of invoice line | Before | After | AMLs scanned | |--------------------|---------|---------|--------------| | 33 | 6s | 4s | 187 | | 172 | 2.52min | 1.27min | 21002 | | 1934 | 40min | 20min | 21002 | [^1]: System parameter `account.bill.predict.history.limit` [^2]: Stopped manually after 3h; full runtime not measured ### Reference: opw-5937519 Forward-Port-Of: odoo/enterprise#128172
Resolved issues and error corrections
This fixes an eCommerce product page issue where multi-checkbox attribute options could become selected automatically after refreshing the page. Shoppers now see the intended default state, reducing confusion and preventing unintended product option choices.
Original PR description
**Steps to reproduce:** 1. Create a product. 2. Add two attributes: multi-checkbox and any single-select type (e.g. Radio). 3. Publish the product and open its page on eCommerce. 4. Verify that no…
**Steps to reproduce:**
1. Create a product.
2. Add two attributes: multi-checkbox and any single-select type (e.g. Radio).
3. Publish the product and open its page on eCommerce.
4. Verify that no multi-checkbox option is selected by default.
5. Refresh the page twice.
**Issue:**
On the second page refresh, the first option of the multi-checkbox attribute is automatically selected, and the URL is updated with its parameter.
**Cause:**
- `_prepare_product_values` construct attribute combinations by mapping requested `attribute_values` query parameters line by line.
- When URL query parameters were present (e.g., set after the first refresh), the fallback logic `or ptal.product_template_value_ids.filtered('ptav_active')[:1]` treated unselected `multi_checkbox` attribute lines as missing required selections rather than empty selections, forcing them to default to their first active option.
**Fix:**
If no selection is provided for `multi_checkbox` line, return an empty recordset instead of falling back to the first active option.
opw-6494697This fixes Mexican payroll calculations so minimum wage employees remain protected from IMSS deductions even when they receive extra pay such as commissions. It also prevents payroll discrepancies from adjusted schedule days and ensures employment subsidy eligibility is not incorrectly reduced by unpaid absences.
Original PR description
According to LSS Art. 36, minimum wage workers are exempt from IMSS deductions. Previously, the system evaluated the period's total gross wage instead of the daily wage, which caused incorrect…
According to LSS Art. 36, minimum wage workers are exempt from IMSS deductions. Previously, the system evaluated the period's total gross wage instead of the daily wage, which caused incorrect withholdings when a minimum wage employee received extra pay (like commissions). We now evaluate the `l10n_mx_daily_salary` directly to protect minimum wage workers while ensuring correct deductions for higher earners with unpaid leaves. Since calculations rely on `schedule_days` retrieved from the schedule table, users commonly adjust these values (e.g., from 15 to 15.2, or 30 to 30.4). To prevent discrepancies caused by this practice, we now round the `schedule_days`. Finally, this commit fixes the employment subsidy eligibility threshold. Previously, the limit was incorrectly reduced by unpaid absences. This caused a double-counting effect (since absences already lower the actual gross wage) and wrongly disqualified employees. The subsidy limit is now based strictly on the full payroll schedule length, while the ISR minimum wage exemption correctly continues to consider actual worked days. target: 19.0 task-6370959
This fix ensures restaurant table orders edited on one point-of-sale device are still saved even after another device synchronizes the same table. It prevents newly added order lines from disappearing, reducing the risk of missed sales and service mistakes in multi-device environments.
Original PR description
Steps to reproduce: - Device A opens table 10 and adds a product - Device B opens table 10, then goes back to the floor plan - Device A goes back to the floor plan => The lines added on A are lost, they are never synced to the database, nor to the other device When B triggers a synchronisation, A reads the open orders from the server. The local lines of A are kept, but `setup`, which is also called when a record is updated, resets the dirty flag of the order. Going back to the floor plan calls `syncAllOrders`, which filters the order out because it is not dirty anymore, so the lines are never sent. The dirty flag is now kept when the record is updated with server data, since that data does not contain the changes made locally and must be synced in the next synchronization call task-id: 6486258 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes several cases where Odoo showed incorrect information or failed to refresh data, including accounting report matching, POS customer details, shipping carrier selection, timesheet status colors, and appointment contact names. It improves reliability across affected business processes so users see the right data and avoid avoidable errors.
This fix ensures cost of goods sold stays accurate when a sale is delivered and invoiced in multiple steps under average cost valuation. Businesses avoid incorrect negative cost entries and get financial reports that reflect the actual value of delivered stock.
Original PR description
## HOW TO REPRODUCE: - Create a product AVCO Perpetual - Receive 10 units with a unit price of $10 => Product average price is now $10 - Create a Sale Order for 10 units, confirm, deliver and invoice…
## HOW TO REPRODUCE:
- Create a product AVCO Perpetual
- Receive 10 units with a unit price of $10 => Product average price is now $10
- Create a Sale Order for 10 units, confirm, deliver and invoice => COGS are at $100
- Receive 1 unit with a price of $5 => Product average price is now $5
- Update SO and add 1 unit, deliver and invoice this new unit => New invoice COGS is $-45
This is because Odoo computes the COGS for the whole SO, and decided that the value of the deliveries is the `quantity * standard_price`, which would means `11 units * $5 = $55`. Because the 1st invoice has a COGS balance of $ 100, the 2nd invoice is set to $ -45.
This behavior is inconsistent with how it was done in previous versions. Furthermore, if we added the +1 unit in a new invoice, the COGS would have been $ 5, for a total products COGS of $ 105.
- - -
With this fix, the COGS are computed using the average of the move value. So if the first move value is $100, and the second is $5, then the global COGS for the sale order should be $105. Because the first invoice COGS are already at $100, the second invoice COGS must be $5.
OPW-6442049
---
## TEST RESULT WITHOUT FIX:
```
2026-08-21 08:00:11,722 28203 INFO oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: Starting TestAngloSaxonValuation.test_cogs_average_multiple_invoices_and_deliveries ...
2026-08-21 08:00:13,055 28203 INFO oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: ======================================================================
2026-08-21 08:00:13,055 28203 ERROR oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: FAIL: TestAngloSaxonValuation.test_cogs_average_multiple_invoices_and_deliveries
Traceback (most recent call last):
File "/home/odoo/Odoo/src/19.0/odoo/addons/sale_stock/tests/test_anglo_saxon_valuation.py", line 1935, in test_cogs_average_multiple_invoices_and_deliveries
self.assertRecordValues((cogs_line_1 | cogs_line_2), [
File "/home/odoo/Odoo/src/19.0/odoo/odoo/tests/common.py", line 727, in assertRecordValues
self.assertSequenceEqual(expected_reformatted, record_reformatted, seq_type=list)
AssertionError: Lists differ: [{'ac[142 chars]it': 5.0}, {'account_id': 3566, 'debit': 5.0, 'credit': 0.0}] != [{'ac[142 chars]it': 45.0}, {'account_id': 3566, 'debit': 45.0, 'credit': 0.0}]
First differing element 2:
{'account_id': 3536, 'debit': 0.0, 'credit': 5.0}
{'account_id': 3536, 'debit': 0.0, 'credit': 45.0}
[{'account_id': 3536, 'credit': 100.0, 'debit': 0.0},
{'account_id': 3566, 'credit': 0.0, 'debit': 100.0},
- {'account_id': 3536, 'credit': 5.0, 'debit': 0.0},
+ {'account_id': 3536, 'credit': 45.0, 'debit': 0.0},
? +
- {'account_id': 3566, 'credit': 0.0, 'debit': 5.0}]
+ {'account_id': 3566, 'credit': 0.0, 'debit': 45.0}]
? +
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prAttendance managers can now access attendance records without errors when overtime rules trigger regeneration. Editing overtime rule settings is also limited to HR Officers, helping keep payroll-related configurations under the right control.
Original PR description
Issue ===== The overtime rules searches the model `hr.version` for versions eligible for attendance regeneration. However, an attendance manager does not have access to `hr.version`, hence an access error is raised. The attendance manager is also able to create and edit overtime rulesets and rules, which should only be done by an HR Officer. Fix ===== - Use `sudo()` to search versions in the attendances regeneration method. - Prevent non-HR-Officers to create or edit overtime rulesets or rule records by making them readonly and fixing the `boolean_radio` widget. TaskID-6128198
This fixes an issue where choosing a website theme could leave the site's header and footer unchanged. The update ensures theme setup runs at the right time and reliably identifies the active website during installation, so business users see the selected design applied as expected.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283174
Fixes a Sales Timesheet billing issue where manually increasing the quantity on an earlier invoice could prevent later timesheet entries from being invoiced. Businesses can now invoice future periods correctly even if a prior invoice was adjusted, while keeping refund-related behavior intact.
Original PR description
## Issue When a use rmanually increases the invoiced quantity on a timesheet invoice, subsequent timesheets logged in future periods can no longer be invoiced. The system assumes that the most recent…
## Issue
When a use rmanually increases the invoiced quantity on a timesheet invoice, subsequent timesheets logged in future periods can no longer be invoiced. The system assumes that the most recent logged hours are already covered by the previously over-invoiced amount, blocking the billing of the most recent timesheet entries.
## Steps to reproduce
1. Install *Sales Timesheet* (`sale_timesheet`)
2. Create a Product P
- Product Type: Service
- Invoicing Policy: Based on Timesheets
- Create on Order: (Project &) Task
3. Create an SO:
- Customer: Any
- Product: P (any quantity)
- Confirm
4. Record hours on the task created:
- 06/01/2026 (June 1st): 1 hour
- 07/01/2026 (July 1st): 1 hour
5. Create the invoice for the June timesheet entry (by setting a timesheets period when creating the invoice), then **change the quantity to any value strictly greater than 2** and confirm.
6. Create the invoice for July
7. **An "Invalid Operation" error appears, stating that there's nothing to invoice, even though the timesheet entry from July was never invoiced.**
## Cause
Since https://github.com/odoo/odoo/commit/3b86ac3d180993239b63fd305ee0ba1f17f7eb20, the computation of the quantity to invoice changed to include the difference between the quantity delivered and the quantity already invoiced. In the flow described by the steps to reproduce above, the quantity to invoice is larger than the quantity delivered, making the `qty_to_invoice` equal to `0.0`.
https://github.com/odoo/odoo/blob/626d31fa0191bfe7ca8e1fcf177357eeeb60f2c7/addons/sale_timesheet/models/sale_order.py#L331-L334
The reason for the fix above being the partial refunding of timesheet-related invoices, we can keep that solution when working with refunded invoices, and keep the previous behavior for other cases.
This solution solves the issue in the steps to reproduce above, but was also manually tested on the issues from https://github.com/odoo/odoo/commit/3b86ac3d180993239b63fd305ee0ba1f17f7eb20 and https://github.com/odoo/odoo/commit/64cf4afabd0c5ef040cf87fc6f3125fe0bb81bbb.
opw-6485674
Forward-Port-Of: odoo/odoo#286043
Forward-Port-Of: odoo/odoo#284470French e-invoicing now ignores PDP responses that do not include a tracking ID. This prevents scheduled status updates from crashing and helps invoices and vendor bills continue processing reliably.
Original PR description
Steps to reproduce: - Install `l10n_fr_pdp` and `l10n_be` module - Activate `French e-invoicing` (you need to put your DB in test mode) (i.e: `account_peppol.edi.mode = 'test'` in system parameter)…
Steps to reproduce:
- Install `l10n_fr_pdp` and `l10n_be` module
- Activate `French e-invoicing` (you need to put your DB in test mode)
(i.e: `account_peppol.edi.mode = 'test'` in system parameter) Refer this Documentation https://www.odoo.com/documentation/19.0/applications/finance/fiscal_localizations/france.html?highlight=e%20invoicing#localizations-france-e-invoicing-fac-elec-config
- Create a Invoice and Sent with `E-invoicing`
- Run `PEPPOL: retrieve new documents` Cron
- In Invoice Other Info > `E-Invoicing Status` should be in `Done` state
- Now Vendor Bill is created for that invoice > Cancel that bill with reason > Check `E-Invoicing Status` response for bill(one response will be without UUID)
- Go to schedule actions > `PEPPOL: update message status`
- Run it and get the traceback: `KeyError: 'false'`
Issue:
When sending a lifecycle response to the French PDP, `_pdp_send_response` calls the `/api/pdp/1/send_response` endpoint and expects IAP to return a `message_uuid` for each response.
However, IAP return a response without a message UUID, for example: ` {'messages': [{'message_uuid': False}]}` `_pdp_send_response` currently assumes that every returned message has a valid UUID and creates an `account.peppol.response` with:
```
'peppol_message_uuid': False
'peppol_state': 'processing'
```
This leaves an `account.peppol.response` in `processing` state without a UUID that can be used to track it.
During the next execution of `_cron_peppol_get_message_status`, `_peppol_get_message_status` retrieves this response through `_peppol_get_documents_for_status` and builds `uuid_to_record` using `peppol_message_uuid` as the key. The resulting mapping contains the Python value `False` as a key.
The cron then calls the PDP `1/get_document` endpoint with this invalid UUID. IAP returns it as the string `'false'`, which is passed to `_peppol_process_messages_status`. The French PDP implementation tries to retrieve the corresponding record with: `uuid_to_record[uid]`
Since the mapping contains `False` while `uid` is `'false'`, this raises: `KeyError: 'false'`
This failure prevents the status cron from completing the processing of the messages.
Solution:
Avoid creating the `account.peppol.response` when IAP does not return a `message_uuid`. A response without a UUID cannot be tracked through the PDP status flow, so creating it in `processing` state only leaves an
invalid record that will later cause the status processing to fail.
opw-6453133
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#281691This fixes a manufacturing issue where entering the produced quantity before picking components could incorrectly show zero component consumption and block completion with a warning. Manufacturing orders now correctly consume reserved components, including partial quantities, so production can be completed accurately.
Original PR description
Steps to reproduce --- 1. Set the warehouse Manufacture route to 2 steps (Pick Components). 2. Create a product to manufacture whose bill of materials has a lot-tracked component, and keep that…
Steps to reproduce --- 1. Set the warehouse Manufacture route to 2 steps (Pick Components). 2. Create a product to manufacture whose bill of materials has a lot-tracked component, and keep that component in stock. 3. Create and confirm a manufacturing order for it; a Pick Components transfer is generated. 4. Set the produced quantity (`qty_producing`) on the order before validating the Pick Components transfer. 5. Validate the Pick Components transfer, then Produce All. A consumption warning shows the components as Consumed 0 instead of producing the order. Issue --- Entering `qty_producing` before the Pick Components transfer is validated runs `_set_qty_producing` while the components are not reserved yet (they have not reached pre-production), so the tracked component stock moves stay at a zero quantity and unpicked; validating the transfer afterwards reserves them to the full quantity but never sets `picked`. At `button_mark_done`, `_set_quantities` only recomputes and picks the component stock moves when `qty_producing` is zero, so with the quantity already set `_set_qty_producing` is skipped and the mark-done fallback picks only `manual_consumption` stock moves, leaving the auto-consumption component stock moves unpicked. https://github.com/odoo/odoo/blob/0d44f26d9b0fb1c1a5db463cf1f8dd0d3c72ba26/addons/mrp/models/mrp_production.py#L2933-L2943 Since `_get_consumption_issues` counts consumption from picked stock moves only, it reads 0 consumed and raises the warning even though the components are fully reserved. https://github.com/odoo/odoo/blob/0d44f26d9b0fb1c1a5db463cf1f8dd0d3c72ba26/addons/mrp/models/mrp_production.py#L1784-L1791 The zero-quantity gate comes from https://github.com/odoo-dev/odoo/commit/ab432cf77311ba852c59ae8675ad4c2dab3bfdf4, which wrapped `_set_qty_producing` in `_set_quantities` to preserve a hand-entered quantity and, as a side effect, stopped picking the component stock moves in that path. When the quantity is already set, the auto-consumption component stock moves are now marked `picked`: a move reserved above what the run consumes (`should_consume_qty`) is trimmed down to it so producing part of the order consumes only its share and backorders the rest, while a move reserved at or below it is picked as reserved so an under-supplied component is consumed at what is available. opw-6415931
Italian withholding tax returns submitted in quarter-ending months no longer incorrectly open the quarterly VAT export. This prevents failed exports or LIPE files being attached to the wrong return, helping users file the correct Italian tax reports.
Original PR description
In Italy the periodic VAT return (LIPE) is filed quarterly, so `is_quarter_month` gates the XML export wizard on March, June, September and December. That field only looks at the date, never at the…
In Italy the periodic VAT return (LIPE) is filed quarterly, so `is_quarter_month` gates the XML export wizard on March, June, September and December. That field only looks at the date, never at the kind of return, so every Italian return locked on a quarter month was treated as a LIPE. Submitting the withholding tax return therefore opened the LIPE export wizard. Depending on the record the wizard receives, it either crashes while reading the VP lines missing from the withholding report, or silently generates a LIPE file and attaches it to another return. Add an `is_lipe_return` field telling whether the return actually produces the LIPE. Steps to reproduce: - Install `l10n_it_xml_export` and `l10n_it_edi_withholding_reports` on an Italian company with monthly returns - Open Accounting > Reporting > Tax Return - Review and submit the withholding returns up to February - Review then submit the March withholding return --> The LIPE export wizard opens, and the export fails on the withholding report. opw-6255016 Forward-Port-Of: odoo/enterprise#125263
Fixed an issue that could prevent shoppers from opening the website homepage after adding a product to their cart when the site header was disabled. This helps businesses using simplified or single-page storefront layouts avoid a visible error for customers.
Original PR description
Currently an exception is generated when the user tries to visit the website home page after adding a product to the cart as follows: - Install the `website_sale` module with demo data - Go to view and disable `template_header_default` view - In another incognito browser, add any product to the cart - Go to main page > Error occurs This issue occurs when a user tries to create a website like a single-page application (no need for a header) because `cache_quantity` is `None` as the `my_cart_quantity_re` regex is not found in html page as user hide the header which include cart. This commit fixes the above issue by returning early from the method when `cache_quantity` is `None`, preventing an error caused by calling the `update` method on a `None` value. Sentry-7505670739
Consolidated invoices for Malaysian PoS orders now avoid showing misleading receipt ranges when orders are held, completed out of order, cancelled, or invoiced separately. This helps businesses ensure invoice lines accurately reflect the receipts included, reducing confusion for customers and reporting teams.
Original PR description
Steps to reproduce: - In a PoS session, ring up orders 16, 17, 18, 19, 20 back to back. - Hold order 17 before finishing it, letting 18, 19 and 20 complete (and so get recorded) first, then confirm…
Steps to reproduce: - In a PoS session, ring up orders 16, 17, 18, 19, 20 back to back. - Hold order 17 before finishing it, letting 18, 19 and 20 complete (and so get recorded) first, then confirm order 17 last. - Cancel order 19 (or otherwise exclude it, e.g. invoice it individually). - Generate a consolidated invoice covering these orders. Issue: A consolidated invoice line grouping several PoS orders is named as a "first-last" receipt range (e.g. "18-20"). Grouping itself relies on `sequence_number`, a gapless counter assigned when the order is recorded in the database - the only field that reliably proves no order was skipped. The receipt reference shown to the customer is reserved earlier, client-side, the instant the ticket is opened, and does not move together with `sequence_number` whenever an order is held (or otherwise finishes) later than orders opened after it. The resulting line can then be named with a range that visually overlaps with, or omits, receipts that are actually reported on a different line, misrepresenting what the consolidated invoice covers. Root Cause: `sequence_number` (point_of_sale/models/pos_order.py) is only assigned once an order's row is created in the database, in recording order. The receipt reference (`pos_reference`/`name`) is assigned client-side the moment the ticket is opened (`setNextOrderRefs` in pos_store.js) and is unaffected by how long the order later takes to complete. `_split_pos_orders_in_lines` only checked `sequence_number` continuity to decide which orders share a line, while the line name (built from the first/last receipt reference, sorted) implicitly assumed the two would always move together. Fix: - l10n_my_edi_pos: `_split_pos_orders_in_lines` now also requires the receipt reference to be continuous - same device, and the number incrementing by one, via the new `pos.order._get_myinvois_reference_key()` - before merging two orders into the same line, on top of the existing `sequence_number` check. An order recorded out of ticket order now gets its own line instead of being merged into one with a misleading name. - l10n_my_edi: extracted the line-naming logic into an overridable `_get_consolidated_line_name`, which only compresses to a "first-last" range when the names are genuinely sequential, and lists every reference individually otherwise, as a safety net for any other flow relying on this base method. [task-6166533](https://www.odoo.com/odoo/my-tasks/6166533)
Users can now safely discard changes after reordering long multi-page line-item lists, such as quotation order lines. This prevents an error that could interrupt sales document editing when many lines are present.
Original PR description
**Steps to reproduce:** - Create a quotation - Add order lines until reaching 200 (duplicating helps), save and ensure that the pager appeared (1-200/201) - Drag one of the lines with the handle to…
**Steps to reproduce:** - Create a quotation - Add order lines until reaching 200 (duplicating helps), save and ensure that the pager appeared (1-200/201) - Drag one of the lines with the handle to reorder them - Discard all changes (X shaped button) You will have an evaluation error **Behavior:** When loading a list of records exceeding the limit, only parts of the records are saved in `_cache`. When triggering a reordering of said list, all records need to be loaded including the ones on other pages: https://github.com/odoo/odoo/blob/d4eff7b14d37a9b59c95d304542a5a12629bc90b/addons/web/static/src/model/relational_model/static_list.js#L1139-L1149 `_getResIdsToLoad()` gets all Ids missing from the cache, these are then passed through `._createRecordDatapoint` and will then be stored in `_cache`. The issue is that the Datapoints are getting created with only `activeFields` as data, which in our case are `id` and `sequence` When discarding the changes `._checkValidity()`is called on each Datapoint: https://github.com/odoo/odoo/blob/d4eff7b14d37a9b59c95d304542a5a12629bc90b/addons/web/static/src/model/relational_model/record.js#L423-L429 And then `._isInvisible()` is called. This is where the issue happens, since only `sequence` and `id` are stored, when we try evaluate `combo_item_id`, which is the condition to see if sequence is invisible, `combo_item_id` is not found and we get an Evaluation Error. This commit prevents going into `._checkValidity()` by adding `this.isInEdition` to the check leading to it, requiring that the record is in 'edit' mode which is not the case for records created with `_createRecordDatapoint()` opw-6399024
This fix ensures Italian POS refunds navigate to the payment page for the refund order, not the product screen or the original order. This helps cashiers complete refund flows correctly when using an Italian fiscal printer.
Original PR description
**Issue**: 1. From versions 18.4 to 19.1 inclusive, the system redirects to the product screen; 2. From version 19.2 onward, the redirection targets the payment page of the original order instead of the refund order. **Expected behavior**: The system navigates to the payment page for the refund order. **Steps to reproduce**: - Set up an Italian fiscal printer; - Open a POS session and process an order; - Create a refund for the order. [Ticket link](https://www.odoo.com/odoo/project/49/tasks/6499079) opw-6499079 Forward-Port-Of: odoo/enterprise#129758
Weekly overtime in Timesheets is now calculated from the employee's actual scheduled total hours, including flexible schedules, instead of a full-time equivalent value. This makes the overtime shown in My Timesheets consistent with Planning and All Timesheets, reducing confusion for employees and managers.
Original PR description
# How to reproduce - Set the current employee's schedule to one with : - Schedule Type : Flexible - Total : a different amount than "Full Time Equivalent" - Go to My Timesheets - Add a new line with…
# How to reproduce
- Set the current employee's schedule to one with :
- Schedule Type : Flexible
- Total : a different amount than "Full Time Equivalent"
- Go to My Timesheets
- Add a new line with some Time Spent > 0
- Hover the bottom right cell of the grid (this is the total overtime for the week)
# The issue
The computation of the overtime for the week is based on "Full Time Equivalent" instead of "Total". This is inconsistent with the Planning app and the All Timesheets view.
# Cause
This [PR] introduced the usage of `full_time_required_hours` to compute the total overtime. This field was used because `hours_per_week` ("Total") was thought to be computed using `resource.calendar.attendance`. However, that is not the case when the schedule is flexible : https://github.com/odoo/odoo/blob/46d3fee5812b8406aac2244baa76b0daeef358c2/addons/resource/models/resource_calendar.py#L220 https://github.com/odoo/odoo/blob/46d3fee5812b8406aac2244baa76b0daeef358c2/addons/resource/models/resource_calendar.py#L163-L166
[PR]: https://github.com/odoo/enterprise/pull/81057
opw-6303520