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