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