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