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
.forms
.models
import BaseInlineFormSet
10 from django
.http
import HttpResponseRedirect
11 from django
.shortcuts
import redirect
12 from reversion
.admin
import VersionAdmin
14 from auf
.django
.emploi
.models
import OffreEmploi
, Candidat
, CandidatPiece
15 from auf
.django
.references
.models
import Region
, Bureau
17 from project
.groups
import get_employe_from_user
as get_emp
18 from project
.rh
import models
as rh
20 from project
.recrutement
.forms
import OffreEmploiForm
21 from project
.recrutement
.groups
import \
23 grp_directeurs_bureau
, \
24 grp_administrateurs
, \
25 grp_correspondants_rh
, \
27 from project
.recrutement
.models
import \
28 Evaluateur
, CandidatEvaluation
, \
29 ProxyOffreEmploi
, ProxyCandidat
, MesCandidatEvaluation
, \
34 IMPLANTATIONS_CENTRALES
= [15, 19]
37 class BaseAdmin(admin
.ModelAdmin
):
40 css
= {'screen': ('css/admin_custom.css',)}
43 class OrderedChangeList(admin
.views
.main
.ChangeList
):
45 Surcharge pour appliquer le order_by d'un annotate
47 def get_query_set(self
):
48 qs
= super(OrderedChangeList
, self
).get_query_set()
49 qs
= qs
.order_by('-moyenne')
53 class OffreEmploiAdmin(BaseAdmin
, VersionAdmin
):
54 date_hierarchy
= 'date_creation'
56 'nom', 'date_limite', 'region', 'statut', 'est_affiche',
59 exclude
= ('actif', 'poste_nom', 'resume',)
60 list_filter
= ('statut',)
61 actions
= ['affecter_evaluateurs_offre_emploi', ]
62 form
= OffreEmploiForm
64 ### Actions à afficher
65 def get_actions(self
, request
):
66 actions
= super(OffreEmploiAdmin
, self
).get_actions(request
)
67 del actions
['delete_selected']
70 ### Affecter un évaluateurs à des offres d'emploi
71 def affecter_evaluateurs_offre_emploi(modeladmin
, obj
, candidats
):
72 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
74 return HttpResponseRedirect(
75 reverse('affecter_evaluateurs_offre_emploi') +
76 "?ids=%s" % (",".join(selected
))
79 affecter_evaluateurs_offre_emploi
.short_description
= \
80 u
'Affecter évaluateur(s)'
82 ### Afficher la liste des candidats pour l'offre d'emploi
83 def _candidatsList(self
, obj
):
84 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
85 </a>" % (reverse('admin:recrutement_candidat_changelist'), obj
.id)
86 _candidatsList
.allow_tags
= True
87 _candidatsList
.short_description
= "Afficher la liste des candidats"
90 def get_form(self
, request
, obj
=None, **kwargs
):
91 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
92 employe
= get_emp(request
.user
)
93 user_groupes
= request
.user
.groups
.all()
96 if 'region' in form
.declared_fields
:
97 region_field
= form
.declared_fields
['region']
99 region_field
= form
.base_fields
['region']
101 if grp_drh
in user_groupes
or \
102 grp_drh2
in user_groupes
or \
103 grp_haute_direction
in user_groupes
:
104 region_field
.queryset
= Region
.objects
.all()
106 region_field
.queryset
= Region
.objects
.\
107 filter(id=employe
.implantation
.region
.id)
110 if 'poste' in form
.declared_fields
:
111 poste_field
= form
.declared_fields
['poste']
113 poste_field
= form
.base_fields
['poste']
115 if grp_drh
in user_groupes
or \
116 grp_drh2
in user_groupes
or \
117 grp_haute_direction
in user_groupes
:
118 poste_field
.queryset
= rh
.Poste
.objects
.all()
120 poste_field
.queryset
= rh
.Poste
.objects
.\
121 filter(implantation__region
=employe
.implantation
.region
).\
122 exclude(implantation__in
=IMPLANTATIONS_CENTRALES
)
125 if 'bureau' in form
.declared_fields
:
126 bureau_field
= form
.declared_fields
['bureau']
128 bureau_field
= form
.base_fields
['bureau']
130 if grp_drh
in user_groupes
or \
131 grp_drh2
in user_groupes
or \
132 grp_haute_direction
in user_groupes
:
133 bureau_field
.queryset
= Bureau
.objects
.all()
135 bureau_field
.queryset
= \
136 Bureau
.objects
.filter(region
=employe
.implantation
.region
)
142 def queryset(self
, request
):
143 qs
= self
.model
._default_manager
.get_query_set() \
144 .select_related('offre_emploi')
145 user_groupes
= request
.user
.groups
.all()
146 if grp_drh
in user_groupes
or \
147 grp_drh2
in user_groupes
or \
148 grp_haute_direction
in user_groupes
:
151 if grp_directeurs_bureau
in user_groupes
or \
152 grp_correspondants_rh
in user_groupes
or \
153 grp_administrateurs
in user_groupes
:
154 employe
= get_emp(request
.user
)
155 return qs
.filter(region
=employe
.implantation
.region
)
157 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
158 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
160 e
.candidat
.offre_emploi_id
161 for e
in CandidatEvaluation
.objects
162 .select_related('candidat')
163 .filter(evaluateur
=evaluateur
)
165 return qs
.filter(id__in
=offre_ids
)
169 ### Permission add, delete, change
170 def has_add_permission(self
, request
):
171 user_groupes
= request
.user
.groups
.all()
172 if request
.user
.is_superuser
is True or \
173 grp_drh
in user_groupes
or \
174 grp_drh2
in user_groupes
or \
175 grp_directeurs_bureau
in user_groupes
or \
176 grp_administrateurs
in user_groupes
or \
177 grp_haute_direction
in user_groupes
:
181 def has_delete_permission(self
, request
, obj
=None):
182 user_groupes
= request
.user
.groups
.all()
183 if request
.user
.is_superuser
is True or \
184 grp_drh
in user_groupes
or \
185 grp_drh2
in user_groupes
or \
186 grp_directeurs_bureau
in user_groupes
or \
187 grp_administrateurs
in user_groupes
or \
188 grp_haute_direction
in user_groupes
:
192 def has_change_permission(self
, request
, obj
=None):
193 user_groupes
= request
.user
.groups
.all()
194 if request
.user
.is_superuser
is True or \
195 grp_drh
in user_groupes
or \
196 grp_drh2
in user_groupes
or \
197 grp_directeurs_bureau
in user_groupes
or \
198 grp_administrateurs
in user_groupes
or \
199 grp_haute_direction
in user_groupes
:
204 class ProxyOffreEmploiAdmin(OffreEmploiAdmin
):
206 'nom', 'date_limite', 'region', 'statut', 'est_affiche'
209 'description', 'bureau', 'duree_affectation', 'renumeration',
210 'debut_affectation', 'lieu_affectation', 'nom', 'resume',
211 'date_limite', 'region', 'poste'
217 ('Description générale', {
218 'fields': ('description', 'date_limite',)
221 'fields': ('lieu_affectation', 'bureau', 'region', 'poste',)
225 'debut_affectation', 'duree_affectation', 'renumeration',
231 ### Lieu de redirection après le change
232 def response_change(self
, request
, obj
):
233 return redirect('admin:recrutement_proxyoffreemploi_changelist')
236 def get_form(self
, request
, obj
=None, **kwargs
):
237 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
240 ### Permissions add, delete, change
241 def has_add_permission(self
, request
):
244 def has_delete_permission(self
, request
, obj
=None):
247 def has_change_permission(self
, request
, obj
=None):
248 user_groupes
= request
.user
.groups
.all()
249 if request
.user
.is_superuser
is True or \
250 grp_correspondants_rh
in user_groupes
or \
251 grp_drh
in user_groupes
or \
252 grp_drh2
in user_groupes
or \
253 grp_directeurs_bureau
in user_groupes
or \
254 grp_administrateurs
in user_groupes
or \
255 grp_haute_direction
in user_groupes
:
264 class CandidatPieceInline(admin
.TabularInline
):
265 model
= CandidatPiece
266 fields
= ('candidat', 'nom', 'path',)
271 class ReadOnlyCandidatPieceInline(CandidatPieceInline
):
272 readonly_fields
= ('candidat', 'nom', 'path', )
276 class CandidatEvaluationInlineFormSet(BaseInlineFormSet
):
278 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
280 def __init__(self
, *args
, **kwargs
):
281 super(CandidatEvaluationInlineFormSet
, self
).__init__(*args
, **kwargs
)
282 self
.can_delete
= False
285 class CandidatEvaluationInline(admin
.TabularInline
):
286 model
= CandidatEvaluation
287 fields
= ('evaluateur', 'note', 'commentaire')
290 formset
= CandidatEvaluationInlineFormSet
293 def get_readonly_fields(self
, request
, obj
=None):
295 Empêche la modification des évaluations
298 return self
.readonly_fields
+ ('evaluateur', 'note', 'commentaire')
299 return self
.readonly_fields
302 class CandidatAdmin(BaseAdmin
, VersionAdmin
):
303 search_fields
= ('nom', 'prenom')
304 exclude
= ('actif', )
305 list_editable
= ('statut', )
306 list_display
= ('_candidat', 'offre_emploi',
307 'voir_offre_emploi', 'calculer_moyenne',
308 'afficher_candidat', '_date_creation', 'statut', )
309 list_filter
= ('offre_emploi', 'offre_emploi__region', 'statut', )
313 'fields': ('offre_emploi', )
315 ('Informations personnelles', {
317 'prenom', 'nom', 'genre', 'nationalite',
318 'situation_famille', 'nombre_dependant'
323 'telephone', 'email', 'adresse', 'ville', 'etat_province',
324 'code_postal', 'pays'
327 ('Informations professionnelles', {
329 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
330 'domaine_professionnel'
334 'fields': ('statut', )
339 CandidatEvaluationInline
,
341 actions
= ['envoyer_courriel_candidats']
343 def _candidat(self
, obj
):
344 txt
= u
"%s %s (%s)" % (obj
.nom
.upper(), obj
.prenom
, obj
.genre
)
345 txt
= textwrap
.wrap(txt
, 30)
346 return "<br/>".join(txt
)
347 _candidat
.short_description
= "Candidat"
348 _candidat
.admin_order_field
= "nom"
349 _candidat
.allow_tags
= True
351 def _date_creation(self
, obj
):
352 return obj
.date_creation
353 _date_creation
.admin_order_field
= "date_creation"
354 _date_creation
.short_description
= "Date de réception"
356 ### Actions à afficher
357 def get_actions(self
, request
):
358 actions
= super(CandidatAdmin
, self
).get_actions(request
)
359 del actions
['delete_selected']
362 ### Envoyer un courriel à des candidats
363 def envoyer_courriel_candidats(modeladmin
, obj
, candidats
):
364 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
366 return HttpResponseRedirect(
367 reverse('selectionner_template') + "?ids=%s" % (",".join(selected
))
369 envoyer_courriel_candidats
.short_description
= u
'Envoyer courriel'
371 ### Évaluer un candidat
372 def evaluer_candidat(self
, obj
):
373 return "<a href='%s?candidat__id__exact=%s'>" \
374 "Évaluer le candidat</a>" % (
375 reverse('admin:recrutement_candidatevaluation_changelist'),
378 evaluer_candidat
.allow_tags
= True
379 evaluer_candidat
.short_description
= 'Évaluation'
381 ### Afficher un candidat
382 def afficher_candidat(self
, obj
):
383 items
= [u
"<li><a href='%s%s'>%s</li>" % \
384 (settings
.OE_PRIVE_MEDIA_URL
, pj
.path
, pj
.get_nom_display()) \
385 for pj
in obj
.pieces_jointes()]
386 html
= "<a href='%s'>Voir le candidat</a>" % (
387 reverse('admin:recrutement_proxycandidat_change', args
=(obj
.id,))
389 return "%s<ul>%s</ul>" % (html
, "\n".join(items
))
390 afficher_candidat
.allow_tags
= True
391 afficher_candidat
.short_description
= u
'Détails du candidat'
393 ### Voir l'offre d'emploi
394 def voir_offre_emploi(self
, obj
):
395 return "<a href='%s'>Voir l'offre d'emploi</a>" % (reverse(
396 'admin:recrutement_proxyoffreemploi_change',
397 args
=(obj
.offre_emploi
.id,)
399 voir_offre_emploi
.allow_tags
= True
400 voir_offre_emploi
.short_description
= "Afficher l'offre d'emploi"
402 ### Calculer la moyenne des notes
403 def calculer_moyenne(self
, obj
):
404 evaluations
= CandidatEvaluation
.objects
.filter(candidat
=obj
)
406 notes
= [evaluation
.note
for evaluation
in evaluations \
407 if evaluation
.note
is not None]
410 moyenne_votes
= round(float(sum(notes
)) / len(notes
), 2)
412 moyenne_votes
= "Non disponible"
414 totales
= len(evaluations
)
417 if obj
.statut
== 'REC':
418 if totales
== faites
:
420 elif faites
> 0 and float(totales
) / float(faites
) >= 2:
427 return """<span style="color: %s;">%s (%s/%s)</span>""" % (
428 color
, moyenne_votes
, faites
, totales
430 calculer_moyenne
.allow_tags
= True
431 calculer_moyenne
.short_description
= "Moyenne"
432 calculer_moyenne
.admin_order_field
= ""
434 ### Permissions add, delete, change
435 def has_add_permission(self
, request
):
436 user_groupes
= request
.user
.groups
.all()
437 if request
.user
.is_superuser
is True or \
438 grp_correspondants_rh
in user_groupes
or \
439 grp_drh
in user_groupes
or \
440 grp_drh2
in user_groupes
or \
441 grp_directeurs_bureau
in user_groupes
or \
442 grp_administrateurs
in user_groupes
or \
443 grp_haute_direction
in user_groupes
:
447 def has_delete_permission(self
, request
, obj
=None):
448 user_groupes
= request
.user
.groups
.all()
449 if request
.user
.is_superuser
is True or \
450 grp_correspondants_rh
in user_groupes
or \
451 grp_drh
in user_groupes
or \
452 grp_drh2
in user_groupes
or \
453 grp_directeurs_bureau
in user_groupes
or \
454 grp_administrateurs
in user_groupes
or \
455 grp_haute_direction
in user_groupes
:
459 def has_change_permission(self
, request
, obj
=None):
460 user_groupes
= request
.user
.groups
.all()
461 if request
.user
.is_superuser
is True or \
462 grp_correspondants_rh
in user_groupes
or \
463 grp_drh
in user_groupes
or \
464 grp_drh2
in user_groupes
or \
465 grp_directeurs_bureau
in user_groupes
or \
466 grp_administrateurs
in user_groupes
or \
467 grp_haute_direction
in user_groupes
:
471 def get_changelist(self
, request
, **kwargs
):
472 return OrderedChangeList
474 def queryset(self
, request
):
476 Spécifie un queryset limité, autrement Django exécute un
477 select_related() sans paramètre, ce qui a pour effet de charger tous
478 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
479 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
480 génération d'une requête infinie.
482 qs
= self
.model
._default_manager
.get_query_set() \
483 .select_related('offre_emploi') \
484 .annotate(moyenne
=Avg('evaluations__note'))
486 user_groupes
= request
.user
.groups
.all()
487 if grp_drh
in user_groupes
or \
488 grp_drh2
in user_groupes
or \
489 grp_haute_direction
in user_groupes
:
492 if grp_directeurs_bureau
in user_groupes
or \
493 grp_correspondants_rh
in user_groupes
or \
494 grp_administrateurs
in user_groupes
:
495 employe
= get_emp(request
.user
)
496 return qs
.filter(offre_emploi__region
=employe
.implantation
.region
)
498 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
499 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
500 candidat_ids
= [e
.candidat
.id for e
in
501 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
)]
502 return qs
.filter(id__in
=candidat_ids
)
506 class ProxyCandidatAdmin(CandidatAdmin
):
509 'statut', 'offre_emploi', 'prenom', 'nom', 'genre', 'nationalite',
510 'situation_famille', 'nombre_dependant', 'telephone', 'email',
511 'adresse', 'ville', 'etat_province', 'code_postal', 'pays',
512 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
513 'domaine_professionnel', 'pieces_jointes'
517 'fields': ('offre_emploi', )
519 ('Informations personnelles', {
521 'prenom', 'nom', 'genre', 'nationalite', 'situation_famille',
527 'telephone', 'email', 'adresse', 'ville', 'etat_province',
528 'code_postal', 'pays'
531 ('Informations professionnelles', {
533 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
534 'domaine_professionnel'
538 inlines
= (CandidatEvaluationInline
, )
540 def has_add_permission(self
, request
):
543 def has_delete_permission(self
, request
, obj
=None):
546 def has_change_permission(self
, request
, obj
=None):
547 user_groupes
= request
.user
.groups
.all()
548 if request
.user
.is_superuser
is True or \
549 grp_correspondants_rh
in user_groupes
or \
550 grp_drh
in user_groupes
or \
551 grp_drh2
in user_groupes
or \
552 grp_directeurs_bureau
in user_groupes
or \
553 grp_administrateurs
in user_groupes
or \
554 grp_haute_direction
in user_groupes
:
558 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
559 for e
in obj
.evaluations
.all():
560 if e
.evaluateur
== evaluateur
:
565 def get_actions(self
, request
):
569 class CandidatPieceAdmin(admin
.ModelAdmin
):
570 list_display
= ('nom', 'candidat', )
573 def queryset(self
, request
):
575 Spécifie un queryset limité, autrement Django exécute un
576 select_related() sans paramètre, ce qui a pour effet de charger tous
577 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
578 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
579 génération d'une requête infinie. Affiche la liste de candidats que
580 si le user connecté possède un Evaluateur
582 qs
= self
.model
._default_manager
.get_query_set()
583 return qs
.select_related('candidat')
586 class EvaluateurAdmin(BaseAdmin
, VersionAdmin
):
593 ### Actions à afficher
594 def get_actions(self
, request
):
595 actions
= super(EvaluateurAdmin
, self
).get_actions(request
)
596 del actions
['delete_selected']
599 ### Permissions add, delete, change
600 def has_add_permission(self
, request
):
601 user_groupes
= request
.user
.groups
.all()
602 if request
.user
.is_superuser
is True or \
603 grp_drh
in user_groupes
or \
604 grp_drh2
in user_groupes
or \
605 grp_haute_direction
in user_groupes
:
609 def has_delete_permission(self
, request
, obj
=None):
610 user_groupes
= request
.user
.groups
.all()
611 if request
.user
.is_superuser
is True or \
612 grp_drh
in user_groupes
or \
613 grp_drh2
in user_groupes
or \
614 grp_haute_direction
in user_groupes
:
618 def has_change_permission(self
, request
, obj
=None):
619 user_groupes
= request
.user
.groups
.all()
620 if request
.user
.is_superuser
is True or \
621 grp_drh
in user_groupes
or \
622 grp_drh2
in user_groupes
or \
623 grp_haute_direction
in user_groupes
:
628 class CandidatEvaluationAdmin(BaseAdmin
):
629 search_fields
= ('candidat__nom', 'candidat__prenom')
631 '_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
634 readonly_fields
= ('candidat', 'evaluateur')
635 list_filter
= ('candidat__statut', 'candidat__offre_emploi',)
637 ('Évaluation du candidat', {
638 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
642 def get_actions(self
, request
):
643 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
645 self
.evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
647 self
.evaluateur
= None
649 actions
= super(CandidatEvaluationAdmin
, self
).get_actions(request
)
650 del actions
['delete_selected']
654 def _note(self
, obj
):
656 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
657 un lien pour Évaluer le candidat.
658 Sinon afficher la note.
660 page
= self
.model
.__name__
.lower()
661 redirect_url
= 'admin:recrutement_%s_change' % page
664 label
= "Candidat non évalué"
668 if self
.evaluateur
== obj
.evaluateur
:
669 return "<a href='%s'>%s</a>" % (
670 reverse(redirect_url
, args
=(obj
.id,)), label
674 _note
.allow_tags
= True
675 _note
.short_description
= "Note"
676 _note
.admin_order_field
= 'note'
678 def _statut(self
, obj
):
679 return obj
.candidat
.get_statut_display()
680 _statut
.order_field
= 'candidat__statut'
681 _statut
.short_description
= 'Statut'
683 ### Lien en lecture seule vers le candidat
684 def _candidat(self
, obj
):
685 return "<a href='%s'>%s</a>" \
686 % (reverse('admin:recrutement_proxycandidat_change',
687 args
=(obj
.candidat
.id,)), obj
.candidat
)
688 _candidat
.allow_tags
= True
689 _candidat
.short_description
= 'Candidat'
691 ### Afficher commentaire
692 def _commentaire(self
, obj
):
694 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
695 dans le champ commentaire, Aucun au lieu de (None)
696 Sinon afficher la note.
698 if obj
.commentaire
is None:
700 return obj
.commentaire
701 _commentaire
.allow_tags
= True
702 _commentaire
.short_description
= "Commentaire"
704 ### Afficher offre d'emploi
705 def _offre_emploi(self
, obj
):
706 return "<a href='%s'>%s</a>" % \
707 (reverse('admin:recrutement_proxyoffreemploi_change',
708 args
=(obj
.candidat
.offre_emploi
.id,)), obj
.candidat
.offre_emploi
)
709 _offre_emploi
.allow_tags
= True
710 _offre_emploi
.short_description
= "Voir offre d'emploi"
712 def has_add_permission(self
, request
):
715 def has_delete_permission(self
, request
, obj
=None):
718 def has_change_permission(self
, request
, obj
=None):
720 Permettre la visualisation dans la changelist
721 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
724 user_groupes
= request
.user
.groups
.all()
726 if request
.user
.is_superuser
or \
727 grp_drh
in user_groupes
or \
728 grp_drh2
in user_groupes
or \
729 grp_correspondants_rh
in user_groupes
or \
730 grp_directeurs_bureau
in user_groupes
or \
731 grp_administrateurs
in user_groupes
or \
732 grp_haute_direction
in user_groupes
:
733 is_recrutement
= True
735 is_recrutement
= False
737 return is_recrutement
739 def queryset(self
, request
):
741 Afficher uniquement les évaluations de l'évaluateur, sauf si
742 l'utilisateur est dans les groupes suivants.
744 qs
= self
.model
._default_manager
.get_query_set() \
745 .select_related('offre_emploi')
746 user_groupes
= request
.user
.groups
.all()
748 if grp_drh
in user_groupes
or \
749 grp_drh2
in user_groupes
or \
750 grp_correspondants_rh
in user_groupes
or \
751 grp_directeurs_bureau
in user_groupes
or \
752 grp_administrateurs
in user_groupes
or \
753 grp_haute_direction
in user_groupes
:
756 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
757 candidats_evaluations
= \
758 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
759 candidat__statut__in
=('REC', ))
760 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
761 return qs
.filter(id__in
=candidats_evaluations_ids
)
764 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin
):
766 def has_change_permission(self
, request
, obj
=None):
768 Evaluateur
.objects
.get(user
=request
.user
)
771 is_evaluateur
= False
773 if obj
is None and is_evaluateur
:
777 return request
.user
== obj
.evaluateur
.user
781 def queryset(self
, request
):
782 qs
= self
.model
._default_manager
.get_query_set() \
783 .select_related('offre_emploi')
784 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
785 candidats_evaluations
= \
786 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
787 candidat__statut__in
=('REC', ))
788 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
789 return qs
.filter(id__in
=candidats_evaluations_ids
)
792 class CourrielTemplateAdmin(BaseAdmin
, VersionAdmin
):
793 ### Actions à afficher
794 def get_actions(self
, request
):
795 actions
= super(CourrielTemplateAdmin
, self
).get_actions(request
)
796 del actions
['delete_selected']
799 admin
.site
.register(OffreEmploi
, OffreEmploiAdmin
)
800 admin
.site
.register(ProxyOffreEmploi
, ProxyOffreEmploiAdmin
)
801 admin
.site
.register(Candidat
, CandidatAdmin
)
802 admin
.site
.register(ProxyCandidat
, ProxyCandidatAdmin
)
803 admin
.site
.register(CandidatEvaluation
, CandidatEvaluationAdmin
)
804 admin
.site
.register(MesCandidatEvaluation
, MesCandidatEvaluationAdmin
)
805 admin
.site
.register(Evaluateur
, EvaluateurAdmin
)
806 admin
.site
.register(CourrielTemplate
, CourrielTemplateAdmin
)