cafc9cd1e5c32d6adffdfb888fb66a1ace9d77a1
[auf_rh_dae.git] / project / 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
7 GENRE_CHOICES = (
8 ('m', 'Homme'),
9 ('f', 'Femme'),
10 )
11 SITUATION_CHOICES = (
12 ('C', 'Célibataire'),
13 ('F', 'Fiancé'),
14 ('M', 'Marié'),
15 )
16
17 class 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)
41
42 def __unicode__(self):
43 return u'%s %s' % (self.prenom, self.nom)
44
45
46 TYPE_DOSSIER_CHOICES = (
47 ('2', 'Local'),
48 ('1', 'Expatrié'),
49 )
50
51 class 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
72 class 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')
79 implantation1 = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation1', related_name='implantation1', blank=True, null=True)
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)
83 implantation2 = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation2', related_name='implantation2', null=True, blank=True)
84 complement2 = models.TextField(null=True, blank=True)
85 responsable_implantation2 = models.IntegerField()
86 #Relations
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)
90 type = models.CharField(max_length=1, choices=TYPE_DOSSIER_CHOICES)
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)
93 #Rémunération
94 classement = models.ForeignKey('Classement', db_column='classement', blank=True, null=True)
95 regime_travail = models.IntegerField()
96 #Mandat
97 mandat_date_debut = models.DateField()
98 mandat_date_fin = models.DateField(null=True, blank=True)
99 #Contrat
100 contrat_date_debut = models.DateField()
101 contrat_date_fin = models.DateField()
102 type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', blank=True, null=True)
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
108 # Managers
109 objects = DossierManager()
110
111 def __unicode__(self):
112 return u'%s : %s %s' % (self.employe, self.poste1, self.complement1)
113
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 if len(remun) == 0:
122 return ""
123
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
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()
141 if len(remun) == 0:
142 return ""
143
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))
155
156 LIEN_PARENTE_CHOICES = (
157 ('Conjoint', 'Conjoint'),
158 ('Conjointe', 'Conjointe'),
159 ('Fille', 'Fille'),
160 ('Fils', 'Fils'),
161 )
162
163 class 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
176 class 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')
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)
186 #Méta
187 date_creation = models.DateField(auto_now_add=True)
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é
195
196 def __unicode__(self):
197 try:
198 devise = self.devise.code
199 except:
200 devise = "???"
201 return "%s %s" % (self.montant, devise)
202
203 class 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
210 class 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
222 def __unicode__(self):
223 return u'%s' % self.nom
224
225 class Meta:
226 ordering = ['nom']
227
228
229 TYPE_PAIEMENT_CHOICES = (
230 ('Régulier', 'Régulier'),
231 ('Ponctuel', 'Ponctuel'),
232 )
233
234 NATURE_REMUNERATION_CHOICES = (
235 ('Accessoire', 'Accessoire'),
236 ('Charges', 'Charges'),
237 ('Indemnité', 'Indemnité'),
238 ('RAS', 'RAS'),
239 ('Traitement', 'Traitement'),
240 )
241
242 class 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()
250
251 def __unicode__(self):
252 return u'%s' % self.nom
253
254
255 class 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
262 PROPORTION_CHOICES = (
263 ('0.5', '0.5'),
264 ('1', '1'),
265 )
266
267 class 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
278 class Poste(models.Model):
279 #Identification
280 id = models.IntegerField(primary_key=True)
281 implantation = models.ForeignKey('datamaster_modeles.Implantation',
282 db_column='implantation', related_name='+')
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
290 # Managers
291 objects = PosteManager()
292
293 def __unicode__(self):
294 return u'%s - %s [%s]' % (self.implantation, self.type_poste.nom, self.id)
295
296
297 class 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
304 def __unicode__(self):
305 return u'%s' % self.nom
306
307 class Meta:
308 ordering = ['nom']
309
310
311 TYPE_ORGANISME_CHOICES = (
312 ('MAD', 'Mise à disposition'),
313 ('DET', 'Détachement'),
314 )
315
316 class 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
324 def __unicode__(self):
325 return u'%s (%s)' % (self.nom, self.type)
326
327 class Meta:
328 ordering = ['type', 'nom']
329
330
331 CONTRAT_CATEGORIE_CHOICES= (
332 ('A', 'A'),
333 ('C', 'C'),
334 )
335 class 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
345 def __unicode__(self):
346 return u'%s : %s' % (self.code, self.nom)
347
348 TYPE_CLASSEMENT_CHOICES = (
349 ('S', 'S'),
350 ('T', 'T'),
351 )
352 class 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
364 def __unicode__(self):
365 return u'%s.%s.%s (%s)' % (self.type, self.echelon, self.degre,
366 self.coefficient)
367 class Meta:
368 ordering = ['type','echelon','degre','coefficient']
369
370 class 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
379 class 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
397
398 class 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()
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
420
421 def __unicode__(self):
422 tx = self.get_tauxchange_courant()
423 if tx:
424 devise_code = tx.devise.code
425 else:
426 devise_code = "??"
427 return u'%s %s (%s-%s)' % (self.valeur, devise_code, self.implantation_id, self.annee)
428
429 class Meta:
430 ordering = ['valeur']
431
432 objects = models.Manager()
433 actuelles = ValeurPointManager()
434
435
436 class 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
441 def __unicode__(self):
442 return u'%s - %s' % (self.code, self.nom)
443
444
445 class 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
454 def __unicode__(self):
455 return u'%s' % (self.nom)