Daily updates from Odoo
Tuesday, August 11, 2026
14 changes · master
Resolved issues and error corrections
The payroll pay run status display now marks earlier steps as completed once a pay run is validated, closed, paid, or cancelled. This gives payroll teams a clearer and more accurate view of pay run progress, reducing confusion during validation and closing.
Original PR description
When a pay run reaches '02_close' or beyond ('03_paid', '04_cancel'), step states remain unchanged because their compute methods lack `@api.depends('state')`, omit '02_close', and check if the field is already set.
Add the missing dependency, include '02_close', and remove the restrictive field check so step states update properly.
Task: 6428646This fix prevents Field Service task completion from getting stuck after a delivery has been returned and then re-delivered. By avoiding repeated processing of the same stock movements, the system no longer risks running out of memory in this workflow.
Original PR description
## **Steps to reproduce:** 1. Create a Service product with Create on Order set to Task and Project set to Field service project. 2. Create a Sales Order containing a storable product and a service…
## **Steps to reproduce:** 1. Create a Service product with Create on Order set to Task and Project set to Field service project. 2. Create a Sales Order containing a storable product and a service product. 3. Confirm the Sales Order to generate the project, task, and delivery order. 4. Validate the delivery order. 5. Create and validate a return for the delivery. 6. Create a return of the return to deliver the products again, but do not validate this new delivery. 7. Open the related task and click on Mark as Done button. ## **Issue:** In a delivery -> return -> return of return workflow, the stock move goes into this code https://github.com/odoo/enterprise/blob/59b86f106862c3a364ba633a1580d9051f2fe7ca/industry_fsm_stock/models/project_task.py#L89-L90 the traversal repeatedly revisits the same stock moves through move_dest_ids, causing the loop to alternate between the same move recordsets indefinitely. As a result, the loop never terminates, eventually exhausting the memory and raising a `MemoryError`. ## **Solution:** Track the stock moves that have already been visited and continue the traversal only with unseen destination moves. Runbot Video : [Video](https://drive.google.com/file/d/1wiqggjx8T-Mtl4T1JgCsfwBbgQU18nYF/view?usp=drive_link) OPW - 6420961 Forward-Port-Of: odoo/enterprise#125962
The bank reconciliation screen now consistently shows the "to review" option when users set an account, apply a reconciliation model, or handle payable and receivable items. This helps accounting teams flag transactions for follow-up across more reconciliation workflows and avoids missed review steps.
Original PR description
This commit will allow to have the "to review" button when using different action: - Set account - Reco model - Payable and receivable task-6409437 Forward-Port-Of: odoo/enterprise#125287
Fixed an issue in Belgian payroll where the public holidays wizard showed only one available time type. Users can now choose from the expected time types when loading public holidays, reducing setup errors for Belgian companies.
Original PR description
**Steps to Reproduce:** 1. Install the `l10n_be_hr_payroll` module. 2. Switch to the Belgium company. 3. Go to the Public Holidays tab and click on `Load Public Holidays`. 4. In the "Time Type" field, you will only see one time type record. **Cause:** The `l10n_be_hr_payroll` module has an overridden computed method that updates the incorrect value. **Fix:** Remove the computed method, as the logic is already covered in the standard method. Task-6448165
Financial reports now show current month and quarter choices correctly when opened with a yearly default period. This prevents misleading date filter options and ensures custom comparison periods default to dates up to today rather than future year-end dates.
Original PR description
When opening reports with `default_opening_date_filter='this_year'`(e.g., P&L, Partner Ledger), the date filter dropdown showed incorrect defaults for non-selected period types: - Month showed the…
When opening reports with `default_opening_date_filter='this_year'`(e.g., P&L, Partner Ledger), the date filter dropdown showed incorrect defaults for non-selected period types: - Month showed the last month of the fiscal year (e.g., December) instead of the current month - Quarter showed Q4 instead of the current quarter This happened because `initDateFilterState()` used the backend's `date_to` (fiscal year end) as the reference for computing all filter periods. For `this_year`, `date_to` is the year-end date (e.g., 2026-12-31), so `computePeriodRange()` for month/quarter returned periods containing that date rather than today's date. Reports with `this_month` or `today` defaults were unaffected because their `date_to` is naturally close to today. Now, non-selected filters use today as their reference date on initial load whenever today falls within the report period, while the selected filter continues to use the backend's `date_to`, preserving the alignment behavior introduced in the date filter refactor (https://github.com/odoo/enterprise/commit/40484f985f511edd7ba2ae759ce63ef564bcf1f7). Additionally, selecting the custom comparison filter now triggers an immediate reload so its default date range is recomputed by the backend. The custom comparison range is initialized using the current fiscal year up to today, capping its end date to today instead of inheriting the report's `date_to`, which could otherwise default to a future date for yearly reports. task-6229588 Forward-Port-Of: odoo/enterprise#127316 Forward-Port-Of: odoo/enterprise#121638
Payroll users can now validate several draft payslips from the list view without the action silently failing. If a country-specific payroll flow needs an extra wizard, such as Belgium payroll language handling, that wizard now appears and the selected payslips can be completed together.
Original PR description
Selecting draft payslips in the list and clicking Validate did nothing, no error, no dialog. `action_validate` called `action_payslip_done` but dropped what it returned, so a localization asking for a wizard got lost on the way. For fixing it, we pass it along now, same for compute_sheet. taskid-6435024
Belgian payroll now correctly excludes retired employees from ONSS contribution types 825 and 835. This prevents incorrect payroll deductions and helps keep employer social security reporting compliant.
Original PR description
If an employee is retired, they should not contribute to 825 and 835 ONSS contributions. Task: 6314865
Users can once again choose a business record after selecting a model from a document’s details panel. This fixes a broken linking flow that showed a notification but did not open the record selection dialog, helping teams correctly attach documents to the right records.
Original PR description
Reproduce: 1. Go to Inbox 2. Select a file 3. Open the details panel 4. Click on the link to record field 5. Select a model -> You get a notification but no dialog to select a record. Cause: since the replacement of useState with useEffect, the state is updated when we save the record which occured as initial step, leading to the temporary resModel stored in the state to be immediately reset. Fix: remove the intermediate save entirely and clean state usage. Task-6313958
Payroll pay run summary figures now refresh automatically when payslips or related time data change, avoiding stale KPI values that previously required a manual page refresh. The fix also ensures cancelled payslips are excluded from employer cost totals and corrects Belgian payroll KPI calculations.
Original PR description
Bug : - create an unvalidated leave - on the payrun Time view, when validating the view -> click on continue -> error popup appears says you have unvalidated leave (BUG 1) - on the payrun Payslips…
Bug : - create an unvalidated leave - on the payrun Time view, when validating the view -> click on continue -> error popup appears says you have unvalidated leave (BUG 1) - on the payrun Payslips view, when canceling a payslip , the KPIs values don't change unless you refresh (BUG 2) Reason : - PayRunMixin now subscribes to its model's "update" bus event and forwards it to updatePayRun, so any pay run view whose model emits "update" keeps the summary in sync. - The natural trigger is the model's "update" bus event, but the mixin never listened to it. On top of that the relational payslip list never even emits "update" on a programmatic reload: model.load() (cog actions) and root.load() (form close, view-button reloads) rebuild the reactive root without calling notify(), which only fires on search/pager changes. The Time view gantt already worked around this because GanttModel.fetchData() calls notify() itself. Fix : - Subscribe payroll mixing to the "update" notif that will come from the underlaying models. - override the onRootLoad hook in payslipListCOntroller to call notify() which sends an "update" message when loading the data.(added a guarderail: only call the notify on the model if it's mounted) task - 6387933 Forward-Port-Of: odoo/enterprise#125194
The barcode flow now correctly blocks scanning products that were not reserved when extra products are not allowed, even after leaving and reopening a transfer. It also restores the ability to add products in immediate delivery transfers where that action is still valid, reducing inventory processing errors and workflow interruptions.
Original PR description
This [PR] made sure it was not possible to scan unreserved products when `allow_extra_product` was disabled, even when exiting and re-entering a transfer. It worked under the assumption that an immediate transfer always stays in draft, which is wrong for deliveries. The 2nd commit of this PR partly address this issue by allowing the user to add multiple products with the "Add Product" button when the transfer is immediate. While working on this issue, we encountered a bug in the scanning prevention that should have been caught by a tour but was not. This is fixed in the 1st commit. More details in the commit messages. [PR]: https://github.com/odoo/enterprise/pull/123793 Forward-Port-Of: odoo/enterprise#125906 Forward-Port-Of: odoo/enterprise#125313
HR Gantt views now handle employee grouping and search filters more consistently, so employees without related records can appear correctly when relevant. The change also prevents a team filter meant for the Time Off overview from showing in other HR planning views.
Original PR description
Every gantt that needed to display employees without records (without leaves, attendances, etc.) would implement their own `_get_gantt_data_group_by_employee()` function. They all do the exact same…
Every gantt that needed to display employees without records (without leaves, attendances, etc.) would implement their own `_get_gantt_data_group_by_employee()` function. They all do the exact same thing. This PR creates the reusable function `_get_gantt_data_with_empty()`, so that all the `_get_gantt_data()` functions can reuse that one. That function will guess the relation model from the `groupby` variable. `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 task-5502544
DHL Express deliveries sent through EasyPost no longer fail validation when an international order is split into multiple packages. The system now treats DHL's multi-package rate notice as informational while still blocking genuine shipping errors.
Original PR description
Steps to reproduce --- 1. Configure a `delivery_easypost` shipping method using the DHL Express carrier. 2. On an international delivery, use Put in Pack to create two or more packages. 3. Validate…
Steps to reproduce --- 1. Configure a `delivery_easypost` shipping method using the DHL Express carrier. 2. On an international delivery, use Put in Pack to create two or more packages. 3. Validate the delivery. Issue --- Validation is blocked with `DHLExpress: rate_error -- DHLExpress multi-shipment rate includes this shipment.` For an EasyPost multi-shipment order, DHL Express returns the aggregate rate on the first (master) shipment only and adds an informational `rate_error` on the order stating that this rate already covers the whole order, so the remaining shipments carry no rate of their own. The message is not a real error, but `send_shipping` raises on any carrier message whose type is not exempt: https://github.com/odoo/enterprise/blob/534b42def8ae5dc884da4398377f828c49557d6e/delivery_easypost/models/easypost_request.py#L359-L364 `_post_process_ship_response` already detects and clears exactly this harmless message, but only for a hardcoded carrier allowlist introduced in a2de5bc5a14 (`Purolator`, `DPD UK`, `UPS`) that was never extended to DHL Express, so for DHL Express the message survives, reaches the raise, and aborts an otherwise valid shipment: https://github.com/odoo/enterprise/blob/a2de5bc5a14f99b8674c3ee234e4d221b406da0f/delivery_easypost/models/easypost_request.py#L416-L434 `DHL Express` is added to that allowlist so the harmless multi-shipment `rate_error` is posted on the picking and cleared instead of raised. The guard still requires a single `rate_error` carrying the "multi-shipment rate includes this shipment." text with the rate present only on the master shipment, so genuine DHL Express errors keep blocking validation. opw-6450365 Forward-Port-Of: odoo/enterprise#127164
Online orders imported through UrbanPiper now calculate the per-item price correctly when taxes are included and customers order more than one unit. This prevents overstated order line prices and helps keep POS totals, tax amounts, and reporting accurate.
Original PR description
Steps to reproduce: --- - Configure a Point of Sale with UrbanPiper credentials. - Create a product priced at 100 with a 5% GST (Tax Included). - Sync the product with UrbanPiper. - Place an online order with a quantity greater than 1. Issue: --- - `total_with_tax` was incorrectly treated as the unit price for multi-quantity tax-included orders. Fix: --- - Calculate the unit price by dividing `total_with_tax` by the ordered quantity before creating the POS order line. task-6427634 Forward-Port-Of: odoo/enterprise#126940 Forward-Port-Of: odoo/enterprise#125989
Belgian payroll now automatically applies the legal minimum employee deduction for meal vouchers when a lower amount is configured. HR managers receive a non-blocking payslip warning so they know the amount was adjusted for compliance.
Original PR description
**What:** - Refactored the meal voucher salary rule computation to take the maximum between the configured employee share and the parameter-defined minimum threshold (€1.09). - Added a non-blocking warning message on the payslip to notify HR managers when an employee's configured share is below the legal minimum and has been automatically adjusted. task-6428585 Forward-Port-Of: odoo/enterprise#127444 Forward-Port-Of: odoo/enterprise#126194