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 datamaster_modeles
.models
import Region
, Bureau
17 from project
.dae
.utils
import get_employe_from_user
as get_emp
18 from project
.recrutement
.forms
import OffreEmploiForm
19 from project
.recrutement
.models
import \
20 Evaluateur
, CandidatEvaluation
, \
21 ProxyOffreEmploi
, ProxyCandidat
, MesCandidatEvaluation
, \
23 from project
.recrutement
.workflow
import \
24 grp_drh_recrutement
, grp_drh2_recrutement
, \
25 grp_directeurs_bureau_recrutement
, \
26 grp_administrateurs_recrutement
, \
27 grp_correspondants_rh_recrutement
, \
28 grp_haute_direction_recrutement
29 from project
.rh
import models
as rh
33 IMPLANTATIONS_CENTRALES
= [15, 19]
36 class BaseAdmin(admin
.ModelAdmin
):
39 css
= {'screen': ('css/admin_custom.css',)}
42 class OrderedChangeList(admin
.views
.main
.ChangeList
):
44 Surcharge pour appliquer le order_by d'un annotate
46 def get_query_set(self
):
47 qs
= super(OrderedChangeList
, self
).get_query_set()
48 qs
= qs
.order_by('-moyenne')
52 class OffreEmploiAdmin(BaseAdmin
, VersionAdmin
):
53 date_hierarchy
= 'date_creation'
55 'nom', 'date_limite', 'region', 'statut', 'est_affiche',
58 exclude
= ('actif', 'poste_nom', 'resume',)
59 list_filter
= ('statut',)
60 actions
= ['affecter_evaluateurs_offre_emploi', ]
61 form
= OffreEmploiForm
63 ### Actions à afficher
64 def get_actions(self
, request
):
65 actions
= super(OffreEmploiAdmin
, self
).get_actions(request
)
66 del actions
['delete_selected']
69 ### Affecter un évaluateurs à des offres d'emploi
70 def affecter_evaluateurs_offre_emploi(modeladmin
, obj
, candidats
):
71 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
73 return HttpResponseRedirect(
74 reverse('affecter_evaluateurs_offre_emploi') +
75 "?ids=%s" % (",".join(selected
))
78 affecter_evaluateurs_offre_emploi
.short_description
= \
79 u
'Affecter évaluateur(s)'
81 ### Afficher la liste des candidats pour l'offre d'emploi
82 def _candidatsList(self
, obj
):
83 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
84 </a>" % (reverse('admin:recrutement_candidat_changelist'), obj
.id)
85 _candidatsList
.allow_tags
= True
86 _candidatsList
.short_description
= "Afficher la liste des candidats"
89 def get_form(self
, request
, obj
=None, **kwargs
):
90 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
91 employe
= get_emp(request
.user
)
92 user_groupes
= request
.user
.groups
.all()
95 if 'region' in form
.declared_fields
:
96 region_field
= form
.declared_fields
['region']
98 region_field
= form
.base_fields
['region']
100 if grp_drh_recrutement
in user_groupes
or \
101 grp_drh2_recrutement
in user_groupes
or \
102 grp_haute_direction_recrutement
in user_groupes
:
103 region_field
.queryset
= Region
.objects
.all()
105 region_field
.queryset
= Region
.objects
.\
106 filter(id=employe
.implantation
.region
.id)
109 if 'poste' in form
.declared_fields
:
110 poste_field
= form
.declared_fields
['poste']
112 poste_field
= form
.base_fields
['poste']
114 if grp_drh_recrutement
in user_groupes
or \
115 grp_drh2_recrutement
in user_groupes
or \
116 grp_haute_direction_recrutement
in user_groupes
:
117 poste_field
.queryset
= rh
.Poste
.objects
.all()
119 poste_field
.queryset
= rh
.Poste
.objects
.\
120 filter(implantation__region
=employe
.implantation
.region
).\
121 exclude(implantation__in
=IMPLANTATIONS_CENTRALES
)
124 if 'bureau' in form
.declared_fields
:
125 bureau_field
= form
.declared_fields
['bureau']
127 bureau_field
= form
.base_fields
['bureau']
129 if grp_drh_recrutement
in user_groupes
or \
130 grp_drh2_recrutement
in user_groupes
or \
131 grp_haute_direction_recrutement
in user_groupes
:
132 bureau_field
.queryset
= Bureau
.objects
.all()
134 bureau_field
.queryset
= \
135 Bureau
.objects
.filter(region
=employe
.implantation
.region
)
141 def queryset(self
, request
):
142 qs
= self
.model
._default_manager
.get_query_set() \
143 .select_related('offre_emploi')
144 user_groupes
= request
.user
.groups
.all()
145 if grp_drh_recrutement
in user_groupes
or \
146 grp_drh2_recrutement
in user_groupes
or \
147 grp_haute_direction_recrutement
in user_groupes
:
150 if grp_directeurs_bureau_recrutement
in user_groupes
or \
151 grp_correspondants_rh_recrutement
in user_groupes
or \
152 grp_administrateurs_recrutement
in user_groupes
:
153 employe
= get_emp(request
.user
)
154 return qs
.filter(region
=employe
.implantation
.region
)
156 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
157 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
159 e
.candidat
.offre_emploi_id
160 for e
in CandidatEvaluation
.objects
161 .select_related('candidat')
162 .filter(evaluateur
=evaluateur
)
164 return qs
.filter(id__in
=offre_ids
)
168 ### Permission add, delete, change
169 def has_add_permission(self
, request
):
170 user_groupes
= request
.user
.groups
.all()
171 if request
.user
.is_superuser
is True or \
172 grp_drh_recrutement
in user_groupes
or \
173 grp_drh2_recrutement
in user_groupes
or \
174 grp_directeurs_bureau_recrutement
in user_groupes
or \
175 grp_administrateurs_recrutement
in user_groupes
or \
176 grp_haute_direction_recrutement
in user_groupes
:
180 def has_delete_permission(self
, request
, obj
=None):
181 user_groupes
= request
.user
.groups
.all()
182 if request
.user
.is_superuser
is True or \
183 grp_drh_recrutement
in user_groupes
or \
184 grp_drh2_recrutement
in user_groupes
or \
185 grp_directeurs_bureau_recrutement
in user_groupes
or \
186 grp_administrateurs_recrutement
in user_groupes
or \
187 grp_haute_direction_recrutement
in user_groupes
:
191 def has_change_permission(self
, request
, obj
=None):
192 user_groupes
= request
.user
.groups
.all()
193 if request
.user
.is_superuser
is True or \
194 grp_drh_recrutement
in user_groupes
or \
195 grp_drh2_recrutement
in user_groupes
or \
196 grp_directeurs_bureau_recrutement
in user_groupes
or \
197 grp_administrateurs_recrutement
in user_groupes
or \
198 grp_haute_direction_recrutement
in user_groupes
:
203 class ProxyOffreEmploiAdmin(OffreEmploiAdmin
):
205 'nom', 'date_limite', 'region', 'statut', 'est_affiche'
208 'description', 'bureau', 'duree_affectation', 'renumeration',
209 'debut_affectation', 'lieu_affectation', 'nom', 'resume',
210 'date_limite', 'region', 'poste'
216 ('Description générale', {
217 'fields': ('description', 'date_limite',)
220 'fields': ('lieu_affectation', 'bureau', 'region', 'poste',)
224 'debut_affectation', 'duree_affectation', 'renumeration',
230 ### Lieu de redirection après le change
231 def response_change(self
, request
, obj
):
232 return redirect('admin:recrutement_proxyoffreemploi_changelist')
235 def get_form(self
, request
, obj
=None, **kwargs
):
236 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
239 ### Permissions add, delete, change
240 def has_add_permission(self
, request
):
243 def has_delete_permission(self
, request
, obj
=None):
246 def has_change_permission(self
, request
, obj
=None):
247 user_groupes
= request
.user
.groups
.all()
248 if request
.user
.is_superuser
is True or \
249 grp_correspondants_rh_recrutement
in user_groupes
or \
250 grp_drh_recrutement
in user_groupes
or \
251 grp_drh2_recrutement
in user_groupes
or \
252 grp_directeurs_bureau_recrutement
in user_groupes
or \
253 grp_administrateurs_recrutement
in user_groupes
or \
254 grp_haute_direction_recrutement
in user_groupes
:
263 class CandidatPieceInline(admin
.TabularInline
):
264 model
= CandidatPiece
265 fields
= ('candidat', 'nom', 'path',)
270 class ReadOnlyCandidatPieceInline(CandidatPieceInline
):
271 readonly_fields
= ('candidat', 'nom', 'path', )
275 class CandidatEvaluationInlineFormSet(BaseInlineFormSet
):
277 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
279 def __init__(self
, *args
, **kwargs
):
280 super(CandidatEvaluationInlineFormSet
, self
).__init__(*args
, **kwargs
)
281 self
.can_delete
= False
284 class CandidatEvaluationInline(admin
.TabularInline
):
285 model
= CandidatEvaluation
286 fields
= ('evaluateur', 'note', 'commentaire')
289 formset
= CandidatEvaluationInlineFormSet
292 def get_readonly_fields(self
, request
, obj
=None):
294 Empêche la modification des évaluations
297 return self
.readonly_fields
+ ('evaluateur', 'note', 'commentaire')
298 return self
.readonly_fields
301 class CandidatAdmin(BaseAdmin
, VersionAdmin
):
302 search_fields
= ('nom', 'prenom')
303 exclude
= ('actif', )
304 list_editable
= ('statut', )
305 list_display
= ('_candidat', 'offre_emploi',
306 'voir_offre_emploi', 'calculer_moyenne',
307 'afficher_candidat', '_date_creation', 'statut', )
308 list_filter
= ('offre_emploi', 'offre_emploi__region', 'statut', )
312 'fields': ('offre_emploi', )
314 ('Informations personnelles', {
316 'prenom', 'nom', 'genre', 'nationalite',
317 'situation_famille', 'nombre_dependant'
322 'telephone', 'email', 'adresse', 'ville', 'etat_province',
323 'code_postal', 'pays'
326 ('Informations professionnelles', {
328 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
329 'domaine_professionnel'
333 'fields': ('statut', )
338 CandidatEvaluationInline
,
340 actions
= ['envoyer_courriel_candidats']
342 def _candidat(self
, obj
):
343 txt
= u
"%s %s (%s)" % (obj
.nom
.upper(), obj
.prenom
, obj
.genre
)
344 txt
= textwrap
.wrap(txt
, 30)
345 return "<br/>".join(txt
)
346 _candidat
.short_description
= "Candidat"
347 _candidat
.admin_order_field
= "nom"
348 _candidat
.allow_tags
= True
350 def _date_creation(self
, obj
):
351 return obj
.date_creation
352 _date_creation
.admin_order_field
= "date_creation"
353 _date_creation
.short_description
= "Date de réception"
355 ### Actions à afficher
356 def get_actions(self
, request
):
357 actions
= super(CandidatAdmin
, self
).get_actions(request
)
358 del actions
['delete_selected']
361 ### Envoyer un courriel à des candidats
362 def envoyer_courriel_candidats(modeladmin
, obj
, candidats
):
363 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
365 return HttpResponseRedirect(
366 reverse('selectionner_template') + "?ids=%s" % (",".join(selected
))
368 envoyer_courriel_candidats
.short_description
= u
'Envoyer courriel'
370 ### Évaluer un candidat
371 def evaluer_candidat(self
, obj
):
372 return "<a href='%s?candidat__id__exact=%s'>" \
373 "Évaluer le candidat</a>" % (
374 reverse('admin:recrutement_candidatevaluation_changelist'),
377 evaluer_candidat
.allow_tags
= True
378 evaluer_candidat
.short_description
= 'Évaluation'
380 ### Afficher un candidat
381 def afficher_candidat(self
, obj
):
382 items
= [u
"<li><a href='%s%s'>%s</li>" % \
383 (settings
.OE_PRIVE_MEDIA_URL
, pj
.path
, pj
.get_nom_display()) \
384 for pj
in obj
.pieces_jointes()]
385 html
= "<a href='%s'>Voir le candidat</a>" % (
386 reverse('admin:recrutement_proxycandidat_change', args
=(obj
.id,))
388 return "%s<ul>%s</ul>" % (html
, "\n".join(items
))
389 afficher_candidat
.allow_tags
= True
390 afficher_candidat
.short_description
= u
'Détails du candidat'
392 ### Voir l'offre d'emploi
393 def voir_offre_emploi(self
, obj
):
394 return "<a href='%s'>Voir l'offre d'emploi</a>" % (reverse(
395 'admin:recrutement_proxyoffreemploi_change',
396 args
=(obj
.offre_emploi
.id,)
398 voir_offre_emploi
.allow_tags
= True
399 voir_offre_emploi
.short_description
= "Afficher l'offre d'emploi"
401 ### Calculer la moyenne des notes
402 def calculer_moyenne(self
, obj
):
403 evaluations
= CandidatEvaluation
.objects
.filter(candidat
=obj
)
405 notes
= [evaluation
.note
for evaluation
in evaluations \
406 if evaluation
.note
is not None]
409 moyenne_votes
= round(float(sum(notes
)) / len(notes
), 2)
411 moyenne_votes
= "Non disponible"
413 totales
= len(evaluations
)
416 if obj
.statut
== 'REC':
417 if totales
== faites
:
419 elif faites
> 0 and float(totales
) / float(faites
) >= 2:
426 return """<span style="color: %s;">%s (%s/%s)</span>""" % (
427 color
, moyenne_votes
, faites
, totales
429 calculer_moyenne
.allow_tags
= True
430 calculer_moyenne
.short_description
= "Moyenne"
431 calculer_moyenne
.admin_order_field
= ""
433 ### Permissions add, delete, change
434 def has_add_permission(self
, request
):
435 user_groupes
= request
.user
.groups
.all()
436 if request
.user
.is_superuser
is True or \
437 grp_correspondants_rh_recrutement
in user_groupes
or \
438 grp_drh_recrutement
in user_groupes
or \
439 grp_drh2_recrutement
in user_groupes
or \
440 grp_directeurs_bureau_recrutement
in user_groupes
or \
441 grp_administrateurs_recrutement
in user_groupes
or \
442 grp_haute_direction_recrutement
in user_groupes
:
446 def has_delete_permission(self
, request
, obj
=None):
447 user_groupes
= request
.user
.groups
.all()
448 if request
.user
.is_superuser
is True or \
449 grp_correspondants_rh_recrutement
in user_groupes
or \
450 grp_drh_recrutement
in user_groupes
or \
451 grp_drh2_recrutement
in user_groupes
or \
452 grp_directeurs_bureau_recrutement
in user_groupes
or \
453 grp_administrateurs_recrutement
in user_groupes
or \
454 grp_haute_direction_recrutement
in user_groupes
:
458 def has_change_permission(self
, request
, obj
=None):
459 user_groupes
= request
.user
.groups
.all()
460 if request
.user
.is_superuser
is True or \
461 grp_correspondants_rh_recrutement
in user_groupes
or \
462 grp_drh_recrutement
in user_groupes
or \
463 grp_drh2_recrutement
in user_groupes
or \
464 grp_directeurs_bureau_recrutement
in user_groupes
or \
465 grp_administrateurs_recrutement
in user_groupes
or \
466 grp_haute_direction_recrutement
in user_groupes
:
470 def get_changelist(self
, request
, **kwargs
):
471 return OrderedChangeList
473 def queryset(self
, request
):
475 Spécifie un queryset limité, autrement Django exécute un
476 select_related() sans paramètre, ce qui a pour effet de charger tous
477 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
478 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
479 génération d'une requête infinie.
481 qs
= self
.model
._default_manager
.get_query_set() \
482 .select_related('offre_emploi') \
483 .annotate(moyenne
=Avg('evaluations__note'))
485 user_groupes
= request
.user
.groups
.all()
486 if grp_drh_recrutement
in user_groupes
or \
487 grp_drh2_recrutement
in user_groupes
or \
488 grp_haute_direction_recrutement
in user_groupes
:
491 if grp_directeurs_bureau_recrutement
in user_groupes
or \
492 grp_correspondants_rh_recrutement
in user_groupes
or \
493 grp_administrateurs_recrutement
in user_groupes
:
494 employe
= get_emp(request
.user
)
495 return qs
.filter(offre_emploi__region
=employe
.implantation
.region
)
497 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
498 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
499 candidat_ids
= [e
.candidat
.id for e
in
500 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
)]
501 return qs
.filter(id__in
=candidat_ids
)
505 class ProxyCandidatAdmin(CandidatAdmin
):
508 'statut', 'offre_emploi', 'prenom', 'nom', 'genre', 'nationalite',
509 'situation_famille', 'nombre_dependant', 'telephone', 'email',
510 'adresse', 'ville', 'etat_province', 'code_postal', 'pays',
511 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
512 'domaine_professionnel', 'pieces_jointes'
516 'fields': ('offre_emploi', )
518 ('Informations personnelles', {
520 'prenom', 'nom', 'genre', 'nationalite', 'situation_famille',
526 'telephone', 'email', 'adresse', 'ville', 'etat_province',
527 'code_postal', 'pays'
530 ('Informations professionnelles', {
532 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
533 'domaine_professionnel'
537 inlines
= (CandidatEvaluationInline
, )
539 def has_add_permission(self
, request
):
542 def has_delete_permission(self
, request
, obj
=None):
545 def has_change_permission(self
, request
, obj
=None):
546 user_groupes
= request
.user
.groups
.all()
547 if request
.user
.is_superuser
is True or \
548 grp_correspondants_rh_recrutement
in user_groupes
or \
549 grp_drh_recrutement
in user_groupes
or \
550 grp_drh2_recrutement
in user_groupes
or \
551 grp_directeurs_bureau_recrutement
in user_groupes
or \
552 grp_administrateurs_recrutement
in user_groupes
or \
553 grp_haute_direction_recrutement
in user_groupes
:
557 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
558 for e
in obj
.evaluations
.all():
559 if e
.evaluateur
== evaluateur
:
564 def get_actions(self
, request
):
568 class CandidatPieceAdmin(admin
.ModelAdmin
):
569 list_display
= ('nom', 'candidat', )
572 def queryset(self
, request
):
574 Spécifie un queryset limité, autrement Django exécute un
575 select_related() sans paramètre, ce qui a pour effet de charger tous
576 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
577 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
578 génération d'une requête infinie. Affiche la liste de candidats que
579 si le user connecté possède un Evaluateur
581 qs
= self
.model
._default_manager
.get_query_set()
582 return qs
.select_related('candidat')
585 class EvaluateurAdmin(BaseAdmin
, VersionAdmin
):
592 ### Actions à afficher
593 def get_actions(self
, request
):
594 actions
= super(EvaluateurAdmin
, self
).get_actions(request
)
595 del actions
['delete_selected']
598 ### Permissions add, delete, change
599 def has_add_permission(self
, request
):
600 user_groupes
= request
.user
.groups
.all()
601 if request
.user
.is_superuser
is True or \
602 grp_drh_recrutement
in user_groupes
or \
603 grp_drh2_recrutement
in user_groupes
or \
604 grp_haute_direction_recrutement
in user_groupes
:
608 def has_delete_permission(self
, request
, obj
=None):
609 user_groupes
= request
.user
.groups
.all()
610 if request
.user
.is_superuser
is True or \
611 grp_drh_recrutement
in user_groupes
or \
612 grp_drh2_recrutement
in user_groupes
or \
613 grp_haute_direction_recrutement
in user_groupes
:
617 def has_change_permission(self
, request
, obj
=None):
618 user_groupes
= request
.user
.groups
.all()
619 if request
.user
.is_superuser
is True or \
620 grp_drh_recrutement
in user_groupes
or \
621 grp_drh2_recrutement
in user_groupes
or \
622 grp_haute_direction_recrutement
in user_groupes
:
627 class CandidatEvaluationAdmin(BaseAdmin
):
628 search_fields
= ('candidat__nom', 'candidat__prenom')
630 '_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
633 readonly_fields
= ('candidat', 'evaluateur')
634 list_filter
= ('candidat__statut', 'candidat__offre_emploi',)
636 ('Évaluation du candidat', {
637 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
641 def get_actions(self
, request
):
642 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
644 self
.evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
646 self
.evaluateur
= None
648 actions
= super(CandidatEvaluationAdmin
, self
).get_actions(request
)
649 del actions
['delete_selected']
653 def _note(self
, obj
):
655 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
656 un lien pour Évaluer le candidat.
657 Sinon afficher la note.
659 page
= self
.model
.__name__
.lower()
660 redirect_url
= 'admin:recrutement_%s_change' % page
663 label
= "Candidat non évalué"
667 if self
.evaluateur
== obj
.evaluateur
:
668 return "<a href='%s'>%s</a>" % (
669 reverse(redirect_url
, args
=(obj
.id,)), label
673 _note
.allow_tags
= True
674 _note
.short_description
= "Note"
675 _note
.admin_order_field
= 'note'
677 def _statut(self
, obj
):
678 return obj
.candidat
.get_statut_display()
679 _statut
.order_field
= 'candidat__statut'
680 _statut
.short_description
= 'Statut'
682 ### Lien en lecture seule vers le candidat
683 def _candidat(self
, obj
):
684 return "<a href='%s'>%s</a>" \
685 % (reverse('admin:recrutement_proxycandidat_change',
686 args
=(obj
.candidat
.id,)), obj
.candidat
)
687 _candidat
.allow_tags
= True
688 _candidat
.short_description
= 'Candidat'
690 ### Afficher commentaire
691 def _commentaire(self
, obj
):
693 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
694 dans le champ commentaire, Aucun au lieu de (None)
695 Sinon afficher la note.
697 if obj
.commentaire
is None:
699 return obj
.commentaire
700 _commentaire
.allow_tags
= True
701 _commentaire
.short_description
= "Commentaire"
703 ### Afficher offre d'emploi
704 def _offre_emploi(self
, obj
):
705 return "<a href='%s'>%s</a>" % \
706 (reverse('admin:recrutement_proxyoffreemploi_change',
707 args
=(obj
.candidat
.offre_emploi
.id,)), obj
.candidat
.offre_emploi
)
708 _offre_emploi
.allow_tags
= True
709 _offre_emploi
.short_description
= "Voir offre d'emploi"
711 def has_add_permission(self
, request
):
714 def has_delete_permission(self
, request
, obj
=None):
717 def has_change_permission(self
, request
, obj
=None):
719 Permettre la visualisation dans la changelist
720 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
723 user_groupes
= request
.user
.groups
.all()
725 if request
.user
.is_superuser
or \
726 grp_drh_recrutement
in user_groupes
or \
727 grp_drh2_recrutement
in user_groupes
or \
728 grp_correspondants_rh_recrutement
in user_groupes
or \
729 grp_directeurs_bureau_recrutement
in user_groupes
or \
730 grp_administrateurs_recrutement
in user_groupes
or \
731 grp_haute_direction_recrutement
in user_groupes
:
732 is_recrutement
= True
734 is_recrutement
= False
736 return is_recrutement
738 def queryset(self
, request
):
740 Afficher uniquement les évaluations de l'évaluateur, sauf si
741 l'utilisateur est dans les groupes suivants.
743 qs
= self
.model
._default_manager
.get_query_set() \
744 .select_related('offre_emploi')
745 user_groupes
= request
.user
.groups
.all()
747 if grp_drh_recrutement
in user_groupes
or \
748 grp_drh2_recrutement
in user_groupes
or \
749 grp_correspondants_rh_recrutement
in user_groupes
or \
750 grp_directeurs_bureau_recrutement
in user_groupes
or \
751 grp_administrateurs_recrutement
in user_groupes
or \
752 grp_haute_direction_recrutement
in user_groupes
:
755 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
756 candidats_evaluations
= \
757 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
758 candidat__statut__in
=('REC', ))
759 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
760 return qs
.filter(id__in
=candidats_evaluations_ids
)
763 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin
):
765 def has_change_permission(self
, request
, obj
=None):
767 Evaluateur
.objects
.get(user
=request
.user
)
770 is_evaluateur
= False
772 if obj
is None and is_evaluateur
:
776 return request
.user
== obj
.evaluateur
.user
780 def queryset(self
, request
):
781 qs
= self
.model
._default_manager
.get_query_set() \
782 .select_related('offre_emploi')
783 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
784 candidats_evaluations
= \
785 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
786 candidat__statut__in
=('REC', ))
787 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
788 return qs
.filter(id__in
=candidats_evaluations_ids
)
791 class CourrielTemplateAdmin(BaseAdmin
, VersionAdmin
):
792 ### Actions à afficher
793 def get_actions(self
, request
):
794 actions
= super(CourrielTemplateAdmin
, self
).get_actions(request
)
795 del actions
['delete_selected']
798 admin
.site
.register(OffreEmploi
, OffreEmploiAdmin
)
799 admin
.site
.register(ProxyOffreEmploi
, ProxyOffreEmploiAdmin
)
800 admin
.site
.register(Candidat
, CandidatAdmin
)
801 admin
.site
.register(ProxyCandidat
, ProxyCandidatAdmin
)
802 admin
.site
.register(CandidatEvaluation
, CandidatEvaluationAdmin
)
803 admin
.site
.register(MesCandidatEvaluation
, MesCandidatEvaluationAdmin
)
804 admin
.site
.register(Evaluateur
, EvaluateurAdmin
)
805 admin
.site
.register(CourrielTemplate
, CourrielTemplateAdmin
)