From 39d3da451ca7bab6ea806e8a7711d53151c100fd Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Thu, 25 Jan 2024 10:51:48 +0100 Subject: [PATCH] [FIX] resource: Improve _leave_intervals_batch performances On N elements resource.calendar.leave and M elements resource.resource recordsets, the __get__ calls to 4 leave fields were done M time per loop, aka 4*N*M times. This commit reduces the number of call to 4*N times, reducing the method executing time for grid_unavailability from 9 seconds to +- 4.5 on odoo.com while displaying all timesheets on Month view. closes odoo/odoo#150408 Related: odoo/enterprise#54830 Signed-off-by: Xavier Bol (xbo) --- addons/resource/models/resource_calendar.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/addons/resource/models/resource_calendar.py b/addons/resource/models/resource_calendar.py index 7d653084c1e..1d2d79d755d 100644 --- a/addons/resource/models/resource_calendar.py +++ b/addons/resource/models/resource_calendar.py @@ -399,9 +399,14 @@ class ResourceCalendar(models.Model): # retrieve leave intervals in (start_dt, end_dt) result = defaultdict(lambda: []) tz_dates = {} - for leave in self.env['resource.calendar.leaves'].search(domain): + all_leaves = self.env['resource.calendar.leaves'].search(domain) + for leave in all_leaves: + leave_resource = leave.resource_id + leave_company = leave.company_id + leave_date_from = leave.date_from + leave_date_to = leave.date_to for resource in resources_list: - if leave.resource_id.id not in [False, resource.id] or (not leave.resource_id and resource and resource.company_id != leave.company_id): + if leave_resource.id not in [False, resource.id] or (not leave_resource and resource and resource.company_id != leave_company): continue tz = tz if tz else timezone((resource or self).tz) if (tz, start_dt) in tz_dates: @@ -414,8 +419,8 @@ class ResourceCalendar(models.Model): else: end = end_dt.astimezone(tz) tz_dates[(tz, end_dt)] = end - dt0 = string_to_datetime(leave.date_from).astimezone(tz) - dt1 = string_to_datetime(leave.date_to).astimezone(tz) + dt0 = string_to_datetime(leave_date_from).astimezone(tz) + dt1 = string_to_datetime(leave_date_to).astimezone(tz) result[resource.id].append((max(start, dt0), min(end, dt1), leave)) return {r.id: Intervals(result[r.id]) for r in resources_list}