import DAE
[auf_rh_dae.git] / project / dae / models.py
CommitLineData
bd28238f 1# -=- encoding: utf-8 -=-
3f3cf5f3 2
5633fa41 3from django.conf import settings
36341125 4from django.core.files.storage import FileSystemStorage
a9c281dd
OL
5from django.db import models
6import reversion
3f5cbabe 7from rh import models as rh
afc204bf 8from workflow import PosteWorkflow, DossierWorkflow
c511cd1f
EMS
9from workflow import DOSSIER_ETAT_DRH_FINALISATION, DOSSIER_ETAT_REGION_FINALISATION, \
10 DOSSIER_ETAT_FINALISE
a2c3ad52 11from auf.django.metadata.models import AUFMetadata
3f5cbabe 12from managers import *
4047b783 13from rh.models import HELP_TEXT_DATE
47d7067b 14from exporter import DossierCopier, PosteCopier
bd28238f 15
d766bf2c 16# Upload de fichiers
34dad720 17UPLOAD_STORAGE = FileSystemStorage(settings.PRIVE_MEDIA_ROOT)
d766bf2c 18
36341125 19
2d4d2fcf 20### POSTE
21
22POSTE_APPEL_CHOICES = (
23 ('interne', 'Interne'),
24 ('externe', 'Externe'),
25)
c3be904d
OL
26POSTE_ACTION = (
27 ('N', u"Nouveau poste"),
28 ('M', u"Poste existant"),
29 ('E', u"Évolution de poste"),
30)
31
36341125 32
ae5c920b
OL
33class DeviseException(Exception):
34 silent_variable_failure = True
35
1c7d67ce 36
3f5cbabe 37class Poste(PosteWorkflow, rh.Poste_):
c3be904d
OL
38
39 type_intervention = models.CharField(max_length=1, choices=POSTE_ACTION, default='N')
40
bd28238f 41 # Modèle existant
5d680e84 42 id_rh = models.ForeignKey(rh.Poste, null=True, related_name='+',
2d4d2fcf 43 editable=False,
c1195471 44 verbose_name=u"Mise à jour du poste")
bd28238f
NC
45
46 # Rémunération
3f5cbabe 47 indemn_expat_min = models.DecimalField(max_digits=13, decimal_places=2, default=0)
5f61bccb
OL
48 indemn_expat_max = models.DecimalField(max_digits=12, decimal_places=2, default=0)
49 indemn_fct_min = models.DecimalField(max_digits=12, decimal_places=2, default=0)
50 indemn_fct_max = models.DecimalField(max_digits=12, decimal_places=2, default=0)
51 charges_patronales_min = models.DecimalField(max_digits=12, decimal_places=2, default=0)
52 charges_patronales_max = models.DecimalField(max_digits=12, decimal_places=2, default=0)
bd28238f 53
1c7d67ce
OL
54 # Managers
55 objects = PosteManager()
56
47d7067b
OL
57 def importer(self, verbosity=0, dry_run=False):
58 copieur = PosteCopier(verbosity=verbosity, dry_run=dry_run)
59 return copieur.duplicate(self)
317ce433 60
03858ba5
OL
61 def _get_key(self):
62 """
1bc84af4 63 Les vues sont montées selon une clef spéciale
2d4d2fcf 64 pour identifier la provenance du poste.
1bc84af4 65 Cette méthode fournit un moyen de reconstruire cette clef
2d4d2fcf 66 afin de générer les URLs.
03858ba5
OL
67 """
68 return "dae-%s" % self.id
69 key = property(_get_key)
70
f3333b0e
OL
71 def get_dossiers(self):
72 """
73 Liste tous les anciens dossiers liés à ce poste.
1bc84af4 74 (Le nom de la relation sur le rh.Poste est mal choisi
2d4d2fcf 75 poste1 au lieu de dossier1)
f3333b0e 76 Note1 : seulement le dosssier principal fait l'objet de la recherche.
1bc84af4
EMS
77 Note2 : les dossiers sont retournés du plus récent au plus vieux.
78 (Ce test est fait en fonction du id,
2d4d2fcf 79 car les dates de création sont absentes de rh v1).
f3333b0e
OL
80 """
81 if self.id_rh is None:
82 return []
16b1454e 83 return self.id_rh.rh_dossiers.all()
428e3c0b 84
f3333b0e
OL
85
86 def get_employe(self):
87 """
88 Inspecte les modèles rh v1 pour trouver l'employé du dernier dossier.
89 """
90 dossiers = self.get_dossiers()
91 if len(dossiers) > 0:
92 return dossiers[0].employe
93 else:
94 return None
95
179f6b49 96 def get_default_devise(self):
1bc84af4 97 """Récupère la devise par défaut en fonction de l'implantation
2d4d2fcf 98 (EUR autrement)
99 """
179f6b49 100 try:
6e4600ef 101 implantation_devise = rh.TauxChange.objects \
102 .filter(implantation=self.implantation)[0].devise
179f6b49
OL
103 except:
104 implantation_devise = 5 # EUR
105 return implantation_devise
106
c0413a6f
OL
107 #####################
108 # Classement de poste
109 #####################
110
111 def get_couts_minimum(self):
83b94a87
EMS
112 return self.salaire_min + self.indemn_expat_min + self.indemn_fct_min + self.charges_patronales_min + self.autre_min
113
114 def get_salaire_minimum(self):
115 return self.get_couts_minimum() - self.charges_patronales_min
c0413a6f
OL
116
117 def get_taux_minimum(self):
4e439a89
OL
118 if self.devise_min.code == 'EUR':
119 return 1
2455f48d 120 liste_taux = self.devise_min.tauxchange_set.order_by('-annee')
4e439a89
OL
121 if len(liste_taux) == 0:
122 raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise_min, self.implantation))
b6825282 123 else:
4e439a89 124 return liste_taux[0].taux
c0413a6f
OL
125
126 def get_couts_minimum_euros(self):
fa5b95ed 127 return float(self.get_couts_minimum()) * self.get_taux_minimum()
c0413a6f 128
83b94a87 129 def get_salaire_minimum_euros(self):
fa5b95ed 130 return float(self.get_salaire_minimum()) * self.get_taux_minimum()
83b94a87 131
c0413a6f 132 def get_couts_maximum(self):
83b94a87
EMS
133 return self.salaire_max + self.indemn_expat_max + self.indemn_fct_max + self.charges_patronales_max + self.autre_max
134
135 def get_salaire_maximum(self):
136 return self.get_couts_maximum() - self.charges_patronales_max
c0413a6f
OL
137
138 def get_taux_maximum(self):
4e439a89
OL
139 if self.devise_max.code == 'EUR':
140 return 1
2455f48d 141 liste_taux = self.devise_max.tauxchange_set.order_by('-annee')
4e439a89
OL
142 if len(liste_taux) == 0:
143 raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise_max, self.implantation))
b6825282 144 else:
4e439a89 145 return liste_taux[0].taux
c0413a6f
OL
146
147 def get_couts_maximum_euros(self):
fa5b95ed 148 return float(self.get_couts_maximum()) * self.get_taux_maximum()
c0413a6f 149
83b94a87 150 def get_salaire_maximum_euros(self):
fa5b95ed 151 return float(self.get_salaire_maximum()) * self.get_taux_maximum()
12c7f8a7
OL
152
153 def show_taux_minimum(self):
154 try:
155 return self.get_taux_minimum()
83b94a87 156 except DeviseException, e:
12c7f8a7
OL
157 return e
158
159 def show_couts_minimum_euros(self):
160 try:
161 return self.get_couts_minimum_euros()
83b94a87
EMS
162 except DeviseException, e:
163 return e
164
165 def show_salaire_minimum_euros(self):
166 try:
167 return self.get_salaire_minimum_euros()
168 except DeviseException, e:
12c7f8a7
OL
169 return e
170
171 def show_taux_maximum(self):
172 try:
173 return self.get_taux_maximum()
83b94a87 174 except DeviseException, e:
12c7f8a7
OL
175 return e
176
177 def show_couts_maximum_euros(self):
178 try:
179 return self.get_couts_maximum_euros()
83b94a87
EMS
180 except DeviseException, e:
181 return e
182
183 def show_salaire_maximum_euros(self):
184 try:
185 return self.get_salaire_maximum_euros()
186 except DeviseException, e:
12c7f8a7
OL
187 return e
188
189
c0413a6f
OL
190 ######################
191 # Comparaison de poste
192 ######################
a3fee9c5
OL
193
194 def est_comparable(self):
195 """
196 Si on a au moins une valeur de saisie dans les comparaisons, alors le poste
197 est comparable.
198 """
199 if self.comp_universite_min is None and \
200 self.comp_fonctionpub_min is None and \
201 self.comp_locale_min is None and \
202 self.comp_ong_min is None and \
203 self.comp_autre_min is None and \
204 self.comp_universite_max is None and \
205 self.comp_fonctionpub_max is None and \
206 self.comp_locale_max is None and \
207 self.comp_ong_max is None and \
208 self.comp_autre_max is None:
209 return False
210 else:
211 return True
1bc84af4 212
a3fee9c5 213
c0413a6f
OL
214 def get_taux_comparaison(self):
215 try:
2455f48d 216 return rh.TauxChange.objects.filter(devise=self.devise_comparaison)[0].taux
c0413a6f
OL
217 except:
218 return 1
219
220 def get_comp_universite_min_euros(self):
221 return (float)(self.comp_universite_min) * self.get_taux_comparaison()
222
223 def get_comp_fonctionpub_min_euros(self):
224 return (float)(self.comp_fonctionpub_min) * self.get_taux_comparaison()
225
226 def get_comp_locale_min_euros(self):
227 return (float)(self.comp_locale_min) * self.get_taux_comparaison()
228
229 def get_comp_ong_min_euros(self):
230 return (float)(self.comp_ong_min) * self.get_taux_comparaison()
231
232 def get_comp_autre_min_euros(self):
233 return (float)(self.comp_autre_min) * self.get_taux_comparaison()
234
235 def get_comp_universite_max_euros(self):
236 return (float)(self.comp_universite_max) * self.get_taux_comparaison()
237
238 def get_comp_fonctionpub_max_euros(self):
239 return (float)(self.comp_fonctionpub_max) * self.get_taux_comparaison()
240
241 def get_comp_locale_max_euros(self):
242 return (float)(self.comp_locale_max) * self.get_taux_comparaison()
243
244 def get_comp_ong_max_euros(self):
245 return (float)(self.comp_ong_max) * self.get_taux_comparaison()
246
247 def get_comp_autre_max_euros(self):
248 return (float)(self.comp_autre_max) * self.get_taux_comparaison()
249
a9e52624 250
5d680e84 251 def __unicode__(self):
f3333b0e 252 """
1bc84af4 253 Cette fonction est consommatrice SQL car elle cherche les dossiers
2d4d2fcf 254 qui ont été liés à celui-ci.
f3333b0e 255 """
f3333b0e
OL
256 data = (
257 self.implantation,
258 self.type_poste.nom,
259 self.nom,
f3333b0e 260 )
a7c68130 261 return u'%s - %s (%s)' % data
5d680e84 262
bd28238f 263
a9c281dd
OL
264# Tester l'enregistrement car les models.py sont importés au complet
265if not reversion.is_registered(Poste):
266 reversion.register(Poste)
267
bd28238f 268
5d680e84
NC
269POSTE_FINANCEMENT_CHOICES = (
270 ('A', 'A - Frais de personnel'),
271 ('B', 'B - Projet(s)-Titre(s)'),
272 ('C', 'C - Autre')
273)
bd28238f 274
317ce433 275class PosteFinancement(rh.PosteFinancement_):
a4125771 276 pass
1d0f4eef 277
317ce433 278class PostePiece(rh.PostePiece_):
a4125771 279 pass
068d1462 280
317ce433 281class PosteComparaison(rh.PosteComparaison_):
766ca378
OL
282 statut = models.ForeignKey(rh.Statut, related_name='+', verbose_name=u'Statut', null=True, blank=True, )
283 classement = models.ForeignKey(rh.Classement, related_name='+', verbose_name=u'Classement', null=True, blank=True, )
068d1462 284
2d4d2fcf 285### EMPLOYÉ/PERSONNE
286
287# TODO : migration pour m -> M, f -> F
c589d980 288
bd28238f 289GENRE_CHOICES = (
139686f2
NC
290 ('m', 'Homme'),
291 ('f', 'Femme'),
bd28238f
NC
292)
293
a2c3ad52 294class Employe(AUFMetadata):
bd28238f
NC
295
296 # Modèle existant
428e3c0b 297 id_rh = models.ForeignKey(rh.Employe, null=True, related_name='+',
c1195471 298 verbose_name=u'Employé')
bd28238f 299 nom = models.CharField(max_length=255)
c1195471 300 prenom = models.CharField(max_length=255, verbose_name=u'Prénom')
07b40eda 301 genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
bd28238f 302
139686f2 303 def __unicode__(self):
2d4d2fcf 304 return u'%s %s' % (self.prenom, self.nom.upper())
139686f2 305
bd28238f 306
2d4d2fcf 307### DOSSIER
308
309STATUT_RESIDENCE_CHOICES = (
310 ('local', 'Local'),
311 ('expat', 'Expatrié'),
312)
313
bd28238f 314COMPTE_COMPTA_CHOICES = (
494ff2be
NC
315 ('coda', 'CODA'),
316 ('scs', 'SCS'),
317 ('aucun', 'Aucun'),
bd28238f
NC
318)
319
16b1454e
OL
320class Dossier(DossierWorkflow, rh.Dossier_):
321 poste = models.ForeignKey('Poste', db_column='poste', related_name='%(app_label)s_dossiers')
322 employe = models.ForeignKey('Employe', db_column='employe',
323 related_name='%(app_label)s_dossiers',
324 verbose_name=u"Employé")
0288adb5 325 organisme_bstg_autre = models.CharField(max_length=255,
c1195471 326 verbose_name=u"Autre organisme",
0288adb5
OL
327 help_text="indiquer l'organisme ici s'il n'est pas dans la liste",
328 null=True,
329 blank=True,)
bd28238f 330
139686f2
NC
331 # Données antérieures de l'employé
332 statut_anterieur = models.ForeignKey(
333 rh.Statut, related_name='+', null=True, blank=True,
c1195471 334 verbose_name=u'Statut antérieur')
139686f2
NC
335 classement_anterieur = models.ForeignKey(
336 rh.Classement, related_name='+', null=True, blank=True,
c1195471 337 verbose_name=u'Classement précédent')
139686f2
NC
338 salaire_anterieur = models.DecimalField(
339 max_digits=12, decimal_places=2, null=True, default=None,
481fbd33 340 blank=True, verbose_name=u'Salaire précédent')
e158c6de
DB
341 devise_anterieur = models.ForeignKey(rh.Devise, related_name='+',
342 null=True, blank=True)
343 type_contrat_anterieur = models.ForeignKey(rh.TypeContrat,
344 related_name='+', null=True, blank=True,
345 verbose_name=u'Type contrat antérieur', )
139686f2
NC
346
347 # Données du titulaire précédent
348 employe_anterieur = models.ForeignKey(
349 rh.Employe, related_name='+', null=True, blank=True,
c1195471 350 verbose_name=u'Employé précédent')
139686f2
NC
351 statut_titulaire_anterieur = models.ForeignKey(
352 rh.Statut, related_name='+', null=True, blank=True,
c1195471 353 verbose_name=u'Statut titulaire précédent')
139686f2
NC
354 classement_titulaire_anterieur = models.ForeignKey(
355 rh.Classement, related_name='+', null=True, blank=True,
c1195471 356 verbose_name=u'Classement titulaire précédent')
139686f2
NC
357 salaire_titulaire_anterieur = models.DecimalField(
358 max_digits=12, decimal_places=2, default=None, null=True,
481fbd33 359 blank=True, verbose_name=u'Salaire titulaire précédent')
f8c7c0b8 360 devise_titulaire_anterieur = models.ForeignKey(rh.Devise, related_name='+', null=True, blank=True)
494ff2be 361
bd28238f 362 # Rémunération
16b1454e 363 salaire = models.DecimalField(max_digits=13, decimal_places=2,
c1195471 364 verbose_name=u'Salaire de base',
2d4d2fcf 365 null=True, default=None)
e8e75458 366 devise = models.ForeignKey(rh.Devise, default=5, related_name='+')
bd28238f
NC
367
368 # Contrat
5d680e84 369 type_contrat = models.ForeignKey(rh.TypeContrat, related_name='+')
b666864e 370 contrat_date_debut = models.DateField(help_text=HELP_TEXT_DATE)
1f109689 371 contrat_date_fin = models.DateField(null=True, blank=True,
b666864e 372 help_text=HELP_TEXT_DATE)
bd28238f 373
29dffede
OL
374 # Justifications
375 justif_nouveau_statut_label = u'Justifier le statut que ce type de poste nécessite (national, expatrié, màd ou détachement)'
376 justif_nouveau_statut = models.TextField(verbose_name=justif_nouveau_statut_label, null=True, blank=True)
a83daab3 377 justif_nouveau_tmp_remplacement_label = u"Si l'employé effectue un remplacement temporaire, préciser"
29dffede 378 justif_nouveau_tmp_remplacement = models.TextField(verbose_name=justif_nouveau_tmp_remplacement_label, null=True, blank=True)
a83daab3 379 justif_nouveau_salaire_label = u"Si le salaire de l'employé ne correspond pas au classement du poste ou est différent du salaire antérieur, justifier "
29dffede 380 justif_nouveau_salaire = models.TextField(verbose_name=justif_nouveau_salaire_label, null=True, blank=True)
a83daab3 381 justif_nouveau_commentaire_label = u"COMMENTAIRES ADDITIONNELS"
29dffede
OL
382 justif_nouveau_commentaire = models.TextField(verbose_name=justif_nouveau_commentaire_label, null=True, blank=True)
383 justif_rempl_type_contrat_label = u"Changement de type de contrat, ex : d'un CDD en CDI"
384 justif_rempl_type_contrat = models.TextField(verbose_name=justif_rempl_type_contrat_label, null=True, blank=True)
a83daab3 385 justif_rempl_statut_employe_label = u"Si le statut de l'employé a été modifié pour ce poste ; ex :national, expatrié, màd, détachement ? Si oui, justifier"
29dffede 386 justif_rempl_statut_employe = models.TextField(verbose_name=justif_rempl_statut_employe_label, null=True, blank=True)
a83daab3 387 justif_rempl_evaluation_label = u"L'évaluation de l'employé est-elle favorable? Préciser"
29dffede
OL
388 justif_rempl_evaluation = models.TextField(verbose_name=justif_rempl_evaluation_label, null=True, blank=True)
389 justif_rempl_salaire_label = u"Si le salaire de l'employé est modifié et/ou ne correspond pas à son classement, justifier"
390 justif_rempl_salaire = models.TextField(verbose_name=justif_rempl_salaire_label, null=True, blank=True)
a83daab3 391 justif_rempl_commentaire_label = u"COMMENTAIRES ADDITIONNELS"
29dffede
OL
392 justif_rempl_commentaire = models.TextField(verbose_name=justif_rempl_commentaire_label, null=True, blank=True)
393
bd28238f 394 # Comptes
dfc2c344 395 compte_compta = models.CharField(max_length=10, default='aucun',
396 verbose_name=u'Compte comptabilité',
397 choices=COMPTE_COMPTA_CHOICES)
bd28238f 398 compte_courriel = models.BooleanField()
428e3c0b 399
c3f0b49f
EMS
400 # DAE numérisée
401 dae_numerisee = models.FileField(upload_to='dae/dae_numerisee', storage=UPLOAD_STORAGE,
5be87e56 402 blank=True, null=True, verbose_name="DAE numérisée")
c3f0b49f 403
e4f56614
OL
404 # Managers
405 objects = DossierManager()
428e3c0b 406
16b1454e
OL
407 def __init__(self, *args, **kwargs):
408 # Bouchon pour créer une date fictive necessaire pour valider un dossier
409 # à cause de l'héritage
410 super(rh.Dossier_, self).__init__(*args, **kwargs)
411 super(DossierWorkflow, self).__init__(*args, **kwargs)
412 import datetime
413 self.date_debut = datetime.datetime.today()
414
aec2c91e 415 def __unicode__(self):
e4f56614 416 return u'[%s] %s - %s' % (self.poste.implantation, self.poste.nom, self.employe)
bd28238f 417
47d7067b
OL
418 def importer(self, verbosity=0, dry_run=False):
419 copieur = DossierCopier(verbosity=verbosity, dry_run=dry_run)
420 return copieur.duplicate(self)
317ce433 421
eed93931 422 def get_salaire_anterieur_euros(self):
88a0e98d
OL
423 if self.devise_anterieur is None:
424 return None
03ff41e3
OL
425 try:
426 taux = self.taux_devise(self.devise_anterieur)
427 except Exception, e:
428 return e
429 if not taux:
430 return None
431 return int(round(float(self.salaire_anterieur) * float(taux), 2))
432
eed93931
OL
433
434 def get_salaire_titulaire_anterieur_euros(self):
16b1454e
OL
435 if self.devise_titulaire_anterieur is None:
436 return None
03ff41e3 437 try:
88a0e98d 438 taux = self.taux_devise(self.devise_titulaire_anterieur)
03ff41e3
OL
439 except Exception, e:
440 return e
441 if not taux:
16b1454e 442 return None
03ff41e3 443 return int(round(float(self.salaire_titulaire_anterieur) * float(taux), 2))
eed93931 444
b1baa306 445 def get_salaire_euros(self):
a7186cbb 446 tx = self.taux_devise()
b1baa306
OL
447 return (float)(tx) * (float)(self.salaire)
448
bf6fbbcf 449 def get_remunerations_brutes(self):
57bd966c 450 """
bf6fbbcf
OL
451 1 Salaire de base
452 3 Indemnité de base
453 4 Indemnité d'expatriation
454 5 Indemnité pour frais
455 6 Indemnité de logement
456 7 Indemnité de fonction
457 8 Indemnité de responsabilité
458 9 Indemnité de transport
459 10 Indemnité compensatrice
460 11 Indemnité de subsistance
461 12 Indemnité différentielle
462 13 Prime d'installation
463 14 Billet d'avion
464 15 Déménagement
465 16 Indemnité de départ
466 18 Prime de 13ième mois
467 19 Prime d'intérim
57bd966c 468 """
bf6fbbcf 469 ids = [1,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,19]
a4125771 470 return [r for r in self.dae_remunerations.all() if r.type_id in ids]
bf6fbbcf
OL
471
472 def get_charges_salariales(self):
473 """
474 20 Charges salariales ?
475 """
476 ids = [20, ]
a4125771 477 return [r for r in self.dae_remunerations.all() if r.type_id in ids]
bf6fbbcf
OL
478
479 def get_total_charges_salariales(self):
480 total = 0.0
481 for r in self.get_charges_salariales():
e84c8ef1 482 total += r.montant_euros()
bf6fbbcf
OL
483 return total
484
485 def get_charges_patronales(self):
486 """
487 17 Charges patronales
488 """
489 ids = [17, ]
a4125771 490 return [r for r in self.dae_remunerations.all() if r.type_id in ids]
bf6fbbcf
OL
491
492 def get_total_charges_patronales(self):
a9e52624 493 total = 0.0
bf6fbbcf 494 for r in self.get_charges_patronales():
e84c8ef1 495 total += r.montant_euros()
a9e52624 496 return total
57bd966c 497
bf6fbbcf
OL
498 def get_salaire_brut(self):
499 """
500 somme des rémuérations brutes
501 """
502 total = 0.0
503 for r in self.get_remunerations_brutes():
e84c8ef1 504 total += r.montant_euros()
bf6fbbcf
OL
505 return total
506
507 def get_salaire_net(self):
508 """
509 salaire brut - charges salariales
510 """
511 total_charges = 0.0
512 for r in self.get_charges_salariales():
e84c8ef1 513 total_charges += r.montant_euros()
bf6fbbcf
OL
514 return self.get_salaire_brut() - total_charges
515
516 def get_couts_auf(self):
517 """
518 salaire net + charges patronales
519 """
520 total_charges = 0.0
521 for r in self.get_charges_patronales():
e84c8ef1 522 total_charges += r.montant_euros()
bf6fbbcf
OL
523 return self.get_salaire_net() + total_charges
524
525 def get_remunerations_tierces(self):
57bd966c 526 """
bf6fbbcf 527 2 Salaire MAD
57bd966c 528 """
a4125771 529 return [r for r in self.dae_remunerations.all() if r.type_id in (2, )]
57bd966c 530
bf6fbbcf 531 def get_total_remunerations_tierces(self):
a9e52624 532 total = 0.0
1bc84af4 533 for r in self.get_remunerations_tierces():
e84c8ef1 534 total += r.montant_euros()
a9e52624
OL
535 return total
536
c511cd1f
EMS
537 def valide(self):
538 return self.etat in (DOSSIER_ETAT_REGION_FINALISATION,
539 DOSSIER_ETAT_DRH_FINALISATION,
540 DOSSIER_ETAT_FINALISE)
541
bd28238f 542
0140cbd2 543# Tester l'enregistrement car les models.py sont importés au complet
544if not reversion.is_registered(Dossier):
545 reversion.register(Dossier)
bd28238f 546
a4125771 547class DossierPiece(rh.DossierPiece_):
2d4d2fcf 548 """Documents relatifs au Dossier (à l'occupation de ce poste par employé).
549 Ex.: Lettre de motivation.
550 """
a4125771 551 pass
2d4d2fcf 552
a4125771 553class DossierComparaison(rh.DossierComparaison_):
03b395db
OL
554 """
555 Photo d'une comparaison salariale au moment de l'embauche.
556 """
766ca378
OL
557 statut = models.ForeignKey(rh.Statut, related_name='+', verbose_name='Statut', null=True, blank=True, )
558 classement = models.ForeignKey(rh.Classement, related_name='+', verbose_name='Classement', null=True, blank=True, )
03b395db 559
c589d980 560
2d4d2fcf 561### RÉMUNÉRATION
562
a4125771
OL
563class Remuneration(rh.Remuneration_):
564 pass
c1834169
EMS
565
566### CONTRATS
567
a4125771
OL
568class Contrat(rh.Contrat_):
569 pass
317ce433 570
47d7067b
OL
571
572class DossierFinalise(Dossier):
573
574 objects = DossierFinaliseManager()
575
576 class Meta:
577 proxy = True
578 verbose_name = "Import d'un dossier finalisé"
579 verbose_name_plural = "Import des dossiers finalisés"
580
317ce433
OL
581# modèle de liaison entre les systèmes
582
583class ImportDossier(models.Model):
584 dae = models.ForeignKey('dae.Dossier', related_name='+')
585 rh = models.ForeignKey('rh.Dossier', related_name='+')
586
587class ImportPoste(models.Model):
588 dae = models.ForeignKey('dae.Poste', related_name='+')
589 rh = models.ForeignKey('rh.Poste', related_name='+')