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
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
69 ### Actions à afficher
70 def get_actions(self
, request
):
71 actions
= super(OffreEmploiAdmin
, self
).get_actions(request
)
72 del actions
['delete_selected']
75 ### Affecter un évaluateurs à des offres d'emploi
76 def affecter_evaluateurs_offre_emploi(modeladmin
, obj
, candidats
):
77 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
79 return HttpResponseRedirect(
80 reverse('affecter_evaluateurs_offre_emploi') +
81 "?ids=%s" % (",".join(selected
))
84 affecter_evaluateurs_offre_emploi
.short_description
= \
85 u
'Affecter évaluateur(s)'
87 ### Afficher la liste des candidats pour l'offre d'emploi
88 def _candidatsList(self
, obj
):
89 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
90 </a>" % (reverse('admin:emploi_candidat_changelist'), obj
.id)
91 _candidatsList
.allow_tags
= True
92 _candidatsList
.short_description
= "Afficher la liste des candidats"
95 def get_form(self
, request
, obj
=None, **kwargs
):
96 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
97 employe
= get_emp(request
.user
)
98 user_groupes
= request
.user
.groups
.all()
101 if 'region' in form
.declared_fields
:
102 region_field
= form
.declared_fields
['region']
104 region_field
= form
.base_fields
['region']
106 if grp_drh
in user_groupes
or \
107 grp_drh2
in user_groupes
or \
108 grp_haute_direction
in user_groupes
:
109 region_field
.queryset
= Region
.objects
.all()
111 region_field
.queryset
= Region
.objects
.\
112 filter(id=employe
.implantation
.region
.id)
115 if 'poste' in form
.declared_fields
:
116 poste_field
= form
.declared_fields
['poste']
118 poste_field
= form
.base_fields
['poste']
120 if grp_drh
in user_groupes
or \
121 grp_drh2
in user_groupes
or \
122 grp_haute_direction
in user_groupes
:
123 poste_field
.queryset
= rh
.Poste
.objects
.all()
125 poste_field
.queryset
= rh
.Poste
.objects
.\
126 filter(implantation__region
=employe
.implantation
.region
).\
127 exclude(implantation__in
=IMPLANTATIONS_CENTRALES
)
130 if 'bureau' in form
.declared_fields
:
131 bureau_field
= form
.declared_fields
['bureau']
133 bureau_field
= form
.base_fields
['bureau']
135 if grp_drh
in user_groupes
or \
136 grp_drh2
in user_groupes
or \
137 grp_haute_direction
in user_groupes
:
138 bureau_field
.queryset
= Bureau
.objects
.all()
140 bureau_field
.queryset
= \
141 Bureau
.objects
.filter(region
=employe
.implantation
.region
)
147 def queryset(self
, request
):
148 qs
= self
.model
._default_manager
.get_query_set() \
149 .select_related('offre_emploi')
150 user_groupes
= request
.user
.groups
.all()
151 if grp_drh
in user_groupes
or \
152 grp_drh2
in user_groupes
or \
153 grp_haute_direction
in user_groupes
:
156 if grp_directeurs_bureau
in user_groupes
or \
157 grp_correspondants_rh
in user_groupes
or \
158 grp_administrateurs
in user_groupes
:
159 employe
= get_emp(request
.user
)
160 return qs
.filter(region
=employe
.implantation
.region
)
162 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
163 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
165 e
.candidat
.offre_emploi_id
166 for e
in CandidatEvaluation
.objects
167 .select_related('candidat')
168 .filter(evaluateur
=evaluateur
)
170 return qs
.filter(id__in
=offre_ids
)
174 ### Permission add, delete, change
175 def has_add_permission(self
, request
):
176 user_groupes
= request
.user
.groups
.all()
177 if request
.user
.is_superuser
is True or \
178 grp_drh
in user_groupes
or \
179 grp_drh2
in user_groupes
or \
180 grp_directeurs_bureau
in user_groupes
or \
181 grp_administrateurs
in user_groupes
or \
182 grp_haute_direction
in user_groupes
:
186 def has_delete_permission(self
, request
, obj
=None):
187 user_groupes
= request
.user
.groups
.all()
188 if request
.user
.is_superuser
is True or \
189 grp_drh
in user_groupes
or \
190 grp_drh2
in user_groupes
or \
191 grp_directeurs_bureau
in user_groupes
or \
192 grp_administrateurs
in user_groupes
or \
193 grp_haute_direction
in user_groupes
:
197 def has_change_permission(self
, request
, obj
=None):
198 user_groupes
= request
.user
.groups
.all()
199 if request
.user
.is_superuser
is True or \
200 grp_drh
in user_groupes
or \
201 grp_drh2
in user_groupes
or \
202 grp_directeurs_bureau
in user_groupes
or \
203 grp_administrateurs
in user_groupes
or \
204 grp_haute_direction
in user_groupes
:
209 class ProxyOffreEmploiAdmin(OffreEmploiAdmin
):
211 'nom', 'date_limite', 'region', 'statut', 'est_affiche'
214 'description', 'bureau', 'duree_affectation', 'renumeration',
215 'debut_affectation', 'lieu_affectation', 'nom', 'resume',
216 'date_limite', 'region', 'poste'
222 ('Description générale', {
223 'fields': ('description', 'date_limite',)
226 'fields': ('lieu_affectation', 'bureau', 'region', 'poste',)
230 'debut_affectation', 'duree_affectation', 'renumeration',
236 ### Lieu de redirection après le change
237 def response_change(self
, request
, obj
):
238 return redirect('admin:recrutement_proxyoffreemploi_changelist')
241 def get_form(self
, request
, obj
=None, **kwargs
):
242 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
245 ### Permissions add, delete, change
246 def has_add_permission(self
, request
):
249 def has_delete_permission(self
, request
, obj
=None):
252 def has_change_permission(self
, request
, obj
=None):
256 return not super(ProxyOffreEmploiAdmin
, self
).has_change_permission(request
, obj
)
259 class CandidatPieceInline(admin
.TabularInline
):
260 model
= CandidatPiece
261 fields
= ('candidat', 'nom', 'path',)
266 class ReadOnlyCandidatPieceInline(CandidatPieceInline
):
267 readonly_fields
= ('candidat', 'nom', 'path', )
271 class CandidatEvaluationInlineFormSet(BaseInlineFormSet
):
273 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
275 def __init__(self
, *args
, **kwargs
):
276 super(CandidatEvaluationInlineFormSet
, self
).__init__(*args
, **kwargs
)
277 self
.can_delete
= False
280 class CandidatEvaluationInline(admin
.TabularInline
):
281 model
= CandidatEvaluation
282 fields
= ('evaluateur', 'note', 'commentaire')
285 formset
= CandidatEvaluationInlineFormSet
288 def get_readonly_fields(self
, request
, obj
=None):
290 Empêche la modification des évaluations
293 return self
.readonly_fields
+ ('evaluateur', 'note', 'commentaire')
294 return self
.readonly_fields
296 class CandidatAdmin(BaseAdmin
, VersionAdmin
, ExportAdmin
):
297 change_list_template
= 'admin/recrutement/candidat/change_list.html'
298 search_fields
= ('nom', 'prenom')
299 exclude
= ('actif', )
300 list_editable
= ('statut', )
301 list_display
= ('_candidat', 'offre_emploi',
302 'voir_offre_emploi', 'calculer_moyenne',
303 'afficher_candidat', '_date_creation', 'statut', )
304 list_filter
= ('offre_emploi__nom', 'offre_emploi__region', 'statut', )
308 'fields': ('offre_emploi', )
310 ('Informations personnelles', {
312 'prenom', 'nom', 'genre', 'nationalite',
313 'situation_famille', 'nombre_dependant'
318 'telephone', 'email', 'adresse', 'ville', 'etat_province',
319 'code_postal', 'pays'
322 ('Informations professionnelles', {
324 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
325 'domaine_professionnel'
329 'fields': ('statut', )
334 CandidatEvaluationInline
,
336 actions
= ['envoyer_courriel_candidats', 'changer_statut']
338 export_fields
= ['statut', 'offre_emploi', 'prenom', 'nom', 'genre',
339 'nationalite', 'situation_famille', 'nombre_dependant',
340 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
341 'domaine_professionnel', 'telephone', 'email', 'adresse',
342 'ville', 'etat_province', 'code_postal', 'pays']
344 def _candidat(self
, obj
):
345 txt
= u
"%s %s (%s)" % (obj
.nom
.upper(), obj
.prenom
, obj
.genre
)
346 txt
= textwrap
.wrap(txt
, 30)
347 return "<br/>".join(txt
)
348 _candidat
.short_description
= "Candidat"
349 _candidat
.admin_order_field
= "nom"
350 _candidat
.allow_tags
= True
352 def _date_creation(self
, obj
):
353 return obj
.date_creation
354 _date_creation
.admin_order_field
= "date_creation"
355 _date_creation
.short_description
= "Date de réception"
357 ### Actions à afficher
358 def get_actions(self
, request
):
359 actions
= super(CandidatAdmin
, self
).get_actions(request
)
360 del actions
['delete_selected']
363 ### Envoyer un courriel à des candidats
364 def envoyer_courriel_candidats(modeladmin
, obj
, candidats
):
365 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
367 return HttpResponseRedirect(
368 reverse('selectionner_template') + "?ids=%s" % (",".join(selected
))
370 envoyer_courriel_candidats
.short_description
= u
'Envoyer courriel'
372 ### Changer le statut à des candidats
373 def changer_statut(modeladmin
, request
, queryset
):
374 if request
.POST
.get('post'):
375 queryset
.update(statut
=request
.POST
.get('statut'))
379 'action_checkbox_name': admin
.helpers
.ACTION_CHECKBOX_NAME
,
380 'queryset': queryset
,
381 'status': STATUT_CHOICES
,
384 return render_to_response("recrutement/selectionner_statut.html",
385 context
, context_instance
= RequestContext(request
))
387 changer_statut
.short_description
= u
'Changer statut'
389 ### Évaluer un candidat
390 def evaluer_candidat(self
, obj
):
391 return "<a href='%s?candidat__id__exact=%s'>" \
392 "Évaluer le candidat</a>" % (
393 reverse('admin:recrutement_candidatevaluation_changelist'),
396 evaluer_candidat
.allow_tags
= True
397 evaluer_candidat
.short_description
= 'Évaluation'
399 ### Afficher un candidat
400 def afficher_candidat(self
, obj
):
401 items
= [u
"<li><a href='%s%s'>%s</li>" % \
402 (settings
.OE_PRIVE_MEDIA_URL
, pj
.path
, pj
.get_nom_display()) \
403 for pj
in obj
.pieces_jointes()]
404 html
= "<a href='%s'>Candidature</a>" % (
405 reverse('admin:recrutement_proxycandidat_change', args
=(obj
.id,))
407 return "%s<ul>%s</ul>" % (html
, "\n".join(items
))
408 afficher_candidat
.allow_tags
= True
409 afficher_candidat
.short_description
= u
'Détails du candidat'
411 ### Voir l'offre d'emploi
412 def voir_offre_emploi(self
, obj
):
413 return "<a href='%s'>Voir l'offre d'emploi</a>" % (reverse(
414 'admin:recrutement_proxyoffreemploi_change',
415 args
=(obj
.offre_emploi
.id,)
417 voir_offre_emploi
.allow_tags
= True
418 voir_offre_emploi
.short_description
= "Afficher l'offre d'emploi"
420 ### Calculer la moyenne des notes
421 def calculer_moyenne(self
, obj
):
422 evaluations
= CandidatEvaluation
.objects
.filter(candidat
=obj
)
424 notes
= [evaluation
.note
for evaluation
in evaluations \
425 if evaluation
.note
is not None]
428 moyenne_votes
= round(float(sum(notes
)) / len(notes
), 2)
430 moyenne_votes
= "Non disponible"
432 totales
= len(evaluations
)
435 if obj
.statut
== 'REC':
436 if totales
== faites
:
438 elif faites
> 0 and float(totales
) / float(faites
) >= 2:
445 return """<span style="color: %s;">%s (%s/%s)</span>""" % (
446 color
, moyenne_votes
, faites
, totales
448 calculer_moyenne
.allow_tags
= True
449 calculer_moyenne
.short_description
= "Moyenne"
450 calculer_moyenne
.admin_order_field
= ""
452 ### Permissions add, delete, change
453 def has_add_permission(self
, request
):
454 user_groupes
= request
.user
.groups
.all()
455 if request
.user
.is_superuser
is True or \
456 grp_correspondants_rh
in user_groupes
or \
457 grp_drh
in user_groupes
or \
458 grp_drh2
in user_groupes
or \
459 grp_directeurs_bureau
in user_groupes
or \
460 grp_administrateurs
in user_groupes
or \
461 grp_haute_direction
in user_groupes
:
465 def has_delete_permission(self
, request
, obj
=None):
466 user_groupes
= request
.user
.groups
.all()
467 if request
.user
.is_superuser
is True or \
468 grp_correspondants_rh
in user_groupes
or \
469 grp_drh
in user_groupes
or \
470 grp_drh2
in user_groupes
or \
471 grp_directeurs_bureau
in user_groupes
or \
472 grp_administrateurs
in user_groupes
or \
473 grp_haute_direction
in user_groupes
:
477 def has_change_permission(self
, request
, obj
=None):
478 user_groupes
= request
.user
.groups
.all()
479 if request
.user
.is_superuser
is True or \
480 grp_correspondants_rh
in user_groupes
or \
481 grp_drh
in user_groupes
or \
482 grp_drh2
in user_groupes
or \
483 grp_directeurs_bureau
in user_groupes
or \
484 grp_administrateurs
in user_groupes
or \
485 grp_haute_direction
in user_groupes
:
489 def formfield_for_foreignkey(self
, db_field
, request
, **kwargs
):
490 if db_field
.name
== 'offre_emploi':
491 employe
= get_emp(request
.user
)
492 kwargs
["queryset"] = OffreEmploi
.objects
.filter(region
=employe
.implantation
.region
)
493 return db_field
.formfield(**kwargs
)
494 return super(CandidatAdmin
, self
).formfield_for_foreignkey(db_field
, request
, **kwargs
)
496 def get_changelist(self
, request
, **kwargs
):
497 return OrderedChangeList
499 def queryset(self
, request
):
501 Spécifie un queryset limité, autrement Django exécute un
502 select_related() sans paramètre, ce qui a pour effet de charger tous
503 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
504 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
505 génération d'une requête infinie.
507 qs
= self
.model
._default_manager
.get_query_set() \
508 .select_related('offre_emploi') \
509 .annotate(moyenne
=Avg('evaluations__note'))
511 user_groupes
= request
.user
.groups
.all()
512 if grp_drh
in user_groupes
or \
513 grp_drh2
in user_groupes
or \
514 grp_haute_direction
in user_groupes
:
517 if grp_directeurs_bureau
in user_groupes
or \
518 grp_correspondants_rh
in user_groupes
or \
519 grp_administrateurs
in user_groupes
:
520 employe
= get_emp(request
.user
)
521 return qs
.filter(offre_emploi__region
=employe
.implantation
.region
)
523 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
524 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
525 candidat_ids
= [e
.candidat
.id for e
in
526 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
)]
527 return qs
.filter(id__in
=candidat_ids
)
531 class ProxyCandidatAdmin(CandidatAdmin
):
534 'statut', 'offre_emploi', 'prenom', 'nom', 'genre', 'nationalite',
535 'situation_famille', 'nombre_dependant', 'telephone', 'email',
536 'adresse', 'ville', 'etat_province', 'code_postal', 'pays',
537 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
538 'domaine_professionnel', 'pieces_jointes'
542 'fields': ('offre_emploi', )
544 ('Informations personnelles', {
546 'prenom', 'nom', 'genre', 'nationalite', 'situation_famille',
552 'telephone', 'email', 'adresse', 'ville', 'etat_province',
553 'code_postal', 'pays'
556 ('Informations professionnelles', {
558 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
559 'domaine_professionnel'
563 inlines
= (CandidatEvaluationInline
, )
565 def has_add_permission(self
, request
):
568 def has_delete_permission(self
, request
, obj
=None):
571 def has_change_permission(self
, request
, obj
=None):
573 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
574 for e
in obj
.evaluations
.all():
575 if e
.evaluateur
== evaluateur
:
578 return not super(ProxyCandidatAdmin
, self
).has_change_permission(request
, obj
)
580 def get_actions(self
, request
):
584 class CandidatPieceAdmin(admin
.ModelAdmin
):
585 list_display
= ('nom', 'candidat', )
588 def queryset(self
, request
):
590 Spécifie un queryset limité, autrement Django exécute un
591 select_related() sans paramètre, ce qui a pour effet de charger tous
592 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
593 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
594 génération d'une requête infinie. Affiche la liste de candidats que
595 si le user connecté possède un Evaluateur
597 qs
= self
.model
._default_manager
.get_query_set()
598 return qs
.select_related('candidat')
601 class EvaluateurAdmin(BaseAdmin
, VersionAdmin
):
608 ### Actions à afficher
609 def get_actions(self
, request
):
610 actions
= super(EvaluateurAdmin
, self
).get_actions(request
)
611 del actions
['delete_selected']
614 ### Permissions add, delete, change
615 def has_add_permission(self
, request
):
616 user_groupes
= request
.user
.groups
.all()
617 if request
.user
.is_superuser
is True or \
618 grp_drh
in user_groupes
or \
619 grp_drh2
in user_groupes
or \
620 grp_haute_direction
in user_groupes
:
624 def has_delete_permission(self
, request
, obj
=None):
625 user_groupes
= request
.user
.groups
.all()
626 if request
.user
.is_superuser
is True or \
627 grp_drh
in user_groupes
or \
628 grp_drh2
in user_groupes
or \
629 grp_haute_direction
in user_groupes
:
633 def has_change_permission(self
, request
, obj
=None):
634 user_groupes
= request
.user
.groups
.all()
635 if request
.user
.is_superuser
is True or \
636 grp_drh
in user_groupes
or \
637 grp_drh2
in user_groupes
or \
638 grp_haute_direction
in user_groupes
:
643 class CandidatEvaluationAdmin(BaseAdmin
):
644 search_fields
= ('candidat__nom', 'candidat__prenom')
646 '_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
649 readonly_fields
= ('candidat', 'evaluateur')
650 list_filter
= ('candidat__statut', 'candidat__offre_emploi',)
652 ('Évaluation du candidat', {
653 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
657 def get_actions(self
, request
):
658 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
660 self
.evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
662 self
.evaluateur
= None
664 actions
= super(CandidatEvaluationAdmin
, self
).get_actions(request
)
665 del actions
['delete_selected']
669 def _note(self
, obj
):
671 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
672 un lien pour Évaluer le candidat.
673 Sinon afficher la note.
675 page
= self
.model
.__name__
.lower()
676 redirect_url
= 'admin:recrutement_%s_change' % page
679 label
= "Candidat non évalué"
683 if self
.evaluateur
== obj
.evaluateur
:
684 return "<a href='%s'>%s</a>" % (
685 reverse(redirect_url
, args
=(obj
.id,)), label
689 _note
.allow_tags
= True
690 _note
.short_description
= "Note"
691 _note
.admin_order_field
= 'note'
693 def _statut(self
, obj
):
694 return obj
.candidat
.get_statut_display()
695 _statut
.order_field
= 'candidat__statut'
696 _statut
.short_description
= 'Statut'
698 ### Lien en lecture seule vers le candidat
699 def _candidat(self
, obj
):
700 return "<a href='%s'>%s</a>" \
701 % (reverse('admin:recrutement_proxycandidat_change',
702 args
=(obj
.candidat
.id,)), obj
.candidat
)
703 _candidat
.allow_tags
= True
704 _candidat
.short_description
= 'Candidat'
706 ### Afficher commentaire
707 def _commentaire(self
, obj
):
709 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
710 dans le champ commentaire, Aucun au lieu de (None)
711 Sinon afficher la note.
713 if obj
.commentaire
is None:
715 return obj
.commentaire
716 _commentaire
.allow_tags
= True
717 _commentaire
.short_description
= "Commentaire"
719 ### Afficher offre d'emploi
720 def _offre_emploi(self
, obj
):
721 return "<a href='%s'>%s</a>" % \
722 (reverse('admin:recrutement_proxyoffreemploi_change',
723 args
=(obj
.candidat
.offre_emploi
.id,)), obj
.candidat
.offre_emploi
)
724 _offre_emploi
.allow_tags
= True
725 _offre_emploi
.short_description
= "Voir offre d'emploi"
727 def has_add_permission(self
, request
):
730 def has_delete_permission(self
, request
, obj
=None):
733 def has_change_permission(self
, request
, obj
=None):
735 Permettre la visualisation dans la changelist
736 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
739 user_groupes
= request
.user
.groups
.all()
741 if request
.user
.is_superuser
or \
742 grp_drh
in user_groupes
or \
743 grp_drh2
in user_groupes
or \
744 grp_correspondants_rh
in user_groupes
or \
745 grp_directeurs_bureau
in user_groupes
or \
746 grp_administrateurs
in user_groupes
or \
747 grp_haute_direction
in user_groupes
:
748 is_recrutement
= True
750 is_recrutement
= False
752 return is_recrutement
754 def queryset(self
, request
):
756 Afficher uniquement les évaluations de l'évaluateur, sauf si
757 l'utilisateur est dans les groupes suivants.
759 qs
= self
.model
._default_manager
.get_query_set() \
760 .select_related('offre_emploi')
761 user_groupes
= request
.user
.groups
.all()
763 if grp_drh
in user_groupes
or \
764 grp_drh2
in user_groupes
or \
765 grp_correspondants_rh
in user_groupes
or \
766 grp_directeurs_bureau
in user_groupes
or \
767 grp_administrateurs
in user_groupes
or \
768 grp_haute_direction
in user_groupes
:
769 return qs
.filter(candidat__statut__in
=('REC', 'SEL'))
771 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
772 candidats_evaluations
= \
773 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
774 candidat__statut__in
=('REC', ))
775 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
776 return qs
.filter(id__in
=candidats_evaluations_ids
)
779 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin
):
782 def has_change_permission(self
, request
, obj
=None):
784 Evaluateur
.objects
.get(user
=request
.user
)
787 is_evaluateur
= False
789 if obj
is None and is_evaluateur
:
793 return request
.user
== obj
.evaluateur
.user
797 def queryset(self
, request
):
798 qs
= self
.model
._default_manager
.get_query_set() \
799 .select_related('offre_emploi')
800 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
801 candidats_evaluations
= \
802 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
803 candidat__statut__in
=('REC', ))
804 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
805 return qs
.filter(id__in
=candidats_evaluations_ids
)
808 class CourrielTemplateAdmin(BaseAdmin
, VersionAdmin
):
809 ### Actions à afficher
810 def get_actions(self
, request
):
811 actions
= super(CourrielTemplateAdmin
, self
).get_actions(request
)
812 del actions
['delete_selected']
815 admin
.site
.register(OffreEmploi
, OffreEmploiAdmin
)
816 admin
.site
.register(ProxyOffreEmploi
, ProxyOffreEmploiAdmin
)
817 admin
.site
.register(Candidat
, CandidatAdmin
)
818 admin
.site
.register(ProxyCandidat
, ProxyCandidatAdmin
)
819 admin
.site
.register(CandidatEvaluation
, CandidatEvaluationAdmin
)
820 admin
.site
.register(MesCandidatEvaluation
, MesCandidatEvaluationAdmin
)
821 admin
.site
.register(Evaluateur
, EvaluateurAdmin
)
822 admin
.site
.register(CourrielTemplate
, CourrielTemplateAdmin
)