示例#1
0
文件: views.py 项目: Syerram/kairos
def post_attach_queue_save(sender, **kwargs):
    """
    Creates a weeksnapshot history &
    attaches the Approver-Queue instance to a Weeksnapshot object
    """

    is_draft = kwargs["is_draft"]
    instance = kwargs["instance"]
    # if not draft, then get next approver queue.
    if not is_draft:
        queue = Queue.objects.get_queue_for_model(sender)

        # add the next user in sequence
        approver_queue = next_approver_in_queue(instance, 0, queue)

        # found one, so lets move to the next approver. create approver queue history
        if approver_queue:
            # create a history for approver_queue with the original user
            # save record with 0 sequence in the history for the submitter
            approver_queue_history = ApproverQueueHistory(
                approver_queue=approver_queue,
                from_user=instance.user,
                from_status=ApproverQueue.submitted_status(),
                from_sequence=0,
                to_user=approver_queue.current_user,
                to_status=approver_queue.current_status,
                to_sequence=approver_queue.current_sequence,
            )
            approver_queue_history.save()
            # TODO: post signal to send email to the next person in queue
        else:
            workflow.signals.post_final_status_event.send(
                sender=type(instance), instance=instance, status=ApproverQueue.approved_status()
            )
示例#2
0
文件: forms.py 项目: Syerram/kairos
 def save(self, commit=True):
     book_timeoff = super(BookTimeOffForm, self).save(commit)
     status = ApproverQueue.in_queue_status()
     
     booktimeoff_inqueue_history = BookTimeOfffHistory(book_timeoff=book_timeoff, book_timeoff_status=status)
     booktimeoff_inqueue_history.save()
     
     return book_timeoff
示例#3
0
文件: views.py 项目: Syerram/kairos
def next_approver_in_queue(instance, sequence, queue=None, approver_queue=None):
    """
        gets next approver using the passed in sequence.
        If the approver is last in the sequence, then update target object        
    """
    if not queue:
        # fetch Queue first
        queue = Queue.objects.get_queue_for_model(instance)

    try:
        approver = Approver.objects.get_next_approver(queue, sequence)
    except Approver.DoesNotExist:
        # last one in the queue, that got approved, update & return none
        if approver_queue:
            approver_queue.current_status = ApproverQueue.approved_status()
            approver_queue.save()
            return approver_queue
        else:
            return None

    # create new approver-queue
    if approver.user:
        user = approver.user
    else:
        # check user or taxonomy user
        # gather the user using the taxonomy role
        taxonomy = instance.user.get_profile().taxonomy
        taxonomy_role = TaxonomyRole.objects.get(Q(taxonomy=taxonomy) & Q(role=approver.role))
        user = taxonomy_role.user

    # If the approver is final then, status will be approved
    status = ApproverQueue.in_queue_status()

    # create a new approver queue if one wasn't passed
    if not approver_queue:
        approver_queue = ApproverQueue(content_object=instance, content_type=queue.content_type)

    approver_queue.current_status = status
    approver_queue.current_user = user
    approver_queue.current_sequence = approver.sequence
    approver_queue.save()

    return approver_queue
