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