b6098716bc0a3c6ea5e1e41e1eaddb6a587a1576
[auf_rh_dae.git] / project / rh / admin.py
1 # -*- encoding: utf-8 -*-
2
3 import datetime
4
5 from django.core.urlresolvers import reverse
6 from django.contrib import admin
7 from django.conf import settings
8 from django.db.models import Q
9 from django.template.defaultfilters import date
10 from ajax_select import make_ajax_form
11 from auf.django.metadata.admin import AUFMetadataAdminMixin, \
12 AUFMetadataInlineAdminMixin, \
13 AUF_METADATA_READONLY_FIELDS
14 from forms import ContratForm, AyantDroitForm, EmployeAdminForm, AjaxSelect
15 from dae.utils import get_employe_from_user
16 from change_list import ChangeList
17 from groups import grp_correspondants_rh
18 from decorators import in_drh_or_admin
19 import models as rh
20 import auf.django.references.models as ref
21
22 class RegionProxy(ref.Region):
23 """ Proxy utilisé pour les organigrammes par région """
24 class Meta:
25 proxy = True
26 verbose_name = u"Organigramme par région"
27 verbose_name_plural = u"Organigramme par région"
28
29
30 class ImplantationProxy(ref.Implantation):
31 """ Proxy utilisé pour les organigrammes par implantation """
32 class Meta:
33 proxy = True
34 verbose_name = u"Organigramme par implantations"
35 verbose_name_plural = u"Organigramme par implantations"
36
37
38 class ServiceProxy(rh.Service):
39 """ Proxy utilisé pour les organigrammes opar service """
40 class Meta:
41 proxy = True
42 verbose_name = u"Organigramme par services"
43 verbose_name_plural = u"Organigramme par services"
44
45
46 class EmployeProxy(rh.Employe):
47 """ Proxy utilisé pour les organigrammes des employés """
48 class Meta:
49 proxy = True
50 verbose_name = u"Organigramme des employés"
51 verbose_name_plural = u"Organigramme des employés"
52
53
54 class DateRangeMixin(object):
55 prefixe_recherche_temporelle = ""
56
57 def get_changelist(self, request, **kwargs):
58 if 'HTTP_REFERER' in request.META.keys():
59 referer = request.META['HTTP_REFERER']
60 referer = "/".join(referer.split('/')[3:])
61 referer = "/%s" % referer.split('?')[0]
62 change_list_view = 'admin:%s_%s_changelist' % (
63 self.model._meta.app_label,
64 self.model.__name__.lower(),)
65 if referer != reverse(change_list_view):
66 params = request.GET.copy()
67 params.update({'statut': 'Actif'})
68 request.GET = params
69 return ChangeList
70
71
72 # Override of the InlineModelAdmin to support the link in the tabular inline
73 class LinkedInline(admin.options.InlineModelAdmin):
74 template = "admin/linked.html"
75 admin_model_path = None
76
77 def __init__(self, *args):
78 super(LinkedInline, self).__init__(*args)
79 if self.admin_model_path is None:
80 self.admin_model_path = self.model.__name__.lower()
81
82
83 class ProtectRegionMixin(object):
84
85 def queryset(self, request):
86 qs = super(ProtectRegionMixin, self).queryset(request)
87
88 user_groups = request.user.groups.all()
89 if in_drh_or_admin(request.user):
90 return qs
91
92 if grp_correspondants_rh in user_groups:
93 employe = get_employe_from_user(request.user)
94 q = Q(**{self.model.prefix_implantation: \
95 employe.implantation.region})
96 qs = qs.filter(q).distinct()
97 return qs
98 return qs.none()
99
100 def has_change_permission(self, request, obj=None):
101 user_groups = request.user.groups.all()
102
103 # Lock pour autoriser uniquement les DRH à utiliser RH
104 if not in_drh_or_admin(request.user):
105 return False
106
107 if len(user_groups) == 0 and not request.user.is_superuser:
108 return False
109
110 if obj is None:
111 return True
112 ids = [o.id for o in self.queryset(request)]
113 return obj.id in ids
114
115
116 # Inlines
117
118 class ReadOnlyInlineMixin(object):
119
120 def get_readonly_fields(self, request, obj=None):
121 return [f.name for f in self.model._meta.fields \
122 if f.name not in AUF_METADATA_READONLY_FIELDS]
123
124
125 class AyantDroitInline(AUFMetadataInlineAdminMixin, admin.StackedInline):
126 model = rh.AyantDroit
127 form = AyantDroitForm
128 extra = 0
129
130 fieldsets = (
131 (None, {
132 'fields': (
133 ('nom', 'prenom'),
134 ('nom_affichage', 'genre'),
135 'nationalite',
136 'date_naissance',
137 'lien_parente',
138 )}),
139 )
140
141
142 class AyantDroitCommentaireInline(AUFMetadataInlineAdminMixin, \
143 admin.TabularInline):
144 readonly_fields = ('owner', )
145 model = rh.AyantDroitCommentaire
146 extra = 1
147
148
149 class ContratInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
150 form = ContratForm
151 model = rh.Contrat
152 extra = 1
153
154
155 class DossierROInline(ReadOnlyInlineMixin, LinkedInline):
156 template = "admin/rh/dossier/linked.html"
157 exclude = AUF_METADATA_READONLY_FIELDS
158 model = rh.Dossier
159 extra = 0
160 can_delete = False
161
162 def has_add_permission(self, request=None):
163 return False
164
165 def has_change_permission(self, request, obj=None):
166 return False
167
168 def has_delete_permission(self, request, obj=None):
169 return False
170
171
172 class DossierCommentaireInline(AUFMetadataInlineAdminMixin, \
173 admin.TabularInline):
174 readonly_fields = ('owner', )
175 model = rh.DossierCommentaire
176 extra = 1
177
178
179 class DossierPieceInline(admin.TabularInline):
180 model = rh.DossierPiece
181 extra = 4
182
183
184 class EmployeInline(admin.TabularInline):
185 model = rh.Employe
186
187
188 class EmployeCommentaireInline(AUFMetadataInlineAdminMixin, \
189 admin.TabularInline):
190 readonly_fields = ('owner', )
191 model = rh.EmployeCommentaire
192 extra = 1
193
194
195 class EmployePieceInline(admin.TabularInline):
196 model = rh.EmployePiece
197 extra = 4
198
199
200 class PosteCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
201 readonly_fields = ('owner', )
202 model = rh.PosteCommentaire
203 extra = 1
204
205
206 class PosteFinancementInline(admin.TabularInline):
207 model = rh.PosteFinancement
208
209
210 class PostePieceInline(admin.TabularInline):
211 model = rh.PostePiece
212
213
214 class RemunerationInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
215 model = rh.Remuneration
216 extra = 1
217
218
219 class RemunerationROInline(ReadOnlyInlineMixin, RemunerationInline):
220 pass
221
222
223 class TypePosteInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
224 model = rh.TypePoste
225
226
227 class PosteComparaisonInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
228 model = rh.PosteComparaison
229
230
231 class ClassementAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
232 list_display = ('_classement', '_date_modification', 'user_modification', )
233 fieldsets = AUFMetadataAdminMixin.fieldsets + (
234 (None, {
235 'fields': ('type', 'echelon', 'degre', 'coefficient',)}),
236 )
237
238 def _classement(self, obj):
239 return unicode(obj)
240 _classement.short_description = u"Classement"
241
242 def _date_modification(self, obj):
243 return date(obj.date_modification) \
244 if obj.date_modification is not None else "(aucune)"
245 _date_modification.short_description = u'date modification'
246 _date_modification.admin_order_field = 'date_modification'
247
248
249 class CommentaireAdmin(admin.ModelAdmin):
250 pass
251
252
253 class DeviseAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
254 list_display = (
255 'code',
256 'nom',
257 '_archive',
258 '_date_modification',
259 'user_modification',
260 )
261 list_filter = ('archive', )
262 fieldsets = AUFMetadataAdminMixin.fieldsets + (
263 (None, {
264 'fields': ('code', 'nom', 'archive', ),
265 }),
266 )
267
268 def queryset(self, request):
269 return self.model._base_manager
270
271 def _archive(self, obj):
272 if obj.archive:
273 return "oui"
274 else:
275 return "non"
276 _archive.short_description = u'Archivé'
277
278 def _date_modification(self, obj):
279 return date(obj.date_modification) \
280 if obj.date_modification is not None else "(aucune)"
281 _date_modification.short_description = u'date modification'
282 _date_modification.admin_order_field = 'date_modification'
283
284
285 class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin, \
286 ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
287 alphabet_filter = 'employe__nom'
288 search_fields = (
289 'employe__nom',
290 'employe__prenom',
291 'poste__nom',
292 'poste__nom_feminin')
293 list_display = (
294 '_id',
295 '_apercu',
296 '_nom',
297 '_poste',
298 '_employe',
299 '_date_debut',
300 '_date_fin',
301 '_date_modification',
302 'user_modification',
303 )
304 list_display_links = ('_nom',)
305 list_filter = (
306 'poste__implantation__region',
307 'poste__implantation',
308 'poste__type_poste__famille_emploi',
309 'poste__type_poste',
310 'rh_contrats__type_contrat',
311 )
312 inlines = (DossierPieceInline, ContratInline,
313 RemunerationInline,
314 DossierCommentaireInline,
315 )
316 fieldsets = AUFMetadataAdminMixin.fieldsets + (
317 (None, {
318 'fields': (
319 'employe',
320 'poste',
321 'statut',
322 'organisme_bstg',)}),
323 ('Recrutement', {
324 'fields': (
325 'statut_residence',
326 'remplacement',
327 'remplacement_de', )}),
328 ('Rémunération', {
329 'fields': (
330 'classement',
331 ('regime_travail', 'regime_travail_nb_heure_semaine'),)}),
332 ('Occupation du Poste par cet Employe', {
333 'fields': (('date_debut', 'date_fin'), )}
334 ),
335 )
336 form = make_ajax_form(rh.Dossier, {
337 'employe': 'employes',
338 'poste': 'postes',
339 'remplacement_de': 'dossiers',
340 })
341
342 def lookup_allowed(self, key, value):
343 if key in (
344 'employe__nom__istartswith',
345 'poste__implantation__region__id__exact',
346 'poste__implantation__id__exact',
347 'poste__type_poste__id__exact',
348 'poste__type_poste__famille_emploi__id__exact',
349 'rh_contrats__type_contrat__id__exact',
350 ):
351 return True
352
353 def _id(self, obj):
354 return obj.id
355 _id.short_description = u"#"
356 _id.admin_order_field = "id"
357
358 def _nom(self, obj):
359 return "%d : %s %s" % (
360 obj.date_debut.year,
361 obj.employe.nom.upper(),
362 obj.employe.prenom)
363 _nom.allow_tags = True
364 _nom.short_description = u"Dossier"
365
366 def _apercu(self, d):
367 apercu_link = u"""<a title="Aperçu du dossier"
368 onclick="return showAddAnotherPopup(this);"
369 href='%s'>
370 <img src="%simg/loupe.png" />
371 </a>""" % \
372 (reverse('dossier_apercu', args=(d.id,)),
373 settings.STATIC_URL,
374 )
375 return apercu_link
376 _apercu.allow_tags = True
377 _apercu.short_description = u""
378
379 def _date_debut(self, obj):
380 return date(obj.date_debut)
381
382 _date_debut.short_description = u'Occupation début'
383 _date_debut.admin_order_field = 'date_debut'
384
385 def _date_fin(self, obj):
386 return date(obj.date_fin)
387 _date_fin.short_description = u'Occupation fin'
388 _date_fin.admin_order_field = 'date_fin'
389
390 def _date_modification(self, obj):
391 return date(obj.date_modification) \
392 if obj.date_modification is not None else "(aucune)"
393 _date_modification.short_description = u'date modification'
394 _date_modification.admin_order_field = 'date_modification'
395
396 def _poste(self, dossier):
397 link = u"""<a title="Aperçu du poste"
398 onclick="return showAddAnotherPopup(this);"
399 href='%s'><img src="%simg/loupe.png" />
400 </a>
401 <a href="%s" title="Modifier le poste">%s</a>""" % \
402 (reverse('poste_apercu', args=(dossier.poste.id,)),
403 settings.STATIC_URL,
404 reverse('admin:rh_poste_change', args=(dossier.poste.id,)),
405 dossier.poste,
406 )
407 return link
408 _poste.allow_tags = True
409 _poste.short_description = u'Poste'
410 _poste.admin_order_field = 'poste__nom'
411
412 def _employe(self, obj):
413 employe = obj.employe
414 view_link = reverse('employe_apercu', args=(employe.id,))
415 edit_link = reverse('admin:rh_employe_change', args=(employe.id,))
416
417 style = ""
418 view = u"""<a href="%s"
419 title="Aperçu l'employé"
420 onclick="return showAddAnotherPopup(this);">
421 <img src="%simg/loupe.png" />
422 </a>""" % (view_link, settings.STATIC_URL,)
423 return u"""%s<a href='%s' style="%s;">%s</a>""" % \
424 (view, edit_link, style, employe)
425 _employe.allow_tags = True
426 _employe.short_description = u"Employé"
427 _employe.admin_order_field = "employe__nom"
428
429 def save_formset(self, request, form, formset, change):
430 instances = formset.save(commit=False)
431 for instance in instances:
432 if instance.__class__ == rh.DossierCommentaire:
433 instance.owner = request.user
434 instance.date_creation = datetime.datetime.now()
435 instance.save()
436
437
438 class DossierPieceAdmin(admin.ModelAdmin):
439 pass
440
441
442 class DossierCommentaireAdmin(admin.ModelAdmin):
443 pass
444
445
446 class EmployeAdmin(DateRangeMixin, AUFMetadataAdminMixin, \
447 ProtectRegionMixin, admin.ModelAdmin,):
448 prefixe_recherche_temporelle = "rh_dossiers__"
449 alphabet_filter = 'nom'
450 DEFAULT_ALPHABET = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
451 search_fields = ('id', 'nom', 'prenom', 'nom_affichage', )
452 ordering = ('nom', )
453 form = EmployeAdminForm
454 list_display = (
455 '_id',
456 '_apercu',
457 '_nom',
458 '_dossiers_postes',
459 '_date_modification',
460 'user_modification',
461 )
462 list_display_links = ('_nom',)
463 list_filter = (
464 'rh_dossiers__poste__implantation__region',
465 'rh_dossiers__poste__implantation',
466 'nb_postes',
467 )
468 inlines = (AyantDroitInline,
469 DossierROInline,
470 EmployePieceInline,
471 EmployeCommentaireInline)
472 fieldsets = AUFMetadataAdminMixin.fieldsets + (
473 ('Identification', {
474 'fields': (
475 ('nom', 'prenom'),
476 ('nom_affichage', 'genre'),
477 'nationalite',
478 'date_naissance',
479 )}
480 ),
481 ('Informations personnelles', {
482 'fields': ('situation_famille', 'date_entree', )}
483 ),
484 ('Coordonnées', {
485 'fields': (
486 ('tel_domicile', 'tel_cellulaire'),
487 ('adresse', 'ville'),
488 ('code_postal', 'province'),
489 'pays',
490 )}
491 ),
492 )
493
494 def _apercu(self, obj):
495 return u"""<a title="Aperçu de l'employé"
496 onclick="return showAddAnotherPopup(this);"
497 href='%s'>
498 <img src="%simg/loupe.png" />
499 </a>""" % \
500 (reverse('employe_apercu', args=(obj.id,)), settings.STATIC_URL)
501 _apercu.allow_tags = True
502 _apercu.short_description = u""
503
504 def _nom(self, obj):
505 edit_link = reverse('admin:rh_employe_change', args=(obj.id,))
506 return u"""<a href='%s'><strong>%s</strong></a>""" % \
507 (edit_link, "%s %s" % (obj.nom.upper(), obj.prenom))
508 _nom.allow_tags = True
509 _nom.short_description = u"Employé"
510 _nom.admin_order_field = "nom"
511
512 def _id(self, obj):
513 return obj.id
514 _id.short_description = u"#"
515 _id.admin_order_field = "id"
516
517 def _date_modification(self, obj):
518 return date(obj.date_modification) \
519 if obj.date_modification is not None else "(aucune)"
520 _date_modification.short_description = u'date modification'
521 _date_modification.admin_order_field = 'date_modification'
522
523 def _dossiers_postes(self, obj):
524 l = []
525 for d in obj.rh_dossiers.all().order_by('-date_debut'):
526 dossier = u"""<a title="Aperçu du dossier"
527 href="%s"
528 onclick="return showAddAnotherPopup(this);"
529 title="Aperçu du dossier">
530 <img src="%simg/loupe.png" />
531 </a>
532 <a href="%s">Dossier</a>
533 &nbsp;""" % \
534 (reverse('dossier_apercu', args=(d.id,)),
535 settings.STATIC_URL,
536 reverse('admin:rh_dossier_change', args=(d.id,)))
537
538 poste = u"""<a title="Aperçu du poste"
539 href="%s"
540 onclick="return showAddAnotherPopup(this);"
541 title="Aperçu du poste">
542 <img src="%simg/loupe.png" />
543 </a>
544 <a href="%s">Poste</a>
545 &nbsp;""" % \
546 (reverse('poste_apercu', args=(d.poste.id,)),
547 settings.STATIC_URL,
548 reverse('admin:rh_poste_change', args=(d.poste.id,)))
549 link = u"""<li>%s %s - %s : [%s] %s</li>""" % \
550 (dossier, poste,
551 d.date_debut.year,
552 d.poste.id,
553 d.poste.nom,
554 )
555
556 # Dossier terminé en gris non cliquable
557 if d.date_fin is not None and d.date_fin < datetime.date.today():
558 link = u"""<li style="color: grey">%s : [%s] %s</li>""" % \
559 (d.date_debut.year,
560 d.poste.id,
561 d.poste.nom,
562 )
563
564 l.append(link)
565 return "<ul>%s</ul>" % "\n".join(l)
566 _dossiers_postes.allow_tags = True
567 _dossiers_postes.short_description = u"Dossiers et postes"
568
569 def queryset(self, request):
570 qs = super(EmployeAdmin, self).queryset(request)
571 return qs.select_related(depth=1).order_by('nom')
572
573 def save_formset(self, request, form, formset, change):
574 instances = formset.save(commit=False)
575 for instance in instances:
576 if instance.__class__ == rh.EmployeCommentaire:
577 instance.owner = request.user
578 instance.date_creation = datetime.datetime.now()
579 instance.save()
580
581
582 class EmployeProxyAdmin(EmployeAdmin):
583 list_display = ('_id', '_apercu', '_nom', '_organigramme')
584 list_display_links = ('_nom',)
585
586 def has_add_permission(self, obj):
587 return False
588
589 def _organigramme(self, obj):
590 l = []
591 for d in rh.Dossier.objects.filter((Q(date_fin__gt=datetime.date.today()) | Q(date_fin=None)) & (Q(date_debut__lt=datetime.date.today()) | Q(date_debut=None)) ).filter(employe=obj.id).all():
592 organigramme = u"""Organigramme, niveau: <input type="text" id="level_%s" style="width:30px;height:15px;" /> <input type="button" value="Générer" onclick="window.location='%s'+document.getElementById('level_%s').value" />""" % \
593 (d.poste.id, reverse('rho_employe_sans_niveau', args=(d.poste.id,)), d.poste.id)
594 link = u"""<li>%s - [%s] %s : %s</li>""" % \
595 (d.date_debut.year,
596 d.poste.id,
597 d.poste.nom,
598 organigramme
599 )
600 l.append(link)
601 return "<ul>%s</ul>" % "\n".join(l)
602
603 _organigramme.allow_tags = True
604 _organigramme.short_description = "Organigramme"
605
606
607 class EmployeCommentaireAdmin(admin.ModelAdmin):
608 pass
609
610
611 class EmployePieceAdmin(admin.ModelAdmin):
612 pass
613
614
615 class FamilleEmploiAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
616 list_display = ('nom', '_date_modification', 'user_modification', )
617 inlines = (TypePosteInline,)
618 fieldsets = AUFMetadataAdminMixin.fieldsets + (
619 (None, {'fields': ('nom', )}),)
620
621 def _date_modification(self, obj):
622 return date(obj.date_modification) \
623 if obj.date_modification is not None else "(aucune)"
624 _date_modification.short_description = u'date modification'
625 _date_modification.admin_order_field = 'date_modification'
626
627
628 class OrganismeBstgAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
629 search_fields = ('nom',)
630 list_display = (
631 'nom',
632 'type',
633 'pays',
634 '_date_modification',
635 'user_modification',
636 )
637 list_filter = ('type', )
638 inlines = (DossierROInline,)
639 fieldsets = AUFMetadataAdminMixin.fieldsets + (
640 (None, {'fields': ('nom', 'type', 'pays',)}),
641 )
642
643 def _date_modification(self, obj):
644 return date(obj.date_modification) \
645 if obj.date_modification is not None else "(aucune)"
646 _date_modification.short_description = u'date modification'
647 _date_modification.admin_order_field = 'date_modification'
648
649
650 class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, \
651 ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
652 form = make_ajax_form(rh.Poste, {
653 'implantation': 'implantations',
654 'type_poste': 'typepostes',
655 'responsable': 'postes',
656 'valeur_point_min': 'valeurpoints',
657 'valeur_point_max': 'valeurpoints',
658 })
659 alphabet_filter = 'nom'
660 search_fields = (
661 'id',
662 'nom',
663 'implantation__nom',
664 'implantation__region__code',
665 'implantation__region__nom',
666 'rh_dossiers__employe__nom',
667 'rh_dossiers__employe__prenom',
668 )
669 list_display = (
670 '_id',
671 '_apercu',
672 '_nom',
673 '_occupe_par',
674 'implantation',
675 '_service',
676 '_responsable',
677 'date_debut',
678 'date_fin',
679 '_date_modification',
680 'user_modification',
681 )
682 list_filter = (
683 'implantation__region',
684 'implantation',
685 'service',
686 'type_poste',
687 'type_poste__famille_emploi',
688 'vacant',
689 )
690 list_display_links = ('_nom',)
691 fieldsets = AUFMetadataAdminMixin.fieldsets + (
692 (None, {'fields': (
693 ('nom', 'nom_feminin'),
694 'implantation',
695 'type_poste',
696 'service',
697 'responsable',
698 )}
699 ),
700 ('Contrat', {
701 'fields': ((
702 'regime_travail',
703 'regime_travail_nb_heure_semaine'),
704 )}
705 ),
706 ('Recrutement', {
707 'fields': (('local', 'expatrie', 'mise_a_disposition', 'appel'),)}
708 ),
709 ('Rémunération', {
710 'fields': (('classement_min',
711 'valeur_point_min',
712 'devise_min',
713 'salaire_min',
714 'indemn_min',
715 'autre_min',),
716 ('classement_max',
717 'valeur_point_max',
718 'devise_max',
719 'salaire_max',
720 'indemn_max',
721 'autre_max',),
722 )}),
723 ('Comparatifs de rémunération', {
724 'fields': ('devise_comparaison',
725 ('comp_locale_min', 'comp_locale_max'),
726 ('comp_universite_min', 'comp_universite_max'),
727 ('comp_fonctionpub_min', 'comp_fonctionpub_max'),
728 ('comp_ong_min', 'comp_ong_max'),
729 ('comp_autre_min', 'comp_autre_max'))}
730 ),
731 ('Justification', {
732 'fields': ('justification',)}
733 ),
734 ('Autres Méta-données', {
735 'fields': ('date_debut', 'date_fin')}
736 ),
737 )
738
739 inlines = (PosteFinancementInline,
740 PostePieceInline,
741 DossierROInline,
742 PosteComparaisonInline,
743 PosteCommentaireInline, )
744
745 def lookup_allowed(self, key, value):
746 if key in (
747 'date_debut__gte',
748 'date_debut__isnull',
749 'date_fin__lte',
750 'date_fin__isnull',
751 'implantation__region__id__exact',
752 'implantation__id__exact',
753 'type_poste__id__exact',
754 'type_poste__famille_emploi__id__exact',
755 'service__id__exact',
756 'service__isnull',
757 'vacant__exact',
758 'vacant__isnull',
759 ):
760 return True
761
762 def _apercu(self, poste):
763 view_link = u"""<a onclick="return showAddAnotherPopup(this);"
764 title="Aperçu du poste"
765 href='%s'>
766 <img src="%simg/loupe.png" />
767 </a>""" % \
768 (reverse('poste_apercu', args=(poste.id,)),
769 settings.STATIC_URL,)
770 return view_link
771 _apercu.allow_tags = True
772 _apercu.short_description = ''
773
774 def _id(self, obj):
775 return "%s" % obj.id
776 _id.short_description = '#'
777 _id.admin_order_field = 'id'
778
779 def _service(self, obj):
780 if obj.service.supprime:
781 return """<span style="color:red">%s</span>""" % obj.service
782 else:
783 return obj.service
784 _service.short_description = 'Service'
785 _service.allow_tags = True
786
787 def _responsable(self, obj):
788 try:
789 responsable = u"""<a href="%s"
790 onclick="return showAddAnotherPopup(this)">
791 <img src="%simg/loupe.png"
792 title="Aperçu du poste" />
793 </a>
794 <a href="%s">%s</a>
795 <br />""" % \
796 (reverse('poste_apercu', args=(obj.responsable.id,)),
797 settings.STATIC_URL,
798 reverse('admin:rh_poste_change', args=(obj.responsable.id,)),
799 obj.responsable.nom)
800 except:
801 responsable = ''
802
803 try:
804 employe_id = obj.responsable.rh_dossiers.all()[0].id
805 employe = u"""<br />
806 <a href="%s"
807 onclick="return showAddAnotherPopup(this)">
808 <img src="%simg/loupe.png"
809 title="Aperçu de l'employé">
810 </a>
811 <a href="%s">%s</a>""" % \
812 (reverse('employe_apercu', args=(employe_id,)),
813 settings.STATIC_URL,
814 reverse('admin:rh_employe_change', args=(employe_id,)),
815 employe)
816 except:
817 employe = ""
818
819 return "%s %s" % (responsable, employe)
820 _responsable.short_description = 'Responsable'
821 _responsable.allow_tags = True
822
823 def _nom(self, poste):
824 return """<a href="%s">%s</a>""" % \
825 (reverse('admin:rh_poste_change', args=(poste.id,)),
826 poste.nom)
827 _nom.allow_tags = True
828 _nom.short_description = u'Nom'
829 _nom.admin_order_field = 'nom'
830
831 def _date_modification(self, obj):
832 return date(obj.date_modification)
833 _date_modification.short_description = u'date modification'
834 _date_modification.admin_order_field = 'date_modification'
835
836 def _occupe_par(self, obj):
837 """Formatte la méthode Poste.occupe_par() pour l'admin"""
838 output = u"Vacant"
839 if obj.date_fin is not None and obj.date_fin < datetime.date.now():
840 return u"s/o"
841 employes = obj.occupe_par()
842 if employes:
843 l = []
844 for e in employes:
845 link = u"""<a href='%s'
846 title='Aperçu de l\'employer'
847 onclick='return showAddAnotherPopup(this)'>
848 <img src='%simg/loupe.png' />
849 </a>
850 <a href='%s'>%s</a>""" % \
851 (reverse('employe_apercu', args=(e.id,)),
852 settings.STATIC_URL,
853 reverse('admin:rh_employe_change', args=(e.id,)),
854 e)
855 l.append(link)
856 output = "\n<br />".join(l)
857 return output
858 _occupe_par.allow_tags = True
859 _occupe_par.short_description = "Occupé par"
860
861 def save_formset(self, request, form, formset, change):
862 instances = formset.save(commit=False)
863 for instance in instances:
864 if instance.__class__ == rh.PosteCommentaire:
865 instance.owner = request.user
866 instance.date_creation = datetime.datetime.now()
867 instance.save()
868 formset.save_m2m()
869
870
871 class PosteCommentaireAdmin(admin.ModelAdmin):
872 pass
873
874
875 class PosteFinancementAdmin(admin.ModelAdmin):
876 pass
877
878
879 class PostePieceAdmin(admin.ModelAdmin):
880 fk_name = 'poste'
881
882
883 class RemunerationAdmin(admin.ModelAdmin):
884 pass
885
886
887 class ResponsableImplantationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
888 fieldsets = AUFMetadataAdminMixin.fieldsets + (
889 (None, {
890 'fields': ('employe', 'implantation', ),
891 }),
892 )
893
894
895 class ServiceAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
896 list_display = (
897 'nom',
898 '_archive',
899 '_date_modification',
900 'user_modification',
901 )
902 list_filter = ('archive', )
903 fieldsets = AUFMetadataAdminMixin.fieldsets + (
904 (None, {
905 'fields': ('nom', 'archive', ),
906 }),
907 )
908
909 def _archive(self, obj):
910 if obj.archive:
911 return "oui"
912 else:
913 return "non"
914 _archive.short_description = u'Archivé'
915
916 def _date_modification(self, obj):
917 return date(obj.date_modification) \
918 if obj.date_modification is not None else "(aucune)"
919 _date_modification.short_description = u'date modification'
920 _date_modification.admin_order_field = 'date_modification'
921
922
923 class ServiceProxyAdmin(ServiceAdmin):
924 list_display = ('nom', '_organigramme')
925 list_display_links = ('nom',)
926
927 def has_add_permission(self, obj):
928 return False
929
930 def _organigramme(self, obj):
931 return """<a href="%s">Organigramme</a>""" % (reverse('rho_service', args=(obj.id,)))
932 _organigramme.allow_tags = True
933 _organigramme.short_description = "Organigramme"
934
935 class StatutAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
936 list_display = ('code', 'nom', '_date_modification', 'user_modification', )
937 fieldsets = AUFMetadataAdminMixin.fieldsets + (
938 (None, {
939 'fields': ('code', 'nom', ),
940 }),
941 )
942
943 def _date_modification(self, obj):
944 return date(obj.date_modification) \
945 if obj.date_modification is not None else "(aucune)"
946 _date_modification.short_description = u'date modification'
947 _date_modification.admin_order_field = 'date_modification'
948
949
950 class TauxChangeAdmin(admin.ModelAdmin):
951 list_display = (
952 'taux',
953 'devise',
954 'annee',
955 '_date_modification',
956 'user_modification',
957 )
958 list_filter = ('devise', )
959 fieldsets = AUFMetadataAdminMixin.fieldsets + (
960 (None, {
961 'fields': ('taux', 'devise', 'annee', ),
962 }),
963 )
964
965 def _date_modification(self, obj):
966 return date(obj.date_modification) \
967 if obj.date_modification is not None else "(aucune)"
968 _date_modification.short_description = u'date modification'
969 _date_modification.admin_order_field = 'date_modification'
970
971
972 class TypeContratAdmin(admin.ModelAdmin):
973 list_display = (
974 'nom',
975 'nom_long',
976 '_date_modification',
977 'user_modification',
978 )
979 fieldsets = AUFMetadataAdminMixin.fieldsets + (
980 (None, {
981 'fields': ('nom', 'nom_long', ),
982 }),
983 )
984
985 def _date_modification(self, obj):
986 return date(obj.date_modification) \
987 if obj.date_modification is not None else "(aucune)"
988 _date_modification.short_description = u'date modification'
989 _date_modification.admin_order_field = 'date_modification'
990
991
992 class TypePosteAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
993 search_fields = ('nom', 'nom_feminin', )
994 list_display = (
995 'nom',
996 'famille_emploi',
997 '_date_modification',
998 'user_modification',
999 )
1000 list_filter = ('famille_emploi', )
1001 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1002 (None, {
1003 'fields': (
1004 'nom',
1005 'nom_feminin',
1006 'is_responsable',
1007 'famille_emploi',
1008 )}
1009 ),
1010 )
1011
1012 def _date_modification(self, obj):
1013 return date(obj.date_modification) \
1014 if obj.date_modification is not None else "(aucune)"
1015 _date_modification.short_description = u'date modification'
1016 _date_modification.admin_order_field = 'date_modification'
1017
1018
1019 class TypeRemunerationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1020 list_display = (
1021 'nom',
1022 'type_paiement',
1023 'nature_remuneration',
1024 '_date_modification',
1025 'user_modification',)
1026 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1027 (None, {'fields': ('nom', 'type_paiement', 'nature_remuneration',)}),
1028 )
1029
1030 def _date_modification(self, obj):
1031 return date(obj.date_modification) \
1032 if obj.date_modification is not None else "(aucune)"
1033 _date_modification.short_description = u'date modification'
1034 _date_modification.admin_order_field = 'date_modification'
1035
1036
1037 class TypeRevalorisationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1038 list_display = ('nom', '_date_modification', 'user_modification', )
1039 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1040 (None, {'fields': ('nom', )}),
1041 )
1042
1043 def _date_modification(self, obj):
1044 return date(obj.date_modification) \
1045 if obj.date_modification is not None else "(aucune)"
1046 _date_modification.short_description = u'date modification'
1047 _date_modification.admin_order_field = 'date_modification'
1048
1049
1050 class ValeurPointAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1051 list_display = (
1052 '_devise_code',
1053 '_devise_nom',
1054 'annee',
1055 'valeur',
1056 '_date_modification',
1057 'user_modification',
1058 )
1059 list_filter = ('annee', 'devise', )
1060 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1061 (None, {'fields': ('valeur', 'devise', 'implantation', 'annee', )}),
1062 )
1063
1064 def _date_modification(self, obj):
1065 return date(obj.date_modification) \
1066 if obj.date_modification is not None else "(aucune)"
1067 _date_modification.short_description = u'date modification'
1068 _date_modification.admin_order_field = 'date_modification'
1069
1070 def _devise_code(self, obj):
1071 return obj.devise.code
1072 _devise_code.short_description = "Code de la devise"
1073
1074 def _devise_nom(self, obj):
1075 return obj.devise.nom
1076 _devise_nom.short_description = "Nom de la devise"
1077
1078 class ImplantationProxyAdmin(admin.ModelAdmin):
1079 list_display = ('nom', '_organigramme')
1080 list_display_links = ('nom',)
1081
1082 def has_add_permission(self, obj):
1083 return False
1084
1085 def _organigramme(self, obj):
1086 return """<a href="%s">Organigramme</a>""" % (reverse('rho_implantation', args=(obj.id,)))
1087 _organigramme.allow_tags = True
1088 _organigramme.short_description = "Organigramme"
1089
1090 class RegionProxyAdmin(admin.ModelAdmin):
1091 list_display = ('nom', '_organigramme')
1092 list_display_links = ('nom',)
1093
1094 def has_add_permission(self, obj):
1095 return False
1096
1097 def _organigramme(self, obj):
1098 return """<a href="%s">Organigramme</a>""" % (reverse('rho_region', args=(obj.id,)))
1099 _organigramme.allow_tags = True
1100 _organigramme.short_description = "Organigramme"
1101
1102
1103
1104
1105 admin.site.register(rh.Classement, ClassementAdmin)
1106 admin.site.register(rh.Devise, DeviseAdmin)
1107 admin.site.register(rh.Dossier, DossierAdmin)
1108 admin.site.register(EmployeProxy, EmployeProxyAdmin)
1109 admin.site.register(ServiceProxy, ServiceProxyAdmin)
1110 admin.site.register(rh.Employe, EmployeAdmin)
1111 admin.site.register(rh.FamilleEmploi, FamilleEmploiAdmin)
1112 admin.site.register(rh.OrganismeBstg, OrganismeBstgAdmin)
1113 admin.site.register(rh.Poste, PosteAdmin)
1114 admin.site.register(rh.ResponsableImplantation, ResponsableImplantationAdmin)
1115 admin.site.register(rh.Service, ServiceAdmin)
1116 admin.site.register(rh.Statut, StatutAdmin)
1117 admin.site.register(rh.TauxChange, TauxChangeAdmin)
1118 admin.site.register(rh.TypeContrat, TypeContratAdmin)
1119 admin.site.register(rh.TypePoste, TypePosteAdmin)
1120 admin.site.register(rh.TypeRemuneration, TypeRemunerationAdmin)
1121 admin.site.register(rh.TypeRevalorisation, TypeRevalorisationAdmin)
1122 admin.site.register(rh.ValeurPoint, ValeurPointAdmin)
1123 admin.site.register(ImplantationProxy, ImplantationProxyAdmin)
1124 admin.site.register(RegionProxy, RegionProxyAdmin)