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