Adding points, accidents and minor bugs fixes

This commit is contained in:
Trullemans Gregory 2021-11-18 21:36:15 +01:00
parent 9108cb3adc
commit e7c9e75d8c
27 changed files with 425 additions and 423 deletions

View File

@ -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)),

View File

@ -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)

View File

@ -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",
# }
# )
# )

View File

@ -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')},
},
),
]

View File

@ -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')),
],
),
]

View File

@ -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.

View File

@ -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"),
]

View File

@ -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)

View File

@ -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',
},
),
]

View File

@ -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',
),
]

View File

@ -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)

View File

@ -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',
},
),
]

View File

@ -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'),
),
]

View File

@ -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

View File

@ -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'),
),
]

View File

@ -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)),
],
),
]

View File

@ -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' %}

View File

@ -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 %}&nbsp;<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 %}&nbsp;<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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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>

View File

@ -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,