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