def _get_attendance(self, cr, uid, ids, field_name, arg, context=None): """ Generate list of attendance associated to the this journal. """ res = {} data = self.read(cr, uid, ids, ['employee_id', 'turn_start', 'turn_end'], context=context) delta = tu.timedelta(hours=2) for d in data: turn_start = d['turn_start'] turn_end = d['turn_end'] employee_id = d['employee_id'][0] _id = d['id'] if turn_start: sql_req= """ SELECT A.id FROM hr_attendance as A WHERE A.employee_id = %d AND ('%s'::timestamp, '%s'::timestamp) OVERLAPS (A.name, A.name) ORDER BY A.name asc""" % ( employee_id, tu.dt(turn_start) - delta, tu.dt(turn_end) + delta ) cr.execute(sql_req) sql_res = cr.fetchall() if len(sql_res) > 0: res[_id] = map(lambda (i,): i, sql_res) else: res[_id] = [] return res
def _date_overlaps(self, cr, uid, ids, date, context=None): res = {} for j in self.browse(cr, uid, ids): r = True r = r and tu.dt(j.turn_start) - tu.timedelta(hours=2) < date r = r and date < tu.dt(j.turn_end) + tu.timedelta(hours=2) res[j.id] = r return res
def _date_range_overlaps(self, cr, uid, ids, date_from, date_to, context=None): res = {} for j in self.browse(cr, uid, ids): r = date_from < date_to and not ( (date_to < tu.dt(j.turn_start)) or (tu.dt(j.turn_end) < date_from) ) res[j.id] = r return res
def _get_day_end(self, cr, uid, ids, field_name, arg, context=None): res = {} dtc = lambda sd: tu.dt(sd.sign_out_id.name) for day in self.browse(cr, uid, ids): if day.attendance_ids: res[day.id] = tu.dt2s(max(map(lambda i: tu.dt(i.name), day.attendance_ids))) else: res[day.id] = False return res
def _inv_attendance(self, cr, uid, ids, field_name, value, arg, context=None): """ Store attendance from a journal. Assign employee id and set the correct datetime. """ jou_id = ids for no_se, att_id, val in value: if val: # Who is the associated journal? if jou_id == 0: if not isinstance(ids, int): raise osv.except_osv(_('Error'), _('I expect process attendance just for one journal')) jou_id = ids jou = self.browse(cr, uid, jou_id) # Check date if not out of turn time. if not jou._date_overlaps(tu.dt(val['name']))[jou.id]: an = tu.datetime.combine(tu.d(jou.date).date(), tu.dt(val['name']).time()) if not jou._date_overlaps(an)[jou.id]: an = tu.datetime.combine(tu.d(jou.date).date() + tu.timedelta(days=1), tu.dt(val['name']).time()) val['name'] = tu.dt2s(an) if not (jou._date_overlaps(tu.dt(val['name']))): raise osv.except_osv(_('Error'), _('Attendance don\'t belong to this journal')) # Sort entries att_ids = [] values = [] for no_se, att_id, val in value: if val: att_ids.append(att_id) values.append(val) att_ids.sort() values.sort(key=lambda i: i['name']) attval = dict(zip(att_ids, values)) # Store new or modification for att_id, val in zip(att_ids, values): if val: if att_id == 0: val['employee_id'] = jou.employee_id.id self.pool.get('hr.attendance').create(cr, uid, val) else: self.pool.get('hr.attendance').write(cr, uid, att_id, val) # Delete entries for no_se, att_id, val in value: if not val: self.pool.get('hr.attendance').unlink(cr, uid, att_id)
def __getitem__(self, name): if name in self._local_cache: return self._local_cache[name] if name in self._cache: ret = self._cache[name] if isinstance(ret, bool): return ret field = self._field[name] if field["type"] in ["char", "int", "float", "selection"]: _r = ret elif field["type"] in ["datetime"]: _r = tu.dt(ret) elif field["type"] in ["date"]: _r = tu.d(ret) elif field["type"] in ["many2one"]: _r = Interface(*(self._parms + (ret[0], field["relation"]))) elif field["type"] in ["many2many", "one2many"]: _r = map(lambda a: Interface(*(self._parms + a)), zip(ret, [field["relation"]] * len(ret))) else: raise NotImplementedError, "Not implemented for %s of type %s (%s)." % (name, field["type"], str(ret)) self._local_cache[name] = _r return _r else: # raise ValueError, "Not exists %s in object." % name return False
def get_turn(self, cr, uid, ids, date, context=None): res = {} if isinstance(date, str): date = tu.dt(date) for cont in self.browse(cr, uid, ids): if (tu.d(cont.date_start) <= date and (cont.date_end == False or date <= tu.d(cont.date_end))): ts = filter( lambda i: i.dayofweek == str(date.weekday()) or i.dayofweek == '', cont.turn_id.timesheet_id) if len(ts) == 1: ddate = tu.datetime.combine(date.date(), tu.time(0)) res[cont.id] = ( ddate + tu.timedelta(hours=ts[0].hour_from), ddate + tu.timedelta(hours=24 * (ts[0].hour_from > ts[0].hour_to) + ts[0].hour_to)) elif len(ts) > 1: raise RuntimeError( "More than one turn enabled at same time. See Timesheet line." ) else: res[cont.id] = False else: res[cont.id] = False return res
def get_turn(self, cr, uid, ids, date, context=None): res = {} if isinstance(date, str): date = tu.dt(date) for cont in self.browse(cr, uid, ids): if (tu.d(cont.date_start) <= date and (cont.date_end == False or date <= tu.d(cont.date_end))): ts = filter(lambda i: i.dayofweek == str(date.weekday()) or i.dayofweek == '', cont.turn_id.timesheet_id) if len(ts) == 1: ddate = tu.datetime.combine(date.date(), tu.time(0)) res[cont.id] = (ddate + tu.timedelta(hours=ts[0].hour_from), ddate + tu.timedelta(hours= 24 * (ts[0].hour_from > ts[0].hour_to) + ts[0].hour_to)) elif len(ts) > 1: raise RuntimeError("More than one turn enabled at same time. See Timesheet line.") else: res[cont.id] = False else: res[cont.id] = False return res
def __getitem__(self, name): if name in self._local_cache: return self._local_cache[name] if name in self._cache: ret = self._cache[name] if isinstance(ret, bool): return ret field = self._field[name] if field['type'] in ['char', 'int', 'float', 'selection']: _r = ret elif field['type'] in ['datetime']: _r = tu.dt(ret) elif field['type'] in ['date']: _r = tu.d(ret) elif field['type'] in ['many2one']: _r = Interface(*(self._parms + (ret[0], field['relation']))) elif field['type'] in ['many2many', 'one2many']: _r = map(lambda a: Interface(*(self._parms + a)), zip(ret, [field['relation']] * len(ret))) else: raise NotImplementedError, \ "Not implemented for %s of type %s (%s)." % (name, field['type'], str(ret)) self._local_cache[name] = _r return _r else: # raise ValueError, "Not exists %s in object." % name return False
def _get_turn_date(self, cr, uid, ids, field_name, arg, context=None): res = self._get_turn_start(cr, uid, ids, field_name, arg, context=context) if not res: return False for k in res: if res[k]: res[k] = tu.dt2s( tu.datetime.combine(tu.dt(res[k]).date(), tu.time(0))) return res
def build(self, cr, uid, date_from, date_to, context=None): emp_pool = self.pool.get('hr.employee') con_pool = self.pool.get('hr.contract') journal_ids = [] for time in tu.daterange(tu.dt(date_from), tu.dt(date_to) + tu.timedelta(days=1)): journal_date = tu.dt2s(time) emp_ids = emp_pool.search(cr, uid, [], context=context) con_ids = emp_pool.get_valid_contract(cr, uid, emp_ids, time) for (emp_id, con_id) in con_ids.items(): emp = emp_pool.browse(cr, uid, emp_id, context=context) con = con_pool.browse(cr, uid, con_id, context=context) contract_hours = ( str(time.weekday()) in [ ts.dayofweek for ts in con.turn_id.timesheet_id ] ) * con.working_hours_per_day journal = { 'name': emp.name + time.strftime(' (%d/%m/%Y)'), 'date': journal_date, 'employee_id': emp_id, 'turn_id': con.turn_id.id, 'department_id': con.department_id.id, 'contract_hours': contract_hours, } jids = self.search(cr, uid, [ ('employee_id', '=', journal['employee_id']), ('date', '=', journal['date']), ]) if len(jids) == 0: journal_ids.append(self.create(cr, uid, journal, context=context)) else: logger.notifyChannel('hr.aa.journal', netsvc.LOG_INFO, 'Yet exists journal \'%s\'' % journal['name']) self.compute(cr, uid, journal_ids, context=context) return len(journal_ids)
def _inv_holidays(self, cr, uid, ids, field_name, value, arg, context=None): """ Store holidays from a journal. Assign employee id and set the correct datetime. Calculate number of days. """ jou_id = ids for no_se, hol_id, val in value: # Who is the associated journal? if jou_id == 0: if not isinstance(ids, int): raise osv.except_osv(_('Error'), _('I expect process holidays just for one journal')) jou_id = ids jou = self.browse(cr, uid, jou_id) # Employee in holiday must be the same employee # or none if not (not val['employee_id'] or jou.employee_id.id == val['employee_id']): raise osv.except_osv(_('Error'), _('You must assign holiday to the same employee of the journal')) # Check if range date if not out of turn range. if not ( jou._date_range_overlaps(tu.dt(val['date_from']), tu.dt(val['date_to']))[jou.id] ): raise osv.except_osv(_('Error'), _('You must define the holiday date range witch overlaps the turn range')) # Calculate number of days val['number_of_days'] = max([(tu.dt(val['date_to']) - tu.dt(val['date_from'])).days, 1]) if hol_id != 0: self.pool.get('hr.holidays').write(cr, uid, hol_id, val) else: self.pool.get('hr.holidays').create(cr, uid, val)
def _get_turn_start(self, cr, uid, ids, field_name, arg, context=None): res = {} conts = self._get_contract(cr, uid, ids, 'contract', None, context=context) items = conts.items() if len(items) == 0: return False att_ids, con_ids = tuple(map(list, zip(*items))) cons = self.pool.get('hr.contract').browse(cr, uid, con_ids) atts = self.pool.get('hr.attendance').browse(cr, uid, att_ids) for (att, cont) in zip(atts, cons): turns = [ (tu.dt(att.date) + tu.timedelta(days = int(i.dayofweek) - tu.dt(att.date).weekday(), hours=i.hour_from), tu.dt(att.date) + tu.timedelta(days = int(i.dayofweek) - tu.dt(att.date).weekday(), hours=i.hour_to + 24*(i.hour_to < i.hour_from))) for i in cont.turn_id.timesheet_id ] turns = filter(lambda (f,t): f - tu.timedelta(hours=6) <= tu.dt(att.datetime) and tu.dt(att.datetime) <= t + tu.timedelta(hours=6), turns) if len(turns) > 0: res[att.id] = tu.dt2s(turns[0][0]) else: res[att.id] = False return res
def _get_date(self, cr, uid, ids, field_name, arg, context=None): res = map(lambda a: (a.id, tu.dt2s(tu.datetime.combine(tu.dt(a.name).date(),tu.time(0)))), self.browse(cr, uid, ids)) return dict(res)