From a23468c845425f3187c9c76dd2200fb9a1c9f3ab Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 5 Nov 2015 16:00:47 +0100 Subject: [PATCH] [FIX] hr_timesheet_sheet: total attendances & timesheets performances For these function fields, bypassing the ORM, using a SQL query, improves the execution time by 100 for a set of 80 timesheets in a database with - 250K `hr.analytic.timesheet` & - 250K `hr.attendance`. These function fields depends on a one2many field which use the SQL view `hr_timesheet_sheet_sheet_day`. When performing `sheet.period_ids`, two SQL requests are performed, - the first just to know the ids in the sql view matching this sheet - the second to read the fields `total_attendance` & `total_timesheet` and the request is performed on the entire set of lines of this view (~250K lines in the observed use case) while, when replaced by this SQL request, only one request is performed, on a restricted set of lines, speeding up significantly the computation of these computed fields for smaller sets of sheets. opw-653447 --- .../hr_timesheet_sheet/hr_timesheet_sheet.py | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py index ceb661f2bb6..d89552f087e 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py @@ -41,18 +41,24 @@ class hr_timesheet_sheet(osv.osv): """ Compute the attendances, analytic lines timesheets and differences between them for all the days of a timesheet and the current day """ + res = dict.fromkeys(ids, { + 'total_attendance': 0.0, + 'total_timesheet': 0.0, + 'total_difference': 0.0, + }) + + cr.execute(""" + SELECT sheet_id as id, + sum(total_attendance) as total_attendance, + sum(total_timesheet) as total_timesheet, + sum(total_difference) as total_difference + FROM hr_timesheet_sheet_sheet_day + WHERE sheet_id IN %s + GROUP BY sheet_id + """, (tuple(ids),)) + + res.update(dict((x.pop('id'), x) for x in cr.dictfetchall())) - res = {} - for sheet in self.browse(cr, uid, ids, context=context or {}): - res.setdefault(sheet.id, { - 'total_attendance': 0.0, - 'total_timesheet': 0.0, - 'total_difference': 0.0, - }) - for period in sheet.period_ids: - res[sheet.id]['total_attendance'] += period.total_attendance - res[sheet.id]['total_timesheet'] += period.total_timesheet - res[sheet.id]['total_difference'] += period.total_attendance - period.total_timesheet return res def check_employee_attendance_state(self, cr, uid, sheet_id, context=None):