Beispiel #1
0
def membership_trainings_stats(request):
    """Display basic statistics for memberships and instructor trainings."""
    # today = datetime.date.today()
    data = (
            Membership.objects
            # .filter(agreement_end__gte=today, agreement_start__lte=today)
            .select_related('organization')
            .prefetch_related('task_set')
            .annotate(
                instructor_training_seats_total=(
                    F('seats_instructor_training') +
                    F('additional_instructor_training_seats')
                ),
                instructor_training_seats_utilized=(
                    Count('task', filter=Q(task__role__name='learner'))
                ),
                instructor_training_seats_remaining=(
                    F('seats_instructor_training') +
                    F('additional_instructor_training_seats') -
                    Count('task', filter=Q(task__role__name='learner'))
                ),
            )
    )

    filter_ = MembershipTrainingsFilter(request.GET, data)
    paginated = get_pagination_items(request, filter_.qs)
    context = {
        'title': 'Membership trainings statistics',
        'data': paginated,
        'filter': filter_,
    }
    return render(request, 'reports/membership_trainings_stats.html',
                  context)
Beispiel #2
0
def membership_trainings_stats(request):
    """Display basic statistics for memberships and instructor trainings."""
    # today = datetime.date.today()
    data = (
            Membership.objects
            # .filter(agreement_end__gte=today, agreement_start__lte=today)
            .select_related('organization')
            .prefetch_related('task_set')
            .annotate(
                instructor_training_seats_total=(
                    F('seats_instructor_training') +
                    F('additional_instructor_training_seats')
                ),
                instructor_training_seats_utilized=(
                    Count('task', filter=Q(task__role__name='learner'))
                ),
                instructor_training_seats_remaining=(
                    F('seats_instructor_training') +
                    F('additional_instructor_training_seats') -
                    Count('task', filter=Q(task__role__name='learner'))
                ),
            )
    )

    filter_ = MembershipTrainingsFilter(request.GET, data)
    paginated = get_pagination_items(request, filter_.qs)
    context = {
        'title': 'Membership trainings statistics',
        'data': paginated,
        'filter': filter_,
    }
    return render(request, 'reports/membership_trainings_stats.html',
                  context)
Beispiel #3
0
 def get_queryset(self):
     """Apply a filter to the queryset. Filter is compatible with pagination
     and queryset. Also, apply pagination."""
     if self.filter_class is None:
         self.filter = super().get_queryset()
     else:
         self.filter = self.filter_class(self.get_filter_data(),
                                         super().get_queryset())
     paginated = get_pagination_items(self.request, self.filter)
     return paginated
Beispiel #4
0
 def get_queryset(self):
     """Apply a filter to the queryset. Filter is compatible with pagination
     and queryset. Also, apply pagination."""
     if self.filter_class is None:
         self.filter = super().get_queryset()
     else:
         self.filter = self.filter_class(self.get_filter_data(),
                                         super().get_queryset())
     paginated = get_pagination_items(self.request, self.filter)
     return paginated
Beispiel #5
0
def membership_trainings_stats(request):
    """Display basic statistics for memberships and instructor trainings."""
    data = Membership.objects.prefetch_related(
        "organizations", "task_set"
    ).annotate(
        instructor_training_seats_public_total=(
            F("public_instructor_training_seats") +
            F("additional_public_instructor_training_seats")
            # Coalesce returns first non-NULL value
            + Coalesce("public_instructor_training_seats_rolled_from_previous",
                       0)),
        instructor_training_seats_public_utilized=(Count(
            "task",
            filter=Q(task__role__name="learner", task__seat_public=True))),
        instructor_training_seats_public_remaining=(
            F("public_instructor_training_seats") +
            F("additional_public_instructor_training_seats") + Coalesce(
                "public_instructor_training_seats_rolled_from_previous", 0) -
            Count("task",
                  filter=Q(task__role__name="learner", task__seat_public=True))
            - Coalesce("public_instructor_training_seats_rolled_over", 0)),
        instructor_training_seats_inhouse_total=(
            F("inhouse_instructor_training_seats") +
            F("additional_inhouse_instructor_training_seats")
            # Coalesce returns first non-NULL value
            + Coalesce(
                "inhouse_instructor_training_seats_rolled_from_previous", 0)),
        instructor_training_seats_inhouse_utilized=(Count(
            "task",
            filter=Q(task__role__name="learner", task__seat_public=False),
        )),
        instructor_training_seats_inhouse_remaining=(
            F("inhouse_instructor_training_seats") +
            F("additional_inhouse_instructor_training_seats") + Coalesce(
                "inhouse_instructor_training_seats_rolled_from_previous", 0) -
            Count(
                "task",
                filter=Q(task__role__name="learner", task__seat_public=False),
            ) - Coalesce("inhouse_instructor_training_seats_rolled_over", 0)),
    )

    filter_ = MembershipTrainingsFilter(request.GET, data)
    paginated = get_pagination_items(request, filter_.qs)
    context = {
        "title": "Membership trainings statistics",
        "data": paginated,
        "filter": filter_,
    }
    return render(request, "reports/membership_trainings_stats.html", context)
