From f44c5465701994e5bc9c8ea327b6baaa3e40e95c Mon Sep 17 00:00:00 2001 From: "Aurelien van Delft (avd)" Date: Wed, 22 Mar 2023 13:32:29 +0000 Subject: [PATCH] [FIX] hr_holidays: speedup Time Off dashboard When opening the Time Off App, the JS performs an rpc to call hr_leave_type.get_days_all_request. Inside this method there are some __get__ on non-stored computed fields. This triggers a recomputation of said fields in _compute_leaves. _compute_leaves uses _get_employees_days_per_allocation. When there is an hr.leave.type with request_unit = 'hour', you may get lots of validated allocations by employee. When this is the case, _get_employees_days_per_allocation gets quite slow, especially the last part about 'Future available leaves'. This commit optimizes this part of _get_employees_days_per_allocation. In this part the allocations are grouped by employees and Intervals instances are of the form (start, stop, records). This means that for a given employee_id, all the records of one Intervals will have the same start and stop values. This allows us to move the call to _get_work_days_data_batch outside of the for future_allocation_interval in future_allocation_intervals._items loop. Because _get_work_days_data_batch is quite expansive, moving it out grealty speeds up the _get_employees_days_per_allocation method. Example speedup: in a database with 50 validated allocations for the same hr.leave.type and employee_id, the timing of _get_employees_days_per_allocation 7.39s -> 158ms opw-3123457 closes odoo/odoo#117778 X-original-commit: 5a2efd2e5c3e65502c031f79f85319f3351f66e3 Signed-off-by: Kevin Baptiste --- addons/hr_holidays/models/hr_leave_type.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/hr_holidays/models/hr_leave_type.py b/addons/hr_holidays/models/hr_leave_type.py index 3d26c56244b..758eb3b1719 100644 --- a/addons/hr_holidays/models/hr_leave_type.py +++ b/addons/hr_holidays/models/hr_leave_type.py @@ -352,17 +352,17 @@ class HolidaysType(models.Model): for future_allocation_interval in future_allocation_intervals._items: if future_allocation_interval[0].date() > search_date: continue + employee_quantity_available = future_allocation_interval[2].employee_id._get_work_days_data_batch( + future_allocation_interval[0], + future_allocation_interval[1], + compute_leaves=False, + domain=company_domain)[employee_id] for allocation in future_allocation_interval[2]: if not allocation.active or allocation.date_from > search_date: continue days_consumed = allocations_days_consumed[employee_id][holiday_status_id][allocation] if future_allocation_interval[1] != fields.datetime.combine(date, time.max) + timedelta(days=5*365): - # Compute the remaining number of days/hours in the allocation only if it has an end date - quantity_available = allocation.employee_id._get_work_days_data_batch( - future_allocation_interval[0], - future_allocation_interval[1], - compute_leaves=False, - domain=company_domain)[employee_id] + quantity_available = employee_quantity_available else: # If no end date to the allocation, consider the number of days remaining as infinite quantity_available = {'days': float('inf'), 'hours': float('inf')}