Adding points, accidents and minor bugs fixes
This commit is contained in:
parent
9108cb3adc
commit
e7c9e75d8c
|
@ -40,9 +40,10 @@ urlpatterns = [
|
|||
|
||||
# Follow-up management
|
||||
path(r"chrono/", include(followup.urls.chrono_urlpatterns)),
|
||||
path(r"skill/", include(followup.urls.skill_urlpatterns)),
|
||||
path(r"learnedskill/", include(followup.urls.learnedskill_urlpatterns)),
|
||||
path(r"score/", include(followup.urls.score_urlpatterns)),
|
||||
path(r"accident/", include(followup.urls.accident_urlpatterns)),
|
||||
path(r"skill/", include(followup.urls.skill_urlpatterns)),
|
||||
|
||||
# Planning management
|
||||
path(r"event/", include(planning.urls.event_urlpatterns)),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.contrib import admin
|
||||
from .models import Chrono, LearnedSkill, Skill, Point
|
||||
from .models import Chrono, LearnedSkill, Skill, Point, Accident
|
||||
from django_extensions.admin import ForeignKeyAutocompleteAdmin
|
||||
|
||||
|
||||
|
@ -51,6 +51,18 @@ class PointAdmin(admin.ModelAdmin):
|
|||
list_filter = ("gymnast", "event", "routine_type")
|
||||
|
||||
|
||||
|
||||
class AccidentAdmin(admin.ModelAdmin):
|
||||
model = Accident
|
||||
|
||||
fields = ("date", "gymnast", "informations") # educative
|
||||
list_display = ("date", "gymnast") # educative
|
||||
list_filter = ("date",)
|
||||
search_fields = ("date", "gymnast") # educative
|
||||
autocomplete_fields = ["gymnast"] # educative
|
||||
|
||||
|
||||
admin.site.register(Accident, AccidentAdmin)
|
||||
admin.site.register(Point, PointAdmin)
|
||||
admin.site.register(Chrono, ChronoAdmin)
|
||||
admin.site.register(LearnedSkill, LearnedSkillAdmin)
|
||||
|
|
|
@ -5,7 +5,7 @@ from datetime import date
|
|||
|
||||
from django.db import models
|
||||
from django.forms import fields, widgets
|
||||
from .models import Chrono, LearnedSkill, Point
|
||||
from .models import Chrono, LearnedSkill, Point, Accident
|
||||
|
||||
class ChronoForm(forms.ModelForm):
|
||||
class Meta:
|
||||
|
@ -146,3 +146,44 @@ class ScoreForm(forms.ModelForm):
|
|||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class AccidentForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Accident
|
||||
fields = ("gymnast", "date", "informations") # , "educative"
|
||||
widgets = {
|
||||
"date": forms.DateInput(
|
||||
attrs={
|
||||
"class": "form-control datepicker",
|
||||
# "value": date.today().strftime("%Y-%m-%d"),
|
||||
}
|
||||
),
|
||||
"gymnast": forms.HiddenInput(),
|
||||
# "educative": forms.HiddenInput(),
|
||||
"informations": forms.Textarea(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Informations about accident: context (why, where, …), consequencies, …",
|
||||
}
|
||||
),
|
||||
}
|
||||
|
||||
gymnast_related = forms.CharField(
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Searching gymnast…",
|
||||
"data-ref": "#id_gymnast",
|
||||
}
|
||||
)
|
||||
)
|
||||
# educative_related = forms.CharField(
|
||||
# widget=forms.TextInput(
|
||||
# attrs={
|
||||
# "class": "form-control",
|
||||
# "placeholder": "Searching skill…",
|
||||
# "data-ref": "#id_educative",
|
||||
# }
|
||||
# )
|
||||
# )
|
|
@ -1,67 +0,0 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-16 09:07
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('people', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Skill',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('short_label', models.CharField(max_length=50, verbose_name='Short label')),
|
||||
('long_label', models.CharField(max_length=255, verbose_name='Long label')),
|
||||
('difficulty', models.DecimalField(decimal_places=1, max_digits=3, verbose_name='Difficulty')),
|
||||
('level', models.PositiveSmallIntegerField(default=0)),
|
||||
('rank', models.PositiveSmallIntegerField(default=0)),
|
||||
('numeric_notation', models.CharField(max_length=25)),
|
||||
('ancestor', models.ManyToManyField(related_name='_followup_skill_ancestor_+', to='followup.Skill')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Skill',
|
||||
'verbose_name_plural': 'Skills',
|
||||
'ordering': ['short_label'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Chrono',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('type', models.PositiveSmallIntegerField(choices=[(0, '10 |'), (1, 'Routine')], verbose_name='Chrono type')),
|
||||
('score_type', models.PositiveSmallIntegerField(choices=[(0, 'Chrono'), (1, 'ToF')], verbose_name='Score type')),
|
||||
('score', models.DecimalField(decimal_places=3, max_digits=5)),
|
||||
('tof', models.DecimalField(blank=True, decimal_places=3, max_digits=5, null=True)),
|
||||
('date', models.DateField(default=datetime.date.today, verbose_name='Date')),
|
||||
('gymnast', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='chronos', to='people.gymnast', verbose_name='gymnast')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Chrono',
|
||||
'verbose_name_plural': 'Chronos',
|
||||
'ordering': ['date', 'gymnast'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LearnedSkill',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cando', models.PositiveSmallIntegerField(choices=[(0, 'No'), (1, 'With help'), (2, 'Without help'), (3, 'Chained')], verbose_name='Can do type')),
|
||||
('date', models.DateField(default=datetime.date.today, verbose_name='Date')),
|
||||
('gymnast', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='can_do_skill', to='people.gymnast', verbose_name='gymnast')),
|
||||
('skill', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='done_by_gymnasts', to='followup.skill', verbose_name='Skill')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Learned Skill',
|
||||
'verbose_name_plural': 'Learned Skills',
|
||||
'unique_together': {('gymnast', 'skill', 'date')},
|
||||
},
|
||||
),
|
||||
]
|
|
@ -1,31 +0,0 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-16 16:29
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('people', '0002_auto_20211116_1144'),
|
||||
('planning', '0001_initial'),
|
||||
('followup', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Point',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('routine_type', models.PositiveSmallIntegerField(choices=[(0, 'Routine 1'), (1, 'Routine 2'), (2, 'Final')])),
|
||||
('point_execution', models.DecimalField(decimal_places=3, max_digits=5)),
|
||||
('point_difficulty', models.DecimalField(decimal_places=1, max_digits=3)),
|
||||
('point_time_of_flight', models.DecimalField(decimal_places=3, max_digits=5)),
|
||||
('point_horizontal_displacement', models.DecimalField(decimal_places=3, max_digits=4)),
|
||||
('penality', models.DecimalField(decimal_places=1, max_digits=3)),
|
||||
('total', models.DecimalField(decimal_places=3, max_digits=6)),
|
||||
('event', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='planning.event')),
|
||||
('gymnast', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='people.gymnast')),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -2,6 +2,7 @@ from django.db import models
|
|||
from datetime import date
|
||||
|
||||
from django.db.models.deletion import CASCADE
|
||||
from tools.models import Markdownizable
|
||||
from people.models import Gymnast
|
||||
from planning.models import Event
|
||||
|
||||
|
@ -45,6 +46,37 @@ class Chrono(models.Model):
|
|||
)
|
||||
|
||||
|
||||
class Accident(Markdownizable):
|
||||
"""
|
||||
La classe `Accident` permet d'indiquer qu'un gymnaste a eu un accident.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Accident"
|
||||
verbose_name_plural = "Accidents"
|
||||
# ordering = ["date", "gymnast"]
|
||||
|
||||
gymnast = models.ForeignKey(
|
||||
Gymnast,
|
||||
verbose_name="Gymnast",
|
||||
related_name="accident",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
# educative = models.ForeignKey(
|
||||
# "objective.Skill",
|
||||
# verbose_name="Skill",
|
||||
# related_name="accident",
|
||||
# on_delete=models.CASCADE,
|
||||
# )
|
||||
date = models.DateField(verbose_name="Date")
|
||||
|
||||
def __str__(self):
|
||||
return "%s(%s)" % (
|
||||
self.gymnast,
|
||||
self.date,
|
||||
)
|
||||
|
||||
|
||||
class Skill(models.Model):
|
||||
"""
|
||||
Représente la ligne d'apprentissage.
|
||||
|
|
|
@ -34,4 +34,17 @@ score_urlpatterns = [
|
|||
path(r"add", views.score_create_or_update, name="score_create"),
|
||||
path(r"edit/<int:scoreid>", views.score_create_or_update, name="score_update"),
|
||||
path(r"", views.score_listing),
|
||||
]
|
||||
|
||||
# Accident
|
||||
accident_urlpatterns = [
|
||||
path(r"search/", views.accident_listing),
|
||||
path(r"", views.accident_listing, name="accident_list"),
|
||||
path(r"add/", views.accident_create_or_update, name="accident_create"),
|
||||
path(
|
||||
r"edit/<int:accidentid>/",
|
||||
views.accident_create_or_update,
|
||||
name="accident_update",
|
||||
),
|
||||
path(r"<int:accidentid>/", views.accident_detail, name="accident_details"),
|
||||
]
|
|
@ -5,8 +5,8 @@ from django.http import HttpResponse, HttpResponseRedirect
|
|||
from django.db.models import Q
|
||||
|
||||
from people.models import Gymnast
|
||||
from .models import Chrono, Skill, Point
|
||||
from .forms import ChronoForm, LearnedSkillForm, ScoreForm
|
||||
from .models import Chrono, Skill, Point, Accident
|
||||
from .forms import ChronoForm, LearnedSkillForm, ScoreForm, AccidentForm
|
||||
|
||||
import simplejson
|
||||
|
||||
|
@ -39,25 +39,17 @@ def chrono_create_or_update(request, chronoid=None, gymnastid=None):
|
|||
form = ChronoForm(request.POST, instance=chrono)
|
||||
|
||||
if form.is_valid():
|
||||
print(form.cleaned_data)
|
||||
new_chrono = form.save(commit=False)
|
||||
# Calcul du ToF
|
||||
if form.cleaned_data['score_type'] == 1:
|
||||
form.cleaned_data['tof'] = form.cleaned_data['score']
|
||||
if new_chrono.score_type == 1:
|
||||
new_chrono.tof = new_chrono.score
|
||||
else:
|
||||
tof = round(( form.cleaned_data['score'] * 13 ) / 15, 3) * 1000
|
||||
tof = round(( new_chrono.score * 13 ) / 15, 3) * 1000
|
||||
tof = tof - (tof % 5)
|
||||
form.cleaned_data['tof'] = tof / 1000
|
||||
new_chrono.tof = tof / 1000
|
||||
|
||||
print(form.cleaned_data)
|
||||
form.save()
|
||||
if chronoid is not None:
|
||||
return HttpResponseRedirect("/chrono/")
|
||||
elif gymnastid is not None:
|
||||
return HttpResponseRedirect(
|
||||
"/gymnast/" + str(gymnastid)
|
||||
)
|
||||
else:
|
||||
return HttpResponseRedirect("/chrono/")
|
||||
new_chrono.save()
|
||||
return HttpResponseRedirect("/gymnast/details/" + str(new_chrono.gymnast.id) + "/")
|
||||
|
||||
else:
|
||||
if data is None and gymnastid is not None:
|
||||
|
@ -223,3 +215,71 @@ def score_listing(request):
|
|||
|
||||
context = {"score_list": score_list}
|
||||
return render(request, "followup/scores/list.html", context)
|
||||
|
||||
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def accident_listing(request):
|
||||
"""
|
||||
Récupère la liste des accidents suivant un pattern si celui-ci est définit.
|
||||
"""
|
||||
pattern = request.GET.get("pattern", None)
|
||||
|
||||
if pattern:
|
||||
accident_list = Accident.objects.filter(
|
||||
Q(gymnast__lastname__icontains=pattern)
|
||||
| Q(gymnast__firstname__icontains=pattern)
|
||||
)
|
||||
else:
|
||||
accident_list = Accident.objects.all()
|
||||
|
||||
context = {"accident_list": accident_list}
|
||||
return render(request, "followup/accidents/list.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def accident_create_or_update(request, accidentid=None):
|
||||
"""
|
||||
Formulaire de création d'un nouvel accident.
|
||||
"""
|
||||
|
||||
if accidentid:
|
||||
accident = get_object_or_404(Accident, pk=accidentid)
|
||||
data = {
|
||||
"gymnast_related": accident.gymnast,
|
||||
"educative_related": accident.educative,
|
||||
}
|
||||
else:
|
||||
accident = None
|
||||
data = {}
|
||||
|
||||
if request.method == "POST":
|
||||
form = AccidentForm(request.POST, instance=accident)
|
||||
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
if accidentid:
|
||||
return HttpResponseRedirect("/accident/" + str(accidentid) + "/")
|
||||
else:
|
||||
return HttpResponseRedirect("/accident/")
|
||||
else:
|
||||
|
||||
form = AccidentForm(instance=accident, initial=data)
|
||||
|
||||
context = {"form": form, "accidentid": accidentid}
|
||||
return render(request, "followup/accidents/create.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def accident_detail(request, accidentid):
|
||||
"""
|
||||
Récupère toutes les informations d'un accident.
|
||||
"""
|
||||
accident = get_object_or_404(Accident, pk=accidentid)
|
||||
context = {"accident": accident}
|
||||
return render(request, "followup/accidents/details.html", context)
|
||||
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-16 09:07
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Country',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('nameus', models.CharField(max_length=255, verbose_name='English name')),
|
||||
('namefr', models.CharField(max_length=255, verbose_name='French Name')),
|
||||
('nationality', models.CharField(max_length=255, verbose_name='Nationality')),
|
||||
('iso2', models.CharField(max_length=2)),
|
||||
('iso3', models.CharField(max_length=3)),
|
||||
('isonum', models.PositiveSmallIntegerField()),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Country',
|
||||
'verbose_name_plural': 'Countries',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Place',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='Name')),
|
||||
('address', models.CharField(max_length=255, verbose_name='Address')),
|
||||
('postal', models.PositiveIntegerField(verbose_name='Postal code')),
|
||||
('city', models.CharField(max_length=255, verbose_name='City')),
|
||||
('nbkm', models.PositiveIntegerField(blank=True, help_text='in km', null=True)),
|
||||
('timing', models.PositiveIntegerField(blank=True, help_text='in minutes', null=True)),
|
||||
('active', models.BooleanField(default=1, verbose_name='Active')),
|
||||
('country', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='location.country', verbose_name='Country')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Place',
|
||||
'verbose_name_plural': 'Places',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Club',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='Name')),
|
||||
('acronym', models.CharField(max_length=4, verbose_name='Acronym')),
|
||||
('active', models.BooleanField(default=1, verbose_name='Active')),
|
||||
('place', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='location.place', verbose_name='Place')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Club',
|
||||
'verbose_name_plural': 'Clubs',
|
||||
},
|
||||
),
|
||||
]
|
|
@ -1,22 +0,0 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-16 09:42
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('location', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='country',
|
||||
old_name='nameus',
|
||||
new_name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='country',
|
||||
name='namefr',
|
||||
),
|
||||
]
|
|
@ -6,17 +6,19 @@ class GymnastAdmin(admin.ModelAdmin):
|
|||
model = Gymnast
|
||||
|
||||
fields = (
|
||||
"last_name",
|
||||
"first_name",
|
||||
"birthdate",
|
||||
"gender",
|
||||
"is_active",
|
||||
'last_name',
|
||||
'first_name',
|
||||
'birthdate',
|
||||
'gender',
|
||||
'trainings_by_week',
|
||||
'hours_by_week',
|
||||
'is_active',
|
||||
# "club"
|
||||
)
|
||||
|
||||
list_display = ("last_name", "first_name", "age", "is_active") # , "club"
|
||||
list_filter = ("gender", "is_active") # , "club"
|
||||
search_fields = ("last_name", "first_name")
|
||||
list_display = ('last_name', 'first_name', 'age', 'is_active') # , "club"
|
||||
list_filter = ('gender', 'is_active') # , "club"
|
||||
search_fields = ('last_name', 'first_name')
|
||||
# autocomplete_fields = ("club",)
|
||||
|
||||
admin.site.register(Gymnast, GymnastAdmin)
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-16 09:07
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('location', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Gymnast',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('informations', models.TextField(blank=True, help_text='Only MarkDown is authorized', null=True, verbose_name='Comments')),
|
||||
('last_name', models.CharField(max_length=40)),
|
||||
('first_name', models.CharField(max_length=25)),
|
||||
('birthdate', models.DateField(verbose_name='Date de naissance')),
|
||||
('gender', models.PositiveSmallIntegerField(choices=[(0, 'Male'), (1, 'Female')], verbose_name='Sexe')),
|
||||
('is_active', models.BooleanField(default=1, verbose_name='Active')),
|
||||
('hours_by_week', models.PositiveSmallIntegerField(verbose_name='Hours by week')),
|
||||
('club', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='gymnast', to='location.club')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Gymnast',
|
||||
'verbose_name_plural': 'Gymnasts',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Accident',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('informations', models.TextField(blank=True, help_text='Only MarkDown is authorized', null=True, verbose_name='Comments')),
|
||||
('date', models.DateField(verbose_name='Date')),
|
||||
('indisponibility', models.PositiveIntegerField()),
|
||||
('gymnast', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='accident', to='people.gymnast', verbose_name='Gymnast')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Accident',
|
||||
'verbose_name_plural': 'Accidents',
|
||||
},
|
||||
),
|
||||
]
|
|
@ -1,24 +0,0 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-16 11:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('people', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='gymnast',
|
||||
name='trainings_by_week',
|
||||
field=models.PositiveSmallIntegerField(default=0, verbose_name='# Training by week'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gymnast',
|
||||
name='hours_by_week',
|
||||
field=models.PositiveSmallIntegerField(verbose_name='# Hours by week'),
|
||||
),
|
||||
]
|
|
@ -49,37 +49,4 @@ class Gymnast(Markdownizable):
|
|||
@property
|
||||
def next_age(self):
|
||||
""" Renvoie l'âge prochain du gymnaste. """
|
||||
return (self.age) + 1
|
||||
|
||||
|
||||
|
||||
|
||||
class Accident(Markdownizable):
|
||||
"""La classe `Accident` permet d'indiquer qu'un gymnaste est tombé durant un saut.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Accident"
|
||||
verbose_name_plural = "Accidents"
|
||||
# ordering = ["date", "gymnast"]
|
||||
|
||||
gymnast = models.ForeignKey(
|
||||
Gymnast,
|
||||
verbose_name="Gymnast",
|
||||
related_name="accident",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
# educative = models.ForeignKey(
|
||||
# "objective.Skill",
|
||||
# verbose_name="Skill",
|
||||
# related_name="accident",
|
||||
# on_delete=models.CASCADE,
|
||||
# )
|
||||
date = models.DateField(verbose_name="Date")
|
||||
indisponibility = models.PositiveIntegerField(null=False, blank=False)
|
||||
|
||||
def __str__(self):
|
||||
return "%s(%s)" % (
|
||||
self.gymnast,
|
||||
self.date,
|
||||
)
|
||||
return (self.age) + 1
|
|
@ -1,70 +0,0 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-16 09:07
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('people', '0001_initial'),
|
||||
('location', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Event',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('informations', models.TextField(blank=True, help_text='Only MarkDown is authorized', null=True, verbose_name='Comments')),
|
||||
('datebegin', models.DateTimeField(verbose_name='Début')),
|
||||
('dateend', models.DateTimeField(blank=True, verbose_name='Fin')),
|
||||
('name', models.CharField(max_length=255, verbose_name='Nom')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Event',
|
||||
'verbose_name_plural': 'Event',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventType',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='Nom')),
|
||||
('acronym', models.CharField(max_length=15, verbose_name='Acronyme')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Event Type',
|
||||
'verbose_name_plural': 'Event Types',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Event_Participation',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('rank', models.PositiveSmallIntegerField(default=0)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='planning.event')),
|
||||
('gymnast', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='people.gymnast')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Event Participation',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='eventtype',
|
||||
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='planning.eventtype', verbose_name='Type'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='gymnasts',
|
||||
field=models.ManyToManyField(related_name='participate_to', through='planning.Event_Participation', to='people.Gymnast', verbose_name='Participants'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='place',
|
||||
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='location.place'),
|
||||
),
|
||||
]
|
|
@ -1,27 +0,0 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-16 09:07
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Profile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('template_color', models.PositiveSmallIntegerField(choices=[(0, 'Dark'), (1, 'Light')], default=0, verbose_name='Template')),
|
||||
('sidebar_color', models.PositiveSmallIntegerField(choices=[(0, 'Purple'), (1, 'Blue'), (2, 'Green'), (3, 'Orange'), (4, 'Red')], default=0, verbose_name='Sidebar')),
|
||||
('is_sidebar_minified', models.BooleanField(default=False)),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -59,8 +59,9 @@
|
|||
<ul class="nav">
|
||||
{% menuitem 'home' 'tim-icons icon-chart-pie-36' 'Dashboard' %}
|
||||
{% menuitem 'gymnast_list' 'tim-icons icon-badge' 'Gymnasts' %}
|
||||
{% menuitem 'event_list' 'tim-icons icon-calendar-60' 'Events' %}
|
||||
{% menuitem 'skill_list' 'tim-icons icon-molecule-40' 'Skills' %}
|
||||
{% menuitem 'event_list' 'tim-icons icon-calendar-60' 'Events' %}
|
||||
{% menuitem 'accident_list' 'tim-icons icon-notes' 'Accidents' %}
|
||||
<!-- {% menuitem 'club_list' 'tim-icons icon-square-pin' 'Clubs' %} -->
|
||||
{% menuitem 'place_list' 'tim-icons icon-square-pin' 'Places' %}
|
||||
{% menuitem 'chrono_list' 'far fa-stopwatch' 'Chronos' %}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-12 col-md-8 col-lg-8 col-xl-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title">{% if accidentid %}Edit{% else %}Add{% endif %} accident</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{% if accidentid %}{% url 'accident_update' accidentid %}{% else %}{% url 'accident_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row ">
|
||||
<label for="id_date" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Date</label>
|
||||
<div class="col-8 col-sm-6 col-md-4 col-lg-4 col-xl-4 {% if form.date.errors %}has-danger{% endif %}">
|
||||
{{ form.date }}
|
||||
{% if form.date.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.date.errors %}{{error}}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row ">
|
||||
<label for="id_gymnast" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Gymnast</label>
|
||||
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.gymnast.errors %}has-danger{% endif %}">
|
||||
{{ form.gymnast }}
|
||||
{{ form.gymnast_related }}
|
||||
{% if form.gymnast.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.gymnast.errors %}{{error}}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row ">
|
||||
<label for="id_skill" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Skill</label>
|
||||
<div class="col-8 col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.educative.errors %}has-danger{% endif %}">
|
||||
{{ form.educative }}
|
||||
{{ form.educative_related }}
|
||||
{% if form.educative.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.educative.errors %}{{error}}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row ">
|
||||
<label for="id_information" class="col-4 col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Informations</label>
|
||||
<div class="col-8 col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_information.errors %}has-danger{% endif %}">
|
||||
{{ form.content }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<input type="submit" value="{% if accidentid %}Save{% else %}Add{% endif %}" class="btn btn-warning" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" >
|
||||
$(function(){
|
||||
blackDashboard.initDateTimePicker();
|
||||
|
||||
$('#id_gymnast_related').autocomplete({
|
||||
source: function(request, response){
|
||||
$.ajax({
|
||||
url: '/gymnast/lookup/?pattern=' + $('#id_gymnast_related').val(),
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.length != 0){
|
||||
response($.map(data, function(item){
|
||||
return {
|
||||
label: item.Name,
|
||||
value: item.Name,
|
||||
gymnastid: item.ID
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
response([{ label: 'No result found.', value: '' }]);
|
||||
};
|
||||
},
|
||||
|
||||
error: function(exception){
|
||||
console.log(exception);
|
||||
}
|
||||
});
|
||||
},
|
||||
minLength: 3,
|
||||
select: function(event, ui){
|
||||
$($(this).data('ref')).val(ui.item.gymnastid);
|
||||
}
|
||||
});
|
||||
|
||||
$('#id_educative_related').autocomplete({
|
||||
source: function(request, response) {
|
||||
$.ajax({
|
||||
url: '/skill/lookup/?pattern=' + $('#id_educative_related').val(),
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if(data.length != 0) {
|
||||
response($.map(data, function(item) {
|
||||
return {
|
||||
label: item.label,
|
||||
value: item.label,
|
||||
skillid: item.id
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
response([{ label: 'No result found.', value: '' }]);
|
||||
};
|
||||
},
|
||||
|
||||
error: function (exception) {
|
||||
console.log(exception);
|
||||
}
|
||||
});
|
||||
},
|
||||
minLength: 3,
|
||||
select: function (event, ui) {
|
||||
$($(this).data('ref')).val(ui.item.skillid);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,34 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
<!-- {% block page_title %}.: Accident's details :.{% endblock %} -->
|
||||
|
||||
<!-- {% block title %}Accident{% endblock %} -->
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title mb-0">Accident : {{ accident.date | date:"d-m-Y" }}</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<a href="{% url 'gymnast_details' accident.gymnast.id %}">{{ accident.gymnast }}</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
{{ accident.to_markdown | safe }}
|
||||
|
||||
<div class="card-footer pl-0 pb-0">
|
||||
<a href="{% url 'accident_list' %}">
|
||||
<button type="submit" value="add" class="btn btn-icon btn-warning ">
|
||||
<i class="tim-icons icon-double-left"></i>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,74 @@
|
|||
{% extends "listing.html" %}
|
||||
|
||||
<!-- {% block page_title %}.: Accident's list :.{% endblock %}
|
||||
{% block searchurl %}accident{% endblock %}
|
||||
{% block title %}Accidents{% endblock %}
|
||||
{% block addurl %}accident{% endblock %}
|
||||
{% block modurl %}accident{% endblock %}
|
||||
{% block search %}accident{% endblock %} -->
|
||||
|
||||
{% block datacontent %}
|
||||
<div class="card mb-0">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title"> Accidents' Listing</h4>
|
||||
</div>
|
||||
<div class="card-body pb-0">
|
||||
<div class="table-responsive pb-0">
|
||||
{% if accident_list.count >= 1 %}
|
||||
<table class="table tablesorter table-striped table-condensed" data-sort="table" id="maintable">
|
||||
<thead class="text-primary">
|
||||
<tr>
|
||||
<th style="width: 3%"></th>
|
||||
<th style="width: 10%">Date</th>
|
||||
<th style="width: 85%">Gymnast</th>
|
||||
<!-- <th style="width: 42%">Skill</th> -->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for accident in accident_list %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url 'accident_update' accident.id %}">
|
||||
<button type="button" rel="tooltip" class="btn btn-link btn-sm btn-icon">
|
||||
<span class="tim-icons icon-pencil text-warning"></span>
|
||||
</button>
|
||||
</a>
|
||||
</td>
|
||||
<td class="text-left"><a href="{% url 'accident_details' accident.id %}">{{ accident.date | date:"d-m-Y" }}</a></td>
|
||||
<td class="text-left"><a href="{% url 'gymnast_details' accident.gymnast.id %}">{{ accident.gymnast }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>There are no accident corresponding to your criterias</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer text-right text-muted pt-0">
|
||||
<a href="{% url 'accident_create' %}">
|
||||
<button type="submit" value="add" class="btn btn-icon btn-warning ">
|
||||
<i class="tim-icons icon-simple-add"></i>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footerscript %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('[data-sort="table"]').tablesorter({
|
||||
headers: {
|
||||
0: { sorter: false }, // disable first column
|
||||
},
|
||||
dateFormat: "uk",
|
||||
sortList: [[1,1]]
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -40,7 +40,7 @@
|
|||
<a href="{% url 'gymnast_details' chrono.gymnast.id %}">{{ chrono.gymnast }}</a>
|
||||
</td>
|
||||
<td class="text-left">{{ chrono.date | date:"d-m-Y" }}</td>
|
||||
<td class="text-left">{{ chrono.tof }}</td>
|
||||
<td class="text-right">{{ chrono.tof }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -22,9 +22,10 @@
|
|||
</div>
|
||||
</p>
|
||||
<div class="card-description">
|
||||
{{ gymnast.age }} years ({{ gymnast.birthdate | date:"d F Y" }})<span class="text-info"><b>{{ gymnast.get_orientation_display }}</b></span><br/>
|
||||
{{ gymnast.club.name }} - {{ gymnast.club.place.city }}<br/>
|
||||
<br \>
|
||||
{{ gymnast.age }} years ({{ gymnast.birthdate | date:"d F Y" }})<span class="text-info"><b>{{ gymnast.get_orientation_display }}</b></span><br />
|
||||
{{ gymnast.club.name }} - {{ gymnast.club.place.city }}<br />
|
||||
{{ gymnast.trainings_by_week }} training/week - {{ gymnast.hours_by_week }} hours/week<br />
|
||||
<br />
|
||||
{% if best_routine or best_straightjump %}
|
||||
<h5><u>Bests Scores</u></h5>
|
||||
<ul>
|
||||
|
@ -155,10 +156,9 @@
|
|||
]
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
{% if routine_score %}
|
||||
{
|
||||
label: 'L2',
|
||||
label: 'Routine',
|
||||
backgroundColor: 'rgb(255, 159, 64, 0.25)',
|
||||
borderColor: 'rgb(255, 159, 64)',
|
||||
fill: true,
|
||||
|
@ -179,8 +179,8 @@
|
|||
xAxes: [{
|
||||
type: "time",
|
||||
time: {
|
||||
format: 'DD-MM-YYYY',
|
||||
round: 'day'
|
||||
unit: 'day',
|
||||
format: 'DD-MM-YYYY'
|
||||
},
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
|
|
Loading…
Reference in New Issue