Add in the generated PDF
This commit is contained in:
parent
a3123d469f
commit
4237a957dd
|
@ -47,6 +47,12 @@
|
||||||
{% if form.learning_step.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.learning_step.errors %}{{error}}{% endfor %}</span>{% endif %}
|
{% if form.learning_step.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.learning_step.errors %}{{error}}{% endfor %}</span>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group row ">
|
||||||
|
<label for="id_information" class="col-4 col-sm-3 col-form-label">Points of attention</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.informations }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group text-center">
|
<div class="form-group text-center">
|
||||||
<input type="submit" value="Save" class="btn btn-fill btn-warning" />
|
<input type="submit" value="Save" class="btn btn-fill btn-warning" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-12 col-sm-12 col-md-8 col-lg-7 col-xl-6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h4 class="">{% if skill_id %}Edit{% else %}Add{% endif %} Skill informations</h4>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form action="{% if skill_id %}{% url 'skill_update' skill_id %}{% else %}{% url 'skill_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
|
||||||
|
{% csrf_token %}
|
||||||
|
<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.informations }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group text-center">
|
||||||
|
<input type="submit" value="Save" class="btn btn-warning" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -97,7 +97,10 @@
|
||||||
{% if skill.twist %}
|
{% if skill.twist %}
|
||||||
with <a href="#">{{ skill.twist }} half-twist</a>
|
with <a href="#">{{ skill.twist }} half-twist</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
in a <a href="#">{{ skill.get_position_display }}</a> position, landing on <a href="#">{{ skill.landing }}</a>.
|
{% if skill.get_position_display %}
|
||||||
|
in a <a href="#">{{ skill.get_position_display }}</a> position
|
||||||
|
{% endif %}
|
||||||
|
, landing on <a href="#">{{ skill.landing }}</a>.
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
{% if skill.informations %}
|
{% if skill.informations %}
|
||||||
|
@ -105,12 +108,16 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="text-muted">No more informations provided for this skill.</p>
|
<p class="text-muted">No more informations provided for this skill.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{% url 'skill_update' skill.id %}">
|
|
||||||
<span class="tim-icons icon-pencil text-warning"></span>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-footer pt-0 row">
|
||||||
|
<div class="col-md-12 text-right">
|
||||||
|
<a href="{% url 'skill_update' skill.id %}">
|
||||||
|
<span class="tim-icons icon-pencil text-warning"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -107,8 +107,12 @@
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td>{{ skill.notation }}</td>
|
<td>{{ skill.notation }}</td>
|
||||||
<td class="text-left"><a href="{% url 'skill_details' skill.id %}">{{ skill.long_label }}</a></td>
|
<td class="text-left">
|
||||||
<td>{{ skill.plan_date | date:"d-m-Y" }}</td>
|
<a href="{% url 'skill_details' skill.id %}">{{ skill.long_label }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ skill.plan_date | date:"d-m-Y" }}
|
||||||
|
</td>
|
||||||
<td>{{ skill.difficulty }}</td>
|
<td>{{ skill.difficulty }}</td>
|
||||||
<td>{{ skill.level }}</td>
|
<td>{{ skill.level }}</td>
|
||||||
<td>{{ skill.rank }}</td>
|
<td>{{ skill.rank }}</td>
|
||||||
|
|
|
@ -441,7 +441,7 @@ class PlanForm(forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Plan
|
model = Plan
|
||||||
fields = ("date", "gymnast", "educative", "learning_step", "is_done")
|
fields = ("date", "gymnast", "educative", "learning_step", "is_done", "informations")
|
||||||
widgets = {
|
widgets = {
|
||||||
"gymnast": forms.HiddenInput(),
|
"gymnast": forms.HiddenInput(),
|
||||||
"educative": forms.HiddenInput(),
|
"educative": forms.HiddenInput(),
|
||||||
|
@ -456,6 +456,12 @@ class PlanForm(forms.ModelForm):
|
||||||
"is_done": forms.CheckboxInput(
|
"is_done": forms.CheckboxInput(
|
||||||
attrs={"class": "form-control form-check-input ml-0 mt-0"}
|
attrs={"class": "form-control form-check-input ml-0 mt-0"}
|
||||||
),
|
),
|
||||||
|
"informations": forms.Textarea(
|
||||||
|
attrs={
|
||||||
|
"class": "form-control",
|
||||||
|
"placeholder": "Informations about gymnast for this particular skill: usual mistake, fear, …", # pylint: disable=line-too-long
|
||||||
|
}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
gymnast_related = forms.CharField(
|
gymnast_related = forms.CharField(
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 4.1.1 on 2022-10-16 06:20
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("followup", "0028_rename_cando_learnedskill_learning_step_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="plan",
|
||||||
|
name="informations",
|
||||||
|
field=models.TextField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Only MarkDown is authorized",
|
||||||
|
null=True,
|
||||||
|
verbose_name="Comments",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -169,7 +169,7 @@ class LearnedSkill(Seasonisable):
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
|
||||||
class Plan(Seasonisable):
|
class Plan(Seasonisable, Markdownizable):
|
||||||
"""
|
"""
|
||||||
Classe représentant les objectifs qu'un gymnaste devra savoir faire pour une date donnée.
|
Classe représentant les objectifs qu'un gymnaste devra savoir faire pour une date donnée.
|
||||||
"""
|
"""
|
||||||
|
@ -206,6 +206,9 @@ class Plan(Seasonisable):
|
||||||
self.date,
|
self.date,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# @property
|
||||||
|
# def is_due(self):
|
||||||
|
# return pendulum.now().date() > self.date
|
||||||
|
|
||||||
class Point(models.Model):
|
class Point(models.Model):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -91,6 +91,10 @@ class Seasonisable(models.Model):
|
||||||
self.season, self.week_number = from_date_to_week_number(self.date)
|
self.season, self.week_number = from_date_to_week_number(self.date)
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
# @property
|
||||||
|
# def is_past(self):
|
||||||
|
# return pendulum.now().date() > self.date
|
||||||
|
|
||||||
|
|
||||||
class TemporizableQuerySet(models.QuerySet):
|
class TemporizableQuerySet(models.QuerySet):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -44,7 +44,7 @@ environ.Env.read_env()
|
||||||
|
|
||||||
X = 35
|
X = 35
|
||||||
Y = 841.89
|
Y = 841.89
|
||||||
INDENT = 5
|
INDENT = 15
|
||||||
RIGHT_X = 595.27 - X
|
RIGHT_X = 595.27 - X
|
||||||
TITLED_X = 125
|
TITLED_X = 125
|
||||||
INDENTED_X = X + INDENT
|
INDENTED_X = X + INDENT
|
||||||
|
@ -85,6 +85,12 @@ class PDFDocument(object):
|
||||||
self.mobile_phone = env("MOBILE_PHONE", default=None)
|
self.mobile_phone = env("MOBILE_PHONE", default=None)
|
||||||
self.coach_email = env("HEAD_COACH_EMAIL", default=None)
|
self.coach_email = env("HEAD_COACH_EMAIL", default=None)
|
||||||
|
|
||||||
|
def new_page(self):
|
||||||
|
""" """
|
||||||
|
# self.y = Y - X
|
||||||
|
self.document.showPage()
|
||||||
|
self.y = Y - X
|
||||||
|
|
||||||
def add_vspace(self, height=COMMON_LINE_HEIGHT):
|
def add_vspace(self, height=COMMON_LINE_HEIGHT):
|
||||||
""" Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
|
""" Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
|
||||||
|
|
||||||
|
@ -190,11 +196,16 @@ class GymnastReportDocument(PDFDocument):
|
||||||
self.add_gymnast_best_scores(gymnast)
|
self.add_gymnast_best_scores(gymnast)
|
||||||
self.add_gymnast_active_routine(gymnast)
|
self.add_gymnast_active_routine(gymnast)
|
||||||
# self.add_gymnast_level_information(gymnast)
|
# self.add_gymnast_level_information(gymnast)
|
||||||
self.add_gymnast_next_skills(gymnast)
|
planned_skill = self.add_gymnast_planned_skill(gymnast)
|
||||||
|
print(planned_skill)
|
||||||
self.add_gymnast_last_learned_skill(gymnast)
|
self.add_gymnast_last_learned_skill(gymnast)
|
||||||
self.add_gymnast_next_events(gymnast)
|
self.add_gymnast_next_events(gymnast)
|
||||||
self.add_gymnast_week_notes(gymnast)
|
self.add_gymnast_week_notes(gymnast)
|
||||||
|
|
||||||
|
if planned_skill:
|
||||||
|
self.new_page()
|
||||||
|
self.add_planned_skills_details(planned_skill)
|
||||||
|
|
||||||
def add_gymnast_personnal_information(self, gymnast):
|
def add_gymnast_personnal_information(self, gymnast):
|
||||||
""" Ajoute les informations personnelles du gymnast.
|
""" Ajoute les informations personnelles du gymnast.
|
||||||
|
|
||||||
|
@ -563,7 +574,7 @@ class GymnastReportDocument(PDFDocument):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def add_gymnast_next_skills(self, gymnast):
|
def add_gymnast_planned_skill(self, gymnast):
|
||||||
""" Ajoute les prochains skill (skill planifié) à apprendre
|
""" Ajoute les prochains skill (skill planifié) à apprendre
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -584,27 +595,29 @@ class GymnastReportDocument(PDFDocument):
|
||||||
# le double F ne fonctionne qu'en précisant le distinct, sinon ca dédouble les résultats.
|
# le double F ne fonctionne qu'en précisant le distinct, sinon ca dédouble les résultats.
|
||||||
# qui lui même ne fonctionne que sur un champ présent dans le `order_by` (que le premier champ ?)
|
# qui lui même ne fonctionne que sur un champ présent dans le `order_by` (que le premier champ ?)
|
||||||
#
|
#
|
||||||
planified_skills = (
|
planned_skills = (
|
||||||
Skill.objects.filter(plan__gymnast=gymnast.id)
|
Skill.objects.filter(plan__gymnast=gymnast.id)
|
||||||
.filter(
|
.filter(
|
||||||
Q(plan__is_done=False)
|
Q(plan__is_done=False)
|
||||||
| Q(plan__date__gte=date.today())
|
| Q(plan__date__gte=date.today())
|
||||||
)
|
)
|
||||||
# .annotate(plan_date=F("plan__date"))
|
# .annotate(plan_date=F("plan__date"))
|
||||||
.annotate(plan_date=F("plan__date"), learning_step=F("plan__learning_step"))
|
.annotate(plan_date=F("plan__date"), learning_step=F("plan__learning_step"), plan_id=F("plan__id"))
|
||||||
.order_by("notation", "-plan__date").distinct('notation')[:6]
|
.order_by("id", "-plan__date").distinct('id')[:6]
|
||||||
)
|
)
|
||||||
|
|
||||||
if planified_skills:
|
if planned_skills:
|
||||||
for planified_skill in planified_skills:
|
for planned_skill in planned_skills:
|
||||||
self.add_new_line(
|
self.add_new_line(
|
||||||
X, planified_skill.short_label + " " + str(LEARNING_STEP_CHOICES[planified_skill.learning_step][1]).lower() + " (" + planified_skill.notation + ") for " + planified_skill.plan_date.strftime("%d-%m-%Y")
|
X, planned_skill.short_label + " " + str(LEARNING_STEP_CHOICES[planned_skill.learning_step][1]).lower() + " (" + planned_skill.notation + ") for " + planned_skill.plan_date.strftime("%d-%m-%Y")
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.add_new_line(
|
self.add_new_line(
|
||||||
X,
|
X,
|
||||||
"No next skill to learn plannified.",
|
"No next skill to learn plannified.",
|
||||||
)
|
)
|
||||||
|
print(planned_skills)
|
||||||
|
return planned_skills
|
||||||
|
|
||||||
def add_gymnast_next_events(self, gymnast):
|
def add_gymnast_next_events(self, gymnast):
|
||||||
""" Ajoute les évènements futurs du gymnaste """
|
""" Ajoute les évènements futurs du gymnaste """
|
||||||
|
@ -678,3 +691,27 @@ class GymnastReportDocument(PDFDocument):
|
||||||
X,
|
X,
|
||||||
"No note associated to this gymnast this week.",
|
"No note associated to this gymnast this week.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def add_planned_skills_details(self, planned_skills):
|
||||||
|
""" """
|
||||||
|
# self.y = 20*cm
|
||||||
|
self.add_new_line(
|
||||||
|
X,
|
||||||
|
"Points of attention",
|
||||||
|
font_decoration="Bold",
|
||||||
|
)
|
||||||
|
self.add_vspace(-0.5*cm)
|
||||||
|
|
||||||
|
for planned_skill in planned_skills:
|
||||||
|
plan = Plan.objects.get(pk=planned_skill.plan_id)
|
||||||
|
|
||||||
|
html_text = "<u>" + planned_skill.short_label + " (" + planned_skill.notation + ") :</u>"
|
||||||
|
paragraph = Paragraph(html_text, self.style)
|
||||||
|
width, height = paragraph.wrap(18*cm, 10*cm)
|
||||||
|
paragraph.drawOn(self.document, INDENTED_X, self.y - (height / 2))
|
||||||
|
|
||||||
|
self.add_new_line(
|
||||||
|
INDENTED_X,
|
||||||
|
plan.informations
|
||||||
|
)
|
||||||
|
self.add_vspace(-0.4*cm)
|
||||||
|
|
Loading…
Reference in New Issue