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