[#3178] Ajouté des champs à la recherche textuelle des employés
[auf_rh_dae.git] / project / rh / admin.py
CommitLineData
53ae644d
OL
1# -*- encoding: utf-8 -*-
2
53ae644d
OL
3import datetime
4
fc4bf968
EMS
5from ajax_select import make_ajax_form
6from auf.django.metadata.admin import \
7 AUFMetadataAdminMixin, AUFMetadataInlineAdminMixin, \
8 AUF_METADATA_READONLY_FIELDS
53ae644d 9from django.core.urlresolvers import reverse
50fa9bc1 10from django.contrib import admin
53ae644d 11from django.conf import settings
f7badf51 12from django.db.models import Q, Count
5f36f262 13from django.template.defaultfilters import date
fc4bf968
EMS
14
15import auf.django.references.models as ref
16import models as rh
17from forms import \
18 ContratForm, AyantDroitForm, EmployeAdminForm, AjaxSelect, DossierForm
53ae644d 19from dae.utils import get_employe_from_user
a17e2236 20from change_list import ChangeList
a12ddd52
OL
21from groups import grp_correspondants_rh
22from decorators import in_drh_or_admin
fc4bf968 23
82af5c19 24
7ba822a6
OL
25class ArchiveMixin(object):
26 """
27 Archive Mixin pour gérer le queryset et le display
28 NON COMPRIS : list_filter, et list_display, field à setter dans la classe.
29 """
30
31 def queryset(self, request):
32 return self.model._base_manager
33
34 def _archive(self, obj):
35 if obj.archive:
36 return "oui"
37 else:
38 return "non"
39 _archive.short_description = u'Archivé'
40 _archive.admin_order_field = 'archive'
41
fc4bf968 42
9da4c195
JPC
43class RegionProxy(ref.Region):
44 """ Proxy utilisé pour les organigrammes par région """
45 class Meta:
46 proxy = True
47 verbose_name = u"Organigramme par région"
48 verbose_name_plural = u"Organigramme par région"
49
50
82af5c19
JPC
51class ImplantationProxy(ref.Implantation):
52 """ Proxy utilisé pour les organigrammes par implantation """
53 class Meta:
54 proxy = True
55 verbose_name = u"Organigramme par implantations"
56 verbose_name_plural = u"Organigramme par implantations"
57
22343fe7 58
5c0f1778
JPC
59class ServiceProxy(rh.Service):
60 """ Proxy utilisé pour les organigrammes opar service """
f7badf51 61
5c0f1778
JPC
62 class Meta:
63 proxy = True
64 verbose_name = u"Organigramme par services"
65 verbose_name_plural = u"Organigramme par services"
66
22343fe7 67
5c0f1778
JPC
68class EmployeProxy(rh.Employe):
69 """ Proxy utilisé pour les organigrammes des employés """
22343fe7
OL
70 class Meta:
71 proxy = True
72 verbose_name = u"Organigramme des employés"
73 verbose_name_plural = u"Organigramme des employés"
74
f614ca5c 75
40b35603 76class DateRangeMixin(object):
a17e2236 77 prefixe_recherche_temporelle = ""
22343fe7 78
40b35603 79 def get_changelist(self, request, **kwargs):
22343fe7 80 if 'HTTP_REFERER' in request.META.keys():
910e39e5
OL
81 referer = request.META['HTTP_REFERER']
82 referer = "/".join(referer.split('/')[3:])
83 referer = "/%s" % referer.split('?')[0]
22343fe7
OL
84 change_list_view = 'admin:%s_%s_changelist' % (
85 self.model._meta.app_label,
86 self.model.__name__.lower(),)
910e39e5
OL
87 if referer != reverse(change_list_view):
88 params = request.GET.copy()
22343fe7 89 params.update({'statut': 'Actif'})
910e39e5 90 request.GET = params
40b35603 91 return ChangeList
3195667e 92
22343fe7 93
53ae644d
OL
94# Override of the InlineModelAdmin to support the link in the tabular inline
95class LinkedInline(admin.options.InlineModelAdmin):
96 template = "admin/linked.html"
97 admin_model_path = None
98
99 def __init__(self, *args):
100 super(LinkedInline, self).__init__(*args)
101 if self.admin_model_path is None:
102 self.admin_model_path = self.model.__name__.lower()
103
104
105class ProtectRegionMixin(object):
106
107 def queryset(self, request):
53ae644d
OL
108 qs = super(ProtectRegionMixin, self).queryset(request)
109
53ae644d 110 user_groups = request.user.groups.all()
a12ddd52 111 if in_drh_or_admin(request.user):
53ae644d
OL
112 return qs
113
114 if grp_correspondants_rh in user_groups:
115 employe = get_employe_from_user(request.user)
22343fe7
OL
116 q = Q(**{self.model.prefix_implantation: \
117 employe.implantation.region})
53ae644d
OL
118 qs = qs.filter(q).distinct()
119 return qs
120 return qs.none()
121
c0be8705
OL
122 def has_add_permission(self, request):
123 if not in_drh_or_admin(request.user):
124 return False
125 else:
126 return True
127
53ae644d 128 def has_change_permission(self, request, obj=None):
20b4867c 129 user_groups = request.user.groups.all()
a0d365ed 130
0309aeb4
DB
131 # Lock pour autoriser uniquement les DRH à utiliser RH
132 if not in_drh_or_admin(request.user):
133 return False
134
a18bc295 135 if len(user_groups) == 0 and not request.user.is_superuser:
20b4867c
OL
136 return False
137
53ae644d
OL
138 if obj is None:
139 return True
140 ids = [o.id for o in self.queryset(request)]
141 return obj.id in ids
142
143
144# Inlines
145
146class ReadOnlyInlineMixin(object):
22343fe7 147
53ae644d 148 def get_readonly_fields(self, request, obj=None):
22343fe7
OL
149 return [f.name for f in self.model._meta.fields \
150 if f.name not in AUF_METADATA_READONLY_FIELDS]
53ae644d
OL
151
152
153class AyantDroitInline(AUFMetadataInlineAdminMixin, admin.StackedInline):
154 model = rh.AyantDroit
155 form = AyantDroitForm
156 extra = 0
157
158 fieldsets = (
159 (None, {
22343fe7
OL
160 'fields': (
161 ('nom', 'prenom'),
162 ('nom_affichage', 'genre'),
163 'nationalite',
164 'date_naissance',
165 'lien_parente',
166 )}),
53ae644d
OL
167 )
168
169
22343fe7
OL
170class AyantDroitCommentaireInline(AUFMetadataInlineAdminMixin, \
171 admin.TabularInline):
53ae644d
OL
172 readonly_fields = ('owner', )
173 model = rh.AyantDroitCommentaire
174 extra = 1
175
176
177class ContratInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
178 form = ContratForm
179 model = rh.Contrat
180 extra = 1
181
182
183class DossierROInline(ReadOnlyInlineMixin, LinkedInline):
184 template = "admin/rh/dossier/linked.html"
185 exclude = AUF_METADATA_READONLY_FIELDS
186 model = rh.Dossier
187 extra = 0
188 can_delete = False
189
190 def has_add_permission(self, request=None):
191 return False
192
193 def has_change_permission(self, request, obj=None):
194 return False
195
196 def has_delete_permission(self, request, obj=None):
197 return False
198
199
22343fe7
OL
200class DossierCommentaireInline(AUFMetadataInlineAdminMixin, \
201 admin.TabularInline):
53ae644d
OL
202 readonly_fields = ('owner', )
203 model = rh.DossierCommentaire
204 extra = 1
205
206
207class DossierPieceInline(admin.TabularInline):
208 model = rh.DossierPiece
209 extra = 4
210
211
212class EmployeInline(admin.TabularInline):
213 model = rh.Employe
214
22343fe7
OL
215
216class EmployeCommentaireInline(AUFMetadataInlineAdminMixin, \
217 admin.TabularInline):
53ae644d
OL
218 readonly_fields = ('owner', )
219 model = rh.EmployeCommentaire
220 extra = 1
221
222
223class EmployePieceInline(admin.TabularInline):
224 model = rh.EmployePiece
225 extra = 4
226
227
53ae644d
OL
228class PosteCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
229 readonly_fields = ('owner', )
230 model = rh.PosteCommentaire
231 extra = 1
232
233
234class PosteFinancementInline(admin.TabularInline):
235 model = rh.PosteFinancement
236
237
238class PostePieceInline(admin.TabularInline):
239 model = rh.PostePiece
240
241
242class RemunerationInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
243 model = rh.Remuneration
244 extra = 1
245
246
247class RemunerationROInline(ReadOnlyInlineMixin, RemunerationInline):
248 pass
249
250
251class TypePosteInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
252 model = rh.TypePoste
253
254
6f037929
OL
255class PosteComparaisonInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
256 model = rh.PosteComparaison
257
53ae644d
OL
258
259class ClassementAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 260 list_display = ('_classement', '_date_modification', 'user_modification', )
53ae644d
OL
261 fieldsets = AUFMetadataAdminMixin.fieldsets + (
262 (None, {
22343fe7 263 'fields': ('type', 'echelon', 'degre', 'coefficient',)}),
53ae644d
OL
264 )
265
c5964dc2
OL
266 def _classement(self, obj):
267 return unicode(obj)
268 _classement.short_description = u"Classement"
53ae644d 269
33232787 270 def _date_modification(self, obj):
22343fe7
OL
271 return date(obj.date_modification) \
272 if obj.date_modification is not None else "(aucune)"
33232787
JPC
273 _date_modification.short_description = u'date modification'
274 _date_modification.admin_order_field = 'date_modification'
275
22343fe7 276
53ae644d
OL
277class CommentaireAdmin(admin.ModelAdmin):
278 pass
279
280
7ba822a6 281class DeviseAdmin(AUFMetadataAdminMixin, admin.ModelAdmin, ArchiveMixin):
22343fe7
OL
282 list_display = (
283 'code',
284 'nom',
285 '_archive',
286 '_date_modification',
287 'user_modification',
288 )
edb35076 289 list_filter = ('archive', )
53ae644d
OL
290 fieldsets = AUFMetadataAdminMixin.fieldsets + (
291 (None, {
edb35076 292 'fields': ('code', 'nom', 'archive', ),
53ae644d
OL
293 }),
294 )
295
33232787 296 def _date_modification(self, obj):
22343fe7
OL
297 return date(obj.date_modification) \
298 if obj.date_modification is not None else "(aucune)"
33232787
JPC
299 _date_modification.short_description = u'date modification'
300 _date_modification.admin_order_field = 'date_modification'
53ae644d 301
22343fe7
OL
302
303class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin, \
304 ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
53ae644d 305 alphabet_filter = 'employe__nom'
22343fe7 306 search_fields = (
35cff4a7
EMS
307 'id',
308 'employe__id',
309 'poste__id',
310 'employe__nom',
311 'employe__prenom',
312 'poste__nom',
313 'poste__nom_feminin',
314 'poste__implantation__nom',
315 )
53ae644d
OL
316 list_display = (
317 '_id',
e49ac947
JPC
318 '_apercu',
319 '_nom',
53ae644d
OL
320 '_poste',
321 '_employe',
322 '_date_debut',
323 '_date_fin',
33232787 324 '_date_modification',
c5964dc2 325 'user_modification',
a47ed016 326 '_dae',
53ae644d 327 )
e49ac947 328 list_display_links = ('_nom',)
53ae644d
OL
329 list_filter = (
330 'poste__implantation__region',
331 'poste__implantation',
7bf28694 332 'poste__type_poste__categorie_emploi',
7baa5523 333 'poste__type_poste',
53ae644d 334 'rh_contrats__type_contrat',
6bee05ff 335 'principal',
53ae644d
OL
336 )
337 inlines = (DossierPieceInline, ContratInline,
338 RemunerationInline,
53ae644d
OL
339 DossierCommentaireInline,
340 )
341 fieldsets = AUFMetadataAdminMixin.fieldsets + (
342 (None, {
22343fe7
OL
343 'fields': (
344 'employe',
345 'poste',
6bee05ff 346 'principal',
22343fe7
OL
347 'statut',
348 'organisme_bstg',)}),
53ae644d 349 ('Recrutement', {
22343fe7
OL
350 'fields': (
351 'statut_residence',
352 'remplacement',
353 'remplacement_de', )}),
53ae644d 354 ('Rémunération', {
22343fe7
OL
355 'fields': (
356 'classement',
357 ('regime_travail', 'regime_travail_nb_heure_semaine'),)}),
53ae644d 358 ('Occupation du Poste par cet Employe', {
22343fe7
OL
359 'fields': (('date_debut', 'date_fin'), )}
360 ),
53ae644d 361 )
22343fe7
OL
362 form = make_ajax_form(rh.Dossier, {
363 'employe': 'employes',
364 'poste': 'postes',
365 'remplacement_de': 'dossiers',
6bee05ff 366 }, superclass=DossierForm)
53ae644d
OL
367
368 def lookup_allowed(self, key, value):
369 if key in (
370 'employe__nom__istartswith',
53ae644d
OL
371 'poste__implantation__region__id__exact',
372 'poste__implantation__id__exact',
373 'poste__type_poste__id__exact',
7bf28694 374 'poste__type_poste__categorie_emploi__id__exact',
53ae644d 375 'rh_contrats__type_contrat__id__exact',
6bee05ff
OL
376 'principal__exact',
377 'principal__isnull',
53ae644d
OL
378 ):
379 return True
380
e49ac947
JPC
381 def _id(self, obj):
382 return obj.id
383 _id.short_description = u"#"
384 _id.admin_order_field = "id"
385
386 def _nom(self, obj):
22343fe7
OL
387 return "%d : %s %s" % (
388 obj.date_debut.year,
389 obj.employe.nom.upper(),
390 obj.employe.prenom)
e49ac947
JPC
391 _nom.allow_tags = True
392 _nom.short_description = u"Dossier"
393
e49ac947 394 def _apercu(self, d):
22343fe7
OL
395 apercu_link = u"""<a title="Aperçu du dossier"
396 onclick="return showAddAnotherPopup(this);"
397 href='%s'>
398 <img src="%simg/loupe.png" />
399 </a>""" % \
b10920ea 400 (reverse('dossier_apercu', args=(d.id,)),
822a2c33 401 settings.STATIC_URL,
b10920ea 402 )
e49ac947
JPC
403 return apercu_link
404 _apercu.allow_tags = True
405 _apercu.short_description = u""
53ae644d 406
a47ed016
OL
407 def _dae(self, d):
408 apercu_link = ""
de151a1e
EMS
409 dossiers_dae = d.dossiers_dae.all()
410 if len(dossiers_dae) > 0:
411 dossier_dae = dossiers_dae[0]
a47ed016
OL
412 apercu_link = u"""<a title="Aperçu du dossier"
413 onclick="return showAddAnotherPopup(this);"
414 href='%s'>
415 <img src="%simg/loupe.png" />
416 </a>""" % \
de151a1e 417 (reverse('embauche_consulter', args=(dossier_dae.id,)),
a47ed016
OL
418 settings.STATIC_URL,
419 )
420 return apercu_link
421 _dae.allow_tags = True
422 _dae.short_description = u"DAE"
423
53ae644d 424 def _date_debut(self, obj):
5f36f262
OL
425 return date(obj.date_debut)
426
53ae644d
OL
427 _date_debut.short_description = u'Occupation début'
428 _date_debut.admin_order_field = 'date_debut'
429
430 def _date_fin(self, obj):
5f36f262 431 return date(obj.date_fin)
53ae644d
OL
432 _date_fin.short_description = u'Occupation fin'
433 _date_fin.admin_order_field = 'date_fin'
434
33232787 435 def _date_modification(self, obj):
22343fe7
OL
436 return date(obj.date_modification) \
437 if obj.date_modification is not None else "(aucune)"
33232787
JPC
438 _date_modification.short_description = u'date modification'
439 _date_modification.admin_order_field = 'date_modification'
440
53ae644d 441 def _poste(self, dossier):
22343fe7
OL
442 link = u"""<a title="Aperçu du poste"
443 onclick="return showAddAnotherPopup(this);"
444 href='%s'><img src="%simg/loupe.png" />
445 </a>
446 <a href="%s" title="Modifier le poste">%s</a>""" % \
53ae644d 447 (reverse('poste_apercu', args=(dossier.poste.id,)),
822a2c33 448 settings.STATIC_URL,
211a0e56
JPC
449 reverse('admin:rh_poste_change', args=(dossier.poste.id,)),
450 dossier.poste,
53ae644d
OL
451 )
452 return link
453 _poste.allow_tags = True
454 _poste.short_description = u'Poste'
455 _poste.admin_order_field = 'poste__nom'
456
457 def _employe(self, obj):
458 employe = obj.employe
459 view_link = reverse('employe_apercu', args=(employe.id,))
460 edit_link = reverse('admin:rh_employe_change', args=(employe.id,))
461
f614ca5c 462 style = ""
22343fe7
OL
463 view = u"""<a href="%s"
464 title="Aperçu l'employé"
465 onclick="return showAddAnotherPopup(this);">
466 <img src="%simg/loupe.png" />
467 </a>""" % (view_link, settings.STATIC_URL,)
e6c107de
JPC
468 return u"""%s<a href='%s' style="%s;">%s</a>""" % \
469 (view, edit_link, style, employe)
53ae644d 470 _employe.allow_tags = True
e49ac947 471 _employe.short_description = u"Employé"
53ae644d 472 _employe.admin_order_field = "employe__nom"
22343fe7 473
53ae644d
OL
474 def save_formset(self, request, form, formset, change):
475 instances = formset.save(commit=False)
476 for instance in instances:
477 if instance.__class__ == rh.DossierCommentaire:
478 instance.owner = request.user
02e69aa2 479 instance.date_creation = datetime.datetime.now()
53ae644d
OL
480 instance.save()
481
482
483class DossierPieceAdmin(admin.ModelAdmin):
484 pass
485
486
487class DossierCommentaireAdmin(admin.ModelAdmin):
488 pass
489
490
22343fe7
OL
491class EmployeAdmin(DateRangeMixin, AUFMetadataAdminMixin, \
492 ProtectRegionMixin, admin.ModelAdmin,):
7eb6b687 493 prefixe_recherche_temporelle = "rh_dossiers__"
53ae644d
OL
494 alphabet_filter = 'nom'
495 DEFAULT_ALPHABET = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
e23da9c3
EMS
496 search_fields = (
497 'id', 'nom', 'prenom', 'nom_affichage',
498 'rh_dossiers__poste__nom',
499 'rh_dossiers__poste__nom_feminin'
500 )
53ae644d
OL
501 ordering = ('nom', )
502 form = EmployeAdminForm
22343fe7
OL
503 list_display = (
504 '_id',
505 '_apercu',
506 '_nom',
507 '_dossiers_postes',
508 '_date_modification',
509 'user_modification',
510 )
e49ac947 511 list_display_links = ('_nom',)
22343fe7
OL
512 list_filter = (
513 'rh_dossiers__poste__implantation__region',
514 'rh_dossiers__poste__implantation',
515 'nb_postes',
516 )
53ae644d
OL
517 inlines = (AyantDroitInline,
518 DossierROInline,
519 EmployePieceInline,
520 EmployeCommentaireInline)
521 fieldsets = AUFMetadataAdminMixin.fieldsets + (
522 ('Identification', {
22343fe7
OL
523 'fields': (
524 ('nom', 'prenom'),
525 ('nom_affichage', 'genre'),
526 'nationalite',
527 'date_naissance',
528 )}
529 ),
53ae644d 530 ('Informations personnelles', {
22343fe7
OL
531 'fields': ('situation_famille', 'date_entree', )}
532 ),
89a8df07 533 ('Coordonnées personnelles', {
22343fe7
OL
534 'fields': (
535 ('tel_domicile', 'tel_cellulaire'),
536 ('adresse', 'ville'),
537 ('code_postal', 'province'),
538 'pays',
89a8df07 539 'courriel_perso'
22343fe7
OL
540 )}
541 ),
53ae644d
OL
542 )
543
b10920ea 544 def _apercu(self, obj):
22343fe7
OL
545 return u"""<a title="Aperçu de l'employé"
546 onclick="return showAddAnotherPopup(this);"
547 href='%s'>
548 <img src="%simg/loupe.png" />
549 </a>""" % \
550 (reverse('employe_apercu', args=(obj.id,)), settings.STATIC_URL)
b10920ea
JPC
551 _apercu.allow_tags = True
552 _apercu.short_description = u""
b10920ea 553
53ae644d 554 def _nom(self, obj):
53ae644d 555 edit_link = reverse('admin:rh_employe_change', args=(obj.id,))
e6c107de 556 return u"""<a href='%s'><strong>%s</strong></a>""" % \
e49ac947 557 (edit_link, "%s %s" % (obj.nom.upper(), obj.prenom))
53ae644d 558 _nom.allow_tags = True
e49ac947 559 _nom.short_description = u"Employé"
53ae644d
OL
560 _nom.admin_order_field = "nom"
561
e49ac947
JPC
562 def _id(self, obj):
563 return obj.id
564 _id.short_description = u"#"
565 _id.admin_order_field = "id"
566
33232787 567 def _date_modification(self, obj):
22343fe7
OL
568 return date(obj.date_modification) \
569 if obj.date_modification is not None else "(aucune)"
33232787
JPC
570 _date_modification.short_description = u'date modification'
571 _date_modification.admin_order_field = 'date_modification'
572
a7f013f5 573 def _dossiers_postes(self, obj):
53ae644d
OL
574 l = []
575 for d in obj.rh_dossiers.all().order_by('-date_debut'):
22343fe7
OL
576 dossier = u"""<a title="Aperçu du dossier"
577 href="%s"
578 onclick="return showAddAnotherPopup(this);"
579 title="Aperçu du dossier">
580 <img src="%simg/loupe.png" />
581 </a>
582 <a href="%s">Dossier</a>
583 &nbsp;""" % \
584 (reverse('dossier_apercu', args=(d.id,)),
585 settings.STATIC_URL,
586 reverse('admin:rh_dossier_change', args=(d.id,)))
587
588 poste = u"""<a title="Aperçu du poste"
589 href="%s"
590 onclick="return showAddAnotherPopup(this);"
591 title="Aperçu du poste">
592 <img src="%simg/loupe.png" />
593 </a>
594 <a href="%s">Poste</a>
595 &nbsp;""" % \
596 (reverse('poste_apercu', args=(d.poste.id,)),
597 settings.STATIC_URL,
598 reverse('admin:rh_poste_change', args=(d.poste.id,)))
a7f013f5
JPC
599 link = u"""<li>%s %s - %s : [%s] %s</li>""" % \
600 (dossier, poste,
53ae644d 601 d.date_debut.year,
a7f013f5
JPC
602 d.poste.id,
603 d.poste.nom,
53ae644d 604 )
b5cc0357
OL
605
606 # Dossier terminé en gris non cliquable
a4329fae 607 if d.date_fin is not None and d.date_fin < datetime.date.today():
a7f013f5 608 link = u"""<li style="color: grey">%s : [%s] %s</li>""" % \
b5cc0357 609 (d.date_debut.year,
a7f013f5
JPC
610 d.poste.id,
611 d.poste.nom,
b5cc0357
OL
612 )
613
53ae644d
OL
614 l.append(link)
615 return "<ul>%s</ul>" % "\n".join(l)
a7f013f5
JPC
616 _dossiers_postes.allow_tags = True
617 _dossiers_postes.short_description = u"Dossiers et postes"
53ae644d
OL
618
619 def queryset(self, request):
22343fe7 620 qs = super(EmployeAdmin, self).queryset(request)
53ae644d
OL
621 return qs.select_related(depth=1).order_by('nom')
622
623 def save_formset(self, request, form, formset, change):
624 instances = formset.save(commit=False)
625 for instance in instances:
626 if instance.__class__ == rh.EmployeCommentaire:
627 instance.owner = request.user
02e69aa2 628 instance.date_creation = datetime.datetime.now()
53ae644d
OL
629 instance.save()
630
22343fe7 631
08faf06e 632class EmployeProxyAdmin(EmployeAdmin):
22343fe7 633 list_display = ('_id', '_apercu', '_nom', '_organigramme')
bd917a45
JPC
634 actions = None
635
636 def __init__(self, *args, **kwargs):
637 super(EmployeProxyAdmin, self).__init__(*args, **kwargs)
638 self.list_display_links = (None, )
08faf06e 639
22343fe7
OL
640 def has_add_permission(self, obj):
641 return False
642
08faf06e
JPC
643 def _organigramme(self, obj):
644 l = []
fc4bf968
EMS
645 for d in rh.Dossier.objects.filter(
646 Q(date_fin__gt=datetime.date.today()) | Q(date_fin=None),
647 Q(date_debut__lt=datetime.date.today()) | Q(date_debut=None),
648 employe=obj.id
649 ):
650 organigramme = \
651 u'Organigramme, niveau: ' \
652 u'<input type="text" id="level_%s" ' \
653 u'style="width:30px;height:15px;" /> ' \
654 u'<input type="button" value="Générer" ' \
655 u"""onclick="window.location='%s' + """ \
656 u"""document.getElementById('level_%s').value" />""" % (
657 d.poste.id,
658 reverse('rho_employe_sans_niveau', args=(d.poste.id,)),
659 d.poste.id
660 )
661 link = u"""<li>%s - [%s] %s : %s</li>""" % (
662 d.date_debut.year,
663 d.poste.id,
664 d.poste.nom,
665 organigramme
666 )
08faf06e
JPC
667 l.append(link)
668 return "<ul>%s</ul>" % "\n".join(l)
669
670 _organigramme.allow_tags = True
671 _organigramme.short_description = "Organigramme"
672
53ae644d 673
53ae644d
OL
674class EmployeCommentaireAdmin(admin.ModelAdmin):
675 pass
676
677
678class EmployePieceAdmin(admin.ModelAdmin):
679 pass
680
681
7bf28694 682class CategorieEmploiAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 683 list_display = ('nom', '_date_modification', 'user_modification', )
53ae644d 684 inlines = (TypePosteInline,)
22343fe7
OL
685 fieldsets = AUFMetadataAdminMixin.fieldsets + (
686 (None, {'fields': ('nom', )}),)
53ae644d 687
33232787 688 def _date_modification(self, obj):
22343fe7
OL
689 return date(obj.date_modification) \
690 if obj.date_modification is not None else "(aucune)"
33232787
JPC
691 _date_modification.short_description = u'date modification'
692 _date_modification.admin_order_field = 'date_modification'
53ae644d 693
22343fe7 694
95b630cf 695class OrganismeBstgAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
c5964dc2 696 search_fields = ('nom',)
22343fe7
OL
697 list_display = (
698 'nom',
699 'type',
700 'pays',
701 '_date_modification',
702 'user_modification',
703 )
c5964dc2 704 list_filter = ('type', )
53ae644d 705 inlines = (DossierROInline,)
22343fe7
OL
706 fieldsets = AUFMetadataAdminMixin.fieldsets + (
707 (None, {'fields': ('nom', 'type', 'pays',)}),
53ae644d
OL
708 )
709
33232787 710 def _date_modification(self, obj):
22343fe7
OL
711 return date(obj.date_modification) \
712 if obj.date_modification is not None else "(aucune)"
33232787
JPC
713 _date_modification.short_description = u'date modification'
714 _date_modification.admin_order_field = 'date_modification'
715
53ae644d 716
22343fe7
OL
717class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, \
718 ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
719 form = make_ajax_form(rh.Poste, {
720 'implantation': 'implantations',
721 'type_poste': 'typepostes',
722 'responsable': 'postes',
723 'valeur_point_min': 'valeurpoints',
724 'valeur_point_max': 'valeurpoints',
53ae644d
OL
725 })
726 alphabet_filter = 'nom'
22343fe7 727 search_fields = (
397bf8dd 728 'id',
22343fe7 729 'nom',
22343fe7
OL
730 'implantation__nom',
731 'implantation__region__code',
732 'implantation__region__nom',
733 'rh_dossiers__employe__nom',
734 'rh_dossiers__employe__prenom',
735 )
53ae644d 736 list_display = (
e49ac947 737 '_id',
8f3ca727 738 '_apercu',
22343fe7 739 '_nom',
53ae644d 740 '_occupe_par',
22343fe7
OL
741 'implantation',
742 '_service',
1ce2ddb9 743 '_responsable',
352fa696 744 'date_debut',
53ae644d 745 'date_fin',
33232787 746 '_date_modification',
53ae644d 747 'user_modification',
a47ed016 748 '_dae',
53ae644d 749 )
f614ca5c 750 list_filter = (
22343fe7 751 'implantation__region',
53ae644d 752 'implantation',
22343fe7 753 'service',
53ae644d 754 'type_poste',
7bf28694 755 'type_poste__categorie_emploi',
118efe7a 756 'type_poste__famille_professionnelle',
4c53dda4 757 'vacant',
53ae644d 758 )
e49ac947 759 list_display_links = ('_nom',)
53ae644d 760 fieldsets = AUFMetadataAdminMixin.fieldsets + (
22343fe7
OL
761 (None, {'fields': (
762 ('nom', 'nom_feminin'),
763 'implantation',
764 'type_poste',
765 'service',
766 'responsable',
767 )}
768 ),
53ae644d 769 ('Contrat', {
22343fe7
OL
770 'fields': ((
771 'regime_travail',
772 'regime_travail_nb_heure_semaine'),
773 )}
774 ),
53ae644d 775 ('Recrutement', {
22343fe7
OL
776 'fields': (('local', 'expatrie', 'mise_a_disposition', 'appel'),)}
777 ),
53ae644d 778 ('Rémunération', {
22343fe7
OL
779 'fields': (('classement_min',
780 'valeur_point_min',
781 'devise_min',
782 'salaire_min',
783 'indemn_min',
784 'autre_min',),
785 ('classement_max',
786 'valeur_point_max',
787 'devise_max',
788 'salaire_max',
789 'indemn_max',
790 'autre_max',),
791 )}),
53ae644d
OL
792 ('Comparatifs de rémunération', {
793 'fields': ('devise_comparaison',
794 ('comp_locale_min', 'comp_locale_max'),
795 ('comp_universite_min', 'comp_universite_max'),
796 ('comp_fonctionpub_min', 'comp_fonctionpub_max'),
797 ('comp_ong_min', 'comp_ong_max'),
22343fe7
OL
798 ('comp_autre_min', 'comp_autre_max'))}
799 ),
53ae644d 800 ('Justification', {
22343fe7
OL
801 'fields': ('justification',)}
802 ),
48a6df80 803 ('Autres Méta-données', {
22343fe7
OL
804 'fields': ('date_debut', 'date_fin')}
805 ),
53ae644d
OL
806 )
807
808 inlines = (PosteFinancementInline,
809 PostePieceInline,
810 DossierROInline,
6f037929 811 PosteComparaisonInline,
53ae644d
OL
812 PosteCommentaireInline, )
813
f614ca5c 814 def lookup_allowed(self, key, value):
118efe7a
EMS
815 return key in (
816 'date_debut__gte', 'date_debut__isnull', 'date_fin__lte',
817 'date_fin__isnull', 'implantation__region__id__exact',
818 'implantation__id__exact', 'type_poste__id__exact',
819 'type_poste__categorie_emploi__id__exact', 'service__id__exact',
820 'service__isnull', 'vacant__exact', 'vacant__isnull',
821 ) or super(PosteAdmin, self).lookup_allowed(key, value)
f614ca5c 822
8f3ca727 823 def _apercu(self, poste):
22343fe7
OL
824 view_link = u"""<a onclick="return showAddAnotherPopup(this);"
825 title="Aperçu du poste"
826 href='%s'>
827 <img src="%simg/loupe.png" />
828 </a>""" % \
8f3ca727 829 (reverse('poste_apercu', args=(poste.id,)),
22343fe7
OL
830 settings.STATIC_URL,)
831 return view_link
8f3ca727 832 _apercu.allow_tags = True
e49ac947
JPC
833 _apercu.short_description = ''
834
a47ed016
OL
835 def _dae(self, poste):
836 apercu_link = ""
de151a1e
EMS
837 postes_dae = poste.postes_dae.all()
838 if len(postes_dae) > 0:
839 poste_dae = postes_dae[0]
840 apercu_link = \
841 u'<a title="Aperçu du dossier" href="%s" ' \
842 u'onclick="return showAddAnotherPopup(this);">' \
843 u'<img src="%simg/loupe.png" /></a>' % (reverse(
844 'poste_consulter', args=("dae-%s" % poste_dae.id,)
845 ), settings.STATIC_URL)
a47ed016
OL
846 return apercu_link
847 _dae.allow_tags = True
848 _dae.short_description = u"DAE"
849
e49ac947
JPC
850 def _id(self, obj):
851 return "%s" % obj.id
852 _id.short_description = '#'
853 _id.admin_order_field = 'id'
8f3ca727 854
c5964dc2 855 def _service(self, obj):
1b130b25
JPC
856 if obj.service.supprime:
857 return """<span style="color:red">%s</span>""" % obj.service
858 else:
859 return obj.service
6c2b1160 860 _service.short_description = 'Service'
1b130b25 861 _service.allow_tags = True
53ae644d 862
1ce2ddb9
JPC
863 def _responsable(self, obj):
864 try:
22343fe7
OL
865 responsable = u"""<a href="%s"
866 onclick="return showAddAnotherPopup(this)">
867 <img src="%simg/loupe.png"
868 title="Aperçu du poste" />
869 </a>
870 <a href="%s">%s</a>
871 <br />""" % \
872 (reverse('poste_apercu', args=(obj.responsable.id,)),
873 settings.STATIC_URL,
874 reverse('admin:rh_poste_change', args=(obj.responsable.id,)),
875 obj.responsable.nom)
1ce2ddb9
JPC
876 except:
877 responsable = ''
878
879 try:
fc4bf968 880 employe = obj.responsable.rh_dossiers.all()[0]
1ce2ddb9 881 employe_id = obj.responsable.rh_dossiers.all()[0].id
fc4bf968 882 employe_html = u"""<br />
22343fe7
OL
883 <a href="%s"
884 onclick="return showAddAnotherPopup(this)">
885 <img src="%simg/loupe.png"
886 title="Aperçu de l'employé">
887 </a>
888 <a href="%s">%s</a>""" % \
889 (reverse('employe_apercu', args=(employe_id,)),
890 settings.STATIC_URL,
891 reverse('admin:rh_employe_change', args=(employe_id,)),
892 employe)
1ce2ddb9 893 except:
fc4bf968 894 employe_html = ""
1ce2ddb9 895
fc4bf968 896 return "%s %s" % (responsable, employe_html)
1ce2ddb9
JPC
897 _responsable.short_description = 'Responsable'
898 _responsable.allow_tags = True
899
53ae644d 900 def _nom(self, poste):
e49ac947
JPC
901 return """<a href="%s">%s</a>""" % \
902 (reverse('admin:rh_poste_change', args=(poste.id,)),
22343fe7 903 poste.nom)
53ae644d
OL
904 _nom.allow_tags = True
905 _nom.short_description = u'Nom'
906 _nom.admin_order_field = 'nom'
907
33232787
JPC
908 def _date_modification(self, obj):
909 return date(obj.date_modification)
910 _date_modification.short_description = u'date modification'
911 _date_modification.admin_order_field = 'date_modification'
912
53ae644d
OL
913 def _occupe_par(self, obj):
914 """Formatte la méthode Poste.occupe_par() pour l'admin"""
15c5f55a 915 output = u"Vacant"
ae5d7df3 916 if obj.date_fin is not None and obj.date_fin < datetime.date.today():
954ead19 917 return u"s/o"
53ae644d
OL
918 employes = obj.occupe_par()
919 if employes:
920 l = []
921 for e in employes:
22343fe7
OL
922 link = u"""<a href='%s'
923 title='Aperçu de l\'employer'
924 onclick='return showAddAnotherPopup(this)'>
925 <img src='%simg/loupe.png' />
926 </a>
927 <a href='%s'>%s</a>""" % \
b10920ea 928 (reverse('employe_apercu', args=(e.id,)),
822a2c33 929 settings.STATIC_URL,
b10920ea 930 reverse('admin:rh_employe_change', args=(e.id,)),
22343fe7 931 e)
53ae644d
OL
932 l.append(link)
933 output = "\n<br />".join(l)
934 return output
935 _occupe_par.allow_tags = True
22343fe7 936 _occupe_par.short_description = "Occupé par"
53ae644d
OL
937
938 def save_formset(self, request, form, formset, change):
939 instances = formset.save(commit=False)
940 for instance in instances:
941 if instance.__class__ == rh.PosteCommentaire:
942 instance.owner = request.user
02e69aa2 943 instance.date_creation = datetime.datetime.now()
53ae644d
OL
944 instance.save()
945 formset.save_m2m()
946
947
948class PosteCommentaireAdmin(admin.ModelAdmin):
949 pass
950
951
952class PosteFinancementAdmin(admin.ModelAdmin):
953 pass
954
955
956class PostePieceAdmin(admin.ModelAdmin):
957 fk_name = 'poste'
958
959
960class RemunerationAdmin(admin.ModelAdmin):
961 pass
962
963
8c8ffc4f
OL
964class ResponsableInline(admin.TabularInline):
965 model = rh.ResponsableImplantation
966 extra = 0
fc4bf968
EMS
967 fk_name = "implantation"
968
22343fe7 969
8c8ffc4f
OL
970class ResponsableImplantationAdmin(admin.ModelAdmin):
971 actions = None
972 list_filter = ('region', 'statut', )
973 list_display = ('nom', 'statut', '_responsable', )
974 readonly_fields = ('nom', )
975 fields = ('nom', )
976 inlines = (ResponsableInline, )
977
978 def _responsable(self, obj):
979 try:
980 employe = obj.responsable.employe
981 dossiers = employe.dossiers_encours()
982 if len(dossiers) == 0:
983 return u"<span style='color: red;'>%s %s </span>" % (
984 employe, u"sans dossier actif")
985 else:
986 return employe
fc4bf968
EMS
987 except Exception:
988 if obj.statut in (1, 2): # ouverte, ouverture imminente
8c8ffc4f
OL
989 css = "style='color: red;'"
990 else:
991 css = ""
992 return u"<span %s>Pas de responsable</span>" % css
993 _responsable.allow_tags = True
994 _responsable.short_description = u"Responsable"
995
996 def has_add_permission(self, request=None):
997 return False
998
999 def has_change_permission(self, request, obj=None):
1000 return in_drh_or_admin(request.user)
1001
1002 def has_delete_permission(self, request, obj=None):
1003 return False
53ae644d 1004
fc4bf968 1005
7ba822a6 1006class ServiceAdmin(AUFMetadataAdminMixin, admin.ModelAdmin, ArchiveMixin):
22343fe7
OL
1007 list_display = (
1008 'nom',
1009 '_archive',
1010 '_date_modification',
1011 'user_modification',
1012 )
cbb0373e 1013 list_filter = ('archive', )
22343fe7 1014 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d 1015 (None, {
cbb0373e 1016 'fields': ('nom', 'archive', ),
53ae644d
OL
1017 }),
1018 )
1019
33232787 1020 def _date_modification(self, obj):
22343fe7
OL
1021 return date(obj.date_modification) \
1022 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1023 _date_modification.short_description = u'date modification'
1024 _date_modification.admin_order_field = 'date_modification'
1025
fc4bf968 1026
5c0f1778 1027class ServiceProxyAdmin(ServiceAdmin):
cfd5ac68 1028 list_display = ('nom', '_organigramme', '_archive', )
8135fc65
JPC
1029 actions = None
1030
1031 def __init__(self, *args, **kwargs):
1032 super(ServiceProxyAdmin, self).__init__(*args, **kwargs)
1033 self.list_display_links = (None, )
5c0f1778 1034
f7badf51
EMS
1035 def queryset(self, request):
1036 return super(ServiceProxyAdmin, self).queryset(request) \
1037 .annotate(num_postes=Count('rh_postes')) \
1038 .filter(num_postes__gt=0)
1039
5c0f1778
JPC
1040 def has_add_permission(self, obj):
1041 return False
1042
aa2c508e
JPC
1043 def has_change_permission(self, request, obj=None):
1044 return in_drh_or_admin(request.user)
1045
5c0f1778 1046 def _organigramme(self, obj):
8135fc65
JPC
1047 return """<a href="%s"><strong>Organigramme</strong></a>""" % \
1048 (reverse('rho_service', args=(obj.id,)))
5c0f1778
JPC
1049 _organigramme.allow_tags = True
1050 _organigramme.short_description = "Organigramme"
1051
8135fc65 1052
53ae644d 1053class StatutAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 1054 list_display = ('code', 'nom', '_date_modification', 'user_modification', )
22343fe7 1055 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d
OL
1056 (None, {
1057 'fields': ('code', 'nom', ),
1058 }),
1059 )
1060
33232787 1061 def _date_modification(self, obj):
22343fe7
OL
1062 return date(obj.date_modification) \
1063 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1064 _date_modification.short_description = u'date modification'
1065 _date_modification.admin_order_field = 'date_modification'
1066
22343fe7 1067
53ae644d 1068class TauxChangeAdmin(admin.ModelAdmin):
22343fe7
OL
1069 list_display = (
1070 'taux',
1071 'devise',
1072 'annee',
1073 '_date_modification',
1074 'user_modification',
1075 )
53ae644d 1076 list_filter = ('devise', )
22343fe7 1077 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d
OL
1078 (None, {
1079 'fields': ('taux', 'devise', 'annee', ),
1080 }),
1081 )
1082
33232787 1083 def _date_modification(self, obj):
22343fe7
OL
1084 return date(obj.date_modification) \
1085 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1086 _date_modification.short_description = u'date modification'
1087 _date_modification.admin_order_field = 'date_modification'
1088
22343fe7 1089
53ae644d 1090class TypeContratAdmin(admin.ModelAdmin):
22343fe7
OL
1091 list_display = (
1092 'nom',
1093 'nom_long',
1094 '_date_modification',
1095 'user_modification',
1096 )
1097 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d
OL
1098 (None, {
1099 'fields': ('nom', 'nom_long', ),
1100 }),
1101 )
1102
33232787 1103 def _date_modification(self, obj):
22343fe7
OL
1104 return date(obj.date_modification) \
1105 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1106 _date_modification.short_description = u'date modification'
1107 _date_modification.admin_order_field = 'date_modification'
1108
53ae644d
OL
1109
1110class TypePosteAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1111 search_fields = ('nom', 'nom_feminin', )
22343fe7
OL
1112 list_display = (
1113 'nom',
7bf28694 1114 'categorie_emploi',
22343fe7
OL
1115 '_date_modification',
1116 'user_modification',
1117 )
321fe481 1118 list_filter = ('categorie_emploi', 'famille_professionnelle')
22343fe7 1119 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d 1120 (None, {
22343fe7
OL
1121 'fields': (
1122 'nom',
1123 'nom_feminin',
1124 'is_responsable',
7bf28694 1125 'categorie_emploi',
321fe481 1126 'famille_professionnelle',
22343fe7
OL
1127 )}
1128 ),
53ae644d
OL
1129 )
1130
33232787 1131 def _date_modification(self, obj):
22343fe7
OL
1132 return date(obj.date_modification) \
1133 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1134 _date_modification.short_description = u'date modification'
1135 _date_modification.admin_order_field = 'date_modification'
1136
53ae644d 1137
fc4bf968
EMS
1138class TypeRemunerationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin,
1139 ArchiveMixin):
22343fe7
OL
1140 list_display = (
1141 'nom',
1142 'type_paiement',
1143 'nature_remuneration',
7ba822a6 1144 '_archive',
22343fe7
OL
1145 '_date_modification',
1146 'user_modification',)
7ba822a6 1147 list_filter = ('archive', )
22343fe7 1148 fieldsets = AUFMetadataAdminMixin.fieldsets + (
7ba822a6
OL
1149 (None, {'fields': ('nom', 'type_paiement', 'nature_remuneration',
1150 'archive')}),
53ae644d
OL
1151 )
1152
33232787 1153 def _date_modification(self, obj):
22343fe7
OL
1154 return date(obj.date_modification) \
1155 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1156 _date_modification.short_description = u'date modification'
1157 _date_modification.admin_order_field = 'date_modification'
1158
53ae644d
OL
1159
1160class TypeRevalorisationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 1161 list_display = ('nom', '_date_modification', 'user_modification', )
22343fe7
OL
1162 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1163 (None, {'fields': ('nom', )}),
53ae644d
OL
1164 )
1165
33232787 1166 def _date_modification(self, obj):
22343fe7
OL
1167 return date(obj.date_modification) \
1168 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1169 _date_modification.short_description = u'date modification'
1170 _date_modification.admin_order_field = 'date_modification'
1171
53ae644d
OL
1172
1173class ValeurPointAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
22343fe7
OL
1174 list_display = (
1175 '_devise_code',
1176 '_devise_nom',
1177 'annee',
88202dc3 1178 'implantation',
22343fe7
OL
1179 'valeur',
1180 '_date_modification',
1181 'user_modification',
1182 )
88202dc3 1183 list_filter = ('annee', 'devise', 'implantation__region', )
22343fe7
OL
1184 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1185 (None, {'fields': ('valeur', 'devise', 'implantation', 'annee', )}),
53ae644d
OL
1186 )
1187
33232787 1188 def _date_modification(self, obj):
22343fe7
OL
1189 return date(obj.date_modification) \
1190 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1191 _date_modification.short_description = u'date modification'
1192 _date_modification.admin_order_field = 'date_modification'
1193
53ae644d
OL
1194 def _devise_code(self, obj):
1195 return obj.devise.code
1196 _devise_code.short_description = "Code de la devise"
1197
1198 def _devise_nom(self, obj):
1199 return obj.devise.nom
1200 _devise_nom.short_description = "Nom de la devise"
1201
fc4bf968 1202
82af5c19
JPC
1203class ImplantationProxyAdmin(admin.ModelAdmin):
1204 list_display = ('nom', '_organigramme')
8135fc65
JPC
1205 actions = None
1206
1207 def __init__(self, *args, **kwargs):
1208 super(ImplantationProxyAdmin, self).__init__(*args, **kwargs)
1209 self.list_display_links = (None, )
82af5c19
JPC
1210
1211 def has_add_permission(self, obj):
1212 return False
1213
aa2c508e
JPC
1214 def has_change_permission(self, request, obj=None):
1215 return in_drh_or_admin(request.user)
1216
82af5c19 1217 def _organigramme(self, obj):
fc4bf968
EMS
1218 return '<a href="%s"><strong>Organigramme</strong></a>' % (
1219 reverse('rho_implantation', args=(obj.id,))
1220 )
82af5c19
JPC
1221 _organigramme.allow_tags = True
1222 _organigramme.short_description = "Organigramme"
1223
fc4bf968 1224
9da4c195
JPC
1225class RegionProxyAdmin(admin.ModelAdmin):
1226 list_display = ('nom', '_organigramme')
8135fc65
JPC
1227 actions = None
1228
1229 def __init__(self, *args, **kwargs):
1230 super(RegionProxyAdmin, self).__init__(*args, **kwargs)
1231 self.list_display_links = (None, )
9da4c195
JPC
1232
1233 def has_add_permission(self, obj):
1234 return False
1235
aa2c508e
JPC
1236 def has_change_permission(self, request, obj=None):
1237 return in_drh_or_admin(request.user)
1238
9da4c195 1239 def _organigramme(self, obj):
fc4bf968
EMS
1240 return """<a href="%s"><strong>Organigramme</strong></a>""" % (
1241 reverse('rho_region', args=(obj.id,))
1242 )
9da4c195
JPC
1243 _organigramme.allow_tags = True
1244 _organigramme.short_description = "Organigramme"
1245
1246
53ae644d
OL
1247admin.site.register(rh.Classement, ClassementAdmin)
1248admin.site.register(rh.Devise, DeviseAdmin)
1249admin.site.register(rh.Dossier, DossierAdmin)
22343fe7 1250admin.site.register(EmployeProxy, EmployeProxyAdmin)
5c0f1778 1251admin.site.register(ServiceProxy, ServiceProxyAdmin)
53ae644d 1252admin.site.register(rh.Employe, EmployeAdmin)
7bf28694 1253admin.site.register(rh.CategorieEmploi, CategorieEmploiAdmin)
321fe481 1254admin.site.register(rh.FamilleProfessionnelle)
53ae644d
OL
1255admin.site.register(rh.OrganismeBstg, OrganismeBstgAdmin)
1256admin.site.register(rh.Poste, PosteAdmin)
fc4bf968
EMS
1257admin.site.register(
1258 rh.ResponsableImplantationProxy, ResponsableImplantationAdmin
1259)
53ae644d 1260admin.site.register(rh.Service, ServiceAdmin)
c5964dc2 1261admin.site.register(rh.Statut, StatutAdmin)
53ae644d 1262admin.site.register(rh.TauxChange, TauxChangeAdmin)
c5964dc2 1263admin.site.register(rh.TypeContrat, TypeContratAdmin)
53ae644d
OL
1264admin.site.register(rh.TypePoste, TypePosteAdmin)
1265admin.site.register(rh.TypeRemuneration, TypeRemunerationAdmin)
1266admin.site.register(rh.TypeRevalorisation, TypeRevalorisationAdmin)
1267admin.site.register(rh.ValeurPoint, ValeurPointAdmin)
82af5c19 1268admin.site.register(ImplantationProxy, ImplantationProxyAdmin)
9da4c195 1269admin.site.register(RegionProxy, RegionProxyAdmin)