Jarvis/jarvis/followup/views_physiological.py

440 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 injury_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)
injury_list = Injury.objects.filter(gymnast=gymnast_id)
else:
if request.user.is_superuser:
injury_list = Injury.objects.all()
else:
injury_list = Injury.objects.filter(
gymnast__in=request.session["available_gymnast"]
)
context = {"injury_list": injury_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 injury_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.user.gymnast.id == gymnast_id
or (
request.session.has_key("available_gymnast")
and gymnast_id in request.session["available_gymnast"]
)
):
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.user.gymnast.id == gymnast_id
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 = {"height_weight_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)