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