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