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