コード例 #1
0
def _get_ctype (db, user, date) :
    # None is a valide contract_type, return -1 in case of error
    dyn = user_dynamic.get_user_dynamic (db, user, date)
    if not dyn :
        dyn = user_dynamic.last_user_dynamic (db, user, date)
    if not dyn :
        return -1
    return dyn.contract_type
コード例 #2
0
def new_user_dynamic(db, cl, nodeid, new_values):
    common.require_attributes \
        ( _, cl, nodeid, new_values
        , 'user'
        , 'valid_from'
        , 'org_location'
        , 'department'
        )
    user = new_values['user']
    valid_from = new_values['valid_from']
    valid_to = new_values.get('valid_to', None)
    olo = new_values['org_location']
    dept = new_values['department']
    if freeze.frozen(db, user, valid_from):
        raise Reject(_("Frozen: %(valid_from)s") % locals())
    last = user_dynamic.last_user_dynamic(db, user)
    if not valid_to or not last or last.valid_from < valid_from:
        update_user_olo_dept(db, user, olo, dept)
    if 'durations_allowed' not in new_values:
        new_values['durations_allowed'] = False
    new_values ['valid_from'], new_values ['valid_to'] = \
        check_ranges (cl, nodeid, user, valid_from, valid_to)
    check_overtime_parameters(db, cl, nodeid, new_values)
    user_dynamic.invalidate_tr_duration \
        (db, user, new_values ['valid_from'], new_values ['valid_to'])
    orgl = db.org_location.getnode(olo)
    prev_dyn = user_dynamic.find_user_dynamic(db, user, valid_from, '-')
    if 'vacation_month' not in new_values and 'vacation_day' not in new_values:
        if prev_dyn:
            new_values['vacation_month'] = prev_dyn.vacation_month
            new_values['vacation_day'] = prev_dyn.vacation_day
        elif orgl.vacation_legal_year:
            new_values['vacation_month'] = 1
            new_values['vacation_day'] = 1
        else:
            d = new_values['valid_from']
            month, mday = (int(x) for x in d.get_tuple()[1:3])
            if month == 2 and mday == 29:
                mday = 28
            new_values['vacation_month'] = month
            new_values['vacation_day'] = mday
    if 'vacation_yearly' not in new_values:
        if prev_dyn:
            new_values['vacation_yearly'] = prev_dyn.vacation_yearly
        elif orgl.vacation_yearly:
            new_values['vacation_yearly'] = orgl.vacation_yearly
    check_vacation(db, cl, nodeid, 'vacation_yearly', new_values)
    check_weekly_hours(db, cl, nodeid, new_values)
コード例 #3
0
def create_dynuser(db, cl, nodeid, old_values):
    u = db.user.getnode(nodeid)
    s = None
    if 'user_status' in db.classes:
        s = db.user_status.lookup('valid')
    olo = cl.get(nodeid, 'org_location')
    dep = cl.get(nodeid, 'department')
    dyn = last_user_dynamic(db, nodeid)
    if nodeid > 2 and (not s or u.status == s) and not dyn and olo and dep:
        db.user_dynamic.create \
            ( user            = nodeid
            , valid_from      = Date ('.')
            , org_location    = olo
            , department      = dep
                   , vacation_yearly = 25
            )
