views.py 11.9 KB
from django.shortcuts import render,redirect,get_object_or_404,reverse
from django.contrib.auth import authenticate
from django.contrib.auth.decorators import login_required
from .forms import ScientificProgramForm, InstituteForm, SP_PeriodForm 
from src.core.pyros_django.dashboard.decorator import level_required
from common.models import ScientificProgram, Institute, Period, SP_Period_User, SP_Period, PyrosUser, UserLevel
from django.http import HttpResponseRedirect
from datetime import datetime

# Scientific program CRUD
@level_required("Admin","Observer")
@login_required
def create_sp(request):
    SPform = ScientificProgramForm(request.POST)
    SP_Periodform = SP_PeriodForm(request.POST)
    usersForm = PyrosUser.objects.filter(user_level=UserLevel.objects.get(name="Observer")).exclude(id=request.user.id)
    if request.POST:
        if SPform.is_valid():
            SP = SPform.save()
            selected_period = Period.objects.get(id=request.POST.get("period"))
            current_sp = ScientificProgram.objects.get(id= SP.id)
            
            sp_period = SP_Period.objects.create(period = selected_period, scientific_program = current_sp)
            
            
            sp_pi_user = PyrosUser.objects.get(id=request.user.id)
            SP_Period_User.objects.create(SP_Period=sp_period,user=sp_pi_user,is_SP_PI=True)
            if request.POST.getlist("user"):
                for user in request.POST.getlist("user"):
                    user_instance = PyrosUser.objects.get(id=int(user))
                    SP_Period_User.objects.create(SP_Period=sp_period,user=user_instance,is_SP_PI=False)
            
            
            
            return HttpResponseRedirect(reverse("scientific_program_list"))
    form = ScientificProgramForm()
    return render(request,"scientific_program/create_scientific_program.html",{"SPForm": SPform, "SP_PeriodForm":SP_Periodform, "usersForm":usersForm})

@level_required("Admin","Unit-PI","Observer")
@login_required
def edit_sp(request,id):
    scientific_program = get_object_or_404(ScientificProgram, pk=id)
    SPForm = ScientificProgramForm(request.POST or None, instance=scientific_program)
    today = datetime.utcnow()
    current_active_period = Period.objects.get(start_date__lte=today,end_date__gte=today)
    sp_period = SP_Period.objects.get(scientific_program=scientific_program,period=current_active_period)
    sp_pi =  SP_Period_User.objects.get(SP_Period__exact=sp_period,is_SP_PI=True)
    if request.session.get("role") == "Observer" and request.user.id != sp_pi.id:
        return HttpResponseRedirect(reverse("scientific_program_detail",id))
    user_of_sp = SP_Period_User.objects.filter(SP_Period__exact=sp_period,is_SP_PI=False)
    users_informations = PyrosUser.objects.filter(id__in=user_of_sp.values_list("user",flat=True))
    usersForm = PyrosUser.objects.filter(user_level=UserLevel.objects.get(name="Observer")).exclude(id=sp_pi.id)
    
    if request.POST:

        
        if SPForm.is_valid():
            SP = SPForm.save()          
            if request.POST.getlist("user"):
                for sp_period_user in users_informations:
                    if sp_period_user.id not in map(int,request.POST.getlist("user")):
                        sp_period_user.delete()

                for user in request.POST.getlist("user"):
                    user_instance = PyrosUser.objects.get(id=int(user))
                    if user_instance not in users_informations:
                        SP_Period_User.objects.create(SP_Period=sp_period,user=user_instance,is_SP_PI=False)
            else:
                SP_Period_User.objects.filter(SP_Period=sp_period,is_SP_PI=False).delete()
            return redirect('detail_scientific_program', id=id)
    return render(request, 'scientific_program/scientific_program_detail_edit.html', {'id' : id, "SPForm": SPForm, "period":sp_period.period, "usersForm":usersForm,"users_of_sp_period":users_informations})

@level_required("Admin","Unit-PI","Observer","TAC")
@login_required
def detail_sp(request,id):
    scientific_program = get_object_or_404(ScientificProgram, pk=id)
    today = datetime.utcnow()
    
    current_active_period = Period.objects.get(start_date__lte=today,end_date__gte=today)
    sp_period = SP_Period.objects.filter(scientific_program=scientific_program).values_list("id",flat=True)
    user_of_sp = SP_Period_User.objects.filter(SP_Period__in=sp_period,is_SP_PI=False)
    users_informations = PyrosUser.objects.filter(id__in=user_of_sp.values_list("user",flat=True))
    sp_pi = SP_Period_User.objects.get(SP_Period__in=sp_period, is_SP_PI=True).user
    # User is observer and not from this SP
    if request.session.get("role") == "Observer" and request.user.id != sp_pi.id and request.user.id not in users_informations:
        return HttpResponseRedirect(reverse("scientific_program_list"))
 
    
    
    return render(request, 'scientific_program/scientific_program_detail.html', {'scientific_program': scientific_program,"users":users_informations, "sp_pi":sp_pi,"period":current_active_period})

@level_required("Admin","Unit-PI","Observer")
@login_required()
def delete_sp(request,id):
    scientific_program = get_object_or_404(ScientificProgram, pk=int(id))
    today = datetime.utcnow()
    current_active_period = Period.objects.get(start_date__lte=today,end_date__gte=today)
    sp_period = SP_Period.objects.get(scientific_program=scientific_program,period=current_active_period)
    sp_period_users = SP_Period_User.objects.filter(SP_Period=sp_period,is_SP_PI=False)
    # If no users (which is not SP_PI) is in this SP_Period
    if not sp_period_users:
        sp_period.delete()
        scientific_program.delete()
    return HttpResponseRedirect(reverse('scientific_program_list'))


