Ajout de try except lors d'un get pour un Evaluateur/Administrateur régional
[auf_rh_dae.git] / project / recrutement / admin.py
CommitLineData
df59fcab 1# -*- encoding: utf-8 -*-
2
6067184b 3from django.core.urlresolvers import reverse
4from django.http import HttpResponseRedirect
df59fcab 5from django.contrib import admin
38df74bb 6from django.shortcuts import get_object_or_404
7
6067184b 8from reversion.admin import VersionAdmin
38df74bb 9from datamaster_modeles.models import Employe, Implantation, Region
6067184b 10
df59fcab 11from recrutement.models import *
f6724c20
NBV
12from recrutement.workflow import grp_administrateurs_recrutement,\
13 grp_evaluateurs_recrutement, grp_drh_recrutement
df59fcab 14
d2b30f5f 15class OffreEmploiAdmin(VersionAdmin):
7f9e891e 16 date_hierarchy = 'date_creation'
ec517164 17 list_display = ('nom', 'resume', 'date_limite', 'region', '_candidatsList')
f6724c20 18
8941aee7 19 # Afficher la liste des candidats pour l'offre d'emploi
596fe324 20 def _candidatsList(self, obj):
8ea41642 21 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
22 </a>" % (reverse('admin:recrutement_candidat_changelist'), obj.id)
2f78949d 23 _candidatsList.allow_tags = True
f6724c20 24 _candidatsList.short_description = "Afficher la liste des candidats"
362a3534 25
2f78949d 26 def queryset(self, request):
beef7690 27 query = self.model._default_manager.get_query_set()
f6724c20
NBV
28 # Si user est superuser afficher toutes les offres d'emploi
29 user_groupes = request.user.groups.all()
30 if not grp_drh_recrutement in user_groupes:
beef7690
NBV
31 """
32 Filtrer les offre d'emploi pour afficher seulement les offres
33 d'emploi actives
34 """
35 qs = query.filter(date_limite__gte=datetime.date.today())
36 """
37 Si le user n'est ni un évaluateur ni un administrateur régional,
38 retourner none
39 Vérifier groupes
40 """
f6724c20 41 if grp_evaluateurs_recrutement in user_groupes:
ca73c3c6
NBV
42 try:
43 user = Evaluateur.objects.get(user=request.user)
44 except Evaluateur.DoesNotExist:
45 return qs.none()
f6724c20 46 elif grp_administrateurs_recrutement in user_groupes:
ca73c3c6
NBV
47 try:
48 user = AdministrateurRegional.objects.get(user=request.user)
49 except AdministrateurRegional.DoesNotExist:
50 return qs.none()
f6724c20
NBV
51 else:
52 return qs.none()
53
54 if type(user) is AdministrateurRegional:
55 region_ids = [g.id for g in user.regions.all()]
56 return qs.select_related('offre_emploi').\
57 filter(region__in=region_ids)
beef7690 58 if type(user) is Evaluateur:
f6724c20 59 candidats = [g for g in user.candidats.all()]
beef7690 60 offre_emploi_ids = [c.offre_emploi.id for c in candidats]
f6724c20 61 return qs.select_related('offre_emploi').\
beef7690 62 filter(id__in=offre_emploi_ids)
3bcef02d 63 return qs.none()
beef7690 64 return query.select_related('offre_emploi')
f6724c20
NBV
65
66 def has_change_permission(self, request, obj=None):
67 user_groupes = request.user.groups.all()
68 if grp_drh_recrutement in user_groupes or \
69 grp_administrateurs_recrutement in user_groupes:
70 return True
71 return False
72
73class ProxyOffreEmploiAdmin(OffreEmploiAdmin):
beef7690 74 list_display = ('nom', 'resume', 'date_limite', 'region', )
f6724c20
NBV
75 readonly_fields = ('actif', 'description', 'poste', 'bureau',
76 'duree_affectation', 'renumeration',
77 'debut_affectation', 'lieu_affectation', 'nom',
78 'resume', 'date_limite', 'region')
79 fieldsets = (
720c3ad5 80 ('Nom', {
f6724c20
NBV
81 'fields': ('nom', )
82 }),
720c3ad5 83 ('Description générale', {
f6724c20
NBV
84 'fields': ('poste', 'resume','description', 'date_limite', )
85 }),
720c3ad5 86 ('Coordonnées', {
f6724c20
NBV
87 'fields': ('lieu_affectation', 'bureau', 'region', )
88 }),
720c3ad5 89 ('Autre', {
f6724c20
NBV
90 'fields': ('debut_affectation', 'duree_affectation',
91 'renumeration', )
92 }),
93 )
94 def has_add_permission(self, request):
95 return False
96
97 def has_delete_permission(self, request, obj=None):
98 return False
99
2d083449
NBV
100 def has_change_permission(self, request, obj=None):
101 user_groupes = request.user.groups.all()
beef7690
NBV
102 if grp_evaluateurs_recrutement in user_groupes or \
103 grp_drh_recrutement in user_groupes:
2d083449
NBV
104 return True
105 return False
106
cced6a23 107class ProxyCandidatPiece(CandidatPiece):
108 """
109 Ce proxy sert uniquement dans l'admin à disposer d'un libellé
110 plus ergonomique.
111 """
112 class Meta:
113 proxy = True
114 verbose_name = "pièce jointe"
74cbc7a7 115 verbose_name_plural = "pièces jointes"
cced6a23 116
170c9aa2 117class CandidatPieceInline(admin.TabularInline):
cced6a23 118 model = ProxyCandidatPiece
119 fields = ('candidat', 'nom', 'path', )
170c9aa2 120 extra = 1
121
27c81d11 122class ProxyEvaluateur(Evaluateur.candidats.through):
cced6a23 123 """
124 Ce proxy sert uniquement dans l'admin à disposer d'un libellé
125 plus ergonomique.
126 """
127 class Meta:
128 proxy = True
129 verbose_name = "évaluateur"
130
eb579d40 131class EvaluateurInline(admin.TabularInline):
cced6a23 132 model = ProxyEvaluateur
720c3ad5 133 fields = ('evaluateur',)
eb579d40 134 extra = 1
135
d2b30f5f 136class CandidatAdmin(VersionAdmin):
7f9e891e 137 date_hierarchy = 'date_creation'
0fd8a26d 138 list_display = ('nom', 'prenom', 'offre_emploi','statut',
720c3ad5 139 'voir_offre_emploi', #'note_evaluateur',
8941aee7 140 'calculer_moyenne', 'afficher_candidat',)
8ea41642 141 list_filter = ('offre_emploi', )
7f9e891e 142 fieldsets = (
4896b661 143 ("Offre d'emploi", {
144 'fields': ('offre_emploi', )
145 }),
7f9e891e 146 ('Informations personnelles', {
147 'fields': ('prenom','nom','genre', 'nationalite', 'date_naissance',
148 'situation_famille', 'nombre_dependant',)
149 }),
ec517164 150 ('Coordonnées', {
151 'fields': ('telephone', 'email', 'adresse', 'ville',
152 'etat_province', 'code_postal', 'pays', )
7f9e891e 153 }),
154 ('Informations professionnelles', {
4896b661 155 'fields': ('niveau_diplome','employeur_actuel',
8ea41642 156 'poste_actuel', 'domaine_professionnel',)
7f9e891e 157 }),
158 ('Options avancées', {
159 'classes': ('collapse',),
160 'fields': ('actif', 'statut', )
161 }),
162 )
170c9aa2 163 inlines = [
164 CandidatPieceInline,
eb579d40 165 EvaluateurInline,
170c9aa2 166 ]
f9983b5a 167
4e8340cf 168 actions = ['affecter_candidats_evaluateur', 'envoyer_courriel_candidats']
362a3534 169 # Affecter un évaluateurs à des candidats
7061f835 170 def affecter_candidats_evaluateur(modeladmin, obj, candidats):
596fe324 171 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
2adf9e0c 172
8ea41642 173 return HttpResponseRedirect(reverse('affecter_evaluateurs_candidats')+
174 "?ids=%s" % (",".join(selected)))
d835c9f3 175 affecter_candidats_evaluateur.short_description = u'Affecter évaluateur'
362a3534 176
4e8340cf 177 # Envoyer un courriel à des candidats
52765380 178 def envoyer_courriel_candidats(modeladmin, obj, candidats):
179 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
180
181 return HttpResponseRedirect(reverse('envoyer_courriel_candidats')+
182 "?ids=%s" % (",".join(selected)))
183 envoyer_courriel_candidats.short_description = u'Envoyer courriel'
184
05503d56 185 # Évaluer un candidat
beef7690
NBV
186 # TODO: Revérifier, si c'est mieux de rediriger vers Évaluation candidat et ensuite
187 # permettre l'évaluation ou laisser le reverse(evaluer_candidat)
596fe324 188 def evaluer_candidat(self, obj):
beef7690
NBV
189 return "<a href='%s?candidat__id__exact=%s'>Évaluer le candidat </a>" % \
190 (reverse('admin:recrutement_candidatevaluation_changelist'),
191 obj.id)
596fe324 192 evaluer_candidat.allow_tags = True
beef7690 193 evaluer_candidat.short_description = 'Évaluation'
596fe324 194
7d82fd33 195 # Afficher un candidat
196 def afficher_candidat(self, obj):
beef7690 197 return "<a href='%s'>Voir le candidat</a>" % (reverse('admin:recrutement_proxycandidat_change', args=(obj.id,)))
7d82fd33 198 afficher_candidat.allow_tags = True
f6724c20 199 afficher_candidat.short_description = u'Afficher les détails du candidat'
7d82fd33 200
8941aee7 201 # Voir l'offre d'emploi
202 def voir_offre_emploi(self, obj):
720c3ad5
NBV
203 return "<a href='%s'>Voir l'offre d'emploi</a>" % \
204 (reverse('admin:recrutement_proxyoffreemploi_change',
205 args=(obj.offre_emploi.id,)))
8941aee7 206 voir_offre_emploi.allow_tags = True
207 voir_offre_emploi.short_description = "Afficher l'offre d'emploi"
208
8941aee7 209 # Calculer la moyenne des notes
210 def calculer_moyenne(self, obj):
211 evaluations = CandidatEvaluation.objects.filter(candidat=obj)
212 offre_emploi = obj.offre_emploi
213
f6724c20
NBV
214 notes = [evaluation.note for evaluation in evaluations.all() \
215 if evaluation.note is not None]
8941aee7 216
217 if len(notes) > 0 and offre_emploi.date_limite <= datetime.date.today():
218 moyenne_votes = float(sum(notes)) / len(notes)
219 else:
220 moyenne_votes = "Non disponible"
221 return moyenne_votes
222 calculer_moyenne.allow_tags = True
223 calculer_moyenne.short_description = "Moyenne des notes"
224
f6724c20
NBV
225 def add_delete_permission(self, request, obj=None) :
226 user_groupes = request.user.groups.all()
227 if grp_drh_recrutement in user_groupes or \
228 grp_administrateurs_recrutement in user_groupes:
229 return True
230 return False
4896b661 231
f6724c20
NBV
232 def has_add_permission(self, request):
233 return self.add_delete_permission(request, request)
4896b661 234
f6724c20
NBV
235 def has_delete_permission(self, request, obj=None):
236 return self.add_delete_permission(request, request)
237
238 def has_change_permission(self, request, obj=None):
239 user_groupes = request.user.groups.all()
240 if grp_drh_recrutement in user_groupes or \
2d083449 241 grp_administrateurs_recrutement in user_groupes:
f6724c20
NBV
242 return True
243 return False
4896b661 244
596fe324 245 def queryset(self, obj):
f9983b5a 246 """
8ea41642 247 Spécifie un queryset limité, autrement Django exécute un
248 select_related() sans paramètre, ce qui a pour effet de charger tous
249 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
250 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
251 génération d'une requête infinie.
d835c9f3 252
f9983b5a 253 """
f6724c20
NBV
254 qs = self.model._default_manager.get_query_set()
255 # Si user est superuser afficher tous les candidats
256 user_groupes = obj.user.groups.all()
257 if not grp_drh_recrutement in user_groupes:
258 # Si le user n'est ni un évaluateur ni un administrateur régional,
259 # retourner none
260
261 # Vérifier groupes
262 if grp_evaluateurs_recrutement in user_groupes:
ca73c3c6
NBV
263 try:
264 user = Evaluateur.objects.get(user=obj.user)
265 except Evaluateur.DoesNotExist:
266 return qs.none()
267 """elif grp_administrateurs_recrutement in user_groupes:
268 try:
269 user = AdministrateurRegional.objects.get(user=obj.user)
270 except AdministrateurRegional.DoesNotExist:
271 return qs.none()
272 """
f6724c20
NBV
273 else:
274 return qs.none()
f6724c20
NBV
275 ids = [c.id for c in user.candidats.all()]
276 return qs.select_related('candidats').filter(id__in=ids)
277 return qs.select_related('candidats')
278
279class ProxyCandidatAdmin(CandidatAdmin):
f6724c20
NBV
280 readonly_fields = ('statut', 'offre_emploi', 'prenom', 'nom',
281 'genre', 'nationalite', 'date_naissance',
282 'situation_famille', 'nombre_dependant', 'telephone',
283 'email', 'adresse', 'ville', 'etat_province',
284 'code_postal', 'pays', 'niveau_diplome',
285 'employeur_actuel', 'poste_actuel',
286 'domaine_professionnel',)
2d083449
NBV
287 fieldsets = (
288 ("Offre d'emploi", {
289 'fields': ('offre_emploi', )
290 }),
291 ('Informations personnelles', {
292 'fields': ('prenom','nom','genre', 'nationalite', 'date_naissance',
293 'situation_famille', 'nombre_dependant',)
294 }),
295 ('Coordonnées', {
296 'fields': ('telephone', 'email', 'adresse', 'ville',
297 'etat_province', 'code_postal', 'pays', )
298 }),
299 ('Informations professionnelles', {
300 'fields': ('niveau_diplome','employeur_actuel',
301 'poste_actuel', 'domaine_professionnel',)
302 }),
303 )
f6724c20 304 inlines = []
2d083449 305
f6724c20
NBV
306 def has_add_permission(self, request):
307 return False
308
309 def has_delete_permission(self, request, obj=None):
310 return False
2adf9e0c 311
2d083449
NBV
312 def has_change_permission(self, request, obj=None):
313 user_groupes = request.user.groups.all()
beef7690
NBV
314 if grp_drh_recrutement in user_groupes or \
315 grp_administrateurs_recrutement in user_groupes or \
316 grp_evaluateurs_recrutement in user_groupes:
2d083449
NBV
317 return True
318 return False
319
2e9ee615 320class CandidatPieceAdmin(admin.ModelAdmin):
170c9aa2 321 list_display = ('nom', 'candidat', )
322
323 def queryset(self, request):
324 """
325 Spécifie un queryset limité, autrement Django exécute un
326 select_related() sans paramètre, ce qui a pour effet de charger tous
327 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
328 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
329 génération d'une requête infinie.
d835c9f3 330 Affiche la liste de candidats que si le user connecté
27c81d11 331 possède un Evaluateur
170c9aa2 332 """
333 qs = self.model._default_manager.get_query_set()
334 return qs.select_related('candidat')
2e9ee615 335
d2b30f5f 336class EvaluateurAdmin(VersionAdmin):
eb579d40 337 fieldsets = (
f6724c20 338 (None, {'fields': ('user', )}),
720c3ad5 339 #(None, {'fields': ('candidats',)}),
eb579d40 340 )
4418c732 341
b89fef74 342class AdministrateurRegionalAdmin(VersionAdmin):
27c81d11 343 pass
344
d2b30f5f 345class CandidatEvaluationAdmin(VersionAdmin):
beef7690
NBV
346 list_display = ('_offre_emploi', '_candidat', '_note', '_commentaire',
347 'evaluateur',)
348 readonly_fields = ('candidat', 'evaluateur')
349 fieldsets = (
350 ('Évaluation du candidat', {
351 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
352 }),
353 )
354
355 def _note(self, obj):
356 """
357 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
358 un lien pour Évaluer le candidat.
359 Sinon afficher la note.
360 """
361 if obj.note is None:
362 return "<a href='%s'>Évaluer le candidat </a>" % \
363 (reverse('admin:recrutement_candidatevaluation_change',
364 args=(obj.candidat.id,)))
365 return obj.note
366 _note.allow_tags = True
367 _note.short_description = "Votre note"
368 _note.admin_order_field = 'note'
369
370 def _candidat(self, obj):
371 return "<a href='%s'>%s</a>" \
372 % (reverse('admin:recrutement_proxycandidat_change',
373 args=(obj.candidat.id,)), obj.candidat)
374 _candidat.allow_tags = True
375 _candidat.short_description = 'Candidat'
376
377 def _commentaire(self, obj):
378 """
379 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
380 dans le champ commentaire, Aucun au lieu de (None)
381 Sinon afficher la note.
382 """
383 if obj.commentaire is None:
384 return "Aucun"
385 return obj.commentaire
386 _commentaire.allow_tags = True
387 _commentaire.short_description = "Commentaire"
720c3ad5 388
720c3ad5 389
beef7690
NBV
390 def _offre_emploi(self, obj):
391 return "<a href='%s'>%s</a>" % \
392 (reverse('admin:recrutement_proxyoffreemploi_change',
393 args=(obj.candidat.offre_emploi.id,)), obj.candidat.offre_emploi)
394 _offre_emploi.allow_tags = True
395 _offre_emploi.short_description = "Voir offre d'emploi"
396 _offre_emploi.admin_order_field = 'offre_emploi'
397
720c3ad5 398 def queryset(self, request):
beef7690
NBV
399 """
400 Afficher uniquement les évaluations de l'évaluateur, sauf si
401 l'utilisateur est super admin.
402 """
720c3ad5 403 qs = self.model._default_manager.get_query_set()
beef7690
NBV
404 user_groupes = request.user.groups.all()
405 if grp_drh_recrutement in user_groupes:
406 return qs.select_related('offre_emploi')
407
ca73c3c6 408 try:
d069cdf1 409 evaluateur = Evaluateur.objects.get(user=request.user)
ca73c3c6
NBV
410 except Evaluateur.DoesNotExist:
411 return qs.none()
412
413 candidats_evaluations = CandidatEvaluation.objects.\
414 filter(evaluateur=evaluateur)
415 candidats_evaluations_ids = [ce.id for ce in \
416 candidats_evaluations.all()]
417 return qs.select_related('offre_emploi').\
418 filter(id__in=candidats_evaluations_ids)
596fe324 419
4e8340cf 420class CourrielTemplateAdmin(VersionAdmin):
421 pass
422
df59fcab 423admin.site.register(OffreEmploi, OffreEmploiAdmin)
424admin.site.register(Candidat, CandidatAdmin)
720c3ad5 425admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
beef7690 426#admin.site.register(CourrielTemplate, CourrielTemplateAdmin)
27c81d11 427admin.site.register(Evaluateur, EvaluateurAdmin)
beef7690 428#admin.site.register(AdministrateurRegional, AdministrateurRegionalAdmin)
f6724c20
NBV
429admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin)
430admin.site.register(ProxyCandidat, ProxyCandidatAdmin)