コード例 #4
0
def approvals_pending (db, request, userlist) :
    try :
        db  = db._db
    except AttributeError :
        pass
    pending   = {}
    submitted = db.daily_record_status.lookup ('submitted')
    spec      = copy (request.filterspec)
    filter    = request.filterspec
    editdict  = {':template' : 'edit', ':filter' : 'user,date'}
    now       = Date ('.')
    for u in userlist :
        find_user   = dict (user = u, status = submitted)
        fdate       = None
        last_frozen = db.daily_record_freeze.filter \
            ( None
            , dict (user = u, date = now.pretty (';%Y-%m-%d'), frozen = True)
            , group = [('-', 'date')]
            )
        if last_frozen :
            fdate = db.daily_record_freeze.get (last_frozen [0], 'date') \
                  + common.day
            find_user ['date'] = fdate.pretty ('%Y-%m-%d;')
        dr_per_user = db.daily_record.filter (None, find_user)
        pending [u] = {}
        if dr_per_user :
            earliest = latest = None
            for p in dr_per_user :
                date = db.daily_record.get (p, 'date')
                week, year = common.weekno_year_from_day (date)
                if not earliest or date < earliest :
                    earliest = date
                if not latest   or date > latest :
                    latest   = date
                start, end = common.week_from_date (date)
                if fdate and start < fdate :
                    start = fdate
                filter ['date'] = common.pretty_range (start, end)
                filter ['user'] = u
                pending [u][(year, week)] = \
                    [ None
                    , request.indexargs_url ('', editdict)
                    , 'todo'
                    ]
            interval = latest - earliest
            for k in pending [u].iterkeys () :
                if interval < Interval ('31d') :
                    filter ['date'] = common.pretty_range (earliest, latest)
                    pending [u][k][0] = request.indexargs_url ('', editdict)
                else :
                    pending [u][k][0] = pending [u][k][1]
        else :
            dyn = user_dynamic.last_user_dynamic (db, u)
            if dyn and (not dyn.valid_to or not fdate or dyn.valid_to > fdate) :
                date = now
                if dyn.valid_to and dyn.valid_to < date :
                    date = dyn.valid_to
                week, year = common.weekno_year_from_day (date)
                start, end = common.week_from_date (date)
                if fdate and start < fdate :
                    start = fdate
                if dyn.valid_to and dyn.valid_to < end :
                    end   = dyn.valid_to
                filter ['date'] = common.pretty_range (start, end)
                filter ['user'] = u
                url = request.indexargs_url ('', editdict)
                pending [u][(year, week)] = [url, url, 'done']
    request.filterspec = spec
    return pending
コード例 #5
0
                )
            if dyn.contract_type:
                d['contract_type'] = dyn.contract_type
            print("Creating dynamic user for user%s" % dyn.user)
            dynid = db.user_dynamic.create(**d)
            dyn = db.user_dynamic.getnode(dynid)
        sys.stdout.flush()
        # Commit new dyn. user record for each user
        db.commit()

# Loop over all obsolete users, find WPs where a user is the only one
# allowed booking and set these WPs to the end-date of the last dyn.
# user record for that user
obs = db.user_status.lookup('obsolete')
for uid in db.user.filter(None, dict(status=obs)):
    dyn = user_dynamic.last_user_dynamic(db, uid)
    if not dyn:
        print("Obsolete user%s has no dynamic user data" % uid)
    if dyn and dyn.valid_to is None:
        print("Obsolete user%s has a valid dynamic user record!" % uid)
        continue
    vt = date.Date('2000-01-01')
    if dyn:
        vt = dyn.valid_to
    user = db.user.getnode(uid)
    snam = user.username.split('@', 1)[0]
    # Find WPs where this user is on the bookers list and which has no
    # end-date set. Note that we do not attempt to set the end-date to
    # the correct valid_to of the dynamic user if there already is an
    # end-date -- this would change the end-date of some project WPs
    # too.
