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