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