Daily updates from Odoo
Tuesday, August 11, 2026
33 changes · master
Enhancements to existing features
Restaurant appointment table timers now use the same timing display and behavior as the core restaurant point-of-sale experience. This gives staff a more consistent, easier-to-read view of how long tables have been active, improving day-to-day floor management.
Original PR description
In this commit - -------------------------- - Match base timer formatting and behavior - Improve overall UX for table time tracking - Remove basic timer functionality from appointment and move it to restaurant Task-6152646 Related PR - https://github.com/odoo/odoo/pull/262756
Payroll warning checks now focus only on the relevant employee or payslip records instead of scanning broader sets of data. This reduces unnecessary processing and helps make some payroll warnings easier to maintain and translate, including for Belgian payroll workflows.
Original PR description
To reduce the amount of records fetched by domain warnings, active_ids will only fetch the ones we care about. This also makes it possible to translate some python warnings into domain now. task-6448866
Payroll accounting payments have been reorganized to make payment handling more consistent across payslips, employees, salary rules, and country-specific payroll flows. This should help payroll teams process and track salary payments more reliably, including payment registration and bank file workflows.
Original PR description
task-4592721
The Belgian payroll rules for double holiday pay have been corrected and improved. This helps payroll teams calculate and validate holiday-related payslips more reliably, reducing the risk of payroll errors.
Original PR description
task-5068001
This update reorganizes how payroll wage pay periods are managed across contracts, salary configuration, and payslip batches. It should make payroll setup and processing more consistent for HR teams, reducing confusion when employees are paid on different schedules.
Original PR description
task-5043999
Belgian payroll now better handles complementary salary payments made outside the normal monthly payroll cycle. The update adds regularization for social security contributions and withholding tax, helping corrections be taxed as if they were part of the regular salary calculation.
Original PR description
Sometimes a complementary salary need to be paid outside of the monthly pay (especially in case of corrections). The difference between a complementary salary and a bonus is the type of withholding tax that must be paid, complementary salary are those for which a standard withholding tax has to be paid. When some complementary salary are paid outside of the monthly pay, the withholding tax amount may be "wrong" and should be regularized. Example: a bonus of 250€ alone on a payslips will lead to a withholding tax of 0€ but if you consider it with the monthly pay it should be have been taxed. This commit introduces two new rules to regularize the ONSS and withholding tax amount. task-6001677
Payroll no longer uses a separate work entry type for periods outside an employee contract. This simplifies payslip calculations and reporting across payroll localizations by avoiding special handling for out-of-contract days.
Original PR description
task-6205747
Calendar events linked to a specific project or task are now matched using that direct link before relying on partner history. This helps employees create more accurate timesheets from calendar events and reduces manual corrections.
Original PR description
…the 'linked to' field Before this commit: - Calendar events are matched based on the most timesheet project of the partners. After this commit: - Calendar events are matched to projects/tasks via the "linked to field" before looking to partners projects. task-6238332 Forward-Port-Of: odoo/enterprise#123158
The spreadsheet date picker now enters dates as actual dates rather than plain numbers. This makes spreadsheet data clearer and helps avoid confusion or incorrect calculations when users work with dates.
Original PR description
Task: 6353692
Payroll now uses one clear rule to identify unpaid time: work entry types with a zero pay rate. This reduces configuration complexity across payroll localizations and helps prevent duplicate deductions, while extra hours are now identified through a dedicated payroll category.
Original PR description
The `unpaid_structure_ids` field was removed from work entry types to simplify the configuration. Previously, a work entry type could be marked as unpaid either by adding payroll structures to…
The `unpaid_structure_ids` field was removed from work entry types to simplify the configuration. Previously, a work entry type could be marked as unpaid either by adding payroll structures to `unpaid_structure_ids` or by setting `amount_rate` to 0. From now on, `amount_rate = 0` is the single source of truth for unpaid work entries. As part of this change: * Set `amount_rate` to 0 for out of contract entries, unpaid leaves, and all work entry types that were previously unpaid in monthly structures across localizations. * Kept `l10n_be_work_entry_type_notice` with `amount_rate = 1`. Although it was marked as unpaid for the 13th month structure, it remains paid in the monthly structure. Since work day lines are not used in the 13th month computation, keeping its rate would have no functional impact on the 13th month payroll calculation. * Removed unpaid work entry types from the Belgian `REMUNERATION_BASE`, `ONSS_BASE`, and `WITHHOLDING_BASE` categories, as they now have `amount_rate = 0` and therefore no impact on these bases. * Removed Egyptian salary rules that deducted unpaid leaves and out of contract periods. Since these work entries now contribute 0 to the base salary, keeping the deduction rules would result in double deductions. --- Introduce the `EXTRA_HOURS` category on work entry types as the source of truth for identifying extra hours. The `is_extra_hours` field is moved from `hr_work_entry` to `hr_payroll` and turned into a stored computed field based on the work entry type categories. This preserves its usage in payroll computations while making the category the source of truth. Task: 6292486
Belgian payroll now supports creating customized premium pay child categories and related rules. This gives payroll teams more flexibility to model company-specific premium pay needs while keeping calculations organized and test-covered.
Original PR description
Allow to create customized premium pay children task-6394804
Payslip salary rule lines are now shown in either the main payslip body or the extra information section, not both. This makes payslips clearer and ensures correction payslips show only the relevant difference in the extra information section too.
Original PR description
For salary rules, the "Visibility" (`appears_on_payslip`) and the "Show in extra info section" (`display_in_pdf_extra_info`) fields were unrelated. That means that a payslip line could be shown twice if (for e.g.) a salary rule with ```python appears_on_payslip = 'always' display_in_pdf_extra_info = True ``` would be shown twice in the payslip (once in the body and once in the extra info section) This PR fixes that to make it intuitive, now `appears_on_payslip` only affects the visibility, and `display_in_pdf_extra_info` only affects the placement of the line. So that it is never shown twice. The PR also makes it so that the "delta" logic (i.e.: showing only the difference in correction payslips) is also done in that section (it wasn't the case previously) task-6376147
Helpdesk customer rating settings are now managed per ticket stage instead of per team. This makes rating visibility and rating request emails more reliable, so businesses can control exactly when customer feedback is requested.
Original PR description
- Before this commit, the customer rating configuration was managed on `helpdesk.team`, which led to inconsistent behavior: - ratings could still appear even when disabled on the team - rating request emails could still be sent after disabling the feature - After this commit, the rating configuration is moved to `helpdesk.stage`, aligning the behavior with the Project and ensuring that ratings and rating request emails are controlled reliably through stage configuration. - The `Customer Ratings` option is removed from the helpdesk team form view. task-5119003
The Time Off planning calendar has been improved to make leave scheduling easier to review and manage. This should help HR teams work more efficiently when viewing and selecting multiple time off entries in the Gantt view.
Original PR description
task-6449840
US payroll configuration is improved with clearer field labels and updated default accounting mappings for salary rules and payroll tax categories. This helps payroll teams produce more consistent accounting entries while removing an obsolete California ETT tax field.
Original PR description
. Change fields labels . Remove CA ETT Tax field . Add default debit account Employee Payroll Taxes to Taxes rules category . Add default debit account Payroll Taxes and default credit account Employee Payroll Taxes to Employer Deductions rules category . Add default debit account Salaries and Wages to Basic salary rule . Remove default debit account and default credit account to Gross salary rule task-6374068
Belgian payroll users can now generate meal voucher reports from branch companies, not only the main company. This helps meet Partena requirements and makes payroll reporting more flexible for businesses with branch structures.
Original PR description
Currently, It's not possible to compute a meal voucher report from branch company. This PR introduces support for generating meal voucher reports from a branch company to meet Partena's requirements. Removing this constraint allows meal voucher reports to be generated from branch companies. task-6428777
All people signing a document can now choose whether their signature includes a frame, not just internal Odoo users. The signing dialog also has clearer borders around the name field and signature options, making the public signing experience easier to understand and use.
Original PR description
Version: 19.0 Before this PR: The 'Frame' checkbox in the 'Adopt Your Signature' dialog was only shown to internal Odoo users (users with the `base.group_user` group).Also, on the public signing page, the Full Name input, the Frame checkbox and the Auto/Draw/Load buttons had no visible border After this PR: The 'Frame' checkbox is now rendered for every signer in the 'Adopt Your Signature' dialog. The Full Name input, Frame checkbox and Auto/Draw/Load buttons now have a visible border. Taskid-4610728 Forward-Port-Of: odoo/enterprise#127439 Forward-Port-Of: odoo/enterprise#126789
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
Code cleanup and technical improvements
Time zone settings are being moved from individual work schedules to the company level. This simplifies configuration and helps keep attendance, leave, payroll, planning, project, and maintenance calculations consistent across business processes.
Original PR description
This commit removes the timezone field on resource_calendar and adds a new timezone field on the company. task-5124688
The pricing label management features have been moved into their own Pricer app so they can be reused beyond Point of Sale, such as in Inventory. This also makes Pricer store and tag management accessible from the Inventory app, supporting broader operational use.
Original PR description
We extract `pricer` logic from `pos_pricer` to later use pricer in other modules (e.g. `stock`). task-6377740