| 1 | # -=- encoding: utf-8 -=- |
| 2 | |
| 3 | from auf.django.emploi import models as emploi |
| 4 | from django.contrib.auth.models import User, Group |
| 5 | from django.db import models |
| 6 | from django.db.models.signals import pre_save, pre_delete |
| 7 | from django.dispatch import receiver |
| 8 | from south.modelsinspector import add_introspection_rules |
| 9 | from tinymce import models as tinymce_models |
| 10 | |
| 11 | from project.recrutement import groups as recrutement_groups |
| 12 | |
| 13 | ### CONSTANTES |
| 14 | |
| 15 | #NOTES |
| 16 | NOTE_MIN = 1 |
| 17 | NOTE_RANGE = 1 |
| 18 | NOTE_MAX = 11 |
| 19 | NOTES = [(i, i) for i in range(NOTE_MIN, NOTE_MAX, NOTE_RANGE)] |
| 20 | |
| 21 | #HELP_TEXT |
| 22 | HELP_TEXT_NB_DEPENDANT = "Le nombre de personnes à charge" |
| 23 | HELP_TEXT_TAGS_ACCEPTES = "Pour le texte, les variables disponibles sont : \ |
| 24 | {{ nom_candidat }} {{ prenom_candidat }} \ |
| 25 | {{ offre_emploi }} et {{ genre_candidat }} \ |
| 26 | (Pour Monsieur/Madame). Ces champs seront \ |
| 27 | automatiquement remplacés par les informations de \ |
| 28 | chaque candidat." |
| 29 | |
| 30 | # Pour South |
| 31 | add_introspection_rules([], ["^tinymce.models.HTMLField"]) |
| 32 | |
| 33 | |
| 34 | class Candidat(emploi.Candidat): |
| 35 | |
| 36 | class Meta: |
| 37 | proxy = True |
| 38 | |
| 39 | def moyenne_notes(self): |
| 40 | evaluations = CandidatEvaluation.objects.filter(candidat=self) |
| 41 | notes = [evaluation.note for evaluation in evaluations.all() \ |
| 42 | if evaluation.note is not None] |
| 43 | |
| 44 | if len(notes) > 0: |
| 45 | moyenne_votes = float(sum(notes)) / len(notes) |
| 46 | else: |
| 47 | moyenne_votes = "Non disponible" |
| 48 | return moyenne_votes |
| 49 | |
| 50 | |
| 51 | class OffreEmploiManager(models.Manager): |
| 52 | |
| 53 | def get_query_set(self): |
| 54 | fkeys = ('region',) |
| 55 | return super(OffreEmploiManager, self).get_query_set().\ |
| 56 | select_related(*fkeys).all() |
| 57 | |
| 58 | |
| 59 | class ProxyOffreEmploi(emploi.OffreEmploi): |
| 60 | |
| 61 | class Meta: |
| 62 | proxy = True |
| 63 | verbose_name = u"offre d'emploi (visualisation)" |
| 64 | verbose_name_plural = u"offres d'emploi (visualisation)" |
| 65 | |
| 66 | def __unicode__(self): |
| 67 | return '%s [%s] - View' % (self.nom, self.id) |
| 68 | |
| 69 | |
| 70 | class ProxyCandidat(emploi.Candidat): |
| 71 | |
| 72 | class Meta: |
| 73 | proxy = True |
| 74 | verbose_name = u"candidat (visualisation)" |
| 75 | verbose_name_plural = u"candidats (visualisation)" |
| 76 | |
| 77 | def __unicode__(self): |
| 78 | return '%s %s [%s]' % (self.prenom, self.nom, self.id) |
| 79 | |
| 80 | |
| 81 | class Evaluateur(models.Model): |
| 82 | user = models.ForeignKey(User, unique=True, verbose_name=u"évaluateur") |
| 83 | |
| 84 | class Meta: |
| 85 | verbose_name = u"évaluateur" |
| 86 | |
| 87 | def __unicode__(self): |
| 88 | return '%s %s' % (self.user.first_name, self.user.last_name) |
| 89 | |
| 90 | |
| 91 | # Synchro des objets évaluateurs pour mettre les users Django dans le groupe |
| 92 | # évaluateurs, afin d'y mettre des permissions |
| 93 | @receiver(pre_save, sender=Evaluateur) |
| 94 | def sync_add_groupe_evaluateur(sender, **kwargs): |
| 95 | instance = kwargs['instance'] |
| 96 | user_groups = [g.name for g in instance.user.groups.all()] |
| 97 | if recrutement_groups.EVALUATEURS not in user_groups: |
| 98 | grp_evaluateurs = Group.objects.get(name=recrutement_groups.EVALUATEURS) |
| 99 | instance.user.groups.add(grp_evaluateurs) |
| 100 | instance.user.save() |
| 101 | |
| 102 | |
| 103 | @receiver(pre_delete, sender=Evaluateur) |
| 104 | def sync_delete_groupe_evaluateur(sender, **kwargs): |
| 105 | instance = kwargs['instance'] |
| 106 | grp_evaluateurs = Group.objects.get(name=recrutement_groups.EVALUATEURS) |
| 107 | instance.user.groups.remove(grp_evaluateurs) |
| 108 | instance.user.save() |
| 109 | |
| 110 | |
| 111 | class OffreEmploiEvaluateur(models.Model): |
| 112 | offre_emploi = models.ForeignKey(emploi.OffreEmploi, db_column='offre_emploi', |
| 113 | verbose_name=u'offre d\'emploi') |
| 114 | evaluateur = models.ForeignKey(Evaluateur, db_column='evaluateur', |
| 115 | verbose_name=u'évaluateur') |
| 116 | |
| 117 | class Meta: |
| 118 | unique_together = ('offre_emploi', 'evaluateur') |
| 119 | verbose_name = 'Évaluateur - offre emploi' |
| 120 | verbose_name_plural = 'Évaluateurs - offre emploi' |
| 121 | |
| 122 | def __unicode__(self): |
| 123 | return u"%s - %s" % (self.offre_emploi, self.evaluateur) |
| 124 | |
| 125 | def delete(self): |
| 126 | candidats = Candidat.objects.filter(offre_emploi=self.offre_emploi) |
| 127 | for candidat in candidats: |
| 128 | CandidatEvaluation.objects.filter(candidat=candidat, evaluateur=self.evaluateur).delete() |
| 129 | |
| 130 | super(OffreEmploiEvaluateur, self).delete() |
| 131 | |
| 132 | |
| 133 | class CandidatEvaluation(models.Model): |
| 134 | candidat = models.ForeignKey(emploi.Candidat, db_column='candidat', |
| 135 | related_name='evaluations',) |
| 136 | evaluateur = models.ForeignKey(Evaluateur, db_column='evaluateur', |
| 137 | related_name='+', verbose_name=u'évaluateur') |
| 138 | note = models.IntegerField(choices=NOTES, blank=True, null=True) |
| 139 | commentaire = models.TextField(null=True, blank=True, default='Aucun') |
| 140 | date = models.DateField(auto_now_add=True,) |
| 141 | |
| 142 | class Meta: |
| 143 | verbose_name = u'évaluation du candidat' |
| 144 | verbose_name_plural = u'évaluations des candidats' |
| 145 | |
| 146 | def __unicode__(self): |
| 147 | return u"Évaluation de %s" % self.candidat |
| 148 | |
| 149 | def get_appreciation(self,): |
| 150 | if self.note is None: |
| 151 | return u"non disponible" |
| 152 | return u"%s %s" % (self.note, self.commentaire,) |
| 153 | |
| 154 | |
| 155 | class MesCandidatEvaluation(CandidatEvaluation): |
| 156 | |
| 157 | class Meta: |
| 158 | proxy = True |
| 159 | verbose_name = u"mon candidat à évaluer" |
| 160 | verbose_name_plural = u"mes candidats à évaluer" |
| 161 | |
| 162 | |
| 163 | #### TEMPLATE COURRIEL |
| 164 | TEMPLATE_CHOICES = ( |
| 165 | ('SEL', 'Sélectionné'), |
| 166 | ('REF', 'Refusé'), |
| 167 | ) |
| 168 | |
| 169 | |
| 170 | class CourrielTemplate(models.Model): |
| 171 | nom_modele = models.CharField(u'nom du modèle', max_length=100) |
| 172 | sujet = models.CharField(u'sujet du courriel', max_length=100) |
| 173 | plain_text = models.TextField(u'texte', help_text=HELP_TEXT_TAGS_ACCEPTES) |
| 174 | |
| 175 | def __unicode__(self): |
| 176 | return self.nom_modele |
| 177 | |
| 178 | class Meta: |
| 179 | ordering = ('nom_modele',) |
| 180 | verbose_name = u"modèle de courriel" |
| 181 | verbose_name_plural = u"modèles de courriel" |
| 182 | |
| 183 | |
| 184 | class CandidatCourriel(models.Model): |
| 185 | candidats = models.ManyToManyField(Candidat, verbose_name=u"candidats") |
| 186 | template = models.ForeignKey( |
| 187 | CourrielTemplate, db_column='template', related_name='+', |
| 188 | verbose_name=u"modèle de courriel" |
| 189 | ) |
| 190 | sujet = models.CharField( |
| 191 | max_length=255, blank=True, help_text=HELP_TEXT_TAGS_ACCEPTES |
| 192 | ) |
| 193 | plain_text = models.TextField( |
| 194 | u'texte', blank=True, help_text=HELP_TEXT_TAGS_ACCEPTES |
| 195 | ) |
| 196 | html = tinymce_models.HTMLField( |
| 197 | verbose_name=u'texte en HTML', null=True, blank=True, |
| 198 | help_text=HELP_TEXT_TAGS_ACCEPTES |
| 199 | ) |
| 200 | |
| 201 | def __unicode__(self): |
| 202 | return self.titre |
| 203 | |
| 204 | class Meta: |
| 205 | verbose_name = u"modèle de courriel" |
| 206 | verbose_name_plural = u"modèles de courriel" |