2005bd9612544d03b54630b1ad79063b3caf6ffd
[auf_rh_dae.git] / project / rh / admin.py
1 # -*- encoding: utf-8 -*-
2
3 from collections import defaultdict
4 import datetime
5
6 from django.db import models
7 from django import forms
8 from django.core.urlresolvers import reverse
9 from django.contrib import admin
10 from django.conf import settings
11 from django.db.models import Q
12 from django.template.defaultfilters import date
13 from ajax_select import make_ajax_form
14 from auf.django.metadata.admin import AUFMetadataAdminMixin, AUFMetadataInlineAdminMixin, AUF_METADATA_READONLY_FIELDS
15 from forms import ContratForm, AyantDroitForm, EmployeAdminForm, AjaxSelect
16 from dae.utils import get_employe_from_user
17 from groups import grp_drh
18 import models as rh
19 import filters
20
21
22 # Override of the InlineModelAdmin to support the link in the tabular inline
23 class LinkedInline(admin.options.InlineModelAdmin):
24 template = "admin/linked.html"
25 admin_model_path = None
26
27 def __init__(self, *args):
28 super(LinkedInline, self).__init__(*args)
29 if self.admin_model_path is None:
30 self.admin_model_path = self.model.__name__.lower()
31
32
33 class ProtectRegionMixin(object):
34
35 def queryset(self, request):
36 from dae.workflow import grp_drh, grp_correspondants_rh
37 qs = super(ProtectRegionMixin, self).queryset(request)
38
39 if request.user.is_superuser:
40 return qs
41
42 user_groups = request.user.groups.all()
43
44 if grp_drh in user_groups:
45 return qs
46
47 if grp_correspondants_rh in user_groups:
48 employe = get_employe_from_user(request.user)
49 q = Q(**{self.model.prefix_implantation: employe.implantation.region})
50 qs = qs.filter(q).distinct()
51 return qs
52 return qs.none()
53
54 def has_change_permission(self, request, obj=None):
55 user_groups = request.user.groups.all()
56
57 # Lock pour autoriser uniquement les DRH à utiliser RH
58 if not request.user.is_superuser and not grp_drh in user_groups:
59 return False
60
61 if len(user_groups) == 0 and not request.user.is_superuser:
62 return False
63
64 if obj is None:
65 return True
66 ids = [o.id for o in self.queryset(request)]
67 return obj.id in ids
68
69
70 # Inlines
71
72 class ReadOnlyInlineMixin(object):
73 def get_readonly_fields(self, request, obj=None):
74 return [f.name for f in self.model._meta.fields if f.name not in AUF_METADATA_READONLY_FIELDS]
75
76
77 class AyantDroitInline(AUFMetadataInlineAdminMixin, admin.StackedInline):
78 model = rh.AyantDroit
79 form = AyantDroitForm
80 extra = 0
81
82 fieldsets = (
83 (None, {
84 'fields': (('nom', 'prenom'), ('nom_affichage', 'genre'), 'nationalite', 'date_naissance', 'lien_parente', )
85 }),
86 )
87
88
89 class AyantDroitCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
90 readonly_fields = ('owner', )
91 model = rh.AyantDroitCommentaire
92 extra = 1
93
94
95 class ContratInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
96 form = ContratForm
97 model = rh.Contrat
98 extra = 1
99
100
101 class DossierROInline(ReadOnlyInlineMixin, LinkedInline):
102 template = "admin/rh/dossier/linked.html"
103 exclude = AUF_METADATA_READONLY_FIELDS
104 model = rh.Dossier
105 extra = 0
106 can_delete = False
107
108 def has_add_permission(self, request=None):
109 return False
110
111 def has_change_permission(self, request, obj=None):
112 return False
113
114 def has_delete_permission(self, request, obj=None):
115 return False
116
117
118 class DossierCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
119 readonly_fields = ('owner', )
120 model = rh.DossierCommentaire
121 extra = 1
122
123
124 class DossierPieceInline(admin.TabularInline):
125 model = rh.DossierPiece
126 extra = 4
127
128
129 class EmployeInline(admin.TabularInline):
130 model = rh.Employe
131
132 class EmployeCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
133 readonly_fields = ('owner', )
134 model = rh.EmployeCommentaire
135 extra = 1
136
137
138 class EmployePieceInline(admin.TabularInline):
139 model = rh.EmployePiece
140 extra = 4
141
142
143 class PosteCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
144 readonly_fields = ('owner', )
145 model = rh.PosteCommentaire
146 extra = 1
147
148
149 class PosteFinancementInline(admin.TabularInline):
150 model = rh.PosteFinancement
151
152
153 class PostePieceInline(admin.TabularInline):
154 model = rh.PostePiece
155
156
157 class RemunerationInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
158 model = rh.Remuneration
159 extra = 1
160
161
162 class RemunerationROInline(ReadOnlyInlineMixin, RemunerationInline):
163 pass
164
165
166 class TypePosteInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
167 model = rh.TypePoste
168
169
170 class PosteComparaisonInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
171 model = rh.PosteComparaison
172
173
174 class ClassementAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
175 list_display = ('_classement', 'date_modification', 'user_modification', )
176 fieldsets = AUFMetadataAdminMixin.fieldsets + (
177 (None, {
178 'fields': ('type', 'echelon', 'degre', 'coefficient', )
179 }),
180 )
181
182 def _classement(self, obj):
183 return unicode(obj)
184 _classement.short_description = u"Classement"
185
186 class CommentaireAdmin(admin.ModelAdmin):
187 pass
188
189
190 class DeviseAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
191 list_display = ('code', 'nom', 'date_modification', 'user_modification', )
192 fieldsets = AUFMetadataAdminMixin.fieldsets + (
193 (None, {
194 'fields': ('code', 'nom', ),
195 }),
196 )
197
198
199 class DossierAdmin(AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin, AjaxSelect):
200 alphabet_filter = 'employe__nom'
201 search_fields = ('employe__nom', 'employe__prenom', 'poste__nom', 'poste__nom_feminin')
202 list_display = (
203 '_id',
204 '_poste',
205 '_employe',
206 '_date_debut',
207 '_date_fin',
208 'date_modification',
209 'user_modification',
210 )
211 list_filter = (
212 'poste__implantation__region',
213 'poste__implantation',
214 'poste__type_poste',
215 'poste__type_poste__famille_emploi',
216 'rh_contrats__type_contrat',
217 'date_debut',
218 'date_fin',
219 )
220 inlines = (DossierPieceInline, ContratInline,
221 RemunerationInline,
222 DossierCommentaireInline,
223 )
224 fieldsets = AUFMetadataAdminMixin.fieldsets + (
225 (None, {
226 'fields': ('employe', 'poste', 'statut', 'organisme_bstg',)
227 }),
228 ('Recrutement', {
229 'fields': ('statut_residence', 'remplacement', 'remplacement_de', )
230 }),
231 ('Rémunération', {
232 'fields': ('classement', ('regime_travail', 'regime_travail_nb_heure_semaine'),)
233 }),
234 ('Occupation du Poste par cet Employe', {
235 'fields': (('date_debut', 'date_fin'), )
236 }),
237 )
238 form = make_ajax_form(rh.Dossier, {
239 'employe' : 'employes',
240 'poste' : 'postes',
241 'remplacement_de' : 'dossiers',
242 })
243
244 def lookup_allowed(self, key, value):
245 if key in (
246 'employe__nom__istartswith',
247 'poste__implantation__region__id__exact',
248 'poste__implantation__id__exact',
249 'poste__type_poste__id__exact',
250 'poste__type_poste__famille_emploi__id__exact',
251 'rh_contrats__type_contrat__id__exact',
252 'date_debut__gte',
253 'date_debut__isnull',
254 'date_fin__lte',
255 'date_fin__isnull',
256 ):
257 return True
258
259
260 def _id(self, d):
261 apercu_link = u"""<a title="Aperçu du dossier" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a>""" % \
262 (reverse('dossier_apercu', args=(d.id,)),
263 settings.STATIC_URL,
264 )
265 link = u"""%s&nbsp;<a href="%s" title="Modifier le dossier"><strong>%s</strong></a>""" % \
266 (apercu_link,
267 reverse('admin:rh_dossier_change', args=(d.id,)),
268 d.id,
269 )
270 return link
271 _id.allow_tags = True
272 _id.short_description = u"Dossier__#"
273 _id.admin_order_field = 'id'
274
275
276 def _date_debut(self, obj):
277 return date(obj.date_debut)
278
279 _date_debut.short_description = u'Occupation début'
280 _date_debut.admin_order_field = 'date_debut'
281
282 def _date_fin(self, obj):
283 return date(obj.date_fin)
284 _date_fin.short_description = u'Occupation fin'
285 _date_fin.admin_order_field = 'date_fin'
286
287 def _poste(self, dossier):
288 link = u"""<a title="Aperçu du poste" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a> <a href="%s" title="Modifier le poste">%s</a>""" % \
289 (reverse('poste_apercu', args=(dossier.poste.id,)),
290 settings.STATIC_URL,
291 reverse('admin:rh_poste_change', args=(dossier.poste.id,)),
292 dossier.poste,
293 )
294 return link
295 _poste.allow_tags = True
296 _poste.short_description = u'Poste'
297 _poste.admin_order_field = 'poste__nom'
298
299 def _employe(self, obj):
300 employe = obj.employe
301 view_link = reverse('employe_apercu', args=(employe.id,))
302 edit_link = reverse('admin:rh_employe_change', args=(employe.id,))
303
304 style = ""
305 view = u"""<a href="%s" title="Aperçu l'employé" onclick="return showAddAnotherPopup(this);"><img src="%simg/loupe.png" /></a>""" % (view_link, settings.STATIC_URL,)
306 return u"""%s<a href='%s' style="%s;">[%s] %s %s</a>""" % \
307 (view, edit_link, style, employe.id, employe.nom.upper(), employe.prenom.title())
308 _employe.allow_tags = True
309 _employe.short_description = u"Employé ([code] NOM Prénom)"
310 _employe.admin_order_field = "employe__nom"
311
312 def save_formset(self, request, form, formset, change):
313 instances = formset.save(commit=False)
314 for instance in instances:
315 if instance.__class__ == rh.DossierCommentaire:
316 instance.owner = request.user
317 instance.date_creation = datetime.datetime.now()
318 instance.save()
319
320
321 class DossierPieceAdmin(admin.ModelAdmin):
322 pass
323
324
325 class DossierCommentaireAdmin(admin.ModelAdmin):
326 pass
327
328
329 class EmployeAdmin(AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin):
330 alphabet_filter = 'nom'
331 DEFAULT_ALPHABET = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
332 search_fields = ('id', 'nom', 'prenom', 'nom_affichage', )
333 ordering = ('nom', )
334 form = EmployeAdminForm
335 list_display = ('_apercu', '_nom', '_dossiers', 'date_modification', 'user_modification', )
336 list_filter = ('rh_dossiers__poste__implantation__region', 'rh_dossiers__poste__implantation', 'nb_postes', )
337 inlines = (AyantDroitInline,
338 DossierROInline,
339 EmployePieceInline,
340 EmployeCommentaireInline)
341 fieldsets = AUFMetadataAdminMixin.fieldsets + (
342 ('Identification', {
343 'fields': (('nom', 'prenom'), ('nom_affichage', 'genre'), 'nationalite', 'date_naissance', )
344 }),
345 ('Informations personnelles', {
346 'fields': ('situation_famille', 'date_entree', )
347 }),
348 ('Coordonnées', {
349 'fields': (('tel_domicile', 'tel_cellulaire'), ('adresse', 'ville'), ('code_postal', 'province'), 'pays', )
350 }),
351 )
352
353 def _apercu(self, obj):
354 return u"""<a title="Aperçu de l'employé" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a>""" % \
355 (reverse('employe_apercu', args=(obj.id,)), settings.STATIC_URL)
356 _apercu.allow_tags = True
357 _apercu.short_description = u""
358 _apercu.admin_order_field = ""
359
360 def _nom(self, obj):
361 edit_link = reverse('admin:rh_employe_change', args=(obj.id,))
362 return u"""<a href='%s'><strong>[%s] %s %s</strong></a>""" % \
363 (edit_link, obj.id, obj.nom.upper(), obj.prenom.title(),)
364 _nom.allow_tags = True
365 _nom.short_description = u"Employé ([code] NOM Prénom)"
366 _nom.admin_order_field = "nom"
367
368 def _dossiers(self, obj):
369 l = []
370 for d in obj.rh_dossiers.all().order_by('-date_debut'):
371 apercu = u"""<a title="Aperçu du dossier" href="%s" onclick="return showAddAnotherPopup(this);" title="Aperçu du dossier"><img src="%simg/loupe.png" /></a>""" % \
372 (reverse('dossier_apercu', args=(d.id,)), settings.STATIC_URL,)
373 link = u"""<li>%s<a href='%s'>%s : %s</a></li>""" % \
374 (apercu,
375 reverse('admin:rh_dossier_change', args=(d.id,)),
376 d.date_debut.year,
377 d.poste,
378 )
379
380 # Dossier terminé en gris non cliquable
381 if d.date_fin is not None:
382 link = u"""<li style="color: grey">%s : %s</li>""" % \
383 (d.date_debut.year,
384 d.poste,
385 )
386
387 l.append(link)
388 return "<ul>%s</ul>" % "\n".join(l)
389 _dossiers.allow_tags = True
390 _dossiers.short_description = u"Dossiers"
391
392 def queryset(self, request):
393 qs = super(EmployeAdmin, self).queryset(request)
394 return qs.select_related(depth=1).order_by('nom')
395
396 def save_formset(self, request, form, formset, change):
397 instances = formset.save(commit=False)
398 for instance in instances:
399 if instance.__class__ == rh.EmployeCommentaire:
400 instance.owner = request.user
401 instance.date_creation = datetime.datetime.now()
402 instance.save()
403
404
405
406 class EmployeCommentaireAdmin(admin.ModelAdmin):
407 pass
408
409
410 class EmployePieceAdmin(admin.ModelAdmin):
411 pass
412
413
414 class FamilleEmploiAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
415 list_display = ('nom', 'date_modification', 'user_modification', )
416 inlines = (TypePosteInline,)
417 fieldsets = AUFMetadataAdminMixin.fieldsets + (
418 (None, {
419 'fields': ('nom', )
420 }),
421 )
422
423
424 class OrganismeBstgAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
425 search_fields = ('nom',)
426 list_display = ('nom', 'type', 'pays', 'date_modification', 'user_modification', )
427 list_filter = ('type', )
428 inlines = (DossierROInline,)
429 fieldsets = AUFMetadataAdminMixin.fieldsets + (
430 (None, {
431 'fields': ('nom', 'type', 'pays', )
432 }),
433 )
434
435
436 class PosteAdmin(AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin, AjaxSelect):
437 form = make_ajax_form(rh.Poste, {
438 'implantation' : 'implantations',
439 'type_poste' : 'typepostes',
440 'responsable' : 'postes',
441 'valeur_point_min' : 'valeurpoints',
442 'valeur_point_max' : 'valeurpoints',
443 })
444 alphabet_filter = 'nom'
445 search_fields = ('nom',
446 'implantation__code',
447 'implantation__nom',
448 'implantation__region__code',
449 'implantation__region__nom',
450 )
451 list_display = (
452 '_apercu',
453 '_nom',
454 '_occupe_par',
455 'implantation',
456 '_service',
457 'date_debut',
458 'date_fin',
459 'date_modification',
460 'user_modification',
461 )
462 list_filter = (
463 'service',
464 'implantation__region',
465 'implantation',
466 'type_poste',
467 'type_poste__famille_emploi',
468 'date_debut',
469 'date_fin',
470 'vacant',
471 )
472 fieldsets = AUFMetadataAdminMixin.fieldsets + (
473 (None, {
474 'fields': (('nom', 'nom_feminin'), 'implantation', 'type_poste',
475 'service', 'responsable')
476 }),
477 ('Contrat', {
478 'fields': (('regime_travail', 'regime_travail_nb_heure_semaine'), )
479 }),
480 ('Recrutement', {
481 'fields': (('local', 'expatrie', 'mise_a_disposition', 'appel'),)
482 }),
483 ('Rémunération', {
484 'fields': (('classement_min', 'valeur_point_min', 'devise_min', 'salaire_min', 'indemn_min', 'autre_min', ),
485 ('classement_max', 'valeur_point_max' ,'devise_max', 'salaire_max', 'indemn_max', 'autre_max', ),
486 )
487 }),
488 ('Comparatifs de rémunération', {
489 'fields': ('devise_comparaison',
490 ('comp_locale_min', 'comp_locale_max'),
491 ('comp_universite_min', 'comp_universite_max'),
492 ('comp_fonctionpub_min', 'comp_fonctionpub_max'),
493 ('comp_ong_min', 'comp_ong_max'),
494 ('comp_autre_min', 'comp_autre_max'))
495 }),
496 ('Justification', {
497 'fields': ('justification',)
498 }),
499 ('Autres Méta-données', {
500 'fields': ('date_debut', 'date_fin')
501 }),
502 )
503
504 inlines = (PosteFinancementInline,
505 PostePieceInline,
506 DossierROInline,
507 PosteComparaisonInline,
508 PosteCommentaireInline, )
509
510 def lookup_allowed(self, key, value):
511 if key in (
512 'date_debut__gte',
513 'date_debut__isnull',
514 'date_fin__lte',
515 'date_fin__isnull',
516 ):
517 return True
518
519
520 def _apercu(self, poste):
521 link = u"""<a onclick="return showAddAnotherPopup(this);" title="Aperçu du poste" href='%s'><img src="%simg/loupe.png" /> %s</a>""" % \
522 (reverse('poste_apercu', args=(poste.id,)),
523 settings.STATIC_URL,
524 poste.id,
525 )
526 return link
527 _apercu.allow_tags = True
528 _apercu.short_description = 'Poste __#'
529 _apercu.admin_order_field = 'id'
530
531 def _service(self, obj):
532 return obj.service
533
534 def _nom(self, poste):
535 link = u"""<a href="%s" title="Modifier le poste"><strong>%s</strong></a>""" % \
536 (reverse('admin:rh_poste_change', args=(poste.id,)),
537 poste.nom,
538 )
539 return link
540 _nom.allow_tags = True
541 _nom.short_description = u'Nom'
542 _nom.admin_order_field = 'nom'
543
544 def _occupe_par(self, obj):
545 """Formatte la méthode Poste.occupe_par() pour l'admin"""
546 output = u"Vacant"
547 if obj.date_fin is not None and obj.date_fin < datetime.datetime.now():
548 return u"s/o"
549 employes = obj.occupe_par()
550 if employes:
551 l = []
552 for e in employes:
553 link = "<a href='%s' title='Aperçu de l\'employer' onclick='return showAddAnotherPopup(this)'><img src='%simg/loupe.png' /></a> <a href='%s'>%s</a>" % \
554 (reverse('employe_apercu', args=(e.id,)),
555 settings.STATIC_URL,
556 reverse('admin:rh_employe_change', args=(e.id,)),
557 e
558 )
559 l.append(link)
560 output = "\n<br />".join(l)
561 return output
562 _occupe_par.allow_tags = True
563 _occupe_par.short_description = "Occupé par"
564
565 def save_formset(self, request, form, formset, change):
566 instances = formset.save(commit=False)
567 for instance in instances:
568 if instance.__class__ == rh.PosteCommentaire:
569 instance.owner = request.user
570 instance.date_creation = datetime.datetime.now()
571 instance.save()
572 formset.save_m2m()
573
574
575 class PosteCommentaireAdmin(admin.ModelAdmin):
576 pass
577
578
579 class PosteFinancementAdmin(admin.ModelAdmin):
580 pass
581
582
583 class PostePieceAdmin(admin.ModelAdmin):
584 fk_name = 'poste'
585
586
587 class RemunerationAdmin(admin.ModelAdmin):
588 pass
589
590
591 class ResponsableImplantationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
592 fieldsets = AUFMetadataAdminMixin.fieldsets + (
593 (None, {
594 'fields': ('employe', 'implantation', ),
595 }),
596 )
597
598
599 class ServiceAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
600 list_display = ('nom', 'date_modification', 'user_modification', )
601 fieldsets = AUFMetadataAdminMixin.fieldsets + (
602 (None, {
603 'fields': ('nom', ),
604 }),
605 )
606
607 class StatutAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
608 list_display = ('code', 'nom', 'date_modification', 'user_modification', )
609 fieldsets = AUFMetadataAdminMixin.fieldsets + (
610 (None, {
611 'fields': ('code', 'nom', ),
612 }),
613 )
614
615 class TauxChangeAdmin(admin.ModelAdmin):
616 list_display = ('taux', 'devise', 'annee', 'date_modification', 'user_modification', )
617 list_filter = ('devise', )
618 fieldsets = AUFMetadataAdminMixin.fieldsets + (
619 (None, {
620 'fields': ('taux', 'devise', 'annee', ),
621 }),
622 )
623
624 class TypeContratAdmin(admin.ModelAdmin):
625 list_display = ('nom', 'nom_long', 'date_modification', 'user_modification', )
626 fieldsets = AUFMetadataAdminMixin.fieldsets + (
627 (None, {
628 'fields': ('nom', 'nom_long', ),
629 }),
630 )
631
632
633 class TypePosteAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
634 search_fields = ('nom', 'nom_feminin', )
635 list_display = ('nom', 'famille_emploi', 'date_modification', 'user_modification', )
636 list_filter = ('famille_emploi', )
637 fieldsets = AUFMetadataAdminMixin.fieldsets + (
638 (None, {
639 'fields': ('nom', 'nom_feminin', 'is_responsable', 'famille_emploi', )
640 }),
641 )
642
643
644 class TypeRemunerationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
645 list_display = ('nom', 'type_paiement', 'nature_remuneration', 'date_modification', 'user_modification', )
646 fieldsets = AUFMetadataAdminMixin.fieldsets + (
647 (None, {
648 'fields': ('nom', 'type_paiement', 'nature_remuneration', )
649 }),
650 )
651
652
653 class TypeRevalorisationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
654 list_display = ('nom', 'date_modification', 'user_modification', )
655 fieldsets = AUFMetadataAdminMixin.fieldsets + (
656 (None, {
657 'fields': ('nom', )
658 }),
659 )
660
661
662 class ValeurPointAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
663 list_display = ('_devise_code', '_devise_nom', 'annee', 'valeur', 'date_modification', 'user_modification', )
664 list_filter = ('annee', 'devise', )
665 fieldsets = AUFMetadataAdminMixin.fieldsets + (
666 (None, {
667 'fields': ('valeur', 'devise', 'implantation', 'annee', )
668 }),
669 )
670
671 def _devise_code(self, obj):
672 return obj.devise.code
673 _devise_code.short_description = "Code de la devise"
674
675 def _devise_nom(self, obj):
676 return obj.devise.nom
677 _devise_nom.short_description = "Nom de la devise"
678
679
680 admin.site.register(rh.Classement, ClassementAdmin)
681 admin.site.register(rh.Devise, DeviseAdmin)
682 admin.site.register(rh.Dossier, DossierAdmin)
683 admin.site.register(rh.Employe, EmployeAdmin)
684 admin.site.register(rh.FamilleEmploi, FamilleEmploiAdmin)
685 admin.site.register(rh.OrganismeBstg, OrganismeBstgAdmin)
686 admin.site.register(rh.Poste, PosteAdmin)
687 admin.site.register(rh.ResponsableImplantation, ResponsableImplantationAdmin)
688 admin.site.register(rh.Service, ServiceAdmin)
689 admin.site.register(rh.Statut, StatutAdmin)
690 admin.site.register(rh.TauxChange, TauxChangeAdmin)
691 admin.site.register(rh.TypeContrat, TypeContratAdmin)
692 admin.site.register(rh.TypePoste, TypePosteAdmin)
693 admin.site.register(rh.TypeRemuneration, TypeRemunerationAdmin)
694 admin.site.register(rh.TypeRevalorisation, TypeRevalorisationAdmin)
695 admin.site.register(rh.ValeurPoint, ValeurPointAdmin)