1 # -*- encoding: utf-8 -*-
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
, Count
9 from django
.template
.defaultfilters
import date
11 from ajax_select
import make_ajax_form
13 from auf
.django
.metadata
.admin
import \
14 AUFMetadataAdminMixin
, AUFMetadataInlineAdminMixin
, \
15 AUF_METADATA_READONLY_FIELDS
16 import auf
.django
.references
.models
as ref
18 from project
.decorators
import in_drh_or_admin
19 from project
.groups
import grp_correspondants_rh
20 from project
.groups
import get_employe_from_user
22 import project
.rh
.models
as rh
23 from project
.rh
.forms
import ContratForm
, AyantDroitForm
, EmployeAdminForm
, \
24 AjaxSelect
, DossierForm
, ResponsableInlineForm
26 from project
.rh
.change_list
import ChangeList
29 class BaseAdmin(admin
.ModelAdmin
):
33 'css/admin_custom.css',
34 'jquery-autocomplete/jquery.autocomplete.css',
37 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',
38 'jquery-autocomplete/jquery.autocomplete.min.js',
42 class ArchiveMixin(object):
44 Archive Mixin pour gérer le queryset et le display
45 NON COMPRIS : list_filter, et list_display, field à setter dans la classe.
48 def queryset(self
, request
):
49 return self
.model
._base_manager
51 def _archive(self
, obj
):
56 _archive
.short_description
= u
'Archivé'
57 _archive
.admin_order_field
= 'archive'
60 class RegionProxy(ref
.Region
):
61 """ Proxy utilisé pour les organigrammes par région """
64 verbose_name
= u
"Organigramme par région"
65 verbose_name_plural
= u
"Organigramme par région"
68 class ImplantationProxy(ref
.Implantation
):
69 """ Proxy utilisé pour les organigrammes par implantation """
72 verbose_name
= u
"Organigramme par implantations"
73 verbose_name_plural
= u
"Organigramme par implantations"
76 class ServiceProxy(rh
.Service
):
77 """ Proxy utilisé pour les organigrammes opar service """
81 verbose_name
= u
"Organigramme par services"
82 verbose_name_plural
= u
"Organigramme par services"
85 class EmployeProxy(rh
.Employe
):
86 """ Proxy utilisé pour les organigrammes des employés """
89 verbose_name
= u
"Organigramme des employés"
90 verbose_name_plural
= u
"Organigramme des employés"
93 class DateRangeMixin(object):
94 prefixe_recherche_temporelle
= ""
96 def get_changelist(self
, request
, **kwargs
):
97 if 'HTTP_REFERER' in request
.META
.keys():
98 referer
= request
.META
['HTTP_REFERER']
99 referer
= "/".join(referer
.split('/')[3:])
100 referer
= "/%s" % referer
.split('?')[0]
101 change_list_view
= 'admin:%s_%s_changelist' % (
102 self
.model
._meta
.app_label
,
103 self
.model
.__name__
.lower(),)
104 if referer
!= reverse(change_list_view
):
105 params
= request
.GET
.copy()
106 params
.update({'statut': 'Actif'})
111 # Override of the InlineModelAdmin to support the link in the tabular inline
112 class LinkedInline(admin
.options
.InlineModelAdmin
):
113 template
= "admin/linked.html"
114 admin_model_path
= None
116 def __init__(self
, *args
):
117 super(LinkedInline
, self
).__init__(*args
)
118 if self
.admin_model_path
is None:
119 self
.admin_model_path
= self
.model
.__name__
.lower()
122 class ProtectRegionMixin(object):
124 def queryset(self
, request
):
125 qs
= super(ProtectRegionMixin
, self
).queryset(request
)
127 user_groups
= request
.user
.groups
.all()
128 if in_drh_or_admin(request
.user
):
131 if grp_correspondants_rh
in user_groups
:
132 employe
= get_employe_from_user(request
.user
)
133 q
= Q(**{self
.model
.prefix_implantation
: \
134 employe
.implantation
.region
})
135 qs
= qs
.filter(q
).distinct()
139 def has_add_permission(self
, request
):
140 if not in_drh_or_admin(request
.user
):
145 def has_change_permission(self
, request
, obj
=None):
146 user_groups
= request
.user
.groups
.all()
148 # Lock pour autoriser uniquement les DRH à utiliser RH
149 if not in_drh_or_admin(request
.user
):
152 if len(user_groups
) == 0 and not request
.user
.is_superuser
:
157 ids
= [o
.id for o
in self
.queryset(request
)]
163 class ReadOnlyInlineMixin(object):
165 def get_readonly_fields(self
, request
, obj
=None):
166 return [f
.name
for f
in self
.model
._meta
.fields \
167 if f
.name
not in AUF_METADATA_READONLY_FIELDS
]
170 class AyantDroitInline(AUFMetadataInlineAdminMixin
, admin
.StackedInline
):
171 model
= rh
.AyantDroit
172 form
= AyantDroitForm
179 ('nom_affichage', 'genre'),
187 class AyantDroitCommentaireInline(AUFMetadataInlineAdminMixin
, \
188 admin
.TabularInline
):
189 readonly_fields
= ('owner', )
190 model
= rh
.AyantDroitCommentaire
194 class ContratInline(AUFMetadataInlineAdminMixin
, admin
.TabularInline
):
200 class DossierROInline(ReadOnlyInlineMixin
, LinkedInline
):
201 template
= "admin/rh/dossier/linked.html"
202 exclude
= AUF_METADATA_READONLY_FIELDS
207 def has_add_permission(self
, request
=None):
210 def has_change_permission(self
, request
, obj
=None):
213 def has_delete_permission(self
, request
, obj
=None):
217 class DossierCommentaireInline(AUFMetadataInlineAdminMixin
, \
218 admin
.TabularInline
):
219 readonly_fields
= ('owner', )
220 model
= rh
.DossierCommentaire
224 class DossierPieceInline(admin
.TabularInline
):
225 model
= rh
.DossierPiece
229 class EmployeInline(admin
.TabularInline
):
233 class EmployeCommentaireInline(AUFMetadataInlineAdminMixin
, \
234 admin
.TabularInline
):
235 readonly_fields
= ('owner', )
236 model
= rh
.EmployeCommentaire
240 class EmployePieceInline(admin
.TabularInline
):
241 model
= rh
.EmployePiece
245 class PosteCommentaireInline(AUFMetadataInlineAdminMixin
, admin
.TabularInline
):
246 readonly_fields
= ('owner', )
247 model
= rh
.PosteCommentaire
251 class PosteFinancementInline(admin
.TabularInline
):
252 model
= rh
.PosteFinancement
255 class PostePieceInline(admin
.TabularInline
):
256 model
= rh
.PostePiece
259 class RemunerationInline(AUFMetadataInlineAdminMixin
, admin
.TabularInline
):
260 model
= rh
.Remuneration
264 class RemunerationROInline(ReadOnlyInlineMixin
, RemunerationInline
):
268 class TypePosteInline(AUFMetadataInlineAdminMixin
, admin
.TabularInline
):
272 class PosteComparaisonInline(AUFMetadataInlineAdminMixin
, admin
.TabularInline
):
273 model
= rh
.PosteComparaison
276 class ClassementAdmin(AUFMetadataAdminMixin
, BaseAdmin
):
277 list_display
= ('_classement', '_date_modification', 'user_modification', )
278 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
280 'fields': ('type', 'echelon', 'degre', 'coefficient',)}),
283 def _classement(self
, obj
):
285 _classement
.short_description
= u
"Classement"
287 def _date_modification(self
, obj
):
288 return date(obj
.date_modification
) \
289 if obj
.date_modification
is not None else "(aucune)"
290 _date_modification
.short_description
= u
'date modification'
291 _date_modification
.admin_order_field
= 'date_modification'
294 class DeviseAdmin(AUFMetadataAdminMixin
, BaseAdmin
, ArchiveMixin
):
299 '_date_modification',
302 list_filter
= ('archive', )
303 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
305 'fields': ('code', 'nom', 'archive', ),
309 def _date_modification(self
, obj
):
310 return date(obj
.date_modification
) \
311 if obj
.date_modification
is not None else "(aucune)"
312 _date_modification
.short_description
= u
'date modification'
313 _date_modification
.admin_order_field
= 'date_modification'
316 class DossierAdmin(DateRangeMixin
, AUFMetadataAdminMixin
,
317 ProtectRegionMixin
, BaseAdmin
, AjaxSelect
):
318 alphabet_filter
= 'employe__nom'
326 'poste__nom_feminin',
327 'poste__implantation__nom',
337 '_date_modification',
341 list_display_links
= ('_nom',)
343 'poste__implantation__region',
344 'poste__implantation',
345 'poste__type_poste__categorie_emploi',
347 'rh_contrats__type_contrat',
350 inlines
= (DossierPieceInline
, ContratInline
,
352 DossierCommentaireInline
,
354 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
361 'organisme_bstg',)}),
366 'remplacement_de', )}),
370 ('regime_travail', 'regime_travail_nb_heure_semaine'),)}),
371 ('Occupation du Poste par cet Employe', {
372 'fields': (('date_debut', 'date_fin'), )}
375 form
= make_ajax_form(rh
.Dossier
, {
376 'employe': 'employes',
378 'remplacement_de': 'dossiers',
379 }, superclass
=DossierForm
)
381 def lookup_allowed(self
, key
, value
):
383 'employe__nom__istartswith',
384 'poste__implantation__region__id__exact',
385 'poste__implantation__id__exact',
386 'poste__type_poste__id__exact',
387 'poste__type_poste__categorie_emploi__id__exact',
388 'rh_contrats__type_contrat__id__exact',
396 _id
.short_description
= u
"#"
397 _id
.admin_order_field
= "id"
400 return "%d : %s %s" % (
402 obj
.employe
.nom
.upper(),
404 _nom
.allow_tags
= True
405 _nom
.short_description
= u
"Dossier"
407 def _apercu(self
, d
):
408 apercu_link
= u
"""<a title="Aperçu du dossier"
409 onclick="return showAddAnotherPopup(this);"
411 <img src="%simg/dossier-apercu.png" />
413 (reverse('dossier_apercu', args
=(d
.id,)),
417 _apercu
.allow_tags
= True
418 _apercu
.short_description
= u
""
422 dossiers_dae
= d
.dossiers_dae
.all()
423 if len(dossiers_dae
) > 0:
424 dossier_dae
= dossiers_dae
[0]
425 apercu_link
= u
"""<a title="Aperçu du dossier"
426 onclick="return showAddAnotherPopup(this);"
428 <img src="%simg/loupe.png" />
430 (reverse('embauche_consulter', args
=(dossier_dae
.id,)),
434 _dae
.allow_tags
= True
435 _dae
.short_description
= u
"DAE"
437 def _date_debut(self
, obj
):
438 return date(obj
.date_debut
)
440 _date_debut
.short_description
= u
'Occupation début'
441 _date_debut
.admin_order_field
= 'date_debut'
443 def _date_fin(self
, obj
):
444 return date(obj
.date_fin
)
445 _date_fin
.short_description
= u
'Occupation fin'
446 _date_fin
.admin_order_field
= 'date_fin'
448 def _date_modification(self
, obj
):
449 return date(obj
.date_modification
) \
450 if obj
.date_modification
is not None else "(aucune)"
451 _date_modification
.short_description
= u
'date modification'
452 _date_modification
.admin_order_field
= 'date_modification'
454 def _poste(self
, dossier
):
455 link
= u
"""<a title="Aperçu du poste"
456 onclick="return showAddAnotherPopup(this);"
457 href='%s'><img src="%simg/poste-apercu.png" />
459 <a href="%s" title="Modifier le poste">%s</a>""" % \
460 (reverse('poste_apercu', args
=(dossier
.poste
.id,)),
462 reverse('admin:rh_poste_change', args
=(dossier
.poste
.id,)),
466 _poste
.allow_tags
= True
467 _poste
.short_description
= u
'Poste'
468 _poste
.admin_order_field
= 'poste__nom'
470 def _employe(self
, obj
):
471 employe
= obj
.employe
472 view_link
= reverse('employe_apercu', args
=(employe
.id,))
473 edit_link
= reverse('admin:rh_employe_change', args
=(employe
.id,))
476 view
= u
"""<a href="%s"
477 title="Aperçu l'employé"
478 onclick="return showAddAnotherPopup(this);">
479 <img src="%simg/employe-apercu.png" />
480 </a>""" % (view_link
, settings
.STATIC_URL
,)
481 return u
"""%s<a href='%s' style="%s;">%s</a>""" % \
482 (view
, edit_link
, style
, employe
)
483 _employe
.allow_tags
= True
484 _employe
.short_description
= u
"Employé"
485 _employe
.admin_order_field
= "employe__nom"
487 def save_formset(self
, request
, form
, formset
, change
):
488 instances
= formset
.save(commit
=False)
489 for instance
in instances
:
490 if instance
.__class__
== rh
.DossierCommentaire
:
491 instance
.owner
= request
.user
492 instance
.date_creation
= datetime
.datetime
.now()
496 class EmployeAdmin(DateRangeMixin
, AUFMetadataAdminMixin
,
497 ProtectRegionMixin
, BaseAdmin
):
498 prefixe_recherche_temporelle
= "rh_dossiers__"
499 alphabet_filter
= 'nom'
500 DEFAULT_ALPHABET
= u
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
502 'id', 'nom', 'prenom', 'nom_affichage',
503 'rh_dossiers__poste__nom',
504 'rh_dossiers__poste__nom_feminin'
507 form
= EmployeAdminForm
514 '_date_modification',
517 list_display_links
= ('_nom',)
519 'rh_dossiers__poste__implantation__region',
520 'rh_dossiers__poste__implantation',
523 inlines
= (AyantDroitInline
,
526 EmployeCommentaireInline
)
527 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
531 ('nom_affichage', 'genre'),
536 ('Informations personnelles', {
537 'fields': ('situation_famille', 'date_entree', )}
539 ('Coordonnées personnelles', {
541 ('tel_domicile', 'tel_cellulaire'),
542 ('adresse', 'ville'),
543 ('code_postal', 'province'),
550 def _apercu(self
, obj
):
551 return u
"""<a title="Aperçu de l'employé"
552 onclick="return showAddAnotherPopup(this);"
554 <img src="%simg/employe-apercu.png" />
556 (reverse('employe_apercu', args
=(obj
.id,)), settings
.STATIC_URL
)
557 _apercu
.allow_tags
= True
558 _apercu
.short_description
= u
""
561 edit_link
= reverse('admin:rh_employe_change', args
=(obj
.id,))
562 return u
"""<a href='%s'><strong>%s</strong></a>""" % \
563 (edit_link
, "%s %s" % (obj
.nom
.upper(), obj
.prenom
))
564 _nom
.allow_tags
= True
565 _nom
.short_description
= u
"Employé"
566 _nom
.admin_order_field
= "nom"
570 _id
.short_description
= u
"#"
571 _id
.admin_order_field
= "id"
573 def _date_modification(self
, obj
):
574 return date(obj
.date_modification
) \
575 if obj
.date_modification
is not None else "(aucune)"
576 _date_modification
.short_description
= u
'date modification'
577 _date_modification
.admin_order_field
= 'date_modification'
579 def _dossiers_postes(self
, obj
):
581 for d
in obj
.rh_dossiers
.all().order_by('-date_debut'):
582 dossier
= u
"""<a title="Aperçu du dossier"
584 onclick="return showAddAnotherPopup(this);"
585 title="Aperçu du dossier">
586 <img src="%simg/dossier-apercu.png" />
588 <a href="%s">Dossier</a>
590 (reverse('dossier_apercu', args
=(d
.id,)),
592 reverse('admin:rh_dossier_change', args
=(d
.id,)))
594 poste
= u
"""<a title="Aperçu du poste"
596 onclick="return showAddAnotherPopup(this);"
597 title="Aperçu du poste">
598 <img src="%simg/poste-apercu.png" />
600 <a href="%s">Poste</a>
602 (reverse('poste_apercu', args
=(d
.poste
.id,)),
604 reverse('admin:rh_poste_change', args
=(d
.poste
.id,)))
605 link
= u
"""<li>%s %s - %s : [%s] %s</li>""" % \
612 # Dossier terminé en gris non cliquable
613 if d
.date_fin
is not None and d
.date_fin
< datetime
.date
.today():
614 link
= u
"""<li style="color: grey">%s : [%s] %s</li>""" % \
621 return "<ul>%s</ul>" % "\n".join(l
)
622 _dossiers_postes
.allow_tags
= True
623 _dossiers_postes
.short_description
= u
"Dossiers et postes"
625 def queryset(self
, request
):
626 qs
= super(EmployeAdmin
, self
).queryset(request
)
627 return qs
.select_related(depth
=1).order_by('nom')
629 def save_formset(self
, request
, form
, formset
, change
):
630 instances
= formset
.save(commit
=False)
631 for instance
in instances
:
632 if instance
.__class__
== rh
.EmployeCommentaire
:
633 instance
.owner
= request
.user
634 instance
.date_creation
= datetime
.datetime
.now()
638 class EmployeProxyAdmin(EmployeAdmin
):
639 list_display
= ('_id', '_apercu', '_nom', '_organigramme')
642 def __init__(self
, *args
, **kwargs
):
643 super(EmployeProxyAdmin
, self
).__init__(*args
, **kwargs
)
644 self
.list_display_links
= (None, )
646 def has_add_permission(self
, obj
):
649 def _organigramme(self
, obj
):
651 for d
in rh
.Dossier
.objects
.filter(
652 Q(date_fin__gt
=datetime
.date
.today()) |
Q(date_fin
=None),
653 Q(date_debut__lt
=datetime
.date
.today()) |
Q(date_debut
=None),
657 u
'Organigramme, niveau: ' \
658 u
'<input type="text" id="level_%s" ' \
659 u
'style="width:30px;height:15px;" /> ' \
660 u
'<input type="button" value="Générer" ' \
661 u
"""onclick="window.location='%s' + """ \
662 u
"""document.getElementById('level_%s').value" />""" % (
664 reverse('rho_employe_sans_niveau', args
=(d
.poste
.id,)),
667 link
= u
"""<li>%s - [%s] %s : %s</li>""" % (
674 return "<ul>%s</ul>" % "\n".join(l
)
676 _organigramme
.allow_tags
= True
677 _organigramme
.short_description
= "Organigramme"
680 class CategorieEmploiAdmin(AUFMetadataAdminMixin
, BaseAdmin
):
681 list_display
= ('nom', '_date_modification', 'user_modification', )
682 inlines
= (TypePosteInline
,)
683 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
684 (None, {'fields': ('nom', )}),)
686 def _date_modification(self
, obj
):
687 return date(obj
.date_modification
) \
688 if obj
.date_modification
is not None else "(aucune)"
689 _date_modification
.short_description
= u
'date modification'
690 _date_modification
.admin_order_field
= 'date_modification'
693 class OrganismeBstgAdmin(AUFMetadataAdminMixin
, BaseAdmin
):
694 search_fields
= ('nom',)
699 '_date_modification',
702 list_filter
= ('type', )
703 inlines
= (DossierROInline
,)
704 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
705 (None, {'fields': ('nom', 'type', 'pays',)}),
708 def _date_modification(self
, obj
):
709 return date(obj
.date_modification
) \
710 if obj
.date_modification
is not None else "(aucune)"
711 _date_modification
.short_description
= u
'date modification'
712 _date_modification
.admin_order_field
= 'date_modification'
715 class PosteAdmin(DateRangeMixin
, AUFMetadataAdminMixin
,
716 ProtectRegionMixin
, BaseAdmin
, AjaxSelect
):
717 form
= make_ajax_form(rh
.Poste
, {
718 'implantation': 'implantations',
719 'type_poste': 'typepostes',
720 'responsable': 'postes',
721 'valeur_point_min': 'valeurpoints',
722 'valeur_point_max': 'valeurpoints',
724 alphabet_filter
= 'nom'
729 'implantation__region__code',
730 'implantation__region__nom',
731 'rh_dossiers__employe__id',
732 'rh_dossiers__employe__nom',
733 'rh_dossiers__employe__prenom',
745 '_date_modification',
750 'implantation__region',
754 'type_poste__categorie_emploi',
755 'type_poste__famille_professionnelle',
758 list_display_links
= ('_nom',)
759 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
761 ('nom', 'nom_feminin'),
771 'regime_travail_nb_heure_semaine'),
775 'fields': (('local', 'expatrie', 'mise_a_disposition', 'appel'),)}
778 'fields': (('classement_min',
791 ('Comparatifs de rémunération', {
792 'fields': ('devise_comparaison',
793 ('comp_locale_min', 'comp_locale_max'),
794 ('comp_universite_min', 'comp_universite_max'),
795 ('comp_fonctionpub_min', 'comp_fonctionpub_max'),
796 ('comp_ong_min', 'comp_ong_max'),
797 ('comp_autre_min', 'comp_autre_max'))}
800 'fields': ('justification',)}
802 ('Autres Méta-données', {
803 'fields': ('date_debut', 'date_fin')}
807 inlines
= (PosteFinancementInline
,
810 PosteComparaisonInline
,
811 PosteCommentaireInline
, )
813 def lookup_allowed(self
, key
, value
):
815 'date_debut__gte', 'date_debut__isnull', 'date_fin__lte',
816 'date_fin__isnull', 'implantation__region__id__exact',
817 'implantation__id__exact', 'type_poste__id__exact',
818 'type_poste__categorie_emploi__id__exact', 'service__id__exact',
819 'service__isnull', 'vacant__exact', 'vacant__isnull',
820 ) or super(PosteAdmin
, self
).lookup_allowed(key
, value
)
822 def _apercu(self
, poste
):
823 view_link
= u
"""<a onclick="return showAddAnotherPopup(this);"
824 title="Aperçu du poste"
826 <img src="%simg/poste-apercu.png" />
828 (reverse('poste_apercu', args
=(poste
.id,)),
829 settings
.STATIC_URL
,)
831 _apercu
.allow_tags
= True
832 _apercu
.short_description
= ''
834 def _dae(self
, poste
):
836 postes_dae
= poste
.postes_dae
.all()
837 if len(postes_dae
) > 0:
838 poste_dae
= postes_dae
[0]
840 u
'<a title="Aperçu du dossier" href="%s" ' \
841 u
'onclick="return showAddAnotherPopup(this);">' \
842 u
'<img src="%simg/loupe.png" /></a>' % (reverse(
843 'poste_consulter', args
=("dae-%s" % poste_dae
.id,)
844 ), settings
.STATIC_URL
)
846 _dae
.allow_tags
= True
847 _dae
.short_description
= u
"DAE"
851 _id
.short_description
= '#'
852 _id
.admin_order_field
= 'id'
854 def _service(self
, obj
):
855 if obj
.service
.supprime
:
856 return """<span style="color:red">%s</span>""" % obj
.service
859 _service
.short_description
= 'Service'
860 _service
.allow_tags
= True
862 def _responsable(self
, obj
):
864 responsable
= u
"""<a href="%s"
865 onclick="return showAddAnotherPopup(this)">
866 <img src="%simg/poste-apercu.png"
867 title="Aperçu du poste" />
871 (reverse('poste_apercu', args
=(obj
.responsable
.id,)),
873 reverse('admin:rh_poste_change', args
=(obj
.responsable
.id,)),
879 dossier
= obj
.responsable
.rh_dossiers
.all().order_by('-date_debut')[0]
880 employe_id
= dossier
.employe
.id
881 employe_html
= u
"""<br />
883 onclick="return showAddAnotherPopup(this)">
884 <img src="%simg/employe-apercu.png"
885 title="Aperçu de l'employé">
887 <a href="%s">%s</a>""" % \
888 (reverse('employe_apercu', args
=(employe_id
,)),
890 reverse('admin:rh_employe_change', args
=(employe_id
,)),
895 return "%s %s" % (responsable
, employe_html
)
896 _responsable
.short_description
= 'Responsable'
897 _responsable
.allow_tags
= True
899 def _implantation(self
, poste
):
900 return poste
.implantation
.nom
901 _implantation
.short_description
= 'Implantation'
902 _implantation
.admin_order_field
= 'implantation'
904 def _nom(self
, poste
):
905 return """<a href="%s">%s</a>""" % \
906 (reverse('admin:rh_poste_change', args
=(poste
.id,)),
908 _nom
.allow_tags
= True
909 _nom
.short_description
= u
'Poste'
910 _nom
.admin_order_field
= 'nom'
912 def _date_modification(self
, obj
):
913 return date(obj
.date_modification
)
914 _date_modification
.short_description
= u
'date modification'
915 _date_modification
.admin_order_field
= 'date_modification'
917 def _occupe_par(self
, obj
):
918 """Formatte la méthode Poste.occupe_par() pour l'admin"""
920 if obj
.date_fin
is not None and obj
.date_fin
< datetime
.date
.today():
922 employes
= obj
.occupe_par()
926 link
= u
"""<a href='%s'
927 title='Aperçu de l\'employé'
928 onclick='return showAddAnotherPopup(this)'>
929 <img src='%simg/employe-apercu.png' />
931 <a href='%s'>%s</a>""" % \
932 (reverse('employe_apercu', args
=(e
.id,)),
934 reverse('admin:rh_employe_change', args
=(e
.id,)),
937 output
= "\n<br />".join(l
)
939 _occupe_par
.allow_tags
= True
940 _occupe_par
.short_description
= "Occupé par"
942 def save_formset(self
, request
, form
, formset
, change
):
943 instances
= formset
.save(commit
=False)
944 for instance
in instances
:
945 if instance
.__class__
== rh
.PosteCommentaire
:
946 instance
.owner
= request
.user
947 instance
.date_creation
= datetime
.datetime
.now()
952 class ResponsableInline(admin
.TabularInline
):
953 model
= rh
.ResponsableImplantation
955 fk_name
= "implantation"
956 form
= ResponsableInlineForm
959 class ResponsableImplantationAdmin(BaseAdmin
):
962 inlines
= (ResponsableInline
, )
963 list_filter
= ('region', 'statut', )
964 list_display
= ('_region', '_nom', 'statut', '_responsable', )
965 list_display_links
= ('_nom',)
966 readonly_fields
= ('nom', )
969 'responsable__employe__id',
970 'responsable__employe__nom',
971 'responsable__employe__prenom',
975 def _region(self
, obj
):
976 return obj
.region
.code
977 _region
.short_description
= u
"Région"
978 _region
.admin_order_field
= 'region__code'
982 _nom
.short_description
= u
"Implantation"
983 _nom
.admin_order_field
= 'nom'
985 def _responsable(self
, obj
):
987 employe
= obj
.responsable
.employe
988 dossiers
= employe
.dossiers_encours()
989 if len(dossiers
) == 0:
990 return u
"<span style='color: red;'>%s %s </span>" % (
991 employe
, u
"sans dossier actif")
995 if obj
.statut
in (1, 2): # ouverte, ouverture imminente
996 css
= "style='color: red;'"
999 return u
"<span %s>Pas de responsable</span>" % css
1000 _responsable
.allow_tags
= True
1001 _responsable
.short_description
= u
"Responsable"
1002 _responsable
.admin_order_field
= 'responsable__employe__nom'
1004 def has_add_permission(self
, request
=None):
1007 def has_change_permission(self
, request
, obj
=None):
1008 return in_drh_or_admin(request
.user
)
1010 def has_delete_permission(self
, request
, obj
=None):
1014 class ServiceAdmin(AUFMetadataAdminMixin
, BaseAdmin
, ArchiveMixin
):
1018 '_date_modification',
1019 'user_modification',
1021 list_filter
= ('archive', )
1022 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
1024 'fields': ('nom', 'archive', ),
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'
1035 class ServiceProxyAdmin(ServiceAdmin
):
1036 list_display
= ('nom', '_organigramme', '_archive', )
1039 def __init__(self
, *args
, **kwargs
):
1040 super(ServiceProxyAdmin
, self
).__init__(*args
, **kwargs
)
1041 self
.list_display_links
= (None, )
1043 def queryset(self
, request
):
1044 return super(ServiceProxyAdmin
, self
).queryset(request
) \
1045 .annotate(num_postes
=Count('rh_postes')) \
1046 .filter(num_postes__gt
=0)
1048 def has_add_permission(self
, obj
):
1051 def has_change_permission(self
, request
, obj
=None):
1052 return in_drh_or_admin(request
.user
)
1054 def _organigramme(self
, obj
):
1055 return """<a href="%s"><strong>Organigramme</strong></a>""" % \
1056 (reverse('rho_service', args
=(obj
.id,)))
1057 _organigramme
.allow_tags
= True
1058 _organigramme
.short_description
= "Organigramme"
1061 class StatutAdmin(AUFMetadataAdminMixin
, BaseAdmin
):
1062 list_display
= ('code', 'nom', '_date_modification', 'user_modification', )
1063 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
1065 'fields': ('code', 'nom', ),
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'
1076 class TauxChangeAdmin(BaseAdmin
):
1081 '_date_modification',
1082 'user_modification',
1084 list_filter
= ('devise', )
1085 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
1087 'fields': ('taux', 'devise', 'annee', ),
1091 def _date_modification(self
, obj
):
1092 return date(obj
.date_modification
) \
1093 if obj
.date_modification
is not None else "(aucune)"
1094 _date_modification
.short_description
= u
'date modification'
1095 _date_modification
.admin_order_field
= 'date_modification'
1098 class TypeContratAdmin(BaseAdmin
):
1102 '_date_modification',
1103 'user_modification',
1105 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
1107 'fields': ('nom', 'nom_long', ),
1111 def _date_modification(self
, obj
):
1112 return date(obj
.date_modification
) \
1113 if obj
.date_modification
is not None else "(aucune)"
1114 _date_modification
.short_description
= u
'date modification'
1115 _date_modification
.admin_order_field
= 'date_modification'
1118 class TypePosteAdmin(AUFMetadataAdminMixin
, BaseAdmin
):
1119 search_fields
= ('nom', 'nom_feminin', )
1123 '_date_modification',
1124 'user_modification',
1126 list_filter
= ('categorie_emploi', 'famille_professionnelle')
1127 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
1134 'famille_professionnelle',
1139 def _date_modification(self
, obj
):
1140 return date(obj
.date_modification
) \
1141 if obj
.date_modification
is not None else "(aucune)"
1142 _date_modification
.short_description
= u
'date modification'
1143 _date_modification
.admin_order_field
= 'date_modification'
1146 class TypeRemunerationAdmin(AUFMetadataAdminMixin
, BaseAdmin
,
1151 'nature_remuneration',
1153 '_date_modification',
1154 'user_modification',)
1155 list_filter
= ('archive', )
1156 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
1157 (None, {'fields': ('nom', 'type_paiement', 'nature_remuneration',
1161 def _date_modification(self
, obj
):
1162 return date(obj
.date_modification
) \
1163 if obj
.date_modification
is not None else "(aucune)"
1164 _date_modification
.short_description
= u
'date modification'
1165 _date_modification
.admin_order_field
= 'date_modification'
1168 class TypeRevalorisationAdmin(AUFMetadataAdminMixin
, BaseAdmin
):
1169 list_display
= ('nom', '_date_modification', 'user_modification', )
1170 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
1171 (None, {'fields': ('nom', )}),
1174 def _date_modification(self
, obj
):
1175 return date(obj
.date_modification
) \
1176 if obj
.date_modification
is not None else "(aucune)"
1177 _date_modification
.short_description
= u
'date modification'
1178 _date_modification
.admin_order_field
= 'date_modification'
1181 class ValeurPointAdmin(AUFMetadataAdminMixin
, BaseAdmin
):
1188 '_date_modification',
1189 'user_modification',
1191 list_filter
= ('annee', 'devise', 'implantation__region', )
1192 fieldsets
= AUFMetadataAdminMixin
.fieldsets
+ (
1193 (None, {'fields': ('valeur', 'devise', 'implantation', 'annee', )}),
1196 def _date_modification(self
, obj
):
1197 return date(obj
.date_modification
) \
1198 if obj
.date_modification
is not None else "(aucune)"
1199 _date_modification
.short_description
= u
'date modification'
1200 _date_modification
.admin_order_field
= 'date_modification'
1202 def _devise_code(self
, obj
):
1203 return obj
.devise
.code
1204 _devise_code
.short_description
= "Code de la devise"
1206 def _devise_nom(self
, obj
):
1207 return obj
.devise
.nom
1208 _devise_nom
.short_description
= "Nom de la devise"
1211 class ImplantationProxyAdmin(BaseAdmin
):
1212 list_display
= ('nom', '_organigramme')
1215 def __init__(self
, *args
, **kwargs
):
1216 super(ImplantationProxyAdmin
, self
).__init__(*args
, **kwargs
)
1217 self
.list_display_links
= (None, )
1219 def has_add_permission(self
, obj
):
1222 def has_change_permission(self
, request
, obj
=None):
1223 return in_drh_or_admin(request
.user
)
1225 def _organigramme(self
, obj
):
1226 return '<a href="%s"><strong>Organigramme</strong></a>' % (
1227 reverse('rho_implantation', args
=(obj
.id,))
1229 _organigramme
.allow_tags
= True
1230 _organigramme
.short_description
= "Organigramme"
1233 class RegionProxyAdmin(BaseAdmin
):
1234 list_display
= ('nom', '_organigramme')
1237 def __init__(self
, *args
, **kwargs
):
1238 super(RegionProxyAdmin
, self
).__init__(*args
, **kwargs
)
1239 self
.list_display_links
= (None, )
1241 def has_add_permission(self
, obj
):
1244 def has_change_permission(self
, request
, obj
=None):
1245 return in_drh_or_admin(request
.user
)
1247 def _organigramme(self
, obj
):
1248 return """<a href="%s"><strong>Organigramme</strong></a>""" % (
1249 reverse('rho_region', args
=(obj
.id,))
1251 _organigramme
.allow_tags
= True
1252 _organigramme
.short_description
= "Organigramme"
1255 admin
.site
.register(rh
.Classement
, ClassementAdmin
)
1256 admin
.site
.register(rh
.Devise
, DeviseAdmin
)
1257 admin
.site
.register(rh
.Dossier
, DossierAdmin
)
1258 admin
.site
.register(EmployeProxy
, EmployeProxyAdmin
)
1259 admin
.site
.register(ServiceProxy
, ServiceProxyAdmin
)
1260 admin
.site
.register(rh
.Employe
, EmployeAdmin
)
1261 admin
.site
.register(rh
.CategorieEmploi
, CategorieEmploiAdmin
)
1262 admin
.site
.register(rh
.FamilleProfessionnelle
)
1263 admin
.site
.register(rh
.OrganismeBstg
, OrganismeBstgAdmin
)
1264 admin
.site
.register(rh
.Poste
, PosteAdmin
)
1265 admin
.site
.register(
1266 rh
.ResponsableImplantationProxy
, ResponsableImplantationAdmin
1268 admin
.site
.register(rh
.Service
, ServiceAdmin
)
1269 admin
.site
.register(rh
.Statut
, StatutAdmin
)
1270 admin
.site
.register(rh
.TauxChange
, TauxChangeAdmin
)
1271 admin
.site
.register(rh
.TypeContrat
, TypeContratAdmin
)
1272 admin
.site
.register(rh
.TypePoste
, TypePosteAdmin
)
1273 admin
.site
.register(rh
.TypeRemuneration
, TypeRemunerationAdmin
)
1274 admin
.site
.register(rh
.TypeRevalorisation
, TypeRevalorisationAdmin
)
1275 admin
.site
.register(rh
.ValeurPoint
, ValeurPointAdmin
)
1276 admin
.site
.register(ImplantationProxy
, ImplantationProxyAdmin
)
1277 admin
.site
.register(RegionProxy
, RegionProxyAdmin
)