def flexi_remain (db, user, date_in_year, ctype) : y = common.start_of_year (date_in_year) eoy = common.end_of_year (y) fa = flexi_alliquot (db, user, date_in_year, ctype) acpt = db.leave_status.lookup ('accepted') cnrq = db.leave_status.lookup ('cancel requested') if not fa : return 0 sd = 0 dyn = user_dynamic.get_user_dynamic (db, user, y) if not dyn : dyn = user_dynamic.first_user_dynamic (db, user, y) while dyn : # Check the case that we found a dyn user record far in the past if dyn.valid_to and dyn.valid_to < y : dyn = user_dynamic.next_user_dynamic (db, dyn) continue if dyn.contract_type == ctype : b = dyn.valid_from if b < y : b = y if b > eoy : break e = dyn.valid_to if e > eoy or not e : e = eoy else : e -= common.day ct = dyn.contract_type if dyn.all_in : sd += flexitime_submission_days (db, user, ct, b, e, acpt, cnrq) dyn = user_dynamic.next_user_dynamic (db, dyn) return fa - sd
def avg_hours_per_week_this_year (db, user, date_in_year) : """ Loop over all dyn records in this year and use only those with all-in set. For those we count the hours and compute the average over all all-in days. """ y = common.start_of_year (date_in_year) eoy = common.end_of_year (y) now = Date ('.') if eoy > now : eoy = now hours = 0.0 dsecs = 0.0 ds = 24 * 60 * 60 for dyn in user_dynamic.user_dynamic_year_iter (db, user, y) : if not dyn.all_in : continue vf = dyn.valid_from if vf < y : vf = y vt = dyn.valid_to if not vt or vt > eoy + common.day : vt = eoy + common.day dsecs += (vt - vf).as_seconds () drs = db.daily_record.filter \ (None, dict (date = common.pretty_range (vf, vt), user = user)) for drid in drs : dr = db.daily_record.getnode (drid) dur = user_dynamic.update_tr_duration (db, dr) hours += dur days = dsecs / ds assert days <= 366 if not days : return 0 avgday = hours / float (days) return avgday * 7
def flexi_alliquot (db, user, date_in_year, ctype) : """ Loop over all dyn records in this year and use only those with all-in set. For those we count the days and compute the year-alliquot number of max_flexitime days. """ y = common.start_of_year (date_in_year) eoy = common.end_of_year (y) flex = 0.0 dsecs = 0.0 ds = 24 * 60 * 60 for dyn in user_dynamic.user_dynamic_year_iter (db, user, y) : if not dyn.all_in or dyn.contract_type != ctype : continue vf = dyn.valid_from if vf < y : vf = y vt = dyn.valid_to if not vt or vt > eoy + common.day : vt = eoy + common.day flex += (vt - vf).as_seconds () * (dyn.max_flexitime or 0) dsecs += (vt - vf).as_seconds () assert dsecs / ds <= 366 if not flex : return 0.0 days = float ((eoy + common.day - y).as_seconds () / ds) flex /= ds return ceil (flex / days)
def user_dynamic_year_iter (db, user, date_in_year) : y = common.start_of_year (date_in_year) eoy = common.end_of_year (y) dyn = get_user_dynamic (db, user, y) if not dyn : dyn = first_user_dynamic (db, user, date = y) if not dyn : raise StopIteration ("No records found") yield dyn while dyn : dyn = next_user_dynamic (db, dyn) if not dyn or dyn.valid_from > eoy : raise StopIteration () yield (dyn)
def need_hr_approval \ (db, tp, user, ctype, first_day, last_day, stname, booked = False) : if tp.approval_hr : return True if stname != 'submitted' : return False if not tp.is_vacation : # Flexitime if tp.no_overtime and tp.max_hours == 0 : dyn = user_dynamic.get_user_dynamic (db, user, first_day) if not dyn or not dyn.all_in : return False fd = first_day if first_day.year != last_day.year : while fd.year != last_day.year : eoy = common.end_of_year (fd) rem = flexi_remain (db, user, fd, ctype) dur = leave_days (db, user, fd, eoy) if rem - dur < 0 : return True fd = eoy + common.day rem = flexi_remain (db, user, fd, ctype) dur = leave_days (db, user, fd, last_day) return rem - dur < 0 else : return False day = common.day ed = next_yearly_vacation_date (db, user, ctype, last_day) - day vac = remaining_vacation (db, user, ctype, ed) assert vac is not None dur = leave_days (db, user, first_day, last_day) # don't count duration if this is already booked, so we would count # this vacation twice. if booked : dur = 0 return ceil (vac) - dur < 0