Monday, August 10, 2026
9 changes · saas-19.3
Enhancements to existing features
Timesheet users can now select multiple assistant suggestions more smoothly by holding the mouse button and hovering across items. Ctrl-click no longer opens an unintended new Odoo page, reducing accidental navigation and making batch actions faster.
Original PR description
Currently when the user uses ctrl + click on a suggestion, a new odoo page is opened. This is an undesirable side effect and it is removed in this commit. Also, users have to manually click on each suggestion when they want to remove them in batch, or create one timesheet for a bunch of suggestion. This commit lets user hover over suggestion with the mouse button pressed to select them. task-6385047 Forward-Port-Of: odoo/enterprise#124642
Payroll no longer automatically changes a company car’s current driver when benefits are updated. Employees who choose or receive a company car are set as the future driver instead, preventing cars already reserved for someone from being offered again and reducing unnecessary follow-up tasks.
Original PR description
. Remove the auto-assignment of the Driver based on the payroll benefits. . If an employee signs a contract and selects the car or the car gets added to the employee's benefits, he should become the car's future driver. . Don't offer in the salary configurator cars for which the future driver is filled. . Don't generate a task every time the payroll officer assigns a new driver to the car . Add the corresponding tests task-6425360
Resolved issues and error corrections
TikTok Shop orders that arrive without a payment time, such as cash-on-delivery orders, can now be created and synchronized instead of failing. The system uses the order creation time temporarily and updates it once TikTok confirms payment, helping businesses avoid missing orders.
Original PR description
**Issue**
- TikTok Shop orders may be received without any `paid_time` value in the returned API data, particularly for _Cash On Delivery ([COD](https://seller-ph.tiktok.com/university/essay?knowledge_id=10004482&lang=en)) payments.
- When creating the order, `_create_order_from_data` accessed `order_data[‘paid_time’]` directly, which triggered a `KeyError` and prevented all orders from being fully synchronised.
**Changes**
- When creating an order, if `paid_time` is missing from the data provided by TikTok:
-> `date_order` is initialised with `create_time` as a fallback
-> The new field `tiktok_payment_pending` is set to `True` to mark the order as awaiting payment confirmation.
- During subsequent synchronisations, if `paid_time` is now provided by TikTok for a pending order,
-> `date_order` is updated with the new provided timestamp and the `tiktok_payment_pending` flag is reset.
opw-6440127
Forward-Port-Of: odoo/enterprise#126797This fix prevents field service tasks from getting stuck when marking them as done after a delivery, return, and re-delivery flow. It avoids repeated stock movement checks that could exhaust memory, improving reliability for service teams handling product returns.
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 EPF Summary report now calculates EPS contributions using the employee's basic salary, capped at ₹15,000, instead of using the EPF amount. This helps Indian payroll reports reflect the correct statutory contribution and reduces the risk of inaccurate compliance reporting.
Original PR description
**Steps to Reproduce** - Create an Indian employee. - Create a payslip for this employee. - Go to **Payroll > Reporting > EPF-ECR Report**. - Create a new report with the report type **EPF Summary**. **Before This Commit** - For the EPS contribution, we were calculating `min(15,000, EPF)` and then applying **8.33%** to the resulting amount. - This resulted in an incorrect EPS contribution amount. **After This Commit** - According to Indian payroll rules, the EPS contribution is calculated as 8.33% of `min(15,000, Basic Salary)`, rather than `8.33% of the EPF amount`. - This commit corrects the EPS contribution calculation accordingly. Task: [6442399](https://www.odoo.com/odoo/project/1251/tasks/6442399) Forward-Port-Of: odoo/enterprise#126608
The Timesheet Assistant now combines similar selected suggestions into one natural description, such as “Discussing with A and B” instead of repeating the same phrase with semicolons. This makes generated timesheet entries easier to read and reduces manual cleanup for users.
Original PR description
In this task, we improved the Timesheet Assistant by merging descriptions generated from the same rule templates. When multiple suggestions are selected that use the same rule template, the assistant now combines them into a single timesheet description instead of joining with ';' Example: Rule template: `Discussing with $1` Before: Discussing with A; Discussing with B After: Discussing with A and B Task-6348575 Forward-Port-Of: odoo/enterprise#126157
This fixes an issue where Kenyan POS receipts could miss the official SCU details and QR code even after the tax authority response was received. Receipts can now generate the verification QR code when the required signature is available, improving customer receipt completeness and compliance visibility.
Original PR description
The original issue coudn't be reproduced. But based on what was reported on the ticket, this should improve the behavior of the order receipt. Steps to reproduce: ------------------- * Setup the…
The original issue coudn't be reproduced. But based on what was reported on the ticket, this should improve the behavior of the order receipt. Steps to reproduce: ------------------- * Setup the l10n_ke module in 'production' mode * Make an order in POS and validate it > Observation: The receipt doesn't contain the SCU information and QR Why the fix: ------------ Based on the receipt screenshot shared on the ticket (from Odoo 19.3) we can see that some informations are shown on the ticket. The information shown are the one received from the etims api, it means the call went through and the response was received. As the qrCode URL only needs `l10n_ke_oscu_signature` to be generated, we can assume that if this field is set we can safely generate the URL and generate the QR code. https://github.com/odoo/enterprise/blob/ee7e6894ed313db844aeff5ba5e19de3ad94898e/l10n_ke_edi_oscu_pos/models/pos_order.py#L252-L256 Based on this assumption we can change the condition to return the URL or not based on the presence of `l10n_ke_oscu_signature` instead of the state of the order being `sent`. In 19.0, the receipt is showing no info at all (when 19.3 is showing some info like the signature). This is also happening because the URL was falsy. And when that is the case we do not show any SCU information https://github.com/odoo/enterprise/blob/ee7e6894ed313db844aeff5ba5e19de3ad94898e/l10n_ke_edi_oscu_pos/static/src/overrides/components/order_receipt/order_receipt.xml#L56 opw-6352120 Forward-Port-Of: odoo/enterprise#127045
DHL Express deliveries with multiple packages through EasyPost are no longer blocked by an informational carrier message. This lets valid international shipments proceed while still stopping genuine carrier 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
Belgian payroll now automatically applies the legal minimum employee contribution for meal vouchers when a lower amount is configured. HR managers also see 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