Black formatting

This commit is contained in:
Gregory Trullemans 2022-10-31 13:51:22 +01:00
parent b84017614f
commit a4fd5c4350
40 changed files with 997 additions and 574 deletions

View File

@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = get_asgi_application()

View File

@ -26,24 +26,17 @@ import ultron.objective.urls
urlpatterns = [
# Profile list
path(r"profile/", include(ultron.profiles.urls.profile_urlpatterns)),
# Gymnast management
path(r"gymnast/", include(ultron.people.urls.gymnast_urlpatterns)),
# Location management
path(r"location/", include(ultron.location.urls.urlpatterns)),
# Follow-up management
path(r"follow-up/", include(ultron.followup.urls.urlpatterns)),
# Objective management
path(r"objective/", include(ultron.objective.urls.urlpatterns)),
# Planning management
path(r"event/", include(ultron.planning.urls.event_urlpatterns)),
path("", include("ultron.core.urls")),
# Administration
path('admin/', admin.site.urls),
path("admin/", admin.site.urls),
]

View File

@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = get_wsgi_application()

View File

@ -3,7 +3,7 @@ from django.contrib import admin
from django_admin_listfilter_dropdown.filters import (
DropdownFilter,
ChoiceDropdownFilter,
RelatedDropdownFilter
RelatedDropdownFilter,
)
from .models import (
@ -18,7 +18,7 @@ from .models import (
LearnedSkill,
ChronoDetails,
GymnastHasRoutine,
NumberOfRoutineDone
NumberOfRoutineDone,
)
@ -26,7 +26,7 @@ class ChronoAdmin(admin.ModelAdmin):
model = Chrono
list_display = ("date", "gymnast", "tof", "chrono_type")
readonly_fields = ('season', 'week_number', 'created_at', 'updated_at')
readonly_fields = ("season", "week_number", "created_at", "updated_at")
list_filter = ("chrono_type",)
autocomplete_fields = ("gymnast",)
date_hierarchy = "date"
@ -36,23 +36,25 @@ class ChronoAdmin(admin.ModelAdmin):
class ChronoDetailsAdmin(admin.ModelAdmin):
model = ChronoDetails
list_display = ("chrono", "order", "value") # "chrono__gymnast",
list_display = ("chrono", "order", "value") # "chrono__gymnast",
list_filter = (
('chrono', RelatedDropdownFilter),
("chrono", RelatedDropdownFilter),
# ('chrono__gymnast', RelatedDropdownFilter),
)
related_search_fields = {"chrono": ("date", "chrono__gymnast__last_name", "chrono__gymnast__first_name")}
related_search_fields = {
"chrono": ("date", "chrono__gymnast__last_name", "chrono__gymnast__first_name")
}
class LearnedSkillAdmin(admin.ModelAdmin):
model = LearnedSkill
list_display = ("gymnast", "skill", "learning_step", "date")
readonly_fields = ('season', 'week_number', 'created_at', 'updated_at')
readonly_fields = ("season", "week_number", "created_at", "updated_at")
list_filter = (
('gymnast', RelatedDropdownFilter),
('skill', RelatedDropdownFilter),
"learning_step"
("gymnast", RelatedDropdownFilter),
("skill", RelatedDropdownFilter),
"learning_step",
)
search_fields = ("gymnast", "skill")
autocomplete_fields = ("gymnast", "skill")
@ -67,21 +69,21 @@ class PointAdmin(admin.ModelAdmin):
"point_execution",
"point_difficulty",
"point_time_of_flight",
"total"
"total",
)
readonly_fields = ('created_at', 'updated_at')
readonly_fields = ("created_at", "updated_at")
ordering = ("gymnast",)
list_filter = (
('gymnast', RelatedDropdownFilter),
('event', RelatedDropdownFilter),
('routine_type', DropdownFilter),
("gymnast", RelatedDropdownFilter),
("event", RelatedDropdownFilter),
("routine_type", DropdownFilter),
)
search_fields = (
"gymnast__first_name",
"gymnast__last_name",
"event__place_name",
"event__place_city",
"event__place__country_name"
"event__place__country_name",
)
autocomplete_fields = ("gymnast", "event")
@ -90,7 +92,7 @@ class AccidentAdmin(admin.ModelAdmin):
model = Accident
fields = ("date", "gymnast", "skill", "informations") # educative
readonly_fields = ('season', 'week_number', 'created_at', 'updated_at')
readonly_fields = ("season", "week_number", "created_at", "updated_at")
list_display = ("date", "gymnast", "skill") # educative
list_filter = ("date",)
date_hierarchy = "date"
@ -102,13 +104,13 @@ class MindStateAdmin(admin.ModelAdmin):
model = MindState
fields = ("gymnast", "date", "score", "informations")
readonly_fields = ('season', 'week_number', 'created_at', 'updated_at')
readonly_fields = ("season", "week_number", "created_at", "updated_at")
list_display = ("date", "gymnast", "score")
list_filter = (
"date",
('gymnast', RelatedDropdownFilter),
("gymnast", RelatedDropdownFilter),
)
autocomplete_fields = ("gymnast", )
autocomplete_fields = ("gymnast",)
date_hierarchy = "date"
@ -117,8 +119,8 @@ class GymnastHasRoutineAdmin(admin.ModelAdmin):
list_display = ("gymnast", "routine", "routine_type", "date_begin", "date_end")
list_filter = (
('gymnast', RelatedDropdownFilter),
('routine_type', DropdownFilter), # A supprimer ?
("gymnast", RelatedDropdownFilter),
("routine_type", DropdownFilter), # A supprimer ?
)
search_fields = ("gymnast", "routine")
autocomplete_fields = ("gymnast", "routine")
@ -135,8 +137,8 @@ class NumberOfRoutineDoneAdmin(admin.ModelAdmin):
"number_of_try",
)
list_filter = (
('gymnast', RelatedDropdownFilter),
('routine_type', DropdownFilter), # A supprimer ?
("gymnast", RelatedDropdownFilter),
("routine_type", DropdownFilter), # A supprimer ?
)
autocomplete_fields = ("gymnast", "routine")
date_hierarchy = "date"
@ -146,10 +148,8 @@ class HeightWeightAdmin(admin.ModelAdmin):
model = HeightWeight
list_display = ("gymnast", "height", "hips_height", "weight", "date")
readonly_fields = ('season', 'week_number')
list_filter = (
('gymnast', RelatedDropdownFilter),
)
readonly_fields = ("season", "week_number")
list_filter = (("gymnast", RelatedDropdownFilter),)
date_hierarchy = "date"
autocomplete_fields = ("gymnast",)
@ -158,10 +158,10 @@ class PlanAdmin(admin.ModelAdmin):
model = Plan
list_display = ("gymnast", "date", "educative")
readonly_fields = ('season', 'week_number', 'created_at', 'updated_at')
readonly_fields = ("season", "week_number", "created_at", "updated_at")
list_filter = (
('gymnast', RelatedDropdownFilter),
('educative', RelatedDropdownFilter),
("gymnast", RelatedDropdownFilter),
("educative", RelatedDropdownFilter),
)
search_fields = (
"gymnast__firstname",
@ -177,10 +177,10 @@ class NoteAdmin(admin.ModelAdmin):
model = Note
list_display = ("gymnast", "coach")
readonly_fields = ('season', 'week_number', 'created_at', 'updated_at')
readonly_fields = ("season", "week_number", "created_at", "updated_at")
list_filter = (
('gymnast', RelatedDropdownFilter),
('coach', RelatedDropdownFilter),
("gymnast", RelatedDropdownFilter),
("coach", RelatedDropdownFilter),
)
search_fields = (
"gymnast__firstname",
@ -195,11 +195,15 @@ class NoteAdmin(admin.ModelAdmin):
class IntensityAdmin(admin.ModelAdmin):
model = Intensity
list_display = ("gymnast", "time", "difficulty", "quantity_of_skill", "number_of_passes")
readonly_fields = ('season', 'week_number')
list_filter = (
('gymnast', RelatedDropdownFilter),
list_display = (
"gymnast",
"time",
"difficulty",
"quantity_of_skill",
"number_of_passes",
)
readonly_fields = ("season", "week_number")
list_filter = (("gymnast", RelatedDropdownFilter),)
search_fields = (
"gymnast__firstname",
"gymnast__lastname",

View File

@ -2,6 +2,7 @@ from django import template
register = template.Library()
@register.filter
def get_value_at_index(list, index):
return list[index]
return list[index]

View File

@ -3,63 +3,144 @@ from django.urls import reverse, resolve
class URLTestCase(TestCase):
def test_skill_url(self):
# Chrono URL
self.assertEqual(resolve("/follow-up/chrono/").view_name, 'chrono_list')
self.assertEqual(resolve("/follow-up/chrono/gymnast/1/").view_name, 'chrono_list_for_gymnast')
self.assertEqual(resolve("/follow-up/chrono/add/").view_name, 'chrono_create')
self.assertEqual(resolve("/follow-up/chrono/add/1/").view_name, 'chrono_create_for_gymnast')
self.assertEqual(resolve("/follow-up/chrono/edit/1/").view_name, 'chrono_update')
self.assertEqual(resolve("/follow-up/chrono/details/1/").view_name, 'jump_chrono_details')
self.assertEqual(resolve("/follow-up/chrono/details/1/add/").view_name, 'jump_chrono_values_create_or_update')
self.assertEqual(resolve("/follow-up/chrono/add_jump_chrono_value/").view_name, 'add_jump_chrono_value')
self.assertEqual(resolve("/follow-up/chrono/remove_jump_chrono_value/").view_name, 'remove_jump_chrono_value')
self.assertEqual(resolve("/follow-up/chrono/detailed_score_for_date_range/1/1/2022-09-01/2022-09-20/").view_name, 'average_jump_chrono_details_between_two_date')
self.assertEqual(resolve("/follow-up/chrono/").view_name, "chrono_list")
self.assertEqual(
resolve("/follow-up/chrono/gymnast/1/").view_name, "chrono_list_for_gymnast"
)
self.assertEqual(resolve("/follow-up/chrono/add/").view_name, "chrono_create")
self.assertEqual(
resolve("/follow-up/chrono/add/1/").view_name, "chrono_create_for_gymnast"
)
self.assertEqual(
resolve("/follow-up/chrono/edit/1/").view_name, "chrono_update"
)
self.assertEqual(
resolve("/follow-up/chrono/details/1/").view_name, "jump_chrono_details"
)
self.assertEqual(
resolve("/follow-up/chrono/details/1/add/").view_name,
"jump_chrono_values_create_or_update",
)
self.assertEqual(
resolve("/follow-up/chrono/add_jump_chrono_value/").view_name,
"add_jump_chrono_value",
)
self.assertEqual(
resolve("/follow-up/chrono/remove_jump_chrono_value/").view_name,
"remove_jump_chrono_value",
)
self.assertEqual(
resolve(
"/follow-up/chrono/detailed_score_for_date_range/1/1/2022-09-01/2022-09-20/"
).view_name,
"average_jump_chrono_details_between_two_date",
)
# Learned Skill URL
self.assertEqual(resolve("/follow-up/learnedskill/add/").view_name, 'learnedskill_create')
self.assertEqual(resolve("/follow-up/learnedskill/add/1/").view_name, 'learnedskill_create')
self.assertEqual(resolve("/follow-up/learnedskill/new/").view_name, 'gymnast_learn_skill')
self.assertEqual(
resolve("/follow-up/learnedskill/add/").view_name, "learnedskill_create"
)
self.assertEqual(
resolve("/follow-up/learnedskill/add/1/").view_name, "learnedskill_create"
)
self.assertEqual(
resolve("/follow-up/learnedskill/new/").view_name, "gymnast_learn_skill"
)
# Score URL
self.assertEqual(resolve("/follow-up/score/").view_name, 'score_listing')
self.assertEqual(resolve("/follow-up/score/gymnast/1/").view_name, 'score_list_for_gymnast')
self.assertEqual(resolve("/follow-up/score/add/gymnast/1/").view_name, 'score_create_for_gymnast')
self.assertEqual(resolve("/follow-up/score/add/").view_name, 'score_create')
self.assertEqual(resolve("/follow-up/score/edit/1/").view_name, 'score_update')
self.assertEqual(resolve("/follow-up/score/").view_name, "score_listing")
self.assertEqual(
resolve("/follow-up/score/gymnast/1/").view_name, "score_list_for_gymnast"
)
self.assertEqual(
resolve("/follow-up/score/add/gymnast/1/").view_name,
"score_create_for_gymnast",
)
self.assertEqual(resolve("/follow-up/score/add/").view_name, "score_create")
self.assertEqual(resolve("/follow-up/score/edit/1/").view_name, "score_update")
# Accident URL
self.assertEqual(resolve("/follow-up/accident/search/").view_name, 'accident_search')
self.assertEqual(resolve("/follow-up/accident/").view_name, 'accident_list')
self.assertEqual(resolve("/follow-up/accident/add/").view_name, 'accident_create')
self.assertEqual(resolve("/follow-up/accident/add/1/").view_name, 'accident_create_for_gymnast')
self.assertEqual(resolve("/follow-up/accident/edit/1/").view_name, 'accident_update')
self.assertEqual(resolve("/follow-up/accident/1/").view_name, 'accident_details')
self.assertEqual(
resolve("/follow-up/accident/search/").view_name, "accident_search"
)
self.assertEqual(resolve("/follow-up/accident/").view_name, "accident_list")
self.assertEqual(
resolve("/follow-up/accident/add/").view_name, "accident_create"
)
self.assertEqual(
resolve("/follow-up/accident/add/1/").view_name,
"accident_create_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/accident/edit/1/").view_name, "accident_update"
)
self.assertEqual(
resolve("/follow-up/accident/1/").view_name, "accident_details"
)
# Mindstate URL
self.assertEqual(resolve("/follow-up/mindstate/").view_name, 'mindstate_list')
self.assertEqual(resolve("/follow-up/mindstate/gymnast/1/").view_name, 'mindstate_list_for_gymnast')
self.assertEqual(resolve("/follow-up/mindstate/add/").view_name, 'mindstate_create')
self.assertEqual(resolve("/follow-up/mindstate/add/1/").view_name, 'mindstate_create_for_gymnast')
self.assertEqual(resolve("/follow-up/mindstate/edit/1/").view_name, 'mindstate_update')
self.assertEqual(resolve("/follow-up/mindstate/1/").view_name, 'mindstate_details')
self.assertEqual(resolve("/follow-up/mindstate/").view_name, "mindstate_list")
self.assertEqual(
resolve("/follow-up/mindstate/gymnast/1/").view_name,
"mindstate_list_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/mindstate/add/").view_name, "mindstate_create"
)
self.assertEqual(
resolve("/follow-up/mindstate/add/1/").view_name,
"mindstate_create_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/mindstate/edit/1/").view_name, "mindstate_update"
)
self.assertEqual(
resolve("/follow-up/mindstate/1/").view_name, "mindstate_details"
)
# HeightWeigh URL
self.assertEqual(resolve("/follow-up/heightweight/gymnast/1/").view_name, 'heightweight_list_for_gymnast')
self.assertEqual(resolve("/follow-up/heightweight/add/").view_name, 'heightweight_create')
self.assertEqual(resolve("/follow-up/heightweight/add/1/").view_name, 'heightweight_create_for_gymnast')
self.assertEqual(resolve("/follow-up/heightweight/edit/1/").view_name, 'heightweight_update')
self.assertEqual(
resolve("/follow-up/heightweight/gymnast/1/").view_name,
"heightweight_list_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/heightweight/add/").view_name, "heightweight_create"
)
self.assertEqual(
resolve("/follow-up/heightweight/add/1/").view_name,
"heightweight_create_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/heightweight/edit/1/").view_name, "heightweight_update"
)
# RoutineDone URL
self.assertEqual(resolve("/follow-up/routinedone/add/").view_name, 'routinedone_create')
self.assertEqual(resolve("/follow-up/routinedone/increment/").view_name, 'increment_routinedone')
self.assertEqual(resolve("/follow-up/routinedone/add/1/").view_name, 'routinedone_create_for_gymnast')
self.assertEqual(resolve("/follow-up/routinedone/edit/1/").view_name, 'routinedone_update')
self.assertEqual(resolve("/follow-up/routinedone/edit/1/").view_name, 'routinedone_update')
self.assertEqual(
resolve("/follow-up/routinedone/add/").view_name, "routinedone_create"
)
self.assertEqual(
resolve("/follow-up/routinedone/increment/").view_name,
"increment_routinedone",
)
self.assertEqual(
resolve("/follow-up/routinedone/add/1/").view_name,
"routinedone_create_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/routinedone/edit/1/").view_name, "routinedone_update"
)
self.assertEqual(
resolve("/follow-up/routinedone/edit/1/").view_name, "routinedone_update"
)
# Plan URL
self.assertEqual(resolve("/follow-up/plan/add/").view_name, 'plan_create')
self.assertEqual(resolve("/follow-up/plan/add/1/").view_name, 'add_plan_for_gymnast')
self.assertEqual(resolve("/follow-up/plan/add/1/2/").view_name, 'add_skill_for_gymnast')
self.assertEqual(resolve("/follow-up/plan/edit/1/").view_name, 'plan_update')
self.assertEqual(resolve("/follow-up/plan/add/").view_name, "plan_create")
self.assertEqual(
resolve("/follow-up/plan/add/1/").view_name, "add_plan_for_gymnast"
)
self.assertEqual(
resolve("/follow-up/plan/add/1/2/").view_name, "add_skill_for_gymnast"
)
self.assertEqual(resolve("/follow-up/plan/edit/1/").view_name, "plan_update")

