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