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