diff --git a/stages/admin.py b/stages/admin.py
index 35bea22..f728754 100644
--- a/stages/admin.py
+++ b/stages/admin.py
@@ -131,8 +131,8 @@ class ExaminationInline(admin.StackedInline):
'Courrier pour l’expert '
'Mail convocation soutenance '
'Indemnité au mentor',
- reverse('print-expert-compens-ede', args=[obj.student.pk]),
- reverse('student-ede-convocation', args=[obj.student.pk]),
+ reverse('print-expert-compens-ede', args=[obj.pk]),
+ reverse('student-ede-convocation', args=[obj.pk]),
reverse('print-mentor-compens-ede', args=[obj.student.pk]),
)
elif obj and obj.student.is_eds_3():
@@ -143,8 +143,8 @@ class ExaminationInline(admin.StackedInline):
'Courrier pour l’expert '
'Mail convocation soutenance '
'Indemnité au mentor',
- reverse('print-expert-compens-eds', args=[obj.student.pk]),
- reverse('student-eds-convocation', args=[obj.student.pk]),
+ reverse('print-expert-compens-eds', args=[obj.pk]),
+ reverse('student-eds-convocation', args=[obj.pk]),
reverse('print-mentor-compens-ede', args=[obj.student.pk]),
)
else:
@@ -157,7 +157,7 @@ class StudentAdmin(admin.ModelAdmin):
ordering = ('last_name', 'first_name')
list_filter = (('archived', ArchivedListFilter), ('klass', KlassRelatedListFilter))
search_fields = ('last_name', 'first_name', 'pcode', 'city', 'klass__name')
- autocomplete_fields = ('corporation', 'instructor', 'supervisor', 'mentor', 'expert', 'expert_ep')
+ autocomplete_fields = ('corporation', 'instructor', 'supervisor', 'mentor')
readonly_fields = ('report_sem1_sent', 'report_sem2_sent')
fieldsets = [
(None, {
diff --git a/stages/migrations/0029_delete_exam_fields_on_student.py b/stages/migrations/0029_delete_exam_fields_on_student.py
new file mode 100644
index 0000000..558c29d
--- /dev/null
+++ b/stages/migrations/0029_delete_exam_fields_on_student.py
@@ -0,0 +1,84 @@
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('stages', '0028_remove_last_appointment'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='examedesession',
+ options={'ordering': ['-year', 'season'], 'verbose_name': 'Session d’examen'},
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='date_confirm_ep_received',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='date_confirm_received',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='date_exam',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='date_exam_ep',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='date_soutenance_ep_mailed',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='date_soutenance_mailed',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='expert_ep',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='internal_expert',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='internal_expert_ep',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='mark',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='mark_acq',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='mark_ep',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='mark_ep_acq',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='room',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='room_ep',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='session',
+ ),
+ migrations.RemoveField(
+ model_name='student',
+ name='session_ep',
+ ),
+ ]
diff --git a/stages/models.py b/stages/models.py
index 80a818d..8160580 100644
--- a/stages/models.py
+++ b/stages/models.py
@@ -252,7 +252,8 @@ class ExamEDESession(models.Model):
season = models.CharField('saison', max_length=10)
class Meta:
- verbose_name = "Session d’examen EDE"
+ verbose_name = "Session d’examen"
+ ordering = ['-year', 'season']
def __str__(self):
return '{0} {1}'.format(self.year, self.season)
@@ -315,36 +316,6 @@ class Student(models.Model):
on_delete=models.SET_NULL, verbose_name='Référent de PP')
referent = models.ForeignKey(Teacher, null=True, blank=True, related_name='rel_referent',
on_delete=models.SET_NULL, verbose_name='Référent avant-projet')
- internal_expert = models.ForeignKey(Teacher, related_name='rel_internal_expert', verbose_name='Expert interne',
- null=True, blank=True, on_delete=models.SET_NULL)
- session = models.ForeignKey(
- ExamEDESession, null=True, blank=True, on_delete=models.SET_NULL, related_name='students_es',
- )
- date_exam = models.DateTimeField(blank=True, null=True)
- room = models.CharField('Salle', max_length=15, blank=True)
- mark = models.DecimalField('Note', max_digits=3, decimal_places=2, blank=True, null=True)
- mark_acq = models.CharField('Note', max_length=5, choices=ACQ_MARK_CHOICES, blank=True)
- date_soutenance_mailed = models.DateTimeField("Convoc. env.", blank=True, null=True)
- date_confirm_received = models.DateTimeField("Récept. confirm", blank=True, null=True)
- # ============== Fields for Entretien professionnel =========
- session_ep = models.ForeignKey(
- ExamEDESession, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='Session EP',
- related_name='students_ep',
- )
- date_exam_ep = models.DateTimeField("Date exam. EP", blank=True, null=True)
- room_ep = models.CharField('Salle EP', max_length=15, blank=True)
- mark_ep = models.DecimalField('Note EP', max_digits=3, decimal_places=2, blank=True, null=True)
- mark_ep_acq = models.CharField('Note EP', max_length=5, choices=ACQ_MARK_CHOICES, blank=True)
- internal_expert_ep = models.ForeignKey(
- Teacher, related_name='rel_internal_expert_ep', verbose_name='Expert interne EP',
- null=True, blank=True, on_delete=models.SET_NULL
- )
- expert_ep = models.ForeignKey(
- 'CorpContact', related_name='rel_expert_ep', verbose_name='Expert externe EP',
- null=True, blank=True, on_delete=models.SET_NULL
- )
- date_soutenance_ep_mailed = models.DateTimeField("Convoc. env.", blank=True, null=True)
- date_confirm_ep_received = models.DateTimeField("Récept. confirm", blank=True, null=True)
# ===============
mc_comment = models.TextField("Commentaires", blank=True)
@@ -411,30 +382,6 @@ class Student(models.Model):
def is_eds_3(self):
return self.klass and self.klass.section.name == 'EDS' and self.klass.level.name == '3'
- def missing_examination_data(self):
- missing = []
- if not self.date_exam:
- missing.append("La date d’examen est manquante")
- if not self.room:
- missing.append("La salle d’examen n’est pas définie")
- if not self.expert:
- missing.append("L’expert externe n’est pas défini")
- if not self.internal_expert:
- missing.append("L’expert interne n’est pas défini")
- return missing
-
- def missing_examination_ep_data(self):
- missing = []
- if not self.date_exam_ep:
- missing.append("La date d’examen est manquante")
- if not self.room_ep:
- missing.append("La salle d’examen n’est pas définie")
- if not self.expert_ep:
- missing.append("L’expert externe n’est pas défini")
- if not self.internal_expert_ep:
- missing.append("L’expert interne n’est pas défini")
- return missing
-
class Examination(models.Model):
ACQ_MARK_CHOICES = (
diff --git a/stages/pdf.py b/stages/pdf.py
index 2295c8f..6cb9242 100644
--- a/stages/pdf.py
+++ b/stages/pdf.py
@@ -335,7 +335,7 @@ class CompensationForm:
self.story.append(t)
self.story.append(Spacer(0, 0.5 * cm))
- def add_accounting_stamp(self, mandat=None):
+ def add_accounting_stamp(self, student, mandat=None):
account = otp = total = ''
if mandat == self.EXPERT_MANDAT:
account = self.EXPERT_ACCOUNT
@@ -343,9 +343,9 @@ class CompensationForm:
account = self.MENTOR_ACCOUNT
total = '500.-'
- if self.student.klass.is_Ede_pe():
+ if student.klass.is_Ede_pe():
otp = self.OTP_EDE_PE_OTP
- elif self.student.klass.is_Ede_ps():
+ elif student.klass.is_Ede_ps():
otp = self.OTP_EDE_PS_OTP
self.story.append((Paragraph(self.points * 2, style_normal)))
@@ -433,8 +433,8 @@ class ExpertEdeLetterPdf(CompensationForm, EpcBaseDocTemplate):
"""
- def __init__(self, out, student):
- self.student = student
+ def __init__(self, out, exam):
+ self.exam = exam
super().__init__(out)
self.addPageTemplates([
PageTemplate(id='FirstPage', frames=[self.page_frame], onPage=self.header),
@@ -443,10 +443,10 @@ class ExpertEdeLetterPdf(CompensationForm, EpcBaseDocTemplate):
def exam_data(self):
return {
- 'expert': self.student.expert,
- 'internal_expert': self.student.internal_expert,
- 'date_exam': self.student.date_exam,
- 'room': self.student.room,
+ 'expert': self.exam.external_expert,
+ 'internal_expert': self.exam.internal_expert,
+ 'date_exam': self.exam.date_exam,
+ 'room': self.exam.room,
}
def produce(self):
@@ -471,7 +471,7 @@ class ExpertEdeLetterPdf(CompensationForm, EpcBaseDocTemplate):
title_lower=self.title.lower(),
expert_civility=exam_data['expert'].civility,
expert_accord=exam_data['expert'].adjective_ending,
- student_civility_full_name=self.student.civility_full_name,
+ student_civility_full_name=self.exam.student.civility_full_name,
), style_normal))
date_text = "
{0} à l'Ecole Santé-social Pierre-Coullery, salle {1}
"
@@ -507,7 +507,7 @@ class ExpertEdeLetterPdf(CompensationForm, EpcBaseDocTemplate):
self.story.append(Paragraph(
"Mandat: Soutenance de {0} {1}, classe {2}".format(
- self.student.civility, self.student.full_name, self.student.klass
+ self.exam.student.civility, self.exam.student.full_name, self.exam.student.klass
), style_normal
))
self.story.append(Paragraph(
@@ -515,7 +515,7 @@ class ExpertEdeLetterPdf(CompensationForm, EpcBaseDocTemplate):
))
self.story.append(Spacer(0, 2 * cm))
- self.add_accounting_stamp(self.EXPERT_MANDAT)
+ self.add_accounting_stamp(self.exam.student, self.EXPERT_MANDAT)
self.build(self.story)
@@ -556,7 +556,7 @@ class MentorCompensationPdfForm(CompensationForm, EpcBaseDocTemplate):
))
self.story.append(Spacer(0, 3 * cm))
- self.add_accounting_stamp(self.MENTOR_MANDAT)
+ self.add_accounting_stamp(self.student, self.MENTOR_MANDAT)
self.build(self.story)
diff --git a/stages/tests.py b/stages/tests.py
index 1e71087..333a8d9 100644
--- a/stages/tests.py
+++ b/stages/tests.py
@@ -12,7 +12,7 @@ from django.utils.html import escape
from candidats.models import Candidate
from .models import (
Level, Domain, Section, Klass, Option, Period, Student, Corporation, Availability,
- CorpContact, Teacher, Training, Course,
+ CorpContact, Teacher, Training, Course, Examination, ExamEDESession,
)
from .utils import school_year
@@ -211,23 +211,24 @@ class StagesTests(TestCase):
def test_send_ede_convocation(self):
st = Student.objects.get(first_name="Albin")
+ exam = Examination.objects.create(student=st, session=ExamEDESession.objects.create(year=2020, season='1'))
self.client.login(username='me', password='mepassword')
- url = reverse('student-ede-convocation', args=[st.pk])
+ url = reverse('student-ede-convocation', args=[exam.pk])
response = self.client.get(url, follow=True)
for err in ("La date d’examen est manquante",
"La salle d’examen n’est pas définie",
"L’expert externe n’est pas défini",
"L’expert interne n’est pas défini"):
self.assertContains(response, err)
- st.date_exam = datetime(2018, 6, 28, 12, 00)
- st.room = "B123"
- st.expert = CorpContact.objects.get(last_name="Horner")
- st.internal_expert = Teacher.objects.get(last_name="Caux")
- st.save()
+ exam.date_exam = datetime(2018, 6, 28, 12, 00)
+ exam.room = "B123"
+ exam.external_expert = CorpContact.objects.get(last_name="Horner")
+ exam.internal_expert = Teacher.objects.get(last_name="Caux")
+ exam.save()
response = self.client.get(url, follow=True)
self.assertContains(response, "L’expert externe n’a pas de courriel valide !")
- st.expert.email = "horner@example.org"
- st.expert.save()
+ exam.external_expert.email = "horner@example.org"
+ exam.external_expert.save()
response = self.client.get(url)
expected_message = """ Albin Dupond,
Madame Julie Caux,
@@ -261,8 +262,8 @@ tél. 032 886 33 00
'sender': 'me@example.org',
})
self.assertEqual(len(mail.outbox), 1)
- st.refresh_from_db()
- self.assertIsNotNone(st.date_soutenance_mailed)
+ exam.refresh_from_db()
+ self.assertIsNotNone(exam.date_soutenance_mailed)
def test_send_eds_convocation(self):
klass = Klass.objects.create(
@@ -272,9 +273,10 @@ tél. 032 886 33 00
first_name="Laurent", last_name="Hots", birth_date="1994-07-12",
pcode="2000", city="Neuchâtel", klass=klass
)
+ exam = Examination.objects.create(student=st, session=ExamEDESession.objects.create(year=2020, season='1'))
self.client.login(username='me', password='mepassword')
- url = reverse('student-eds-convocation', args=[st.pk])
+ url = reverse('student-eds-convocation', args=[exam.pk])
response = self.client.get(url, follow=True)
for err in ("L’étudiant-e n’a pas de courriel valide",
"La date d’examen est manquante",
@@ -283,15 +285,16 @@ tél. 032 886 33 00
"L’expert interne n’est pas défini"):
self.assertContains(response, err)
st.email = 'hots@example.org'
- st.date_exam = datetime(2018, 6, 28, 12, 00)
- st.room = "B123"
- st.expert = CorpContact.objects.get(last_name="Horner")
- st.internal_expert = Teacher.objects.get(last_name="Caux")
st.save()
+ exam.date_exam = datetime(2018, 6, 28, 12, 00)
+ exam.room = "B123"
+ exam.external_expert = CorpContact.objects.get(last_name="Horner")
+ exam.internal_expert = Teacher.objects.get(last_name="Caux")
+ exam.save()
response = self.client.get(url, follow=True)
self.assertContains(response, "L’expert externe n’a pas de courriel valide !")
- st.expert.email = "horner@example.org"
- st.expert.save()
+ exam.external_expert.email = "horner@example.org"
+ exam.external_expert.save()
response = self.client.get(url)
expected_message = """ Laurent Hots,
Madame Julie Caux,
@@ -325,21 +328,22 @@ tél. 032 886 33 00
'sender': 'me@example.org',
})
self.assertEqual(len(mail.outbox), 1)
- st.refresh_from_db()
- self.assertIsNotNone(st.date_soutenance_mailed)
+ exam.refresh_from_db()
+ self.assertIsNotNone(exam.date_soutenance_mailed)
def test_print_ede_compensation_forms(self):
st = Student.objects.get(first_name="Albin")
- url = reverse('print-expert-compens-ede', args=[st.pk])
+ exam = Examination.objects.create(student=st, session=ExamEDESession.objects.create(year=2020, season='1'))
+ url = reverse('print-expert-compens-ede', args=[exam.pk])
self.client.login(username='me', password='mepassword')
response = self.client.get(url, follow=True)
self.assertContains(response, "Toutes les informations ne sont pas disponibles")
- st.expert = CorpContact.objects.get(last_name="Horner")
- st.internal_expert = Teacher.objects.get(last_name="Caux")
- st.date_exam = datetime(2018, 6, 28, 12, 00)
- st.room = "B123"
- st.save()
+ exam.external_expert = CorpContact.objects.get(last_name="Horner")
+ exam.internal_expert = Teacher.objects.get(last_name="Caux")
+ exam.date_exam = datetime(2018, 6, 28, 12, 00)
+ exam.room = "B123"
+ exam.save()
self.client.login(username='me', password='mepassword')
response = self.client.get(url, follow=True)
self.assertEqual(
@@ -349,8 +353,8 @@ tél. 032 886 33 00
self.assertEqual(response['Content-Type'], 'application/pdf')
self.assertGreater(int(response['Content-Length']), 1000)
# Expert without corporation
- st.expert = CorpContact.objects.create(first_name='James', last_name='Bond')
- st.save()
+ exam.external_expert = CorpContact.objects.create(first_name='James', last_name='Bond')
+ exam.save()
response = self.client.get(url, follow=True)
self.assertEqual(response.status_code, 200)
@@ -373,16 +377,17 @@ tél. 032 886 33 00
first_name="Laurent", last_name="Hots", birth_date="1994-07-12",
pcode="2000", city="Neuchâtel", klass=klass
)
- url = reverse('print-expert-compens-eds', args=[st.pk])
+ exam = Examination.objects.create(student=st, session=ExamEDESession.objects.create(year=2020, season='1'))
+ url = reverse('print-expert-compens-eds', args=[exam.pk])
self.client.login(username='me', password='mepassword')
response = self.client.get(url, follow=True)
self.assertContains(response, "Toutes les informations ne sont pas disponibles")
- st.expert = CorpContact.objects.get(last_name="Horner")
- st.internal_expert = Teacher.objects.get(last_name="Caux")
- st.date_exam = datetime(2018, 6, 28, 12, 00)
- st.room = "B123"
- st.save()
+ exam.external_expert = CorpContact.objects.get(last_name="Horner")
+ exam.internal_expert = Teacher.objects.get(last_name="Caux")
+ exam.date_exam = datetime(2018, 6, 28, 12, 00)
+ exam.room = "B123"
+ exam.save()
response = self.client.get(url, follow=True)
self.assertEqual(
@@ -392,8 +397,8 @@ tél. 032 886 33 00
self.assertEqual(response['Content-Type'], 'application/pdf')
self.assertGreater(int(response['Content-Length']), 1000)
# Expert without corporation
- st.expert = CorpContact.objects.create(first_name='James', last_name='Bond')
- st.save()
+ exam.external_expert = CorpContact.objects.create(first_name='James', last_name='Bond')
+ exam.save()
response = self.client.get(url, follow=True)
self.assertEqual(response.status_code, 200)
diff --git a/stages/views/__init__.py b/stages/views/__init__.py
index 64280f5..307c964 100644
--- a/stages/views/__init__.py
+++ b/stages/views/__init__.py
@@ -24,7 +24,7 @@ from .imports import HPContactsImportView, HPImportView, ImportReportsView, Stud
from ..forms import CorporationMergeForm, EmailBaseForm, StudentCommentForm
from ..models import (
Klass, Section, Student, Teacher, Corporation, CorpContact, Period,
- Training, Availability
+ Training, Availability, Examination,
)
from ..pdf import (
ChargeSheetPDF, ExpertEdeLetterPdf, ExpertEdsLetterPdf, UpdateDataFormPDF,
@@ -401,53 +401,41 @@ class StudentConvocationExaminationView(EmailConfirmationView):
title = "Convocation à la soutenance du travail de diplôme"
email_template = 'email/student_convocation_EDE.txt'
- @property
- def expert(self):
- return self.student.expert
-
- @property
- def internal_expert(self):
- return self.student.internal_expert
-
- @property
- def date_soutenance_mailed(self):
- return self.student.date_soutenance_mailed
-
- def missing_examination_data(self):
- return self.student.missing_examination_data()
-
def dispatch(self, request, *args, **kwargs):
- self.student = Student.objects.get(pk=self.kwargs['pk'])
- errors = self.missing_examination_data()
+ self.exam = Examination.objects.get(pk=self.kwargs['pk'])
+ errors = self.exam.missing_examination_data()
errors.extend(self.check_errors())
if errors:
messages.error(request, "\n".join(errors))
- return redirect(reverse("admin:stages_student_change", args=(self.student.pk,)))
+ return redirect(reverse("admin:stages_student_change", args=(self.exam.student.pk,)))
return super().dispatch(request, *args, **kwargs)
+ def get_person(self):
+ return self.exam.student
+
def check_errors(self):
errors = []
- if not self.student.email:
+ if not self.exam.student.email:
errors.append("L’étudiant-e n’a pas de courriel valide !")
- if self.expert and not self.expert.email:
+ if self.exam.external_expert and not self.exam.external_expert.email:
errors.append("L’expert externe n’a pas de courriel valide !")
- if self.internal_expert and not self.internal_expert.email:
+ if self.exam.internal_expert and not self.exam.internal_expert.email:
errors.append("L’expert interne n'a pas de courriel valide !")
- if self.date_soutenance_mailed is not None:
+ if self.exam.date_soutenance_mailed is not None:
errors.append("Une convocation a déjà été envoyée !")
return errors
def msg_context(self):
# Recipients with ladies first!
recip_names = sorted([
- self.student.civility_full_name,
- self.expert.civility_full_name,
- self.internal_expert.civility_full_name,
+ self.exam.student.civility_full_name,
+ self.exam.external_expert.civility_full_name,
+ self.exam.internal_expert.civility_full_name,
])
titles = [
- self.student.civility,
- self.expert.civility,
- self.internal_expert.civility,
+ self.exam.student.civility,
+ self.exam.external_expert.civility,
+ self.exam.internal_expert.civility,
]
mme_count = titles.count('Madame')
# Civilities, with ladies first!
@@ -463,16 +451,18 @@ class StudentConvocationExaminationView(EmailConfirmationView):
'recipient1': recip_names[0],
'recipient2': recip_names[1],
'recipient3': recip_names[2],
- 'student': self.student,
+ 'student': self.exam.student,
'sender': self.request.user,
'global_civilities': civilities,
- 'date_examen': django_format(self.student.date_exam, 'l j F Y à H\hi') if self.student.date_exam else '-',
- 'salle': self.student.room,
+ 'date_examen': django_format(self.exam.date_exam, 'l j F Y à H\hi') if self.exam.date_exam else '-',
+ 'salle': self.exam.room,
+ 'internal_expert': self.exam.internal_expert,
+ 'external_expert': self.exam.external_expert,
}
def get_initial(self):
initial = super().get_initial()
- to = [self.student.email, self.expert.email, self.internal_expert.email]
+ to = [self.exam.student.email, self.exam.external_expert.email, self.exam.internal_expert.email]
initial.update({
'cci': self.request.user.email,
@@ -484,8 +474,8 @@ class StudentConvocationExaminationView(EmailConfirmationView):
return initial
def on_success(self, student):
- self.student.date_soutenance_mailed = timezone.now()
- self.student.save()
+ self.exam.date_soutenance_mailed = timezone.now()
+ self.exam.save()
class StudentConvocationEDSView(StudentConvocationExaminationView):
@@ -523,24 +513,24 @@ class PrintExpertEDECompensationForm(PDFBaseView):
"""
pdf_class = ExpertEdeLetterPdf
- def filename(self, student):
- return slugify('{0}_{1}'.format(student.last_name, student.first_name)) + '_Expert.pdf'
+ def filename(self, exam):
+ return slugify('{0}_{1}'.format(exam.student.last_name, exam.student.first_name)) + '_Expert.pdf'
def get_object(self):
- return Student.objects.get(pk=self.kwargs['pk'])
+ return Examination.objects.get(pk=self.kwargs['pk'])
- def check_object(self, student):
- missing = student.missing_examination_data()
+ def check_object(self, exam):
+ missing = exam.missing_examination_data()
if missing:
messages.error(self.request, "\n".join(
["Toutes les informations ne sont pas disponibles pour la lettre à l’expert!"]
+ missing
))
- return redirect(reverse("admin:stages_student_change", args=(student.pk,)))
+ return redirect(reverse("admin:stages_student_change", args=(exam.student.pk,)))
def get(self, request, *args, **kwargs):
- student = self.get_object()
- response = self.check_object(student)
+ exam = self.get_object()
+ response = self.check_object(exam)
if response:
return response
return super().get(request, *args, **kwargs)
@@ -575,14 +565,14 @@ class PrintExpertEDSCompensationForm(PrintExpertEDECompensationForm):
"""
pdf_class = ExpertEdsLetterPdf
- def check_object(self, student):
- missing = student.missing_examination_data()
+ def check_object(self, exam):
+ missing = exam.missing_examination_data()
if missing:
messages.error(self.request, "\n".join(
["Toutes les informations ne sont pas disponibles pour la lettre à l’expert!"]
+ missing
))
- return redirect(reverse("admin:stages_student_change", args=(student.pk,)))
+ return redirect(reverse("admin:stages_student_change", args=[exam.student.pk]))
class PrintKlassList(ZippedFilesBaseView):
diff --git a/stages/views/base.py b/stages/views/base.py
index 7cab06f..905349d 100644
--- a/stages/views/base.py
+++ b/stages/views/base.py
@@ -21,6 +21,9 @@ class EmailConfirmationBaseView(FormView):
success_message = "Le message a été envoyé pour {person}"
error_message = "Échec d’envoi pour {person} ({err})"
+ def get_person(self):
+ return self.person_model.objects.get(pk=self.kwargs['pk'])
+
def form_valid(self, form):
email = EmailMessage(
subject=form.cleaned_data['subject'],
@@ -29,7 +32,7 @@ class EmailConfirmationBaseView(FormView):
to=form.cleaned_data['to'].split(';'),
bcc=form.cleaned_data['cci'].split(';'),
)
- person = self.person_model.objects.get(pk=self.kwargs['pk'])
+ person = self.get_person()
try:
email.send()
except Exception as err:
@@ -46,7 +49,7 @@ class EmailConfirmationBaseView(FormView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
- 'person': self.person_model.objects.get(pk=self.kwargs['pk']),
+ 'person': self.get_person(),
'title': self.title,
})
return context
diff --git a/stages/views/export.py b/stages/views/export.py
index 06ed0dc..3afe8fd 100644
--- a/stages/views/export.py
+++ b/stages/views/export.py
@@ -432,7 +432,7 @@ def export_qualification(request, section='ede'):
# Data
empty_values = [''] * 7
for student in Student.objects.filter(klass__name__startswith='3%s' % section.upper(), archived=False
- ).select_related('klass', 'referent', 'training_referent', 'mentor', 'expert', 'internal_expert',
+ ).select_related('klass', 'referent', 'training_referent', 'mentor',
).prefetch_related('examination_set'
).order_by('klass__name', 'last_name'):
stud_values = [
diff --git a/templates/email/student_convocation_EDE.txt b/templates/email/student_convocation_EDE.txt
index b70209f..ee97b25 100644
--- a/templates/email/student_convocation_EDE.txt
+++ b/templates/email/student_convocation_EDE.txt
@@ -8,7 +8,7 @@ Nous vous informons que la soutenance du travail de diplôme de {{ student.civil
- {{ date_examen }} en salle {{ salle }}
-Nous informons également {{ student.expert.civility }} {{ student.expert.last_name }} que le mémoire lui est adressé ce jour par courrier postal.
+Nous informons également {{ external_expert.civility }} {{ external_expert.last_name }} que le mémoire lui est adressé ce jour par courrier postal.
Nous vous remercions de nous confirmer par retour de courriel que vous avez bien reçu ce message et dans l’attente du plaisir de vous rencontrer prochainement, nous vous prions d’agréer, {{ global_civilities }}, nos salutations les meilleures.
diff --git a/templates/email/student_convocation_EDS.txt b/templates/email/student_convocation_EDS.txt
index 7a573e1..830ed17 100644
--- a/templates/email/student_convocation_EDS.txt
+++ b/templates/email/student_convocation_EDS.txt
@@ -8,7 +8,7 @@ Nous vous informons que la soutenance du travail final de {{ student.civility_fu
- {{ date_examen }} en salle {{ salle }}
-Nous informons également {{ student.expert.civility }} {{ student.expert.last_name }} que le mémoire lui est adressé ce jour par courrier postal.
+Nous informons également {{ external_expert.civility }} {{ external_expert.last_name }} que le mémoire lui est adressé ce jour par courrier postal.
Nous vous remercions de nous confirmer par retour de courriel que vous avez bien reçu ce message et dans l’attente du plaisir de vous rencontrer prochainement, nous vous prions d’agréer, {{ global_civilities }}, nos salutations les meilleures.