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