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