2022-09-22 12:45:02 +02:00
import locale
2022-09-27 08:24:01 +02:00
import os
import re
from datetime import date , datetime , timedelta
from statistics import mean
2022-09-22 12:45:02 +02:00
2022-09-27 08:24:01 +02:00
import pendulum
import yaml
from django . conf import settings
2022-10-12 09:55:01 +02:00
from django . db . models import F , Max , Q
2022-09-28 11:47:47 +02:00
2022-09-22 12:45:02 +02:00
from PIL import Image
2022-09-27 08:24:01 +02:00
from reportlab . lib import colors
from reportlab . lib . pagesizes import A4
from reportlab . lib . styles import getSampleStyleSheet
from reportlab . lib . units import cm
from reportlab . pdfgen . canvas import Canvas
from reportlab . platypus import Paragraph , Table , TableStyle
2022-10-12 09:55:01 +02:00
from ultron . followup . models import (
2022-10-14 10:35:40 +02:00
Plan ,
Point ,
2022-10-12 09:55:01 +02:00
Chrono ,
2022-10-14 10:35:40 +02:00
Accident ,
2022-10-12 09:55:01 +02:00
MindState ,
2022-10-14 10:35:40 +02:00
HeightWeight ,
LearnedSkill ,
2022-10-12 09:55:01 +02:00
)
2022-10-12 17:05:43 +02:00
from ultron . followup . models import LEARNING_STEP_CHOICES
2022-09-27 08:24:01 +02:00
from ultron . objective . models import Skill
2022-09-22 12:45:02 +02:00
from ultron . people . models import Gymnast
2022-09-27 08:24:01 +02:00
from ultron . planning . models import Event
2022-09-22 12:45:02 +02:00
2022-10-06 13:44:49 +02:00
from . date_week_transition import from_date_to_week_number
2022-09-22 12:45:02 +02:00
2022-09-30 12:05:57 +02:00
import environ
from pathlib import Path
# Initialise environment variables
env = environ . Env ( )
environ . Env . read_env ( )
2022-09-22 12:45:02 +02:00
# EXPENSES = 0
# RECETTES = 1
X = 35
Y = 841.89
INDENT = 5
RIGHT_X = 595.27 - X
TITLED_X = 125
INDENTED_X = X + INDENT
INDENTED_RIGHT_X = RIGHT_X - INDENT
MIDDLE = ( RIGHT_X - X ) / 2
PRESTATION_COLUMN_2 = INDENTED_X + 65
PRESTATION_COLUMN_3 = INDENTED_X + 400
PRESTATION_COLUMN_4 = INDENTED_X + 455
COMMON_LINE_HEIGHT = - 15
SMALL_LINE_HEIGHT = COMMON_LINE_HEIGHT + 5
LARGE_LINE_HEIGHT = COMMON_LINE_HEIGHT - 5
DOUBLE_LINE_HEIGHT = COMMON_LINE_HEIGHT * 2
BIG_LINE_HEIGHT = COMMON_LINE_HEIGHT * 3
HUGE_LINE_HEIGHT = COMMON_LINE_HEIGHT * 4
class PDFDocument ( object ) :
# Create the PDF object, using the response object as its "file."
# http://www.reportlab.com/docs/reportlab-userguide.pdf
# canvas.rect(x, y, width, height, stroke=1, fill=0)
# localhost:8000/billing/contract/pdf/2
def __init__ ( self , response ) :
# Create the PDF object, using the response object as its "file."
2022-09-23 16:02:20 +02:00
self . document = Canvas ( response , pagesize = A4 )
2022-09-22 12:45:02 +02:00
self . y = Y - X
2022-09-27 08:24:01 +02:00
self . styles = getSampleStyleSheet ( )
self . style = self . styles [ " Normal " ]
2022-09-22 12:45:02 +02:00
2022-09-30 12:05:57 +02:00
self . site_title = env ( " SITE_TITLE " , default = None )
self . club_name = env ( " CLUB_NAME " , default = None )
self . address = env ( " ADDRESS " , default = None )
self . city = env ( " CITY " , default = None )
self . zip = env ( " ZIP " , default = None )
self . head_coach = env ( " HEAD_COACH " , default = None )
self . mobile_phone = env ( " MOBILE_PHONE " , default = None )
2022-10-01 07:10:25 +02:00
self . coach_email = env ( " HEAD_COACH_EMAIL " , default = None )
2022-09-22 12:45:02 +02:00
def add_vspace ( self , height = COMMON_LINE_HEIGHT ) :
""" Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
Args :
height ( int ) : hauteur de la ligne .
Returns :
ne retourne rien .
"""
self . y + = height
2022-09-30 11:36:03 +02:00
# print(self.y)
2022-09-22 12:45:02 +02:00
# if y < 120;
# document.PageBreak()
# y = 790
def add_string (
self , x , string , font_family = " Helvetica " , font_decoration = None , font_size = 10
) :
if font_decoration :
font_family + = " - " + font_decoration
self . document . setFont ( font_family , font_size )
self . document . drawString ( x , self . y , string )
def add_new_line (
self ,
x ,
string ,
height = COMMON_LINE_HEIGHT ,
font_family = " Helvetica " ,
font_decoration = None ,
font_size = 10 ,
) :
self . add_vspace ( height )
self . add_string ( x , string , font_family , font_decoration , font_size )
def add_header ( self , contract = None ) :
""" Génère le header du document.
Args :
contract ( contract ) : instance de la class Contract .
Returns :
ne retourne rien .
"""
2022-09-23 16:02:20 +02:00
self . document . setFillColorRGB ( 0.75 , 0.75 , 0.75 )
2022-09-27 08:24:01 +02:00
self . add_vspace ( 15 )
2022-09-30 12:05:57 +02:00
self . add_new_line ( X , self . site_title + ' - ' + self . club_name )
2022-09-22 12:45:02 +02:00
self . document . drawRightString (
2022-09-23 16:02:20 +02:00
RIGHT_X ,
2022-09-22 12:45:02 +02:00
self . y ,
2022-09-30 12:05:57 +02:00
self . address
2022-09-22 12:45:02 +02:00
+ " - "
2022-09-30 12:05:57 +02:00
+ self . zip
2022-09-22 12:45:02 +02:00
+ " "
2022-09-30 12:05:57 +02:00
+ self . city ,
2022-09-23 16:02:20 +02:00
)
2022-09-27 08:24:01 +02:00
2022-09-23 16:02:20 +02:00
self . add_new_line (
X ,
" Head Coach : "
2022-09-30 12:05:57 +02:00
+ self . head_coach
2022-09-22 12:45:02 +02:00
)
self . document . drawRightString (
2022-09-23 16:02:20 +02:00
RIGHT_X ,
2022-09-22 12:45:02 +02:00
self . y ,
2022-10-01 07:10:25 +02:00
self . coach_email
2022-09-22 12:45:02 +02:00
)
2022-09-27 08:24:01 +02:00
today = pendulum . now ( ) . date ( )
2022-10-01 07:10:25 +02:00
self . add_new_line ( X , today . strftime ( " %d % B % Y " ) )
2022-09-27 08:24:01 +02:00
begin_season = date ( today . year , 9 , 1 )
2022-10-07 14:56:31 +02:00
season , week_number = from_date_to_week_number ( )
self . document . drawRightString ( RIGHT_X , self . y , " Season " + season + " - week " + str ( week_number ) )
2022-09-27 08:24:01 +02:00
2022-09-23 16:02:20 +02:00
self . document . setFillColorRGB ( 0 , 0 , 0 )
2022-09-22 12:45:02 +02:00
self . add_vspace ( BIG_LINE_HEIGHT )
def download ( self ) :
# Close the PDF object cleanly, and we're done.
self . document . showPage ( )
self . document . save ( )
class GymnastReportDocument ( PDFDocument ) :
def generate ( self , gymnast_id ) :
""" Genère un document aux normes du SPF Finance.
Args :
accounting_year ( int ) : année comptable .
Returns :
ne retourne rien .
"""
gymnast = Gymnast . objects . get ( pk = gymnast_id )
self . document . setTitle ( gymnast . first_name + ' ' + gymnast . last_name )
self . add_header ( )
self . add_gymnast_personnal_information ( gymnast )
self . add_gymnast_physiological_information ( gymnast )
self . add_gymnast_best_scores ( gymnast )
2022-09-23 16:02:20 +02:00
self . add_gymnast_active_routine ( gymnast )
# self.add_gymnast_level_information(gymnast)
2022-09-22 12:45:02 +02:00
self . add_gymnast_next_skills ( gymnast )
2022-10-14 10:35:40 +02:00
self . add_gymnast_last_learned_skill ( gymnast )
2022-09-27 08:24:01 +02:00
self . add_gymnast_next_events ( gymnast )
self . add_gymnast_week_notes ( gymnast )
2022-09-22 12:45:02 +02:00
def add_gymnast_personnal_information ( self , gymnast ) :
""" Ajoute les informations personnelles du gymnast.
Args :
gymnast < Gymnast > : gymnaste
Returns :
ne retourne rien .
"""
2022-09-23 16:02:20 +02:00
self . y = 26 * cm
url = os . path . join ( settings . STATICFILES_DIRS [ 0 ] , " img/default-avatar.png " )
self . document . drawImage ( url , X , self . y - 65 , width = 80 , height = 80 )
2022-09-22 12:45:02 +02:00
self . add_string (
2022-09-23 16:02:20 +02:00
130 ,
2022-09-22 12:45:02 +02:00
str ( gymnast ) ,
font_decoration = " Bold " ,
2022-09-23 16:02:20 +02:00
font_size = 14 ,
2022-09-22 12:45:02 +02:00
)
2022-10-04 11:38:25 +02:00
2022-09-23 16:02:20 +02:00
self . document . setFillColorRGB ( 0.75 , 0.75 , 0.75 )
2022-09-22 12:45:02 +02:00
self . add_new_line (
2022-09-23 16:02:20 +02:00
130 ,
2022-09-22 12:45:02 +02:00
str ( gymnast . age )
)
2022-09-23 16:02:20 +02:00
self . document . setFillColorRGB ( 0 , 0 , 0 )
2022-10-05 10:38:23 +02:00
if gymnast . informations :
self . add_new_line (
130 ,
str ( gymnast . informations )
)
2022-09-23 16:02:20 +02:00
def analyse_score ( self , value , value_list ) :
""" Analyse une value (value) par rapport à la moyenne de value_list et à la dernière
valeur de value_list
Args :
2022-09-30 21:33:16 +02:00
value float valeur
value_list array < float > liste de valeurs
2022-09-23 16:02:20 +02:00
Returns :
string
Examples :
"""
res = ' '
mean_value = mean ( value_list )
if value > value_list [ - 1 ] :
res + = ' + '
elif value < value_list [ - 1 ] :
res + = ' - '
else :
res + = ' = '
if value > mean_value :
res = ' + ' + res
elif value < mean_value :
res = ' - ' + res
else :
res = ' = ' + res
return res
2022-09-22 12:45:02 +02:00
def add_gymnast_physiological_information ( self , gymnast ) :
""" Ajoute les informations physique et psychologique.
Args :
gymnast < Gymnast > : gymnaste
Returns :
ne retourne rien
"""
2022-09-23 16:02:20 +02:00
self . y = 26 * cm
self . add_new_line (
13.5 * cm ,
" Physics/Mind state " ,
font_decoration = " Bold " ,
)
2022-09-22 12:45:02 +02:00
2022-09-23 16:02:20 +02:00
data = [ ]
mindstate_queryset = MindState . objects . filter ( gymnast = gymnast ) . order_by ( ' -date ' )
last_mindstate = mindstate_queryset . first ( )
lasts_mindstate = list ( mindstate_queryset . values_list ( " score " , flat = True ) [ 1 : 6 ] )
2022-09-30 15:56:58 +02:00
have_physiological = False
if lasts_mindstate :
res = self . analyse_score ( last_mindstate . score , lasts_mindstate )
data . append ( [ " Mind state " , str ( last_mindstate . score ) , res ] )
have_physiological = True
2022-09-23 16:02:20 +02:00
height_weight_queryset = HeightWeight . objects . filter ( gymnast = gymnast ) . order_by ( ' -date ' )
last_height_weigth = height_weight_queryset . first ( )
lasts_height = list ( height_weight_queryset . values_list ( " height " , flat = True ) [ 1 : 6 ] )
lasts_weight = list ( height_weight_queryset . values_list ( " weight " , flat = True ) [ 1 : 6 ] )
2022-09-30 15:56:58 +02:00
if lasts_height :
res = self . analyse_score ( last_height_weigth . height , lasts_height )
data . append ( [ " Height " , str ( last_height_weigth . height ) , res ] )
have_physiological = True
2022-09-23 16:02:20 +02:00
2022-09-30 15:56:58 +02:00
if lasts_weight :
res = self . analyse_score ( last_height_weigth . weight , lasts_weight )
data . append ( [ " Weight " , str ( last_height_weigth . weight ) , res ] )
have_physiological = True
2022-09-23 16:02:20 +02:00
2022-09-30 15:56:58 +02:00
if have_physiological :
style = TableStyle (
[
( ' ALIGN ' , ( 1 , 0 ) , ( - 1 , - 1 ) , ' RIGHT ' ) ,
# ('GRID', (0,0), (-1,-1), 0.25, colors.black),
# ('BOX', (0,0), (-1,-1), 0.25, colors.black),
]
)
table = Table ( data , [ 2 * cm , 1.5 * cm , 1.5 * cm ] )
table . setStyle ( style )
width , height = table . wrapOn ( self . document , 19 * cm , 15.5 * cm )
table . drawOn ( self . document , 13.3 * cm , self . y - height - 5 )
2022-09-30 21:33:16 +02:00
else :
self . add_new_line (
13.5 * cm ,
" No recorded data. " ,
)
2022-09-23 16:02:20 +02:00
2022-09-22 12:45:02 +02:00
def add_gymnast_best_scores ( self , gymnast ) :
""" Ajoute les meilleurs scores du gymnaste (Tof, compétition, …).
Args :
gymnast < Gymnast > : gymnaste
Returns :
ne retourne rien
"""
2022-09-23 16:02:20 +02:00
self . y = 23 * cm
self . add_new_line (
X ,
" Best ToF " ,
font_decoration = " Bold " ,
)
2022-09-30 12:08:49 +02:00
2022-09-30 15:56:58 +02:00
has_score = False
2022-10-04 11:24:23 +02:00
data = [ ]
2022-09-22 12:45:02 +02:00
best_tof = (
Chrono . objects . filter ( gymnast = gymnast )
. filter ( chrono_type = 0 )
. order_by ( " -score " )
. first ( )
)
2022-09-30 12:08:49 +02:00
if best_tof :
2022-10-04 11:24:23 +02:00
data . append ( [ " ToF |: " , str ( best_tof . tof ) , str ( best_tof . score ) , " ( " + best_tof . date . strftime ( " %d - % m- % Y " ) + " ) " ] )
2022-09-30 15:56:58 +02:00
has_score = True
2022-09-30 12:08:49 +02:00
2022-09-22 12:45:02 +02:00
best_tof = (
Chrono . objects . filter ( gymnast = gymnast )
. filter ( chrono_type = 1 )
. order_by ( " -score " )
. first ( )
)
2022-09-30 12:08:49 +02:00
if best_tof :
data . append ( [ " ToF R1: " , str ( best_tof . tof ) , str ( best_tof . score ) , " ( " + best_tof . date . strftime ( " %d - % m- % Y " ) + " ) " ] )
2022-09-30 15:56:58 +02:00
has_score = True
2022-09-30 12:08:49 +02:00
2022-09-22 12:45:02 +02:00
best_tof = (
Chrono . objects . filter ( gymnast = gymnast )
. filter ( chrono_type = 2 )
. order_by ( " -score " )
. first ( )
)
2022-09-30 12:08:49 +02:00
if best_tof :
data . append ( [ " ToF R2: " , str ( best_tof . tof ) , str ( best_tof . score ) , " ( " + best_tof . date . strftime ( " %d - % m- % Y " ) + " ) " ] )
2022-09-30 15:56:58 +02:00
has_score = True
2022-09-22 12:45:02 +02:00
2022-09-30 15:56:58 +02:00
if has_score :
style = TableStyle (
[
( ' TEXTCOLOR ' , ( - 1 , 0 ) , ( - 1 , - 1 ) , ' #AAAAAA ' ) ,
]
)
table = Table ( data )
table . setStyle ( style )
width , height = table . wrapOn ( self . document , 19 * cm , 15 * cm )
table . drawOn ( self . document , X - 6 , self . y - height - 5 )
else :
self . add_new_line (
2022-10-04 11:38:25 +02:00
X ,
" No chrono for this gymnast. " ,
)
2022-09-30 15:56:58 +02:00
2022-09-23 16:02:20 +02:00
self . y = 20 * cm
self . add_new_line (
X ,
" Best Scores " ,
font_decoration = " Bold " ,
)
2022-09-22 12:45:02 +02:00
2022-09-30 15:56:58 +02:00
has_score = False
2022-09-23 16:02:20 +02:00
data = [ [ " " , " Exe. " , " Diff. " , " ToF " , " HD " , " Tot. " , " " ] ]
best_point_routine_1 = Point . objects . filter ( gymnast = gymnast ) . filter ( routine_type = 1 ) . order_by ( ' -total ' ) . first ( )
if best_point_routine_1 :
data . append (
[
" R1: " ,
best_point_routine_1 . point_execution ,
best_point_routine_1 . point_difficulty ,
best_point_routine_1 . point_time_of_flight ,
best_point_routine_1 . point_horizontal_displacement ,
best_point_routine_1 . total ,
best_point_routine_1 . event . date_begin . strftime ( " %d - % m- % Y " ) ,
]
)
2022-09-30 15:56:58 +02:00
has_score = True
2022-09-27 08:24:01 +02:00
2022-09-23 16:02:20 +02:00
best_point_routine_2 = Point . objects . filter ( gymnast = gymnast ) . filter ( routine_type = 2 ) . order_by ( ' -total ' ) . first ( )
if best_point_routine_2 :
data . append (
[
" R2 : " ,
best_point_routine_2 . point_execution ,
best_point_routine_2 . point_difficulty ,
best_point_routine_2 . point_time_of_flight ,
best_point_routine_2 . point_horizontal_displacement ,
best_point_routine_2 . total ,
best_point_routine_2 . event . date_begin . strftime ( " %d - % m- % Y " ) ,
]
)
2022-09-30 15:56:58 +02:00
has_score = True
2022-09-23 16:02:20 +02:00
else :
data . append (
[
" R2: " ,
" - " ,
" - " ,
" - " ,
" - " ,
" - " ,
]
)
2022-09-22 12:45:02 +02:00
2022-09-30 15:56:58 +02:00
if has_score :
style = TableStyle (
[
( ' ALIGN ' , ( 0 , 0 ) , ( - 1 , 0 ) , ' CENTER ' ) ,
( ' ALIGN ' , ( 1 , 1 ) , ( - 1 , - 1 ) , ' RIGHT ' ) ,
( ' TEXTCOLOR ' , ( - 1 , 0 ) , ( - 1 , - 1 ) , ' #AAAAAA ' ) ,
# ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
# ('LINEABOVE', (0,-1), (-1,-1), 0.25, colors.black),
]
)
table = Table ( data )
table . setStyle ( style )
width , height = table . wrapOn ( self . document , 19 * cm , 15 * cm )
table . drawOn ( self . document , X - 6 , self . y - height - 5 )
else :
self . add_new_line (
2022-10-04 11:38:25 +02:00
X ,
" No scores for this gymnast. " ,
)
2022-09-22 12:45:02 +02:00
2022-09-23 16:02:20 +02:00
self . add_vspace ( HUGE_LINE_HEIGHT )
def add_gymnast_active_routine ( self , gymnast ) :
""" Ajoute les routines actives """
self . y = 23 * cm
self . add_new_line (
15.9 * cm ,
" Routines " ,
font_decoration = " Bold " ,
)
2022-09-30 12:12:46 +02:00
2022-09-23 16:02:20 +02:00
routine_1 = gymnast . has_routine . filter ( routine_type = 1 ) . filter ( date_begin__lte = date . today ( ) ) . filter ( Q ( date_end__gte = date . today ( ) ) | Q ( date_end__isnull = True ) ) . first ( )
2022-09-30 12:12:46 +02:00
if routine_1 :
data = [ ]
for routine_skill in routine_1 . routine . skill_links . all ( ) :
data . append ( [ routine_skill . skill . notation , routine_skill . skill . difficulty ] )
data . append ( [ None , routine_1 . routine . difficulty ] )
style = TableStyle (
[
( ' ALIGN ' , ( 1 , 0 ) , ( 1 , - 1 ) , ' RIGHT ' ) ,
# ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
( ' LINEABOVE ' , ( 0 , - 1 ) , ( - 1 , - 1 ) , 0.25 , colors . black ) ,
]
)
table = Table ( data , [ 2 * cm , 1 * cm ] )
table . setStyle ( style )
width , height = table . wrapOn ( self . document , 19 * cm , 15 * cm )
table . drawOn ( self . document , 13.5 * cm , self . y - height - 5 )
2022-09-30 21:33:16 +02:00
else :
self . add_new_line (
2022-10-04 11:38:25 +02:00
14 * cm ,
" No compulsary "
)
self . add_new_line (
14 * cm ,
" routine defined. "
)
self . add_vspace ( - DOUBLE_LINE_HEIGHT )
2022-09-30 21:33:16 +02:00
2022-09-23 16:02:20 +02:00
routine_2 = gymnast . has_routine . filter ( routine_type = 2 ) . filter ( date_begin__lte = date . today ( ) ) . filter ( Q ( date_end__gte = date . today ( ) ) | Q ( date_end__isnull = True ) ) . first ( )
2022-09-30 12:12:46 +02:00
if routine_2 :
data = [ ]
for routine_skill in routine_2 . routine . skill_links . all ( ) :
data . append ( [ routine_skill . skill . notation , routine_skill . skill . difficulty ] )
data . append ( [ None , routine_2 . routine . difficulty ] )
style = TableStyle (
[
( ' ALIGN ' , ( 1 , 0 ) , ( 1 , - 1 ) , ' RIGHT ' ) ,
# ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
( ' LINEABOVE ' , ( 0 , - 1 ) , ( - 1 , - 1 ) , 0.25 , colors . black ) ,
]
)
table = Table ( data , [ 2 * cm , 1 * cm ] )
table . setStyle ( style )
width , height = table . wrapOn ( self . document , 19 * cm , 15.5 * cm )
table . drawOn ( self . document , 17 * cm , self . y - height - 5 )
2022-09-30 21:33:16 +02:00
else :
self . add_new_line (
2022-10-04 11:38:25 +02:00
17 * cm ,
" No volontary "
)
self . add_new_line (
17 * cm ,
" routine defined. "
)
2022-09-22 12:45:02 +02:00
2022-10-14 10:35:40 +02:00
def add_gymnast_last_learned_skill ( self , gymnast ) :
""" Ajoute les derniers skill appris par le gymnaste
Args :
gymnast < Gymnast > gymnaste
Returns :
Ne retourne rien
"""
self . y = 17 * cm
self . add_new_line (
2022-10-14 10:46:34 +02:00
7.5 * cm ,
2022-10-14 10:35:40 +02:00
" New learned skills " ,
font_decoration = " Bold " ,
)
self . add_vspace ( - 3 )
# le double F ne fonctionne qu'en précisant le distinct, sinon ca dédouble les résultats.
# qui lui même ne fonctionne que sur un champ présent dans le `order_by` (que le premier champ ?)
#
learned_skills = (
LearnedSkill . objects . filter ( gymnast = gymnast . id )
. annotate ( skill_notation = F ( " skill__notation " ) )
. order_by ( " skill_notation " , " -date " ) . distinct ( ' skill_notation ' ) [ : 5 ]
)
if learned_skills :
for learned_skill in learned_skills :
self . add_new_line (
2022-10-14 10:46:34 +02:00
7.5 * cm , learned_skill . skill . short_label + " " + str ( LEARNING_STEP_CHOICES [ learned_skill . learning_step ] [ 1 ] ) . lower ( ) + " ( " + learned_skill . skill . notation + " ), " + learned_skill . date . strftime ( " %d - % m- % Y " )
2022-10-14 10:35:40 +02:00
)
else :
self . add_new_line (
2022-10-14 10:46:34 +02:00
7.5 * cm ,
2022-10-14 10:35:40 +02:00
" No skill to learn this week. " ,
)
2022-09-22 12:45:02 +02:00
def add_gymnast_next_skills ( self , gymnast ) :
""" Ajoute les prochains skill (skill planifié) à apprendre
Args :
gymnast < Gymnast > gymnaste
Returns :
Ne retourne rien
"""
2022-09-23 16:02:20 +02:00
self . y = 17 * cm
self . add_new_line (
X ,
" Next skills to learn " ,
font_decoration = " Bold " ,
)
self . add_vspace ( - 3 )
2022-10-12 17:05:43 +02:00
# le double F ne fonctionne qu'en précisant le distinct, sinon ca dédouble les résultats.
# qui lui même ne fonctionne que sur un champ présent dans le `order_by` (que le premier champ ?)
#
2022-09-23 16:02:20 +02:00
planified_skills = (
2022-09-22 12:45:02 +02:00
Skill . objects . filter ( plan__gymnast = gymnast . id )
. filter (
Q ( plan__is_done = False )
| Q ( plan__date__gte = date . today ( ) )
)
2022-10-12 17:05:43 +02:00
# .annotate(plan_date=F("plan__date"))
2022-10-12 17:21:27 +02:00
. annotate ( plan_date = F ( " plan__date " ) , learning_step = F ( " plan__learning_step " ) )
2022-10-12 17:05:43 +02:00
. order_by ( " notation " , " -plan__date " ) . distinct ( ' notation ' ) [ : 6 ]
2022-09-22 12:45:02 +02:00
)
2022-09-30 15:56:58 +02:00
if planified_skills :
for planified_skill in planified_skills :
self . add_new_line (
2022-10-12 17:21:27 +02:00
X , planified_skill . short_label + " " + str ( LEARNING_STEP_CHOICES [ planified_skill . learning_step ] [ 1 ] ) . lower ( ) + " ( " + planified_skill . notation + " ) for " + planified_skill . plan_date . strftime ( " %d - % m- % Y " )
2022-09-30 15:56:58 +02:00
)
else :
2022-09-22 12:45:02 +02:00
self . add_new_line (
2022-09-30 15:56:58 +02:00
X ,
2022-10-12 10:30:46 +02:00
" No next skill to learn plannified. " ,
2022-09-30 15:56:58 +02:00
)
2022-09-27 08:24:01 +02:00
def add_gymnast_next_events ( self , gymnast ) :
""" Ajoute les évènements futurs du gymnaste """
self . y = 13.5 * cm
self . add_new_line (
X ,
" Next event " ,
font_decoration = " Bold " ,
)
self . add_vspace ( - 3 )
today = pendulum . now ( ) . date ( )
next_event_list = Event . objects . filter ( gymnasts = gymnast . id , date_begin__gte = today ) . order_by ( " date_begin " ) [ : 5 ]
data = [ ]
for event in next_event_list :
data . append ( [ event . date_begin . strftime ( " %d - % m- % Y " ) , " in " + str ( event . number_of_week_from_today ) + " week(s) " , event . name ] )
2022-09-30 15:56:58 +02:00
if data :
style = TableStyle (
[
( ' ALIGN ' , ( 1 , 0 ) , ( 1 , - 1 ) , ' CENTER ' ) ,
# ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
# ('GRID', (0,0), (-1,-1), 0.25, colors.black),
# ('LINEABOVE', (0,-1), (-1,-1), 0.25, colors.black),
]
)
table = Table ( data , [ 2.3 * cm , 2.2 * cm , 8 * cm ] )
table . setStyle ( style )
width , height = table . wrapOn ( self . document , 19 * cm , 15.5 * cm )
table . drawOn ( self . document , X - 6 , self . y - height - 5 )
else :
self . add_new_line (
X ,
" No futur event associated to this gymnast. " ,
)
2022-09-27 08:24:01 +02:00
def add_gymnast_week_notes ( self , gymnast ) :
""" Ajoute les notes de la semaine du gymnaste passé en paramètre """
2022-10-05 10:05:11 +02:00
self . y = 8.8 * cm
2022-09-27 08:24:01 +02:00
self . add_new_line (
X ,
" Notes " ,
font_decoration = " Bold " ,
)
self . add_vspace ( - 2 * cm )
today = pendulum . today ( ) . date ( )
2022-09-30 11:36:03 +02:00
begin_of_the_week = today
2022-09-27 08:24:01 +02:00
if today . weekday ( ) != 0 :
2022-09-30 11:36:03 +02:00
begin_of_the_week - = timedelta ( today . weekday ( ) )
2022-09-27 08:24:01 +02:00
2022-10-07 09:31:56 +02:00
notes = gymnast . remarks . filter ( created_at__gte = begin_of_the_week ) . filter ( status = 1 )
2022-09-27 08:24:01 +02:00
2022-09-30 15:56:58 +02:00
if notes :
html_text = ' '
for note in notes :
html_text + = ' <br /> ' + note . to_markdown ( )
2022-09-27 08:24:01 +02:00
2022-09-30 15:56:58 +02:00
html_text = html_text [ 6 : ]
# print(html_text)
2022-09-27 08:24:01 +02:00
2022-10-05 09:47:43 +02:00
paragraph = Paragraph ( html_text , self . style )
width , height = paragraph . wrap ( 18 * cm , 10 * cm )
paragraph . drawOn ( self . document , X , self . y - ( height / 1.5 ) )
2022-09-30 15:56:58 +02:00
else :
2022-09-30 21:33:16 +02:00
self . add_vspace ( 1.8 * cm )
2022-09-30 15:56:58 +02:00
self . add_new_line (
X ,
2022-09-30 21:33:16 +02:00
" No note associated to this gymnast this week. " ,
2022-09-30 15:56:58 +02:00
)