uclouvain/osis-dissertation

View on GitHub
views/information.py

Summary

Maintainability
A
50 mins
Test Coverage
##############################################################################
#
#    OSIS stands for Open Student Information System. It's an application
#    designed to manage the core business of higher education institutions,
#    such as universities, faculties, institutes and professional schools.
#    The core business involves the administration of students, teachers,
#    courses, programs and so on.
#
#    Copyright (C) 2015-2019 Université catholique de Louvain (http://www.uclouvain.be)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    A copy of this license - GNU General Public License - is available
#    at the root of the source code of this program.  If not,
#    see http://www.gnu.org/licenses/.
#
##############################################################################
from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import user_passes_test
from django.db import models
from django.db.models import Q
from django.shortcuts import redirect, render, get_object_or_404

from base import models as mdl
from base.models.academic_year import current_academic_year
from base.models.education_group import EducationGroup
from base.models.enums import person_source_type
from base.models.person import Person
from dissertation.forms import AdviserForm, ManagerAdviserForm, ManagerAddAdviserForm, ManagerAddAdviserPreForm, \
    ManagerAddAdviserPerson, AddAdviserForm
from dissertation.models import adviser
from dissertation.models import dissertation_role
from dissertation.models import faculty_adviser
from dissertation.models.adviser import Adviser
from dissertation.models.dissertation_role import DissertationRole
from dissertation.models.enums import dissertation_status
from dissertation.models.enums.dissertation_role_status import DissertationRoleStatus
from dissertation.models.faculty_adviser import FacultyAdviser


###########################
#      TEACHER VIEWS      #
###########################


@login_required
@user_passes_test(adviser.is_teacher)
def informations(request):
    person = mdl.person.find_by_user(request.user)
    adv = adviser.search_by_person(person)
    return render(request, "informations.html", {
        'adviser': adv,
        'first_name': adv.person.first_name.title(),
        'last_name': adv.person.last_name.title()
    })


@login_required
@user_passes_test(adviser.is_teacher)
def informations_detail_stats(request):
    person = mdl.person.find_by_user(request.user)
    adv = adviser.search_by_person(person)

    advisers_pro = dissertation_role.search_by_adviser_and_role_stats(adv, 'PROMOTEUR')
    count_advisers_pro = dissertation_role.count_by_adviser_and_role_stats(adv, 'PROMOTEUR')
    count_advisers_pro_request = dissertation_role.count_by_adviser(adv, 'PROMOTEUR', 'DIR_SUBMIT')
    tab_education_group_count_pro = dissertation_role.get_tab_count_role_by_education_group(advisers_pro)

    advisers_copro = dissertation_role.search_by_adviser_and_role_stats(adv, 'CO_PROMOTEUR')
    count_advisers_copro = dissertation_role.count_by_adviser_and_role_stats(adv, 'CO_PROMOTEUR')
    tab_education_group_count_copro = dissertation_role.get_tab_count_role_by_education_group(advisers_copro)

    advisers_reader = dissertation_role.search_by_adviser_and_role_stats(adv, 'READER')
    count_advisers_reader = dissertation_role.count_by_adviser_and_role_stats(adv, 'READER')
    tab_education_group_count_read = dissertation_role.get_tab_count_role_by_education_group(advisers_reader)

    return render(request, 'informations_detail_stats.html',
                  {
                      'adviser': adv,
                      'count_advisers_copro': count_advisers_copro,
                      'count_advisers_pro': count_advisers_pro,
                      'count_advisers_reader': count_advisers_reader,
                      'count_advisers_pro_request': count_advisers_pro_request,
                      'tab_offer_count_pro': tab_education_group_count_pro,
                      'tab_offer_count_read': tab_education_group_count_read,
                      'tab_offer_count_copro': tab_education_group_count_copro
                  })


@login_required
@user_passes_test(adviser.is_teacher)
def informations_edit(request):
    person = mdl.person.find_by_user(request.user)
    adv = adviser.search_by_person(person)
    if request.method == "POST":
        form = AdviserForm(request.POST, instance=adv)
        if form.is_valid():
            adv = form.save(commit=False)
            adv.save()
            return redirect('informations')
    else:
        form = AdviserForm(instance=adv)
    return render(request, "informations_edit.html", {
        'form': form,
        'first_name': person.first_name.title(),
        'last_name': person.last_name.title(),
        'email': person.email,
        'phone': person.phone,
        'phone_mobile': person.phone_mobile
    })


