Add EDE convocation form
This commit is contained in:
parent
1f49b198ec
commit
ffb54c9f78
9 changed files with 207 additions and 2 deletions
|
|
@ -6,6 +6,7 @@ from django.contrib import admin
|
|||
from django.core.mail import EmailMessage
|
||||
from django.db.models import BooleanField
|
||||
from django.template import loader
|
||||
from django.urls import reverse
|
||||
|
||||
from stages.exports import OpenXMLExport
|
||||
from .models import Candidate, Interview, GENDER_CHOICES
|
||||
|
|
@ -119,7 +120,7 @@ class CandidateAdminForm(forms.ModelForm):
|
|||
|
||||
class CandidateAdmin(admin.ModelAdmin):
|
||||
form = CandidateAdminForm
|
||||
list_display = ('last_name', 'first_name', 'section', 'confirm_mail')
|
||||
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]
|
||||
|
|
@ -157,6 +158,17 @@ class CandidateAdmin(admin.ModelAdmin):
|
|||
return obj.date_confirmation_mail is not None
|
||||
confirm_mail.boolean = True
|
||||
|
||||
def convocation(self, obj):
|
||||
if obj.interview is None:
|
||||
return '???'
|
||||
elif obj.interview and obj.convocation_date:
|
||||
return obj.interview
|
||||
else:
|
||||
url = reverse('candidate-convocation', args=[obj.pk])
|
||||
return '<a href="' + url + '">Envoyer convocation</a>'
|
||||
convocation.short_description = 'Convoc. aux examens'
|
||||
convocation.allow_tags = True
|
||||
|
||||
|
||||
class InterviewAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -166,7 +166,11 @@ class Interview(models.Model):
|
|||
|
||||
def __str__(self):
|
||||
return '{0} : {1}/{2} - ({3}) -salle:{4}-{5}'.format(
|
||||
django_format(self.date, "l j F Y à H\hi"),
|
||||
self.date_formatted,
|
||||
self.teacher_int or '?', self.teacher_file or '?',
|
||||
self.status, self.room, self.candidat or '???'
|
||||
)
|
||||
|
||||
@property
|
||||
def date_formatted(self):
|
||||
return django_format(self.date, "l j F Y à H\hi")
|
||||
|
|
|
|||
|
|
@ -113,3 +113,53 @@ me@example.org
|
|||
self.assertContains(response, "Échec d’envoi pour le candidat Dupond Henri (Error sending mail)")
|
||||
henri.refresh_from_db()
|
||||
self.assertIsNone(henri.date_confirmation_mail)
|
||||
|
||||
def test_convocation_ede(self):
|
||||
ede = Section.objects.create(name='EDE')
|
||||
henri = Candidate.objects.create(
|
||||
first_name='Henri', last_name='Dupond', gender='M', section=ede,
|
||||
email='henri@example.org', deposite_date=date.today()
|
||||
)
|
||||
inter = Interview.objects.create(date=datetime(2018, 3, 10, 10, 30), room='B103', candidat=henri)
|
||||
self.client.login(username='me', password='mepassword')
|
||||
response = self.client.get(reverse('candidate-convocation', args=[henri.pk]))
|
||||
self.assertContains(response, '<h2>Dupond Henri</h2>')
|
||||
self.assertContains(response, '<input type="text" name="to" value="henri@example.org" size="60" id="id_to" required>', html=True)
|
||||
self.assertContains(response, """
|
||||
Monsieur Henri Dupond,
|
||||
|
||||
Nous vous adressons par la présente votre convocation personnelle à la procédure d’admission de la filière Education de l’enfance, dipl. ES.
|
||||
|
||||
Vous êtes attendu-e à l’Ecole Santé-social Pierre-Coullery, rue de la Prévoyance 82, 2300 La Chaux-de-Fonds aux dates suivantes:
|
||||
|
||||
- mercredi 7 mars 2018, à 13h30, salle 405, pour l’examen écrit (durée approx. 4 heures)
|
||||
|
||||
- samedi 10 mars 2018 à 10h30, en salle B103, pour l’entretien d’admission (durée approx. 45 min.).
|
||||
|
||||
En cas d’empêchement de dernière minute, nous vous remercions d’annoncer votre absence au secrétariat (Tél. 032 886 33 00).
|
||||
|
||||
De plus, afin que nous puissions enregistrer définitivement votre inscription, nous vous remercions par avance
|
||||
de nous faire parvenir, dans les meilleurs délais, le ou les documents suivants:
|
||||
- Formulaire d'inscription, Attest. de paiement, Casier judic., CV, Texte réflexif, Photo passeport, Bilan act. prof./dernier stage, Bull. de notes
|
||||
|
||||
Dans l’intervalle, nous vous adressons, Monsieur, nos salutations les plus cordiales.
|
||||
|
||||
Secrétariat de la filière Education de l’enfance, dipl. ES
|
||||
Hans Schmid
|
||||
me@example.org
|
||||
tél. 032 886 33 00"""
|
||||
)
|
||||
response = self.client.post(reverse('candidate-convocation', args=[henri.pk]), data={
|
||||
'id_candidate': str(henri.pk),
|
||||
'cci': 'me@example.org',
|
||||
'to': henri.email,
|
||||
'subject': "Procédure de qualification",
|
||||
'message': "Monsieur Henri Dupond, ...",
|
||||
'sender': 'me@example.org',
|
||||
})
|
||||
self.assertRedirects(response, reverse('admin:candidats_candidate_changelist'))
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(mail.outbox[0].recipients(), ['henri@example.org', 'me@example.org'])
|
||||
self.assertEqual(mail.outbox[0].subject, "Procédure de qualification")
|
||||
henri.refresh_from_db()
|
||||
self.assertIsNotNone(henri.convocation_date)
|
||||
|
|
|
|||
90
candidats/views.py
Normal file
90
candidats/views.py
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core.mail import EmailMessage
|
||||
from django.template import loader
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.views.generic import FormView
|
||||
|
||||
from candidats.models import Candidate
|
||||
|
||||
|
||||
class ConvocationForm(forms.Form):
|
||||
id_candidate = forms.CharField(widget=forms.HiddenInput())
|
||||
sender = forms.CharField(widget=forms.HiddenInput())
|
||||
to = forms.CharField(widget=forms.TextInput(attrs={'size': '60'}))
|
||||
cci = forms.CharField(widget=forms.TextInput(attrs={'size': '60'}))
|
||||
subject = forms.CharField(widget=forms.TextInput(attrs={'size': '60'}))
|
||||
message = forms.CharField(widget=forms.Textarea(attrs={'rows': 25, 'cols': 120}))
|
||||
|
||||
|
||||
class SendConvocationView(FormView):
|
||||
template_name = 'candidats/convocation.html'
|
||||
form_class = ConvocationForm
|
||||
success_url = reverse_lazy('admin:candidats_candidate_changelist')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
candidate = Candidate.objects.get(pk=self.kwargs['pk'])
|
||||
docs = [
|
||||
'registration_form', 'certificate_of_payement', 'police_record', 'cv', 'reflexive_text',
|
||||
'has_photo', 'work_certificate', 'marks_certificate',
|
||||
]
|
||||
if candidate.option == 'PE-5400h':
|
||||
docs.append('promise', 'contract', 'certif_of_800h')
|
||||
elif candidate.option == 'PE-3600h':
|
||||
docs.append('certif_of_cfc', 'promise', 'contract')
|
||||
elif candidate.option == 'PS':
|
||||
docs.append('certif_of_800h')
|
||||
|
||||
missing_documents = {'documents': ', '.join([
|
||||
Candidate._meta.get_field(doc).verbose_name for doc in docs if not getattr(candidate, doc)
|
||||
])}
|
||||
|
||||
msg_context = {
|
||||
'candidate_name': " ".join([candidate.civility, candidate.first_name, candidate.last_name]),
|
||||
'candidate_civility': candidate.civility,
|
||||
'date_lieu_examen': settings.DATE_LIEU_EXAMEN_EDE,
|
||||
'date_entretien': candidate.interview.date_formatted,
|
||||
'salle_entretien': candidate.interview.room,
|
||||
'rappel': loader.render_to_string('email/rappel_document_EDE.txt', missing_documents),
|
||||
'sender_name': " ".join([self.request.user.first_name, self.request.user.last_name]),
|
||||
'sender_email': self.request.user.email,
|
||||
}
|
||||
|
||||
form = ConvocationForm(initial={
|
||||
'id_candidate': candidate.pk,
|
||||
'cci': self.request.user.email,
|
||||
'to': candidate.email,
|
||||
'subject': "Procédure de qualification",
|
||||
'message': loader.render_to_string('email/candidate_convocation_EDE.txt', msg_context),
|
||||
'sender': self.request.user.email,
|
||||
})
|
||||
context.update({
|
||||
'candidat': candidate,
|
||||
'form': form,
|
||||
})
|
||||
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)
|
||||
|
|
@ -146,6 +146,8 @@ CHARGE_SHEET_TITLE = "Feuille de charge pour l'année scolaire 2017-2018"
|
|||
MAX_ENS_PERIODS = 1900
|
||||
MAX_ENS_FORMATION = 250
|
||||
|
||||
DATE_LIEU_EXAMEN_EDE = "mercredi 7 mars 2018, à 13h30, salle 405"
|
||||
|
||||
if 'TRAVIS' in os.environ:
|
||||
SECRET_KEY = 'secretkeyfortravistests'
|
||||
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from django.conf.urls import include, url
|
|||
from django.contrib import admin
|
||||
from django.views.generic import RedirectView
|
||||
|
||||
from candidats import views as candidats_views
|
||||
from stages import views
|
||||
|
||||
urlpatterns = [
|
||||
|
|
@ -21,6 +22,9 @@ urlpatterns = [
|
|||
url(r'^classes/$', views.KlassListView.as_view(), name='classes'),
|
||||
url(r'^classes/(?P<pk>\d+)/$', views.KlassView.as_view(), name='class'),
|
||||
|
||||
url(r'^candidate/(?P<pk>\d+)/send_convocation/$', candidats_views.SendConvocationView.as_view(),
|
||||
name='candidate-convocation'),
|
||||
|
||||
url(r'^imputations/export/$', views.imputations_export, name='imputations_export'),
|
||||
url(r'^print/update_form/$', views.print_update_form, name='print_update_form'),
|
||||
url(r'^general_export/$', views.general_export, name='general-export'),
|
||||
|
|
|
|||
20
templates/candidats/convocation.html
Normal file
20
templates/candidats/convocation.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
|
||||
› Envoi de la convocation EDE
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{{ candidat }}</h2>
|
||||
<form name="convocation" action="." method="post">{% csrf_token %}
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
<tr><td><input type="submit" value="Envoyer"></td></tr>
|
||||
|
||||
</table>
|
||||
</form>
|
||||
{% endblock %}
|
||||
19
templates/email/candidate_convocation_EDE.txt
Normal file
19
templates/email/candidate_convocation_EDE.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{{ candidate_name }},
|
||||
|
||||
Nous vous adressons par la présente votre convocation personnelle à la procédure d’admission de la filière Education de l’enfance, dipl. ES.
|
||||
|
||||
Vous êtes attendu-e à l’Ecole Santé-social Pierre-Coullery, rue de la Prévoyance 82, 2300 La Chaux-de-Fonds aux dates suivantes:
|
||||
|
||||
- {{ date_lieu_examen }}, pour l’examen écrit (durée approx. 4 heures)
|
||||
|
||||
- {{ date_entretien }}, en salle {{ salle_entretien }}, pour l’entretien d’admission (durée approx. 45 min.).
|
||||
|
||||
En cas d’empêchement de dernière minute, nous vous remercions d’annoncer votre absence au secrétariat (Tél. 032 886 33 00).
|
||||
{{ rappel }}
|
||||
|
||||
Dans l’intervalle, nous vous adressons, {{ candidate_civility }}, nos salutations les plus cordiales.
|
||||
|
||||
Secrétariat de la filière Education de l’enfance, dipl. ES
|
||||
{{ sender_name }}
|
||||
{{ sender_email }}
|
||||
tél. 032 886 33 00
|
||||
4
templates/email/rappel_document_EDE.txt
Normal file
4
templates/email/rappel_document_EDE.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
De plus, afin que nous puissions enregistrer définitivement votre inscription, nous vous remercions par avance
|
||||
de nous faire parvenir, dans les meilleurs délais, le ou les documents suivants:
|
||||
- {{ documents }}
|
||||
Loading…
Add table
Add a link
Reference in a new issue