Add confirmation/validation/convocation views
This commit is contained in:
parent
5a2a5d769f
commit
e62284d55c
8 changed files with 312 additions and 159 deletions
|
|
@ -1,21 +1,13 @@
|
|||
import os
|
||||
import tempfile
|
||||
import zipfile
|
||||
from collections import OrderedDict
|
||||
from datetime import date
|
||||
|
||||
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 django.utils.html import format_html
|
||||
|
||||
from stages.exports import OpenXMLExport
|
||||
from .forms import CandidateForm
|
||||
from .models import Candidate, Interview, GENDER_CHOICES
|
||||
from .pdf import InscriptionSummaryPDF
|
||||
|
||||
|
||||
def export_candidates(modeladmin, request, queryset):
|
||||
|
|
@ -46,85 +38,21 @@ def export_candidates(modeladmin, request, queryset):
|
|||
export_candidates.short_description = "Exporter les candidats sélectionnés"
|
||||
|
||||
|
||||
def send_confirmation_mail(modeladmin, request, queryset):
|
||||
from_email = request.user.email
|
||||
subject = "Confirmation de votre inscription à l'Ecole Santé-social Pierre-Coullery"
|
||||
email_sent = 0
|
||||
|
||||
for candidate in queryset.filter(
|
||||
deposite_date__isnull=False, date_confirmation_mail__isnull=True, canceled_file=False):
|
||||
to = [candidate.email]
|
||||
|
||||
if candidate.corporation and candidate.corporation.email:
|
||||
to.append(candidate.corporation.email)
|
||||
if candidate.instructor and candidate.instructor.email:
|
||||
to.append(candidate.instructor.email)
|
||||
|
||||
context = {
|
||||
'candidate_civility': candidate.civility,
|
||||
'candidate_name': " ".join([candidate.civility, candidate.first_name, candidate.last_name]),
|
||||
'section': candidate.section,
|
||||
'sender_name': " ".join([request.user.first_name, request.user.last_name]),
|
||||
'sender_email': from_email,
|
||||
}
|
||||
|
||||
if candidate.section == 'EDE':
|
||||
body = loader.render_to_string('email/candidate_confirm_EDE.txt', context)
|
||||
else:
|
||||
body = loader.render_to_string('email/candidate_confirm_FE.txt', context)
|
||||
|
||||
email = EmailMessage(
|
||||
subject=subject,
|
||||
body=body,
|
||||
from_email=from_email,
|
||||
to=to,
|
||||
bcc=[from_email]
|
||||
)
|
||||
|
||||
try:
|
||||
email.send()
|
||||
email_sent += 1
|
||||
except Exception as err:
|
||||
modeladmin.message_user(request, "Échec d’envoi pour le candidat {0} ({1})".format(candidate, err))
|
||||
else:
|
||||
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 CandidateAdmin(admin.ModelAdmin):
|
||||
form = CandidateForm
|
||||
list_display = ('last_name', 'first_name', 'section', 'confirm_mail', 'convocation')
|
||||
list_filter = ('section', 'option')
|
||||
readonly_fields = ('total_result_points', 'total_result_mark', 'confirmation_date')
|
||||
actions = [export_candidates, send_confirmation_mail, print_summary]
|
||||
readonly_fields = (
|
||||
'total_result_points', 'total_result_mark', 'confirmation_date', 'validation_date',
|
||||
'convocation_date', 'candidate_actions',
|
||||
)
|
||||
actions = [export_candidates]
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': (('first_name', 'last_name', 'gender'),
|
||||
('street', 'pcode', 'city', 'district'),
|
||||
('mobile', 'email'),
|
||||
('birth_date', 'avs', 'handicap', 'has_photo'),
|
||||
('birth_date', 'avs', 'handicap'),
|
||||
('section', 'option'),
|
||||
('corporation', 'instructor'),
|
||||
('deposite_date', 'confirmation_date', 'canceled_file'),
|
||||
|
|
@ -138,15 +66,19 @@ class CandidateAdmin(admin.ModelAdmin):
|
|||
("EDE/EDS", {
|
||||
'classes': ('collapse',),
|
||||
'fields': (('diploma', 'diploma_detail', 'diploma_status'),
|
||||
('registration_form', 'certificate_of_payement', 'cv', 'police_record', 'reflexive_text',
|
||||
('registration_form', 'has_photo', 'certificate_of_payement', 'cv', 'police_record', 'reflexive_text',
|
||||
'marks_certificate', 'residence_permits', 'aes_accords'),
|
||||
('certif_of_800_childhood', 'certif_of_800_general', 'work_certificate'),
|
||||
('promise', 'contract', 'activity_rate'),
|
||||
('interview',),
|
||||
('examination_result', 'interview_result', 'file_result', 'total_result_points',
|
||||
'total_result_mark')
|
||||
'total_result_mark'),
|
||||
('confirmation_date', 'validation_date', 'convocation_date'),
|
||||
),
|
||||
}),
|
||||
(None, {
|
||||
'fields': (('candidate_actions',)),
|
||||
}),
|
||||
)
|
||||
|
||||
def confirm_mail(self, obj):
|
||||
|
|
@ -164,6 +96,20 @@ class CandidateAdmin(admin.ModelAdmin):
|
|||
convocation.short_description = 'Convoc. aux examens'
|
||||
convocation.allow_tags = True
|
||||
|
||||
def candidate_actions(self, obj):
|
||||
return format_html(
|
||||
'<a class="button" href="{}">Confirmation de réception</a> '
|
||||
'<a class="button" href="{}">Validation enseignants EDE</a> '
|
||||
'<a class="button" href="{}">Convocation aux examens EDE</a> '
|
||||
'<a class="button" href="{}">Impression du résumé du dossier EDE</a>',
|
||||
reverse('candidate-confirmation', args=[obj.pk]),
|
||||
reverse('candidate-validation', args=[obj.pk]),
|
||||
reverse('candidate-convocation', args=[obj.pk]),
|
||||
reverse('candidate-summary', args=[obj.pk]),
|
||||
)
|
||||
candidate_actions.short_description = 'Actions pour candidats'
|
||||
candidate_actions.allow_tags = True
|
||||
|
||||
|
||||
class InterviewAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -139,6 +139,13 @@ class Candidate(models.Model):
|
|||
else:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def section_option(self):
|
||||
if not self.option:
|
||||
return self.get_section_display()
|
||||
else:
|
||||
return '{0}, option «{1}»'.format(self.get_section_display(), self.get_option_display())
|
||||
|
||||
def get_ok(self, fieldname):
|
||||
return 'OK' if getattr(self, fieldname) is True else 'NON'
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ class CandidateTests(TestCase):
|
|||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def test_send_confirmation_mail(self):
|
||||
self.maxDiff = None
|
||||
|
||||
ede = Section.objects.create(name='EDE')
|
||||
ase = Section.objects.create(name='ASE')
|
||||
Candidate.objects.bulk_create([
|
||||
|
|
@ -96,50 +98,67 @@ class CandidateTests(TestCase):
|
|||
Candidate(first_name='Hervé', last_name='Bern', gender='M', section=ede,
|
||||
deposite_date=date.today(), canceled_file=True),
|
||||
# Good
|
||||
Candidate(first_name='Henri', last_name='Dupond', gender='M', section=ede, option='ENF',
|
||||
email='henri@example.org', deposite_date=date.today()),
|
||||
Candidate(first_name='Joé', last_name='Glatz', gender='F', section=ase,
|
||||
email='joe@example.org', deposite_date=date.today()),
|
||||
Candidate(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': 'send_confirmation_mail',
|
||||
'_selected_action': Candidate.objects.values_list('pk', flat=True)
|
||||
}, follow=True)
|
||||
self.assertEqual(len(mail.outbox), 2)
|
||||
cand1 = Candidate.objects.get(last_name='Simth')
|
||||
response = self.client.get(reverse('candidate-confirmation', args=[cand1.pk]), follow=True)
|
||||
msg = "\n".join(str(m) for m in response.context['messages'])
|
||||
self.assertEqual(msg, "Une confirmation a déjà été envoyée!")
|
||||
|
||||
cand2 = Candidate.objects.get(last_name='Bern')
|
||||
response = self.client.get(reverse('candidate-confirmation', args=[cand2.pk]), follow=True)
|
||||
msg = "\n".join(str(m) for m in response.context['messages'])
|
||||
self.assertEqual(msg, "Ce dossier a été annulé!")
|
||||
|
||||
cand3 = Candidate.objects.get(last_name='Dupond')
|
||||
response = self.client.get(reverse('candidate-confirmation', args=[cand3.pk]))
|
||||
data = response.context['form'].initial
|
||||
response = self.client.post(
|
||||
reverse('candidate-confirmation', args=[cand3.pk]), data=data, follow=True
|
||||
)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
# Logged-in user also receives as Bcc
|
||||
self.assertEqual(mail.outbox[0].recipients(), ['henri@example.org', 'me@example.org'])
|
||||
self.assertEqual(mail.outbox[1].recipients(), ['joe@example.org', 'me@example.org'])
|
||||
# Mail content differ depending on the section
|
||||
self.assertEqual(mail.outbox[0].body, """Monsieur,
|
||||
self.assertEqual(mail.outbox[0].body, """Monsieur Henri Dupond,
|
||||
|
||||
Par ce courriel, nous vous confirmons la bonne réception de votre dossier de candidature à la formation ES d’Educateur-trice de l’enfance et vous remercions de l’intérêt que vous portez à notre institution.
|
||||
Par ce courriel, nous vous confirmons la bonne réception de vos documents de candidature à la formation Education de l'enfance, dipl. ES, option «Enfance» et vous remercions de l’intérêt que vous portez à notre institution.
|
||||
|
||||
Celui-ci sera traité et des nouvelles vous seront communiquées par courriel durant la 2ème quinzaine du mois de février.
|
||||
Votre dossier sera traité dans les jours à venir et des nouvelles vous seront communiquées par courriel durant la 2ème quinzaine du mois de février.
|
||||
|
||||
Dans l’intervalle, nous vous adressons, Monsieur, nos salutations les plus cordiales.
|
||||
|
||||
|
||||
Secrétariat de l'EPC
|
||||
tél. 032 886 33 00
|
||||
|
||||
Secrétariat de la filière Education de l’enfance, dipl. ES
|
||||
Hans Schmid
|
||||
me@example.org
|
||||
""".format()
|
||||
tél. 032 886 33 00"""
|
||||
)
|
||||
self.assertEqual(mail.outbox[1].body, """Madame, Monsieur,
|
||||
|
||||
Nous vous confirmons la bonne réception de l'inscription de Madame Joé Glatz dans la filière ASE pour l'année scolaire à venir.
|
||||
mail.outbox = []
|
||||
cand4 = Candidate.objects.get(last_name='Glatz')
|
||||
response = self.client.get(reverse('candidate-confirmation', args=[cand4.pk]))
|
||||
data = response.context['form'].initial
|
||||
response = self.client.post(
|
||||
reverse('candidate-confirmation', args=[cand4.pk]), data=data, follow=True
|
||||
)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
# Logged-in user also receives as Bcc
|
||||
self.assertEqual(mail.outbox[0].recipients(), ['joe@example.org', 'me@example.org'])
|
||||
self.assertEqual(mail.outbox[0].body, """Madame, Monsieur,
|
||||
|
||||
Nous vous confirmons la bonne réception de l’inscription de Madame Joé Glatz dans la filière Assist. socio-éducatif-ve CFC pour l’année scolaire à venir.
|
||||
|
||||
Nous nous tenons à votre disposition pour tout renseignement complémentaire et vous prions de recevoir, Madame, Monsieur, nos salutations les plus cordiales.
|
||||
|
||||
Secrétariat de l'EPC
|
||||
tél. 032 886 33 00
|
||||
|
||||
Secrétariat de l’EPC
|
||||
Hans Schmid
|
||||
me@example.org
|
||||
""".format()
|
||||
tél. 032 886 33 00"""
|
||||
)
|
||||
# One was already set, 2 new.
|
||||
self.assertEqual(Candidate.objects.filter(confirmation_date__isnull=False).count(), 3)
|
||||
|
|
@ -150,14 +169,14 @@ me@example.org
|
|||
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.get(reverse('candidate-confirmation', args=[henri.pk]))
|
||||
data = response.context['form'].initial
|
||||
with mock.patch('django.core.mail.EmailMessage.send') as mocked:
|
||||
mocked.side_effect = Exception("Error sending mail")
|
||||
response = self.client.post(change_url, {
|
||||
'action': 'send_confirmation_mail',
|
||||
'_selected_action': Candidate.objects.values_list('pk', flat=True)
|
||||
}, follow=True)
|
||||
response = self.client.post(
|
||||
reverse('candidate-confirmation', args=[henri.pk]), data=data, follow=True
|
||||
)
|
||||
self.assertContains(response, "Échec d’envoi pour le candidat Dupond Henri (Error sending mail)")
|
||||
henri.refresh_from_db()
|
||||
self.assertIsNone(henri.confirmation_date)
|
||||
|
|
@ -217,21 +236,69 @@ tél. 032 886 33 00
|
|||
henri.refresh_from_db()
|
||||
self.assertIsNotNone(henri.convocation_date)
|
||||
|
||||
def test_validation_enseignant_ede(self):
|
||||
self.maxDiff = None
|
||||
ede = Section.objects.create(name='EDE')
|
||||
henri = Candidate.objects.create(
|
||||
first_name='Henri', last_name='Dupond', gender='M', birth_date=date(2000, 5, 15),
|
||||
street="Rue Neuve 3", pcode='2222', city='Petaouchnok',
|
||||
section=ede, option='ENF',
|
||||
email='henri@example.org', deposite_date=date.today()
|
||||
)
|
||||
t1 = Teacher.objects.create(
|
||||
first_name="Julie", last_name="Caux", abrev="JCA", email="julie@example.org"
|
||||
)
|
||||
t2 = Teacher.objects.create(
|
||||
first_name='Jeanne', last_name='Dubois', abrev="JDU", email="jeanne@example.org"
|
||||
)
|
||||
inter = Interview.objects.create(
|
||||
date=datetime(2018, 3, 10, 10, 30), room='B103', candidat=henri,
|
||||
teacher_int=t1, teacher_file=t2,
|
||||
)
|
||||
self.client.login(username='me', password='mepassword')
|
||||
response = self.client.get(reverse('candidate-validation', args=[henri.pk]))
|
||||
expected_message = """Bonjour,
|
||||
|
||||
Par ce courriel, je vous informe qu'un entretien d'admission a été planifié selon les modalités suivantes:
|
||||
|
||||
- samedi 10 mars 2018 à 10h30, en salle B103
|
||||
Candidat :
|
||||
Monsieur Henri Dupond
|
||||
Rue Neuve 3
|
||||
2222 Petaouchnok
|
||||
Date de naiss.: 15 mai 2000
|
||||
|
||||
Sans nouvelle de votre part dans les 48 heures, une convocation définitive sera envoyée au candidat.
|
||||
|
||||
Avec mes meilleurs messages.
|
||||
|
||||
Secrétariat de la filière Education de l’enfance, dipl. ES
|
||||
Hans Schmid
|
||||
me@example.org
|
||||
tél. 032 886 33 00
|
||||
"""
|
||||
self.assertEqual(response.context['form'].initial['message'], expected_message)
|
||||
|
||||
data = response.context['form'].initial
|
||||
response = self.client.post(reverse('candidate-validation', args=[henri.pk]), data=data)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(mail.outbox[0].recipients(), ["julie@example.org", "jeanne@example.org", 'me@example.org'])
|
||||
self.assertEqual(mail.outbox[0].subject, "Validation de l'entretien d'admission")
|
||||
henri.refresh_from_db()
|
||||
self.assertIsNotNone(henri.validation_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')
|
||||
summary_url = reverse('candidate-summary', args=[cand.pk])
|
||||
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)
|
||||
response = self.client.post(summary_url, follow=True)
|
||||
self.assertEqual(
|
||||
response['Content-Disposition'],
|
||||
'attachment; filename="archive_InscriptionResumes.zip"'
|
||||
'attachment; filename="dupond_henri.pdf"'
|
||||
)
|
||||
self.assertEqual(response['Content-Type'], 'application/zip')
|
||||
self.assertEqual(response['Content-Type'], 'application/pdf')
|
||||
self.assertGreater(len(response.content), 200)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,145 @@
|
|||
import os
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core.mail import EmailMessage
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
from django.template import loader
|
||||
from django.urls import reverse_lazy
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.views.generic import FormView
|
||||
|
||||
from candidats.forms import EmailBaseForm
|
||||
from candidats.models import Candidate
|
||||
from candidats.models import Candidate, Interview
|
||||
from .pdf import InscriptionSummaryPDF
|
||||
|
||||
|
||||
class SendConvocationView(FormView):
|
||||
class EmailConfirmationBaseView(FormView):
|
||||
template_name = 'email_base.html'
|
||||
form_class = EmailBaseForm
|
||||
success_url = reverse_lazy('admin:candidats_candidate_changelist')
|
||||
success_message = "Le message a été envoyé pour le candidat {candidate}"
|
||||
candidate_date_field = None
|
||||
|
||||
def form_valid(self, form):
|
||||
email = EmailMessage(
|
||||
subject=form.cleaned_data['subject'],
|
||||
body=form.cleaned_data['message'],
|
||||
from_email=form.cleaned_data['sender'],
|
||||
to=form.cleaned_data['to'].split(';'),
|
||||
bcc=form.cleaned_data['cci'].split(';'),
|
||||
)
|
||||
candidate = Candidate.objects.get(pk=self.kwargs['pk'])
|
||||
try:
|
||||
email.send()
|
||||
except Exception as err:
|
||||
messages.error(self.request, "Échec d’envoi pour le candidat {0} ({1})".format(candidate, err))
|
||||
else:
|
||||
setattr(candidate, self.candidate_date_field, timezone.now())
|
||||
candidate.save()
|
||||
messages.success(self.request, self.success_message.format(candidate=candidate))
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context.update({
|
||||
'candidat': Candidate.objects.get(pk=self.kwargs['pk']),
|
||||
'title': self.title,
|
||||
})
|
||||
return context
|
||||
|
||||
|
||||
class ConfirmationView(EmailConfirmationBaseView):
|
||||
success_message = "Le message de confirmation a été envoyé pour le candidat {candidate}"
|
||||
candidate_date_field = 'confirmation_date'
|
||||
title = "Confirmation de réception de dossier"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
candidate = Candidate.objects.get(pk=self.kwargs['pk'])
|
||||
if candidate.confirmation_date:
|
||||
messages.error(request, 'Une confirmation a déjà été envoyée!')
|
||||
return redirect(reverse("admin:candidats_candidate_change", args=(candidate.pk,)))
|
||||
elif candidate.canceled_file:
|
||||
messages.error(request, 'Ce dossier a été annulé!')
|
||||
return redirect(reverse("admin:candidats_candidate_change", args=(candidate.pk,)))
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_initial(self):
|
||||
initial = super().get_initial()
|
||||
candidate = Candidate.objects.get(pk=self.kwargs['pk'])
|
||||
|
||||
to = [candidate.email]
|
||||
if candidate.section == 'EDE':
|
||||
src_email = 'email/candidate_confirm_EDE.txt'
|
||||
else:
|
||||
src_email = 'email/candidate_confirm_FE.txt'
|
||||
if candidate.corporation and candidate.corporation.email:
|
||||
to.append(candidate.corporation.email)
|
||||
if candidate.instructor and candidate.instructor.email:
|
||||
to.append(candidate.instructor.email)
|
||||
|
||||
msg_context = {
|
||||
'candidate': candidate,
|
||||
'sender': self.request.user,
|
||||
}
|
||||
initial.update({
|
||||
'id_candidate': candidate.pk,
|
||||
'cci': self.request.user.email,
|
||||
'to': '; '.join(to),
|
||||
'subject': "Inscription à la formation {0}".format(candidate.section_option),
|
||||
'message': loader.render_to_string(src_email, msg_context),
|
||||
'sender': self.request.user.email,
|
||||
})
|
||||
return initial
|
||||
|
||||
|
||||
class ValidationView(EmailConfirmationBaseView):
|
||||
success_message = "Le message de validation a été envoyé pour le candidat {candidate}"
|
||||
candidate_date_field = 'validation_date'
|
||||
title = "Validation des examens par les enseignant-e-s EDE"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
candidate = Candidate.objects.get(pk=self.kwargs['pk'])
|
||||
if candidate.validation_date:
|
||||
messages.error(request, 'Une validation a déjà été envoyée!')
|
||||
return redirect(reverse("admin:candidats_candidate_change", args=(candidate.pk,)))
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_initial(self):
|
||||
initial = super().get_initial()
|
||||
candidate = Candidate.objects.get(pk=self.kwargs['pk'])
|
||||
|
||||
msg_context = {
|
||||
'candidate': candidate,
|
||||
'sender': self.request.user,
|
||||
}
|
||||
initial.update({
|
||||
'id_candidate': candidate.pk,
|
||||
'cci': self.request.user.email,
|
||||
'to': ';'.join([
|
||||
candidate.interview.teacher_int.email, candidate.interview.teacher_file.email
|
||||
]),
|
||||
'subject': "Validation de l'entretien d'admission",
|
||||
'message': loader.render_to_string('email/validation_enseignant_EDE.txt', msg_context),
|
||||
'sender': self.request.user.email,
|
||||
})
|
||||
return initial
|
||||
|
||||
|
||||
class ConvocationView(EmailConfirmationBaseView):
|
||||
success_message = "Le message de convocation a été envoyé pour le candidat {candidate}"
|
||||
candidate_date_field = 'convocation_date'
|
||||
title = "Convocation aux examens d'admission EDE"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
candidate = Candidate.objects.get(pk=self.kwargs['pk'])
|
||||
try:
|
||||
candidate.interview
|
||||
except Interview.DoesNotExist:
|
||||
messages.error(request, "Impossible de convoquer sans d'abord définir un interview!")
|
||||
return redirect(reverse("admin:candidats_candidate_change", args=(candidate.pk,)))
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_initial(self):
|
||||
initial = super().get_initial()
|
||||
|
|
@ -59,31 +185,16 @@ class SendConvocationView(FormView):
|
|||
})
|
||||
return initial
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context.update({
|
||||
'candidat': Candidate.objects.get(pk=self.kwargs['pk']),
|
||||
'title': "Convocation aux examens d'admission EDE",
|
||||
})
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
email = EmailMessage(
|
||||
subject=form.cleaned_data['subject'],
|
||||
body=form.cleaned_data['message'],
|
||||
from_email=form.cleaned_data['sender'],
|
||||
to=form.cleaned_data['to'].split(';'),
|
||||
bcc=form.cleaned_data['cci'].split(';'),
|
||||
)
|
||||
candidate = Candidate.objects.get(pk=self.kwargs['pk'])
|
||||
try:
|
||||
email.send()
|
||||
except Exception as err:
|
||||
messages.error(self.request, "Échec d’envoi pour le candidat {0} ({1})".format(candidate, err))
|
||||
else:
|
||||
candidate.convocation_date = timezone.now()
|
||||
candidate.save()
|
||||
messages.success(self.request,
|
||||
"Le message de convocation a été envoyé pour le candidat {0}".format(candidate)
|
||||
)
|
||||
return super().form_valid(form)
|
||||
def inscription_summary(request, pk):
|
||||
"""
|
||||
Print a PDF summary of inscription
|
||||
"""
|
||||
candidat = Candidate.objects.get(pk=pk)
|
||||
pdf = InscriptionSummaryPDF(candidat)
|
||||
pdf.produce(candidat)
|
||||
|
||||
with open(pdf.filename, mode='rb') as fh:
|
||||
response = HttpResponse(fh.read(), content_type='application/pdf')
|
||||
response['Content-Disposition'] = 'attachment; filename="{0}"'.format(os.path.basename(pdf.filename))
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -22,8 +22,13 @@ urlpatterns = [
|
|||
path('classes/', views.KlassListView.as_view(), name='classes'),
|
||||
path('classes/<int:pk>/', views.KlassView.as_view(), name='class'),
|
||||
|
||||
path('candidate/<int:pk>/send_convocation/', candidats_views.SendConvocationView.as_view(),
|
||||
path('candidate/<int:pk>/send_convocation/', candidats_views.ConvocationView.as_view(),
|
||||
name='candidate-convocation'),
|
||||
path('candidate/<int:pk>/send_confirmation/', candidats_views.ConfirmationView.as_view(),
|
||||
name='candidate-confirmation'),
|
||||
path('candidate/<int:pk>/send_validation/', candidats_views.ValidationView.as_view(),
|
||||
name='candidate-validation'),
|
||||
path('candidate/<int:pk>/summary/', candidats_views.inscription_summary, name='candidate-summary'),
|
||||
|
||||
path('imputations/export/', views.imputations_export, name='imputations_export'),
|
||||
path('print/update_form/', views.print_update_form, name='print_update_form'),
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
{{ candidate_civility }},
|
||||
{{ candidate.civility }} {{ candidate.first_name }} {{ candidate.last_name }},
|
||||
|
||||
Par ce courriel, nous vous confirmons la bonne réception de votre dossier de candidature à la formation ES d’Educateur-trice de l’enfance et vous remercions de l’intérêt que vous portez à notre institution.
|
||||
Par ce courriel, nous vous confirmons la bonne réception de vos documents de candidature à la formation {{ candidate.section_option }} et vous remercions de l’intérêt que vous portez à notre institution.
|
||||
|
||||
Celui-ci sera traité et des nouvelles vous seront communiquées par courriel durant la 2ème quinzaine du mois de février.
|
||||
Votre dossier sera traité dans les jours à venir et des nouvelles vous seront communiquées par courriel durant la 2ème quinzaine du mois de février.
|
||||
|
||||
Dans l’intervalle, nous vous adressons, {{ candidate_civility }}, nos salutations les plus cordiales.
|
||||
Dans l’intervalle, nous vous adressons, {{ candidate.civility }}, nos salutations les plus cordiales.
|
||||
|
||||
|
||||
Secrétariat de l'EPC
|
||||
Secrétariat de la filière Education de l’enfance, dipl. ES
|
||||
{{ sender.first_name }} {{ sender.last_name }}
|
||||
{{ sender.email }}
|
||||
tél. 032 886 33 00
|
||||
|
||||
{{ sender_name }}
|
||||
{{ sender_email }}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
Madame, Monsieur,
|
||||
|
||||
Nous vous confirmons la bonne réception de l'inscription de {{ candidate_name }} dans la filière {{ section }} pour l'année scolaire à venir.
|
||||
Nous vous confirmons la bonne réception de l’inscription de {{ candidate.civility }} {{ candidate.first_name }} {{candidate.last_name}} dans la filière {{ candidate.section_option }} pour l’année scolaire à venir.
|
||||
|
||||
Nous nous tenons à votre disposition pour tout renseignement complémentaire et vous prions de recevoir, Madame, Monsieur, nos salutations les plus cordiales.
|
||||
|
||||
Secrétariat de l'EPC
|
||||
Secrétariat de l’EPC
|
||||
{{ sender.first_name }} {{ sender.last_name }}
|
||||
{{ sender.email }}
|
||||
tél. 032 886 33 00
|
||||
|
||||
{{ sender_name }}
|
||||
{{ sender_email }}
|
||||
|
|
|
|||
19
templates/email/validation_enseignant_EDE.txt
Normal file
19
templates/email/validation_enseignant_EDE.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Bonjour,
|
||||
|
||||
Par ce courriel, je vous informe qu'un entretien d'admission a été planifié selon les modalités suivantes:
|
||||
|
||||
- {{ candidate.interview.date_formatted }}, en salle {{ candidate.interview.room }}
|
||||
Candidat{% if candidate.gender == "F" %}e{% endif %} :
|
||||
{{ candidate.civility }} {{ candidate.first_name }} {{ candidate.last_name }}
|
||||
{{ candidate.street }}
|
||||
{{ candidate.pcode }} {{ candidate.city }}
|
||||
Date de naiss.: {{ candidate.birth_date }}
|
||||
|
||||
Sans nouvelle de votre part dans les 48 heures, une convocation définitive sera envoyée {% if candidate.gender == "F" %}à la candidate{% else %} au candidat{% endif %}.
|
||||
|
||||
Avec mes meilleurs messages.
|
||||
|
||||
Secrétariat de la filière Education de l’enfance, dipl. ES
|
||||
{{ sender.first_name }} {{ sender.last_name }}
|
||||
{{ sender.email }}
|
||||
tél. 032 886 33 00
|
||||
Loading…
Add table
Add a link
Reference in a new issue