@login_required
@user_passes_test(adviser.is_teacher)
def informations_add(request):
    if request.method == "POST":
        if 'search_form' in request.POST:  # step 2 : second form to select person in list
            return _manage_search_form(request)

        else:  # step 3 : everything ok, register the person as adviser
            form = AddAdviserForm(request.POST)
            if form.is_valid():
                adv = form.save(commit=False)
                adv.save()
                return render(request, 'informations_add.html', {'adv': adv})
            else:
                return redirect('dissertations')

    else:  # step 1 : initial form to search person by email
        form = ManagerAddAdviserPreForm()
        return render(request, 'manager_informations_add_search.html', {'form': form})


def _manage_search_form(request, manager=False):
    template_prefix = 'manager_' if manager else ''
    template = template_prefix + 'informations_add_search.html'
    form = ManagerAddAdviserPreForm(request.POST)

    if form.is_valid():  # mail format is valid
        email, form, message, message_add, pers, template = _get_rendering_data(
            form,
            manager,
            template,
            template_prefix
        )
        return render(request, template, {
            'form': form,
            'message': message,
            'email': email,
            'message_add': message_add,
            'pers': pers
        })
    else:  # invalid form (invalid format for email)
        form = ManagerAddAdviserPreForm()
        message = "invalid_data"
        return render(request, template, {
            'form': form,
            'message': message
        })


def _get_rendering_data(form, manager, template, template_prefix):
    data = form.cleaned_data
    person = Person.objects.filter(email=data['email'])
    message, email, message_add = '', '', ''
    form = ManagerAddAdviserPreForm()
    pers = None
    if not data['email']:  # empty search -> step 1
        message = "empty_data"

    elif person and adviser.find_by_person(person[0]):  # person already adviser -> step 1
        email = "%s (%s)" % (list(person)[0], data['email'])
        message = "person_already_adviser"

    elif Person.objects.filter(email=data['email']).count() > 0:  # person found and not adviser -> go forward
        pers = list(person)[0]
        form = ManagerAddAdviserForm() if manager else AddAdviserForm()
        template = template_prefix + 'informations_add.html'

    else:  # person not found by email -> step 1
        email = data['email']
        message = "person_not_found_by_mail"
        message_add = "add_new_person_explanation"
    return email, form, message, message_add, pers, template