@login_required
@level_required("Admin","Unit-PI","Observer","TAC")
def scientific_program_list(request):
    nb_scientific_program = 0
    if (len(ScientificProgram.objects.all()) > 0):                             
        scientific_programs = ScientificProgram.objects.order_by("-id")[:100]         
        sp_periods = SP_Period_User.objects.filter(user=request.user.id)
        sp_of_user = []
        for sp_period in sp_periods:
            
            nb_scientific_program +=1
            sp_of_user.append(sp_period.SP_Period.scientific_program)
        
    else:                                                                       
        scientific_programs = None

    return render(request, 'scientific_program/scientific_programs.html', {'scientific_programs' : scientific_programs, 'nb_scientific_program' : nb_scientific_program,"sp_of_user":sp_of_user})

# Institute CRUD

@login_required
@level_required("Admin","Unit-PI")
def create_institute(request):
    form = InstituteForm(request.POST)
    if request.POST:
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse("institute_list"))
    form = InstituteForm()
    return render(request,"scientific_program/create_institute.html",{"form": form})



@level_required("Admin","Unit-PI")
@login_required
def edit_institute(request,id):
    edit = get_object_or_404(Institute, pk=id)
    form = InstituteForm(request.POST or None, instance=edit)
    if form.is_valid():
        form.save()
        return redirect('detail_institute', id=id)
    return render(request, 'scientific_program/institute_detail_edit.html', {'id' : id, 'form': form})

@level_required("Admin","Unit-PI","Observer","Operator","TAC","Management board member")
@login_required
def detail_institute(request,id):
    institute = get_object_or_404(Institute, pk=id)
    representative_member = PyrosUser.objects.get(is_institute_representative=True,institute=institute)
    scientific_programs = ScientificProgram.objects.filter(institute=institute)
    
    return render(request, 'scientific_program/institute_detail.html', {'institute': institute,"representative_member":representative_member,"scientific_programs":scientific_programs})

@level_required("Admin","Unit-PI")
@login_required()
def delete_institute(request,id):
    institute = get_object_or_404(Institute, pk=int(id))
    institute.delete()
    return HttpResponseRedirect(reverse('institute_list'))


@login_required
@level_required("Admin","Unit-PI","Observer","Operator","TAC","Management board member")
def institute_list(request):
    institutes = Institute.objects.all()
    return render(request, 'scientific_program/institutes.html', {'institutes' : institutes})


# Time Periods CRUD

@login_required
@level_required("Admin","Unit-PI","Unit board")
def create_period(request):
    today = datetime.utcnow().date()
    error = False
    error_message = ""
    if request.POST:
        start_date = datetime.strptime(request.POST.get("start_date_picker"),"%d/%m/%Y")
        end_date = datetime.strptime(request.POST.get("end_date_picker"),"%d/%m/%Y")

        # most common check
        if start_date != end_date and end_date > start_date:
            # get all future periods
            future_periods = Period.objects.filter(end_date__gte=today).order_by("end_date")
            for future_period in future_periods:
            # check if submitted period isn't covering an existing period
                if start_date.date() < future_period.end_date and end_date.date() > future_period.start_date:
                    error_message = f"Period already covered ({future_period})"
                    error = True
                    break
            if not error:
                new_period = Period.objects.create()
                new_period.start_date = start_date
                new_period.end_date = end_date
                new_period.save()
                return HttpResponseRedirect(reverse("period_list"))

    return render(request,"scientific_program/create_period.html",{"error_message" : error_message,"error":error})



@login_required
@level_required("Admin","Unit-PI")
def edit_period(request,id):
    edit = get_object_or_404(Period, pk=id)
    

    # own validation 
    if request.POST:
        start_date = datetime.strptime(request.POST.get("start_date_picker"),"%d/%m/%Y")
        end_date = datetime.strptime(request.POST.get("start_date_picker"),"%d/%m/%Y")
        if start_date != end_date and end_date > start_date:
            edit.start_date = start_date
            edit.end_date = end_date
            edit.save()
        return redirect('detail_period', id=id)
    return render(request, 'scientific_program/period_detail_edit.html', {'id' : id, 'period': edit})


@login_required
@level_required("Admin","Unit-PI")
def detail_period(request,id):
    period = get_object_or_404(Period, pk=id)
    sp_periods = SP_Period.objects.filter(period=period)
    scientific_programs = []
    for sp_period in sp_periods:
        
        scientific_programs.append(sp_period.scientific_program)
    return render(request, 'scientific_program/period_detail.html', {'period': period,"scientific_programs":scientific_programs})

@login_required()
@level_required("Admin","Unit-PI")
def delete_period(request,id):
    period = get_object_or_404(Period, pk=int(id))
    period.delete()
    return HttpResponseRedirect(reverse('period_list'))


@login_required
@level_required("Admin","Unit-PI")
def period_list(request):
    today = datetime.utcnow().date()
    periods = Period.objects.all().order_by("start_date","end_date")
    future_periods = []
    past_periods = []
    active_period = None
    for period in periods:
        if period.is_currently_active():
            future_periods.insert(0,period)
            active_period = period
        else:
            if active_period is not None:
                future_periods.append(period)
            else:
                past_periods.append(period)
    return render(request, 'scientific_program/periods.html', {'past_periods' : past_periods,"future_periods" : future_periods})