[#2658] Retrait du hack app_label() dans rh.models
[auf_rh_dae.git] / project / rh / views.py
CommitLineData
e9bbd6ba 1# -*- encoding: utf-8 -*-
22343fe7 2
e90b19fd 3import urllib
c9122f1d 4from datetime import date
a7de62d7 5from itertools import izip
eabb27fd 6import StringIO
9b0a8554 7
9f55f18a 8import pygraphviz as pgv
00ca4d9f 9from datamaster_modeles import models as ref
4ba84959
EMS
10from django import forms
11from django.conf import settings
12from django.contrib.auth.decorators import login_required
13from django.core.servers.basehttp import FileWrapper
dcd1b959 14from django.core.urlresolvers import reverse
fbe60a9d 15from django.db.models import Q
4ba84959 16from django.http import HttpResponse
22343fe7 17from django.shortcuts import render_to_response, get_object_or_404
e9bbd6ba 18from django.template import RequestContext
4ba84959 19from django.utils.encoding import smart_str
a9faef67 20
4ba84959
EMS
21from project.dae.utils import get_employe_from_user
22from project.dae.decorators import redirect_interdiction
23from project.dae.workflow import grp_drh, grp_correspondants_rh
24from project.rh import models as rh
25from project.rh.lib import calc_remun
26from project.rh.decorators import drh_or_admin_required
27from project.rh.templatetags.rapports import SortHeaders
28from project.rh.change_list import RechercheTemporelle
29from project.rh import graph as rh_graph
30from project.rh.masse_salariale import MasseSalariale
9817fed5 31
22343fe7 32
c9122f1d 33@login_required
34def profil(request):
35 """Profil personnel de l'employé - éditable"""
36 rc = RequestContext(request)
37 c = {}
22343fe7 38
c9122f1d 39 employe = rc['this_employe']
22343fe7 40
c9122f1d 41 c['user'] = request.user
42 c['employe'] = employe
c9122f1d 43 return render_to_response('rh/profil.html', c, rc)
22343fe7
OL
44
45
3411ac33 46@login_required
a9faef67 47def employes_liste(request):
48 """Liste des employés."""
5ea6b5bb 49 today = date.today()
50 employes = rh.Employe.objects \
5ea6b5bb 51 .exclude(dossiers__date_debut__gt=today) \
52 .exclude(dossiers__date_fin__lt=today) \
53 .order_by('nom')
a9faef67 54 c = {
22343fe7
OL
55 'user': request.user,
56 'employes': employes,
a9faef67 57 }
22343fe7
OL
58 return render_to_response('rh/employes_liste.html',
59 c,
60 RequestContext(request))
61
62
3411ac33 63@login_required
a9faef67 64def employe(request, id):
65 """Information publique sur un employé."""
66 try:
67 employe = rh.Employe.objects.get(pk=id)
68 except:
69 employe = rh.Employe.objects.none()
70 c = {
22343fe7
OL
71 'user': request.user,
72 'employe': employe,
a9faef67 73 }
74 return render_to_response('rh/employe.html', c, RequestContext(request))
63e17dff
PP
75
76
08faf06e
JPC
77@login_required
78@drh_or_admin_required
63e17dff
PP
79def rapports_poste(request):
80
fd009814
PP
81 lookup_params = dict(request.GET.items())
82
83 for key, value in lookup_params.items():
9d53bc73
JPC
84 if key == 'o' or key == 'ot':
85 del lookup_params[key]
86 continue
fd009814
PP
87 if not isinstance(key, str):
88 # 'key' will be used as a keyword argument later, so Python
89 # requires it to be a string.
90 del lookup_params[key]
91 lookup_params[smart_str(key)] = value
92
7821915f 93 if key == 'comble':
7821915f
PP
94 del lookup_params[key]
95
00ca4d9f
EMS
96 sort_order = 'ASC' if request.GET.get('ot') == 'asc' else 'DESC'
97
ed3cbb32 98 postes = rh.Poste.objects.select_related('implantation') \
00ca4d9f
EMS
99 .extra(select={
100 'employe_id':
101 'SELECT GROUP_CONCAT(employe SEPARATOR "|") '
102 'FROM rh_dossier '
103 'WHERE poste = rh_poste.id '
104 'AND rh_dossier.date_fin IS NULL ' + (
105 'ORDER BY employe ' + sort_order
106 if request.GET.get('o') == 'employe_id' else ''
107 )
9202c5db 108 }) \
00ca4d9f
EMS
109 .extra(select={
110 'employe_nom':
111 'SELECT GROUP_CONCAT(rh_employe.nom SEPARATOR "|") '
112 'FROM rh_dossier INNER JOIN rh_employe '
113 'ON rh_dossier.employe = rh_employe.id '
114 'WHERE poste = rh_poste.id '
115 'AND rh_dossier.date_fin IS NULL ' + (
116 'ORDER BY rh_employe.nom ' + sort_order
117 if request.GET.get('o') == 'employe_nom' else ''
118 )
9202c5db 119 }) \
00ca4d9f
EMS
120 .extra(select={
121 'employe_prenom':
122 'SELECT GROUP_CONCAT(rh_employe.prenom SEPARATOR "|") '
123 'FROM rh_dossier INNER JOIN rh_employe '
124 'ON rh_dossier.employe = rh_employe.id '
125 'WHERE poste = rh_poste.id '
126 'AND rh_dossier.date_fin IS NULL ' + (
127 'ORDER BY rh_employe.prenom ' + sort_order
128 if request.GET.get('o') == 'employe_prenom' else ''
129 )
9202c5db 130 })
9d53bc73 131
65e02621 132 postes = postes.filter(**lookup_params)
9d53bc73 133 if 'o' in request.GET:
00ca4d9f
EMS
134 postes = postes.order_by(
135 ('-' if sort_order == "DESC" else '') + request.GET['o']
136 )
65e02621 137
a7de62d7
JPC
138 out = []
139 for p in postes:
140 out.append({
141 'id': p.id,
142 'nom': p.nom,
143 'implantation': p.implantation,
00ca4d9f
EMS
144 'employes': [] if not p.employe_id else [
145 {'id': id, 'nom': nom, 'prenom': prenom}
146 for id, nom, prenom in izip(
147 p.employe_id.split('|'),
148 p.employe_nom.split('|'),
149 p.employe_prenom.split('|')
150 )
151 ]
152 })
a7de62d7 153
4dade240
JPC
154 headers = [
155 ("id", u"# du poste"),
156 ("nom", u"Nom du poste"),
65e02621 157 ("implantation__id", u"Implantation"),
4dade240 158 ("employe_nom", u"Nom"),
4dade240
JPC
159 ]
160 h = SortHeaders(request, headers, order_field_type="ot", order_field="o")
63e17dff
PP
161 c = {
162 'title': 'Rapport des postes',
a7de62d7
JPC
163 'postes': out,
164 'count': len(out),
65e02621 165 'headers': list(h.headers()),
63e17dff
PP
166 }
167
00ca4d9f
EMS
168 return render_to_response(
169 'rh/rapports/postes.html', c, RequestContext(request)
170 )
171
f2d65e83 172
02c1b3dc
JPC
173@login_required
174@drh_or_admin_required
f2d65e83 175def rapports_contrat(request):
dcd1b959
OL
176 if 'HTTP_REFERER' in request.META.keys():
177 referer = request.META['HTTP_REFERER']
178 referer = "/".join(referer.split('/')[3:])
179 referer = "/%s" % referer.split('?')[0]
180 if referer != reverse('rhr_contrats'):
181 params = request.GET.copy()
182 params.update({'statut': 'Actif'})
183 request.GET = params
f2d65e83
PP
184
185 lookup_params = dict(request.GET.items())
65e02621
JPC
186 if 'ot' in lookup_params:
187 del lookup_params['ot']
188 if 'o' in lookup_params:
189 del lookup_params['o']
f2d65e83
PP
190
191 for key, value in lookup_params.items():
192 if not isinstance(key, str):
193 # 'key' will be used as a keyword argument later, so Python
194 # requires it to be a string.
195 del lookup_params[key]
196 lookup_params[smart_str(key)] = value
197
00ca4d9f
EMS
198 contrats = rh.Contrat.objects.select_related(
199 'dossier', 'dossier__poste', 'dossier__poste__implantation',
200 'type_contrat', 'dossier__employe'
201 )
22343fe7 202
6bee05ff 203 cl = RechercheTemporelle(dict(request.GET.items()), rh.Contrat)
f0f6b03e 204 lookup_params = cl.purge_params(lookup_params)
dcd1b959
OL
205 q_temporel = cl.get_q_temporel(contrats)
206 q = Q(**lookup_params) & q_temporel
207 contrats = contrats.filter(q).exclude(dossier__employe__supprime=1)
f0f6b03e 208
65e02621 209 if 'o' in request.GET:
00ca4d9f
EMS
210 contrats = contrats.order_by(
211 ('-' if request.GET.get('ot') == "desc" else '') + request.GET['o']
212 )
f2d65e83 213
8ee135b7
JPC
214 employes = set([c.dossier.employe_id for c in contrats])
215
65e02621
JPC
216 headers = [
217 ("dossier__employe__id", u"# de l'employé"),
d50a5e5d 218 ("dossier__employe__nom", u"Employé"),
65e02621 219 ("type_contrat__nom", u"Poste"),
d50a5e5d
OL
220 ("dossier__poste__implantation__region", u"Région"),
221 ("dossier__poste__implantation", u"Implantation"),
65e02621
JPC
222 ("type_contrat__nom", u"Type de contrat"),
223 ("date_debut", u"Date début"),
224 ("date_fin", u"Date fin"),
225 ]
226 h = SortHeaders(request, headers, order_field_type="ot", order_field="o")
227
f2d65e83 228 c = {
00ca4d9f 229 'cl': cl,
f2d65e83
PP
230 'title': 'Rapport des contrats',
231 'contrats': contrats,
8ee135b7 232 'count': len(contrats),
00ca4d9f 233 'count_employe': len(employes),
65e02621 234 'headers': list(h.headers()),
f2d65e83
PP
235 }
236
00ca4d9f
EMS
237 return render_to_response(
238 'rh/rapports/contrats.html', c, RequestContext(request)
239 )
e2c0b1ac
PP
240
241
02c1b3dc
JPC
242@login_required
243@drh_or_admin_required
98d6eb6c 244def rapports_masse_salariale(request):
df37184c 245
e90b19fd 246 class RechercheTemporelle(forms.Form):
aecb222b 247 CHOICE_ANNEES = range(
00ca4d9f
EMS
248 rh.Remuneration.objects.exclude(date_debut=None)
249 .order_by('date_debut')[0].date_debut.year,
250 date.today().year + 1
251 )
252
253 annee = forms.CharField(
254 initial=date.today().year,
255 widget=forms.Select(
256 choices=((a, a) for a in reversed(CHOICE_ANNEES))
257 )
444f3223 258 )
aecb222b 259
48c0abfe
JPC
260 region = forms.CharField(
261 widget=forms.Select(choices=[('', '')] +
262 [(i.id, i) for i in ref.Region.objects.all()]
263 )
264 )
265
266 implantation = forms.CharField(
267 widget=forms.Select(choices=[('', '')] +
268 [(i.id, i) for i in ref.Implantation.objects.all()]
269 )
270 )
271
aecb222b
JPC
272 #date_debut = forms.DateField(widget=adminwidgets.AdminDateWidget)
273 #date_fin = forms.DateField(widget=adminwidgets.AdminDateWidget)
e90b19fd 274
e90b19fd 275 form = RechercheTemporelle(request.GET)
00ca4d9f
EMS
276 get_filtre = [
277 (k, v) for k, v in request.GET.items()
278 if k not in ('date_debut', 'date_fin', 'implantation')
279 ]
e90b19fd
OL
280 query_string = urllib.urlencode(get_filtre)
281
aecb222b
JPC
282 date_debut = None
283 date_fin = None
444f3223
JPC
284 if request.GET.get('annee', None):
285 date_debut = "01-01-%s" % request.GET.get('annee', None)
286 date_fin = "31-12-%s" % request.GET.get('annee', None)
df37184c 287
48c0abfe
JPC
288 implantation = request.GET.get('implantation')
289 region = request.GET.get('region')
df37184c
JPC
290
291 custom_filter = {}
292 if implantation:
293 custom_filter['dossier__poste__implantation'] = implantation
294 if region:
295 custom_filter['dossier__poste__implantation__region'] = region
296
df37184c 297 c = {
e90b19fd
OL
298 'title': 'Rapport de masse salariale',
299 'form': form,
df37184c 300 'headers': [],
e90b19fd 301 'query_string': query_string,
df37184c 302 }
22b53270 303 if date_debut or date_fin:
c99116c3
JPC
304 masse = MasseSalariale(date_debut, date_fin, custom_filter,
305 request.GET.get('ne_pas_grouper', False))
515b83c3 306 if masse.rapport:
eabb27fd 307 if request.GET.get('ods'):
00ca4d9f
EMS
308 for h in (
309 h for h in masse.headers if 'background-color' in h[2]
310 ):
eabb27fd
JPC
311 del h[2]['background-color']
312 masse.ods()
313 output = StringIO.StringIO()
314 masse.doc.save(output)
315 output.seek(0)
316
00ca4d9f
EMS
317 response = HttpResponse(
318 FileWrapper(output),
319 content_type=(
320 'application/vnd.oasis.opendocument.spreadsheet'
321 )
322 )
eabb27fd
JPC
323 response['Content-Disposition'] = \
324 'attachment; filename=Masse Salariale %s.ods' % \
325 masse.annee
326 return response
327 else:
328 c['rapport'] = masse.rapport
329 c['header_keys'] = [h[0] for h in masse.headers]
330 #on enleve le background pour le header
00ca4d9f
EMS
331 for h in (
332 h for h in masse.headers if 'background-color' in h[2]
333 ):
eabb27fd
JPC
334 h[2]['background'] = 'none'
335 h = SortHeaders(request, masse.headers, order_field_type="ot",
336 not_sortable=c['header_keys'], order_field="o")
337 c['headers'] = list(h.headers())
338 for key, nom, opts in masse.headers:
339 c['headers']
340 c['total'] = masse.grand_totaux[0]
341 c['total_euro'] = masse.grand_totaux[1]
342 c['colspan'] = len(c['header_keys']) - 1
343 get_filtre.append(('ods', True))
344 query_string = urllib.urlencode(get_filtre)
345 c['url_ods'] = "%s?%s" % (
346 reverse('rhr_masse_salariale'), query_string)
22b53270 347
00ca4d9f
EMS
348 return render_to_response(
349 'rh/rapports/masse_salariale.html', c, RequestContext(request)
350 )
98d6eb6c
JPC
351
352
353@login_required
354@drh_or_admin_required
e2c0b1ac
PP
355def rapports_remuneration(request):
356
357 lookup_params = dict(request.GET.items())
9202c5db
JPC
358 if 'ot' in lookup_params:
359 del lookup_params['ot']
360 if 'o' in lookup_params:
361 del lookup_params['o']
e2c0b1ac
PP
362
363 for key, value in lookup_params.items():
364 if not isinstance(key, str):
365 # 'key' will be used as a keyword argument later, so Python
366 # requires it to be a string.
367 del lookup_params[key]
368 lookup_params[smart_str(key)] = value
369
370 employes = rh.Employe.objects.all()
9202c5db 371 if 'o' in request.GET:
00ca4d9f
EMS
372 employes = employes.order_by(
373 ('-' if request.GET.get('ot') == "desc" else '') + request.GET['o']
374 )
9202c5db 375
e2c0b1ac
PP
376 employes = employes.filter(**lookup_params)
377
378 output = []
9202c5db
JPC
379 headers = [
380 ("id", u"# de l'employé"),
381 ("nom", u"Nom"),
382 ("prenom", u"Prénom"),
383 ("", u"Salaire"),
384 ("", u"RAS"),
385 ("", u"Indemnités"),
386 ("", u"Accessoire"),
387 ("", u"Charges patronales"),
388 ("", u"Total"),
389 ]
390 h = SortHeaders(request, headers, order_field_type="ot", order_field="o")
e2c0b1ac
PP
391
392 for employe in employes:
393 line = {}
394 output.append(line)
395
da6c523f 396 dossiers = employe.rh_dossiers.all()
e2c0b1ac
PP
397
398 remun = {}
399 remun_sum_euro = 0
400
401 for dossier in dossiers:
00ca4d9f
EMS
402 this_remun, this_remun_sum, this_remun_sum_euro = \
403 calc_remun(dossier)
e2c0b1ac
PP
404
405 for item in this_remun:
406 if item not in remun:
407 remun[item] = this_remun[item]
408 else:
409 remun[item][0] += this_remun[item][0]
410 remun[item][1] += this_remun[item][1]
411
412 remun_sum_euro += this_remun_sum_euro
413
414 line['remun_sum_euro'] = remun_sum_euro
415
416 for r in remun:
417 if r == u'Indemnité':
e2c0b1ac
PP
418 line['Indemnite'] = remun[r][1]
419 else:
420 line[r] = remun[r][1]
421
422 line['id'] = employe.id
423 line['nom'] = employe.nom
424 line['prenom'] = employe.prenom
425
e2c0b1ac
PP
426 c = {
427 'title': 'Rapport de remuneration',
428 'employes': output,
9202c5db 429 'headers': list(h.headers()),
e2c0b1ac
PP
430 }
431
00ca4d9f
EMS
432 return render_to_response(
433 'rh/rapports/remuneration.html', c, RequestContext(request)
434 )
435
3ebc0952 436
783e077a
JPC
437@login_required
438@drh_or_admin_required
c8b22fd1
JPC
439def rapports_employe_sans_contrat(request):
440
441 lookup_params = dict(request.GET.items())
442 if 'ot' in lookup_params:
443 del lookup_params['ot']
444 if 'o' in lookup_params:
445 del lookup_params['o']
446
447 for key, value in lookup_params.items():
448 if not isinstance(key, str):
449 # 'key' will be used as a keyword argument later, so Python
450 # requires it to be a string.
451 del lookup_params[key]
452 lookup_params[smart_str(key)] = value
453
454 employes_query = rh.Employe.objects
455 if 'o' in request.GET:
00ca4d9f
EMS
456 employes_query = employes_query.order_by(
457 ('-' if request.GET.get('ot') == "desc" else '') + request.GET['o']
458 )
c8b22fd1 459
7c5645f0 460 employes = {}
22343fe7 461
00ca4d9f
EMS
462 dossiers_en_cours = rh.Dossier.objects.filter(
463 Q(date_fin=None) | Q(date_fin__gt=date.today())
464 )
465 tous_contrats_echus = rh.Contrat.objects.filter(
466 date_fin__lt=date.today(), dossier__in=dossiers_en_cours
467 )
00c9d7c2
OL
468 contrats = tous_contrats_echus.filter(**lookup_params).all()
469 for c in contrats:
470 if c.dossier.employe.id not in employes.keys():
00ca4d9f
EMS
471 employes[c.dossier.employe.id] = {
472 'employe': c.dossier.employe,
473 'dossiers': []
474 }
475 employes[c.dossier.employe.id]['dossiers'] += [c.dossier]
c8b22fd1
JPC
476
477 headers = [
1d2d4dc2
JPC
478 ("id", u"# de l'employé"),
479 ("nom", u"Nom"),
480 ("prenom", u"Prénom"),
80518280 481 ("dossier", u"Dossiers"),
c8b22fd1 482 ]
00ca4d9f
EMS
483 h = SortHeaders(
484 request, headers, order_field_type="ot", order_field="o",
485 not_sortable=('dossier',)
486 )
c8b22fd1
JPC
487
488 c = {
489 'title': u'Rapport des employés sans contrat',
490 'employes': employes,
491 'count': len(employes),
492 'headers': list(h.headers()),
493 }
494
00ca4d9f
EMS
495 return render_to_response(
496 'rh/rapports/employes_sans_contrat.html', c, RequestContext(request)
497 )
498
c8b22fd1
JPC
499
500@login_required
501@drh_or_admin_required
857b5c24
JPC
502def rapports_postes_modelisation(request):
503 c = {}
504 data = []
3c1ba807 505
7bf28694
EMS
506 for categorie in rh.CategorieEmploi.objects.all():
507 types = rh.TypePoste.objects.filter(categorie_emploi=categorie)
3c1ba807
JPC
508 data_types = []
509 for t in types.all():
510 postes = rh.Poste.objects.filter(type_poste=t)
511 data_types.append({
512 'num_postes': postes.count(),
513 'postes': postes.all(),
7bf28694 514 'type': categorie,
857b5c24 515 })
3c1ba807 516
857b5c24 517 data.append({
7bf28694 518 'categorie': categorie,
3c1ba807 519 'nb_types': types.count(),
00ca4d9f
EMS
520 'types': data_types
521 })
857b5c24
JPC
522
523 c['data'] = data
524
00ca4d9f
EMS
525 return render_to_response(
526 'rh/rapports/postes_modelisation.html', c, RequestContext(request)
527 )
857b5c24
JPC
528
529
530@login_required
531@drh_or_admin_required
783e077a
JPC
532def rapports_postes_implantation(request):
533 c = {}
534 data = []
535 for r in ref.Region.objects.all():
536 implantations = []
537 for i in ref.Implantation.objects.filter(region=r):
538 implantations.append({
539 'implantation': i,
540 'postes': rh.Poste.objects.filter(implantation=i),
541 'num_postes': rh.Poste.objects.filter(implantation=i).count(),
542 })
543 data.append({
544 'region': r,
545 'implantations': implantations
546 })
547
548 c['data'] = data
549
00ca4d9f
EMS
550 return render_to_response(
551 'rh/rapports/postes_implantation.html', c, RequestContext(request)
552 )
783e077a
JPC
553
554
555@login_required
556@drh_or_admin_required
557def rapports_postes_service(request):
558 c = {}
9988aafb
JPC
559 data = []
560 for s in rh.Service.objects.all():
561 postes = rh.Poste.objects.filter(service=s).all()
562 num_postes = rh.Poste.objects.filter(service=s).count()
22343fe7 563 data.append({'service': s, 'num_postes': num_postes, 'postes': postes})
783e077a 564
9988aafb 565 c['data'] = data
00ca4d9f
EMS
566 return render_to_response(
567 'rh/rapports/postes_service.html', c, RequestContext(request)
568 )
783e077a
JPC
569
570
32373f2e
OL
571def region_protected(model):
572 def wrapper(func):
573 def wrapped(request, id):
32373f2e
OL
574 if request.user.is_superuser:
575 return func(request, id)
576 user_groups = request.user.groups.all()
577 if grp_drh in user_groups:
578 return func(request, id)
579 if grp_correspondants_rh in user_groups:
580 employe = get_employe_from_user(request.user)
00ca4d9f
EMS
581 q = Q(**{
582 model.prefix_implantation: employe.implantation.region
583 })
32373f2e 584 qs = model.objects.filter(q)
718abc4d 585 if int(id) in [o.id for o in qs]:
32373f2e
OL
586 return func(request, id)
587 return redirect_interdiction(request)
588 return wrapped
589 return wrapper
590
591
592@region_protected(rh.Dossier)
3ebc0952 593def dossier_apercu(request, dossier_id):
baf9b78c 594 d = get_object_or_404(rh.Dossier, pk=dossier_id)
3ebc0952 595 c = {
838bc59d 596 'title': u"Dossier %s" % (d, ),
00ca4d9f
EMS
597 'is_popup': request.GET.get('_popup', False),
598 'dossier': d,
599 'pieces': rh.DossierPiece.objects.filter(dossier__exact=d),
600 'contrats': rh.Contrat.objects.filter(dossier__exact=d),
601 'commentaires': rh.DossierCommentaire.objects.filter(dossier=d).all(),
abf91905 602 'media_url': settings.PRIVE_MEDIA_URL,
3ebc0952 603 }
00ca4d9f
EMS
604 return render_to_response(
605 'admin/rh/dossier/apercu.html', c, RequestContext(request)
606 )
607
4a1f2ece 608
fbe60a9d
OL
609@region_protected(rh.Poste)
610def poste_apercu(request, poste_id):
c8cb18e3 611 p = get_object_or_404(rh.Poste, pk=poste_id)
fbe60a9d 612 c = {
c8cb18e3 613 'title': u"Poste %s" % (p, ),
00ca4d9f
EMS
614 'is_popup': request.GET.get('_popup', False),
615 'poste': p,
616 'financements': (
617 rh.PosteFinancement.objects.filter(poste=poste_id).all()
618 ),
619 'pieces': rh.PostePiece.objects.filter(poste=poste_id).all(),
620 'dossiers': (
621 rh.Dossier.objects.filter(poste=poste_id)
622 .order_by("-date_debut").all()
623 ),
624 'comparaisons': (
625 rh.PosteComparaison.objects.filter(poste=poste_id).all()
626 ),
627 'commentaires': (
628 rh.PosteCommentaire.objects.filter(poste=poste_id).all()
629 ),
abf91905 630 'media_url': settings.PRIVE_MEDIA_URL,
fbe60a9d 631 }
00ca4d9f
EMS
632 return render_to_response(
633 'admin/rh/poste/apercu.html', c, RequestContext(request)
634 )
635
fbe60a9d 636
4a1f2ece
OL
637def employe_apercu(request, employe_id):
638 employe = get_object_or_404(rh.Employe, pk=employe_id)
fbe60a9d 639 user_groups = request.user.groups.all()
fbe60a9d
OL
640 dossiers = None
641
642 if request.user.is_superuser or \
643 grp_drh in user_groups:
644 q = Q(employe=employe)
645 if grp_correspondants_rh in user_groups:
00ca4d9f
EMS
646 regions = [
647 d.poste.implantation.region for d in employe.rh_dossiers.all()
648 ]
fbe60a9d 649 q = Q(employe=employe) & Q(implantation__region__in=regions)
22343fe7
OL
650
651 dossiers = rh.Dossier.objects.filter(q).order_by('-date_debut')
652
4a1f2ece 653 c = {
ce740bb5 654 'title': u"Employe %s" % (employe, ),
00ca4d9f
EMS
655 'is_popup': request.GET.get('_popup', False),
656 'employe': employe,
657 'dossiers': dossiers,
abf91905 658 'media_url': settings.PRIVE_MEDIA_URL,
4a1f2ece 659 }
00ca4d9f
EMS
660 return render_to_response(
661 'admin/rh/employe/apercu.html', c, RequestContext(request)
662 )
663
150d83ec 664
77bd83d1
JPC
665@login_required
666@drh_or_admin_required
56264a85 667def organigrammes_employe(request, id, level="all"):
08faf06e
JPC
668
669 poste = get_object_or_404(rh.Poste, pk=id)
00ca4d9f
EMS
670 dossiers_by_poste = dict(
671 (d.poste_id, d)
672 for d in rh.Dossier.objects.select_related('employe', 'poste').all()
673 )
5c0f1778
JPC
674 postes_by_id = dict((p.id, p) for p in rh.Poste.objects.all())
675
676 e = dossiers_by_poste[poste.id].employe
677 name = u"Organigramme de [%s] %s %s" % (e.id, e.nom.upper(), e.prenom)
58014aec 678 graph = pgv.AGraph()
5c0f1778 679
f187a10f 680 if rh.Poste.objects.filter(responsable=poste).count() > 0:
58014aec
JPC
681 postes_handle = [poste]
682 while postes_handle:
00ca4d9f
EMS
683 postes_handle = rh.Poste.objects.select_related('implantation') \
684 .filter(
685 Q(date_fin__gt=date.today()) | Q(date_fin=None),
686 Q(date_debut__lt=date.today()) | Q(date_debut=None),
687 responsable__in=postes_handle
688 ).exclude(supprime=True).exclude(responsable=None).all()
32373f2e 689
58014aec
JPC
690 for p in postes_handle:
691 if p.responsable_id != p.id:
00ca4d9f
EMS
692 graph.add_edge(
693 dossiers_by_poste[p.responsable_id].poste_id, p.id
694 )
13ad5ad5 695
f187a10f 696 else:
5c0f1778
JPC
697 graph.add_node(poste.id)
698
4afec2e1
JPC
699 if level != "all":
700 postes_niveau = [poste.id]
701 for niveau in range(int(level)):
00ca4d9f
EMS
702 postes_niveau = [
703 p.id for p in
704 rh.Poste.objects.filter(responsable__in=postes_niveau).all()
705 ]
4afec2e1
JPC
706
707 while postes_niveau:
00ca4d9f
EMS
708 postes_niveau = [
709 p.id for p in
710 rh.Poste.objects.filter(responsable__in=postes_niveau).all()
711 ]
4afec2e1
JPC
712 if postes_niveau:
713 for p in postes_niveau:
714 if graph.has_node(p):
4cc81304 715 graph.delete_node(p)
4afec2e1 716
58014aec 717 a = graph
4afec2e1 718 a.name = name.encode('ascii', 'xmlcharrefreplace')
5c0f1778
JPC
719
720 poste_remontant = poste
721 while poste_remontant.responsable_id:
722 a.add_edge(poste_remontant.responsable_id, poste_remontant.id)
723 poste_remontant = poste_remontant.responsable
724
725 rh_graph.bind_poste_to_graph(a, postes_by_id)
726 #a.graph_attr['normalize'] = True
727 #a.graph_attr['level'] = 2
728 a.layout(prog='dot')
729
730 svg = a.draw(format='svg')
731
732 c = {
733 'svg': svg
734 }
a251ac8d
JPC
735
736 if 'forcer' in request.GET:
737 response = HttpResponse(svg, mimetype='image/svg+xml')
00ca4d9f
EMS
738 response['Content-Disposition'] = \
739 'attachment; filename=organigramme.svg'
a251ac8d
JPC
740 return response
741
00ca4d9f
EMS
742 return render_to_response(
743 'rh/organigrammes/employe.html', c, RequestContext(request),
744 mimetype="image/svg+xml"
745 )
5c0f1778
JPC
746
747
748@login_required
749@drh_or_admin_required
750def organigrammes_service(request, id):
751
752 service = get_object_or_404(rh.Service, pk=id)
82af5c19
JPC
753 svg = rh_graph.organigramme_postes_cluster( \
754 cluster_filter={"service": service}, \
755 titre=u"Organigramme du service %s" % service.nom,
756 cluster_titre=service.nom)
5c0f1778 757
82af5c19
JPC
758 c = {
759 'svg': svg
760 }
5c0f1778 761
00ca4d9f
EMS
762 return render_to_response(
763 'rh/organigrammes/vide.html', c, RequestContext(request),
764 mimetype="image/svg+xml"
765 )
766
5c0f1778 767
82af5c19
JPC
768@login_required
769@drh_or_admin_required
770def organigrammes_implantation(request, id):
5c0f1778 771
82af5c19
JPC
772 implantation = get_object_or_404(ref.Implantation, pk=id)
773 svg = rh_graph.organigramme_postes_cluster( \
774 cluster_filter={"implantation": implantation}, \
775 titre=u"Organigramme de l'implantation %s" % implantation.nom,
776 cluster_titre=implantation.nom)
5c0f1778
JPC
777
778 c = {
779 'svg': svg
780 }
781
00ca4d9f
EMS
782 return render_to_response(
783 'rh/organigrammes/vide.html', c, RequestContext(request),
784 mimetype="image/svg+xml"
785 )
786
5c0f1778 787
9da4c195
JPC
788@login_required
789@drh_or_admin_required
790def organigrammes_region(request, id):
791
792 region = get_object_or_404(ref.Region, pk=id)
793 svg = rh_graph.organigramme_postes_cluster( \
794 cluster_filter={"implantation__region": region}, \
795 titre=u"Organigramme du bureau de %s" % region.nom,
796 cluster_titre=region.nom)
797
798 c = {
799 'svg': svg
800 }
801
00ca4d9f
EMS
802 return render_to_response(
803 'rh/organigrammes/vide.html', c, RequestContext(request),
804 mimetype="image/svg+xml"
805 )