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