示例#4
0
文件: views.py 项目: Syerram/kairos
def weeksnapshot_post_final_status_update(sender, **kwargs):
    """
    Called when weeksnapshot is updated with final status. 
    If banking, it updates the timeoff policy associated with the user's overtime policy.
    If not banking, ??? Lost in thin air
    
    Arguments:
        sender: expected to be `weeksnapshot`
        
    
    """
    if kwargs['status'] == ApproverQueue.approved_status():
        weeksnapshot = kwargs['instance']
        #check if user has overtime policy set
        user_overtime_policy = UserOverTimePolicy.objects.get(user_profile=weeksnapshot.user.get_profile())
        if user_overtime_policy:
            
            timesheet_type = ContentType.objects.get_for_model(Timesheet)
            week_type = ContentType.objects.get_for_model(WeekSnapshot)
                        
            #get the ruleset and run thru the validation
            conditions = user_overtime_policy.overtime_policy.overtime_policy_conditions.all()
            overtime_hours = 0
            banked_hours = 0
            for condition in conditions:
                if condition.ruleset.content_type == timesheet_type:
                    for timesheet in weeksnapshot.timesheets: 
                        if not timesheet.is_timeoff:                                                   
                            validated_instance = GenericAspect.validate((condition.ruleset,), timesheet)
                            overtime_hours, banked_hours = tally(validated_instance, condition, overtime_hours, banked_hours)                                
                elif condition.ruleset.content_type == week_type:
                    validated_instance = GenericAspect.validate((condition.ruleset,), weeksnapshot)
                    overtime_hours, banked_hours = tally(validated_instance, condition, overtime_hours, banked_hours)
            
            #update the user's timeoff policy linked to the overtime. only update if banked 
            if banked_hours:
                user_overtime_policy.bank_user_timeoff_policy.time_remaining += banked_hours
                user_overtime_policy.bank_user_timeoff_policy.save()
示例#5
0
文件: views.py 项目: Syerram/kairos
def queue_queryset(user):
    return ApproverQueue.objects.user_queue(user, ApproverQueue.in_queue_status())
示例#6
0
文件: views.py 项目: Syerram/kairos
def queue_shift(request, bit, id):
    """Shifts the queue according to the bit operator"""
    approver_queue = ApproverQueue.objects.get(id=id)
    current_user, current_sequence, current_status = (
        approver_queue.current_user,
        approver_queue.current_sequence,
        approver_queue.current_status,
    )
    if bit == "+":
        approver_queue = next_approver_in_queue(
            approver_queue.content_object, approver_queue.current_sequence, None, approver_queue
        )

        approver_queue_history = ApproverQueueHistory(
            approver_queue=approver_queue,
            from_user=current_user,
            from_status=current_status,
            from_sequence=current_sequence,
            to_user=approver_queue.current_user,
            to_status=approver_queue.current_status,
            to_sequence=approver_queue.current_sequence,
        )
        approver_queue_history.save()

        if approver_queue.current_status == ApproverQueue.approved_status():
            workflow.signals.post_final_status_event.send(
                sender=type(approver_queue.content_object),
                instance=approver_queue.content_object,
                status=ApproverQueue.approved_status(),
            )

        # TODO: post signal to send email to the next person in queue if not the last one

    elif bit == "-":
        # need to send it back to the original submitter
        approver_queue_history_head = ApproverQueueHistory.objects.get_head(approver_queue)

        # add a new approver-queue-history
        # TODO: duplicate code, make it generic
        approver_queue_history = ApproverQueueHistory(
            approver_queue=approver_queue,
            from_user=current_user,
            from_status=current_status,
            from_sequence=current_sequence,
            to_user=approver_queue_history_head.from_user,
            to_status=ApproverQueue.rejected_status(),
            to_sequence=approver_queue_history_head.from_sequence,
        )

        approver_queue_history.save()

        # update the current approver queue and set it to the original user
        approver_queue.current_status = ApproverQueue.rejected_status()
        approver_queue.current_user = approver_queue_history_head.from_user
        approver_queue.current_sequence = approver_queue_history_head.from_sequence
        approver_queue.save()

        # update the weeksnapshot status
        workflow.signals.post_final_status_event.send(
            sender=type(approver_queue.content_object),
            instance=approver_queue.content_object,
            status=ApproverQueue.rejected_status(),
        )

        # TODO: post signal to send email to the submitter with the rejection

    return "queue-r", {"items": ApproverQueue.objects.user_queue(request.user, ApproverQueue.in_queue_status())}
