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