[candidates] Add Interview model

This commit is contained in:
Claude Paroz 2018-01-25 15:51:51 +01:00
parent 3ff766bc37
commit 3f7a24769d
4 changed files with 146 additions and 18 deletions

View file

@ -8,7 +8,7 @@ from django.db.models import BooleanField
from django.template import loader
from stages.exports import OpenXMLExport
from .models import Candidate, GENDER_CHOICES
from .models import Candidate, Interview, GENDER_CHOICES
def export_candidates(modeladmin, request, queryset):
@ -88,6 +88,8 @@ send_confirmation_mail.short_description = "Envoyer email de confirmation"
class CandidateAdminForm(forms.ModelForm):
interview = forms.ModelChoiceField(queryset=Interview.objects.all(), required=False)
class Meta:
model = Candidate
widgets = {
@ -96,6 +98,24 @@ class CandidateAdminForm(forms.ModelForm):
}
fields = '__all__'
def __init__(self, *args, **kwargs):
try:
kwargs['initial'] = {'interview': kwargs['instance'].interview}
except Interview.DoesNotExist:
pass
return super().__init__(*args, **kwargs)
def save(self, **kwargs):
obj = super().save(**kwargs)
if 'interview' in self.changed_data:
if self.cleaned_data['interview'] is None:
self.initial['interview'].candidat = None
self.initial['interview'].save()
else:
self.cleaned_data['interview'].candidat = obj
self.cleaned_data['interview'].save()
return obj
class CandidateAdmin(admin.ModelAdmin):
form = CandidateAdminForm
@ -124,7 +144,7 @@ class CandidateAdmin(admin.ModelAdmin):
'fields': (('registration_form', 'certificate_of_payement', 'cv', 'certif_of_cfc',
'police_record', 'certif_of_800h', 'reflexive_text', 'work_certificate',
'marks_certificate', 'proc_admin_ext', 'promise', 'contract'),
('interview_date', 'interview_room'),
('interview',),
('examination_result', 'interview_result', 'file_result', 'total_result_points',
'total_result_mark')
),
@ -135,4 +155,10 @@ class CandidateAdmin(admin.ModelAdmin):
return obj.date_confirmation_mail is not None
confirm_mail.boolean = True
class InterviewAdmin(admin.ModelAdmin):
pass
admin.site.register(Candidate, CandidateAdmin)
admin.site.register(Interview, InterviewAdmin)

View file

@ -0,0 +1,58 @@
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('stages', '__latest__'),
('candidats', '0002_deposit_date_non_null'),
]
operations = [
migrations.CreateModel(
name='Interview',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateTimeField(verbose_name='Date')),
('room', models.CharField(max_length=20, verbose_name="Salle d'entretien")),
('status', models.CharField(choices=[('N', 'Normal'), ('R', 'Réserve'), ('X', 'Attente confirmation enseignants')], default='N', max_length=1, verbose_name='Statut')),
],
options={
'ordering': ('date',),
'verbose_name': "Entretien d'admission",
'verbose_name_plural': "Entretiens d'admission",
},
),
migrations.RemoveField(
model_name='candidate',
name='file_resp',
),
migrations.RemoveField(
model_name='candidate',
name='interview_date',
),
migrations.RemoveField(
model_name='candidate',
name='interview_resp',
),
migrations.RemoveField(
model_name='candidate',
name='interview_room',
),
migrations.AddField(
model_name='interview',
name='candidat',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='candidats.Candidate'),
),
migrations.AddField(
model_name='interview',
name='teacher_file',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='stages.Teacher', verbose_name='Ens. dossier'),
),
migrations.AddField(
model_name='interview',
name='teacher_int',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='stages.Teacher', verbose_name='Ens. entretien'),
),
]

View file

