Black formatting
This commit is contained in:
parent
b84017614f
commit
a4fd5c4350
|
@ -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()
|
||||
|
|
|
@ -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),
|
||||
]
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
)
|
||||
),
|
||||
)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
from django.db import models
|
||||
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"),
|
||||
]
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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={
|
||||
|
|
|
@ -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 d’une figure est calculé par rapport aux prérequis : par
|
||||
défaut le niveau d’une 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 d’une figure est calculé par rapport aux prérequis : par défaut le niveau
|
||||
d’une figure est égal au niveau maximum de ses prérequis.
|
||||
Le niveau, avec le rang, ont pour but d’aider les coaches à planifier l’évolution et
|
||||
l’apprentissage des figures les unes par rapport aux autres.
|
||||
|
||||
|
|
|
@ -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],
|
||||
],
|
||||
)
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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",
|
||||
)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -54,5 +54,5 @@ class EventForm(forms.ModelForm):
|
|||
"placeholder": "Searching place…",
|
||||
"data-ref": "#id_place",
|
||||
}
|
||||
)
|
||||
),
|
||||
)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -13,6 +13,7 @@ from .models import (
|
|||
|
||||
from .forms import EventForm
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def event_lookup(request):
|
||||
|
|
|
@ -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={
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django import template
|
||||
|
||||
|
||||
register = template.Library()
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django import template
|
||||
|
||||
|
||||
register = template.Library()
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
|
|
|
@ -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>',
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -6,7 +6,6 @@ import pendulum
|
|||
|
||||
|
||||
class ModelTestCase(TestCase):
|
||||
|
||||
def test_init_season(self):
|
||||
season = Season("2022-2023")
|
||||
self.assertEqual(season.is_valid(), True)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue