Add in the generated PDF

This commit is contained in:
Gregory Trullemans 2022-10-16 18:23:36 +02:00
parent a3123d469f
commit 4237a957dd
9 changed files with 135 additions and 17 deletions

View File

@ -47,6 +47,12 @@
{% if form.learning_step.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.learning_step.errors %}{{error}}{% endfor %}</span>{% endif %} {% if form.learning_step.errors %}&nbsp;<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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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