Jarvis/jarvis/people/views_reports.py

1147 lines
38 KiB
Python
Raw Normal View History

from datetime import date
from statistics import mean
from django.contrib.auth.decorators import login_required
from django.contrib.auth import get_user_model
from django.db.models import (
Q,
Avg,
Sum,
Min,
Max,
)
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, get_object_or_404
from django.views.decorators.http import require_http_methods
from django.template.loader import render_to_string
from django.conf import settings
from weasyprint import HTML, CSS
# from weasyprint.fonts import FontConfiguration
import pendulum
from jarvis.followup.models import Event
from jarvis.followup.models import (
Note,
Plan,
Skill,
Point,
Chrono,
Injury,
WellBeing,
Intensity,
LearnedSkill,
HeightWeight,
SeasonInformation,
NumberOfRoutineDone,
)
from jarvis.followup.models import LEARNING_STEP_CHOICES
from jarvis.followup.views_physiological import get_wellbeing_stats_for_season_week
from jarvis.followup.views_intensity import get_intensity_stats_for_season_week
from jarvis.tools.models import Season
# from jarvis.tools.pdf_generator import GymnastReportDocument
from jarvis.tools.date_week_transition import (
from_date_to_week_number,
from_week_number_to_date,
from_month_number_to_date,
from_season_to_date,
)
from .models import Gymnast
User = get_user_model()
def __get_distinct_followup_season_for_gymnast(gymnast_id):
"""Recupère les saisons pour lesquelles le gymnastes à des followup.
Args:
gymnast_id (int) Identifiant de la classe Gymnast
"""
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
season_list = list(
gymnast.chronos.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list += list(
gymnast.injuries.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list += list(
gymnast.known_skills.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list += list(
gymnast.todo.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list += list(
gymnast.wellbeings.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list += list(
gymnast.number_of_routine_done.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list += list(
gymnast.height_weight.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list += list(
gymnast.remarks.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list += list(
gymnast.intensities.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
season_list = list(dict.fromkeys(season_list))
season_list.sort()
return season_list
def __get_distinct_week_number_for_season_and_gymnast(gymnast_id, season):
"""Récupère les numéro de semaines pour lesquelles le gymnaste à des followup.
Args:
gymnast_id (int) Identifiant de la classe Gymnast
season (int) Numéro de semaine
"""
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
weeknumber_list = list(
gymnast.chronos.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list += list(
gymnast.injuries.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list += list(
gymnast.known_skills.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list += list(
gymnast.todo.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list += list(
gymnast.wellbeings.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list += list(
gymnast.number_of_routine_done.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list += list(
gymnast.height_weight.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list += list(
gymnast.remarks.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list += list(
gymnast.intensities.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
)
weeknumber_list = list(dict.fromkeys(weeknumber_list))
weeknumber_list.sort(reverse=True)
return weeknumber_list
2024-02-17 07:43:31 +01:00
def get_distinct_week_number_for_season_and_gymnast(gymnast_id, season=None):
"""
Args:
gymnast_id (int) Identifiant de la classe Gymnast
season (int) Numéro de semaine
"""
if not season:
season = Season()
weeknumber_list = __get_distinct_week_number_for_season_and_gymnast(
gymnast_id, season
)
return JsonResponse(weeknumber_list, safe=False)
@login_required
@require_http_methods(["GET"])
def report_choice(request, gymnast_id):
"""Recupère les saisons pour lesquelles le gymnastes à des followup.
Args:
gymnast_id (int) Identifiant de la classe Gymnast
"""
today = pendulum.now().date()
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
season, week_number = from_date_to_week_number(today)
season_list = __get_distinct_followup_season_for_gymnast(gymnast_id)
week_number_list = __get_distinct_week_number_for_season_and_gymnast(
gymnast_id, season
)
context = {
"gymnast": gymnast,
"actual_season": season,
"season_list": season_list,
"actual_week_number": week_number,
"week_number_list": week_number_list,
}
2024-02-17 07:43:31 +01:00
# return render(request, "gymnasts/report_choices.html", context)
return render(request, "gymnasts/tabs/tab_documents.html", context)
def analyse_score(value, value_list):
"""Analyse une valeur (value) par rapport à la moyenne de value_list et à la dernière
valeur de value_list.
Args:
value float valeur
value_list array<float> liste de valeurs
Returns:
string
Examples:
"""
result = ""
average_value = mean(value_list)
if value > value_list[-1]:
result += "+"
elif value < value_list[-1]:
result += "-"
else:
result += "="
if value > average_value:
result = "+" + result
elif value < average_value:
result = "-" + result
else:
result = "=" + result
return result
def __compute_curve_orientation(value, previous_value, previous_previous_value):
"""Analyse une valeur (value) par rapport à la moyenne de value_list et à la dernière
valeur de value_list.
Args:
value float valeur
value_list array<float> liste de valeurs
Returns:
string
Examples:
"""
result = ""
if value > previous_value:
result += "+"
elif value < previous_value:
result += "-"
else:
result += "="
if previous_value > previous_previous_value:
result = "+" + result
elif previous_value < previous_previous_value:
result = "-" + result
else:
result = "=" + result
return result
def __mindstate_analyse(gymnast, date_begin, date_end, period, mindstate_score):
"""Analyse de l'état d'esprit entre deux dates."""
previous_period_date_end = date_begin
if period == "week":
period_length = 7
elif period == "month":
period_length = 30
else:
period_length = 365
previous_period_date_begin = previous_period_date_end.subtract(days=period_length)
previous_mindstate_score = gymnast.wellbeings.filter(
date__gte=previous_period_date_begin, date__lte=previous_period_date_end
).aggregate(average_mindstate_value=Avg("mindstate"))
previous_previous_period_date_end = previous_period_date_begin
previous_previous_period_date_begin = previous_previous_period_date_end.subtract(
days=period_length
)
previous_previous_mindstate_score = gymnast.wellbeings.filter(
date__gte=previous_previous_period_date_begin,
date__lte=previous_previous_period_date_end,
).aggregate(average_mindstate_value=Avg("mindstate"))
return __compute_curve_orientation(
mindstate_score,
previous_mindstate_score["average_mindstate_value"],
previous_previous_mindstate_score["average_mindstate_value"],
)
def __height_analyse(gymnast, date_begin, date_end, period, height_score):
"""Analyse de la taille du gymnaste entre deux dates."""
previous_period_date_end = date_begin
if period == "week":
period_length = 7
elif period == "month":
period_length = 30
else:
period_length = 365
previous_period_date_begin = previous_period_date_end.subtract(days=period_length)
previous_height_score = gymnast.height_weight.filter(
date__gte=previous_period_date_begin, date__lte=previous_period_date_end
).aggregate(average_height_value=Avg("height"))
previous_previous_period_date_end = previous_period_date_begin
previous_previous_period_date_begin = previous_previous_period_date_end.subtract(
days=period_length
)
previous_previous_height_score = gymnast.height_weight.filter(
date__gte=previous_previous_period_date_begin,
date__lte=previous_previous_period_date_end,
).aggregate(average_height_value=Avg("height"))
return __compute_curve_orientation(
height_score,
previous_height_score["average_height_value"],
previous_previous_height_score["average_height_value"],
)
def __weight_analyse(gymnast, date_begin, date_end, period, weight_score):
"""Analyse du poids du gymnaste entre deux dates."""
previous_period_date_end = date_begin
if period == "week":
period_length = 7
elif period == "month":
period_length = 30
else:
period_length = 365
previous_period_date_begin = previous_period_date_end.subtract(days=period_length)
previous_height_score = gymnast.height_weight.filter(
date__gte=previous_period_date_begin, date__lte=previous_period_date_end
).aggregate(average_weight_value=Avg("weight"))
previous_previous_period_date_end = previous_period_date_begin
previous_previous_period_date_begin = previous_previous_period_date_end.subtract(
days=period_length
)
previous_previous_height_score = gymnast.height_weight.filter(
date__gte=previous_previous_period_date_begin,
date__lte=previous_previous_period_date_end,
).aggregate(average_weight_value=Avg("weight"))
return __compute_curve_orientation(
weight_score,
previous_height_score["average_weight_value"],
previous_previous_height_score["average_weight_value"],
)
@login_required
@require_http_methods(["GET"])
def generate_report_for_period(
request, gymnast_id, season, period_value, date_begin, date_end, period="week"
):
"""Génère un rapport de toutes les informations entre les deux dates passées en paramètre.
Args:
gymnast_id (int) Identifiant de la classe Gymnast
date_begin (datetime) Date de début de la période à considérer # pendulum
date_end (datetime) Date de fin de la période à considérer # pendulum
"""
today = pendulum.now().date()
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
season_informations = gymnast.season_informations.filter(season=season).first()
# PHYSIOLOGICAL INFORMATIONS
# WellBeing Score
wellbeing_score_quantity = gymnast.wellbeings.filter(
date__gte=date_begin, date__lte=date_end
).count()
wellbeing_score = gymnast.wellbeings.filter(
date__gte=date_begin, date__lte=date_end
).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"),
)
height_weight_quantity = gymnast.height_weight.filter(
date__gte=date_begin, date__lte=date_end
).count()
height_weight_value = gymnast.height_weight.filter(
date__gte=date_begin, date__lte=date_end
).aggregate(
min_height_value=Min("height"),
average_height_value=Avg("height"),
max_height_value=Max("height"),
min_weight_value=Min("weight"),
average_weight_value=Avg("weight"),
max_weight_value=Max("weight"),
)
intensity_quantity = gymnast.intensities.filter(
date__gte=date_begin, date__lte=date_end
).count()
intensity_value = gymnast.intensities.filter(
date__gte=date_begin, date__lte=date_end
).aggregate(
average_intensity_time_value=Avg("time"),
average_intensity_difficulty_value=Avg("difficulty"),
average_quantity_of_skill_value=Avg("quantity_of_skill"),
average_number_of_passes_value=Avg("number_of_passes"),
average_time_quality=Avg("time_quality"),
average_difficulty_quality=Avg("difficulty_quality"),
average_quantity_of_skill_quality=Avg("quantity_of_skill_quality"),
average_number_of_passes_quality=Avg("number_of_passes_quality"),
average_average_training_quality=Avg("average_training_quality"),
min_intensity_time_value=Min("time"),
min_intensity_difficulty_value=Min("difficulty"),
min_quantity_of_skill_value=Min("quantity_of_skill"),
min_number_of_passes_value=Min("number_of_passes"),
min_time_quality=Min("time_quality"),
min_difficulty_quality=Min("difficulty_quality"),
min_quantity_of_skill_quality=Min("quantity_of_skill_quality"),
min_number_of_passes_quality=Min("number_of_passes_quality"),
min_average_training_quality=Min("average_training_quality"),
max_intensity_time_value=Max("time"),
max_intensity_difficulty_value=Max("difficulty"),
max_quantity_of_skill_value=Max("quantity_of_skill"),
max_number_of_passes_value=Max("number_of_passes"),
max_time_quality=Max("time_quality"),
max_difficulty_quality=Max("difficulty_quality"),
max_quantity_of_skill_quality=Max("quantity_of_skill_quality"),
max_number_of_passes_quality=Max("number_of_passes_quality"),
max_average_training_quality=Max("average_training_quality"),
)
injury_list = gymnast.injuries.filter(
date__gte=date_begin, date__lte=date_end
).order_by("date")
# BEST TOF
number_of_tof_straightjump = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=0
).count()
best_tof_straightjump = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=0
).aggregate(
min_score=Min("score"),
min_tof=Min("tof"),
average_score=Avg("score"),
average_tof=Avg("tof"),
max_score=Max("score"),
max_tof=Max("tof"),
)
number_of_tof_q1r1 = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=1
).count()
best_tof_q1r1 = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=1
).aggregate(
min_score=Min("score"),
min_tof=Min("tof"),
average_score=Avg("score"),
average_tof=Avg("tof"),
max_score=Max("score"),
max_tof=Max("tof"),
)
number_of_tof_q1r2 = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=2
).count()
best_tof_q1r2 = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=2
).aggregate(
min_score=Min("score"),
min_tof=Min("tof"),
average_score=Avg("score"),
average_tof=Avg("tof"),
max_score=Max("score"),
max_tof=Max("tof"),
)
number_of_tof_q2r1 = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=3
).count()
best_tof_q2r1 = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=3
).aggregate(
min_score=Min("score"),
min_tof=Min("tof"),
average_score=Avg("score"),
average_tof=Avg("tof"),
max_score=Max("score"),
max_tof=Max("tof"),
)
number_of_tof_sf = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=3
).count()
best_tof_sf = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=3
).aggregate(
min_score=Min("score"),
min_tof=Min("tof"),
average_score=Avg("score"),
average_tof=Avg("tof"),
max_score=Max("score"),
max_tof=Max("tof"),
)
number_of_tof_f = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=3
).count()
best_tof_f = Chrono.objects.filter(
gymnast=gymnast, date__gte=date_begin, date__lte=date_end, chrono_type=3
).aggregate(
min_score=Min("score"),
min_tof=Min("tof"),
average_score=Avg("score"),
average_tof=Avg("tof"),
max_score=Max("score"),
max_tof=Max("tof"),
)
# BEST SCORES
best_point_routine_1 = (
Point.objects.filter(
gymnast=gymnast, event__date_begin__lte=date_begin, routine_type=1
)
.order_by("-total")
.first()
)
best_point_routine_2 = (
Point.objects.filter(
gymnast=gymnast, event__date_begin__lte=date_begin, routine_type=2
)
.order_by("-total")
.first()
)
best_point_routine_3 = (
Point.objects.filter(
gymnast=gymnast, event__date_begin__lte=date_begin, routine_type=3
)
.order_by("-total")
.first()
)
best_point_routine_4 = (
Point.objects.filter(
gymnast=gymnast, event__date_begin__lte=date_begin, routine_type=4
)
.order_by("-total")
.first()
)
best_point_routine_5 = (
Point.objects.filter(
gymnast=gymnast, event__date_begin__lte=date_begin, routine_type=5
)
.order_by("-total")
.first()
)
# ROUTINES
q1r1 = (
gymnast.has_routine.filter(routine_type=1)
.filter(date_begin__lte=date_begin)
.filter(Q(date_end__gte=date_begin) | Q(date_end__isnull=True))
.first()
)
routine_1_done_stat = gymnast.number_of_routine_done.filter(
routine_type=1, date__gte=date_begin, date__lte=date_end
).aggregate(
total_try=Sum("number_of_try"), total_succeeded=Sum("number_of_successes")
)
q1r2 = (
gymnast.has_routine.filter(routine_type=2)
.filter(date_begin__lte=date_begin)
.filter(Q(date_end__gte=date_begin) | Q(date_end__isnull=True))
.first()
)
routine_2_done_stat = gymnast.number_of_routine_done.filter(
routine_type=2, date__gte=date_begin, date__lte=date_end
).aggregate(
total_try=Sum("number_of_try"), total_succeeded=Sum("number_of_successes")
)
q2r1 = (
gymnast.has_routine.filter(routine_type=3)
.filter(date_begin__lte=date_begin)
.filter(Q(date_end__gte=date_begin) | Q(date_end__isnull=True))
.first()
)
routine_3_done_stat = gymnast.number_of_routine_done.filter(
routine_type=3, date__gte=date_begin, date__lte=date_end
).aggregate(
total_try=Sum("number_of_try"), total_succeeded=Sum("number_of_successes")
)
sfinal = (
gymnast.has_routine.filter(routine_type=4)
.filter(date_begin__lte=date_begin)
.filter(Q(date_end__gte=date_begin) | Q(date_end__isnull=True))
.first()
)
routine_4_done_stat = gymnast.number_of_routine_done.filter(
routine_type=4, date__gte=date_begin, date__lte=date_end
).aggregate(
total_try=Sum("number_of_try"), total_succeeded=Sum("number_of_successes")
)
final = (
gymnast.has_routine.filter(routine_type=5)
.filter(date_begin__lte=date_begin)
.filter(Q(date_end__gte=date_begin) | Q(date_end__isnull=True))
.first()
)
routine_5_done_stat = gymnast.number_of_routine_done.filter(
routine_type=5, date__gte=date_begin, date__lte=date_end
).aggregate(
total_try=Sum("number_of_try"), total_succeeded=Sum("number_of_successes")
)
# LAST LEARNED SKILLS
learned_skills = LearnedSkill.objects.filter(
gymnast=gymnast.id, date__gte=date_begin, date__lte=date_end
).order_by("-date")
# PLANNED SKILLS
plan_list = (
Plan.objects.filter(gymnast=gymnast, educative__in=Skill.objects.all())
.filter(Q(is_done=False) | Q(date__gte=date.today()))
.order_by("date")
.distinct()[:6]
)
# NEXT EVENTS
next_event_list = Event.objects.filter(
gymnasts=gymnast, date_begin__gte=date_begin
).order_by("date_begin")[:5]
# NOTES
# begin_of_the_week = date_begin
# if date_begin.weekday() != 0:
# begin_of_the_week -= timedelta(date_begin.weekday())
notes = (
gymnast.remarks.filter(date__gte=date_begin, date__lte=date_end)
.filter(status=1)
.order_by("date")
)
context = {
# HEADER
"SITE_TITLE": settings.SITE_TITLE,
"CLUB_NAME": settings.CLUB_NAME,
"ADDRESS": settings.ADDRESS,
"CITY": settings.CITY,
"ZIP": settings.ZIP,
"HEAD_COACH": settings.HEAD_COACH,
"MOBILE_PHONE": settings.MOBILE_PHONE,
"HEAD_COACH_EMAIL": settings.HEAD_COACH_EMAIL,
"season": season,
"date_begin": date_begin,
"date_end": date_end,
"period": period,
"period_value": period_value,
"today": today,
# GYMNAST INFORMATIONS
"gymnast": gymnast,
"season_informations": season_informations,
# MEDICAL INFORMATIONS
"wellbeing_score_quantity": wellbeing_score_quantity,
"wellbeing_score": wellbeing_score,
"height_weight_value": height_weight_value,
"injury_list": injury_list,
# INTENSITY
"intensity_quantity": intensity_quantity,
"intensity_value": intensity_value,
# TOF
"number_of_tof_straightjump": number_of_tof_straightjump,
"best_tof_straightjump": best_tof_straightjump,
"number_of_tof_q1r1": number_of_tof_q1r1,
"best_tof_q1r1": best_tof_q1r1,
"number_of_tof_q1r2": number_of_tof_q1r2,
"best_tof_q1r2": best_tof_q1r2,
"number_of_tof_q2r1": number_of_tof_q2r1,
"best_tof_q2r1": best_tof_q2r1,
"number_of_tof_sf": number_of_tof_sf,
"best_tof_sf": best_tof_sf,
"number_of_tof_f": number_of_tof_f,
"best_tof_f": best_tof_f,
# SCORES
"best_point_q1r1": best_point_routine_1,
"best_point_q1r2": best_point_routine_2,
"best_point_q2r1": best_point_routine_3,
"best_point_sf": best_point_routine_4,
"best_point_f": best_point_routine_5,
"q1r1": q1r1,
"q1r2": q1r2,
"q2r1": q2r1,
"sfinal": sfinal,
"final": final,
"q1r1_done_stat": routine_1_done_stat,
"q1r2_done_stat": routine_2_done_stat,
"q2r1_done_stat": routine_3_done_stat,
"sfinal_done_stat": routine_4_done_stat,
"final_done_stat": routine_5_done_stat,
"LEARNING_STEP_CHOICES": LEARNING_STEP_CHOICES,
"learned_skills": learned_skills,
"plan_list": plan_list,
"next_event_list": next_event_list,
"notes": notes,
}
return render(request, "gymnasts/reports/report_periodical.html", context)
# response = HttpResponse(content_type="application/pdf")
# response[
# "Content-Disposition"
# ] = f"attachment; filename={gymnast.last_name}_{gymnast.first_name}_{period}-report_{date_begin}_{date_end}.pdf" # pylint: disable=line-too-long
# html = render_to_string("gymnasts/reports/report_periodical.html", context)
# # font_config = FontConfiguration()
# HTML(string=html, base_url=request.build_absolute_uri()).write_pdf(
# response,
# stylesheets=[
# CSS(settings.STATICFILES_DIRS[0] + "/css/gymnast_report.css"),
# CSS(settings.STATICFILES_DIRS[0] + "/css/black-dashboard_report.css"),
# CSS(settings.STATICFILES_DIRS[0] + "/css/font_awesome_all_5.15.3.css"),
# ],
# ) # , font_config=font_config)
# return response
@login_required
@require_http_methods(["GET"])
def generate_report_week_comparison(
request, gymnast_id, season_source, week_source, season_target, week_target
):
"""Génère un rapport avec une comparaison de deux semaines entre elles.
Args:
gymnast_id (int) Identifiant de la classe Gymnast
season_source (str) saison de comparaison
week_source (int) semaine de comparaison
season_target (str) saison comparée
week_target (int) semaine comparée
"""
today = pendulum.now().date()
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
# season_informations = gymnast.season_informations.filter(season=season).first()
# PHYSIOLOGICAL INFORMATIONS
# WellBeing Score
source_wellbeing_score_quantity = gymnast.wellbeings.filter(
season=season_source, week_number=week_source
).count()
source_wellbeing_score = get_wellbeing_stats_for_season_week(
gymnast_id, season_source, week_source
)
target_wellbeing_score_quantity = gymnast.wellbeings.filter(
season=season_target, week_number=week_target
).count()
target_wellbeing_score = get_wellbeing_stats_for_season_week(
gymnast_id, season_target, week_target
)
# Intensity Score
source_intensity_quantity = gymnast.intensities.filter(
season=season_source, week_number=week_source
).count()
source_intensity_value = get_intensity_stats_for_season_week(
gymnast_id, season_source, week_source
)
target_intensity_quantity = gymnast.intensities.filter(
season=season_target, week_number=week_target
).count()
target_intensity_value = get_intensity_stats_for_season_week(
gymnast_id, season_target, week_target
)
context = {
# HEADER
"SITE_TITLE": settings.SITE_TITLE,
"CLUB_NAME": settings.CLUB_NAME,
"ADDRESS": settings.ADDRESS,
"CITY": settings.CITY,
"ZIP": settings.ZIP,
"HEAD_COACH": settings.HEAD_COACH,
"MOBILE_PHONE": settings.MOBILE_PHONE,
"HEAD_COACH_EMAIL": settings.HEAD_COACH_EMAIL,
# "season": season,
# "date_begin": date_begin,
# "date_end": date_end,
# "period": period,
# "period_value": period_value,
"today": today,
# GYMNAST INFORMATIONS
"gymnast": gymnast,
# "season_informations": season_informations,
# MEDICAL INFORMATIONS
"source_wellbeing_score_quantity": source_wellbeing_score_quantity,
"source_wellbeing_score": source_wellbeing_score,
"target_wellbeing_score_quantity": target_wellbeing_score_quantity,
"target_wellbeing_score": target_wellbeing_score,
# "height_weight_value": height_weight_value,
# "injury_list": injury_list,
# # INTENSITY
"source_intensity_quantity": source_intensity_quantity,
"source_intensity_value": source_intensity_value,
"target_intensity_quantity": target_intensity_quantity,
"target_intensity_value": target_intensity_value,
# # TOF
# "number_of_tof_straightjump": number_of_tof_straightjump,
# "best_tof_straightjump": best_tof_straightjump,
# "number_of_tof_q1r1": number_of_tof_q1r1,
# "best_tof_q1r1": best_tof_q1r1,
# "number_of_tof_q1r2": number_of_tof_q1r2,
# "best_tof_q1r2": best_tof_q1r2,
# "number_of_tof_q2r1": number_of_tof_q2r1,
# "best_tof_q2r1": best_tof_q2r1,
# "number_of_tof_sf": number_of_tof_sf,
# "best_tof_sf": best_tof_sf,
# "number_of_tof_f": number_of_tof_f,
# "best_tof_f": best_tof_f,
# # SCORES
# "best_point_q1r1": best_point_routine_1,
# "best_point_q1r2": best_point_routine_2,
# "best_point_q2r1": best_point_routine_3,
# "best_point_sf": best_point_routine_4,
# "best_point_f": best_point_routine_5,
# "q1r1": q1r1,
# "q1r2": q1r2,
# "q2r1": q2r1,
# "sfinal": sfinal,
# "final": final,
# "q1r1_done_stat": routine_1_done_stat,
# "q1r2_done_stat": routine_2_done_stat,
# "q2r1_done_stat": routine_3_done_stat,
# "sfinal_done_stat": routine_4_done_stat,
# "final_done_stat": routine_5_done_stat,
# "LEARNING_STEP_CHOICES": LEARNING_STEP_CHOICES,
# "learned_skills": learned_skills,
# "plan_list": plan_list,
# "next_event_list": next_event_list,
# "notes": notes,
}
return render(request, "gymnasts/reports/report_week_comparison.html", context)
# response = HttpResponse(content_type="application/pdf")
# response[
# "Content-Disposition"
# ] = f"attachment; filename={gymnast.last_name}_{gymnast.first_name}_{period}-report_{date_begin}_{date_end}.pdf" # pylint: disable=line-too-long
# html = render_to_string("gymnasts/reports/report_week_comparison.html", context)
# # font_config = FontConfiguration()
# HTML(string=html, base_url=request.build_absolute_uri()).write_pdf(
# response,
# stylesheets=[
# CSS(settings.STATICFILES_DIRS[0] + "/css/gymnast_report.css"),
# CSS(settings.STATICFILES_DIRS[0] + "/css/black-dashboard_report.css"),
# CSS(settings.STATICFILES_DIRS[0] + "/css/font_awesome_all_5.15.3.css"),
# ],
# ) # , font_config=font_config)
# return response
@login_required
@require_http_methods(["GET"])
def generate_season_report(request, gymnast_id, season):
"""Génère un rapport pour une saison passée en paramètre.
Args:
gymnast_id (int) identifiant de gymnaste
season (str) saison
"""
date_begin, date_end = from_season_to_date(season)
return generate_report_for_period(
request,
gymnast_id,
season,
season,
date_begin,
date_end,
period="season",
)
@login_required
@require_http_methods(["GET"])
def generate_month_report(request, gymnast_id, season, month_number):
"""Génère un rapport pour une saison et un mois passée en paramètre.
Args:
gymnast_id (int) identifiant de gymnaste
season (str) saison
month_number (int) mois de l'année
"""
date_begin, date_end = from_month_number_to_date(season, month_number)
month = date_begin.format("MMMM")
return generate_report_for_period(
request,
gymnast_id,
season,
month,
date_begin,
date_end,
period="month",
)
@login_required
@require_http_methods(["GET"])
def generate_week_report(request, gymnast_id, season, week_number):
"""Génère un rapport hebdomadaire.
Args:
gymnast_id (int) Identifiant de la classe Gymnast
season (int) Numéro de semaine
week_number (int) Numéro de semaine
"""
date_begin, date_end = from_week_number_to_date(season, week_number)
return generate_report_for_period(
request,
gymnast_id,
season,
week_number,
date_begin,
date_end,
period="week",
)
@login_required
@require_http_methods(["GET"])
def generate_timeline_report(
request, gymnast_id, season=None, week_number=None, date=None
):
"""Génère une timeline pour un gymnaste. On va chercher tous les
- records (Chrono/ToF),
- points (compétition),
- nouveau apprentissage (learned skill)
- blessures
- GymnastHasRoutine
et on les trie par date.
Args:
gymnast_id (int) identifiant du gymnast
season (int) saison
week_number (int) numéro de semaine
date (date) date
"""
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
if season is None:
date_begin = pendulum.now().date()
season, week_number = from_date_to_week_number(date_begin)
else:
date_begin, _ = from_week_number_to_date(season, week_number)
date_begin = date_begin.date()
selected_record = []
list_record_straightjumps = list(
gymnast.chronos.filter(chrono_type=0).order_by("date")
)
last_top_score = 0
for record in list_record_straightjumps:
if record.score > last_top_score:
last_top_score = record.score
selected_record.append(record)
list_record_first_routine = list(
gymnast.chronos.filter(chrono_type=1).order_by("date")
)
last_top_score = 0
for record in list_record_first_routine:
if record.score > last_top_score:
last_top_score = record.score
selected_record.append(record)
list_record_second_routine = list(
gymnast.chronos.filter(chrono_type=2).order_by("date")
)
last_top_score = 0
for record in list_record_second_routine:
if record.score > last_top_score:
last_top_score = record.score
selected_record.append(record)
list_record_third_routine = list(
gymnast.chronos.filter(chrono_type=3).order_by("date")
)
last_top_score = 0
for record in list_record_third_routine:
if record.score > last_top_score:
last_top_score = record.score
selected_record.append(record)
list_record_fourth_routine = list(
gymnast.chronos.filter(chrono_type=4).order_by("date")
)
last_top_score = 0
for record in list_record_fourth_routine:
if record.score > last_top_score:
last_top_score = record.score
selected_record.append(record)
list_record_fifth_routine = list(
gymnast.chronos.filter(chrono_type=5).order_by("date")
)
last_top_score = 0
for record in list_record_fifth_routine:
if record.score > last_top_score:
last_top_score = record.score
selected_record.append(record)
# print(selected_record)
list_record = selected_record
list_record.extend(list(gymnast.injuries.all().order_by("date")))
# list_record.extend(list(gymnast.points.all().order_by("date")))
list_record.extend(list(gymnast.known_skills.all().order_by("date")))
# print(list_record)
sorted_records = sorted(list_record, key=lambda x: x.date)
# print(sorted_records)
context = {
"SITE_TITLE": settings.SITE_TITLE,
"CLUB_NAME": settings.CLUB_NAME,
"ADDRESS": settings.ADDRESS,
"CITY": settings.CITY,
"ZIP": settings.ZIP,
"HEAD_COACH": settings.HEAD_COACH,
"MOBILE_PHONE": settings.MOBILE_PHONE,
"HEAD_COACH_EMAIL": settings.HEAD_COACH_EMAIL,
"week_number": week_number,
"gymnast": gymnast,
"today": date_begin,
"season": season,
"sorted_records": sorted_records,
}
# return render(request, "gymnasts/reports/report_timeline.html", context)
response = HttpResponse(content_type="application/pdf")
response[
"Content-Disposition"
] = "attachment; filename={lastname}-{firstname}-report-timeline.pdf".format(
lastname=gymnast.last_name,
firstname=gymnast.first_name,
)
html = render_to_string("gymnasts/reports/report_timeline.html", context)
# font_config = FontConfiguration()
HTML(string=html, base_url=request.build_absolute_uri()).write_pdf(
response,
stylesheets=[
CSS(settings.STATICFILES_DIRS[0] + "/css/gymnast_report.css"),
CSS(settings.STATICFILES_DIRS[0] + "/css/black-dashboard_report.css"),
CSS(settings.STATICFILES_DIRS[0] + "/css/font_awesome_all_5.15.3.css"),
],
) # , font_config=font_config)
return response
# @login_required
# @require_http_methods(["GET"])
# def generate_week_resume(request, gymnast_id, season=None, week_number=None):
# """va rechercher les informations nécessaires pour aider à la note de la semaine
# - wellbeing
# - intensity
# - injury
# Args:
# gymnast_id (int) identifiant du gymnast
# season (int) saison
# week_number (int) numéro de semaine
# date (date) date
# """
# gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
# if season is None:
# date_begin = pendulum.now().date()
# season, week_number = from_date_to_week_number(date_begin)
# else:
# date_begin, _ = from_week_number_to_date(season, week_number)
# date_begin = date_begin.date()
# wellbeing_list = gymnast.wellbeing.objects.filter(season="season", week_number="week_number")
# intensity_list = gymnast.intensities.objects.filter(season="season", week_number="week_number") # pylint: disable=line-too-long
# injury_list = gymnast.injuries.filter(season="season", week_number="week_number")