1 # -*- encoding: utf-8 -*-
4 from django
.core
.urlresolvers
import reverse
5 from django
.http
import HttpResponseRedirect
6 from django
.contrib
import admin
7 from django
.forms
.models
import BaseInlineFormSet
8 from django
.db
.models
import Avg
9 from django
.conf
import settings
11 from reversion
.admin
import VersionAdmin
12 from datamaster_modeles
.models
import Region
, Bureau
13 from project
.rh
import models
as rh
15 from project
.dae
.utils
import get_employe_from_user
as get_emp
16 from recrutement
.models
import *
17 from recrutement
.workflow
import grp_drh_recrutement
, grp_drh2_recrutement
, \
18 grp_directeurs_bureau_recrutement
, \
19 grp_administrateurs_recrutement
, \
20 grp_correspondants_rh_recrutement
22 from recrutement
.forms
import *
25 IMPLANTATIONS_CENTRALES
= [15, 19]
27 class OrderedChangeList(admin
.views
.main
.ChangeList
):
29 Surcharge pour appliquer le order_by d'un annotate
31 def get_query_set(self
):
32 qs
= super(OrderedChangeList
, self
).get_query_set()
33 qs
= qs
.order_by('-moyenne')
36 class OffreEmploiAdmin(VersionAdmin
):
37 date_hierarchy
= 'date_creation'
38 list_display
= ('nom', 'date_limite', 'region', 'statut',
39 'est_affiche', '_candidatsList', )
40 exclude
= ('actif', 'poste_nom', 'resume',)
41 list_filter
= ('statut',)
42 actions
= ['affecter_evaluateurs_offre_emploi', ]
43 form
= OffreEmploiForm
45 ### Actions à afficher
46 def get_actions(self
, request
):
47 actions
= super(OffreEmploiAdmin
, self
).get_actions(request
)
48 del actions
['delete_selected']
51 ### Affecter un évaluateurs à des offres d'emploi
52 def affecter_evaluateurs_offre_emploi(modeladmin
, obj
, candidats
):
53 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
55 return HttpResponseRedirect(reverse('affecter_evaluateurs_offre_emploi')+
56 "?ids=%s" % (",".join(selected
)))
57 affecter_evaluateurs_offre_emploi
.short_description
= u
'Affecter évaluateur(s)'
59 ### Afficher la liste des candidats pour l'offre d'emploi
60 def _candidatsList(self
, obj
):
61 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
62 </a>" % (reverse('admin:recrutement_candidat_changelist'), obj
.id)
63 _candidatsList
.allow_tags
= True
64 _candidatsList
.short_description
= "Afficher la liste des candidats"
67 def get_form(self
, request
, obj
=None, **kwargs
):
68 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
69 employe
= get_emp(request
.user
)
70 user_groupes
= request
.user
.groups
.all()
74 if form
.declared_fields
.has_key('region'):
75 region_field
= form
.declared_fields
['region']
77 region_field
= form
.base_fields
['region']
79 if grp_drh_recrutement
in user_groupes
or \
80 grp_drh2_recrutement
in user_groupes
:
81 region_field
.queryset
= Region
.objects
.all()
83 region_field
.queryset
= Region
.objects
.\
84 filter(id=employe
.implantation
.region
.id)
87 if form
.declared_fields
.has_key('poste'):
88 poste_field
= form
.declared_fields
['poste']
90 poste_field
= form
.base_fields
['poste']
92 if grp_drh_recrutement
in user_groupes
or \
93 grp_drh2_recrutement
in user_groupes
:
94 poste_field
.queryset
= rh
.Poste
.objects
.all()
96 poste_field
.queryset
= rh
.Poste
.objects
.\
97 filter(implantation__region
=employe
.implantation
.region
).\
98 exclude(implantation__in
=IMPLANTATIONS_CENTRALES
)
101 if form
.declared_fields
.has_key('bureau'):
102 bureau_field
= form
.declared_fields
['bureau']
104 bureau_field
= form
.base_fields
['bureau']
106 if grp_drh_recrutement
in user_groupes
or \
107 grp_drh2_recrutement
in user_groupes
:
108 bureau_field
.queryset
= Bureau
.objects
.all()
110 bureau_field
.queryset
= Bureau
.objects
.\
111 filter(region
=employe
.implantation
.region
)
116 def queryset(self
, request
):
117 qs
= self
.model
._default_manager
.get_query_set().select_related('offre_emploi')
118 user_groupes
= request
.user
.groups
.all()
119 if grp_drh_recrutement
in user_groupes
or \
120 grp_drh2_recrutement
in user_groupes
:
123 if grp_directeurs_bureau_recrutement
in user_groupes
or \
124 grp_correspondants_rh_recrutement
in user_groupes
or \
125 grp_administrateurs_recrutement
in user_groupes
:
126 employe
= get_emp(request
.user
)
127 return qs
.filter(region
=employe
.implantation
.region
)
129 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
130 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
131 offre_ids
= [e
.candidat
.offre_emploi_id
for e
in
132 CandidatEvaluation
.objects
.select_related('candidat').filter(evaluateur
=evaluateur
)]
133 return qs
.filter(id__in
=offre_ids
)
137 ### Permission add, delete, change
138 def has_add_permission(self
, request
):
139 user_groupes
= request
.user
.groups
.all()
140 if request
.user
.is_superuser
is True or \
141 grp_drh_recrutement
in user_groupes
or \
142 grp_drh2_recrutement
in user_groupes
or \
143 grp_directeurs_bureau_recrutement
in user_groupes
or \
144 grp_administrateurs_recrutement
in user_groupes
:
148 def has_delete_permission(self
, request
, obj
=None):
149 user_groupes
= request
.user
.groups
.all()
150 if request
.user
.is_superuser
is True or \
151 grp_drh_recrutement
in user_groupes
or \
152 grp_drh2_recrutement
in user_groupes
or \
153 grp_directeurs_bureau_recrutement
in user_groupes
or \
154 grp_administrateurs_recrutement
in user_groupes
:
158 def has_change_permission(self
, request
, obj
=None):
159 user_groupes
= request
.user
.groups
.all()
160 if request
.user
.is_superuser
is True or \
161 grp_drh_recrutement
in user_groupes
or \
162 grp_drh2_recrutement
in user_groupes
or \
163 grp_directeurs_bureau_recrutement
in user_groupes
or \
164 grp_administrateurs_recrutement
in user_groupes
:
168 class ProxyOffreEmploiAdmin(OffreEmploiAdmin
):
169 list_display
= ('nom', 'date_limite', 'region', 'statut',
171 readonly_fields
= ('description', 'bureau', 'duree_affectation',
172 'renumeration', 'debut_affectation', 'lieu_affectation',
173 'nom', 'resume', 'date_limite', 'region', 'poste')
178 ('Description générale', {
179 'fields': ('description', 'date_limite', )
182 'fields': ('lieu_affectation', 'bureau', 'region', 'poste',)
185 'fields': ('debut_affectation', 'duree_affectation',
192 ### Lieu de redirection après le change
193 def response_change(self
, request
, obj
):
194 return HttpResponseRedirect(reverse\
195 ('admin:recrutement_proxyoffreemploi_changelist'))
198 def get_form(self
, request
, obj
=None, **kwargs
):
199 form
= super(OffreEmploiAdmin
, self
).get_form(request
, obj
, **kwargs
)
202 ### Permissions add, delete, change
203 def has_add_permission(self
, request
):
206 def has_delete_permission(self
, request
, obj
=None):
209 def has_change_permission(self
, request
, obj
=None):
210 user_groupes
= request
.user
.groups
.all()
211 if request
.user
.is_superuser
is True or \
212 grp_correspondants_rh_recrutement
in user_groupes
or \
213 grp_drh_recrutement
in user_groupes
or \
214 grp_drh2_recrutement
in user_groupes
or \
215 grp_directeurs_bureau_recrutement
in user_groupes
or \
216 grp_administrateurs_recrutement
in user_groupes
:
224 class CandidatPieceInline(admin
.TabularInline
):
225 model
= CandidatPiece
226 fields
= ('candidat', 'nom', 'path',)
230 class ReadOnlyCandidatPieceInline(CandidatPieceInline
):
231 readonly_fields
= ('candidat', 'nom', 'path', )
235 class CandidatEvaluationInlineFormSet(BaseInlineFormSet
):
237 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
239 def __init__(self
, *args
, **kwargs
):
240 super(CandidatEvaluationInlineFormSet
, self
).__init__(*args
, **kwargs
)
241 self
.can_delete
= False
243 class CandidatEvaluationInline(admin
.TabularInline
):
244 model
= CandidatEvaluation
245 fields
= ('evaluateur', 'note', 'commentaire')
248 formset
= CandidatEvaluationInlineFormSet
251 def get_readonly_fields(self
, request
, obj
=None):
253 Empêche la modification des évaluations
256 return self
.readonly_fields
+('evaluateur', 'note', 'commentaire')
257 return self
.readonly_fields
259 class CandidatAdmin(VersionAdmin
):
260 search_fields
= ('nom', 'prenom' )
261 exclude
= ('actif', )
262 list_editable
= ('statut', )
263 list_display
= ('_candidat', 'offre_emploi',
264 'voir_offre_emploi', 'calculer_moyenne',
265 'afficher_candidat', '_date_creation', 'statut', )
266 list_filter
= ('offre_emploi', 'offre_emploi__region', 'statut', )
270 'fields': ('offre_emploi', )
272 ('Informations personnelles', {
273 'fields': ('prenom','nom','genre', 'nationalite',
274 'situation_famille', 'nombre_dependant',)
277 'fields': ('telephone', 'email', 'adresse', 'ville',
278 'etat_province', 'code_postal', 'pays', )
280 ('Informations professionnelles', {
281 'fields': ('niveau_diplome','employeur_actuel',
282 'poste_actuel', 'domaine_professionnel',)
285 'fields': ('statut', )
290 CandidatEvaluationInline
,
292 actions
= ['envoyer_courriel_candidats']
294 def _candidat(self
, obj
):
295 txt
= u
"%s %s (%s)" % ( obj
.nom
.upper(), obj
.prenom
,
297 txt
= textwrap
.wrap(txt
, 30)
298 return "<br/>".join(txt
)
299 _candidat
.short_description
= "Candidat"
300 _candidat
.admin_order_field
= "nom"
301 _candidat
.allow_tags
= True
303 def _date_creation(self
, obj
):
304 return obj
.date_creation
305 _date_creation
.admin_order_field
= "date_creation"
306 _date_creation
.short_description
= "Date de réception"
308 ### Actions à afficher
309 def get_actions(self
, request
):
310 actions
= super(CandidatAdmin
, self
).get_actions(request
)
311 del actions
['delete_selected']
314 ### Envoyer un courriel à des candidats
315 def envoyer_courriel_candidats(modeladmin
, obj
, candidats
):
316 selected
= obj
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
318 return HttpResponseRedirect(reverse('selectionner_template')+
319 "?ids=%s" % (",".join(selected
)))
320 envoyer_courriel_candidats
.short_description
= u
'Envoyer courriel'
322 ### Évaluer un candidat
323 def evaluer_candidat(self
, obj
):
324 return "<a href='%s?candidat__id__exact=%s'>Évaluer le candidat</a>" % \
325 (reverse('admin:recrutement_candidatevaluation_changelist'),
327 evaluer_candidat
.allow_tags
= True
328 evaluer_candidat
.short_description
= 'Évaluation'
330 ### Afficher un candidat
331 def afficher_candidat(self
, obj
):
332 items
= [u
"<li><a href='%s%s'>%s</li>" % \
333 (settings
.OE_PRIVE_MEDIA_URL
, pj
.path
, pj
.get_nom_display()) \
334 for pj
in obj
.pieces_jointes()]
335 html
= "<a href='%s'>Voir le candidat</a>" % \
336 (reverse('admin:recrutement_proxycandidat_change', args
=(obj
.id,)))
337 return "%s<ul>%s</ul>" % (html
, "\n".join(items
))
338 afficher_candidat
.allow_tags
= True
339 afficher_candidat
.short_description
= u
'Détails du candidat'
341 ### Voir l'offre d'emploi
342 def voir_offre_emploi(self
, obj
):
343 return "<a href='%s'>Voir l'offre d'emploi</a>" % \
344 (reverse('admin:recrutement_proxyoffreemploi_change',
345 args
=(obj
.offre_emploi
.id,)))
346 voir_offre_emploi
.allow_tags
= True
347 voir_offre_emploi
.short_description
= "Afficher l'offre d'emploi"
349 ### Calculer la moyenne des notes
350 def calculer_moyenne(self
, obj
):
351 evaluations
= CandidatEvaluation
.objects
.filter(candidat
=obj
)
353 notes
= [evaluation
.note
for evaluation
in evaluations \
354 if evaluation
.note
is not None]
357 moyenne_votes
= round(float(sum(notes
)) / len(notes
), 2)
359 moyenne_votes
= "Non disponible"
361 totales
= len(evaluations
)
364 if obj
.statut
== 'REC':
365 if totales
== faites
:
367 elif faites
> 0 and float(totales
) / float(faites
) >= 2:
374 return """<span style="color: %s;">%s (%s/%s)</span>""" % (color
, moyenne_votes
, faites
, totales
)
375 calculer_moyenne
.allow_tags
= True
376 calculer_moyenne
.short_description
= "Moyenne"
377 calculer_moyenne
.admin_order_field
= ""
379 ### Permissions add, delete, change
380 def has_add_permission(self
, request
):
381 user_groupes
= request
.user
.groups
.all()
382 if request
.user
.is_superuser
is True or \
383 grp_correspondants_rh_recrutement
in user_groupes
or \
384 grp_drh_recrutement
in user_groupes
or \
385 grp_drh2_recrutement
in user_groupes
or \
386 grp_directeurs_bureau_recrutement
in user_groupes
or \
387 grp_administrateurs_recrutement
in user_groupes
:
391 def has_delete_permission(self
, request
, obj
=None):
392 user_groupes
= request
.user
.groups
.all()
393 if request
.user
.is_superuser
is True or \
394 grp_correspondants_rh_recrutement
in user_groupes
or \
395 grp_drh_recrutement
in user_groupes
or \
396 grp_drh2_recrutement
in user_groupes
or \
397 grp_directeurs_bureau_recrutement
in user_groupes
or \
398 grp_administrateurs_recrutement
in user_groupes
:
402 def has_change_permission(self
, request
, obj
=None):
403 user_groupes
= request
.user
.groups
.all()
404 if request
.user
.is_superuser
is True or \
405 grp_correspondants_rh_recrutement
in user_groupes
or \
406 grp_drh_recrutement
in user_groupes
or \
407 grp_drh2_recrutement
in user_groupes
or \
408 grp_directeurs_bureau_recrutement
in user_groupes
or \
409 grp_administrateurs_recrutement
in user_groupes
:
413 def get_changelist(self
, request
, **kwargs
):
414 return OrderedChangeList
416 def queryset(self
, request
):
418 Spécifie un queryset limité, autrement Django exécute un
419 select_related() sans paramètre, ce qui a pour effet de charger tous
420 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
421 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
422 génération d'une requête infinie.
426 qs
= self
.model
._default_manager
.get_query_set().select_related('offre_emploi').annotate(moyenne
=Avg('evaluations__note'))
428 user_groupes
= request
.user
.groups
.all()
429 if grp_drh_recrutement
in user_groupes
or \
430 grp_drh2_recrutement
in user_groupes
:
433 if grp_directeurs_bureau_recrutement
in user_groupes
or \
434 grp_correspondants_rh_recrutement
in user_groupes
or \
435 grp_administrateurs_recrutement
in user_groupes
:
436 employe
= get_emp(request
.user
)
437 return qs
.filter(offre_emploi__region
=employe
.implantation
.region
)
439 if Evaluateur
.objects
.filter(user
=request
.user
).exists():
440 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
441 candidat_ids
= [e
.candidat
.id for e
in
442 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
)]
443 return qs
.filter(id__in
=candidat_ids
)
447 class ProxyCandidatAdmin(CandidatAdmin
):
449 readonly_fields
= ('statut', 'offre_emploi', 'prenom', 'nom',
450 'genre', 'nationalite', 'situation_famille',
451 'nombre_dependant', 'telephone', 'email', 'adresse',
452 'ville', 'etat_province', 'code_postal', 'pays',
453 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
454 'domaine_professionnel', 'pieces_jointes',)
457 'fields': ('offre_emploi', )
459 ('Informations personnelles', {
460 'fields': ('prenom','nom','genre', 'nationalite',
461 'situation_famille', 'nombre_dependant',)
464 'fields': ('telephone', 'email', 'adresse', 'ville',
465 'etat_province', 'code_postal', 'pays', )
467 ('Informations professionnelles', {
468 'fields': ('niveau_diplome','employeur_actuel',
469 'poste_actuel', 'domaine_professionnel',)
472 inlines
= (CandidatEvaluationInline
, )
474 def has_add_permission(self
, request
):
477 def has_delete_permission(self
, request
, obj
=None):
480 def has_change_permission(self
, request
, obj
=None):
481 user_groupes
= request
.user
.groups
.all()
482 if request
.user
.is_superuser
is True or \
483 grp_correspondants_rh_recrutement
in user_groupes
or \
484 grp_drh_recrutement
in user_groupes
or \
485 grp_drh2_recrutement
in user_groupes
or \
486 grp_directeurs_bureau_recrutement
in user_groupes
or \
487 grp_administrateurs_recrutement
in user_groupes
:
491 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
492 for e
in obj
.evaluations
.all():
493 if e
.evaluateur
== evaluateur
:
498 def get_actions(self
, request
):
501 class CandidatPieceAdmin(admin
.ModelAdmin
):
502 list_display
= ('nom', 'candidat', )
505 def queryset(self
, request
):
507 Spécifie un queryset limité, autrement Django exécute un
508 select_related() sans paramètre, ce qui a pour effet de charger tous
509 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
510 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
511 génération d'une requête infinie.
512 Affiche la liste de candidats que si le user connecté
513 possède un Evaluateur
515 qs
= self
.model
._default_manager
.get_query_set()
516 return qs
.select_related('candidat')
518 class EvaluateurAdmin(VersionAdmin
):
525 ### Actions à afficher
526 def get_actions(self
, request
):
527 actions
= super(EvaluateurAdmin
, self
).get_actions(request
)
528 del actions
['delete_selected']
531 ### Permissions add, delete, change
532 def has_add_permission(self
, request
):
533 user_groupes
= request
.user
.groups
.all()
534 if request
.user
.is_superuser
is True or \
535 grp_drh_recrutement
in user_groupes
or \
536 grp_drh2_recrutement
in user_groupes
:
540 def has_delete_permission(self
, request
, obj
=None):
541 user_groupes
= request
.user
.groups
.all()
542 if request
.user
.is_superuser
is True or \
543 grp_drh_recrutement
in user_groupes
or \
544 grp_drh2_recrutement
in user_groupes
:
548 def has_change_permission(self
, request
, obj
=None):
549 user_groupes
= request
.user
.groups
.all()
550 if request
.user
.is_superuser
is True or \
551 grp_drh_recrutement
in user_groupes
or \
552 grp_drh2_recrutement
in user_groupes
:
556 class CandidatEvaluationAdmin(admin
.ModelAdmin
):
557 search_fields
= ('candidat__nom', 'candidat__prenom' )
558 list_display
= ('_candidat', '_statut', '_offre_emploi', 'evaluateur', '_note',
560 readonly_fields
= ('candidat', 'evaluateur')
561 list_filter
= ('candidat__statut', 'candidat__offre_emploi',)
563 ('Évaluation du candidat', {
564 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
568 def get_actions(self
, request
):
569 # on stocke l'evaluateur connecté (pas forcément la meilleure place...)
571 self
.evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
573 self
.evaluateur
= None
575 actions
= super(CandidatEvaluationAdmin
, self
).get_actions(request
)
576 del actions
['delete_selected']
580 def _note(self
, obj
):
582 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
583 un lien pour Évaluer le candidat.
584 Sinon afficher la note.
586 page
= self
.model
.__name__
.lower()
587 redirect_url
= 'admin:recrutement_%s_change' % page
590 label
= "Candidat non évalué"
594 if self
.evaluateur
== obj
.evaluateur
:
595 return "<a href='%s'>%s</a>" % (reverse(redirect_url
, args
=(obj
.id,)), label
)
598 _note
.allow_tags
= True
599 _note
.short_description
= "Note"
600 _note
.admin_order_field
= 'note'
602 def _statut(self
, obj
):
603 return obj
.candidat
.get_statut_display()
604 _statut
.order_field
= 'candidat__statut'
605 _statut
.short_description
= 'Statut'
608 ### Lien en lecture seule vers le candidat
609 def _candidat(self
, obj
):
610 return "<a href='%s'>%s</a>" \
611 % (reverse('admin:recrutement_proxycandidat_change',
612 args
=(obj
.candidat
.id,)), obj
.candidat
)
613 _candidat
.allow_tags
= True
614 _candidat
.short_description
= 'Candidat'
616 ### Afficher commentaire
617 def _commentaire(self
, obj
):
619 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
620 dans le champ commentaire, Aucun au lieu de (None)
621 Sinon afficher la note.
623 if obj
.commentaire
is None:
625 return obj
.commentaire
626 _commentaire
.allow_tags
= True
627 _commentaire
.short_description
= "Commentaire"
629 ### Afficher offre d'emploi
630 def _offre_emploi(self
, obj
):
631 return "<a href='%s'>%s</a>" % \
632 (reverse('admin:recrutement_proxyoffreemploi_change',
633 args
=(obj
.candidat
.offre_emploi
.id,)), obj
.candidat
.offre_emploi
)
634 _offre_emploi
.allow_tags
= True
635 _offre_emploi
.short_description
= "Voir offre d'emploi"
637 def has_add_permission(self
, request
):
640 def has_delete_permission(self
, request
, obj
=None):
643 def has_change_permission(self
, request
, obj
=None):
645 Permettre la visualisation dans la changelist
646 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
649 user_groupes
= request
.user
.groups
.all()
651 if request
.user
.is_superuser
or \
652 grp_drh_recrutement
in user_groupes
or \
653 grp_drh2_recrutement
in user_groupes
or \
654 grp_correspondants_rh_recrutement
in user_groupes
or \
655 grp_directeurs_bureau_recrutement
in user_groupes
or \
656 grp_administrateurs_recrutement
in user_groupes
:
657 is_recrutement
= True
659 is_recrutement
= False
661 return is_recrutement
663 def queryset(self
, request
):
665 Afficher uniquement les évaluations de l'évaluateur, sauf si
666 l'utilisateur est dans les groupes suivants.
668 qs
= self
.model
._default_manager
.get_query_set().select_related('offre_emploi')
669 user_groupes
= request
.user
.groups
.all()
671 if grp_drh_recrutement
in user_groupes
or \
672 grp_drh2_recrutement
in user_groupes
or \
673 grp_correspondants_rh_recrutement
in user_groupes
or \
674 grp_directeurs_bureau_recrutement
in user_groupes
or \
675 grp_administrateurs_recrutement
in user_groupes
:
678 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
679 candidats_evaluations
= \
680 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
681 candidat__statut__in
=('REC', ))
682 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
683 return qs
.filter(id__in
=candidats_evaluations_ids
)
686 class MesCandidatEvaluationAdmin(CandidatEvaluationAdmin
):
688 def has_change_permission(self
, request
, obj
=None):
690 Evaluateur
.objects
.get(user
=request
.user
)
693 is_evaluateur
= False
695 if obj
is None and is_evaluateur
:
699 return request
.user
== obj
.evaluateur
.user
703 def queryset(self
, request
):
704 qs
= self
.model
._default_manager
.get_query_set().select_related('offre_emploi')
705 evaluateur
= Evaluateur
.objects
.get(user
=request
.user
)
706 candidats_evaluations
= \
707 CandidatEvaluation
.objects
.filter(evaluateur
=evaluateur
,
708 candidat__statut__in
=('REC', ))
709 candidats_evaluations_ids
= [ce
.id for ce
in candidats_evaluations
]
710 return qs
.filter(id__in
=candidats_evaluations_ids
)
713 class CourrielTemplateAdmin(VersionAdmin
):
714 ### Actions à afficher
715 def get_actions(self
, request
):
716 actions
= super(CourrielTemplateAdmin
, self
).get_actions(request
)
717 del actions
['delete_selected']
720 admin
.site
.register(OffreEmploi
, OffreEmploiAdmin
)
721 admin
.site
.register(ProxyOffreEmploi
, ProxyOffreEmploiAdmin
)
722 admin
.site
.register(Candidat
, CandidatAdmin
)
723 admin
.site
.register(ProxyCandidat
, ProxyCandidatAdmin
)
724 admin
.site
.register(CandidatEvaluation
, CandidatEvaluationAdmin
)
725 admin
.site
.register(MesCandidatEvaluation
, MesCandidatEvaluationAdmin
)
726 admin
.site
.register(Evaluateur
, EvaluateurAdmin
)
727 admin
.site
.register(CourrielTemplate
, CourrielTemplateAdmin
)