diff --git a/addons/hr_attendance/hr_attendance.py b/addons/hr_attendance/hr_attendance.py index a138d66a285..08323ce7847 100644 --- a/addons/hr_attendance/hr_attendance.py +++ b/addons/hr_attendance/hr_attendance.py @@ -64,18 +64,22 @@ class hr_attendance(osv.osv): } def _altern_si_so(self, cr, uid, ids, context=None): - for id in ids: - sql = ''' - SELECT action, name - FROM hr_attendance AS att - WHERE employee_id = (SELECT employee_id FROM hr_attendance WHERE id=%s) - AND action IN ('sign_in','sign_out') - AND name <= (SELECT name FROM hr_attendance WHERE id=%s) - ORDER BY name DESC - LIMIT 2 ''' - cr.execute(sql,(id,id)) - atts = cr.fetchall() - if not ((len(atts)==1 and atts[0][0] == 'sign_in') or (len(atts)==2 and atts[0][0] != atts[1][0] and atts[0][1] != atts[1][1])): + """ Alternance sign_in/sign_out check. + Previous (if exists) must be of opposite action. + Next (if exists) must be of opposite action. + """ + for att in self.browse(cr, uid, ids, context=context): + # search and browse for first previous and first next records + prev_att_ids = self.search(cr, uid, [('employee_id', '=', att.employee_id.id), ('name', '<', att.name), ('action', 'in', ('sign_in', 'sign_out'))], limit=1, order='name DESC') + next_add_ids = self.search(cr, uid, [('employee_id', '=', att.employee_id.id), ('name', '>', att.name), ('action', 'in', ('sign_in', 'sign_out'))], limit=1, order='name ASC') + prev_atts = self.browse(cr, uid, prev_att_ids, context=context) + next_atts = self.browse(cr, uid, next_add_ids, context=context) + # check for alternance, return False if at least one condition is not satisfied + if prev_atts and prev_atts[0].action == att.action: # previous exists and is same action + return False + if next_atts and next_atts[0].action == att.action: # next exists and is same action + return False + if (not prev_atts) and (not next_atts) and att.action != 'sign_in': # first attendance must be sign_in return False return True diff --git a/addons/hr_attendance/test/attendance_process.yml b/addons/hr_attendance/test/attendance_process.yml index 1d8308c2f45..4ad765d65df 100644 --- a/addons/hr_attendance/test/attendance_process.yml +++ b/addons/hr_attendance/test/attendance_process.yml @@ -28,4 +28,62 @@ - !assert {model: hr.employee, id: hr.employee_al, severity: error, string: Employee should be in absent state}: - state == 'absent' - +- + In order to check that first attendance must be Sign In. +- + !python {model: hr.attendance}: | + import time + try: + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 09:59:25'), 'action': 'sign_out'}, None) + except Exception, e: + assert e[0]=='ValidateError', e +- + First of all, Employee Sign's In. +- + !record {model: hr.attendance, id: hr_attendance_0}: + employee_id: hr.employee_niv + name: !eval time.strftime('%Y-%m-%d 09:59:25') + action: 'sign_in' +- + Now Employee is going to Sign In prior to First Sign In. +- + !python {model: hr.attendance}: | + import time + try: + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 08:59:25'), 'action': 'sign_in'}, None) + except Exception, e: + assert e[0]=='ValidateError', e +- + After that Employee is going to Sign In after First Sign In. +- + !python {model: hr.attendance}: | + import time + try: + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 10:59:25'), 'action': 'sign_in'}, None) + except Exception, e: + assert e[0]=='ValidateError', e +- + After two hours, Employee Sign's Out. +- + !record {model: hr.attendance, id: hr_attendance_1}: + employee_id: hr.employee_niv + name: !eval time.strftime('%Y-%m-%d 11:59:25') + action: 'sign_out' +- + Now Employee is going to Sign Out prior to First Sign Out. +- + !python {model: hr.attendance}: | + import time + try: + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 10:59:25'), 'action': 'sign_out'}, None) + except Exception, e: + assert e[0]=='ValidateError', e +- + After that Employee is going to Sign Out After First Sign Out. +- + !python {model: hr.attendance}: | + import time + try: + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 12:59:25'), 'action': 'sign_out'}, None) + except Exception, e: + assert e[0]=='ValidateError', e