Début du tableau de bord des évaluations pour les Évaluateurs
[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
38df74bb 6from django.shortcuts import get_object_or_404
7
6067184b 8from reversion.admin import VersionAdmin
38df74bb 9from datamaster_modeles.models import Employe, Implantation, Region
6067184b 10
df59fcab 11from recrutement.models import *
f6724c20
NBV
12from recrutement.workflow import grp_administrateurs_recrutement,\
13 grp_evaluateurs_recrutement, grp_drh_recrutement
df59fcab 14
d2b30f5f 15class OffreEmploiAdmin(VersionAdmin):
7f9e891e 16 date_hierarchy = 'date_creation'
ec517164 17 list_display = ('nom', 'resume', 'date_limite', 'region', '_candidatsList')
f6724c20 18
8941aee7 19 # Afficher la liste des candidats pour l'offre d'emploi
596fe324 20 def _candidatsList(self, obj):
8ea41642 21 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
22 </a>" % (reverse('admin:recrutement_candidat_changelist'), obj.id)
2f78949d 23 _candidatsList.allow_tags = True
f6724c20 24 _candidatsList.short_description = "Afficher la liste des candidats"
362a3534 25
2f78949d 26 def queryset(self, request):
2f78949d 27 qs = self.model._default_manager.get_query_set()
f6724c20
NBV
28 # Si user est superuser afficher toutes les offres d'emploi
29 user_groupes = request.user.groups.all()
30 if not grp_drh_recrutement in user_groupes:
31 # Si le user n'est ni un évaluateur ni un administrateur régional,
32 # retourner none
33 # Vérifier groupes
34 if grp_evaluateurs_recrutement in user_groupes:
35 user = Evaluateur.objects.get(user=request.user)
36 elif grp_administrateurs_recrutement in user_groupes:
37 user = AdministrateurRegional.objects.get(user=request.user)
38 else:
39 return qs.none()
40
41 if type(user) is AdministrateurRegional:
42 region_ids = [g.id for g in user.regions.all()]
43 return qs.select_related('offre_emploi').\
44 filter(region__in=region_ids)
45 if type(user) is Evaluateur:
46
47 candidats = [g for g in user.candidats.all()]
48 offre_emploi_ids = [offre.id for offre in candidats]
49 return qs.select_related('offre_emploi').\
50 filter(id__in=offre_emploi_ids)
51
3bcef02d 52 return qs.none()
f6724c20
NBV
53 return qs.select_related('offre_emploi')
54
55 def has_change_permission(self, request, obj=None):
56 user_groupes = request.user.groups.all()
57 if grp_drh_recrutement in user_groupes or \
58 grp_administrateurs_recrutement in user_groupes:
59 return True
60 return False
61
62class ProxyOffreEmploiAdmin(OffreEmploiAdmin):
63 list_display = ('nom', 'resume', 'date_limite', 'region', '_candidatsList', )
64 readonly_fields = ('actif', 'description', 'poste', 'bureau',
65 'duree_affectation', 'renumeration',
66 'debut_affectation', 'lieu_affectation', 'nom',
67 'resume', 'date_limite', 'region')
68 fieldsets = (
720c3ad5 69 ('Nom', {
f6724c20
NBV
70 'fields': ('nom', )
71 }),
720c3ad5 72 ('Description générale', {
f6724c20
NBV
73 'fields': ('poste', 'resume','description', 'date_limite', )
74 }),
720c3ad5 75 ('Coordonnées', {
f6724c20
NBV
76 'fields': ('lieu_affectation', 'bureau', 'region', )
77 }),
720c3ad5 78 ('Autre', {
f6724c20
NBV
79 'fields': ('debut_affectation', 'duree_affectation',
80 'renumeration', )
81 }),
82 )
83 def has_add_permission(self, request):
84 return False
85
86 def has_delete_permission(self, request, obj=None):
87 return False
88
2d083449
NBV
89 def has_change_permission(self, request, obj=None):
90 user_groupes = request.user.groups.all()
91 if grp_evaluateurs_recrutement in user_groupes:
92 return True
93 return False
94
f6724c20
NBV
95 def _candidatsList(self, obj):
96 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
97 </a>" % (reverse('admin:recrutement_proxycandidat_changelist'),
98 obj.id)
99 _candidatsList.allow_tags = True
100 _candidatsList.short_description = "Afficher la liste des candidats"
362a3534 101
cced6a23 102class ProxyCandidatPiece(CandidatPiece):
103 """
104 Ce proxy sert uniquement dans l'admin à disposer d'un libellé
105 plus ergonomique.
106 """
107 class Meta:
108 proxy = True
109 verbose_name = "pièce jointe"
74cbc7a7 110 verbose_name_plural = "pièces jointes"
cced6a23 111
170c9aa2 112class CandidatPieceInline(admin.TabularInline):
cced6a23 113 model = ProxyCandidatPiece
114 fields = ('candidat', 'nom', 'path', )
170c9aa2 115 extra = 1
116
27c81d11 117class ProxyEvaluateur(Evaluateur.candidats.through):
cced6a23 118 """
119 Ce proxy sert uniquement dans l'admin à disposer d'un libellé
120 plus ergonomique.
121 """
122 class Meta:
123 proxy = True
124 verbose_name = "évaluateur"
125
eb579d40 126class EvaluateurInline(admin.TabularInline):
cced6a23 127 model = ProxyEvaluateur
720c3ad5 128 fields = ('evaluateur',)
eb579d40 129 extra = 1
130
d2b30f5f 131class CandidatAdmin(VersionAdmin):
7f9e891e 132 date_hierarchy = 'date_creation'
0fd8a26d 133 list_display = ('nom', 'prenom', 'offre_emploi','statut',
720c3ad5 134 'voir_offre_emploi', #'note_evaluateur',
8941aee7 135 'calculer_moyenne', 'afficher_candidat',)
8ea41642 136 list_filter = ('offre_emploi', )
7f9e891e 137 fieldsets = (
4896b661 138 ("Offre d'emploi", {
139 'fields': ('offre_emploi', )
140 }),
7f9e891e 141 ('Informations personnelles', {
142 'fields': ('prenom','nom','genre', 'nationalite', 'date_naissance',
143 'situation_famille', 'nombre_dependant',)
144 }),
ec517164 145 ('Coordonnées', {
146 'fields': ('telephone', 'email', 'adresse', 'ville',
147 'etat_province', 'code_postal', 'pays', )
7f9e891e 148 }),
149 ('Informations professionnelles', {
4896b661 150 'fields': ('niveau_diplome','employeur_actuel',
8ea41642 151 'poste_actuel', 'domaine_professionnel',)
7f9e891e 152 }),
153 ('Options avancées', {
154 'classes': ('collapse',),
155 'fields': ('actif', 'statut', )
156 }),
157 )
170c9aa2 158 inlines = [
159 CandidatPieceInline,
eb579d40 160 EvaluateurInline,
170c9aa2 161 ]
f9983b5a 162
4e8340cf 163 actions = ['affecter_candidats_evaluateur', 'envoyer_courriel_candidats']
362a3534 164 # Affecter un évaluateurs à des candidats
7061f835 165 def affecter_candidats_evaluateur(modeladmin, obj, candidats):
596fe324 166 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
2adf9e0c 167
8ea41642 168 return HttpResponseRedirect(reverse('affecter_evaluateurs_candidats')+
169 "?ids=%s" % (",".join(selected)))
d835c9f3 170 affecter_candidats_evaluateur.short_description = u'Affecter évaluateur'
362a3534 171
4e8340cf 172 # Envoyer un courriel à des candidats
52765380 173 def envoyer_courriel_candidats(modeladmin, obj, candidats):
174 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
175
176 return HttpResponseRedirect(reverse('envoyer_courriel_candidats')+
177 "?ids=%s" % (",".join(selected)))
178 envoyer_courriel_candidats.short_description = u'Envoyer courriel'
179
05503d56 180 # Évaluer un candidat
596fe324 181 def evaluer_candidat(self, obj):
8ea41642 182 return "<a href='%s?id=%s'>Évaluer le candidat \
183 </a>" % (reverse('evaluer_candidat'), obj.id)
596fe324 184 evaluer_candidat.allow_tags = True
720c3ad5 185 evaluer_candidat.short_description = 'Note du candidat'
596fe324 186
7d82fd33 187 # Afficher un candidat
188 def afficher_candidat(self, obj):
720c3ad5
NBV
189 return "<a href='%s'>Voir le candidat </a>" \
190 % (reverse('admin:recrutement_proxycandidat_change', args=(obj.id,)))
7d82fd33 191 afficher_candidat.allow_tags = True
f6724c20 192 afficher_candidat.short_description = u'Afficher les détails du candidat'
7d82fd33 193
8941aee7 194 # Voir l'offre d'emploi
195 def voir_offre_emploi(self, obj):
720c3ad5
NBV
196 return "<a href='%s'>Voir l'offre d'emploi</a>" % \
197 (reverse('admin:recrutement_proxyoffreemploi_change',
198 args=(obj.offre_emploi.id,)))
8941aee7 199 voir_offre_emploi.allow_tags = True
200 voir_offre_emploi.short_description = "Afficher l'offre d'emploi"
201
202 """ # Afficher note poster par l'évaluateur
203 def note_evaluateur(self, obj):
204 import pdb;pdb.set_trace()
27c81d11 205 evaluateur = Evaluateur.objects.get(user=obj.user)
8941aee7 206 import pdb;pdb.set_trace()
207 note_eval = CandidatEvaluation.objects.filter(evaluateur=evaluateur,
208 candidat=obj.user)
209 return "blabla"
210 note_evaluateur.allow_tags = True
211 note_evaluateur.short_description = "Votre note"
212 """
213
214 # Calculer la moyenne des notes
215 def calculer_moyenne(self, obj):
216 evaluations = CandidatEvaluation.objects.filter(candidat=obj)
217 offre_emploi = obj.offre_emploi
218
f6724c20
NBV
219 notes = [evaluation.note for evaluation in evaluations.all() \
220 if evaluation.note is not None]
8941aee7 221
222 if len(notes) > 0 and offre_emploi.date_limite <= datetime.date.today():
223 moyenne_votes = float(sum(notes)) / len(notes)
224 else:
225 moyenne_votes = "Non disponible"
226 return moyenne_votes
227 calculer_moyenne.allow_tags = True
228 calculer_moyenne.short_description = "Moyenne des notes"
229
f6724c20
NBV
230 def add_delete_permission(self, request, obj=None) :
231 user_groupes = request.user.groups.all()
232 if grp_drh_recrutement in user_groupes or \
233 grp_administrateurs_recrutement in user_groupes:
234 return True
235 return False
4896b661 236
f6724c20
NBV
237 def has_add_permission(self, request):
238 return self.add_delete_permission(request, request)
4896b661 239
f6724c20
NBV
240 def has_delete_permission(self, request, obj=None):
241 return self.add_delete_permission(request, request)
242
243 def has_change_permission(self, request, obj=None):
244 user_groupes = request.user.groups.all()
245 if grp_drh_recrutement in user_groupes or \
2d083449 246 grp_administrateurs_recrutement in user_groupes:
f6724c20
NBV
247 return True
248 return False
4896b661 249
596fe324 250 def queryset(self, obj):
f9983b5a 251 """
8ea41642 252 Spécifie un queryset limité, autrement Django exécute un
253 select_related() sans paramètre, ce qui a pour effet de charger tous
254 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
255 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
256 génération d'une requête infinie.
d835c9f3 257
f9983b5a 258 """
f6724c20
NBV
259 qs = self.model._default_manager.get_query_set()
260 # Si user est superuser afficher tous les candidats
261 user_groupes = obj.user.groups.all()
262 if not grp_drh_recrutement in user_groupes:
263 # Si le user n'est ni un évaluateur ni un administrateur régional,
264 # retourner none
265
266 # Vérifier groupes
267 if grp_evaluateurs_recrutement in user_groupes:
268 user = Evaluateur.objects.get(user=obj.user)
269 #elif grp_administrateurs_recrutement in user_groupes:
270 # user = AdministrateurRegional.objects.get(user=obj.user)
271 else:
272 return qs.none()
273
274 ids = [c.id for c in user.candidats.all()]
275 return qs.select_related('candidats').filter(id__in=ids)
276 return qs.select_related('candidats')
277
278class ProxyCandidatAdmin(CandidatAdmin):
279 #TODO: init boucler sur les fields pour le readonly
720c3ad5
NBV
280 list_display = ('nom', 'prenom','statut', 'offre_emploi',
281 'voir_offre_emploi', 'evaluer_candidat', 'afficher_candidat')#'note_evaluateur',)
f6724c20
NBV
282 readonly_fields = ('statut', 'offre_emploi', 'prenom', 'nom',
283 'genre', 'nationalite', 'date_naissance',
284 'situation_famille', 'nombre_dependant', 'telephone',
285 'email', 'adresse', 'ville', 'etat_province',
286 'code_postal', 'pays', 'niveau_diplome',
287 'employeur_actuel', 'poste_actuel',
288 'domaine_professionnel',)
2d083449
NBV
289 fieldsets = (
290 ("Offre d'emploi", {
291 'fields': ('offre_emploi', )
292 }),
293 ('Informations personnelles', {
294 'fields': ('prenom','nom','genre', 'nationalite', 'date_naissance',
295 'situation_famille', 'nombre_dependant',)
296 }),
297 ('Coordonnées', {
298 'fields': ('telephone', 'email', 'adresse', 'ville',
299 'etat_province', 'code_postal', 'pays', )
300 }),
301 ('Informations professionnelles', {
302 'fields': ('niveau_diplome','employeur_actuel',
303 'poste_actuel', 'domaine_professionnel',)
304 }),
305 )
f6724c20 306 inlines = []
2d083449 307
f6724c20
NBV
308 def has_add_permission(self, request):
309 return False
310
311 def has_delete_permission(self, request, obj=None):
312 return False
2adf9e0c 313
2d083449
NBV
314 def has_change_permission(self, request, obj=None):
315 user_groupes = request.user.groups.all()
316 if grp_evaluateurs_recrutement in user_groupes:
317 return True
318 return False
319
2e9ee615 320class CandidatPieceAdmin(admin.ModelAdmin):
170c9aa2 321 list_display = ('nom', 'candidat', )
322
323 def queryset(self, request):
324 """
325 Spécifie un queryset limité, autrement Django exécute un
326 select_related() sans paramètre, ce qui a pour effet de charger tous
327 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
328 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
329 génération d'une requête infinie.
d835c9f3 330 Affiche la liste de candidats que si le user connecté
27c81d11 331 possède un Evaluateur
170c9aa2 332 """
333 qs = self.model._default_manager.get_query_set()
334 return qs.select_related('candidat')
2e9ee615 335
d2b30f5f 336class EvaluateurAdmin(VersionAdmin):
eb579d40 337 fieldsets = (
f6724c20 338 (None, {'fields': ('user', )}),
720c3ad5 339 #(None, {'fields': ('candidats',)}),
eb579d40 340 )
4418c732 341
f6724c20 342 # Peut-être qu'on peut enlever cette def, à cause des permissions
d835c9f3 343 def queryset(self, request):
344 """
345 Affiche la liste d'évaluateur que si le user connecté
27c81d11 346 possède un Evaluateur
d835c9f3 347 """
720c3ad5 348 user_groupes = request.user.groups.all()
f6724c20
NBV
349 if grp_drh_recrutement in user_groupes:
350 return self.model._default_manager.get_query_set()
351
352 return qs.none()
d835c9f3 353
b89fef74 354class AdministrateurRegionalAdmin(VersionAdmin):
27c81d11 355 pass
356
d2b30f5f 357class CandidatEvaluationAdmin(VersionAdmin):
720c3ad5
NBV
358 list_display = ('candidat', 'offre_emploi_candidat', 'evaluateur', 'note',
359 'commentaire', 'date',)
360
361 def offre_emploi_candidat(self, obj):
362 return obj.candidat.offre_emploi
363
364 def queryset(self, request):
365 evaluateur = Evaluateur.objects.get(user=request.user)
366 candidats = Candidat.objects.filter(evaluateurs=evaluateur)
367 candidats_evaluations = CandidatEvaluation.objects.\
368 filter(evaluateur=evaluateur,
369 candidat__in=candidats)
370 qs = self.model._default_manager.get_query_set()
371 candidats_evaluations_ids = [ce.id for ce in \
372 candidats_evaluations.all()]
373 return qs.select_related('offre_emploi')#.\
374 #filter(id__in=candidats_evaluations_ids)
596fe324 375
4e8340cf 376class CourrielTemplateAdmin(VersionAdmin):
377 pass
378
df59fcab 379admin.site.register(OffreEmploi, OffreEmploiAdmin)
380admin.site.register(Candidat, CandidatAdmin)
720c3ad5 381admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
4e8340cf 382admin.site.register(CourrielTemplate, CourrielTemplateAdmin)
27c81d11 383admin.site.register(Evaluateur, EvaluateurAdmin)
b89fef74 384admin.site.register(AdministrateurRegional, AdministrateurRegionalAdmin)
f6724c20
NBV
385admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin)
386admin.site.register(ProxyCandidat, ProxyCandidatAdmin)