Beispiel #6
0
def all_trainees(request):
    filter = TraineeFilter(
        request.GET,
        queryset=Person.objects.annotate_with_instructor_eligibility(
        ).prefetch_related(
            Prefetch('task_set',
                     to_attr='training_tasks',
                     queryset=Task.objects.filter(role__name='learner',
                                                  event__tags__name='TTT')),
            'training_tasks__event',
            'trainingrequest_set',
            'trainingprogress_set',
            'trainingprogress_set__requirement',
            'trainingprogress_set__evaluated_by',
        ).annotate(
            is_swc_instructor=Sum(
                Case(When(badges__name='swc-instructor', then=1),
                     default=0,
                     output_field=IntegerField())),
            is_dc_instructor=Sum(
                Case(When(badges__name='dc-instructor', then=1),
                     default=0,
                     output_field=IntegerField())),
            is_lc_instructor=Sum(
                Case(When(badges__name='lc-instructor', then=1),
                     default=0,
                     output_field=IntegerField())),
        ).order_by('family', 'personal'))
    trainees = get_pagination_items(request, filter.qs)

    if request.method == 'POST' and 'discard' in request.POST:
        # Bulk discard progress of selected trainees
        form = BulkAddTrainingProgressForm()
        discard_form = BulkDiscardProgressesForm(request.POST)
        if discard_form.is_valid():
            for trainee in discard_form.cleaned_data['trainees']:
                TrainingProgress.objects.filter(trainee=trainee)\
                                        .update(discarded=True)
            messages.success(
                request, 'Successfully discarded progress of '
                'all selected trainees.')

            # Raw uri contains GET parameters from django filters. We use it
            # to preserve filter settings.
            return redirect(request.get_raw_uri())

    elif request.method == 'POST' and 'submit' in request.POST:
        # Bulk add progress to selected trainees
        instance = TrainingProgress(evaluated_by=request.user)
        form = BulkAddTrainingProgressForm(request.POST, instance=instance)
        discard_form = BulkDiscardProgressesForm()
        if form.is_valid():
            for trainee in form.cleaned_data['trainees']:
                TrainingProgress.objects.create(
                    trainee=trainee,
                    evaluated_by=request.user,
                    requirement=form.cleaned_data['requirement'],
                    state=form.cleaned_data['state'],
                    discarded=False,
                    event=form.cleaned_data['event'],
                    url=form.cleaned_data['url'],
                    notes=form.cleaned_data['notes'],
                )
            messages.success(
                request, 'Successfully changed progress of '
                'all selected trainees.')

            return redirect(request.get_raw_uri())

    else:  # GET request
        # If the user filters by training, we want to set initial values for
        # "requirement" and "training" fields.
        training_id = request.GET.get('training', None) or None
        try:
            initial = {
                'event': Event.objects.get(pk=training_id),
                'requirement': TrainingRequirement.objects.get(name='Training')
            }
        except Event.DoesNotExist:  # or there is no `training` GET parameter
            initial = None

        form = BulkAddTrainingProgressForm(initial=initial)
        discard_form = BulkDiscardProgressesForm()

    context = {
        'title': 'Trainees',
        'all_trainees': trainees,
        'swc': Badge.objects.get(name='swc-instructor'),
        'dc': Badge.objects.get(name='dc-instructor'),
        'lc': Badge.objects.get(name='lc-instructor'),
        'filter': filter,
        'form': form,
        'discard_form': discard_form
    }
    return render(request, 'trainings/all_trainees.html', context)
