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