Multiples zones par user implémenté
[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',
22343fe7
OL
432 'statut',
433 'organisme_bstg',)}),
53ae644d 434 ('Recrutement', {
22343fe7
OL
435 'fields': (
436 'statut_residence',
437 'remplacement',
438 'remplacement_de', )}),
53ae644d 439 ('Rémunération', {
22343fe7
OL
440 'fields': (
441 'classement',
442 ('regime_travail', 'regime_travail_nb_heure_semaine'),)}),
53ae644d 443 ('Occupation du Poste par cet Employe', {
22343fe7
OL
444 'fields': (('date_debut', 'date_fin'), )}
445 ),
53ae644d 446 )
22343fe7
OL
447 form = make_ajax_form(rh.Dossier, {
448 'employe': 'employes',
449 'poste': 'postes',
450 'remplacement_de': 'dossiers',
6bee05ff 451 }, superclass=DossierForm)
53ae644d
OL
452
453 def lookup_allowed(self, key, value):
454 if key in (
455 'employe__nom__istartswith',
b0cf30b8 456 'poste__implantation__zone_administrative__code__exact',
e8b6a20c 457 'poste__implantation__zone_administrative__in',
53ae644d
OL
458 'poste__implantation__id__exact',
459 'poste__type_poste__id__exact',
7bf28694 460 'poste__type_poste__categorie_emploi__id__exact',
53ae644d 461 'rh_contrats__type_contrat__id__exact',
6bee05ff
OL
462 'principal__exact',
463 'principal__isnull',
53ae644d
OL
464 ):
465 return True
466
e49ac947
JPC
467 def _id(self, obj):
468 return obj.id
469 _id.short_description = u"#"
470 _id.admin_order_field = "id"
471
e49ac947 472 def _apercu(self, d):
22343fe7
OL
473 apercu_link = u"""<a title="Aperçu du dossier"
474 onclick="return showAddAnotherPopup(this);"
475 href='%s'>
9533bd15 476 <img src="%simg/dossier-apercu.png" />
22343fe7 477 </a>""" % \
b10920ea 478 (reverse('dossier_apercu', args=(d.id,)),
822a2c33 479 settings.STATIC_URL,
b10920ea 480 )
e49ac947
JPC
481 return apercu_link
482 _apercu.allow_tags = True
483 _apercu.short_description = u""
53ae644d 484
5db1c5a3
DB
485 def _nom(self, obj):
486 return "Dossier"
487 _nom.allow_tags = True
488 _nom.short_description = u"Dossier"
53ae644d 489
5db1c5a3
DB
490 def _employe(self, obj):
491 employe = obj.employe
492 view_link = reverse('employe_apercu', args=(employe.id,))
493 edit_link = reverse('admin:rh_employe_change', args=(employe.id,))
5db1c5a3
DB
494 style = ""
495 view = u"""<a href="%s"
496 title="Aperçu l'employé"
497 onclick="return showAddAnotherPopup(this);">
498 <img src="%simg/employe-apercu.png" />
499 </a>""" % (view_link, settings.STATIC_URL,)
500 return u"""%s<a href='%s' style="%s;">%s</a>""" % \
501 (view, edit_link, style, employe)
502 _employe.allow_tags = True
503 _employe.short_description = u"Employé"
504 _employe.admin_order_field = "employe__nom"
53ae644d
OL
505
506 def _poste(self, dossier):
22343fe7
OL
507 link = u"""<a title="Aperçu du poste"
508 onclick="return showAddAnotherPopup(this);"
9533bd15 509 href='%s'><img src="%simg/poste-apercu.png" />
22343fe7 510 </a>
5db1c5a3 511 <a href="%s" title="Modifier le poste">%s [%d]</a>""" % \
53ae644d 512 (reverse('poste_apercu', args=(dossier.poste.id,)),
822a2c33 513 settings.STATIC_URL,
211a0e56 514 reverse('admin:rh_poste_change', args=(dossier.poste.id,)),
5db1c5a3
DB
515 dossier.poste.nom,
516 dossier.poste.id,
53ae644d
OL
517 )
518 return link
519 _poste.allow_tags = True
520 _poste.short_description = u'Poste'
521 _poste.admin_order_field = 'poste__nom'
522
b0cf30b8
EMS
523 def _zone_administrative(self, obj):
524 return obj.poste.implantation.zone_administrative.code
525 _zone_administrative.short_description = u"Zone administrative"
90440a65
EMS
526 _zone_administrative.admin_order_field = \
527 'poste__implantation__zone_administrative__code'
53ae644d 528
5db1c5a3
DB
529 def _implantation(self, obj):
530 return obj.poste.implantation.nom
531 _implantation.short_description = u"Implantation"
532 _implantation.admin_order_field = 'poste__implantation__nom'
533
534 def _date_debut(self, obj):
535 return date(obj.date_debut)
536
537 _date_debut.short_description = u'Début'
538 _date_debut.admin_order_field = 'date_debut'
539
540 def _date_fin(self, obj):
541 return date(obj.date_fin)
542 _date_fin.short_description = u'Fin'
543 _date_fin.admin_order_field = 'date_fin'
544
545 def _date_modification(self, obj):
546 return date(obj.date_modification) \
547 if obj.date_modification is not None else "(aucune)"
548 _date_modification.short_description = u'date modification'
549 _date_modification.admin_order_field = 'date_modification'
550
551 def _dae(self, d):
552 apercu_link = ""
553 dossiers_dae = d.dossiers_dae.all()
554 if len(dossiers_dae) > 0:
555 dossier_dae = dossiers_dae[0]
556 apercu_link = u"""<a title="Aperçu du dossier"
557 onclick="return showAddAnotherPopup(this);"
558 href='%s'>
559 <img src="%simg/loupe.png" />
560 </a>""" % \
561 (reverse('embauche_consulter', args=(dossier_dae.id,)),
562 settings.STATIC_URL,
563 )
564 return apercu_link
565 _dae.allow_tags = True
566 _dae.short_description = u"DAE"
22343fe7 567
53ae644d
OL
568 def save_formset(self, request, form, formset, change):
569 instances = formset.save(commit=False)
570 for instance in instances:
571 if instance.__class__ == rh.DossierCommentaire:
572 instance.owner = request.user
02e69aa2 573 instance.date_creation = datetime.datetime.now()
53ae644d
OL
574 instance.save()
575
576
45066657
EMS
577class EmployeAdminBase(DateRangeMixin, ProtectRegionMixin,
578 DerniereModificationAdmin, BaseAdmin):
7eb6b687 579 prefixe_recherche_temporelle = "rh_dossiers__"
53ae644d
OL
580 alphabet_filter = 'nom'
581 DEFAULT_ALPHABET = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
e23da9c3
EMS
582 search_fields = (
583 'id', 'nom', 'prenom', 'nom_affichage',
584 'rh_dossiers__poste__nom',
585 'rh_dossiers__poste__nom_feminin'
586 )
53ae644d
OL
587 ordering = ('nom', )
588 form = EmployeAdminForm
22343fe7 589 list_display = (
f80b83c6 590 '_id', '_apercu', '_nom', '_dossiers_postes',
b0cf30b8 591 #'_zone_administrative',
f80b83c6
OL
592 #'_implantation',
593 'date_entree',
45066657
EMS
594 'derniere_modification'
595 )
e49ac947 596 list_display_links = ('_nom',)
22343fe7 597 list_filter = (
b0cf30b8 598 'rh_dossiers__poste__implantation__zone_administrative',
45066657
EMS
599 'rh_dossiers__poste__implantation', 'nb_postes'
600 )
601 inlines = (
340307bd 602 AyantDroitInline, DossierROInline, EmployePieceInline,
45066657
EMS
603 EmployeCommentaireInline
604 )
605 fieldsets = (
53ae644d 606 ('Identification', {
22343fe7
OL
607 'fields': (
608 ('nom', 'prenom'),
609 ('nom_affichage', 'genre'),
610 'nationalite',
611 'date_naissance',
45066657
EMS
612 )
613 }),
53ae644d 614 ('Informations personnelles', {
45066657
EMS
615 'fields': ('situation_famille', 'date_entree', )
616 }),
89a8df07 617 ('Coordonnées personnelles', {
22343fe7
OL
618 'fields': (
619 ('tel_domicile', 'tel_cellulaire'),
620 ('adresse', 'ville'),
621 ('code_postal', 'province'),
622 'pays',
89a8df07 623 'courriel_perso'
45066657
EMS
624 )
625 }),
626 )
53ae644d 627
5db1c5a3
DB
628 def _id(self, obj):
629 return obj.id
630 _id.short_description = u"#"
631 _id.admin_order_field = "id"
632
b10920ea 633 def _apercu(self, obj):
22343fe7
OL
634 return u"""<a title="Aperçu de l'employé"
635 onclick="return showAddAnotherPopup(this);"
636 href='%s'>
9533bd15 637 <img src="%simg/employe-apercu.png" />
22343fe7
OL
638 </a>""" % \
639 (reverse('employe_apercu', args=(obj.id,)), settings.STATIC_URL)
b10920ea
JPC
640 _apercu.allow_tags = True
641 _apercu.short_description = u""
b10920ea 642
53ae644d 643 def _nom(self, obj):
53ae644d 644 edit_link = reverse('admin:rh_employe_change', args=(obj.id,))
e6c107de 645 return u"""<a href='%s'><strong>%s</strong></a>""" % \
e49ac947 646 (edit_link, "%s %s" % (obj.nom.upper(), obj.prenom))
53ae644d 647 _nom.allow_tags = True
e49ac947 648 _nom.short_description = u"Employé"
53ae644d
OL
649 _nom.admin_order_field = "nom"
650
b0cf30b8 651 def _zone_administrative(self, obj):
5db1c5a3
DB
652 try:
653 d = rh.Dossier.objects.filter(employe=obj.id, principal=True)[0]
b0cf30b8 654 zone = d.poste.implantation.zone_administrative.code
5db1c5a3 655 except:
b0cf30b8
EMS
656 zone = None
657 return zone
658 _zone_administrative.short_description = u"Zone administrative"
e49ac947 659
5db1c5a3
DB
660 def _implantation(self, obj):
661 try:
662 d = rh.Dossier.objects.filter(employe=obj.id, principal=True)[0]
663 implantation = d.poste.implantation.nom
664 except:
665 implantation = None
666 return implantation
667 _implantation.short_description = u"Implantation"
33232787 668
a7f013f5 669 def _dossiers_postes(self, obj):
53ae644d
OL
670 l = []
671 for d in obj.rh_dossiers.all().order_by('-date_debut'):
5db1c5a3
DB
672 link_style = u''
673 list_style = u''
674 if d.date_fin is not None and d.date_fin < datetime.date.today():
5db1c5a3
DB
675 link_style = u' style="color:#666;"'
676 list_style = u' style="color:grey;"'
08ecf07e 677
22343fe7
OL
678 dossier = u"""<a title="Aperçu du dossier"
679 href="%s"
680 onclick="return showAddAnotherPopup(this);"
681 title="Aperçu du dossier">
9533bd15 682 <img src="%simg/dossier-apercu.png" />
22343fe7 683 </a>
5db1c5a3 684 <a href="%s"%s>Dossier</a>
22343fe7
OL
685 &nbsp;""" % \
686 (reverse('dossier_apercu', args=(d.id,)),
687 settings.STATIC_URL,
5db1c5a3
DB
688 reverse('admin:rh_dossier_change', args=(d.id,)),
689 link_style,)
22343fe7
OL
690
691 poste = u"""<a title="Aperçu du poste"
692 href="%s"
693 onclick="return showAddAnotherPopup(this);"
694 title="Aperçu du poste">
9533bd15 695 <img src="%simg/poste-apercu.png" />
22343fe7 696 </a>
5db1c5a3 697 <a href="%s"%s>%s [%d]</a>
22343fe7
OL
698 &nbsp;""" % \
699 (reverse('poste_apercu', args=(d.poste.id,)),
700 settings.STATIC_URL,
5db1c5a3
DB
701 reverse('admin:rh_poste_change', args=(d.poste.id,)),
702 link_style,
a7f013f5 703 d.poste.nom,
5db1c5a3 704 d.poste.id)
b5cc0357 705
5db1c5a3
DB
706 link = u"""<li%s>%s %s</li>""" % \
707 (list_style, dossier, poste)
b5cc0357 708
53ae644d
OL
709 l.append(link)
710 return "<ul>%s</ul>" % "\n".join(l)
a7f013f5
JPC
711 _dossiers_postes.allow_tags = True
712 _dossiers_postes.short_description = u"Dossiers et postes"
53ae644d 713
5db1c5a3
DB
714 def _date_modification(self, obj):
715 return date(obj.date_modification) \
716 if obj.date_modification is not None else "(aucune)"
717 _date_modification.short_description = u'date modification'
718 _date_modification.admin_order_field = 'date_modification'
719
53ae644d 720 def queryset(self, request):
45066657 721 qs = super(EmployeAdminBase, self).queryset(request)
53ae644d
OL
722 return qs.select_related(depth=1).order_by('nom')
723
724 def save_formset(self, request, form, formset, change):
725 instances = formset.save(commit=False)
726 for instance in instances:
727 if instance.__class__ == rh.EmployeCommentaire:
728 instance.owner = request.user
02e69aa2 729 instance.date_creation = datetime.datetime.now()
53ae644d
OL
730 instance.save()
731
22343fe7 732
45066657 733class EmployeAdmin(reversion.VersionAdmin, EmployeAdminBase):
b2d1cc93 734 change_list_template = "admin/rh/employe/change_list.html"
45066657 735 ignore_duplicate_revisions = True
d104b0ae
EMS
736
737
45066657 738class EmployeProxyAdmin(EmployeAdminBase):
22343fe7 739 list_display = ('_id', '_apercu', '_nom', '_organigramme')
664bdc2f 740 list_per_page = 500
bd917a45
JPC
741 actions = None
742
743 def __init__(self, *args, **kwargs):
744 super(EmployeProxyAdmin, self).__init__(*args, **kwargs)
745 self.list_display_links = (None, )
08faf06e 746
8f7b2d7b
DB
747 def queryset(self, request):
748 qs = super(ProtectRegionMixin, self).queryset(request)
749
750 if in_drh_or_admin(request.user) or \
751 user_gere_obj_de_sa_region(request.user):
752 return qs
753
754 return qs.none()
755
22343fe7
OL
756 def has_add_permission(self, obj):
757 return False
758
c5dab350 759 def has_change_permission(self, request, obj=None):
3383b2d1
OL
760 user_groups = [g.name for g in request.user.groups.all()]
761 if groups.CORRESPONDANT_RH in user_groups or \
762 groups.ADMINISTRATEURS in user_groups or \
763 groups.DIRECTEUR_DE_BUREAU in user_groups or \
c5dab350
OL
764 in_drh_or_admin(request.user):
765 return True
766 return False
767
08faf06e
JPC
768 def _organigramme(self, obj):
769 l = []
fc4bf968
EMS
770 for d in rh.Dossier.objects.filter(
771 Q(date_fin__gt=datetime.date.today()) | Q(date_fin=None),
772 Q(date_debut__lt=datetime.date.today()) | Q(date_debut=None),
773 employe=obj.id
774 ):
775 organigramme = \
776 u'Organigramme, niveau: ' \
777 u'<input type="text" id="level_%s" ' \
778 u'style="width:30px;height:15px;" /> ' \
779 u'<input type="button" value="Générer" ' \
780 u"""onclick="window.location='%s' + """ \
781 u"""document.getElementById('level_%s').value" />""" % (
782 d.poste.id,
783 reverse('rho_employe_sans_niveau', args=(d.poste.id,)),
784 d.poste.id
785 )
e4fa851f 786 link = u"""<li>%s [%s]:<br />%s</li>""" % (
fc4bf968 787 d.poste.nom,
e4fa851f 788 d.poste.id,
fc4bf968
EMS
789 organigramme
790 )
08faf06e
JPC
791 l.append(link)
792 return "<ul>%s</ul>" % "\n".join(l)
793
794 _organigramme.allow_tags = True
795 _organigramme.short_description = "Organigramme"
796
53ae644d 797
45066657
EMS
798class CategorieEmploiAdmin(reversion.VersionAdmin,
799 DerniereModificationAdmin, BaseAdmin):
800 ignore_duplicate_revisions = True
801 list_display = ('nom', 'derniere_modification')
53ae644d 802 inlines = (TypePosteInline,)
45066657
EMS
803 fieldsets = (
804 (None, {'fields': ('nom', )}),
805 )
53ae644d 806
22343fe7 807
45066657 808class OrganismeBstgAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
d104b0ae 809 BaseAdmin):
45066657 810 ignore_duplicate_revisions = True
c5964dc2 811 search_fields = ('nom',)
45066657 812 list_display = ('nom', 'type', 'pays', 'derniere_modification')
c5964dc2 813 list_filter = ('type', )
340307bd 814 inlines = (DossierROInline,)
45066657 815 fieldsets = (
22343fe7 816 (None, {'fields': ('nom', 'type', 'pays',)}),
45066657 817 )
33232787 818
53ae644d 819
45066657
EMS
820class PosteAdmin(DateRangeMixin, ProtectRegionMixin, reversion.VersionAdmin,
821 AjaxSelect, DerniereModificationAdmin, BaseAdmin):
b2d1cc93 822 change_list_template = "admin/rh/poste/change_list.html"
45066657 823 ignore_duplicate_revisions = True
22343fe7
OL
824 form = make_ajax_form(rh.Poste, {
825 'implantation': 'implantations',
826 'type_poste': 'typepostes',
827 'responsable': 'postes',
828 'valeur_point_min': 'valeurpoints',
829 'valeur_point_max': 'valeurpoints',
53ae644d
OL
830 })
831 alphabet_filter = 'nom'
22343fe7 832 search_fields = (
45066657
EMS
833 'id',
834 'nom',
835 'implantation__nom',
b0cf30b8
EMS
836 'implantation__zone_administrative__code',
837 'implantation__zone_administrative__nom',
45066657
EMS
838 'rh_dossiers__employe__id',
839 'rh_dossiers__employe__nom',
840 'rh_dossiers__employe__prenom',
841 )
53ae644d 842 list_display = (
45066657
EMS
843 '_id', '_apercu', '_nom', '_occupe_par', 'implantation', '_service',
844 '_responsable', 'date_debut', 'date_fin', 'derniere_modification',
845 '_dae'
846 )
f614ca5c 847 list_filter = (
b0cf30b8 848 'implantation__zone_administrative',
53ae644d 849 'implantation',
22343fe7 850 'service',
53ae644d 851 'type_poste',
7bf28694 852 'type_poste__categorie_emploi',
118efe7a 853 'type_poste__famille_professionnelle',
4c53dda4 854 'vacant',
45066657 855 )
e49ac947 856 list_display_links = ('_nom',)
45066657 857 fieldsets = (
22343fe7
OL
858 (None, {'fields': (
859 ('nom', 'nom_feminin'),
860 'implantation',
861 'type_poste',
862 'service',
863 'responsable',
864 )}
865 ),
53ae644d 866 ('Contrat', {
22343fe7
OL
867 'fields': ((
868 'regime_travail',
869 'regime_travail_nb_heure_semaine'),
870 )}
871 ),
53ae644d 872 ('Recrutement', {
22343fe7
OL
873 'fields': (('local', 'expatrie', 'mise_a_disposition', 'appel'),)}
874 ),
53ae644d 875 ('Rémunération', {
22343fe7
OL
876 'fields': (('classement_min',
877 'valeur_point_min',
878 'devise_min',
879 'salaire_min',
880 'indemn_min',
881 'autre_min',),
882 ('classement_max',
883 'valeur_point_max',
884 'devise_max',
885 'salaire_max',
886 'indemn_max',
887 'autre_max',),
888 )}),
53ae644d
OL
889 ('Comparatifs de rémunération', {
890 'fields': ('devise_comparaison',
891 ('comp_locale_min', 'comp_locale_max'),
892 ('comp_universite_min', 'comp_universite_max'),
893 ('comp_fonctionpub_min', 'comp_fonctionpub_max'),
894 ('comp_ong_min', 'comp_ong_max'),
22343fe7
OL
895 ('comp_autre_min', 'comp_autre_max'))}
896 ),
53ae644d 897 ('Justification', {
22343fe7
OL
898 'fields': ('justification',)}
899 ),
48a6df80 900 ('Autres Méta-données', {
22343fe7
OL
901 'fields': ('date_debut', 'date_fin')}
902 ),
53ae644d
OL
903 )
904
905 inlines = (PosteFinancementInline,
906 PostePieceInline,
340307bd 907 DossierROInline,
6f037929 908 PosteComparaisonInline,
53ae644d
OL
909 PosteCommentaireInline, )
910
f614ca5c 911 def lookup_allowed(self, key, value):
118efe7a
EMS
912 return key in (
913 'date_debut__gte', 'date_debut__isnull', 'date_fin__lte',
90440a65
EMS
914 'date_fin__isnull',
915 'implantation__zone_administrative__code__exact',
118efe7a
EMS
916 'implantation__id__exact', 'type_poste__id__exact',
917 'type_poste__categorie_emploi__id__exact', 'service__id__exact',
90440a65 918 'service__isnull', 'vacant__exact', 'vacant__isnull'
118efe7a 919 ) or super(PosteAdmin, self).lookup_allowed(key, value)
f614ca5c 920
5db1c5a3
DB
921 def _id(self, obj):
922 return "%s" % obj.id
923 _id.short_description = '#'
924 _id.admin_order_field = 'id'
925
8f3ca727 926 def _apercu(self, poste):
22343fe7
OL
927 view_link = u"""<a onclick="return showAddAnotherPopup(this);"
928 title="Aperçu du poste"
929 href='%s'>
9533bd15 930 <img src="%simg/poste-apercu.png" />
22343fe7 931 </a>""" % \
8f3ca727 932 (reverse('poste_apercu', args=(poste.id,)),
22343fe7
OL
933 settings.STATIC_URL,)
934 return view_link
8f3ca727 935 _apercu.allow_tags = True
e49ac947
JPC
936 _apercu.short_description = ''
937
5db1c5a3
DB
938 def _nom(self, poste):
939 return """<a href="%s">%s</a>""" % \
940 (reverse('admin:rh_poste_change', args=(poste.id,)),
941 poste.nom)
942 _nom.allow_tags = True
943 _nom.short_description = u'Poste'
944 _nom.admin_order_field = 'nom'
a47ed016 945
5db1c5a3
DB
946 def _occupe_par(self, obj):
947 """Formatte la méthode Poste.occupe_par() pour l'admin"""
948 output = u"Vacant"
949 if obj.date_fin is not None and obj.date_fin < datetime.date.today():
950 return u"s/o"
951 employes = obj.occupe_par()
952 if employes:
953 l = []
954 for e in employes:
955 link = u"""<a href='%s'
956 title='Aperçu de l\'employé'
957 onclick='return showAddAnotherPopup(this)'>
958 <img src='%simg/employe-apercu.png' />
959 </a>
960 <a href='%s'>%s</a>""" % \
961 (reverse('employe_apercu', args=(e.id,)),
962 settings.STATIC_URL,
963 reverse('admin:rh_employe_change', args=(e.id,)),
964 e)
965 l.append(link)
966 output = "\n<br />".join(l)
967 return output
968 _occupe_par.allow_tags = True
969 _occupe_par.short_description = "Occupé par"
970
b0cf30b8
EMS
971 def _zone_administrative(self, poste):
972 return poste.implantation.zone_administrative.code
973 _zone_administrative.short_description = 'Zone administrative'
90440a65
EMS
974 _zone_administrative.admin_order_field = \
975 'implantation__zone_administrative__code'
5db1c5a3
DB
976
977 def _implantation(self, poste):
978 return poste.implantation.nom
979 _implantation.short_description = 'Implantation'
980 _implantation.admin_order_field = 'implantation'
8f3ca727 981
c5964dc2 982 def _service(self, obj):
45066657 983 return obj.service
6c2b1160 984 _service.short_description = 'Service'
1b130b25 985 _service.allow_tags = True
53ae644d 986
1ce2ddb9
JPC
987 def _responsable(self, obj):
988 try:
22343fe7
OL
989 responsable = u"""<a href="%s"
990 onclick="return showAddAnotherPopup(this)">
9533bd15 991 <img src="%simg/poste-apercu.png"
22343fe7
OL
992 title="Aperçu du poste" />
993 </a>
5db1c5a3 994 <a href="%s">%s [%d]</a>
22343fe7
OL
995 <br />""" % \
996 (reverse('poste_apercu', args=(obj.responsable.id,)),
997 settings.STATIC_URL,
998 reverse('admin:rh_poste_change', args=(obj.responsable.id,)),
5db1c5a3
DB
999 obj.responsable.nom,
1000 obj.responsable.id)
1ce2ddb9
JPC
1001 except:
1002 responsable = ''
1003
1004 try:
d104b0ae
EMS
1005 dossier = obj.responsable.rh_dossiers.all() \
1006 .order_by('-date_debut')[0]
60f34330 1007 employe_id = dossier.employe.id
fc4bf968 1008 employe_html = u"""<br />
22343fe7
OL
1009 <a href="%s"
1010 onclick="return showAddAnotherPopup(this)">
9533bd15 1011 <img src="%simg/employe-apercu.png"
22343fe7
OL
1012 title="Aperçu de l'employé">
1013 </a>
1014 <a href="%s">%s</a>""" % \
1015 (reverse('employe_apercu', args=(employe_id,)),
1016 settings.STATIC_URL,
1017 reverse('admin:rh_employe_change', args=(employe_id,)),
60f34330 1018 dossier.employe)
1ce2ddb9 1019 except:
fc4bf968 1020 employe_html = ""
1ce2ddb9 1021
fc4bf968 1022 return "%s %s" % (responsable, employe_html)
1ce2ddb9
JPC
1023 _responsable.short_description = 'Responsable'
1024 _responsable.allow_tags = True
1025
5db1c5a3
DB
1026 def _date_debut(self, obj):
1027 return date_format(obj.date_debut)
1028 _date_debut.short_description = u'Début'
1029 _date_debut.admin_order_field = 'date_debut'
f3e3ac6f 1030
5db1c5a3
DB
1031 def _date_fin(self, obj):
1032 return date_format(obj.date_fin)
1033 _date_fin.short_description = u'Fin'
1034 _date_fin.admin_order_field = 'date_fin'
53ae644d 1035
5db1c5a3
DB
1036 def _dae(self, poste):
1037 apercu_link = ""
1038 postes_dae = poste.postes_dae.all()
1039 if len(postes_dae) > 0:
1040 poste_dae = postes_dae[0]
1041 apercu_link = \
1042 u'<a title="Aperçu du dossier" href="%s" ' \
1043 u'onclick="return showAddAnotherPopup(this);">' \
1044 u'<img src="%simg/loupe.png" /></a>' % (reverse(
1045 'poste_consulter', args=("dae-%s" % poste_dae.id,)
1046 ), settings.STATIC_URL)
1047 return apercu_link
1048 _dae.allow_tags = True
1049 _dae.short_description = u"DAE"
53ae644d
OL
1050
1051 def save_formset(self, request, form, formset, change):
1052 instances = formset.save(commit=False)
1053 for instance in instances:
1054 if instance.__class__ == rh.PosteCommentaire:
1055 instance.owner = request.user
02e69aa2 1056 instance.date_creation = datetime.datetime.now()
53ae644d
OL
1057 instance.save()
1058 formset.save_m2m()
1059
1060
8c8ffc4f
OL
1061class ResponsableInline(admin.TabularInline):
1062 model = rh.ResponsableImplantation
1063 extra = 0
fc4bf968 1064 fk_name = "implantation"
6fb68b2f 1065 form = ResponsableInlineForm
fc4bf968 1066
22343fe7 1067
08a9b6fc 1068class ResponsableImplantationAdmin(BaseAdmin):
8c8ffc4f 1069 actions = None
6fb68b2f
DB
1070 fields = ('nom', )
1071 inlines = (ResponsableInline, )
b0cf30b8
EMS
1072 list_filter = ('zone_administrative', 'statut', )
1073 list_display = ('_zone_administrative', '_nom', 'statut', '_responsable', )
6fb68b2f 1074 list_display_links = ('_nom',)
664bdc2f 1075 list_per_page = 500
8c8ffc4f 1076 readonly_fields = ('nom', )
6fb68b2f
DB
1077 search_fields = (
1078 'nom',
1079 'responsable__employe__id',
1080 'responsable__employe__nom',
1081 'responsable__employe__prenom',
1082 )
1083 ordering = ('nom',)
8c8ffc4f 1084 inlines = (ResponsableInline, )
d104b0ae 1085
b0cf30b8
EMS
1086 def _zone_administrative(self, obj):
1087 return obj.zone_administrative.code
1088 _zone_administrative.short_description = u"Zone administrative"
1089 _zone_administrative.admin_order_field = 'zone_administrative__code'
d104b0ae 1090
30dabdc3
DB
1091 def _nom(self, obj):
1092 return obj.nom
1093 _nom.short_description = u"Implantation"
1094 _nom.admin_order_field = 'nom'
d104b0ae 1095
8c8ffc4f
OL
1096 def _responsable(self, obj):
1097 try:
da202402
OL
1098 employe = employe = obj.responsable.employe
1099 except Exception, e:
90440a65
EMS
1100 return (
1101 u"<span style='color: red;'>"
1102 u"Pas de responsable</span><!-- %s -->" % e
1103 )
da202402 1104 try:
8c8ffc4f
OL
1105 dossiers = employe.dossiers_encours()
1106 if len(dossiers) == 0:
1107 return u"<span style='color: red;'>%s %s </span>" % (
1108 employe, u"sans dossier actif")
1109 else:
1110 return employe
da202402
OL
1111 except Exception, e:
1112 return u"<!-- %s -->" % e
8c8ffc4f
OL
1113 _responsable.allow_tags = True
1114 _responsable.short_description = u"Responsable"
6fb68b2f 1115 _responsable.admin_order_field = 'responsable__employe__nom'
8c8ffc4f
OL
1116
1117 def has_add_permission(self, request=None):
1118 return False
1119
1120 def has_change_permission(self, request, obj=None):
1121 return in_drh_or_admin(request.user)
1122
1123 def has_delete_permission(self, request, obj=None):
1124 return False
53ae644d 1125
fc4bf968 1126
7013d234 1127class ServiceAdminBase(ArchivableAdmin, DerniereModificationAdmin, BaseAdmin):
45066657 1128 list_display = ('nom', '_archive', 'derniere_modification')
cbb0373e 1129 list_filter = ('archive', )
45066657
EMS
1130 fieldsets = (
1131 (None, {'fields': ('nom', 'archive')}),
1132 )
33232787 1133
fc4bf968 1134
45066657
EMS
1135class ServiceAdmin(reversion.VersionAdmin, ServiceAdminBase):
1136 ignore_duplicate_revisions = True
d104b0ae
EMS
1137
1138
45066657 1139class ServiceProxyAdmin(ServiceAdminBase):
cfd5ac68 1140 list_display = ('nom', '_organigramme', '_archive', )
8135fc65
JPC
1141 actions = None
1142
1143 def __init__(self, *args, **kwargs):
1144 super(ServiceProxyAdmin, self).__init__(*args, **kwargs)
1145 self.list_display_links = (None, )
5c0f1778 1146
f7badf51
EMS
1147 def queryset(self, request):
1148 return super(ServiceProxyAdmin, self).queryset(request) \
1149 .annotate(num_postes=Count('rh_postes')) \
1150 .filter(num_postes__gt=0)
1151
5c0f1778
JPC
1152 def has_add_permission(self, obj):
1153 return False
1154
aa2c508e 1155 def has_change_permission(self, request, obj=None):
3383b2d1
OL
1156 user_groups = [g.name for g in request.user.groups.all()]
1157 if groups.CORRESPONDANT_RH in user_groups or \
1158 groups.ADMINISTRATEURS in user_groups or \
1159 groups.DIRECTEUR_DE_BUREAU in user_groups or \
c5dab350
OL
1160 in_drh_or_admin(request.user):
1161 return True
1162 return False
aa2c508e 1163
5c0f1778 1164 def _organigramme(self, obj):
8135fc65
JPC
1165 return """<a href="%s"><strong>Organigramme</strong></a>""" % \
1166 (reverse('rho_service', args=(obj.id,)))
5c0f1778
JPC
1167 _organigramme.allow_tags = True
1168 _organigramme.short_description = "Organigramme"
1169
8135fc65 1170
15659516
BS
1171class StatutAdmin(reversion.VersionAdmin,
1172 ArchivableAdmin,
1173 DerniereModificationAdmin,
45066657
EMS
1174 BaseAdmin):
1175 ignore_duplicate_revisions = True
15659516
BS
1176 list_display = ('code', 'nom', 'derniere_modification', '_archive')
1177 list_filter = ('archive', )
45066657 1178 fieldsets = (
53ae644d 1179 (None, {
15659516 1180 'fields': ('code', 'nom', 'archive'),
53ae644d 1181 }),
45066657 1182 )
33232787 1183
22343fe7 1184
45066657
EMS
1185class TauxChangeAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
1186 BaseAdmin):
1187 ignore_duplicate_revisions = True
1188 list_display = ('taux', 'devise', 'annee', 'derniere_modification')
1189 list_filter = ('devise',)
1190 fieldsets = (
53ae644d
OL
1191 (None, {
1192 'fields': ('taux', 'devise', 'annee', ),
1193 }),
45066657 1194 )
33232787 1195
22343fe7 1196
15659516
BS
1197class TypeContratAdmin(reversion.VersionAdmin,
1198 ArchivableAdmin,
1199 DerniereModificationAdmin,
45066657
EMS
1200 BaseAdmin):
1201 ignore_duplicate_revisions = True
15659516
BS
1202 list_display = ('nom', 'nom_long', 'derniere_modification', '_archive')
1203 list_filter = ('archive', )
45066657 1204 fieldsets = (
53ae644d 1205 (None, {
15659516 1206 'fields': ('nom', 'nom_long', 'archive'),
53ae644d 1207 }),
45066657 1208 )
33232787 1209
53ae644d 1210
15659516
BS
1211class TypePosteAdmin(reversion.VersionAdmin,
1212 ArchivableAdmin,
1213 DerniereModificationAdmin,
d104b0ae 1214 BaseAdmin):
45066657 1215 ignore_duplicate_revisions = True
53ae644d 1216 search_fields = ('nom', 'nom_feminin', )
15659516
BS
1217 list_display = ('nom', 'categorie_emploi',
1218 'derniere_modification', '_archive',)
1219 list_filter = ('categorie_emploi', 'famille_professionnelle', 'archive')
45066657 1220 fieldsets = (
53ae644d 1221 (None, {
22343fe7 1222 'fields': (
45066657 1223 'nom', 'nom_feminin', 'is_responsable', 'categorie_emploi',
321fe481 1224 'famille_professionnelle',
15659516 1225 'archive',
45066657
EMS
1226 )
1227 }),
1228 )
33232787 1229
53ae644d 1230
7013d234 1231class TypeRemunerationAdmin(reversion.VersionAdmin, ArchivableAdmin,
45066657
EMS
1232 DerniereModificationAdmin, BaseAdmin):
1233 ignore_duplicate_revisions = True
22343fe7 1234 list_display = (
45066657
EMS
1235 'nom', 'type_paiement', 'nature_remuneration', '_archive',
1236 'derniere_modification'
1237 )
7ba822a6 1238 list_filter = ('archive', )
45066657
EMS
1239 fieldsets = (
1240 (None, {
1241 'fields': (
1242 'nom', 'type_paiement', 'nature_remuneration', 'archive'
1243 )
1244 }),
1245 )
53ae644d 1246
53ae644d 1247
45066657 1248class TypeRevalorisationAdmin(reversion.VersionAdmin,
15659516
BS
1249 ArchivableAdmin,
1250 DerniereModificationAdmin,
1251 BaseAdmin):
45066657 1252 ignore_duplicate_revisions = True
15659516
BS
1253 list_display = ('nom', 'derniere_modification', '_archive')
1254 list_filter = ('archive', )
45066657 1255 fieldsets = (
15659516 1256 (None, {'fields': ('nom', 'archive')}),
45066657 1257 )
33232787 1258
53ae644d 1259
15659516
BS
1260class ValeurPointAdmin(reversion.VersionAdmin,
1261 DerniereModificationAdmin,
d104b0ae 1262 BaseAdmin):
45066657 1263 ignore_duplicate_revisions = True
22343fe7 1264 list_display = (
45066657
EMS
1265 '_devise_code', '_devise_nom', 'annee', 'implantation',
1266 'valeur', 'derniere_modification'
1267 )
b0cf30b8 1268 list_filter = ('annee', 'devise', 'implantation__zone_administrative', )
45066657
EMS
1269 fieldsets = (
1270 (None, {'fields': ('valeur', 'devise', 'implantation', 'annee')}),
1271 )
33232787 1272
866bba57
EMS
1273 def queryset(self, request):
1274 return super(ValeurPointAdmin, self).queryset(request) \
1275 .select_related('devise', 'implantation')
1276
53ae644d
OL
1277 def _devise_code(self, obj):
1278 return obj.devise.code
1279 _devise_code.short_description = "Code de la devise"
1280
1281 def _devise_nom(self, obj):
1282 return obj.devise.nom
1283 _devise_nom.short_description = "Nom de la devise"
1284
fc4bf968 1285
08a9b6fc 1286class ImplantationProxyAdmin(BaseAdmin):
82af5c19 1287 list_display = ('nom', '_organigramme')
8135fc65
JPC
1288 actions = None
1289
1290 def __init__(self, *args, **kwargs):
1291 super(ImplantationProxyAdmin, self).__init__(*args, **kwargs)
1292 self.list_display_links = (None, )
82af5c19
JPC
1293
1294 def has_add_permission(self, obj):
1295 return False
1296
aa2c508e 1297 def has_change_permission(self, request, obj=None):
3383b2d1
OL
1298 user_groups = [g.name for g in request.user.groups.all()]
1299 if groups.CORRESPONDANT_RH in user_groups or \
1300 groups.ADMINISTRATEURS in user_groups or \
1301 groups.DIRECTEUR_DE_BUREAU in user_groups or \
c5dab350
OL
1302 in_drh_or_admin(request.user):
1303 return True
1304 return False
aa2c508e 1305
82af5c19 1306 def _organigramme(self, obj):
fc4bf968
EMS
1307 return '<a href="%s"><strong>Organigramme</strong></a>' % (
1308 reverse('rho_implantation', args=(obj.id,))
1309 )
82af5c19
JPC
1310 _organigramme.allow_tags = True
1311 _organigramme.short_description = "Organigramme"
1312
fc4bf968 1313
08a9b6fc 1314class RegionProxyAdmin(BaseAdmin):
9da4c195 1315 list_display = ('nom', '_organigramme')
8135fc65
JPC
1316 actions = None
1317
1318 def __init__(self, *args, **kwargs):
1319 super(RegionProxyAdmin, self).__init__(*args, **kwargs)
1320 self.list_display_links = (None, )
9da4c195
JPC
1321
1322 def has_add_permission(self, obj):
1323 return False
1324
aa2c508e 1325 def has_change_permission(self, request, obj=None):
3383b2d1
OL
1326 user_groups = [g.name for g in request.user.groups.all()]
1327 if groups.CORRESPONDANT_RH in user_groups or \
1328 groups.ADMINISTRATEURS in user_groups or \
1329 groups.DIRECTEUR_DE_BUREAU in user_groups or \
c5dab350
OL
1330 in_drh_or_admin(request.user):
1331 return True
1332 return False
aa2c508e 1333
9da4c195 1334 def _organigramme(self, obj):
fc4bf968
EMS
1335 return """<a href="%s"><strong>Organigramme</strong></a>""" % (
1336 reverse('rho_region', args=(obj.id,))
1337 )
9da4c195
JPC
1338 _organigramme.allow_tags = True
1339 _organigramme.short_description = "Organigramme"
1340
1341
e8b6a20c
BS
1342class ProfileInline(admin.StackedInline):
1343 model = rh.UserProfile
1344
1345
1346class RHUserAdmin(UserAdmin):
1347 inlines = list(UserAdmin.inlines) + [ProfileInline]
1348
1349
1350admin.site.unregister(User)
1351admin.site.register(User, RHUserAdmin)
1352
53ae644d
OL
1353admin.site.register(rh.Classement, ClassementAdmin)
1354admin.site.register(rh.Devise, DeviseAdmin)
1355admin.site.register(rh.Dossier, DossierAdmin)
22343fe7 1356admin.site.register(EmployeProxy, EmployeProxyAdmin)
5c0f1778 1357admin.site.register(ServiceProxy, ServiceProxyAdmin)
53ae644d 1358admin.site.register(rh.Employe, EmployeAdmin)
7bf28694 1359admin.site.register(rh.CategorieEmploi, CategorieEmploiAdmin)
321fe481 1360admin.site.register(rh.FamilleProfessionnelle)
53ae644d
OL
1361admin.site.register(rh.OrganismeBstg, OrganismeBstgAdmin)
1362admin.site.register(rh.Poste, PosteAdmin)
fc4bf968
EMS
1363admin.site.register(
1364 rh.ResponsableImplantationProxy, ResponsableImplantationAdmin
1365)
53ae644d 1366admin.site.register(rh.Service, ServiceAdmin)
c5964dc2 1367admin.site.register(rh.Statut, StatutAdmin)
53ae644d 1368admin.site.register(rh.TauxChange, TauxChangeAdmin)
c5964dc2 1369admin.site.register(rh.TypeContrat, TypeContratAdmin)
53ae644d
OL
1370admin.site.register(rh.TypePoste, TypePosteAdmin)
1371admin.site.register(rh.TypeRemuneration, TypeRemunerationAdmin)
1372admin.site.register(rh.TypeRevalorisation, TypeRevalorisationAdmin)
1373admin.site.register(rh.ValeurPoint, ValeurPointAdmin)
82af5c19 1374admin.site.register(ImplantationProxy, ImplantationProxyAdmin)
9da4c195 1375admin.site.register(RegionProxy, RegionProxyAdmin)