View File

@ -27,7 +27,7 @@ class PlaceAdmin(admin.ModelAdmin):
ordering = ("name",)
list_filter = ("is_active",)
search_fields = ("name", "address", "postal", "city")
autocomplete_fields = ("country",) # , "place"
autocomplete_fields = ("country",) # , "place"
admin.site.register(Place, PlaceAdmin)

View File

@ -1,4 +1,3 @@
from django import forms
from .models import Place
@ -50,5 +49,5 @@ class PlaceForm(forms.ModelForm):
"placeholder": "Searching…",
"data-ref": "#id_country",
}
)
),
)

View File

@ -1,4 +1,3 @@
from django.db import models

View File

@ -3,17 +3,18 @@ from django.urls import reverse, resolve
class URLTestCase(TestCase):
def test_place_url(self):
self.assertEqual(resolve("/location/place/lookup/").view_name, 'place_lookup')
self.assertEqual(resolve("/location/place/add/").view_name, 'place_create')
self.assertEqual(resolve("/location/place/edit/1/").view_name, 'place_update')
self.assertEqual(resolve("/location/place/1/").view_name, 'place_details')
self.assertEqual(resolve("/location/place/").view_name, 'place_list')
self.assertEqual(resolve("/location/place/lookup/").view_name, "place_lookup")
self.assertEqual(resolve("/location/place/add/").view_name, "place_create")
self.assertEqual(resolve("/location/place/edit/1/").view_name, "place_update")
self.assertEqual(resolve("/location/place/1/").view_name, "place_details")
self.assertEqual(resolve("/location/place/").view_name, "place_list")
def test_country_url(self):
self.assertEqual(resolve("/location/country/lookup/").view_name, 'country_lookup')
self.assertEqual(
resolve("/location/country/lookup/").view_name, "country_lookup"
)
def test_club_url(self):
self.assertEqual(resolve("/location/club/lookup/").view_name, 'club_lookup')
self.assertEqual(resolve("/location/club/").view_name, 'club_list')
self.assertEqual(resolve("/location/club/lookup/").view_name, "club_lookup")
self.assertEqual(resolve("/location/club/").view_name, "club_list")

View File

@ -1,4 +1,3 @@
from django.urls import path
from . import views
@ -6,12 +5,12 @@ from . import views
urlpatterns = [
path(r"place/lookup/", views.place_lookup, name="place_lookup"),
path(r"place/add/", views.place_create_or_update, name="place_create"),
path(r"place/edit/<int:place_id>/", views.place_create_or_update, name="place_update"),
path(
r"place/edit/<int:place_id>/", views.place_create_or_update, name="place_update"
),
path(r"place/<int:place_id>/", views.place_details, name="place_details"),
path(r"place/", views.place_listing, name="place_list"),
path(r"country/lookup/", views.country_lookup, name="country_lookup"),
path(r"club/", views.club_listing, name="club_list"),
path(r"club/lookup/", views.club_lookup, name="club_lookup"),
]

View File

@ -92,7 +92,6 @@ def place_create_or_update(request, place_id=None):
else:
return render(request, "locations/places/create.html", {"form": form})
form = PlaceForm(instance=place, initial=data)
context = {"form": form, "place_id": place_id}
return render(request, "locations/places/create.html", context)

View File

