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