1 # -=- encoding: utf-8 -=-
4 from dateutil
.relativedelta
import relativedelta
5 from datetime
import date
, timedelta
7 from django
.conf
import settings
8 from django
.core
.files
.storage
import FileSystemStorage
9 from django
.db
import models
10 from django
.db
.models
import Q
14 from auf
.django
.references
import models
as ref
16 from project
.dae
.managers
import (
17 PosteManager
, DossierManager
, ImplantationManager
)
18 from project
.dae
.workflow
import PosteWorkflow
, DossierWorkflow
19 from project
.dae
.workflow
import \
20 DOSSIER_ETAT_DRH_FINALISATION
, DOSSIER_ETAT_REGION_FINALISATION
, \
22 from project
.rh
import models
as rh
23 from project
.rh
.models
import HELP_TEXT_DATE
26 UPLOAD_STORAGE
= FileSystemStorage(settings
.PRIVE_MEDIA_ROOT
)
31 POSTE_APPEL_CHOICES
= (
32 ('interne', 'Interne'),
33 ('externe', 'Externe'),
36 ('N', u
"Nouveau poste"),
37 ('M', u
"Poste existant"),
38 ('E', u
"Évolution de poste"),
42 class DeviseException(Exception):
43 silent_variable_failure
= True
46 class Poste(PosteWorkflow
, rh
.Poste_
):
48 type_intervention
= models
.CharField(
49 max_length
=1, choices
=POSTE_ACTION
, default
='N'
53 id_rh
= models
.ForeignKey(
54 rh
.Poste
, null
=True, related_name
='postes_dae', editable
=False,
55 verbose_name
=u
"Mise à jour du poste"
59 indemn_expat_min
= models
.DecimalField(
60 max_digits
=13, decimal_places
=2, default
=0
62 indemn_expat_max
= models
.DecimalField(
63 max_digits
=12, decimal_places
=2, default
=0
65 indemn_fct_min
= models
.DecimalField(
66 max_digits
=12, decimal_places
=2, default
=0
68 indemn_fct_max
= models
.DecimalField(
69 max_digits
=12, decimal_places
=2, default
=0
71 charges_patronales_min
= models
.DecimalField(
72 max_digits
=12, decimal_places
=2, default
=0
74 charges_patronales_max
= models
.DecimalField(
75 max_digits
=12, decimal_places
=2, default
=0
79 objects
= PosteManager()
83 Les vues sont montées selon une clef spéciale
84 pour identifier la provenance du poste.
85 Cette méthode fournit un moyen de reconstruire cette clef
86 afin de générer les URLs.
88 return "dae-%s" % self
.id
89 key
= property(_get_key
)
91 def get_dossiers(self
):
93 Liste tous les anciens dossiers liés à ce poste.
94 (Le nom de la relation sur le rh.Poste est mal choisi
95 poste1 au lieu de dossier1)
96 Note1 : seulement le dosssier principal fait l'objet de la recherche.
97 Note2 : les dossiers sont retournés du plus récent au plus vieux.
98 (Ce test est fait en fonction du id,
99 car les dates de création sont absentes de rh v1).
101 if self
.id_rh
is None:
103 return self
.id_rh
.rh_dossiers
.all()
107 Retourne le poste RH s'il existe.
111 def importer_dans_rh(self
):
113 Importe le poste DAE dans un poste RH existant ou nouveau.
115 dans_rh
= self
.dans_rh()
116 poste_rh
= dans_rh
or rh
.Poste()
117 poste_rh
.nom
= self
.nom
118 poste_rh
.implantation
= self
.implantation
119 poste_rh
.type_poste
= self
.type_poste
120 poste_rh
.service
= self
.service
121 poste_rh
.responsable
= self
.responsable
122 poste_rh
.regime_travail
= self
.regime_travail
123 poste_rh
.regime_travail_nb_heure_semaine
= \
124 self
.regime_travail_nb_heure_semaine
125 poste_rh
.local
= self
.local
126 poste_rh
.expatrie
= self
.expatrie
127 poste_rh
.mise_a_disposition
= self
.mise_a_disposition
128 poste_rh
.appel
= self
.appel
129 poste_rh
.classement_min
= self
.classement_min
130 poste_rh
.classement_max
= self
.classement_max
131 poste_rh
.valeur_point_min
= self
.valeur_point_min
132 poste_rh
.valeur_point_max
= self
.valeur_point_max
133 poste_rh
.devise_min
= self
.devise_min
134 poste_rh
.devise_max
= self
.devise_max
135 poste_rh
.salaire_min
= self
.salaire_min
136 poste_rh
.salaire_max
= self
.salaire_max
137 poste_rh
.indemn_min
= self
.indemn_fct_min
138 poste_rh
.indemn_max
= self
.indemn_fct_max
139 poste_rh
.autre_min
= \
140 self
.indemn_expat_min
+ self
.charges_patronales_min
+ \
142 poste_rh
.autre_max
= \
143 self
.indemn_expat_max
+ self
.charges_patronales_max
+ \
145 poste_rh
.devise_comparaison
= self
.devise_comparaison
146 poste_rh
.comp_locale_min
= self
.comp_locale_min
147 poste_rh
.comp_locale_max
= self
.comp_locale_max
148 poste_rh
.comp_universite_min
= self
.comp_universite_min
149 poste_rh
.comp_universite_max
= self
.comp_universite_max
150 poste_rh
.comp_fonctionpub_min
= self
.comp_fonctionpub_min
151 poste_rh
.comp_fonctionpub_max
= self
.comp_fonctionpub_max
152 poste_rh
.comp_ong_min
= self
.comp_ong_min
153 poste_rh
.comp_ong_max
= self
.comp_ong_max
154 poste_rh
.comp_autre_min
= self
.comp_autre_min
155 poste_rh
.comp_autre_max
= self
.comp_autre_max
156 poste_rh
.justification
= self
.justification
158 poste_rh
.date_debut
= self
.date_debut
159 poste_rh
.date_fin
= self
.date_fin
162 for piece
in self
.dae_pieces
.all():
163 piece_rh
= poste_rh
.rh_pieces
.create(
167 if not settings
.DEBUG
:
168 piece_rh
.fichier
.save(
169 os
.path
.basename(piece
.fichier
.name
), piece
.fichier
172 rh
.PosteComparaison
.objects
.filter(poste
=poste_rh
).delete()
173 for comp
in self
.dae_comparaisons_internes
.all():
174 poste_rh
.rh_comparaisons_internes
.create(
175 implantation
=comp
.implantation
,
177 montant
=comp
.montant
,
181 rh
.PosteFinancement
.objects
.filter(poste
=poste_rh
).delete()
182 for financement
in self
.dae_financements
.all():
183 poste_rh
.rh_financements
.create(
184 type=financement
.type,
185 pourcentage
=financement
.pourcentage
,
186 commentaire
=financement
.commentaire
189 self
.id_rh
= poste_rh
193 def get_employe(self
):
195 Inspecte les modèles rh v1 pour trouver l'employé du dernier dossier.
197 dossiers
= self
.get_dossiers()
198 if len(dossiers
) > 0:
199 return dossiers
[0].employe
203 def get_default_devise(self
):
204 """Récupère la devise par défaut en fonction de l'implantation
208 implantation_devise
= rh
.TauxChange
.objects \
209 .filter(implantation
=self
.implantation
)[0].devise
211 implantation_devise
= 5 # EUR
212 return implantation_devise
214 #####################
215 # Classement de poste
216 #####################
218 def get_couts_minimum(self
):
219 return self
.salaire_min
+ self
.indemn_expat_min
+ \
220 self
.indemn_fct_min
+ self
.charges_patronales_min
+ \
223 def get_salaire_minimum(self
):
224 return self
.get_couts_minimum() - self
.charges_patronales_min
226 def get_taux_minimum(self
):
227 if self
.devise_min
.code
== 'EUR':
229 liste_taux
= self
.devise_min
.tauxchange_set
.order_by('-annee')
230 if len(liste_taux
) == 0:
231 raise DeviseException(
232 u
"La devise %s n'a pas de taux pour l'implantation %s" %
233 (self
.devise_min
, self
.implantation
))
235 return liste_taux
[0].taux
237 def get_couts_minimum_euros(self
):
238 return float(self
.get_couts_minimum()) * self
.get_taux_minimum()
240 def get_salaire_minimum_euros(self
):
241 return float(self
.get_salaire_minimum()) * self
.get_taux_minimum()
243 def get_couts_maximum(self
):
244 return self
.salaire_max
+ self
.indemn_expat_max
+ \
245 self
.indemn_fct_max
+ self
.charges_patronales_max
+ \
248 def get_salaire_maximum(self
):
249 return self
.get_couts_maximum() - self
.charges_patronales_max
251 def get_taux_maximum(self
):
252 if self
.devise_max
.code
== 'EUR':
254 liste_taux
= self
.devise_max
.tauxchange_set
.order_by('-annee')
255 if len(liste_taux
) == 0:
256 raise DeviseException(
257 u
"La devise %s n'a pas de taux pour l'implantation %s" %
258 (self
.devise_max
, self
.implantation
)
261 return liste_taux
[0].taux
263 def get_couts_maximum_euros(self
):
264 return float(self
.get_couts_maximum()) * self
.get_taux_maximum()
266 def get_salaire_maximum_euros(self
):
267 return float(self
.get_salaire_maximum()) * self
.get_taux_maximum()
269 def show_taux_minimum(self
):
271 return self
.get_taux_minimum()
272 except DeviseException
, e
:
275 def show_couts_minimum_euros(self
):
277 return self
.get_couts_minimum_euros()
278 except DeviseException
, e
:
281 def show_salaire_minimum_euros(self
):
283 return self
.get_salaire_minimum_euros()
284 except DeviseException
, e
:
287 def show_taux_maximum(self
):
289 return self
.get_taux_maximum()
290 except DeviseException
, e
:
293 def show_couts_maximum_euros(self
):
295 return self
.get_couts_maximum_euros()
296 except DeviseException
, e
:
299 def show_salaire_maximum_euros(self
):
301 return self
.get_salaire_maximum_euros()
302 except DeviseException
, e
:
305 # Comparaison de poste
306 def est_comparable(self
):
308 Si on a au moins une valeur de saisie dans les comparaisons, alors
309 le poste est comparable.
311 if self
.comp_universite_min
is None and \
312 self
.comp_fonctionpub_min
is None and \
313 self
.comp_locale_min
is None and \
314 self
.comp_ong_min
is None and \
315 self
.comp_autre_min
is None and \
316 self
.comp_universite_max
is None and \
317 self
.comp_fonctionpub_max
is None and \
318 self
.comp_locale_max
is None and \
319 self
.comp_ong_max
is None and \
320 self
.comp_autre_max
is None:
325 def get_taux_comparaison(self
):
327 return rh
.TauxChange
.objects \
328 .filter(devise
=self
.devise_comparaison
)[0].taux
332 def get_comp_universite_min_euros(self
):
333 return (float)(self
.comp_universite_min
) * self
.get_taux_comparaison()
335 def get_comp_fonctionpub_min_euros(self
):
336 return (float)(self
.comp_fonctionpub_min
) * self
.get_taux_comparaison()
338 def get_comp_locale_min_euros(self
):
339 return (float)(self
.comp_locale_min
) * self
.get_taux_comparaison()
341 def get_comp_ong_min_euros(self
):
342 return (float)(self
.comp_ong_min
) * self
.get_taux_comparaison()
344 def get_comp_autre_min_euros(self
):
345 return (float)(self
.comp_autre_min
) * self
.get_taux_comparaison()
347 def get_comp_universite_max_euros(self
):
348 return (float)(self
.comp_universite_max
) * self
.get_taux_comparaison()
350 def get_comp_fonctionpub_max_euros(self
):
351 return (float)(self
.comp_fonctionpub_max
) * self
.get_taux_comparaison()
353 def get_comp_locale_max_euros(self
):
354 return (float)(self
.comp_locale_max
) * self
.get_taux_comparaison()
356 def get_comp_ong_max_euros(self
):
357 return (float)(self
.comp_ong_max
) * self
.get_taux_comparaison()
359 def get_comp_autre_max_euros(self
):
360 return (float)(self
.comp_autre_max
) * self
.get_taux_comparaison()
362 def __unicode__(self
):
364 Cette fonction est consommatrice SQL car elle cherche les dossiers
365 qui ont été liés à celui-ci.
375 return u
'%s - %s (%s)' % data
377 reversion
.register(Poste
, format
='xml', follow
=[
378 'dae_financements', 'dae_pieces', 'dae_comparaisons_internes'
381 POSTE_FINANCEMENT_CHOICES
= (
382 ('A', 'A - Frais de personnel'),
383 ('B', 'B - Projet(s)-Titre(s)'),
388 class PosteFinancement(rh
.PosteFinancement_
):
389 poste
= models
.ForeignKey(
390 Poste
, db_column
='poste', related_name
='dae_financements'
393 reversion
.register(PosteFinancement
, format
='xml')
396 class PostePiece(rh
.PostePiece_
):
397 poste
= models
.ForeignKey(
398 Poste
, db_column
='poste', related_name
='dae_pieces'
401 reversion
.register(PostePiece
, format
='xml')
404 class PosteComparaison(rh
.PosteComparaison_
):
405 poste
= models
.ForeignKey(
406 Poste
, related_name
='dae_comparaisons_internes'
408 statut
= models
.ForeignKey(
409 rh
.Statut
, related_name
='+', verbose_name
=u
'Statut', null
=True,
412 classement
= models
.ForeignKey(
413 rh
.Classement
, related_name
='+', verbose_name
=u
'Classement',
414 null
=True, blank
=True
417 reversion
.register(PosteComparaison
, format
='xml')
420 class PosteComparaisonRemuneration(rh
.Remuneration_
):
421 poste_comparaison
= models
.ForeignKey(
422 PosteComparaison
, related_name
='poste_comparaison_remunerations'
425 reversion
.register(PosteComparaisonRemuneration
, format
='xml')
430 # TODO : migration pour m -> M, f -> F
438 class Employe(models
.Model
):
441 id_rh
= models
.ForeignKey(rh
.Employe
, null
=True, related_name
='+',
442 verbose_name
=u
'Employé')
443 nom
= models
.CharField(max_length
=255)
444 prenom
= models
.CharField(max_length
=255, verbose_name
=u
'Prénom')
445 genre
= models
.CharField(max_length
=1, choices
=GENRE_CHOICES
)
447 def __unicode__(self
):
448 return u
'%s %s' % (self
.prenom
, self
.nom
.upper())
452 Retourne l'employé RH associé à cet employé DAE.
456 def importer_dans_rh(self
):
458 Importe l'employé DAE dans un employé RH existant ou nouveau.
460 employe_rh
= self
.dans_rh() or rh
.Employe
.objects
.create(
465 self
.id_rh
= employe_rh
469 reversion
.register(Employe
, format
='xml')
474 STATUT_RESIDENCE_CHOICES
= (
476 ('expat', 'Expatrié'),
479 class Dossier(DossierWorkflow
, rh
.Dossier_
):
480 poste
= models
.ForeignKey(
481 'Poste', db_column
='poste', related_name
='dae_dossiers'
483 employe
= models
.ForeignKey(
484 'Employe', db_column
='employe',
485 related_name
='rh_dossiers', verbose_name
=u
"Employé"
487 organisme_bstg_autre
= models
.CharField(max_length
=255,
488 verbose_name
=u
"Autre organisme",
489 help_text
="indiquer l'organisme ici s'il n'est pas dans la liste",
493 # Lien avec le dossier
494 dossier_rh
= models
.ForeignKey(
495 rh
.Dossier
, related_name
='dossiers_dae', null
=True, blank
=True
498 # Données antérieures de l'employé
499 statut_anterieur
= models
.ForeignKey(
500 rh
.Statut
, related_name
='+', null
=True, blank
=True,
501 verbose_name
=u
'Statut antérieur')
502 classement_anterieur
= models
.ForeignKey(
503 rh
.Classement
, related_name
='+', null
=True, blank
=True,
504 verbose_name
=u
'Classement précédent')
505 salaire_anterieur
= models
.DecimalField(
506 max_digits
=12, decimal_places
=2, null
=True, default
=None,
507 blank
=True, verbose_name
=u
'Salaire précédent')
508 devise_anterieur
= models
.ForeignKey(
509 rh
.Devise
, related_name
='+', null
=True, blank
=True
511 type_contrat_anterieur
= models
.ForeignKey(
512 rh
.TypeContrat
, related_name
='+', null
=True, blank
=True,
513 verbose_name
=u
'Type contrat antérieur'
516 # Données du titulaire précédent
517 employe_anterieur
= models
.ForeignKey(
518 rh
.Employe
, related_name
='+', null
=True, blank
=True,
519 verbose_name
=u
'Employé précédent')
520 statut_titulaire_anterieur
= models
.ForeignKey(
521 rh
.Statut
, related_name
='+', null
=True, blank
=True,
522 verbose_name
=u
'Statut titulaire précédent')
523 classement_titulaire_anterieur
= models
.ForeignKey(
524 rh
.Classement
, related_name
='+', null
=True, blank
=True,
525 verbose_name
=u
'Classement titulaire précédent')
526 salaire_titulaire_anterieur
= models
.DecimalField(
527 max_digits
=12, decimal_places
=2, default
=None, null
=True,
528 blank
=True, verbose_name
=u
'Salaire titulaire précédent')
529 devise_titulaire_anterieur
= models
.ForeignKey(
530 rh
.Devise
, related_name
='+', null
=True, blank
=True
534 salaire
= models
.DecimalField(max_digits
=13, decimal_places
=2,
535 verbose_name
=u
'Salaire de base',
536 null
=True, default
=None)
537 devise
= models
.ForeignKey(rh
.Devise
, default
=5, related_name
='+')
540 type_contrat
= models
.ForeignKey(rh
.TypeContrat
, related_name
='+')
541 contrat_date_debut
= models
.DateField(help_text
=HELP_TEXT_DATE
)
542 contrat_date_fin
= models
.DateField(null
=True, blank
=True,
543 help_text
=HELP_TEXT_DATE
)
546 justif_nouveau_statut_label
= u
'Justifier le statut que ce type ' \
547 u
'de poste nécessite (national, expatrié, màd ou détachement)'
548 justif_nouveau_statut
= models
.TextField(
549 verbose_name
=justif_nouveau_statut_label
, null
=True, blank
=True
551 justif_nouveau_tmp_remplacement_label
= u
"Si l'employé effectue un " \
552 u
"remplacement temporaire, préciser"
553 justif_nouveau_tmp_remplacement
= models
.TextField(
554 verbose_name
=justif_nouveau_tmp_remplacement_label
, null
=True,
557 justif_nouveau_salaire_label
= u
"Si le salaire de l'employé ne " \
558 u
"correspond pas au classement du poste ou est différent " \
559 u
"du salaire antérieur, justifier "
560 justif_nouveau_salaire
= models
.TextField(
561 verbose_name
=justif_nouveau_salaire_label
, null
=True, blank
=True
563 justif_nouveau_commentaire_label
= u
"COMMENTAIRES ADDITIONNELS"
564 justif_nouveau_commentaire
= models
.TextField(
565 verbose_name
=justif_nouveau_commentaire_label
, null
=True, blank
=True
567 justif_rempl_type_contrat_label
= \
568 u
"Changement de type de contrat, ex : d'un CDD en CDI"
569 justif_rempl_type_contrat
= models
.TextField(
570 verbose_name
=justif_rempl_type_contrat_label
, null
=True, blank
=True
572 justif_rempl_statut_employe_label
= \
573 u
"Si le statut de l'employé a été modifié pour ce poste ; " \
574 u
"ex : national, expatrié, màd, détachement ? Si oui, justifier"
575 justif_rempl_statut_employe
= models
.TextField(
576 verbose_name
=justif_rempl_statut_employe_label
, null
=True, blank
=True
578 justif_rempl_evaluation_label
= \
579 u
"L'évaluation de l'employé est-elle favorable? Préciser"
580 justif_rempl_evaluation
= models
.TextField(
581 verbose_name
=justif_rempl_evaluation_label
, null
=True, blank
=True
583 justif_rempl_salaire_label
= \
584 u
"Si le salaire de l'employé est modifié et/ou ne correspond " \
585 u
"pas à son classement, justifier"
586 justif_rempl_salaire
= models
.TextField(
587 verbose_name
=justif_rempl_salaire_label
, null
=True, blank
=True
589 justif_rempl_commentaire_label
= u
"COMMENTAIRES ADDITIONNELS"
590 justif_rempl_commentaire
= models
.TextField(
591 verbose_name
=justif_rempl_commentaire_label
, null
=True, blank
=True
595 dae_numerisee
= models
.FileField(
596 upload_to
='dae/dae_numerisee', storage
=UPLOAD_STORAGE
, blank
=True,
597 null
=True, verbose_name
="DAE numérisée"
601 objects
= DossierManager()
603 def __init__(self
, *args
, **kwargs
):
604 # Bouchon pour créer une date fictive necessaire pour valider un
605 # dossier à cause de l'héritage
606 super(rh
.Dossier_
, self
).__init__(*args
, **kwargs
)
607 super(DossierWorkflow
, self
).__init__(*args
, **kwargs
)
609 self
.date_debut
= datetime
.datetime
.today()
611 def __unicode__(self
):
612 return u
'[%s] %s - %s' % (
613 self
.poste
.implantation
, self
.poste
.nom
, self
.employe
618 Retourne le dossier associé dans le système RH ou ``None`` s'il n'y
622 return self
.dossier_rh
624 poste_rh
= self
.poste
.dans_rh()
627 employe_rh
= self
.employe
.dans_rh()
628 if employe_rh
is None:
631 return rh
.Dossier
.objects
.get(
632 Q(date_debut
=None) |
Q(date_debut__lte
=today
),
633 Q(date_fin
=None) |
Q(date_fin__gte
=today
),
637 except rh
.Dossier
.DoesNotExist
:
640 def importer_dans_rh(self
):
642 Importe les données du dossier DAE dans un dossier RH existant ou
645 poste_rh
= self
.poste
.importer_dans_rh()
646 employe_rh
= self
.employe
.importer_dans_rh()
647 dossier_rh
= self
.dans_rh() or \
648 rh
.Dossier(poste
=poste_rh
, employe
=employe_rh
)
650 dossier_rh
.statut
= self
.statut
651 dossier_rh
.organisme_bstg
= self
.organisme_bstg
652 dossier_rh
.remplacement
= self
.remplacement
653 dossier_rh
.remplacement_de
= self
.remplacement_de
654 dossier_rh
.statut_residence
= self
.statut_residence
655 dossier_rh
.classement
= self
.classement
656 dossier_rh
.regime_travail
= self
.regime_travail
657 dossier_rh
.est_cadre
= self
.est_cadre
658 dossier_rh
.compte_compta
= self
.compte_compta
659 dossier_rh
.compte_courriel
= self
.compte_courriel
660 dossier_rh
.regime_travail_nb_heure_semaine
= \
661 self
.regime_travail_nb_heure_semaine
662 dossier_rh
.date_debut
= self
.contrat_date_debut
665 rh
.DossierComparaison
.objects
.filter(dossier
=dossier_rh
).delete()
666 for comp
in self
.dae_comparaisons
.all():
667 dossier_rh
.rh_comparaisons
.create(
668 implantation
=comp
.implantation
,
670 personne
=comp
.personne
,
671 montant
=comp
.montant
,
675 for contrat
in self
.dae_contrats
.all():
676 contrat_rh
= dossier_rh
.rh_contrats
.create(
677 type_contrat
=self
.type_contrat
,
678 date_debut
=self
.contrat_date_debut
,
679 date_fin
=self
.contrat_date_fin
,
681 contrat_rh
.fichier
.save(
682 os
.path
.basename(contrat
.fichier
.name
), contrat
.fichier
685 for piece
in self
.dae_dossierpieces
.all():
686 piece_rh
= dossier_rh
.rh_dossierpieces
.create(
689 if not settings
.DEBUG
:
690 piece_rh
.fichier
.save(
691 os
.path
.basename(piece
.fichier
.name
), piece
.fichier
694 if self
.dae_numerisee
:
695 dae_numerisee_rh
= dossier_rh
.rh_dossierpieces
.create(
698 if not settings
.DEBUG
:
699 dae_numerisee_rh
.fichier
.save(
700 os
.path
.basename(self
.dae_numerisee
.name
),
704 # Fermer les rémunérations qui commencent avant le début du contrat
705 dossier_rh
.rh_remunerations
.filter(
706 Q(date_debut
=None) |
Q(date_debut__lt
=self
.contrat_date_debut
),
707 Q(date_fin
=None) |
Q(date_fin__gte
=self
.contrat_date_debut
)
708 ).update(date_fin
=self
.contrat_date_debut
- timedelta(1))
710 # Effacer les rémunérations qui commencent à la date du contrat
711 dossier_rh
.rh_remunerations \
712 .filter(date_debut
=self
.contrat_date_debut
) \
715 for remun
in self
.dae_remunerations
.all():
716 dossier_rh
.rh_remunerations
.get_or_create(
718 type_revalorisation
=remun
.type_revalorisation
,
719 montant
=remun
.montant
,
721 commentaire
=remun
.commentaire
,
722 date_debut
=self
.contrat_date_debut
,
723 date_fin
=self
.contrat_date_fin
726 # Enregistrer le lien avec le dossier RH
727 self
.dossier_rh
= dossier_rh
732 def get_salaire_anterieur_euros(self
):
733 if self
.devise_anterieur
is None:
736 taux
= self
.taux_devise(self
.devise_anterieur
)
741 return int(round(float(self
.salaire_anterieur
) * float(taux
), 2))
743 def get_salaire_titulaire_anterieur_euros(self
):
744 if self
.devise_titulaire_anterieur
is None:
747 taux
= self
.taux_devise(self
.devise_titulaire_anterieur
)
753 float(self
.salaire_titulaire_anterieur
) * float(taux
), 2
757 return self
.etat
in (DOSSIER_ETAT_REGION_FINALISATION
,
758 DOSSIER_ETAT_DRH_FINALISATION
,
759 DOSSIER_ETAT_FINALISE
)
761 reversion
.register(Dossier
, format
='xml', follow
=[
762 'dae_dossierpieces', 'dae_comparaisons', 'dae_remunerations',
767 class DossierPiece(rh
.DossierPiece_
):
769 Documents relatifs au Dossier (à l'occupation de ce poste par employé).
770 Ex.: Lettre de motivation.
772 dossier
= models
.ForeignKey(
773 Dossier
, db_column
='dossier', related_name
='dae_dossierpieces'
776 reversion
.register(DossierPiece
, format
='xml')
779 class DossierComparaison(rh
.DossierComparaison_
):
781 Photo d'une comparaison salariale au moment de l'embauche.
783 dossier
= models
.ForeignKey(
784 Dossier
, related_name
='dae_comparaisons'
786 statut
= models
.ForeignKey(
787 rh
.Statut
, related_name
='+', verbose_name
='Statut', null
=True,
790 classement
= models
.ForeignKey(
791 rh
.Classement
, related_name
='+', verbose_name
='Classement',
792 null
=True, blank
=True
795 reversion
.register(DossierComparaison
, format
='xml')
797 class DossierComparaisonRemuneration(rh
.Remuneration_
):
798 dossier_comparaison
= models
.ForeignKey(
799 DossierComparaison
, related_name
='dossier_comparaison_remunerations'
802 reversion
.register(DossierComparaisonRemuneration
, format
='xml')
806 class Remuneration(rh
.Remuneration_
):
807 dossier
= models
.ForeignKey(
808 Dossier
, db_column
='dossier', related_name
='dae_remunerations'
811 reversion
.register(Remuneration
, format
='xml')
816 class Contrat(rh
.Contrat_
):
817 dossier
= models
.ForeignKey(
818 Dossier
, db_column
='dossier', related_name
='dae_contrats'
821 reversion
.register(Contrat
, format
='xml')
824 class ProxyDossierStatut(Dossier
):
827 verbose_name
= "Statut du dossier"
828 verbose_name_plural
= "Statut des dossiers"
831 class ProxyPosteStatut(Poste
):
834 verbose_name
= "Statut du poste"
835 verbose_name_plural
= "Statut des postes"
838 class ProxyImplantation(ref
.Implantation
):
840 # Ajout d'un manager pour ref.Implantation
841 dae_manager
= ImplantationManager()