Normalisation de la liste pour employes, dossiers et postes
[auf_rh_dae.git] / project / rh / admin.py
CommitLineData
53ae644d
OL
1# -*- encoding: utf-8 -*-
2
3from collections import defaultdict
4import datetime
5
6from django.db import models
7from django import forms
8from django.core.urlresolvers import reverse
50fa9bc1 9from django.contrib import admin
3195667e 10from django.contrib.admin.views.main import ChangeList as DjangoChangeList
53ae644d
OL
11from django.conf import settings
12from django.db.models import Q
5f36f262 13from django.template.defaultfilters import date
53ae644d
OL
14from ajax_select import make_ajax_form
15from auf.django.metadata.admin import AUFMetadataAdminMixin, AUFMetadataInlineAdminMixin, AUF_METADATA_READONLY_FIELDS
16from forms import ContratForm, AyantDroitForm, EmployeAdminForm, AjaxSelect
17from dae.utils import get_employe_from_user
a0d365ed 18from groups import grp_drh
53ae644d 19import models as rh
f614ca5c
OL
20import filters
21
40b35603
OL
22################################################################################
23# FILTRAGE PAR DATE
24################################################################################
25class DateRangeMixin(object):
26 """
27 Mixin pour que le model admin utilise le changelist trafiqué permettant de filter par range
28 non strict.
29 Par défaut, le filtrage est configuré sur aujourd'hui, soit les actifs
30 """
7f4d1233
OL
31 date_borne_gauche = 'date_debut'
32 date_borne_droite = 'date_fin'
40b35603
OL
33 def get_changelist(self, request, **kwargs):
34 if request.META.has_key('HTTP_REFERER'):
35 referer = request.META['HTTP_REFERER']
36 referer = "/".join(referer.split('/')[3:])
37 referer = "/%s" % referer.split('?')[0]
38 change_list_view = 'admin:%s_%s_changelist' % (self.model._meta.app_label, self.model.__name__.lower())
39 if referer != reverse(change_list_view):
40 params = request.GET.copy()
41 today = datetime.date.today()
7f4d1233 42 params.update({'%s__gte' % self.date_borne_gauche : str(today), '%s__lte' % self.date_borne_droite : str(today) })
40b35603
OL
43 request.GET = params
44 return ChangeList
3195667e
OL
45
46class ChangeList(DjangoChangeList):
47
48 def __init__(self, *args, **kwargs):
49 super(ChangeList, self).__init__(*args, **kwargs)
50
51 def get_query_set(self):
52 old = self.params.copy()
53 date_debut = None
54 date_fin = None
55 for k, v in self.params.items():
b46d18bc
OL
56 if 'date_debut' in k:
57 prefix_debut = "".join(k.split('date_debut')[0:-1]) + 'date_debut'
3195667e
OL
58 date_debut = v
59 del self.params[k]
b46d18bc
OL
60 elif 'date_fin' in k:
61 prefix_fin = "".join(k.split('date_fin')[0:-1]) + 'date_fin'
3195667e
OL
62 date_fin = v
63 del self.params[k]
3195667e
OL
64 qs = super(ChangeList, self).get_query_set()
65
66 if date_fin is None and date_debut is not None:
67 date_fin = date_debut
b46d18bc 68 prefix_fin = prefix_debut.replace('debut', 'fin')
3195667e
OL
69 if date_debut is None and date_fin is not None:
70 date_debut = date_fin
b46d18bc 71 prefix_debut = prefix_fin.replace('fin', 'debut')
3195667e
OL
72
73 if date_debut is not None and date_fin is not None:
b46d18bc
OL
74 q_left = (Q(**{'%s__isnull' % prefix_debut : True}) | Q(**{'%s__lte' % prefix_debut : date_debut})) & (Q(**{'%s__gte' % prefix_fin : date_debut}) & Q(**{'%s__lte' % prefix_fin : date_fin}))
75 q_right = (Q(**{'%s__isnull' % prefix_fin : True}) | Q(**{'%s__gte' % prefix_fin : date_fin})) & (Q(**{'%s__gte' % prefix_debut : date_debut}) & Q(**{'%s__lte' % prefix_debut : date_fin}))
76 q_both = Q(**{'%s__isnull' % prefix_fin : True}) | Q(**{'%s__lte' % prefix_fin : date_fin}) & (Q(**{'%s__isnull' % prefix_debut : True}) | Q(**{'%s__gte' % prefix_debut : date_debut}))
6b1d6053
OL
77 q_non_supprime = Q(**{'%s__exact' % prefix_debut.replace('date_debut', 'supprime') : False})
78 q = (q_left | q_right | q_both) & q_non_supprime
79 qs = qs.filter(q).distinct()
3195667e 80
3195667e
OL
81 self.params = old
82 return qs
83
40b35603
OL
84################################################################################
85
53ae644d
OL
86# Override of the InlineModelAdmin to support the link in the tabular inline
87class LinkedInline(admin.options.InlineModelAdmin):
88 template = "admin/linked.html"
89 admin_model_path = None
90
91 def __init__(self, *args):
92 super(LinkedInline, self).__init__(*args)
93 if self.admin_model_path is None:
94 self.admin_model_path = self.model.__name__.lower()
95
96
97class ProtectRegionMixin(object):
98
99 def queryset(self, request):
100 from dae.workflow import grp_drh, grp_correspondants_rh
101 qs = super(ProtectRegionMixin, self).queryset(request)
102
103 if request.user.is_superuser:
104 return qs
105
106 user_groups = request.user.groups.all()
107
108 if grp_drh in user_groups:
109 return qs
110
111 if grp_correspondants_rh in user_groups:
112 employe = get_employe_from_user(request.user)
113 q = Q(**{self.model.prefix_implantation: employe.implantation.region})
114 qs = qs.filter(q).distinct()
115 return qs
116 return qs.none()
117
118 def has_change_permission(self, request, obj=None):
20b4867c 119 user_groups = request.user.groups.all()
a0d365ed
OL
120
121 # Lock pour autoriser uniquement les DRH à utiliser RH
122 if not request.user.is_superuser and not grp_drh in user_groups:
123 return False
124
a18bc295 125 if len(user_groups) == 0 and not request.user.is_superuser:
20b4867c
OL
126 return False
127
53ae644d
OL
128 if obj is None:
129 return True
130 ids = [o.id for o in self.queryset(request)]
131 return obj.id in ids
132
133
134# Inlines
135
136class ReadOnlyInlineMixin(object):
137 def get_readonly_fields(self, request, obj=None):
138 return [f.name for f in self.model._meta.fields if f.name not in AUF_METADATA_READONLY_FIELDS]
139
140
141class AyantDroitInline(AUFMetadataInlineAdminMixin, admin.StackedInline):
142 model = rh.AyantDroit
143 form = AyantDroitForm
144 extra = 0
145
146 fieldsets = (
147 (None, {
148 'fields': (('nom', 'prenom'), ('nom_affichage', 'genre'), 'nationalite', 'date_naissance', 'lien_parente', )
149 }),
150 )
151
152
153class AyantDroitCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
154 readonly_fields = ('owner', )
155 model = rh.AyantDroitCommentaire
156 extra = 1
157
158
159class ContratInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
160 form = ContratForm
161 model = rh.Contrat
162 extra = 1
163
164
165class DossierROInline(ReadOnlyInlineMixin, LinkedInline):
166 template = "admin/rh/dossier/linked.html"
167 exclude = AUF_METADATA_READONLY_FIELDS
168 model = rh.Dossier
169 extra = 0
170 can_delete = False
171
172 def has_add_permission(self, request=None):
173 return False
174
175 def has_change_permission(self, request, obj=None):
176 return False
177
178 def has_delete_permission(self, request, obj=None):
179 return False
180
181
182class DossierCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
183 readonly_fields = ('owner', )
184 model = rh.DossierCommentaire
185 extra = 1
186
187
188class DossierPieceInline(admin.TabularInline):
189 model = rh.DossierPiece
190 extra = 4
191
192
193class EmployeInline(admin.TabularInline):
194 model = rh.Employe
195
196class EmployeCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
197 readonly_fields = ('owner', )
198 model = rh.EmployeCommentaire
199 extra = 1
200
201
202class EmployePieceInline(admin.TabularInline):
203 model = rh.EmployePiece
204 extra = 4
205
206
53ae644d
OL
207class PosteCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
208 readonly_fields = ('owner', )
209 model = rh.PosteCommentaire
210 extra = 1
211
212
213class PosteFinancementInline(admin.TabularInline):
214 model = rh.PosteFinancement
215
216
217class PostePieceInline(admin.TabularInline):
218 model = rh.PostePiece
219
220
221class RemunerationInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
222 model = rh.Remuneration
223 extra = 1
224
225
226class RemunerationROInline(ReadOnlyInlineMixin, RemunerationInline):
227 pass
228
229
230class TypePosteInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
231 model = rh.TypePoste
232
233
6f037929
OL
234class PosteComparaisonInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
235 model = rh.PosteComparaison
236
53ae644d
OL
237
238class ClassementAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 239 list_display = ('_classement', '_date_modification', 'user_modification', )
53ae644d
OL
240 fieldsets = AUFMetadataAdminMixin.fieldsets + (
241 (None, {
242 'fields': ('type', 'echelon', 'degre', 'coefficient', )
243 }),
244 )
245
c5964dc2
OL
246 def _classement(self, obj):
247 return unicode(obj)
248 _classement.short_description = u"Classement"
53ae644d 249
33232787
JPC
250 def _date_modification(self, obj):
251 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
252 _date_modification.short_description = u'date modification'
253 _date_modification.admin_order_field = 'date_modification'
254
53ae644d
OL
255class CommentaireAdmin(admin.ModelAdmin):
256 pass
257
258
53ae644d 259class DeviseAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 260 list_display = ('code', 'nom', '_date_modification', 'user_modification', )
53ae644d
OL
261 fieldsets = AUFMetadataAdminMixin.fieldsets + (
262 (None, {
263 'fields': ('code', 'nom', ),
264 }),
265 )
266
33232787
JPC
267 def _date_modification(self, obj):
268 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
269 _date_modification.short_description = u'date modification'
270 _date_modification.admin_order_field = 'date_modification'
53ae644d 271
40b35603 272class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
53ae644d
OL
273 alphabet_filter = 'employe__nom'
274 search_fields = ('employe__nom', 'employe__prenom', 'poste__nom', 'poste__nom_feminin')
275 list_display = (
276 '_id',
e49ac947
JPC
277 '_apercu',
278 '_nom',
53ae644d
OL
279 '_poste',
280 '_employe',
281 '_date_debut',
282 '_date_fin',
33232787 283 '_date_modification',
c5964dc2 284 'user_modification',
53ae644d 285 )
e49ac947 286 list_display_links = ('_nom',)
53ae644d
OL
287 list_filter = (
288 'poste__implantation__region',
289 'poste__implantation',
53ae644d 290 'poste__type_poste__famille_emploi',
7baa5523 291 'poste__type_poste',
53ae644d 292 'rh_contrats__type_contrat',
f614ca5c
OL
293 'date_debut',
294 'date_fin',
53ae644d
OL
295 )
296 inlines = (DossierPieceInline, ContratInline,
297 RemunerationInline,
53ae644d
OL
298 DossierCommentaireInline,
299 )
300 fieldsets = AUFMetadataAdminMixin.fieldsets + (
301 (None, {
302 'fields': ('employe', 'poste', 'statut', 'organisme_bstg',)
303 }),
304 ('Recrutement', {
305 'fields': ('statut_residence', 'remplacement', 'remplacement_de', )
306 }),
307 ('Rémunération', {
308 'fields': ('classement', ('regime_travail', 'regime_travail_nb_heure_semaine'),)
309 }),
310 ('Occupation du Poste par cet Employe', {
311 'fields': (('date_debut', 'date_fin'), )
312 }),
313 )
314 form = make_ajax_form(rh.Dossier, {
315 'employe' : 'employes',
316 'poste' : 'postes',
317 'remplacement_de' : 'dossiers',
318 })
319
320 def lookup_allowed(self, key, value):
321 if key in (
322 'employe__nom__istartswith',
53ae644d
OL
323 'poste__implantation__region__id__exact',
324 'poste__implantation__id__exact',
325 'poste__type_poste__id__exact',
326 'poste__type_poste__famille_emploi__id__exact',
327 'rh_contrats__type_contrat__id__exact',
f614ca5c
OL
328 'date_debut__gte',
329 'date_debut__isnull',
330 'date_fin__lte',
331 'date_fin__isnull',
53ae644d
OL
332 ):
333 return True
334
e49ac947
JPC
335 def _id(self, obj):
336 return obj.id
337 _id.short_description = u"#"
338 _id.admin_order_field = "id"
339
340 def _nom(self, obj):
341 return "%d : %s %s" % \
342 (obj.date_debut.year, obj.employe.nom.upper(), obj.employe.prenom)
343 _nom.allow_tags = True
344 _nom.short_description = u"Dossier"
345
346
347 def _apercu(self, d):
5429c435 348 apercu_link = u"""<a title="Aperçu du dossier" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a>""" % \
b10920ea 349 (reverse('dossier_apercu', args=(d.id,)),
822a2c33 350 settings.STATIC_URL,
b10920ea 351 )
e49ac947
JPC
352 return apercu_link
353 _apercu.allow_tags = True
354 _apercu.short_description = u""
53ae644d
OL
355
356
53ae644d 357 def _date_debut(self, obj):
5f36f262
OL
358 return date(obj.date_debut)
359
53ae644d
OL
360 _date_debut.short_description = u'Occupation début'
361 _date_debut.admin_order_field = 'date_debut'
362
363 def _date_fin(self, obj):
5f36f262 364 return date(obj.date_fin)
53ae644d
OL
365 _date_fin.short_description = u'Occupation fin'
366 _date_fin.admin_order_field = 'date_fin'
367
33232787
JPC
368
369 def _date_modification(self, obj):
370 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
371 _date_modification.short_description = u'date modification'
372 _date_modification.admin_order_field = 'date_modification'
373
53ae644d 374 def _poste(self, dossier):
211a0e56 375 link = u"""<a title="Aperçu du poste" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a> <a href="%s" title="Modifier le poste">%s</a>""" % \
53ae644d 376 (reverse('poste_apercu', args=(dossier.poste.id,)),
822a2c33 377 settings.STATIC_URL,
211a0e56
JPC
378 reverse('admin:rh_poste_change', args=(dossier.poste.id,)),
379 dossier.poste,
53ae644d
OL
380 )
381 return link
382 _poste.allow_tags = True
383 _poste.short_description = u'Poste'
384 _poste.admin_order_field = 'poste__nom'
385
386 def _employe(self, obj):
387 employe = obj.employe
388 view_link = reverse('employe_apercu', args=(employe.id,))
389 edit_link = reverse('admin:rh_employe_change', args=(employe.id,))
390
f614ca5c
OL
391 style = ""
392 view = u"""<a href="%s" title="Aperçu l'employé" onclick="return showAddAnotherPopup(this);"><img src="%simg/loupe.png" /></a>""" % (view_link, settings.STATIC_URL,)
e6c107de
JPC
393 return u"""%s<a href='%s' style="%s;">%s</a>""" % \
394 (view, edit_link, style, employe)
53ae644d 395 _employe.allow_tags = True
e49ac947 396 _employe.short_description = u"Employé"
53ae644d
OL
397 _employe.admin_order_field = "employe__nom"
398
399 def save_formset(self, request, form, formset, change):
400 instances = formset.save(commit=False)
401 for instance in instances:
402 if instance.__class__ == rh.DossierCommentaire:
403 instance.owner = request.user
02e69aa2 404 instance.date_creation = datetime.datetime.now()
53ae644d
OL
405 instance.save()
406
407
408class DossierPieceAdmin(admin.ModelAdmin):
409 pass
410
411
412class DossierCommentaireAdmin(admin.ModelAdmin):
413 pass
414
415
40b35603 416class EmployeAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin,):
53ae644d
OL
417 alphabet_filter = 'nom'
418 DEFAULT_ALPHABET = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
419 search_fields = ('id', 'nom', 'prenom', 'nom_affichage', )
420 ordering = ('nom', )
421 form = EmployeAdminForm
e49ac947
JPC
422 list_display = ('_id', '_apercu', '_nom', '_dossiers', '_date_modification', 'user_modification', )
423 list_display_links = ('_nom',)
b46d18bc 424 list_filter = ('rh_dossiers__poste__implantation__region', 'rh_dossiers__poste__implantation', 'nb_postes', 'rh_dossiers__date_debut', 'rh_dossiers__date_fin')
7f4d1233
OL
425 date_borne_gauche = 'rh_dossiers__date_debut'
426 date_borne_droite = 'rh_dossiers__date_fin'
53ae644d
OL
427 inlines = (AyantDroitInline,
428 DossierROInline,
429 EmployePieceInline,
430 EmployeCommentaireInline)
431 fieldsets = AUFMetadataAdminMixin.fieldsets + (
432 ('Identification', {
433 'fields': (('nom', 'prenom'), ('nom_affichage', 'genre'), 'nationalite', 'date_naissance', )
434 }),
435 ('Informations personnelles', {
436 'fields': ('situation_famille', 'date_entree', )
437 }),
438 ('Coordonnées', {
439 'fields': (('tel_domicile', 'tel_cellulaire'), ('adresse', 'ville'), ('code_postal', 'province'), 'pays', )
440 }),
441 )
442
b10920ea
JPC
443 def _apercu(self, obj):
444 return u"""<a title="Aperçu de l'employé" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a>""" % \
822a2c33 445 (reverse('employe_apercu', args=(obj.id,)), settings.STATIC_URL)
b10920ea
JPC
446 _apercu.allow_tags = True
447 _apercu.short_description = u""
b10920ea 448
53ae644d 449 def _nom(self, obj):
53ae644d 450 edit_link = reverse('admin:rh_employe_change', args=(obj.id,))
e6c107de 451 return u"""<a href='%s'><strong>%s</strong></a>""" % \
e49ac947 452 (edit_link, "%s %s" % (obj.nom.upper(), obj.prenom))
53ae644d 453 _nom.allow_tags = True
e49ac947 454 _nom.short_description = u"Employé"
53ae644d
OL
455 _nom.admin_order_field = "nom"
456
e49ac947
JPC
457 def _id(self, obj):
458 return obj.id
459 _id.short_description = u"#"
460 _id.admin_order_field = "id"
461
33232787
JPC
462 def _date_modification(self, obj):
463 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
464 _date_modification.short_description = u'date modification'
465 _date_modification.admin_order_field = 'date_modification'
466
53ae644d
OL
467 def _dossiers(self, obj):
468 l = []
469 for d in obj.rh_dossiers.all().order_by('-date_debut'):
b10920ea 470 apercu = u"""<a title="Aperçu du dossier" href="%s" onclick="return showAddAnotherPopup(this);" title="Aperçu du dossier"><img src="%simg/loupe.png" /></a>""" % \
822a2c33 471 (reverse('dossier_apercu', args=(d.id,)), settings.STATIC_URL,)
b5cc0357 472 link = u"""<li>%s<a href='%s'>%s : %s</a></li>""" % \
b10920ea 473 (apercu,
b10920ea 474 reverse('admin:rh_dossier_change', args=(d.id,)),
53ae644d
OL
475 d.date_debut.year,
476 d.poste,
53ae644d 477 )
b5cc0357
OL
478
479 # Dossier terminé en gris non cliquable
480 if d.date_fin is not None:
481 link = u"""<li style="color: grey">%s : %s</li>""" % \
482 (d.date_debut.year,
483 d.poste,
484 )
485
53ae644d
OL
486 l.append(link)
487 return "<ul>%s</ul>" % "\n".join(l)
488 _dossiers.allow_tags = True
489 _dossiers.short_description = u"Dossiers"
490
491 def queryset(self, request):
492 qs = super(EmployeAdmin, self).queryset(request)
493 return qs.select_related(depth=1).order_by('nom')
494
495 def save_formset(self, request, form, formset, change):
496 instances = formset.save(commit=False)
497 for instance in instances:
498 if instance.__class__ == rh.EmployeCommentaire:
499 instance.owner = request.user
02e69aa2 500 instance.date_creation = datetime.datetime.now()
53ae644d
OL
501 instance.save()
502
503
504
505class EmployeCommentaireAdmin(admin.ModelAdmin):
506 pass
507
508
509class EmployePieceAdmin(admin.ModelAdmin):
510 pass
511
512
513class FamilleEmploiAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 514 list_display = ('nom', '_date_modification', 'user_modification', )
53ae644d
OL
515 inlines = (TypePosteInline,)
516 fieldsets = AUFMetadataAdminMixin.fieldsets + (
517 (None, {
518 'fields': ('nom', )
519 }),
520 )
521
33232787
JPC
522 def _date_modification(self, obj):
523 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
524 _date_modification.short_description = u'date modification'
525 _date_modification.admin_order_field = 'date_modification'
53ae644d 526
95b630cf 527class OrganismeBstgAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
c5964dc2 528 search_fields = ('nom',)
33232787 529 list_display = ('nom', 'type', 'pays', '_date_modification', 'user_modification', )
c5964dc2 530 list_filter = ('type', )
53ae644d
OL
531 inlines = (DossierROInline,)
532 fieldsets = AUFMetadataAdminMixin.fieldsets + (
533 (None, {
534 'fields': ('nom', 'type', 'pays', )
535 }),
536 )
537
33232787
JPC
538 def _date_modification(self, obj):
539 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
540 _date_modification.short_description = u'date modification'
541 _date_modification.admin_order_field = 'date_modification'
542
53ae644d 543
40b35603 544class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
53ae644d
OL
545 form = make_ajax_form(rh.Poste, {
546 'implantation' : 'implantations',
547 'type_poste' : 'typepostes',
548 'responsable' : 'postes',
549 'valeur_point_min' : 'valeurpoints',
550 'valeur_point_max' : 'valeurpoints',
551 })
552 alphabet_filter = 'nom'
553 search_fields = ('nom',
554 'implantation__code',
555 'implantation__nom',
556 'implantation__region__code',
557 'implantation__region__nom',
1ce71322
JPC
558 'rh_dossiers__employe__nom',
559 'rh_dossiers__employe__prenom',
53ae644d
OL
560 )
561 list_display = (
e49ac947 562 '_id',
8f3ca727 563 '_apercu',
53ae644d
OL
564 '_nom',
565 '_occupe_par',
566 'implantation',
c5964dc2 567 '_service',
53ae644d
OL
568 'date_debut',
569 'date_fin',
33232787 570 '_date_modification',
53ae644d 571 'user_modification',
53ae644d 572 )
f614ca5c 573 list_filter = (
53ae644d
OL
574 'implantation__region',
575 'implantation',
e8dd3d54 576 'service',
53ae644d
OL
577 'type_poste',
578 'type_poste__famille_emploi',
f614ca5c
OL
579 'date_debut',
580 'date_fin',
4c53dda4 581 'vacant',
53ae644d 582 )
e49ac947 583 list_display_links = ('_nom',)
53ae644d
OL
584 fieldsets = AUFMetadataAdminMixin.fieldsets + (
585 (None, {
586 'fields': (('nom', 'nom_feminin'), 'implantation', 'type_poste',
587 'service', 'responsable')
588 }),
589 ('Contrat', {
590 'fields': (('regime_travail', 'regime_travail_nb_heure_semaine'), )
591 }),
592 ('Recrutement', {
593 'fields': (('local', 'expatrie', 'mise_a_disposition', 'appel'),)
594 }),
595 ('Rémunération', {
596 'fields': (('classement_min', 'valeur_point_min', 'devise_min', 'salaire_min', 'indemn_min', 'autre_min', ),
597 ('classement_max', 'valeur_point_max' ,'devise_max', 'salaire_max', 'indemn_max', 'autre_max', ),
598 )
599 }),
600 ('Comparatifs de rémunération', {
601 'fields': ('devise_comparaison',
602 ('comp_locale_min', 'comp_locale_max'),
603 ('comp_universite_min', 'comp_universite_max'),
604 ('comp_fonctionpub_min', 'comp_fonctionpub_max'),
605 ('comp_ong_min', 'comp_ong_max'),
606 ('comp_autre_min', 'comp_autre_max'))
607 }),
608 ('Justification', {
609 'fields': ('justification',)
610 }),
48a6df80 611 ('Autres Méta-données', {
53ae644d
OL
612 'fields': ('date_debut', 'date_fin')
613 }),
614 )
615
616 inlines = (PosteFinancementInline,
617 PostePieceInline,
618 DossierROInline,
6f037929 619 PosteComparaisonInline,
53ae644d
OL
620 PosteCommentaireInline, )
621
b46d18bc 622
f614ca5c
OL
623 def lookup_allowed(self, key, value):
624 if key in (
625 'date_debut__gte',
626 'date_debut__isnull',
627 'date_fin__lte',
628 'date_fin__isnull',
7f4d1233
OL
629 'implantation__region__id__exact',
630 'implantation__id__exact',
631 'type_poste__id__exact',
632 'type_poste__famille_emploi__id__exact',
633 'service__id__exact',
634 'vacant__exact',
f614ca5c
OL
635 ):
636 return True
637
c5964dc2 638
8f3ca727 639 def _apercu(self, poste):
23de8cea 640 view_link = u"""<a onclick="return showAddAnotherPopup(this);" title="Aperçu du poste" href='%s'><img src="%simg/loupe.png" /></a>""" % \
8f3ca727 641 (reverse('poste_apercu', args=(poste.id,)),
822a2c33 642 settings.STATIC_URL,
23de8cea 643 )
e49ac947 644 return view_link
8f3ca727 645 _apercu.allow_tags = True
e49ac947
JPC
646 _apercu.short_description = ''
647
648 def _id(self, obj):
649 return "%s" % obj.id
650 _id.short_description = '#'
651 _id.admin_order_field = 'id'
8f3ca727 652
c5964dc2
OL
653 def _service(self, obj):
654 return obj.service
53ae644d
OL
655
656 def _nom(self, poste):
e49ac947
JPC
657 return """<a href="%s">%s</a>""" % \
658 (reverse('admin:rh_poste_change', args=(poste.id,)),
659 poste.nom
660 )
53ae644d
OL
661 _nom.allow_tags = True
662 _nom.short_description = u'Nom'
663 _nom.admin_order_field = 'nom'
664
33232787
JPC
665 def _date_modification(self, obj):
666 return date(obj.date_modification)
667 _date_modification.short_description = u'date modification'
668 _date_modification.admin_order_field = 'date_modification'
669
53ae644d
OL
670 def _occupe_par(self, obj):
671 """Formatte la méthode Poste.occupe_par() pour l'admin"""
15c5f55a 672 output = u"Vacant"
3195667e 673 if obj.date_fin is not None and obj.date_fin < datetime.date.now():
954ead19 674 return u"s/o"
53ae644d
OL
675 employes = obj.occupe_par()
676 if employes:
677 l = []
678 for e in employes:
b10920ea
JPC
679 link = "<a href='%s' title='Aperçu de l\'employer' onclick='return showAddAnotherPopup(this)'><img src='%simg/loupe.png' /></a> <a href='%s'>%s</a>" % \
680 (reverse('employe_apercu', args=(e.id,)),
822a2c33 681 settings.STATIC_URL,
b10920ea
JPC
682 reverse('admin:rh_employe_change', args=(e.id,)),
683 e
684 )
53ae644d
OL
685 l.append(link)
686 output = "\n<br />".join(l)
687 return output
688 _occupe_par.allow_tags = True
689 _occupe_par.short_description = "Occupé par"
690
691 def save_formset(self, request, form, formset, change):
692 instances = formset.save(commit=False)
693 for instance in instances:
694 if instance.__class__ == rh.PosteCommentaire:
695 instance.owner = request.user
02e69aa2 696 instance.date_creation = datetime.datetime.now()
53ae644d
OL
697 instance.save()
698 formset.save_m2m()
699
700
701class PosteCommentaireAdmin(admin.ModelAdmin):
702 pass
703
704
705class PosteFinancementAdmin(admin.ModelAdmin):
706 pass
707
708
709class PostePieceAdmin(admin.ModelAdmin):
710 fk_name = 'poste'
711
712
713class RemunerationAdmin(admin.ModelAdmin):
714 pass
715
716
717class ResponsableImplantationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
718 fieldsets = AUFMetadataAdminMixin.fieldsets + (
719 (None, {
720 'fields': ('employe', 'implantation', ),
721 }),
722 )
723
724
725class ServiceAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 726 list_display = ('nom', '_date_modification', 'user_modification', )
53ae644d
OL
727 fieldsets = AUFMetadataAdminMixin.fieldsets + (
728 (None, {
729 'fields': ('nom', ),
730 }),
731 )
732
33232787
JPC
733 def _date_modification(self, obj):
734 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
735 _date_modification.short_description = u'date modification'
736 _date_modification.admin_order_field = 'date_modification'
737
738
53ae644d 739class StatutAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 740 list_display = ('code', 'nom', '_date_modification', 'user_modification', )
53ae644d
OL
741 fieldsets = AUFMetadataAdminMixin.fieldsets + (
742 (None, {
743 'fields': ('code', 'nom', ),
744 }),
745 )
746
33232787
JPC
747 def _date_modification(self, obj):
748 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
749 _date_modification.short_description = u'date modification'
750 _date_modification.admin_order_field = 'date_modification'
751
53ae644d 752class TauxChangeAdmin(admin.ModelAdmin):
33232787 753 list_display = ('taux', 'devise', 'annee', '_date_modification', 'user_modification', )
53ae644d
OL
754 list_filter = ('devise', )
755 fieldsets = AUFMetadataAdminMixin.fieldsets + (
756 (None, {
757 'fields': ('taux', 'devise', 'annee', ),
758 }),
759 )
760
33232787
JPC
761 def _date_modification(self, obj):
762 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
763 _date_modification.short_description = u'date modification'
764 _date_modification.admin_order_field = 'date_modification'
765
53ae644d 766class TypeContratAdmin(admin.ModelAdmin):
33232787 767 list_display = ('nom', 'nom_long', '_date_modification', 'user_modification', )
53ae644d
OL
768 fieldsets = AUFMetadataAdminMixin.fieldsets + (
769 (None, {
770 'fields': ('nom', 'nom_long', ),
771 }),
772 )
773
33232787
JPC
774 def _date_modification(self, obj):
775 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
776 _date_modification.short_description = u'date modification'
777 _date_modification.admin_order_field = 'date_modification'
778
53ae644d
OL
779
780class TypePosteAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
781 search_fields = ('nom', 'nom_feminin', )
33232787 782 list_display = ('nom', 'famille_emploi', '_date_modification', 'user_modification', )
53ae644d
OL
783 list_filter = ('famille_emploi', )
784 fieldsets = AUFMetadataAdminMixin.fieldsets + (
785 (None, {
786 'fields': ('nom', 'nom_feminin', 'is_responsable', 'famille_emploi', )
787 }),
788 )
789
33232787
JPC
790 def _date_modification(self, obj):
791 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
792 _date_modification.short_description = u'date modification'
793 _date_modification.admin_order_field = 'date_modification'
794
53ae644d
OL
795
796class TypeRemunerationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 797 list_display = ('nom', 'type_paiement', 'nature_remuneration', '_date_modification', 'user_modification', )
53ae644d
OL
798 fieldsets = AUFMetadataAdminMixin.fieldsets + (
799 (None, {
800 'fields': ('nom', 'type_paiement', 'nature_remuneration', )
801 }),
802 )
803
33232787
JPC
804 def _date_modification(self, obj):
805 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
806 _date_modification.short_description = u'date modification'
807 _date_modification.admin_order_field = 'date_modification'
808
53ae644d
OL
809
810class TypeRevalorisationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 811 list_display = ('nom', '_date_modification', 'user_modification', )
53ae644d
OL
812 fieldsets = AUFMetadataAdminMixin.fieldsets + (
813 (None, {
814 'fields': ('nom', )
815 }),
816 )
817
33232787
JPC
818 def _date_modification(self, obj):
819 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
820 _date_modification.short_description = u'date modification'
821 _date_modification.admin_order_field = 'date_modification'
822
53ae644d
OL
823
824class ValeurPointAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 825 list_display = ('_devise_code', '_devise_nom', 'annee', 'valeur', '_date_modification', 'user_modification', )
c5964dc2 826 list_filter = ('annee', 'devise', )
53ae644d
OL
827 fieldsets = AUFMetadataAdminMixin.fieldsets + (
828 (None, {
829 'fields': ('valeur', 'devise', 'implantation', 'annee', )
830 }),
831 )
832
33232787
JPC
833 def _date_modification(self, obj):
834 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
835 _date_modification.short_description = u'date modification'
836 _date_modification.admin_order_field = 'date_modification'
837
53ae644d
OL
838 def _devise_code(self, obj):
839 return obj.devise.code
840 _devise_code.short_description = "Code de la devise"
841
842 def _devise_nom(self, obj):
843 return obj.devise.nom
844 _devise_nom.short_description = "Nom de la devise"
845
846
847admin.site.register(rh.Classement, ClassementAdmin)
848admin.site.register(rh.Devise, DeviseAdmin)
849admin.site.register(rh.Dossier, DossierAdmin)
850admin.site.register(rh.Employe, EmployeAdmin)
851admin.site.register(rh.FamilleEmploi, FamilleEmploiAdmin)
852admin.site.register(rh.OrganismeBstg, OrganismeBstgAdmin)
853admin.site.register(rh.Poste, PosteAdmin)
854admin.site.register(rh.ResponsableImplantation, ResponsableImplantationAdmin)
855admin.site.register(rh.Service, ServiceAdmin)
c5964dc2 856admin.site.register(rh.Statut, StatutAdmin)
53ae644d 857admin.site.register(rh.TauxChange, TauxChangeAdmin)
c5964dc2 858admin.site.register(rh.TypeContrat, TypeContratAdmin)
53ae644d
OL
859admin.site.register(rh.TypePoste, TypePosteAdmin)
860admin.site.register(rh.TypeRemuneration, TypeRemunerationAdmin)
861admin.site.register(rh.TypeRevalorisation, TypeRevalorisationAdmin)
862admin.site.register(rh.ValeurPoint, ValeurPointAdmin)