示例#7
0
文件: views.py 项目: Syerram/kairos
def weekly_view(request, year=None, week=None):
    """
    Current timesheet pulls the current week from the database. 
    if one doesn't exists, it creates in-mem object.
    If Post, saves it to the database
    """
    #TODO: have submit thru JSON
    year = year or date.today().year
    week = week or date.isocalendar()[1]
    
    if request.method == 'GET':
        user_projects = request.user.get_profile().projects
        start_week, end_week = determine_period(monday_of_week(int(week), int(year))) 
        extra_form = 1
        
        week_snapshot, timesheets = WeekSnapshot.objects.in_period(year, week, request.user)
        
        if not week_snapshot:
            week_snapshot = WeekSnapshot(user=request.user, year=year, week=week, start_week=start_week, end_week=end_week)
        else:
            extra_form = 0
            
        week_snapshot_form = WeekSnapshotForm(prefix="week_snapshot", instance=week_snapshot)
        
        TimesheetFormSet = modelformset_factory(Timesheet, can_delete=True, extra=extra_form, form=TimesheetForm)
        timesheet_form_set = TimesheetFormSet(queryset=timesheets)
        
        return 'timesheet', {'projects': user_projects, 'year': int(year), 'week': int(week), 'timesheet_form_set': timesheet_form_set, \
                             'week_snapshot': week_snapshot, 'week_snapshot_form': week_snapshot_form}
    else:
        is_draft = request.POST['is_draft'] == 'true'
        status = ApproverQueue.draft_status if is_draft else ApproverQueue.in_queue_status()
        
        week_snapshot = WeekSnapshot.objects.get_or_none(year=year, week=week, user=request.user)
        week_snapshot_form = WeekSnapshotForm(request.POST, prefix="week_snapshot", instance=week_snapshot)
        if week_snapshot_form.is_valid():
            week_snapshot = week_snapshot_form.save(request.user)            
        
        TimesheetFormSet = modelformset_factory(Timesheet, can_delete=True)    
        timesheet_form_set = TimesheetFormSet(request.POST)
        
        #Pull rulesets for weeksnapshot
        rulesets = RuleSet.objects.for_invoker_model(WeekSnapshot)
        
        timesheet_rulesets = rulesets.filter(content_type=ContentType.objects.get_for_model(Timesheet))
        week_rulesets = rulesets.filter(content_type=ContentType.objects.get_for_model(WeekSnapshot))
        #TODO: serve the errors through JSON errors
        if timesheet_form_set.is_valid():
            timsheets = timesheet_form_set.save()
            week_snapshot.timesheets.clear()
            #TODO: should batch all of the errors into one and send them back
            for timesheet in timsheets:
                if timesheet_rulesets:
                    validated_instance = GenericAspect.validate(timesheet_rulesets, timesheet)
                    if validated_instance.has_errors:
                        raise TypeError('ruleset errors encountered')
                week_snapshot.timesheets.add(timesheet)
            week_snapshot.save()
        else:
            raise TypeError('validation errors encountered')
        
        #check if we have validators
        if week_rulesets:
            validated_instance = GenericAspect.validate(week_rulesets, week_snapshot)
            if validated_instance.has_errors:
                raise TypeError('ruleset errors encountered')
        
        #add new status to the weeksnapshot
        post_status_update(week_snapshot, status)            
    
        #send signal since everything is done correctly
        workflow.signals.post_attach_queue_save_event.send(sender=WeekSnapshot, instance=week_snapshot, is_draft=is_draft)
            
        return 'home-r', {}
示例#8
0
def is_approved(weeksnapshot):
    return weeksnapshot.last_status == ApproverQueue.approved_status()
示例#9
0
def is_editable(weeksnapshot_status):
    """its editable if its in draft mode or rejected mode"""
    return weeksnapshot_status.code in (ApproverQueue.draft_status().code, ApproverQueue.rejected_status().code)
示例#10
0
def is_approved(booked_timeoff):
    return booked_timeoff.last_status == ApproverQueue.approved_status()