[candidats] Add summary print action
This commit is contained in:
parent
ffb54c9f78
commit
50af7f321c
5 changed files with 218 additions and 5 deletions
|
|
@ -1,3 +1,6 @@
|
|||
import os
|
||||
import tempfile
|
||||
import zipfile
|
||||
from collections import OrderedDict
|
||||
from datetime import date
|
||||
|
||||
|
|
@ -5,11 +8,13 @@ from django import forms
|
|||
from django.contrib import admin
|
||||
from django.core.mail import EmailMessage
|
||||
from django.db.models import BooleanField
|
||||
from django.http import HttpResponse
|
||||
from django.template import loader
|
||||
from django.urls import reverse
|
||||
|
||||
from stages.exports import OpenXMLExport
|
||||
from .models import Candidate, Interview, GENDER_CHOICES
|
||||
from .pdf import InscriptionSummaryPDF
|
||||
|
||||
|
||||
def export_candidates(modeladmin, request, queryset):
|
||||
|
|
@ -84,10 +89,29 @@ def send_confirmation_mail(modeladmin, request, queryset):
|
|||
candidate.date_confirmation_mail = date.today()
|
||||
candidate.save()
|
||||
modeladmin.message_user(request, "%d messages de confirmation ont été envoyés." % email_sent)
|
||||
|
||||
send_confirmation_mail.short_description = "Envoyer email de confirmation"
|
||||
|
||||
|
||||
def print_summary(modeladmin, request, queryset):
|
||||
"""
|
||||
Print a summary of inscription
|
||||
"""
|
||||
filename = 'archive_InscriptionResumes.zip'
|
||||
path = os.path.join(tempfile.gettempdir(), filename)
|
||||
|
||||
with zipfile.ZipFile(path, mode='w', compression=zipfile.ZIP_DEFLATED) as filezip:
|
||||
for candidate in queryset:
|
||||
pdf = InscriptionSummaryPDF(candidate)
|
||||
pdf.produce(candidate)
|
||||
filezip.write(pdf.filename)
|
||||
|
||||
with open(filezip.filename, mode='rb') as fh:
|
||||
response = HttpResponse(fh.read(), content_type='application/zip')
|
||||
response['Content-Disposition'] = 'attachment; filename="{0}"'.format(filename)
|
||||
return response
|
||||
print_summary.short_description = 'Imprimer résumé'
|
||||
|
||||
|
||||
class CandidateAdminForm(forms.ModelForm):
|
||||
interview = forms.ModelChoiceField(queryset=Interview.objects.all(), required=False)
|
||||
|
||||
|
|
@ -123,7 +147,7 @@ class CandidateAdmin(admin.ModelAdmin):
|
|||
list_display = ('last_name', 'first_name', 'section', 'confirm_mail', 'convocation')
|
||||
list_filter = ('section', 'option')
|
||||
readonly_fields = ('total_result_points', 'total_result_mark', 'date_confirmation_mail')
|
||||
actions = [export_candidates, send_confirmation_mail]
|
||||
actions = [export_candidates, send_confirmation_mail, print_summary]
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': (('first_name', 'last_name', 'gender'),
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ class Candidate(models.Model):
|
|||
else:
|
||||
return ''
|
||||
|
||||
def get_ok(self, fieldname):
|
||||
return 'OK' if getattr(self, fieldname) is True else 'NON'
|
||||
|
||||
|
||||
INTERVIEW_CHOICES = (
|
||||
('N', 'Normal'),
|
||||
|
|
|
|||
113
candidats/pdf.py
Normal file
113
candidats/pdf.py
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import os
|
||||
import tempfile
|
||||
|
||||
from reportlab.lib.enums import TA_LEFT
|
||||
from reportlab.lib.styles import ParagraphStyle as PS
|
||||
from reportlab.lib.units import cm
|
||||
from reportlab.platypus import Paragraph, Preformatted, Table, TableStyle
|
||||
|
||||
from django.utils.text import slugify
|
||||
|
||||
from stages.pdf import EpcBaseDocTemplate
|
||||
from .models import (
|
||||
AES_ACCORDS_CHOICES, DIPLOMA_CHOICES, DIPLOMA_STATUS_CHOICES,
|
||||
OPTION_CHOICES, RESIDENCE_PERMITS_CHOICES,
|
||||
)
|
||||
|
||||
style_normal = PS(name='CORPS', fontName='Helvetica', fontSize=9, alignment=TA_LEFT)
|
||||
style_normal_bold = PS(name='CORPS', fontName='Helvetica-Bold', fontSize=9, alignment=TA_LEFT, spaceBefore=0.5 * cm)
|
||||
|
||||
|
||||
class InscriptionSummaryPDF(EpcBaseDocTemplate):
|
||||
"""
|
||||
PDF for summary of inscription
|
||||
"""
|
||||
def __init__(self, candidate, **kwargs):
|
||||
filename = slugify('{0}_{1}'.format(candidate.last_name, candidate.first_name)) + '.pdf'
|
||||
path = os.path.join(tempfile.gettempdir(), filename)
|
||||
super().__init__(path, title="Dossier d'inscription", **kwargs)
|
||||
self.setNormalTemplatePage()
|
||||
|
||||
def produce(self, candidate):
|
||||
# personal data
|
||||
options = dict(OPTION_CHOICES)
|
||||
diploma = dict(DIPLOMA_CHOICES)
|
||||
diploma_status = dict(DIPLOMA_STATUS_CHOICES)
|
||||
aes_accords = dict(AES_ACCORDS_CHOICES)
|
||||
residence_permits = dict(RESIDENCE_PERMITS_CHOICES)
|
||||
|
||||
myTableStyle = TableStyle([
|
||||
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
|
||||
('FONT', (0, 0), (-1, -1), 'Helvetica'),
|
||||
('SIZE', (0, 0), (-1, -1), 8)
|
||||
])
|
||||
|
||||
self.story.append(Paragraph("Données personnelles", style_normal_bold))
|
||||
data = [
|
||||
['Nom: ', candidate.last_name, 'Date de naissance:', candidate.birth_date],
|
||||
['Prénom:', candidate.first_name, 'Canton:', candidate.district],
|
||||
['N° de tél.:', candidate.mobile, '',''],
|
||||
]
|
||||
t = Table(data, colWidths=[2 * cm, 6 * cm, 4 * cm, 5 * cm], hAlign=TA_LEFT)
|
||||
t.setStyle(myTableStyle)
|
||||
self.story.append(t)
|
||||
|
||||
# Chosen Option
|
||||
data = []
|
||||
self.story.append(Paragraph("Option choisie", style_normal_bold))
|
||||
data.append([options.get(candidate.option, '')])
|
||||
t = Table(data, colWidths=[17 * cm], hAlign=TA_LEFT)
|
||||
t.setStyle(myTableStyle)
|
||||
self.story.append(t)
|
||||
|
||||
# Diploma
|
||||
data = []
|
||||
self.story.append(Paragraph("Titres / diplômes /attest. prof.", style_normal_bold))
|
||||
data.append([
|
||||
diploma[candidate.diploma],
|
||||
'{0} {1}'.format(candidate.diploma_detail, diploma_status[candidate.diploma_status])
|
||||
])
|
||||
|
||||
if candidate.diploma == 1: # CFC ASE
|
||||
data.append(['Evaluation du dernier stage', candidate.get_ok('work_certificate')])
|
||||
elif candidate.diploma == 2: # CFC autre domaine
|
||||
data.append(['Attestation de 800h. min. domaine Enfance',candidate.get_ok('certif_of_800_childhood')])
|
||||
data.append(["Bilan de l'activité professionnelle", candidate.get_ok('work_certificate')])
|
||||
elif candidate.diploma == 3 or candidate.diploma == 4: # Matu. aca ou ECG ou Portfolio
|
||||
data.append(['Attestation de 800h. min. domaine Général', candidate.get_ok('certif_800_general')])
|
||||
data.append(['Attestation de 800h. min. domaine Enfance', candidate.get_ok('certif_of_800_childhood')])
|
||||
data.append(["Bilan de l'activité professionnelle", candidate.get_ok('work_certificate')])
|
||||
|
||||
if candidate.option != 'PS':
|
||||
data.append(["Contrat de travail", candidate.get_ok('contract')])
|
||||
data.append(["Promesse d'engagement", candidate.get_ok('promise')])
|
||||
data.append(["Taux d'activité", candidate.activity_rate])
|
||||
t = Table(data, colWidths=[12 * cm, 5 * cm], hAlign=TA_LEFT)
|
||||
t.setStyle(myTableStyle)
|
||||
self.story.append(t)
|
||||
|
||||
# Others documents
|
||||
data = []
|
||||
self.story.append(Paragraph("Autres documents", style_normal_bold))
|
||||
docs = [
|
||||
'registration_form', 'certificate_of_payement', 'police_record', 'cv', 'has_photo',
|
||||
'reflexive_text', 'marks_certificate', 'aes_accords', 'residence_permits'
|
||||
]
|
||||
for doc in docs:
|
||||
data.append([candidate._meta.get_field(doc).verbose_name, candidate.get_ok(doc)])
|
||||
data.append(['Validation des accords AES', aes_accords[candidate.aes_accords]])
|
||||
data.append(['Autorisation de séjour (pour les personnes étrangères)', residence_permits[candidate.residence_permits]])
|
||||
|
||||
t = Table(data, colWidths=[12 * cm, 5 * cm], hAlign=TA_LEFT)
|
||||
t.setStyle(myTableStyle)
|
||||
self.story.append(t)
|
||||
|
||||
# Remarks
|
||||
data = []
|
||||
self.story.append(Paragraph("Remarques", style_normal_bold))
|
||||
data.append([Preformatted(candidate.comment, style_normal, maxLineLength=100)])
|
||||
t = Table(data, colWidths=[17 * cm], hAlign=TA_LEFT)
|
||||
t.setStyle(myTableStyle)
|
||||
self.story.append(t)
|
||||
|
||||
self.build(self.story)
|
||||
|
|
@ -163,3 +163,22 @@ tél. 032 886 33 00"""
|
|||
self.assertEqual(mail.outbox[0].subject, "Procédure de qualification")
|
||||
henri.refresh_from_db()
|
||||
self.assertIsNotNone(henri.convocation_date)
|
||||
|
||||
def test_summary_pdf(self):
|
||||
ede = Section.objects.create(name='EDE')
|
||||
cand = Candidate.objects.create(
|
||||
first_name='Henri', last_name='Dupond', gender='M', section=ede,
|
||||
email='henri@example.org', deposite_date=date.today()
|
||||
)
|
||||
change_url = reverse('admin:candidats_candidate_changelist')
|
||||
self.client.login(username='me', password='mepassword')
|
||||
response = self.client.post(change_url, {
|
||||
'action': 'print_summary',
|
||||
'_selected_action': Candidate.objects.values_list('pk', flat=True)
|
||||
}, follow=True)
|
||||
self.assertEqual(
|
||||
response['Content-Disposition'],
|
||||
'attachment; filename="archive_InscriptionResumes.zip"'
|
||||
)
|
||||
self.assertEqual(response['Content-Type'], 'application/zip')
|
||||
self.assertGreater(len(response.content), 200)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue