Rapports: trie par colonne, filtres rajoutés, modification du visuel
[auf_rh_dae.git] / project / rh / views.py
1 # -*- encoding: utf-8 -*-
2 from datetime import date
3
4 from django.db.models import Q
5 from django.contrib.auth.decorators import login_required
6 from django.utils.encoding import smart_str
7 from django.shortcuts import redirect, render_to_response, get_object_or_404
8 from django.template import RequestContext
9 from django.http import Http404
10 from sendfile import sendfile
11
12 from datamaster_modeles import models as ref
13 from project.lib import get_employe_from_id
14
15 from rh import models as rh
16 from rh.lib import calc_remun
17 from rh.decorators import drh_or_admin_required
18 from rh.templatetags.rapports import SortHeaders
19
20 # pas de reference a DAE devrait etre refactorisé
21 from dae.utils import get_employe_from_user
22 from dae.decorators import redirect_interdiction
23 from dae.workflow import grp_drh, grp_correspondants_rh
24
25 @login_required
26 def piece(request, filename):
27 """Téléchargement d'une pièce jointe à un poste."""
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)
32 return sendfile(request, piece.fichier.path)
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)
39
40 # homes
41 @login_required
42 def profil(request):
43 """Profil personnel de l'employé - éditable"""
44 rc = RequestContext(request)
45 c = {}
46
47 employe = rc['this_employe']
48
49 c['user'] = request.user
50 c['employe'] = employe
51 return render_to_response('rh/profil.html', c, rc)
52
53 # employes
54 @login_required
55 def employes_liste(request):
56 """Liste des employés."""
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')
64 c = {
65 'user':request.user,
66 'employes':employes,
67 }
68 return render_to_response('rh/employes_liste.html', c, RequestContext(request))
69
70 @login_required
71 def 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))
82
83
84 # Rapports
85
86 @login_required
87 @drh_or_admin_required
88 def rapports_poste(request):
89
90 lookup_params = dict(request.GET.items())
91
92 comble = 'all'
93
94 for key, value in lookup_params.items():
95 if key == 'o' or key == 'ot':
96 del lookup_params[key]
97 continue
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
104 if key == 'comble':
105 comble = value
106 del lookup_params[key]
107
108 #postes = rh.Poste.actifs.select_related('implantation', 'dossier').all()
109 postes = rh.Poste.actifs.select_related('implantation') \
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 })
119
120 postes = postes.filter(**lookup_params)
121 if 'o' in request.GET:
122 postes = postes.order_by("%s%s" % ('-' if 'ot' in request.GET and request.GET['ot'] == "desc" else '', request.GET['o']))
123
124 headers = [
125 ("id", u"# du poste"),
126 ("nom", u"Nom du poste"),
127 ("implantation__id", u"Implantation"),
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")
133 c = {
134 'title': 'Rapport des postes',
135 'postes': postes,
136 'count': len(postes),
137 'headers': list(h.headers()),
138 }
139
140 return render_to_response('rh/rapports/postes.html', c, RequestContext(request))
141
142 @login_required
143 @drh_or_admin_required
144 def rapports_contrat(request):
145
146 lookup_params = dict(request.GET.items())
147 if 'ot' in lookup_params:
148 del lookup_params['ot']
149 if 'o' in lookup_params:
150 del lookup_params['o']
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
159 contrats = rh.Contrat.objects.select_related('dossier', 'dossier__poste', 'dossier__poste__implantation', 'type_contrat', 'dossier__employe')
160 contrats = contrats.filter(**lookup_params)
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']))
163
164 employes = set([c.dossier.employe_id for c in contrats])
165
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
177 c = {
178 'title': 'Rapport des contrats',
179 'contrats': contrats,
180 'count': len(contrats),
181 'count_employe' : len(employes),
182 'headers': list(h.headers()),
183 }
184
185 return render_to_response('rh/rapports/contrats.html', c, RequestContext(request))
186
187
188 @login_required
189 @drh_or_admin_required
190 def rapports_remuneration(request):
191
192 lookup_params = dict(request.GET.items())
193 if 'ot' in lookup_params:
194 del lookup_params['ot']
195 if 'o' in lookup_params:
196 del lookup_params['o']
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()
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
209 employes = employes.filter(**lookup_params)
210
211 output = []
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")
224
225 for employe in employes:
226 line = {}
227 output.append(line)
228
229 dossiers = employe.rh_dossiers.all()
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é':
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,
262 'headers': list(h.headers()),
263 }
264
265 return render_to_response('rh/rapports/remuneration.html', c, RequestContext(request))
266
267 def region_protected(model):
268 def wrapper(func):
269 def wrapped(request, id):
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)
279 if int(id) in [o.id for o in qs]:
280 return func(request, id)
281 return redirect_interdiction(request)
282 return wrapped
283 return wrapper
284
285
286 @region_protected(rh.Dossier)
287 def 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))
294
295 @region_protected(rh.Poste)
296 def 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
304 def employe_apercu(request, employe_id):
305 from dae.workflow import grp_drh, grp_correspondants_rh
306 employe = get_object_or_404(rh.Employe, pk=employe_id)
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:
316 regions = [d.poste.implantation.region for d in employe.rh_dossiers.all()]
317 q = Q(employe=employe) & Q(implantation__region__in=regions)
318
319 dossiers = rh.Dossier.objects.filter(employe=employe).order_by('-date_debut')
320
321 c = {
322 'is_popup' : request.GET.get('_popup', False),
323 'employe' : employe,
324 'dossiers' : dossiers,
325 }
326 return render_to_response('admin/rh/employe/apercu.html', c, RequestContext(request))
327
328