From 8e192e1c1169076e6d808adc8df68868c848110b Mon Sep 17 00:00:00 2001 From: Gregory Trullemans Date: Thu, 21 Mar 2024 17:30:24 +0100 Subject: [PATCH] [WIP] Training & more --- jarvis/objective/admin.py | 147 ++++-- jarvis/objective/forms.py | 158 +++--- jarvis/objective/models.py | 494 ++++++++++-------- jarvis/objective/signals.py | 11 + .../details.html | 26 +- .../{passes => trainingrounds}/create.html | 6 +- .../{passes => trainingrounds}/details.html | 42 +- .../{passes => trainingrounds}/list.html | 0 jarvis/objective/tests_models.py | 124 ++--- jarvis/objective/urls.py | 56 +- jarvis/objective/views.py | 291 +++++------ .../tabs/tab_intensity_and_chronos.html | 6 +- jarvis/people/views.py | 11 +- 13 files changed, 726 insertions(+), 646 deletions(-) create mode 100644 jarvis/objective/signals.py rename jarvis/objective/templates/{trainingprograms => gymnasttrainings}/details.html (76%) rename jarvis/objective/templates/{passes => trainingrounds}/create.html (93%) rename jarvis/objective/templates/{passes => trainingrounds}/details.html (65%) rename jarvis/objective/templates/{passes => trainingrounds}/list.html (100%) diff --git a/jarvis/objective/admin.py b/jarvis/objective/admin.py index 287696c..6d784a2 100644 --- a/jarvis/objective/admin.py +++ b/jarvis/objective/admin.py @@ -7,16 +7,24 @@ from django_admin_listfilter_dropdown.filters import ( ) from .models import ( - TouchPosition, Skill, - # Passe, Routine, + Educative, RoutineSkill, - # TrainingProgram, + TouchPosition, + TrainingRound, + GymnastTraining, PrerequisiteClosure, + GymnastTrainingRound, ) +# @admin.register(Educative) +# class EducativeAdmin(admin.ModelAdmin): +# model = Educative +# list_display = ("long_label", "short_label", "difficulty", "level", "rank") + + @admin.register(TouchPosition) class TouchPositionAdmin(admin.ModelAdmin): model = TouchPosition @@ -194,57 +202,94 @@ class PrerequisiteClosureAdmin(admin.ModelAdmin): ) -# @admin.register(Passe) -# class PasseAdmin(admin.ModelAdmin): -# model = Passe +@admin.register(TrainingRound) +class TrainingRoundAdmin(admin.ModelAdmin): + model = TrainingRound -# fields = ( -# "label", -# "educatives", -# "regexp", -# "number_of_skill", -# "difficulty", -# "informations", -# ) + fields = ( + "label", + "educatives", + "regexp", + "number_of_skill", + "difficulty", + "informations", + ) -# list_display = ("label", "regexp", "number_of_skill", "difficulty") -# list_filter = ( -# ("number_of_skill", DropdownFilter), -# ("difficulty", DropdownFilter), -# ) -# filter_horizontal = ("educatives",) + list_display = ("label", "regexp", "number_of_skill", "difficulty") + list_filter = ( + ("number_of_skill", DropdownFilter), + ("difficulty", DropdownFilter), + ) + filter_horizontal = ("educatives",) -# class Media: -# js = ( -# "js/core/jquery-3.6.0.min.js", -# "js/admin/passe.js", -# ) + # def save_model(self, request, obj, form, change): + # if obj.educatives: + # form.cleaned_data["educatives"] = obj.educatives.all().values_list( + # "id", flat=True + # ) + + # super(TrainingRoundAdmin, self).save_model(request, obj, form, change) + + class Media: + js = ( + "js/core/jquery-3.6.0.min.js", + "js/admin/passe.js", + ) -# @admin.register(TrainingProgram) -# class TrainingProgramAdmin(admin.ModelAdmin): -# model = TrainingProgram +@admin.register(GymnastTraining) +class GymnastTrainingAdmin(admin.ModelAdmin): + model = GymnastTraining -# fields = ( -# "gymnast", -# "date", -# "rank", -# "passe", -# "repetition", -# "number_of_skill", -# "difficulty", -# # "score", -# ) -# list_display = ( -# "date", -# "gymnast", -# "passe", -# "rank", -# "repetition", -# "number_of_skill", -# "difficulty", -# ) -# list_filter = ( -# ("gymnast", RelatedDropdownFilter), -# ("date", DropdownFilter), -# ) + fields = ( + "label", + "date", + "gymnast", + # "trainingrounds", + "difficulty", + "number_of_skill", + "score", + ) + + list_display = ( + "label", + "date", + "gymnast", + # "trainingrounds", + "difficulty", + "number_of_skill", + "score", + ) + + list_filter = ( + ("gymnast", RelatedDropdownFilter), + ("trainingrounds", RelatedDropdownFilter), + ) + + +@admin.register(GymnastTrainingRound) +class GymnastTrainingRoundAdmin(admin.ModelAdmin): + model = TrainingRound + + fields = ( + "gymnast_training", + "training_round", + "repetition", + "rank", + "number_of_skill", + "score", + "difficulty", + ) + list_display = ( + "gymnast_training", + "training_round", + "repetition", + "rank", + "number_of_skill", + "score", + "difficulty", + ) + list_filter = ( + ("gymnast_training", RelatedDropdownFilter), + ("training_round", RelatedDropdownFilter), + ) diff --git a/jarvis/objective/forms.py b/jarvis/objective/forms.py index b271b79..0311533 100644 --- a/jarvis/objective/forms.py +++ b/jarvis/objective/forms.py @@ -9,7 +9,7 @@ from .models import ( Skill, Routine, RoutineSkill, - # Passe, + TrainingRound, ) @@ -74,87 +74,101 @@ class CombinationSkillForm(forms.ModelForm): } -# class PasseForm(forms.ModelForm): +class TrainingRoundForm(forms.ModelForm): -# educatives = forms.ModelMultipleChoiceField( -# required=False, -# queryset=Educative.objects.all(), -# widget=FilteredSelectMultiple("Educatives", is_stacked=False), -# # widget=customFilteredSelectMultiple(verbose_name='test2',is_stacked=False) -# ) + educatives = forms.ModelMultipleChoiceField( + required=False, + queryset=Educative.objects.all(), + widget=FilteredSelectMultiple("Educatives", is_stacked=False), + # widget=customFilteredSelectMultiple(verbose_name='test2',is_stacked=False) + ) -# class Media: -# css = { -# "all": ["admin/css/widgets.css"], -# } -# # Adding this javascript is crucial -# js = ["/admin/jsi18n/"] + class Media: + css = { + "all": ["admin/css/widgets.css"], + } + # Adding this javascript is crucial + js = ["/admin/jsi18n/"] -# class Meta: -# model = Passe -# fields = ("label", "regexp", "educatives", "informations") + class Meta: + model = TrainingRound + fields = ("label", "regexp", "educatives", "informations") -# widgets = { -# "label": forms.TextInput( -# attrs={ -# "class": "form-control", -# "placeholder": "Label (not mandatory)", -# "maxlength": 30, -# } -# ), -# "regexp": forms.TextInput( -# attrs={"class": "form-control", "placeholder": "[2-8]"} -# ), -# "informations": forms.Textarea( -# attrs={ -# "class": "form-control", -# "placeholder": "Informations about the passe…", # pylint: disable=line-too-long -# } -# ), -# } + widgets = { + "label": forms.TextInput( + attrs={ + "class": "form-control", + "placeholder": "Label (not mandatory)", + "maxlength": 30, + } + ), + "regexp": forms.TextInput( + attrs={"class": "form-control", "placeholder": "[2-8]"} + ), + "informations": forms.Textarea( + attrs={ + "class": "form-control", + "placeholder": "Informations about the passe…", # pylint: disable=line-too-long + } + ), + } -# def clean_regexp(self): -# """Vérifie que la regexp entrée par l'utilisateur est valide.""" -# regexp = self.cleaned_data["regexp"] -# if not Passe.is_valid_regexp(regexp): -# raise ValidationError("Entered regexp not valid.") + def clean_regexp(self): + """Vérifie que la regexp entrée par l'utilisateur est valide.""" + regexp = self.cleaned_data["regexp"] + if not TrainingRound.is_valid_regexp(regexp): + raise ValidationError("Entered regexp not valid.") -# return regexp + return regexp -# def clean(self): -# """Vérifie le contenu des champs `educatives` par rapport à la valeur de `regexp`. Si -# `regexp` est définie par : -# - valeurs de ROUTINE_TYPE_CHOICE il faut que Educatives soit VIDE -# - avec [x-y] -# - [x-y] " Educatives soit NON VIDE -# - WC " il y ait 2+ Educatives -# - x| " il y ait 1! Educatives -# """ -# cleaned_data = super().clean() -# regexp = ["regexp"] + def clean(self): + """Vérifie le contenu des champs `educatives` par rapport à la valeur de `regexp`. Si + `regexp` est définie par : + - valeurs de ROUTINE_TYPE_CHOICE il faut que Educatives soit VIDE + - avec [x-y] + - [x-y] " Educatives soit NON VIDE + - WC " il y ait 2+ Educatives + - x| " il y ait 1! Educatives + """ + cleaned_data = super().clean() + regexp = cleaned_data["regexp"] -# if regexp is not None: -# arguments = regexp.split(" ") -# educatives = cleaned_data["educatives"] + if regexp is not None: + # print + arguments = regexp.split(" ") + educatives = cleaned_data["educatives"] + print("----------------------------------------------------------------") + print(educatives) + print("----------------------------------------------------------------") -# if Passe.is_valid_routine_type(arguments[0]) and educatives is not None: -# raise ValidationError( -# "Educatives must be empty with the entered Regexp." -# ) + if TrainingRound.is_valid_routine_type(arguments[0]) and educatives: + raise ValidationError( + "Educatives must be empty with the entered Regexp." + ) -# if Passe.is_valid_subset(arguments[0]) and educatives is None: -# raise ValidationError( -# "Educatives can't be empty with the entered Regexp." -# ) + if TrainingRound.is_valid_subset(arguments[0]) and educatives is None: + raise ValidationError( + "Educatives can't be empty with the entered Regexp." + ) -# if re.match(r"[1-9]+\|", arguments[0]) and len(educatives) != 1: -# raise ValidationError( -# "One and only one Educatives allowed with the entered Regexp." -# ) + if re.match(r"[1-9]+\|", arguments[0]) and len(educatives) != 1: + raise ValidationError( + "One and only one Educatives allowed with the entered Regexp." + ) -# if arguments[0] == "WC" and (educatives is None or len(educatives) < 2): -# raise ValidationError( -# "At least two Educatives with the entered Regexp." -# ) + if arguments[0] == "WC" and (educatives is None or len(educatives) < 2): + raise ValidationError( + "At least two Educatives with the entered Regexp." + ) -# return cleaned_data + return cleaned_data + + # def save_model(self, request, obj, form, change): + # obj.save() + # for educative in form.cleaned_data["educatives"]: + # print(educative) + # book = Book.objects.get(pk=bk.id) + # book.quantity -= 1 + # if book.quantity == 0: + # book.sold = True; + # book.save() diff --git a/jarvis/objective/models.py b/jarvis/objective/models.py index eacdd0b..7ca8fd5 100644 --- a/jarvis/objective/models.py +++ b/jarvis/objective/models.py @@ -1,4 +1,4 @@ -from django.db import models +from django.db import models, transaction from django.db.models import Q import re @@ -8,6 +8,7 @@ from jarvis.tools.models import ( Seasonisable, max_even_if_none, ) +from .signals import * # from jarvis.followup.models import ROUTINE_TYPE_CHOICE @@ -466,281 +467,316 @@ class RoutineSkill(models.Model): return f"{self.rank} - {self.routine.short_label} : {self.skill.short_label}" -# class TrainingRound(Markdownizable): -# """Classe représentant les passages (à faire pendant un entraînement).""" +class TrainingRound(Markdownizable): + """Classe représentant les passages (à faire pendant un entraînement).""" -# class Meta: -# ordering = [ -# "label", -# ] + class Meta: + ordering = [ + "label", + ] -# label = models.CharField(max_length=30) -# educatives = models.ManyToManyField( -# Educative, related_name="passes", blank=True, symmetrical=False -# ) -# regexp = models.CharField(max_length=50, null=True, blank=True) -# number_of_skill = models.PositiveSmallIntegerField(default=0) -# difficulty = models.DecimalField(max_digits=4, decimal_places=1, default=0.0) -# # TODO: number_of_skill doit être calculé correctement dans tous les cas. + label = models.CharField(max_length=30) + educatives = models.ManyToManyField( + Educative, related_name="trainingrounds", blank=True, symmetrical=False + ) + regexp = models.CharField(max_length=50, null=True, blank=True) + number_of_skill = models.PositiveSmallIntegerField(default=0) + difficulty = models.DecimalField(max_digits=4, decimal_places=1, default=0.0) -# def save(self, *args, **kwargs): -# """Sauve les informations de la personne et initialise les champs nettoyés. -# On part du principe que self.regexp est correct. -# """ -# self.difficulty = 0 -# self.number_of_skill = 0 -# super().save(*args, **kwargs) -# # print("Dans le save") + @staticmethod + def number_of_skill_from_subset(subset, educative=None): + """ """ + if not TrainingRound.is_valid_subset(subset): + return 0, 0, 0 -# if self.educatives.count() == 0: -# # print("educative is none") -# present = False -# operation_list = self.regexp.split(" ") -# for item in ROUTINE_TYPE_CHOICE: -# if item[1] == operation_list[0]: -# present = True -# break + subset = subset.replace("[", "").replace("]", "") + ranks = subset.split("-") -# if present and len(operation_list) == 2: -# # print("present") -# content = operation_list[1].replace("[", "").replace("]", "") -# ranks = content.split("-") + if ranks[0] == "": + start = 0 + else: + start = int(ranks[0]) -# if ranks[0] == "": -# self.number_of_skill += int(ranks[1]) -# elif ranks[1] == "": -# self.number_of_skill += (10 - int(ranks[0])) + 1 -# else: -# self.number_of_skill += (int(ranks[1]) - int(ranks[0])) + 1 -# else: -# self.number_of_skill += 10 + if ranks[1] == "": + if educative is not None: + end = educative.jumps.all().count() + else: + end = 10 + else: + end = int(ranks[1]) -# else: -# for educative in self.educatives.all(): -# is_skill = False -# try: -# educative = Routine.objects.get(pk=educative) -# except Routine.DoesNotExist: -# educative = Skill.objects.get(pk=educative) -# is_skill = True + number_of_skill = (end - start) + 1 -# if is_skill: -# self.difficulty += educative.difficulty -# self.number_of_skill += 1 -# else: -# if self.regexp is not None: -# regexp = self.regexp.replace("[", "").replace("]", "") -# position = regexp.find("-") + return start, end, number_of_skill -# start = regexp[:position] -# if start == "": -# start = 0 -# else: -# start = int(start) + @staticmethod + def difficulty_from_regexp(educative, start, end): + """ """ + difficulty = 0 + list_of_skill = educative.skill_links.filter(rank__gte=start, rank__lte=end) + # .aggregate(total=Sum("value")) -# end = regexp[position + 1 :] -# if end == "": -# end = educative.jumps.all().count() -# else: -# end = int(end) + for routine_skill in list_of_skill: + difficulty += routine_skill.skill.difficulty -# self.number_of_skill += end - (start - 1) -# list_of_skill = educative.skill_links.filter( -# rank__gte=start, rank__lte=end -# ) -# # .aggregate(total=Sum("value")) -# tmp_difficulty = 0 -# for routine_skill in list_of_skill: -# tmp_difficulty += routine_skill.skill.difficulty -# self.difficulty += tmp_difficulty + return difficulty -# else: -# self.number_of_skill += educative.jumps.all().count() -# self.difficulty += educative.difficulty + def update_traininground(self): + """Update `number_of_skill` et `difficulty`. + S'il n'y a pas d'educatives, la difficulté ne peut pas être calculée. + """ + difficulty = 0 + number_of_skill = 0 -# super().save(*args, **kwargs) + if self.educatives.count() == 0: + operation_list = self.regexp.split(" ") -# def __str__(self): -# return f"{self.label} ({self.number_of_skill} | {self.difficulty})" + if len(operation_list) == 2: + _, _, number_of_skill = TrainingRound.number_of_skill_from_subset( + operation_list[1] + ) + else: + number_of_skill += 10 -# @staticmethod -# def is_valid_regexp_one_arg(arg): -# """Vérifie une regexp avec un paramètre.""" -# if arg == "WC": -# return True + else: + for educative in self.educatives.all(): + is_skill = False -# if re.match(r"[1-9]+\|", arg): -# return True + try: + educ = Routine.objects.get(pk=educative) + except Routine.DoesNotExist: + educ = Skill.objects.get(pk=educative) + is_skill = True -# if not TrainingRound.is_valid_dot(arg): -# return False + if is_skill: + difficulty += educ.difficulty + number_of_skill += 1 + elif ( + self.regexp is not None + and self.regexp != "WC" + and not re.match(r"[1-9]+\|", self.regexp) + ): + ( + start, + end, + number_of_skill, + ) = TrainingRound.number_of_skill_from_subset(self.regexp) + difficulty = TrainingRound.difficulty_from_regexp(educ, start, end) -# value = arg.replace(".", "") -# is_valid_routine = TrainingRound.is_valid_routine_type(value) + else: + number_of_skill += educ.jumps.all().count() + difficulty += educ.difficulty -# if is_valid_routine: -# return True + self.difficulty = difficulty + self.number_of_skill = number_of_skill + self.save() -# return TrainingRound.is_valid_subset(arg) + # def save(self, *args, **kwargs): + # """Sauve les informations de la personne et initialise les champs nettoyés. + # On part du principe que self.regexp est correct. -# @staticmethod -# def is_valid_regexp_two_args(arg1, arg2): -# """Vérifie une regexp avec deux paramètres.""" -# if not TrainingRound.is_valid_dot(arg1): -# return False + # https://stackoverflow.com/questions/13751217/can-the-super-save-method-be-used-several-times-in-a-model + # """ + # # print("Object:" + str(self)) + # instance = super().save(*args, **kwargs) + # # print("Calling update_fileds on commit transaction.") + # transaction.on_commit(self.update_fields) + # # print("Fields updated.") + # return instance -# value = arg1.replace(".", "") -# is_valid_routine = TrainingRound.is_valid_routine_type(value) + def __str__(self): + return f"{self.label} ({self.number_of_skill} | {self.difficulty})" -# if is_valid_routine: -# return TrainingRound.is_valid_subset(arg2) + def is_regexp_wc(self): + """ """ + return self.regexp == "WC" -# return False + @staticmethod + def is_valid_regexp_one_arg(regexp): + """Vérifie une regexp avec un paramètre.""" + if regexp == "WC": + return True -# @staticmethod -# def is_valid_dot(pattern): -# """Reçoit une chaine de caratère et vérifie que si elle contient un point (.), il se trouve -# soit à la première position soit à la dernière position. -# """ -# if len(re.findall("\.", pattern)) > 1: -# return False + if re.match(r"[1-9]+\|", regexp): + return True -# if re.search("\.", pattern): -# last_place = len(pattern) - 1 -# if pattern[0] != "." and pattern[last_place] != ".": -# return False + if not TrainingRound.is_valid_dot(regexp): + return False -# return True + value = regexp.replace(".", "") + is_valid_routine = TrainingRound.is_valid_routine_type(value) -# @staticmethod -# def is_valid_routine_type(routine_type): -# """Recoit une chaine de caractère et vérifie si elle est présente dans la liste -# ROUTINE_TYPE_CHOICE (Educative vide !) -# """ -# is_valid = False -# for item in ROUTINE_TYPE_CHOICE: -# if item[1] == routine_type: -# is_valid = True -# break + if is_valid_routine: + return True -# return is_valid + return TrainingRound.is_valid_subset(regexp) -# @staticmethod -# def is_valid_subset(subset): -# """Reçoit la description d'un subset sous forme de string et vérifie qu'elle est conforme. + @staticmethod + def is_valid_regexp_two_args(arg1, arg2): + """Vérifie une regexp avec deux paramètres.""" + if not TrainingRound.is_valid_dot(arg1): + return False -# Format attendu : [X-Y] -# X ou Y peuvent être vide mais pas en même temps. -# X est un entier >= 2 -# Y est un entier >= 2 OU Y > X si X est non vide + value = arg1.replace(".", "") + is_valid_routine = TrainingRound.is_valid_routine_type(value) -# Exemples : -# - [2-8] True -# - [-5] True -# - [3-] True -# - [8-2] False -# - [4--8] False -# - [-] False -# - [1-] False -# - [-1] False -# - [4] False -# - [6-6] False -# """ -# if re.match(r"^\[(([2-9]+\-{1})|([2-9]+\-{1}[2-9]+)|(\-{1}[2-9]+))\]$", subset): -# value = subset.replace("[", "").replace("]", "") -# ranks = value.split("-") + if is_valid_routine: + return TrainingRound.is_valid_subset(arg2) -# if ranks[0] == "" or ranks[1] == "": -# return True + return False -# if int(ranks[0]) < int(ranks[1]): -# return True + @staticmethod + def is_valid_dot(pattern): + """Reçoit une chaine de caratère et vérifie que si elle contient un point (.), il se trouve + soit à la première position soit à la dernière position. + """ + if len(re.findall("\.", pattern)) > 1: + return False -# return False + if re.search("\.", pattern): + last_place = len(pattern) - 1 + if pattern[0] != "." and pattern[last_place] != ".": + return False -# @staticmethod -# def is_valid_regexp(regexp): -# """Vérifie le champ regexp + return True -# Exemples : -# - Q1R1 True -# - Q1R2 [2-8] True -# - Q2R1 [-5] True -# - SF [6-] True -# - FS [3-7] True -# - Q1R1. True -# - .Q1R2 True -# - Q1R1. [-4] True -# - .Q1R2 [4-] True -# - .FS [3-7] True -# - [2-8] True -# - [-5] True -# - WC True -# - 1| True -# """ -# argument_list = regexp.split(" ") + @staticmethod + def is_valid_routine_type(routine_type): + """Recoit une chaine de caractère et vérifie si elle est présente dans la liste + ROUTINE_TYPE_CHOICE (Educative vide !) + """ + is_valid_routine = False + for item in ROUTINE_TYPE_CHOICE: + if item[1] == routine_type: + is_valid_routine = True + break -# if len(argument_list) >= 3: -# return False + return is_valid_routine -# if len(argument_list) == 2: -# return TrainingRound.is_valid_regexp_two_args( -# argument_list[0], argument_list[1] -# ) -# else: -# return TrainingRound.is_valid_regexp_one_arg(argument_list[0]) + @staticmethod + def is_valid_subset(subset): + """Reçoit la description d'un subset sous forme de string et vérifie qu'elle est conforme. -# return False + Format attendu : [X-Y] + X ou Y peuvent être vide mais pas en même temps. + X est un entier >= 2 + Y est un entier >= 2 OU Y > X si X est non vide + + Exemples : + - [2-8] True + - [-5] True + - [3-] True + - [8-2] False + - [4--8] False + - [-] False + - [1-] False + - [-1] False + - [4] False + - [6-6] False + """ + if re.match(r"^\[(([2-9]+\-{1})|([2-9]+\-{1}[2-9]+)|(\-{1}[2-9]+))\]$", subset): + value = subset.replace("[", "").replace("]", "") + ranks = value.split("-") + + if ranks[0] == "" or ranks[1] == "": + return True + + if int(ranks[0]) < int(ranks[1]): + return True + + return False + + @staticmethod + def is_valid_regexp(regexp): + """Vérifie le champ regexp + + Exemples : + - "" True + - Q1R1 True + - Q1R2 [2-8] True + - Q2R1 [-5] True + - SF [6-] True + - FS [3-7] True + - Q1R1. True + - .Q1R2 True + - Q1R1. [-4] True + - .Q1R2 [4-] True + - .FS [3-7] True + - [2-8] True + - [-5] True + - WC True + - 1| True + """ + if regexp == "" or regexp is None: + return True + + print("---" + regexp + "---") + + argument_list = regexp.split(" ") + + if len(argument_list) >= 3: + return False + + if len(argument_list) == 2: + return TrainingRound.is_valid_regexp_two_args( + argument_list[0], argument_list[1] + ) + else: + return TrainingRound.is_valid_regexp_one_arg(argument_list[0]) + + return False -# class GymnastTraining(Seasonisable, Markdownizable): -# """Classe représentant un entraînement.""" +class GymnastTraining(Seasonisable, Markdownizable): + """Classe représentant un entraînement.""" -# label = models.CharField() -# gymnast = models.ForeignKey("people.Gymnast", on_delete=models.CASCADE) -# training_rounds = models.ManyToManyField( -# TrainingRound, through="GymnastTrainingRound", verbose_name="trainings" -# ) -# difficulty = models.DecimalField(max_digits=4, decimal_places=1, default=0.0) -# number_of_skill = models.PositiveSmallIntegerField(default=0) -# score = models.PositiveSmallIntegerField(default=1) + label = models.CharField() + gymnast = models.ForeignKey( + "people.Gymnast", + on_delete=models.CASCADE, + related_name="trainings", + ) + trainingrounds = models.ManyToManyField( + TrainingRound, through="GymnastTrainingRound", verbose_name="trainings" + ) + difficulty = models.DecimalField(max_digits=4, decimal_places=1, default=0.0) + number_of_skill = models.PositiveSmallIntegerField(default=0) + score = models.PositiveSmallIntegerField(default=1) -# def __str__(self): -# return f"Training on {self.date} for {self.gymnast}: {self.number_of_skill} | {self.difficulty}" + def __str__(self): + return f"Training on {self.date} for {self.gymnast}: {self.number_of_skill} | {self.difficulty}" -# class GymnastTrainingRound(Markdownizable): -# """Classe représentant un passage.""" +class GymnastTrainingRound(Markdownizable): + """Classe représentant un passage.""" -# class Meta: -# verbose_name = "Gymnast Training Round" -# verbose_name_plural = "Gymnast Training Rounds" -# ordering = [ -# "rank", -# ] -# unique_together = ["gymnast_training", "rank"] + class Meta: + verbose_name = "Gymnast Training Round" + verbose_name_plural = "Gymnast Training Rounds" + ordering = [ + "rank", + ] + unique_together = ["gymnast_training", "rank"] -# gymnast_training = models.ForeignKey( -# GymnastTraining, -# on_delete=models.CASCADE, -# related_name="training_rounds", -# ) -# training_round = models.ForeignKey(TrainingRound, on_delete=models.CASCADE) -# repetition = models.PositiveSmallIntegerField(default=1) -# rank = models.PositiveSmallIntegerField(default=1) -# updated_at = models.DateTimeField(auto_now=True) -# number_of_skill = models.PositiveSmallIntegerField(default=0) -# score = models.PositiveSmallIntegerField(blank=True, null=True) -# difficulty = models.DecimalField(max_digits=4, decimal_places=1, default=0.0) + gymnast_training = models.ForeignKey( + GymnastTraining, + on_delete=models.CASCADE, + related_name="training_rounds", + ) + training_round = models.ForeignKey(TrainingRound, on_delete=models.CASCADE) + repetition = models.PositiveSmallIntegerField(default=1) + rank = models.PositiveSmallIntegerField(default=1) + updated_at = models.DateTimeField(auto_now=True) + number_of_skill = models.PositiveSmallIntegerField(default=0) + score = models.PositiveSmallIntegerField(blank=True, null=True) + difficulty = models.DecimalField(max_digits=4, decimal_places=1, default=0.0) -# def __str__(self): -# return ( -# f"{self.gymnast} {self.date} - {self.rank} : {self.passe} {self.repetition}" -# ) + def __str__(self): + return f"{self.gymnast_training} {self.gymnast_training.date} - {self.rank} : {self.training_round} {self.repetition}" -# def save(self, *args, **kwargs): -# """Sauve les informations de la personne et initialise les champs nettoyés.""" -# super().save(*args, **kwargs) -# self.difficulty = self.round.difficulty * self.repetition -# self.number_of_skill = self.round.number_of_skill * self.repetition -# super().save(*args, **kwargs) + def save(self, *args, **kwargs): + """Sauve les informations de la personne et initialise les champs nettoyés.""" + super().save(*args, **kwargs) + self.difficulty = self.training_round.difficulty * self.repetition + self.number_of_skill = self.training_round.number_of_skill * self.repetition + super().save(*args, **kwargs) diff --git a/jarvis/objective/signals.py b/jarvis/objective/signals.py new file mode 100644 index 0000000..d59aa5e --- /dev/null +++ b/jarvis/objective/signals.py @@ -0,0 +1,11 @@ +# from django.db.models.signals import post_save +# from django.dispatch import receiver +# from .models import TrainingRound + + +# @receiver(post_save, sender=TrainingRound) +# def compute_traininground_fields(**kwargs): +# print("In the post_save function.") +# # job = kwargs.get("instance") +# # logger.info("POST_SAVE : Job : %s" % job) +# # find people to email based on `job` instance diff --git a/jarvis/objective/templates/trainingprograms/details.html b/jarvis/objective/templates/gymnasttrainings/details.html similarity index 76% rename from jarvis/objective/templates/trainingprograms/details.html rename to jarvis/objective/templates/gymnasttrainings/details.html index 36a69d1..b3a510f 100644 --- a/jarvis/objective/templates/trainingprograms/details.html +++ b/jarvis/objective/templates/gymnasttrainings/details.html @@ -8,29 +8,29 @@
- {% if trainingprogram_list %} + {% if gymnast_training %} - + - {% for trainingprogram in trainingprogram_list %} + {% for round in training_rounds %} - - - - + + + + {% if request.user|has_group:"trainer" %} - - + + {% if request.user|has_group:"trainer" %} {% endif %} @@ -67,7 +67,7 @@ $(document).ready(function(){ if ($(this).is(".up")) { $.ajax({ - url: "{% url 'switch_trainingprogram_line' %}", + url: "{% url 'switch_traininground' %}", method: "POST", data: { tpid: $(this).data('tp_id'), @@ -85,7 +85,7 @@ $(document).ready(function(){ }); } else { $.ajax({ - url: "{% url 'switch_trainingprogram_line' %}", + url: "{% url 'switch_traininground' %}", method: "POST", data: { tpid: $(this).data('tp_id'), diff --git a/jarvis/objective/templates/passes/create.html b/jarvis/objective/templates/trainingrounds/create.html similarity index 93% rename from jarvis/objective/templates/passes/create.html rename to jarvis/objective/templates/trainingrounds/create.html index 7113248..b719dc7 100644 --- a/jarvis/objective/templates/passes/create.html +++ b/jarvis/objective/templates/trainingrounds/create.html @@ -8,7 +8,7 @@

{% if passe_id %}Edit{% else %}Add{% endif %} Passe

-
+ {% csrf_token %} {% for hidden in form.hidden_fields %} @@ -16,7 +16,7 @@ {% endfor %}
- +
{{ form.label }} {% if form.label.errors %} {% for error in form.label.errors %}{{ error }}{% endfor %}{% endif %} @@ -24,7 +24,7 @@
- +
{{ form.regexp }} {% if form.regexp.errors %} {% for error in form.regexp.errors %}{{ error }}{% endfor %}{% endif %} diff --git a/jarvis/objective/templates/passes/details.html b/jarvis/objective/templates/trainingrounds/details.html similarity index 65% rename from jarvis/objective/templates/passes/details.html rename to jarvis/objective/templates/trainingrounds/details.html index 4a83193..06e3a7b 100644 --- a/jarvis/objective/templates/passes/details.html +++ b/jarvis/objective/templates/trainingrounds/details.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% load has_group %} -{% block page_title %}Passe details{% endblock %} +{% block page_title %}Training Round details{% endblock %} {% block content %}
@@ -9,8 +9,8 @@
-

Passe details

-
{{ passe.label }} {% if passe.regexp %}{{ passe.regexp }}{% endif %}   {{ passe.repetition }}
+

Training round details

+
{{ traininground.label }} {% if traininground.regexp and traininground.label != traininground.label %}{{ traininground.regexp }}{% endif %}   {{ traininground.repetition }}
@@ -19,34 +19,48 @@
- {{ passe.label }} + {{ traininground.label }}
+ {% if content %}
-
+ {% endif %} - {% if passe.regexp and passe.regexp != passe.label %} + {% if traininground.regexp and traininground.regexp != traininground.label %}
- {{ passe.regexp }} + {{ traininground.regexp }}
{% endif %} @@ -54,22 +68,22 @@
- {{ number_of_educative }} + {{ traininground.number_of_skill }}
- {{ difficulty }} + {{ traininground.difficulty }}
- {% if information %} + {% if traininground.information %}
- {{ informations }} + {{ traininground.informations }}
{% endif %} diff --git a/jarvis/objective/templates/passes/list.html b/jarvis/objective/templates/trainingrounds/list.html similarity index 100% rename from jarvis/objective/templates/passes/list.html rename to jarvis/objective/templates/trainingrounds/list.html diff --git a/jarvis/objective/tests_models.py b/jarvis/objective/tests_models.py index 2293333..f6e2c48 100644 --- a/jarvis/objective/tests_models.py +++ b/jarvis/objective/tests_models.py @@ -5,7 +5,7 @@ from jarvis.objective.models import ( TouchPosition, Routine, RoutineSkill, - Passe, + TrainingRound, ) from jarvis.core.global_vars import ROUTINE_TYPE_CHOICE @@ -106,7 +106,7 @@ class ToolsModels(TestCase): ) -class PasseTestCase(TestCase): +class TrainingRoundTestCase(TestCase): def setUp(self): """ Structure finale : @@ -126,134 +126,134 @@ class PasseTestCase(TestCase): def test_is_valid_dot(self): arg = "" - self.assertEqual(Passe.is_valid_dot(arg), True) + self.assertEqual(TrainingRound.is_valid_dot(arg), True) arg = "Q1R1" - self.assertEqual(Passe.is_valid_dot(arg), True) + self.assertEqual(TrainingRound.is_valid_dot(arg), True) arg = ".Q1R1" - self.assertEqual(Passe.is_valid_dot(arg), True) + self.assertEqual(TrainingRound.is_valid_dot(arg), True) arg = "Q1R1." - self.assertEqual(Passe.is_valid_dot(arg), True) + self.assertEqual(TrainingRound.is_valid_dot(arg), True) arg = "Q1.R1" - self.assertEqual(Passe.is_valid_dot(arg), False) + self.assertEqual(TrainingRound.is_valid_dot(arg), False) arg = ".Q1.R1." - self.assertEqual(Passe.is_valid_dot(arg), False) + self.assertEqual(TrainingRound.is_valid_dot(arg), False) def test_is_valid_subset(self): subset = "" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[2-8]" - self.assertEqual(Passe.is_valid_subset(subset), True) + self.assertEqual(TrainingRound.is_valid_subset(subset), True) subset = "[2--8]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[-5]" - self.assertEqual(Passe.is_valid_subset(subset), True) + self.assertEqual(TrainingRound.is_valid_subset(subset), True) subset = "[3-]" - self.assertEqual(Passe.is_valid_subset(subset), True) + self.assertEqual(TrainingRound.is_valid_subset(subset), True) subset = "[8-2]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[-]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[1-]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[-1]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[4]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[6-6]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "4" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[6-6" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[66]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "4-8" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "6-]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[4-" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "[6" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "Q1R1 [4-8]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) subset = "Q1R1 [-8]" - self.assertEqual(Passe.is_valid_subset(subset), False) + self.assertEqual(TrainingRound.is_valid_subset(subset), False) def test_is_valid_routine_type(self): for item in ROUTINE_TYPE_CHOICE: - self.assertEqual(Passe.is_valid_routine_type(item[1]), True) + self.assertEqual(TrainingRound.is_valid_routine_type(item[1]), True) routine_type = "" - self.assertEqual(Passe.is_valid_routine_type(routine_type), False) + self.assertEqual(TrainingRound.is_valid_routine_type(routine_type), False) routine_type = ".Q1R1" - self.assertEqual(Passe.is_valid_routine_type(routine_type), False) + self.assertEqual(TrainingRound.is_valid_routine_type(routine_type), False) routine_type = "SFS." - self.assertEqual(Passe.is_valid_routine_type(routine_type), False) + self.assertEqual(TrainingRound.is_valid_routine_type(routine_type), False) routine_type = "Q1R1 [4-8]" - self.assertEqual(Passe.is_valid_routine_type(routine_type), False) + self.assertEqual(TrainingRound.is_valid_routine_type(routine_type), False) routine_type = "SFS [-8]" - self.assertEqual(Passe.is_valid_routine_type(routine_type), False) + self.assertEqual(TrainingRound.is_valid_routine_type(routine_type), False) def test_is_valid_regexp_one_arg(self): arg = "" - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), False) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), False) arg = "WC" - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), True) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), True) arg = "1|" - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), True) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), True) arg = ".Q1R1" - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), True) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), True) arg = "Q1R2." - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), True) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), True) arg = ".Q1R1 [4-8" - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), False) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), False) arg = "Q1R2. [4-8" - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), False) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), False) arg = "Q1R1 [4-8]" - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), False) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), False) arg = "Q1R1 [8-4]" - self.assertEqual(Passe.is_valid_regexp_one_arg(arg), False) + self.assertEqual(TrainingRound.is_valid_regexp_one_arg(arg), False) def test_is_valid_regexp_two_args(self): arg1 = "" arg2 = "" - self.assertEqual(Passe.is_valid_regexp_two_args(arg1, arg2), False) + self.assertEqual(TrainingRound.is_valid_regexp_two_args(arg1, arg2), False) arg1 = "Q1R1" - self.assertEqual(Passe.is_valid_regexp_two_args(arg1, arg2), False) + self.assertEqual(TrainingRound.is_valid_regexp_two_args(arg1, arg2), False) arg2 = "[4-8]" - self.assertEqual(Passe.is_valid_regexp_two_args(arg1, arg2), True) + self.assertEqual(TrainingRound.is_valid_regexp_two_args(arg1, arg2), True) arg2 = "[8-8]" - self.assertEqual(Passe.is_valid_regexp_two_args(arg1, arg2), False) + self.assertEqual(TrainingRound.is_valid_regexp_two_args(arg1, arg2), False) arg2 = "[8-4]" - self.assertEqual(Passe.is_valid_regexp_two_args(arg1, arg2), False) + self.assertEqual(TrainingRound.is_valid_regexp_two_args(arg1, arg2), False) arg2 = "[-8]" - self.assertEqual(Passe.is_valid_regexp_two_args(arg1, arg2), True) + self.assertEqual(TrainingRound.is_valid_regexp_two_args(arg1, arg2), True) arg2 = "[4-]" - self.assertEqual(Passe.is_valid_regexp_two_args(arg1, arg2), True) + self.assertEqual(TrainingRound.is_valid_regexp_two_args(arg1, arg2), True) arg1 = "Q1R1." - self.assertEqual(Passe.is_valid_regexp_two_args(arg1, arg2), True) + self.assertEqual(TrainingRound.is_valid_regexp_two_args(arg1, arg2), True) def test_is_valid_regexp(self): regexp = "" - self.assertEqual(Passe.is_valid_regexp(regexp), False) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), False) regexp = "Q1R1 [4-8]" - self.assertEqual(Passe.is_valid_regexp(regexp), True) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), True) regexp = "Q1R1 [8-8]" - self.assertEqual(Passe.is_valid_regexp(regexp), False) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), False) regexp = "Q1R1 [8-4]" - self.assertEqual(Passe.is_valid_regexp(regexp), False) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), False) regexp = "Q1R1 [-8]" - self.assertEqual(Passe.is_valid_regexp(regexp), True) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), True) regexp = "Q1R1 [4-]" - self.assertEqual(Passe.is_valid_regexp(regexp), True) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), True) regexp = "Q1R1. [4-8]" - self.assertEqual(Passe.is_valid_regexp(regexp), True) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), True) regexp = "Q1R1. [4-]" - self.assertEqual(Passe.is_valid_regexp(regexp), True) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), True) regexp = ".Q1R1 [-8]" - self.assertEqual(Passe.is_valid_regexp(regexp), True) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), True) regexp = "Q1R1. [8-8]" - self.assertEqual(Passe.is_valid_regexp(regexp), False) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), False) regexp = ".Q1R1 [8-4]" - self.assertEqual(Passe.is_valid_regexp(regexp), False) + self.assertEqual(TrainingRound.is_valid_regexp(regexp), False) diff --git a/jarvis/objective/urls.py b/jarvis/objective/urls.py index 93492a3..25bb5e1 100644 --- a/jarvis/objective/urls.py +++ b/jarvis/objective/urls.py @@ -90,35 +90,35 @@ urlpatterns = [ ), path(r"combination/", views.combination_listing, name="combination_listing"), # - # PASSES + # TRAININGROUND # - # path( - # r"passe//gymnast//date//", - # views.passe_details, - # name="passe_details", - # ), - # path(r"passe/", views.passe_listing, name="passe_listing"), - # path( - # r"passe/add/", - # views.passe_create_or_update, - # name="passe_create", - # ), - # path( - # r"passe/edit//", - # views.passe_create_or_update, - # name="passe_update", - # ), + path( + r"traininground//", + views.traininground_details, + name="traininground_details", + ), + path(r"traininground/", views.traininground_listing, name="traininground_listing"), + path( + r"traininground/add/", + views.traininground_create_or_update, + name="traininground_create", + ), + path( + r"traininground/edit//", + views.traininground_create_or_update, + name="traininground_update", + ), # - # TRAININGPROGRAM + # GYMNASTTRAINING # - # path( - # r"trainingprogram/detail/date//gymnast//", - # views.trainingprogram_details, - # name="trainingprogram_details", - # ), - # path( - # r"trainingprogram/switch_trainingprogram_line/", - # views.switch_trainingprogram_line, - # name="switch_trainingprogram_line", - # ), + path( + r"gymnasttraining/detail//", + views.gymnast_training_details, + name="gymnast_training_details", + ), + path( + r"gymnasttraining/switch_traininground/", + views.switch_traininground, + name="switch_traininground", + ), ] diff --git a/jarvis/objective/views.py b/jarvis/objective/views.py index 7e91f5b..57e1d48 100644 --- a/jarvis/objective/views.py +++ b/jarvis/objective/views.py @@ -5,25 +5,24 @@ from django.shortcuts import render, get_object_or_404 from django.views.decorators.http import require_http_methods from django.urls import reverse -import pendulum - from jarvis.core.global_vars import ROUTINE_TYPE_CHOICE from jarvis.people.models import Gymnast from jarvis.followup.models import GymnastHasRoutine from .forms import ( SkillForm, - # PasseForm, + TrainingRoundForm, CombinationForm, CombinationSkillForm, ) from .models import ( Skill, - # Passe, + TrainingRound, Routine, Educative, RoutineSkill, - # TrainingProgram, + GymnastTraining, + GymnastTrainingRound, PrerequisiteClosure, ) @@ -512,189 +511,155 @@ def unlink_skill_from_combination(request): return HttpResponse(200) -# @login_required -# @require_http_methods(["GET"]) -# def passe_listing(request): -# """Liste des passages.""" -# passe_listing = Passe.objects.all() -# context = {"passe_listing": passe_listing} -# return render(request, "passes/list.html", context) +@login_required +@require_http_methods(["GET"]) +def traininground_listing(request): + """Liste des passages.""" + passe_listing = TrainingRound.objects.all() + context = {"passe_listing": passe_listing} + return render(request, "trainingrounds/list.html", context) -# @login_required -# @require_http_methods(["GET"]) -# def passe_details(request, passe_id, gymnast_id, date): -# """Détails d'un passage.""" +@login_required +@require_http_methods(["GET"]) +def traininground_details(request, traininground_id, date=None): + """Détails d'un passage.""" -# is_skill = False -# passe = get_object_or_404(Passe, pk=passe_id) -# educative_list = passe.educatives.all() -# # TODO: décryptage de la regexp -# regexp = passe.regexp -# routine = None -# skill_link_list = None + is_skill = False + traininground = get_object_or_404(TrainingRound, pk=traininground_id) + educative_list = traininground.educatives.all() -# if regexp is not None: -# operation_list = regexp.split(" ") -# routine_type = None + routine = None + skill_link_list = None -# for item in ROUTINE_TYPE_CHOICE: -# if item[1] == operation_list[0]: -# routine_type = item[0] -# break + traininground.update_traininground() -# if routine_type is not None: -# # Récupération de la série -# ghr = GymnastHasRoutine.objects.filter( -# gymnast=gymnast_id, -# date_begin__lte=date, -# # date_end__gte=date, -# routine_type=routine_type, -# ) + # Decryptage de la regexp + if traininground.regexp is not None and traininground.regexp != "": + arguments = traininground.regexp.split(" ") + if TrainingRound.is_valid_routine_type(arguments[0]) and date is not None: + # get routine_type + routine_type = 0 + ghr = GymnastHasRoutine.objects.filter( + gymnast=traininground.gymnast, + date_begin__lte=date, + routine_type=routine_type, + ).first() -# print(ghr.query) + routine = ghr.routine + skill_link_list = routine.skill_links.all() + if len(arguments) == 2: + content = arguments[1].replace("[", "").replace("]", "") + ranks = content.split("-") -# if ghr.count() > 1: -# print("Plus d'une série trouvée...") + if ranks[0] != "": + skill_link_list = skill_link_list.filter(rank__gte=ranks[0]) -# print(ghr) + if ranks[1] != "": + skill_link_list = skill_link_list.filter(rank__lte=ranks[1]) -# routine = ghr.first().routine -# skill_link_list = routine.skill_links.all() -# if len(operation_list) == 2: -# content = operation_list[1].replace("[", "").replace("]", "") -# ranks = content.split("-") + content = False + if skill_link_list or routine or educative_list: + content = True -# if ranks[0] != "": -# skill_link_list = skill_link_list.filter(rank__gte=ranks[0]) - -# if ranks[1] != "": -# skill_link_list = skill_link_list.filter(rank__lte=ranks[1]) - -# number_of_educative = skill_link_list.count() -# print(number_of_educative) - -# else: -# number_of_educative = educative_list.count() - -# context = { -# "passe": passe, -# "is_skill": is_skill, -# "educative_list": educative_list, -# "routine": routine, -# "skill_link_list": skill_link_list, -# "difficulty": passe.difficulty, -# "number_of_skill": passe.number_of_skill, -# "number_of_educative": number_of_educative, -# } -# return render(request, "passes/details.html", context) + context = { + "is_skill": is_skill, + "traininground": traininground, + "educative_list": educative_list, + "routine": routine, + "skill_link_list": skill_link_list, + "content": content, + "is_wc": traininground.is_regexp_wc + # "number_of_educative": number_of_educative, + } + return render(request, "trainingrounds/details.html", context) -# @login_required -# @require_http_methods(["GET", "POST"]) -# def passe_create_or_update(request, passe_id=None): -# """Création d'un passage. +@login_required +@require_http_methods(["GET", "POST"]) +def traininground_create_or_update(request, traininground_id=None): + """Création d'un passage. -# Args: -# passe_id (int) identifiant d'un object de classe . -# """ -# if passe_id: -# passe = get_object_or_404(Passe, pk=passe_id) -# else: -# passe = None + Args: + traininground_id (int) identifiant d'un object de classe . + """ + if traininground_id: + traininground = get_object_or_404(TrainingRound, pk=traininground_id) + else: + traininground = None -# if request.method == "POST": -# form = PasseForm(request.POST, instance=passe) + if request.method == "POST": + form = TrainingRoundForm(request.POST, instance=traininground) -# if form.is_valid(): -# passe = form.save() -# return HttpResponseRedirect(reverse("passe_details", args=(passe.pk,))) + if form.is_valid(): + traininground = form.save() + return HttpResponseRedirect( + reverse("traininground_details", args=(traininground.pk,)) + ) + # print(form.errors) + return render(request, "trainingrounds/create.html", {"form": form}) -# return render(request, "passes/create.html", {"form": form}) - -# form = PasseForm(instance=passe) -# context = {"form": form, "passe_id": passe_id} -# return render(request, "passes/create.html", context) + form = TrainingRoundForm(instance=traininground) + context = {"form": form, "traininground_id": traininground_id} + return render(request, "trainingrounds/create.html", context) -# @login_required -# @require_http_methods(["GET"]) -# def trainingprogram_details(request, date=None, gymnast_id=None): -# """Détails d'un entraînement.""" +@login_required +@require_http_methods(["GET"]) +def gymnast_training_details(request, gymnast_training_id): + """Détails d'un entraînement.""" -# gymnast = None -# trainingprogram_id = None -# if trainingprogram_id is not None: -# trainingprogram = get_object_or_404(TrainingProgram, pk=trainingprogram_id) -# trainingprogram_list = None -# else: -# trainingprogram = None -# trainingprogram_list = TrainingProgram.objects.all() -# parsed_date = pendulum.parse(date).date() -# if date is not None: -# trainingprogram_list = trainingprogram_list.filter(date=parsed_date) + gymnast_training = get_object_or_404(GymnastTraining, pk=gymnast_training_id) + training_rounds = gymnast_training.training_rounds.all() -# if gymnast_id is not None: -# gymnast = get_object_or_404(Gymnast, pk=gymnast_id) -# trainingprogram_list = trainingprogram_list.filter(gymnast=gymnast_id) - -# difficulty = 0 -# number_of_skill = 0 -# for trainingprogram in trainingprogram_list: -# difficulty += trainingprogram.difficulty -# number_of_skill += trainingprogram.number_of_skill - -# context = { -# "gymnast": gymnast, -# "date": parsed_date, -# "difficulty": difficulty, -# "number_of_skill": number_of_skill, -# "trainingprogram": trainingprogram, -# "trainingprogram_list": trainingprogram_list, -# } -# return render(request, "trainingprograms/details.html", context) + context = { + "gymnast": gymnast_training.gymnast, + "gymnast_training": gymnast_training, + "training_rounds": training_rounds, + } + return render(request, "gymnasttrainings/details.html", context) -# @require_http_methods(["POST"]) -# def switch_trainingprogram_line(request): -# """ -# Recoit dans request deux identifiants de trainingprogram qu'il faut échanger () : -# - tp_id (int) identifiant d'une instance de TraiingProgram -# - direction (str) la direction du changement (0: haut, 1: bas) +@require_http_methods(["POST"]) +def switch_traininground(request): + """ + Recoit dans request deux identifiants de trainingprogram qu'il faut échanger : + - tp_id (int) identifiant d'une instance de TraiingProgram + - direction (str) la direction du changement (0: haut, 1: bas) -# J'utilise `32767` comme valeur intermédiaire pour le `rank` car c'est la limite supérieure d'un -# PositiveSmallIntegerField. -# """ -# try: -# target_trainingprogram_id = request.POST.get("tpid", None) -# direction = int(request.POST.get("direction", 0)) + J'utilise `32767` comme valeur intermédiaire pour le `rank` car c'est la limite supérieure d'un + PositiveSmallIntegerField. + """ + try: + target_trainingprogram_id = request.POST.get("tpid", None) + direction = int(request.POST.get("direction", 0)) -# target_trainingprogram = get_object_or_404( -# TrainingProgram, pk=target_trainingprogram_id -# ) + target_trainingpround = get_object_or_404( + GymnastTrainingRound, pk=target_trainingprogram_id + ) -# if direction == 0: -# source_trainingprogram = ( -# TrainingProgram.objects.filter(rank__lt=target_trainingprogram.rank) -# .order_by("-id") -# .first() -# ) -# else: -# source_trainingprogram = ( -# TrainingProgram.objects.filter(rank__gt=target_trainingprogram.rank) -# .order_by("id") -# .first() -# ) + if direction == 0: + source_traininground = ( + GymnastTrainingRound.objects.filter(rank__lt=target_trainingpround.rank) + .order_by("-id") + .first() + ) + else: + source_traininground = ( + GymnastTrainingRound.objects.filter(rank__gt=target_trainingpround.rank) + .order_by("id") + .first() + ) -# saved_source_rank = source_trainingprogram.rank -# saved_target_rank = target_trainingprogram.rank -# source_trainingprogram.rank = 32767 -# source_trainingprogram.save() -# target_trainingprogram.rank = saved_source_rank -# target_trainingprogram.save() -# source_trainingprogram.rank = saved_target_rank -# source_trainingprogram.save() + saved_source_rank = source_traininground.rank + saved_target_rank = target_trainingpround.rank + source_traininground.rank = 32767 + source_traininground.save() + target_trainingpround.rank = saved_source_rank + target_trainingpround.save() + source_traininground.rank = saved_target_rank + source_traininground.save() -# return HttpResponse(200) -# except Exception: -# return HttpResponse(409) + return HttpResponse(200) + except Exception: + return HttpResponse(409) diff --git a/jarvis/people/templates/gymnasts/tabs/tab_intensity_and_chronos.html b/jarvis/people/templates/gymnasts/tabs/tab_intensity_and_chronos.html index 79f3b92..b4ef3ac 100644 --- a/jarvis/people/templates/gymnasts/tabs/tab_intensity_and_chronos.html +++ b/jarvis/people/templates/gymnasts/tabs/tab_intensity_and_chronos.html @@ -82,9 +82,9 @@

Training Program

- {% if date_list %} - {% for date in date_list %} - {{ date|date:"l j F Y" }} + {% if training_list %} + {% for training in training_list %} + {{ training.date|date:"l j F Y" }}
{% endfor %} {% else %}

Pas de training planifié.

diff --git a/jarvis/people/views.py b/jarvis/people/views.py index 87be0d3..5d578d0 100644 --- a/jarvis/people/views.py +++ b/jarvis/people/views.py @@ -21,7 +21,7 @@ import pendulum from jarvis.followup.models import Event from jarvis.followup.forms import GymnastHasRoutineForm -# from jarvis.objective.models import TrainingProgram +from jarvis.objective.models import GymnastTraining from jarvis.followup.models import ( Note, Plan, @@ -258,12 +258,7 @@ def gymnast_display_scores_chrono(request, gymnast_id): ).order_by("date") base_queryset = chrono_list.values("date").annotate(score_avg=Avg("tof")) today = pendulum.now().date() - # date_list = ( - # TrainingProgram.objects.filter(gymnast=gymnast_id, date__gte=today) - # .values_list("date", flat=True) - # .order_by("date") - # .distinct() - # ) + training_list = GymnastTraining.objects.filter(gymnast=gymnast_id, date__gte=today) context = { "intensity_list": intensity_list, @@ -272,7 +267,7 @@ def gymnast_display_scores_chrono(request, gymnast_id): "chrono_r1": base_queryset.filter(chrono_type=1), "chrono_r2": base_queryset.filter(chrono_type=2), "chrono_rf": base_queryset.filter(chrono_type=3), - # "date_list": date_list, + "training_list": training_list, "gymnast_id": gymnast_id, } return render(request, "gymnasts/tabs/tab_intensity_and_chronos.html", context)
{% if gymnast %}{{ gymnast }} - {% endif %}{{ date|date:"l j F Y" }}{{ gymnast_training.gymnast }} - {{ gymnast_training.date|date:"l j F Y" }}
{{ trainingprogram.rank }}{{ trainingprogram.passe.label }}{% if trainingprogram.repetition != 1 %}   {{ trainingprogram.repetition }}{% endif %}{{ trainingprogram.number_of_skill}}{{ trainingprogram.difficulty }}{{ round.rank }}{{ round.training_round.label }}{% if round.repetition != 1 %}   {{ round.repetition }}{% endif %}{{ round.number_of_skill}}{{ round.difficulty }} - + - + @@ -42,8 +42,8 @@
TOTAL{{ number_of_skill }}{{ difficulty }}{{ gymnast_training.number_of_skill }}{{ gymnast_training.difficulty }}