comparaison EUR
[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()
121 devise = None
122 for r in remun:
123 try:
124 if r.devise_id is not None:
125 devise = Devise.objects.get(id=r.devise_id).code
126 except:
127 pass
62dbbb71
OL
128 return "%s %s" % (int(remun[0].montant), devise)
129
130 def get_salaire_euro_display(self):
131 """
132 Moyen rapide de récupérer le salaire correspodant à un dossier. Par contre,
133 toutes les rémuérations n'ont pas de devise associées, c'est pourquoi on récupère
134 les anciennes rémunérations pour rechercher si elle existait auparavant.
135 La valeur est est affichée en Euros en se servant du taux actuel.
136 """
137 remun = self.remuneration_set.all()
138 devise = None
139 montant_euros = 0
140 for r in remun:
141 try:
142 if r.devise_id is not None:
143 devise = Devise.objects.get(id=r.devise_id)
144 taux = TauxChange.objects.filter(devise=devise).order_by("annee")[0]
145 except:
146 pass
147 montant_euros = remun[0].montant * taux.taux
148 return "%s EUR" % (int(montant_euros))
7e43f9b6 149
a3121a38
AJ
150LIEN_PARENTE_CHOICES = (
151 ('Conjoint', 'Conjoint'),
152 ('Conjointe', 'Conjointe'),
153 ('Fille', 'Fille'),
154 ('Fils', 'Fils'),
155)
156
157class AyantDroit(models.Model):
158 #Identification
159 id = models.IntegerField(primary_key=True)
160 nom = models.CharField(max_length=255)
161 prenom = models.CharField(max_length=255)
162 #Relation
163 employe = models.ForeignKey('Employe', db_column='employe', related_name='employe')
164 lien_parente = models.CharField(max_length=10, choices=LIEN_PARENTE_CHOICES, null=True, blank=True)
165 #Méta
166 commentaire = models.TextField(null=True, blank=True)
167 actif = models.BooleanField()
168
169
170class Remuneration(models.Model):
171 #Identification
172 id = models.IntegerField(primary_key=True)
173 dossier = models.ForeignKey('Dossier', db_column='dossier')
174 type = models.ForeignKey('TypeRemuneration', db_column='type')
139686f2
NC
175 type_revalorisation = models.ForeignKey('TypeRevalorisation', db_column='type_revalorisation', null=True, blank=True)
176 montant = models.FloatField(null=True, blank=True)
177 devise = models.ForeignKey('Devise', to_field='code', db_column='devise', null=True, blank=True)
178 date_effective = models.DateField(null=True, blank=True)
179 pourcentage = models.IntegerField(null=True, blank=True)
a3121a38
AJ
180 #Méta
181 date_creation = models.DateField(auto_now_add=True)
139686f2
NC
182 user_creation = models.IntegerField(null=True, blank=True) #User ou employé
183 desactivation = models.NullBooleanField(null=True, blank=True) #
184 date_desactivation = models.DateField(null=True, blank=True)
185 user_desactivation = models.IntegerField(null=True, blank=True) #User ou employé
186 annulation = models.NullBooleanField(null=True, blank=True)
187 date_annulation = models.DateField(null=True, blank=True)
188 user_annulation = models.IntegerField(null=True, blank=True) #User ou employé
a3121a38 189
7e43f9b6
OL
190 def __unicode__(self):
191 try:
192 devise = self.devise.code
193 except:
194 devise = "???"
195 return "%s %s" % (self.montant, devise)
196
a3121a38
AJ
197class FamilleEmploi(models.Model):
198 #Identification
199 id = models.IntegerField(primary_key=True)
200 nom = models.CharField(max_length=255)
201 #Méta
202 actif = models.BooleanField()
203
204class TypePoste(models.Model):
205 #Identification
206 id = models.IntegerField(primary_key=True)
207 nom = models.CharField(max_length=255)
208 nom_feminin = models.CharField(max_length=255)
209 description = models.CharField(max_length=255)
210 is_responsable = models.BooleanField()
211 famille_emploi = models.ForeignKey('FamilleEmploi', db_column='famille_emploi')
212 #Méta
213 date_modification = models.DateField(auto_now=True)
214 actif = models.BooleanField()
215
5d680e84
NC
216 def __unicode__(self):
217 return u'%s' % self.nom
6d704629 218
219 class Meta:
220 ordering = ['nom']
5d680e84
NC
221
222
a3121a38
AJ
223TYPE_PAIEMENT_CHOICES = (
224 ('Régulier', 'Régulier'),
225 ('Ponctuel', 'Ponctuel'),
226)
227
228NATURE_REMUNERATION_CHOICES = (
229 ('Accessoire', 'Accessoire'),
230 ('Charges', 'Charges'),
231 ('Indemnité', 'Indemnité'),
232 ('RAS', 'RAS'),
233 ('Traitement', 'Traitement'),
234)
235
236class TypeRemuneration(models.Model):
237 #Identification
238 id = models.IntegerField(primary_key=True)
239 nom = models.CharField(max_length=255)
240 type_paiement = models.CharField(max_length=30, choices=TYPE_PAIEMENT_CHOICES)
241 nature_remuneration = models.CharField(max_length=30, choices=NATURE_REMUNERATION_CHOICES)
242 #Méta
243 actif = models.BooleanField()
cb1d62b5
NC
244
245 def __unicode__(self):
246 return u'%s' % self.nom
247
248
a3121a38
AJ
249class TypeRevalorisation(models.Model):
250 #Identification
251 id = models.IntegerField(primary_key=True)
252 nom = models.CharField(max_length=255)
253 #Méta
254 actif = models.BooleanField()
255
256PROPORTION_CHOICES = (
257 ('0.5', '0.5'),
258 ('1', '1'),
259)
260
1c7d67ce
OL
261class PosteManager(models.Manager):
262 """
263 Chargement de tous les objets FK existants sur chaque QuerySet.
264 """
265 def get_query_set(self):
266 fkeys = (
267 'implantation',
268 'type_poste',
269 )
270 return super(PosteManager, self).get_query_set().select_related(*fkeys).all()
271
a3121a38
AJ
272class Poste(models.Model):
273 #Identification
274 id = models.IntegerField(primary_key=True)
5d680e84
NC
275 implantation = models.ForeignKey('datamaster_modeles.Implantation',
276 db_column='implantation', related_name='+')
a3121a38
AJ
277 type_poste = models.ForeignKey('TypePoste', db_column='type_poste')
278 proportion = models.CharField(max_length=10, choices=PROPORTION_CHOICES)
279 #(sert à quoi?) renommer "regime_travail" ou autre? convertir data en % (data * 100; ex: 1 = 100%)
280 #Méta
281 date_modification = models.DateField(auto_now=True)
282 actif = models.BooleanField()
283
1c7d67ce
OL
284 # Managers
285 objects = PosteManager()
286
5d680e84 287 def __unicode__(self):
6d704629 288 return u'%s - %s [%s]' % (self.implantation, self.type_poste.nom, self.id)
5d680e84
NC
289
290
a3121a38
AJ
291class Service(models.Model):
292 #Identification
293 id = models.IntegerField(primary_key=True)
294 nom = models.CharField(max_length=255)
295 #Méta
296 actif = models.BooleanField()
297
5d680e84
NC
298 def __unicode__(self):
299 return u'%s' % self.nom
6d704629 300
301 class Meta:
302 ordering = ['nom']
5d680e84
NC
303
304
a3121a38
AJ
305TYPE_ORGANISME_CHOICES = (
306 ('MAD', 'Mise à disposition'),
307 ('DET', 'Détachement'),
308)
309
310class OrganismeBstg(models.Model):
311 #Identification
312 id = models.IntegerField(primary_key=True)
313 nom = models.CharField(max_length=255)
314 type = models.CharField(max_length=10, choices=TYPE_ORGANISME_CHOICES)
315 #Méta
316 actif = models.BooleanField()
317
139686f2
NC
318 def __unicode__(self):
319 return u'%s (%s)' % (self.nom, self.type)
320
0f23302a 321 class Meta:
322 ordering = ['type', 'nom']
323
139686f2 324
a3121a38
AJ
325CONTRAT_CATEGORIE_CHOICES= (
326 ('A', 'A'),
327 ('C', 'C'),
328)
329class Statut(models.Model):
330 #Identification
331 id = models.IntegerField(primary_key=True)
332 code = models.CharField(max_length=25, unique=True)
333 nom = models.CharField(max_length=255)
334 type_contrat_categorie = models.CharField(max_length=10, choices=CONTRAT_CATEGORIE_CHOICES)
335 #CHOICES A, C (veut dire quoi?) voir TypeContrat.categorie
336 #Méta
337 actif = models.BooleanField()
338
139686f2 339 def __unicode__(self):
0f23302a 340 return u'%s : %s' % (self.code, self.nom)
139686f2 341
a3121a38
AJ
342TYPE_CLASSEMENT_CHOICES = (
343 ('S', 'S'),
344 ('T', 'T'),
345)
346class Classement(models.Model):
347 #Identification
348 id = models.IntegerField(primary_key=True)
349 type = models.CharField(max_length=10, choices=TYPE_CLASSEMENT_CHOICES)
350 echelon = models.IntegerField()
351 degre = models.IntegerField()
352 coefficient = models.FloatField()
353 #Méta
354 commentaire = models.TextField(null=True, blank=True)
355 date_modification = models.DateField(auto_now=True)
356 actif = models.BooleanField()
357
5d680e84
NC
358 def __unicode__(self):
359 return u'%s.%s.%s (%s)' % (self.type, self.echelon, self.degre,
360 self.coefficient)
e57fb3d8 361 class Meta:
362 ordering = ['type','echelon','degre','coefficient']
5d680e84 363
6301bd59
OL
364class TauxChange(models.Model):
365 #Identification
366 id = models.IntegerField(primary_key=True)
367 devise = models.ForeignKey('Devise', db_column='devise')
368 annee = models.IntegerField()
369 taux = models.FloatField()
370 #Relations
371 implantation = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation')
372
373class ValeurPointManager(models.Manager):
374 """
375 Manager qui travaille uniquement sur les valeurs du point de l'année en cours.
376 """
377 mois = datetime.datetime.now().month
378 annee_courante = datetime.datetime.now().year
379
380 # Pour le mois de janvier et décembre on mets les 2 années pour faire la transition
381 if mois == 1:
382 filtre_annee = (annee_courante-1, annee_courante)
383 elif mois == 12:
384 filtre_annee = (annee_courante, annee_courante+1)
385 else:
386 filtre_annee = (annee_courante,)
387
388 def get_query_set(self):
389 return super(ValeurPointManager, self).get_query_set().select_related('implantation').filter(annee__in=self.filtre_annee)
390
5d680e84 391
a3121a38
AJ
392class ValeurPoint(models.Model):
393 #Identification
394 id = models.IntegerField(primary_key=True)
395 valeur = models.FloatField()
396 implantation = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation')
397 #Méta
398 annee = models.IntegerField()
6301bd59
OL
399
400 # Stockage de tous les taux de change pour optimiser la recherche de la devise associée
401 annee_courante = datetime.datetime.now().year
402 tauxchange = TauxChange.objects.select_related('devise').filter(annee=annee_courante)
403
404 def get_tauxchange_courant(self):
405 """
406 Recherche le taux courant associé à la valeur d'un point.
407 Tous les taux de l'année courante sont chargés, pour optimiser un affichage en liste.
408 (On pourrait probablement améliorer le manager pour lui greffer le taux courant sous forme de JOIN)
409 """
410 for tauxchange in self.tauxchange:
411 if tauxchange.implantation_id == self.implantation_id:
412 return tauxchange
413 return None
a3121a38 414
5d680e84 415 def __unicode__(self):
17353922
OL
416 tx = self.get_tauxchange_courant()
417 if tx:
418 devise_code = tx.devise.code
419 else:
420 devise_code = "??"
da3ca955 421 return u'%s %s (%s-%s)' % (self.valeur, devise_code, self.implantation_id, self.annee)
6d704629 422
423 class Meta:
424 ordering = ['valeur']
5d680e84 425
4dd75e7b 426 objects = models.Manager()
6301bd59 427 actuelles = ValeurPointManager()
a3121a38 428
5d680e84 429
a3121a38
AJ
430class Devise(models.Model):
431 id = models.IntegerField(primary_key=True)
432 code = models.CharField(max_length=10, unique=True)
433 nom = models.CharField(max_length=255)
434
5d680e84
NC
435 def __unicode__(self):
436 return u'%s - %s' % (self.code, self.nom)
437
438
a3121a38
AJ
439class TypeContrat(models.Model):
440 #Identification
441 id = models.IntegerField(primary_key=True)
442 nom = models.CharField(max_length=255)
443 nom_long = models.CharField(max_length=255) #description
444 categorie = models.CharField(max_length=10, choices=CONTRAT_CATEGORIE_CHOICES)
445 #Méta
446 actif = models.BooleanField()
447
139686f2 448 def __unicode__(self):
0f23302a 449 return u'%s' % (self.nom)