fix voir emploi
[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
210 if obj is not None:
211 return True
212
213 return False
214
215 class CandidatPieceInline(admin.TabularInline):
216 model = CandidatPiece
217 fields = ('candidat', 'nom', 'path',)
218 extra = 1
219 max_num = 3
220
221 class ReadOnlyCandidatPieceInline(CandidatPieceInline):
222 readonly_fields = ('candidat', 'nom', 'path', )
223 cand_delete = False
224
225
226 class CandidatEvaluationInlineFormSet(BaseInlineFormSet):
227 """
228 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
229 """
230 def __init__(self, *args, **kwargs):
231 super(CandidatEvaluationInlineFormSet, self).__init__(*args, **kwargs)
232 self.can_delete = False
233
234 class CandidatEvaluationInline(admin.TabularInline):
235 model = CandidatEvaluation
236 fields = ('evaluateur', 'note', 'commentaire')
237 max_num = 0
238 extra = 0
239 formset = CandidatEvaluationInlineFormSet
240
241 ### Fields readonly
242 def get_readonly_fields(self, request, obj=None):
243 """
244 Empêche la modification des évaluations
245 """
246 if obj:
247 return self.readonly_fields+('evaluateur', 'note', 'commentaire')
248 return self.readonly_fields
249
250 class CandidatAdmin(VersionAdmin):
251 search_fields = ('nom', 'prenom' )
252 exclude = ('actif', )
253 list_editable = ('statut', )
254 list_display = ('_candidat', 'offre_emploi',
255 'voir_offre_emploi', 'calculer_moyenne',
256 'afficher_candidat', '_date_creation', 'statut', )
257 list_filter = ('offre_emploi', 'offre_emploi__region', 'statut', )
258
259 fieldsets = (
260 ("Offre d'emploi", {
261 'fields': ('offre_emploi', )
262 }),
263 ('Informations personnelles', {
264 'fields': ('prenom','nom','genre', 'nationalite',
265 'situation_famille', 'nombre_dependant',)
266 }),
267 ('Coordonnées', {
268 'fields': ('telephone', 'email', 'adresse', 'ville',
269 'etat_province', 'code_postal', 'pays', )
270 }),
271 ('Informations professionnelles', {
272 'fields': ('niveau_diplome','employeur_actuel',
273 'poste_actuel', 'domaine_professionnel',)
274 }),
275 ('Traitement', {
276 'fields': ('statut', )
277 }),
278 )
279 inlines = [
280 CandidatPieceInline,
281 CandidatEvaluationInline,
282 ]
283 actions = ['envoyer_courriel_candidats']
284
285 def _candidat(self, obj):
286 txt = u"%s %s (%s)" % ( obj.nom.upper(), obj.prenom,
287 obj.genre)
288 txt = textwrap.wrap(txt, 30)
289 return "<br/>".join(txt)
290 _candidat.short_description = "Candidat"
291 _candidat.admin_order_field = "nom"
292 _candidat.allow_tags = True
293
294 def _date_creation(self, obj):
295 return obj.date_creation
296 _date_creation.admin_order_field = "date_creation"
297 _date_creation.short_description = "Date de réception"
298
299 ### Actions à afficher
300 def get_actions(self, request):
301 actions = super(CandidatAdmin, self).get_actions(request)
302 del actions['delete_selected']
303 return actions
304
305 ### Envoyer un courriel à des candidats
306 def envoyer_courriel_candidats(modeladmin, obj, candidats):
307 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
308
309 return HttpResponseRedirect(reverse('selectionner_template')+
310 "?ids=%s" % (",".join(selected)))
311 envoyer_courriel_candidats.short_description = u'Envoyer courriel'
312
313 ### Évaluer un candidat
314 def evaluer_candidat(self, obj):
315 return "<a href='%s?candidat__id__exact=%s'>Évaluer le candidat</a>" % \
316 (reverse('admin:recrutement_candidatevaluation_changelist'),
317 obj.id)
318 evaluer_candidat.allow_tags = True
319 evaluer_candidat.short_description = 'Évaluation'
320
321 ### Afficher un candidat
322 def afficher_candidat(self, obj):
323 items = [u"<li><a href='%s%s'>%s</li>" % \
324 (settings.OE_PRIVE_MEDIA_URL, pj.path, pj.get_nom_display()) \
325 for pj in obj.pieces_jointes()]
326 html = "<a href='%s'>Voir le candidat</a>" % \
327 (reverse('admin:recrutement_proxycandidat_change', args=(obj.id,)))
328 return "%s<ul>%s</ul>" % (html, "\n".join(items))
329 afficher_candidat.allow_tags = True
330 afficher_candidat.short_description = u'Détails du candidat'
331
332 ### Voir l'offre d'emploi
333 def voir_offre_emploi(self, obj):
334 return "<a href='%s'>Voir l'offre d'emploi</a>" % \
335 (reverse('admin:recrutement_proxyoffreemploi_change',
336 args=(obj.offre_emploi.id,)))
337 voir_offre_emploi.allow_tags = True
338 voir_offre_emploi.short_description = "Afficher l'offre d'emploi"
339
340 ### Calculer la moyenne des notes
341 def calculer_moyenne(self, obj):
342 evaluations = CandidatEvaluation.objects.filter(candidat=obj)
343
344 notes = [evaluation.note for evaluation in evaluations \
345 if evaluation.note is not None]
346
347 if len(notes) > 0:
348 moyenne_votes = round(float(sum(notes)) / len(notes), 2)
349 else:
350 moyenne_votes = "Non disponible"
351
352 totales = len(evaluations)
353 faites = len(notes)
354
355 if obj.statut == 'REC':
356 if totales == faites:
357 color = "green"
358 elif faites > 0 and float(totales) / float(faites) >= 2:
359 color = "orange"
360 else:
361 color = "red"
362 else:
363 color = "black"
364
365 return """<span style="color: %s;">%s (%s/%s)</span>""" % (color, moyenne_votes, faites, totales)
366 calculer_moyenne.allow_tags = True
367 calculer_moyenne.short_description = "Moyenne"
368 calculer_moyenne.admin_order_field = ""
369
370 ### Permissions add, delete, change
371 def has_add_permission(self, request):
372 user_groupes = request.user.groups.all()
373 if request.user.is_superuser is True or \
374 grp_correspondants_rh_recrutement in user_groupes or \
375 grp_drh_recrutement in user_groupes or \
376 grp_directeurs_bureau_recrutement in user_groupes or \
377 grp_administrateurs_recrutement in user_groupes:
378 return True
379 return False
380
381 def has_delete_permission(self, request, obj=None):
382 user_groupes = request.user.groups.all()
383 if request.user.is_superuser is True or \
384 grp_correspondants_rh_recrutement in user_groupes or \
385 grp_drh_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_change_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_directeurs_bureau_recrutement in user_groupes or \
397 grp_administrateurs_recrutement in user_groupes:
398 return True
399 return False
400
401 def get_changelist(self, request, **kwargs):
402 return OrderedChangeList
403
404 def queryset(self, request):
405 """
406 Spécifie un queryset limité, autrement Django exécute un
407 select_related() sans paramètre, ce qui a pour effet de charger tous
408 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
409 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
410 génération d'une requête infinie.
411
412 """
413
414 qs = self.model._default_manager.get_query_set().select_related('offre_emploi').annotate(moyenne=Avg('evaluations__note'))
415
416 user_groupes = request.user.groups.all()
417 if grp_drh_recrutement in user_groupes:
418 return qs
419
420 if grp_directeurs_bureau_recrutement in user_groupes or \
421 grp_correspondants_rh_recrutement in user_groupes or \
422 grp_administrateurs_recrutement in user_groupes:
423 employe = get_emp(request.user)
424 return qs.filter(offre_emploi__region=employe.implantation.region)
425
426 if Evaluateur.objects.filter(user=request.user).exists():
427 evaluateur = Evaluateur.objects.get(user=request.user)
428 candidat_ids = [e.candidat.id for e in
429 CandidatEvaluation.objects.filter(evaluateur=evaluateur)]
430 return qs.filter(id__in=candidat_ids)
431 return qs.none()
432
433
434 class ProxyCandidatAdmin(CandidatAdmin):
435 list_editable = ()
436 readonly_fields = ('statut', 'offre_emploi', 'prenom', 'nom',
437 'genre', 'nationalite', 'situation_famille',
438 'nombre_dependant', 'telephone', 'email', 'adresse',
439 'ville', 'etat_province', 'code_postal', 'pays',
440 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
441 'domaine_professionnel', 'pieces_jointes',)
442 fieldsets = (
443 ("Offre d'emploi", {
444 'fields': ('offre_emploi', )
445 }),
446 ('Informations personnelles', {
447 'fields': ('prenom','nom','genre', 'nationalite',
448 'situation_famille', 'nombre_dependant',)
449 }),
450 ('Coordonnées', {
451 'fields': ('telephone', 'email', 'adresse', 'ville',
452 'etat_province', 'code_postal', 'pays', )
453 }),
454 ('Informations professionnelles', {
455 'fields': ('niveau_diplome','employeur_actuel',
456 'poste_actuel', 'domaine_professionnel',)
457 }),
458 )
459 inlines = (CandidatEvaluationInline, )
460
461 def has_add_permission(self, request):
462 return False
463
464 def has_delete_permission(self, request, obj=None):
465 return False
466
467 def has_change_permission(self, request, obj=None):
468 user_groupes = request.user.groups.all()
469 if request.user.is_superuser is True or \
470 grp_correspondants_rh_recrutement in user_groupes or \
471 grp_drh_recrutement in user_groupes or \
472 grp_directeurs_bureau_recrutement in user_groupes or \
473 grp_administrateurs_recrutement in user_groupes:
474 return True
475
476 if obj is not None:
477 evaluateur = Evaluateur.objects.get(user=request.user)
478 for e in obj.evaluations.all():
479 if e.evaluateur == evaluateur:
480 return True
481
482 return False
483
484 def get_actions(self, request):
485 return None
486
487 class CandidatPieceAdmin(admin.ModelAdmin):
488 list_display = ('nom', 'candidat', )
489
490 ### Queryset
491 def queryset(self, request):
492 """
493 Spécifie un queryset limité, autrement Django exécute un
494 select_related() sans paramètre, ce qui a pour effet de charger tous
495 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
496 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
497 génération d'une requête infinie.
498 Affiche la liste de candidats que si le user connecté
499 possède un Evaluateur
500 """
501 qs = self.model._default_manager.get_query_set()
502 return qs.select_related('candidat')
503
504 class EvaluateurAdmin(VersionAdmin):
505 fieldsets = (
506 ("Utilisateur", {
507 'fields': ('user',)
508 }),
509 )
510
511 ### Actions à afficher
512 def get_actions(self, request):
513 actions = super(EvaluateurAdmin, self).get_actions(request)
514 del actions['delete_selected']
515 return actions
516
517 ### Permissions add, delete, change
518 def has_add_permission(self, request):
519 user_groupes = request.user.groups.all()
520 if request.user.is_superuser is True or \
521 grp_drh_recrutement in user_groupes:
522 return True
523 return False
524
525 def has_delete_permission(self, request, obj=None):
526 user_groupes = request.user.groups.all()
527 if request.user.is_superuser is True or \
528 grp_drh_recrutement in user_groupes:
529 return True
530 return False
531
532 def has_change_permission(self, request, obj=None):
533 user_groupes = request.user.groups.all()
534 if request.user.is_superuser is True or \
535 grp_drh_recrutement in user_groupes:
536 return True
537 return False
538
539 class CandidatEvaluationAdmin(admin.ModelAdmin):
540 search_fields = ('candidat__nom', 'candidat__prenom' )
541 list_display = ('_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
542 '_commentaire', )
543 readonly_fields = ('candidat', 'evaluateur')
544 list_filter = ('candidat__statut', 'candidat__offre_emploi',)
545 fieldsets = (
546 ('Évaluation du candidat', {
547 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
548 }),
549 )
550
551 def get_actions(self, request):
552 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
553 try:
554 self.evaluateur = Evaluateur.objects.get(user=request.user)
555 except:
556 self.evaluateur = None
557
558 actions = super(CandidatEvaluationAdmin, self).get_actions(request)
559 del actions['delete_selected']
560 return actions
561
562 ### Afficher la note
563 def _note(self, obj):
564 """
565 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
566 un lien pour Évaluer le candidat.
567 Sinon afficher la note.
568 """
569 page = self.model.__name__.lower()
570 redirect_url = 'admin:recrutement_%s_change' % page
571
572 if obj.note is None:
573 label = "Candidat non évalué"
574 else:
575 label = obj.note
576
577 if self.evaluateur == obj.evaluateur:
578 return "<a href='%s'>%s</a>" % (reverse(redirect_url, args=(obj.id,)), label)
579 else:
580 return label
581 _note.allow_tags = True
582 _note.short_description = "Note"
583 _note.admin_order_field = 'note'
584
585 def _statut(self, obj):
586 return obj.candidat.get_statut_display()
587 _statut.order_field = 'candidat__statut'
588 _statut.short_description = 'Statut'
589
590
591 ### Lien en lecture seule vers le candidat
592 def _candidat(self, obj):
593 return "<a href='%s'>%s</a>" \
594 % (reverse('admin:recrutement_proxycandidat_change',
595 args=(obj.candidat.id,)), obj.candidat)
596 _candidat.allow_tags = True
597 _candidat.short_description = 'Candidat'
598
599 ### Afficher commentaire
600 def _commentaire(self, obj):
601 """
602 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
603 dans le champ commentaire, Aucun au lieu de (None)
604 Sinon afficher la note.
605 """
606 if obj.commentaire is None:
607 return "Aucun"
608 return obj.commentaire
609 _commentaire.allow_tags = True
610 _commentaire.short_description = "Commentaire"
611
612 ### Afficher offre d'emploi
613 def _offre_emploi(self, obj):
614 return "<a href='%s'>%s</a>" % \
615 (reverse('admin:recrutement_proxyoffreemploi_change',
616 args=(obj.candidat.offre_emploi.id,)), obj.candidat.offre_emploi)
617 _offre_emploi.allow_tags = True
618 _offre_emploi.short_description = "Voir offre d'emploi"
619
620 def has_add_permission(self, request):
621 return False
622
623 def has_delete_permission(self, request, obj=None):
624 return False
625
626 def has_change_permission(self, request, obj=None):
627 """
628 Permettre la visualisation dans la changelist
629 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
630 le request.user
631 """
632 user_groupes = request.user.groups.all()
633
634 if request.user.is_superuser or \
635 grp_drh_recrutement in user_groupes or \
636 grp_correspondants_rh_recrutement in user_groupes or \
637 grp_directeurs_bureau_recrutement in user_groupes or \
638 grp_administrateurs_recrutement in user_groupes:
639 is_recrutement = True
640 else:
641 is_recrutement = False
642
643 return is_recrutement
644
645 def queryset(self, request):
646 """
647 Afficher uniquement les évaluations de l'évaluateur, sauf si
648 l'utilisateur est dans les groupes suivants.
649 """
650 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
651 user_groupes = request.user.groups.all()
652
653 if grp_drh_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 return qs
658
659 evaluateur = Evaluateur.objects.get(user=request.user)
660 candidats_evaluations = \
661 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
662 candidat__statut__in=('REC', ))
663 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
664 return qs.filter(id__in=candidats_evaluations_ids)
665
666
667 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin):
668
669 def has_change_permission(self, request, obj=None):
670 try:
671 Evaluateur.objects.get(user=request.user)
672 is_evaluateur = True
673 except:
674 is_evaluateur = False
675
676 if obj is None and is_evaluateur:
677 return True
678
679 try:
680 return request.user == obj.evaluateur.user
681 except:
682 return False
683
684 def queryset(self, request):
685 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
686 evaluateur = Evaluateur.objects.get(user=request.user)
687 candidats_evaluations = \
688 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
689 candidat__statut__in=('REC', ))
690 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
691 return qs.filter(id__in=candidats_evaluations_ids)
692
693
694 class CourrielTemplateAdmin(VersionAdmin):
695 ### Actions à afficher
696 def get_actions(self, request):
697 actions = super(CourrielTemplateAdmin, self).get_actions(request)
698 del actions['delete_selected']
699 return actions
700
701 admin.site.register(OffreEmploi, OffreEmploiAdmin)
702 admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin)
703 admin.site.register(Candidat, CandidatAdmin)
704 admin.site.register(ProxyCandidat, ProxyCandidatAdmin)
705 admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
706 admin.site.register(MesCandidatEvaluation, MesCandidatEvaluationAdmin)
707 admin.site.register(Evaluateur, EvaluateurAdmin)
708 admin.site.register(CourrielTemplate, CourrielTemplateAdmin)