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