order by moyenne
[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
2e9ee615 443class CandidatPieceAdmin(admin.ModelAdmin):
170c9aa2 444 list_display = ('nom', 'candidat', )
445
7d9736ba 446 ### Queryset
170c9aa2 447 def queryset(self, request):
448 """
449 Spécifie un queryset limité, autrement Django exécute un
450 select_related() sans paramètre, ce qui a pour effet de charger tous
451 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
452 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
453 génération d'une requête infinie.
d835c9f3 454 Affiche la liste de candidats que si le user connecté
27c81d11 455 possède un Evaluateur
170c9aa2 456 """
457 qs = self.model._default_manager.get_query_set()
458 return qs.select_related('candidat')
2e9ee615 459
d2b30f5f 460class EvaluateurAdmin(VersionAdmin):
eb579d40 461 fieldsets = (
540dfae4
NBV
462 ("Utilisateur", {
463 'fields': ('user',)
464 }),
eb579d40 465 )
4418c732 466
7d9736ba 467 ### Actions à afficher
a029f641
NBV
468 def get_actions(self, request):
469 actions = super(EvaluateurAdmin, self).get_actions(request)
470 del actions['delete_selected']
540dfae4 471 return actions
a029f641 472
7d9736ba
NBV
473 ### Permissions add, delete, change
474 def has_add_permission(self, request):
475 user_groupes = request.user.groups.all()
26add0fd
OL
476 if request.user.is_superuser is True or \
477 grp_drh_recrutement in user_groupes or \
7d9736ba
NBV
478 grp_directeurs_bureau_recrutement in user_groupes or \
479 grp_administrateurs_recrutement in user_groupes:
480 return True
481 return False
482
483 def has_delete_permission(self, request, obj=None):
484 user_groupes = request.user.groups.all()
26add0fd
OL
485 if request.user.is_superuser is True or \
486 grp_drh_recrutement in user_groupes or \
7d9736ba
NBV
487 grp_directeurs_bureau_recrutement in user_groupes or \
488 grp_administrateurs_recrutement in user_groupes:
489 return True
490 return False
491
492 def has_change_permission(self, request, obj=None):
493 user_groupes = request.user.groups.all()
26add0fd
OL
494 if request.user.is_superuser is True or \
495 grp_drh_recrutement in user_groupes or \
7d9736ba
NBV
496 grp_directeurs_bureau_recrutement in user_groupes or \
497 grp_administrateurs_recrutement in user_groupes:
498 return True
499 return False
27c81d11 500
940c9dd8
OL
501class CandidatEvaluationAdmin(admin.ModelAdmin):
502 search_fields = ('candidat__nom', 'candidat__prenom' )
503 list_display = ('_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
b903198b 504 '_commentaire', )
940c9dd8
OL
505 readonly_fields = ('candidat', 'evaluateur')
506 list_filter = ('candidat__statut', 'candidat__offre_emploi',)
beef7690
NBV
507 fieldsets = (
508 ('Évaluation du candidat', {
509 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
510 }),
511 )
512
a029f641 513 def get_actions(self, request):
5fe6986f
OL
514 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
515 try:
516 self.evaluateur = Evaluateur.objects.get(user=request.user)
517 except:
518 self.evaluateur = None
519
a029f641
NBV
520 actions = super(CandidatEvaluationAdmin, self).get_actions(request)
521 del actions['delete_selected']
540dfae4 522 return actions
a029f641 523
7d9736ba 524 ### Afficher la note
beef7690
NBV
525 def _note(self, obj):
526 """
527 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
528 un lien pour Évaluer le candidat.
529 Sinon afficher la note.
530 """
c44cb3de
OL
531 page = self.model.__name__.lower()
532 redirect_url = 'admin:recrutement_%s_change' % page
5fe6986f 533
beef7690 534 if obj.note is None:
5fe6986f
OL
535 label = "Candidat non évalué"
536 else:
537 label = obj.note
538
539 if self.evaluateur == obj.evaluateur:
540 return "<a href='%s'>%s</a>" % (reverse(redirect_url, args=(obj.id,)), label)
541 else:
542 return label
beef7690 543 _note.allow_tags = True
7d0ae1ba 544 _note.short_description = "Note"
beef7690
NBV
545 _note.admin_order_field = 'note'
546
940c9dd8
OL
547 def _statut(self, obj):
548 return obj.candidat.get_statut_display()
549 _statut.order_field = 'candidat__statut'
550 _statut.short_description = 'Statut'
551
552
7d9736ba 553 ### Lien en lecture seule vers le candidat
beef7690
NBV
554 def _candidat(self, obj):
555 return "<a href='%s'>%s</a>" \
556 % (reverse('admin:recrutement_proxycandidat_change',
557 args=(obj.candidat.id,)), obj.candidat)
558 _candidat.allow_tags = True
559 _candidat.short_description = 'Candidat'
560
7d9736ba 561 ### Afficher commentaire
beef7690
NBV
562 def _commentaire(self, obj):
563 """
564 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
565 dans le champ commentaire, Aucun au lieu de (None)
566 Sinon afficher la note.
567 """
568 if obj.commentaire is None:
569 return "Aucun"
570 return obj.commentaire
571 _commentaire.allow_tags = True
572 _commentaire.short_description = "Commentaire"
720c3ad5 573
7d9736ba 574 ### Afficher offre d'emploi
beef7690
NBV
575 def _offre_emploi(self, obj):
576 return "<a href='%s'>%s</a>" % \
577 (reverse('admin:recrutement_proxyoffreemploi_change',
dc7faf2b 578 args=(obj.candidat.offre_emploi.id,)), obj.candidat.offre_emploi)
beef7690
NBV
579 _offre_emploi.allow_tags = True
580 _offre_emploi.short_description = "Voir offre d'emploi"
beef7690 581
7d9736ba 582 def has_add_permission(self, request):
940c9dd8
OL
583 return False
584
585 def has_delete_permission(self, request, obj=None):
586 return False
7d9736ba 587
21b02da5
NBV
588 def has_change_permission(self, request, obj=None):
589 """
590 Permettre la visualisation dans la changelist
591 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
592 le request.user
593 """
f133459f
OL
594 user_groupes = request.user.groups.all()
595
3bc5ea42
OL
596 if request.user.is_superuser or \
597 grp_drh_recrutement in user_groupes or \
f133459f
OL
598 grp_correspondants_rh_recrutement in user_groupes or \
599 grp_directeurs_bureau_recrutement in user_groupes or \
600 grp_administrateurs_recrutement in user_groupes:
c5a263d6 601 is_recrutement = True
f133459f 602 else:
6c6c51bb 603 is_recrutement = False
f133459f
OL
604
605 try:
606 Evaluateur.objects.get(user=request.user)
607 is_evaluateur = True
608 except:
609 is_evaluateur = False
610
611 if obj is None and (is_recrutement or is_evaluateur):
940c9dd8
OL
612 return True
613
26add0fd
OL
614 if request.user.is_superuser is True:
615 return True
940c9dd8 616
f133459f
OL
617 try:
618 return request.user == obj.evaluateur.user
619 except:
620 return False
21b02da5 621
7d9736ba 622 ### Queryset
720c3ad5 623 def queryset(self, request):
beef7690
NBV
624 """
625 Afficher uniquement les évaluations de l'évaluateur, sauf si
7d9736ba 626 l'utilisateur est dans les groupes suivants.
beef7690 627 """
940c9dd8 628 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
beef7690 629 user_groupes = request.user.groups.all()
940c9dd8 630
3a542b85 631 if grp_drh_recrutement in user_groupes or \
940c9dd8 632 grp_correspondants_rh_recrutement in user_groupes or \
3a542b85 633 grp_directeurs_bureau_recrutement in user_groupes or \
7d9736ba 634 grp_administrateurs_recrutement in user_groupes:
940c9dd8
OL
635 return qs
636
637 evaluateur = Evaluateur.objects.get(user=request.user)
638 candidats_evaluations = \
639 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
640 candidat__statut__in=('REC', ))
641 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
642 return qs.filter(id__in=candidats_evaluations_ids)
596fe324 643
3bc5ea42
OL
644
645class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin):
646
647 def has_change_permission(self, request, obj=None):
648 try:
649 Evaluateur.objects.get(user=request.user)
650 is_evaluateur = True
651 except:
652 is_evaluateur = False
653
5fe6986f 654 if obj is None and is_evaluateur:
3bc5ea42
OL
655 return True
656
657 try:
658 return request.user == obj.evaluateur.user
659 except:
660 return False
661
662 def queryset(self, request):
663 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
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
4e8340cf 672class CourrielTemplateAdmin(VersionAdmin):
7d9736ba 673 ### Actions à afficher
a029f641
NBV
674 def get_actions(self, request):
675 actions = super(CourrielTemplateAdmin, self).get_actions(request)
676 del actions['delete_selected']
540dfae4 677 return actions
4e8340cf 678
df59fcab 679admin.site.register(OffreEmploi, OffreEmploiAdmin)
382501c1 680admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin)
df59fcab 681admin.site.register(Candidat, CandidatAdmin)
382501c1 682admin.site.register(ProxyCandidat, ProxyCandidatAdmin)
720c3ad5 683admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
3bc5ea42 684admin.site.register(MesCandidatEvaluation, MesCandidatEvaluationAdmin)
27c81d11 685admin.site.register(Evaluateur, EvaluateurAdmin)
32834000 686admin.site.register(CourrielTemplate, CourrielTemplateAdmin)