Commit | Line | Data |
---|---|---|
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 |
8e0d552d | 7 | from django.core.files.storage import default_storage |
38df74bb | 8 | |
6067184b | 9 | from reversion.admin import VersionAdmin |
38df74bb | 10 | from datamaster_modeles.models import Employe, Implantation, Region |
6067184b | 11 | |
df59fcab | 12 | from recrutement.models import * |
f6724c20 NBV |
13 | from recrutement.workflow import grp_administrateurs_recrutement,\ |
14 | grp_evaluateurs_recrutement, grp_drh_recrutement | |
df59fcab | 15 | |
d2b30f5f | 16 | class OffreEmploiAdmin(VersionAdmin): |
7f9e891e | 17 | date_hierarchy = 'date_creation' |
4fd0c4a2 NBV |
18 | list_display = ('nom', 'resume', 'date_limite', 'region', 'statut', |
19 | 'est_affiche', '_candidatsList') | |
514db699 | 20 | list_filter = ('statut', 'est_affiche', ) |
c4874d66 NBV |
21 | actions = ['affecter_evaluateurs_offre_emploi', ] |
22 | # Affecter un évaluateurs à des offres d'emploi | |
23 | def affecter_evaluateurs_offre_emploi(modeladmin, obj, candidats): | |
24 | selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME) | |
25 | ||
26 | return HttpResponseRedirect(reverse('affecter_evaluateurs_offre_emploi')+ | |
27 | "?ids=%s" % (",".join(selected))) | |
28 | affecter_evaluateurs_offre_emploi.short_description = u'Affecter évaluateur(s)' | |
29 | ||
8941aee7 | 30 | # Afficher la liste des candidats pour l'offre d'emploi |
596fe324 | 31 | def _candidatsList(self, obj): |
8ea41642 | 32 | return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \ |
33 | </a>" % (reverse('admin:recrutement_candidat_changelist'), obj.id) | |
2f78949d | 34 | _candidatsList.allow_tags = True |
f6724c20 | 35 | _candidatsList.short_description = "Afficher la liste des candidats" |
362a3534 | 36 | |
c4874d66 | 37 | |
2f78949d | 38 | def queryset(self, request): |
382501c1 | 39 | qs = self.model._default_manager.get_query_set() |
f6724c20 NBV |
40 | # Si user est superuser afficher toutes les offres d'emploi |
41 | user_groupes = request.user.groups.all() | |
d46075cb NBV |
42 | if not grp_drh_recrutement in user_groupes and \ |
43 | not request.user.is_superuser: | |
beef7690 | 44 | """ |
beef7690 NBV |
45 | Si le user n'est ni un évaluateur ni un administrateur régional, |
46 | retourner none | |
47 | Vérifier groupes | |
48 | """ | |
f6724c20 | 49 | if grp_evaluateurs_recrutement in user_groupes: |
ca73c3c6 NBV |
50 | try: |
51 | user = Evaluateur.objects.get(user=request.user) | |
52 | except Evaluateur.DoesNotExist: | |
53 | return qs.none() | |
f6724c20 | 54 | elif grp_administrateurs_recrutement in user_groupes: |
ca73c3c6 NBV |
55 | try: |
56 | user = AdministrateurRegional.objects.get(user=request.user) | |
57 | except AdministrateurRegional.DoesNotExist: | |
58 | return qs.none() | |
f6724c20 NBV |
59 | else: |
60 | return qs.none() | |
61 | ||
62 | if type(user) is AdministrateurRegional: | |
63 | region_ids = [g.id for g in user.regions.all()] | |
64 | return qs.select_related('offre_emploi').\ | |
65 | filter(region__in=region_ids) | |
beef7690 | 66 | if type(user) is Evaluateur: |
f6724c20 | 67 | candidats = [g for g in user.candidats.all()] |
beef7690 | 68 | offre_emploi_ids = [c.offre_emploi.id for c in candidats] |
f6724c20 | 69 | return qs.select_related('offre_emploi').\ |
beef7690 | 70 | filter(id__in=offre_emploi_ids) |
3bcef02d | 71 | return qs.none() |
382501c1 | 72 | return qs.select_related('offre_emploi') |
f6724c20 NBV |
73 | |
74 | def has_change_permission(self, request, obj=None): | |
75 | user_groupes = request.user.groups.all() | |
76 | if grp_drh_recrutement in user_groupes or \ | |
d46075cb NBV |
77 | grp_administrateurs_recrutement in user_groupes or \ |
78 | request.user.is_superuser: | |
f6724c20 NBV |
79 | return True |
80 | return False | |
81 | ||
82 | class ProxyOffreEmploiAdmin(OffreEmploiAdmin): | |
4fd0c4a2 NBV |
83 | list_display = ('nom', 'resume', 'date_limite', 'region', 'statut', |
84 | 'est_affiche') | |
14e06ff6 | 85 | readonly_fields = ('description', 'bureau', |
f6724c20 NBV |
86 | 'duree_affectation', 'renumeration', |
87 | 'debut_affectation', 'lieu_affectation', 'nom', | |
88 | 'resume', 'date_limite', 'region') | |
89 | fieldsets = ( | |
720c3ad5 | 90 | ('Nom', { |
f6724c20 NBV |
91 | 'fields': ('nom', ) |
92 | }), | |
720c3ad5 | 93 | ('Description générale', { |
14e06ff6 | 94 | 'fields': ('resume','description', 'date_limite', ) |
f6724c20 | 95 | }), |
720c3ad5 | 96 | ('Coordonnées', { |
f6724c20 NBV |
97 | 'fields': ('lieu_affectation', 'bureau', 'region', ) |
98 | }), | |
720c3ad5 | 99 | ('Autre', { |
f6724c20 NBV |
100 | 'fields': ('debut_affectation', 'duree_affectation', |
101 | 'renumeration', ) | |
102 | }), | |
103 | ) | |
104 | def has_add_permission(self, request): | |
105 | return False | |
106 | ||
107 | def has_delete_permission(self, request, obj=None): | |
108 | return False | |
109 | ||
2d083449 NBV |
110 | def has_change_permission(self, request, obj=None): |
111 | user_groupes = request.user.groups.all() | |
beef7690 | 112 | if grp_evaluateurs_recrutement in user_groupes or \ |
d46075cb NBV |
113 | grp_drh_recrutement in user_groupes or \ |
114 | request.user.is_superuser: | |
2d083449 NBV |
115 | return True |
116 | return False | |
117 | ||
cced6a23 | 118 | class ProxyCandidatPiece(CandidatPiece): |
cced6a23 | 119 | class Meta: |
120 | proxy = True | |
121 | verbose_name = "pièce jointe" | |
74cbc7a7 | 122 | verbose_name_plural = "pièces jointes" |
cced6a23 | 123 | |
170c9aa2 | 124 | class CandidatPieceInline(admin.TabularInline): |
cced6a23 | 125 | model = ProxyCandidatPiece |
8e0d552d | 126 | fields = ('candidat', 'nom', 'path',) |
170c9aa2 | 127 | extra = 1 |
8e0d552d | 128 | max_num = 3 |
170c9aa2 | 129 | |
27c81d11 | 130 | class ProxyEvaluateur(Evaluateur.candidats.through): |
cced6a23 | 131 | """ |
132 | Ce proxy sert uniquement dans l'admin à disposer d'un libellé | |
133 | plus ergonomique. | |
134 | """ | |
135 | class Meta: | |
136 | proxy = True | |
137 | verbose_name = "évaluateur" | |
138 | ||
eb579d40 | 139 | class EvaluateurInline(admin.TabularInline): |
cced6a23 | 140 | model = ProxyEvaluateur |
720c3ad5 | 141 | fields = ('evaluateur',) |
eb579d40 | 142 | extra = 1 |
143 | ||
d2b30f5f | 144 | class CandidatAdmin(VersionAdmin): |
7f9e891e | 145 | date_hierarchy = 'date_creation' |
0fd8a26d | 146 | list_display = ('nom', 'prenom', 'offre_emploi','statut', |
dc7faf2b NBV |
147 | 'voir_offre_emploi', 'calculer_moyenne', |
148 | 'afficher_candidat',) | |
8ea41642 | 149 | list_filter = ('offre_emploi', ) |
7f9e891e | 150 | fieldsets = ( |
4896b661 | 151 | ("Offre d'emploi", { |
152 | 'fields': ('offre_emploi', ) | |
153 | }), | |
7f9e891e | 154 | ('Informations personnelles', { |
4fd0c4a2 | 155 | 'fields': ('prenom','nom','genre', 'nationalite', |
7f9e891e | 156 | 'situation_famille', 'nombre_dependant',) |
157 | }), | |
ec517164 | 158 | ('Coordonnées', { |
159 | 'fields': ('telephone', 'email', 'adresse', 'ville', | |
160 | 'etat_province', 'code_postal', 'pays', ) | |
7f9e891e | 161 | }), |
162 | ('Informations professionnelles', { | |
4896b661 | 163 | 'fields': ('niveau_diplome','employeur_actuel', |
8ea41642 | 164 | 'poste_actuel', 'domaine_professionnel',) |
7f9e891e | 165 | }), |
65c4cbd9 NBV |
166 | ('Traitement', { |
167 | 'fields': ('statut', ) | |
7f9e891e | 168 | }), |
169 | ) | |
170c9aa2 | 170 | inlines = [ |
171 | CandidatPieceInline, | |
eb579d40 | 172 | EvaluateurInline, |
170c9aa2 | 173 | ] |
f9983b5a | 174 | |
4e8340cf | 175 | actions = ['affecter_candidats_evaluateur', 'envoyer_courriel_candidats'] |
362a3534 | 176 | # Affecter un évaluateurs à des candidats |
7061f835 | 177 | def affecter_candidats_evaluateur(modeladmin, obj, candidats): |
596fe324 | 178 | selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME) |
2adf9e0c | 179 | |
8ea41642 | 180 | return HttpResponseRedirect(reverse('affecter_evaluateurs_candidats')+ |
181 | "?ids=%s" % (",".join(selected))) | |
c4874d66 | 182 | affecter_candidats_evaluateur.short_description = u'Affecter évaluateur(s)' |
362a3534 | 183 | |
4e8340cf | 184 | # Envoyer un courriel à des candidats |
52765380 | 185 | def envoyer_courriel_candidats(modeladmin, obj, candidats): |
186 | selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME) | |
187 | ||
32834000 | 188 | return HttpResponseRedirect(reverse('selectionner_template')+ |
52765380 | 189 | "?ids=%s" % (",".join(selected))) |
190 | envoyer_courriel_candidats.short_description = u'Envoyer courriel' | |
191 | ||
05503d56 | 192 | # Évaluer un candidat |
596fe324 | 193 | def evaluer_candidat(self, obj): |
dc7faf2b | 194 | return "<a href='%s?candidat__id__exact=%s'>Évaluer le candidat</a>" % \ |
beef7690 NBV |
195 | (reverse('admin:recrutement_candidatevaluation_changelist'), |
196 | obj.id) | |
596fe324 | 197 | evaluer_candidat.allow_tags = True |
beef7690 | 198 | evaluer_candidat.short_description = 'Évaluation' |
596fe324 | 199 | |
7d82fd33 | 200 | # Afficher un candidat |
201 | def afficher_candidat(self, obj): | |
382501c1 NBV |
202 | return "<a href='%s'>Voir le candidat</a>" % \ |
203 | (reverse('admin:recrutement_proxycandidat_change', args=(obj.id,))) | |
7d82fd33 | 204 | afficher_candidat.allow_tags = True |
8e0d552d | 205 | afficher_candidat.short_description = u'Détails du candidat' |
7d82fd33 | 206 | |
8941aee7 | 207 | # Voir l'offre d'emploi |
208 | def voir_offre_emploi(self, obj): | |
720c3ad5 NBV |
209 | return "<a href='%s'>Voir l'offre d'emploi</a>" % \ |
210 | (reverse('admin:recrutement_proxyoffreemploi_change', | |
211 | args=(obj.offre_emploi.id,))) | |
8941aee7 | 212 | voir_offre_emploi.allow_tags = True |
213 | voir_offre_emploi.short_description = "Afficher l'offre d'emploi" | |
214 | ||
8941aee7 | 215 | # Calculer la moyenne des notes |
216 | def calculer_moyenne(self, obj): | |
217 | evaluations = CandidatEvaluation.objects.filter(candidat=obj) | |
218 | offre_emploi = obj.offre_emploi | |
219 | ||
f6724c20 NBV |
220 | notes = [evaluation.note for evaluation in evaluations.all() \ |
221 | if evaluation.note is not None] | |
8941aee7 | 222 | |
223 | if len(notes) > 0 and offre_emploi.date_limite <= datetime.date.today(): | |
224 | moyenne_votes = float(sum(notes)) / len(notes) | |
225 | else: | |
226 | moyenne_votes = "Non disponible" | |
227 | return moyenne_votes | |
228 | calculer_moyenne.allow_tags = True | |
229 | calculer_moyenne.short_description = "Moyenne des notes" | |
230 | ||
f6724c20 NBV |
231 | def add_delete_permission(self, request, obj=None) : |
232 | user_groupes = request.user.groups.all() | |
233 | if grp_drh_recrutement in user_groupes or \ | |
d46075cb NBV |
234 | grp_administrateurs_recrutement in user_groupes or \ |
235 | request.user.is_superuser: | |
f6724c20 NBV |
236 | return True |
237 | return False | |
4896b661 | 238 | |
f6724c20 NBV |
239 | def has_add_permission(self, request): |
240 | return self.add_delete_permission(request, request) | |
4896b661 | 241 | |
f6724c20 NBV |
242 | def has_delete_permission(self, request, obj=None): |
243 | return self.add_delete_permission(request, request) | |
244 | ||
245 | def has_change_permission(self, request, obj=None): | |
246 | user_groupes = request.user.groups.all() | |
247 | if grp_drh_recrutement in user_groupes or \ | |
d46075cb NBV |
248 | grp_administrateurs_recrutement in user_groupes or \ |
249 | request.user.is_superuser: | |
f6724c20 NBV |
250 | return True |
251 | return False | |
4896b661 | 252 | |
d46075cb | 253 | def queryset(self, request): |
f9983b5a | 254 | """ |
8ea41642 | 255 | Spécifie un queryset limité, autrement Django exécute un |
256 | select_related() sans paramètre, ce qui a pour effet de charger tous | |
257 | les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les | |
258 | modèles de Region, il existe plusieurs boucles, ce qui conduit à la | |
259 | génération d'une requête infinie. | |
d835c9f3 | 260 | |
f9983b5a | 261 | """ |
f6724c20 NBV |
262 | qs = self.model._default_manager.get_query_set() |
263 | # Si user est superuser afficher tous les candidats | |
d46075cb NBV |
264 | user_groupes = request.user.groups.all() |
265 | if not grp_drh_recrutement in user_groupes and \ | |
266 | not request.user.is_superuser: | |
f6724c20 NBV |
267 | # Si le user n'est ni un évaluateur ni un administrateur régional, |
268 | # retourner none | |
269 | ||
270 | # Vérifier groupes | |
271 | if grp_evaluateurs_recrutement in user_groupes: | |
ca73c3c6 NBV |
272 | try: |
273 | user = Evaluateur.objects.get(user=obj.user) | |
274 | except Evaluateur.DoesNotExist: | |
275 | return qs.none() | |
efedc086 NBV |
276 | """ |
277 | elif grp_administrateurs_recrutement in user_groupes: | |
278 | try: | |
279 | user = AdministrateurRegional.objects.get(user=obj.user) | |
280 | except AdministrateurRegional.DoesNotExist: | |
281 | return qs.none() | |
282 | """ | |
f6724c20 NBV |
283 | else: |
284 | return qs.none() | |
f6724c20 NBV |
285 | ids = [c.id for c in user.candidats.all()] |
286 | return qs.select_related('candidats').filter(id__in=ids) | |
287 | return qs.select_related('candidats') | |
288 | ||
289 | class ProxyCandidatAdmin(CandidatAdmin): | |
f6724c20 | 290 | readonly_fields = ('statut', 'offre_emploi', 'prenom', 'nom', |
4fd0c4a2 NBV |
291 | 'genre', 'nationalite', 'situation_famille', |
292 | 'nombre_dependant', 'telephone', 'email', 'adresse', | |
293 | 'ville', 'etat_province', 'code_postal', 'pays', | |
294 | 'niveau_diplome', 'employeur_actuel', 'poste_actuel', | |
8e0d552d | 295 | 'domaine_professionnel', 'pieces_jointes',) |
2d083449 NBV |
296 | fieldsets = ( |
297 | ("Offre d'emploi", { | |
298 | 'fields': ('offre_emploi', ) | |
299 | }), | |
300 | ('Informations personnelles', { | |
4fd0c4a2 | 301 | 'fields': ('prenom','nom','genre', 'nationalite', |
2d083449 NBV |
302 | 'situation_famille', 'nombre_dependant',) |
303 | }), | |
304 | ('Coordonnées', { | |
305 | 'fields': ('telephone', 'email', 'adresse', 'ville', | |
306 | 'etat_province', 'code_postal', 'pays', ) | |
307 | }), | |
308 | ('Informations professionnelles', { | |
309 | 'fields': ('niveau_diplome','employeur_actuel', | |
310 | 'poste_actuel', 'domaine_professionnel',) | |
8e0d552d | 311 | }), |
2d083449 | 312 | ) |
f6724c20 | 313 | inlines = [] |
2d083449 | 314 | |
f6724c20 NBV |
315 | def has_add_permission(self, request): |
316 | return False | |
317 | ||
318 | def has_delete_permission(self, request, obj=None): | |
319 | return False | |
2adf9e0c | 320 | |
2d083449 NBV |
321 | def has_change_permission(self, request, obj=None): |
322 | user_groupes = request.user.groups.all() | |
beef7690 NBV |
323 | if grp_drh_recrutement in user_groupes or \ |
324 | grp_administrateurs_recrutement in user_groupes or \ | |
d46075cb NBV |
325 | grp_evaluateurs_recrutement in user_groupes or \ |
326 | request.user.is_superuser: | |
2d083449 NBV |
327 | return True |
328 | return False | |
329 | ||
2e9ee615 | 330 | class CandidatPieceAdmin(admin.ModelAdmin): |
170c9aa2 | 331 | list_display = ('nom', 'candidat', ) |
332 | ||
333 | def queryset(self, request): | |
334 | """ | |
335 | Spécifie un queryset limité, autrement Django exécute un | |
336 | select_related() sans paramètre, ce qui a pour effet de charger tous | |
337 | les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les | |
338 | modèles de Region, il existe plusieurs boucles, ce qui conduit à la | |
339 | génération d'une requête infinie. | |
d835c9f3 | 340 | Affiche la liste de candidats que si le user connecté |
27c81d11 | 341 | possède un Evaluateur |
170c9aa2 | 342 | """ |
343 | qs = self.model._default_manager.get_query_set() | |
344 | return qs.select_related('candidat') | |
2e9ee615 | 345 | |
d2b30f5f | 346 | class EvaluateurAdmin(VersionAdmin): |
eb579d40 | 347 | fieldsets = ( |
f6724c20 | 348 | (None, {'fields': ('user', )}), |
720c3ad5 | 349 | #(None, {'fields': ('candidats',)}), |
eb579d40 | 350 | ) |
4418c732 | 351 | |
b89fef74 | 352 | class AdministrateurRegionalAdmin(VersionAdmin): |
27c81d11 | 353 | pass |
354 | ||
d2b30f5f | 355 | class CandidatEvaluationAdmin(VersionAdmin): |
b903198b NBV |
356 | list_display = ('_offre_emploi', '_candidat', 'evaluateur', '_note', |
357 | '_commentaire', ) | |
beef7690 NBV |
358 | readonly_fields = ('candidat', 'evaluateur') |
359 | fieldsets = ( | |
360 | ('Évaluation du candidat', { | |
361 | 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', ) | |
362 | }), | |
363 | ) | |
364 | ||
365 | def _note(self, obj): | |
366 | """ | |
367 | Si l'évaluateur n'a pas encore donné de note au candidat, indiquer | |
368 | un lien pour Évaluer le candidat. | |
369 | Sinon afficher la note. | |
370 | """ | |
b903198b NBV |
371 | evaluateur = obj.evaluateur |
372 | candidat = obj.candidat | |
373 | candidat_evaluation = CandidatEvaluation.objects.\ | |
374 | get(candidat=candidat, evaluateur=evaluateur) | |
beef7690 | 375 | if obj.note is None: |
b903198b | 376 | return "<a href='%s'>Candidat non évalué</a>" % \ |
beef7690 | 377 | (reverse('admin:recrutement_candidatevaluation_change', |
b903198b NBV |
378 | args=(candidat_evaluation.id,))) |
379 | return "<a href='%s'>%s</a>" % \ | |
380 | (reverse('admin:recrutement_candidatevaluation_change', | |
381 | args=(candidat_evaluation.id,)), obj.note) | |
382 | return | |
beef7690 NBV |
383 | _note.allow_tags = True |
384 | _note.short_description = "Votre note" | |
385 | _note.admin_order_field = 'note' | |
386 | ||
387 | def _candidat(self, obj): | |
388 | return "<a href='%s'>%s</a>" \ | |
389 | % (reverse('admin:recrutement_proxycandidat_change', | |
390 | args=(obj.candidat.id,)), obj.candidat) | |
391 | _candidat.allow_tags = True | |
392 | _candidat.short_description = 'Candidat' | |
393 | ||
394 | def _commentaire(self, obj): | |
395 | """ | |
396 | Si l'évaluateur n'a pas encore donné de note au candidat, indiquer | |
397 | dans le champ commentaire, Aucun au lieu de (None) | |
398 | Sinon afficher la note. | |
399 | """ | |
400 | if obj.commentaire is None: | |
401 | return "Aucun" | |
402 | return obj.commentaire | |
403 | _commentaire.allow_tags = True | |
404 | _commentaire.short_description = "Commentaire" | |
720c3ad5 | 405 | |
720c3ad5 | 406 | |
beef7690 NBV |
407 | def _offre_emploi(self, obj): |
408 | return "<a href='%s'>%s</a>" % \ | |
409 | (reverse('admin:recrutement_proxyoffreemploi_change', | |
dc7faf2b | 410 | args=(obj.candidat.offre_emploi.id,)), obj.candidat.offre_emploi) |
beef7690 NBV |
411 | _offre_emploi.allow_tags = True |
412 | _offre_emploi.short_description = "Voir offre d'emploi" | |
413 | _offre_emploi.admin_order_field = 'offre_emploi' | |
414 | ||
21b02da5 NBV |
415 | def has_change_permission(self, request, obj=None): |
416 | """ | |
417 | Permettre la visualisation dans la changelist | |
418 | mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas | |
419 | le request.user | |
420 | """ | |
421 | return obj is None or request.user == obj.evaluateur.user | |
422 | ||
720c3ad5 | 423 | def queryset(self, request): |
beef7690 NBV |
424 | """ |
425 | Afficher uniquement les évaluations de l'évaluateur, sauf si | |
426 | l'utilisateur est super admin. | |
427 | """ | |
720c3ad5 | 428 | qs = self.model._default_manager.get_query_set() |
beef7690 | 429 | user_groupes = request.user.groups.all() |
d46075cb NBV |
430 | if grp_drh_recrutement in user_groupes or \ |
431 | request.user.is_superuser: | |
beef7690 NBV |
432 | return qs.select_related('offre_emploi') |
433 | ||
ca73c3c6 | 434 | try: |
d069cdf1 | 435 | evaluateur = Evaluateur.objects.get(user=request.user) |
ca73c3c6 NBV |
436 | except Evaluateur.DoesNotExist: |
437 | return qs.none() | |
438 | ||
439 | candidats_evaluations = CandidatEvaluation.objects.\ | |
440 | filter(evaluateur=evaluateur) | |
441 | candidats_evaluations_ids = [ce.id for ce in \ | |
442 | candidats_evaluations.all()] | |
443 | return qs.select_related('offre_emploi').\ | |
444 | filter(id__in=candidats_evaluations_ids) | |
596fe324 | 445 | |
4e8340cf | 446 | class CourrielTemplateAdmin(VersionAdmin): |
447 | pass | |
448 | ||
df59fcab | 449 | admin.site.register(OffreEmploi, OffreEmploiAdmin) |
382501c1 | 450 | admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin) |
df59fcab | 451 | admin.site.register(Candidat, CandidatAdmin) |
382501c1 | 452 | admin.site.register(ProxyCandidat, ProxyCandidatAdmin) |
720c3ad5 | 453 | admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin) |
27c81d11 | 454 | admin.site.register(Evaluateur, EvaluateurAdmin) |
beef7690 | 455 | #admin.site.register(AdministrateurRegional, AdministrateurRegionalAdmin) |
32834000 | 456 | admin.site.register(CourrielTemplate, CourrielTemplateAdmin) |