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
)
33 def dossier_piece_dispatch(instance
, filename
):
34 path
= "dossier/%s/%s" % (instance
.dossier
.id, filename
)
38 class PostePiece(models
.Model
):
39 poste
= models
.ForeignKey("Poste")
40 nom
= models
.CharField(verbose_name
="Nom", max_length
=255)
41 fichier
= models
.FileField(verbose_name
="Fichier", upload_to
=poste_piece_dispatch
, storage
=storage_prive
)
43 class PosteManager(models
.Manager
):
45 Chargement de tous les objets FK existants sur chaque QuerySet.
47 def get_query_set(self
):
59 return super(PosteManager
, self
).get_query_set() \
60 .select_related(*fkeys
).all()
63 class Poste(models
.Model
):
65 id_rh
= models
.ForeignKey(rh
.Poste
, null
=True, related_name
='+',
67 verbose_name
="Mise à jour du poste")
68 nom
= models
.CharField(verbose_name
="Titre du poste", max_length
=255)
69 implantation
= models
.ForeignKey(ref
.Implantation
)
70 type_poste
= models
.ForeignKey(rh
.TypePoste
, null
=True, related_name
='+')
71 service
= models
.ForeignKey(rh
.Service
, related_name
='+',
72 verbose_name
=u
"Direction/Service/Pôle support")
73 responsable
= models
.ForeignKey(rh
.Poste
, related_name
='+',
74 verbose_name
="Poste du responsable")
76 regime_travail
= models
.DecimalField(max_digits
=12, decimal_places
=2,
78 verbose_name
="Temps de travail",
79 help_text
="% du temps complet")
80 regime_travail_nb_heure_semaine
= models
.DecimalField(max_digits
=12,
83 verbose_name
="Nb. heures par semaine")
86 statut_residence
= models
.CharField(max_length
=10, default
='local',
87 verbose_name
="Statut",
88 choices
=STATUT_RESIDENCE_CHOICES
)
90 mise_a_disposition
= models
.BooleanField(verbose_name
="Mise à disposition")
91 appel
= models
.CharField(max_length
=10, default
='interne',
92 verbose_name
="Appel à candidature",
93 choices
=POSTE_APPEL_CHOICES
)
96 classement_min
= models
.ForeignKey(rh
.Classement
, related_name
='+')
97 classement_max
= models
.ForeignKey(rh
.Classement
, related_name
='+')
98 coefficient_min
= models
.FloatField(null
=True) # pour classement "hors grille"
99 coefficient_max
= models
.FloatField(null
=True) # pour classement "hors grille"
100 valeur_point_min
= models
.ForeignKey(rh
.ValeurPoint
, related_name
='+', blank
=True, null
=True)
101 valeur_point_max
= models
.ForeignKey(rh
.ValeurPoint
, related_name
='+', blank
=True, null
=True)
102 devise_min
= models
.ForeignKey(rh
.Devise
, default
=5, related_name
='+')
103 devise_max
= models
.ForeignKey(rh
.Devise
, default
=5, related_name
='+')
104 salaire_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
106 salaire_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
108 indemn_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
110 indemn_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
112 autre_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
114 autre_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
117 # Comparatifs de rémunération
118 devise_comparaison
= models
.ForeignKey(rh
.Devise
, related_name
='+',
120 comp_locale_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
121 null
=True, blank
=True)
122 comp_locale_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
123 null
=True, blank
=True)
124 comp_universite_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
125 null
=True, blank
=True)
126 comp_universite_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
127 null
=True, blank
=True)
128 comp_fonctionpub_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
129 null
=True, blank
=True)
130 comp_fonctionpub_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
131 null
=True, blank
=True)
132 comp_ong_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
133 null
=True, blank
=True)
134 comp_ong_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
135 null
=True, blank
=True)
136 comp_autre_min
= models
.DecimalField(max_digits
=12, decimal_places
=2,
137 null
=True, blank
=True)
138 comp_autre_max
= models
.DecimalField(max_digits
=12, decimal_places
=2,
139 null
=True, blank
=True)
142 date_creation
= models
.DateTimeField(auto_now_add
=True)
143 date_modification
= models
.DateTimeField(auto_now
=True)
144 date_debut
= models
.DateField(verbose_name
="Date de début",
145 help_text
="format: aaaa-mm-jj")
146 date_fin
= models
.DateField(null
=True, blank
=True,
147 verbose_name
="Date de fin",
148 help_text
="format: aaaa-mm-jj")
149 actif
= models
.BooleanField(default
=True)
152 objects
= PosteManager()
154 def get_dossiers(self
):
156 Liste tous les anciens dossiers liés à ce poste.
157 (Le nom de la relation sur le rh.Poste est mal choisi poste1 au lieu de dossier1)
158 Note1 : seulement le dosssier principal fait l'objet de la recherche.
159 Note2 : les dossiers sont retournés du plus récent au plus vieux. (Ce test est fait
160 en fonction du id, car les dates de création sont absentes de rh v1).
162 if self
.id_rh
is None:
164 postes
= [p
for p
in self
.id_rh
.poste1
.all()]
165 return sorted(postes
, key
=lambda poste
: poste
.id, reverse
=True)
167 def get_complement_nom(self
):
169 Inspecte les modèles rh v1 pour trouver dans le dernier dossier un complément de titre de poste.
171 dossiers
= self
.get_dossiers()
172 if len(dossiers
) > 0:
173 nom
= dossiers
[0].complement1
178 def get_employe(self
):
180 Inspecte les modèles rh v1 pour trouver l'employé du dernier dossier.
182 dossiers
= self
.get_dossiers()
183 if len(dossiers
) > 0:
184 return dossiers
[0].employe
188 def __unicode__(self
):
190 Cette fonction est consommatrice SQL car elle cherche les dossiers qui ont été liés à celui-ci.
192 complement_nom_poste
= self
.get_complement_nom()
193 if complement_nom_poste
is None:
194 complement_nom_poste
= ""
195 employe
= self
.get_employe()
203 complement_nom_poste
,
206 return u
'%s - %s (%s) [dae-%s %s %s]' % data
209 # Tester l'enregistrement car les models.py sont importés au complet
210 if not reversion
.is_registered(Poste
):
211 reversion
.register(Poste
)
214 POSTE_FINANCEMENT_CHOICES
= (
215 ('A', 'A - Frais de personnel'),
216 ('B', 'B - Projet(s)-Titre(s)'),
221 class PosteFinancement(models
.Model
):
222 montant
= models
.DecimalField(max_digits
=12, decimal_places
=2,
223 help_text
="ex.: 12000.00 € (décimale avec point, devise = EUR)")
224 poste
= models
.ForeignKey('Poste', related_name
='financements')
225 type = models
.CharField(max_length
=1, choices
=POSTE_FINANCEMENT_CHOICES
)
226 pourcentage
= models
.DecimalField(max_digits
=12, decimal_places
=2,
227 help_text
="ex.: 33.33 % (décimale avec point)")
228 commentaire
= models
.TextField(
229 help_text
="Spécifiez la source de financement.")
240 class Employe(models
.Model
):
243 id_rh
= models
.ForeignKey(rh
.Employe
, null
=True, related_name
='+',
244 verbose_name
='Employé')
245 nom
= models
.CharField(max_length
=255)
246 prenom
= models
.CharField(max_length
=255, verbose_name
='Prénom')
247 genre
= models
.CharField(max_length
=1, choices
=GENRE_CHOICES
,
248 null
=True, blank
=True)
250 def __unicode__(self
):
251 return u
'%s %s' % (self
.prenom
, self
.nom
)
254 COMPTE_COMPTA_CHOICES
= (
260 class DossierPiece(models
.Model
):
261 dossier
= models
.ForeignKey("Dossier")
262 nom
= models
.CharField(verbose_name
="Nom", max_length
=255)
263 fichier
= models
.FileField(verbose_name
="Fichier", upload_to
=dossier_piece_dispatch
, storage
=storage_prive
)
265 class Dossier(models
.Model
):
268 employe
= models
.ForeignKey('Employe', related_name
='+', editable
=False)
269 poste
= models
.ForeignKey('Poste', related_name
='+', editable
=False)
270 statut
= models
.ForeignKey(rh
.Statut
, related_name
='+')
271 organisme_bstg
= models
.ForeignKey(rh
.OrganismeBstg
, related_name
='+')
273 # Données antérieures de l'employé
274 statut_anterieur
= models
.ForeignKey(
275 rh
.Statut
, related_name
='+', null
=True, blank
=True,
276 verbose_name
='Statut antérieur')
278 classement_anterieur
= models
.ForeignKey(
279 rh
.Classement
, related_name
='+', null
=True, blank
=True,
280 verbose_name
='Classement précédent')
281 salaire_anterieur
= models
.DecimalField(
282 max_digits
=12, decimal_places
=2, null
=True, default
=None,
283 blank
=True, verbose_name
='Salaire précédent')
285 # Données du titulaire précédent
286 employe_anterieur
= models
.ForeignKey(
287 rh
.Employe
, related_name
='+', null
=True, blank
=True,
288 verbose_name
='Employé précédent')
289 statut_titulaire_anterieur
= models
.ForeignKey(
290 rh
.Statut
, related_name
='+', null
=True, blank
=True,
291 verbose_name
='Statut titulaire précédent')
292 classement_titulaire_anterieur
= models
.ForeignKey(
293 rh
.Classement
, related_name
='+', null
=True, blank
=True,
294 verbose_name
='Classement titulaire précédent')
295 salaire_titulaire_anterieur
= models
.DecimalField(
296 max_digits
=12, decimal_places
=2, default
=None, null
=True,
297 blank
=True, verbose_name
='Salaire titulaire précédent')
300 remplacement
= models
.BooleanField()
301 statut_residence
= models
.CharField(max_length
=10, default
='local',
302 verbose_name
="Statut",
303 choices
=STATUT_RESIDENCE_CHOICES
)
306 classement
= models
.ForeignKey(rh
.Classement
, related_name
='+',
307 verbose_name
='Classement proposé')
308 salaire
= models
.DecimalField(max_digits
=12, decimal_places
=2,
309 verbose_name
='Salaire de base',
310 null
=True, default
=None)
311 devise
= models
.ForeignKey(rh
.Devise
, related_name
='+')
312 regime_travail
= models
.DecimalField(max_digits
=12, decimal_places
=2,
313 verbose_name
="Régime de travail",
314 help_text
="% du temps complet")
315 regime_travail_nb_heure_semaine
= models
.DecimalField(max_digits
=12,
316 decimal_places
=2, verbose_name
="Nb. heures par semaine")
319 type_contrat
= models
.ForeignKey(rh
.TypeContrat
, related_name
='+')
320 contrat_date_debut
= models
.DateField(help_text
="format: aaaa-mm-jj")
321 contrat_date_fin
= models
.DateField(help_text
="format: aaaa-mm-jj")
324 compte_compta
= models
.CharField(max_length
=10,
325 choices
=COMPTE_COMPTA_CHOICES
)
326 compte_courriel
= models
.BooleanField()
329 class Remuneration(models
.Model
):
331 dossier
= models
.ForeignKey('Dossier', db_column
='dossier')
332 type = models
.ForeignKey(rh
.TypeRemuneration
, db_column
='type',
335 # type_revalorisation = models.ForeignKey('TypeRevalorisation',
336 # db_column='type_revalorisation')
337 montant
= models
.DecimalField(max_digits
=12, decimal_places
=2,
339 devise
= models
.ForeignKey(rh
.Devise
, to_field
='code',
340 db_column
='devise', related_name
='+')
341 precision
= models
.CharField(max_length
=255, null
=True, blank
=True)
342 # date_effective = models.DateField(null=True, blank=True)
343 # pourcentage = models.IntegerField(null=True, blank=True)
346 date_creation
= models
.DateField(auto_now_add
=True)
347 user_creation
= models
.IntegerField(null
=True, blank
=True)
348 # desactivation = models.BooleanField(default=False, blank=True)
349 # date_desactivation = models.DateField(null=True, blank=True)
350 # user_desactivation = models.IntegerField(null=True, blank=True)
351 # annulation = models.BooleanField(default=False, blank=True)
352 # date_annulation = models.DateField(null=True, blank=True)
353 # user_annulation = models.IntegerField(null=True, blank=True)
355 def montant_mois(self
):
356 return round(self
.montant
/ 12, 2)
358 def taux_devise(self
):
359 return self
.devise
.tauxchange_set
.order_by('-annee').all()[0].taux
361 def montant_euro(self
):
362 return round(float(self
.montant
) / float(self
.taux_devise()), 2)
364 def montant_euro_mois(self
):
365 return round(self
.montant_euro() / 12, 2)
368 class JustificationPoste(models
.Model
):
372 class JustificationEmploye(models
.Model
):
376 class DocumentPoste(models
.Model
):
380 class DocumentEmploye(models
.Model
):
384 class Validation(models
.Model
):
386 date
= models
.DateField()
388 # avis = ? (CHOICES?)
391 class ValidationPoste(models
.Model
):
392 poste
= models
.ForeignKey('Poste')
395 class ValidationEmploye(models
.Model
):
396 employe
= models
.ForeignKey('Employe')