corr RH peut ajouter des candidats a la main
[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 348 if request.user.is_superuser is True or \
07df182e 349 grp_correspondants_rh_recrutement in user_groupes or \
26add0fd 350 grp_drh_recrutement in user_groupes or \
3a542b85 351 grp_directeurs_bureau_recrutement in user_groupes or \
7d9736ba 352 grp_administrateurs_recrutement in user_groupes:
f6724c20 353 return True
3a542b85 354 return False
4896b661 355
f6724c20 356 def has_delete_permission(self, request, obj=None):
3a542b85 357 user_groupes = request.user.groups.all()
26add0fd 358 if request.user.is_superuser is True or \
07df182e 359 grp_correspondants_rh_recrutement in user_groupes or \
26add0fd 360 grp_drh_recrutement in user_groupes or \
3a542b85 361 grp_directeurs_bureau_recrutement in user_groupes or \
7d9736ba 362 grp_administrateurs_recrutement in user_groupes:
3a542b85
NBV
363 return True
364 return False
f6724c20
NBV
365
366 def has_change_permission(self, request, obj=None):
367 user_groupes = request.user.groups.all()
26add0fd 368 if request.user.is_superuser is True or \
940c9dd8 369 grp_correspondants_rh_recrutement in user_groupes or \
26add0fd 370 grp_drh_recrutement in user_groupes or \
3a542b85 371 grp_directeurs_bureau_recrutement in user_groupes or \
7d9736ba 372 grp_administrateurs_recrutement in user_groupes:
f6724c20 373 return True
97b168d6
OL
374 return False
375
376 def get_changelist(self, request, **kwargs):
377 return OrderedChangeList
4896b661 378
d46075cb 379 def queryset(self, request):
f9983b5a 380 """
8ea41642 381 Spécifie un queryset limité, autrement Django exécute un
382 select_related() sans paramètre, ce qui a pour effet de charger tous
383 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
384 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
385 génération d'une requête infinie.
d835c9f3 386
f9983b5a 387 """
97b168d6
OL
388
389 qs = self.model._default_manager.get_query_set().select_related('offre_emploi').annotate(moyenne=Avg('evaluations__note'))
390
d46075cb 391 user_groupes = request.user.groups.all()
7d9736ba 392 if grp_drh_recrutement in user_groupes:
d6790a12 393 return qs
7d9736ba
NBV
394
395 if grp_directeurs_bureau_recrutement in user_groupes or \
940c9dd8 396 grp_correspondants_rh_recrutement in user_groupes or \
7d9736ba
NBV
397 grp_administrateurs_recrutement in user_groupes:
398 employe = get_emp(request.user)
d6790a12 399 return qs.filter(offre_emploi__region=employe.implantation.region)
7d9736ba 400
c69ecb4f 401 if Evaluateur.objects.filter(user=request.user).exists():
940c9dd8
OL
402 evaluateur = Evaluateur.objects.get(user=request.user)
403 candidat_ids = [e.candidat.id for e in
404 CandidatEvaluation.objects.filter(evaluateur=evaluateur)]
d6790a12 405 return qs.filter(id__in=candidat_ids)
7d9736ba 406 return qs.none()
f6724c20 407
613e8dfe 408
f6724c20 409class ProxyCandidatAdmin(CandidatAdmin):
940c9dd8 410 list_editable = ()
f6724c20 411 readonly_fields = ('statut', 'offre_emploi', 'prenom', 'nom',
4fd0c4a2
NBV
412 'genre', 'nationalite', 'situation_famille',
413 'nombre_dependant', 'telephone', 'email', 'adresse',
414 'ville', 'etat_province', 'code_postal', 'pays',
415 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
8e0d552d 416 'domaine_professionnel', 'pieces_jointes',)
2d083449
NBV
417 fieldsets = (
418 ("Offre d'emploi", {
419 'fields': ('offre_emploi', )
420 }),
421 ('Informations personnelles', {
4fd0c4a2 422 'fields': ('prenom','nom','genre', 'nationalite',
2d083449
NBV
423 'situation_famille', 'nombre_dependant',)
424 }),
425 ('Coordonnées', {
426 'fields': ('telephone', 'email', 'adresse', 'ville',
427 'etat_province', 'code_postal', 'pays', )
428 }),
429 ('Informations professionnelles', {
430 'fields': ('niveau_diplome','employeur_actuel',
431 'poste_actuel', 'domaine_professionnel',)
8e0d552d 432 }),
2d083449 433 )
c69ecb4f 434 inlines = (CandidatEvaluationInline, )
2d083449 435
f6724c20
NBV
436 def has_add_permission(self, request):
437 return False
438
439 def has_delete_permission(self, request, obj=None):
440 return False
2adf9e0c 441
2d083449 442 def has_change_permission(self, request, obj=None):
c69ecb4f 443 return True
2d083449 444
fe6fe6bb
OL
445 def get_actions(self, request):
446 return None
447
2e9ee615 448class CandidatPieceAdmin(admin.ModelAdmin):
170c9aa2 449 list_display = ('nom', 'candidat', )
450
7d9736ba 451 ### Queryset
170c9aa2 452 def queryset(self, request):
453 """
454 Spécifie un queryset limité, autrement Django exécute un
455 select_related() sans paramètre, ce qui a pour effet de charger tous
456 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
457 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
458 génération d'une requête infinie.
d835c9f3 459 Affiche la liste de candidats que si le user connecté
27c81d11 460 possède un Evaluateur
170c9aa2 461 """
462 qs = self.model._default_manager.get_query_set()
463 return qs.select_related('candidat')
2e9ee615 464
d2b30f5f 465class EvaluateurAdmin(VersionAdmin):
eb579d40 466 fieldsets = (
540dfae4
NBV
467 ("Utilisateur", {
468 'fields': ('user',)
469 }),
eb579d40 470 )
4418c732 471
7d9736ba 472 ### Actions à afficher
a029f641
NBV
473 def get_actions(self, request):
474 actions = super(EvaluateurAdmin, self).get_actions(request)
475 del actions['delete_selected']
540dfae4 476 return actions
a029f641 477
7d9736ba
NBV
478 ### Permissions add, delete, change
479 def has_add_permission(self, request):
480 user_groupes = request.user.groups.all()
26add0fd 481 if request.user.is_superuser is True or \
783ee3f6 482 grp_drh_recrutement in user_groupes:
7d9736ba
NBV
483 return True
484 return False
485
486 def has_delete_permission(self, request, obj=None):
487 user_groupes = request.user.groups.all()
26add0fd 488 if request.user.is_superuser is True or \
783ee3f6 489 grp_drh_recrutement in user_groupes:
7d9736ba
NBV
490 return True
491 return False
492
493 def has_change_permission(self, request, obj=None):
494 user_groupes = request.user.groups.all()
26add0fd 495 if request.user.is_superuser is True or \
783ee3f6 496 grp_drh_recrutement in user_groupes:
7d9736ba
NBV
497 return True
498 return False
27c81d11 499
940c9dd8
OL
500class CandidatEvaluationAdmin(admin.ModelAdmin):
501 search_fields = ('candidat__nom', 'candidat__prenom' )
502 list_display = ('_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
b903198b 503 '_commentaire', )
940c9dd8
OL
504 readonly_fields = ('candidat', 'evaluateur')
505 list_filter = ('candidat__statut', 'candidat__offre_emploi',)
beef7690
NBV
506 fieldsets = (
507 ('Évaluation du candidat', {
508 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
509 }),
510 )
511
a029f641 512 def get_actions(self, request):
5fe6986f
OL
513 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
514 try:
515 self.evaluateur = Evaluateur.objects.get(user=request.user)
516 except:
517 self.evaluateur = None
518
a029f641
NBV
519 actions = super(CandidatEvaluationAdmin, self).get_actions(request)
520 del actions['delete_selected']
540dfae4 521 return actions
a029f641 522
7d9736ba 523 ### Afficher la note
beef7690
NBV
524 def _note(self, obj):
525 """
526 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
527 un lien pour Évaluer le candidat.
528 Sinon afficher la note.
529 """
c44cb3de
OL
530 page = self.model.__name__.lower()
531 redirect_url = 'admin:recrutement_%s_change' % page
5fe6986f 532
beef7690 533 if obj.note is None:
5fe6986f
OL
534 label = "Candidat non évalué"
535 else:
536 label = obj.note
537
538 if self.evaluateur == obj.evaluateur:
539 return "<a href='%s'>%s</a>" % (reverse(redirect_url, args=(obj.id,)), label)
540 else:
541 return label
beef7690 542 _note.allow_tags = True
7d0ae1ba 543 _note.short_description = "Note"
beef7690
NBV
544 _note.admin_order_field = 'note'
545
940c9dd8
OL
546 def _statut(self, obj):
547 return obj.candidat.get_statut_display()
548 _statut.order_field = 'candidat__statut'
549 _statut.short_description = 'Statut'
550
551
7d9736ba 552 ### Lien en lecture seule vers le candidat
beef7690
NBV
553 def _candidat(self, obj):
554 return "<a href='%s'>%s</a>" \
555 % (reverse('admin:recrutement_proxycandidat_change',
556 args=(obj.candidat.id,)), obj.candidat)
557 _candidat.allow_tags = True
558 _candidat.short_description = 'Candidat'
559
7d9736ba 560 ### Afficher commentaire
beef7690
NBV
561 def _commentaire(self, obj):
562 """
563 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
564 dans le champ commentaire, Aucun au lieu de (None)
565 Sinon afficher la note.
566 """
567 if obj.commentaire is None:
568 return "Aucun"
569 return obj.commentaire
570 _commentaire.allow_tags = True
571 _commentaire.short_description = "Commentaire"
720c3ad5 572
7d9736ba 573 ### Afficher offre d'emploi
beef7690
NBV
574 def _offre_emploi(self, obj):
575 return "<a href='%s'>%s</a>" % \
576 (reverse('admin:recrutement_proxyoffreemploi_change',
dc7faf2b 577 args=(obj.candidat.offre_emploi.id,)), obj.candidat.offre_emploi)
beef7690
NBV
578 _offre_emploi.allow_tags = True
579 _offre_emploi.short_description = "Voir offre d'emploi"
beef7690 580
7d9736ba 581 def has_add_permission(self, request):
940c9dd8
OL
582 return False
583
584 def has_delete_permission(self, request, obj=None):
585 return False
7d9736ba 586
21b02da5
NBV
587 def has_change_permission(self, request, obj=None):
588 """
589 Permettre la visualisation dans la changelist
590 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
591 le request.user
592 """
f133459f
OL
593 user_groupes = request.user.groups.all()
594
3bc5ea42
OL
595 if request.user.is_superuser or \
596 grp_drh_recrutement in user_groupes or \
f133459f
OL
597 grp_correspondants_rh_recrutement in user_groupes or \
598 grp_directeurs_bureau_recrutement in user_groupes or \
599 grp_administrateurs_recrutement in user_groupes:
c5a263d6 600 is_recrutement = True
f133459f 601 else:
6c6c51bb 602 is_recrutement = False
f133459f
OL
603
604 try:
605 Evaluateur.objects.get(user=request.user)
606 is_evaluateur = True
607 except:
608 is_evaluateur = False
609
610 if obj is None and (is_recrutement or is_evaluateur):
940c9dd8
OL
611 return True
612
26add0fd
OL
613 if request.user.is_superuser is True:
614 return True
940c9dd8 615
f133459f
OL
616 try:
617 return request.user == obj.evaluateur.user
618 except:
619 return False
21b02da5 620
7d9736ba 621 ### Queryset
720c3ad5 622 def queryset(self, request):
beef7690
NBV
623 """
624 Afficher uniquement les évaluations de l'évaluateur, sauf si
7d9736ba 625 l'utilisateur est dans les groupes suivants.
beef7690 626 """
940c9dd8 627 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
beef7690 628 user_groupes = request.user.groups.all()
940c9dd8 629
3a542b85 630 if grp_drh_recrutement in user_groupes or \
940c9dd8 631 grp_correspondants_rh_recrutement in user_groupes or \
3a542b85 632 grp_directeurs_bureau_recrutement in user_groupes or \
7d9736ba 633 grp_administrateurs_recrutement in user_groupes:
940c9dd8
OL
634 return qs
635
636 evaluateur = Evaluateur.objects.get(user=request.user)
637 candidats_evaluations = \
638 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
639 candidat__statut__in=('REC', ))
640 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
641 return qs.filter(id__in=candidats_evaluations_ids)
596fe324 642
3bc5ea42
OL
643
644class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin):
645
646 def has_change_permission(self, request, obj=None):
647 try:
648 Evaluateur.objects.get(user=request.user)
649 is_evaluateur = True
650 except:
651 is_evaluateur = False
652
5fe6986f 653 if obj is None and is_evaluateur:
3bc5ea42
OL
654 return True
655
656 try:
657 return request.user == obj.evaluateur.user
658 except:
659 return False
660
661 def queryset(self, request):
662 qs = self.model._default_manager.get_query_set().select_related('offre_emploi')
663 evaluateur = Evaluateur.objects.get(user=request.user)
664 candidats_evaluations = \
665 CandidatEvaluation.objects.filter(evaluateur=evaluateur,
666 candidat__statut__in=('REC', ))
667 candidats_evaluations_ids = [ce.id for ce in candidats_evaluations]
668 return qs.filter(id__in=candidats_evaluations_ids)
669
670
4e8340cf 671class CourrielTemplateAdmin(VersionAdmin):
7d9736ba 672 ### Actions à afficher
a029f641
NBV
673 def get_actions(self, request):
674 actions = super(CourrielTemplateAdmin, self).get_actions(request)
675 del actions['delete_selected']
540dfae4 676 return actions
4e8340cf 677
df59fcab 678admin.site.register(OffreEmploi, OffreEmploiAdmin)
382501c1 679admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin)
df59fcab 680admin.site.register(Candidat, CandidatAdmin)
382501c1 681admin.site.register(ProxyCandidat, ProxyCandidatAdmin)
720c3ad5 682admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
3bc5ea42 683admin.site.register(MesCandidatEvaluation, MesCandidatEvaluationAdmin)
27c81d11 684admin.site.register(Evaluateur, EvaluateurAdmin)
32834000 685admin.site.register(CourrielTemplate, CourrielTemplateAdmin)