1 # -*- encoding: utf-8 -*-
5 from auf
.django
.emploi
.models
import OffreEmploi
, Candidat
, CandidatPiece
6 from auf
.django
.references
.models
import Region
, Bureau
7 from django
.conf
import settings
8 from django
.contrib
import admin
9 from django
.core
.urlresolvers
import reverse
10 from django
.db
.models
import Avg
11 from django
.forms
.models
import BaseInlineFormSet
12 from django
.http
import HttpResponseRedirect
13 from django
.shortcuts
import redirect
14 from reversion
.admin
import VersionAdmin
16 from project
.groups
import get_employe_from_user
as get_emp
17 from project
.rh
import models
as rh
18 from project
.recrutement
.forms
import OffreEmploiForm
19 from project
.recrutement
.groups
import \
21 grp_directeurs_bureau
, \
22 grp_administrateurs
, \
23 grp_correspondants_rh
, \
25 from project
.recrutement
.models
import \
26 Evaluateur
, CandidatEvaluation
, \
27 ProxyOffreEmploi
, ProxyCandidat
, MesCandidatEvaluation
, \
31 IMPLANTATIONS_CENTRALES
= [15, 19]
34 class BaseAdmin(admin
.ModelAdmin
):
38 'css/admin_custom.css',
39 'jquery-autocomplete/jquery.autocomplete.css',
42 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',
43 'jquery-autocomplete/jquery.autocomplete.min.js',
47 class OrderedChangeList(admin
.views
.main
.ChangeList
):
49 Surcharge pour appliquer le order_by d'un annotate
51 def get_query_set(self
):
52 qs
= super(OrderedChangeList
, self
).get_query_set()
53 qs
= qs
.order_by('-moyenne')
57 class OffreEmploiAdminMixin(BaseAdmin
):
58 date_hierarchy
= 'date_creation'
60 'nom', 'date_limite', 'region', 'statut', 'est_affiche',
63 exclude
= ('actif', 'poste_nom', 'resume',)
64 list_filter
= ('statut',)
65 actions
= ['affecter_evaluateurs_offre_emploi', ]
66 form
= OffreEmploiForm
68 ### Actions à afficher
69 def get_actions(self
, request
):
70 actions
= super(OffreEmploiAdmin
, self
).get_actions(request
)
71 del actions
['delete_selected']
74 ### Affecter un évaluateurs à des offres d'emploi
75 def affecter_evaluateurs_offre_emploi(modeladmin
, obj
, candidats
):
76 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
78 return HttpResponseRedirect(
79 reverse('affecter_evaluateurs_offre_emploi') +
80 "?ids=%s" % (",".join(selected
))
83 affecter_evaluateurs_offre_emploi
.short_description
= \
84 u
'Affecter évaluateur(s)'
86 ### Afficher la liste des candidats pour l'offre d'emploi
87 def _candidatsList(self
, obj
):
88 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
89 </a>" % (reverse('admin:recrutement_candidat_changelist'), obj
.id)
90 _candidatsList
.allow_tags
= True
91 _candidatsList
.short_description
= "Afficher la liste des candidats"
94 def get_form(self
, request
, obj
=None, **kwargs
):
95 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
96 employe
= get_emp(request
.user
)
97 user_groupes
= request
.user
.groups
.all()
100 if 'region' in form
.declared_fields
:
101 region_field
= form
.declared_fields
['region']
103 region_field
= form
.base_fields
['region']
105 if grp_drh
in user_groupes
or \
106 grp_drh2
in user_groupes
or \
107 grp_haute_direction
in user_groupes
:
108 region_field
.queryset
= Region
.objects
.all()
110 region_field
.queryset
= Region
.objects
.\
111 filter(id=employe
.implantation
.region
.id)
114 if 'poste' in form
.declared_fields
:
115 poste_field
= form
.declared_fields
['poste']
117 poste_field
= form
.base_fields
['poste']
119 if grp_drh
in user_groupes
or \
120 grp_drh2
in user_groupes
or \
121 grp_haute_direction
in user_groupes
:
122 poste_field
.queryset
= rh
.Poste
.objects
.all()
124 poste_field
.queryset
= rh
.Poste
.objects
.\
125 filter(implantation__region
=employe
.implantation
.region
).\
126 exclude(implantation__in
=IMPLANTATIONS_CENTRALES
)
129 if 'bureau' in form
.declared_fields
:
130 bureau_field
= form
.declared_fields
['bureau']
132 bureau_field
= form
.base_fields
['bureau']
134 if grp_drh
in user_groupes
or \
135 grp_drh2
in user_groupes
or \
136 grp_haute_direction
in user_groupes
:
137 bureau_field
.queryset
= Bureau
.objects
.all()
139 bureau_field
.queryset
= \
140 Bureau
.objects
.filter(region
=employe
.implantation
.region
)
146 def queryset(self
, request
):
147 qs
= self
.model
._default_manager
.get_query_set() \
148 .select_related('offre_emploi')
149 user_groupes
= request
.user
.groups
.all()
150 if grp_drh
in user_groupes
or \
151 grp_drh2
in user_groupes
or \
152 grp_haute_direction
in user_groupes
:
155 if grp_directeurs_bureau
in user_groupes
or \
156 grp_correspondants_rh
in user_groupes
or \
157 grp_administrateurs
in user_groupes
:
158 employe
= get_emp(request
.user
)
159 return qs
.filter(region
=employe
.implantation
.region
)
161 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
162 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
164 e
.candidat
.offre_emploi_id
165 for e
in CandidatEvaluation
.objects
166 .select_related('candidat')
167 .filter(evaluateur
=evaluateur
)
169 return qs
.filter(id__in
=offre_ids
)
173 ### Permission add, delete, change
174 def has_add_permission(self
, request
):
175 user_groupes
= request
.user
.groups
.all()
176 if request
.user
.is_superuser
is True or \
177 grp_drh
in user_groupes
or \
178 grp_drh2
in user_groupes
or \
179 grp_directeurs_bureau
in user_groupes
or \
180 grp_administrateurs
in user_groupes
or \
181 grp_haute_direction
in user_groupes
:
185 def has_delete_permission(self
, request
, obj
=None):
186 user_groupes
= request
.user
.groups
.all()
187 if request
.user
.is_superuser
is True or \
188 grp_drh
in user_groupes
or \
189 grp_drh2
in user_groupes
or \
190 grp_directeurs_bureau
in user_groupes
or \
191 grp_administrateurs
in user_groupes
or \
192 grp_haute_direction
in user_groupes
:
196 def has_change_permission(self
, request
, obj
=None):
197 user_groupes
= request
.user
.groups
.all()
198 if request
.user
.is_superuser
is True or \
199 grp_drh
in user_groupes
or \
200 grp_drh2
in user_groupes
or \
201 grp_directeurs_bureau
in user_groupes
or \
202 grp_administrateurs
in user_groupes
or \
203 grp_haute_direction
in user_groupes
:
208 class OffreEmploiAdmin(VersionAdmin
, OffreEmploiAdminMixin
):
212 class ProxyOffreEmploiAdmin(OffreEmploiAdminMixin
):
214 'nom', 'date_limite', 'region', 'statut', 'est_affiche'
217 'description', 'bureau', 'duree_affectation', 'renumeration',
218 'debut_affectation', 'lieu_affectation', 'nom', 'resume',
219 'date_limite', 'region', 'poste'
225 ('Description générale', {
226 'fields': ('description', 'date_limite',)
229 'fields': ('lieu_affectation', 'bureau', 'region', 'poste',)
233 'debut_affectation', 'duree_affectation', 'renumeration',
239 ### Lieu de redirection après le change
240 def response_change(self
, request
, obj
):
241 return redirect('admin:recrutement_proxyoffreemploi_changelist')
244 def get_form(self
, request
, obj
=None, **kwargs
):
245 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
248 ### Permissions add, delete, change
249 def has_add_permission(self
, request
):
252 def has_delete_permission(self
, request
, obj
=None):
255 def has_change_permission(self
, request
, obj
=None):
256 user_groupes
= request
.user
.groups
.all()
257 if request
.user
.is_superuser
is True or \
258 grp_correspondants_rh
in user_groupes
or \
259 grp_drh
in user_groupes
or \
260 grp_drh2
in user_groupes
or \
261 grp_directeurs_bureau
in user_groupes
or \
262 grp_administrateurs
in user_groupes
or \
263 grp_haute_direction
in user_groupes
:
272 class CandidatPieceInline(admin
.TabularInline
):
273 model
= CandidatPiece
274 fields
= ('candidat', 'nom', 'path',)
279 class ReadOnlyCandidatPieceInline(CandidatPieceInline
):
280 readonly_fields
= ('candidat', 'nom', 'path', )
284 class CandidatEvaluationInlineFormSet(BaseInlineFormSet
):
286 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
288 def __init__(self
, *args
, **kwargs
):
289 super(CandidatEvaluationInlineFormSet
, self
).__init__(*args
, **kwargs
)
290 self
.can_delete
= False
293 class CandidatEvaluationInline(admin
.TabularInline
):
294 model
= CandidatEvaluation
295 fields
= ('evaluateur', 'note', 'commentaire')
298 formset
= CandidatEvaluationInlineFormSet
301 def get_readonly_fields(self
, request
, obj
=None):
303 Empêche la modification des évaluations
306 return self
.readonly_fields
+ ('evaluateur', 'note', 'commentaire')
307 return self
.readonly_fields
310 class CandidatAdminMixin(BaseAdmin
):
311 search_fields
= ('nom', 'prenom')
312 exclude
= ('actif', )
313 list_editable
= ('statut', )
314 list_display
= ('_candidat', 'offre_emploi',
315 'voir_offre_emploi', 'calculer_moyenne',
316 'afficher_candidat', '_date_creation', 'statut', )
317 list_filter
= ('offre_emploi', 'offre_emploi__region', 'statut', )
321 'fields': ('offre_emploi', )
323 ('Informations personnelles', {
325 'prenom', 'nom', 'genre', 'nationalite',
326 'situation_famille', 'nombre_dependant'
331 'telephone', 'email', 'adresse', 'ville', 'etat_province',
332 'code_postal', 'pays'
335 ('Informations professionnelles', {
337 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
338 'domaine_professionnel'
342 'fields': ('statut', )
347 CandidatEvaluationInline
,
349 actions
= ['envoyer_courriel_candidats']
351 def _candidat(self
, obj
):
352 txt
= u
"%s %s (%s)" % (obj
.nom
.upper(), obj
.prenom
, obj
.genre
)
353 txt
= textwrap
.wrap(txt
, 30)
354 return "<br/>".join(txt
)
355 _candidat
.short_description
= "Candidat"
356 _candidat
.admin_order_field
= "nom"
357 _candidat
.allow_tags
= True
359 def _date_creation(self
, obj
):
360 return obj
.date_creation
361 _date_creation
.admin_order_field
= "date_creation"
362 _date_creation
.short_description
= "Date de réception"
364 ### Actions à afficher
365 def get_actions(self
, request
):
366 actions
= super(CandidatAdmin
, self
).get_actions(request
)
367 del actions
['delete_selected']
370 ### Envoyer un courriel à des candidats
371 def envoyer_courriel_candidats(modeladmin
, obj
, candidats
):
372 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
374 return HttpResponseRedirect(
375 reverse('selectionner_template') + "?ids=%s" % (",".join(selected
))
377 envoyer_courriel_candidats
.short_description
= u
'Envoyer courriel'
379 ### Évaluer un candidat
380 def evaluer_candidat(self
, obj
):
381 return "<a href='%s?candidat__id__exact=%s'>" \
382 "Évaluer le candidat</a>" % (
383 reverse('admin:recrutement_candidatevaluation_changelist'),
386 evaluer_candidat
.allow_tags
= True
387 evaluer_candidat
.short_description
= 'Évaluation'
389 ### Afficher un candidat
390 def afficher_candidat(self
, obj
):
391 items
= [u
"<li><a href='%s%s'>%s</li>" % \
392 (settings
.OE_PRIVE_MEDIA_URL
, pj
.path
, pj
.get_nom_display()) \
393 for pj
in obj
.pieces_jointes()]
394 html
= "<a href='%s'>Voir le candidat</a>" % (
395 reverse('admin:recrutement_proxycandidat_change', args
=(obj
.id,))
397 return "%s<ul>%s</ul>" % (html
, "\n".join(items
))
398 afficher_candidat
.allow_tags
= True
399 afficher_candidat
.short_description
= u
'Détails du candidat'
401 ### Voir l'offre d'emploi
402 def voir_offre_emploi(self
, obj
):
403 return "<a href='%s'>Voir l'offre d'emploi</a>" % (reverse(
404 'admin:recrutement_proxyoffreemploi_change',
405 args
=(obj
.offre_emploi
.id,)
407 voir_offre_emploi
.allow_tags
= True
408 voir_offre_emploi
.short_description
= "Afficher l'offre d'emploi"
410 ### Calculer la moyenne des notes
411 def calculer_moyenne(self
, obj
):
412 evaluations
= CandidatEvaluation
.objects
.filter(candidat
=obj
)
414 notes
= [evaluation
.note
for evaluation
in evaluations \
415 if evaluation
.note
is not None]
418 moyenne_votes
= round(float(sum(notes
)) / len(notes
), 2)
420 moyenne_votes
= "Non disponible"
422 totales
= len(evaluations
)
425 if obj
.statut
== 'REC':
426 if totales
== faites
:
428 elif faites
> 0 and float(totales
) / float(faites
) >= 2:
435 return """<span style="color: %s;">%s (%s/%s)</span>""" % (
436 color
, moyenne_votes
, faites
, totales
438 calculer_moyenne
.allow_tags
= True
439 calculer_moyenne
.short_description
= "Moyenne"
440 calculer_moyenne
.admin_order_field
= ""
442 ### Permissions add, delete, change
443 def has_add_permission(self
, request
):
444 user_groupes
= request
.user
.groups
.all()
445 if request
.user
.is_superuser
is True or \
446 grp_correspondants_rh
in user_groupes
or \
447 grp_drh
in user_groupes
or \
448 grp_drh2
in user_groupes
or \
449 grp_directeurs_bureau
in user_groupes
or \
450 grp_administrateurs
in user_groupes
or \
451 grp_haute_direction
in user_groupes
:
455 def has_delete_permission(self
, request
, obj
=None):
456 user_groupes
= request
.user
.groups
.all()
457 if request
.user
.is_superuser
is True or \
458 grp_correspondants_rh
in user_groupes
or \
459 grp_drh
in user_groupes
or \
460 grp_drh2
in user_groupes
or \
461 grp_directeurs_bureau
in user_groupes
or \
462 grp_administrateurs
in user_groupes
or \
463 grp_haute_direction
in user_groupes
:
467 def has_change_permission(self
, request
, obj
=None):
468 user_groupes
= request
.user
.groups
.all()
469 if request
.user
.is_superuser
is True or \
470 grp_correspondants_rh
in user_groupes
or \
471 grp_drh
in user_groupes
or \
472 grp_drh2
in user_groupes
or \
473 grp_directeurs_bureau
in user_groupes
or \
474 grp_administrateurs
in user_groupes
or \
475 grp_haute_direction
in user_groupes
:
479 def get_changelist(self
, request
, **kwargs
):
480 return OrderedChangeList
482 def queryset(self
, request
):
484 Spécifie un queryset limité, autrement Django exécute un
485 select_related() sans paramètre, ce qui a pour effet de charger tous
486 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
487 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
488 génération d'une requête infinie.
490 qs
= self
.model
._default_manager
.get_query_set() \
491 .select_related('offre_emploi') \
492 .annotate(moyenne
=Avg('evaluations__note'))
494 user_groupes
= request
.user
.groups
.all()
495 if grp_drh
in user_groupes
or \
496 grp_drh2
in user_groupes
or \
497 grp_haute_direction
in user_groupes
:
500 if grp_directeurs_bureau
in user_groupes
or \
501 grp_correspondants_rh
in user_groupes
or \
502 grp_administrateurs
in user_groupes
:
503 employe
= get_emp(request
.user
)
504 return qs
.filter(offre_emploi__region
=employe
.implantation
.region
)
506 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
507 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
508 candidat_ids
= [e
.candidat
.id for e
in
509 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
)]
510 return qs
.filter(id__in
=candidat_ids
)
514 class CandidatAdmin(VersionAdmin
, CandidatAdminMixin
):
518 class ProxyCandidatAdmin(CandidatAdminMixin
):
521 'statut', 'offre_emploi', 'prenom', 'nom', 'genre', 'nationalite',
522 'situation_famille', 'nombre_dependant', 'telephone', 'email',
523 'adresse', 'ville', 'etat_province', 'code_postal', 'pays',
524 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
525 'domaine_professionnel', 'pieces_jointes'
529 'fields': ('offre_emploi', )
531 ('Informations personnelles', {
533 'prenom', 'nom', 'genre', 'nationalite', 'situation_famille',
539 'telephone', 'email', 'adresse', 'ville', 'etat_province',
540 'code_postal', 'pays'
543 ('Informations professionnelles', {
545 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
546 'domaine_professionnel'
550 inlines
= (CandidatEvaluationInline
, )
552 def has_add_permission(self
, request
):
555 def has_delete_permission(self
, request
, obj
=None):
558 def has_change_permission(self
, request
, obj
=None):
559 user_groupes
= request
.user
.groups
.all()
560 if request
.user
.is_superuser
is True or \
561 grp_correspondants_rh
in user_groupes
or \
562 grp_drh
in user_groupes
or \
563 grp_drh2
in user_groupes
or \
564 grp_directeurs_bureau
in user_groupes
or \
565 grp_administrateurs
in user_groupes
or \
566 grp_haute_direction
in user_groupes
:
570 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
571 for e
in obj
.evaluations
.all():
572 if e
.evaluateur
== evaluateur
:
577 def get_actions(self
, request
):
581 class CandidatPieceAdmin(admin
.ModelAdmin
):
582 list_display
= ('nom', 'candidat', )
585 def queryset(self
, request
):
587 Spécifie un queryset limité, autrement Django exécute un
588 select_related() sans paramètre, ce qui a pour effet de charger tous
589 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
590 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
591 génération d'une requête infinie. Affiche la liste de candidats que
592 si le user connecté possède un Evaluateur
594 qs
= self
.model
._default_manager
.get_query_set()
595 return qs
.select_related('candidat')
598 class EvaluateurAdmin(BaseAdmin
, VersionAdmin
):
605 ### Actions à afficher
606 def get_actions(self
, request
):
607 actions
= super(EvaluateurAdmin
, self
).get_actions(request
)
608 del actions
['delete_selected']
611 ### Permissions add, delete, change
612 def has_add_permission(self
, request
):
613 user_groupes
= request
.user
.groups
.all()
614 if request
.user
.is_superuser
is True or \
615 grp_drh
in user_groupes
or \
616 grp_drh2
in user_groupes
or \
617 grp_haute_direction
in user_groupes
:
621 def has_delete_permission(self
, request
, obj
=None):
622 user_groupes
= request
.user
.groups
.all()
623 if request
.user
.is_superuser
is True or \
624 grp_drh
in user_groupes
or \
625 grp_drh2
in user_groupes
or \
626 grp_haute_direction
in user_groupes
:
630 def has_change_permission(self
, request
, obj
=None):
631 user_groupes
= request
.user
.groups
.all()
632 if request
.user
.is_superuser
is True or \
633 grp_drh
in user_groupes
or \
634 grp_drh2
in user_groupes
or \
635 grp_haute_direction
in user_groupes
:
640 class CandidatEvaluationAdmin(BaseAdmin
):
641 search_fields
= ('candidat__nom', 'candidat__prenom')
643 '_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
646 readonly_fields
= ('candidat', 'evaluateur')
647 list_filter
= ('candidat__statut', 'candidat__offre_emploi',)
649 ('Évaluation du candidat', {
650 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
654 def get_actions(self
, request
):
655 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
657 self
.evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
659 self
.evaluateur
= None
661 actions
= super(CandidatEvaluationAdmin
, self
).get_actions(request
)
662 del actions
['delete_selected']
666 def _note(self
, obj
):
668 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
669 un lien pour Évaluer le candidat.
670 Sinon afficher la note.
672 page
= self
.model
.__name__
.lower()
673 redirect_url
= 'admin:recrutement_%s_change' % page
676 label
= "Candidat non évalué"
680 if self
.evaluateur
== obj
.evaluateur
:
681 return "<a href='%s'>%s</a>" % (
682 reverse(redirect_url
, args
=(obj
.id,)), label
686 _note
.allow_tags
= True
687 _note
.short_description
= "Note"
688 _note
.admin_order_field
= 'note'
690 def _statut(self
, obj
):
691 return obj
.candidat
.get_statut_display()
692 _statut
.order_field
= 'candidat__statut'
693 _statut
.short_description
= 'Statut'
695 ### Lien en lecture seule vers le candidat
696 def _candidat(self
, obj
):
697 return "<a href='%s'>%s</a>" \
698 % (reverse('admin:recrutement_proxycandidat_change',
699 args
=(obj
.candidat
.id,)), obj
.candidat
)
700 _candidat
.allow_tags
= True
701 _candidat
.short_description
= 'Candidat'
703 ### Afficher commentaire
704 def _commentaire(self
, obj
):
706 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
707 dans le champ commentaire, Aucun au lieu de (None)
708 Sinon afficher la note.
710 if obj
.commentaire
is None:
712 return obj
.commentaire
713 _commentaire
.allow_tags
= True
714 _commentaire
.short_description
= "Commentaire"
716 ### Afficher offre d'emploi
717 def _offre_emploi(self
, obj
):
718 return "<a href='%s'>%s</a>" % \
719 (reverse('admin:recrutement_proxyoffreemploi_change',
720 args
=(obj
.candidat
.offre_emploi
.id,)), obj
.candidat
.offre_emploi
)
721 _offre_emploi
.allow_tags
= True
722 _offre_emploi
.short_description
= "Voir offre d'emploi"
724 def has_add_permission(self
, request
):
727 def has_delete_permission(self
, request
, obj
=None):
730 def has_change_permission(self
, request
, obj
=None):
732 Permettre la visualisation dans la changelist
733 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
736 user_groupes
= request
.user
.groups
.all()
738 if request
.user
.is_superuser
or \
739 grp_drh
in user_groupes
or \
740 grp_drh2
in user_groupes
or \
741 grp_correspondants_rh
in user_groupes
or \
742 grp_directeurs_bureau
in user_groupes
or \
743 grp_administrateurs
in user_groupes
or \
744 grp_haute_direction
in user_groupes
:
745 is_recrutement
= True
747 is_recrutement
= False
749 return is_recrutement
751 def queryset(self
, request
):
753 Afficher uniquement les évaluations de l'évaluateur, sauf si
754 l'utilisateur est dans les groupes suivants.
756 qs
= self
.model
._default_manager
.get_query_set() \
757 .select_related('offre_emploi')
758 user_groupes
= request
.user
.groups
.all()
760 if grp_drh
in user_groupes
or \
761 grp_drh2
in user_groupes
or \
762 grp_correspondants_rh
in user_groupes
or \
763 grp_directeurs_bureau
in user_groupes
or \
764 grp_administrateurs
in user_groupes
or \
765 grp_haute_direction
in user_groupes
:
768 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
769 candidats_evaluations
= \
770 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
771 candidat__statut__in
=('REC', ))
772 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
773 return qs
.filter(id__in
=candidats_evaluations_ids
)
776 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin
):
778 def has_change_permission(self
, request
, obj
=None):
780 Evaluateur
.objects
.get(user
=request
.user
)
783 is_evaluateur
= False
785 if obj
is None and is_evaluateur
:
789 return request
.user
== obj
.evaluateur
.user
793 def queryset(self
, request
):
794 qs
= self
.model
._default_manager
.get_query_set() \
795 .select_related('offre_emploi')
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 CourrielTemplateAdmin(BaseAdmin
, VersionAdmin
):
805 ### Actions à afficher
806 def get_actions(self
, request
):
807 actions
= super(CourrielTemplateAdmin
, self
).get_actions(request
)
808 del actions
['delete_selected']
811 admin
.site
.register(OffreEmploi
, OffreEmploiAdmin
)
812 admin
.site
.register(ProxyOffreEmploi
, ProxyOffreEmploiAdmin
)
813 admin
.site
.register(Candidat
, CandidatAdmin
)
814 admin
.site
.register(ProxyCandidat
, ProxyCandidatAdmin
)
815 admin
.site
.register(CandidatEvaluation
, CandidatEvaluationAdmin
)
816 admin
.site
.register(MesCandidatEvaluation
, MesCandidatEvaluationAdmin
)
817 admin
.site
.register(Evaluateur
, EvaluateurAdmin
)
818 admin
.site
.register(CourrielTemplate
, CourrielTemplateAdmin
)