df59fcab |
1 | # -*- encoding: utf-8 -*- |
2 | |
6067184b |
3 | from django.core.urlresolvers import reverse |
4 | from django.http import HttpResponseRedirect |
df59fcab |
5 | from django.contrib import admin |
38df74bb |
6 | from django.shortcuts import get_object_or_404 |
7 | |
6067184b |
8 | from reversion.admin import VersionAdmin |
38df74bb |
9 | from datamaster_modeles.models import Employe, Implantation, Region |
6067184b |
10 | |
df59fcab |
11 | from recrutement.models import * |
12 | |
d2b30f5f |
13 | class OffreEmploiAdmin(VersionAdmin): |
7f9e891e |
14 | date_hierarchy = 'date_creation' |
ec517164 |
15 | list_display = ('nom', 'resume', 'date_limite', 'region', '_candidatsList') |
38df74bb |
16 | |
8941aee7 |
17 | # Afficher la liste des candidats pour l'offre d'emploi |
596fe324 |
18 | def _candidatsList(self, obj): |
8ea41642 |
19 | return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \ |
20 | </a>" % (reverse('admin:recrutement_candidat_changelist'), obj.id) |
2f78949d |
21 | _candidatsList.allow_tags = True |
22 | _candidatsList.short_description = "Liste des candidats" |
362a3534 |
23 | |
2f78949d |
24 | def queryset(self, request): |
d835c9f3 |
25 | """ |
26 | N'affiche la liste de candidats que si le user connecté |
27 | possède un UserProfile |
2f78949d |
28 | """ |
29 | qs = self.model._default_manager.get_query_set() |
3bcef02d |
30 | try: |
31 | user = UserProfile.objects.get(user=request.user) |
32 | except UserProfile.DoesNotExist: |
33 | return qs.none() |
4e8e178f |
34 | |
3bcef02d |
35 | region_ids = [g.id for g in user.regions.all()] |
f6749f29 |
36 | return qs.select_related('offre_emploi').filter(region__in=region_ids) |
362a3534 |
37 | |
cced6a23 |
38 | class ProxyCandidatPiece(CandidatPiece): |
39 | """ |
40 | Ce proxy sert uniquement dans l'admin à disposer d'un libellé |
41 | plus ergonomique. |
42 | """ |
43 | class Meta: |
44 | proxy = True |
45 | verbose_name = "pièce jointe" |
74cbc7a7 |
46 | verbose_name_plural = "pièces jointes" |
cced6a23 |
47 | |
170c9aa2 |
48 | class CandidatPieceInline(admin.TabularInline): |
cced6a23 |
49 | model = ProxyCandidatPiece |
50 | fields = ('candidat', 'nom', 'path', ) |
170c9aa2 |
51 | extra = 1 |
52 | |
cced6a23 |
53 | class ProxyEvaluateur(UserProfile.candidats.through): |
54 | """ |
55 | Ce proxy sert uniquement dans l'admin à disposer d'un libellé |
56 | plus ergonomique. |
57 | """ |
58 | class Meta: |
59 | proxy = True |
60 | verbose_name = "évaluateur" |
61 | |
eb579d40 |
62 | class EvaluateurInline(admin.TabularInline): |
cced6a23 |
63 | model = ProxyEvaluateur |
eb579d40 |
64 | extra = 1 |
65 | |
d2b30f5f |
66 | class CandidatAdmin(VersionAdmin): |
7f9e891e |
67 | date_hierarchy = 'date_creation' |
0fd8a26d |
68 | list_display = ('nom', 'prenom', 'offre_emploi','statut', |
8941aee7 |
69 | 'voir_offre_emploi', 'evaluer_candidat', #'note_evaluateur', |
70 | 'calculer_moyenne', 'afficher_candidat',) |
8ea41642 |
71 | list_filter = ('offre_emploi', ) |
7f9e891e |
72 | fieldsets = ( |
4896b661 |
73 | ("Offre d'emploi", { |
74 | 'fields': ('offre_emploi', ) |
75 | }), |
7f9e891e |
76 | ('Informations personnelles', { |
77 | 'fields': ('prenom','nom','genre', 'nationalite', 'date_naissance', |
78 | 'situation_famille', 'nombre_dependant',) |
79 | }), |
ec517164 |
80 | ('Coordonnées', { |
81 | 'fields': ('telephone', 'email', 'adresse', 'ville', |
82 | 'etat_province', 'code_postal', 'pays', ) |
7f9e891e |
83 | }), |
84 | ('Informations professionnelles', { |
4896b661 |
85 | 'fields': ('niveau_diplome','employeur_actuel', |
8ea41642 |
86 | 'poste_actuel', 'domaine_professionnel',) |
7f9e891e |
87 | }), |
88 | ('Options avancées', { |
89 | 'classes': ('collapse',), |
90 | 'fields': ('actif', 'statut', ) |
91 | }), |
92 | ) |
170c9aa2 |
93 | inlines = [ |
94 | CandidatPieceInline, |
eb579d40 |
95 | EvaluateurInline, |
170c9aa2 |
96 | ] |
f9983b5a |
97 | |
52765380 |
98 | actions = ['affecter_candidats_evaluateur', ] #'envoyer_courriel_candidats'] |
362a3534 |
99 | # Affecter un évaluateurs à des candidats |
7061f835 |
100 | def affecter_candidats_evaluateur(modeladmin, obj, candidats): |
596fe324 |
101 | selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME) |
2adf9e0c |
102 | |
8ea41642 |
103 | return HttpResponseRedirect(reverse('affecter_evaluateurs_candidats')+ |
104 | "?ids=%s" % (",".join(selected))) |
d835c9f3 |
105 | affecter_candidats_evaluateur.short_description = u'Affecter évaluateur' |
362a3534 |
106 | |
52765380 |
107 | # Affecter un évaluateurs à des candidats |
108 | def envoyer_courriel_candidats(modeladmin, obj, candidats): |
109 | selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME) |
110 | |
111 | return HttpResponseRedirect(reverse('envoyer_courriel_candidats')+ |
112 | "?ids=%s" % (",".join(selected))) |
113 | envoyer_courriel_candidats.short_description = u'Envoyer courriel' |
114 | |
05503d56 |
115 | # Évaluer un candidat |
596fe324 |
116 | def evaluer_candidat(self, obj): |
8ea41642 |
117 | return "<a href='%s?id=%s'>Évaluer le candidat \ |
118 | </a>" % (reverse('evaluer_candidat'), obj.id) |
596fe324 |
119 | evaluer_candidat.allow_tags = True |
d835c9f3 |
120 | evaluer_candidat.short_description = 'Évaluer' |
596fe324 |
121 | |
7d82fd33 |
122 | # Afficher un candidat |
123 | def afficher_candidat(self, obj): |
124 | return "<a href='%s?id=%s'>Voir le candidat \ |
125 | </a>" % (reverse('afficher_candidat'), obj.id) |
126 | afficher_candidat.allow_tags = True |
127 | afficher_candidat.short_description = u'Afficher les détails' |
128 | |
8941aee7 |
129 | # Voir l'offre d'emploi |
130 | def voir_offre_emploi(self, obj): |
131 | return "<a href='%s?id=%s'>Voir l'offre d'emploi</a> \ |
132 | " % (reverse('admin:recrutement_offreemploi_changelist'), |
133 | obj.offre_emploi.id) |
134 | voir_offre_emploi.allow_tags = True |
135 | voir_offre_emploi.short_description = "Afficher l'offre d'emploi" |
136 | |
137 | """ # Afficher note poster par l'évaluateur |
138 | def note_evaluateur(self, obj): |
139 | import pdb;pdb.set_trace() |
140 | evaluateur = UserProfile.objects.get(user=obj.user) |
141 | import pdb;pdb.set_trace() |
142 | note_eval = CandidatEvaluation.objects.filter(evaluateur=evaluateur, |
143 | candidat=obj.user) |
144 | return "blabla" |
145 | note_evaluateur.allow_tags = True |
146 | note_evaluateur.short_description = "Votre note" |
147 | """ |
148 | |
149 | # Calculer la moyenne des notes |
150 | def calculer_moyenne(self, obj): |
151 | evaluations = CandidatEvaluation.objects.filter(candidat=obj) |
152 | offre_emploi = obj.offre_emploi |
153 | |
154 | notes = [evaluation.note for evaluation in evaluations.all() if evaluation.note is not None] |
155 | |
156 | if len(notes) > 0 and offre_emploi.date_limite <= datetime.date.today(): |
157 | moyenne_votes = float(sum(notes)) / len(notes) |
158 | else: |
159 | moyenne_votes = "Non disponible" |
160 | return moyenne_votes |
161 | calculer_moyenne.allow_tags = True |
162 | calculer_moyenne.short_description = "Moyenne des notes" |
163 | |
4896b661 |
164 | def get_form(self, request, obj=None, **kwargs): |
d835c9f3 |
165 | """ |
166 | Affiche la liste des offres d'emploi, seulement si le user |
167 | connecté possède un UserProfile |
168 | """ |
4896b661 |
169 | form = super(CandidatAdmin, self).get_form(request, obj, **kwargs) |
170 | if form.declared_fields.has_key('offre_emploi'): |
171 | region_field = form.declared_fields['offre_emploi'] |
172 | else: |
173 | region_field = form.base_fields['offre_emploi'] |
174 | |
175 | try: |
176 | user = UserProfile.objects.get(user=request.user) |
177 | except UserProfile.DoesNotExist: |
178 | region_field.queryset = region_field.queryset.none() |
179 | return form |
180 | |
181 | region_ids = [g.id for g in user.regions.all()] |
05503d56 |
182 | region_field.queryset = OffreEmploi.objects.filter(region__in=region_ids) |
4896b661 |
183 | return form |
184 | |
596fe324 |
185 | def queryset(self, obj): |
f9983b5a |
186 | """ |
8ea41642 |
187 | Spécifie un queryset limité, autrement Django exécute un |
188 | select_related() sans paramètre, ce qui a pour effet de charger tous |
189 | les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les |
190 | modèles de Region, il existe plusieurs boucles, ce qui conduit à la |
191 | génération d'une requête infinie. |
d835c9f3 |
192 | |
f9983b5a |
193 | """ |
2adf9e0c |
194 | |
f9983b5a |
195 | qs = self.model._default_manager.get_query_set() |
3bcef02d |
196 | try: |
197 | user = UserProfile.objects.get(user=obj.user) |
198 | except UserProfile.DoesNotExist: |
199 | return qs.none() |
200 | |
2adf9e0c |
201 | ids = [c.id for c in user.candidats.all()] |
202 | return qs.select_related('candidats').filter(id__in=ids) |
df59fcab |
203 | |
2e9ee615 |
204 | class CandidatPieceAdmin(admin.ModelAdmin): |
170c9aa2 |
205 | list_display = ('nom', 'candidat', ) |
206 | |
207 | def queryset(self, request): |
208 | """ |
209 | Spécifie un queryset limité, autrement Django exécute un |
210 | select_related() sans paramètre, ce qui a pour effet de charger tous |
211 | les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les |
212 | modèles de Region, il existe plusieurs boucles, ce qui conduit à la |
213 | génération d'une requête infinie. |
d835c9f3 |
214 | Affiche la liste de candidats que si le user connecté |
215 | possède un UserProfile |
170c9aa2 |
216 | """ |
217 | qs = self.model._default_manager.get_query_set() |
218 | return qs.select_related('candidat') |
2e9ee615 |
219 | |
d2b30f5f |
220 | class EvaluateurAdmin(VersionAdmin): |
eb579d40 |
221 | fieldsets = ( |
3b4bfad3 |
222 | (None, {'fields': ('user', 'regions')}), |
eb579d40 |
223 | (None, {'fields': ('candidats',)}), |
224 | ) |
4418c732 |
225 | |
d835c9f3 |
226 | def get_form(self, request, obj=None, **kwargs): |
227 | """ |
228 | Affiche la liste des users, regions et candidats, seulement si le user |
229 | connecté possède un UserProfile |
230 | """ |
231 | form = super(EvaluateurAdmin, self).get_form(request, obj, **kwargs) |
232 | if form.declared_fields.has_key('user'): |
233 | permission_field = form.declared_fields['user'] |
234 | else: |
235 | permission_field = form.base_fields['user'] |
236 | |
237 | if form.declared_fields.has_key('regions'): |
238 | region_field = form.declared_fields['regions'] |
239 | else: |
240 | region_field = form.base_fields['regions'] |
241 | |
242 | if form.declared_fields.has_key('candidats'): |
243 | candidats_field = form.declared_fields['candidats'] |
244 | else: |
245 | candidats_field = form.base_fields['candidats'] |
246 | |
247 | try: |
248 | user = UserProfile.objects.get(user=request.user) |
249 | except UserProfile.DoesNotExist: |
250 | region_field.queryset = Region.objects.none() |
251 | permission_field.queryset = UserProfile.objects.none() |
252 | candidats_field.queryset = Candidat.objects.none() |
253 | return form |
254 | |
d835c9f3 |
255 | return form |
256 | |
257 | def queryset(self, request): |
258 | """ |
259 | Affiche la liste d'évaluateur que si le user connecté |
260 | possède un UserProfile |
261 | """ |
262 | qs = self.model._default_manager.get_query_set() |
263 | try: |
264 | user = UserProfile.objects.get(user=request.user) |
265 | except UserProfile.DoesNotExist: |
266 | return qs.none() |
267 | |
268 | return qs |
269 | |
d2b30f5f |
270 | class CandidatEvaluationAdmin(VersionAdmin): |
596fe324 |
271 | list_display = ('candidat', 'evaluateur', 'note', 'commentaire', 'date', ) |
272 | |
d835c9f3 |
273 | def get_form(self, request, obj=None, **kwargs): |
596fe324 |
274 | """ |
d835c9f3 |
275 | Affiche la liste des candidats et évaluateur, seulement si le user |
276 | connecté possède un UserProfile |
277 | """ |
278 | form = super(CandidatEvaluationAdmin, self).get_form(request, obj, |
279 | **kwargs) |
280 | if form.declared_fields.has_key('evaluateur'): |
281 | evaluateur_field = form.declared_fields['evaluateur'] |
282 | else: |
283 | evaluateur_field = form.base_fields['evaluateur'] |
284 | |
285 | if form.declared_fields.has_key('candidat'): |
286 | candidats_field = form.declared_fields['candidat'] |
287 | else: |
288 | candidats_field = form.base_fields['candidat'] |
289 | |
290 | try: |
291 | user = UserProfile.objects.get(user=request.user) |
292 | except UserProfile.DoesNotExist: |
293 | evaluateur_field.queryset = UserProfile.objects.none() |
294 | candidats_field.queryset = Candidat.objects.none() |
295 | return form |
296 | |
297 | return form |
298 | |
299 | def queryset(self, request): |
300 | """ |
301 | Affiche la liste d'évaluation que si le user connecté |
302 | possède un UserProfile |
596fe324 |
303 | """ |
304 | qs = self.model._default_manager.get_query_set() |
d835c9f3 |
305 | try: |
306 | user = UserProfile.objects.get(user=request.user) |
307 | except UserProfile.DoesNotExist: |
308 | return qs.none() |
309 | |
a7b36f5a |
310 | return qs.select_related('candidat') |
4418c732 |
311 | |
df59fcab |
312 | admin.site.register(OffreEmploi, OffreEmploiAdmin) |
313 | admin.site.register(Candidat, CandidatAdmin) |
f6749f29 |
314 | admin.site.register(UserProfile, EvaluateurAdmin) |