limiter la liste des postes à sa région / service
[auf_rh_dae.git] / project / rh_v1 / models.py
CommitLineData
a3121a38
AJ
1# -=- encoding: utf-8 -=-
2
6301bd59 3import datetime
a3121a38
AJ
4from django.db import models
5from datamaster_modeles.models import Pays, Implantation
6
7GENRE_CHOICES = (
139686f2
NC
8 ('m', 'Homme'),
9 ('f', 'Femme'),
a3121a38
AJ
10)
11SITUATION_CHOICES = (
12 ('C', 'Célibataire'),
13 ('F', 'Fiancé'),
14 ('M', 'Marié'),
15)
16
17class Employe(models.Model):
18 #Identification
19 id = models.IntegerField(primary_key=True)
20 nom = models.CharField(max_length=255)
21 prenom = models.CharField(max_length=255)
22 nationalite = models.ForeignKey('datamaster_modeles.Pays', to_field='code', related_name='nationalite', db_column='nationalite')
23 date_naissance = models.DateField(null=True, blank=True)
24 #Infos personnelles
25 genre = models.CharField(max_length=1, choices=GENRE_CHOICES, null=True, blank=True)
26 situation_famille = models.CharField(max_length=1, choices=SITUATION_CHOICES, null=True, blank=True)
27 date_entree = models.DateField(null=True, blank=True) #devrait pas être là
28 #Coordonnées
29 tel_domicile = models.CharField(max_length=255, null=True, blank=True)
30 tel_cellulaire = models.CharField(max_length=255, null=True, blank=True)
31 adresse = models.CharField(max_length=255, null=True, blank=True)
32 no_rue = models.CharField(max_length=255, null=True, blank=True)
33 ville = models.CharField(max_length=255, null=True, blank=True)
34 province = models.CharField(max_length=255, null=True, blank=True)
35 code_postal = models.CharField(max_length=255, null=True, blank=True)
36 pays = models.ForeignKey('datamaster_modeles.Pays', to_field='code', null=True, blank=True, related_name='pays', db_column='pays')
37 #Métas
38 date_creation = models.DateField(auto_now_add=True)
39 date_maj = models.DateField(auto_now=True)
40 commentaire = models.TextField(null=True, blank=True)
139686f2
NC
41
42 def __unicode__(self):
43 return u'%s %s' % (self.prenom, self.nom)
44
45
a3121a38
AJ
46TYPE_DOSSIER_CHOICES = (
47 ('2', 'Local'),
48 ('1', 'Expatrié'),
49)
50
1c7d67ce
OL
51class DossierManager(models.Manager):
52 """
53 Chargement de tous les objets FK existants sur chaque QuerySet.
54 """
55 def get_query_set(self):
56 fkeys = (
57 'employe',
58 'poste1',
59 'implantation1',
60 'poste2',
61 'implantation2',
62 'service',
63 'responsable',
64 'remplacement_de',
65 'statut',
66 'organisme_bstg',
67 'classement',
68 'type_contrat',
69 )
70 return super(DossierManager, self).get_query_set().select_related(*fkeys).all()
71
a3121a38
AJ
72class Dossier(models.Model):
73 #Identification
74 id = models.IntegerField(primary_key=True)
75 code = models.CharField(max_length=10, unique=True)
76 employe = models.ForeignKey('Employe', db_column='employe')
77 #Postes
78 poste1 = models.ForeignKey('Poste', db_column='poste1', related_name='poste1')
f48decfd 79 implantation1 = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation1', related_name='implantation1', blank=True, null=True)
a3121a38
AJ
80 complement1 = models.TextField(null=True, blank=True)
81 responsable_implantation1 = models.IntegerField()
82 poste2 = models.ForeignKey('Poste', db_column='poste2', related_name='poste2', blank=True, null=True)
f48decfd 83 implantation2 = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation2', related_name='implantation2', null=True, blank=True)
a3121a38
AJ
84 complement2 = models.TextField(null=True, blank=True)
85 responsable_implantation2 = models.IntegerField()
86 #Relations
f48decfd
NC
87 service = models.ForeignKey('Service', db_column='service', blank=True, null=True)
88 responsable = models.ForeignKey('Employe', db_column='responsable', related_name='responsable', blank=True, null=True)
89 remplacement_de = models.ForeignKey('Employe', db_column='remplacement_de', related_name='remplacement_de', blank=True, null=True)
a3121a38 90 type = models.CharField(max_length=1, choices=TYPE_DOSSIER_CHOICES)
f48decfd
NC
91 statut = models.ForeignKey('Statut', db_column='statut', blank=True, null=True)
92 organisme_bstg = models.ForeignKey('OrganismeBstg', db_column='organisme_bstg', blank=True, null=True)
a3121a38 93 #Rémunération
f48decfd 94 classement = models.ForeignKey('Classement', db_column='classement', blank=True, null=True)
a3121a38
AJ
95 regime_travail = models.IntegerField()
96 #Mandat
97 mandat_date_debut = models.DateField()
f48decfd 98 mandat_date_fin = models.DateField(null=True, blank=True)
a3121a38
AJ
99 #Contrat
100 contrat_date_debut = models.DateField()
101 contrat_date_fin = models.DateField()
f48decfd 102 type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', blank=True, null=True)
a3121a38
AJ
103 #Meta
104 date_creation = models.DateField(auto_now_add=True)
105 date_maj = models.DateField(auto_now=True)
106 commentaire = models.TextField(null=True, blank=True)
107
1c7d67ce
OL
108 # Managers
109 objects = DossierManager()
0f23302a 110
111 def __unicode__(self):
112 return u'%s : %s %s' % (self.employe, self.poste1, self.complement1)
1c7d67ce 113
7e43f9b6
OL
114 def get_salaire_display(self):
115 """
116 Moyen rapide de récupérer le salaire correspodant à un dossier. Par contre,
117 toutes les rémuérations n'ont pas de devise associées, c'est pourquoi on récupère
118 les anciennes rémunérations pour rechercher si elle existait auparavant.
119 """
120 remun = self.remuneration_set.all()
b1baa306
OL
121 if len(remun) == 0:
122 return ""
123
7e43f9b6
OL
124 devise = None
125 for r in remun:
126 try:
127 if r.devise_id is not None:
128 devise = Devise.objects.get(id=r.devise_id).code
129 except:
130 pass
62dbbb71
OL
131 return "%s %s" % (int(remun[0].montant), devise)
132
133 def get_salaire_euro_display(self):
134 """
135 Moyen rapide de récupérer le salaire correspodant à un dossier. Par contre,
136 toutes les rémuérations n'ont pas de devise associées, c'est pourquoi on récupère
137 les anciennes rémunérations pour rechercher si elle existait auparavant.
138 La valeur est est affichée en Euros en se servant du taux actuel.
139 """
140 remun = self.remuneration_set.all()
b1baa306
OL
141 if len(remun) == 0:
142 return ""
143
62dbbb71
OL
144 devise = None
145 montant_euros = 0
146 for r in remun:
147 try:
148 if r.devise_id is not None:
149 devise = Devise.objects.get(id=r.devise_id)
150 taux = TauxChange.objects.filter(devise=devise).order_by("annee")[0]
151 except:
152 pass
153 montant_euros = remun[0].montant * taux.taux
154 return "%s EUR" % (int(montant_euros))
7e43f9b6 155
a3121a38
AJ
156LIEN_PARENTE_CHOICES = (
157 ('Conjoint', 'Conjoint'),
158 ('Conjointe', 'Conjointe'),
159 ('Fille', 'Fille'),
160 ('Fils', 'Fils'),
161)
162
163class AyantDroit(models.Model):
164 #Identification
165 id = models.IntegerField(primary_key=True)
166 nom = models.CharField(max_length=255)
167 prenom = models.CharField(max_length=255)
168 #Relation
169 employe = models.ForeignKey('Employe', db_column='employe', related_name='employe')
170 lien_parente = models.CharField(max_length=10, choices=LIEN_PARENTE_CHOICES, null=True, blank=True)
171 #Méta
172 commentaire = models.TextField(null=True, blank=True)
173 actif = models.BooleanField()
174
175
176class Remuneration(models.Model):
177 #Identification
178 id = models.IntegerField(primary_key=True)
179 dossier = models.ForeignKey('Dossier', db_column='dossier')
180 type = models.ForeignKey('TypeRemuneration', db_column='type')
139686f2
NC
181 type_revalorisation = models.ForeignKey('TypeRevalorisation', db_column='type_revalorisation', null=True, blank=True)
182 montant = models.FloatField(null=True, blank=True)
183 devise = models.ForeignKey('Devise', to_field='code', db_column='devise', null=True, blank=True)
184 date_effective = models.DateField(null=True, blank=True)
185 pourcentage = models.IntegerField(null=True, blank=True)
a3121a38
AJ
186 #Méta
187 date_creation = models.DateField(auto_now_add=True)
139686f2
NC
188 user_creation = models.IntegerField(null=True, blank=True) #User ou employé
189 desactivation = models.NullBooleanField(null=True, blank=True) #
190 date_desactivation = models.DateField(null=True, blank=True)
191 user_desactivation = models.IntegerField(null=True, blank=True) #User ou employé
192 annulation = models.NullBooleanField(null=True, blank=True)
193 date_annulation = models.DateField(null=True, blank=True)
194 user_annulation = models.IntegerField(null=True, blank=True) #User ou employé
a3121a38 195
7e43f9b6
OL
196 def __unicode__(self):
197 try:
198 devise = self.devise.code
199 except:
200 devise = "???"
201 return "%s %s" % (self.montant, devise)
202
a3121a38
AJ
203class FamilleEmploi(models.Model):
204 #Identification
205 id = models.IntegerField(primary_key=True)
206 nom = models.CharField(max_length=255)
207 #Méta
208 actif = models.BooleanField()
209
210class TypePoste(models.Model):
211 #Identification
212 id = models.IntegerField(primary_key=True)
213 nom = models.CharField(max_length=255)
214 nom_feminin = models.CharField(max_length=255)
215 description = models.CharField(max_length=255)
216 is_responsable = models.BooleanField()
217 famille_emploi = models.ForeignKey('FamilleEmploi', db_column='famille_emploi')
218 #Méta
219 date_modification = models.DateField(auto_now=True)
220 actif = models.BooleanField()
221
5d680e84
NC
222 def __unicode__(self):
223 return u'%s' % self.nom
6d704629 224
225 class Meta:
226 ordering = ['nom']
5d680e84
NC
227
228
a3121a38
AJ
229TYPE_PAIEMENT_CHOICES = (
230 ('Régulier', 'Régulier'),
231 ('Ponctuel', 'Ponctuel'),
232)
233
234NATURE_REMUNERATION_CHOICES = (
235 ('Accessoire', 'Accessoire'),
236 ('Charges', 'Charges'),
237 ('Indemnité', 'Indemnité'),
238 ('RAS', 'RAS'),
239 ('Traitement', 'Traitement'),
240)
241
242class TypeRemuneration(models.Model):
243 #Identification
244 id = models.IntegerField(primary_key=True)
245 nom = models.CharField(max_length=255)
246 type_paiement = models.CharField(max_length=30, choices=TYPE_PAIEMENT_CHOICES)
247 nature_remuneration = models.CharField(max_length=30, choices=NATURE_REMUNERATION_CHOICES)
248 #Méta
249 actif = models.BooleanField()
cb1d62b5
NC
250
251 def __unicode__(self):
252 return u'%s' % self.nom
253
254
a3121a38
AJ
255class TypeRevalorisation(models.Model):
256 #Identification
257 id = models.IntegerField(primary_key=True)
258 nom = models.CharField(max_length=255)
259 #Méta
260 actif = models.BooleanField()
261
262PROPORTION_CHOICES = (
263 ('0.5', '0.5'),
264 ('1', '1'),
265)
266
1c7d67ce
OL
267class PosteManager(models.Manager):
268 """
269 Chargement de tous les objets FK existants sur chaque QuerySet.
270 """
271 def get_query_set(self):
272 fkeys = (
273 'implantation',
274 'type_poste',
275 )
276 return super(PosteManager, self).get_query_set().select_related(*fkeys).all()
277
a3121a38
AJ
278class Poste(models.Model):
279 #Identification
280 id = models.IntegerField(primary_key=True)
5d680e84
NC
281 implantation = models.ForeignKey('datamaster_modeles.Implantation',
282 db_column='implantation', related_name='+')
a3121a38
AJ
283 type_poste = models.ForeignKey('TypePoste', db_column='type_poste')
284 proportion = models.CharField(max_length=10, choices=PROPORTION_CHOICES)
285 #(sert à quoi?) renommer "regime_travail" ou autre? convertir data en % (data * 100; ex: 1 = 100%)
286 #Méta
287 date_modification = models.DateField(auto_now=True)
288 actif = models.BooleanField()
289
1c7d67ce
OL
290 # Managers
291 objects = PosteManager()
292
5d680e84 293 def __unicode__(self):
6d704629 294 return u'%s - %s [%s]' % (self.implantation, self.type_poste.nom, self.id)
5d680e84
NC
295
296
a3121a38
AJ
297class Service(models.Model):
298 #Identification
299 id = models.IntegerField(primary_key=True)
300 nom = models.CharField(max_length=255)
301 #Méta
302 actif = models.BooleanField()
303
5d680e84
NC
304 def __unicode__(self):
305 return u'%s' % self.nom
6d704629 306
307 class Meta:
308 ordering = ['nom']
5d680e84
NC
309
310
a3121a38
AJ
311TYPE_ORGANISME_CHOICES = (
312 ('MAD', 'Mise à disposition'),
313 ('DET', 'Détachement'),
314)
315
316class OrganismeBstg(models.Model):
317 #Identification
318 id = models.IntegerField(primary_key=True)
319 nom = models.CharField(max_length=255)
320 type = models.CharField(max_length=10, choices=TYPE_ORGANISME_CHOICES)
321 #Méta
322 actif = models.BooleanField()
323
139686f2
NC
324 def __unicode__(self):
325 return u'%s (%s)' % (self.nom, self.type)
326
0f23302a 327 class Meta:
328 ordering = ['type', 'nom']
329
139686f2 330
a3121a38
AJ
331CONTRAT_CATEGORIE_CHOICES= (
332 ('A', 'A'),
333 ('C', 'C'),
334)
335class Statut(models.Model):
336 #Identification
337 id = models.IntegerField(primary_key=True)
338 code = models.CharField(max_length=25, unique=True)
339 nom = models.CharField(max_length=255)
340 type_contrat_categorie = models.CharField(max_length=10, choices=CONTRAT_CATEGORIE_CHOICES)
341 #CHOICES A, C (veut dire quoi?) voir TypeContrat.categorie
342 #Méta
343 actif = models.BooleanField()
344
139686f2 345 def __unicode__(self):
0f23302a 346 return u'%s : %s' % (self.code, self.nom)
139686f2 347
a3121a38
AJ
348TYPE_CLASSEMENT_CHOICES = (
349 ('S', 'S'),
350 ('T', 'T'),
351)
352class Classement(models.Model):
353 #Identification
354 id = models.IntegerField(primary_key=True)
355 type = models.CharField(max_length=10, choices=TYPE_CLASSEMENT_CHOICES)
356 echelon = models.IntegerField()
357 degre = models.IntegerField()
358 coefficient = models.FloatField()
359 #Méta
360 commentaire = models.TextField(null=True, blank=True)
361 date_modification = models.DateField(auto_now=True)
362 actif = models.BooleanField()
363
5d680e84
NC
364 def __unicode__(self):
365 return u'%s.%s.%s (%s)' % (self.type, self.echelon, self.degre,
366 self.coefficient)
e57fb3d8 367 class Meta:
368 ordering = ['type','echelon','degre','coefficient']
5d680e84 369
6301bd59
OL
370class TauxChange(models.Model):
371 #Identification
372 id = models.IntegerField(primary_key=True)
373 devise = models.ForeignKey('Devise', db_column='devise')
374 annee = models.IntegerField()
375 taux = models.FloatField()
376 #Relations
377 implantation = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation')
378
379class ValeurPointManager(models.Manager):
380 """
381 Manager qui travaille uniquement sur les valeurs du point de l'année en cours.
382 """
383 mois = datetime.datetime.now().month
384 annee_courante = datetime.datetime.now().year
385
386 # Pour le mois de janvier et décembre on mets les 2 années pour faire la transition
387 if mois == 1:
388 filtre_annee = (annee_courante-1, annee_courante)
389 elif mois == 12:
390 filtre_annee = (annee_courante, annee_courante+1)
391 else:
392 filtre_annee = (annee_courante,)
393
394 def get_query_set(self):
395 return super(ValeurPointManager, self).get_query_set().select_related('implantation').filter(annee__in=self.filtre_annee)
396
5d680e84 397
a3121a38
AJ
398class ValeurPoint(models.Model):
399 #Identification
400 id = models.IntegerField(primary_key=True)
401 valeur = models.FloatField()
402 implantation = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation')
403 #Méta
404 annee = models.IntegerField()
6301bd59
OL
405
406 # Stockage de tous les taux de change pour optimiser la recherche de la devise associée
407 annee_courante = datetime.datetime.now().year
408 tauxchange = TauxChange.objects.select_related('devise').filter(annee=annee_courante)
409
410 def get_tauxchange_courant(self):
411 """
412 Recherche le taux courant associé à la valeur d'un point.
413 Tous les taux de l'année courante sont chargés, pour optimiser un affichage en liste.
414 (On pourrait probablement améliorer le manager pour lui greffer le taux courant sous forme de JOIN)
415 """
416 for tauxchange in self.tauxchange:
417 if tauxchange.implantation_id == self.implantation_id:
418 return tauxchange
419 return None
a3121a38 420
5d680e84 421 def __unicode__(self):
17353922
OL
422 tx = self.get_tauxchange_courant()
423 if tx:
424 devise_code = tx.devise.code
425 else:
426 devise_code = "??"
da3ca955 427 return u'%s %s (%s-%s)' % (self.valeur, devise_code, self.implantation_id, self.annee)
6d704629 428
429 class Meta:
430 ordering = ['valeur']
5d680e84 431
4dd75e7b 432 objects = models.Manager()
6301bd59 433 actuelles = ValeurPointManager()
a3121a38 434
5d680e84 435
a3121a38
AJ
436class Devise(models.Model):
437 id = models.IntegerField(primary_key=True)
438 code = models.CharField(max_length=10, unique=True)
439 nom = models.CharField(max_length=255)
440
5d680e84
NC
441 def __unicode__(self):
442 return u'%s - %s' % (self.code, self.nom)
443
444
a3121a38
AJ
445class TypeContrat(models.Model):
446 #Identification
447 id = models.IntegerField(primary_key=True)
448 nom = models.CharField(max_length=255)
449 nom_long = models.CharField(max_length=255) #description
450 categorie = models.CharField(max_length=10, choices=CONTRAT_CATEGORIE_CHOICES)
451 #Méta
452 actif = models.BooleanField()
453
139686f2 454 def __unicode__(self):
0f23302a 455 return u'%s' % (self.nom)