Beispiel #7
0
def all_trainees(request):
    filter = TraineeFilter(
        request.GET,
        queryset=all_trainees_queryset(),
    )
    trainees = get_pagination_items(request, filter.qs)

    if request.method == "POST" and "discard" in request.POST:
        # Bulk discard progress of selected trainees
        form = BulkAddTrainingProgressForm()
        discard_form = BulkDiscardProgressesForm(request.POST)
        if discard_form.is_valid():
            for trainee in discard_form.cleaned_data["trainees"]:
                TrainingProgress.objects.filter(trainee=trainee).update(
                    discarded=True)
            messages.success(
                request, "Successfully discarded progress of "
                "all selected trainees.")

            # Raw uri contains GET parameters from django filters. We use it
            # to preserve filter settings.
            return redirect(request.get_raw_uri())

    elif request.method == "POST" and "submit" in request.POST:
        # Bulk add progress to selected trainees
        instance = TrainingProgress(evaluated_by=request.user)
        form = BulkAddTrainingProgressForm(request.POST, instance=instance)
        discard_form = BulkDiscardProgressesForm()
        if form.is_valid():
            for trainee in form.cleaned_data["trainees"]:
                TrainingProgress.objects.create(
                    trainee=trainee,
                    evaluated_by=request.user,
                    requirement=form.cleaned_data["requirement"],
                    state=form.cleaned_data["state"],
                    discarded=False,
                    event=form.cleaned_data["event"],
                    url=form.cleaned_data["url"],
                    notes=form.cleaned_data["notes"],
                )
            messages.success(
                request, "Successfully changed progress of "
                "all selected trainees.")

            return redirect(request.get_raw_uri())

    else:  # GET request
        # If the user filters by training, we want to set initial values for
        # "requirement" and "training" fields.
        training_id = request.GET.get("training", None) or None
        try:
            initial = {
                "event": Event.objects.get(pk=training_id),
                "requirement":
                TrainingRequirement.objects.get(name="Training"),
            }
        except Event.DoesNotExist:  # or there is no `training` GET parameter
            initial = None

        form = BulkAddTrainingProgressForm(initial=initial)
        discard_form = BulkDiscardProgressesForm()

    context = {
        "title": "Trainees",
        "all_trainees": trainees,
        "swc": Badge.objects.get(name="swc-instructor"),
        "dc": Badge.objects.get(name="dc-instructor"),
        "lc": Badge.objects.get(name="lc-instructor"),
        "filter": filter,
        "form": form,
        "discard_form": discard_form,
    }
    return render(request, "trainings/all_trainees.html", context)
Beispiel #8
0
def all_trainees(request):
    filter = TraineeFilter(
        request.GET,
        queryset=Person.objects
            .annotate_with_instructor_eligibility()
            .prefetch_related(
                Prefetch('task_set',
                         to_attr='training_tasks',
                         queryset=Task.objects.filter(role__name='learner',
                                                      event__tags__name='TTT')),
                'training_tasks__event',
                'trainingrequest_set',
                'trainingprogress_set',
                'trainingprogress_set__requirement',
                'trainingprogress_set__evaluated_by',
            ).annotate(
                is_swc_instructor=Sum(Case(When(badges__name='swc-instructor',
                                                then=1),
                                           default=0,
                                           output_field=IntegerField())),
                is_dc_instructor=Sum(Case(When(badges__name='dc-instructor',
                                               then=1),
                                          default=0,
                                          output_field=IntegerField())),
                is_lc_instructor=Sum(Case(When(badges__name='lc-instructor',
                                               then=1),
                                          default=0,
                                          output_field=IntegerField())),
            )
    )
    trainees = get_pagination_items(request, filter.qs)

    if request.method == 'POST' and 'discard' in request.POST:
        # Bulk discard progress of selected trainees
        form = BulkAddTrainingProgressForm()
        discard_form = BulkDiscardProgressesForm(request.POST)
        if discard_form.is_valid():
            for trainee in discard_form.cleaned_data['trainees']:
                TrainingProgress.objects.filter(trainee=trainee)\
                                        .update(discarded=True)
            messages.success(request, 'Successfully discarded progress of '
                                      'all selected trainees.')

            # Raw uri contains GET parameters from django filters. We use it
            # to preserve filter settings.
            return redirect(request.get_raw_uri())

    elif request.method == 'POST' and 'submit' in request.POST:
        # Bulk add progress to selected trainees
        instance = TrainingProgress(evaluated_by=request.user)
        form = BulkAddTrainingProgressForm(request.POST, instance=instance)
        discard_form = BulkDiscardProgressesForm()
        if form.is_valid():
            for trainee in form.cleaned_data['trainees']:
                TrainingProgress.objects.create(
                    trainee=trainee,
                    evaluated_by=request.user,
                    requirement=form.cleaned_data['requirement'],
                    state=form.cleaned_data['state'],
                    discarded=False,
                    event=form.cleaned_data['event'],
                    url=form.cleaned_data['url'],
                    notes=form.cleaned_data['notes'],
                )
            messages.success(request, 'Successfully changed progress of '
                                      'all selected trainees.')

            return redirect(request.get_raw_uri())

    else:  # GET request
        # If the user filters by training, we want to set initial values for
        # "requirement" and "training" fields.
        training_id = request.GET.get('training', None) or None
        try:
            initial = {
                'event': Event.objects.get(pk=training_id),
                'requirement': TrainingRequirement.objects.get(name='Training')
            }
        except Event.DoesNotExist:  # or there is no `training` GET parameter
            initial = None

        form = BulkAddTrainingProgressForm(initial=initial)
        discard_form = BulkDiscardProgressesForm()

    context = {'title': 'Trainees',
               'all_trainees': trainees,
               'swc': Badge.objects.get(name='swc-instructor'),
               'dc': Badge.objects.get(name='dc-instructor'),
               'lc': Badge.objects.get(name='lc-instructor'),
               'filter': filter,
               'form': form,
               'discard_form': discard_form}
    return render(request, 'trainings/all_trainees.html', context)