コード例 #6
0
def check_freeze_record (db, cl, nodeid, new_values) :
    """Check that edits of a freeze record are ok.
       
       - editable
       - no thawed records before current record

       This also has to handle the case that while thawed the daily
       record was edited and we don't have a valid daily_record any
       longer. In that case we change the date to the last valid
       daily_record date. If that date is already frozen we retire the
       current record.
    """
    for i in ('date', 'user') :
        if i in new_values :
            raise Reject, _ ("%(attr)s must not be changed") % {'attr' : _ (i)}
    date = cl.get (nodeid, 'date')
    user = cl.get (nodeid, 'user')
    # special cases for fixing existing freeze records:
    if  (   db.getuid () == '1'
        and new_values.keys () == ['validity_date']
        and new_values ['validity_date'] == date
        and cl.get (nodeid, 'validity_date') is None
        ) :
        return
    if  (   db.getuid () == '1'
        and new_values.keys () == ['achieved_hours']
        and new_values ['achieved_hours'] == 0
        and cl.get (nodeid, 'achieved_hours') is None
        ) :
        return
    dyn  = get_user_dynamic (db, user, date)
    if not dyn :
        dyn    = last_user_dynamic (db, user, date = date)
        prev   = cl.filter \
            ( None
            , dict (user = user, date = date.pretty (';%Y-%m-%d'))
            , group = [('-', 'date')]
            )
        prev   = [p for p in prev if p != nodeid]
        if prev :
            prev = db.daily_record_freeze.getnode (prev [0])
        assert (dyn.valid_to)
        # already frozen??
        if prev and prev.date >= dyn.valid_to - day :
            for k in new_values.keys () :
                del new_values [k]
            cl.retire (nodeid)
            return
        date = dyn.valid_to - day
        new_values ['date'] = date
    check_editable (db, cl, nodeid, new_values, date = date)
    old_frozen = cl.get (nodeid, 'frozen')
    new_frozen = new_values.get ('frozen', old_frozen)
    freezing   = new_frozen != old_frozen and new_frozen
    attr       = 'balance'
    if freezing :
        check_thawed_records (db, user, date)
	fdate = new_values ['validity_date'] = min_freeze (db, user, date)
	balance, achieved = compute_balance (db, user, fdate, not_after = True)
	new_values [attr] = start_balance = balance
	new_values ['achieved_hours'] = achieved
    else :
	new_values ['validity_date'] = None
	new_values ['achieved_hours']      = None
	new_values [attr] = None
コード例 #7
0
def check_avc(db, cl, nodeid, new_values):
    """ Check that an absolute vacation correction exists at the date of
        the user_dynamic record if either the vac_aliq changed or the
        vac_aliq is monthly and the vacation changed (compared to the
        last user_dynamic record). We currently do not require a
        vacation correction if one already exists *and* there is a gap
        in user_dynamic record validity ranges.
    """
    # At least one of the following attributes must be in new_values
    # otherwise we don't have anything to check.
    attrs = ('vac_aliq', 'vacation_yearly', 'valid_from')
    for a in attrs:
        if a in new_values:
            break
    else:
        return
    va = new_values.get('vac_aliq')
    if not va and nodeid:
        va = cl.get(nodeid, 'vac_aliq')
    vy = new_values.get('vacation_yearly')
    if vy is None and nodeid:
        vy = cl.get(nodeid, 'vacation_yearly')
    # User must exist
    user = new_values.get('user')
    if not user:
        user = cl.get(nodeid, 'user')
    # valid_from must exist
    valid_from = new_values.get('valid_from')
    if not valid_from:
        valid_from = cl.get(nodeid, 'valid_from')
    prev_dyn = user_dynamic.find_user_dynamic(db, user, valid_from, '-')
    if not prev_dyn:
        return
    # Check if there is an absolute vacation correction for our
    # valid_from, everything ok if there is:
    dt = valid_from.pretty(common.ymd)
    vcs = db.vacation_correction.filter \
        (None, dict (user = user, date = dt, absolute = True))
    assert len(vcs) <= 1
    if not vcs:
        # Find the next vc backwards and check if it is at the end of
        # employment
        vcs = db.vacation_correction.filter \
            ( None
            , dict (user = user, date = ';%s' % dt, absolute = True)
            , sort = ('+', 'date')
            )
        if vcs:
            vc = db.vacation_correction.getnode(vcs[0])
            day = common.day
            # - day because we don't want to find the currently-change dyn
            vcdyn = user_dynamic.last_user_dynamic(db, user, valid_from - day)
            if not vcdyn.valid_to or vcdyn.valid_to > vc.date:
                vcs = []
    if vcs:
        assert db.vacation_correction.get(vcs[0], 'date') <= valid_from
        return
    if prev_dyn.vac_aliq != va:
        van = _('vac_aliq')
        raise Reject \
            ( _ ('Change of "%(van)s" without absolute vacation correction')
            % locals ()
            )
    vyo = prev_dyn.vacation_yearly
    if db.vac_aliq.get(va, 'name') == 'Monthly' and vy != vyo:
        vyn = _('vacation_yearly')
        raise Reject \
            ( _ ('Change of "%(vyn)s" without absolute vacation correction')
            % locals ()
            )
