1 # -=- encoding: utf-8 -=-
4 from django
.core
.files
.storage
import FileSystemStorage
5 from django
.db
import models
7 import datamaster_modeles
.models
as ref
8 from rh_v1
import models
as rh
11 STATUT_RESIDENCE_CHOICES
= (
13 ('expat', 'Expatrié'),
16 POSTE_APPEL_CHOICES
= (
17 ('interne', 'Interne'),
18 ('externe', 'Externe'),
21 POSTE_STATUT_CHOICES
= (
22 ('MAD', 'Mise à disposition'),
23 ('DET', 'Détachement'),
27 storage_prive
= FileSystemStorage(settings
.PRIVE_MEDIA_ROOT
, base_url
=settings
.PRIVE_MEDIA_URL
)
29 def poste_piece_dispatch(instance
, filename
):
30 path
= "poste/%s/%s" % (instance
.poste
.id, filename
)
34 class PostePiece(models
.Model
):
35 poste
= models
.ForeignKey("Poste")
36 nom
= models
.CharField(verbose_name
="Nom", max_length
=255)
37 fichier
= models
.FileField(verbose_name
="Fichier", upload_to
=poste_piece_dispatch
, storage
=storage_prive
)
39 class PosteManager(models
.Manager
):
41 Chargement de tous les objets FK existants sur chaque QuerySet.
43 def get_query_set(self
):
55 return super(PosteManager
, self
).get_query_set() \
56 .select_related(*fkeys
).all()
59 class Poste(models
.Model
):
61 id_rh
= models
.ForeignKey(rh
.Poste
, null
=True, related_name
='+',
63 verbose_name
="Mise à jour du poste")
64 nom
= models
.CharField(verbose_name
="Titre du poste", max_length
=255)
65 implantation
= models
.ForeignKey(ref
.Implantation
)
66 type_poste
= models
.ForeignKey(rh
.TypePoste
, null
=True, related_name
='+')
67 service
= models
.ForeignKey(rh
.Service
, related_name
='+',
68 verbose_name
=u
"Direction/Service/Pôle support")
69 responsable
= models
.ForeignKey(rh
.Poste
, related_name
='+',
70 verbose_name
="Poste du responsable")
72 regime_travail
= models
.DecimalField(max_digits
=12, decimal_places
=2,
74 verbose_name
="Temps de travail",
75 help_text
="% du temps complet")
76 regime_travail_nb_heure_semaine
= models
.DecimalField(max_digits
=12,
79 verbose_name
="Nb. heures par semaine")
82 statut_residence
= models
.CharField(max_length
=10, default
='MAD',
83 verbose_name
="Statut",
84 choices
=STATUT_RESIDENCE_CHOICES
)
86 mise_a_disposition
= models
.BooleanField(verbose_name
="Mise à disposition")
87 appel
= models
.CharField(max_length
=10, default
='interne',
88 verbose_name
="Appel à candidature",
89 choices
=POSTE_APPEL_CHOICES
)
92 classement_min
= models
.ForeignKey(rh
.Classement
, related_name
='+')
93 classement_max
= models
.ForeignKey(rh
.Classement
, related_name
='+')
94 coefficient_min
= models
.FloatField(null
=True) # pour classement "hors grille"
95 coefficient_max
= models
.FloatField(null
=True) # pour classement "hors grille"
96 valeur_point_min
= models
.ForeignKey(rh
.ValeurPoint
, related_name
='+', blank
=True, null
=True)
97 valeur_point_max
= models
.ForeignKey(rh
.ValeurPoint
, related_name
='+', blank
=True, null
=True)
98 devise_min
= models
.ForeignKey(rh
.Devise
, default
=5, related_name
='+')
99 devise_max
= models
.ForeignKey(rh
.Devise
, default
=5, related_name
='+')
100 salaire_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
102 salaire_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
104 indemn_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
106 indemn_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
108 autre_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
110 autre_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
113 # Comparatifs de rémunération
114 devise_comparaison
= models
.ForeignKey(rh
.Devise
, related_name
='+',
116 comp_locale_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
117 null
=True, blank
=True)
118 comp_locale_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
119 null
=True, blank
=True)
120 comp_universite_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
121 null
=True, blank
=True)
122 comp_universite_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
123 null
=True, blank
=True)
124 comp_fonctionpub_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
125 null
=True, blank
=True)
126 comp_fonctionpub_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
127 null
=True, blank
=True)
128 comp_ong_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
129 null
=True, blank
=True)
130 comp_ong_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
131 null
=True, blank
=True)
132 comp_autre_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
133 null
=True, blank
=True)
134 comp_autre_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
135 null
=True, blank
=True)
138 date_creation
= models
.DateTimeField(auto_now_add
=True)
139 date_modification
= models
.DateTimeField(auto_now
=True)
140 date_debut
= models
.DateField(verbose_name
="Date de début",
141 help_text
="format: aaaa-mm-jj")
142 date_fin
= models
.DateField(null
=True, blank
=True,
143 verbose_name
="Date de fin",
144 help_text
="format: aaaa-mm-jj")
145 actif
= models
.BooleanField(default
=True)
148 objects
= PosteManager()
150 def get_dossiers(self
):
152 Liste tous les anciens dossiers liés à ce poste.
153 (Le nom de la relation sur le rh.Poste est mal choisi poste1 au lieu de dossier1)
154 Note1 : seulement le dosssier principal fait l'objet de la recherche.
155 Note2 : les dossiers sont retournés du plus récent au plus vieux. (Ce test est fait
156 en fonction du id, car les dates de création sont absentes de rh v1).
158 if self
.id_rh
is None:
160 postes
= [p
for p
in self
.id_rh
.poste1
.all()]
161 return sorted(postes
, key
=lambda poste
: poste
.id, reverse
=True)
163 def get_complement_nom(self
):
165 Inspecte les modèles rh v1 pour trouver dans le dernier dossier un complément de titre de poste.
167 dossiers
= self
.get_dossiers()
168 if len(dossiers
) > 0:
169 nom
= dossiers
[0].complement1
174 def get_employe(self
):
176 Inspecte les modèles rh v1 pour trouver l'employé du dernier dossier.
178 dossiers
= self
.get_dossiers()
179 if len(dossiers
) > 0:
180 return dossiers
[0].employe
184 def __unicode__(self
):
186 Cette fonction est consommatrice SQL car elle cherche les dossiers qui ont été liés à celui-ci.
188 complement_nom_poste
= self
.get_complement_nom()
189 if complement_nom_poste
is None:
190 complement_nom_poste
= ""
191 employe
= self
.get_employe()
199 complement_nom_poste
,
202 return u
'%s - %s (%s) [dae-%s %s %s]' % data
204 def DISABLED_save(self
, *args
, **kwargs
):
205 # calculate nb_mois = nb of months between date_debut and date_fin
206 from datetime
import date
207 if not self
.salaire_min
:
208 self
.salaire_min
= self
.classement_min
* self
.valeur_point_min
209 if not self
.salaire_max
:
210 self
.salaire_max
= self
.classement_max
* self
.valeur_point_min
211 if not self
.valeur_point_min
:
212 self
.valeur_point_min
= \
213 rh
.ValeurPoint
.objects
.filter(implantation
=self
.implantation
)
214 if not self
.valeur_point_max
:
215 self
.valeur_point_max
= \
216 rh
.ValeurPoint
.objects
.filter(implantation
=self
.implantation
)
217 super(Subject
, self
).save(*args
, **kwargs
)
219 # Tester l'enregistrement car les models.py sont importés au complet
220 if not reversion
.is_registered(Poste
):
221 reversion
.register(Poste
)
224 POSTE_FINANCEMENT_CHOICES
= (
225 ('A', 'A - Frais de personnel'),
226 ('B', 'B - Projet(s)-Titre(s)'),
231 class PosteFinancement(models
.Model
):
232 montant
= models
.DecimalField(max_digits
=12, decimal_places
=2,
233 help_text
="ex.: 12000.00 € (décimale avec point, devise = EUR)")
234 poste
= models
.ForeignKey('Poste', related_name
='financements')
235 type = models
.CharField(max_length
=1, choices
=POSTE_FINANCEMENT_CHOICES
)
236 pourcentage
= models
.DecimalField(max_digits
=12, decimal_places
=2,
237 help_text
="ex.: 33.33 % (décimale avec point)")
238 commentaire
= models
.TextField(
239 help_text
="Spécifiez la source de financement.")
250 class Employe(models
.Model
):
253 id_rh
= models
.ForeignKey(rh
.Employe
, null
=True, related_name
='+',
254 verbose_name
='Employé')
255 nom
= models
.CharField(max_length
=255)
256 prenom
= models
.CharField(max_length
=255, verbose_name
='Prénom')
257 genre
= models
.CharField(max_length
=1, choices
=GENRE_CHOICES
,
258 null
=True, blank
=True)
260 def __unicode__(self
):
261 return u
'%s %s' % (self
.prenom
, self
.nom
)
264 COMPTE_COMPTA_CHOICES
= (
271 class Dossier(models
.Model
):
274 employe
= models
.ForeignKey('Employe', related_name
='+', editable
=False)
275 poste
= models
.ForeignKey('Poste', related_name
='+', editable
=False)
276 statut
= models
.ForeignKey(rh
.Statut
, related_name
='+')
277 organisme_bstg
= models
.ForeignKey(rh
.OrganismeBstg
, related_name
='+')
279 # Données antérieures de l'employé
280 statut_anterieur
= models
.ForeignKey(
281 rh
.Statut
, related_name
='+', null
=True, blank
=True,
282 verbose_name
='Statut antérieur')
284 classement_anterieur
= models
.ForeignKey(
285 rh
.Classement
, related_name
='+', null
=True, blank
=True,
286 verbose_name
='Classement précédent')
287 salaire_anterieur
= models
.DecimalField(
288 max_digits
=12, decimal_places
=2, null
=True, default
=None,
289 blank
=True, verbose_name
='Salaire précédent')
291 # Données du titulaire précédent
292 employe_anterieur
= models
.ForeignKey(
293 rh
.Employe
, related_name
='+', null
=True, blank
=True,
294 verbose_name
='Employé précédent')
295 statut_titulaire_anterieur
= models
.ForeignKey(
296 rh
.Statut
, related_name
='+', null
=True, blank
=True,
297 verbose_name
='Statut titulaire précédent')
298 classement_titulaire_anterieur
= models
.ForeignKey(
299 rh
.Classement
, related_name
='+', null
=True, blank
=True,
300 verbose_name
='Classement titulaire précédent')
301 salaire_titulaire_anterieur
= models
.DecimalField(
302 max_digits
=12, decimal_places
=2, default
=None, null
=True,
303 blank
=True, verbose_name
='Salaire titulaire précédent')
306 remplacement
= models
.BooleanField()
307 statut_residence
= models
.CharField(max_length
=10,
308 choices
=STATUT_RESIDENCE_CHOICES
)
311 classement
= models
.ForeignKey(rh
.Classement
, related_name
='+',
312 verbose_name
='Classement proposé')
313 salaire
= models
.DecimalField(max_digits
=12, decimal_places
=2,
314 verbose_name
='Salaire de base',
315 null
=True, default
=None)
316 devise
= models
.ForeignKey(rh
.Devise
, related_name
='+')
317 regime_travail
= models
.DecimalField(max_digits
=12, decimal_places
=2,
318 verbose_name
="Régime de travail")
319 regime_travail_nb_heure_semaine
= models
.DecimalField(max_digits
=12,
320 decimal_places
=2, verbose_name
="Nbr heures par semaine")
323 type_contrat
= models
.ForeignKey(rh
.TypeContrat
, related_name
='+')
324 contrat_date_debut
= models
.DateField()
325 contrat_date_fin
= models
.DateField()
328 compte_compta
= models
.CharField(max_length
=10,
329 choices
=COMPTE_COMPTA_CHOICES
)
330 compte_courriel
= models
.BooleanField()
333 class Remuneration(models
.Model
):
335 id = models
.IntegerField(primary_key
=True)
336 dossier
= models
.ForeignKey('Dossier', db_column
='dossier')
337 type = models
.ForeignKey('TypeRemuneration', db_column
='type')
339 # type_revalorisation = models.ForeignKey('TypeRevalorisation',
340 # db_column='type_revalorisation')
341 montant
= models
.DecimalField(max_digits
=12, decimal_places
=2) # Annuel
342 devise
= models
.ForeignKey(rh
.Devise
, to_field
='code',
343 db_column
='devise', related_name
='+')
344 date_effective
= models
.DateField(null
=True, blank
=True)
345 pourcentage
= models
.IntegerField(null
=True, blank
=True)
348 date_creation
= models
.DateField(auto_now_add
=True)
349 user_creation
= models
.IntegerField(null
=True, blank
=True)
350 desactivation
= models
.BooleanField(default
=False, blank
=True)
351 date_desactivation
= models
.DateField(null
=True, blank
=True)
352 user_desactivation
= models
.IntegerField(null
=True, blank
=True)
353 annulation
= models
.BooleanField(default
=False, blank
=True)
354 date_annulation
= models
.DateField(null
=True, blank
=True)
355 user_annulation
= models
.IntegerField(null
=True, blank
=True)
358 class JustificationPoste(models
.Model
):
362 class JustificationEmploye(models
.Model
):
366 class DocumentPoste(models
.Model
):
370 class DocumentEmploye(models
.Model
):
374 class Validation(models
.Model
):
376 date
= models
.DateField()
378 # avis = ? (CHOICES?)
381 class ValidationPoste(models
.Model
):
382 poste
= models
.ForeignKey('Poste')
385 class ValidationEmploye(models
.Model
):
386 employe
= models
.ForeignKey('Employe')
389 class TypeRemuneration(models
.Model
):
390 ordre
= models
.IntegerField()
391 groupe
= models
.ForeignKey('GroupeTypeRemuneration')
394 class GroupeTypeRemuneration(models
.Model
):
395 nom
= models
.CharField(max_length
=255)
396 ordre
= models
.IntegerField()