Ultron/ultron/followup/views.py

635 lines
20 KiB
Python

from datetime import date, 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 django.contrib.auth import get_user_model
User = get_user_model()
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,
"score_type": chrono.score_type,
}
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:
print(form.errors)
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']:
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)
@require_http_methods(["POST"])
def increment_routinedone(request):
"""
Incrémente le nombre de routine faite pour aujourd'hui et incrémente, si besoin, le nombre
de routine réussie
"""
gymnast = get_object_or_404(Gymnast, pk=request.POST.get("gymnast_id"))
today = date.today()
routine_type = request.POST.get("routine_type", 0)
routinedone, _ = NumberOfRoutineDone.objects.get_or_create(date=today, gymnast=gymnast, routine_type=routine_type)
routinedone.number_of_try += 1
success = request.POST.get("success")
if int(success) == 1:
routinedone.number_of_successes += 1
routinedone.save()
return HttpResponse(status=200)
@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()
return HttpResponseRedirect(
reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
)
else:
form = PlanForm(instance=plan, initial=data)
context = {"form": form, "plan_id": plan_id}
return render(request, "followup/plan/create.html", context)