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