439 lines
15 KiB
Python
439 lines
15 KiB
Python
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 HttpResponseRedirect
|
|
from django.db.models import Min, Avg, Max
|
|
from django.core.mail import send_mail
|
|
from django.urls import reverse
|
|
from django.conf import settings
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
from jarvis.core.models import Email
|
|
from .models import Gymnast
|
|
from .models import (
|
|
Injury,
|
|
WellBeing,
|
|
HeightWeight,
|
|
)
|
|
|
|
from .forms import (
|
|
InjuryForm,
|
|
WellBeingForm,
|
|
HeightWeightForm,
|
|
)
|
|
|
|
from .models import (
|
|
INJURY_MECHANISM_CHOICE,
|
|
INJURY_BODY_SIDE_CHOICE,
|
|
INJURY_TYPE_CHOICE,
|
|
INJURY_LOCATION_CHOICE,
|
|
)
|
|
|
|
from .email_vars import MAIL_HEADER, MAIL_FOOTER
|
|
|
|
|
|
@login_required
|
|
@require_http_methods(["GET"])
|
|
def injuries_listing(request, gymnast_id=None):
|
|
"""
|
|
Récupère la liste des bessures.
|
|
Si c'est un gymnaste qui est connecté, il ne peut récupérer que la liste de ses blessures.
|
|
Si c'est un autre utilisateur (entraîneur), la liste peut répondre à un pattern si celui-ci est
|
|
définit.
|
|
"""
|
|
|
|
gymnast = None
|
|
if gymnast_id and (
|
|
request.user.is_superuser
|
|
or (
|
|
request.session.has_key("available_gymnast")
|
|
and gymnast_id in request.session["available_gymnast"]
|
|
)
|
|
):
|
|
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
|
|
injuries_list = Injury.objects.filter(gymnast=gymnast_id)
|
|
else:
|
|
if request.user.is_superuser:
|
|
injuries_list = Injury.objects.all()
|
|
else:
|
|
injuries_list = Injury.objects.filter(
|
|
gymnast__in=request.session["available_gymnast"]
|
|
)
|
|
|
|
context = {"injuries_list": injuries_list, "gymnast": gymnast}
|
|
return render(request, "injuries/list.html", context)
|
|
|
|
|
|
@login_required
|
|
@require_http_methods(["GET", "POST"])
|
|
def injury_create_or_update(request, injury_id=None, gymnast_id=None):
|
|
"""
|
|
Formulaire de création d'un nouvel blessure.
|
|
|
|
Args:
|
|
injury_id (int) identifiant d'une blessure
|
|
gymnast_id (int) identifiant d'un gymnaste
|
|
"""
|
|
|
|
if injury_id:
|
|
injury = get_object_or_404(Injury, pk=injury_id)
|
|
if not request.user.is_superuser and (
|
|
request.session.has_key("available_gymnast")
|
|
and injury.gymnast.id not in request.session["available_gymnast"]
|
|
):
|
|
return injury_listing(request)
|
|
data = {
|
|
"gymnast_related": injury.gymnast,
|
|
"skill_related": injury.skill,
|
|
}
|
|
else:
|
|
injury = 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 = InjuryForm(request.POST, instance=injury)
|
|
|
|
if form.is_valid():
|
|
injury = form.save()
|
|
|
|
# notification
|
|
receivers = []
|
|
date = form.cleaned_data["date"]
|
|
functionality = ContentType.objects.get(model="injury")
|
|
for notification in injury.gymnast.notifications.filter(
|
|
functionality=functionality
|
|
):
|
|
receivers.append(notification.user.email)
|
|
|
|
title = f"{injury.gymnast} : Nouvelle blessure enregistrée"
|
|
body = f"""<p>Bonjour,</p>
|
|
<p>Un nouvelle blessure enregistrée pour {injury.gymnast} pour le {date.strftime('%d %B %Y')}:</p>
|
|
<ul>
|
|
<li>{INJURY_TYPE_CHOICE[injury.injury_type][1]},</li>
|
|
<li>caused by {INJURY_MECHANISM_CHOICE[injury.mechanism][1]},</li>
|
|
<li>on {INJURY_LOCATION_CHOICE[injury.location][1]},</li>
|
|
<li>{INJURY_BODY_SIDE_CHOICE[injury.body_side][1]} side,</li>
|
|
</ul>"""
|
|
Email.objects.create(receivers=receivers, title=title, body=body)
|
|
|
|
send_mail(
|
|
title,
|
|
f"{injury.gymnast} a ajouté état de bien être ({date})",
|
|
settings.EMAIL_HOST_USER,
|
|
receivers,
|
|
fail_silently=False,
|
|
html_message=body + MAIL_FOOTER,
|
|
)
|
|
|
|
return HttpResponseRedirect(reverse("injury_details", args=(injury.pk,)))
|
|
|
|
return render(request, "injuries/create.html", {"form": form})
|
|
|
|
form = InjuryForm(instance=injury, initial=data)
|
|
context = {"form": form, "injury_id": injury_id}
|
|
return render(request, "injuries/create.html", context)
|
|
|
|
|
|
@login_required
|
|
@require_http_methods(["GET"])
|
|
def injury_details(request, injury_id):
|
|
"""
|
|
Récupère toutes les informations d'une blessure.
|
|
|
|
Args:
|
|
injury_id (int) identifiant d'une blessure
|
|
"""
|
|
injury = get_object_or_404(Injury, pk=injury_id)
|
|
|
|
if not request.user.is_superuser and (
|
|
request.session.has_key("available_gymnast")
|
|
and injury.gymnast.id not in request.session["available_gymnast"]
|
|
):
|
|
return injuries_listing(request)
|
|
|
|
return render(request, "injuries/details.html", {"injury": injury})
|
|
|
|
|
|
@login_required
|
|
@require_http_methods(["GET"])
|
|
def wellbeing_listing(request, gymnast_id=None):
|
|
"""
|
|
Récupère la liste des évaluations de bien-être.
|
|
|
|
Args:
|
|
gymnast_id (int) identifiant d'un gymnaste
|
|
"""
|
|
|
|
gymnast = None
|
|
if gymnast_id and (
|
|
request.user.is_superuser
|
|
or (
|
|
request.session.has_key("available_gymnast")
|
|
and gymnast_id in request.session["available_gymnast"]
|
|
)
|
|
):
|
|
# wellbeing_list = WellBeing.objects.filter(gymnast=gymnast_id)
|
|
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
|
|
wellbeing_list = gymnast.wellbeings.all()
|
|
else:
|
|
if request.user.is_superuser:
|
|
# les super user peuvent voir tout le monde.
|
|
wellbeing_list = WellBeing.objects.all()
|
|
else:
|
|
# les autres entraîneurs ne peuvent voir que certains élèves.
|
|
wellbeing_list = WellBeing.objects.filter(
|
|
gymnast__in=request.session["available_gymnast"]
|
|
)
|
|
|
|
context = {"wellbeing_list": wellbeing_list, "gymnast": gymnast}
|
|
return render(request, "wellbeing/list.html", context)
|
|
|
|
|
|
def get_wellbeing_stats_for_season_week(gymnast_id, season, week_number):
|
|
"""Calcule le min, max et moyenne de bien-être d'un gymnaste pour une semaine donnéee
|
|
|
|
Args:
|
|
gymnast_id (int) identifiant d'un gymnaste
|
|
season (str) saison
|
|
week_number (int) numéro de semaine
|
|
"""
|
|
wellbeing_score = WellBeing.objects.filter(
|
|
gymnast_id=gymnast_id, season=season, week_number=week_number
|
|
).aggregate(
|
|
min_mindstate_value=Min("mindstate"),
|
|
average_mindstate_value=Avg("mindstate"),
|
|
max_mindstate_value=Max("mindstate"),
|
|
min_sleep_value=Min("sleep"),
|
|
average_sleep_value=Avg("sleep"),
|
|
max_sleep_value=Max("sleep"),
|
|
min_stress_value=Min("stress"),
|
|
average_stress_value=Avg("stress"),
|
|
max_stress_value=Max("stress"),
|
|
min_fatigue_value=Min("fatigue"),
|
|
average_fatigue_value=Avg("fatigue"),
|
|
max_fatigue_value=Max("fatigue"),
|
|
min_muscle_soreness_value=Min("muscle_soreness"),
|
|
average_muscle_soreness_value=Avg("muscle_soreness"),
|
|
max_muscle_soreness_value=Max("muscle_soreness"),
|
|
)
|
|
return wellbeing_score
|
|
|
|
|
|
@login_required
|
|
@require_http_methods(["GET", "POST"])
|
|
def wellbeing_create_or_update(
|
|
request, wellbeing_id=None, gymnast_id=None, event_id=None
|
|
):
|
|
"""
|
|
Formulaire de création d'une nouvelle blessure.
|
|
|
|
Args:
|
|
wellbeing_id (int) identifiant d'une blessure
|
|
gymnast_id (int) identifiant d'un gymnaste
|
|
event_id (int) identifiant d'un événement
|
|
"""
|
|
|
|
if wellbeing_id:
|
|
wellbeing = get_object_or_404(WellBeing, pk=wellbeing_id)
|
|
if not request.user.is_superuser and (
|
|
request.session.has_key("available_gymnast")
|
|
and wellbeing.gymnast.id not in request.session["available_gymnast"]
|
|
):
|
|
return wellbeing_listing(request)
|
|
data = {"gymnast_related": wellbeing.gymnast, "event_related": wellbeing.event}
|
|
else:
|
|
wellbeing = 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 = WellBeingForm(request.POST, instance=wellbeing)
|
|
|
|
if form.is_valid():
|
|
wellbeing = form.save()
|
|
|
|
# notification
|
|
receivers = []
|
|
date = form.cleaned_data["date"]
|
|
functionality = ContentType.objects.get(model="wellbeing")
|
|
for notification in wellbeing.gymnast.notifications.filter(
|
|
functionality=functionality
|
|
):
|
|
receivers.append(notification.user.email)
|
|
|
|
title = f"{wellbeing.gymnast} : Nouveau score de bien être"
|
|
html_message = f"""<p>Bonjour,</p>
|
|
<p>{wellbeing.gymnast} a ajouté son état de bien être pour le ({date.strftime('%d %B %Y')}) :</p>
|
|
<ul>
|
|
<li>Mindstate: {wellbeing.mindstate}</li>
|
|
<li>Sleep: {wellbeing.sleep}</li>
|
|
<li>Stress: {wellbeing.stress}</li>
|
|
<li>Fatigue: {wellbeing.fatigue}</li>
|
|
<li>Muscle soreness: {wellbeing.muscle_soreness}</li>
|
|
</ul>
|
|
{wellbeing.informations}"""
|
|
|
|
Email.objects.create(receivers=receivers, title=title, body=html_message)
|
|
send_mail(
|
|
title,
|
|
f"{wellbeing.gymnast} a ajouté état de bien être ({date})",
|
|
settings.EMAIL_HOST_USER,
|
|
receivers,
|
|
fail_silently=False,
|
|
html_message=html_message + MAIL_FOOTER,
|
|
)
|
|
|
|
return HttpResponseRedirect(
|
|
reverse("wellbeing_details", args=(wellbeing.pk,))
|
|
)
|
|
|
|
return render(request, "wellbeing/create.html", {"form": form})
|
|
|
|
form = WellBeingForm(instance=wellbeing, initial=data)
|
|
context = {"form": form, "wellbeing_id": wellbeing_id}
|
|
return render(request, "wellbeing/create.html", context)
|
|
|
|
|
|
@login_required
|
|
@require_http_methods(["GET"])
|
|
def wellbeing_details(request, wellbeing_id):
|
|
"""
|
|
Récupère toutes les informations d'une évaluation psychologique.
|
|
|
|
Args:
|
|
wellbeing_id (int) identifiant d'une évaluation psycho
|
|
"""
|
|
wellbeing = get_object_or_404(WellBeing, pk=wellbeing_id)
|
|
|
|
if not request.user.is_superuser and (
|
|
request.session.has_key("available_gymnast")
|
|
and wellbeing.gymnast.id not in request.session["available_gymnast"]
|
|
):
|
|
return wellbeing_listing(request)
|
|
|
|
return render(request, "wellbeing/details.html", {"wellbeing": wellbeing})
|
|
|
|
|
|
@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).
|
|
|
|
Args:
|
|
gymnast_id (int) identifiant d'un gymnaste
|
|
"""
|
|
|
|
gymnast = None
|
|
if gymnast_id and (
|
|
request.user.is_superuser
|
|
or (
|
|
request.session.has_key("available_gymnast")
|
|
and gymnast_id in request.session["available_gymnast"]
|
|
)
|
|
):
|
|
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
|
|
heightweight_list = HeightWeight.objects.filter(gymnast=gymnast_id)
|
|
else:
|
|
if request.user.is_superuser:
|
|
heightweight_list = HeightWeight.objects.all()
|
|
else:
|
|
heightweight_list = HeightWeight.objects.filter(
|
|
gymnast__in=request.session["available_gymnast"]
|
|
)
|
|
|
|
context = {"heightweight_list": heightweight_list, "gymnast": gymnast}
|
|
return render(request, "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.
|
|
|
|
Args:
|
|
heightweight_id (int) identifiant d'un couple taille/couple
|
|
gymnast_id (int) identifiant d'un gymnaste
|
|
"""
|
|
|
|
if heightweight_id:
|
|
heightweight = get_object_or_404(HeightWeight, pk=heightweight_id)
|
|
if not request.user.is_superuser and (
|
|
request.session.has_key("available_gymnast")
|
|
and heightweight.gymnast.id not in request.session["available_gymnast"]
|
|
):
|
|
return heightweight_listing(request)
|
|
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():
|
|
heightweight = form.save()
|
|
|
|
# notification
|
|
receivers = []
|
|
date = form.cleaned_data["date"]
|
|
functionality = ContentType.objects.get(model="heightweight")
|
|
for notification in heightweight.gymnast.notifications.filter(
|
|
functionality=functionality
|
|
):
|
|
receivers.append(notification.user.email)
|
|
|
|
title = f"{heightweight.gymnast} : Nouveau poids/taille enregistré"
|
|
body = f"""<p>Bonjour,</p>
|
|
<p>Un nouveau poids/taille enregistré pour {heightweight.gymnast} pour le {date.strftime('%d %B %Y')}:</p>
|
|
<ul>
|
|
<li>Height: {heightweight.height} cm</li>
|
|
<li>Weight: {heightweight.weight} kg</li>
|
|
<li>BMI: {heightweight.bmi:.2f}</li>
|
|
</ul>"""
|
|
|
|
Email.objects.create(receivers=receivers, title=title, body=body)
|
|
|
|
send_mail(
|
|
title,
|
|
f"Un nouveau poids/taille enregistré pour {heightweight.gymnast} ({date}) : {heightweight.height} cm / {heightweight.weight} kg (BMI: {heightweight.bmi:.2f}).", # pylint: disable=line-too-long
|
|
settings.EMAIL_HOST_USER,
|
|
receivers,
|
|
fail_silently=False,
|
|
html_message=body + MAIL_FOOTER,
|
|
)
|
|
|
|
return HttpResponseRedirect(
|
|
reverse(
|
|
"gymnast_details_tab",
|
|
args=(form.cleaned_data["gymnast"].id, "physiological"),
|
|
)
|
|
)
|
|
|
|
return render(request, "heightweight/create.html", {"form": form})
|
|
|
|
form = HeightWeightForm(instance=heightweight, initial=data)
|
|
context = {
|
|
"form": form,
|
|
"gymnast_id": gymnast_id,
|
|
"heightweight_id": heightweight_id,
|
|
}
|
|
return render(request, "heightweight/create.html", context)
|