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)