1 # -=- encoding: utf-8 -=-
4 from datetime
import date
, timedelta
7 from auf
.django
.metadata
.models
import AUFMetadata
8 from django
.conf
import settings
9 from django
.core
.files
.storage
import FileSystemStorage
10 from django
.db
import models
11 from django
.db
.models
import Q
13 from project
.dae
.exporter
import DossierCopier
, PosteCopier
14 from project
.dae
.managers
import \
15 PosteManager
, DossierManager
, DossierFinaliseManager
, \
17 from project
.dae
.workflow
import PosteWorkflow
, DossierWorkflow
18 from project
.dae
.workflow
import \
19 DOSSIER_ETAT_DRH_FINALISATION
, DOSSIER_ETAT_REGION_FINALISATION
, \
22 # XXX: Saloperie, il faut importer rh.models à partir d'un autre namespace
23 # à cause du hack app_context() dans project.rh.models. Très fragile. Il
24 # faut régler ça aussi vite que possible.
25 from rh
import models
as rh
26 from rh
.models
import HELP_TEXT_DATE
29 UPLOAD_STORAGE
= FileSystemStorage(settings
.PRIVE_MEDIA_ROOT
)
34 POSTE_APPEL_CHOICES
= (
35 ('interne', 'Interne'),
36 ('externe', 'Externe'),
39 ('N', u
"Nouveau poste"),
40 ('M', u
"Poste existant"),
41 ('E', u
"Évolution de poste"),
45 class DeviseException(Exception):
46 silent_variable_failure
= True
49 class Poste(PosteWorkflow
, rh
.Poste_
):
51 type_intervention
= models
.CharField(
52 max_length
=1, choices
=POSTE_ACTION
, default
='N'
56 id_rh
= models
.ForeignKey(
57 rh
.Poste
, null
=True, related_name
='+', editable
=False,
58 verbose_name
=u
"Mise à jour du poste"
62 indemn_expat_min
= models
.DecimalField(
63 max_digits
=13, decimal_places
=2, default
=0
65 indemn_expat_max
= models
.DecimalField(
66 max_digits
=12, decimal_places
=2, default
=0
68 indemn_fct_min
= models
.DecimalField(
69 max_digits
=12, decimal_places
=2, default
=0
71 indemn_fct_max
= models
.DecimalField(
72 max_digits
=12, decimal_places
=2, default
=0
74 charges_patronales_min
= models
.DecimalField(
75 max_digits
=12, decimal_places
=2, default
=0
77 charges_patronales_max
= models
.DecimalField(
78 max_digits
=12, decimal_places
=2, default
=0
82 objects
= PosteManager()
86 Les vues sont montées selon une clef spéciale
87 pour identifier la provenance du poste.
88 Cette méthode fournit un moyen de reconstruire cette clef
89 afin de générer les URLs.
91 return "dae-%s" % self
.id
92 key
= property(_get_key
)
94 def get_dossiers(self
):
96 Liste tous les anciens dossiers liés à ce poste.
97 (Le nom de la relation sur le rh.Poste est mal choisi
98 poste1 au lieu de dossier1)
99 Note1 : seulement le dosssier principal fait l'objet de la recherche.
100 Note2 : les dossiers sont retournés du plus récent au plus vieux.
101 (Ce test est fait en fonction du id,
102 car les dates de création sont absentes de rh v1).
104 if self
.id_rh
is None:
106 return self
.id_rh
.rh_dossiers
.all()
108 def rh_importation(self
):
109 if ImportPoste
.objects
.filter(dae
=self
).exists():
110 return ImportPoste
.objects
.get(dae
=self
).rh
114 def importer(self
, verbosity
=0, dry_run
=False):
115 copieur
= PosteCopier(verbosity
=verbosity
, dry_run
=dry_run
)
116 return copieur
.copy(self
)
120 Retourne le poste RH s'il existe.
124 def importer_dans_rh(self
):
126 Importe le poste DAE dans un poste RH existant ou nouveau.
128 poste_rh
= self
.dans_rh() or rh
.Poste()
129 poste_rh
.nom
= self
.nom
130 poste_rh
.implantation
= self
.implantation
131 poste_rh
.type_poste
= self
.type_poste
132 poste_rh
.service
= self
.service
133 poste_rh
.responsable
= self
.responsable
134 poste_rh
.regime_travail
= self
.regime_travail
135 poste_rh
.regime_travail_nb_heure_semaine
= \
136 self
.regime_travail_nb_heure_semaine
137 poste_rh
.local
= self
.local
138 poste_rh
.expatrie
= self
.expatrie
139 poste_rh
.mise_a_disposition
= self
.mise_a_disposition
140 poste_rh
.appel
= self
.appel
141 poste_rh
.classement_min
= self
.classement_min
142 poste_rh
.classement_max
= self
.classement_max
143 poste_rh
.valeur_point_min
= self
.valeur_point_min
144 poste_rh
.valeur_point_max
= self
.valeur_point_max
145 poste_rh
.devise_min
= self
.devise_min
146 poste_rh
.devise_max
= self
.devise_max
147 poste_rh
.salaire_min
= self
.salaire_min
148 poste_rh
.salaire_max
= self
.salaire_max
149 poste_rh
.indemn_min
= self
.indemn_min
150 poste_rh
.indemn_max
= self
.indemn_max
151 poste_rh
.autre_min
= self
.autre_min
152 poste_rh
.autre_max
= self
.autre_max
153 poste_rh
.devise_comparaison
= self
.devise_comparaison
154 poste_rh
.comp_locale_min
= self
.comp_locale_min
155 poste_rh
.comp_locale_max
= self
.comp_locale_max
156 poste_rh
.comp_universite_min
= self
.comp_universite_min
157 poste_rh
.comp_universite_max
= self
.comp_universite_max
158 poste_rh
.comp_fonctionpub_min
= self
.comp_fonctionpub_min
159 poste_rh
.comp_fonctionpub_max
= self
.comp_fonctionpub_max
160 poste_rh
.comp_ong_min
= self
.comp_ong_min
161 poste_rh
.comp_ong_max
= self
.comp_ong_max
162 poste_rh
.comp_autre_min
= self
.comp_autre_min
163 poste_rh
.comp_autre_max
= self
.comp_autre_max
164 poste_rh
.justification
= self
.justification
165 poste_rh
.date_debut
= self
.date_debut
166 poste_rh
.date_fin
= self
.date_fin
169 for piece
in self
.dae_pieces
.all():
170 piece_rh
= poste_rh
.rh_pieces
.create(
174 piece_rh
.fichier
.save(
175 os
.path
.basename(piece
.fichier
.name
), piece
.fichier
178 rh
.PosteComparaison
.objects
.filter(poste
=poste_rh
).delete()
179 for comp
in self
.dae_comparaisons_internes
.all():
180 poste_rh
.rh_comparaisons_internes
.create(
181 implantation
=comp
.implantation
,
183 montant
=comp
.montant
,
187 rh
.PosteFinancement
.objects
.filter(poste
=poste_rh
).delete()
188 for financement
in self
.dae_financements
.all():
189 poste_rh
.rh_financements
.create(
190 type=financement
.type,
191 pourcentage
=financement
.pourcentage
,
192 commentaire
=financement
.commentaire
195 self
.id_rh
= poste_rh
199 def get_employe(self
):
201 Inspecte les modèles rh v1 pour trouver l'employé du dernier dossier.
203 dossiers
= self
.get_dossiers()
204 if len(dossiers
) > 0:
205 return dossiers
[0].employe
209 def get_default_devise(self
):
210 """Récupère la devise par défaut en fonction de l'implantation
214 implantation_devise
= rh
.TauxChange
.objects \
215 .filter(implantation
=self
.implantation
)[0].devise
217 implantation_devise
= 5 # EUR
218 return implantation_devise
220 #####################
221 # Classement de poste
222 #####################
224 def get_couts_minimum(self
):
225 return self
.salaire_min
+ self
.indemn_expat_min
+ \
226 self
.indemn_fct_min
+ self
.charges_patronales_min
+ \
229 def get_salaire_minimum(self
):
230 return self
.get_couts_minimum() - self
.charges_patronales_min
232 def get_taux_minimum(self
):
233 if self
.devise_min
.code
== 'EUR':
235 liste_taux
= self
.devise_min
.tauxchange_set
.order_by('-annee')
236 if len(liste_taux
) == 0:
237 raise DeviseException(
238 u
"La devise %s n'a pas de taux pour l'implantation %s" %
239 (self
.devise_min
, self
.implantation
))
241 return liste_taux
[0].taux
243 def get_couts_minimum_euros(self
):
244 return float(self
.get_couts_minimum()) * self
.get_taux_minimum()
246 def get_salaire_minimum_euros(self
):
247 return float(self
.get_salaire_minimum()) * self
.get_taux_minimum()
249 def get_couts_maximum(self
):
250 return self
.salaire_max
+ self
.indemn_expat_max
+ \
251 self
.indemn_fct_max
+ self
.charges_patronales_max
+ \
254 def get_salaire_maximum(self
):
255 return self
.get_couts_maximum() - self
.charges_patronales_max
257 def get_taux_maximum(self
):
258 if self
.devise_max
.code
== 'EUR':
260 liste_taux
= self
.devise_max
.tauxchange_set
.order_by('-annee')
261 if len(liste_taux
) == 0:
262 raise DeviseException(
263 u
"La devise %s n'a pas de taux pour l'implantation %s" %
264 (self
.devise_max
, self
.implantation
)
267 return liste_taux
[0].taux
269 def get_couts_maximum_euros(self
):
270 return float(self
.get_couts_maximum()) * self
.get_taux_maximum()
272 def get_salaire_maximum_euros(self
):
273 return float(self
.get_salaire_maximum()) * self
.get_taux_maximum()
275 def show_taux_minimum(self
):
277 return self
.get_taux_minimum()
278 except DeviseException
, e
:
281 def show_couts_minimum_euros(self
):
283 return self
.get_couts_minimum_euros()
284 except DeviseException
, e
:
287 def show_salaire_minimum_euros(self
):
289 return self
.get_salaire_minimum_euros()
290 except DeviseException
, e
:
293 def show_taux_maximum(self
):
295 return self
.get_taux_maximum()
296 except DeviseException
, e
:
299 def show_couts_maximum_euros(self
):
301 return self
.get_couts_maximum_euros()
302 except DeviseException
, e
:
305 def show_salaire_maximum_euros(self
):
307 return self
.get_salaire_maximum_euros()
308 except DeviseException
, e
:
311 # Comparaison de poste
312 def est_comparable(self
):
314 Si on a au moins une valeur de saisie dans les comparaisons, alors
315 le poste est comparable.
317 if self
.comp_universite_min
is None and \
318 self
.comp_fonctionpub_min
is None and \
319 self
.comp_locale_min
is None and \
320 self
.comp_ong_min
is None and \
321 self
.comp_autre_min
is None and \
322 self
.comp_universite_max
is None and \
323 self
.comp_fonctionpub_max
is None and \
324 self
.comp_locale_max
is None and \
325 self
.comp_ong_max
is None and \
326 self
.comp_autre_max
is None:
331 def get_taux_comparaison(self
):
333 return rh
.TauxChange
.objects \
334 .filter(devise
=self
.devise_comparaison
)[0].taux
338 def get_comp_universite_min_euros(self
):
339 return (float)(self
.comp_universite_min
) * self
.get_taux_comparaison()
341 def get_comp_fonctionpub_min_euros(self
):
342 return (float)(self
.comp_fonctionpub_min
) * self
.get_taux_comparaison()
344 def get_comp_locale_min_euros(self
):
345 return (float)(self
.comp_locale_min
) * self
.get_taux_comparaison()
347 def get_comp_ong_min_euros(self
):
348 return (float)(self
.comp_ong_min
) * self
.get_taux_comparaison()
350 def get_comp_autre_min_euros(self
):
351 return (float)(self
.comp_autre_min
) * self
.get_taux_comparaison()
353 def get_comp_universite_max_euros(self
):
354 return (float)(self
.comp_universite_max
) * self
.get_taux_comparaison()
356 def get_comp_fonctionpub_max_euros(self
):
357 return (float)(self
.comp_fonctionpub_max
) * self
.get_taux_comparaison()
359 def get_comp_locale_max_euros(self
):
360 return (float)(self
.comp_locale_max
) * self
.get_taux_comparaison()
362 def get_comp_ong_max_euros(self
):
363 return (float)(self
.comp_ong_max
) * self
.get_taux_comparaison()
365 def get_comp_autre_max_euros(self
):
366 return (float)(self
.comp_autre_max
) * self
.get_taux_comparaison()
368 def __unicode__(self
):
370 Cette fonction est consommatrice SQL car elle cherche les dossiers
371 qui ont été liés à celui-ci.
378 return u
'%s - %s (%s)' % data
380 # Tester l'enregistrement car les models.py sont importés au complet
381 if not reversion
.is_registered(Poste
):
382 reversion
.register(Poste
)
384 POSTE_FINANCEMENT_CHOICES
= (
385 ('A', 'A - Frais de personnel'),
386 ('B', 'B - Projet(s)-Titre(s)'),
391 class PosteFinancement(rh
.PosteFinancement_
):
395 class PostePiece(rh
.PostePiece_
):
399 class PosteComparaison(rh
.PosteComparaison_
):
400 statut
= models
.ForeignKey(
401 rh
.Statut
, related_name
='+', verbose_name
=u
'Statut', null
=True,
404 classement
= models
.ForeignKey(
405 rh
.Classement
, related_name
='+', verbose_name
=u
'Classement',
406 null
=True, blank
=True
411 # TODO : migration pour m -> M, f -> F
419 class Employe(AUFMetadata
):
422 id_rh
= models
.ForeignKey(rh
.Employe
, null
=True, related_name
='+',
423 verbose_name
=u
'Employé')
424 nom
= models
.CharField(max_length
=255)
425 prenom
= models
.CharField(max_length
=255, verbose_name
=u
'Prénom')
426 genre
= models
.CharField(max_length
=1, choices
=GENRE_CHOICES
)
428 def __unicode__(self
):
429 return u
'%s %s' % (self
.prenom
, self
.nom
.upper())
433 Retourne l'employé RH associé à cet employé DAE.
437 def importer_dans_rh(self
):
439 Importe l'employé DAE dans un employé RH existant ou nouveau.
441 employe_rh
= self
.dans_rh() or rh
.Employe
.objects
.create(
446 self
.id_rh
= employe_rh
453 STATUT_RESIDENCE_CHOICES
= (
455 ('expat', 'Expatrié'),
458 COMPTE_COMPTA_CHOICES
= (
465 class Dossier(DossierWorkflow
, rh
.Dossier_
):
466 poste
= models
.ForeignKey(
467 'Poste', db_column
='poste', related_name
='%(app_label)s_dossiers'
469 employe
= models
.ForeignKey(
470 'Employe', db_column
='employe',
471 related_name
='%(app_label)s_dossiers', verbose_name
=u
"Employé"
473 organisme_bstg_autre
= models
.CharField(max_length
=255,
474 verbose_name
=u
"Autre organisme",
475 help_text
="indiquer l'organisme ici s'il n'est pas dans la liste",
479 # Lien avec le dossier
480 dossier_rh
= models
.ForeignKey(
481 rh
.Dossier
, related_name
='dossiers_dae', null
=True, blank
=True
484 # Données antérieures de l'employé
485 statut_anterieur
= models
.ForeignKey(
486 rh
.Statut
, related_name
='+', null
=True, blank
=True,
487 verbose_name
=u
'Statut antérieur')
488 classement_anterieur
= models
.ForeignKey(
489 rh
.Classement
, related_name
='+', null
=True, blank
=True,
490 verbose_name
=u
'Classement précédent')
491 salaire_anterieur
= models
.DecimalField(
492 max_digits
=12, decimal_places
=2, null
=True, default
=None,
493 blank
=True, verbose_name
=u
'Salaire précédent')
494 devise_anterieur
= models
.ForeignKey(
495 rh
.Devise
, related_name
='+', null
=True, blank
=True
497 type_contrat_anterieur
= models
.ForeignKey(
498 rh
.TypeContrat
, related_name
='+', null
=True, blank
=True,
499 verbose_name
=u
'Type contrat antérieur'
502 # Données du titulaire précédent
503 employe_anterieur
= models
.ForeignKey(
504 rh
.Employe
, related_name
='+', null
=True, blank
=True,
505 verbose_name
=u
'Employé précédent')
506 statut_titulaire_anterieur
= models
.ForeignKey(
507 rh
.Statut
, related_name
='+', null
=True, blank
=True,
508 verbose_name
=u
'Statut titulaire précédent')
509 classement_titulaire_anterieur
= models
.ForeignKey(
510 rh
.Classement
, related_name
='+', null
=True, blank
=True,
511 verbose_name
=u
'Classement titulaire précédent')
512 salaire_titulaire_anterieur
= models
.DecimalField(
513 max_digits
=12, decimal_places
=2, default
=None, null
=True,
514 blank
=True, verbose_name
=u
'Salaire titulaire précédent')
515 devise_titulaire_anterieur
= models
.ForeignKey(
516 rh
.Devise
, related_name
='+', null
=True, blank
=True
520 salaire
= models
.DecimalField(max_digits
=13, decimal_places
=2,
521 verbose_name
=u
'Salaire de base',
522 null
=True, default
=None)
523 devise
= models
.ForeignKey(rh
.Devise
, default
=5, related_name
='+')
526 type_contrat
= models
.ForeignKey(rh
.TypeContrat
, related_name
='+')
527 contrat_date_debut
= models
.DateField(help_text
=HELP_TEXT_DATE
)
528 contrat_date_fin
= models
.DateField(null
=True, blank
=True,
529 help_text
=HELP_TEXT_DATE
)
532 justif_nouveau_statut_label
= u
'Justifier le statut que ce type ' \
533 u
'de poste nécessite (national, expatrié, màd ou détachement)'
534 justif_nouveau_statut
= models
.TextField(
535 verbose_name
=justif_nouveau_statut_label
, null
=True, blank
=True
537 justif_nouveau_tmp_remplacement_label
= u
"Si l'employé effectue un " \
538 u
"remplacement temporaire, préciser"
539 justif_nouveau_tmp_remplacement
= models
.TextField(
540 verbose_name
=justif_nouveau_tmp_remplacement_label
, null
=True,
543 justif_nouveau_salaire_label
= u
"Si le salaire de l'employé ne " \
544 u
"correspond pas au classement du poste ou est différent " \
545 u
"du salaire antérieur, justifier "
546 justif_nouveau_salaire
= models
.TextField(
547 verbose_name
=justif_nouveau_salaire_label
, null
=True, blank
=True
549 justif_nouveau_commentaire_label
= u
"COMMENTAIRES ADDITIONNELS"
550 justif_nouveau_commentaire
= models
.TextField(
551 verbose_name
=justif_nouveau_commentaire_label
, null
=True, blank
=True
553 justif_rempl_type_contrat_label
= \
554 u
"Changement de type de contrat, ex : d'un CDD en CDI"
555 justif_rempl_type_contrat
= models
.TextField(
556 verbose_name
=justif_rempl_type_contrat_label
, null
=True, blank
=True
558 justif_rempl_statut_employe_label
= \
559 u
"Si le statut de l'employé a été modifié pour ce poste ; " \
560 u
"ex : national, expatrié, màd, détachement ? Si oui, justifier"
561 justif_rempl_statut_employe
= models
.TextField(
562 verbose_name
=justif_rempl_statut_employe_label
, null
=True, blank
=True
564 justif_rempl_evaluation_label
= \
565 u
"L'évaluation de l'employé est-elle favorable? Préciser"
566 justif_rempl_evaluation
= models
.TextField(
567 verbose_name
=justif_rempl_evaluation_label
, null
=True, blank
=True
569 justif_rempl_salaire_label
= \
570 u
"Si le salaire de l'employé est modifié et/ou ne correspond " \
571 u
"pas à son classement, justifier"
572 justif_rempl_salaire
= models
.TextField(
573 verbose_name
=justif_rempl_salaire_label
, null
=True, blank
=True
575 justif_rempl_commentaire_label
= u
"COMMENTAIRES ADDITIONNELS"
576 justif_rempl_commentaire
= models
.TextField(
577 verbose_name
=justif_rempl_commentaire_label
, null
=True, blank
=True
581 compte_compta
= models
.CharField(max_length
=10, default
='aucun',
582 verbose_name
=u
'Compte comptabilité',
583 choices
=COMPTE_COMPTA_CHOICES
)
584 compte_courriel
= models
.BooleanField()
587 dae_numerisee
= models
.FileField(
588 upload_to
='dae/dae_numerisee', storage
=UPLOAD_STORAGE
, blank
=True,
589 null
=True, verbose_name
="DAE numérisée"
593 objects
= DossierManager()
595 def __init__(self
, *args
, **kwargs
):
596 # Bouchon pour créer une date fictive necessaire pour valider un
597 # dossier à cause de l'héritage
598 super(rh
.Dossier_
, self
).__init__(*args
, **kwargs
)
599 super(DossierWorkflow
, self
).__init__(*args
, **kwargs
)
601 self
.date_debut
= datetime
.datetime
.today()
603 def __unicode__(self
):
604 return u
'[%s] %s - %s' % (
605 self
.poste
.implantation
, self
.poste
.nom
, self
.employe
608 def importer(self
, verbosity
=0, dry_run
=False):
609 copieur
= DossierCopier(verbosity
=verbosity
, dry_run
=dry_run
)
610 return copieur
.copy(self
)
614 Retourne le dossier associé dans le système RH ou ``None`` s'il n'y
618 return self
.dossier_rh
620 poste_rh
= self
.poste
.dans_rh()
623 employe_rh
= self
.employe
.dans_rh()
624 if employe_rh
is None:
627 return rh
.Dossier
.objects
.get(
628 Q(date_debut
=None) |
Q(date_debut__lte
=today
),
629 Q(date_fin
=None) |
Q(date_fin__gte
=today
),
633 except rh
.Dossier
.DoesNotExist
:
636 def importer_dans_rh(self
):
638 Importe les données du dossier DAE dans un dossier RH existant ou
641 poste_rh
= self
.poste
.importer_dans_rh()
642 employe_rh
= self
.employe
.importer_dans_rh()
643 dossier_rh
= self
.dans_rh() or \
644 rh
.Dossier(poste
=poste_rh
, employe
=employe_rh
)
646 dossier_rh
.statut
= self
.statut
647 dossier_rh
.organisme_bstg
= self
.organisme_bstg
648 dossier_rh
.remplacement
= self
.remplacement
649 dossier_rh
.remplacement_de
= self
.remplacement_de
650 dossier_rh
.statut_residence
= self
.statut_residence
651 dossier_rh
.classement
= self
.classement
652 dossier_rh
.regime_travail
= self
.regime_travail
653 dossier_rh
.regime_travail_nb_heure_semaine
= \
654 self
.regime_travail_nb_heure_semaine
655 dossier_rh
.date_debut
= self
.date_debut
656 dossier_rh
.date_fin
= self
.date_fin
659 rh
.DossierComparaison
.objects
.filter(dossier
=dossier_rh
).delete()
660 for comp
in self
.dae_comparaisons
.all():
661 dossier_rh
.rh_comparaisons
.create(
662 implantation
=comp
.implantation
,
664 personne
=comp
.personne
,
665 montant
=comp
.montant
,
669 if not dossier_rh
.rh_contrats
.filter(
670 type_contrat
=self
.type_contrat
,
671 date_debut
=self
.contrat_date_debut
,
672 date_fin
=self
.contrat_date_fin
674 dossier_rh
.rh_contrats
.create(
675 type_contrat
=self
.type_contrat
,
676 date_debut
=self
.contrat_date_debut
,
677 date_fin
=self
.contrat_date_fin
,
680 for piece
in self
.dae_dossierpieces
.all():
681 piece_rh
= dossier_rh
.rh_dossierpieces
.create(
684 piece_rh
.fichier
.save(
685 os
.path
.basename(piece
.fichier
.name
), piece
.fichier
688 # Fermer les rémunérations qui commencent avant le début du contrat
689 dossier_rh
.rh_remunerations
.filter(
690 Q(date_debut
=None) |
Q(date_debut__lt
=self
.contrat_date_debut
),
691 Q(date_fin
=None) |
Q(date_fin__gte
=self
.contrat_date_debut
)
692 ).update(date_fin
=self
.contrat_date_debut
- timedelta(1))
694 # Effacer les rémunérations qui commencent à la date du contrat
695 dossier_rh
.rh_remunerations \
696 .filter(date_debut
=self
.contrat_date_debut
) \
699 for remun
in self
.dae_remunerations
.all():
700 dossier_rh
.rh_remunerations
.get_or_create(
702 type_revalorisation
=remun
.type_revalorisation
,
703 montant
=remun
.montant
,
705 commentaire
=remun
.commentaire
,
706 date_debut
=self
.contrat_date_debut
,
707 date_fin
=self
.contrat_date_fin
710 # Enregistrer le lien avec le dossier RH
711 self
.dossier_rh
= dossier_rh
716 def get_salaire_anterieur_euros(self
):
717 if self
.devise_anterieur
is None:
720 taux
= self
.taux_devise(self
.devise_anterieur
)
725 return int(round(float(self
.salaire_anterieur
) * float(taux
), 2))
727 def get_salaire_titulaire_anterieur_euros(self
):
728 if self
.devise_titulaire_anterieur
is None:
731 taux
= self
.taux_devise(self
.devise_titulaire_anterieur
)
737 float(self
.salaire_titulaire_anterieur
) * float(taux
), 2
741 return self
.etat
in (DOSSIER_ETAT_REGION_FINALISATION
,
742 DOSSIER_ETAT_DRH_FINALISATION
,
743 DOSSIER_ETAT_FINALISE
)
746 # Tester l'enregistrement car les models.py sont importés au complet
747 if not reversion
.is_registered(Dossier
):
748 reversion
.register(Dossier
)
751 class DossierPiece(rh
.DossierPiece_
):
752 """Documents relatifs au Dossier (à l'occupation de ce poste par employé).
753 Ex.: Lettre de motivation.
758 class DossierComparaison(rh
.DossierComparaison_
):
760 Photo d'une comparaison salariale au moment de l'embauche.
762 statut
= models
.ForeignKey(
763 rh
.Statut
, related_name
='+', verbose_name
='Statut', null
=True,
766 classement
= models
.ForeignKey(
767 rh
.Classement
, related_name
='+', verbose_name
='Classement',
768 null
=True, blank
=True
774 class Remuneration(rh
.Remuneration_
):
780 class Contrat(rh
.Contrat_
):
784 class DossierFinalise(Dossier
):
786 objects
= DossierFinaliseManager()
790 verbose_name
= "Import d'un dossier dans RH"
791 verbose_name_plural
= "Import des dossiers dans RH"
794 class PosteFinalise(Poste
):
796 objects
= PosteFinaliseManager()
800 verbose_name
= "Import d'un poste dans RH"
801 verbose_name_plural
= "Import des postes dans RH"
804 # modèle de liaison entre les systèmes
806 class ImportDossier(models
.Model
):
807 dae
= models
.ForeignKey('dae.Dossier', related_name
='+')
808 rh
= models
.ForeignKey('rh.Dossier', related_name
='+')
811 class ImportPoste(models
.Model
):
812 dae
= models
.ForeignKey('dae.Poste', related_name
='+')
813 rh
= models
.ForeignKey('rh.Poste', related_name
='+')