PDF to update students data

This commit is contained in:
alazo 2017-08-08 16:11:55 +02:00 committed by Claude Paroz
parent e08356e6eb
commit 8b673665ce
6 changed files with 167 additions and 9 deletions

View file

@ -161,6 +161,18 @@ class Student(models.Model):
def __str__(self):
return '%s %s' % (self.last_name, self.first_name)
@property
def civility(self):
return 'Monsieur' if self.gender == 'M' else 'Madame'
@property
def full_name(self):
return '{0} {1}'.format(self.first_name, self.last_name)
@property
def pcode_city(self):
return '{0} {1}'.format(self.pcode, self.city)
def save(self, **kwargs):
if self.archived and not self.archived_text:
# Fill archived_text with training data, JSON-formatted
@ -222,6 +234,10 @@ class Corporation(models.Model):
sect = ' (%s)' % self.sector if self.sector else ''
return "%s%s, %s %s" % (self.name, sect, self.pcode, self.city)
@property
def pcode_city(self):
return '{0} {1}'.format(self.pcode, self.city)
class CorpContact(models.Model):
corporation = models.ForeignKey(Corporation, verbose_name='Institution', on_delete=models.CASCADE)

View file

@ -71,3 +71,109 @@ class ChargeSheetPDF(SimpleDocTemplate):
self.story.append(Paragraph('la direction', style_normal))
self.story.append(PageBreak())
self.build(self.story)
class UpdateDataFormPDF(SimpleDocTemplate):
"""
Génération des formulaires PDF de mise à jour des données.
"""
def __init__(self, path):
super().__init__(path, pagesize=A4, topMargin=0*cm, leftMargin=2*cm)
self.text = (
"Afin de mettre à jour nos bases de données, nous vous serions reconnaissant "
"de contrôler les données ci-dessous qui vous concernent selon votre filière "
"et de retourner le présent document corrigé et complété à votre maître de classe jusqu'au "
"vendredi 9 septembre prochain.<br/><br/>"
"Nous vous remercions de votre précieuse collaboration.<br/><br/>"
"Le secrétariat"
)
self.underline = '__________________________________'
def produce(self, klass):
self.story = []
for student in klass.student_set.all():
self.story.append(Image(find('img/header.gif'), width=520, height=75))
self.story.append(Spacer(0, 2*cm))
destinataire = '{0}<br/>{1}<br/>{2}'.format(student.civility, student.full_name, student.klass)
self.story.append(Paragraph(destinataire, style_adress))
self.story.append(Spacer(0, 2*cm))
self.story.append(Paragraph('{0},<br/>'.format(student.civility), style_normal))
self.story.append(Paragraph(self.text, style_normal))
self.story.append(Spacer(0, 2*cm))
data = [['Données enregistrées', 'Données corrigées et/ou complétées']]
t = Table(data, colWidths=[8*cm, 8*cm])
t.setStyle(TableStyle([
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
('FONT', (0, 0), (-1, -1), 'Helvetica-Bold'),
]))
t.hAlign = TA_CENTER
self.story.append(t)
# Personal data
data = [
['NOM', student.last_name, self.underline],
['PRENOM', student.first_name, self.underline],
['ADRESSE', student.street, self.underline],
['LOCALITE', student.pcode_city, self.underline],
['MOBILE', student.mobile, self.underline],
['CLASSE', student.klass, self.underline],
['', '', ''],
]
# Corporation data
if self.is_corp_required(student.klass.name):
if student.corporation is None:
data.extend([
["Données de l'Employeur", '', ''],
['NOM', '', self.underline],
['ADRESSE', '', self.underline],
['LOCALITE', '', self.underline],
['', '', '']
])
else:
data.extend([
["Données de l'Employeur", '', ''],
['NOM', student.corporation.name, self.underline],
['ADRESSE', student.corporation.street, self.underline],
['LOCALITE', student.corporation.pcode_city, self.underline],
['', '', '']
])
# Instructor data
if self.is_instr_required(student.klass.name):
if student.instructor is None:
data.extend([
['Données du FEE/FPP (personne de contact pour les informations)', '', ''],
['NOM', '', self.underline],
['PRENOM', '', self.underline],
['TELEPHONE', '', self.underline],
['E-MAIL', '', self.underline],
])
else:
data.extend([
['Données du FEE/FPP (personne de contact pour les informations)', '', ''],
['NOM', student.instructor.last_name, self.underline],
['PRENOM', student.instructor.first_name, self.underline],
['TELEPHONE', student.instructor.tel, self.underline],
['E-MAIL', student.instructor.email, self.underline],
])
t = Table(data, colWidths=[3*cm, 5*cm, 8*cm])
t.setStyle(TableStyle([
('ALIGN', (1, 0), (-1, -1), 'LEFT'),
('FONT', (0, 0), (0, -1), 'Helvetica-Bold'),
]))
t.hAlign = TA_CENTER
self.story.append(t)
self.story.append(PageBreak())
if len(self.story) == 0:
self.story.append(Paragraph("Pas d'élèves dans cette classe", style_normal))
self.build(self.story)
def is_corp_required(self, klass_name):
return any(el in klass_name for el in ['FE', 'EDS', 'EDEpe'])
def is_instr_required(self, klass_name):
return any(el in klass_name for el in ['FE', 'EDS'])