@ -5,7 +5,7 @@ from django.contrib import admin
from django_admin_listfilter_dropdown.filters import (
DropdownFilter,
ChoiceDropdownFilter,
RelatedDropdownFilter
RelatedDropdownFilter,
)
from .models import (
@ -76,15 +76,15 @@ class SkillAdmin(admin.ModelAdmin):
search_fields = ("rank", "long_label", "short_label", "notation")
list_filter = (
"is_competitive",
('difficulty', DropdownFilter),
('departure', RelatedDropdownFilter),
('landing', RelatedDropdownFilter),
('level', DropdownFilter),
('rank', DropdownFilter),
'rotation_type',
('position', DropdownFilter),
('rotation', DropdownFilter),
('twist', DropdownFilter),
("difficulty", DropdownFilter),
("departure", RelatedDropdownFilter),
("landing", RelatedDropdownFilter),
("level", DropdownFilter),
("rank", DropdownFilter),
"rotation_type",
("position", DropdownFilter),
("rotation", DropdownFilter),
("twist", DropdownFilter),
)
filter_horizontal = ("educatives", "prerequisites")
@ -130,10 +130,10 @@ class RoutineAdmin(admin.ModelAdmin):
"difficulty",
)
list_filter = (
('level', DropdownFilter),
("level", DropdownFilter),
"difficulty",
"is_competitive",
"is_active"
"is_active",
)
search_fields = (
"long_label",
@ -159,9 +159,7 @@ class RoutineSkillAdmin(admin.ModelAdmin):
model = RoutineSkill
list_display = ("routine", "skill", "rank")
list_filter = (
('rank', DropdownFilter),
)
list_filter = (("rank", DropdownFilter),)
search_fields = (
"routine__long_label",
"routine__short_label",

View File

@ -1,18 +1,12 @@
from django import forms
from .models import (
Skill,
Routine,
RoutineSkill
)
from .models import Skill, Routine, RoutineSkill
class SkillForm(forms.ModelForm):
class Meta:
model = Skill
fields = (
"informations",
)
fields = ("informations",)
widgets = {
"informations": forms.Textarea(
attrs={

View File

@ -10,9 +10,12 @@ class Educative(Markdownizable):
série de compétition, .
Level : Toutes les figures appartiennent à un niveau. Un niveau peut contenir plusieurs
figures. Exemple : les trois sauts de base (saut groupé, saut carpé joint et saut écart)
sont dans le même niveau. Le niveau dune figure est calculé par rapport aux prérequis : par
défaut le niveau dune figure est égal au niveau maximum de ses prérequis.
figures.
Exemple : les trois sauts de base (saut groupé, saut carpé joint et saut écart)
sont dans le même niveau, salto avant groupé et salto arrière groupé appartiennent au même
niveau.
Le niveau dune figure est calculé par rapport aux prérequis : par défaut le niveau
dune figure est égal au niveau maximum de ses prérequis.
Le niveau, avec le rang, ont pour but daider les coaches à planifier lévolution et
lapprentissage des figures les unes par rapport aux autres.

View File

@ -3,8 +3,6 @@ from ultron.objective.models import Educative
class EducativeTestCase(TestCase):
def setUp(self):
"""
Structure finale :
@ -15,25 +13,41 @@ class EducativeTestCase(TestCase):
3 -> 4 -> 5 -> 6 -> 7 -> 9
"""
# 1 et 3 Eductative sans pre-requis
educ_1 = Educative.objects.create(long_label="1/2 vrille", difficulty=0.1, level=1, rank=1)
educ_3 = Educative.objects.create(long_label="4 pattes", difficulty=0.1, level=1, rank=1)
educ_1 = Educative.objects.create(
long_label="1/2 vrille", difficulty=0.1, level=1, rank=1
)
educ_3 = Educative.objects.create(
long_label="4 pattes", difficulty=0.1, level=1, rank=1
)
educ_2 = Educative.objects.create(long_label="tour", difficulty=0.2, level=1, rank=2)
educ_2 = Educative.objects.create(
long_label="tour", difficulty=0.2, level=1, rank=2
)
educ_2.prerequisites.add(educ_1)
educ_4 = Educative.objects.create(long_label="Ventre", difficulty=0.1, level=1, rank=1)
educ_4 = Educative.objects.create(
long_label="Ventre", difficulty=0.1, level=1, rank=1
)
educ_4.prerequisites.add(educ_3)
educ_5 = Educative.objects.create(long_label="3/4 Avant /", difficulty=0.3, level=1, rank=1)
educ_5 = Educative.objects.create(
long_label="3/4 Avant /", difficulty=0.3, level=1, rank=1
)
educ_5.prerequisites.add(educ_4)
educ_6 = Educative.objects.create(long_label="Avant /", difficulty=0.6, level=1, rank=1)
educ_6 = Educative.objects.create(
long_label="Avant /", difficulty=0.6, level=1, rank=1
)
educ_6.prerequisites.add(educ_5)
educ_7 = Educative.objects.create(long_label="Barani /", difficulty=0.6, level=1, rank=1)
educ_7 = Educative.objects.create(
long_label="Barani /", difficulty=0.6, level=1, rank=1
)
educ_7.prerequisites.add(educ_6)
educ_7.prerequisites.add(educ_1)
# educ_8 = Educative.objects.create(long_label="3/4 Avant vrille", difficulty=0.5, level=1, rank=1)
# educ_8.prerequisites.add(educ_6)
# educ_8.prerequisites.add(educ_2)
educ_9 = Educative.objects.create(long_label="Rudy", difficulty=0.8, level=1, rank=1)
educ_9 = Educative.objects.create(
long_label="Rudy", difficulty=0.8, level=1, rank=1
)
educ_9.prerequisites.add(educ_2)
educ_9.prerequisites.add(educ_7)
@ -53,8 +67,18 @@ class EducativeTestCase(TestCase):
educ_5 = Educative.objects.get(long_label="3/4 Avant /")
educ_6 = Educative.objects.get(long_label="Avant /")
educ_7 = Educative.objects.get(long_label="Barani /")
self.assertEqual(educ_7.breadcrumb(), [[educ_1, educ_7], [educ_3, educ_4, educ_5, educ_6, educ_7]])
self.assertEqual(
educ_7.breadcrumb(),
[[educ_1, educ_7], [educ_3, educ_4, educ_5, educ_6, educ_7]],
)
# Cas plus complexe : l'éduc 8 a deux encetres qui ont chacun une lignée d'encêtres
educ_9 = Educative.objects.get(long_label="Rudy")
self.assertEqual(educ_9.breadcrumb(), [[educ_1, educ_7, educ_9], [educ_3, educ_4, educ_5, educ_6, educ_7, educ_9], [educ_1, educ_2, educ_9]])
self.assertEqual(
educ_9.breadcrumb(),
[
[educ_1, educ_7, educ_9],
[educ_3, educ_4, educ_5, educ_6, educ_7, educ_9],
[educ_1, educ_2, educ_9],
],
)

View File

@ -5,23 +5,59 @@ from ultron.objective.models import (
max_even_if_none,
TouchPosition,
Routine,
RoutineSkill
RoutineSkill,
)
class ToolsModels(TestCase):
def setUp(self):
""" """
touch_position_1 = TouchPosition.objects.create(long_label="debout", short_label="debout", is_default=True)
touch_position_2 = TouchPosition.objects.create(long_label="quadrupédique", short_label="4 patte", is_default=False)
educ_1 = Educative.objects.create(long_label="1/2 vrille", short_label="1/2T", difficulty=0.1, level=1, rank=1)
educ_3 = Educative.objects.create(long_label="4 pattes", short_label="4P", difficulty=0.1, level=1, rank=1)
skill_1 = Skill.objects.create(long_label="Salto arrière groupé", short_label="Arrière o", rotation_type=2, notation="4.-o", rotation=4, twist=0, departure=touch_position_1, landing=touch_position_1, difficulty=0.5)
skill_2 = Skill.objects.create(long_label="Barani groupé", short_label="Barani o", rotation_type=2, notation=".41o", rotation=4, twist=1, departure=touch_position_1, landing=touch_position_1, difficulty=0.5)
routine_1 = Routine.objects.create(long_label="BOT Bronze", short_label="Bronze", is_active=True, is_competitive=True)
routine_skill_1 = RoutineSkill.objects.create(routine=routine_1, skill=skill_1, rank=1)
routine_skill_1 = RoutineSkill.objects.create(routine=routine_1, skill=skill_2, rank=2)
""" """
touch_position_1 = TouchPosition.objects.create(
long_label="debout", short_label="debout", is_default=True
)
touch_position_2 = TouchPosition.objects.create(
long_label="quadrupédique", short_label="4 patte", is_default=False
)
educ_1 = Educative.objects.create(
long_label="1/2 vrille", short_label="1/2T", difficulty=0.1, level=1, rank=1
)
educ_3 = Educative.objects.create(
long_label="4 pattes", short_label="4P", difficulty=0.1, level=1, rank=1
)
skill_1 = Skill.objects.create(
long_label="Salto arrière groupé",
short_label="Arrière o",
rotation_type=2,
notation="4.-o",
rotation=4,
twist=0,
departure=touch_position_1,
landing=touch_position_1,
difficulty=0.5,
)
skill_2 = Skill.objects.create(
long_label="Barani groupé",
short_label="Barani o",
rotation_type=2,
notation=".41o",
rotation=4,
twist=1,
departure=touch_position_1,
landing=touch_position_1,
difficulty=0.5,
)
routine_1 = Routine.objects.create(
long_label="BOT Bronze",
short_label="Bronze",
is_active=True,
is_competitive=True,
)
routine_skill_1 = RoutineSkill.objects.create(
routine=routine_1, skill=skill_1, rank=1
)
routine_skill_1 = RoutineSkill.objects.create(
routine=routine_1, skill=skill_2, rank=2
)
def test_max_even_if_none(self):
self.assertEqual(max_even_if_none(None, None), 0)
@ -39,18 +75,37 @@ class ToolsModels(TestCase):
def test_educative_to_string(self):
educ_1 = Educative.objects.get(long_label="1/2 vrille")
self.assertEqual(str(educ_1), educ_1.long_label + " (" + educ_1.short_label + " - " + str(educ_1.difficulty) + ")")
self.assertEqual(
str(educ_1),
educ_1.long_label
+ " ("
+ educ_1.short_label
+ " - "
+ str(educ_1.difficulty)
+ ")",
)
def test_skill_to_string(self):
skill_1 = Skill.objects.get(long_label="Salto arrière groupé")
self.assertEqual(str(skill_1), skill_1.long_label + " (" + skill_1.notation + ")")
self.assertEqual(
str(skill_1), skill_1.long_label + " (" + skill_1.notation + ")"
)
def test_routine_to_string(self):
routine_1 = Routine.objects.get(long_label="BOT Bronze")
self.assertEqual(str(routine_1), routine_1.long_label + " (" + routine_1.short_label + ")")
self.assertEqual(
str(routine_1), routine_1.long_label + " (" + routine_1.short_label + ")"
)
def test_routine_skill_to_string(self):
routine_1 = Routine.objects.get(long_label="BOT Bronze")
skill_1 = Skill.objects.get(long_label="Salto arrière groupé")
routine_skill_1 = RoutineSkill.objects.get(routine=routine_1, skill=skill_1)
self.assertEqual(str(routine_skill_1), str(routine_skill_1.rank) + " - " + routine_skill_1.routine.short_label + " : " + routine_skill_1.skill.short_label)
self.assertEqual(
str(routine_skill_1),
str(routine_skill_1.rank)
+ " - "
+ routine_skill_1.routine.short_label
+ " : "
+ routine_skill_1.skill.short_label,
)

View File

@ -9,22 +9,120 @@ from ultron.objective.tools import (
class ToolsTestCase(TestCase):
def setUp(self):
"""
""" """
departure_and_landing, _ = TouchPosition.objects.get_or_create(
long_label="debout", short_label="debout"
)
"""
departure_and_landing, _ = TouchPosition.objects.get_or_create(long_label="debout", short_label="debout")
skill_1 = Skill.objects.create(long_label="1/2 vrille", difficulty=0.1, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=1, rank=1)
skill_3 = Skill.objects.create(long_label="4 pattes", difficulty=0.1, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=1, rank=1)
skill_2 = Skill.objects.create(long_label="tour", difficulty=0.2, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=2, rank=2)
skill_4 = Skill.objects.create(long_label="Ventre", difficulty=0.1, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=2, rank=2)
skill_5 = Skill.objects.create(long_label="3/4 Avant /", difficulty=0.3, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=3, rank=3)
skill_6 = Skill.objects.create(long_label="Avant /", difficulty=0.6, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=3, rank=3)
skill_7 = Skill.objects.create(long_label="Barani /", difficulty=0.6, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=4, rank=4)
skill_8 = Skill.objects.create(long_label="3/4 Avant vrille", difficulty=0.5, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=4, rank=4)
skill_9 = Skill.objects.create(long_label="Rudy", difficulty=0.8, departure=departure_and_landing, landing=departure_and_landing, position="0", rotation_type="0", rotation="0", twist="1", level=4, rank=4)
skill_1 = Skill.objects.create(
long_label="1/2 vrille",
difficulty=0.1,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=1,
rank=1,
)
skill_3 = Skill.objects.create(
long_label="4 pattes",
difficulty=0.1,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=1,
rank=1,
)
skill_2 = Skill.objects.create(
long_label="tour",
difficulty=0.2,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=2,
rank=2,
)
skill_4 = Skill.objects.create(
long_label="Ventre",
difficulty=0.1,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=2,
rank=2,
)
skill_5 = Skill.objects.create(
long_label="3/4 Avant /",
difficulty=0.3,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=3,
rank=3,
)
skill_6 = Skill.objects.create(
long_label="Avant /",
difficulty=0.6,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=3,
rank=3,
)
skill_7 = Skill.objects.create(
long_label="Barani /",
difficulty=0.6,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=4,
rank=4,
)
skill_8 = Skill.objects.create(
long_label="3/4 Avant vrille",
difficulty=0.5,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=4,
rank=4,
)
skill_9 = Skill.objects.create(
long_label="Rudy",
difficulty=0.8,
departure=departure_and_landing,
landing=departure_and_landing,
position="0",
rotation_type="0",
rotation="0",
twist="1",
level=4,
rank=4,
)
def test_nb_skill_lte_type(self):
# Cas "None"
@ -35,7 +133,7 @@ class ToolsTestCase(TestCase):
self.assertEqual(nb_skill_lte_type(4, "level"), 9)
def test_compute_completude(self):
self.assertEqual(compute_completude(10, 1, 4), ('10%', 0))
self.assertEqual(compute_completude(10, 1, 4), ('10%', 0))
self.assertEqual(compute_completude(10, 5, 4), ('50%', 2))
self.assertEqual(compute_completude(10, 10, 4), ('100%', 4))
self.assertEqual(compute_completude(10, 1, 4), ("10%", 0))
self.assertEqual(compute_completude(10, 1, 4), ("10%", 0))
self.assertEqual(compute_completude(10, 5, 4), ("50%", 2))
self.assertEqual(compute_completude(10, 10, 4), ("100%", 4))

View File

@ -3,27 +3,53 @@ from django.urls import reverse, resolve
class URLTestCase(TestCase):
def test_skill_url(self):
self.assertEqual(resolve("/objective/skill/level/exact/1/").view_name, 'skill_listing_by_key')
self.assertEqual(resolve("/objective/skill/rank/lte/1/").view_name, 'skill_listing_by_key')
self.assertEqual(resolve("/objective/skill/difficulty/gt/1/").view_name, 'skill_listing_by_key')
self.assertEqual(
resolve("/objective/skill/level/exact/1/").view_name, "skill_listing_by_key"
)
self.assertEqual(
resolve("/objective/skill/rank/lte/1/").view_name, "skill_listing_by_key"
)
self.assertEqual(
resolve("/objective/skill/difficulty/gt/1/").view_name,
"skill_listing_by_key",
)
self.assertEqual(resolve("/objective/skill/lookup/").view_name, 'skill_lookup')
self.assertEqual(resolve("/objective/skill/search/").view_name, 'skill_search')
self.assertEqual(resolve("/objective/skill/1/").view_name, 'skill_details')
self.assertEqual(resolve("/objective/skill/1/tree/").view_name, 'skill_tree')
self.assertEqual(resolve("/objective/skill/prerequisiteless/").view_name, 'skill_without_prerequisite')
self.assertEqual(resolve("/objective/skill/").view_name, 'skill_list')
self.assertEqual(resolve("/objective/skill/lookup/").view_name, "skill_lookup")
self.assertEqual(resolve("/objective/skill/search/").view_name, "skill_search")
self.assertEqual(resolve("/objective/skill/1/").view_name, "skill_details")
self.assertEqual(resolve("/objective/skill/1/tree/").view_name, "skill_tree")
self.assertEqual(
resolve("/objective/skill/prerequisiteless/").view_name,
"skill_without_prerequisite",
)
self.assertEqual(resolve("/objective/skill/").view_name, "skill_list")
def test_routine_url(self):
self.assertEqual(resolve("/objective/routine/lookup/").view_name, 'routine_lookup')
self.assertEqual(resolve("/objective/routine/search/").view_name, 'routine_search')
self.assertEqual(resolve("/objective/routine/add/").view_name, 'routine_create')
self.assertEqual(resolve("/objective/routine/edit/1/").view_name, 'routine_update')
self.assertEqual(resolve("/objective/routine/1/").view_name, 'routine_details')
self.assertEqual(resolve("/objective/routine/compose/1/").view_name, 'compose_routine')
self.assertEqual(resolve("/objective/routine/compose/link_skill/").view_name, 'link_skill_to_routine')
self.assertEqual(resolve("/objective/routine/compose/unlink_skill/").view_name, 'unlink_skill_from_routine')
self.assertEqual(resolve("/objective/routine/").view_name, 'routine_list')
self.assertEqual(resolve("/objective/routine/gymnast/1/").view_name, 'routine_list_for_gymnast')
self.assertEqual(
resolve("/objective/routine/lookup/").view_name, "routine_lookup"
)
self.assertEqual(
resolve("/objective/routine/search/").view_name, "routine_search"
)
self.assertEqual(resolve("/objective/routine/add/").view_name, "routine_create")
self.assertEqual(
resolve("/objective/routine/edit/1/").view_name, "routine_update"
)
self.assertEqual(resolve("/objective/routine/1/").view_name, "routine_details")
self.assertEqual(
resolve("/objective/routine/compose/1/").view_name, "compose_routine"
)
self.assertEqual(
resolve("/objective/routine/compose/link_skill/").view_name,
"link_skill_to_routine",
)
self.assertEqual(
resolve("/objective/routine/compose/unlink_skill/").view_name,
"unlink_skill_from_routine",
)
self.assertEqual(resolve("/objective/routine/").view_name, "routine_list")
self.assertEqual(
resolve("/objective/routine/gymnast/1/").view_name,
"routine_list_for_gymnast",
)

View File

@ -87,7 +87,9 @@ def compute_completude(total_skill, gymnast_nb_known_skills, max_level_skill):
return completude, evaluated_level
def compute_statistics_by_type(nb_skill_by_type, nb_known_skill_by_type, desired_type="level"):
def compute_statistics_by_type(
nb_skill_by_type, nb_known_skill_by_type, desired_type="level"
):
"""
Calcule les statistiques par niveau.

View File

@ -86,8 +86,7 @@ def skill_listing(request, field=None, expression=None, value=None, level=None):
@login_required
@require_http_methods(["GET"])
def skill_tree(request, skill_id):
"""
"""
""" """
skill = get_object_or_404(Skill, pk=skill_id)
node_dict = {}
skill_closure = PrerequisiteClosure.objects.filter(descendant=skill)
@ -117,21 +116,29 @@ def skill_details(request, skill_id):
skill.level = max(prerequisite.level + 1, skill.level)
skill.rank = max(prerequisite.rank + 1, skill.rank)
skill.age_boy_with_help = max(skill.age_boy_with_help, prerequisite.age_boy_with_help)
skill.age_boy_with_help = max(
skill.age_boy_with_help, prerequisite.age_boy_with_help
)
skill.age_boy_without_help = max(
skill.age_boy_without_help,
prerequisite.age_boy_without_help
skill.age_boy_without_help, prerequisite.age_boy_without_help
)
skill.age_boy_chained = max(skill.age_boy_chained, prerequisite.age_boy_chained)
skill.age_boy_masterised = max(skill.age_boy_masterised, prerequisite.age_boy_masterised)
skill.age_girl_with_help = max(skill.age_girl_with_help, prerequisite.age_girl_with_help)
skill.age_girl_without_help = max(
skill.age_girl_without_help,
prerequisite.age_girl_without_help
skill.age_boy_masterised = max(
skill.age_boy_masterised, prerequisite.age_boy_masterised
)
skill.age_girl_with_help = max(
skill.age_girl_with_help, prerequisite.age_girl_with_help
)
skill.age_girl_without_help = max(
skill.age_girl_without_help, prerequisite.age_girl_without_help
)
skill.age_girl_chained = max(
skill.age_girl_chained, prerequisite.age_girl_chained
)
skill.age_girl_masterised = max(
skill.age_girl_masterised, prerequisite.age_girl_masterised
)
skill.age_girl_chained = max(skill.age_girl_chained, prerequisite.age_girl_chained)
skill.age_girl_masterised = max(skill.age_girl_masterised, prerequisite.age_girl_masterised)
skill.save()
@ -170,8 +177,7 @@ def skill_create_or_update(request, skill_id=None):
@login_required
@require_http_methods(["GET"])
def routine_listing(request, gymnast_id=None):
"""Récupère la liste des routines suivant un pattern si celui-ci est défini
"""
"""Récupère la liste des routines suivant un pattern si celui-ci est défini"""
gymnast = None
pattern = request.GET.get("pattern", None)
@ -296,7 +302,7 @@ def link_skill_to_routine(request):
link, created = RoutineSkill.objects.get_or_create(
routine=form.cleaned_data["routine"],
skill=form.cleaned_data["skill"],
rank=form.cleaned_data["rank"]
rank=form.cleaned_data["rank"],
)
return HttpResponse(200, (link, created))
else:
@ -316,4 +322,4 @@ def unlink_skill_from_routine(request):
except:
return HttpResponse(409)
return HttpResponse(200)
return HttpResponse(200)

View File

@ -35,7 +35,10 @@ class GymnastForm(forms.ModelForm):
"gender": forms.Select(attrs={"class": "form-control selectpicker"}),
"club": forms.HiddenInput(),
"email_trainer": forms.TextInput(
attrs={"class": "form-control", "placeholder": "trainer_email@email.com"}
attrs={
"class": "form-control",
"placeholder": "trainer_email@email.com",
}
),
"trainings_by_week": forms.TextInput(
attrs={"class": "form-control", "placeholder": "5"}
@ -68,7 +71,7 @@ class GymnastForm(forms.ModelForm):
required=False,
widget=forms.TextInput(
attrs={"class": "form-control", "placeholder": "my_email@email.com"}
)
),
)
club_related = forms.CharField(
@ -79,7 +82,7 @@ class GymnastForm(forms.ModelForm):
"placeholder": "Searching club…",
"data-ref": "#id_club",
}
)
),
)

View File

@ -3,6 +3,7 @@
from django.contrib.auth import get_user_model
from django.db.models import Count
from django.db import models
User = get_user_model()
from datetime import date
@ -32,11 +33,7 @@ class Gymnast(Markdownizable):
# CATEGORY_CHOICES = ((9, "I9"), (10, "I10"), (11, "A11"), (12, "A12"), (13, "A13-14"), (15, "A15-16"), (18, "Senior"))
user = models.OneToOneField(
User,
on_delete=models.SET_NULL,
related_name="gymnast",
blank=True,
null=True
User, on_delete=models.SET_NULL, related_name="gymnast", blank=True, null=True
)
last_name = models.CharField(max_length=40, null=False, blank=False)
first_name = models.CharField(max_length=25, null=False, blank=False)
@ -51,7 +48,9 @@ class Gymnast(Markdownizable):
# category = models.PositiveSmallIntegerField(
# choices=CATEGORY_CHOICES, verbose_name="Category"
# )
email_trainer = models.EmailField(max_length=254, null=True, blank=True, verbose_name="Trainer's email")
email_trainer = models.EmailField(
max_length=254, null=True, blank=True, verbose_name="Trainer's email"
)
trainings_by_week = models.PositiveSmallIntegerField(
verbose_name="# Training by week"
)
@ -248,7 +247,9 @@ class Gymnast(Markdownizable):
gymnast_nb_known_skills = self.known_skills.distinct("skill").count()
if skill_max > 0:
cpt_known_skill_by_type = self.nb_known_skill_by_type(desired_type) # à remonter ???
cpt_known_skill_by_type = self.nb_known_skill_by_type(
desired_type
) # à remonter ???
cpt_skill_by_type = nb_skill_by_type(skill_max, desired_type)
context["total_skill"] = nb_skill_lte_type(skill_max, desired_type)
context["percentages"] = compute_statistics_by_type(

View File

@ -18,7 +18,6 @@ class GymnastTestCase(TestCase):
)
self.assertEqual(gymnast.age, 36)
def test_gymnaste_get_next_age(self):
gymnast = Gymnast(
last_name="Pauchou",
@ -27,14 +26,15 @@ class GymnastTestCase(TestCase):
)
self.assertEqual(gymnast.next_age, 37)
def test_gymnaste_next_birthday(self):
gymnast = Gymnast(
last_name="Pauchou",
first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
)
self.assertEqual(gymnast.next_birthday, datetime.strptime("03/07/2022", "%d/%m/%Y"))
self.assertEqual(
gymnast.next_birthday, datetime.strptime("03/07/2022", "%d/%m/%Y")
)
def test_next_birthday_in_days(self):
gymnast = Gymnast(

View File

@ -4,14 +4,15 @@ from ultron.profiles.views import profile_update
class URLTestCase(TestCase):
def setUp(self):
# Every test needs access to the request factory.
# Every test needs access to the request factory.
self.factory = RequestFactory()
self.user = User.objects.create_user(username='test', email='test@gmail.com', password='top_secret')
self.user = User.objects.create_user(
username="test", email="test@gmail.com", password="top_secret"
)
def test_view_profile_update(self):
request = self.factory.get('/profile/edit/')
request = self.factory.get("/profile/edit/")
request.user = self.user
response = my_view(request)

View File

@ -54,5 +54,5 @@ class EventForm(forms.ModelForm):
"placeholder": "Searching place…",
"data-ref": "#id_place",
}
)
),
)

View File

@ -28,11 +28,11 @@ class EventType(models.Model):
"""
COLOR_CHOICES = (
(0, 'default'),
(1, 'azure'),
(2, 'green'),
(3, 'orange'),
(4, 'red'),
(0, "default"),
(1, "azure"),
(2, "green"),
(3, "orange"),
(4, "red"),
)
class Meta:

View File

@ -13,6 +13,7 @@ from .models import (
from .forms import EventForm
@login_required
@require_http_methods(["POST"])
def event_lookup(request):

View File

@ -1,4 +1,3 @@
from django import forms
from .models import Profile
@ -13,7 +12,9 @@ class ProfileForm(forms.ModelForm):
"is_sidebar_minified",
)
widgets = {
"template_color": forms.Select(attrs={"class": "form-control selectpicker"}),
"template_color": forms.Select(
attrs={"class": "form-control selectpicker"}
),
"sidebar_color": forms.Select(attrs={"class": "form-control selectpicker"}),
"is_sidebar_minified": forms.CheckboxInput(
attrs={

View File

@ -1,10 +1,10 @@
from django.test import TestCase
from django.urls import reverse, resolve
# from ultron.profiles.views import profile_update
class URLTestCase(TestCase):
def test_profile_url(self):
# self.assertEqual(reverse("profile_update"), profile_update())
@ -12,4 +12,4 @@ class URLTestCase(TestCase):
# response = self.client.get(url)
# self.assertEqual(response.status_code, 200)
self.assertEqual(resolve('/profile/edit/').view_name, 'profile_update')
self.assertEqual(resolve("/profile/edit/").view_name, "profile_update")

View File

@ -5,13 +5,14 @@ from django.contrib.auth.models import AnonymousUser, User
class ViewsTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.user = User.objects.create_user(username='test', email='test@gmail.com', password='top_secret')
self.user = User.objects.create_user(
username="test", email="test@gmail.com", password="top_secret"
)
def test_view_profile_update(self):
request = self.factory.get('/profile/edit/')
request = self.factory.get("/profile/edit/")
# request = self.client.get('/profile/edit/') ## Ne fonctionne pas à cause de whitenoise ?
# Not connected user
@ -35,5 +36,5 @@ class ViewsTestCase(TestCase):
# self.assertContains(response, 'font_awesome_all_5.15.3.css')
client = Client()
response = self.client.get('/profile/edit/')
response = self.client.get("/profile/edit/")
self.assertEqual(response.status_code, 200)

View File

@ -7,7 +7,7 @@ import pendulum
def from_week_number_to_date(season, week_number):
""" Renvoie la date du début de semaine (lundi) et la date de fin de semaine (dimanche) à
"""Renvoie la date du début de semaine (lundi) et la date de fin de semaine (dimanche) à
partir d'une saison et d'un numéro de semaine.
Args:
@ -39,10 +39,10 @@ def from_week_number_to_date(season, week_number):
week_string = "-W"
if week_number <= rest_of_week:
week_number += season_first_week - 1
year = first_year
year = first_year
else:
week_number -= rest_of_week
year = str(season[dash + 1:])
year = str(season[dash + 1 :])
if week_number - rest_of_week < 10:
week_string += "0"
@ -53,7 +53,7 @@ def from_week_number_to_date(season, week_number):
def from_date_to_week_number(the_date=None):
""" Renvoie le numéro de la semaine depuis le début de la saison.
"""Renvoie le numéro de la semaine depuis le début de la saison.
Une saison commence le 1er septembre.
La semaine contenant le 1er septembre est la semaine 1, même si le 1er septembre est un
diamnche.
@ -83,12 +83,12 @@ def from_date_to_week_number(the_date=None):
the_date = pendulum.parse(the_date.strftime("%Y%m%d"))
number_of_year_week = the_date.week_of_year
if the_date.month >= 9: # nouvelle saison
if the_date.month >= 9: # nouvelle saison
season = str(the_date.year) + "-" + str(the_date.year + 1)
begin_season = pendulum.date(the_date.year, 9, 1)
season_first_week = begin_season.week_of_year
number_of_season_week = number_of_year_week + 1 - season_first_week
else: # "ancienne" saison
else: # "ancienne" saison
season = str(the_date.year - 1) + "-" + str(the_date.year)
begin_season = pendulum.date(the_date.year - 1, 9, 1)
season_first_week = begin_season.week_of_year
@ -131,7 +131,7 @@ def get_number_of_weeks_between(first_date, second_date):
second = pendulum.parse(second_date.strftime("%Y%m%d"))
if first_date.year == second.year:
return (second.week_of_year - first.week_of_year)
return second.week_of_year - first.week_of_year
elif second_date.year > first_date.year:
return (52 - first.week_of_year) + second.week_of_year
else:

View File

@ -12,19 +12,21 @@ import markdown
import pendulum
import re
class Season:
""" Class pour représenter une saison """
"""Class pour représenter une saison"""
def __init__(self, label=None):
self.label = label
if not self.is_valid():
the_date = pendulum.today().date()
if the_date.month >= 9: # nouvelle saison
if the_date.month >= 9: # nouvelle saison
self.label = str(the_date.year) + "-" + str(the_date.year + 1)
else:
self.label = str(the_date.year - 1) + "-" + str(the_date.year)
def is_valid(self):
""" Test si une chaine de caractère correspond bien à une saison
"""Test si une chaine de caractère correspond bien à une saison
Args:
season string saison sous la forme "xxxx-xxxy"
@ -61,7 +63,7 @@ class Season:
return False
first_year = int(self.label[:dash_position])
second_year = int(self.label[dash_position + 1:])
second_year = int(self.label[dash_position + 1 :])
if first_year != second_year - 1:
return False
@ -75,6 +77,7 @@ def get_default_date():
class Seasonisable(models.Model):
""" """
class Meta:
abstract = True
@ -83,7 +86,7 @@ class Seasonisable(models.Model):
week_number = models.PositiveSmallIntegerField(editable=False)
def save(self, *args, **kwargs):
""" Calcule les valeurs `season` et `week_number` sur base d'une date lors de l'
"""Calcule les valeurs `season` et `week_number` sur base d'une date lors de l'
enregistrement d'un object enfant.
"""
if self.date is None:
@ -109,7 +112,9 @@ class TemporizableQuerySet(models.QuerySet):
:type limit: int
:return: une liste de `limit` éléments temporizables.
"""
return self.filter(date_begin__gte=timezone.now()).order_by("date_begin")[0:limit]
return self.filter(date_begin__gte=timezone.now()).order_by("date_begin")[
0:limit
]
def last(self, limit):
"""

View File

@ -92,7 +92,7 @@ class PDFDocument(object):
self.y = Y - X
def add_vspace(self, height=COMMON_LINE_HEIGHT):
""" Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
"""Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
Args:
height (int): hauteur de la ligne.
@ -129,7 +129,7 @@ class PDFDocument(object):
self.add_string(x, string, font_family, font_decoration, font_size)
def add_header(self, contract=None):
""" Génère le header du document.
"""Génère le header du document.
Args:
contract (contract): instance de la class Contract.
@ -137,37 +137,27 @@ class PDFDocument(object):
Returns:
ne retourne rien.
"""
self.document.setFillColorRGB(0.75,0.75,0.75)
self.document.setFillColorRGB(0.75, 0.75, 0.75)
self.add_vspace(15)
self.add_new_line(X, self.site_title + ' - ' + self.club_name)
self.add_new_line(X, self.site_title + " - " + self.club_name)
self.document.drawRightString(
RIGHT_X,
self.y,
self.address
+ " - "
+ self.zip
+ " "
+ self.city,
self.address + " - " + self.zip + " " + self.city,
)
self.add_new_line(
X,
"Head Coach : "
+ self.head_coach
)
self.document.drawRightString(
RIGHT_X,
self.y,
self.coach_email
)
self.add_new_line(X, "Head Coach : " + self.head_coach)
self.document.drawRightString(RIGHT_X, self.y, self.coach_email)
today = pendulum.now().date()
self.add_new_line(X, today.strftime("%d %B %Y"))
begin_season = date(today.year, 9, 1)
season, week_number = from_date_to_week_number()
self.document.drawRightString(RIGHT_X, self.y, "Season " + season + " - week " + str(week_number))
self.document.drawRightString(
RIGHT_X, self.y, "Season " + season + " - week " + str(week_number)
)
self.document.setFillColorRGB(0,0,0)
self.document.setFillColorRGB(0, 0, 0)
self.add_vspace(BIG_LINE_HEIGHT)
def download(self):
@ -178,7 +168,7 @@ class PDFDocument(object):
class GymnastReportDocument(PDFDocument):
def generate(self, gymnast_id):
""" Genère un document aux normes du SPF Finance.
"""Genère un document aux normes du SPF Finance.
Args:
accounting_year (int): année comptable.
@ -188,7 +178,7 @@ class GymnastReportDocument(PDFDocument):
"""
gymnast = Gymnast.objects.get(pk=gymnast_id)
self.document.setTitle(gymnast.first_name + ' ' + gymnast.last_name)
self.document.setTitle(gymnast.first_name + " " + gymnast.last_name)
self.add_header()
self.add_gymnast_personnal_information(gymnast)
@ -206,7 +196,7 @@ class GymnastReportDocument(PDFDocument):
self.add_planned_skills_details(plan_list)
def add_gymnast_personnal_information(self, gymnast):
""" Ajoute les informations personnelles du gymnast.
"""Ajoute les informations personnelles du gymnast.
Args:
gymnast <Gymnast>: gymnaste
@ -214,7 +204,7 @@ class GymnastReportDocument(PDFDocument):
Returns:
ne retourne rien.
"""
self.y = 26*cm
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)
@ -226,20 +216,14 @@ class GymnastReportDocument(PDFDocument):
)
self.document.setFillColorRGB(0.75, 0.75, 0.75)
self.add_new_line(
130,
str(gymnast.age)
)
self.add_new_line(130, str(gymnast.age))
self.document.setFillColorRGB(0, 0, 0)
if gymnast.informations:
self.add_new_line(
130,
str(gymnast.informations)
)
self.add_new_line(130, str(gymnast.informations))
def analyse_score(self, value, value_list):
""" Analyse une value (value) par rapport à la moyenne de value_list et à la dernière
"""Analyse une value (value) par rapport à la moyenne de value_list et à la dernière
valeur de value_list
Args:
@ -251,27 +235,27 @@ class GymnastReportDocument(PDFDocument):
Examples:
"""
res = ''
res = ""
mean_value = mean(value_list)
if value > value_list[-1]:
res += '+'
res += "+"
elif value < value_list[-1]:
res += '-'
res += "-"
else:
res += '='
res += "="
if value > mean_value:
res = '+' + res
res = "+" + res
elif value < mean_value:
res = '-' + res
res = "-" + res
else:
res = '=' + res
res = "=" + res
return res
def add_gymnast_physiological_information(self, gymnast):
""" Ajoute les informations physique et psychologique.
"""Ajoute les informations physique et psychologique.
Args:
gymnast <Gymnast>: gymnaste
@ -279,15 +263,15 @@ class GymnastReportDocument(PDFDocument):
Returns:
ne retourne rien
"""
self.y = 26*cm
self.y = 26 * cm
self.add_new_line(
13.5*cm,
13.5 * cm,
"Physics/Mind state",
font_decoration="Bold",
)
data = []
mindstate_queryset = MindState.objects.filter(gymnast=gymnast).order_by('-date')
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])
@ -297,10 +281,16 @@ class GymnastReportDocument(PDFDocument):
data.append(["Mind state", str(last_mindstate.score), res])
have_physiological = True
height_weight_queryset = HeightWeight.objects.filter(gymnast=gymnast).order_by('-date')
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])
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]
)
if lasts_height:
res = self.analyse_score(last_height_weigth.height, lasts_height)
@ -314,24 +304,24 @@ class GymnastReportDocument(PDFDocument):
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])
[
("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)
width, height = table.wrapOn(self.document, 19 * cm, 15.5 * cm)
table.drawOn(self.document, 13.3 * cm, self.y - height - 5)
else:
self.add_new_line(
13.5*cm,
"No recorded data.",
)
13.5 * cm,
"No recorded data.",
)
def add_gymnast_best_scores(self, gymnast):
""" Ajoute les meilleurs scores du gymnaste (Tof, compétition, …).
"""Ajoute les meilleurs scores du gymnaste (Tof, compétition, …).
Args:
gymnast <Gymnast>: gymnaste
@ -339,7 +329,7 @@ class GymnastReportDocument(PDFDocument):
Returns:
ne retourne rien
"""
self.y = 23*cm
self.y = 23 * cm
self.add_new_line(
X,
"Best ToF",
@ -356,7 +346,14 @@ class GymnastReportDocument(PDFDocument):
.first()
)
if best_tof:
data.append(["ToF |:", str(best_tof.tof), str(best_tof.score), "(" + best_tof.date.strftime("%d-%m-%Y") + ")"])
data.append(
[
"ToF |:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
]
)
has_score = True
best_tof = (
@ -366,7 +363,14 @@ class GymnastReportDocument(PDFDocument):
.first()
)
if best_tof:
data.append(["ToF R1:", str(best_tof.tof), str(best_tof.score), "(" + best_tof.date.strftime("%d-%m-%Y") + ")"])
data.append(
[
"ToF R1:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
]
)
has_score = True
best_tof = (
@ -376,18 +380,25 @@ class GymnastReportDocument(PDFDocument):
.first()
)
if best_tof:
data.append(["ToF R2:", str(best_tof.tof), str(best_tof.score), "(" + best_tof.date.strftime("%d-%m-%Y") + ")"])
data.append(
[
"ToF R2:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
]
)
has_score = True
if has_score:
style = TableStyle(
[
('TEXTCOLOR', (-1,0), (-1,-1), '#AAAAAA'),
("TEXTCOLOR", (-1, 0), (-1, -1), "#AAAAAA"),
]
)
table = Table(data)
table.setStyle(style)
width, height = table.wrapOn(self.document, 19*cm, 15*cm)
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(
@ -395,7 +406,7 @@ class GymnastReportDocument(PDFDocument):
"No chrono for this gymnast.",
)
self.y = 20*cm
self.y = 20 * cm
self.add_new_line(
X,
"Best Scores",
@ -404,7 +415,12 @@ class GymnastReportDocument(PDFDocument):
has_score = False
data = [["", "Exe.", "Diff.", "ToF", "HD", "Tot.", ""]]
best_point_routine_1 = Point.objects.filter(gymnast=gymnast).filter(routine_type=1).order_by('-total').first()
best_point_routine_1 = (
Point.objects.filter(gymnast=gymnast)
.filter(routine_type=1)
.order_by("-total")
.first()
)
if best_point_routine_1:
data.append(
[
@ -419,7 +435,12 @@ class GymnastReportDocument(PDFDocument):
)
has_score = True
best_point_routine_2 = Point.objects.filter(gymnast=gymnast).filter(routine_type=2).order_by('-total').first()
best_point_routine_2 = (
Point.objects.filter(gymnast=gymnast)
.filter(routine_type=2)
.order_by("-total")
.first()
)
if best_point_routine_2:
data.append(
[
@ -448,16 +469,16 @@ class GymnastReportDocument(PDFDocument):
if has_score:
style = TableStyle(
[
('ALIGN', (0,0), (-1,0), 'CENTER'),
('ALIGN', (1,1), (-1,-1), 'RIGHT'),
('TEXTCOLOR', (-1,0), (-1,-1), '#AAAAAA'),
("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)
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(
@ -468,74 +489,75 @@ class GymnastReportDocument(PDFDocument):
self.add_vspace(HUGE_LINE_HEIGHT)
def add_gymnast_active_routine(self, gymnast):
""" Ajoute les routines actives """
self.y = 23*cm
"""Ajoute les routines actives"""
self.y = 23 * cm
self.add_new_line(
15.9*cm,
15.9 * cm,
"Routines",
font_decoration="Bold",
)
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()
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()
)
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(
[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])
[
("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)
width, height = table.wrapOn(self.document, 19 * cm, 15 * cm)
table.drawOn(self.document, 13.5 * cm, self.y - height - 5)
else:
self.add_new_line(
14*cm,
"No compulsary"
)
self.add_new_line(
14*cm,
"routine defined."
)
self.add_new_line(14 * cm, "No compulsary")
self.add_new_line(14 * cm, "routine defined.")
self.add_vspace(-DOUBLE_LINE_HEIGHT)
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()
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()
)
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(
[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])
[
("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)
width, height = table.wrapOn(self.document, 19 * cm, 15.5 * cm)
table.drawOn(self.document, 17 * cm, self.y - height - 5)
else:
self.add_new_line(
17*cm,
"No volontary"
)
self.add_new_line(
17*cm,
"routine defined."
)
self.add_new_line(17 * cm, "No volontary")
self.add_new_line(17 * cm, "routine defined.")
def add_gymnast_last_learned_skill(self, gymnast):
""" Ajoute les derniers skill appris par le gymnaste
"""Ajoute les derniers skill appris par le gymnaste
Args:
gymnast <Gymnast> gymnaste
@ -544,9 +566,9 @@ class GymnastReportDocument(PDFDocument):
Ne retourne rien
"""
self.y = 17*cm
self.y = 17 * cm
self.add_new_line(
7.5*cm,
7.5 * cm,
"New learned skills",
font_decoration="Bold",
)
@ -558,23 +580,30 @@ class GymnastReportDocument(PDFDocument):
learned_skills = (
LearnedSkill.objects.filter(gymnast=gymnast.id)
.annotate(skill_notation=F("skill__notation"))
.order_by("skill_notation", "-date").distinct('skill_notation')[:5]
.order_by("skill_notation", "-date")
.distinct("skill_notation")[:5]
)
if learned_skills:
for learned_skill in learned_skills:
self.add_new_line(
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")
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"),
)
else:
self.add_new_line(
7.5*cm,
"No skill to learn this week.",
)
7.5 * cm,
"No skill to learn this week.",
)
def add_gymnast_planned_skill(self, gymnast):
""" Ajoute les prochains skill (skill planifié) à apprendre
"""Ajoute les prochains skill (skill planifié) à apprendre
Args:
gymnast <Gymnast> gymnaste
@ -583,7 +612,7 @@ class GymnastReportDocument(PDFDocument):
Ne retourne rien
"""
self.y = 17*cm
self.y = 17 * cm
self.add_new_line(
X,
"Next skills to learn",
@ -605,11 +634,9 @@ class GymnastReportDocument(PDFDocument):
plan_list = (
Plan.objects.filter(gymnast=gymnast, educative__in=(Skill.objects.all()))
.filter(
Q(is_done=False)
| Q(date__gte=date.today())
)
.order_by('educative', '-date').distinct()[:6]
.filter(Q(is_done=False) | Q(date__gte=date.today()))
.order_by("educative", "-date")
.distinct()[:6]
)
if plan_list:
@ -620,20 +647,27 @@ class GymnastReportDocument(PDFDocument):
# )
skill = Skill.objects.get(pk=plan.educative)
self.add_new_line(
X, plan.educative.short_label + " " + str(LEARNING_STEP_CHOICES[plan.learning_step][1]).lower() + " (" + skill.notation + ") for " + plan.date.strftime("%d-%m-%Y")
X,
plan.educative.short_label
+ " "
+ str(LEARNING_STEP_CHOICES[plan.learning_step][1]).lower()
+ " ("
+ skill.notation
+ ") for "
+ plan.date.strftime("%d-%m-%Y"),
)
else:
self.add_new_line(
X,
"No next skill to learn plannified.",
)
X,
"No next skill to learn plannified.",
)
print()
print()
return plan_list
def add_gymnast_next_events(self, gymnast):
""" Ajoute les évènements futurs du gymnaste """
self.y = 13.5*cm
"""Ajoute les évènements futurs du gymnaste"""
self.y = 13.5 * cm
self.add_new_line(
X,
"Next event",
@ -642,63 +676,72 @@ class GymnastReportDocument(PDFDocument):
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]
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])
data.append(
[
event.date_begin.strftime("%d-%m-%Y"),
"in " + str(event.number_of_week_from_today) + " week(s)",
event.name,
]
)
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])
[
("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)
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.",
)
X,
"No futur event associated to this gymnast.",
)
def add_gymnast_week_notes(self, gymnast):
""" Ajoute les notes de la semaine du gymnaste passé en paramètre """
"""Ajoute les notes de la semaine du gymnaste passé en paramètre"""
self.y = 8.8*cm
self.y = 8.8 * cm
self.add_new_line(
X,
"Notes",
font_decoration="Bold",
)
self.add_vspace(-2*cm)
self.add_vspace(-2 * cm)
today = pendulum.today().date()
begin_of_the_week = today
if today.weekday() != 0:
begin_of_the_week -= timedelta(today.weekday())
notes = gymnast.remarks.filter(created_at__gte=begin_of_the_week).filter(status=1)
notes = gymnast.remarks.filter(created_at__gte=begin_of_the_week).filter(
status=1
)
if notes:
html_text = ''
html_text = ""
for note in notes:
html_text += '<br />' + note.to_markdown()
html_text += "<br />" + note.to_markdown()
html_text = html_text[6:]
# print(html_text)
paragraph = Paragraph(html_text, self.style)
width, height = paragraph.wrap(18*cm, 10*cm)
width, height = paragraph.wrap(18 * cm, 10 * cm)
paragraph.drawOn(self.document, X, self.y - (height / 1.5))
else:
self.add_vspace(1.8*cm)
self.add_vspace(1.8 * cm)
self.add_new_line(
X,
"No note associated to this gymnast this week.",
@ -712,7 +755,7 @@ class GymnastReportDocument(PDFDocument):
"Points of attention",
font_decoration="Bold",
)
self.add_vspace(-0.5*cm)
self.add_vspace(-0.5 * cm)
for plan in plan_list:
if plan.informations:
@ -721,16 +764,22 @@ class GymnastReportDocument(PDFDocument):
print(planned_skill)
# Titre du skill
html_text = "<u>" + planned_skill.short_label + " (" + planned_skill.notation + ") :</u>"
html_text = (
"<u>"
+ planned_skill.short_label
+ " ("
+ planned_skill.notation
+ ") :</u>"
)
paragraph = Paragraph(html_text, self.style)
width, height = paragraph.wrap(18*cm, 10*cm)
width, height = paragraph.wrap(18 * cm, 10 * cm)
paragraph.drawOn(self.document, INDENTED_X, self.y)
self.add_vspace(- height - 0.5*cm)
self.add_vspace(-height - 0.5 * cm)
# Informations du skill pour le gymnaste
paragraph = Paragraph(plan.informations, self.style)
width, height = paragraph.wrap(18*cm, 10*cm)
width, height = paragraph.wrap(18 * cm, 10 * cm)
paragraph.drawOn(self.document, INDENTED_X, self.y)
self.add_vspace(- height)
self.add_vspace(-height)
self.add_vspace(-0.4*cm)
self.add_vspace(-0.4 * cm)

View File

@ -1,7 +1,7 @@
from django import template
register = template.Library()
register = template.Library()
@register.filter

View File

@ -1,7 +1,7 @@
from django import template
register = template.Library()
register = template.Library()
@register.filter

View File

@ -28,19 +28,19 @@ def menuitem(context, url, css_class, title):
title,
)
return format_html(
'<li><a href="{}"><i class="{}"></i><p>{}</p></a></li>',
url,
css_class,
title,
)
'<li><a href="{}"><i class="{}"></i><p>{}</p></a></li>',
url,
css_class,
title,
)
if context.request.path == url: # si le contexte est "/"
if context.request.path == url: # si le contexte est "/"
return format_html(
'<li class="active"><a href="{}"><i class="{}"></i><p>{}</p></a></li>',
url,
css_class,
title,
)
)
return format_html(
'<li><a href="{}"><i class="{}"></i><p>{}</p></a></li>',

View File

@ -14,29 +14,60 @@ import pendulum
class FunctionTestCase(TestCase):
def test_from_week_number_to_date(self):
timezone = pytz.timezone("UTC")
start_date = datetime(2022, 10, 3, 0, 0, 0, tzinfo=pytz.UTC)
end_date = datetime(2022, 10, 9, 0, 0, 0, tzinfo=pytz.UTC)
self.assertEqual(from_week_number_to_date("2022-2023", 6), (start_date, end_date))
self.assertEqual(
from_week_number_to_date("2022-2023", 6), (start_date, end_date)
)
start_date = datetime(2023, 1, 30, 0, 0, 0, tzinfo=pytz.UTC)
end_date = datetime(2023, 2, 5, 0, 0, 0, tzinfo=pytz.UTC)
self.assertEqual(from_week_number_to_date("2022-2023", 22), (start_date, end_date))
self.assertEqual(
from_week_number_to_date("2022-2023", 22), (start_date, end_date)
)
start_date = datetime(2023, 7, 3, 0, 0, 0, tzinfo=pytz.UTC)
end_date = datetime(2023, 7, 9, 0, 0, 0, tzinfo=pytz.UTC)
self.assertEqual(from_week_number_to_date("2022-2023", 44), (start_date, end_date))
self.assertEqual(
from_week_number_to_date("2022-2023", 44), (start_date, end_date)
)
def test_from_date_to_week_number(self):
self.assertEqual(from_date_to_week_number(pendulum.date(2022, 9, 1)), ("2022-2023", 1))
self.assertEqual(from_date_to_week_number(pendulum.date(2023, 2, 5)), ("2022-2023", 22))
self.assertEqual(from_date_to_week_number(pendulum.date(2023, 7, 5)), ("2022-2023", 44))
self.assertEqual(
from_date_to_week_number(pendulum.date(2022, 9, 1)), ("2022-2023", 1)
)
self.assertEqual(
from_date_to_week_number(pendulum.date(2023, 2, 5)), ("2022-2023", 22)
)
self.assertEqual(
from_date_to_week_number(pendulum.date(2023, 7, 5)), ("2022-2023", 44)
)
def test_get_number_of_weeks_between(self):
self.assertEqual(get_number_of_weeks_between(pendulum.date(2022, 9, 1), pendulum.date(2022, 9, 4)), 0)
self.assertEqual(get_number_of_weeks_between(pendulum.date(2022, 9, 1), pendulum.date(2023, 2, 5)), 22)
self.assertEqual(get_number_of_weeks_between(pendulum.date(2022, 9, 1), pendulum.date(2023, 7, 5)), 44)
self.assertEqual(get_number_of_weeks_between(pendulum.date(2023, 2, 5), pendulum.date(2023, 7, 5)), 22)
self.assertEqual(
get_number_of_weeks_between(
pendulum.date(2022, 9, 1), pendulum.date(2022, 9, 4)
),
0,
)
self.assertEqual(
get_number_of_weeks_between(
pendulum.date(2022, 9, 1), pendulum.date(2023, 2, 5)
),
22,
)
self.assertEqual(
get_number_of_weeks_between(
pendulum.date(2022, 9, 1), pendulum.date(2023, 7, 5)
),
44,
)
self.assertEqual(
get_number_of_weeks_between(
pendulum.date(2023, 2, 5), pendulum.date(2023, 7, 5)
),
22,
)

View File

@ -6,7 +6,6 @@ import pendulum
class ModelTestCase(TestCase):
def test_init_season(self):
season = Season("2022-2023")
self.assertEqual(season.is_valid(), True)

View File

@ -16,8 +16,14 @@ 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
from ultron.followup.models import (Accident, Chrono, HeightWeight, MindState,
Plan, Point)
from ultron.followup.models import (
Accident,
Chrono,
HeightWeight,
MindState,
Plan,
Point,
)
from ultron.objective.models import Skill
from ultron.people.models import Gymnast
from ultron.planning.models import Event
@ -63,7 +69,7 @@ class PDFDocument(object):
self.__load_config()
def __load_config(self):
""" Charge le contenu du fichier SITE_CONFIG.YAML qui contient les données relatives à
"""Charge le contenu du fichier SITE_CONFIG.YAML qui contient les données relatives à
l'ASBL.
"""
current_path = os.path.dirname(os.path.realpath(__file__))
@ -75,7 +81,7 @@ class PDFDocument(object):
print(exc)
def add_vspace(self, height=COMMON_LINE_HEIGHT):
""" Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
"""Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
Args:
height (int): hauteur de la ligne.
@ -112,7 +118,7 @@ class PDFDocument(object):
self.add_string(x, string, font_family, font_decoration, font_size)
def add_header(self, contract=None):
""" Génère le header du document.
"""Génère le header du document.
Args:
contract (contract): instance de la class Contract.
@ -120,9 +126,11 @@ class PDFDocument(object):
Returns:
ne retourne rien.
"""
self.document.setFillColorRGB(0.75,0.75,0.75)
self.document.setFillColorRGB(0.75, 0.75, 0.75)
self.add_vspace(15)
self.add_new_line(X, self.club_infos["SITE_TITLE"] + ' - ' + self.club_infos['CLUB_NAME'])
self.add_new_line(
X, self.club_infos["SITE_TITLE"] + " - " + self.club_infos["CLUB_NAME"]
)
self.document.drawRightString(
RIGHT_X,
self.y,
@ -133,24 +141,18 @@ class PDFDocument(object):
+ self.club_infos["CITY"],
)
self.add_new_line(
X,
"Head Coach : "
+ self.club_infos["HEAD_COACH"]
)
self.document.drawRightString(
RIGHT_X,
self.y,
self.club_infos["MOBILE_PHONE"]
)
self.add_new_line(X, "Head Coach : " + self.club_infos["HEAD_COACH"])
self.document.drawRightString(RIGHT_X, self.y, self.club_infos["MOBILE_PHONE"])
today = pendulum.now().date()
# print(today)
self.add_new_line(X, str(today))
begin_season = date(today.year, 9, 1)
self.document.drawRightString(RIGHT_X, self.y, "Week " + str(from_date_to_week_number()))
self.document.drawRightString(
RIGHT_X, self.y, "Week " + str(from_date_to_week_number())
)
self.document.setFillColorRGB(0,0,0)
self.document.setFillColorRGB(0, 0, 0)
self.add_vspace(BIG_LINE_HEIGHT)
def download(self):
@ -161,7 +163,7 @@ class PDFDocument(object):
class GymnastReportDocument(PDFDocument):
def generate(self, gymnast_id):
""" Genère un document aux normes du SPF Finance.
"""Genère un document aux normes du SPF Finance.
Args:
accounting_year (int): année comptable.
@ -171,7 +173,7 @@ class GymnastReportDocument(PDFDocument):
"""
gymnast = Gymnast.objects.get(pk=gymnast_id)
self.document.setTitle(gymnast.first_name + ' ' + gymnast.last_name)
self.document.setTitle(gymnast.first_name + " " + gymnast.last_name)
self.add_header()
self.add_gymnast_personnal_information(gymnast)
@ -184,7 +186,7 @@ class GymnastReportDocument(PDFDocument):
self.add_gymnast_week_notes(gymnast)
def add_gymnast_personnal_information(self, gymnast):
""" Ajoute les informations personnelles du gymnast.
"""Ajoute les informations personnelles du gymnast.
Args:
gymnast <Gymnast>: gymnaste
@ -192,7 +194,7 @@ class GymnastReportDocument(PDFDocument):
Returns:
ne retourne rien.
"""
self.y = 26*cm
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)
@ -204,19 +206,13 @@ class GymnastReportDocument(PDFDocument):
)
# self.add_vspace()
self.document.setFillColorRGB(0.75, 0.75, 0.75)
self.add_new_line(
130,
str(gymnast.age)
)
self.add_new_line(130, str(gymnast.age))
self.document.setFillColorRGB(0, 0, 0)
self.add_new_line(
130,
str(gymnast.informations)
)
self.add_new_line(130, str(gymnast.informations))
# self.add_vspace(HUGE_LINE_HEIGHT)
def analyse_score(self, value, value_list):
""" Analyse une value (value) par rapport à la moyenne de value_list et à la dernière
"""Analyse une value (value) par rapport à la moyenne de value_list et à la dernière
valeur de value_list
Args:
@ -228,27 +224,27 @@ class GymnastReportDocument(PDFDocument):
Examples:
"""
res = ''
res = ""
mean_value = mean(value_list)
if value > value_list[-1]:
res += '+'
res += "+"
elif value < value_list[-1]:
res += '-'
res += "-"
else:
res += '='
res += "="
if value > mean_value:
res = '+' + res
res = "+" + res
elif value < mean_value:
res = '-' + res
res = "-" + res
else:
res = '=' + res
res = "=" + res
return res
def add_gymnast_physiological_information(self, gymnast):
""" Ajoute les informations physique et psychologique.
"""Ajoute les informations physique et psychologique.
Args:
gymnast <Gymnast>: gymnaste
@ -256,25 +252,31 @@ class GymnastReportDocument(PDFDocument):
Returns:
ne retourne rien
"""
self.y = 26*cm
self.y = 26 * cm
self.add_new_line(
13.5*cm,
13.5 * cm,
"Physics/Mind state",
font_decoration="Bold",
)
data = []
mindstate_queryset = MindState.objects.filter(gymnast=gymnast).order_by('-date')
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])
res = self.analyse_score(last_mindstate.score, lasts_mindstate)
data.append(["Mind state", str(last_mindstate.score), res])
height_weight_queryset = HeightWeight.objects.filter(gymnast=gymnast).order_by('-date')
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])
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]
)
res = self.analyse_score(last_height_weigth.height, lasts_height)
data.append(["Height", str(last_height_weigth.height), res])
@ -283,22 +285,22 @@ class GymnastReportDocument(PDFDocument):
data.append(["Weight", str(last_height_weigth.weight), res])
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])
[
("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)
width, height = table.wrapOn(self.document, 19 * cm, 15.5 * cm)
table.drawOn(self.document, 13.3 * cm, self.y - height - 5)
# last_accident = Accident.objects.filter(gymnast=gymnast).order_by("-date").first()
# print(last_accident)
def add_gymnast_best_scores(self, gymnast):
""" Ajoute les meilleurs scores du gymnaste (Tof, compétition, …).
"""Ajoute les meilleurs scores du gymnaste (Tof, compétition, …).
Args:
gymnast <Gymnast>: gymnaste
@ -306,7 +308,7 @@ class GymnastReportDocument(PDFDocument):
Returns:
ne retourne rien
"""
self.y = 23*cm
self.y = 23 * cm
self.add_new_line(
X,
"Best ToF",
@ -320,7 +322,12 @@ class GymnastReportDocument(PDFDocument):
.first()
)
data = [
["ToF |:", str(best_tof.tof), str(best_tof.score), "(" + best_tof.date.strftime("%d-%m-%Y") + ")"],
[
"ToF |:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
],
]
best_tof = (
Chrono.objects.filter(gymnast=gymnast)
@ -328,26 +335,40 @@ class GymnastReportDocument(PDFDocument):
.order_by("-score")
.first()
)
data.append(["ToF R1:", str(best_tof.tof), str(best_tof.score), "(" + best_tof.date.strftime("%d-%m-%Y") + ")"])
data.append(
[
"ToF R1:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
]
)
best_tof = (
Chrono.objects.filter(gymnast=gymnast)
.filter(chrono_type=2)
.order_by("-score")
.first()
)
data.append(["ToF R2:", str(best_tof.tof), str(best_tof.score), "(" + best_tof.date.strftime("%d-%m-%Y") + ")"])
data.append(
[
"ToF R2:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
]
)
style = TableStyle(
[
('TEXTCOLOR', (-1,0), (-1,-1), '#AAAAAA'),
("TEXTCOLOR", (-1, 0), (-1, -1), "#AAAAAA"),
]
)
table = Table(data)
table.setStyle(style)
width, height = table.wrapOn(self.document, 19*cm, 15*cm)
width, height = table.wrapOn(self.document, 19 * cm, 15 * cm)
table.drawOn(self.document, X - 6, self.y - height - 5)
# self.add_vspace(self.y - height - 5)
self.y = 20*cm
self.y = 20 * cm
self.add_new_line(
X,
"Best Scores",
@ -355,7 +376,12 @@ class GymnastReportDocument(PDFDocument):
)
data = [["", "Exe.", "Diff.", "ToF", "HD", "Tot.", ""]]
best_point_routine_1 = Point.objects.filter(gymnast=gymnast).filter(routine_type=1).order_by('-total').first()
best_point_routine_1 = (
Point.objects.filter(gymnast=gymnast)
.filter(routine_type=1)
.order_by("-total")
.first()
)
if best_point_routine_1:
data.append(
[
@ -369,7 +395,12 @@ class GymnastReportDocument(PDFDocument):
]
)
best_point_routine_2 = Point.objects.filter(gymnast=gymnast).filter(routine_type=2).order_by('-total').first()
best_point_routine_2 = (
Point.objects.filter(gymnast=gymnast)
.filter(routine_type=2)
.order_by("-total")
.first()
)
if best_point_routine_2:
data.append(
[
@ -396,16 +427,16 @@ class GymnastReportDocument(PDFDocument):
style = TableStyle(
[
('ALIGN', (0,0), (-1,0), 'CENTER'),
('ALIGN', (1,1), (-1,-1), 'RIGHT'),
('TEXTCOLOR', (-1,0), (-1,-1), '#AAAAAA'),
("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)
width, height = table.wrapOn(self.document, 19 * cm, 15 * cm)
table.drawOn(self.document, X - 6, self.y - height - 5)
# routine_1 = gymnast.has_routine.prefetch_related("routine").filter(
@ -415,16 +446,26 @@ class GymnastReportDocument(PDFDocument):
self.add_vspace(HUGE_LINE_HEIGHT)
def add_gymnast_active_routine(self, gymnast):
""" Ajoute les routines actives """
self.y = 23*cm
"""Ajoute les routines actives"""
self.y = 23 * cm
self.add_new_line(
15.9*cm,
15.9 * cm,
"Routines",
font_decoration="Bold",
)
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()
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()
)
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()
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()
)
data = []
for routine_skill in routine_1.routine.skill_links.all():
@ -432,16 +473,16 @@ class GymnastReportDocument(PDFDocument):
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])
[
("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)
width, height = table.wrapOn(self.document, 19 * cm, 15 * cm)
table.drawOn(self.document, 13.5 * cm, self.y - height - 5)
data = []
for routine_skill in routine_2.routine.skill_links.all():
@ -449,19 +490,19 @@ class GymnastReportDocument(PDFDocument):
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])
[
("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)
width, height = table.wrapOn(self.document, 19 * cm, 15.5 * cm)
table.drawOn(self.document, 17 * cm, self.y - height - 5)
def add_gymnast_next_skills(self, gymnast):
""" Ajoute les prochains skill (skill planifié) à apprendre
"""Ajoute les prochains skill (skill planifié) à apprendre
Args:
gymnast <Gymnast> gymnaste
@ -470,7 +511,7 @@ class GymnastReportDocument(PDFDocument):
Ne retourne rien
"""
self.y = 17*cm
self.y = 17 * cm
self.add_new_line(
X,
"Next skills to learn",
@ -480,10 +521,7 @@ class GymnastReportDocument(PDFDocument):
planified_skills = (
Skill.objects.filter(plan__gymnast=gymnast.id)
.filter(
Q(plan__is_done=False)
| Q(plan__date__gte=date.today())
)
.filter(Q(plan__is_done=False) | Q(plan__date__gte=date.today()))
.order_by("-plan__date")[:6]
)
@ -499,12 +537,16 @@ class GymnastReportDocument(PDFDocument):
for planified_skill in planified_skills:
self.add_new_line(
X, planified_skill.skill.short_label + " (" + planified_skill.skill.notation + ") for (todo: compute deadline)"
X,
planified_skill.skill.short_label
+ " ("
+ planified_skill.skill.notation
+ ") for (todo: compute deadline)",
)
def add_gymnast_next_events(self, gymnast):
""" Ajoute les évènements futurs du gymnaste """
self.y = 13.5*cm
"""Ajoute les évènements futurs du gymnaste"""
self.y = 13.5 * cm
self.add_new_line(
X,
"Next event",
@ -513,39 +555,46 @@ class GymnastReportDocument(PDFDocument):
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]
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])
data.append(
[
event.date_begin.strftime("%d-%m-%Y"),
"in " + str(event.number_of_week_from_today) + " week(s)",
event.name,
]
)
if not data:
return
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])
[
("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)
width, height = table.wrapOn(self.document, 19 * cm, 15.5 * cm)
table.drawOn(self.document, X - 6, self.y - height - 5)
def add_gymnast_week_notes(self, gymnast):
""" Ajoute les notes de la semaine du gymnaste passé en paramètre """
"""Ajoute les notes de la semaine du gymnaste passé en paramètre"""
self.y = 10.3*cm
self.y = 10.3 * cm
self.add_new_line(
X,
"Notes",
font_decoration="Bold",
)
self.add_vspace(-2*cm)
self.add_vspace(-2 * cm)
today = pendulum.today().date()
begin_week = today
@ -554,13 +603,13 @@ class GymnastReportDocument(PDFDocument):
notes = gymnast.remarks.filter(created_at__gte=begin_week)
html_text = ''
html_text = ""
for note in notes:
html_text += '<br />' + note.to_markdown()
html_text += "<br />" + note.to_markdown()
html_text = html_text[6:]
print(html_text)
paragraph = Paragraph(html_text, self.style, bulletText='*')
width, height = paragraph.wrap(18*cm, 18*cm)
paragraph = Paragraph(html_text, self.style, bulletText="*")
width, height = paragraph.wrap(18 * cm, 18 * cm)
paragraph.drawOn(self.document, X, self.y)