1 # -=- encoding: utf-8 -=-
4 from django
.db
import models
5 from datamaster_modeles
.models
import Pays
, Implantation
6 from dae
.managers
import SecurityManager
18 class Employe(models
.Model
):
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',
24 related_name
='nationalite',
25 db_column
='nationalite')
26 date_naissance
= models
.DateField(null
=True, blank
=True)
28 genre
= models
.CharField(max_length
=1, null
=True, blank
=True,
29 choices
=GENRE_CHOICES
)
30 situation_famille
= models
.CharField(max_length
=1, null
=True, blank
=True,
31 choices
=SITUATION_CHOICES
)
32 date_entree
= models
.DateField(null
=True, blank
=True) #devrait pas être là
34 tel_domicile
= models
.CharField(max_length
=255, null
=True, blank
=True)
35 tel_cellulaire
= models
.CharField(max_length
=255, null
=True, blank
=True)
36 adresse
= models
.CharField(max_length
=255, null
=True, blank
=True)
37 no_rue
= models
.CharField(max_length
=255, null
=True, blank
=True)
38 ville
= models
.CharField(max_length
=255, null
=True, blank
=True)
39 province
= models
.CharField(max_length
=255, null
=True, blank
=True)
40 code_postal
= models
.CharField(max_length
=255, null
=True, blank
=True)
41 pays
= models
.ForeignKey('datamaster_modeles.Pays', to_field
='code',
42 null
=True, blank
=True,
43 related_name
='pays', db_column
='pays')
45 date_creation
= models
.DateField(auto_now_add
=True)
46 date_maj
= models
.DateField(auto_now
=True)
47 commentaire
= models
.TextField(null
=True, blank
=True)
49 def __unicode__(self
):
50 return u
'%s %s' % (self
.prenom
, self
.nom
)
53 TYPE_DOSSIER_CHOICES
= (
58 class DossierManager(models
.Manager
):
60 Chargement de tous les objets FK existants sur chaque QuerySet.
62 prefixe_service
= "poste1__service"
63 prefixe_implantation
= "poste1__implantation__region"
65 def get_query_set(self
):
80 return super(DossierManager
, self
).get_query_set().select_related(*fkeys
).all()
82 class Dossier(models
.Model
):
84 id = models
.IntegerField(primary_key
=True)
85 code
= models
.CharField(max_length
=10, unique
=True)
86 employe
= models
.ForeignKey('Employe', db_column
='employe')
88 poste1
= models
.ForeignKey('Poste', db_column
='poste1',
89 related_name
='poste1')
90 implantation1
= models
.ForeignKey('datamaster_modeles.Implantation',
91 db_column
='implantation1',
92 related_name
='implantation1',
93 blank
=True, null
=True)
94 complement1
= models
.TextField(null
=True, blank
=True)
95 responsable_implantation1
= models
.IntegerField()
96 poste2
= models
.ForeignKey('Poste', db_column
='poste2',
97 related_name
='poste2',
98 blank
=True, null
=True)
99 implantation2
= models
.ForeignKey('datamaster_modeles.Implantation',
100 db_column
='implantation2',
101 related_name
='implantation2',
102 null
=True, blank
=True)
103 complement2
= models
.TextField(null
=True, blank
=True)
104 responsable_implantation2
= models
.IntegerField()
106 service
= models
.ForeignKey('Service', db_column
='service',
107 blank
=True, null
=True)
108 responsable
= models
.ForeignKey('Employe', db_column
='responsable',
109 related_name
='responsable',
110 blank
=True, null
=True)
111 remplacement_de
= models
.ForeignKey('Employe', db_column
='remplacement_de',
112 related_name
='remplacement_de',
113 blank
=True, null
=True)
114 type = models
.CharField(max_length
=1, choices
=TYPE_DOSSIER_CHOICES
)
115 statut
= models
.ForeignKey('Statut', db_column
='statut',
116 blank
=True, null
=True)
117 organisme_bstg
= models
.ForeignKey('OrganismeBstg',
118 db_column
='organisme_bstg',
119 blank
=True, null
=True)
121 classement
= models
.ForeignKey('Classement', db_column
='classement',
122 blank
=True, null
=True)
123 regime_travail
= models
.IntegerField()
125 mandat_date_debut
= models
.DateField()
126 mandat_date_fin
= models
.DateField(null
=True, blank
=True)
128 contrat_date_debut
= models
.DateField()
129 contrat_date_fin
= models
.DateField()
130 type_contrat
= models
.ForeignKey('TypeContrat', db_column
='type_contrat',
131 blank
=True, null
=True)
133 date_creation
= models
.DateField(auto_now_add
=True)
134 date_maj
= models
.DateField(auto_now
=True)
135 commentaire
= models
.TextField(null
=True, blank
=True)
138 objects
= DossierManager()
140 def __unicode__(self
):
141 return u
'%s : %s %s' % (self
.employe
, self
.poste1
, self
.complement1
)
143 def get_dernier_salaire_remun(self
):
144 remun
= [r
for r
in self
.remuneration_set
.all().order_by('-id') if r
.type_id
== 1] # type salaire de base
150 def get_salaire(self
):
151 remun
= self
.get_dernier_salaire_remun()
152 if remun
is not None:
153 return int(remun
.montant
)
157 def get_salaire_display(self
):
159 Moyen rapide de récupérer le salaire correspodant à un dossier. Par contre,
160 toutes les rémuérations n'ont pas de devise associées, c'est pourquoi on récupère
161 les anciennes rémunérations pour rechercher si elle existait auparavant.
163 if self
.dernier_salaire_remun() is not None:
164 devise_code
= self
.dernier_salaire_remun().devise
.code
167 return "%s %s" % (self
.get_salaire(), devise_code
, )
169 def get_salaire_euro_display(self
):
171 Moyen rapide de récupérer le salaire correspodant à un dossier. Par contre,
172 toutes les rémuérations n'ont pas de devise associées, c'est pourquoi on récupère
173 les anciennes rémunérations pour rechercher si elle existait auparavant.
174 La valeur est est affichée en Euros en se servant du taux actuel.
176 return "%s EUR" % (self
.get_dernier_salaire_remun().en_euros())
178 LIEN_PARENTE_CHOICES
= (
179 ('Conjoint', 'Conjoint'),
180 ('Conjointe', 'Conjointe'),
185 class AyantDroit(models
.Model
):
187 id = models
.IntegerField(primary_key
=True)
188 nom
= models
.CharField(max_length
=255)
189 prenom
= models
.CharField(max_length
=255)
191 employe
= models
.ForeignKey('Employe', db_column
='employe',
192 related_name
='employe')
193 lien_parente
= models
.CharField(max_length
=10, null
=True, blank
=True,
194 choices
=LIEN_PARENTE_CHOICES
)
196 commentaire
= models
.TextField(null
=True, blank
=True)
197 actif
= models
.BooleanField()
200 class Remuneration(models
.Model
):
202 id = models
.IntegerField(primary_key
=True)
203 dossier
= models
.ForeignKey('Dossier', db_column
='dossier')
204 type = models
.ForeignKey('TypeRemuneration', db_column
='type')
205 type_revalorisation
= models
.ForeignKey('TypeRevalorisation',
206 db_column
='type_revalorisation',
207 null
=True, blank
=True)
208 montant
= models
.FloatField(null
=True, blank
=True)
209 devise
= models
.ForeignKey('Devise', to_field
='id', db_column
='devise', null
=True, blank
=True)
210 date_effective
= models
.DateField(null
=True, blank
=True)
211 pourcentage
= models
.IntegerField(null
=True, blank
=True)
213 date_creation
= models
.DateField(auto_now_add
=True)
214 user_creation
= models
.IntegerField(null
=True, blank
=True) #User ou employé
215 desactivation
= models
.NullBooleanField(null
=True, blank
=True) #
216 date_desactivation
= models
.DateField(null
=True, blank
=True)
217 user_desactivation
= models
.IntegerField(null
=True, blank
=True) #User ou employé
218 annulation
= models
.NullBooleanField(null
=True, blank
=True)
219 date_annulation
= models
.DateField(null
=True, blank
=True)
220 user_annulation
= models
.IntegerField(null
=True, blank
=True) #User ou employé
222 def __unicode__(self
):
224 devise
= self
.devise
.code
227 return "%s %s (%s EUR - %s)" % (self
.montant
, devise
, self
.en_euros(), self
.get_taux_historique(), )
229 def get_taux_historique(self
):
231 Retourne le taux en vigueur durant l'année considérée. Un taux de 0 est crée, si le taux de change
234 taux
= TauxChange
.objects
.filter(devise
=self
.devise
, annee
=self
.date_creation
.year
)
241 tauxchange
= self
.get_taux_historique()
242 if tauxchange
is not None:
243 return int(self
.montant
* tauxchange
.taux
)
247 class FamilleEmploi(models
.Model
):
249 id = models
.IntegerField(primary_key
=True)
250 nom
= models
.CharField(max_length
=255)
252 actif
= models
.BooleanField()
254 class TypePoste(models
.Model
):
256 id = models
.IntegerField(primary_key
=True)
257 nom
= models
.CharField(max_length
=255)
258 nom_feminin
= models
.CharField(max_length
=255)
259 description
= models
.CharField(max_length
=255)
260 is_responsable
= models
.BooleanField()
261 famille_emploi
= models
.ForeignKey('FamilleEmploi',
262 db_column
='famille_emploi')
264 date_modification
= models
.DateField(auto_now
=True)
265 actif
= models
.BooleanField()
267 def __unicode__(self
):
268 return u
'%s' % self
.nom
274 TYPE_PAIEMENT_CHOICES
= (
275 ('Régulier', 'Régulier'),
276 ('Ponctuel', 'Ponctuel'),
279 NATURE_REMUNERATION_CHOICES
= (
280 ('Accessoire', 'Accessoire'),
281 ('Charges', 'Charges'),
282 ('Indemnité', 'Indemnité'),
284 ('Traitement', 'Traitement'),
287 class TypeRemuneration(models
.Model
):
289 id = models
.IntegerField(primary_key
=True)
290 nom
= models
.CharField(max_length
=255)
291 type_paiement
= models
.CharField(max_length
=30,
292 choices
=TYPE_PAIEMENT_CHOICES
)
293 nature_remuneration
= models
.CharField(max_length
=30,
294 choices
=NATURE_REMUNERATION_CHOICES
)
296 actif
= models
.BooleanField()
298 def __unicode__(self
):
299 return u
'%s' % self
.nom
302 class TypeRevalorisation(models
.Model
):
304 id = models
.IntegerField(primary_key
=True)
305 nom
= models
.CharField(max_length
=255)
307 actif
= models
.BooleanField()
309 PROPORTION_CHOICES
= (
314 class PosteManager(SecurityManager
):
316 Chargement de tous les objets FK existants sur chaque QuerySet.
318 prefixe_implantation
= "implantation__region"
320 def get_query_set(self
):
325 return super(PosteManager
, self
).get_query_set().select_related(*fkeys
).all()
327 class Poste(models
.Model
):
329 id = models
.IntegerField(primary_key
=True)
330 implantation
= models
.ForeignKey('datamaster_modeles.Implantation',
331 db_column
='implantation', related_name
='+')
332 type_poste
= models
.ForeignKey('TypePoste', db_column
='type_poste')
333 proportion
= models
.CharField(max_length
=10, choices
=PROPORTION_CHOICES
)
334 #(sert à quoi?) renommer "regime_travail" ou autre? convertir data en % (data * 100; ex: 1 = 100%)
336 date_modification
= models
.DateField(auto_now
=True)
337 actif
= models
.BooleanField()
340 objects
= PosteManager()
342 def __unicode__(self
):
343 return u
'%s - %s [%s]' % (self
.implantation
, self
.type_poste
.nom
,
347 class Service(models
.Model
):
349 id = models
.IntegerField(primary_key
=True)
350 nom
= models
.CharField(max_length
=255)
352 actif
= models
.BooleanField()
354 def __unicode__(self
):
355 return u
'%s' % self
.nom
361 TYPE_ORGANISME_CHOICES
= (
362 ('MAD', 'Mise à disposition'),
363 ('DET', 'Détachement'),
366 class OrganismeBstg(models
.Model
):
368 id = models
.IntegerField(primary_key
=True)
369 nom
= models
.CharField(max_length
=255)
370 type = models
.CharField(max_length
=10, choices
=TYPE_ORGANISME_CHOICES
)
372 actif
= models
.BooleanField()
374 def __unicode__(self
):
375 return u
'%s (%s)' % (self
.nom
, self
.type)
378 ordering
= ['type', 'nom']
381 CONTRAT_CATEGORIE_CHOICES
= (
385 class Statut(models
.Model
):
387 id = models
.IntegerField(primary_key
=True)
388 code
= models
.CharField(max_length
=25, unique
=True)
389 nom
= models
.CharField(max_length
=255)
390 type_contrat_categorie
= models
.CharField(max_length
=10,
391 choices
=CONTRAT_CATEGORIE_CHOICES
)
392 #CHOICES A, C (veut dire quoi?) voir TypeContrat.categorie
394 actif
= models
.BooleanField()
396 def __unicode__(self
):
397 return u
'%s : %s' % (self
.code
, self
.nom
)
399 TYPE_CLASSEMENT_CHOICES
= (
404 class ClassementManager(models
.Manager
):
406 Ordonner les spcéfiquement les classements.
408 def get_query_set(self
):
409 qs
= super(self
.__class__
, self
).get_query_set()
410 qs
= qs
.extra(select
={'ponderation': 'FIND_IN_SET(type,"SO,HG,S,T,P,C,D")'})
411 qs
= qs
.extra(order_by
=('ponderation', ))
415 class Classement(models
.Model
):
417 id = models
.IntegerField(primary_key
=True)
418 type = models
.CharField(max_length
=10, choices
=TYPE_CLASSEMENT_CHOICES
)
419 echelon
= models
.IntegerField()
420 degre
= models
.IntegerField()
421 coefficient
= models
.FloatField()
423 commentaire
= models
.TextField(null
=True, blank
=True)
424 date_modification
= models
.DateField(auto_now
=True)
425 actif
= models
.BooleanField()
428 objects
= ClassementManager()
430 def __unicode__(self
):
431 return u
'%s.%s.%s' % (self
.type, self
.echelon
, self
.degre
)
434 ordering
= ['type','echelon','degre','coefficient']
436 class TauxChange(models
.Model
):
438 id = models
.IntegerField(primary_key
=True)
439 devise
= models
.ForeignKey('Devise', to_field
='id', db_column
='devise')
440 annee
= models
.IntegerField()
441 taux
= models
.FloatField()
443 implantation
= models
.ForeignKey('datamaster_modeles.Implantation',
444 db_column
='implantation',
445 related_name
='taux_change')
447 def __unicode__(self
):
448 return u
"%s %s : %s" % (self
.devise
, self
.annee
, self
.taux
)
450 class ValeurPointManager(models
.Manager
):
452 Manager qui travaille uniquement sur les valeurs du point de l'année en cours.
454 mois
= datetime
.datetime
.now().month
455 annee_courante
= datetime
.datetime
.now().year
457 # Pour le mois de janvier et décembre on mets les 2 années pour faire la transition
459 filtre_annee
= (annee_courante
-1, annee_courante
)
461 filtre_annee
= (annee_courante
, annee_courante
+1)
463 filtre_annee
= (annee_courante
,)
465 def get_query_set(self
):
466 return super(ValeurPointManager
, self
).get_query_set().select_related('implantation').filter(annee__in
=self
.filtre_annee
)
469 class ValeurPoint(models
.Model
):
471 id = models
.IntegerField(primary_key
=True)
472 valeur
= models
.FloatField()
473 implantation
= models
.ForeignKey('datamaster_modeles.Implantation',
474 db_column
='implantation',
475 related_name
='valeurs_point')
477 annee
= models
.IntegerField()
479 # Stockage de tous les taux de change pour optimiser la recherche de la devise associée
480 annee_courante
= datetime
.datetime
.now().year
481 tauxchange
= TauxChange
.objects
.select_related('devise').filter(annee
=annee_courante
)
483 def get_tauxchange_courant(self
):
485 Recherche le taux courant associé à la valeur d'un point.
486 Tous les taux de l'année courante sont chargés, pour optimiser un affichage en liste.
487 (On pourrait probablement améliorer le manager pour lui greffer le taux courant sous forme de JOIN)
489 for tauxchange
in self
.tauxchange
:
490 if tauxchange
.implantation_id
== self
.implantation_id
:
494 def __unicode__(self
):
495 tx
= self
.get_tauxchange_courant()
497 devise_code
= tx
.devise
.code
500 return u
'%s %s (%s-%s)' % (self
.valeur
, devise_code
, self
.implantation
.nom
, self
.annee
)
503 ordering
= ['valeur']
505 objects
= models
.Manager()
506 actuelles
= ValeurPointManager()
508 class DeviseManager(models
.Manager
):
510 On oublie le US et le CAN
512 def get_query_set(self
):
513 return super(DeviseManager
, self
).get_query_set().exclude(id__in
=(3, 15))
515 class Devise(models
.Model
):
517 objects
= DeviseManager()
519 id = models
.IntegerField(primary_key
=True)
520 code
= models
.CharField(max_length
=10, unique
=True)
521 nom
= models
.CharField(max_length
=255)
523 def __unicode__(self
):
524 return u
'%s - %s' % (self
.code
, self
.nom
)
527 class TypeContrat(models
.Model
):
529 id = models
.IntegerField(primary_key
=True)
530 nom
= models
.CharField(max_length
=255)
531 nom_long
= models
.CharField(max_length
=255) #description
532 categorie
= models
.CharField(max_length
=10,
533 choices
=CONTRAT_CATEGORIE_CHOICES
)
535 actif
= models
.BooleanField()
537 def __unicode__(self
):
538 return u
'%s' % (self
.nom
)