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