fix employes du poste
[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"""
ae5d7df3
OL
856 import pdb; pdb.set_trace()
857
15c5f55a 858 output = u"Vacant"
ae5d7df3 859 if obj.date_fin is not None and obj.date_fin < datetime.date.today():
954ead19 860 return u"s/o"
53ae644d
OL
861 employes = obj.occupe_par()
862 if employes:
863 l = []
864 for e in employes:
22343fe7
OL
865 link = u"""<a href='%s'
866 title='Aperçu de l\'employer'
867 onclick='return showAddAnotherPopup(this)'>
868 <img src='%simg/loupe.png' />
869 </a>
870 <a href='%s'>%s</a>""" % \
b10920ea 871 (reverse('employe_apercu', args=(e.id,)),
822a2c33 872 settings.STATIC_URL,
b10920ea 873 reverse('admin:rh_employe_change', args=(e.id,)),
22343fe7 874 e)
53ae644d
OL
875 l.append(link)
876 output = "\n<br />".join(l)
877 return output
878 _occupe_par.allow_tags = True
22343fe7 879 _occupe_par.short_description = "Occupé par"
53ae644d
OL
880
881 def save_formset(self, request, form, formset, change):
882 instances = formset.save(commit=False)
883 for instance in instances:
884 if instance.__class__ == rh.PosteCommentaire:
885 instance.owner = request.user
02e69aa2 886 instance.date_creation = datetime.datetime.now()
53ae644d
OL
887 instance.save()
888 formset.save_m2m()
889
890
891class PosteCommentaireAdmin(admin.ModelAdmin):
892 pass
893
894
895class PosteFinancementAdmin(admin.ModelAdmin):
896 pass
897
898
899class PostePieceAdmin(admin.ModelAdmin):
900 fk_name = 'poste'
901
902
903class RemunerationAdmin(admin.ModelAdmin):
904 pass
905
906
907class ResponsableImplantationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
22343fe7 908 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d
OL
909 (None, {
910 'fields': ('employe', 'implantation', ),
911 }),
912 )
22343fe7 913
53ae644d 914
7ba822a6 915class ServiceAdmin(AUFMetadataAdminMixin, admin.ModelAdmin, ArchiveMixin):
22343fe7
OL
916 list_display = (
917 'nom',
918 '_archive',
919 '_date_modification',
920 'user_modification',
921 )
cbb0373e 922 list_filter = ('archive', )
22343fe7 923 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d 924 (None, {
cbb0373e 925 'fields': ('nom', 'archive', ),
53ae644d
OL
926 }),
927 )
928
33232787 929 def _date_modification(self, obj):
22343fe7
OL
930 return date(obj.date_modification) \
931 if obj.date_modification is not None else "(aucune)"
33232787
JPC
932 _date_modification.short_description = u'date modification'
933 _date_modification.admin_order_field = 'date_modification'
934
935
5c0f1778
JPC
936class ServiceProxyAdmin(ServiceAdmin):
937 list_display = ('nom', '_organigramme')
938 list_display_links = ('nom',)
939
940 def has_add_permission(self, obj):
941 return False
942
943 def _organigramme(self, obj):
1035822c 944 return """<a href="%s">Organigramme</a>""" % (reverse('rho_service', args=(obj.id,)))
5c0f1778
JPC
945 _organigramme.allow_tags = True
946 _organigramme.short_description = "Organigramme"
947
53ae644d 948class StatutAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 949 list_display = ('code', 'nom', '_date_modification', 'user_modification', )
22343fe7 950 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d
OL
951 (None, {
952 'fields': ('code', 'nom', ),
953 }),
954 )
955
33232787 956 def _date_modification(self, obj):
22343fe7
OL
957 return date(obj.date_modification) \
958 if obj.date_modification is not None else "(aucune)"
33232787
JPC
959 _date_modification.short_description = u'date modification'
960 _date_modification.admin_order_field = 'date_modification'
961
22343fe7 962
53ae644d 963class TauxChangeAdmin(admin.ModelAdmin):
22343fe7
OL
964 list_display = (
965 'taux',
966 'devise',
967 'annee',
968 '_date_modification',
969 'user_modification',
970 )
53ae644d 971 list_filter = ('devise', )
22343fe7 972 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d
OL
973 (None, {
974 'fields': ('taux', 'devise', 'annee', ),
975 }),
976 )
977
33232787 978 def _date_modification(self, obj):
22343fe7
OL
979 return date(obj.date_modification) \
980 if obj.date_modification is not None else "(aucune)"
33232787
JPC
981 _date_modification.short_description = u'date modification'
982 _date_modification.admin_order_field = 'date_modification'
983
22343fe7 984
53ae644d 985class TypeContratAdmin(admin.ModelAdmin):
22343fe7
OL
986 list_display = (
987 'nom',
988 'nom_long',
989 '_date_modification',
990 'user_modification',
991 )
992 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d
OL
993 (None, {
994 'fields': ('nom', 'nom_long', ),
995 }),
996 )
997
33232787 998 def _date_modification(self, obj):
22343fe7
OL
999 return date(obj.date_modification) \
1000 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1001 _date_modification.short_description = u'date modification'
1002 _date_modification.admin_order_field = 'date_modification'
1003
53ae644d
OL
1004
1005class TypePosteAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
1006 search_fields = ('nom', 'nom_feminin', )
22343fe7
OL
1007 list_display = (
1008 'nom',
1009 'famille_emploi',
1010 '_date_modification',
1011 'user_modification',
1012 )
53ae644d 1013 list_filter = ('famille_emploi', )
22343fe7 1014 fieldsets = AUFMetadataAdminMixin.fieldsets + (
53ae644d 1015 (None, {
22343fe7
OL
1016 'fields': (
1017 'nom',
1018 'nom_feminin',
1019 'is_responsable',
1020 'famille_emploi',
1021 )}
1022 ),
53ae644d
OL
1023 )
1024
33232787 1025 def _date_modification(self, obj):
22343fe7
OL
1026 return date(obj.date_modification) \
1027 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1028 _date_modification.short_description = u'date modification'
1029 _date_modification.admin_order_field = 'date_modification'
1030
53ae644d 1031
7ba822a6 1032class TypeRemunerationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin, ArchiveMixin):
22343fe7
OL
1033 list_display = (
1034 'nom',
1035 'type_paiement',
1036 'nature_remuneration',
7ba822a6 1037 '_archive',
22343fe7
OL
1038 '_date_modification',
1039 'user_modification',)
7ba822a6 1040 list_filter = ('archive', )
22343fe7 1041 fieldsets = AUFMetadataAdminMixin.fieldsets + (
7ba822a6
OL
1042 (None, {'fields': ('nom', 'type_paiement', 'nature_remuneration',
1043 'archive')}),
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 TypeRevalorisationAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
33232787 1054 list_display = ('nom', '_date_modification', 'user_modification', )
22343fe7
OL
1055 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1056 (None, {'fields': ('nom', )}),
53ae644d
OL
1057 )
1058
33232787 1059 def _date_modification(self, obj):
22343fe7
OL
1060 return date(obj.date_modification) \
1061 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1062 _date_modification.short_description = u'date modification'
1063 _date_modification.admin_order_field = 'date_modification'
1064
53ae644d
OL
1065
1066class ValeurPointAdmin(AUFMetadataAdminMixin, admin.ModelAdmin):
22343fe7
OL
1067 list_display = (
1068 '_devise_code',
1069 '_devise_nom',
1070 'annee',
1071 'valeur',
1072 '_date_modification',
1073 'user_modification',
1074 )
c5964dc2 1075 list_filter = ('annee', 'devise', )
22343fe7
OL
1076 fieldsets = AUFMetadataAdminMixin.fieldsets + (
1077 (None, {'fields': ('valeur', 'devise', 'implantation', 'annee', )}),
53ae644d
OL
1078 )
1079
33232787 1080 def _date_modification(self, obj):
22343fe7
OL
1081 return date(obj.date_modification) \
1082 if obj.date_modification is not None else "(aucune)"
33232787
JPC
1083 _date_modification.short_description = u'date modification'
1084 _date_modification.admin_order_field = 'date_modification'
1085
53ae644d
OL
1086 def _devise_code(self, obj):
1087 return obj.devise.code
1088 _devise_code.short_description = "Code de la devise"
1089
1090 def _devise_nom(self, obj):
1091 return obj.devise.nom
1092 _devise_nom.short_description = "Nom de la devise"
1093
82af5c19
JPC
1094class ImplantationProxyAdmin(admin.ModelAdmin):
1095 list_display = ('nom', '_organigramme')
1096 list_display_links = ('nom',)
1097
1098 def has_add_permission(self, obj):
1099 return False
1100
1101 def _organigramme(self, obj):
1102 return """<a href="%s">Organigramme</a>""" % (reverse('rho_implantation', args=(obj.id,)))
1103 _organigramme.allow_tags = True
1104 _organigramme.short_description = "Organigramme"
1105
9da4c195
JPC
1106class RegionProxyAdmin(admin.ModelAdmin):
1107 list_display = ('nom', '_organigramme')
1108 list_display_links = ('nom',)
1109
1110 def has_add_permission(self, obj):
1111 return False
1112
1113 def _organigramme(self, obj):
1114 return """<a href="%s">Organigramme</a>""" % (reverse('rho_region', args=(obj.id,)))
1115 _organigramme.allow_tags = True
1116 _organigramme.short_description = "Organigramme"
1117
1118
82af5c19 1119
53ae644d
OL
1120
1121admin.site.register(rh.Classement, ClassementAdmin)
1122admin.site.register(rh.Devise, DeviseAdmin)
1123admin.site.register(rh.Dossier, DossierAdmin)
22343fe7 1124admin.site.register(EmployeProxy, EmployeProxyAdmin)
5c0f1778 1125admin.site.register(ServiceProxy, ServiceProxyAdmin)
53ae644d
OL
1126admin.site.register(rh.Employe, EmployeAdmin)
1127admin.site.register(rh.FamilleEmploi, FamilleEmploiAdmin)
1128admin.site.register(rh.OrganismeBstg, OrganismeBstgAdmin)
1129admin.site.register(rh.Poste, PosteAdmin)
1130admin.site.register(rh.ResponsableImplantation, ResponsableImplantationAdmin)
1131admin.site.register(rh.Service, ServiceAdmin)
c5964dc2 1132admin.site.register(rh.Statut, StatutAdmin)
53ae644d 1133admin.site.register(rh.TauxChange, TauxChangeAdmin)
c5964dc2 1134admin.site.register(rh.TypeContrat, TypeContratAdmin)
53ae644d
OL
1135admin.site.register(rh.TypePoste, TypePosteAdmin)
1136admin.site.register(rh.TypeRemuneration, TypeRemunerationAdmin)
1137admin.site.register(rh.TypeRevalorisation, TypeRevalorisationAdmin)
1138admin.site.register(rh.ValeurPoint, ValeurPointAdmin)
82af5c19 1139admin.site.register(ImplantationProxy, ImplantationProxyAdmin)
9da4c195 1140admin.site.register(RegionProxy, RegionProxyAdmin)