Multiple updates
This commit is contained in:
parent
b9a9bd2c9a
commit
c302214924
17
README.md
17
README.md
|
@ -59,7 +59,22 @@ Dans le répertoire racine, tapez la commande suivante :
|
|||
(à venir)
|
||||
|
||||
### Coverage
|
||||
(à venir)
|
||||
```bash
|
||||
pip install coverage
|
||||
```
|
||||
|
||||
#### Configuration
|
||||
```bash
|
||||
touch .coveragerc
|
||||
vim .coveragerc
|
||||
```
|
||||
|
||||
Ajoutez les lignes suivantes :
|
||||
|
||||
```bash
|
||||
omit = *__init__.py,*/migrations/*,*test*,*settings*,*urls*,*wsgi*,manage.py,*apps*
|
||||
```
|
||||
|
||||
|
||||
## Déploiement sur Heroku
|
||||
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
"""All global variables to avoid circular import."""
|
||||
|
||||
INJURY_MECHANISM_CHOICE = (
|
||||
(0, "Overuse"),
|
||||
(1, "Trauma"),
|
||||
)
|
||||
|
||||
INJURY_BODY_SIDE_CHOICE = (
|
||||
(0, "Not Applicable"),
|
||||
(1, "Left"),
|
||||
(2, "Right"),
|
||||
(3, "Both"),
|
||||
)
|
||||
|
||||
INJURY_TYPE_CHOICE = (
|
||||
(0, "Abrasion"),
|
||||
(1, "Dental Injury"),
|
||||
(2, "Dislocation / Subluxation"),
|
||||
(3, "Fracture"),
|
||||
(4, "Haematoma / Contusion / Bruise"),
|
||||
(5, "Head Concussion"),
|
||||
(6, "Laceration"),
|
||||
(7, "Lesion of Meniscus or Cartilage"),
|
||||
(8, "Muscle Rupture / Strain / Tear / Cramps"),
|
||||
(9, "Nerve Injury"),
|
||||
(10, "Other Bone Injury"),
|
||||
(11, "Sprain / Ligament Injury"),
|
||||
(12, "Tendon Injury / Rupture / Tendinosis / Bursitis"),
|
||||
)
|
||||
|
||||
INJURY_LOCATION_CHOICE = (
|
||||
(0, "Abdomen"),
|
||||
(1, "Ankle"),
|
||||
(2, "Elbow"),
|
||||
(3, "Foot / Toe"),
|
||||
(4, "Hand / Finger / Thumb"),
|
||||
(5, "Head / Face"),
|
||||
(6, "Hip / Groin"),
|
||||
(7, "Knee"),
|
||||
(8, "Low back / Sacrum / Pelvis"),
|
||||
(9, "Lower Leg / Achilles Tendon"),
|
||||
(10, "Neck / Cervical Spine"),
|
||||
(11, "Shoulder / Clavicula"),
|
||||
(12, "Sternum / Ribs / Upper back"),
|
||||
(13, "Thigh"),
|
||||
(14, "Upper arm"),
|
||||
(15, "Wrist"),
|
||||
)
|
||||
|
||||
ROUTINE_TYPE_CHOICE = (
|
||||
(0, "Other"),
|
||||
(1, "Q1R1"),
|
||||
(2, "Q1R2"),
|
||||
(3, "Q2R1"),
|
||||
(4, "SF"),
|
||||
(5, "F"),
|
||||
(6, "Q1R1S"),
|
||||
(7, "Q1R2S"),
|
||||
(8, "Q2R1S"),
|
||||
(9, "SFS"),
|
||||
(9, "FS"),
|
||||
(99, "Other"),
|
||||
)
|
||||
|
||||
LEARNING_STEP_CHOICES = (
|
||||
(0, "No"),
|
||||
(1, "With help"),
|
||||
(2, "Without help"),
|
||||
(3, "Chained"),
|
||||
(4, "Masterised"),
|
||||
)
|
||||
|
||||
CHRONO_TYPE_CHOICE = (
|
||||
(0, "10 |"),
|
||||
(1, "Q1R1"),
|
||||
(2, "Q1R2"),
|
||||
(3, "Q2R1"),
|
||||
(4, "SF"),
|
||||
(5, "F"),
|
||||
(99, "Other"),
|
||||
)
|
||||
|
||||
SCORE_TYPE_CHOICE = (
|
||||
(0, "Chrono"),
|
||||
(1, "ToF"),
|
||||
)
|
||||
|
||||
CATEGORY_CHOICES = {
|
||||
9: "I9",
|
||||
10: "I10",
|
||||
11: "A11",
|
||||
12: "A12",
|
||||
13: "A13-14",
|
||||
15: "A Junior",
|
||||
18: "A Senior",
|
||||
21: "B11",
|
||||
22: "B12",
|
||||
23: "B13-14",
|
||||
24: "B Junior",
|
||||
25: "B Senior",
|
||||
}
|
||||
|
||||
AGE_CATOGORY_CHOICES = (
|
||||
(11, "11-12"),
|
||||
(13, "13-14"),
|
||||
(15, "15-16"),
|
||||
(17, "17-21"),
|
||||
(22, "Senior"),
|
||||
)
|
||||
|
||||
NOTE_STATUS_CHOICES = (
|
||||
(0, "Draft"),
|
||||
(1, "Published"),
|
||||
)
|
||||
|
||||
GENDER_CHOICES = (
|
||||
(0, "Female"),
|
||||
(1, "Male"),
|
||||
)
|
||||
|
||||
ORIENTATION_CHOICES = (
|
||||
(None, "Unknown"),
|
||||
(1, "Left"),
|
||||
(2, "Right"),
|
||||
)
|
||||
|
||||
# MOD_THOMAS_TEST_CHOICES = (
|
||||
# (0, "not evaluated"),
|
||||
# (1, "tight psoas"),
|
||||
# (2, "tight quadriceps"),
|
||||
# (3, "tight TFL"),
|
||||
# (4, "tight psoas en quadriceps"),
|
||||
# (5, "tight quadriceps en TFL"),
|
||||
# (6, "tight psoas en TFL"),
|
||||
# (7, "tight psoas en quadriceps en TFL"),
|
||||
# )
|
||||
|
||||
# LOMBO_PELVIC_AND_CERVICAL_CONTROL_CHOICES = (
|
||||
# (0, "not evaluated"),
|
||||
# (1, "good control, good mobility"),
|
||||
# (2, "good control, bad mobility"),
|
||||
# (3, "bad control, good mobility"),
|
||||
# (4, "bad control, bad mobility"),
|
||||
# )
|
|
@ -3,6 +3,20 @@ from django.db import models
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
|
||||
from jarvis.core.global_vars import (
|
||||
INJURY_MECHANISM_CHOICE,
|
||||
INJURY_BODY_SIDE_CHOICE,
|
||||
INJURY_TYPE_CHOICE,
|
||||
INJURY_LOCATION_CHOICE,
|
||||
ROUTINE_TYPE_CHOICE,
|
||||
LEARNING_STEP_CHOICES,
|
||||
CHRONO_TYPE_CHOICE,
|
||||
SCORE_TYPE_CHOICE,
|
||||
CATEGORY_CHOICES,
|
||||
AGE_CATOGORY_CHOICES,
|
||||
NOTE_STATUS_CHOICES,
|
||||
)
|
||||
|
||||
from jarvis.tools.models import Markdownizable, Seasonisable
|
||||
from jarvis.people.models import Gymnast, GENDER_CHOICES
|
||||
from jarvis.planning.models import Event
|
||||
|
@ -11,138 +25,6 @@ from jarvis.location.models import Club
|
|||
|
||||
User = get_user_model()
|
||||
|
||||
INJURY_MECHANISM_CHOICE = (
|
||||
(0, "Overuse"),
|
||||
(1, "Trauma"),
|
||||
)
|
||||
|
||||
INJURY_BODY_SIDE_CHOICE = (
|
||||
(0, "Not Applicable"),
|
||||
(1, "Left"),
|
||||
(2, "Right"),
|
||||
(3, "Both"),
|
||||
)
|
||||
|
||||
INJURY_TYPE_CHOICE = (
|
||||
(0, "Abrasion"),
|
||||
(1, "Dental Injury"),
|
||||
(2, "Dislocation / Subluxation"),
|
||||
(3, "Fracture"),
|
||||
(4, "Haematoma / Contusion / Bruise"),
|
||||
(5, "Head Concussion"),
|
||||
(6, "Laceration"),
|
||||
(7, "Lesion of Meniscus or Cartilage"),
|
||||
(8, "Muscle Rupture / Strain / Tear / Cramps"),
|
||||
(9, "Nerve Injury"),
|
||||
(10, "Other Bone Injury"),
|
||||
(11, "Sprain / Ligament Injury"),
|
||||
(12, "Tendon Injury / Rupture / Tendinosis / Bursitis"),
|
||||
)
|
||||
|
||||
INJURY_LOCATION_CHOICE = (
|
||||
(0, "Abdomen"),
|
||||
(1, "Ankle"),
|
||||
(2, "Elbow"),
|
||||
(3, "Foot / Toe"),
|
||||
(4, "Hand / Finger / Thumb"),
|
||||
(5, "Head / Face"),
|
||||
(6, "Hip / Groin"),
|
||||
(7, "Knee"),
|
||||
(8, "Low back / Sacrum / Pelvis"),
|
||||
(9, "Lower Leg / Achilles Tendon"),
|
||||
(10, "Neck / Cervical Spine"),
|
||||
(11, "Shoulder / Clavicula"),
|
||||
(12, "Sternum / Ribs / Upper back"),
|
||||
(13, "Thigh"),
|
||||
(14, "Upper arm"),
|
||||
(15, "Wrist"),
|
||||
)
|
||||
|
||||
ROUTINE_TYPE_CHOICE = (
|
||||
(0, "Other"),
|
||||
(1, "Q1R1"),
|
||||
(2, "Q1R2"),
|
||||
(3, "Q2R1"),
|
||||
(4, "SF"),
|
||||
(5, "F"),
|
||||
(6, "Q1R1S"),
|
||||
(7, "Q1R2S"),
|
||||
(8, "Q2R1S"),
|
||||
(9, "SFS"),
|
||||
(9, "FS"),
|
||||
(99, "Other"),
|
||||
)
|
||||
|
||||
LEARNING_STEP_CHOICES = (
|
||||
(0, "No"),
|
||||
(1, "With help"),
|
||||
(2, "Without help"),
|
||||
(3, "Chained"),
|
||||
(4, "Masterised"),
|
||||
)
|
||||
|
||||
CHRONO_TYPE_CHOICE = (
|
||||
(0, "10 |"),
|
||||
(1, "Q1R1"),
|
||||
(2, "Q1R2"),
|
||||
(3, "Q2R1"),
|
||||
(4, "SF"),
|
||||
(5, "F"),
|
||||
(99, "Other"),
|
||||
)
|
||||
|
||||
SCORE_TYPE_CHOICE = (
|
||||
(0, "Chrono"),
|
||||
(1, "ToF"),
|
||||
)
|
||||
|
||||
CATEGORY_CHOICES = {
|
||||
9: "I9",
|
||||
10: "I10",
|
||||
11: "A11",
|
||||
12: "A12",
|
||||
13: "A13-14",
|
||||
15: "A Junior",
|
||||
18: "A Senior",
|
||||
21: "B11",
|
||||
22: "B12",
|
||||
23: "B13-14",
|
||||
24: "B Junior",
|
||||
25: "B Senior",
|
||||
}
|
||||
|
||||
AGE_CATOGORY_CHOICES = (
|
||||
(11, "11-12"),
|
||||
(13, "13-14"),
|
||||
(15, "15-16"),
|
||||
(17, "17-21"),
|
||||
(22, "Senior"),
|
||||
)
|
||||
|
||||
NOTE_STATUS_CHOICES = (
|
||||
(0, "Draft"),
|
||||
(1, "Published"),
|
||||
)
|
||||
|
||||
# MOD_THOMAS_TEST_CHOICES = (
|
||||
# (0, "not evaluated"),
|
||||
# (1, "tight psoas"),
|
||||
# (2, "tight quadriceps"),
|
||||
# (3, "tight TFL"),
|
||||
# (4, "tight psoas en quadriceps"),
|
||||
# (5, "tight quadriceps en TFL"),
|
||||
# (6, "tight psoas en TFL"),
|
||||
# (7, "tight psoas en quadriceps en TFL"),
|
||||
# )
|
||||
|
||||
# LOMBO_PELVIC_AND_CERVICAL_CONTROL_CHOICES = (
|
||||
# (0, "not evaluated"),
|
||||
# (1, "good control, good mobility"),
|
||||
# (2, "good control, bad mobility"),
|
||||
# (3, "bad control, good mobility"),
|
||||
# (4, "bad control, bad mobility"),
|
||||
# )
|
||||
|
||||
|
||||
class Chrono(Seasonisable):
|
||||
"""
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.2 on 2024-03-06 06:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("objective", "0019_alter_passe_options_trainingprogram_informations_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="passe",
|
||||
name="educatives",
|
||||
field=models.ManyToManyField(blank=True, to="objective.educative"),
|
||||
),
|
||||
]
|
|
@ -1,12 +1,16 @@
|
|||
from django.db import models
|
||||
from django.db.models import Q
|
||||
|
||||
import re
|
||||
from jarvis.core.global_vars import ROUTINE_TYPE_CHOICE
|
||||
from jarvis.tools.models import (
|
||||
Markdownizable,
|
||||
Seasonisable,
|
||||
max_even_if_none,
|
||||
)
|
||||
|
||||
# from jarvis.followup.models import ROUTINE_TYPE_CHOICE
|
||||
|
||||
|
||||
class Educative(Markdownizable):
|
||||
"""
|
||||
|
@ -469,7 +473,7 @@ class Passe(Markdownizable):
|
|||
ordering = ["label"]
|
||||
|
||||
label = models.CharField(max_length=30)
|
||||
educatives = models.ManyToManyField(Educative)
|
||||
educatives = models.ManyToManyField(Educative, blank=True)
|
||||
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)
|
||||
|
@ -527,6 +531,62 @@ class Passe(Markdownizable):
|
|||
def __str__(self):
|
||||
return f"{self.label} ({self.number_of_skill} | {self.difficulty})"
|
||||
|
||||
@staticmethod
|
||||
def check_regexp(regexp, label, educatives_list):
|
||||
"""Vérifie le champ regexp
|
||||
|
||||
Type de string pris en compte :
|
||||
- Toutes les valeurs de ROUTINE_TYPE_CHOICE (Educative vide !)
|
||||
- avec [x-y] (avec X ou Y vide mais pas les deux en même temps)
|
||||
- [x-y] (avec X ou Y vide mais pas les deux en même temps) (EDUCATIVE non vide !!!)
|
||||
- WC
|
||||
- x| (x entier)
|
||||
|
||||
Exemples :
|
||||
- Q1R1 True (si educatives.count() vide)
|
||||
- Q1R2 [2-8] True (si educatives.count() vide)
|
||||
- Q1R1 [8-2] False
|
||||
- Q2R3 [-5] True (si educatives.count() vide)
|
||||
- SF [6-] True (si educatives.count() vide)
|
||||
- FS [3-7] True (si educatives.count() vide)
|
||||
- WC True (si educatives.count() >= 2)
|
||||
- 1| True (si educatives.count() >= 2)
|
||||
"""
|
||||
if label is None and educatives_list is None and regexp is None:
|
||||
return False
|
||||
|
||||
operation_list = regexp.split(" ")
|
||||
|
||||
if operation_list.count() >= 3:
|
||||
return False
|
||||
|
||||
if operation_list.count() == 2:
|
||||
if operation_list[0] in ROUTINE_TYPE_CHOICE:
|
||||
if re.match(r"\[[1-9]*\-[1-9]*\]", operation_list[1]):
|
||||
content = operation_list[1].replace("[", "").replace("]", "")
|
||||
ranks = content.split("-")
|
||||
if ranks.count() > 1:
|
||||
if ranks[1] > ranks[1]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
if operation_list[0] == "WC" and educatives_list.count() == 2:
|
||||
return True
|
||||
|
||||
if (
|
||||
re.match(r"[1-9]+\|", operation_list[0])
|
||||
and educatives_list.count() >= 1
|
||||
):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class TrainingProgram(Seasonisable, Markdownizable):
|
||||
"""Classe représentant un entraînement (ensemble de passage)."""
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.test import TestCase
|
||||
from jarvis.objective.models import Educative
|
||||
from jarvis.objective.models import Educative, Passe
|
||||
|
||||
|
||||
class EducativeTestCase(TestCase):
|
||||
|
@ -87,3 +87,52 @@ class EducativeTestCase(TestCase):
|
|||
[educ_1, educ_2, educ_9],
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class PasseTestCase(TestCase):
|
||||
def setUp(self):
|
||||
"""
|
||||
Structure finale :
|
||||
1 -> 2
|
||||
1 -> 6
|
||||
3 -> 4 -> 5 -> 6 -> 7
|
||||
1 -> 2 -> 9
|
||||
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
|
||||
)
|
||||
|
||||
def test_check_regexp(self):
|
||||
label = ""
|
||||
regexp = ""
|
||||
educatives_list = []
|
||||
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
|
||||
regexp = "Q1R1 [4-8] WC"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
|
||||
regexp = "Q1R1"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
|
||||
regexp = "Q1R1 [4-8"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
|
||||
regexp = "Q1R1 [4-8]"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
|
||||
regexp = "Q1R1 [4-]"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
|
||||
regexp = "Q1R1 [-8]"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
|
||||
regexp = "Q1R1 [8-4]"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
|
||||
regexp = "WC"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
|
||||
educ_1 = Educative.objects.get(long_label="1/2 vrille")
|
||||
educatives_list.append(educ_1)
|
||||
regexp = "1|"
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
|
||||
educ_3 = Educative.objects.get(long_label="4 pattes")
|
||||
educatives_list.append(educ_3)
|
||||
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
|
||||
|
|
|
@ -527,6 +527,7 @@ def passe_details(request, passe_id):
|
|||
is_skill = False
|
||||
passe = get_object_or_404(Passe, pk=passe_id)
|
||||
educative_list = passe.educatives.all()
|
||||
# TODO: décryptage de la regexp
|
||||
number_of_educative = educative_list.count()
|
||||
|
||||
context = {
|
||||
|
|
|
@ -6,6 +6,8 @@ from django.db import models
|
|||
|
||||
import pendulum
|
||||
|
||||
from jarvis.core.global_vars import GENDER_CHOICES, ORIENTATION_CHOICES
|
||||
|
||||
from jarvis.objective.models import Skill
|
||||
|
||||
# from jarvis.profiles.models import TrainerGymnast
|
||||
|
@ -20,8 +22,6 @@ from jarvis.tools.clean_name import clean_name
|
|||
|
||||
User = get_user_model()
|
||||
|
||||
GENDER_CHOICES = ((0, "Female"), (1, "Male"))
|
||||
|
||||
|
||||
class Gymnast(Markdownizable):
|
||||
"""Représente un gymnaste.
|
||||
|
@ -32,8 +32,6 @@ class Gymnast(Markdownizable):
|
|||
verbose_name = "Gymnast"
|
||||
verbose_name_plural = "Gymnasts"
|
||||
|
||||
ORIENTATION_CHOICES = ((None, "Unknown"), (1, "Left"), (2, "Right"))
|
||||
|
||||
user = models.OneToOneField(
|
||||
User, on_delete=models.SET_NULL, related_name="gymnast", blank=True, null=True
|
||||
)
|
||||
|
|
|
@ -258,7 +258,7 @@ def gymnast_display_scores_chrono(request, gymnast_id):
|
|||
base_queryset = chrono_list.values("date").annotate(score_avg=Avg("tof"))
|
||||
today = pendulum.now().date()
|
||||
date_list = (
|
||||
TrainingProgram.objects.filter(gymnast=6, date__gte=today)
|
||||
TrainingProgram.objects.filter(gymnast=gymnast_id, date__gte=today)
|
||||
.values_list("date", flat=True)
|
||||
.order_by("date")
|
||||
.distinct()
|
||||
|
|
Loading…
Reference in New Issue