View file

@ -18,15 +18,24 @@ class StagesTest(TestCase):
@classmethod
def setUpTestData(cls):
Section.objects.bulk_create([
Section(name='ASE'), Section(name='ASSC'), Section(name='EDE')
Section(name='ASE'), Section(name='ASSC'), Section(name='EDE'), Section(name='EDS')
])
sect_ase = Section.objects.get(name='ASE')
lev1 = Level.objects.create(name='1')
lev2 = Level.objects.create(name='2')
klass1 = Klass.objects.create(name="1ASE3", section=sect_ase, level=lev1)
klass2 = Klass.objects.create(name="2ASE3", section=sect_ase, level=lev2)
klass3 = Klass.objects.create(name="2EDS", section=Section.objects.get(name='EDS'), level=lev2)
dom_hand = Domain.objects.create(name="handicap")
dom_pe = Domain.objects.create(name="petite enfance")
corp = Corporation.objects.create(
name="Centre pédagogique XY", typ="Institution", street="Rue des champs 12",
city="Moulineaux", pcode="2500",
)
contact = CorpContact.objects.create(
corporation=corp, title="Monsieur", first_name="Jean", last_name="Horner",
is_main=True, role="Responsable formation",
)
Student.objects.bulk_create([
Student(first_name="Albin", last_name="Dupond", birth_date="1994-05-12",
pcode="2300", city="La Chaux-de-Fonds", klass=klass1),
@ -36,16 +45,10 @@ class StagesTest(TestCase):
pcode="2053", city="Cernier", klass=klass1),
Student(first_name="André", last_name="Allemand", birth_date="1994-10-11",
pcode="2314", city="La Sagne", klass=klass2),
Student(first_name="Gil", last_name="Schmid", birth_date="1996-02-14",
pcode="2000", city="Neuchâtel", klass=klass3, corporation=corp),
])
ref1 = Teacher.objects.create(first_name="Julie", last_name="Caux", abrev="JCA")
corp = Corporation.objects.create(
name="Centre pédagogique XY", typ="Institution", street="Rue des champs 12",
city="Moulineaux", pcode="2500",
)
contact = CorpContact.objects.create(
corporation=corp, title="Monsieur", first_name="Jean", last_name="Horner",
is_main=True, role="Responsable formation",
)
cls.p1 = Period.objects.create(
title="Stage de pré-sensibilisation", start_date="2012-11-26", end_date="2012-12-07",
section=sect_ase, level=lev1,
@ -130,6 +133,14 @@ class StagesTest(TestCase):
self.assertEqual(len(decoded), 2)
self.assertEqual([item['priority'] for item in decoded], [True, False])
def test_export_update_forms(self):
self.client.login(username='me', password='mepassword')
response = self.client.get(reverse('print_update_form'))
self.assertEqual(
response['Content-Disposition'], 'attachment; filename="modification.zip"'
)
self.assertGreater(int(response['Content-Length']), 10)
class PeriodTest(TestCase):
def setUp(self):

View file

@ -1,4 +1,7 @@
import json
import os
import tempfile
import zipfile
from collections import OrderedDict
from datetime import date, datetime, timedelta
@ -23,6 +26,7 @@ from .models import (
Klass, Section, Student, Teacher, Corporation, CorpContact, Course, Period,
Training, Availability,
)
from .pdf import UpdateDataFormPDF
from .utils import is_int
@ -628,3 +632,22 @@ def imputations_export(request):
response['Content-Disposition'] = 'attachment; filename=%s%s.xlsx' % (
'Imputations_export', date.strftime(date.today(), '%Y-%m-%d'))
return response
def print_update_form(request):
"""
PDF form to update personal data
"""
tmp_file = tempfile.NamedTemporaryFile()
with zipfile.ZipFile(tmp_file, mode='w', compression=zipfile.ZIP_DEFLATED) as filezip:
for klass in Klass.objects.filter(level__gte=2).exclude(section__name='MP_ASSC').exclude(section__name='MP_ASE'):
path = os.path.join(tempfile.gettempdir(), '{0}.pdf'.format(klass.name))
pdf = UpdateDataFormPDF(path)
pdf.produce(klass)
filezip.write(pdf.filename)
break
with open(filezip.filename, mode='rb') as fh:
response = HttpResponse(fh.read(), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename="modification.zip"'
return response