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