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