Création à la volée des évaluations à chaque fois qu'on affiche la liste
[auf_rh_dae.git] / project / recrutement / admin.py
index 1524e16..c2b14aa 100644 (file)
@@ -2,33 +2,32 @@
 
 import textwrap
 
 
 import textwrap
 
+from auf.django.emploi.models import CandidatPiece, Candidat, OffreEmploi
+from auf.django.references.models import Region, Bureau, Implantation
 from django.conf import settings
 from django.contrib import admin
 from django.core.urlresolvers import reverse
 from django.db.models import Avg
 from django.conf import settings
 from django.contrib import admin
 from django.core.urlresolvers import reverse
 from django.db.models import Avg
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+
+from auf.django.export.admin import ExportAdmin
+from auf.django.emploi.models import STATUT_CHOICES
 from django.forms.models import BaseInlineFormSet
 from django.http import HttpResponseRedirect
 from django.shortcuts import redirect
 from reversion.admin import VersionAdmin
 
 from django.forms.models import BaseInlineFormSet
 from django.http import HttpResponseRedirect
 from django.shortcuts import redirect
 from reversion.admin import VersionAdmin
 
-from auf.django.emploi.models import OffreEmploi, Candidat, CandidatPiece
-from auf.django.references.models import Region, Bureau
+from project import groups
+from project.permissions import get_user_groupnames
 
 
-from project.groups import get_employe_from_user as get_emp
 from project.rh import models as rh
 from project.rh import models as rh
-
 from project.recrutement.forms import OffreEmploiForm
 from project.recrutement.forms import OffreEmploiForm
-from project.recrutement.groups import \
-        grp_drh, grp_drh2, \
-        grp_directeurs_bureau, \
-        grp_administrateurs, \
-        grp_correspondants_rh, \
-        grp_haute_direction
 from project.recrutement.models import \
         Evaluateur, CandidatEvaluation, \
         ProxyOffreEmploi, ProxyCandidat, MesCandidatEvaluation, \
 from project.recrutement.models import \
         Evaluateur, CandidatEvaluation, \
         ProxyOffreEmploi, ProxyCandidat, MesCandidatEvaluation, \
-        CourrielTemplate
-        
+        CourrielTemplate, OffreEmploiEvaluateur
+
 
 ### CONSTANTES
 IMPLANTATIONS_CENTRALES = [15, 19]
 
 ### CONSTANTES
 IMPLANTATIONS_CENTRALES = [15, 19]
@@ -57,7 +56,7 @@ class OrderedChangeList(admin.views.main.ChangeList):
         return qs
 
 
         return qs
 
 