Beispiel #9
0
def all_trainingrequests(request):
    filter = TrainingRequestFilter(
        request.GET,
        queryset=TrainingRequest.objects.all().prefetch_related(
            Prefetch('person__task_set',
                     to_attr='training_tasks',
                     queryset=Task.objects.filter(
                         role__name='learner',
                         event__tags__name='TTT').select_related('event')), ))

    emails = filter.qs.values_list('email', flat=True)
    requests = get_pagination_items(request, filter.qs)

    if request.method == 'POST' and 'match' in request.POST:
        # Bulk match people associated with selected TrainingRequests to
        # trainings.
        form = BulkChangeTrainingRequestForm()
        match_form = BulkMatchTrainingRequestForm(request.POST)

        if match_form.is_valid():
            event = match_form.cleaned_data['event']
            member_site = match_form.cleaned_data['seat_membership']
            open_seat = match_form.cleaned_data['seat_open_training']

            # Perform bulk match
            for r in match_form.cleaned_data['requests']:
                # automatically accept this request
                r.state = 'a'
                r.save()

                # assign to an event
                Task.objects.get_or_create(
                    person=r.person,
                    role=Role.objects.get(name='learner'),
                    event=event,
                    seat_membership=member_site,
                    seat_open_training=open_seat,
                )

            requests_count = len(match_form.cleaned_data['requests'])
            today = datetime.date.today()

            if member_site:
                if (member_site.seats_instructor_training_remaining -
                        requests_count <= 0):
                    messages.warning(
                        request,
                        'Membership "{}" is using more training seats than '
                        "it's been allowed.".format(str(member_site)),
                    )

                # check if membership is active
                if not (member_site.agreement_start <= today <=
                        member_site.agreement_end):
                    messages.warning(
                        request, 'Membership "{}" is not active.'.format(
                            str(member_site)))

                # show warning if training falls out of agreement dates
                if event.start and event.start < member_site.agreement_start \
                        or event.end and event.end > member_site.agreement_end:
                    messages.warning(
                        request,
                        'Training "{}" has start or end date outside '
                        'membership "{}" agreement dates.'.format(
                            str(event),
                            str(member_site),
                        ),
                    )

            messages.success(
                request, 'Successfully accepted and matched '
                'selected people to training.')

            # Raw uri contains GET parameters from django filters. We use it
            # to preserve filter settings.
            return redirect(request.get_raw_uri())

    elif request.method == 'POST' and 'discard' in request.POST:
        # Bulk discard selected TrainingRequests.
        form = BulkChangeTrainingRequestForm(request.POST)
        match_form = BulkMatchTrainingRequestForm()

        if form.is_valid():
            # Perform bulk discard
            for r in form.cleaned_data['requests']:
                r.state = 'd'
                r.save()

            messages.success(request, 'Successfully discarded selected '
                             'requests.')

            return redirect(request.get_raw_uri())

    elif request.method == 'POST' and 'accept' in request.POST:
        # Bulk discard selected TrainingRequests.
        form = BulkChangeTrainingRequestForm(request.POST)
        match_form = BulkMatchTrainingRequestForm()

        if form.is_valid():
            # Perform bulk discard
            for r in form.cleaned_data['requests']:
                r.state = 'a'
                r.save()

            messages.success(request, 'Successfully accepted selected '
                             'requests.')

            return redirect(request.get_raw_uri())

    elif request.method == 'POST' and 'unmatch' in request.POST:
        # Bulk unmatch people associated with selected TrainingRequests from
        # trainings.
        form = BulkChangeTrainingRequestForm(request.POST)
        match_form = BulkMatchTrainingRequestForm()

        form.check_person_matched = True
        if form.is_valid():
            # Perform bulk unmatch
            for r in form.cleaned_data['requests']:
                r.person.get_training_tasks().delete()

            messages.success(
                request, 'Successfully unmatched selected '
                'people from trainings.')

            return redirect(request.get_raw_uri())

    else:  # GET request
        form = BulkChangeTrainingRequestForm()
        match_form = BulkMatchTrainingRequestForm()

    context = {
        'title': 'Training Requests',
        'requests': requests,
        'filter': filter,
        'form': form,
        'match_form': match_form,
        'emails': emails,
    }

    return render(request, 'requests/all_trainingrequests.html', context)