Ultron/ultron/followup/views.py

609 lines
19 KiB
Python

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()
if form.cleaned_data['add_to_chrono'] is not None:
new_chrono = Chrono(
gymnast=form.cleaned_data["gymnast"],
chrono_type=form.cleaned_data["routine_type"],
score_type=1,
score=form.cleaned_data["point_time_of_flight"],
tof=form.cleaned_data["point_time_of_flight"],
date=form.cleaned_data["event"].datebegin,
)
new_chrono.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 <Plan>).
gymnast_id (int): identifiant d'un gymnaste (classe <Gymnast>).
skill_id (int): identifiant d'un skill (classe <Skill>).
"""
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)