Rapports: trie par colonne, filtres rajoutés, modification du visuel
[auf_rh_dae.git] / project / rh / views.py
CommitLineData
e9bbd6ba 1# -*- encoding: utf-8 -*-
c9122f1d 2from datetime import date
9b0a8554 3
fbe60a9d 4from django.db.models import Q
3411ac33 5from django.contrib.auth.decorators import login_required
fd009814 6from django.utils.encoding import smart_str
e9bbd6ba 7from django.shortcuts import redirect, render_to_response, get_object_or_404
8from django.template import RequestContext
9d53bc73 9from django.http import Http404
a184c555 10from sendfile import sendfile
e9bbd6ba 11
d04d084c 12from datamaster_modeles import models as ref
d04d084c 13from project.lib import get_employe_from_id
ae936f8d 14
d04d084c 15from rh import models as rh
e2c0b1ac 16from rh.lib import calc_remun
02c1b3dc 17from rh.decorators import drh_or_admin_required
9d53bc73 18from rh.templatetags.rapports import SortHeaders
a9faef67 19
9817fed5
OL
20# pas de reference a DAE devrait etre refactorisé
21from dae.utils import get_employe_from_user
22from dae.decorators import redirect_interdiction
23from dae.workflow import grp_drh, grp_correspondants_rh
24
a184c555 25@login_required
9817fed5 26def piece(request, filename):
a184c555 27 """Téléchargement d'une pièce jointe à un poste."""
9817fed5
OL
28 model, id, f = filename.split('/')
29 if model == 'employe':
30 # TODO definir peut-être un controle d'accès
31 piece = get_object_or_404(rh.EmployePiece, fichier=filename)
a184c555 32 return sendfile(request, piece.fichier.path)
9817fed5
OL
33 if model == 'poste':
34 piece = get_object_or_404(rh.PostePiece, fichier=filename)
35 if rh.Poste.objects.ma_region_ou_service(request.user).filter(id=piece.poste_id).exists():
36 return sendfile(request, piece.fichier.path)
37 else:
38 return redirect_interdiction(request)
a184c555 39
3411ac33 40# homes
c9122f1d 41@login_required
42def profil(request):
43 """Profil personnel de l'employé - éditable"""
44 rc = RequestContext(request)
45 c = {}
d04d084c 46
c9122f1d 47 employe = rc['this_employe']
65f9fac8 48
c9122f1d 49 c['user'] = request.user
50 c['employe'] = employe
c9122f1d 51 return render_to_response('rh/profil.html', c, rc)
a9faef67 52
53# employes
3411ac33 54@login_required
a9faef67 55def employes_liste(request):
56 """Liste des employés."""
5ea6b5bb 57 today = date.today()
58 employes = rh.Employe.objects \
59 .filter(actif=True, supprime=False) \
60 .filter(dossiers__actif=True, dossiers__supprime=False) \
61 .exclude(dossiers__date_debut__gt=today) \
62 .exclude(dossiers__date_fin__lt=today) \
63 .order_by('nom')
a9faef67 64 c = {
65 'user':request.user,
66 'employes':employes,
67 }
68 return render_to_response('rh/employes_liste.html', c, RequestContext(request))
69
3411ac33 70@login_required
a9faef67 71def employe(request, id):
72 """Information publique sur un employé."""
73 try:
74 employe = rh.Employe.objects.get(pk=id)
75 except:
76 employe = rh.Employe.objects.none()
77 c = {
78 'user':request.user,
79 'employe':employe,
80 }
81 return render_to_response('rh/employe.html', c, RequestContext(request))
63e17dff
PP
82
83
84# Rapports
85
86@login_required
02c1b3dc 87@drh_or_admin_required
63e17dff
PP
88def rapports_poste(request):
89
fd009814
PP
90 lookup_params = dict(request.GET.items())
91
7821915f
PP
92 comble = 'all'
93
fd009814 94 for key, value in lookup_params.items():
9d53bc73
JPC
95 if key == 'o' or key == 'ot':
96 del lookup_params[key]
97 continue
fd009814
PP
98 if not isinstance(key, str):
99 # 'key' will be used as a keyword argument later, so Python
100 # requires it to be a string.
101 del lookup_params[key]
102 lookup_params[smart_str(key)] = value
103
7821915f
PP
104 if key == 'comble':
105 comble = value
106 del lookup_params[key]
107
65e02621
JPC
108 #postes = rh.Poste.actifs.select_related('implantation', 'dossier').all()
109 postes = rh.Poste.actifs.select_related('implantation') \
9202c5db
JPC
110 .extra(select={'employe_id':'select group_concat(employe separator "|") from rh_dossier where poste=rh_poste.id and rh_dossier.actif = 1 and rh_dossier.date_fin is null %s' % \
111 ("%s" % (('order by employe %s' % ('asc' if 'ot' in request.GET and request.GET['ot'] == "asc" else "desc"))) if 'o' in request.GET and request.GET['o'] == "employe_id" else "") \
112 }) \
113 .extra(select={'employe_nom':'select group_concat(rh_employe.nom separator "|") from rh_dossier inner join rh_employe on rh_dossier.employe = rh_employe.id where poste=rh_poste.id and rh_dossier.actif = 1 and rh_dossier.date_fin is null %s' % \
114 ("%s" % (('order by rh_employe.nom %s' % ('asc' if 'ot' in request.GET and request.GET['ot'] == "asc" else "desc"))) if 'o' in request.GET and request.GET['o'] == "employe_nom" else "") \
115 }) \
116 .extra(select={'employe_prenom':'select group_concat(rh_employe.prenom separator "|") from rh_dossier inner join rh_employe on rh_dossier.employe = rh_employe.id where poste=rh_poste.id and rh_dossier.actif = 1 and rh_dossier.date_fin is null %s' % \
117 ("%s" % (('order by rh_employe.prenom %s' % ('asc' if 'ot' in request.GET and request.GET['ot'] == "asc" else "desc"))) if 'o' in request.GET and request.GET['o'] == "employe_prenom" else "") \
118 })
9d53bc73 119
65e02621 120 postes = postes.filter(**lookup_params)
9d53bc73 121 if 'o' in request.GET:
65e02621
JPC
122 postes = postes.order_by("%s%s" % ('-' if 'ot' in request.GET and request.GET['ot'] == "desc" else '', request.GET['o']))
123
4dade240
JPC
124 headers = [
125 ("id", u"# du poste"),
126 ("nom", u"Nom du poste"),
65e02621 127 ("implantation__id", u"Implantation"),
4dade240
JPC
128 ("employe_id", u"# de l'employé"),
129 ("employe_nom", u"Nom"),
130 ("employe_prenom", u"Prénom"),
131 ]
132 h = SortHeaders(request, headers, order_field_type="ot", order_field="o")
63e17dff
PP
133 c = {
134 'title': 'Rapport des postes',
65e02621
JPC
135 'postes': postes,
136 'count': len(postes),
137 'headers': list(h.headers()),
63e17dff
PP
138 }
139
140 return render_to_response('rh/rapports/postes.html', c, RequestContext(request))
f2d65e83 141
02c1b3dc
JPC
142@login_required
143@drh_or_admin_required
f2d65e83
PP
144def rapports_contrat(request):
145
146 lookup_params = dict(request.GET.items())
65e02621
JPC
147 if 'ot' in lookup_params:
148 del lookup_params['ot']
149 if 'o' in lookup_params:
150 del lookup_params['o']
f2d65e83
PP
151
152 for key, value in lookup_params.items():
153 if not isinstance(key, str):
154 # 'key' will be used as a keyword argument later, so Python
155 # requires it to be a string.
156 del lookup_params[key]
157 lookup_params[smart_str(key)] = value
158
65e02621 159 contrats = rh.Contrat.objects.select_related('dossier', 'dossier__poste', 'dossier__poste__implantation', 'type_contrat', 'dossier__employe')
f2d65e83 160 contrats = contrats.filter(**lookup_params)
65e02621
JPC
161 if 'o' in request.GET:
162 contrats = contrats.order_by("%s%s" % ('-' if 'ot' in request.GET and request.GET['ot'] == "desc" else '', request.GET['o']))
f2d65e83 163
8ee135b7
JPC
164 employes = set([c.dossier.employe_id for c in contrats])
165
65e02621
JPC
166 headers = [
167 ("dossier__employe__id", u"# de l'employé"),
168 ("dossier__employe__nom", u"Nom"),
169 ("dossier__employe__prenom", u"Prénom"),
170 ("type_contrat__nom", u"Poste"),
171 ("type_contrat__nom", u"Type de contrat"),
172 ("date_debut", u"Date début"),
173 ("date_fin", u"Date fin"),
174 ]
175 h = SortHeaders(request, headers, order_field_type="ot", order_field="o")
176
f2d65e83
PP
177 c = {
178 'title': 'Rapport des contrats',
179 'contrats': contrats,
8ee135b7
JPC
180 'count': len(contrats),
181 'count_employe' : len(employes),
65e02621 182 'headers': list(h.headers()),
f2d65e83
PP
183 }
184
185 return render_to_response('rh/rapports/contrats.html', c, RequestContext(request))
e2c0b1ac
PP
186
187
02c1b3dc
JPC
188@login_required
189@drh_or_admin_required
e2c0b1ac
PP
190def rapports_remuneration(request):
191
192 lookup_params = dict(request.GET.items())
9202c5db
JPC
193 if 'ot' in lookup_params:
194 del lookup_params['ot']
195 if 'o' in lookup_params:
196 del lookup_params['o']
e2c0b1ac
PP
197
198 for key, value in lookup_params.items():
199 if not isinstance(key, str):
200 # 'key' will be used as a keyword argument later, so Python
201 # requires it to be a string.
202 del lookup_params[key]
203 lookup_params[smart_str(key)] = value
204
205 employes = rh.Employe.objects.all()
9202c5db
JPC
206 if 'o' in request.GET:
207 employes = employes.order_by("%s%s" % ('-' if 'ot' in request.GET and request.GET['ot'] == "desc" else '', request.GET['o']))
208
e2c0b1ac
PP
209 employes = employes.filter(**lookup_params)
210
211 output = []
9202c5db
JPC
212 headers = [
213 ("id", u"# de l'employé"),
214 ("nom", u"Nom"),
215 ("prenom", u"Prénom"),
216 ("", u"Salaire"),
217 ("", u"RAS"),
218 ("", u"Indemnités"),
219 ("", u"Accessoire"),
220 ("", u"Charges patronales"),
221 ("", u"Total"),
222 ]
223 h = SortHeaders(request, headers, order_field_type="ot", order_field="o")
e2c0b1ac
PP
224
225 for employe in employes:
226 line = {}
227 output.append(line)
228
da6c523f 229 dossiers = employe.rh_dossiers.all()
e2c0b1ac
PP
230
231 remun = {}
232 remun_sum_euro = 0
233
234 for dossier in dossiers:
235 this_remun, this_remun_sum, this_remun_sum_euro = calc_remun(dossier)
236
237 for item in this_remun:
238 if item not in remun:
239 remun[item] = this_remun[item]
240 else:
241 remun[item][0] += this_remun[item][0]
242 remun[item][1] += this_remun[item][1]
243
244 remun_sum_euro += this_remun_sum_euro
245
246 line['remun_sum_euro'] = remun_sum_euro
247
248 for r in remun:
249 if r == u'Indemnité':
e2c0b1ac
PP
250 line['Indemnite'] = remun[r][1]
251 else:
252 line[r] = remun[r][1]
253
254 line['id'] = employe.id
255 line['nom'] = employe.nom
256 line['prenom'] = employe.prenom
257
258
259 c = {
260 'title': 'Rapport de remuneration',
261 'employes': output,
9202c5db 262 'headers': list(h.headers()),
e2c0b1ac
PP
263 }
264
265 return render_to_response('rh/rapports/remuneration.html', c, RequestContext(request))
3ebc0952 266
32373f2e
OL
267def region_protected(model):
268 def wrapper(func):
269 def wrapped(request, id):
32373f2e
OL
270 if request.user.is_superuser:
271 return func(request, id)
272 user_groups = request.user.groups.all()
273 if grp_drh in user_groups:
274 return func(request, id)
275 if grp_correspondants_rh in user_groups:
276 employe = get_employe_from_user(request.user)
277 q = Q(**{model.prefix_implantation: employe.implantation.region})
278 qs = model.objects.filter(q)
718abc4d 279 if int(id) in [o.id for o in qs]:
32373f2e
OL
280 return func(request, id)
281 return redirect_interdiction(request)
282 return wrapped
283 return wrapper
284
285
286@region_protected(rh.Dossier)
3ebc0952
OL
287def dossier_apercu(request, dossier_id):
288 c = {
289 'is_popup' : request.GET.get('_popup', False),
290 'dossier' : get_object_or_404(rh.Dossier, pk=dossier_id)
291
292 }
293 return render_to_response('admin/rh/dossier/apercu.html', c, RequestContext(request))
4a1f2ece 294
fbe60a9d
OL
295@region_protected(rh.Poste)
296def poste_apercu(request, poste_id):
297 c = {
298 'is_popup' : request.GET.get('_popup', False),
299 'poste' : get_object_or_404(rh.Poste, pk=poste_id)
300
301 }
302 return render_to_response('admin/rh/poste/apercu.html', c, RequestContext(request))
303
4a1f2ece 304def employe_apercu(request, employe_id):
fbe60a9d 305 from dae.workflow import grp_drh, grp_correspondants_rh
4a1f2ece 306 employe = get_object_or_404(rh.Employe, pk=employe_id)
fbe60a9d
OL
307 user_groups = request.user.groups.all()
308
309 dernier_dossier = None
310 dossiers = None
311
312 if request.user.is_superuser or \
313 grp_drh in user_groups:
314 q = Q(employe=employe)
315 if grp_correspondants_rh in user_groups:
7eeafa57 316 regions = [d.poste.implantation.region for d in employe.rh_dossiers.all()]
fbe60a9d
OL
317 q = Q(employe=employe) & Q(implantation__region__in=regions)
318
319 dossiers = rh.Dossier.objects.filter(employe=employe).order_by('-date_debut')
320
4a1f2ece
OL
321 c = {
322 'is_popup' : request.GET.get('_popup', False),
323 'employe' : employe,
fbe60a9d 324 'dossiers' : dossiers,
4a1f2ece
OL
325 }
326 return render_to_response('admin/rh/employe/apercu.html', c, RequestContext(request))
150d83ec 327
32373f2e 328