1 # -*- encoding: utf-8 -*-
5 from django
.conf
import settings
6 from django
.contrib
import admin
7 from django
.core
.urlresolvers
import reverse
8 from django
.db
.models
import Avg
9 from django
.shortcuts
import render_to_response
10 from django
.template
import RequestContext
12 from auf
.django
.emploi
.models
import STATUT_CHOICES
13 from django
.forms
.models
import BaseInlineFormSet
14 from django
.http
import HttpResponseRedirect
15 from django
.shortcuts
import redirect
16 from reversion
.admin
import VersionAdmin
18 from auf
.django
.emploi
.models
import OffreEmploi
, Candidat
, CandidatPiece
19 from auf
.django
.references
.models
import Region
, Bureau
, Implantation
20 from auf
.django
.export
.admin
import ExportAdmin
22 from project
.groups
import get_employe_from_user
as get_emp
23 from project
.rh
import models
as rh
25 from project
.recrutement
.forms
import OffreEmploiForm
26 from project
.recrutement
.groups
import \
28 grp_directeurs_bureau
, \
29 grp_administrateurs
, \
30 grp_correspondants_rh
, \
32 from project
.recrutement
.models
import \
33 Evaluateur
, CandidatEvaluation
, \
34 ProxyOffreEmploi
, ProxyCandidat
, MesCandidatEvaluation
, \
39 IMPLANTATIONS_CENTRALES
= [15, 19]
42 class BaseAdmin(admin
.ModelAdmin
):
45 css
= {'screen': ('css/admin_custom.css',)}
48 class OrderedChangeList(admin
.views
.main
.ChangeList
):
50 Surcharge pour appliquer le order_by d'un annotate
52 def get_query_set(self
):
53 qs
= super(OrderedChangeList
, self
).get_query_set()
54 qs
= qs
.order_by('-moyenne')
58 class OffreEmploiAdmin(BaseAdmin
, VersionAdmin
):
59 date_hierarchy
= 'date_creation'
61 'nom', 'date_limite', 'region', 'statut', 'est_affiche',
64 exclude
= ('actif', 'poste_nom', 'resume',)
65 list_filter
= ('statut',)
66 actions
= ['affecter_evaluateurs_offre_emploi', ]
67 form
= OffreEmploiForm
87 ### Actions à afficher
88 def get_actions(self
, request
):
89 actions
= super(OffreEmploiAdmin
, self
).get_actions(request
)
90 del actions
['delete_selected']
93 ### Affecter un évaluateurs à des offres d'emploi
94 def affecter_evaluateurs_offre_emploi(modeladmin
, obj
, candidats
):
95 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
97 return HttpResponseRedirect(
98 reverse('affecter_evaluateurs_offre_emploi') +
99 "?ids=%s" % (",".join(selected
))
102 affecter_evaluateurs_offre_emploi
.short_description
= \
103 u
'Affecter évaluateur(s)'
105 ### Afficher la liste des candidats pour l'offre d'emploi
106 def _candidatsList(self
, obj
):
107 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
108 </a>" % (reverse('admin:emploi_candidat_changelist'), obj
.id)
109 _candidatsList
.allow_tags
= True
110 _candidatsList
.short_description
= "Afficher la liste des candidats"
113 def get_form(self
, request
, obj
=None, **kwargs
):
114 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
115 employe
= get_emp(request
.user
)
116 user_groupes
= request
.user
.groups
.all()
119 if 'region' in form
.declared_fields
:
120 region_field
= form
.declared_fields
['region']
122 region_field
= form
.base_fields
['region']
124 if grp_drh
in user_groupes
or \
125 grp_drh2
in user_groupes
or \
126 grp_haute_direction
in user_groupes
:
127 region_field
.queryset
= Region
.objects
.all()
129 region_field
.queryset
= Region
.objects
.\
130 filter(id=employe
.implantation
.region
.id)
133 if 'poste' in form
.declared_fields
:
134 poste_field
= form
.declared_fields
['poste']
136 poste_field
= form
.base_fields
['poste']
138 if grp_drh
in user_groupes
or \
139 grp_drh2
in user_groupes
or \
140 grp_haute_direction
in user_groupes
:
141 poste_field
.queryset
= rh
.Poste
.objects
.all()
143 poste_field
.queryset
= rh
.Poste
.objects
.\
144 filter(implantation__region
=employe
.implantation
.region
).\
145 exclude(implantation__in
=IMPLANTATIONS_CENTRALES
)
148 if 'bureau' in form
.declared_fields
:
149 bureau_field
= form
.declared_fields
['bureau']
151 bureau_field
= form
.base_fields
['bureau']
153 if grp_drh
in user_groupes
or \
154 grp_drh2
in user_groupes
or \
155 grp_haute_direction
in user_groupes
:
156 bureau_field
.queryset
= Bureau
.objects
.all()
158 bureau_field
.queryset
= \
159 Bureau
.objects
.filter(region
=employe
.implantation
.region
)
165 def queryset(self
, request
):
166 qs
= self
.model
._default_manager
.get_query_set() \
167 .select_related('offre_emploi')
168 user_groupes
= request
.user
.groups
.all()
169 if grp_drh
in user_groupes
or \
170 grp_drh2
in user_groupes
or \
171 grp_haute_direction
in user_groupes
:
174 if grp_directeurs_bureau
in user_groupes
or \
175 grp_correspondants_rh
in user_groupes
or \
176 grp_administrateurs
in user_groupes
:
177 employe
= get_emp(request
.user
)
178 return qs
.filter(region
=employe
.implantation
.region
)
180 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
181 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
183 e
.candidat
.offre_emploi_id
184 for e
in CandidatEvaluation
.objects
185 .select_related('candidat')
186 .filter(evaluateur
=evaluateur
)
188 return qs
.filter(id__in
=offre_ids
)
192 ### Permission add, delete, change
193 def has_add_permission(self
, request
):
194 user_groupes
= request
.user
.groups
.all()
195 if request
.user
.is_superuser
is True or \
196 grp_drh
in user_groupes
or \
197 grp_drh2
in user_groupes
or \
198 grp_directeurs_bureau
in user_groupes
or \
199 grp_administrateurs
in user_groupes
or \
200 grp_haute_direction
in user_groupes
:
204 def has_delete_permission(self
, request
, obj
=None):
205 user_groupes
= request
.user
.groups
.all()
206 if request
.user
.is_superuser
is True or \
207 grp_drh
in user_groupes
or \
208 grp_drh2
in user_groupes
or \
209 grp_directeurs_bureau
in user_groupes
or \
210 grp_administrateurs
in user_groupes
or \
211 grp_haute_direction
in user_groupes
:
215 def has_change_permission(self
, request
, obj
=None):
216 user_groupes
= request
.user
.groups
.all()
217 if request
.user
.is_superuser
is True or \
218 grp_drh
in user_groupes
or \
219 grp_drh2
in user_groupes
or \
220 grp_directeurs_bureau
in user_groupes
or \
221 grp_administrateurs
in user_groupes
or \
222 grp_haute_direction
in user_groupes
:
226 def formfield_for_foreignkey(self
, db_field
, request
, **kwargs
):
227 if db_field
.name
== 'lieu_affectation':
228 employe
= get_emp(request
.user
)
229 kwargs
["queryset"] = Implantation
.objects
.filter(region
=employe
.implantation
.region
)
230 return db_field
.formfield(**kwargs
)
231 return super(OffreEmploiAdmin
, self
).formfield_for_foreignkey(db_field
, request
, **kwargs
)
234 class ProxyOffreEmploiAdmin(OffreEmploiAdmin
):
236 'nom', 'date_limite', 'region', 'statut', 'est_affiche'
239 'description', 'bureau', 'duree_affectation', 'renumeration',
240 'debut_affectation', 'lieu_affectation', 'nom', 'resume',
241 'date_limite', 'region', 'poste'
247 ('Description générale', {
248 'fields': ('description', 'date_limite',)
251 'fields': ('lieu_affectation', 'bureau', 'region', 'poste',)
255 'debut_affectation', 'duree_affectation', 'renumeration',
261 ### Lieu de redirection après le change
262 def response_change(self
, request
, obj
):
263 return redirect('admin:recrutement_proxyoffreemploi_changelist')
266 def get_form(self
, request
, obj
=None, **kwargs
):
267 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
270 ### Permissions add, delete, change
271 def has_add_permission(self
, request
):
274 def has_delete_permission(self
, request
, obj
=None):
277 def has_change_permission(self
, request
, obj
=None):
281 return not super(ProxyOffreEmploiAdmin
, self
).has_change_permission(request
, obj
)
284 class CandidatPieceInline(admin
.TabularInline
):
285 model
= CandidatPiece
286 fields
= ('candidat', 'nom', 'path',)
291 class ReadOnlyCandidatPieceInline(CandidatPieceInline
):
292 readonly_fields
= ('candidat', 'nom', 'path', )
296 class CandidatEvaluationInlineFormSet(BaseInlineFormSet
):
298 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
300 def __init__(self
, *args
, **kwargs
):
301 super(CandidatEvaluationInlineFormSet
, self
).__init__(*args
, **kwargs
)
302 self
.can_delete
= False
305 class CandidatEvaluationInline(admin
.TabularInline
):
306 model
= CandidatEvaluation
307 fields
= ('evaluateur', 'note', 'commentaire')
310 formset
= CandidatEvaluationInlineFormSet
313 def get_readonly_fields(self
, request
, obj
=None):
315 Empêche la modification des évaluations
318 return self
.readonly_fields
+ ('evaluateur', 'note', 'commentaire')
319 return self
.readonly_fields
321 class CandidatAdmin(BaseAdmin
, VersionAdmin
, ExportAdmin
):
322 change_list_template
= 'admin/recrutement/candidat/change_list.html'
323 search_fields
= ('nom', 'prenom')
324 exclude
= ('actif', )
325 list_editable
= ('statut', )
326 list_display
= ('_candidat', 'offre_emploi',
327 'voir_offre_emploi', 'calculer_moyenne',
328 'afficher_candidat', '_date_creation', 'statut', )
329 list_filter
= ('offre_emploi__nom', 'offre_emploi__region', 'statut', )
333 'fields': ('offre_emploi', )
335 ('Informations personnelles', {
337 'nom', 'prenom', 'genre', 'nationalite',
338 'situation_famille', 'nombre_dependant'
343 'telephone', 'email', 'adresse', 'ville', 'etat_province',
344 'code_postal', 'pays'
347 ('Informations professionnelles', {
349 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
350 'domaine_professionnel'
354 'fields': ('statut', )
359 CandidatEvaluationInline
,
361 actions
= ['envoyer_courriel_candidats', 'changer_statut']
363 export_fields
= ['statut', 'offre_emploi', 'prenom', 'nom', 'genre',
364 'nationalite', 'situation_famille', 'nombre_dependant',
365 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
366 'domaine_professionnel', 'telephone', 'email', 'adresse',
367 'ville', 'etat_province', 'code_postal', 'pays']
369 def _candidat(self
, obj
):
370 txt
= u
"%s %s (%s)" % (obj
.nom
.upper(), obj
.prenom
, obj
.genre
)
371 txt
= textwrap
.wrap(txt
, 30)
372 return "<br/>".join(txt
)
373 _candidat
.short_description
= "Candidat"
374 _candidat
.admin_order_field
= "nom"
375 _candidat
.allow_tags
= True
377 def _date_creation(self
, obj
):
378 return obj
.date_creation
379 _date_creation
.admin_order_field
= "date_creation"
380 _date_creation
.short_description
= "Date de réception"
382 ### Actions à afficher
383 def get_actions(self
, request
):
384 actions
= super(CandidatAdmin
, self
).get_actions(request
)
385 del actions
['delete_selected']
388 ### Envoyer un courriel à des candidats
389 def envoyer_courriel_candidats(modeladmin
, obj
, candidats
):
390 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
392 return HttpResponseRedirect(
393 reverse('selectionner_template') + "?ids=%s" % (",".join(selected
))
395 envoyer_courriel_candidats
.short_description
= u
'Envoyer courriel'
397 ### Changer le statut à des candidats
398 def changer_statut(modeladmin
, request
, queryset
):
399 if request
.POST
.get('post'):
400 queryset
.update(statut
=request
.POST
.get('statut'))
404 'action_checkbox_name': admin
.helpers
.ACTION_CHECKBOX_NAME
,
405 'queryset': queryset
,
406 'status': STATUT_CHOICES
,
409 return render_to_response("recrutement/selectionner_statut.html",
410 context
, context_instance
= RequestContext(request
))
412 changer_statut
.short_description
= u
'Changer statut'
414 ### Évaluer un candidat
415 def evaluer_candidat(self
, obj
):
416 return "<a href='%s?candidat__id__exact=%s'>" \
417 "Évaluer le candidat</a>" % (
418 reverse('admin:recrutement_candidatevaluation_changelist'),
421 evaluer_candidat
.allow_tags
= True
422 evaluer_candidat
.short_description
= 'Évaluation'
424 ### Afficher un candidat
425 def afficher_candidat(self
, obj
):
426 items
= [u
"<li><a href='%s%s'>%s</li>" % \
427 (settings
.OE_PRIVE_MEDIA_URL
, pj
.path
, pj
.get_nom_display()) \
428 for pj
in obj
.pieces_jointes()]
429 html
= "<a href='%s'>Candidature</a>" % (
430 reverse('admin:recrutement_proxycandidat_change', args
=(obj
.id,))
432 return "%s<ul>%s</ul>" % (html
, "\n".join(items
))
433 afficher_candidat
.allow_tags
= True
434 afficher_candidat
.short_description
= u
'Détails du candidat'
436 ### Voir l'offre d'emploi
437 def voir_offre_emploi(self
, obj
):
438 return "<a href='%s'>Voir l'offre d'emploi</a>" % (reverse(
439 'admin:recrutement_proxyoffreemploi_change',
440 args
=(obj
.offre_emploi
.id,)
442 voir_offre_emploi
.allow_tags
= True
443 voir_offre_emploi
.short_description
= "Afficher l'offre d'emploi"
445 ### Calculer la moyenne des notes
446 def calculer_moyenne(self
, obj
):
447 evaluations
= CandidatEvaluation
.objects
.filter(candidat
=obj
)
449 notes
= [evaluation
.note
for evaluation
in evaluations \
450 if evaluation
.note
is not None]
453 moyenne_votes
= round(float(sum(notes
)) / len(notes
), 2)
455 moyenne_votes
= "Non disponible"
457 totales
= len(evaluations
)
460 if obj
.statut
== 'REC':
461 if totales
== faites
:
463 elif faites
> 0 and float(totales
) / float(faites
) >= 2:
470 return """<span style="color: %s;">%s (%s/%s)</span>""" % (
471 color
, moyenne_votes
, faites
, totales
473 calculer_moyenne
.allow_tags
= True
474 calculer_moyenne
.short_description
= "Moyenne"
475 calculer_moyenne
.admin_order_field
= ""
477 ### Permissions add, delete, change
478 def has_add_permission(self
, request
):
479 user_groupes
= request
.user
.groups
.all()
480 if request
.user
.is_superuser
is True or \
481 grp_correspondants_rh
in user_groupes
or \
482 grp_drh
in user_groupes
or \
483 grp_drh2
in user_groupes
or \
484 grp_directeurs_bureau
in user_groupes
or \
485 grp_administrateurs
in user_groupes
or \
486 grp_haute_direction
in user_groupes
:
490 def has_delete_permission(self
, request
, obj
=None):
491 user_groupes
= request
.user
.groups
.all()
492 if request
.user
.is_superuser
is True or \
493 grp_correspondants_rh
in user_groupes
or \
494 grp_drh
in user_groupes
or \
495 grp_drh2
in user_groupes
or \
496 grp_directeurs_bureau
in user_groupes
or \
497 grp_administrateurs
in user_groupes
or \
498 grp_haute_direction
in user_groupes
:
502 def has_change_permission(self
, request
, obj
=None):
503 user_groupes
= request
.user
.groups
.all()
504 if request
.user
.is_superuser
is True or \
505 grp_correspondants_rh
in user_groupes
or \
506 grp_drh
in user_groupes
or \
507 grp_drh2
in user_groupes
or \
508 grp_directeurs_bureau
in user_groupes
or \
509 grp_administrateurs
in user_groupes
or \
510 grp_haute_direction
in user_groupes
:
514 def formfield_for_foreignkey(self
, db_field
, request
, **kwargs
):
515 if db_field
.name
== 'offre_emploi':
516 employe
= get_emp(request
.user
)
517 kwargs
["queryset"] = OffreEmploi
.objects
.filter(region
=employe
.implantation
.region
)
518 return db_field
.formfield(**kwargs
)
519 return super(CandidatAdmin
, self
).formfield_for_foreignkey(db_field
, request
, **kwargs
)
521 def get_changelist(self
, request
, **kwargs
):
522 return OrderedChangeList
524 def queryset(self
, request
):
526 Spécifie un queryset limité, autrement Django exécute un
527 select_related() sans paramètre, ce qui a pour effet de charger tous
528 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
529 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
530 génération d'une requête infinie.
532 qs
= self
.model
._default_manager
.get_query_set() \
533 .select_related('offre_emploi') \
534 .annotate(moyenne
=Avg('evaluations__note'))
536 user_groupes
= request
.user
.groups
.all()
537 if grp_drh
in user_groupes
or \
538 grp_drh2
in user_groupes
or \
539 grp_haute_direction
in user_groupes
:
542 if grp_directeurs_bureau
in user_groupes
or \
543 grp_correspondants_rh
in user_groupes
or \
544 grp_administrateurs
in user_groupes
:
545 employe
= get_emp(request
.user
)
546 return qs
.filter(offre_emploi__region
=employe
.implantation
.region
)
548 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
549 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
550 candidat_ids
= [e
.candidat
.id for e
in
551 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
)]
552 return qs
.filter(id__in
=candidat_ids
)
556 class ProxyCandidatAdmin(CandidatAdmin
):
559 'statut', 'offre_emploi', 'prenom', 'nom', 'genre', 'nationalite',
560 'situation_famille', 'nombre_dependant', 'telephone', 'email',
561 'adresse', 'ville', 'etat_province', 'code_postal', 'pays',
562 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
563 'domaine_professionnel', 'pieces_jointes'
567 'fields': ('offre_emploi', )
569 ('Informations personnelles', {
571 'prenom', 'nom', 'genre', 'nationalite', 'situation_famille',
577 'telephone', 'email', 'adresse', 'ville', 'etat_province',
578 'code_postal', 'pays'
581 ('Informations professionnelles', {
583 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
584 'domaine_professionnel'
588 inlines
= (CandidatEvaluationInline
, )
590 def has_add_permission(self
, request
):
593 def has_delete_permission(self
, request
, obj
=None):
596 def has_change_permission(self
, request
, obj
=None):
598 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
599 for e
in obj
.evaluations
.all():
600 if e
.evaluateur
== evaluateur
:
603 return not super(ProxyCandidatAdmin
, self
).has_change_permission(request
, obj
)
605 def get_actions(self
, request
):
609 class CandidatPieceAdmin(admin
.ModelAdmin
):
610 list_display
= ('nom', 'candidat', )
613 def queryset(self
, request
):
615 Spécifie un queryset limité, autrement Django exécute un
616 select_related() sans paramètre, ce qui a pour effet de charger tous
617 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
618 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
619 génération d'une requête infinie. Affiche la liste de candidats que
620 si le user connecté possède un Evaluateur
622 qs
= self
.model
._default_manager
.get_query_set()
623 return qs
.select_related('candidat')
626 class EvaluateurAdmin(BaseAdmin
, VersionAdmin
):
633 ### Actions à afficher
634 def get_actions(self
, request
):
635 actions
= super(EvaluateurAdmin
, self
).get_actions(request
)
636 del actions
['delete_selected']
639 ### Permissions add, delete, change
640 def has_add_permission(self
, request
):
641 user_groupes
= request
.user
.groups
.all()
642 if request
.user
.is_superuser
is True or \
643 grp_drh
in user_groupes
or \
644 grp_drh2
in user_groupes
or \
645 grp_haute_direction
in user_groupes
:
649 def has_delete_permission(self
, request
, obj
=None):
650 user_groupes
= request
.user
.groups
.all()
651 if request
.user
.is_superuser
is True or \
652 grp_drh
in user_groupes
or \
653 grp_drh2
in user_groupes
or \
654 grp_haute_direction
in user_groupes
:
658 def has_change_permission(self
, request
, obj
=None):
659 user_groupes
= request
.user
.groups
.all()
660 if request
.user
.is_superuser
is True or \
661 grp_drh
in user_groupes
or \
662 grp_drh2
in user_groupes
or \
663 grp_haute_direction
in user_groupes
:
668 class CandidatEvaluationAdmin(BaseAdmin
):
669 search_fields
= ('candidat__nom', 'candidat__prenom')
671 '_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
674 readonly_fields
= ('candidat', 'evaluateur')
675 list_filter
= ('candidat__statut', 'candidat__offre_emploi',)
677 ('Évaluation du candidat', {
678 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
682 def get_actions(self
, request
):
683 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
685 self
.evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
687 self
.evaluateur
= None
689 actions
= super(CandidatEvaluationAdmin
, self
).get_actions(request
)
690 del actions
['delete_selected']
694 def _note(self
, obj
):
696 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
697 un lien pour Évaluer le candidat.
698 Sinon afficher la note.
700 page
= self
.model
.__name__
.lower()
701 redirect_url
= 'admin:recrutement_%s_change' % page
704 label
= "Candidat non évalué"
708 if self
.evaluateur
== obj
.evaluateur
:
709 return "<a href='%s'>%s</a>" % (
710 reverse(redirect_url
, args
=(obj
.id,)), label
714 _note
.allow_tags
= True
715 _note
.short_description
= "Note"
716 _note
.admin_order_field
= 'note'
718 def _statut(self
, obj
):
719 return obj
.candidat
.get_statut_display()
720 _statut
.order_field
= 'candidat__statut'
721 _statut
.short_description
= 'Statut'
723 ### Lien en lecture seule vers le candidat
724 def _candidat(self
, obj
):
725 return "<a href='%s'>%s</a>" \
726 % (reverse('admin:recrutement_proxycandidat_change',
727 args
=(obj
.candidat
.id,)), obj
.candidat
)
728 _candidat
.allow_tags
= True
729 _candidat
.short_description
= 'Candidat'
731 ### Afficher commentaire
732 def _commentaire(self
, obj
):
734 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
735 dans le champ commentaire, Aucun au lieu de (None)
736 Sinon afficher la note.
738 if obj
.commentaire
is None:
740 return obj
.commentaire
741 _commentaire
.allow_tags
= True
742 _commentaire
.short_description
= "Commentaire"
744 ### Afficher offre d'emploi
745 def _offre_emploi(self
, obj
):
746 return "<a href='%s'>%s</a>" % \
747 (reverse('admin:recrutement_proxyoffreemploi_change',
748 args
=(obj
.candidat
.offre_emploi
.id,)), obj
.candidat
.offre_emploi
)
749 _offre_emploi
.allow_tags
= True
750 _offre_emploi
.short_description
= "Voir offre d'emploi"
752 def has_add_permission(self
, request
):
755 def has_delete_permission(self
, request
, obj
=None):
758 def has_change_permission(self
, request
, obj
=None):
760 Permettre la visualisation dans la changelist
761 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
764 user_groupes
= request
.user
.groups
.all()
766 if request
.user
.is_superuser
or \
767 grp_drh
in user_groupes
or \
768 grp_drh2
in user_groupes
or \
769 grp_correspondants_rh
in user_groupes
or \
770 grp_directeurs_bureau
in user_groupes
or \
771 grp_administrateurs
in user_groupes
or \
772 grp_haute_direction
in user_groupes
:
773 is_recrutement
= True
775 is_recrutement
= False
777 return is_recrutement
779 def queryset(self
, request
):
781 Afficher uniquement les évaluations de l'évaluateur, sauf si
782 l'utilisateur est dans les groupes suivants.
784 qs
= self
.model
._default_manager
.get_query_set() \
785 .select_related('offre_emploi')
786 user_groupes
= request
.user
.groups
.all()
788 if grp_drh
in user_groupes
or \
789 grp_drh2
in user_groupes
or \
790 grp_correspondants_rh
in user_groupes
or \
791 grp_directeurs_bureau
in user_groupes
or \
792 grp_administrateurs
in user_groupes
or \
793 grp_haute_direction
in user_groupes
:
794 return qs
.filter(candidat__statut__in
=('REC', 'SEL'))
796 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
797 candidats_evaluations
= \
798 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
799 candidat__statut__in
=('REC', ))
800 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
801 return qs
.filter(id__in
=candidats_evaluations_ids
)
804 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin
):
807 def has_change_permission(self
, request
, obj
=None):
809 Evaluateur
.objects
.get(user
=request
.user
)
812 is_evaluateur
= False
814 if obj
is None and is_evaluateur
:
818 return request
.user
== obj
.evaluateur
.user
822 def queryset(self
, request
):
823 qs
= self
.model
._default_manager
.get_query_set() \
824 .select_related('offre_emploi')
825 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
826 candidats_evaluations
= \
827 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
828 candidat__statut__in
=('REC', ))
829 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
830 return qs
.filter(id__in
=candidats_evaluations_ids
)
833 class CourrielTemplateAdmin(BaseAdmin
, VersionAdmin
):
834 ### Actions à afficher
835 def get_actions(self
, request
):
836 actions
= super(CourrielTemplateAdmin
, self
).get_actions(request
)
837 del actions
['delete_selected']
840 admin
.site
.register(OffreEmploi
, OffreEmploiAdmin
)
841 admin
.site
.register(ProxyOffreEmploi
, ProxyOffreEmploiAdmin
)
842 admin
.site
.register(Candidat
, CandidatAdmin
)
843 admin
.site
.register(ProxyCandidat
, ProxyCandidatAdmin
)
844 admin
.site
.register(CandidatEvaluation
, CandidatEvaluationAdmin
)
845 admin
.site
.register(MesCandidatEvaluation
, MesCandidatEvaluationAdmin
)
846 admin
.site
.register(Evaluateur
, EvaluateurAdmin
)
847 admin
.site
.register(CourrielTemplate
, CourrielTemplateAdmin
)