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)
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
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)
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)
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)
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)
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)