コード例 #8
0
def check_user_dynamic(db, cl, nodeid, new_values):
    old_ot = cl.get(nodeid, 'overtime_period')
    for i in 'user', :
        if i in new_values and cl.get(nodeid, i):
            raise Reject(_("%(attr)s may not be changed") % {'attr': _(i)})
    common.require_attributes \
        ( _, cl, nodeid, new_values
        , 'valid_from'
        , 'org_location'
        , 'department'
        )
    user = new_values.get('user', cl.get(nodeid, 'user'))
    old_from = cl.get(nodeid, 'valid_from')
    val_from = new_values.get('valid_from', old_from)
    val_to = new_values.get('valid_to', cl.get(nodeid, 'valid_to'))
    olo = new_values.get('org_location', cl.get(nodeid, 'org_location'))
    dept = new_values.get('department', cl.get(nodeid, 'department'))
    # Note: The valid_to date is *not* part of the validity interval of
    # the user_dynamic record. So when checking for frozen status we
    # can allow exactly the valid_to date.
    otw = common.overtime_period_week(db)
    nvk = list(sorted(new_values.keys()))
    old_flexmax = cl.get(nodeid, 'max_flexitime')
    vac_all = ('vacation_day', 'vacation_month', 'vacation_yearly', 'vac_aliq')
    vac_aliq = cl.get(nodeid, 'vac_aliq')
    vac_fix  = \
        (   set (nvk) <= set (vac_all)
        and 'vac_aliq' not in nvk or vac_aliq is None
        and db.getuid () == '1'
        )
    flexi_fix = \
        new_values.keys () == ['max_flexitime'] and old_flexmax is None
    if (freeze.frozen(db, user, old_from)
            and (new_values.keys() != ['valid_to'] or not val_to
                 or freeze.frozen(db, user, val_to))
            and (db.getuid() != '1' or old_ot or not otw
                 or new_values != dict(overtime_period=otw.id))
            and (db.getuid() != '1' or not flexi_fix) and not vac_fix):
        raise Reject(_("Frozen: %(old_from)s") % locals())
    last = user_dynamic.last_user_dynamic(db, user)
    if (('org_location' in new_values or 'department' in new_values) and
        (not val_to or last.id == nodeid or last.valid_from < val_from)):
        update_user_olo_dept(db, user, olo, dept)
    if 'valid_from' in new_values or 'valid_to' in new_values:
        new_values ['valid_from'], new_values ['valid_to'] = \
            check_ranges (cl, nodeid, user, val_from, val_to)
        val_from = new_values['valid_from']
        val_to = new_values['valid_to']
    if not vac_fix and not flexi_fix:
        check_overtime_parameters(db, cl, nodeid, new_values)
        check_vacation(db, cl, nodeid, 'vacation_yearly', new_values)
        if not freeze.frozen(db, user, old_from):
            user_dynamic.invalidate_tr_duration(db, user, val_from, val_to)
        else:
            old_to = cl.get(nodeid, 'valid_to')
            use_to = val_to
            if old_to:
                if val_to:
                    use_to = min(old_to, val_to)
                else:
                    use_to = old_to
            user_dynamic.invalidate_tr_duration(db, user, use_to, None)
    check_weekly_hours(db, cl, nodeid, new_values)