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