@ -1,5 +1,7 @@
from django.db import models
from django.utils.dateformat import format as django_format
from stages.models import Corporation, CorpContact, Teacher
GENDER_CHOICES = (
('M', 'Masculin'),
@ -53,10 +55,10 @@ class Candidate(models.Model):
has_photo = models.BooleanField(default=False, verbose_name='Photo passeport')
corporation = models.ForeignKey(
'stages.Corporation', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='Employeur'
Corporation, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='Employeur'
)
instructor = models.ForeignKey(
'stages.CorpContact', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='FEE/FPP'
CorpContact, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='FEE/FPP'
)
# Checking for registration file
@ -75,23 +77,12 @@ class Candidate(models.Model):
work_certificate = models.BooleanField("Certif. de travail", default=False)
marks_certificate = models.BooleanField("Bull. de notes", default=False)
deposite_date = models.DateField('Date dépôt dossier')
interview_date = models.DateTimeField('Date entretien prof.', blank=True, null=True)
interview_room = models.CharField("Salle d'entretien prof.", max_length=50, blank=True)
examination_result = models.PositiveSmallIntegerField('Points examen', blank=True, null=True)
interview_result = models.PositiveSmallIntegerField('Points entretien prof.', blank=True, null=True)
file_result = models.PositiveSmallIntegerField('Points dossier', blank=True, null=True)
total_result_points = models.PositiveSmallIntegerField('Total points', blank=True, null=True)
total_result_mark = models.PositiveSmallIntegerField('Note finale', blank=True, null=True)
accepted = models.BooleanField('Admis', default=False)
interview_resp = models.ForeignKey(
'stages.Teacher', null=True, blank=True, related_name='+', verbose_name='Exp. entretien',
on_delete=models.SET_NULL
)
file_resp = models.ForeignKey(
'stages.Teacher', null=True, blank=True, related_name='+', verbose_name='Exp. dossier',
on_delete=models.SET_NULL
)
class Meta:
verbose_name = 'Candidat'
@ -107,3 +98,36 @@ class Candidate(models.Model):
return 'Madame'
else:
return ''
INTERVIEW_CHOICES = (
('N', 'Normal'),
('R', 'Réserve'),
('X', 'Attente confirmation enseignants'),
)
class Interview(models.Model):
date = models.DateTimeField('Date')
room = models.CharField("Salle d'entretien", max_length=20)
candidat = models.OneToOneField(Candidate, null=True, blank=True, on_delete=models.SET_NULL)
teacher_int = models.ForeignKey(
Teacher, null=True, blank=True, on_delete=models.SET_NULL, related_name='+',
verbose_name='Ens. entretien'
)
teacher_file = models.ForeignKey(
Teacher, null=True, blank=True, on_delete=models.SET_NULL, related_name='+',
verbose_name='Ens. dossier'
)
status = models.CharField('Statut', max_length=1, choices=INTERVIEW_CHOICES, default='N')
class Meta:
verbose_name = "Entretien d'admission"
verbose_name_plural = "Entretiens d'admission"
ordering = ('date',)
def __str__(self):
return '{0} : {1}/{2} - ({3}) -salle:{4}-{5}'.format(
django_format(self.date, "l j F Y à H\hi"),
self.teacher_int or '?', self.teacher_file or '?',
self.status, self.room, self.candidat or '???'
)

View file

@ -1,4 +1,4 @@
from datetime import date
from datetime import date, datetime
from unittest import mock
from django.contrib.auth.models import User
@ -6,8 +6,8 @@ from django.core import mail
from django.test import TestCase
from django.urls import reverse
from stages.models import Section
from .models import Candidate
from stages.models import Section, Teacher
from .models import Candidate, Interview
class CandidateTests(TestCase):
@ -17,6 +17,26 @@ class CandidateTests(TestCase):
'me', 'me@example.org', 'mepassword', first_name='Hans', last_name='Schmid',
)
def test_interview(self):
inter = Interview.objects.create(date=datetime(2018, 3, 10, 10, 30), room='B103')
self.assertEqual(str(inter), 'samedi 10 mars 2018 à 10h30 : ?/? - (N) -salle:B103-???')
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()
)
t1 = Teacher.objects.create(first_name="Julie", last_name="Caux", abrev="JCA")
t2 = Teacher.objects.create(first_name='Jeanne', last_name='Dubois')
inter.teacher_int = t1
inter.teacher_file = t2
inter.candidat = cand
inter.save()
self.assertEqual(
str(inter),
'samedi 10 mars 2018 à 10h30 : Caux Julie/Dubois Jeanne - (N) -salle:B103-Dupond Henri'
)
self.assertEqual(cand.interview, inter)
def test_send_confirmation_mail(self):
ede = Section.objects.create(name='EDE')
ase = Section.objects.create(name='ASE')