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 def get_query_set(self
):
77 return super(DossierManager
, self
).get_query_set().select_related(*fkeys
).all()
79 class Dossier(models
.Model
):
81 id = models
.IntegerField(primary_key
=True)
82 code
= models
.CharField(max_length
=10, unique
=True)
83 employe
= models
.ForeignKey('Employe', db_column
='employe')
85 poste1
= models
.ForeignKey('Poste', db_column
='poste1',
86 related_name
='poste1')
87 implantation1
= models
.ForeignKey('datamaster_modeles.Implantation',
88 db_column
='implantation1',
89 related_name
='implantation1',
90 blank
=True, null
=True)
91 complement1
= models
.TextField(null
=True, blank
=True)
92 responsable_implantation1
= models
.IntegerField()
93 poste2
= models
.ForeignKey('Poste', db_column
='poste2',
94 related_name
='poste2',
95 blank
=True, null
=True)
96 implantation2
= models
.ForeignKey('datamaster_modeles.Implantation',
97 db_column
='implantation2',
98 related_name
='implantation2',
99 null
=True, blank
=True)
100 complement2
= models
.TextField(null
=True, blank
=True)
101 responsable_implantation2
= models
.IntegerField()
103 service
= models
.ForeignKey('Service', db_column
='service',
104 blank
=True, null
=True)
105 responsable
= models
.ForeignKey('Employe', db_column
='responsable',
106 related_name
='responsable',
107 blank
=True, null
=True)
108 remplacement_de
= models
.ForeignKey('Employe', db_column
='remplacement_de',
109 related_name
='remplacement_de',
110 blank
=True, null
=True)
111 type = models
.CharField(max_length
=1, choices
=TYPE_DOSSIER_CHOICES
)
112 statut
= models
.ForeignKey('Statut', db_column
='statut',
113 blank
=True, null
=True)
114 organisme_bstg
= models
.ForeignKey('OrganismeBstg',
115 db_column
='organisme_bstg',
116 blank
=True, null
=True)
118 classement
= models
.ForeignKey('Classement', db_column
='classement',
119 blank
=True, null
=True)
120 regime_travail
= models
.IntegerField()
122 mandat_date_debut
= models
.DateField()
123 mandat_date_fin
= models
.DateField(null
=True, blank
=True)
125 contrat_date_debut
= models
.DateField()
126 contrat_date_fin
= models
.DateField()
127 type_contrat
= models
.ForeignKey('TypeContrat', db_column
='type_contrat',
128 blank
=True, null
=True)
130 date_creation
= models
.DateField(auto_now_add
=True)
131 date_maj
= models
.DateField(auto_now
=True)
132 commentaire
= models
.TextField(null
=True, blank
=True)
135 objects
= DossierManager()
137 def __unicode__(self
):
138 return u
'%s : %s %s' % (self
.employe
, self
.poste1
, self
.complement1
)
140 def get_dernier_salaire_remun(self
):
141 remun
= [r
for r
in self
.remuneration_set
.all() if r
.type_id
== 1] # type salaire de base
147 def get_salaire(self
):
148 remun
= self
.get_dernier_salaire_remun()
149 if remun
is not None:
150 return int(remun
.montant
)
154 def get_salaire_display(self
):
156 Moyen rapide de récupérer le salaire correspodant à un dossier. Par contre,
157 toutes les rémuérations n'ont pas de devise associées, c'est pourquoi on récupère
158 les anciennes rémunérations pour rechercher si elle existait auparavant.
160 if self
.dernier_salaire_remun() is not None:
161 devise_code
= self
.dernier_salaire_remun().devise
.code
164 return "%s %s" % (self
.get_salaire(), devise_code
, )
166 def get_salaire_euro_display(self
):
168 Moyen rapide de récupérer le salaire correspodant à un dossier. Par contre,
169 toutes les rémuérations n'ont pas de devise associées, c'est pourquoi on récupère
170 les anciennes rémunérations pour rechercher si elle existait auparavant.
171 La valeur est est affichée en Euros en se servant du taux actuel.
173 return "%s EUR" % (self
.get_dernier_salaire_remun().en_euros())
175 LIEN_PARENTE_CHOICES
= (
176 ('Conjoint', 'Conjoint'),
177 ('Conjointe', 'Conjointe'),
182 class AyantDroit(models
.Model
):
184 id = models
.IntegerField(primary_key
=True)
185 nom
= models
.CharField(max_length
=255)
186 prenom
= models
.CharField(max_length
=255)
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
)
193 commentaire
= models
.TextField(null
=True, blank
=True)
194 actif
= models
.BooleanField()
197 class Remuneration(models
.Model
):
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
='id', db_column
='devise', null
=True, blank
=True)
207 date_effective
= models
.DateField(null
=True, blank
=True)
208 pourcentage
= models
.IntegerField(null
=True, blank
=True)
210 date_creation
= models
.DateField(auto_now_add
=True)
211 user_creation
= models
.IntegerField(null
=True, blank
=True) #User ou employé
212 desactivation
= models
.NullBooleanField(null
=True, blank
=True) #
213 date_desactivation
= models
.DateField(null
=True, blank
=True)
214 user_desactivation
= models
.IntegerField(null
=True, blank
=True) #User ou employé
215 annulation
= models
.NullBooleanField(null
=True, blank
=True)
216 date_annulation
= models
.DateField(null
=True, blank
=True)
217 user_annulation
= models
.IntegerField(null
=True, blank
=True) #User ou employé
219 def __unicode__(self
):
221 devise
= self
.devise
.code
224 return "%s %s (%s EUR - %s)" % (self
.montant
, devise
, self
.en_euros(), self
.get_taux_historique(), )
226 def get_taux_historique(self
):
228 Retourne le taux en vigueur durant l'année considérée. Un taux de 0 est crée, si le taux de change
231 taux
= TauxChange
.objects
.filter(devise
=self
.devise
, annee
=self
.date_creation
.year
)
238 tauxchange
= self
.get_taux_historique()
239 if tauxchange
is not None:
240 return int(self
.montant
* tauxchange
.taux
)
244 class FamilleEmploi(models
.Model
):
246 id = models
.IntegerField(primary_key
=True)
247 nom
= models
.CharField(max_length
=255)
249 actif
= models
.BooleanField()
251 class TypePoste(models
.Model
):
253 id = models
.IntegerField(primary_key
=True)
254 nom
= models
.CharField(max_length
=255)
255 nom_feminin
= models
.CharField(max_length
=255)
256 description
= models
.CharField(max_length
=255)
257 is_responsable
= models
.BooleanField()
258 famille_emploi
= models
.ForeignKey('FamilleEmploi',
259 db_column
='famille_emploi')
261 date_modification
= models
.DateField(auto_now
=True)
262 actif
= models
.BooleanField()
264 def __unicode__(self
):
265 return u
'%s' % self
.nom
271 TYPE_PAIEMENT_CHOICES
= (
272 ('Régulier', 'Régulier'),
273 ('Ponctuel', 'Ponctuel'),
276 NATURE_REMUNERATION_CHOICES
= (
277 ('Accessoire', 'Accessoire'),
278 ('Charges', 'Charges'),
279 ('Indemnité', 'Indemnité'),
281 ('Traitement', 'Traitement'),
284 class TypeRemuneration(models
.Model
):
286 id = models
.IntegerField(primary_key
=True)
287 nom
= models
.CharField(max_length
=255)
288 type_paiement
= models
.CharField(max_length
=30,
289 choices
=TYPE_PAIEMENT_CHOICES
)
290 nature_remuneration
= models
.CharField(max_length
=30,
291 choices
=NATURE_REMUNERATION_CHOICES
)
293 actif
= models
.BooleanField()
295 def __unicode__(self
):
296 return u
'%s' % self
.nom
299 class TypeRevalorisation(models
.Model
):
301 id = models
.IntegerField(primary_key
=True)
302 nom
= models
.CharField(max_length
=255)
304 actif
= models
.BooleanField()
306 PROPORTION_CHOICES
= (
311 class PosteManager(SecurityManager
):
313 Chargement de tous les objets FK existants sur chaque QuerySet.
315 prefixe_implantation
= 'implantation'
317 def get_query_set(self
):
322 return super(PosteManager
, self
).get_query_set().select_related(*fkeys
).all()
324 class Poste(models
.Model
):
326 id = models
.IntegerField(primary_key
=True)
327 implantation
= models
.ForeignKey('datamaster_modeles.Implantation',
328 db_column
='implantation', related_name
='+')
329 type_poste
= models
.ForeignKey('TypePoste', db_column
='type_poste')
330 proportion
= models
.CharField(max_length
=10, choices
=PROPORTION_CHOICES
)
331 #(sert à quoi?) renommer "regime_travail" ou autre? convertir data en % (data * 100; ex: 1 = 100%)
333 date_modification
= models
.DateField(auto_now
=True)
334 actif
= models
.BooleanField()
337 objects
= PosteManager()
339 def __unicode__(self
):
340 return u
'%s - %s [%s]' % (self
.implantation
, self
.type_poste
.nom
,
344 class Service(models
.Model
):
346 id = models
.IntegerField(primary_key
=True)
347 nom
= models
.CharField(max_length
=255)
349 actif
= models
.BooleanField()
351 def __unicode__(self
):
352 return u
'%s' % self
.nom
358 TYPE_ORGANISME_CHOICES
= (
359 ('MAD', 'Mise à disposition'),
360 ('DET', 'Détachement'),
363 class OrganismeBstg(models
.Model
):
365 id = models
.IntegerField(primary_key
=True)
366 nom
= models
.CharField(max_length
=255)
367 type = models
.CharField(max_length
=10, choices
=TYPE_ORGANISME_CHOICES
)
369 actif
= models
.BooleanField()
371 def __unicode__(self
):
372 return u
'%s (%s)' % (self
.nom
, self
.type)
375 ordering
= ['type', 'nom']
378 CONTRAT_CATEGORIE_CHOICES
= (
382 class Statut(models
.Model
):
384 id = models
.IntegerField(primary_key
=True)
385 code
= models
.CharField(max_length
=25, unique
=True)
386 nom
= models
.CharField(max_length
=255)
387 type_contrat_categorie
= models
.CharField(max_length
=10,
388 choices
=CONTRAT_CATEGORIE_CHOICES
)
389 #CHOICES A, C (veut dire quoi?) voir TypeContrat.categorie
391 actif
= models
.BooleanField()
393 def __unicode__(self
):
394 return u
'%s : %s' % (self
.code
, self
.nom
)
396 TYPE_CLASSEMENT_CHOICES
= (
401 class ClassementManager(models
.Manager
):
403 Ordonner les spcéfiquement les classements.
405 def get_query_set(self
):
406 qs
= super(self
.__class__
, self
).get_query_set()
407 qs
= qs
.extra(select
={'ponderation': 'FIND_IN_SET(type,"SO,HG,S,T,P,C,D")'})
408 qs
= qs
.extra(order_by
=('ponderation', ))
412 class Classement(models
.Model
):
414 id = models
.IntegerField(primary_key
=True)
415 type = models
.CharField(max_length
=10, choices
=TYPE_CLASSEMENT_CHOICES
)
416 echelon
= models
.IntegerField()
417 degre
= models
.IntegerField()
418 coefficient
= models
.FloatField()
420 commentaire
= models
.TextField(null
=True, blank
=True)
421 date_modification
= models
.DateField(auto_now
=True)
422 actif
= models
.BooleanField()
425 objects
= ClassementManager()
427 def __unicode__(self
):
428 return u
'%s.%s.%s' % (self
.type, self
.echelon
, self
.degre
)
431 ordering
= ['type','echelon','degre','coefficient']
433 class TauxChange(models
.Model
):
435 id = models
.IntegerField(primary_key
=True)
436 devise
= models
.ForeignKey('Devise', to_field
='id', db_column
='devise')
437 annee
= models
.IntegerField()
438 taux
= models
.FloatField()
440 implantation
= models
.ForeignKey('datamaster_modeles.Implantation',
441 db_column
='implantation',
442 related_name
='taux_change')
444 def __unicode__(self
):
445 return u
"%s %s : %s" % (self
.devise
, self
.annee
, self
.taux
)
447 class ValeurPointManager(models
.Manager
):
449 Manager qui travaille uniquement sur les valeurs du point de l'année en cours.
451 mois
= datetime
.datetime
.now().month
452 annee_courante
= datetime
.datetime
.now().year
454 # Pour le mois de janvier et décembre on mets les 2 années pour faire la transition
456 filtre_annee
= (annee_courante
-1, annee_courante
)
458 filtre_annee
= (annee_courante
, annee_courante
+1)
460 filtre_annee
= (annee_courante
,)
462 def get_query_set(self
):
463 return super(ValeurPointManager
, self
).get_query_set().select_related('implantation').filter(annee__in
=self
.filtre_annee
)
466 class ValeurPoint(models
.Model
):
468 id = models
.IntegerField(primary_key
=True)
469 valeur
= models
.FloatField()
470 implantation
= models
.ForeignKey('datamaster_modeles.Implantation',
471 db_column
='implantation',
472 related_name
='valeurs_point')
474 annee
= models
.IntegerField()
476 # Stockage de tous les taux de change pour optimiser la recherche de la devise associée
477 annee_courante
= datetime
.datetime
.now().year
478 tauxchange
= TauxChange
.objects
.select_related('devise').filter(annee
=annee_courante
)
480 def get_tauxchange_courant(self
):
482 Recherche le taux courant associé à la valeur d'un point.
483 Tous les taux de l'année courante sont chargés, pour optimiser un affichage en liste.
484 (On pourrait probablement améliorer le manager pour lui greffer le taux courant sous forme de JOIN)
486 for tauxchange
in self
.tauxchange
:
487 if tauxchange
.implantation_id
== self
.implantation_id
:
491 def __unicode__(self
):
492 tx
= self
.get_tauxchange_courant()
494 devise_code
= tx
.devise
.code
497 return u
'%s %s (%s-%s)' % (self
.valeur
, devise_code
, self
.implantation_id
, self
.annee
)
500 ordering
= ['valeur']
502 objects
= models
.Manager()
503 actuelles
= ValeurPointManager()
506 class Devise(models
.Model
):
507 id = models
.IntegerField(primary_key
=True)
508 code
= models
.CharField(max_length
=10, unique
=True)
509 nom
= models
.CharField(max_length
=255)
511 def __unicode__(self
):
512 return u
'%s - %s' % (self
.code
, self
.nom
)
515 class TypeContrat(models
.Model
):
517 id = models
.IntegerField(primary_key
=True)
518 nom
= models
.CharField(max_length
=255)
519 nom_long
= models
.CharField(max_length
=255) #description
520 categorie
= models
.CharField(max_length
=10,
521 choices
=CONTRAT_CATEGORIE_CHOICES
)
523 actif
= models
.BooleanField()
525 def __unicode__(self
):
526 return u
'%s' % (self
.nom
)