f-string and notification refactoring
This commit is contained in:
parent
0ab362eb7c
commit
1998895e6d
12
README.md
12
README.md
|
@ -23,8 +23,8 @@ services:
|
||||||
- ./data:/var/lib/postgresql/data
|
- ./data:/var/lib/postgresql/data
|
||||||
```
|
```
|
||||||
- tapez la commande `docker-compose up -d`
|
- tapez la commande `docker-compose up -d`
|
||||||
|
- `pip install -r requirements.txt`
|
||||||
- pip install -r requirements.txt
|
- `python manage.py runserver`
|
||||||
### Installation de weasyprint
|
### Installation de weasyprint
|
||||||
En plus du `pip install weasyprint` et `pip install django-weasyprint`, il faut installer weasyprint (via homebrew, …)
|
En plus du `pip install weasyprint` et `pip install django-weasyprint`, il faut installer weasyprint (via homebrew, …)
|
||||||
puis, **pour les mac M1** exécuter les commandes :
|
puis, **pour les mac M1** exécuter les commandes :
|
||||||
|
@ -54,12 +54,14 @@ puis, **pour les mac M1** exécuter les commandes :
|
||||||
heroku config:set ALLOWED_HOSTS="avengers-jarvis.herokuapp.com"
|
heroku config:set ALLOWED_HOSTS="avengers-jarvis.herokuapp.com"
|
||||||
heroku config:set SECRET_KEY="django-insecure-g_eoy6z%xshku4o5#k%o%i_%nb%_pz80config_#+t%f"
|
heroku config:set SECRET_KEY="django-insecure-g_eoy6z%xshku4o5#k%o%i_%nb%_pz80config_#+t%f"
|
||||||
heroku config:set DATABASE_NAME="ultron"
|
heroku config:set DATABASE_NAME="ultron"
|
||||||
```
|
```
|
||||||
|
|
||||||
- Push de l'application : `git push heroku master`
|
|
||||||
|
|
||||||
- Se connecter à Héroku (via l'invite de commande) : `heroku login`
|
- Se connecter à Héroku (via l'invite de commande) : `heroku login`
|
||||||
|
|
||||||
|
- Ajouter Heroku à Git : `git remote add heroku https://git.heroku.com/flying-ultron.git`
|
||||||
|
|
||||||
|
- Push de l'application : `git push heroku master`
|
||||||
|
|
||||||
- Création du super user : `heroku run python manage.py createsuperuser`
|
- Création du super user : `heroku run python manage.py createsuperuser`
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,12 +101,7 @@ class Chrono(Seasonisable):
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s (%s - %s)" % (
|
return f"{self.gymnast} - {self.score} ({self.date} - {self.chrono_type})"
|
||||||
self.gymnast,
|
|
||||||
self.score,
|
|
||||||
self.date,
|
|
||||||
self.chrono_type,
|
|
||||||
)
|
|
||||||
|
|
||||||
def timeline_representation(self):
|
def timeline_representation(self):
|
||||||
return f"<li>{self.date:%d %b %Y} - New personel best {CHRONO_TYPE_CHOICE[self.chrono_type][1]}: {self.score}' ({self.tof}')</li>"
|
return f"<li>{self.date:%d %b %Y} - New personel best {CHRONO_TYPE_CHOICE[self.chrono_type][1]}: {self.score}' ({self.tof}')</li>"
|
||||||
|
@ -167,10 +162,7 @@ class Accident(Markdownizable, Seasonisable):
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s)" % (
|
return f"{self.gymnast} ({self.date})"
|
||||||
self.gymnast,
|
|
||||||
self.date,
|
|
||||||
)
|
|
||||||
|
|
||||||
def timeline_representation(self):
|
def timeline_representation(self):
|
||||||
return f"<li>{self.date:%d %b %Y} - Accident ({self.skill}): {self.nb_week_off} (weeks off)</li>"
|
return f"<li>{self.date:%d %b %Y} - Accident ({self.skill}): {self.nb_week_off} (weeks off)</li>"
|
||||||
|
@ -205,12 +197,7 @@ class LearnedSkill(Seasonisable):
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s - %s - %s" % (
|
return f"{self.gymnast} - {self.date} - {self.learning_step} - {self.skill}"
|
||||||
self.gymnast,
|
|
||||||
self.date,
|
|
||||||
self.learning_step,
|
|
||||||
self.skill,
|
|
||||||
)
|
|
||||||
|
|
||||||
def timeline_representation(self):
|
def timeline_representation(self):
|
||||||
return f"<li>{self.date:%d %b %Y} - learning of {self.skill.long_label} ({self.skill.short_label}): {LEARNING_STEP_CHOICES[self.learning_step][1]}</li>"
|
return f"<li>{self.date:%d %b %Y} - learning of {self.skill.long_label} ({self.skill.short_label}): {LEARNING_STEP_CHOICES[self.learning_step][1]}</li>"
|
||||||
|
@ -247,11 +234,7 @@ class Plan(Seasonisable, Markdownizable):
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s - %s" % (
|
return f"{self.gymnast} - {self.educative.short_label} - {self.date}"
|
||||||
self.gymnast,
|
|
||||||
self.educative.short_label,
|
|
||||||
self.date,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Point(models.Model):
|
class Point(models.Model):
|
||||||
|
@ -282,10 +265,7 @@ class Point(models.Model):
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated")
|
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s" % (
|
return f"{self.gymnast} - {self.total}"
|
||||||
self.gymnast,
|
|
||||||
self.total,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class MindState(Markdownizable, Seasonisable):
|
class MindState(Markdownizable, Seasonisable):
|
||||||
|
@ -309,7 +289,7 @@ class MindState(Markdownizable, Seasonisable):
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s : %s" % (self.gymnast, self.date, self.score)
|
return f"{self.gymnast} - {self.date} : {self.score}"
|
||||||
|
|
||||||
|
|
||||||
class GymnastHasRoutine(models.Model):
|
class GymnastHasRoutine(models.Model):
|
||||||
|
@ -343,7 +323,7 @@ class GymnastHasRoutine(models.Model):
|
||||||
date_end = models.DateField(verbose_name="Date end", null=True, blank=True)
|
date_end = models.DateField(verbose_name="Date end", null=True, blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s : %s" % (self.gymnast, self.routine_type, self.routine)
|
return f"{self.gymnast} - {self.routine_type} : {self.routine}"
|
||||||
|
|
||||||
|
|
||||||
class NumberOfRoutineDone(Seasonisable):
|
class NumberOfRoutineDone(Seasonisable):
|
||||||
|
@ -381,13 +361,7 @@ class NumberOfRoutineDone(Seasonisable):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s (%s) : %s | %s" % (
|
return f"{self.gymnast} - {self.routine_type} ({self.routine}) : {self.number_of_try} | {self.number_of_successes}"
|
||||||
self.gymnast,
|
|
||||||
self.routine_type,
|
|
||||||
self.routine,
|
|
||||||
self.number_of_try,
|
|
||||||
self.number_of_successes,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class HeightWeight(Seasonisable):
|
class HeightWeight(Seasonisable):
|
||||||
|
@ -417,12 +391,7 @@ class HeightWeight(Seasonisable):
|
||||||
weight = models.DecimalField(max_digits=4, decimal_places=1, verbose_name="Weight")
|
weight = models.DecimalField(max_digits=4, decimal_places=1, verbose_name="Weight")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s : %s/%s - %s" % (
|
return f"{self.gymnast} : {self.height}/{self.hips_height} - {self.weight}"
|
||||||
self.gymnast,
|
|
||||||
self.height,
|
|
||||||
self.hips_height,
|
|
||||||
self.weight,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Note(Markdownizable, Seasonisable):
|
class Note(Markdownizable, Seasonisable):
|
||||||
|
@ -448,7 +417,7 @@ class Note(Markdownizable, Seasonisable):
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s : %s" % (self.gymnast, self.created_at, self.coach)
|
return f"{self.gymnast} - {self.created_at} : {self.coach}"
|
||||||
|
|
||||||
|
|
||||||
class Intensity(Markdownizable, Seasonisable):
|
class Intensity(Markdownizable, Seasonisable):
|
||||||
|
@ -480,14 +449,7 @@ class Intensity(Markdownizable, Seasonisable):
|
||||||
number_of_passes = models.PositiveSmallIntegerField()
|
number_of_passes = models.PositiveSmallIntegerField()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s : %s - %s - %s - %s" % (
|
return f"{self.gymnast} - {self.date} : {self.time} - {self.difficulty} - {self.quantity_of_skill} - {self.number_of_passes}"
|
||||||
self.gymnast,
|
|
||||||
self.date,
|
|
||||||
self.time,
|
|
||||||
self.difficulty,
|
|
||||||
self.quantity_of_skill,
|
|
||||||
self.number_of_passes,
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mean_difficulty_by_passe(self):
|
def mean_difficulty_by_passe(self):
|
||||||
|
@ -546,14 +508,7 @@ class SeasonInformation(models.Model):
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s : %s - %s - %s - %s" % (
|
return f"{self.gymnast} - {self.season} : {self.number_of_training_sessions_per_week} - {self.number_of_hours_per_week} - {self.category} - {self.club}"
|
||||||
self.gymnast,
|
|
||||||
self.season,
|
|
||||||
self.number_of_training_sessions_per_week,
|
|
||||||
self.number_of_hours_per_week,
|
|
||||||
self.category,
|
|
||||||
self.club,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CompetitivePointsStats(Markdownizable, Seasonisable):
|
class CompetitivePointsStats(Markdownizable, Seasonisable):
|
||||||
|
|
|
@ -545,23 +545,24 @@ def chrono_create_or_update(request, chrono_id=None, gymnast_id=None):
|
||||||
new_chrono.save()
|
new_chrono.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="chrono")
|
functionality = ContentType.objects.get(model="chrono")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouveau chrono",
|
|
||||||
f"Un nouveau chrono enregistré pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouveau chrono",
|
||||||
[
|
f"Un nouveau chrono enregistré pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Un nouveau chrono enregistré pour {gymnast}.</p><br />
|
<p>Un nouveau chrono enregistré pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse("gymnast_details_tab", args=(new_chrono.gymnast.id, "scores"))
|
reverse("gymnast_details_tab", args=(new_chrono.gymnast.id, "scores"))
|
||||||
|
@ -627,23 +628,24 @@ def learnedskill_create_or_update(request, gymnast_id=None):
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="learnedskill")
|
functionality = ContentType.objects.get(model="learnedskill")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouveau skill appris",
|
|
||||||
f"Un nouveau skill a été appris par {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouveau skill appris",
|
||||||
[
|
f"Un nouveau skill a été appris par {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Un nouveau skill () a été appris par {gymnast}.</p><br />
|
<p>Un nouveau skill () a été appris par {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
|
reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
|
||||||
|
@ -683,23 +685,24 @@ def score_create_or_update(request, score_id=None, gymnast_id=None):
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="point")
|
functionality = ContentType.objects.get(model="point")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouveau score enregistré",
|
|
||||||
f"Un nouveau score a été enregistré pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouveau score enregistré",
|
||||||
[
|
f"Un nouveau score a été enregistré pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Un nouveau score a été enregistré pour {gymnast}.</p><br />
|
<p>Un nouveau score a été enregistré pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
if form.cleaned_data["add_to_chrono"]:
|
if form.cleaned_data["add_to_chrono"]:
|
||||||
new_chrono = Chrono(
|
new_chrono = Chrono(
|
||||||
|
@ -806,23 +809,24 @@ def accident_create_or_update(request, accident_id=None, gymnast_id=None):
|
||||||
accident = form.save()
|
accident = form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="accident")
|
functionality = ContentType.objects.get(model="accident")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouvel accident enregistré",
|
|
||||||
f"Un nouvel accident enregistré pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouvel accident enregistré",
|
||||||
[
|
f"Un nouvel accident enregistré pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Un nouvel accident enregistré pour {gymnast}.</p><br />
|
<p>Un nouvel accident enregistré pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse("accident_details", args=(accident.pk,))
|
reverse("accident_details", args=(accident.pk,))
|
||||||
|
@ -891,23 +895,24 @@ def mindstate_create_or_update(
|
||||||
mindstate = form.save()
|
mindstate = form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="mindstate")
|
functionality = ContentType.objects.get(model="mindstate")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouvel état d'esprit enregistré",
|
|
||||||
f"Un nouvel état d'esprit enregistré pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouvel état d'esprit enregistré",
|
||||||
[
|
f"Un nouvel état d'esprit enregistré pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Un nouvel état d'esprit enregistré pour {gymnast}.</p><br />
|
<p>Un nouvel état d'esprit enregistré pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse("mindstate_details", args=(mindstate.pk,))
|
reverse("mindstate_details", args=(mindstate.pk,))
|
||||||
|
@ -976,23 +981,24 @@ def heightweight_create_or_update(request, heightweight_id=None, gymnast_id=None
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="heightweight")
|
functionality = ContentType.objects.get(model="heightweight")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouveau poids/taille enregistré",
|
|
||||||
f"Un nouveau poids/taille enregistré pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouveau poids/taille enregistré",
|
||||||
[
|
f"Un nouveau poids/taille enregistré pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Un nouveau poids/taille enregistré pour {gymnast}.</p><br />
|
<p>Un nouveau poids/taille enregistré pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse(
|
reverse(
|
||||||
|
@ -1107,23 +1113,24 @@ def routinedone_create_or_update(request, routinedone_id=None, gymnast_id=None):
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="numberofroutinedone")
|
functionality = ContentType.objects.get(model="numberofroutinedone")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouvelle série comptabilisée",
|
|
||||||
f"Nouvelle série comptabilisée pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouvelle série comptabilisée",
|
||||||
[
|
f"Nouvelle série comptabilisée pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Nouvelle série comptabilisée pour {gymnast}.</p><br />
|
<p>Nouvelle série comptabilisée pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse(
|
reverse(
|
||||||
|
@ -1179,23 +1186,24 @@ def plan_create_or_update(request, plan_id=None, gymnast_id=None, skill_id=None)
|
||||||
plan = form.save()
|
plan = form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="plan")
|
functionality = ContentType.objects.get(model="plan")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouvelle série comptabilisée",
|
|
||||||
f"Nouvelle série comptabilisée pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouvelle série comptabilisée",
|
||||||
[
|
f"Nouvelle série comptabilisée pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Nouvelle série comptabilisée pour {gymnast}.</p><br />
|
<p>Nouvelle série comptabilisée pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
|
reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
|
||||||
|
@ -1270,23 +1278,24 @@ def intensity_create_or_update(request, intensity_id=None, gymnast_id=None):
|
||||||
intensity = form.save()
|
intensity = form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="intensity")
|
functionality = ContentType.objects.get(model="intensity")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouvelle intensité",
|
|
||||||
f"Une nouvelle note vous a été envoyée pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouvelle intensité",
|
||||||
[
|
f"Une nouvelle note vous a été envoyée pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Une nouvelle intensité a été encodée pour {gymnast}.</p><br />
|
<p>Une nouvelle intensité a été encodée pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse(
|
reverse(
|
||||||
|
@ -1340,23 +1349,24 @@ def season_information_create_or_update(
|
||||||
season_information = form.save()
|
season_information = form.save()
|
||||||
|
|
||||||
# notification
|
# notification
|
||||||
|
receiver = []
|
||||||
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
|
||||||
functionality = ContentType.objects.get(model="seasoninformation")
|
functionality = ContentType.objects.get(model="seasoninformation")
|
||||||
for notification in gymnast.notifications.filter(
|
for notification in gymnast.notifications.filter(
|
||||||
functionality=functionality
|
functionality=functionality
|
||||||
):
|
):
|
||||||
send_mail(
|
receiver.append(notification.user.email)
|
||||||
f"{gymnast} : Nouvelle information de saison",
|
|
||||||
f"Une nouvelle information de saison enregistrée pour {gymnast}",
|
send_mail(
|
||||||
settings.EMAIL_HOST_USER,
|
f"{gymnast} : Nouvelle information de saison",
|
||||||
[
|
f"Une nouvelle information de saison enregistrée pour {gymnast}",
|
||||||
notification.user.email,
|
settings.EMAIL_HOST_USER,
|
||||||
],
|
receiver,
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message=f"""<p>Bonjour,</p>
|
html_message=f"""<p>Bonjour,</p>
|
||||||
<p>Une nouvelle information de saison enregistrée pour {gymnast}.</p><br />
|
<p>Une nouvelle information de saison enregistrée pour {gymnast}.</p><br />
|
||||||
<p>Excellente journée</p><p>Jarvis</p>""",
|
<p>Excellente journée</p><p>Jarvis</p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse(
|
reverse(
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Country(models.Model):
|
||||||
isonum = models.PositiveSmallIntegerField()
|
isonum = models.PositiveSmallIntegerField()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s)" % (self.name, self.iso2)
|
return f"{self.name} ({self.iso2})"
|
||||||
|
|
||||||
|
|
||||||
class Place(models.Model):
|
class Place(models.Model):
|
||||||
|
|
|
@ -102,11 +102,7 @@ class Educative(Markdownizable):
|
||||||
# is_competitive = models.BooleanField(default=False)
|
# is_competitive = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s - %s)" % (
|
return f"{self.long_label} ({self.short_label} - {self.difficulty})"
|
||||||
self.long_label,
|
|
||||||
self.short_label,
|
|
||||||
self.difficulty,
|
|
||||||
)
|
|
||||||
|
|
||||||
def breadcrumb(self, path=[]):
|
def breadcrumb(self, path=[]):
|
||||||
"""
|
"""
|
||||||
|
@ -149,12 +145,7 @@ class PrerequisiteClosure(models.Model):
|
||||||
path = models.PositiveIntegerField()
|
path = models.PositiveIntegerField()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s -> %s (%s|%s)" % (
|
return f"{self.ancestor.long_label} -> {self.descendant.long_label} ({self.level}|{self.path})"
|
||||||
self.ancestor.long_label,
|
|
||||||
self.descendant.long_label,
|
|
||||||
self.level,
|
|
||||||
self.path,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TouchPosition(models.Model):
|
class TouchPosition(models.Model):
|
||||||
|
@ -175,7 +166,7 @@ class TouchPosition(models.Model):
|
||||||
is_default = models.BooleanField(verbose_name="Défault ?", default=False)
|
is_default = models.BooleanField(verbose_name="Défault ?", default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s" % (self.long_label)
|
return f"{self.long_label}"
|
||||||
|
|
||||||
|
|
||||||
def get_default_position():
|
def get_default_position():
|
||||||
|
@ -250,7 +241,7 @@ class Skill(Educative):
|
||||||
# importance = models.PositiveSmallIntegerField(default = 1)
|
# importance = models.PositiveSmallIntegerField(default = 1)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s)" % (self.long_label, self.notation)
|
return f"{self.long_label} ({self.notation})"
|
||||||
|
|
||||||
|
|
||||||
class Routine(Educative):
|
class Routine(Educative):
|
||||||
|
@ -270,7 +261,7 @@ class Routine(Educative):
|
||||||
is_competitive = models.BooleanField(default=False)
|
is_competitive = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s)" % (self.long_label, self.short_label)
|
return f"{self.long_label} ({self.short_label})"
|
||||||
|
|
||||||
def compute_informations(self):
|
def compute_informations(self):
|
||||||
"""Calcule les informations (rank, niveau, ages, …) d'une routine."""
|
"""Calcule les informations (rank, niveau, ages, …) d'une routine."""
|
||||||
|
@ -418,11 +409,7 @@ class RoutineSkill(models.Model):
|
||||||
rank = models.PositiveSmallIntegerField()
|
rank = models.PositiveSmallIntegerField()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s : %s" % (
|
return f"{self.rank} - {self.routine.short_label} : {self.skill.short_label}"
|
||||||
self.rank,
|
|
||||||
self.routine.short_label,
|
|
||||||
self.skill.short_label,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def max_even_if_none(value_1, value_2):
|
def max_even_if_none(value_1, value_2):
|
||||||
|
|
|
@ -4,12 +4,9 @@ from django.contrib.auth import get_user_model
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
User = get_user_model()
|
|
||||||
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
import pendulum
|
import pendulum
|
||||||
|
|
||||||
from jarvis.location.models import Club
|
|
||||||
from jarvis.objective.models import Skill
|
from jarvis.objective.models import Skill
|
||||||
from jarvis.tools.models import Markdownizable
|
from jarvis.tools.models import Markdownizable
|
||||||
from jarvis.objective.tools import (
|
from jarvis.objective.tools import (
|
||||||
|
@ -19,6 +16,8 @@ from jarvis.objective.tools import (
|
||||||
compute_statistics_by_type,
|
compute_statistics_by_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
GENDER_CHOICES = ((0, "Male"), (1, "Female"))
|
GENDER_CHOICES = ((0, "Male"), (1, "Female"))
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ class Gymnast(Markdownizable):
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s %s" % (self.first_name, self.last_name)
|
return f"{self.first_name} {self.last_name}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def next_birthday(self):
|
def next_birthday(self):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
Q,
|
Q,
|
||||||
|
@ -41,10 +42,7 @@ from jarvis.followup.models import (
|
||||||
NumberOfRoutineDone,
|
NumberOfRoutineDone,
|
||||||
)
|
)
|
||||||
|
|
||||||
from jarvis.followup.models import (
|
from jarvis.followup.models import LEARNING_STEP_CHOICES
|
||||||
CATEGORY_CHOICES,
|
|
||||||
LEARNING_STEP_CHOICES,
|
|
||||||
)
|
|
||||||
|
|
||||||
from jarvis.tools.models import Season
|
from jarvis.tools.models import Season
|
||||||
|
|
||||||
|
@ -391,11 +389,19 @@ def link_routine_to_gymnast(request, gymnast_id=None):
|
||||||
form.save()
|
form.save()
|
||||||
if not gymnast:
|
if not gymnast:
|
||||||
gymnast = get_object_or_404(Gymnast, pk=form.cleaned_data["gymnast"])
|
gymnast = get_object_or_404(Gymnast, pk=form.cleaned_data["gymnast"])
|
||||||
|
|
||||||
|
receiver = []
|
||||||
|
functionality = ContentType.objects.get(model="gymnasthasroutine")
|
||||||
|
for notification in gymnast.notifications.filter(
|
||||||
|
functionality=functionality
|
||||||
|
):
|
||||||
|
receiver.append(notification.user.email)
|
||||||
|
|
||||||
send_mail(
|
send_mail(
|
||||||
"Nouvelle série",
|
"Nouvelle série",
|
||||||
"Une nouvelle série vous a été associée.",
|
"Une nouvelle série vous a été associée.",
|
||||||
settings.EMAIL_HOST_USER,
|
settings.EMAIL_HOST_USER,
|
||||||
[gymnast.user.email, gymnast.email_trainer],
|
[gymnast.user.email, gymnast.email_trainer].append(receiver),
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
html_message="""<p>Bonjour,</p>
|
html_message="""<p>Bonjour,</p>
|
||||||
<p>Une nouvelle série vous a été associée.</p><br />
|
<p>Une nouvelle série vous a été associée.</p><br />
|
||||||
|
|
|
@ -44,7 +44,7 @@ class EventType(models.Model):
|
||||||
color = models.PositiveSmallIntegerField(choices=COLOR_CHOICES)
|
color = models.PositiveSmallIntegerField(choices=COLOR_CHOICES)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s)" % (self.name, self.acronym)
|
return f"{self.name} ({self.acronym})"
|
||||||
|
|
||||||
|
|
||||||
class Event(Markdownizable, Temporizable):
|
class Event(Markdownizable, Temporizable):
|
||||||
|
@ -74,7 +74,7 @@ class Event(Markdownizable, Temporizable):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (à %s)" % (self.name, self.place)
|
return f"{self.name} (à {self.place})"
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
self.checkdates()
|
self.checkdates()
|
||||||
|
@ -105,4 +105,4 @@ class EventParticipation(models.Model):
|
||||||
rank = models.PositiveSmallIntegerField(default=0)
|
rank = models.PositiveSmallIntegerField(default=0)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s to %s" % (self.gymnast, self.event)
|
return f"{self.gymnast} to {self.event}"
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Profile(models.Model):
|
||||||
is_sidebar_minified = models.BooleanField(default=False)
|
is_sidebar_minified = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s %s" % (self.user.first_name, self.user.last_name)
|
return f"{self.user.first_name} {self.user.last_name}"
|
||||||
|
|
||||||
|
|
||||||
class Notification(models.Model):
|
class Notification(models.Model):
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
{% for gymnast in gymnast_list %}
|
{% for gymnast in gymnast_list %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-md-8">
|
||||||
<b>{{ gymnast }}</b>
|
<b>{{ gymnast }}</b>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-3 ml-3"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{% for functionality in functionality_list %}
|
{% for functionality in functionality_list %}
|
||||||
|
@ -54,7 +55,7 @@
|
||||||
csrfmiddlewaretoken: '{{ csrf_token }}'
|
csrfmiddlewaretoken: '{{ csrf_token }}'
|
||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
alert("Demande de notification ajoutée.");
|
// alert("Demande de notification ajoutée.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@
|
||||||
csrfmiddlewaretoken: '{{ csrf_token }}'
|
csrfmiddlewaretoken: '{{ csrf_token }}'
|
||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
alert("Demande de notification supprimée.");
|
// alert("Demande de notification supprimée.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Season:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s" % (self.label)
|
return f"{self.label}"
|
||||||
|
|
||||||
|
|
||||||
def get_default_date():
|
def get_default_date():
|
||||||
|
|
Loading…
Reference in New Issue