diff --git a/stages/admin.py b/stages/admin.py
index b4ad258..77f2f23 100644
--- a/stages/admin.py
+++ b/stages/admin.py
@@ -2,18 +2,29 @@ import os
import tempfile
import zipfile
+from collections import OrderedDict
from django import forms
from django.contrib import admin
from django.db import models
from django.db.models import Case, Count, When
from django.http import HttpResponse
+from django.core.mail import send_mail
+from datetime import date, datetime
+from openpyxl import Workbook
+from openpyxl.styles import Font, Style
+from openpyxl.writer.excel import save_virtual_workbook
from stages.models import (
Teacher, Option, Student, Section, Level, Klass, Corporation,
CorpContact, Domain, Period, Availability, Training, Course,
+ District, Candidate, Config
)
+from django.db.models import BooleanField
+from .forms import CandidateAdminForm
from stages.pdf import ChargeSheetPDF
+openxml_contenttype = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+
def print_charge_sheet(modeladmin, request, queryset):
"""
@@ -184,13 +195,14 @@ class AvailabilityAdminForm(forms.ModelForm):
comment=instance.comment)
return instance
+
class AvailabilityInline(admin.StackedInline):
model = Availability
form = AvailabilityAdminForm
ordering = ('corporation__name',)
extra = 1
formfield_overrides = {
- models.TextField: {'widget': forms.Textarea(attrs={'rows':2, 'cols':40})},
+ models.TextField: {'widget': forms.Textarea(attrs={'rows': 2, 'cols': 40})},
}
@@ -225,6 +237,114 @@ class CourseAdmin(admin.ModelAdmin):
search_fields = ('teacher__last_name', 'public', 'subject')
+def send_confirmation_mail(modeladmin, request, queryset):
+ for candidate in queryset:
+ if candidate.deposite_date is not None and candidate.date_confirmation_mail is None:
+ # Send confirmation message
+ src = 'cifom-epc@rpn.ch'
+ to = '{0}'.format(candidate.email)
+ if candidate.corporation:
+ to += ';'.format(candidate.corporation.email)
+ if candidate.instructor:
+ to += ';'.format(candidate.instructor.email)
+ subject = "Confirmation de votre inscription à l'Ecole Santé-social Pierre-Coullery"
+ message = "Madame, Monsieur,
Nous vous confirmons la bonne réception de l'inscription de {0} {1} {2}"
+ message += " dans la filière {3} pour l'année scolaire à venir.
"
+ message += " Nous nous tenons à votre disposition pour tout renseignement complémentaire et "
+ message += " vous prions de recevoir, Madame, Monsieur, nos salutations les plus cordiales.
"
+ message += "Secrétariat de l'EPC"
+ msg = message.format(candidate.civility, candidate.first_name, candidate.last_name, candidate.section)
+
+ """ ********************** to be uncommented !!
+ send_mail(
+ subject,
+ msg,
+ src,
+ [to],
+ fail_silently=False,
+ )
+ **************************************************
+ """
+
+ cand = Candidate.objects.get(pk=candidate.id)
+ cand.date_confirmation_mail = datetime.now()
+ cand.save()
+ return
+send_confirmation_mail.short_description = "Envoyer email de confirmation"
+
+
+def export_candidates(modeladmin, request, queryset):
+ """
+ Export all candidates fields
+ """
+ export_fields = OrderedDict([(f.verbose_name, f.name) for f in Candidate._meta.get_fields()])
+ boolean_fields = [f.name for f in Candidate._meta.get_fields() if isinstance(f, BooleanField)]
+ export_fields['Canton'] = 'district__abrev'
+ export_fields['Employeur'] = 'corporation__name'
+ export_fields['Employeur_localite'] = 'corporation__city'
+ export_fields['FEE/FPP'] = 'instructor__last_name'
+ del export_fields['ID']
+
+ wb = Workbook()
+ ws = wb.active
+ ws.title = 'Exportation'
+ bold = Style(font=Font(bold=True))
+ for col_idx, header in enumerate(export_fields.keys(), start=1):
+ cell = ws.cell(row=1, column=col_idx)
+ cell.value = header
+ cell.style = bold
+ query_keys = [f for f in export_fields.values() if f is not None]
+ for row_idx, tr in enumerate(queryset.values(*query_keys), start=2):
+ for col_idx, field in enumerate(query_keys, start=1):
+ if field == 'gender':
+ tr[field] = ('Madame', 'Monsieur')[tr[field] == 'M']
+ if field in boolean_fields:
+ tr[field] = ('', 'Oui')[tr[field] == 1]
+ ws.cell(row=row_idx, column=col_idx).value = tr[field]
+
+ response = HttpResponse(save_virtual_workbook(wb), content_type=openxml_contenttype)
+ response['Content-Disposition'] = 'attachment; filename=%s%s.xlsx' % (
+ 'candidats_export_', date.strftime(date.today(), '%Y-%m-%d'))
+ return response
+
+export_candidates.short_description = "Exporter les candidats sélectionnés"
+
+
+class CandidateAdmin(admin.ModelAdmin):
+ form = CandidateAdminForm
+ list_display = ('last_name', 'first_name', 'section', 'option', 'confirm_email')
+ list_filter = ('section', 'option', )
+ readonly_fields = ('total_result_points', 'total_result_mark', 'date_confirmation_mail')
+ actions = [send_confirmation_mail, export_candidates]
+ fieldsets = (
+ (None, {
+ 'fields': (('first_name', 'last_name', 'gender'),
+ ('street', 'pcode', 'city', 'district'),
+ ('mobile', 'email'),
+ ('birth_date', 'avs', 'handicap', ),
+ ('section', 'option'),
+ ('corporation', 'instructor'),
+ ('deposite_date', 'date_confirmation_mail', 'canceled_file', ),
+ 'comment',
+ ),
+ }),
+ ("FE", {
+ 'classes': ('collapse',),
+ 'fields': (('exemption_ecg', 'integration_second_year', 'validation_sfpo'),),
+ }),
+ ("EDE/EDS", {
+ 'classes': ('collapse',),
+ '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'),
+ ('examination_result', 'interview_result', 'file_result', 'total_result_points',
+ 'total_result_mark')
+ ),
+ }),
+ )
+
admin.site.register(Section)
admin.site.register(Level)
admin.site.register(Klass, KlassAdmin)
@@ -238,3 +358,6 @@ admin.site.register(Domain)
admin.site.register(Period, PeriodAdmin)
admin.site.register(Availability, AvailabilityAdmin)
admin.site.register(Training, TrainingAdmin)
+admin.site.register(Candidate, CandidateAdmin)
+admin.site.register(District)
+admin.site.register(Config)
diff --git a/stages/forms.py b/stages/forms.py
index 2fd2a0f..7bd2871 100644
--- a/stages/forms.py
+++ b/stages/forms.py
@@ -3,7 +3,7 @@ from django.conf import settings
from tabimport import FileFactory, UnsupportedFileFormat
-from .models import Section, Period
+from .models import Section, Period, Candidate
class StudentImportForm(forms.Form):
@@ -34,3 +34,14 @@ class PeriodForm(forms.Form):
class UploadHPFileForm(forms.Form):
upload = forms.FileField(label='Fichier HyperPlanning')
+
+
+class CandidateAdminForm(forms.ModelForm):
+
+ class Meta:
+ model = Candidate
+ widgets = {
+ 'comment': forms.Textarea(attrs={'cols': 100, 'rows': 1}),
+ 'pcode': forms.TextInput(attrs={'size': 10 }),
+ }
+ fields = ('__all__')
\ No newline at end of file
diff --git a/stages/migrations/0003_ame=Add_Candidate_Model.py b/stages/migrations/0003_ame=Add_Candidate_Model.py
new file mode 100644
index 0000000..a437fa9
--- /dev/null
+++ b/stages/migrations/0003_ame=Add_Candidate_Model.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.2 on 2017-09-08 08:41
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('stages', '0002_add_student_option_ase'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Candidate',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('first_name', models.CharField(max_length=40, verbose_name='Prénom')),
+ ('last_name', models.CharField(max_length=40, verbose_name='Nom')),
+ ('gender', models.CharField(choices=[('M', 'Masculin'), ('F', 'Féminin'), ('I', 'Inconnu')], max_length=3, verbose_name='Genre')),
+ ('birth_date', models.DateField(blank=True, default=None, null=True, verbose_name='Date de naissance')),
+ ('street', models.CharField(blank=True, max_length=150, verbose_name='Rue')),
+ ('pcode', models.CharField(max_length=4, verbose_name='Code postal')),
+ ('city', models.CharField(max_length=40, verbose_name='Localité')),
+ ('mobile', models.CharField(blank=True, max_length=40, verbose_name='Portable')),
+ ('email', models.EmailField(blank=True, max_length=254, verbose_name='Courriel')),
+ ('avs', models.CharField(blank=True, max_length=15, verbose_name='No AVS')),
+ ('handicap', models.BooleanField(default=False)),
+ ('section', models.CharField(choices=[('ASA', 'Aide en soin et accompagnement AFP'), ('ASE', 'Assist. socio-éducatif-ve CFC'), ('ASSC', 'Assist. en soin et santé communautaire CFC'), ('EDE', "Educ. de l'enfance, dipl. ES"), ('EDS', 'Educ. social-e, dipl. ES')], max_length=10, verbose_name='Filière')),
+ ('option', models.CharField(blank=True, max_length=20, null=True)),
+ ('exemption_ecg', models.BooleanField(default=False)),
+ ('date_confirmation_mail', models.DateField(blank=True, default=None, null=True, verbose_name='Mail de confirmation')),
+ ('registration_form', models.BooleanField(default=False, verbose_name="Formulaire d'inscription")),
+ ('certificate_of_payement', models.BooleanField(default=False, verbose_name='Attest. paiement')),
+ ('police_record', models.BooleanField(default=False, verbose_name='Casier judic.')),
+ ('cv', models.BooleanField(default=False, verbose_name='CV')),
+ ('certif_of_cfc', models.BooleanField(default=False, verbose_name='CFC')),
+ ('certif_of_800h', models.BooleanField(default=False, verbose_name='Attest. 800h.')),
+ ('reflexive_text', models.BooleanField(default=False, verbose_name='Texte réflexif')),
+ ('promise', models.BooleanField(default=False, verbose_name="Promesse d'eng.")),
+ ('contract', models.BooleanField(default=False, verbose_name='Contrat valide')),
+ ('comment', models.TextField(blank=True, default='', verbose_name='Remarques')),
+ ('proc_admin_ext', models.BooleanField(default=False, verbose_name='Insc. autre école')),
+ ('work_certificate', models.BooleanField(default=False, verbose_name='Certif. de travail')),
+ ('marks_certificate', models.BooleanField(default=False, verbose_name='Bull. notes')),
+ ('deposite_date', models.DateField(blank=True, default=None, null=True, verbose_name='Date dépôt dossier')),
+ ('interview_date', models.DateTimeField(blank=True, default=None, null=True, verbose_name='Date entretien prof.')),
+ ('interview_room', models.CharField(blank=True, max_length=50, verbose_name="Salle d'entretien prof.")),
+ ('examination_result', models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Points examen')),
+ ('interview_result', models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Points entretien prof.')),
+ ('file_result', models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Points dossier')),
+ ('total_result_points', models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Total points')),
+ ('total_result_mark', models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Note finale')),
+ ('corporation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stages.Corporation', verbose_name='Employeur')),
+ ],
+ options={
+ 'verbose_name': 'Candidat',
+ },
+ ),
+ migrations.CreateModel(
+ name='Config',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('key', models.CharField(max_length=100)),
+ ('value', models.TextField()),
+ ('comment', models.TextField()),
+ ],
+ ),
+ migrations.CreateModel(
+ name='District',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('abrev', models.CharField(max_length=10)),
+ ('name', models.CharField(max_length=30)),
+ ],
+ options={
+ 'verbose_name': 'Canton',
+ },
+ ),
+ migrations.AddField(
+ model_name='candidate',
+ name='district',
+ field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='stages.District', verbose_name='Canton'),
+ ),
+ migrations.AddField(
+ model_name='candidate',
+ name='instructor',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stages.CorpContact', verbose_name='FEE/FPP'),
+ ),
+ migrations.AddField(
+ model_name='candidate',
+ name='integration_second_year',
+ field=models.BooleanField(default=False, verbose_name='Intégration'),
+ ),
+ migrations.AddField(
+ model_name='candidate',
+ name='validation_sfpo',
+ field=models.DateField(blank=True, default=None, null=True, verbose_name='Confirmation SFPO'),
+ ),
+ migrations.AlterField(
+ model_name='candidate',
+ name='option',
+ field=models.CharField(blank=True,
+ choices=[('GEN', 'Généraliste'), ('ENF', 'Enfance'), ('PAG', 'Personnes âgées'),
+ ('HAN', 'Handicap'), ('PE-5400h', 'Parcours Emploi 5400h.'),
+ ('PE-3600h', 'Parcours Emploi 3600h.'), ('PS', 'Parcours stage')],
+ max_length=20, null=True),
+ ),
+ migrations.AddField(
+ model_name='candidate',
+ name='canceled_file',
+ field=models.BooleanField(default=False, verbose_name='Dossier retiré'),
+ ),
+ ]
diff --git a/stages/migrations/0004_ame=Add_fields_in_Candidate_model.py b/stages/migrations/0004_ame=Add_fields_in_Candidate_model.py
new file mode 100644
index 0000000..7e3b339
--- /dev/null
+++ b/stages/migrations/0004_ame=Add_fields_in_Candidate_model.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.2 on 2017-09-14 11:18
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('stages', '0003_ame=Add_Candidate_Model'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='candidate',
+ name='accepted',
+ field=models.BooleanField(default=False, verbose_name='Admis'),
+ ),
+ migrations.AddField(
+ model_name='candidate',
+ name='file_resp',
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rel_file_exp', to='stages.Teacher', verbose_name='Exp. dossier'),
+ ),
+ migrations.AddField(
+ model_name='candidate',
+ name='interview_resp',
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='stages.Teacher', verbose_name='Exp. entretien'),
+ ),
+ migrations.AddField(
+ model_name='candidate',
+ name='photo',
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/stages/models.py b/stages/models.py
index 15cfba3..439704e 100644
--- a/stages/models.py
+++ b/stages/models.py
@@ -166,11 +166,11 @@ class Student(models.Model):
dispense_eps = models.BooleanField(default=False)
soutien_dys = models.BooleanField(default=False)
corporation = models.ForeignKey('Corporation', null=True, blank=True,
- on_delete=models.SET_NULL, verbose_name='Employeur')
+ on_delete=models.SET_NULL, verbose_name='Employeur')
instructor = models.ForeignKey('CorpContact', null=True, blank=True,
- on_delete=models.SET_NULL, verbose_name='FEE/FPP')
+ on_delete=models.SET_NULL, verbose_name='FEE/FPP')
klass = models.ForeignKey(Klass, verbose_name='Classe', blank=True, null=True,
- on_delete=models.PROTECT)
+ on_delete=models.PROTECT)
archived = models.BooleanField(default=False, verbose_name='Archivé')
archived_text = models.TextField(blank=True)
@@ -214,7 +214,7 @@ class Student(models.Model):
@classmethod
def prepare_import(cls, student_values):
- ''' Hook for tabimport, before new object get created '''
+ """ Hook for tabimport, before new object get created """
if 'klass' in student_values:
try:
k = Klass.objects.get(name=student_values['klass'])
@@ -235,7 +235,7 @@ class Corporation(models.Model):
short_name = models.CharField(max_length=40, blank=True, verbose_name='Nom court')
district = models.CharField(max_length=20, blank=True, verbose_name='Canton')
parent = models.ForeignKey('self', null=True, blank=True, verbose_name='Institution mère',
- on_delete=models.SET_NULL)
+ on_delete=models.SET_NULL)
sector = models.CharField(max_length=40, blank=True, verbose_name='Secteur')
typ = models.CharField(max_length=40, blank=True, verbose_name='Type de structure')
street = models.CharField(max_length=100, blank=True, verbose_name='Rue')
@@ -296,7 +296,7 @@ class Period(models.Model):
""" Périodes de stages """
title = models.CharField(max_length=150, verbose_name='Titre')
section = models.ForeignKey(Section, verbose_name='Filière', on_delete=models.PROTECT,
- limit_choices_to={'name__startswith': 'MP'})
+ limit_choices_to={'name__startswith': 'MP'})
level = models.ForeignKey(Level, verbose_name='Niveau', on_delete=models.PROTECT)
start_date = models.DateField(verbose_name='Date de début')
end_date = models.DateField(verbose_name='Date de fin')
@@ -338,7 +338,7 @@ class Availability(models.Model):
period = models.ForeignKey(Period, verbose_name='Période', on_delete=models.CASCADE)
domain = models.ForeignKey(Domain, verbose_name='Domaine', on_delete=models.CASCADE)
contact = models.ForeignKey(CorpContact, null=True, blank=True, verbose_name='Contact institution',
- on_delete=models.SET_NULL)
+ on_delete=models.SET_NULL)
priority = models.BooleanField('Prioritaire', default=False)
comment = models.TextField(blank=True, verbose_name='Remarques')
@@ -362,7 +362,7 @@ class Training(models.Model):
student = models.ForeignKey(Student, verbose_name='Étudiant', on_delete=models.CASCADE)
availability = models.OneToOneField(Availability, verbose_name='Disponibilité', on_delete=models.CASCADE)
referent = models.ForeignKey(Teacher, null=True, blank=True, verbose_name='Référent',
- on_delete=models.SET_NULL)
+ on_delete=models.SET_NULL)
comment = models.TextField(blank=True, verbose_name='Remarques')
class Meta:
@@ -403,7 +403,7 @@ IMPUTATION_CHOICES = (
class Course(models.Model):
"""Cours et mandats attribués aux enseignants"""
teacher = models.ForeignKey(Teacher, blank=True, null=True,
- verbose_name="Enseignant-e", on_delete=models.SET_NULL)
+ verbose_name="Enseignant-e", on_delete=models.SET_NULL)
public = models.CharField("Classe(s)", max_length=200, default='')
subject = models.CharField("Sujet", max_length=100, default='')
period = models.IntegerField("Nb de périodes", default=0)
@@ -418,3 +418,126 @@ class Course(models.Model):
return '{0} - {1} - {2} - {3}'.format(
self.teacher, self.public, self.subject, self.period
)
+
+GENDER_CHOICES = (
+ ('M', 'Masculin'),
+ ('F', 'Féminin'),
+ ('I', 'Inconnu')
+)
+
+SECTION_CHOICES = (
+ ('ASA', 'Aide en soin et accompagnement AFP'),
+ ('ASE', 'Assist. socio-éducatif-ve CFC'),
+ ('ASSC', 'Assist. en soin et santé communautaire CFC'),
+ ('EDE', 'Educ. de l\'enfance, dipl. ES'),
+ ('EDS', 'Educ. social-e, dipl. ES'),
+)
+
+
+OPTION_CHOICES = (
+ ('GEN', 'Généraliste'),
+ ('ENF', 'Enfance'),
+ ('PAG', 'Personnes âgées'),
+ ('HAN', 'Handicap'),
+ ('PE-5400h', 'Parcours Emploi 5400h.'),
+ ('PE-3600h', 'Parcours Emploi 3600h.'),
+ ('PS', 'Parcours stage'),
+)
+
+
+class Config(models.Model):
+ key = models.CharField(max_length=100)
+ value = models.TextField()
+ comment = models.TextField()
+
+ def __str__(self):
+ return '{0} : {1}'.format(self.key, self.value)
+
+
+class District(models.Model):
+ class Meta:
+ verbose_name = 'Canton'
+
+ abrev = models.CharField(max_length=10)
+ name = models.CharField(max_length=30)
+
+ def __str__(self):
+ return '{0} - {1}'.format(self.abrev, self.name)
+
+
+class Candidate(models.Model):
+ """
+ Inscriptions for new students
+ """
+ first_name = models.CharField(max_length=40, verbose_name='Prénom')
+ last_name = models.CharField(max_length=40, verbose_name='Nom')
+ gender = models.CharField(max_length=3, choices=GENDER_CHOICES, verbose_name='Genre')
+ birth_date = models.DateField(default=None, blank=True, null=True, verbose_name='Date de naissance')
+ street = models.CharField(max_length=150, blank=True, verbose_name='Rue')
+ pcode = models.CharField(max_length=4, verbose_name='Code postal')
+ city = models.CharField(max_length=40, verbose_name='Localité')
+ district = models.ForeignKey(District, default=None, null=True, verbose_name='Canton')
+ mobile = models.CharField(max_length=40, blank=True, verbose_name='Portable')
+ email = models.EmailField(verbose_name='Courriel', blank=True)
+ avs = models.CharField(max_length=15, blank=True, verbose_name='No AVS')
+ handicap = models.BooleanField(default=False)
+ section = models.CharField(max_length=10, choices=SECTION_CHOICES, null=False, verbose_name='Filière')
+ option = models.CharField(max_length=20, choices=OPTION_CHOICES, null=True, blank=True)
+ exemption_ecg = models.BooleanField(default=False)
+ validation_sfpo = models.DateField(default=None, blank=True, null=True, verbose_name='Confirmation SFPO')
+ integration_second_year = models.BooleanField(default=False, verbose_name='Intégration')
+ date_confirmation_mail = models.DateField(default=None, blank=True, null=True, verbose_name='Mail de confirmation')
+ canceled_file = models.BooleanField(default=False, verbose_name='Dossier retiré')
+ photo = models.BooleanField(default=False)
+ corporation = models.ForeignKey('Corporation', null=True, blank=True,
+ on_delete=models.SET_NULL, verbose_name='Employeur')
+ instructor = models.ForeignKey('CorpContact', null=True, blank=True,
+ on_delete=models.SET_NULL, verbose_name='FEE/FPP')
+
+ # Checking for registration file
+ registration_form = models.BooleanField(default=False, verbose_name="Formulaire d'inscription")
+ certificate_of_payement = models.BooleanField(default=False, verbose_name="Attest. paiement")
+ police_record = models.BooleanField(default=False, verbose_name="Casier judic.")
+ cv = models.BooleanField(default=False, verbose_name="CV")
+ certif_of_cfc = models.BooleanField(default=False, verbose_name="CFC")
+ certif_of_800h = models.BooleanField(default=False, verbose_name="Attest. 800h.")
+ reflexive_text = models.BooleanField(default=False, verbose_name="Texte réflexif")
+ promise = models.BooleanField(default=False, verbose_name="Promesse d'eng.")
+ contract = models.BooleanField(default=False, verbose_name="Contrat valide")
+ comment = models.TextField(default='', blank=True, verbose_name='Remarques')
+
+ proc_admin_ext = models.BooleanField(default=False, verbose_name="Insc. autre école")
+ work_certificate = models.BooleanField(default=False, verbose_name="Certif. de travail")
+ marks_certificate = models.BooleanField(default=False, verbose_name="Bull. notes")
+ deposite_date = models.DateField(default=None, blank=True, null=True, verbose_name='Date dépôt dossier')
+ interview_date = models.DateTimeField(default=None, blank=True, null=True, verbose_name='Date entretien prof.')
+ interview_room = models.CharField(max_length=50, blank=True, verbose_name="Salle d'entretien prof.")
+ examination_result = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Points examen')
+ interview_result = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Points entretien prof.')
+ file_result = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Points dossier')
+ total_result_points = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Total points')
+ total_result_mark = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Note finale')
+ accepted = models.BooleanField(default=False, verbose_name='Admis')
+ interview_resp = models.ForeignKey(Teacher, default=None, null=True, blank=True, verbose_name='Exp. entretien')
+ file_resp = models.ForeignKey(Teacher, default=None, related_name='rel_file_exp', null=True,
+ blank=True, verbose_name='Exp. dossier')
+
+ class Meta:
+ verbose_name = 'Candidat'
+
+ @property
+ def civility(self):
+ if self.gender == 'M':
+ return 'Monsieur'
+ if self.gender == 'F':
+ return 'Madame'
+ else:
+ return ''
+
+ def confirm_email(self):
+ if self.date_confirmation_mail is None:
+ return u'
'.format('/static/img/no_ok.jpg')
+ else:
+ return u'
'.format('/static/img/ok.jpeg')
+
+ confirm_email.allow_tags = True
diff --git a/stages/static/img/no_ok.jpg b/stages/static/img/no_ok.jpg
new file mode 100644
index 0000000..3ee7540
Binary files /dev/null and b/stages/static/img/no_ok.jpg differ
diff --git a/stages/static/img/ok.jpeg b/stages/static/img/ok.jpeg
new file mode 100644
index 0000000..6bc7f9e
Binary files /dev/null and b/stages/static/img/ok.jpeg differ
diff --git a/stages/views.py b/stages/views.py
index 81ba162..8fbd3ee 100644
--- a/stages/views.py
+++ b/stages/views.py
@@ -154,8 +154,9 @@ class AttributionView(TemplateView):
# Populate each referent with the number of referencies done during the current school year
ref_counts = dict([(ref.id, ref.num_refs)
- for ref in Teacher.objects.filter(archived=False, training__availability__period__end_date__gte=school_year_start()
- ).annotate(num_refs=Count('training'))])
+ for ref in Teacher.objects.filter(
+ archived=False, training__availability__period__end_date__gte=school_year_start()
+ ).annotate(num_refs=Count('training'))])
for ref in referents:
ref.num_refs = ref_counts.get(ref.id, 0)
@@ -224,6 +225,7 @@ def section_periods(request, pk):
for p in section.period_set.filter(start_date__gt=two_years_ago).order_by('-start_date')]
return HttpResponse(json.dumps(periods), content_type="application/json")
+
def section_classes(request, pk):
section = get_object_or_404(Section, pk=pk)
classes = [(k.id, k.name) for k in section.klass_set.all()]
@@ -247,6 +249,7 @@ def period_students(request, pk):
'klass': s.klass.name} for s in students]
return HttpResponse(json.dumps(data), content_type="application/json")
+
def period_availabilities(request, pk):
""" Return all availabilities in the specified period """
period = get_object_or_404(Period, pk=pk)
@@ -257,6 +260,7 @@ def period_availabilities(request, pk):
).order_by('-priority', 'corporation__name')]
return HttpResponse(json.dumps(corps), content_type="application/json")
+
def new_training(request):
if request.method != 'POST':
return HttpResponseNotAllowed()
@@ -278,6 +282,7 @@ def new_training(request):
return HttpResponse(str(exc))
return HttpResponse(b'OK')
+
def del_training(request):
""" Delete training and return the referent id """
if request.method != 'POST':
@@ -778,11 +783,11 @@ def general_export(request):
if field == 'gender':
tr[field] = ('Madame', 'Monsieur')[tr[field] == 'M']
if field == 'dispense_ecg':
- tr[field] = ('', 'Oui')[tr[field]==1]
+ tr[field] = ('', 'Oui')[tr[field] == 1]
if field == 'dispense_eps':
- tr[field] = ('', 'Oui')[tr[field]==1]
+ tr[field] = ('', 'Oui')[tr[field] == 1]
if field == 'soutien_dys':
- tr[field] = ('', 'Oui')[tr[field]==1]
+ tr[field] = ('', 'Oui')[tr[field] == 1]
ws.cell(row=row_idx, column=col_idx).value = tr[field]
response = HttpResponse(save_virtual_workbook(wb), content_type=openxml_contenttype)