-class OffreEmploiAdmin(BaseAdmin, VersionAdmin):
+class OffreEmploiAdminMixin(BaseAdmin):
     date_hierarchy = 'date_creation'
     list_display = (
         'nom', 'date_limite', 'region',  'statut', 'est_affiche',
     date_hierarchy = 'date_creation'
     list_display = (
         'nom', 'date_limite', 'region',  'statut', 'est_affiche',
@@ -67,10 +66,28 @@ class OffreEmploiAdmin(BaseAdmin, VersionAdmin):
     list_filter = ('statut',)
     actions = ['affecter_evaluateurs_offre_emploi', ]
     form = OffreEmploiForm
     list_filter = ('statut',)
     actions = ['affecter_evaluateurs_offre_emploi', ]
     form = OffreEmploiForm
+    fieldsets = (
+        (None, {
+            'fields': (
+                'est_affiche',
+                'statut',
+                'date_limite',
+                'nom',
+                'description',
+                'poste',
+                'region',
+                'lieu_affectation',
+                'bureau',
+                'debut_affectation',
+                'duree_affectation',
+                'renumeration',
+            )
+        }),
+    )
 
     ### Actions à afficher
     def get_actions(self, request):
 
     ### Actions à afficher
     def get_actions(self, request):
-        actions = super(OffreEmploiAdmin, self).get_actions(request)
+        actions = super(OffreEmploiAdminMixin, self).get_actions(request)
         del actions['delete_selected']
         return actions
 
         del actions['delete_selected']
         return actions
 
@@ -89,58 +106,61 @@ class OffreEmploiAdmin(BaseAdmin, VersionAdmin):
     ### Afficher la liste des candidats pour l'offre d'emploi
     def _candidatsList(self, obj):
         return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
     ### Afficher la liste des candidats pour l'offre d'emploi
     def _candidatsList(self, obj):
         return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
-            </a>" % (reverse('admin:recrutement_candidat_changelist'), obj.id)
+            </a>" % (reverse('admin:recrutement_proxycandidat_changelist'), obj.id)
     _candidatsList.allow_tags = True
     _candidatsList.short_description = "Afficher la liste des candidats"
 
     ### Formulaire
     def get_form(self, request, obj=None, **kwargs):
     _candidatsList.allow_tags = True
     _candidatsList.short_description = "Afficher la liste des candidats"
 
     ### Formulaire
     def get_form(self, request, obj=None, **kwargs):
-        form = super(OffreEmploiAdmin, self).get_form(request, obj, **kwargs)
-        employe = get_emp(request.user)
-        user_groupes = request.user.groups.all()
+        form = super(OffreEmploiAdminMixin, self).get_form(request, obj, **kwargs)
+        employe = groups.get_employe_from_user(request.user)
+        user_groupes = get_user_groupnames(request.user)
 
         # Region
 
         # Region
-        if 'region' in form.declared_fields:
+        region_field = None
+        if 'region' in form.declared_fields.keys():
             region_field = form.declared_fields['region']
             region_field = form.declared_fields['region']
-        else:
+        if 'region' in form.base_fields.keys():
             region_field = form.base_fields['region']
             region_field = form.base_fields['region']
-
-        if grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_haute_direction in user_groupes:
-            region_field.queryset = Region.objects.all()
-        else:
-            region_field.queryset = Region.objects.\
+        if region_field:
+            if groups.DRH_NIVEAU_1 in user_groupes or \
+               groups.DRH_NIVEAU_2 in user_groupes or \
+               groups.HAUTE_DIRECTION in user_groupes:
+                region_field.queryset = Region.objects.all()
+            else:
+                region_field.queryset = Region.objects.\
                                     filter(id=employe.implantation.region.id)
 
         # Poste
                                     filter(id=employe.implantation.region.id)
 
         # Poste
-        if 'poste' in form.declared_fields:
+        poste_field = None
+        if 'poste' in form.declared_fields.keys():
             poste_field = form.declared_fields['poste']
             poste_field = form.declared_fields['poste']
-        else:
+        if 'poste' in form.base_fields.keys():
             poste_field = form.base_fields['poste']
             poste_field = form.base_fields['poste']
-
-        if grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_haute_direction in user_groupes:
-            poste_field.queryset = rh.Poste.objects.all()
-        else:
-            poste_field.queryset = rh.Poste.objects.\
-                    filter(implantation__region=employe.implantation.region).\
-                    exclude(implantation__in=IMPLANTATIONS_CENTRALES)
+        if poste_field:
+            if groups.DRH_NIVEAU_1 in user_groupes or \
+               groups.DRH_NIVEAU_2 in user_groupes or \
+               groups.HAUTE_DIRECTION in user_groupes:
+                poste_field.queryset = rh.Poste.objects.all()
+            else:
+                poste_field.queryset = rh.Poste.objects.\
+                        filter(implantation__region=employe.implantation.region).\
+                        exclude(implantation__in=IMPLANTATIONS_CENTRALES)
 
         # Bureau
 
         # Bureau
-        if 'bureau' in form.declared_fields:
+        bureau_field = None
+        if 'bureau' in form.declared_fields.keys():
             bureau_field = form.declared_fields['bureau']
             bureau_field = form.declared_fields['bureau']
-        else:
+        if 'bureau' in form.base_fields.keys():
             bureau_field = form.base_fields['bureau']
             bureau_field = form.base_fields['bureau']
-
-        if grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_haute_direction in user_groupes:
-            bureau_field.queryset = Bureau.objects.all()
-        else:
-            bureau_field.queryset = \
-                    Bureau.objects.filter(region=employe.implantation.region)
+        if bureau_field:
+            if groups.DRH_NIVEAU_1 in user_groupes or \
+                groups.DRH_NIVEAU_2 in user_groupes or \
+                groups.HAUTE_DIRECTION in user_groupes:
+                bureau_field.queryset = Bureau.objects.all()
+            else:
+                bureau_field.queryset = \
+                        Bureau.objects.filter(region=employe.implantation.region)
 
         return form
 
 
         return form
 
@@ -149,16 +169,16 @@ class OffreEmploiAdmin(BaseAdmin, VersionAdmin):
     def queryset(self, request):
         qs = self.model._default_manager.get_query_set() \
                 .select_related('offre_emploi')
     def queryset(self, request):
         qs = self.model._default_manager.get_query_set() \
                 .select_related('offre_emploi')
-        user_groupes = request.user.groups.all()
-        if grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_haute_direction in user_groupes:
+        user_groupes = get_user_groupnames(request.user)
+        if groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             return qs
 
             return qs
 
-        if grp_directeurs_bureau in user_groupes or \
-            grp_correspondants_rh in user_groupes or \
-            grp_administrateurs in user_groupes:
-            employe = get_emp(request.user)
+        if groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+            groups.CORRESPONDANT_RH in user_groupes or \
+            groups.ADMINISTRATEURS in user_groupes:
+            employe = groups.get_employe_from_user(request.user)
             return qs.filter(region=employe.implantation.region)
 
         if  Evaluateur.objects.filter(user=request.user).exists():
             return qs.filter(region=employe.implantation.region)
 
         if  Evaluateur.objects.filter(user=request.user).exists():
@@ -175,40 +195,72 @@ class OffreEmploiAdmin(BaseAdmin, VersionAdmin):
 
     ### Permission add, delete, change
     def has_add_permission(self, request):
 
     ### Permission add, delete, change
     def has_add_permission(self, request):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
+            groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+            groups.ADMINISTRATEURS in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             return True
         return False
 
     def has_delete_permission(self, request, obj=None):
             return True
         return False
 
     def has_delete_permission(self, request, obj=None):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
+            groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             return True
             return True
+
+        if obj is not None:
+            employe = groups.get_employe_from_user(request.user)
+            if (groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+                groups.ADMINISTRATEURS in user_groupes) and ( 
+                employe.implantation.region == obj.lieu_affectation.region):
+                return True
+
         return False
 
     def has_change_permission(self, request, obj=None):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
+            groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             return True
             return True
+
+        if obj is not None:
+            employe = groups.get_employe_from_user(request.user)
+            if (groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+                groups.ADMINISTRATEURS in user_groupes) and ( 
+                employe.implantation.region == obj.lieu_affectation.region):
+                return True
+        else:
+            if  groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+                    groups.ADMINISTRATEURS in user_groupes:
+                return True
+
+
         return False
 
         return False
 
+    def formfield_for_foreignkey(self, db_field, request, **kwargs):
+        if db_field.name == 'lieu_affectation':
+            user_groupes = [g.name for g in request.user.groups.all()]
+            if not (request.user.is_superuser is True or \
+                groups.DRH_NIVEAU_1 in user_groupes or \
+                groups.DRH_NIVEAU_2 in user_groupes):
+                employe = groups.get_employe_from_user(request.user)
+                kwargs["queryset"] = Implantation.objects.filter(region=employe.implantation.region)
+            return db_field.formfield(**kwargs)
+        return super(OffreEmploiAdminMixin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+
+
+class OffreEmploiAdmin(VersionAdmin, OffreEmploiAdminMixin):
+    pass
+
 
 
-class ProxyOffreEmploiAdmin(OffreEmploiAdmin):
+class ProxyOffreEmploiAdmin(OffreEmploiAdminMixin):
     list_display = (
         'nom', 'date_limite', 'region', 'statut', 'est_affiche'
     )
     list_display = (
         'nom', 'date_limite', 'region', 'statut', 'est_affiche'
     )
@@ -239,11 +291,6 @@ class ProxyOffreEmploiAdmin(OffreEmploiAdmin):
     def response_change(self, request, obj):
         return redirect('admin:recrutement_proxyoffreemploi_changelist')
 
     def response_change(self, request, obj):
         return redirect('admin:recrutement_proxyoffreemploi_changelist')
 
-    ### Formulaire
-    def get_form(self, request, obj=None, **kwargs):
-        form = super(OffreEmploiAdmin, self).get_form(request, obj, **kwargs)
-        return form
-
     ### Permissions add, delete, change
     def has_add_permission(self, request):
         return False
     ### Permissions add, delete, change
     def has_add_permission(self, request):
         return False
@@ -252,20 +299,10 @@ class ProxyOffreEmploiAdmin(OffreEmploiAdmin):
         return False
 
     def has_change_permission(self, request, obj=None):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groupes = request.user.groups.all()
-        if request.user.is_superuser is True or \
-            grp_correspondants_rh in user_groupes or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
-            return True
-
         if obj is not None:
             return True
 
         if obj is not None:
             return True
 
-        return False
+        return not super(ProxyOffreEmploiAdmin, self).has_change_permission(request, obj)
 
 
 class CandidatPieceInline(admin.TabularInline):
 
 
 class CandidatPieceInline(admin.TabularInline):
@@ -306,14 +343,14 @@ class CandidatEvaluationInline(admin.TabularInline):
         return self.readonly_fields
 
 
         return self.readonly_fields
 
 
-class CandidatAdmin(BaseAdmin, VersionAdmin):
+class CandidatAdminMixin(BaseAdmin, ExportAdmin):
     search_fields = ('nom', 'prenom')
     exclude = ('actif', )
     list_editable = ('statut', )
     list_display = ('_candidat', 'offre_emploi',
                     'voir_offre_emploi', 'calculer_moyenne',
                     'afficher_candidat', '_date_creation', 'statut', )
     search_fields = ('nom', 'prenom')
     exclude = ('actif', )
     list_editable = ('statut', )
     list_display = ('_candidat', 'offre_emploi',
                     'voir_offre_emploi', 'calculer_moyenne',
                     'afficher_candidat', '_date_creation', 'statut', )
-    list_filter = ('offre_emploi', 'offre_emploi__region', 'statut', )
+    list_filter = ('offre_emploi__nom', 'offre_emploi__region', 'statut', )
 
     fieldsets = (
         ("Offre d'emploi", {
 
     fieldsets = (
         ("Offre d'emploi", {
@@ -321,7 +358,7 @@ class CandidatAdmin(BaseAdmin, VersionAdmin):
         }),
         ('Informations personnelles', {
             'fields': (
         }),
         ('Informations personnelles', {
             'fields': (
-                'prenom', 'nom', 'genre', 'nationalite',
+                'nom', 'prenom', 'genre', 'nationalite',
                 'situation_famille', 'nombre_dependant'
             )
         }),
                 'situation_famille', 'nombre_dependant'
             )
         }),
@@ -345,7 +382,13 @@ class CandidatAdmin(BaseAdmin, VersionAdmin):
         CandidatPieceInline,
         CandidatEvaluationInline,
     ]
         CandidatPieceInline,
         CandidatEvaluationInline,
     ]
-    actions = ['envoyer_courriel_candidats']
+    actions = ['envoyer_courriel_candidats', 'changer_statut']
+
+    export_fields = ['statut', 'offre_emploi', 'prenom', 'nom', 'genre',
+                     'nationalite', 'situation_famille', 'nombre_dependant',
+                     'niveau_diplome', 'employeur_actuel', 'poste_actuel',
+                     'domaine_professionnel', 'telephone', 'email', 'adresse',
+                     'ville', 'etat_province', 'code_postal', 'pays']
 
     def _candidat(self, obj):
         txt = u"%s %s (%s)" % (obj.nom.upper(), obj.prenom, obj.genre)
 
     def _candidat(self, obj):
         txt = u"%s %s (%s)" % (obj.nom.upper(), obj.prenom, obj.genre)
@@ -362,7 +405,7 @@ class CandidatAdmin(BaseAdmin, VersionAdmin):
 
     ### Actions à afficher
     def get_actions(self, request):
 
     ### Actions à afficher
     def get_actions(self, request):
-        actions = super(CandidatAdmin, self).get_actions(request)
+        actions = super(CandidatAdminMixin, self).get_actions(request)
         del actions['delete_selected']
         return actions
 
         del actions['delete_selected']
         return actions
 
@@ -375,6 +418,23 @@ class CandidatAdmin(BaseAdmin, VersionAdmin):
         )
     envoyer_courriel_candidats.short_description = u'Envoyer courriel'
 
         )
     envoyer_courriel_candidats.short_description = u'Envoyer courriel'
 
+    ### Changer le statut à des candidats
+    def changer_statut(modeladmin, request, queryset):
+        if request.POST.get('post'):
+            queryset.update(statut=request.POST.get('statut'))
+            return None
+
+        context = {
+            'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
+            'queryset': queryset,
+            'status': STATUT_CHOICES,
+        }
+
+        return render_to_response("recrutement/selectionner_statut.html",
+                context, context_instance = RequestContext(request))
+
+    changer_statut.short_description = u'Changer statut'
+
     ### Évaluer un candidat
     def evaluer_candidat(self, obj):
         return "<a href='%s?candidat__id__exact=%s'>" \
     ### Évaluer un candidat
     def evaluer_candidat(self, obj):
         return "<a href='%s?candidat__id__exact=%s'>" \
@@ -390,7 +450,7 @@ class CandidatAdmin(BaseAdmin, VersionAdmin):
         items = [u"<li><a href='%s%s'>%s</li>" % \
                 (settings.OE_PRIVE_MEDIA_URL, pj.path, pj.get_nom_display()) \
                 for pj in obj.pieces_jointes()]
         items = [u"<li><a href='%s%s'>%s</li>" % \
                 (settings.OE_PRIVE_MEDIA_URL, pj.path, pj.get_nom_display()) \
                 for pj in obj.pieces_jointes()]
-        html = "<a href='%s'>Voir le candidat</a>" % (
+        html = "<a href='%s'>Candidature</a>" % (
             reverse('admin:recrutement_proxycandidat_change', args=(obj.id,))
         )
         return "%s<ul>%s</ul>" % (html, "\n".join(items))
             reverse('admin:recrutement_proxycandidat_change', args=(obj.id,))
         )
         return "%s<ul>%s</ul>" % (html, "\n".join(items))
@@ -440,41 +500,56 @@ class CandidatAdmin(BaseAdmin, VersionAdmin):
 
     ### Permissions add, delete, change
     def has_add_permission(self, request):
 
     ### Permissions add, delete, change
     def has_add_permission(self, request):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-            grp_correspondants_rh in user_groupes or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
+            groups.CORRESPONDANT_RH in user_groupes or \
+            groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+            groups.ADMINISTRATEURS in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             return True
         return False
 
     def has_delete_permission(self, request, obj=None):
             return True
         return False
 
     def has_delete_permission(self, request, obj=None):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-            grp_correspondants_rh in user_groupes or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
+            groups.CORRESPONDANT_RH in user_groupes or \
+            groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+            groups.ADMINISTRATEURS in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             return True
         return False
 
     def has_change_permission(self, request, obj=None):
             return True
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-            grp_correspondants_rh in user_groupes or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
+            groups.CORRESPONDANT_RH in user_groupes or \
+            groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+            groups.ADMINISTRATEURS in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             return True
         return False
 
             return True
         return False
 
+    def formfield_for_foreignkey(self, db_field, request, **kwargs):
+        if db_field.name == 'offre_emploi':
+            employe = groups.get_employe_from_user(request.user)
+            user_groupes = [g.name for g in request.user.groups.all()]
+            if request.user.is_superuser is True or \
+                groups.CORRESPONDANT_RH in user_groupes or \
+                groups.DRH_NIVEAU_1 in user_groupes or \
+                groups.DRH_NIVEAU_2 in user_groupes:
+                qs_offres = OffreEmploi.objects.all()
+            else:
+                qs_offres =OffreEmploi.objects.filter(region=employe.implantation.region)
+            kwargs["queryset"] = qs_offres
+            return db_field.formfield(**kwargs)
+        return super(CandidatAdminMixin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+
     def get_changelist(self, request, **kwargs):
         return OrderedChangeList
 
     def get_changelist(self, request, **kwargs):
         return OrderedChangeList
 
@@ -490,16 +565,16 @@ class CandidatAdmin(BaseAdmin, VersionAdmin):
                 .select_related('offre_emploi') \
                 .annotate(moyenne=Avg('evaluations__note'))
 
                 .select_related('offre_emploi') \
                 .annotate(moyenne=Avg('evaluations__note'))
 
-        user_groupes = request.user.groups.all()
-        if grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_haute_direction in user_groupes:
+        user_groupes = get_user_groupnames(request.user)
+        if groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             return qs
 
             return qs
 
-        if grp_directeurs_bureau in user_groupes or \
-            grp_correspondants_rh in user_groupes or \
-            grp_administrateurs in user_groupes:
-            employe = get_emp(request.user)
+        if groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+            groups.CORRESPONDANT_RH in user_groupes or \
+            groups.ADMINISTRATEURS in user_groupes:
+            employe = groups.get_employe_from_user(request.user)
             return qs.filter(offre_emploi__region=employe.implantation.region)
 
         if  Evaluateur.objects.filter(user=request.user).exists():
             return qs.filter(offre_emploi__region=employe.implantation.region)
 
         if  Evaluateur.objects.filter(user=request.user).exists():
@@ -510,7 +585,13 @@ class CandidatAdmin(BaseAdmin, VersionAdmin):
         return qs.none()
 
 
         return qs.none()
 
 
-class ProxyCandidatAdmin(CandidatAdmin):
+class CandidatAdmin(VersionAdmin, CandidatAdminMixin):
+    change_list_template = 'admin/recrutement/candidat/change_list.html'
+    pass
+
+
+class ProxyCandidatAdmin(CandidatAdminMixin):
+    change_list_template = 'admin/recrutement/candidat/change_list.html'
     list_editable = ()
     readonly_fields = (
         'statut', 'offre_emploi', 'prenom', 'nom', 'genre', 'nationalite',
     list_editable = ()
     readonly_fields = (
         'statut', 'offre_emploi', 'prenom', 'nom', 'genre', 'nationalite',
@@ -551,23 +632,17 @@ class ProxyCandidatAdmin(CandidatAdmin):
         return False
 
     def has_change_permission(self, request, obj=None):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groupes = request.user.groups.all()
-        if request.user.is_superuser is True or \
-            grp_correspondants_rh in user_groupes or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
-            return True
-
         if obj is not None:
         if obj is not None:
-            evaluateur = Evaluateur.objects.get(user=request.user)
-            for e in obj.evaluations.all():
-                if e.evaluateur == evaluateur:
-                    return True
-
-        return False
+            return obj in self.queryset(request)
+            #try:
+            #    evaluateur = Evaluateur.objects.get(user=request.user)
+            #    for e in obj.evaluations.all():
+            #        if e.evaluateur == evaluateur:
+            #            return True
+            #    return False
+            #except:
+            #    pass
+        return super(ProxyCandidatAdmin, self).has_change_permission(request, obj)
 
     def get_actions(self, request):
         return None
 
     def get_actions(self, request):
         return None
@@ -605,29 +680,29 @@ class EvaluateurAdmin(BaseAdmin, VersionAdmin):
 
     ### Permissions add, delete, change
     def has_add_permission(self, request):
 
     ### Permissions add, delete, change
     def has_add_permission(self, request):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-                grp_drh in user_groupes or \
-                grp_drh2 in user_groupes or \
-                grp_haute_direction in user_groupes:
+                groups.DRH_NIVEAU_1 in user_groupes or \
+                groups.DRH_NIVEAU_2 in user_groupes or \
+                groups.HAUTE_DIRECTION in user_groupes:
             return True
         return False
 
     def has_delete_permission(self, request, obj=None):
             return True
         return False
 
     def has_delete_permission(self, request, obj=None):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-                grp_drh in user_groupes or \
-                grp_drh2 in user_groupes or \
-                grp_haute_direction in user_groupes:
+                groups.DRH_NIVEAU_1 in user_groupes or \
+                groups.DRH_NIVEAU_2 in user_groupes or \
+                groups.HAUTE_DIRECTION in user_groupes:
             return True
         return False
 
     def has_change_permission(self, request, obj=None):
             return True
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
         if request.user.is_superuser is True or \
-                grp_drh in user_groupes or \
-                grp_drh2 in user_groupes or \
-                grp_haute_direction in user_groupes:
+                groups.DRH_NIVEAU_1 in user_groupes or \
+                groups.DRH_NIVEAU_2 in user_groupes or \
+                groups.HAUTE_DIRECTION in user_groupes:
             return True
         return False
 
             return True
         return False
 
@@ -728,15 +803,15 @@ class CandidatEvaluationAdmin(BaseAdmin):
         mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
         le request.user
         """
         mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
         le request.user
         """
-        user_groupes = request.user.groups.all()
+        user_groupes = get_user_groupnames(request.user)
 
         if request.user.is_superuser or \
 
         if request.user.is_superuser or \
-            grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_correspondants_rh in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
+            groups.CORRESPONDANT_RH in user_groupes or \
+            groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+            groups.ADMINISTRATEURS in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
             is_recrutement = True
         else:
             is_recrutement = False
             is_recrutement = True
         else:
             is_recrutement = False
@@ -750,15 +825,16 @@ class CandidatEvaluationAdmin(BaseAdmin):
         """
         qs = self.model._default_manager.get_query_set() \
                 .select_related('offre_emploi')
         """
         qs = self.model._default_manager.get_query_set() \
                 .select_related('offre_emploi')
-        user_groupes = request.user.groups.all()
-
-        if grp_drh in user_groupes or \
-            grp_drh2 in user_groupes or \
-            grp_correspondants_rh in user_groupes or \
-            grp_directeurs_bureau in user_groupes or \
-            grp_administrateurs in user_groupes or \
-            grp_haute_direction in user_groupes:
-            return qs
+        user_groupes = get_user_groupnames(request.user)
+
+        if request.user.is_superuser or \
+            groups.CORRESPONDANT_RH in user_groupes or \
+            groups.DRH_NIVEAU_1 in user_groupes or \
+            groups.DRH_NIVEAU_2 in user_groupes or \
+            groups.DIRECTEUR_DE_BUREAU in user_groupes or \
+            groups.ADMINISTRATEURS in user_groupes or \
+            groups.HAUTE_DIRECTION in user_groupes:
+            return qs.filter(candidat__statut__in=('REC', 'SEL'))
 
         evaluateur = Evaluateur.objects.get(user=request.user)
         candidats_evaluations = \
 
         evaluateur = Evaluateur.objects.get(user=request.user)
         candidats_evaluations = \
@@ -769,6 +845,7 @@ class CandidatEvaluationAdmin(BaseAdmin):
 
 
 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin):
 
 
 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin):
+    list_filter = []
 
     def has_change_permission(self, request, obj=None):
         try:
 
     def has_change_permission(self, request, obj=None):
         try:
@@ -787,13 +864,27 @@ class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin):
 
     def queryset(self, request):
         qs = self.model._default_manager.get_query_set() \
 
     def queryset(self, request):
         qs = self.model._default_manager.get_query_set() \
-                .select_related('offre_emploi')
+            .select_related('offre_emploi')
         evaluateur = Evaluateur.objects.get(user=request.user)
         evaluateur = Evaluateur.objects.get(user=request.user)
-        candidats_evaluations = \
-            CandidatEvaluation.objects.filter(evaluateur=evaluateur,
-                    candidat__statut__in=('REC', ))
-        candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
-        return qs.filter(id__in=candidats_evaluations_ids)
+
+        # XXX: Pas l'idéal, mais on doit créer les objets CandidatEvaluation
+        # ici pour garder la liste à jour. Idéalement, il vaudrait peut-être
+        # mieux utiliser directement les objets Candidat.
+        for candidat in Candidat.objects .filter(
+            offre_emploi__offreemploievaluateur__evaluateur=evaluateur,
+        ).exclude(evaluations__evaluateur=evaluateur):
+            print candidat, candidat.offre_emploi
+            CandidatEvaluation.objects.get_or_create(
+                candidat=candidat, evaluateur=evaluateur
+            )
+
+        return qs.filter(
+            evaluateur=evaluateur, candidat__statut__in=('NOUV', 'REC')
+        )
+
+
+class OffreEmploiEvaluateurAdmin(BaseAdmin):
+    pass
 
 
 class CourrielTemplateAdmin(BaseAdmin, VersionAdmin):
 
 
 class CourrielTemplateAdmin(BaseAdmin, VersionAdmin):
@@ -811,3 +902,4 @@ admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
 admin.site.register(MesCandidatEvaluation, MesCandidatEvaluationAdmin)
 admin.site.register(Evaluateur, EvaluateurAdmin)
 admin.site.register(CourrielTemplate, CourrielTemplateAdmin)
 admin.site.register(MesCandidatEvaluation, MesCandidatEvaluationAdmin)
 admin.site.register(Evaluateur, EvaluateurAdmin)
 admin.site.register(CourrielTemplate, CourrielTemplateAdmin)
+admin.site.register(OffreEmploiEvaluateur, OffreEmploiEvaluateurAdmin)