From 63c46f6e6eb54e8f6f1f50df2db2c851929b4b1b Mon Sep 17 00:00:00 2001 From: Fred Date: Wed, 23 Jun 2021 20:13:59 +0200 Subject: [PATCH] Test location and planning models This will allows an easier refactoring of build_statistics functions --- src/location/models.py | 27 +++++++++++-- src/planning/models.py | 20 +++++++-- src/planning/tests/tests_models.py | 65 +++++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 7 deletions(-) diff --git a/src/location/models.py b/src/location/models.py index 8fdae83..18a7b44 100644 --- a/src/location/models.py +++ b/src/location/models.py @@ -51,7 +51,6 @@ class Place(models.Model): return "%s (%s)" % (self.name, self.city if self.city else "?") - class GymnastStatistics(): def __init__(self, gymnast): self.gymnast = gymnast @@ -66,6 +65,14 @@ class GymnastStatistics(): self.number_of_hours_of_absence = 0 self.percentage_of_absence = 0 + def add_course(self, course): + """Ajoute le fait que ce gymnaste a assisté à un cours""" + self.number_of_trainings += 1 + self.number_of_training_hours += course.number_of + + def percentage_of_absence(self): + return int(self.number_of_hours_of_absence / self.number_of_training_hours) * 100 + class Club(models.Model): """Représentation d'un club. @@ -116,5 +123,19 @@ class Club(models.Model): for course in self.courses: gymnasts.extend(Gymnast.objects.filter(to_gym__in=course.to_subgroup.all())) - def build_statistics(self): - pass + def build_statistics(self, season): + """Construit des statistiques liées à la saison passée en paramètre + + Args: + season_id (pk): L'identifiant de la saison. + + Returns: + Une structure (dict) reprenant les informations suivantes: + * La liste des cours associés à ce club et à la saison passée en paramètre + * Des informations statistiques concernant les gymnastes associés à chacun de ces cours + * Le nombre total de cours réellement donnés + * Le nombre + + """ + + courses = self.courses.filter(season=season) diff --git a/src/planning/models.py b/src/planning/models.py index 53c1a80..d60bb12 100644 --- a/src/planning/models.py +++ b/src/planning/models.py @@ -280,11 +280,15 @@ class Course(Markdownizable, Temporizable): * est associé à un ou plusieurs entraineurs, * est associé à un club * est associé à un jour de la semaine (numéro du jour dans la semaine : 0 = lundi, 6 = dimanche). + + Remarks: + Les cours par défaut triés sur les jours et sur les heures de début. """ class Meta: verbose_name = "Cours" verbose_name_plural = "Cours" + ordering = ("iso_day_number", "hour_begin") DAY_CHOICE = ( (1, "Lundi"), @@ -297,7 +301,7 @@ class Course(Markdownizable, Temporizable): ) club = models.ForeignKey( - "location.Club", verbose_name="Club", on_delete=models.CASCADE, default=None + "location.Club", verbose_name="Club", on_delete=models.CASCADE, default=None, related_name="courses" ) iso_day_number = models.PositiveSmallIntegerField( choices=DAY_CHOICE, verbose_name="Jour" @@ -340,14 +344,24 @@ class Course(Markdownizable, Temporizable): Examples: >>> """ - counted = course.get_total_occurence() + counted = self.get_number_of_planned_occurrences - unavailabilities = Unavailability.objects.filter(course=course) + unavailabilities = Unavailability.objects.filter(course=self) for unavailable in unavailabilities: counted -= unavailable.get_total_occurence() return counted + @property + def get_real_time_spent_during_season(self): + """Calcule le temps total dépensé pour ce cours + + + + """ + return self.get_number_of_real_occurrences * self.duration + + @property def get_gymnasts(self): return Gymnast.objects.filter(to_gym__in=self.to_subgroup.all()) diff --git a/src/planning/tests/tests_models.py b/src/planning/tests/tests_models.py index eeffa9d..d8cb8e5 100644 --- a/src/planning/tests/tests_models.py +++ b/src/planning/tests/tests_models.py @@ -6,7 +6,7 @@ from django.test import TestCase from location.models import Club, Place, Country -from ..models import get_number_of_weeks_between, Season, Course +from ..models import get_number_of_weeks_between, Season, Course, Unavailability USER_MODEL = get_user_model() @@ -29,6 +29,69 @@ class TestCourse(TestCase): self.user1 = USER_MODEL.objects.create(username="james_bond") self.user2 = USER_MODEL.objects.create(username="doctor_no") + def test_number_of_planned_occurrences(self): + """Vérifie le calcul du nombre de séances planifiées durant une saison""" + course = Course.objects.create( + iso_day_number=2, + datebegin=datetime(2021, 1, 1), + dateend=datetime(2021, 9, 30), + hour_begin=time(hour=19, minute=30), + hour_end=time(hour=22, minute=45), + club=self.club + ) + + self.assertEqual(course.get_number_of_real_occurrences, 39) + + course = Course.objects.create( + iso_day_number=2, + datebegin=datetime(2022, 1, 1), + dateend=datetime(2022, 10, 20), + hour_begin=time(hour=8, minute=30), + hour_end=time(hour=20, minute=0), + club=self.club + ) + + self.assertEqual(course.get_number_of_real_occurrences, 42) + + def test_number_of_real_occurrences_should_be_zero(self): + """Vérifie le calcul du nombre de séances réalisées durant une saison""" + course = Course.objects.create( + iso_day_number=2, + datebegin=datetime(2021, 1, 1), + dateend=datetime(2021, 9, 30), + hour_begin=time(hour=19, minute=30), + hour_end=time(hour=22, minute=45), + club=self.club + ) + + unavailabiliy = Unavailability.objects.create( + datebegin=datetime(2021, 1, 1), + dateend=datetime(2021, 9, 30), + ) + + unavailabiliy.course.add(course) + + self.assertEqual(course.get_number_of_real_occurrences, 0) + + def test_number_of_real_occurrences_should_be_21(self): + course = Course.objects.create( + iso_day_number=2, + datebegin=datetime(2021, 1, 1), + dateend=datetime(2021, 9, 30), + hour_begin=time(hour=19, minute=30), + hour_end=time(hour=22, minute=45), + club=self.club + ) + + unavailabiliy = Unavailability.objects.create( + datebegin=datetime(2021, 6, 1), + dateend=datetime(2021, 9, 30), + ) + + unavailabiliy.course.add(course) + + self.assertEqual(course.get_number_of_real_occurrences, 21) + def test_number_of_trainers_should_be_calculated(self): course = Course.objects.create( iso_day_number=2,