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 min_freeze (db, user, date) : """ Compute minimum freeze date over all monthly periods. We loop over all the dyn user records to find the last date when that period was active and compare the freeze_date to the current freeze_date. Only if these match is the period considered for selecting the min_freeze. """ periods = overtime_periods (db, user, start_of_year (date), date) freeze = date for s, e, p in periods : x = freeze_date (date, p) y = freeze_date (e, p) if y < x : continue if x < freeze : freeze = x return freeze