def list_own_projects(request, timeslot=None): """ This lists all proposals that the given user has something to do with. Either a responsible or assistant. For Type3staff this lists all proposals. This is the usual view for staff to view their proposals. :param request: :param timeslot: optional timeslot to view proposals from, default is current ts. :return: """ if timeslot: ts = get_object_or_404(TimeSlot, pk=timeslot) projects = get_all_projects(old=True).filter(TimeSlot=ts) else: ts = None projects = get_all_projects(old=True).filter(TimeSlot=None) # proposals of future timeslot if get_grouptype("3") in request.user.groups.all() or get_grouptype("5") in request.user.groups.all(): pass else: projects = projects.filter(Q(ResponsibleStaff=request.user) | Q(Assistants=request.user)).distinct() projects = prefetch(projects) return render(request, 'proposals/list_projects_custom.html', { 'hide_sidebar': True, 'projects': projects, 'favorite_projects': get_favorites(request.user), 'timeslots': get_recent_timeslots(), 'timeslot': ts, })
def list_private_projects(request, timeslot=None): """ List all private proposals. :param request: :param timeslot: timeslot to show projects from. :return: """ if timeslot: ts = get_object_or_404(TimeSlot, pk=timeslot) projects = get_all_projects(old=True).filter(TimeSlot=ts) else: ts = None projects = get_all_projects(old=True).filter(TimeSlot=None) # proposals of future timeslot projects = prefetch(projects.filter(Private__isnull=False).distinct()) return render(request, "proposals/list_projects_custom.html", { 'hide_sidebar': True, 'projects': projects, 'favorite_projects': get_favorites(request.user), "title": "All private proposals", 'timeslots': get_recent_timeslots(), 'timeslot': ts, "private": True # to show extra column with private students })
def list_track(request, timeslot=None): """ List all proposals of the track that the user is head of. :param request: :param timeslot: Time slot to show projects from :return: """ if not Track.objects.filter(Head=request.user).exists(): raise PermissionDenied("This page is only for track heads.") tracks = Track.objects.filter(Head__id=request.user.id) if timeslot: ts = get_object_or_404(TimeSlot, pk=timeslot) projects = get_all_projects(old=True).filter(TimeSlot=ts) else: ts = None projects = get_all_projects(old=True).filter(TimeSlot=None) # proposals of future timeslot projects = projects.filter(Track__in=tracks) projects = prefetch(projects) return render(request, "proposals/list_projects_custom.html", { 'projects': projects, 'favorite_projects': get_favorites(request.user), "title": "Proposals of track {}".format(print_list(tracks)), 'timeslots': get_recent_timeslots(), 'timeslot': ts, })
def list_group_projects(request, timeslot=None): """ List all proposals of a group. :param request: :param timeslot: timeslot to view.l :return: """ if timeslot: ts = get_object_or_404(TimeSlot, pk=timeslot) projects = get_all_projects(old=True).filter(TimeSlot=ts) else: ts = None projects = get_all_projects(old=True).filter( TimeSlot=None) # proposals of future timeslot projects = prefetch( projects.filter(Group__Administrators=request.user).distinct()) return render( request, 'proposals/list_projects_custom.html', { 'hide_sidebar': True, 'projects': projects, 'title': 'Proposals of {}'.format( print_list( request.user.administratoredgroups.all().values_list( 'Group__ShortName', flat=True))), 'timeslots': get_recent_timeslots(), 'timeslot': ts, })
def list_users(request, filter=False): """ List of all active users, including upgrade/downgrade button for staff and impersonate button for admins :param request: :return: """ if filter == 'all': users = User.objects.all() elif filter == 'current': users = User.objects.filter( Q(groups__isnull=False) | Q(usermeta__TimeSlot=get_timeslot())).distinct() else: # recent users = User.objects.filter( Q(groups__isnull=False) | Q(usermeta__TimeSlot__id__in=[ x.id for x in get_recent_timeslots() ]) | (Q(usermeta__TimeSlot=None) & Q(last_login__isnull=False))).distinct() return render( request, "support/list_users.html", { "users": users.prefetch_related('groups', 'usermeta', 'usermeta__TimeSlot', 'administratoredgroups'), 'hide_sidebar': True, })
def project_stats(request, timeslot=None): """ Statistics for projects, allowed for all staff except unverified. :param request: :param timeslot: the time slot to view proposals from :return: """ Project = Proposal if timeslot is None: # all projects p = Proposal.objects.filter(TimeSlot=None) else: timeslot = get_object_or_404(TimeSlot, pk=timeslot) p = Proposal.objects.filter(TimeSlot=timeslot) totalnum = p.count() groups = CapacityGroup.objects.all() group_count_prop = [] group_count_distr = [] group_count_appl = [] group_labels = [] group_labels_appl = [] group_labels_distr = [] group_labels_prop = [] for group in groups: # groups is tupple of (shortname, longname) group_labels.append(str(group)) group_count_prop.append(p.filter(Group=group).count()) group_count_distr.append(p.filter(Group=group, distributions__isnull=False).count()) # not distinct because users. group_count_appl.append(p.filter(Group=group, applications__isnull=False).count()) # not distinct because users. # sort both lists for each count-type by count number, make sure labels are in correct order. if group_count_prop: group_count_prop, group_labels_prop = (list(t) for t in zip(*sorted(zip(group_count_prop, group_labels), reverse=True))) if group_count_distr: group_count_distr, group_labels_distr = (list(t) for t in zip(*sorted(zip(group_count_distr, group_labels), reverse=True))) if group_count_appl: group_count_appl, group_labels_appl = (list(t) for t in zip(*sorted(zip(group_count_appl, group_labels), reverse=True))) status_count = [] status_labels = [] for option in Project.StatusOptions: status_count.append(p.filter(Status=option[0]).count()) status_labels.append(option[1]) if status_count: status_count, status_labels = (list(t) for t in zip(*sorted(zip(status_count, status_labels), reverse=True))) track_count = [] track_labels = [] for track in Track.objects.all(): track_count.append(p.filter(Track=track).distinct().count()) track_labels.append(track.__str__()) if track_count: track_count, track_labels = (list(t) for t in zip(*sorted(zip(track_count, track_labels), reverse=True))) return render(request, 'proposals/stats_project.html', { 'num': totalnum, # 'done': p.filter(Approved=True).count(), 'timeslots': get_recent_timeslots(), 'timeslot': timeslot, "mincapacity": p.aggregate(Sum('NumStudentsMin'))['NumStudentsMin__sum'], "maxcapacity": p.aggregate(Sum('NumStudentsMax'))['NumStudentsMax__sum'], 'data': [ { 'label': 'Projects by capacity group', 'labels': group_labels_prop, 'counts': group_count_prop, 'total': sum(group_count_prop), }, { # 'label': 'Master program', # 'labels': program_labels, # 'counts': program_count, # 'total': totalnum, # }, { 'label': 'Status options', 'labels': status_labels, 'counts': status_count, 'total': sum(status_count), }, { 'label': 'Track options', 'labels': track_labels, 'counts': track_count, 'total': sum(track_count), }, { 'label': 'Applications by capacity group', 'labels': group_labels_appl, 'counts': group_count_appl, 'total': sum(group_count_appl), }, { 'label': 'Distributions by capacity group', 'labels': group_labels_distr, 'counts': group_count_distr, 'total': sum(group_count_distr), }, # { # 'label': 'Progress', # 'labels': progress_labels, # 'counts': progress_count, # 'total': sum(progress_count), # }, { # 'label': 'Type', # 'labels': type_labels, # 'counts': type_count, # 'total': sum(type_count), # } ], })
def list_students(request, timeslot): """ For support staff, responsibles and assistants to view their students. List all students with distributions that the current user is allowed to see. Including a button to view the students files. In later timephase shows the grades as well. :param request: :param timeslot: the timeslot to look at. None for current timeslot (Future distributions do not exist) :return: """ ts = get_object_or_404(TimeSlot, pk=timeslot) if ts.Begin > timezone.now().date(): raise PermissionDenied("Future students are not yet known.") if ts == get_timeslot(): current_ts = True else: current_ts = False if current_ts: # for current timeslot, check time phases. if get_timephase_number() < 0: # no timephase if get_timeslot() is None: # no timeslot raise PermissionDenied("System is closed.") else: if get_timephase_number() < 4: raise PermissionDenied("Students are not yet distributed") if get_timephase_number() < 5 and not get_grouptype( "3") in request.user.groups.all(): return render( request, "base.html", { 'Message': "When the phase 'Distribution of projects' is finished, you can view your students here." }) if get_timephase_number() == -1 or get_timephase_number( ) >= 6: # also show grades when timeslot but no timephase. show_grades = True else: show_grades = False else: # historic view of distributions. Hide grades, as they might have changed outside the system. show_grades = False des = get_distributions(request.user, ts).select_related( 'Proposal__ResponsibleStaff', 'Proposal__Track', 'Student__usermeta').prefetch_related('Proposal__Assistants') cats = None if show_grades: cats = GradeCategory.objects.filter(TimeSlot=get_timeslot()) des.prefetch_related('results__Category') deslist = [] # make grades for d in des: reslist = [] if show_grades: for c in cats: try: reslist.append(d.results.get(Category=c).Grade) except CategoryResult.DoesNotExist: reslist.append('-') deslist.append([d, reslist]) return render( request, "support/list_students.html", { 'des': deslist, 'typ': cats, 'show_grades': show_grades, 'hide_sidebar': True, 'timeslots': get_recent_timeslots(), 'timeslot': ts, 'is_current': current_ts, })
def list_students(request, timeslot=None): """ For support staff, responsibles and assistants to view their students. List all students with distributions that the current user is allowed to see. Including a button to view the students files. Shows the grades as well. :param request: :param timeslot: the timeslot to look at. None for current timeslot (Future distributions do not exist) :return: """ ts = None show_grades = False error = None # if error set, don't show students but do show notify and tabcontrol current_ts = False if not timeslot: error = 'There is currently not time slot active in the system.' else: ts = get_object_or_404(TimeSlot, pk=timeslot) if ts.Begin > timezone.now().date(): error = 'Future students are not yet known.' if ts == get_timeslot(): current_ts = True if current_ts: # for current timeslot, check time phases. if get_timephase_number() < 0: # no timephase if get_timeslot() is None: # no timeslot error = "System is closed." else: if get_timephase_number() < 4: error = "Students are not yet distributed" if get_timephase_number() < 5 and not get_grouptype( "3") in request.user.groups.all(): error = "When the phase 'Distribution of projects' is finished, you can view your students here." if get_timephase_number() == -1 or get_timephase_number( ) >= 6: # also show grades when timeslot but no timephase. show_grades = True else: # historic grades show_grades = True if error: # show error but not permissiondenied so still the tab view is shown. return render( request, "students/list_students.html", { 'error': error, 'hide_sidebar': True, 'timeslots': get_recent_timeslots(), 'timeslot': ts, 'is_current': current_ts, }) # show students and possibly grades des = get_distributions(request.user, ts).select_related( 'Proposal__ResponsibleStaff', 'Proposal__Track', 'Student__usermeta').prefetch_related('Proposal__Assistants', 'files__staffresponse') cats = None if show_grades: cats = GradeCategory.objects.filter(TimeSlot=ts) des.prefetch_related('results__Category') deslist = [] # make grades for d in des: reslist = [] if show_grades: for c in cats: try: reslist.append(d.results.get(Category=c).Grade) except CategoryResult.DoesNotExist: reslist.append('-') deslist.append([d, reslist]) return render( request, "students/list_students.html", { 'des': deslist, 'typ': cats, 'show_grades': show_grades, 'hide_sidebar': True, 'timeslots': get_recent_timeslots(), 'timeslot': ts, 'is_current': current_ts, })