###########################
#      MANAGER VIEWS      #
###########################


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations(request):
    dissert_status_exclued = (dissertation_status.DRAFT,
                              dissertation_status.DIR_KO,
                              dissertation_status.DIR_SUBMIT,
                              dissertation_status.ENDED_WIN,
                              dissertation_status.ENDED_LOS,
                              dissertation_status.ENDED)
    active_dissert = Q(dissertations__active=True) & ~Q(dissertations__status__in=dissert_status_exclued)

    education_groups_manager = EducationGroup.objects.filter(facultyadviser__adviser__person__user=request.user)

    advisers = Adviser.objects.filter(type='PRF').select_related('person'). \
        prefetch_related('dissertations'). \
        order_by(
        'person__last_name',
        'person__first_name') \
        .annotate(
        dissertations_count_actif_this_academic_year=models.Sum(
            models.Case(
                models.When(active_dissert & Q(
                    dissertations__education_group_year__academic_year=current_academic_year(),
                ), then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_all_actif=models.Sum(
            models.Case(
                models.When(active_dissert, then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_all_actif_in_your_education_groups=models.Sum(
            models.Case(
                models.When(active_dissert & Q(
                    dissertations__education_group_year__education_group__in=education_groups_manager,
                ), then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_promotor_actif=models.Sum(
            models.Case(
                models.When(active_dissert & Q(
                    dissertations_roles__status=DissertationRoleStatus.PROMOTEUR.name
                ), then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_copromoteur_actif=models.Sum(
            models.Case(
                models.When(active_dissert & Q(
                    dissertations_roles__status=DissertationRoleStatus.CO_PROMOTEUR.name
                ), then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_reader_actif=models.Sum(
            models.Case(
                models.When(active_dissert & Q(
                    dissertations_roles__status=DissertationRoleStatus.READER.name
                ), then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_accompanist_actif=models.Sum(
            models.Case(
                models.When(active_dissert & Q(
                    dissertations_roles__status=DissertationRoleStatus.ACCOMPANIST.name
                ), then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_internship_actif=models.Sum(
            models.Case(
                models.When(active_dissert & Q(
                    dissertations_roles__status=DissertationRoleStatus.INTERNSHIP.name
                ), then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_president_actif=models.Sum(
            models.Case(
                models.When(active_dissert & Q(
                    dissertations_roles__status=DissertationRoleStatus.PRESIDENT.name
                ), then=1), default=0,
                output_field=models.IntegerField()
            )),
        dissertations_count_need_to_respond_actif=models.Sum(
            models.Case(
                models.When(Q(
                    dissertations__active=True,
                    dissertations__status=dissertation_status.DIR_SUBMIT,
                    dissertations_roles__status=DissertationRoleStatus.PROMOTEUR.name
                ), then=1), default=0,
                output_field=models.IntegerField()
            )))
    return render(request, 'manager_informations_list.html', {'advisers': advisers})


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations_add(request):
    if request.method == "POST":
        if 'search_form' in request.POST:  # step 2 : second form to select person in list
            return _manage_search_form(request, manager=True)
        else:  # step 3 : everything ok, register the person as adviser
            form = ManagerAddAdviserForm(request.POST)
            if form.is_valid():
                adv = form.save(commit=False)
                adv.save()
                return redirect('manager_informations_detail', pk=adv.pk)
            else:
                return redirect('manager_informations')

    else:  # step 1 : initial form to search person by email
        form = ManagerAddAdviserPreForm()
        return render(request, 'manager_informations_add_search.html', {'form': form})


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations_add_person(request):
    if request.method == "POST":
        form = ManagerAddAdviserPerson(request.POST)
        if form.is_valid():
            person = Person(
                **form.cleaned_data,
                source=person_source_type.DISSERTATION
            )
            person.save()
            adv = adviser.add(person, 'PRF', False, False, False, '')
            return redirect('manager_informations_detail', pk=adv.pk)
    else:
        form = ManagerAddAdviserPerson()
    return render(request, 'manager_information_add_person.html', {'form': form})


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations_detail(request, pk):
    adv = adviser.get_by_id(pk)
    if adv is None:
        return redirect('manager_informations')
    return render(request, 'manager_informations_detail.html',
                  {
                      'adviser': adv,
                      'first_name': adv.person.first_name.title(),
                      'last_name': adv.person.last_name.title()
                  })


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations_edit(request, pk):
    adv = adviser.get_by_id(pk)
    if adv is None:
        return redirect('manager_informations')
    if request.method == "POST":
        form = ManagerAdviserForm(request.POST, instance=adv)
        if form.is_valid():
            adv = form.save(commit=False)
            adv.save()
            return redirect('manager_informations_detail', pk=adv.pk)
    else:
        form = ManagerAdviserForm(instance=adv)
    return render(request, "manager_informations_edit.html",
                  {
                      'adviser': adv,
                      'form': form,
                      'first_name': adv.person.first_name.title(),
                      'last_name': adv.person.last_name.title(),
                      'email': adv.person.email,
                      'phone': adv.person.phone,
                      'phone_mobile': adv.person.phone_mobile
                  })


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations_list_request(request):
    educ_groups_of_fac_manager = FacultyAdviser.objects.filter(adviser=request.user.person.adviser).values_list(
        'education_group',
        flat=True)
    advisers_need_request = Adviser.objects.filter(type='PRF', ).filter(
        Q(
            dissertations__active=True,
            dissertations__status=dissertation_status.DIR_SUBMIT,
            dissertations_roles__status=DissertationRoleStatus.PROMOTEUR.name,
            dissertations__education_group_year__education_group__in=educ_groups_of_fac_manager
          )
    ).annotate(
        dissertations_count_need_to_respond_actif=models.Sum(
            models.Case(
                models.When(Q(
                    dissertations__active=True,
                    dissertations__status=dissertation_status.DIR_SUBMIT,
                    dissertations_roles__status=DissertationRoleStatus.PROMOTEUR.name,
                    dissertations__education_group_year__education_group__in=educ_groups_of_fac_manager
                ), then=1), default=0, output_field=models.IntegerField()
            )
        )
    ).select_related('person').prefetch_related('dissertations').order_by('person__last_name', 'person__first_name')
    return render(request, "manager_informations_list_request.html",
                  {'advisers_need_request': advisers_need_request})


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations_detail_list(request, pk):
    person = mdl.person.find_by_user(request.user)
    connected_adviser = adviser.search_by_person(person)
    education_groups = faculty_adviser.find_education_groups_by_adviser(connected_adviser)
    adv = adviser.get_by_id(pk)
    if adv is None:
        return redirect('manager_informations')

    adv_list_disserts_pro = dissertation_role.search_by_adviser_and_role_and_education_groups(
        adv,
        DissertationRoleStatus.PROMOTEUR.name,
        education_groups
    )
    adv_list_disserts_copro = dissertation_role.search_by_adviser_and_role_and_education_groups(
        adv,
        DissertationRoleStatus.CO_PROMOTEUR.name,
        education_groups
    )
    adv_list_disserts_reader = dissertation_role.search_by_adviser_and_role_and_education_groups(
        adv,
        DissertationRoleStatus.READER.name,
        education_groups
    )
    adv_list_disserts_accompanist = dissertation_role.search_by_adviser_and_role_and_education_groups(
        adv,
        DissertationRoleStatus.ACCOMPANIST.name,
        education_groups
    )
    adv_list_disserts_internship = dissertation_role.search_by_adviser_and_role_and_education_groups(
        adv,
        DissertationRoleStatus.INTERNSHIP.name,
        education_groups
    )
    adv_list_disserts_president = dissertation_role.search_by_adviser_and_role_and_education_groups(
        adv,
        DissertationRoleStatus.PRESIDENT.name,
        education_groups
    )

    return render(request, "manager_informations_detail_list.html", locals())


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations_detail_list_wait(request, pk):
    education_groups = request.user.person.adviser.education_groups.all()
    adv = get_object_or_404(Adviser, pk=pk)
    disserts_role = DissertationRole.objects.filter(
        status=DissertationRoleStatus.PROMOTEUR.name,
        dissertation__status=dissertation_status.DIR_SUBMIT,
        dissertation__education_group_year__education_group__in=education_groups,
        dissertation__active=True,
        adviser=adv
    ).select_related('adviser__person').distinct()
    return render(request, "manager_informations_detail_list_wait.html",
                  {'disserts_role': disserts_role, 'adviser': adv})


@login_required
@user_passes_test(adviser.is_manager)
def manager_informations_detail_stats(request, pk):
    adv = adviser.get_by_id(pk)
    if adv is None:
        return redirect('manager_informations')
    advisers_pro = dissertation_role.search_by_adviser_and_role_stats(adv, 'PROMOTEUR')
    count_advisers_pro = dissertation_role.count_by_adviser_and_role_stats(adv, 'PROMOTEUR')
    count_advisers_pro_request = dissertation_role.count_by_adviser(adv, 'PROMOTEUR', 'DIR_SUBMIT')
    tab_education_group_count_pro = dissertation_role.get_tab_count_role_by_education_group(advisers_pro)

    advisers_copro = dissertation_role.search_by_adviser_and_role_stats(adv, 'CO_PROMOTEUR')
    count_advisers_copro = dissertation_role.count_by_adviser_and_role_stats(adv, 'CO_PROMOTEUR')
    tab_education_group_count_copro = dissertation_role.get_tab_count_role_by_education_group(advisers_copro)

    advisers_reader = dissertation_role.search_by_adviser_and_role_stats(adv, 'READER')
    count_advisers_reader = dissertation_role.count_by_adviser_and_role_stats(adv, 'READER')
    tab_education_group_count_read = dissertation_role.get_tab_count_role_by_education_group(advisers_reader)

    return render(request, 'manager_informations_detail_stats.html',
                  {
                      'adviser': adv,
                      'count_advisers_copro': count_advisers_copro,
                      'count_advisers_pro': count_advisers_pro,
                      'count_advisers_reader': count_advisers_reader,
                      'count_advisers_pro_request': count_advisers_pro_request,
                      'tab_offer_count_pro': tab_education_group_count_pro,
                      'tab_offer_count_read': tab_education_group_count_read,
                      'tab_offer_count_copro': tab_education_group_count_copro
                  })