fix proxy candidat 403
[auf_rh_dae.git] / project / recrutement / admin.py
1 # -*- encoding: utf-8 -*-
2
3 import textwrap
4 from django.core.urlresolvers import reverse
5 from django.http import HttpResponseRedirect
6 from django.contrib import admin
7 from django.forms.models import BaseInlineFormSet
8 from django.db.models import Avg
9 from django.conf import settings
10
11 from reversion.admin import VersionAdmin
12 from datamaster_modeles.models import Region, Bureau
13 from project.rh import models as rh
14
15 from project.dae.utils import get_employe_from_user as get_emp
16 from recrutement.models import *
17 from recrutement.workflow import grp_drh_recrutement, grp_directeurs_bureau_recrutement, \
18 grp_administrateurs_recrutement, \
19 grp_correspondants_rh_recrutement
20
21 from recrutement.forms import *
22
23 ### CONSTANTES
24 IMPLANTATIONS_CENTRALES = [15, 19]
25
26 class OrderedChangeList(admin.views.main.ChangeList):
27 """
28 Surcharge pour appliquer le order_by d'un annotate
29 """
30 def get_query_set(self):
31 qs = super(OrderedChangeList, self).get_query_set()
32 qs = qs.order_by('-moyenne')
33 return qs
34
35 class OffreEmploiAdmin(VersionAdmin):
36 date_hierarchy = 'date_creation'
37 list_display = ('nom', 'date_limite', 'region', 'statut',
38 'est_affiche', '_candidatsList', )
39 exclude = ('actif', 'poste_nom', 'resume',)
40 list_filter = ('statut',)
41 actions = ['affecter_evaluateurs_offre_emploi', ]
42 form = OffreEmploiForm
43
44 ### Actions à afficher
45 def get_actions(self, request):
46 actions = super(OffreEmploiAdmin, self).get_actions(request)
47 del actions['delete_selected']
48 return actions
49
50 ### Affecter un évaluateurs à des offres d'emploi
51 def affecter_evaluateurs_offre_emploi(modeladmin, obj, candidats):
52 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
53
54 return HttpResponseRedirect(reverse('affecter_evaluateurs_offre_emploi')+
55 "?ids=%s" % (",".join(selected)))
56 affecter_evaluateurs_offre_emploi.short_description = u'Affecter évaluateur(s)'
57
58 ### Afficher la liste des candidats pour l'offre d'emploi
59 def _candidatsList(self, obj):
60 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
61 </a>" % (reverse('admin:recrutement_candidat_changelist'), obj.id)
62 _candidatsList.allow_tags = True
63 _candidatsList.short_description = "Afficher la liste des candidats"
64
65 ### Formulaire
66 def get_form(self, request, obj=None, **kwargs):
67 form = super(OffreEmploiAdmin, self).get_form(request, obj, **kwargs)
68 employe = get_emp(request.user)
69 user_groupes = request.user.groups.all()
70
71
72 # Region
73 if form.declared_fields.has_key('region'):
74 region_field = form.declared_fields['region']
75 else:
76 region_field = form.base_fields['region']
77
78 if grp_drh_recrutement in user_groupes:
79 region_field.queryset = Region.objects.all()
80 else:
81 region_field.queryset = Region.objects.\
82 filter(id=employe.implantation.region.id)
83
84 # Poste
85 if form.declared_fields.has_key('poste'):
86 poste_field = form.declared_fields['poste']
87 else:
88 poste_field = form.base_fields['poste']
89
90 if grp_drh_recrutement in user_groupes:
91 poste_field.queryset = rh.Poste.objects.all()
92 else:
93 poste_field.queryset = rh.Poste.objects.\
94 filter(implantation__region=employe.implantation.region).\
95 exclude(implantation__in=IMPLANTATIONS_CENTRALES)
96
97 # Bureau
98 if form.declared_fields.has_key('bureau'):
99 bureau_field = form.declared_fields['bureau']
100 else:
101 bureau_field = form.base_fields['bureau']
102
103 if grp_drh_recrutement in user_groupes:
104 bureau_field.queryset = Bureau.objects.all()
105 else:
106 bureau_field.queryset = Bureau.objects.\
107 filter(region=employe.implantation.region)
108
109 return form
110
111 ### Queryset
112 def queryset(self, request):
113 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
114 user_groupes = request.user.groups.all()
115 if grp_drh_recrutement in user_groupes:
116 return qs
117
118 if grp_directeurs_bureau_recrutement in user_groupes or \
119 grp_correspondants_rh_recrutement in user_groupes or \
120 grp_administrateurs_recrutement in user_groupes:
121 employe = get_emp(request.user)
122 return qs.filter(region=employe.implantation.region)
123
124 if Evaluateur.objects.filter(user=request.user).exists():
125 evaluateur = Evaluateur.objects.get(user=request.user)
126 offre_ids = [e.candidat.offre_emploi_id for e in
127 CandidatEvaluation.objects.select_related('candidat').filter(evaluateur=evaluateur)]
128 return qs.filter(id__in=offre_ids)
129
130 return qs.none()
131
132 ### Permission add, delete, change
133 def has_add_permission(self, request):
134 user_groupes = request.user.groups.all()
135 if request.user.is_superuser is True or \
136 grp_drh_recrutement in user_groupes or \
137 grp_directeurs_bureau_recrutement in user_groupes or \
138 grp_administrateurs_recrutement in user_groupes:
139 return True
140 return False
141
142 def has_delete_permission(self, request, obj=None):
143 user_groupes = request.user.groups.all()
144 if request.user.is_superuser is True or \
145 grp_drh_recrutement in user_groupes or \
146 grp_directeurs_bureau_recrutement in user_groupes or \
147 grp_administrateurs_recrutement in user_groupes:
148 return True
149 return False
150
151 def has_change_permission(self, request, obj=None):
152 user_groupes = request.user.groups.all()
153 if request.user.is_superuser is True or \
154 grp_drh_recrutement in user_groupes or \
155 grp_directeurs_bureau_recrutement in user_groupes or \
156 grp_administrateurs_recrutement in user_groupes:
157 return True
158 return False
159
160 class ProxyOffreEmploiAdmin(OffreEmploiAdmin):
161 list_display = ('nom', 'date_limite', 'region', 'statut',
162 'est_affiche')
163 readonly_fields = ('description', 'bureau', 'duree_affectation',
164 'renumeration', 'debut_affectation', 'lieu_affectation',
165 'nom', 'resume', 'date_limite', 'region', 'poste')
166 fieldsets = (
167 ('Nom', {
168 'fields': ('nom', )
169 }),
170 ('Description générale', {
171 'fields': ('description', 'date_limite', )
172 }),
173 ('Coordonnées', {
174 'fields': ('lieu_affectation', 'bureau', 'region', 'poste',)
175 }),
176 ('Autre', {
177 'fields': ('debut_affectation', 'duree_affectation',
178 'renumeration', )
179 }),
180 )
181 inlines = []
182
183
184 ### Lieu de redirection après le change
185 def response_change(self, request, obj):
186 return HttpResponseRedirect(reverse\
187 ('admin:recrutement_proxyoffreemploi_changelist'))
188
189 ### Formulaire
190 def get_form(self, request, obj=None, **kwargs):
191 form = super(OffreEmploiAdmin, self).get_form(request, obj, **kwargs)
192 return form
193
194 ### Permissions add, delete, change
195 def has_add_permission(self, request):
196 return False
197
198 def has_delete_permission(self, request, obj=None):
199 return False
200
201 def has_change_permission(self, request, obj=None):
202 return True
203
204 class CandidatPieceInline(admin.TabularInline):
205 model = CandidatPiece
206 fields = ('candidat', 'nom', 'path',)
207 extra = 1
208 max_num = 3
209
210 class ReadOnlyCandidatPieceInline(CandidatPieceInline):
211 readonly_fields = ('candidat', 'nom', 'path', )
212 cand_delete = False
213
214
215 class CandidatEvaluationInlineFormSet(BaseInlineFormSet):
216 """
217 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
218 """
219 def __init__(self, *args, **kwargs):
220 super(CandidatEvaluationInlineFormSet, self).__init__(*args, **kwargs)
221 self.can_delete = False
222
223 class CandidatEvaluationInline(admin.TabularInline):
224 model = CandidatEvaluation
225 fields = ('evaluateur', 'note', 'commentaire')
226 max_num = 0
227 extra = 0
228 formset = CandidatEvaluationInlineFormSet
229
230 ### Fields readonly
231 def get_readonly_fields(self, request, obj=None):
232 """
233 Empêche la modification des évaluations
234 """
235 if obj:
236 return self.readonly_fields+('evaluateur', 'note', 'commentaire')
237 return self.readonly_fields
238
239 class CandidatAdmin(VersionAdmin):
240 search_fields = ('nom', 'prenom' )
241 exclude = ('actif', )
242 list_editable = ('statut', )
243 list_display = ('_candidat', 'offre_emploi',
244 'voir_offre_emploi', 'calculer_moyenne',
245 'afficher_candidat', '_date_creation', 'statut', )
246 list_filter = ('offre_emploi', 'offre_emploi__region', 'statut', )
247
248 fieldsets = (
249 ("Offre d'emploi", {
250 'fields': ('offre_emploi', )
251 }),
252 ('Informations personnelles', {
253 'fields': ('prenom','nom','genre', 'nationalite',
254 'situation_famille', 'nombre_dependant',)
255 }),
256 ('Coordonnées', {
257 'fields': ('telephone', 'email', 'adresse', 'ville',
258 'etat_province', 'code_postal', 'pays', )
259 }),
260 ('Informations professionnelles', {
261 'fields': ('niveau_diplome','employeur_actuel',
262 'poste_actuel', 'domaine_professionnel',)
263 }),
264 ('Traitement', {
265 'fields': ('statut', )
266 }),
267 )
268 inlines = [
269 CandidatPieceInline,
270 CandidatEvaluationInline,
271 ]
272 actions = ['envoyer_courriel_candidats']
273
274 def _candidat(self, obj):
275 txt = u"%s %s (%s)" % ( obj.nom.upper(), obj.prenom,
276 obj.genre)
277 txt = textwrap.wrap(txt, 30)
278 return "<br/>".join(txt)
279 _candidat.short_description = "Candidat"
280 _candidat.admin_order_field = "nom"
281 _candidat.allow_tags = True
282
283 def _date_creation(self, obj):
284 return obj.date_creation
285 _date_creation.admin_order_field = "date_creation"
286 _date_creation.short_description = "Date de réception"
287
288 ### Actions à afficher
289 def get_actions(self, request):
290 actions = super(CandidatAdmin, self).get_actions(request)
291 del actions['delete_selected']
292 return actions
293
294 ### Envoyer un courriel à des candidats
295 def envoyer_courriel_candidats(modeladmin, obj, candidats):
296 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
297
298 return HttpResponseRedirect(reverse('selectionner_template')+
299 "?ids=%s" % (",".join(selected)))
300 envoyer_courriel_candidats.short_description = u'Envoyer courriel'
301
302 ### Évaluer un candidat
303 def evaluer_candidat(self, obj):
304 return "<a href='%s?candidat__id__exact=%s'>Évaluer le candidat</a>" % \
305 (reverse('admin:recrutement_candidatevaluation_changelist'),
306 obj.id)
307 evaluer_candidat.allow_tags = True
308 evaluer_candidat.short_description = 'Évaluation'
309
310 ### Afficher un candidat
311 def afficher_candidat(self, obj):
312 items = [u"<li><a href='%s%s'>%s</li>" % \
313 (settings.OE_PRIVE_MEDIA_URL, pj.path, pj.get_nom_display()) \
314 for pj in obj.pieces_jointes()]
315 html = "<a href='%s'>Voir le candidat</a>" % \
316 (reverse('admin:recrutement_proxycandidat_change', args=(obj.id,)))
317 return "%s<ul>%s</ul>" % (html, "\n".join(items))
318 afficher_candidat.allow_tags = True
319 afficher_candidat.short_description = u'Détails du candidat'
320
321 ### Voir l'offre d'emploi
322 def voir_offre_emploi(self, obj):
323 return "<a href='%s'>Voir l'offre d'emploi</a>" % \
324 (reverse('admin:recrutement_proxyoffreemploi_change',
325 args=(obj.offre_emploi.id,)))
326 voir_offre_emploi.allow_tags = True
327 voir_offre_emploi.short_description = "Afficher l'offre d'emploi"
328
329 ### Calculer la moyenne des notes
330 def calculer_moyenne(self, obj):
331 evaluations = CandidatEvaluation.objects.filter(candidat=obj)
332
333 notes = [evaluation.note for evaluation in evaluations \
334 if evaluation.note is not None]
335
336 if len(notes) > 0:
337 moyenne_votes = round(float(sum(notes)) / len(notes), 2)
338 else:
339 moyenne_votes = "Non disponible"
340
341 totales = len(evaluations)
342 faites = len(notes)
343
344 if obj.statut == 'REC':
345 if totales == faites:
346 color = "green"
347 elif faites > 0 and float(totales) / float(faites) >= 2:
348 color = "orange"
349 else:
350 color = "red"
351 else:
352 color = "black"
353
354 return """<span style="color: %s;">%s (%s/%s)</span>""" % (color, moyenne_votes, faites, totales)
355 calculer_moyenne.allow_tags = True
356 calculer_moyenne.short_description = "Moyenne"
357 calculer_moyenne.admin_order_field = ""
358
359 ### Permissions add, delete, change
360 def has_add_permission(self, request):
361 user_groupes = request.user.groups.all()
362 if request.user.is_superuser is True or \
363 grp_correspondants_rh_recrutement in user_groupes or \
364 grp_drh_recrutement in user_groupes or \
365 grp_directeurs_bureau_recrutement in user_groupes or \
366 grp_administrateurs_recrutement in user_groupes:
367 return True
368 return False
369
370 def has_delete_permission(self, request, obj=None):
371 user_groupes = request.user.groups.all()
372 if request.user.is_superuser is True or \
373 grp_correspondants_rh_recrutement in user_groupes or \
374 grp_drh_recrutement in user_groupes or \
375 grp_directeurs_bureau_recrutement in user_groupes or \
376 grp_administrateurs_recrutement in user_groupes:
377 return True
378 return False
379
380 def has_change_permission(self, request, obj=None):
381 user_groupes = request.user.groups.all()
382 if request.user.is_superuser is True or \
383 grp_correspondants_rh_recrutement in user_groupes or \
384 grp_drh_recrutement in user_groupes or \
385 grp_directeurs_bureau_recrutement in user_groupes or \
386 grp_administrateurs_recrutement in user_groupes:
387 return True
388 return False
389
390 def get_changelist(self, request, **kwargs):
391 return OrderedChangeList
392
393 def queryset(self, request):
394 """
395 Spécifie un queryset limité, autrement Django exécute un
396 select_related() sans paramètre, ce qui a pour effet de charger tous
397 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
398 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
399 génération d'une requête infinie.
400
401 """
402
403 qs = self.model._default_manager.get_query_set().select_related('offre_emploi').annotate(moyenne=Avg('evaluations__note'))
404
405 user_groupes = request.user.groups.all()
406 if grp_drh_recrutement in user_groupes:
407 return qs
408
409 if grp_directeurs_bureau_recrutement in user_groupes or \
410 grp_correspondants_rh_recrutement in user_groupes or \
411 grp_administrateurs_recrutement in user_groupes:
412 employe = get_emp(request.user)
413 return qs.filter(offre_emploi__region=employe.implantation.region)
414
415 if Evaluateur.objects.filter(user=request.user).exists():
416 evaluateur = Evaluateur.objects.get(user=request.user)
417 candidat_ids = [e.candidat.id for e in
418 CandidatEvaluation.objects.filter(evaluateur=evaluateur)]
419 return qs.filter(id__in=candidat_ids)
420 return qs.none()
421
422
423 class ProxyCandidatAdmin(CandidatAdmin):
424 list_editable = ()
425 readonly_fields = ('statut', 'offre_emploi', 'prenom', 'nom',
426 'genre', 'nationalite', 'situation_famille',
427 'nombre_dependant', 'telephone', 'email', 'adresse',
428 'ville', 'etat_province', 'code_postal', 'pays',
429 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
430 'domaine_professionnel', 'pieces_jointes',)
431 fieldsets = (
432 ("Offre d'emploi", {
433 'fields': ('offre_emploi', )
434 }),
435 ('Informations personnelles', {
436 'fields': ('prenom','nom','genre', 'nationalite',
437 'situation_famille', 'nombre_dependant',)
438 }),
439 ('Coordonnées', {
440 'fields': ('telephone', 'email', 'adresse', 'ville',
441 'etat_province', 'code_postal', 'pays', )
442 }),
443 ('Informations professionnelles', {
444 'fields': ('niveau_diplome','employeur_actuel',
445 'poste_actuel', 'domaine_professionnel',)
446 }),
447 )
448 inlines = (CandidatEvaluationInline, )
449
450 def has_add_permission(self, request):
451 return False
452
453 def has_delete_permission(self, request, obj=None):
454 return False
455
456 def has_change_permission(self, request, obj=None):
457 user_groupes = request.user.groups.all()
458 if request.user.is_superuser is True or \
459 grp_correspondants_rh_recrutement in user_groupes or \
460 grp_drh_recrutement in user_groupes or \
461 grp_directeurs_bureau_recrutement in user_groupes or \
462 grp_administrateurs_recrutement in user_groupes:
463 return True
464
465 if obj is not None:
466 evaluateur = Evaluateur.objects.get(user=request.user)
467 for e in obj.evaluations.all():
468 if e.evaluateur == evaluateur:
469 return True
470
471 return False
472
473 def get_actions(self, request):
474 return None
475
476 class CandidatPieceAdmin(admin.ModelAdmin):
477 list_display = ('nom', 'candidat', )
478
479 ### Queryset
480 def queryset(self, request):
481 """
482 Spécifie un queryset limité, autrement Django exécute un
483 select_related() sans paramètre, ce qui a pour effet de charger tous
484 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
485 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
486 génération d'une requête infinie.
487 Affiche la liste de candidats que si le user connecté
488 possède un Evaluateur
489 """
490 qs = self.model._default_manager.get_query_set()
491 return qs.select_related('candidat')
492
493 class EvaluateurAdmin(VersionAdmin):
494 fieldsets = (
495 ("Utilisateur", {
496 'fields': ('user',)
497 }),
498 )
499
500 ### Actions à afficher
501 def get_actions(self, request):
502 actions = super(EvaluateurAdmin, self).get_actions(request)
503 del actions['delete_selected']
504 return actions
505
506 ### Permissions add, delete, change
507 def has_add_permission(self, request):
508 user_groupes = request.user.groups.all()
509 if request.user.is_superuser is True or \
510 grp_drh_recrutement in user_groupes:
511 return True
512 return False
513
514 def has_delete_permission(self, request, obj=None):
515 user_groupes = request.user.groups.all()
516 if request.user.is_superuser is True or \
517 grp_drh_recrutement in user_groupes:
518 return True
519 return False
520
521 def has_change_permission(self, request, obj=None):
522 user_groupes = request.user.groups.all()
523 if request.user.is_superuser is True or \
524 grp_drh_recrutement in user_groupes:
525 return True
526 return False
527
528 class CandidatEvaluationAdmin(admin.ModelAdmin):
529 search_fields = ('candidat__nom', 'candidat__prenom' )
530 list_display = ('_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
531 '_commentaire', )
532 readonly_fields = ('candidat', 'evaluateur')
533 list_filter = ('candidat__statut', 'candidat__offre_emploi',)
534 fieldsets = (
535 ('Évaluation du candidat', {
536 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
537 }),
538 )
539
540 def get_actions(self, request):
541 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
542 try:
543 self.evaluateur = Evaluateur.objects.get(user=request.user)
544 except:
545 self.evaluateur = None
546
547 actions = super(CandidatEvaluationAdmin, self).get_actions(request)
548 del actions['delete_selected']
549 return actions
550
551 ### Afficher la note
552 def _note(self, obj):
553 """
554 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
555 un lien pour Évaluer le candidat.
556 Sinon afficher la note.
557 """
558 page = self.model.__name__.lower()
559 redirect_url = 'admin:recrutement_%s_change' % page
560
561 if obj.note is None:
562 label = "Candidat non évalué"
563 else:
564 label = obj.note
565
566 if self.evaluateur == obj.evaluateur:
567 return "<a href='%s'>%s</a>" % (reverse(redirect_url, args=(obj.id,)), label)
568 else:
569 return label
570 _note.allow_tags = True
571 _note.short_description = "Note"
572 _note.admin_order_field = 'note'
573
574 def _statut(self, obj):
575 return obj.candidat.get_statut_display()
576 _statut.order_field = 'candidat__statut'
577 _statut.short_description = 'Statut'
578
579
580 ### Lien en lecture seule vers le candidat
581 def _candidat(self, obj):
582 return "<a href='%s'>%s</a>" \
583 % (reverse('admin:recrutement_proxycandidat_change',
584 args=(obj.candidat.id,)), obj.candidat)
585 _candidat.allow_tags = True
586 _candidat.short_description = 'Candidat'
587
588 ### Afficher commentaire
589 def _commentaire(self, obj):
590 """
591 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
592 dans le champ commentaire, Aucun au lieu de (None)
593 Sinon afficher la note.
594 """
595 if obj.commentaire is None:
596 return "Aucun"
597 return obj.commentaire
598 _commentaire.allow_tags = True
599 _commentaire.short_description = "Commentaire"
600
601 ### Afficher offre d'emploi
602 def _offre_emploi(self, obj):
603 return "<a href='%s'>%s</a>" % \
604 (reverse('admin:recrutement_proxyoffreemploi_change',
605 args=(obj.candidat.offre_emploi.id,)), obj.candidat.offre_emploi)
606 _offre_emploi.allow_tags = True
607 _offre_emploi.short_description = "Voir offre d'emploi"
608
609 def has_add_permission(self, request):
610 return False
611
612 def has_delete_permission(self, request, obj=None):
613 return False
614
615 def has_change_permission(self, request, obj=None):
616 """
617 Permettre la visualisation dans la changelist
618 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
619 le request.user
620 """
621 user_groupes = request.user.groups.all()
622
623 if request.user.is_superuser or \
624 grp_drh_recrutement in user_groupes or \
625 grp_correspondants_rh_recrutement in user_groupes or \
626 grp_directeurs_bureau_recrutement in user_groupes or \
627 grp_administrateurs_recrutement in user_groupes:
628 is_recrutement = True
629 else:
630 is_recrutement = False
631
632 return is_recrutement
633
634 def queryset(self, request):
635 """
636 Afficher uniquement les évaluations de l'évaluateur, sauf si
637 l'utilisateur est dans les groupes suivants.
638 """
639 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
640 user_groupes = request.user.groups.all()
641
642 if grp_drh_recrutement in user_groupes or \
643 grp_correspondants_rh_recrutement in user_groupes or \
644 grp_directeurs_bureau_recrutement in user_groupes or \
645 grp_administrateurs_recrutement in user_groupes:
646 return qs
647
648 evaluateur = Evaluateur.objects.get(user=request.user)
649 candidats_evaluations = \
650 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
651 candidat__statut__in=('REC', ))
652 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
653 return qs.filter(id__in=candidats_evaluations_ids)
654
655
656 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin):
657
658 def has_change_permission(self, request, obj=None):
659 try:
660 Evaluateur.objects.get(user=request.user)
661 is_evaluateur = True
662 except:
663 is_evaluateur = False
664
665 if obj is None and is_evaluateur:
666 return True
667
668 try:
669 return request.user == obj.evaluateur.user
670 except:
671 return False
672
673 def queryset(self, request):
674 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
675 evaluateur = Evaluateur.objects.get(user=request.user)
676 candidats_evaluations = \
677 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
678 candidat__statut__in=('REC', ))
679 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
680 return qs.filter(id__in=candidats_evaluations_ids)
681
682
683 class CourrielTemplateAdmin(VersionAdmin):
684 ### Actions à afficher
685 def get_actions(self, request):
686 actions = super(CourrielTemplateAdmin, self).get_actions(request)
687 del actions['delete_selected']
688 return actions
689
690 admin.site.register(OffreEmploi, OffreEmploiAdmin)
691 admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin)
692 admin.site.register(Candidat, CandidatAdmin)
693 admin.site.register(ProxyCandidat, ProxyCandidatAdmin)
694 admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
695 admin.site.register(MesCandidatEvaluation, MesCandidatEvaluationAdmin)
696 admin.site.register(Evaluateur, EvaluateurAdmin)
697 admin.site.register(CourrielTemplate, CourrielTemplateAdmin)