| 1 | # -=- encoding: utf-8 -=- |
| 2 | |
| 3 | import datetime |
| 4 | from django.contrib.auth.models import User |
| 5 | from django.core.files.storage import FileSystemStorage |
| 6 | from tinymce import models as tinymce_models |
| 7 | from django.db import models |
| 8 | import settings |
| 9 | #from private_files import PrivateFileField |
| 10 | |
| 11 | import datamaster_modeles.models as ref |
| 12 | from project.rh.models import Poste |
| 13 | |
| 14 | ### CONSTANTES |
| 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 | HELP_TEXT_NB_DEPENDANT = "Le nombre de personnes à charge" |
| 21 | |
| 22 | # Abstracts |
| 23 | class Metadata(models.Model): |
| 24 | """Méta-données AUF. |
| 25 | Metadata.actif = flag remplaçant la suppression. |
| 26 | actif == False : objet réputé supprimé. |
| 27 | """ |
| 28 | actif = models.BooleanField(default=True) |
| 29 | date_creation = models.DateField(auto_now_add=True) |
| 30 | |
| 31 | class Meta: |
| 32 | abstract = True |
| 33 | |
| 34 | class OffreEmploiManager(models.Manager): |
| 35 | def get_query_set(self): |
| 36 | fkeys = ('region',) |
| 37 | return super(OffreEmploiManager, self).get_query_set().select_related(*fkeys).all() |
| 38 | |
| 39 | class ProxyPoste(Poste): |
| 40 | class Meta: |
| 41 | proxy = True |
| 42 | |
| 43 | def __unicode__(self): |
| 44 | return '%s [%s]' % (self.nom, self.id) |
| 45 | |
| 46 | class OffreEmploi(Metadata): |
| 47 | #objects = OffreEmploiManager() |
| 48 | nom = models.CharField(max_length=255) |
| 49 | resume = models.TextField(verbose_name="Résumé") |
| 50 | description = tinymce_models.HTMLField() |
| 51 | poste = models.ForeignKey(ProxyPoste, db_column='poste') |
| 52 | date_limite = models.DateField(verbose_name="Date limite") |
| 53 | region = models.ForeignKey(ref.Region, db_column='region', |
| 54 | verbose_name="Région") |
| 55 | bureau = models.ForeignKey(ref.Bureau, db_column='bureau', ) |
| 56 | duree_affectation = models.CharField(max_length=255, |
| 57 | verbose_name="Durée de l'affectation") |
| 58 | renumeration = models.CharField(max_length=255, |
| 59 | verbose_name='Rénumération') |
| 60 | debut_affectation = models.DateField(verbose_name="Début de l'affectation") |
| 61 | lieu_affectation = models.ForeignKey(ref.Implantation, |
| 62 | db_column='implantation', |
| 63 | verbose_name="Lieu d'affectation") |
| 64 | |
| 65 | class Meta: |
| 66 | verbose_name_plural = "offres d'emploi" |
| 67 | |
| 68 | def __unicode__(self): |
| 69 | return '%s [%s]' % (self.nom, self.id) |
| 70 | |
| 71 | |
| 72 | ### CANDIDAT |
| 73 | |
| 74 | GENRE_CHOICES = ( |
| 75 | ('M', 'Homme'), |
| 76 | ('F', 'Femme'), |
| 77 | ) |
| 78 | SITUATION_CHOICES = ( |
| 79 | ('C', 'Célibataire'), |
| 80 | ('F', 'Fiancé'), |
| 81 | ('M', 'Marié'), |
| 82 | ('D', 'Divorcé'), |
| 83 | ) |
| 84 | STATUT_CHOICES = ( |
| 85 | ('NOUV', 'Nouveau'), |
| 86 | ('REF', 'Refusé'), |
| 87 | ('SEL', 'Sélectionné'), |
| 88 | ('ACC', 'Accepté'), |
| 89 | ('REC', 'Recevable'), # Trouver une lettre plus appropriée? |
| 90 | ) |
| 91 | |
| 92 | class Candidat(Metadata): |
| 93 | statut = models.CharField(max_length=4, choices=STATUT_CHOICES, |
| 94 | default='NOUV') |
| 95 | offre_emploi = models.ForeignKey('OffreEmploi', db_column='offre_emploi', |
| 96 | related_name='+') |
| 97 | prenom = models.CharField(max_length=255, verbose_name='Prénom', ) |
| 98 | nom = models.CharField(max_length=255) |
| 99 | genre = models.CharField(max_length=1, choices=GENRE_CHOICES) |
| 100 | nationalite = models.ForeignKey(ref.Pays, |
| 101 | db_column='nationalite', related_name='+', |
| 102 | verbose_name='Nationalité') |
| 103 | date_naissance = models.DateField(verbose_name='Date de naissance') |
| 104 | situation_famille = models.CharField(max_length=1, |
| 105 | choices=SITUATION_CHOICES, |
| 106 | verbose_name='Situation familiale') |
| 107 | nombre_dependant = models.IntegerField(verbose_name='Nombre de dépendant', |
| 108 | help_text=HELP_TEXT_NB_DEPENDANT) |
| 109 | niveau_diplome = models.CharField(max_length=255, |
| 110 | verbose_name='Niveau du diplôme') |
| 111 | employeur_actuel = models.CharField(max_length=255) |
| 112 | poste_actuel = models.CharField(max_length=255) |
| 113 | domaine_professionnel = models.CharField(max_length=255) |
| 114 | telephone = models.CharField(max_length=255, verbose_name='Téléphone', ) |
| 115 | email = models.EmailField(max_length=255, verbose_name = 'Courriel', ) |
| 116 | |
| 117 | # Adresse |
| 118 | adresse = models.CharField(max_length=255) |
| 119 | ville = models.CharField(max_length=255) |
| 120 | etat_province = models.CharField(max_length=255, |
| 121 | verbose_name="État/Province") |
| 122 | code_postal = models.CharField(max_length=255, blank=True) |
| 123 | pays = models.ForeignKey(ref.Pays, db_column='pays', |
| 124 | related_name='+') |
| 125 | |
| 126 | def __unicode__(self): |
| 127 | return '%s %s [%s]' % (self.prenom, self.nom, self.id) |
| 128 | |
| 129 | ### PIECE CANDIDAT |
| 130 | |
| 131 | TYPE_PIECE_CHOICES = ( |
| 132 | ('CV','CV'), |
| 133 | ('LET','Lettre'), |
| 134 | ('AUT','Autre'), |
| 135 | ) |
| 136 | # Upload de fichiers |
| 137 | storage_prive = FileSystemStorage(settings.PRIVE_MEDIA_ROOT, |
| 138 | base_url=settings.PRIVE_MEDIA_URL) |
| 139 | |
| 140 | def candidat_piece_dispatch(instance, filename): |
| 141 | path = "offre_emploi/%s_%s/%s/%s_%s" % (instance.candidat.nom, |
| 142 | instance.candidat.prenom, instance.nom, instance.candidat.id, |
| 143 | filename) |
| 144 | return path |
| 145 | |
| 146 | class CandidatPiece(models.Model): |
| 147 | candidat = models.ForeignKey(Candidat, db_column='candidat', |
| 148 | related_name='candidat_piece') |
| 149 | nom = models.CharField(max_length=3, choices=TYPE_PIECE_CHOICES) |
| 150 | #path = PrivateFileField("file", upload_to=candidat_piece_dispatch) |
| 151 | path = models.FileField(verbose_name="Fichier", |
| 152 | upload_to=candidat_piece_dispatch, |
| 153 | storage=storage_prive, ) |
| 154 | |
| 155 | class Meta: |
| 156 | verbose_name = "pièce jointe" |
| 157 | verbose_name_plural = "pièces jointes" |
| 158 | |
| 159 | def __unicode__(self): |
| 160 | return '%s' % (self.nom) |
| 161 | |
| 162 | class Evaluateur(models.Model): |
| 163 | user = models.ForeignKey(User, unique=True, |
| 164 | verbose_name="permission") |
| 165 | candidats = models.ManyToManyField(Candidat, verbose_name='candidats', |
| 166 | blank=True, null=True,related_name="evaluateurs") |
| 167 | |
| 168 | class Meta: |
| 169 | verbose_name = "évaluateur" |
| 170 | |
| 171 | def __unicode__(self): |
| 172 | return '%s %s' % (self.user.first_name, self.user.last_name) |
| 173 | |
| 174 | class AdministrateurRegional(models.Model): |
| 175 | user = models.ForeignKey(User, unique=True, |
| 176 | verbose_name="permission") |
| 177 | regions = models.ManyToManyField(ref.Region, |
| 178 | verbose_name="Régions", ) |
| 179 | |
| 180 | class Meta: |
| 181 | verbose_name = "administrateur régional" |
| 182 | verbose_name_plural = "administrateurs régionaux" |
| 183 | |
| 184 | def __unicode__(self): |
| 185 | return '%s %s' % (self.user.first_name, self.user.last_name) |
| 186 | |
| 187 | |
| 188 | class CandidatEvaluation(models.Model): |
| 189 | candidat = models.ForeignKey(Candidat, db_column='candidat', |
| 190 | related_name='+',) |
| 191 | evaluateur = models.ForeignKey(Evaluateur, db_column='evaluateur', |
| 192 | related_name='+', verbose_name='Évaluateur') |
| 193 | note = models.IntegerField(choices=NOTES, blank=True, null=True) |
| 194 | commentaire = models.TextField(null=True, blank=True) |
| 195 | date = models.DateField(auto_now_add=True) |
| 196 | |
| 197 | class Meta: |
| 198 | verbose_name = 'évaluation du candidat' |
| 199 | verbose_name_plural = 'évaluations des candidats' |
| 200 | |
| 201 | #### TEMPLATE COURRIEL |
| 202 | TEMPLATE_CHOICES = ( |
| 203 | ('SEL', 'Sélectionné'), |
| 204 | ('REF', 'Refusé'), |
| 205 | ) |
| 206 | |
| 207 | class CourrielTemplate(models.Model): |
| 208 | nom_modele = models.CharField(max_length=100, verbose_name='Nom modèle', ) |
| 209 | sujet = models.CharField(max_length=100, ) |
| 210 | plain_text = models.TextField(verbose_name='Texte', ) |
| 211 | html = tinymce_models.HTMLField(verbose_name='Texte HTML', ) |
| 212 | |
| 213 | def __unicode__(self): |
| 214 | return u'%s' % self.nom_modele |
| 215 | |
| 216 | class Meta: |
| 217 | ordering = ['nom_modele',] |
| 218 | |
| 219 | class CandidatCourriel(models.Model): |
| 220 | candidat = models.ForeignKey(Candidat, db_column='candidat', |
| 221 | related_name='+', ) |
| 222 | template = models.ForeignKey(CourrielTemplate, db_column='nom', |
| 223 | related_name='+', verbose_name="Modèle de courriel", ) |
| 224 | titre = models.CharField(max_length=255, ) |
| 225 | texte = models.TextField(null=True, blank=True, ) |
| 226 | |
| 227 | def __unicode__(self): |
| 228 | return '%s' % (self.titre) |
| 229 | |