Ajout des organigrammes par région (bureau)
[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 obj.rh_dossiers.all().order_by('-date_debut'):
597 poste = u"""<a title="Aperçu du poste"
598 href="%s"
599 onclick="return showAddAnotherPopup(this);"
600 title="Aperçu du poste">
601 <img src="%simg/loupe.png" />
602 </a>
603 <a href="%s">Poste</a>
604 &nbsp;""" % \
605 (reverse('poste_apercu', args=(d.poste.id,)),
606 settings.STATIC_URL,
607 reverse('admin:rh_poste_change', args=(d.poste.id,)))
608 organigramme = u"""<a href="%s">Organigramme</a>""" % \
609 (reverse('rho_employe', args=(d.poste.id,)))
610 link = u"""<li>%s - %s - %s : [%s] %s</li>""" % \
611 (poste, organigramme,
612 d.date_debut.year,
613 d.poste.id,
614 d.poste.nom,
615 )
616 l.append(link)
617 return "<ul>%s</ul>" % "\n".join(l)
618
619 _organigramme.allow_tags = True
620 _organigramme.short_description = "Organigramme"
621
622
623 class EmployeCommentaireAdmin(admin.ModelAdmin):
624 pass
625
626
627 class EmployePieceAdmin(admin.ModelAdmin):
628 pass
629
630
631 class FamilleEmploiAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
632 list_display = ('nom', '_date_modification', 'user_modification', )
633 inlines = (TypePosteInline,)
634 fieldsets = AUFMetadataAdminMixin.fieldsets + (
635 (None, {'fields': ('nom', )}),)
636
637 def _date_modification(self, obj):
638 return date(obj.date_modification) \
639 if obj.date_modification is not None else "(aucune)"
640 _date_modification.short_description = u'date modification'
641 _date_modification.admin_order_field = 'date_modification'
642
643
644 class OrganismeBstgAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
645 search_fields = ('nom',)
646 list_display = (
647 'nom',
648 'type',
649 'pays',
650 '_date_modification',
651 'user_modification',
652 )
653 list_filter = ('type', )
654 inlines = (DossierROInline,)
655 fieldsets = AUFMetadataAdminMixin.fieldsets + (
656 (None, {'fields': ('nom', 'type', 'pays',)}),
657 )
658
659 def _date_modification(self, obj):
660 return date(obj.date_modification) \
661 if obj.date_modification is not None else "(aucune)"
662 _date_modification.short_description = u'date modification'
663 _date_modification.admin_order_field = 'date_modification'
664
665
666 class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, \
667 ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
668 form = make_ajax_form(rh.Poste, {
669 'implantation': 'implantations',
670 'type_poste': 'typepostes',
671 'responsable': 'postes',
672 'valeur_point_min': 'valeurpoints',
673 'valeur_point_max': 'valeurpoints',
674 })
675 alphabet_filter = 'nom'
676 search_fields = (
677 'id',
678 'nom',
679 'implantation__nom',
680 'implantation__region__code',
681 'implantation__region__nom',
682 'rh_dossiers__employe__nom',
683 'rh_dossiers__employe__prenom',
684 )
685 list_display = (
686 '_id',
687 '_apercu',
688 '_nom',
689 '_occupe_par',
690 'implantation',
691 '_service',
692 '_responsable',
693 'date_debut',
694 'date_fin',
695 '_date_modification',
696 'user_modification',
697 )
698 list_filter = (
699 'implantation__region',
700 'implantation',
701 'service',
702 'type_poste',
703 'type_poste__famille_emploi',
704 'vacant',
705 )
706 list_display_links = ('_nom',)
707 fieldsets = AUFMetadataAdminMixin.fieldsets + (
708 (None, {'fields': (
709 ('nom', 'nom_feminin'),
710 'implantation',
711 'type_poste',
712 'service',
713 'responsable',
714 )}
715 ),
716 ('Contrat', {
717 'fields': ((
718 'regime_travail',
719 'regime_travail_nb_heure_semaine'),
720 )}
721 ),
722 ('Recrutement', {
723 'fields': (('local', 'expatrie', 'mise_a_disposition', 'appel'),)}
724 ),
725 ('Rémunération', {
726 'fields': (('classement_min',
727 'valeur_point_min',
728 'devise_min',
729 'salaire_min',
730 'indemn_min',
731 'autre_min',),
732 ('classement_max',
733 'valeur_point_max',
734 'devise_max',
735 'salaire_max',
736 'indemn_max',
737 'autre_max',),
738 )}),
739 ('Comparatifs de rémunération', {
740 'fields': ('devise_comparaison',
741 ('comp_locale_min', 'comp_locale_max'),
742 ('comp_universite_min', 'comp_universite_max'),
743 ('comp_fonctionpub_min', 'comp_fonctionpub_max'),
744 ('comp_ong_min', 'comp_ong_max'),
745 ('comp_autre_min', 'comp_autre_max'))}
746 ),
747 ('Justification', {
748 'fields': ('justification',)}
749 ),
750 ('Autres Méta-données', {
751 'fields': ('date_debut', 'date_fin')}
752 ),
753 )
754
755 inlines = (PosteFinancementInline,
756 PostePieceInline,
757 DossierROInline,
758 PosteComparaisonInline,
759 PosteCommentaireInline, )
760
761 def lookup_allowed(self, key, value):
762 if key in (
763 'date_debut__gte',
764 'date_debut__isnull',
765 'date_fin__lte',
766 'date_fin__isnull',
767 'implantation__region__id__exact',
768 'implantation__id__exact',
769 'type_poste__id__exact',
770 'type_poste__famille_emploi__id__exact',
771 'service__id__exact',
772 'service__isnull',
773 'vacant__exact',
774 'vacant__isnull',
775 ):
776 return True
777
778 def _apercu(self, poste):
779 view_link = u"""<a onclick="return showAddAnotherPopup(this);"
780 title="Aperçu du poste"
781 href='%s'>
782 <img src="%simg/loupe.png" />
783 </a>""" % \
784 (reverse('poste_apercu', args=(poste.id,)),
785 settings.STATIC_URL,)
786 return view_link
787 _apercu.allow_tags = True
788 _apercu.short_description = ''
789
790 def _id(self, obj):
791 return "%s" % obj.id
792 _id.short_description = '#'
793 _id.admin_order_field = 'id'
794
795 def _service(self, obj):
796 if obj.service.supprime:
797 return """<span style="color:red">%s</span>""" % obj.service
798 else:
799 return obj.service
800 _service.short_description = 'Service'
801 _service.allow_tags = True
802
803 def _responsable(self, obj):
804 try:
805 responsable = u"""<a href="%s"
806 onclick="return showAddAnotherPopup(this)">
807 <img src="%simg/loupe.png"
808 title="Aperçu du poste" />
809 </a>
810 <a href="%s">%s</a>
811 <br />""" % \
812 (reverse('poste_apercu', args=(obj.responsable.id,)),
813 settings.STATIC_URL,
814 reverse('admin:rh_poste_change', args=(obj.responsable.id,)),
815 obj.responsable.nom)
816 except:
817 responsable = ''
818
819 try:
820 employe_id = obj.responsable.rh_dossiers.all()[0].id
821 employe = u"""<br />
822 <a href="%s"
823 onclick="return showAddAnotherPopup(this)">
824 <img src="%simg/loupe.png"
825 title="Aperçu de l'employé">
826 </a>
827 <a href="%s">%s</a>""" % \
828 (reverse('employe_apercu', args=(employe_id,)),
829 settings.STATIC_URL,
830 reverse('admin:rh_employe_change', args=(employe_id,)),
831 employe)
832 except:
833 employe = ""
834
835 return "%s %s" % (responsable, employe)
836 _responsable.short_description = 'Responsable'
837 _responsable.allow_tags = True
838
839 def _nom(self, poste):
840 return """<a href="%s">%s</a>""" % \
841 (reverse('admin:rh_poste_change', args=(poste.id,)),
842 poste.nom)
843 _nom.allow_tags = True
844 _nom.short_description = u'Nom'
845 _nom.admin_order_field = 'nom'
846
847 def _date_modification(self, obj):
848 return date(obj.date_modification)
849 _date_modification.short_description = u'date modification'
850 _date_modification.admin_order_field = 'date_modification'
851
852 def _occupe_par(self, obj):
853 """Formatte la méthode Poste.occupe_par() pour l'admin"""
854 output = u"Vacant"
855 if obj.date_fin is not None and obj.date_fin < datetime.date.now():
856 return u"s/o"
857 employes = obj.occupe_par()
858 if employes:
859 l = []
860 for e in employes:
861 link = u"""<a href='%s'
862 title='Aperçu de l\'employer'
863 onclick='return showAddAnotherPopup(this)'>
864 <img src='%simg/loupe.png' />
865 </a>
866 <a href='%s'>%s</a>""" % \
867 (reverse('employe_apercu', args=(e.id,)),
868 settings.STATIC_URL,
869 reverse('admin:rh_employe_change', args=(e.id,)),
870 e)
871 l.append(link)
872 output = "\n<br />".join(l)
873 return output
874 _occupe_par.allow_tags = True
875 _occupe_par.short_description = "Occupé par"
876
877 def save_formset(self, request, form, formset, change):
878 instances = formset.save(commit=False)
879 for instance in instances:
880 if instance.__class__ == rh.PosteCommentaire:
881 instance.owner = request.user
882 instance.date_creation = datetime.datetime.now()
883 instance.save()
884 formset.save_m2m()
885
886
887 class PosteCommentaireAdmin(admin.ModelAdmin):
888 pass
889
890
891 class PosteFinancementAdmin(admin.ModelAdmin):
892 pass
893
894
895 class PostePieceAdmin(admin.ModelAdmin):
896 fk_name = 'poste'
897
898
899 class RemunerationAdmin(admin.ModelAdmin):
900 pass
901
902
903 class ResponsableImplantationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
904 fieldsets = AUFMetadataAdminMixin.fieldsets + (
905 (None, {
906 'fields': ('employe', 'implantation', ),
907 }),
908 )
909
910
911 class ServiceAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
912 list_display = (
913 'nom',
914 '_archive',
915 '_date_modification',
916 'user_modification',
917 )
918 list_filter = ('archive', )
919 fieldsets = AUFMetadataAdminMixin.fieldsets + (
920 (None, {
921 'fields': ('nom', 'archive', ),
922 }),
923 )
924
925 def _archive(self, obj):
926 if obj.archive:
927 return "oui"
928 else:
929 return "non"
930 _archive.short_description = u'Archivé'
931
932 def _date_modification(self, obj):
933 return date(obj.date_modification) \
934 if obj.date_modification is not None else "(aucune)"
935 _date_modification.short_description = u'date modification'
936 _date_modification.admin_order_field = 'date_modification'
937
938
939 class ServiceProxyAdmin(ServiceAdmin):
940 list_display = ('nom', '_organigramme')
941 list_display_links = ('nom',)
942
943 def has_add_permission(self, obj):
944 return False
945
946 def _organigramme(self, obj):
947 return """<a href="%s">Organigramme</a>""" % (reverse('rho_implantation', args=(obj.id,)))
948 _organigramme.allow_tags = True
949 _organigramme.short_description = "Organigramme"
950
951 class StatutAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
952 list_display = ('code', 'nom', '_date_modification', 'user_modification', )
953 fieldsets = AUFMetadataAdminMixin.fieldsets + (
954 (None, {
955 'fields': ('code', 'nom', ),
956 }),
957 )
958
959 def _date_modification(self, obj):
960 return date(obj.date_modification) \
961 if obj.date_modification is not None else "(aucune)"
962 _date_modification.short_description = u'date modification'
963 _date_modification.admin_order_field = 'date_modification'
964
965
966 class TauxChangeAdmin(admin.ModelAdmin):
967 list_display = (
968 'taux',
969 'devise',
970 'annee',
971 '_date_modification',
972 'user_modification',
973 )
974 list_filter = ('devise', )
975 fieldsets = AUFMetadataAdminMixin.fieldsets + (
976 (None, {
977 'fields': ('taux', 'devise', 'annee', ),
978 }),
979 )
980
981 def _date_modification(self, obj):
982 return date(obj.date_modification) \
983 if obj.date_modification is not None else "(aucune)"
984 _date_modification.short_description = u'date modification'
985 _date_modification.admin_order_field = 'date_modification'
986
987
988 class TypeContratAdmin(admin.ModelAdmin):
989 list_display = (
990 'nom',
991 'nom_long',
992 '_date_modification',
993 'user_modification',
994 )
995 fieldsets = AUFMetadataAdminMixin.fieldsets + (
996 (None, {
997 'fields': ('nom', 'nom_long', ),
998 }),
999 )
1000
1001 def _date_modification(self, obj):
1002 return date(obj.date_modification) \
1003 if obj.date_modification is not None else "(aucune)"
1004 _date_modification.short_description = u'date modification'
1005 _date_modification.admin_order_field = 'date_modification'
1006
1007
1008 class TypePosteAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1009 search_fields = ('nom', 'nom_feminin', )
1010 list_display = (
1011 'nom',
1012 'famille_emploi',
1013 '_date_modification',
1014 'user_modification',
1015 )
1016 list_filter = ('famille_emploi', )
1017 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1018 (None, {
1019 'fields': (
1020 'nom',
1021 'nom_feminin',
1022 'is_responsable',
1023 'famille_emploi',
1024 )}
1025 ),
1026 )
1027
1028 def _date_modification(self, obj):
1029 return date(obj.date_modification) \
1030 if obj.date_modification is not None else "(aucune)"
1031 _date_modification.short_description = u'date modification'
1032 _date_modification.admin_order_field = 'date_modification'
1033
1034
1035 class TypeRemunerationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1036 list_display = (
1037 'nom',
1038 'type_paiement',
1039 'nature_remuneration',
1040 '_date_modification',
1041 'user_modification',)
1042 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1043 (None, {'fields': ('nom', 'type_paiement', 'nature_remuneration',)}),
1044 )
1045
1046 def _date_modification(self, obj):
1047 return date(obj.date_modification) \
1048 if obj.date_modification is not None else "(aucune)"
1049 _date_modification.short_description = u'date modification'
1050 _date_modification.admin_order_field = 'date_modification'
1051
1052
1053 class TypeRevalorisationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1054 list_display = ('nom', '_date_modification', 'user_modification', )
1055 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1056 (None, {'fields': ('nom', )}),
1057 )
1058
1059 def _date_modification(self, obj):
1060 return date(obj.date_modification) \
1061 if obj.date_modification is not None else "(aucune)"
1062 _date_modification.short_description = u'date modification'
1063 _date_modification.admin_order_field = 'date_modification'
1064
1065
1066 class ValeurPointAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1067 list_display = (
1068 '_devise_code',
1069 '_devise_nom',
1070 'annee',
1071 'valeur',
1072 '_date_modification',
1073 'user_modification',
1074 )
1075 list_filter = ('annee', 'devise', )
1076 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1077 (None, {'fields': ('valeur', 'devise', 'implantation', 'annee', )}),
1078 )
1079
1080 def _date_modification(self, obj):
1081 return date(obj.date_modification) \
1082 if obj.date_modification is not None else "(aucune)"
1083 _date_modification.short_description = u'date modification'
1084 _date_modification.admin_order_field = 'date_modification'
1085
1086 def _devise_code(self, obj):
1087 return obj.devise.code
1088 _devise_code.short_description = "Code de la devise"
1089
1090 def _devise_nom(self, obj):
1091 return obj.devise.nom
1092 _devise_nom.short_description = "Nom de la devise"
1093
1094 class ImplantationProxyAdmin(admin.ModelAdmin):
1095 list_display = ('nom', '_organigramme')
1096 list_display_links = ('nom',)
1097
1098 def has_add_permission(self, obj):
1099 return False
1100
1101 def _organigramme(self, obj):
1102 return """<a href="%s">Organigramme</a>""" % (reverse('rho_implantation', args=(obj.id,)))
1103 _organigramme.allow_tags = True
1104 _organigramme.short_description = "Organigramme"
1105
1106 class RegionProxyAdmin(admin.ModelAdmin):
1107 list_display = ('nom', '_organigramme')
1108 list_display_links = ('nom',)
1109
1110 def has_add_permission(self, obj):
1111 return False
1112
1113 def _organigramme(self, obj):
1114 return """<a href="%s">Organigramme</a>""" % (reverse('rho_region', args=(obj.id,)))
1115 _organigramme.allow_tags = True
1116 _organigramme.short_description = "Organigramme"
1117
1118
1119
1120
1121 admin.site.register(rh.Classement, ClassementAdmin)
1122 admin.site.register(rh.Devise, DeviseAdmin)
1123 admin.site.register(rh.Dossier, DossierAdmin)
1124 admin.site.register(EmployeProxy, EmployeProxyAdmin)
1125 admin.site.register(ServiceProxy, ServiceProxyAdmin)
1126 admin.site.register(rh.Employe, EmployeAdmin)
1127 admin.site.register(rh.FamilleEmploi, FamilleEmploiAdmin)
1128 admin.site.register(rh.OrganismeBstg, OrganismeBstgAdmin)
1129 admin.site.register(rh.Poste, PosteAdmin)
1130 admin.site.register(rh.ResponsableImplantation, ResponsableImplantationAdmin)
1131 admin.site.register(rh.Service, ServiceAdmin)
1132 admin.site.register(rh.Statut, StatutAdmin)
1133 admin.site.register(rh.TauxChange, TauxChangeAdmin)
1134 admin.site.register(rh.TypeContrat, TypeContratAdmin)
1135 admin.site.register(rh.TypePoste, TypePosteAdmin)
1136 admin.site.register(rh.TypeRemuneration, TypeRemunerationAdmin)
1137 admin.site.register(rh.TypeRevalorisation, TypeRevalorisationAdmin)
1138 admin.site.register(rh.ValeurPoint, ValeurPointAdmin)
1139 admin.site.register(ImplantationProxy, ImplantationProxyAdmin)
1140 admin.site.register(RegionProxy, RegionProxyAdmin)