date poste import
[auf_rh_dae.git] / project / rh / admin.py
CommitLineData
53ae644d
OL
1# -*- encoding: utf-8 -*-
2
3from collections import defaultdict
4import datetime
5
6from django.db import models
7from django import forms
8from django.core.urlresolvers import reverse
50fa9bc1 9from django.contrib import admin
3195667e 10from django.contrib.admin.views.main import ChangeList as DjangoChangeList
53ae644d
OL
11from django.conf import settings
12from django.db.models import Q
5f36f262 13from django.template.defaultfilters import date
53ae644d
OL
14from ajax_select import make_ajax_form
15from auf.django.metadata.admin import AUFMetadataAdminMixin, AUFMetadataInlineAdminMixin, AUF_METADATA_READONLY_FIELDS
16from forms import ContratForm, AyantDroitForm, EmployeAdminForm, AjaxSelect
17from dae.utils import get_employe_from_user
a0d365ed 18from groups import grp_drh
53ae644d 19import models as rh
f614ca5c
OL
20import filters
21
40b35603
OL
22################################################################################
23# FILTRAGE PAR DATE
24################################################################################
25class DateRangeMixin(object):
26 """
27 Mixin pour que le model admin utilise le changelist trafiqué permettant de filter par range
28 non strict.
29 Par défaut, le filtrage est configuré sur aujourd'hui, soit les actifs
30 """
7f4d1233
OL
31 date_borne_gauche = 'date_debut'
32 date_borne_droite = 'date_fin'
40b35603
OL
33 def get_changelist(self, request, **kwargs):
34 if request.META.has_key('HTTP_REFERER'):
35 referer = request.META['HTTP_REFERER']
36 referer = "/".join(referer.split('/')[3:])
37 referer = "/%s" % referer.split('?')[0]
38 change_list_view = 'admin:%s_%s_changelist' % (self.model._meta.app_label, self.model.__name__.lower())
39 if referer != reverse(change_list_view):
40 params = request.GET.copy()
41 today = datetime.date.today()
7f4d1233 42 params.update({'%s__gte' % self.date_borne_gauche : str(today), '%s__lte' % self.date_borne_droite : str(today) })
40b35603
OL
43 request.GET = params
44 return ChangeList
3195667e
OL
45
46class ChangeList(DjangoChangeList):
47
48 def __init__(self, *args, **kwargs):
49 super(ChangeList, self).__init__(*args, **kwargs)
50
51 def get_query_set(self):
52 old = self.params.copy()
53 date_debut = None
54 date_fin = None
55 for k, v in self.params.items():
b46d18bc
OL
56 if 'date_debut' in k:
57 prefix_debut = "".join(k.split('date_debut')[0:-1]) + 'date_debut'
3195667e
OL
58 date_debut = v
59 del self.params[k]
b46d18bc
OL
60 elif 'date_fin' in k:
61 prefix_fin = "".join(k.split('date_fin')[0:-1]) + 'date_fin'
3195667e
OL
62 date_fin = v
63 del self.params[k]
3195667e
OL
64 qs = super(ChangeList, self).get_query_set()
65
d48f0922 66 # hack pour spécifier un range
3195667e 67 if date_fin is None and date_debut is not None:
d48f0922 68 date_fin = '2020-01-01'
b46d18bc 69 prefix_fin = prefix_debut.replace('debut', 'fin')
3195667e 70 if date_debut is None and date_fin is not None:
d48f0922 71 date_debut = '1000-01-01'
b46d18bc 72 prefix_debut = prefix_fin.replace('fin', 'debut')
3195667e
OL
73
74 if date_debut is not None and date_fin is not None:
b46d18bc
OL
75 q_left = (Q(**{'%s__isnull' % prefix_debut : True}) | Q(**{'%s__lte' % prefix_debut : date_debut})) & (Q(**{'%s__gte' % prefix_fin : date_debut}) & Q(**{'%s__lte' % prefix_fin : date_fin}))
76 q_right = (Q(**{'%s__isnull' % prefix_fin : True}) | Q(**{'%s__gte' % prefix_fin : date_fin})) & (Q(**{'%s__gte' % prefix_debut : date_debut}) & Q(**{'%s__lte' % prefix_debut : date_fin}))
860c9ec9 77 q_both = Q(**{'%s__isnull' % prefix_fin : True}) | Q(**{'%s__lte' % prefix_fin : date_fin}) & (Q(**{'%s__isnull' % prefix_debut : True}) | Q(**{'%s__gte' % prefix_debut : date_debut}))
6b1d6053 78 q_non_supprime = Q(**{'%s__exact' % prefix_debut.replace('date_debut', 'supprime') : False})
860c9ec9 79 q = (q_left | q_right | q_both) & q_non_supprime
6b1d6053 80 qs = qs.filter(q).distinct()
3195667e 81
3195667e
OL
82 self.params = old
83 return qs
84
40b35603
OL
85################################################################################
86
53ae644d
OL
87# Override of the InlineModelAdmin to support the link in the tabular inline
88class LinkedInline(admin.options.InlineModelAdmin):
89 template = "admin/linked.html"
90 admin_model_path = None
91
92 def __init__(self, *args):
93 super(LinkedInline, self).__init__(*args)
94 if self.admin_model_path is None:
95 self.admin_model_path = self.model.__name__.lower()
96
97
98class ProtectRegionMixin(object):
99
100 def queryset(self, request):
101 from dae.workflow import grp_drh, grp_correspondants_rh
102 qs = super(ProtectRegionMixin, self).queryset(request)
103
104 if request.user.is_superuser:
105 return qs
106
107 user_groups = request.user.groups.all()
108
109 if grp_drh in user_groups:
110 return qs
111
112 if grp_correspondants_rh in user_groups:
113 employe = get_employe_from_user(request.user)
114 q = Q(**{self.model.prefix_implantation: employe.implantation.region})
115 qs = qs.filter(q).distinct()
116 return qs
117 return qs.none()
118
119 def has_change_permission(self, request, obj=None):
20b4867c 120 user_groups = request.user.groups.all()
a0d365ed
OL
121
122 # Lock pour autoriser uniquement les DRH à utiliser RH
123 if not request.user.is_superuser and not grp_drh in user_groups:
124 return False
125
a18bc295 126 if len(user_groups) == 0 and not request.user.is_superuser:
20b4867c
OL
127 return False
128
53ae644d
OL
129 if obj is None:
130 return True
131 ids = [o.id for o in self.queryset(request)]
132 return obj.id in ids
133
134
135# Inlines
136
137class ReadOnlyInlineMixin(object):
138 def get_readonly_fields(self, request, obj=None):
139 return [f.name for f in self.model._meta.fields if f.name not in AUF_METADATA_READONLY_FIELDS]
140
141
142class AyantDroitInline(AUFMetadataInlineAdminMixin, admin.StackedInline):
143 model = rh.AyantDroit
144 form = AyantDroitForm
145 extra = 0
146
147 fieldsets = (
148 (None, {
149 'fields': (('nom', 'prenom'), ('nom_affichage', 'genre'), 'nationalite', 'date_naissance', 'lien_parente', )
150 }),
151 )
152
153
154class AyantDroitCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
155 readonly_fields = ('owner', )
156 model = rh.AyantDroitCommentaire
157 extra = 1
158
159
160class ContratInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
161 form = ContratForm
162 model = rh.Contrat
163 extra = 1
164
165
166class DossierROInline(ReadOnlyInlineMixin, LinkedInline):
167 template = "admin/rh/dossier/linked.html"
168 exclude = AUF_METADATA_READONLY_FIELDS
169 model = rh.Dossier
170 extra = 0
171 can_delete = False
172
173 def has_add_permission(self, request=None):
174 return False
175
176 def has_change_permission(self, request, obj=None):
177 return False
178
179 def has_delete_permission(self, request, obj=None):
180 return False
181
182
183class DossierCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
184 readonly_fields = ('owner', )
185 model = rh.DossierCommentaire
186 extra = 1
187
188
189class DossierPieceInline(admin.TabularInline):
190 model = rh.DossierPiece
191 extra = 4
192
193
194class EmployeInline(admin.TabularInline):
195 model = rh.Employe
196
197class EmployeCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
198 readonly_fields = ('owner', )
199 model = rh.EmployeCommentaire
200 extra = 1
201
202
203class EmployePieceInline(admin.TabularInline):
204 model = rh.EmployePiece
205 extra = 4
206
207
53ae644d
OL
208class PosteCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
209 readonly_fields = ('owner', )
210 model = rh.PosteCommentaire
211 extra = 1
212
213
214class PosteFinancementInline(admin.TabularInline):
215 model = rh.PosteFinancement
216
217
218class PostePieceInline(admin.TabularInline):
219 model = rh.PostePiece
220
221
222class RemunerationInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
223 model = rh.Remuneration
224 extra = 1
225
226
227class RemunerationROInline(ReadOnlyInlineMixin, RemunerationInline):
228 pass
229
230
231class TypePosteInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
232 model = rh.TypePoste
233
234
6f037929
OL
235class PosteComparaisonInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
236 model = rh.PosteComparaison
237
53ae644d
OL
238
239class ClassementAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 240 list_display = ('_classement', '_date_modification', 'user_modification', )
53ae644d
OL
241 fieldsets = AUFMetadataAdminMixin.fieldsets + (
242 (None, {
243 'fields': ('type', 'echelon', 'degre', 'coefficient', )
244 }),
245 )
246
c5964dc2
OL
247 def _classement(self, obj):
248 return unicode(obj)
249 _classement.short_description = u"Classement"
53ae644d 250
33232787
JPC
251 def _date_modification(self, obj):
252 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
253 _date_modification.short_description = u'date modification'
254 _date_modification.admin_order_field = 'date_modification'
255
53ae644d
OL
256class CommentaireAdmin(admin.ModelAdmin):
257 pass
258
259
53ae644d 260class DeviseAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 261 list_display = ('code', 'nom', '_date_modification', 'user_modification', )
53ae644d
OL
262 fieldsets = AUFMetadataAdminMixin.fieldsets + (
263 (None, {
264 'fields': ('code', 'nom', ),
265 }),
266 )
267
33232787
JPC
268 def _date_modification(self, obj):
269 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
270 _date_modification.short_description = u'date modification'
271 _date_modification.admin_order_field = 'date_modification'
53ae644d 272
40b35603 273class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
53ae644d
OL
274 alphabet_filter = 'employe__nom'
275 search_fields = ('employe__nom', 'employe__prenom', 'poste__nom', 'poste__nom_feminin')
276 list_display = (
277 '_id',
e49ac947
JPC
278 '_apercu',
279 '_nom',
53ae644d
OL
280 '_poste',
281 '_employe',
282 '_date_debut',
283 '_date_fin',
33232787 284 '_date_modification',
c5964dc2 285 'user_modification',
53ae644d 286 )
e49ac947 287 list_display_links = ('_nom',)
53ae644d
OL
288 list_filter = (
289 'poste__implantation__region',
290 'poste__implantation',
53ae644d 291 'poste__type_poste__famille_emploi',
7baa5523 292 'poste__type_poste',
53ae644d 293 'rh_contrats__type_contrat',
f614ca5c
OL
294 'date_debut',
295 'date_fin',
53ae644d
OL
296 )
297 inlines = (DossierPieceInline, ContratInline,
298 RemunerationInline,
53ae644d
OL
299 DossierCommentaireInline,
300 )
301 fieldsets = AUFMetadataAdminMixin.fieldsets + (
302 (None, {
303 'fields': ('employe', 'poste', 'statut', 'organisme_bstg',)
304 }),
305 ('Recrutement', {
306 'fields': ('statut_residence', 'remplacement', 'remplacement_de', )
307 }),
308 ('Rémunération', {
309 'fields': ('classement', ('regime_travail', 'regime_travail_nb_heure_semaine'),)
310 }),
311 ('Occupation du Poste par cet Employe', {
312 'fields': (('date_debut', 'date_fin'), )
313 }),
314 )
315 form = make_ajax_form(rh.Dossier, {
316 'employe' : 'employes',
317 'poste' : 'postes',
318 'remplacement_de' : 'dossiers',
319 })
320
321 def lookup_allowed(self, key, value):
322 if key in (
323 'employe__nom__istartswith',
53ae644d
OL
324 'poste__implantation__region__id__exact',
325 'poste__implantation__id__exact',
326 'poste__type_poste__id__exact',
327 'poste__type_poste__famille_emploi__id__exact',
328 'rh_contrats__type_contrat__id__exact',
f614ca5c
OL
329 'date_debut__gte',
330 'date_debut__isnull',
331 'date_fin__lte',
332 'date_fin__isnull',
53ae644d
OL
333 ):
334 return True
335
e49ac947
JPC
336 def _id(self, obj):
337 return obj.id
338 _id.short_description = u"#"
339 _id.admin_order_field = "id"
340
341 def _nom(self, obj):
342 return "%d : %s %s" % \
343 (obj.date_debut.year, obj.employe.nom.upper(), obj.employe.prenom)
344 _nom.allow_tags = True
345 _nom.short_description = u"Dossier"
346
347
348 def _apercu(self, d):
5429c435 349 apercu_link = u"""<a title="Aperçu du dossier" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a>""" % \
b10920ea 350 (reverse('dossier_apercu', args=(d.id,)),
822a2c33 351 settings.STATIC_URL,
b10920ea 352 )
e49ac947
JPC
353 return apercu_link
354 _apercu.allow_tags = True
355 _apercu.short_description = u""
53ae644d
OL
356
357
53ae644d 358 def _date_debut(self, obj):
5f36f262
OL
359 return date(obj.date_debut)
360
53ae644d
OL
361 _date_debut.short_description = u'Occupation début'
362 _date_debut.admin_order_field = 'date_debut'
363
364 def _date_fin(self, obj):
5f36f262 365 return date(obj.date_fin)
53ae644d
OL
366 _date_fin.short_description = u'Occupation fin'
367 _date_fin.admin_order_field = 'date_fin'
368
33232787
JPC
369
370 def _date_modification(self, obj):
371 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
372 _date_modification.short_description = u'date modification'
373 _date_modification.admin_order_field = 'date_modification'
374
53ae644d 375 def _poste(self, dossier):
211a0e56 376 link = u"""<a title="Aperçu du poste" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a> <a href="%s" title="Modifier le poste">%s</a>""" % \
53ae644d 377 (reverse('poste_apercu', args=(dossier.poste.id,)),
822a2c33 378 settings.STATIC_URL,
211a0e56
JPC
379 reverse('admin:rh_poste_change', args=(dossier.poste.id,)),
380 dossier.poste,
53ae644d
OL
381 )
382 return link
383 _poste.allow_tags = True
384 _poste.short_description = u'Poste'
385 _poste.admin_order_field = 'poste__nom'
386
387 def _employe(self, obj):
388 employe = obj.employe
389 view_link = reverse('employe_apercu', args=(employe.id,))
390 edit_link = reverse('admin:rh_employe_change', args=(employe.id,))
391
f614ca5c
OL
392 style = ""
393 view = u"""<a href="%s" title="Aperçu l'employé" onclick="return showAddAnotherPopup(this);"><img src="%simg/loupe.png" /></a>""" % (view_link, settings.STATIC_URL,)
e6c107de
JPC
394 return u"""%s<a href='%s' style="%s;">%s</a>""" % \
395 (view, edit_link, style, employe)
53ae644d 396 _employe.allow_tags = True
e49ac947 397 _employe.short_description = u"Employé"
53ae644d
OL
398 _employe.admin_order_field = "employe__nom"
399
400 def save_formset(self, request, form, formset, change):
401 instances = formset.save(commit=False)
402 for instance in instances:
403 if instance.__class__ == rh.DossierCommentaire:
404 instance.owner = request.user
02e69aa2 405 instance.date_creation = datetime.datetime.now()
53ae644d
OL
406 instance.save()
407
408
409class DossierPieceAdmin(admin.ModelAdmin):
410 pass
411
412
413class DossierCommentaireAdmin(admin.ModelAdmin):
414 pass
415
416
40b35603 417class EmployeAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin,):
53ae644d
OL
418 alphabet_filter = 'nom'
419 DEFAULT_ALPHABET = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
420 search_fields = ('id', 'nom', 'prenom', 'nom_affichage', )
421 ordering = ('nom', )
422 form = EmployeAdminForm
e49ac947
JPC
423 list_display = ('_id', '_apercu', '_nom', '_dossiers', '_date_modification', 'user_modification', )
424 list_display_links = ('_nom',)
b46d18bc 425 list_filter = ('rh_dossiers__poste__implantation__region', 'rh_dossiers__poste__implantation', 'nb_postes', 'rh_dossiers__date_debut', 'rh_dossiers__date_fin')
7f4d1233
OL
426 date_borne_gauche = 'rh_dossiers__date_debut'
427 date_borne_droite = 'rh_dossiers__date_fin'
53ae644d
OL
428 inlines = (AyantDroitInline,
429 DossierROInline,
430 EmployePieceInline,
431 EmployeCommentaireInline)
432 fieldsets = AUFMetadataAdminMixin.fieldsets + (
433 ('Identification', {
434 'fields': (('nom', 'prenom'), ('nom_affichage', 'genre'), 'nationalite', 'date_naissance', )
435 }),
436 ('Informations personnelles', {
437 'fields': ('situation_famille', 'date_entree', )
438 }),
439 ('Coordonnées', {
440 'fields': (('tel_domicile', 'tel_cellulaire'), ('adresse', 'ville'), ('code_postal', 'province'), 'pays', )
441 }),
442 )
443
b10920ea
JPC
444 def _apercu(self, obj):
445 return u"""<a title="Aperçu de l'employé" onclick="return showAddAnotherPopup(this);" href='%s'><img src="%simg/loupe.png" /></a>""" % \
822a2c33 446 (reverse('employe_apercu', args=(obj.id,)), settings.STATIC_URL)
b10920ea
JPC
447 _apercu.allow_tags = True
448 _apercu.short_description = u""
b10920ea 449
53ae644d 450 def _nom(self, obj):
53ae644d 451 edit_link = reverse('admin:rh_employe_change', args=(obj.id,))
e6c107de 452 return u"""<a href='%s'><strong>%s</strong></a>""" % \
e49ac947 453 (edit_link, "%s %s" % (obj.nom.upper(), obj.prenom))
53ae644d 454 _nom.allow_tags = True
e49ac947 455 _nom.short_description = u"Employé"
53ae644d
OL
456 _nom.admin_order_field = "nom"
457
e49ac947
JPC
458 def _id(self, obj):
459 return obj.id
460 _id.short_description = u"#"
461 _id.admin_order_field = "id"
462
33232787
JPC
463 def _date_modification(self, obj):
464 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
465 _date_modification.short_description = u'date modification'
466 _date_modification.admin_order_field = 'date_modification'
467
53ae644d
OL
468 def _dossiers(self, obj):
469 l = []
470 for d in obj.rh_dossiers.all().order_by('-date_debut'):
b10920ea 471 apercu = u"""<a title="Aperçu du dossier" href="%s" onclick="return showAddAnotherPopup(this);" title="Aperçu du dossier"><img src="%simg/loupe.png" /></a>""" % \
822a2c33 472 (reverse('dossier_apercu', args=(d.id,)), settings.STATIC_URL,)
b5cc0357 473 link = u"""<li>%s<a href='%s'>%s : %s</a></li>""" % \
b10920ea 474 (apercu,
b10920ea 475 reverse('admin:rh_dossier_change', args=(d.id,)),
53ae644d
OL
476 d.date_debut.year,
477 d.poste,
53ae644d 478 )
b5cc0357
OL
479
480 # Dossier terminé en gris non cliquable
481 if d.date_fin is not None:
482 link = u"""<li style="color: grey">%s : %s</li>""" % \
483 (d.date_debut.year,
484 d.poste,
485 )
486
53ae644d
OL
487 l.append(link)
488 return "<ul>%s</ul>" % "\n".join(l)
489 _dossiers.allow_tags = True
490 _dossiers.short_description = u"Dossiers"
491
492 def queryset(self, request):
493 qs = super(EmployeAdmin, self).queryset(request)
494 return qs.select_related(depth=1).order_by('nom')
495
496 def save_formset(self, request, form, formset, change):
497 instances = formset.save(commit=False)
498 for instance in instances:
499 if instance.__class__ == rh.EmployeCommentaire:
500 instance.owner = request.user
02e69aa2 501 instance.date_creation = datetime.datetime.now()
53ae644d
OL
502 instance.save()
503
504
505
506class EmployeCommentaireAdmin(admin.ModelAdmin):
507 pass
508
509
510class EmployePieceAdmin(admin.ModelAdmin):
511 pass
512
513
514class FamilleEmploiAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 515 list_display = ('nom', '_date_modification', 'user_modification', )
53ae644d
OL
516 inlines = (TypePosteInline,)
517 fieldsets = AUFMetadataAdminMixin.fieldsets + (
518 (None, {
519 'fields': ('nom', )
520 }),
521 )
522
33232787
JPC
523 def _date_modification(self, obj):
524 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
525 _date_modification.short_description = u'date modification'
526 _date_modification.admin_order_field = 'date_modification'
53ae644d 527
95b630cf 528class OrganismeBstgAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
c5964dc2 529 search_fields = ('nom',)
33232787 530 list_display = ('nom', 'type', 'pays', '_date_modification', 'user_modification', )
c5964dc2 531 list_filter = ('type', )
53ae644d
OL
532 inlines = (DossierROInline,)
533 fieldsets = AUFMetadataAdminMixin.fieldsets + (
534 (None, {
535 'fields': ('nom', 'type', 'pays', )
536 }),
537 )
538
33232787
JPC
539 def _date_modification(self, obj):
540 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
541 _date_modification.short_description = u'date modification'
542 _date_modification.admin_order_field = 'date_modification'
543
53ae644d 544
40b35603 545class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin, admin.ModelAdmin, AjaxSelect,):
53ae644d
OL
546 form = make_ajax_form(rh.Poste, {
547 'implantation' : 'implantations',
548 'type_poste' : 'typepostes',
549 'responsable' : 'postes',
550 'valeur_point_min' : 'valeurpoints',
551 'valeur_point_max' : 'valeurpoints',
552 })
553 alphabet_filter = 'nom'
554 search_fields = ('nom',
555 'implantation__code',
556 'implantation__nom',
557 'implantation__region__code',
558 'implantation__region__nom',
1ce71322
JPC
559 'rh_dossiers__employe__nom',
560 'rh_dossiers__employe__prenom',
53ae644d
OL
561 )
562 list_display = (
e49ac947 563 '_id',
8f3ca727 564 '_apercu',
53ae644d
OL
565 '_nom',
566 '_occupe_par',
567 'implantation',
c5964dc2 568 '_service',
53ae644d
OL
569 'date_debut',
570 'date_fin',
33232787 571 '_date_modification',
53ae644d 572 'user_modification',
53ae644d 573 )
f614ca5c 574 list_filter = (
53ae644d
OL
575 'implantation__region',
576 'implantation',
e8dd3d54 577 'service',
53ae644d
OL
578 'type_poste',
579 'type_poste__famille_emploi',
f614ca5c
OL
580 'date_debut',
581 'date_fin',
4c53dda4 582 'vacant',
53ae644d 583 )
e49ac947 584 list_display_links = ('_nom',)
53ae644d
OL
585 fieldsets = AUFMetadataAdminMixin.fieldsets + (
586 (None, {
587 'fields': (('nom', 'nom_feminin'), 'implantation', 'type_poste',
588 'service', 'responsable')
589 }),
590 ('Contrat', {
591 'fields': (('regime_travail', 'regime_travail_nb_heure_semaine'), )
592 }),
593 ('Recrutement', {
594 'fields': (('local', 'expatrie', 'mise_a_disposition', 'appel'),)
595 }),
596 ('Rémunération', {
597 'fields': (('classement_min', 'valeur_point_min', 'devise_min', 'salaire_min', 'indemn_min', 'autre_min', ),
598 ('classement_max', 'valeur_point_max' ,'devise_max', 'salaire_max', 'indemn_max', 'autre_max', ),
599 )
600 }),
601 ('Comparatifs de rémunération', {
602 'fields': ('devise_comparaison',
603 ('comp_locale_min', 'comp_locale_max'),
604 ('comp_universite_min', 'comp_universite_max'),
605 ('comp_fonctionpub_min', 'comp_fonctionpub_max'),
606 ('comp_ong_min', 'comp_ong_max'),
607 ('comp_autre_min', 'comp_autre_max'))
608 }),
609 ('Justification', {
610 'fields': ('justification',)
611 }),
48a6df80 612 ('Autres Méta-données', {
53ae644d
OL
613 'fields': ('date_debut', 'date_fin')
614 }),
615 )
616
617 inlines = (PosteFinancementInline,
618 PostePieceInline,
619 DossierROInline,
6f037929 620 PosteComparaisonInline,
53ae644d
OL
621 PosteCommentaireInline, )
622
b46d18bc 623
f614ca5c
OL
624 def lookup_allowed(self, key, value):
625 if key in (
626 'date_debut__gte',
627 'date_debut__isnull',
628 'date_fin__lte',
629 'date_fin__isnull',
7f4d1233
OL
630 'implantation__region__id__exact',
631 'implantation__id__exact',
632 'type_poste__id__exact',
633 'type_poste__famille_emploi__id__exact',
634 'service__id__exact',
d48f0922 635 'service__isnull',
7f4d1233 636 'vacant__exact',
f614ca5c
OL
637 ):
638 return True
639
c5964dc2 640
8f3ca727 641 def _apercu(self, poste):
23de8cea 642 view_link = u"""<a onclick="return showAddAnotherPopup(this);" title="Aperçu du poste" href='%s'><img src="%simg/loupe.png" /></a>""" % \
8f3ca727 643 (reverse('poste_apercu', args=(poste.id,)),
822a2c33 644 settings.STATIC_URL,
23de8cea 645 )
e49ac947 646 return view_link
8f3ca727 647 _apercu.allow_tags = True
e49ac947
JPC
648 _apercu.short_description = ''
649
650 def _id(self, obj):
651 return "%s" % obj.id
652 _id.short_description = '#'
653 _id.admin_order_field = 'id'
8f3ca727 654
c5964dc2
OL
655 def _service(self, obj):
656 return obj.service
53ae644d
OL
657
658 def _nom(self, poste):
e49ac947
JPC
659 return """<a href="%s">%s</a>""" % \
660 (reverse('admin:rh_poste_change', args=(poste.id,)),
661 poste.nom
662 )
53ae644d
OL
663 _nom.allow_tags = True
664 _nom.short_description = u'Nom'
665 _nom.admin_order_field = 'nom'
666
33232787
JPC
667 def _date_modification(self, obj):
668 return date(obj.date_modification)
669 _date_modification.short_description = u'date modification'
670 _date_modification.admin_order_field = 'date_modification'
671
53ae644d
OL
672 def _occupe_par(self, obj):
673 """Formatte la méthode Poste.occupe_par() pour l'admin"""
15c5f55a 674 output = u"Vacant"
3195667e 675 if obj.date_fin is not None and obj.date_fin < datetime.date.now():
954ead19 676 return u"s/o"
53ae644d
OL
677 employes = obj.occupe_par()
678 if employes:
679 l = []
680 for e in employes:
b10920ea
JPC
681 link = "<a href='%s' title='Aperçu de l\'employer' onclick='return showAddAnotherPopup(this)'><img src='%simg/loupe.png' /></a> <a href='%s'>%s</a>" % \
682 (reverse('employe_apercu', args=(e.id,)),
822a2c33 683 settings.STATIC_URL,
b10920ea
JPC
684 reverse('admin:rh_employe_change', args=(e.id,)),
685 e
686 )
53ae644d
OL
687 l.append(link)
688 output = "\n<br />".join(l)
689 return output
690 _occupe_par.allow_tags = True
691 _occupe_par.short_description = "Occupé par"
692
693 def save_formset(self, request, form, formset, change):
694 instances = formset.save(commit=False)
695 for instance in instances:
696 if instance.__class__ == rh.PosteCommentaire:
697 instance.owner = request.user
02e69aa2 698 instance.date_creation = datetime.datetime.now()
53ae644d
OL
699 instance.save()
700 formset.save_m2m()
701
702
703class PosteCommentaireAdmin(admin.ModelAdmin):
704 pass
705
706
707class PosteFinancementAdmin(admin.ModelAdmin):
708 pass
709
710
711class PostePieceAdmin(admin.ModelAdmin):
712 fk_name = 'poste'
713
714
715class RemunerationAdmin(admin.ModelAdmin):
716 pass
717
718
719class ResponsableImplantationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
720 fieldsets = AUFMetadataAdminMixin.fieldsets + (
721 (None, {
722 'fields': ('employe', 'implantation', ),
723 }),
724 )
725
726
727class ServiceAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 728 list_display = ('nom', '_date_modification', 'user_modification', )
53ae644d
OL
729 fieldsets = AUFMetadataAdminMixin.fieldsets + (
730 (None, {
731 'fields': ('nom', ),
732 }),
733 )
734
33232787
JPC
735 def _date_modification(self, obj):
736 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
737 _date_modification.short_description = u'date modification'
738 _date_modification.admin_order_field = 'date_modification'
739
740
53ae644d 741class StatutAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 742 list_display = ('code', 'nom', '_date_modification', 'user_modification', )
53ae644d
OL
743 fieldsets = AUFMetadataAdminMixin.fieldsets + (
744 (None, {
745 'fields': ('code', 'nom', ),
746 }),
747 )
748
33232787
JPC
749 def _date_modification(self, obj):
750 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
751 _date_modification.short_description = u'date modification'
752 _date_modification.admin_order_field = 'date_modification'
753
53ae644d 754class TauxChangeAdmin(admin.ModelAdmin):
33232787 755 list_display = ('taux', 'devise', 'annee', '_date_modification', 'user_modification', )
53ae644d
OL
756 list_filter = ('devise', )
757 fieldsets = AUFMetadataAdminMixin.fieldsets + (
758 (None, {
759 'fields': ('taux', 'devise', 'annee', ),
760 }),
761 )
762
33232787
JPC
763 def _date_modification(self, obj):
764 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
765 _date_modification.short_description = u'date modification'
766 _date_modification.admin_order_field = 'date_modification'
767
53ae644d 768class TypeContratAdmin(admin.ModelAdmin):
33232787 769 list_display = ('nom', 'nom_long', '_date_modification', 'user_modification', )
53ae644d
OL
770 fieldsets = AUFMetadataAdminMixin.fieldsets + (
771 (None, {
772 'fields': ('nom', 'nom_long', ),
773 }),
774 )
775
33232787
JPC
776 def _date_modification(self, obj):
777 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
778 _date_modification.short_description = u'date modification'
779 _date_modification.admin_order_field = 'date_modification'
780
53ae644d
OL
781
782class TypePosteAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
783 search_fields = ('nom', 'nom_feminin', )
33232787 784 list_display = ('nom', 'famille_emploi', '_date_modification', 'user_modification', )
53ae644d
OL
785 list_filter = ('famille_emploi', )
786 fieldsets = AUFMetadataAdminMixin.fieldsets + (
787 (None, {
788 'fields': ('nom', 'nom_feminin', 'is_responsable', 'famille_emploi', )
789 }),
790 )
791
33232787
JPC
792 def _date_modification(self, obj):
793 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
794 _date_modification.short_description = u'date modification'
795 _date_modification.admin_order_field = 'date_modification'
796
53ae644d
OL
797
798class TypeRemunerationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 799 list_display = ('nom', 'type_paiement', 'nature_remuneration', '_date_modification', 'user_modification', )
53ae644d
OL
800 fieldsets = AUFMetadataAdminMixin.fieldsets + (
801 (None, {
802 'fields': ('nom', 'type_paiement', 'nature_remuneration', )
803 }),
804 )
805
33232787
JPC
806 def _date_modification(self, obj):
807 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
808 _date_modification.short_description = u'date modification'
809 _date_modification.admin_order_field = 'date_modification'
810
53ae644d
OL
811
812class TypeRevalorisationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 813 list_display = ('nom', '_date_modification', 'user_modification', )
53ae644d
OL
814 fieldsets = AUFMetadataAdminMixin.fieldsets + (
815 (None, {
816 'fields': ('nom', )
817 }),
818 )
819
33232787
JPC
820 def _date_modification(self, obj):
821 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
822 _date_modification.short_description = u'date modification'
823 _date_modification.admin_order_field = 'date_modification'
824
53ae644d
OL
825
826class ValeurPointAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 827 list_display = ('_devise_code', '_devise_nom', 'annee', 'valeur', '_date_modification', 'user_modification', )
c5964dc2 828 list_filter = ('annee', 'devise', )
53ae644d
OL
829 fieldsets = AUFMetadataAdminMixin.fieldsets + (
830 (None, {
831 'fields': ('valeur', 'devise', 'implantation', 'annee', )
832 }),
833 )
834
33232787
JPC
835 def _date_modification(self, obj):
836 return date(obj.date_modification) if obj.date_modification is not None else "(aucune)"
837 _date_modification.short_description = u'date modification'
838 _date_modification.admin_order_field = 'date_modification'
839
53ae644d
OL
840 def _devise_code(self, obj):
841 return obj.devise.code
842 _devise_code.short_description = "Code de la devise"
843
844 def _devise_nom(self, obj):
845 return obj.devise.nom
846 _devise_nom.short_description = "Nom de la devise"
847
848
849admin.site.register(rh.Classement, ClassementAdmin)
850admin.site.register(rh.Devise, DeviseAdmin)
851admin.site.register(rh.Dossier, DossierAdmin)
852admin.site.register(rh.Employe, EmployeAdmin)
853admin.site.register(rh.FamilleEmploi, FamilleEmploiAdmin)
854admin.site.register(rh.OrganismeBstg, OrganismeBstgAdmin)
855admin.site.register(rh.Poste, PosteAdmin)
856admin.site.register(rh.ResponsableImplantation, ResponsableImplantationAdmin)
857admin.site.register(rh.Service, ServiceAdmin)
c5964dc2 858admin.site.register(rh.Statut, StatutAdmin)
53ae644d 859admin.site.register(rh.TauxChange, TauxChangeAdmin)
c5964dc2 860admin.site.register(rh.TypeContrat, TypeContratAdmin)
53ae644d
OL
861admin.site.register(rh.TypePoste, TypePosteAdmin)
862admin.site.register(rh.TypeRemuneration, TypeRemunerationAdmin)
863admin.site.register(rh.TypeRevalorisation, TypeRevalorisationAdmin)
864admin.site.register(rh.ValeurPoint, ValeurPointAdmin)