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