2024-01-14 14:48:31 +01:00
from datetime import date , datetime
2023-04-25 17:06:14 +02:00
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 , JsonResponse
from django . db . models import Q , Min , Avg , Max , Sum
from django . urls import reverse
from django . conf import settings
from django . contrib . auth import get_user_model
2023-04-28 12:20:55 +02:00
from django . contrib . contenttypes . models import ContentType
2023-04-25 17:06:14 +02:00
from django . core . mail import send_mail
2024-01-14 14:48:31 +01:00
import pendulum
2024-02-03 17:20:42 +01:00
from jarvis . core . models import Email
2023-04-25 17:06:14 +02:00
from jarvis . people . models import Gymnast
from jarvis . planning . models import Event
from jarvis . objective . models import Skill
2024-01-14 14:48:31 +01:00
from jarvis . tools . date_week_transition import from_date_to_week_number
from jarvis . tools . models import Season
2023-04-25 17:06:14 +02:00
2023-11-18 18:29:18 +01:00
from . models import (
CHRONO_TYPE_CHOICE ,
SCORE_TYPE_CHOICE ,
INJURY_MECHANISM_CHOICE ,
INJURY_BODY_SIDE_CHOICE ,
INJURY_TYPE_CHOICE ,
INJURY_LOCATION_CHOICE ,
)
2023-04-25 17:06:14 +02:00
from . models import (
Plan ,
Note ,
Point ,
Chrono ,
2023-10-11 16:32:09 +02:00
Injury ,
2023-07-05 10:51:49 +02:00
WellBeing ,
2023-04-25 17:06:14 +02:00
Intensity ,
LearnedSkill ,
HeightWeight ,
ChronoDetails ,
GymnastHasRoutine ,
SeasonInformation ,
NumberOfRoutineDone ,
)
from . forms import (
PlanForm ,
NoteForm ,
ScoreForm ,
ChronoForm ,
2023-10-11 16:32:09 +02:00
InjuryForm ,
2023-07-05 09:33:03 +02:00
WellBeingForm ,
2023-04-25 17:06:14 +02:00
IntensityForm ,
HeightWeightForm ,
LearnedSkillForm ,
SeasonInformationForm ,
NumberOfRoutineDoneForm ,
)
User = get_user_model ( )
2023-11-22 10:27:41 +01:00
MAIL_HEADER = """
< html > < head > < style id = " canary-invert " > html {
filter : invert ( 100 % ) hue - rotate ( 180 deg ) ! important ;
}
img ,
video ,
: not ( object ) : not ( body ) > embed ,
object ,
svg image ,
[ style * = " background:url " ] ,
[ style * = " background-image:url " ] ,
[ style * = " background: url " ] ,
[ style * = " background-image: url " ] ,
[ background ] ,
twitterwidget ,
. canary - emoji {
filter : invert ( 100 % ) hue - rotate ( 180 deg ) ! important ;
}
[ style * = " background:url " ] * ,
[ style * = " background-image:url " ] * ,
[ style * = " background: url " ] * ,
[ style * = " background-image: url " ] * ,
input ,
[ background ] * ,
img [ src ^ = " https://s0.wp.com/latex.php " ] ,
twitterwidget . NaturalImage - image {
filter : none ! important ;
}
< / style > < / head > < body contenteditable = " true " style = " font-family:Helvetica;font-size:13px; " > Gregory Trullemans < br >
< / body > < / html > """
2023-11-26 17:29:28 +01:00
MAIL_FOOTER = """ <br />
< p > Excellente journée < / p >
< p > Jarvis < / p >
< p > < b > Trampoline Trainer Help < / b > < / p >
< table border = " 0 " >
< tbody >
< tr >
< td >
< img id = " CB70323B-AC4A-4992-9DD8-3F25DC32658C " height = " 80px " src = " https://www.flyingacrobaticstrampoline.be/img/logo_120px.png " style = " max-width: 100vw; " >
< / td >
< td >
< b > < span class = " " style = " color: rgb(253, 221, 12); " > F < / span > < span class = " " style = " color: rgb(251, 214, 13); " > l < / span > < span class = " " style = " color: rgb(249, 207, 14); " > y < / span > < span class = " " style = " color: rgb(247, 200, 15); " > i < / span > < span class = " " style = " color: rgb(245, 194, 16); " > n < / span > < span class = " " style = " color: rgb(243, 187, 17); " > g < / span > & nbsp ; < span class = " " style = " color: rgb(241, 180, 18); " > < / span > < span class = " " style = " color: rgb(239, 173, 19); " > A < / span > < span class = " " style = " color: rgb(237, 166, 20); " > c < / span > < span class = " " style = " color: rgb(234, 159, 21); " > r < / span > < span class = " " style = " color: rgb(232, 153, 22); " > o < / span > < span class = " " style = " color: rgb(230, 146, 23); " > b < / span > < span class = " " style = " color: rgb(228, 139, 24); " > a < / span > < span class = " " style = " color: rgb(226, 132, 25); " > t < / span > < span class = " " style = " color: rgb(224, 125, 26); " > i < / span > < span class = " " style = " color: rgb(222, 118, 27); " > c < / span > < span class = " " style = " color: rgb(220, 112, 28); " > s < / span > & nbsp ; < span class = " " style = " color: rgb(218, 105, 29); " > < / span > < span class = " " style = " color: rgb(216, 98, 30); " > T < / span > < span class = " " style = " color: rgb(214, 91, 31); " > r < / span > < span class = " " style = " color: rgb(212, 84, 32); " > a < / span > < span class = " " style = " color: rgb(210, 77, 33); " > m < / span > < span class = " " style = " color: rgb(208, 70, 34); " > p < / span > < span class = " " style = " color: rgb(206, 64, 35); " > o < / span > < span class = " " style = " color: rgb(204, 57, 36); " > l < / span > < span class = " " style = " color: rgb(201, 50, 37); " > i < / span > < span class = " " style = " color: rgb(199, 43, 38); " > n < / span > < span class = " " style = " color: rgb(197, 36, 39); " > e < / span > & nbsp ; < span class = " " style = " color: rgb(195, 29, 40); " > < / span > < span class = " " style = " color: rgb(193, 23, 41); " > C < / span > < span class = " " style = " color: rgb(191, 16, 42); " > l < / span > < span class = " " style = " color: rgb(189, 9, 43); " > u < / span > < span class = " " style = " color: rgb(187, 2, 44); " > b < / span > < / b > < br >
< span style = " font-size: 13px; letter-spacing: 0.01em; line-height: 1.2; " > Rue René Francq , 7 < / span > < br >
< span style = " font-size: 13px; letter-spacing: 0.01em; line-height: 1.2; " > 1428 Lillois - Witterzée < / span >
< / td >
< / tr >
< / tbody >
< / table > """
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " ] )
def jump_chrono_details ( request , chrono_id ) :
""" Récupère toutes les informations détaillées d ' un chrono. La fonction en profite pour
recalculer le total et s ' assure que cela correspond à la valeur stockée dans le model
Chrono .
Args :
chrono_id ( int ) identifiant chrono
2024-01-14 14:48:31 +01:00
QTF : Est - ce que je ne devrais pas faire un prefetch_related sur mon objet chrono pour
optimiser mon affichage ?
2023-04-25 17:06:14 +02:00
chrono = Chrono . object . get ( pk = chrono_id ) . prefetch_related ( ' chrono_details ' ) ?
"""
chrono = get_object_or_404 ( Chrono , pk = chrono_id )
sum_value = chrono . details . all ( ) . aggregate ( total = Sum ( " value " ) )
if chrono . score != sum_value [ " total " ] :
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 ( mean = Avg ( " value " ) ) [ " mean " ]
tmp_min_value = chrono . details . all ( ) . aggregate ( min = Min ( " value " ) ) [ " min " ]
tmp_max_value = chrono . details . all ( ) . aggregate ( max = Max ( " value " ) ) [ " max " ]
chart_min_value = mean_value - ( tmp_min_value / 20 )
chart_max_value = mean_value - ( tmp_max_value / 20 )
context = {
" chrono " : chrono ,
" mean_value " : mean_value ,
" chart_min_value " : chart_min_value ,
" chart_max_value " : chart_max_value ,
}
return render ( request , " chronos/details.html " , context )
@login_required
@require_http_methods ( [ " GET " ] )
def average_jump_chrono_details_for_gymnast (
request , gymnast_id , routine_type = 1 , season = None , week_number = 1
) :
""" Récupère tout les chronos entre deux date pour un gymnaste et un type de série
Args :
2023-05-14 19:10:34 +02:00
gymnast_id ( int ) Identifiant d ' un gymnaste
routine_type ( int ) Type de série ( cf . jarvis / followup / models . py > ROUTINE_CHOICE )
season ( string ) Saison sous forme " xxxx-xxxy "
week_number ( int ) numéro de semaine ( 1 , … , 52 )
2023-04-25 17:06:14 +02:00
"""
if season is None :
today = pendulum . now ( ) . date ( )
season , week_number = from_date_to_week_number ( today )
else :
2023-06-13 19:32:35 +02:00
season = Season ( season ) . label
2024-01-14 14:48:31 +01:00
week_number = min ( week_number , 52 )
week_number = max ( week_number , 1 )
2023-04-25 17:06:14 +02:00
return average_jump_chrono_details_for_season_and_week (
request ,
gymnast_id ,
routine_type ,
season ,
week_number ,
)
@require_http_methods ( [ " POST " ] )
def remove_jump_chrono_value ( request ) :
"""
2023-05-14 19:10:34 +02:00
Recoit trois informations permettant de supprimer le chrono d ' un saut à un chrono.
2023-04-25 17:06:14 +02:00
"""
chrono_id = request . POST . get ( " chrono_id " , None )
order = request . POST . get ( " order " , None )
chrono = get_object_or_404 ( Chrono , pk = chrono_id )
try :
ChronoDetails . objects . filter ( chrono = chrono , order = order ) . delete ( )
except Exception :
return HttpResponse ( 409 )
return HttpResponse ( 200 )
@require_http_methods ( [ " POST " ] )
def add_jump_chrono_value ( request ) :
"""
2023-05-14 19:10:34 +02:00
Recoit trois informations permettant d ' ajouter le chrono d ' un saut à un chrono .
2023-04-25 17:06:14 +02:00
"""
chrono_id = request . POST . get ( " chrono_id " , None )
order = request . POST . get ( " order " , None )
value = request . POST . get ( " value " , None )
chrono = get_object_or_404 ( Chrono , pk = chrono_id )
row , created = ChronoDetails . objects . get_or_create (
chrono = chrono , order = order , value = value
)
if created :
return HttpResponse ( 200 , ( row , created ) ) # devrait être un 201
2024-01-14 14:48:31 +01:00
return HttpResponse ( 400 , ( row , created ) )
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " ] )
def jump_chrono_values_create_or_update ( request , chrono_id ) :
"""
Ajoute des scores de saut à un chrono .
Args :
chrono_id ( int ) identifiant 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 , " chronos/add_details.html " , context )
@login_required
@require_http_methods ( [ " GET " ] )
def average_jump_chrono_details_between_two_date (
request , gymnast_id , routine_type = 1 , date_begin = None , date_end = None
) :
""" Récupère tout les chronos entre deux date pour un gymnaste et un type de série
2023-05-14 19:10:34 +02:00
2023-04-25 17:06:14 +02:00
Args :
gymnast_id ( int ) Identifiant d ' un gymnaste
routine_type ( int ) type de série ( cf . jarvis / followup / models . py > ROUTINE_CHOICE )
date_begin ( date ) date de début
date_end ( date ) date de fin
2023-05-14 19:10:34 +02:00
2024-01-14 14:48:31 +01:00
QTF : le cast en date devrait être dans un try mais comment gérer correctement l ' erreur - si
erreur il y a ?
2023-04-25 17:06:14 +02:00
"""
if date_end :
try :
date_end = datetime . strptime ( date_end , " % Y- % m- %d " ) . date ( )
except ( ValueError , TypeError ) :
date_end = pendulum . now ( ) . date ( )
else :
date_end = pendulum . now ( ) . date ( )
if date_begin :
try :
date_begin = datetime . strptime ( date_begin , " % Y- % m- %d " ) . date ( )
except ( ValueError , TypeError ) :
date_begin = datetime ( date_end . year , 9 , 1 )
else :
date_begin = datetime ( date_end . year , 9 , 1 )
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 , " chronos/list_details.html " , context )
@require_http_methods ( [ " GET " ] )
def get_chrono_detail_distinct_season ( request , gymnast_id ) :
2023-05-14 19:10:34 +02:00
""" Récupère toutes les saisons pour lesquelles le gymnaste a des chronos détaillés.
Args :
gymnast_id ( int ) Identifiant d ' un gymnaste
"""
2023-04-25 17:06:14 +02:00
gymnast = get_object_or_404 ( Gymnast , pk = gymnast_id )
season_list = list (
gymnast . chronos . values_list ( " season " , flat = True )
. distinct ( " season " )
. order_by ( " season " )
)
return JsonResponse ( season_list , safe = False )
@require_http_methods ( [ " GET " ] )
def get_chrono_detail_distinct_weeknumber_for_season ( request , gymnast_id , season ) :
""" Récupère toutes les week_number pour lesquelles le gymnaste a des chronos détaillés au cours
2023-05-14 19:10:34 +02:00
d ' une saison.
Args :
gymnast_id ( int ) Identifiant d ' un gymnaste
season ( string ) Season
"""
2023-04-25 17:06:14 +02:00
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 " )
)
return JsonResponse ( weeknumber_list , safe = False )
@require_http_methods ( [ " GET " ] )
def get_average_jump_chrono_details_for_season_and_week (
request , gymnast_id , routine_type , season , week_number
) :
""" Récupère tout les chronos moyen par saut pour une saison & semaine d ' un gymnaste
2023-05-14 19:10:34 +02:00
2023-04-25 17:06:14 +02:00
Args :
gymnast_id ( int ) Identifiant d ' un gymnaste
routine_type ( int ) Type de série ( cf . jarvis / followup / models . py > ROUTINE_CHOICE )
season ( string ) Season
week_number ( int ) Numero de la semaine
"""
stat_values = list (
ChronoDetails . objects . filter (
chrono__gymnast = gymnast_id ,
chrono__chrono_type = routine_type ,
chrono__season = season ,
chrono__week_number = week_number ,
)
. values ( " order " )
. annotate ( avg_score = Avg ( " value " ) )
. order_by ( " order " )
)
return JsonResponse ( stat_values , safe = False )
@login_required
@require_http_methods ( [ " GET " ] )
def average_jump_chrono_details_for_season_and_week (
request , gymnast_id , routine_type , season , week_number
) :
""" Récupère tout les chronos entre deux date pour un gymnaste et un type de série
2023-05-14 19:10:34 +02:00
2023-04-25 17:06:14 +02:00
Args :
gymnast_id ( int ) Identifiant d ' un gymnaste
routine_type ( int ) Type de série ( cf . jarvis / followup / models . py > ROUTINE_CHOICE )
season ( string ) Season
week_number ( int ) Numero de la semaine
"""
gymnast = get_object_or_404 ( Gymnast , pk = gymnast_id )
stat_values = (
ChronoDetails . objects . filter (
chrono__gymnast = gymnast_id ,
chrono__chrono_type = routine_type ,
chrono__season = season ,
chrono__week_number = week_number ,
)
. values ( " order " )
. annotate (
avg_score = Avg ( " value " ) , max_score = Max ( " value " ) , min_score = Min ( " value " )
)
. order_by ( " order " )
)
# print(stat_values)
distinct_season_list = (
gymnast . chronos . values_list ( " season " , flat = True )
. distinct ( " season " )
. order_by ( " season " )
)
distinct_week_number_list = (
gymnast . chronos . values_list ( " week_number " , flat = True )
. filter ( season = season )
. distinct ( " week_number " )
. order_by ( " week_number " )
)
distinct_routine_type_list = (
gymnast . chronos . values_list ( " chrono_type " , flat = True )
. distinct ( " chrono_type " )
. order_by ( " chrono_type " )
)
chrono_list = Chrono . objects . filter (
gymnast = gymnast_id ,
season = season ,
week_number = week_number ,
chrono_type = routine_type ,
)
# print(chrono_list)
context = {
" gymnast " : gymnast ,
" selected_season " : season ,
" selected_week_number " : week_number ,
" selected_routine_type " : routine_type ,
" chrono_list " : chrono_list ,
" stat_values " : stat_values ,
" distinct_season_list " : distinct_season_list ,
" distinct_week_number_list " : distinct_week_number_list ,
" distinct_routine_type_list " : distinct_routine_type_list ,
}
return render ( request , " chronos/list_details.html " , context )
@login_required
@require_http_methods ( [ " GET " ] )
def chrono_listing ( request , gymnast_id = None ) :
"""
Si la personne connectée est un entraîneur , la fonction récupère la liste des chronos d ' un
gymnaste précis ou de tout le monde .
Si la personne connectée est un gymnaste , la fonction récupère la liste de ses chronos .
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
"""
gymnast = None
if request . user . groups . filter ( name = " trainer " ) . exists ( ) :
if gymnast_id :
chrono_list = Chrono . objects . filter ( gymnast = gymnast_id )
gymnast = Gymnast . objects . get ( pk = gymnast_id )
else :
chrono_list = Chrono . objects . all ( )
else :
chrono_list = Chrono . objects . filter (
Q ( gymnast__last_name = request . user . last_name )
& Q ( gymnast__first_name = request . user . first_name )
)
context = { " chrono_list " : chrono_list , " gymnast " : gymnast }
return render ( request , " chronos/list.html " , context )
@login_required
@require_http_methods ( [ " GET " ] )
def note_listing ( request , gymnast_id = None ) :
"""
Si la personne connectée est un entraîneur , la fonction récupère la liste des notes d ' un
gymnaste précis ou de tout le monde .
Si la personne connectée est un gymnaste , la fonction récupère la liste de ses notes à
lui / elle .
2023-05-14 19:10:34 +02:00
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
gymnast = None
if request . user . groups . filter ( name = " trainer " ) . exists ( ) :
if gymnast_id :
note_list = Note . objects . filter ( gymnast = gymnast_id )
gymnast = Gymnast . objects . get ( pk = gymnast_id )
else :
note_list = Note . objects . all ( )
else :
note_list = Note . objects . filter (
Q ( gymnast__last_name = request . user . last_name )
& Q ( gymnast__first_name = request . user . first_name )
)
context = { " note_list " : note_list , " gymnast " : gymnast }
return render ( request , " notes/list.html " , context )
@login_required
@require_http_methods ( [ " GET " ] )
def note_details ( request , note_id ) :
"""
Récupère toutes les informations d ' un note.
2023-05-14 19:10:34 +02:00
Args :
note_id ( int ) identifiant d ' une note
2023-04-25 17:06:14 +02:00
"""
note = get_object_or_404 ( Note , pk = note_id )
return render ( request , " notes/details.html " , { " note " : note } )
@login_required
@require_http_methods ( [ " GET " , " POST " ] )
def note_create_or_update ( request , note_id = None , gymnast_id = None ) :
""" Création ou modification d ' un chrono
Args :
note_id ( int ) identifiant d ' une note
gymnast_id ( int ) identifiant d ' un gymnaste
2023-05-14 19:10:34 +02:00
TODO : pq ne puis - je pas récuperer l ' idantifiant du coach via le form ?
2023-04-25 17:06:14 +02:00
"""
coach = User . objects . get ( pk = request . user . id )
if note_id :
note = get_object_or_404 ( Note , pk = note_id )
data = {
" coach " : coach . id ,
" gymnast " : note . gymnast . id ,
" gymnast_related " : str ( note . gymnast ) ,
}
else :
note = None
2023-11-14 14:17:55 +01:00
today = pendulum . now ( ) . date ( )
season , week_number = from_date_to_week_number ( today )
2023-11-14 14:19:15 +01:00
data = {
" coach " : coach . id ,
" title " : f " Note of the week { week_number } ( { season } ) " ,
}
2023-04-25 17:06:14 +02:00
if gymnast_id is not None :
gymnast = get_object_or_404 ( Gymnast , pk = gymnast_id )
data [ " gymnast " ] = gymnast_id
data [ " gymnast_related " ] = str ( gymnast )
if request . method == " POST " :
form = NoteForm ( request . POST , instance = note )
if form . is_valid ( ) :
new_note = form . save ( )
2023-07-05 09:33:03 +02:00
if (
( new_note . gymnast . user . email or new_note . gymnast . email_trainer )
and ( ( not note_id ) or ( note_id and note . status == 0 ) )
and new_note . status == 1
) :
2023-10-31 12:34:53 +01:00
url = request . build_absolute_uri (
reverse ( " gymnast_details_tab " , args = ( new_note . gymnast . id , " event " ) )
)
2024-02-03 18:19:39 +01:00
receivers = [
new_note . gymnast . user . email ,
new_note . gymnast . email_trainer ,
]
title = f " { new_note . gymnast } : Nouvelle note "
body = f """ <p>Bonjour,</p><p>Une nouvelle note vous a été envoyée. Vous pouvez la consulter en cliquant <a href= ' { url } ' >ici</a>.</p> """
2023-10-31 12:34:53 +01:00
2023-07-05 09:33:03 +02:00
send_mail (
2024-02-03 18:19:39 +01:00
title ,
2023-07-05 09:33:03 +02:00
" Une nouvelle note vous a été envoyée " ,
settings . EMAIL_HOST_USER ,
2024-02-03 18:19:39 +01:00
receivers ,
2023-07-05 09:33:03 +02:00
fail_silently = False ,
2024-02-03 18:19:39 +01:00
html_message = body + MAIL_FOOTER ,
2023-07-05 09:33:03 +02:00
)
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
2024-02-03 19:56:07 +01:00
reverse ( " gymnast_details_tab " , args = ( new_note . gymnast . id , " event " ) )
2023-04-25 17:06:14 +02:00
)
2024-01-14 14:48:31 +01:00
return render ( request , " notes/create.html " , { " form " : form } )
last_note = (
Note . objects . filter ( gymnast = gymnast_id , status = 1 ) . order_by ( " -date " ) . first ( )
)
if last_note :
data [ " informations " ] = last_note . informations
2023-04-25 17:06:14 +02:00
form = NoteForm ( instance = note , initial = data )
context = { " form " : form , " note_id " : note_id }
return render ( request , " notes/create.html " , context )
@login_required
@require_http_methods ( [ " GET " , " POST " ] )
def chrono_create_or_update ( request , chrono_id = None , gymnast_id = None ) :
2023-05-14 19:10:34 +02:00
""" Création ou modification d ' un chrono
Args :
chrono_id ( int ) identifiant d ' un chrono
gymnast_id ( int ) identifiant d ' un gymnaste
"""
2023-04-25 17:06:14 +02:00
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 ( )
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-04-28 12:20:55 +02:00
functionality = ContentType . objects . get ( model = " chrono " )
2024-02-03 17:20:42 +01:00
for notification in new_chrono . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
receivers . append ( notification . user . email )
title = f " { new_chrono . gymnast } : Nouveau chrono "
html_message = f """ <p>Bonjour,</p><p>Nouveau chrono pour { new_chrono . gymnast } : { SCORE_TYPE_CHOICE [ new_chrono . score_type ] [ 1 ] } { CHRONO_TYPE_CHOICE [ new_chrono . chrono_type ] [ 1 ] } - { new_chrono . score } .</p> """
Email . objects . create (
receivers = receivers ,
title = title ,
body = html_message ,
2023-04-29 15:31:14 +02:00
)
2023-04-25 17:06:14 +02:00
2024-02-03 17:39:12 +01:00
send_mail (
title ,
f " { new_chrono . gymnast } a enregistrer un nouveau chrono ( { date } ) " ,
settings . EMAIL_HOST_USER ,
receivers ,
fail_silently = False ,
html_message = html_message + MAIL_FOOTER ,
)
2024-02-03 17:20:42 +01:00
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
reverse ( " gymnast_details_tab " , args = ( new_chrono . gymnast . id , " scores " ) )
)
2024-01-14 14:48:31 +01:00
return render ( request , " chronos/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
form = ChronoForm ( instance = chrono , initial = data )
context = { " form " : form , " chrono_id " : chrono_id }
return render ( request , " chronos/create.html " , context )
@login_required
@require_http_methods ( [ " POST " ] )
def gymnast_learn_skill ( request ) :
"""
Lie un gymnast à une figure .
"""
# utiliser un FORM pour cette fonction.
gymnast_id = request . POST . get ( " gymnast_id " , None )
skill_id = request . POST . get ( " skill_id " , None )
learning_step = request . POST . get ( " learning_step " , 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 ,
learning_step = learning_step ,
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.
2023-05-14 19:10:34 +02:00
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
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 ( ) :
2024-02-03 17:20:42 +01:00
learned_skill = form . save ( )
2023-04-25 17:06:14 +02:00
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-04-28 12:20:55 +02:00
functionality = ContentType . objects . get ( model = " learnedskill " )
for notification in gymnast . notifications . filter (
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
receivers . append ( notification . user . email )
title = f " { learned_skill . gymnast } : Nouveau skill appris "
html_message = f """ <p>Bonjour,</p><p> { learned_skill . gymnast } a appris { learned_skill . skill } ( { learned_skill . learning_step } ).</p> """
Email . objects . create (
receivers = receivers ,
title = title ,
body = html_message ,
2023-04-29 15:31:14 +02:00
)
2023-04-25 17:06:14 +02:00
2024-02-03 17:39:12 +01:00
send_mail (
title ,
f " { learned_skill . gymnast } a appris une nouvelle figure ( { date } ) " ,
settings . EMAIL_HOST_USER ,
receivers ,
fail_silently = False ,
html_message = html_message + MAIL_FOOTER ,
)
2024-02-03 17:20:42 +01:00
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
reverse ( " gymnast_details " , args = ( form . cleaned_data [ " gymnast " ] . id , ) )
)
2024-01-14 14:48:31 +01:00
2024-02-03 17:20:42 +01:00
return render ( request , " learnedskills/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
form = LearnedSkillForm ( initial = data )
context = { " form " : form , " gymnast_id " : gymnast_id }
return render ( request , " 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.
2023-05-14 19:10:34 +02:00
Args :
score_id ( int ) identifiant d ' un score
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
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 ( ) :
2024-02-03 17:20:42 +01:00
score = form . save ( )
2023-04-25 17:06:14 +02:00
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-04-28 12:20:55 +02:00
functionality = ContentType . objects . get ( model = " point " )
2024-02-03 17:20:42 +01:00
for notification in score . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
receivers . append ( notification . user . email )
title = f " { score . gymnast } : Nouveau score enregistré "
html_message = f """ <p>Bonjour,</p><p>Un nouveau score a été enregistré pour { score . gymnast } ( { score . event } ) : { score . routine_type } - { score . total } .</p> """
Email . objects . create (
receivers = receivers ,
title = title ,
body = html_message ,
2023-04-29 15:31:14 +02:00
)
2023-04-25 17:06:14 +02:00
2024-02-03 17:39:12 +01:00
send_mail (
title ,
f " { score . gymnast } a ajouté un nouveau score ( { date } ) " ,
settings . EMAIL_HOST_USER ,
receivers ,
fail_silently = False ,
html_message = html_message + MAIL_FOOTER ,
)
2024-02-03 17:20:42 +01:00
2023-04-25 17:06:14 +02:00
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 " ] . date_begin ,
)
new_chrono . save ( )
return HttpResponseRedirect (
reverse (
" gymnast_details_tab " ,
args = ( form . cleaned_data [ " gymnast " ] . id , " scores " ) ,
)
)
2024-01-14 14:48:31 +01:00
2024-02-03 17:20:42 +01:00
return render ( request , " scores/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
form = ScoreForm ( instance = score , initial = data )
context = { " form " : form , " score_id " : score_id }
return render ( request , " scores/create.html " , context )
@login_required
@require_http_methods ( [ " GET " ] )
def score_listing ( request , gymnast_id = None ) :
"""
Revoie la liste des scores
2023-05-14 19:10:34 +02:00
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
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 , " scores/list.html " , context )
@login_required
@require_http_methods ( [ " GET " ] )
2023-07-06 23:37:07 +02:00
def injuries_listing ( request ) :
2023-04-25 17:06:14 +02:00
"""
2023-07-06 23:37:07 +02:00
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.
2023-04-25 17:06:14 +02:00
Si c ' est un autre utilisateur (entraîneur), la liste peut répondre à un pattern si celui-ci est
définit .
"""
if request . user . groups . filter ( name = " trainer " ) . exists ( ) :
pattern = request . GET . get ( " pattern " , None )
if pattern :
2023-07-06 23:37:07 +02:00
injuries_list = Injury . objects . filter (
2023-04-25 17:06:14 +02:00
Q ( gymnast__last_name__icontains = pattern )
| Q ( gymnast__first_name__icontains = pattern )
)
else :
2023-07-06 23:37:07 +02:00
injuries_list = Injury . objects . all ( )
2023-04-25 17:06:14 +02:00
else :
2023-07-06 23:37:07 +02:00
injuries_list = Injury . objects . filter (
2023-04-25 17:06:14 +02:00
Q ( gymnast__last_name = request . user . last_name )
& Q ( gymnast__first_name = request . user . first_name )
)
2023-07-06 23:37:07 +02:00
context = { " injuries_list " : injuries_list }
return render ( request , " injuries/list.html " , context )
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " , " POST " ] )
2023-07-06 23:37:07 +02:00
def injury_create_or_update ( request , injury_id = None , gymnast_id = None ) :
2023-04-25 17:06:14 +02:00
"""
2023-07-06 23:37:07 +02:00
Formulaire de création d ' un nouvel blessure.
2023-05-14 19:10:34 +02:00
Args :
2023-07-06 23:37:07 +02:00
injury_id ( int ) identifiant d ' une blessure
2023-05-14 19:10:34 +02:00
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
2023-07-06 23:37:07 +02:00
if injury_id :
injury = get_object_or_404 ( Injury , pk = injury_id )
2023-04-25 17:06:14 +02:00
data = {
2023-07-06 23:37:07 +02:00
" gymnast_related " : injury . gymnast ,
" skill_related " : injury . skill ,
2023-04-25 17:06:14 +02:00
}
else :
2023-07-06 23:37:07 +02:00
injury = None
2023-04-25 17:06:14 +02:00
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 " :
2023-07-06 23:37:07 +02:00
form = InjuryForm ( request . POST , instance = injury )
2023-04-25 17:06:14 +02:00
if form . is_valid ( ) :
2023-07-06 23:37:07 +02:00
injury = form . save ( )
2023-04-25 17:06:14 +02:00
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-11-18 18:29:18 +01:00
date = form . cleaned_data [ " date " ]
2023-07-06 23:37:07 +02:00
functionality = ContentType . objects . get ( model = " injury " )
2024-02-03 17:20:42 +01:00
for notification in injury . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
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 )
2024-02-03 17:39:12 +01:00
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 ,
)
2023-04-25 17:06:14 +02:00
2023-07-06 23:37:07 +02:00
return HttpResponseRedirect ( reverse ( " injury_details " , args = ( injury . pk , ) ) )
2024-01-14 14:48:31 +01:00
return render ( request , " injuries/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
2023-07-06 23:37:07 +02:00
form = InjuryForm ( instance = injury , initial = data )
context = { " form " : form , " injury_id " : injury_id }
return render ( request , " injuries/create.html " , context )
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " ] )
2023-07-06 23:37:07 +02:00
def injury_detail ( request , injury_id ) :
2023-04-25 17:06:14 +02:00
"""
2023-07-06 23:37:07 +02:00
Récupère toutes les informations d ' une blessure.
2023-05-14 19:10:34 +02:00
Args :
2023-07-06 23:37:07 +02:00
injury_id ( int ) identifiant d ' une blessure
2023-04-25 17:06:14 +02:00
"""
2023-07-06 23:37:07 +02:00
injury = get_object_or_404 ( Injury , pk = injury_id )
return render ( request , " injuries/details.html " , { " injury " : injury } )
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " ] )
2023-07-05 09:33:03 +02:00
def wellbeing_listing ( request , gymnast_id = None ) :
2023-04-25 17:06:14 +02:00
"""
Récupère la liste des évaluations mentales suivant ( d ' un gymnaste si définit en paramètre).
2023-05-14 19:10:34 +02:00
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
gymnast = None
if gymnast_id :
2023-07-05 10:51:49 +02:00
wellbeing_list = WellBeing . objects . filter ( gymnast = gymnast_id )
2023-04-25 17:06:14 +02:00
gymnast = get_object_or_404 ( Gymnast , pk = gymnast_id )
else :
2023-07-05 10:51:49 +02:00
wellbeing_list = WellBeing . objects . all ( )
2023-04-25 17:06:14 +02:00
2023-07-05 09:33:03 +02:00
context = { " wellbeing_list " : wellbeing_list , " gymnast " : gymnast }
return render ( request , " wellbeing/list.html " , context )
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " , " POST " ] )
2023-07-05 09:33:03 +02:00
def wellbeing_create_or_update (
request , wellbeing_id = None , gymnast_id = None , event_id = None
2023-04-25 17:06:14 +02:00
) :
"""
2023-07-06 23:37:07 +02:00
Formulaire de création d ' une nouvelle blessure.
2023-05-14 19:10:34 +02:00
Args :
2023-07-06 23:37:07 +02:00
wellbeing_id ( int ) identifiant d ' une blessure
2023-05-14 19:10:34 +02:00
gymnast_id ( int ) identifiant d ' un gymnaste
event_id ( int ) identifiant d ' un événement
2023-04-25 17:06:14 +02:00
"""
2023-07-05 09:33:03 +02:00
if wellbeing_id :
2023-07-05 10:51:49 +02:00
wellbeing = get_object_or_404 ( WellBeing , pk = wellbeing_id )
2023-07-05 09:33:03 +02:00
data = { " gymnast_related " : wellbeing . gymnast , " event_related " : wellbeing . event }
2023-04-25 17:06:14 +02:00
else :
2023-07-05 09:33:03 +02:00
wellbeing = None
2023-04-25 17:06:14 +02:00
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 " :
2023-07-05 09:33:03 +02:00
form = WellBeingForm ( request . POST , instance = wellbeing )
2023-04-25 17:06:14 +02:00
if form . is_valid ( ) :
2023-07-05 09:33:03 +02:00
wellbeing = form . save ( )
2023-04-25 17:06:14 +02:00
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-05-11 10:51:10 +02:00
date = form . cleaned_data [ " date " ]
2023-07-05 10:51:49 +02:00
functionality = ContentType . objects . get ( model = " wellbeing " )
2024-02-03 17:20:42 +01:00
for notification in wellbeing . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
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 >
2023-07-05 09:33:03 +02:00
< ul >
2024-02-03 17:20:42 +01:00
< 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 >
2023-10-11 12:12:01 +02:00
< / ul >
2024-02-03 17:20:42 +01:00
{ wellbeing . details } """
Email . objects . create ( receivers = receivers , title = title , body = html_message )
2024-02-03 17:39:12 +01:00
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 ,
)
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
2023-07-05 09:33:03 +02:00
reverse ( " wellbeing_details " , args = ( wellbeing . pk , ) )
2023-04-25 17:06:14 +02:00
)
2024-01-14 14:48:31 +01:00
return render ( request , " wellbeing/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
2023-07-05 09:33:03 +02:00
form = WellBeingForm ( instance = wellbeing , initial = data )
context = { " form " : form , " wellbeing_id " : wellbeing_id }
return render ( request , " wellbeing/create.html " , context )
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " ] )
2023-07-05 09:33:03 +02:00
def wellbeing_detail ( request , wellbeing_id ) :
2023-04-25 17:06:14 +02:00
"""
Récupère toutes les informations d ' une évaluation psychologique.
2023-05-14 19:10:34 +02:00
Args :
2023-07-05 09:33:03 +02:00
wellbeing_id ( int ) identifiant d ' une évaluation psycho
2023-04-25 17:06:14 +02:00
"""
2023-07-05 10:51:49 +02:00
wellbeing = get_object_or_404 ( WellBeing , pk = wellbeing_id )
2023-07-05 09:33:03 +02:00
return render ( request , " wellbeing/details.html " , { " wellbeing " : wellbeing } )
2023-04-25 17:06:14 +02:00
@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).
2023-05-14 19:10:34 +02:00
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
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 , " 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.
2023-05-14 19:10:34 +02:00
Args :
2023-05-16 14:55:41 +02:00
heightweight_id ( int ) identifiant d ' un couple taille/couple
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
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 ( ) :
2024-02-03 17:20:42 +01:00
heightweight = form . save ( )
2023-04-25 17:06:14 +02:00
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-11-14 12:15:09 +01:00
date = form . cleaned_data [ " date " ]
2023-04-28 12:20:55 +02:00
functionality = ContentType . objects . get ( model = " heightweight " )
2024-02-03 17:20:42 +01:00
for notification in heightweight . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
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 >
2023-11-14 12:15:09 +01:00
< ul >
2024-02-03 17:20:42 +01:00
< li > Height : { heightweight . height } cm < / li >
< li > Weight : { heightweight . weight } kg < / li >
< li > BMI : { heightweight . bmi } < / li >
< / ul > """
Email . objects . create ( receivers = receivers , title = title , body = body )
2024-02-03 17:39:12 +01:00
send_mail (
title ,
f " Un nouveau poids/taille enregistré pour { heightweight . gymnast } ( { date } ) : { heightweight . height } cm / { heightweight . weight } kg (BMI: { heightweight . bmi } ). " , # pylint: disable=line-too-long
settings . EMAIL_HOST_USER ,
receivers ,
fail_silently = False ,
html_message = body + { MAIL_FOOTER } ,
)
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
reverse (
" gymnast_details_tab " ,
args = ( form . cleaned_data [ " gymnast " ] . id , " physiological " ) ,
)
)
2024-01-14 14:48:31 +01:00
return render ( request , " heightweight/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
form = HeightWeightForm ( instance = heightweight , initial = data )
context = {
" form " : form ,
" gymnast_id " : gymnast_id ,
" heightweight_id " : heightweight_id ,
}
return render ( request , " 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
2023-05-14 19:10:34 +02:00
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
2023-04-25 17:06:14 +02:00
"""
if gymnast_id :
gymnast = get_object_or_404 ( Gymnast , pk = gymnast_id )
routine_done_list = gymnast . number_of_routine_done . all ( )
else :
gymnast = None
routine_done_list = NumberOfRoutineDone . objects . all ( )
context = { " routine_done_list " : routine_done_list , " gymnast " : gymnast }
return render ( request , " 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
"""
data = {
" gymnast " : get_object_or_404 ( Gymnast , pk = request . POST . get ( " gymnast_id " , None ) ) ,
" routine_type " : request . POST . get ( " routine_type " , 1 ) ,
" date " : request . POST . get ( " date " , date . today ( ) ) ,
}
routine = (
data [ " gymnast " ]
. has_routine . filter ( routine_type = request . POST . get ( " routine_type " , 1 ) )
. first ( )
)
data [ " routine " ] = routine . routine
routinedone , _ = NumberOfRoutineDone . objects . get_or_create (
date = data [ " date " ] , gymnast = data [ " gymnast " ] , routine_type = data [ " routine_type " ]
)
data [ " number_of_try " ] = routinedone . number_of_try + 1
success = request . POST . get ( " success " , 0 )
if int ( success ) == 1 :
data [ " number_of_successes " ] = routinedone . number_of_successes + 1
else :
data [ " number_of_successes " ] = routinedone . number_of_successes
form = NumberOfRoutineDoneForm ( data , instance = routinedone )
if form . is_valid ( ) :
form . save ( )
return HttpResponse ( status = 200 )
2024-01-14 14:48:31 +01:00
return HttpResponse ( status = 406 )
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " , " POST " ] )
def routinedone_create_or_update ( request , routinedone_id = None , gymnast_id = None ) :
2023-05-14 19:10:34 +02:00
""" Création ou modification d ' un nombre de série tentée.
Args :
routinedone_id ( int ) identifiant d ' une routinedone
gymnast_id ( int ) identifiant d ' un gymnaste
"""
2023-04-25 17:06:14 +02:00
if routinedone_id :
routinedone = get_object_or_404 ( NumberOfRoutineDone , pk = routinedone_id )
data = {
" gymnast " : routinedone . gymnast . id ,
" gymnast_related " : str ( routinedone . gymnast ) ,
}
if routinedone . routine :
data [ " routine " ] = routinedone . routine . id
data [ " routine_related " ] = str ( routinedone . routine )
else :
routine = (
GymnastHasRoutine . objects . filter ( gymnast = routinedone . gymnast )
. filter ( routine_type = routinedone . routine_type )
. filter ( date_begin__lte = routinedone . date )
. filter ( Q ( date_end__gte = routinedone . date ) | Q ( date_end__isnull = True ) )
. first ( )
)
if routine :
data [ " routine " ] = routine . id
data [ " routine_related " ] = str ( routine )
else :
data = None
routinedone = 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 ( ) :
2024-02-03 17:20:42 +01:00
routine_done = form . save ( )
2023-04-25 17:06:14 +02:00
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-04-25 17:06:14 +02:00
gymnast = Gymnast . objects . get ( pk = form . cleaned_data [ " gymnast " ] . id )
2023-04-28 12:20:55 +02:00
functionality = ContentType . objects . get ( model = " numberofroutinedone " )
2024-02-03 17:20:42 +01:00
for notification in routine_done . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
receivers . append ( notification . user . email )
title = f " { routine_done . gymnast } : Nouvelle série comptabilisée "
body = f """ <p>Bonjour,</p>
< p > Nouvelle série comptabilisée pour { routine_done . gymnast } . < / p > """
Email . objects . create ( receivers = receivers , title = title , body = body )
2024-02-03 17:39:12 +01:00
send_mail (
title ,
f " Nouvelle série comptabilisée pour { routine_done . gymnast } " ,
settings . EMAIL_HOST_USER ,
receivers ,
fail_silently = False ,
html_message = body + { MAIL_FOOTER } ,
)
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
reverse (
" gymnast_details_tab " ,
args = ( form . cleaned_data [ " gymnast " ] . id , " routine " ) ,
)
)
2024-01-14 14:48:31 +01:00
return render ( request , " routinedone/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
form = NumberOfRoutineDoneForm ( instance = routinedone , initial = data )
context = { " form " : form , " routinedone_id " : routinedone_id }
return render ( request , " 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 :
2023-05-14 19:10:34 +02:00
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>).
2023-04-25 17:06:14 +02:00
"""
if plan_id :
plan = get_object_or_404 ( Plan , pk = plan_id )
data = {
" gymnast " : plan . gymnast . id ,
" gymnast_related " : str ( plan . gymnast ) ,
" educative " : plan . educative . id ,
" educative_related " : str ( plan . educative ) ,
}
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 ( )
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-06-13 14:35:29 +02:00
date = form . cleaned_data [ " date " ]
2023-04-28 12:20:55 +02:00
functionality = ContentType . objects . get ( model = " plan " )
2024-02-03 17:20:42 +01:00
for notification in plan . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
receivers . append ( notification . user . email )
title = f " { plan . gymnast } : Nouvel objectif fixé "
body = f """ <p>Bonjour,</p>
< p > Nouvel objectif fixé pour { plan . gymnast } : { plan . educative } ( { plan . learning_step } ) pour le { date . strftime ( ' %d % B % Y ' ) } au plus tard . < / p > """
Email . objects . create ( receivers = receivers , title = title , body = body )
2024-02-03 17:39:12 +01:00
send_mail (
title ,
f " Nouvel objectif fixé pour { gymnast } " ,
settings . EMAIL_HOST_USER ,
receivers ,
fail_silently = False ,
html_message = body + { MAIL_FOOTER } ,
)
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
reverse ( " gymnast_details " , args = ( form . cleaned_data [ " gymnast " ] . id , ) )
)
2024-01-14 14:48:31 +01:00
return render ( request , " plan/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
form = PlanForm ( instance = plan , initial = data )
context = { " form " : form , " plan_id " : plan_id }
return render ( request , " plan/create.html " , context )
2023-11-12 19:22:52 +01:00
@login_required
@require_http_methods ( [ " GET " ] )
def intensity_details ( request , intensity_id ) :
"""
Récupère toutes les informations d ' une intensité.
Args :
intensity_id ( int ) identifiant d ' une intensité
"""
intensity = get_object_or_404 ( Intensity , pk = intensity_id )
return render ( request , " intensities/details.html " , { " intensity " : intensity } )
2023-04-25 17:06:14 +02:00
@login_required
@require_http_methods ( [ " GET " ] )
def intensity_listing ( request , gymnast_id = None ) :
"""
Si la personne connectée est un entraîneur , la fonction récupère la liste des intensités d ' un
gymnaste précis ou de tout le monde .
Si la personne connectée est un gymnaste , la fonction récupère la liste de ses intensités à
lui / elle .
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
"""
gymnast = None
if request . user . groups . filter ( name = " trainer " ) . exists ( ) :
if gymnast_id :
intensity_list = Intensity . objects . filter ( gymnast = gymnast_id )
gymnast = Gymnast . objects . get ( pk = gymnast_id )
else :
intensity_list = Intensity . objects . all ( )
else :
intensity_list = Intensity . objects . filter (
Q ( gymnast__last_name = request . user . last_name )
& Q ( gymnast__first_name = request . user . first_name )
)
context = { " intensity_list " : intensity_list , " gymnast " : gymnast }
return render ( request , " intensities/list.html " , context )
@login_required
@require_http_methods ( [ " GET " , " POST " ] )
def intensity_create_or_update ( request , intensity_id = None , gymnast_id = None ) :
""" Création d ' un record de la class Intentity.
Args :
2023-05-15 13:58:02 +02:00
intensity_id ( int ) identifiant d ' une intensité (classe <Intensity>).
gymnast_id ( int ) identifiant d ' un gymnaste (classe <Gymnast>).
2023-04-25 17:06:14 +02:00
"""
if intensity_id :
intensity = get_object_or_404 ( Intensity , pk = intensity_id )
data = {
" gymnast " : intensity . gymnast . id ,
" gymnast_related " : str ( intensity . gymnast ) ,
}
else :
intensity = None
data = { }
if gymnast_id :
gymnast = get_object_or_404 ( Gymnast , pk = gymnast_id )
data [ " gymnast " ] = gymnast_id
data [ " gymnast_related " ] = str ( gymnast )
if request . method == " POST " :
form = IntensityForm ( request . POST , instance = intensity )
if form . is_valid ( ) :
intensity = form . save ( )
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-05-15 13:58:02 +02:00
date = form . cleaned_data [ " date " ]
2023-04-28 12:20:55 +02:00
functionality = ContentType . objects . get ( model = " intensity " )
2024-02-03 17:20:42 +01:00
for notification in intensity . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
receivers . append ( notification . user . email )
2024-02-03 18:51:57 +01:00
title = f " { intensity . gymnast } : Nouvelle intensité "
body = f """ <p>Bonjour,</p><p> { intensity . gymnast } a encodé une nouvelle intensité pour le { date . strftime ( ' %d % B % Y ' ) } :</p>
< ul >
< li > { intensity . number_of_passes } passages < / li >
< li > { intensity . time } minutes < / li >
< li > { intensity . quantity_of_skill } figures < / li >
< li > { intensity . difficulty_in_unit } difficulty < / li >
< / ul >
< p > < u > Quality : < / u > < / p >
< ul >
< li > Time : { intensity . time_quality : .1 f } % < / li >
< li > Diff : { intensity . difficulty_quality : .1 f } % < / li >
< li > Skill : { intensity . quantity_of_skill_quality : .1 f } % < / li >
< li > Passe : { intensity . number_of_passes_quality : .1 f } % < / li >
< li > < b > Passe : { intensity . average_quality : .2 f } % < / b > < / li >
< / ul >
< p > < u > Statistics : < / u > < / p >
< ul >
< li > Passe / time : { intensity . mean_time_by_passe : .2 f } min < / li >
< li > Skill / time : { intensity . mean_quantity_of_skill_by_time : .2 f } min < / li >
< li > Skill / passe : { intensity . mean_quantity_of_skill_by_passe : .2 f } < / li >
< li > Diff / passe : { intensity . mean_difficulty_by_passe : .2 f } < / li >
< li > Diff / skill : { intensity . mean_difficulty_by_skill : .2 f } < / li >
< / ul > """
2024-02-03 17:20:42 +01:00
Email . objects . create (
receivers = receivers ,
2024-02-03 18:51:57 +01:00
title = title ,
body = body ,
)
2024-02-03 19:56:07 +01:00
# send_mail(
# title,
# f"Une nouvelle information de saison enregistrée pour {intensity.gymnast}",
# settings.EMAIL_HOST_USER,
# receivers,
# fail_silently=False,
# html_message=body + {MAIL_FOOTER},
# )
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
reverse (
2024-02-03 19:56:07 +01:00
" intensity_details " ,
args = ( intensity . id , ) ,
2023-04-25 17:06:14 +02:00
)
)
2024-01-14 14:48:31 +01:00
return render ( request , " intensities/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
form = IntensityForm ( instance = intensity , initial = data )
context = { " form " : form , " intensity_id " : intensity_id }
return render ( request , " intensities/create.html " , context )
@login_required
@require_http_methods ( [ " GET " , " POST " ] )
def season_information_create_or_update (
request , season_information_id = None , gymnast_id = None
) :
""" Création d ' un record de la class Intentity.
Args :
season_information_id ( int ) : identifiant d ' un plan (classe <SeasonInformation>).
gymnast_id ( int ) : identifiant d ' un gymnaste (classe <Gymnast>).
"""
if season_information_id :
season_information = get_object_or_404 (
SeasonInformation , pk = season_information_id
)
data = {
" gymnast " : season_information . gymnast . id ,
" gymnast_related " : str ( season_information . gymnast ) ,
" club " : season_information . club . id ,
" club_related " : str ( season_information . club ) ,
}
else :
season_information = None
data = { }
if gymnast_id :
gymnast = get_object_or_404 ( Gymnast , pk = gymnast_id )
data [ " gymnast " ] = gymnast_id
data [ " gymnast_related " ] = str ( gymnast )
if request . method == " POST " :
form = SeasonInformationForm ( request . POST , instance = season_information )
if form . is_valid ( ) :
season_information = form . save ( )
# notification
2024-02-03 17:20:42 +01:00
receivers = [ ]
2023-04-28 12:20:55 +02:00
functionality = ContentType . objects . get ( model = " seasoninformation " )
2024-02-03 17:20:42 +01:00
for notification in season_information . gymnast . notifications . filter (
2023-04-28 12:20:55 +02:00
functionality = functionality
) :
2024-02-03 17:20:42 +01:00
receivers . append ( notification . user . email )
title = f " { season_information . gymnast } : Nouvelle information de saison "
body = f """ <p>Bonjour,</p>
< p > Une nouvelle information de saison enregistrée pour { gymnast } . < / p > """
Email . objects . create ( receivers = receivers , title = title , body = body )
2024-02-03 17:39:12 +01:00
send_mail (
title ,
f " Une nouvelle information de saison enregistrée pour { gymnast } " ,
settings . EMAIL_HOST_USER ,
receivers ,
fail_silently = False ,
html_message = body + { MAIL_FOOTER } ,
)
2023-04-25 17:06:14 +02:00
return HttpResponseRedirect (
reverse (
" gymnast_details " ,
args = ( form . cleaned_data [ " gymnast " ] . id , ) ,
)
)
2024-01-14 14:48:31 +01:00
return render ( request , " seasoninformations/create.html " , { " form " : form } )
2023-04-25 17:06:14 +02:00
form = SeasonInformationForm ( instance = season_information , initial = data )
context = { " form " : form , " season_information_id " : season_information_id }
return render ( request , " seasoninformations/create.html " , context )
@login_required
@require_http_methods ( [ " GET " ] )
def season_information_listing ( request , gymnast_id = None ) :
2023-05-14 19:10:34 +02:00
""" Liste toutes les informations de saison pour un gymnaste.
Args :
gymnast_id ( int ) identifiant d ' un gymnaste
"""
2023-04-25 17:06:14 +02:00
if gymnast_id is not None :
gymnast = Gymnast . objects . get ( pk = gymnast_id )
season_information_list = SeasonInformation . objects . filter ( gymnast = gymnast_id )
else :
season_information_list = SeasonInformation . objects . all ( )
context = { " season_information_list " : season_information_list , " gymnast " : gymnast }
return render ( request , " seasoninformations/list.html " , context )