df59fcab |
1 | # -=- encoding: utf-8 -=- |
2 | |
3 | import datetime |
b235ec9d |
4 | from django.contrib.auth.models import User |
4418c732 |
5 | from django.core.files.storage import FileSystemStorage |
ec517164 |
6 | from tinymce import models as tinymce_models |
6f2d5d58 |
7 | from django.db import models |
4418c732 |
8 | import settings |
362a3534 |
9 | #from private_files import PrivateFileField |
6f2d5d58 |
10 | |
df59fcab |
11 | import datamaster_modeles.models as ref |
47cf4908 |
12 | from project.rh import models import Poste, |
df59fcab |
13 | |
596fe324 |
14 | ### CONSTANTES |
15 | #NOTES |
16 | NOTE_MIN = 1 |
17 | NOTE_RANGE = 1 |
e34a2ae0 |
18 | NOTE_MAX = 11 |
596fe324 |
19 | NOTES = [(i, i) for i in range(NOTE_MIN, NOTE_MAX, NOTE_RANGE)] |
ee42ad96 |
20 | HELP_TEXT_NB_DEPENDANT = "Le nombre de personnes à charge" |
596fe324 |
21 | |
df59fcab |
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 | |
4e8e178f |
34 | class OffreEmploiManager(models.Manager): |
35 | def get_query_set(self): |
61a4b478 |
36 | fkeys = ('region',) |
4e8e178f |
37 | return super(OffreEmploiManager, self).get_query_set().select_related(*fkeys).all() |
38 | |
47cf4908 |
39 | class ProxyPoste(Poste): |
4e8e178f |
40 | class Meta: |
41 | proxy = True |
42 | |
43 | def __unicode__(self): |
44 | return '%s [%s]' % (self.nom, self.id) |
df59fcab |
45 | |
46 | class OffreEmploi(Metadata): |
4e8e178f |
47 | objects = OffreEmploiManager() |
df59fcab |
48 | nom = models.CharField(max_length=255) |
b235ec9d |
49 | resume = models.TextField(verbose_name="Résumé") |
ec517164 |
50 | description = tinymce_models.HTMLField() |
51 | poste = models.ForeignKey(ProxyPoste, db_column='poste') |
df59fcab |
52 | date_limite = models.DateField(verbose_name="Date limite") |
b235ec9d |
53 | region = models.ForeignKey(ref.Region, db_column='region', |
54 | verbose_name="Région") |
55 | bureau = models.ForeignKey(ref.Bureau, db_column='bureau', ) |
ec517164 |
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") |
b235ec9d |
64 | |
65 | class Meta: |
66 | verbose_name_plural = "offres d'emploi" |
4418c732 |
67 | |
68 | def __unicode__(self): |
69 | return '%s [%s]' % (self.nom, self.id) |
df59fcab |
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 | |
b235ec9d |
92 | class Candidat(Metadata): |
8ea41642 |
93 | statut = models.CharField(max_length=4, choices=STATUT_CHOICES, |
94 | default='NOUV') |
df59fcab |
95 | offre_emploi = models.ForeignKey('OffreEmploi', db_column='offre_emploi', |
7f9e891e |
96 | related_name='+') |
3b4b948e |
97 | prenom = models.CharField(max_length=255, verbose_name='Prénom', ) |
df59fcab |
98 | nom = models.CharField(max_length=255) |
99 | genre = models.CharField(max_length=1, choices=GENRE_CHOICES) |
100 | nationalite = models.ForeignKey(ref.Pays, |
3b4b948e |
101 | db_column='nationalite', related_name='+', |
102 | verbose_name='Nationalité') |
ee42ad96 |
103 | date_naissance = models.DateField(verbose_name='Date de naissance') |
df59fcab |
104 | situation_famille = models.CharField(max_length=1, |
ec517164 |
105 | choices=SITUATION_CHOICES, |
106 | verbose_name='Situation familiale') |
ee42ad96 |
107 | nombre_dependant = models.IntegerField(verbose_name='Nombre de dépendant', |
108 | help_text=HELP_TEXT_NB_DEPENDANT) |
df59fcab |
109 | niveau_diplome = models.CharField(max_length=255, |
3b4b948e |
110 | verbose_name='Niveau du diplôme') |
df59fcab |
111 | employeur_actuel = models.CharField(max_length=255) |
112 | poste_actuel = models.CharField(max_length=255) |
113 | domaine_professionnel = models.CharField(max_length=255) |
ec517164 |
114 | telephone = models.CharField(max_length=255, verbose_name='Téléphone', ) |
115 | email = models.EmailField(max_length=255, verbose_name = 'Courriel', ) |
df59fcab |
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, |
4418c732 |
121 | verbose_name="État/Province") |
ec517164 |
122 | code_postal = models.CharField(max_length=255, blank=True) |
df59fcab |
123 | pays = models.ForeignKey(ref.Pays, db_column='pays', |
7f9e891e |
124 | related_name='+') |
4418c732 |
125 | |
126 | def __unicode__(self): |
127 | return '%s %s [%s]' % (self.prenom, self.nom, self.id) |
128 | |
129 | ### PIECE CANDIDAT |
ee42ad96 |
130 | |
131 | TYPE_PIECE_CHOICES = ( |
132 | ('CV','CV'), |
133 | ('LET','Lettre'), |
134 | ('AUT','Autre'), |
135 | ) |
4418c732 |
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', |
2b3edf33 |
148 | related_name='candidat_piece') |
ee42ad96 |
149 | nom = models.CharField(max_length=3, choices=TYPE_PIECE_CHOICES) |
362a3534 |
150 | #path = PrivateFileField("file", upload_to=candidat_piece_dispatch) |
f6749f29 |
151 | path = models.FileField(verbose_name="Fichier", |
152 | upload_to=candidat_piece_dispatch, |
2b3edf33 |
153 | storage=storage_prive, ) |
4418c732 |
154 | |
b235ec9d |
155 | class Meta: |
12767731 |
156 | verbose_name = "pièce jointe" |
157 | verbose_name_plural = "pièces jointes" |
b235ec9d |
158 | |
4418c732 |
159 | def __unicode__(self): |
160 | return '%s' % (self.nom) |
161 | |
f6749f29 |
162 | class UserProfile(models.Model): |
b235ec9d |
163 | user = models.ForeignKey("auth.User", unique=True, |
d835c9f3 |
164 | verbose_name="permission") |
cced6a23 |
165 | candidats = models.ManyToManyField(Candidat, verbose_name='candidats', |
2adf9e0c |
166 | blank=True, null=True,related_name="evaluateurs") |
3b4bfad3 |
167 | regions = models.ManyToManyField(ref.Region, |
168 | verbose_name="Régions", ) |
eb579d40 |
169 | |
b235ec9d |
170 | class Meta: |
cced6a23 |
171 | verbose_name = "évaluateur" |
b235ec9d |
172 | |
2adf9e0c |
173 | def __unicode__(self): |
174 | return '%s %s' % (self.user.first_name, self.user.last_name) |
175 | |
f6749f29 |
176 | UserProfile.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0]) |
4418c732 |
177 | |
178 | class CandidatEvaluation(models.Model): |
179 | candidat = models.ForeignKey(Candidat, db_column='candidat', |
3b4b948e |
180 | related_name='+',) |
f6749f29 |
181 | evaluateur = models.ForeignKey(UserProfile, db_column='evaluateur', |
cced6a23 |
182 | related_name='+', verbose_name='Évaluateur') |
596fe324 |
183 | note = models.IntegerField(choices=NOTES, blank=True, null=True) |
362a3534 |
184 | commentaire = models.TextField(null=True, blank=True) |
4418c732 |
185 | date = models.DateField(auto_now_add=True) |
b235ec9d |
186 | |
187 | class Meta: |
cced6a23 |
188 | verbose_name = 'évaluation du candidat' |
189 | verbose_name_plural = 'évaluations des candidats' |
ec517164 |
190 | |
d84c3a68 |
191 | ### TEMPLATE COURRIEL |
192 | TEMPLATE_CHOICES = ( |
193 | ('SEL', 'Sélectionné'), |
194 | ('REF', 'Refusé'), |
195 | ) |
196 | |
197 | class CourrielTemplate(models.Model): |
198 | template_name = models.CharField(max_length=100, ) |
199 | subject = models.CharField(max_length=100, ) |
200 | heading = models.CharField(max_length=100, ) |
201 | plain_text = models.TextField() |
47cf4908 |
202 | html = models.TextField() |
d84c3a68 |
203 | |
204 | def __unicode__(self): |
205 | return u'%s' % self.template_name |
206 | |
207 | class Meta: |
208 | ordering = ['template_name',] |
209 | |
210 | class CandidatCourriel(models.Model): |
ec517164 |
211 | candidat = models.ForeignKey(Candidat, db_column='candidat', |
d84c3a68 |
212 | related_name='+', ) |
213 | template = models.CharField(max_length=4, choices=TEMPLATE_CHOICES, |
214 | default='SEL', verbose_name="Modèle de courriel", ) |
ec517164 |
215 | titre = models.CharField(max_length=255, ) |
d84c3a68 |
216 | texte = models.TextField(null=True, blank=True, ) |
ec517164 |
217 | |
218 | def __unicode__(self): |
219 | return '%s' % (self.titre) |
ec517164 |
220 | |