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 ( Plan, Skill, Point, Chrono, LearnedSkill, ) 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 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, } # 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 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 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/a4_paper.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/a4_paper.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/a4_paper.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")