fix acces
[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 user_groupes = request.user.groups.all()
203 if request.user.is_superuser is True or \
204 grp_correspondants_rh_recrutement in user_groupes or \
205 grp_drh_recrutement in user_groupes or \
206 grp_directeurs_bureau_recrutement in user_groupes or \
207 grp_administrateurs_recrutement in user_groupes:
208 return True
209 return False
210
211 class CandidatPieceInline(admin.TabularInline):
212 model = CandidatPiece
213 fields = ('candidat', 'nom', 'path',)
214 extra = 1
215 max_num = 3
216
217 class ReadOnlyCandidatPieceInline(CandidatPieceInline):
218 readonly_fields = ('candidat', 'nom', 'path', )
219 cand_delete = False
220
221
222 class CandidatEvaluationInlineFormSet(BaseInlineFormSet):
223 """
224 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
225 """
226 def __init__(self, *args, **kwargs):
227 super(CandidatEvaluationInlineFormSet, self).__init__(*args, **kwargs)
228 self.can_delete = False
229
230 class CandidatEvaluationInline(admin.TabularInline):
231 model = CandidatEvaluation
232 fields = ('evaluateur', 'note', 'commentaire')
233 max_num = 0
234 extra = 0
235 formset = CandidatEvaluationInlineFormSet
236
237 ### Fields readonly
238 def get_readonly_fields(self, request, obj=None):
239 """
240 Empêche la modification des évaluations
241 """
242 if obj:
243 return self.readonly_fields+('evaluateur', 'note', 'commentaire')
244 return self.readonly_fields
245
246 class CandidatAdmin(VersionAdmin):
247 search_fields = ('nom', 'prenom' )
248 exclude = ('actif', )
249 list_editable = ('statut', )
250 list_display = ('_candidat', 'offre_emploi',
251 'voir_offre_emploi', 'calculer_moyenne',
252 'afficher_candidat', '_date_creation', 'statut', )
253 list_filter = ('offre_emploi', 'offre_emploi__region', 'statut', )
254
255 fieldsets = (
256 ("Offre d'emploi", {
257 'fields': ('offre_emploi', )
258 }),
259 ('Informations personnelles', {
260 'fields': ('prenom','nom','genre', 'nationalite',
261 'situation_famille', 'nombre_dependant',)
262 }),
263 ('Coordonnées', {
264 'fields': ('telephone', 'email', 'adresse', 'ville',
265 'etat_province', 'code_postal', 'pays', )
266 }),
267 ('Informations professionnelles', {
268 'fields': ('niveau_diplome','employeur_actuel',
269 'poste_actuel', 'domaine_professionnel',)
270 }),
271 ('Traitement', {
272 'fields': ('statut', )
273 }),
274 )
275 inlines = [
276 CandidatPieceInline,
277 CandidatEvaluationInline,
278 ]
279 actions = ['envoyer_courriel_candidats']
280
281 def _candidat(self, obj):
282 txt = u"%s %s (%s)" % ( obj.nom.upper(), obj.prenom,
283 obj.genre)
284 txt = textwrap.wrap(txt, 30)
285 return "<br/>".join(txt)
286 _candidat.short_description = "Candidat"
287 _candidat.admin_order_field = "nom"
288 _candidat.allow_tags = True
289
290 def _date_creation(self, obj):
291 return obj.date_creation
292 _date_creation.admin_order_field = "date_creation"
293 _date_creation.short_description = "Date de réception"
294
295 ### Actions à afficher
296 def get_actions(self, request):
297 actions = super(CandidatAdmin, self).get_actions(request)
298 del actions['delete_selected']
299 return actions
300
301 ### Envoyer un courriel à des candidats
302 def envoyer_courriel_candidats(modeladmin, obj, candidats):
303 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
304
305 return HttpResponseRedirect(reverse('selectionner_template')+
306 "?ids=%s" % (",".join(selected)))
307 envoyer_courriel_candidats.short_description = u'Envoyer courriel'
308
309 ### Évaluer un candidat
310 def evaluer_candidat(self, obj):
311 return "<a href='%s?candidat__id__exact=%s'>Évaluer le candidat</a>" % \
312 (reverse('admin:recrutement_candidatevaluation_changelist'),
313 obj.id)
314 evaluer_candidat.allow_tags = True
315 evaluer_candidat.short_description = 'Évaluation'
316
317 ### Afficher un candidat
318 def afficher_candidat(self, obj):
319 items = [u"<li><a href='%s%s'>%s</li>" % \
320 (settings.OE_PRIVE_MEDIA_URL, pj.path, pj.get_nom_display()) \
321 for pj in obj.pieces_jointes()]
322 html = "<a href='%s'>Voir le candidat</a>" % \
323 (reverse('admin:recrutement_proxycandidat_change', args=(obj.id,)))
324 return "%s<ul>%s</ul>" % (html, "\n".join(items))
325 afficher_candidat.allow_tags = True
326 afficher_candidat.short_description = u'Détails du candidat'
327
328 ### Voir l'offre d'emploi
329 def voir_offre_emploi(self, obj):
330 return "<a href='%s'>Voir l'offre d'emploi</a>" % \
331 (reverse('admin:recrutement_proxyoffreemploi_change',
332 args=(obj.offre_emploi.id,)))
333 voir_offre_emploi.allow_tags = True
334 voir_offre_emploi.short_description = "Afficher l'offre d'emploi"
335
336 ### Calculer la moyenne des notes
337 def calculer_moyenne(self, obj):
338 evaluations = CandidatEvaluation.objects.filter(candidat=obj)
339
340 notes = [evaluation.note for evaluation in evaluations \
341 if evaluation.note is not None]
342
343 if len(notes) > 0:
344 moyenne_votes = round(float(sum(notes)) / len(notes), 2)
345 else:
346 moyenne_votes = "Non disponible"
347
348 totales = len(evaluations)
349 faites = len(notes)
350
351 if obj.statut == 'REC':
352 if totales == faites:
353 color = "green"
354 elif faites > 0 and float(totales) / float(faites) >= 2:
355 color = "orange"
356 else:
357 color = "red"
358 else:
359 color = "black"
360
361 return """<span style="color: %s;">%s (%s/%s)</span>""" % (color, moyenne_votes, faites, totales)
362 calculer_moyenne.allow_tags = True
363 calculer_moyenne.short_description = "Moyenne"
364 calculer_moyenne.admin_order_field = ""
365
366 ### Permissions add, delete, change
367 def has_add_permission(self, request):
368 user_groupes = request.user.groups.all()
369 if request.user.is_superuser is True or \
370 grp_correspondants_rh_recrutement in user_groupes or \
371 grp_drh_recrutement in user_groupes or \
372 grp_directeurs_bureau_recrutement in user_groupes or \
373 grp_administrateurs_recrutement in user_groupes:
374 return True
375 return False
376
377 def has_delete_permission(self, request, obj=None):
378 user_groupes = request.user.groups.all()
379 if request.user.is_superuser is True or \
380 grp_correspondants_rh_recrutement in user_groupes or \
381 grp_drh_recrutement in user_groupes or \
382 grp_directeurs_bureau_recrutement in user_groupes or \
383 grp_administrateurs_recrutement in user_groupes:
384 return True
385 return False
386
387 def has_change_permission(self, request, obj=None):
388 user_groupes = request.user.groups.all()
389 if request.user.is_superuser is True or \
390 grp_correspondants_rh_recrutement in user_groupes or \
391 grp_drh_recrutement in user_groupes or \
392 grp_directeurs_bureau_recrutement in user_groupes or \
393 grp_administrateurs_recrutement in user_groupes:
394 return True
395 return False
396
397 def get_changelist(self, request, **kwargs):
398 return OrderedChangeList
399
400 def queryset(self, request):
401 """
402 Spécifie un queryset limité, autrement Django exécute un
403 select_related() sans paramètre, ce qui a pour effet de charger tous
404 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
405 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
406 génération d'une requête infinie.
407
408 """
409
410 qs = self.model._default_manager.get_query_set().select_related('offre_emploi').annotate(moyenne=Avg('evaluations__note'))
411
412 user_groupes = request.user.groups.all()
413 if grp_drh_recrutement in user_groupes:
414 return qs
415
416 if grp_directeurs_bureau_recrutement in user_groupes or \
417 grp_correspondants_rh_recrutement in user_groupes or \
418 grp_administrateurs_recrutement in user_groupes:
419 employe = get_emp(request.user)
420 return qs.filter(offre_emploi__region=employe.implantation.region)
421
422 if Evaluateur.objects.filter(user=request.user).exists():
423 evaluateur = Evaluateur.objects.get(user=request.user)
424 candidat_ids = [e.candidat.id for e in
425 CandidatEvaluation.objects.filter(evaluateur=evaluateur)]
426 return qs.filter(id__in=candidat_ids)
427 return qs.none()
428
429
430 class ProxyCandidatAdmin(CandidatAdmin):
431 list_editable = ()
432 readonly_fields = ('statut', 'offre_emploi', 'prenom', 'nom',
433 'genre', 'nationalite', 'situation_famille',
434 'nombre_dependant', 'telephone', 'email', 'adresse',
435 'ville', 'etat_province', 'code_postal', 'pays',
436 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
437 'domaine_professionnel', 'pieces_jointes',)
438 fieldsets = (
439 ("Offre d'emploi", {
440 'fields': ('offre_emploi', )
441 }),
442 ('Informations personnelles', {
443 'fields': ('prenom','nom','genre', 'nationalite',
444 'situation_famille', 'nombre_dependant',)
445 }),
446 ('Coordonnées', {
447 'fields': ('telephone', 'email', 'adresse', 'ville',
448 'etat_province', 'code_postal', 'pays', )
449 }),
450 ('Informations professionnelles', {
451 'fields': ('niveau_diplome','employeur_actuel',
452 'poste_actuel', 'domaine_professionnel',)
453 }),
454 )
455 inlines = (CandidatEvaluationInline, )
456
457 def has_add_permission(self, request):
458 return False
459
460 def has_delete_permission(self, request, obj=None):
461 return False
462
463 def has_change_permission(self, request, obj=None):
464 user_groupes = request.user.groups.all()
465 if request.user.is_superuser is True or \
466 grp_correspondants_rh_recrutement in user_groupes or \
467 grp_drh_recrutement in user_groupes or \
468 grp_directeurs_bureau_recrutement in user_groupes or \
469 grp_administrateurs_recrutement in user_groupes:
470 return True
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 try:
633 Evaluateur.objects.get(user=request.user)
634 is_evaluateur = True
635 except:
636 is_evaluateur = False
637
638 if obj is None and (is_recrutement or is_evaluateur):
639 return True
640
641 if request.user.is_superuser is True:
642 return True
643
644 try:
645 return request.user == obj.evaluateur.user
646 except:
647 return False
648
649 ### Queryset
650 def queryset(self, request):
651 """
652 Afficher uniquement les évaluations de l'évaluateur, sauf si
653 l'utilisateur est dans les groupes suivants.
654 """
655 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
656 user_groupes = request.user.groups.all()
657
658 if grp_drh_recrutement in user_groupes or \
659 grp_correspondants_rh_recrutement in user_groupes or \
660 grp_directeurs_bureau_recrutement in user_groupes or \
661 grp_administrateurs_recrutement in user_groupes:
662 return qs
663
664 evaluateur = Evaluateur.objects.get(user=request.user)
665 candidats_evaluations = \
666 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
667 candidat__statut__in=('REC', ))
668 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
669 return qs.filter(id__in=candidats_evaluations_ids)
670
671
672 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin):
673
674 def has_change_permission(self, request, obj=None):
675 try:
676 Evaluateur.objects.get(user=request.user)
677 is_evaluateur = True
678 except:
679 is_evaluateur = False
680
681 if obj is None and is_evaluateur:
682 return True
683
684 try:
685 return request.user == obj.evaluateur.user
686 except:
687 return False
688
689 def queryset(self, request):
690 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
691 evaluateur = Evaluateur.objects.get(user=request.user)
692 candidats_evaluations = \
693 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
694 candidat__statut__in=('REC', ))
695 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
696 return qs.filter(id__in=candidats_evaluations_ids)
697
698
699 class CourrielTemplateAdmin(VersionAdmin):
700 ### Actions à afficher
701 def get_actions(self, request):
702 actions = super(CourrielTemplateAdmin, self).get_actions(request)
703 del actions['delete_selected']
704 return actions
705
706 admin.site.register(OffreEmploi, OffreEmploiAdmin)
707 admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin)
708 admin.site.register(Candidat, CandidatAdmin)
709 admin.site.register(ProxyCandidat, ProxyCandidatAdmin)
710 admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
711 admin.site.register(MesCandidatEvaluation, MesCandidatEvaluationAdmin)
712 admin.site.register(Evaluateur, EvaluateurAdmin)
713 admin.site.register(CourrielTemplate, CourrielTemplateAdmin)