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):
253 user_groupes
= request
.user
.groups
.all()
254 if request
.user
.is_superuser
is True or \
255 grp_correspondants_rh
in user_groupes
or \
256 grp_drh
in user_groupes
or \
257 grp_drh2
in user_groupes
or \
258 grp_directeurs_bureau
in user_groupes
or \
259 grp_administrateurs
in user_groupes
or \
260 grp_haute_direction
in user_groupes
:
269 class CandidatPieceInline(admin
.TabularInline
):
270 model
= CandidatPiece
271 fields
= ('candidat', 'nom', 'path',)
276 class ReadOnlyCandidatPieceInline(CandidatPieceInline
):
277 readonly_fields
= ('candidat', 'nom', 'path', )
281 class CandidatEvaluationInlineFormSet(BaseInlineFormSet
):
283 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
285 def __init__(self
, *args
, **kwargs
):
286 super(CandidatEvaluationInlineFormSet
, self
).__init__(*args
, **kwargs
)
287 self
.can_delete
= False
290 class CandidatEvaluationInline(admin
.TabularInline
):
291 model
= CandidatEvaluation
292 fields
= ('evaluateur', 'note', 'commentaire')
295 formset
= CandidatEvaluationInlineFormSet
298 def get_readonly_fields(self
, request
, obj
=None):
300 Empêche la modification des évaluations
303 return self
.readonly_fields
+ ('evaluateur', 'note', 'commentaire')
304 return self
.readonly_fields
306 class CandidatAdmin(BaseAdmin
, VersionAdmin
, ExportAdmin
):
307 change_list_template
= 'admin/recrutement/candidat/change_list.html'
308 search_fields
= ('nom', 'prenom')
309 exclude
= ('actif', )
310 list_editable
= ('statut', )
311 list_display
= ('_candidat', 'offre_emploi',
312 'voir_offre_emploi', 'calculer_moyenne',
313 'afficher_candidat', '_date_creation', 'statut', )
314 list_filter
= ('offre_emploi__nom', 'offre_emploi__region', 'statut', )
318 'fields': ('offre_emploi', )
320 ('Informations personnelles', {
322 'prenom', 'nom', 'genre', 'nationalite',
323 'situation_famille', 'nombre_dependant'
328 'telephone', 'email', 'adresse', 'ville', 'etat_province',
329 'code_postal', 'pays'
332 ('Informations professionnelles', {
334 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
335 'domaine_professionnel'
339 'fields': ('statut', )
344 CandidatEvaluationInline
,
346 actions
= ['envoyer_courriel_candidats', 'changer_statut']
348 export_fields
= ['statut', 'offre_emploi', 'prenom', 'nom', 'genre',
349 'nationalite', 'situation_famille', 'nombre_dependant',
350 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
351 'domaine_professionnel', 'telephone', 'email', 'adresse',
352 'ville', 'etat_province', 'code_postal', 'pays']
354 def _candidat(self
, obj
):
355 txt
= u
"%s %s (%s)" % (obj
.nom
.upper(), obj
.prenom
, obj
.genre
)
356 txt
= textwrap
.wrap(txt
, 30)
357 return "<br/>".join(txt
)
358 _candidat
.short_description
= "Candidat"
359 _candidat
.admin_order_field
= "nom"
360 _candidat
.allow_tags
= True
362 def _date_creation(self
, obj
):
363 return obj
.date_creation
364 _date_creation
.admin_order_field
= "date_creation"
365 _date_creation
.short_description
= "Date de réception"
367 ### Actions à afficher
368 def get_actions(self
, request
):
369 actions
= super(CandidatAdmin
, self
).get_actions(request
)
370 del actions
['delete_selected']
373 ### Envoyer un courriel à des candidats
374 def envoyer_courriel_candidats(modeladmin
, obj
, candidats
):
375 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
377 return HttpResponseRedirect(
378 reverse('selectionner_template') + "?ids=%s" % (",".join(selected
))
380 envoyer_courriel_candidats
.short_description
= u
'Envoyer courriel'
382 ### Changer le statut à des candidats
383 def changer_statut(modeladmin
, request
, queryset
):
384 if request
.POST
.get('post'):
385 queryset
.update(statut
=request
.POST
.get('statut'))
389 'action_checkbox_name': admin
.helpers
.ACTION_CHECKBOX_NAME
,
390 'queryset': queryset
,
391 'status': STATUT_CHOICES
,
394 return render_to_response("recrutement/selectionner_statut.html",
395 context
, context_instance
= RequestContext(request
))
397 changer_statut
.short_description
= u
'Changer statut'
399 ### Évaluer un candidat
400 def evaluer_candidat(self
, obj
):
401 return "<a href='%s?candidat__id__exact=%s'>" \
402 "Évaluer le candidat</a>" % (
403 reverse('admin:recrutement_candidatevaluation_changelist'),
406 evaluer_candidat
.allow_tags
= True
407 evaluer_candidat
.short_description
= 'Évaluation'
409 ### Afficher un candidat
410 def afficher_candidat(self
, obj
):
411 items
= [u
"<li><a href='%s%s'>%s</li>" % \
412 (settings
.OE_PRIVE_MEDIA_URL
, pj
.path
, pj
.get_nom_display()) \
413 for pj
in obj
.pieces_jointes()]
414 html
= "<a href='%s'>Candidature</a>" % (
415 reverse('admin:recrutement_proxycandidat_change', args
=(obj
.id,))
417 return "%s<ul>%s</ul>" % (html
, "\n".join(items
))
418 afficher_candidat
.allow_tags
= True
419 afficher_candidat
.short_description
= u
'Détails du candidat'
421 ### Voir l'offre d'emploi
422 def voir_offre_emploi(self
, obj
):
423 return "<a href='%s'>Voir l'offre d'emploi</a>" % (reverse(
424 'admin:recrutement_proxyoffreemploi_change',
425 args
=(obj
.offre_emploi
.id,)
427 voir_offre_emploi
.allow_tags
= True
428 voir_offre_emploi
.short_description
= "Afficher l'offre d'emploi"
430 ### Calculer la moyenne des notes
431 def calculer_moyenne(self
, obj
):
432 evaluations
= CandidatEvaluation
.objects
.filter(candidat
=obj
)
434 notes
= [evaluation
.note
for evaluation
in evaluations \
435 if evaluation
.note
is not None]
438 moyenne_votes
= round(float(sum(notes
)) / len(notes
), 2)
440 moyenne_votes
= "Non disponible"
442 totales
= len(evaluations
)
445 if obj
.statut
== 'REC':
446 if totales
== faites
:
448 elif faites
> 0 and float(totales
) / float(faites
) >= 2:
455 return """<span style="color: %s;">%s (%s/%s)</span>""" % (
456 color
, moyenne_votes
, faites
, totales
458 calculer_moyenne
.allow_tags
= True
459 calculer_moyenne
.short_description
= "Moyenne"
460 calculer_moyenne
.admin_order_field
= ""
462 ### Permissions add, delete, change
463 def has_add_permission(self
, request
):
464 user_groupes
= request
.user
.groups
.all()
465 if request
.user
.is_superuser
is True or \
466 grp_correspondants_rh
in user_groupes
or \
467 grp_drh
in user_groupes
or \
468 grp_drh2
in user_groupes
or \
469 grp_directeurs_bureau
in user_groupes
or \
470 grp_administrateurs
in user_groupes
or \
471 grp_haute_direction
in user_groupes
:
475 def has_delete_permission(self
, request
, obj
=None):
476 user_groupes
= request
.user
.groups
.all()
477 if request
.user
.is_superuser
is True or \
478 grp_correspondants_rh
in user_groupes
or \
479 grp_drh
in user_groupes
or \
480 grp_drh2
in user_groupes
or \
481 grp_directeurs_bureau
in user_groupes
or \
482 grp_administrateurs
in user_groupes
or \
483 grp_haute_direction
in user_groupes
:
487 def has_change_permission(self
, request
, obj
=None):
488 user_groupes
= request
.user
.groups
.all()
489 if request
.user
.is_superuser
is True or \
490 grp_correspondants_rh
in user_groupes
or \
491 grp_drh
in user_groupes
or \
492 grp_drh2
in user_groupes
or \
493 grp_directeurs_bureau
in user_groupes
or \
494 grp_administrateurs
in user_groupes
or \
495 grp_haute_direction
in user_groupes
:
499 def formfield_for_foreignkey(self
, db_field
, request
, **kwargs
):
500 if db_field
.name
== 'offre_emploi':
501 employe
= get_emp(request
.user
)
502 kwargs
["queryset"] = OffreEmploi
.objects
.filter(region
=employe
.implantation
.region
)
503 return db_field
.formfield(**kwargs
)
504 return super(CandidatAdmin
, self
).formfield_for_foreignkey(db_field
, request
, **kwargs
)
506 def get_changelist(self
, request
, **kwargs
):
507 return OrderedChangeList
509 def queryset(self
, request
):
511 Spécifie un queryset limité, autrement Django exécute un
512 select_related() sans paramètre, ce qui a pour effet de charger tous
513 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
514 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
515 génération d'une requête infinie.
517 qs
= self
.model
._default_manager
.get_query_set() \
518 .select_related('offre_emploi') \
519 .annotate(moyenne
=Avg('evaluations__note'))
521 user_groupes
= request
.user
.groups
.all()
522 if grp_drh
in user_groupes
or \
523 grp_drh2
in user_groupes
or \
524 grp_haute_direction
in user_groupes
:
527 if grp_directeurs_bureau
in user_groupes
or \
528 grp_correspondants_rh
in user_groupes
or \
529 grp_administrateurs
in user_groupes
:
530 employe
= get_emp(request
.user
)
531 return qs
.filter(offre_emploi__region
=employe
.implantation
.region
)
533 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
534 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
535 candidat_ids
= [e
.candidat
.id for e
in
536 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
)]
537 return qs
.filter(id__in
=candidat_ids
)
541 class ProxyCandidatAdmin(CandidatAdmin
):
544 'statut', 'offre_emploi', 'prenom', 'nom', 'genre', 'nationalite',
545 'situation_famille', 'nombre_dependant', 'telephone', 'email',
546 'adresse', 'ville', 'etat_province', 'code_postal', 'pays',
547 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
548 'domaine_professionnel', 'pieces_jointes'
552 'fields': ('offre_emploi', )
554 ('Informations personnelles', {
556 'prenom', 'nom', 'genre', 'nationalite', 'situation_famille',
562 'telephone', 'email', 'adresse', 'ville', 'etat_province',
563 'code_postal', 'pays'
566 ('Informations professionnelles', {
568 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
569 'domaine_professionnel'
573 inlines
= (CandidatEvaluationInline
, )
575 def has_add_permission(self
, request
):
578 def has_delete_permission(self
, request
, obj
=None):
581 def has_change_permission(self
, request
, obj
=None):
582 user_groupes
= request
.user
.groups
.all()
583 if request
.user
.is_superuser
is True or \
584 grp_correspondants_rh
in user_groupes
or \
585 grp_drh
in user_groupes
or \
586 grp_drh2
in user_groupes
or \
587 grp_directeurs_bureau
in user_groupes
or \
588 grp_administrateurs
in user_groupes
or \
589 grp_haute_direction
in user_groupes
:
593 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
594 for e
in obj
.evaluations
.all():
595 if e
.evaluateur
== evaluateur
:
600 def get_actions(self
, request
):
604 class CandidatPieceAdmin(admin
.ModelAdmin
):
605 list_display
= ('nom', 'candidat', )
608 def queryset(self
, request
):
610 Spécifie un queryset limité, autrement Django exécute un
611 select_related() sans paramètre, ce qui a pour effet de charger tous
612 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
613 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
614 génération d'une requête infinie. Affiche la liste de candidats que
615 si le user connecté possède un Evaluateur
617 qs
= self
.model
._default_manager
.get_query_set()
618 return qs
.select_related('candidat')
621 class EvaluateurAdmin(BaseAdmin
, VersionAdmin
):
628 ### Actions à afficher
629 def get_actions(self
, request
):
630 actions
= super(EvaluateurAdmin
, self
).get_actions(request
)
631 del actions
['delete_selected']
634 ### Permissions add, delete, change
635 def has_add_permission(self
, request
):
636 user_groupes
= request
.user
.groups
.all()
637 if request
.user
.is_superuser
is True or \
638 grp_drh
in user_groupes
or \
639 grp_drh2
in user_groupes
or \
640 grp_haute_direction
in user_groupes
:
644 def has_delete_permission(self
, request
, obj
=None):
645 user_groupes
= request
.user
.groups
.all()
646 if request
.user
.is_superuser
is True or \
647 grp_drh
in user_groupes
or \
648 grp_drh2
in user_groupes
or \
649 grp_haute_direction
in user_groupes
:
653 def has_change_permission(self
, request
, obj
=None):
654 user_groupes
= request
.user
.groups
.all()
655 if request
.user
.is_superuser
is True or \
656 grp_drh
in user_groupes
or \
657 grp_drh2
in user_groupes
or \
658 grp_haute_direction
in user_groupes
:
663 class CandidatEvaluationAdmin(BaseAdmin
):
664 search_fields
= ('candidat__nom', 'candidat__prenom')
666 '_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
669 readonly_fields
= ('candidat', 'evaluateur')
670 list_filter
= ('candidat__statut', 'candidat__offre_emploi',)
672 ('Évaluation du candidat', {
673 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
677 def get_actions(self
, request
):
678 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
680 self
.evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
682 self
.evaluateur
= None
684 actions
= super(CandidatEvaluationAdmin
, self
).get_actions(request
)
685 del actions
['delete_selected']
689 def _note(self
, obj
):
691 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
692 un lien pour Évaluer le candidat.
693 Sinon afficher la note.
695 page
= self
.model
.__name__
.lower()
696 redirect_url
= 'admin:recrutement_%s_change' % page
699 label
= "Candidat non évalué"
703 if self
.evaluateur
== obj
.evaluateur
:
704 return "<a href='%s'>%s</a>" % (
705 reverse(redirect_url
, args
=(obj
.id,)), label
709 _note
.allow_tags
= True
710 _note
.short_description
= "Note"
711 _note
.admin_order_field
= 'note'
713 def _statut(self
, obj
):
714 return obj
.candidat
.get_statut_display()
715 _statut
.order_field
= 'candidat__statut'
716 _statut
.short_description
= 'Statut'
718 ### Lien en lecture seule vers le candidat
719 def _candidat(self
, obj
):
720 return "<a href='%s'>%s</a>" \
721 % (reverse('admin:recrutement_proxycandidat_change',
722 args
=(obj
.candidat
.id,)), obj
.candidat
)
723 _candidat
.allow_tags
= True
724 _candidat
.short_description
= 'Candidat'
726 ### Afficher commentaire
727 def _commentaire(self
, obj
):
729 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
730 dans le champ commentaire, Aucun au lieu de (None)
731 Sinon afficher la note.
733 if obj
.commentaire
is None:
735 return obj
.commentaire
736 _commentaire
.allow_tags
= True
737 _commentaire
.short_description
= "Commentaire"
739 ### Afficher offre d'emploi
740 def _offre_emploi(self
, obj
):
741 return "<a href='%s'>%s</a>" % \
742 (reverse('admin:recrutement_proxyoffreemploi_change',
743 args
=(obj
.candidat
.offre_emploi
.id,)), obj
.candidat
.offre_emploi
)
744 _offre_emploi
.allow_tags
= True
745 _offre_emploi
.short_description
= "Voir offre d'emploi"
747 def has_add_permission(self
, request
):
750 def has_delete_permission(self
, request
, obj
=None):
753 def has_change_permission(self
, request
, obj
=None):
755 Permettre la visualisation dans la changelist
756 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
759 user_groupes
= request
.user
.groups
.all()
761 if request
.user
.is_superuser
or \
762 grp_drh
in user_groupes
or \
763 grp_drh2
in user_groupes
or \
764 grp_correspondants_rh
in user_groupes
or \
765 grp_directeurs_bureau
in user_groupes
or \
766 grp_administrateurs
in user_groupes
or \
767 grp_haute_direction
in user_groupes
:
768 is_recrutement
= True
770 is_recrutement
= False
772 return is_recrutement
774 def queryset(self
, request
):
776 Afficher uniquement les évaluations de l'évaluateur, sauf si
777 l'utilisateur est dans les groupes suivants.
779 qs
= self
.model
._default_manager
.get_query_set() \
780 .select_related('offre_emploi')
781 user_groupes
= request
.user
.groups
.all()
783 if grp_drh
in user_groupes
or \
784 grp_drh2
in user_groupes
or \
785 grp_correspondants_rh
in user_groupes
or \
786 grp_directeurs_bureau
in user_groupes
or \
787 grp_administrateurs
in user_groupes
or \
788 grp_haute_direction
in user_groupes
:
789 return qs
.filter(candidat__statut__in
=('REC', 'SEL'))
791 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
792 candidats_evaluations
= \
793 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
794 candidat__statut__in
=('REC', ))
795 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
796 return qs
.filter(id__in
=candidats_evaluations_ids
)
799 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin
):
802 def has_change_permission(self
, request
, obj
=None):
804 Evaluateur
.objects
.get(user
=request
.user
)
807 is_evaluateur
= False
809 if obj
is None and is_evaluateur
:
813 return request
.user
== obj
.evaluateur
.user
817 def queryset(self
, request
):
818 qs
= self
.model
._default_manager
.get_query_set() \
819 .select_related('offre_emploi')
820 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
821 candidats_evaluations
= \
822 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
823 candidat__statut__in
=('REC', ))
824 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
825 return qs
.filter(id__in
=candidats_evaluations_ids
)
828 class CourrielTemplateAdmin(BaseAdmin
, VersionAdmin
):
829 ### Actions à afficher
830 def get_actions(self
, request
):
831 actions
= super(CourrielTemplateAdmin
, self
).get_actions(request
)
832 del actions
['delete_selected']
835 admin
.site
.register(OffreEmploi
, OffreEmploiAdmin
)
836 admin
.site
.register(ProxyOffreEmploi
, ProxyOffreEmploiAdmin
)
837 admin
.site
.register(Candidat
, CandidatAdmin
)
838 admin
.site
.register(ProxyCandidat
, ProxyCandidatAdmin
)
839 admin
.site
.register(CandidatEvaluation
, CandidatEvaluationAdmin
)
840 admin
.site
.register(MesCandidatEvaluation
, MesCandidatEvaluationAdmin
)
841 admin
.site
.register(Evaluateur
, EvaluateurAdmin
)
842 admin
.site
.register(CourrielTemplate
, CourrielTemplateAdmin
)