from datetime import datetime from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods from django.http import HttpResponse, HttpResponseRedirect from django.db.models import Q, Min, Avg, Max, Sum from django.urls import reverse from ultron.people.models import Gymnast from ultron.planning.models import Event from ultron.objective.models import Skill from .models import ( Plan, Point, Chrono, Accident, MindState, LearnedSkill, HeightWeight, ChronoDetails, NumberOfRoutineDone, ) from .forms import ( PlanForm, ScoreForm, ChronoForm, AccidentForm, MindStateForm, HeightWeightForm, LearnedSkillForm, NumberOfRoutineDoneForm, ) @login_required @require_http_methods(["GET"]) def jump_chrono_details(request, chrono_id): """Récupère toutes les informations d'un chrono""" chrono = get_object_or_404(Chrono, pk=chrono_id) sum_value = chrono.details.all().aggregate(total=Sum('value')) chrono.score = sum_value['total'] if chrono.score_type == 0: chrono.tof = Chrono.compute_tof(sum_value['total']) chrono.save() mean_value = chrono.details.all().aggregate(Avg('value')) tmp_min_value = chrono.details.all().aggregate(Min('value')) tmp_max_value = chrono.details.all().aggregate(Max('value')) min_value = mean_value['value__avg'] - (tmp_min_value['value__min'] / 20) max_value = mean_value['value__avg'] - (tmp_max_value['value__max'] / 20) context = {"chrono": chrono, "average_value": mean_value['value__avg'], "min_value": min_value, "max_value": max_value} return render(request, "followup/chronos/details.html", context) @login_required @require_http_methods(["GET"]) def average_jump_chrono_details(request, gymnast_id, routine_type=1, date_begin=None, date_end=None): """Récupère toutes les informations d'un chrono""" # Pendant le dev date_begin = datetime(2022, 1, 20) date_end = datetime(2022, 1, 25) gymnast = get_object_or_404(Gymnast, pk=gymnast_id) stat_values = ChronoDetails.objects \ .filter(chrono__gymnast=gymnast_id, chrono__chrono_type=routine_type, chrono__date__gte=date_begin, chrono__date__lte=date_end) \ .values('order') \ .annotate(avg_score=Avg('value'), max_score=Max('value'), min_score=Min('value')) \ .order_by('order') chrono_list = Chrono.objects.filter(gymnast=gymnast_id, date__gte=date_begin, date__lte=date_end, chrono_type=routine_type) context = { "gymnast": gymnast, "date_begin": date_begin, "date_end": date_end, "chrono_list": chrono_list, "stat_values": stat_values, } return render(request, "followup/chronos/list_details.html", context) @require_http_methods(["POST"]) def remove_jump_chrono_value(request, chrono_id): """ Recoit trois informations permettant d'ajouter le chrono d'un saut à un chrono """ chrono = get_object_or_404(Chrono, pk=chrono_id) order = request.POST.get("order", None) row, created = ChronoDetails.objects.filter(chrono=chrono, order=order).delete() return HttpResponse(200, (row, created)) @require_http_methods(["POST"]) def add_jump_chrono_value(request, chrono_id): """ Recoit trois informations permettant d'ajouter le chrono d'un saut à un chrono """ chrono = get_object_or_404(Chrono, pk=chrono_id) order = request.POST.get("order", None) value = request.POST.get("value", None) row, created = ChronoDetails.objects.get_or_create( chrono=chrono, order=order, value=value ) return HttpResponse(200, (row, created)) @login_required @require_http_methods(["GET"]) def jump_chrono_values_create_or_update(request, chrono_id): """ Ajoute des scores de saut à un chrono """ chrono = get_object_or_404(Chrono, pk=chrono_id) jump_list = chrono.details.all() number_of_jump = jump_list.count() context = { "chrono": chrono, "jump_list": jump_list, "number_of_jump": number_of_jump, } return render(request, "followup/chronos/add_details.html", context) @login_required @require_http_methods(["GET"]) def chrono_listing(request, gymnast_id=None): """Récupère la liste des chronos""" gymnast = None if gymnast_id: chrono_list = Chrono.objects.filter(gymnast=gymnast_id) gymnast = Gymnast.objects.get(pk=gymnast_id) else: chrono_list = Chrono.objects.all() context = {"chrono_list": chrono_list, "gymnast": gymnast} return render(request, "followup/chronos/list.html", context) @login_required @require_http_methods(["GET", "POST"]) def chrono_create_or_update(request, chrono_id=None, gymnast_id=None): """Création ou modification d'un chrono""" if chrono_id: chrono = get_object_or_404(Chrono, pk=chrono_id) data = { "gymnast": chrono.gymnast.id, "gymnast_related": str(chrono.gymnast), } else: chrono = None data = None if gymnast_id is not None: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = {"gymnast": gymnast_id, "gymnast_related": gymnast} if request.method == "POST": form = ChronoForm(request.POST, instance=chrono) if form.is_valid(): new_chrono = form.save(commit=False) if new_chrono.score_type == 1: new_chrono.tof = new_chrono.score else: new_chrono.tof = Chrono.compute_tof(new_chrono.score) new_chrono.save() return HttpResponseRedirect(reverse("gymnast_details", args=(new_chrono.gymnast.id,))) else: form = ChronoForm(instance=chrono, initial=data) context = {"form": form, "chrono_id": chrono_id} return render(request, "followup/chronos/create.html", context) @login_required @require_http_methods(["POST"]) def gymnast_learn_skill(request): """ Lie un gymnast à une figure. """ # print(request) # utiliser un FORM pour cette fonction. gymnast_id = request.POST.get("gymnast_id", None) skill_id = request.POST.get("skill_id", None) cando = request.POST.get("cando", 0) if gymnast_id and skill_id: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) skill = Skill.objects.get(pk=skill_id) learned_skill = LearnedSkill( gymnast=gymnast, skill=skill, cando=cando, date=datetime.now() ) learned_skill.save() return HttpResponse(status=200) if gymnast_id: print("Error : can not link Gymnast and skill. Missing Skill_ID.") else: print("Error : can not link Gymnast and skill. Missing Gymnast_ID.") return HttpResponse(status=500) @login_required @require_http_methods(["GET", "POST"]) def learnedskill_create_or_update(request, gymnast_id=None): """ Formulaire de creation et modification d'un lien skill/gymnaste. """ if gymnast_id: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = { "gymnast": gymnast.id, "gymnast_related": str(gymnast), } else: data = None if request.method == "POST": form = LearnedSkillForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect( reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) ) else: form = LearnedSkillForm(initial=data) context = {"form": form, "gymnast_id": gymnast_id} return render(request, "followup/learnedskills/create.html", context) @login_required @require_http_methods(["GET", "POST"]) def score_create_or_update(request, score_id=None, gymnast_id=None): """ Formulaire de création d'un nouveau score. """ if score_id: score = get_object_or_404(Point, pk=score_id) data = { "gymnast_related": str(score.gymnast), "event_related": str(score.event), } else: score = None data = None if gymnast_id is not None: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)} if request.method == "POST": form = ScoreForm(request.POST, instance=score) if form.is_valid(): form.save() return HttpResponseRedirect( reverse( "gymnast_details", args=(form.cleaned_data["gymnast"].id,) ) ) else: form = ScoreForm(instance=score, initial=data) context = {"form": form, "score_id": score_id} return render(request, "followup/scores/create.html", context) @login_required @require_http_methods(["GET"]) def score_listing(request, gymnast_id=None): """ Revoie la liste des scores """ pattern = request.GET.get("pattern", None) gymnast = None if pattern: score_list = Point.objects.filter( Q(event__icontains=pattern) | Q(gymnast__icontains=pattern) ) elif gymnast_id: score_list = Point.objects.filter(gymnast=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id) else: score_list = Point.objects.all() context = {"score_list": score_list, "gymnast": gymnast} return render(request, "followup/scores/list.html", context) @login_required @require_http_methods(["GET"]) def accident_listing(request): """ Récupère la liste des accidents suivant un pattern si celui-ci est définit. """ pattern = request.GET.get("pattern", None) if pattern: accident_list = Accident.objects.filter( Q(gymnast__lastname__icontains=pattern) | Q(gymnast__firstname__icontains=pattern) ) else: accident_list = Accident.objects.all() context = {"accident_list": accident_list} return render(request, "followup/accidents/list.html", context) @login_required @require_http_methods(["GET", "POST"]) def accident_create_or_update(request, accident_id=None, gymnast_id=None): """ Formulaire de création d'un nouvel accident. """ if accident_id: accident = get_object_or_404(Accident, pk=accident_id) data = { "gymnast_related": accident.gymnast, "skill_related": accident.skill, } else: accident = None data = None if gymnast_id is not None: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)} if request.method == "POST": form = AccidentForm(request.POST, instance=accident) if form.is_valid(): accident = form.save() return HttpResponseRedirect(reverse("accident_details", args=(accident.pk,))) else: form = AccidentForm(instance=accident, initial=data) context = {"form": form, "accident_id": accident_id} return render(request, "followup/accidents/create.html", context) @login_required @require_http_methods(["GET"]) def accident_detail(request, accident_id): """ Récupère toutes les informations d'un accident. """ accident = get_object_or_404(Accident, pk=accident_id) context = {"accident": accident} return render(request, "followup/accidents/details.html", context) @login_required @require_http_methods(["GET"]) def mindstate_listing(request, gymnast_id=None): """ Récupère la liste des évaluations mentales suivant (d'un gymnaste si définit en paramètre). """ gymnast = None if gymnast_id: mindstate_list = MindState.objects.filter(gymnast=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id) else: mindstate_list = MindState.objects.all() context = {"mindstate_list": mindstate_list, "gymnast": gymnast} return render(request, "followup/mindstates/list.html", context) @login_required @require_http_methods(["GET", "POST"]) def mindstate_create_or_update( request, mindstate_id=None, gymnast_id=None, event_id=None ): """ Formulaire de création d'un nouvel accident. """ if mindstate_id: mindstate = get_object_or_404(MindState, pk=mindstate_id) data = {"gymnast_related": mindstate.gymnast, "event_related": mindstate.event} else: mindstate = None data = None if gymnast_id is not None: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)} if event_id is not None: event = get_object_or_404(Event, pk=event_id) data = {"event": event_id, "event_related": str(event)} if request.method == "POST": form = MindStateForm(request.POST, instance=mindstate) if form.is_valid(): mindstate = form.save() return HttpResponseRedirect(reverse("mindstate_details", args=(mindstate.pk,))) else: form = MindStateForm(instance=mindstate, initial=data) context = {"form": form, "mindstate_id": mindstate_id} return render(request, "followup/mindstates/create.html", context) @login_required @require_http_methods(["GET"]) def mindstate_detail(request, mindstate_id): """ Récupère toutes les informations d'une évaluation psychologique. """ mindstate = get_object_or_404(MindState, pk=mindstate_id) context = {"mindstate": mindstate} return render(request, "followup/mindstates/details.html", context) @login_required @require_http_methods(["GET"]) def heightweight_listing(request, gymnast_id=None): """ Récupère la liste des couples taille/poids suivant (d'un gymnast si définit en paramètre). """ gymnast = None if gymnast_id: heightweight_list = HeightWeight.objects.filter(gymnast=gymnast_id) gymnast = Gymnast.objects.get(pk=gymnast_id) else: heightweight_list = HeightWeight.objects.all() context = {"heightweight_list": heightweight_list, "gymnast": gymnast} return render(request, "followup/heightweight/list.html", context) @login_required @require_http_methods(["GET", "POST"]) def heightweight_create_or_update(request, heightweight_id=None, gymnast_id=None): """ Formulaire de creation et modification d'un couple taille/couple. """ if heightweight_id: heightweight = get_object_or_404(HeightWeight, pk=heightweight_id) data = {"gymnast_related": heightweight.gymnast} else: heightweight = None data = None if gymnast_id: heightweight = ( HeightWeight.objects.filter(gymnast=gymnast_id) .order_by("-date") .first() ) gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)} if request.method == "POST": form = HeightWeightForm(request.POST, instance=heightweight) if form.is_valid(): form.save() return HttpResponseRedirect( reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) ) else: form = HeightWeightForm(instance=heightweight, initial=data) context = { "form": form, "gymnast_id": gymnast_id, "heightweight_id": heightweight_id, } return render(request, "followup/heightweight/create.html", context) @login_required @require_http_methods(["GET"]) def routine_done_listing(request, gymnast_id=None): """ Liste tous les record de la table NumberOfRoutineDone """ gymnast = None if gymnast_id: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) routine_done_list = gymnast.number_of_routine_done.all() else: routine_done_list = NumberOfRoutineDone.objects.all() context = {"routine_done_list": routine_done_list, "gymnast": gymnast} return render(request, "followup/routinedone/list.html", context) @login_required @require_http_methods(["GET", "POST"]) def routinedone_create_or_update(request, routinedone_id=None, gymnast_id=None): """Création ou modification d'un chrono""" if routinedone_id: routinedone = get_object_or_404(NumberOfRoutineDone, pk=routinedone_id) data = { "gymnast": routinedone.gymnast.id, "gymnast_related": str(routinedone.gymnast), "routine": routinedone.routine.id, "routine_related": str(routinedone.routine), } else: routinedone = None data = None if gymnast_id is not None: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = {"gymnast": gymnast_id, "gymnast_related": gymnast} if request.method == "POST": form = NumberOfRoutineDoneForm(request.POST, instance=routinedone) if form.is_valid(): form.save() return HttpResponseRedirect( reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) ) else: form = NumberOfRoutineDoneForm(instance=routinedone, initial=data) context = {"form": form, "routinedone_id": routinedone_id} return render(request, "followup/routinedone/create.html", context) @login_required @require_http_methods(["GET", "POST"]) def plan_create_or_update(request, plan_id=None, gymnast_id=None, skill_id=None): """Création d'un plan. Args: plan_id (int): identifiant d'un plan (classe ). gymnast_id (int): identifiant d'un gymnaste (classe ). skill_id (int): identifiant d'un skill (classe ). """ if plan_id: plan = get_object_or_404(Plan, pk=plan_id) data = { "gymnast": plan.gymnast.id, "gymnast_related": str(plan.gymnast), "skill": plan.skill.id, "skill_related": str(plan.skill), } else: plan = None data = {} if gymnast_id: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data["gymnast"] = gymnast_id data["gymnast_related"] = str(gymnast) if skill_id: skill = get_object_or_404(Skill, pk=skill_id) data["educative"] = skill_id data["educative_related"] = str(skill) if request.method == "POST": form = PlanForm(request.POST, instance=plan) if form.is_valid(): plan = form.save() else: form = PlanForm(instance=plan, initial=data) context = {"form": form, "plan_id": plan_id} return render(request, "followup/plan/create.html", context)