ajouté la section du coût global
[auf_rh_dae.git] / project / dae / views.py
CommitLineData
5d680e84 1# -*- encoding: utf-8 -*-
cb1d62b5 2from collections import defaultdict
8e30e17f 3from datetime import date
139686f2 4from json import dumps
768d7e1b 5import warnings
139686f2
NC
6
7from django.http import Http404, HttpResponse
5d680e84
NC
8from django.shortcuts import redirect, render_to_response, get_object_or_404
9from django.template import RequestContext
10
139686f2
NC
11from project.dae.forms import (ChoosePosteForm, DossierForm, EmployeForm,
12 PosteForm, PosteFinancementForm)
5d680e84
NC
13from project.dae import models as dae
14from project.rh_v1 import models as rh
15
e993f3dc 16from project.decorators import admin_required
5d680e84 17
ed1982f3 18
5d680e84
NC
19def index(request):
20 return render_to_response('dae/index.html', {}, RequestContext(request))
21
ed1982f3 22
3ed49093 23def poste(request, key=None):
5d680e84
NC
24 """ Formulaire pour un poste.
25
26 Permet de créer ou modifier un poste. Si le poste n'existe que dans rh_v1
27 il est automatiquement copié dans dae.
28
29 """
30 poste, data, vars = None, dict(), dict()
31
3ed49093 32 if key:
5d680e84 33 # Poste existant
3ed49093 34 data['poste'] = key
139686f2 35 source, id = key.split('-')
5d680e84 36
139686f2 37 if source == 'dae':
5d680e84 38 poste = get_object_or_404(dae.Poste, pk=id)
139686f2
NC
39 elif source == 'rh':
40 p = get_object_or_404(rh.Poste, pk=id)
5d680e84
NC
41 # Initialisation avec les valeurs du poste de rh_v1
42 poste = dae.Poste(id_rh=p, nom=p.type_poste.nom)
43 for field in ('implantation', 'type_poste', 'actif'):
44 setattr(poste, field, getattr(p, field))
3ed49093
NC
45 else:
46 # Nouveau poste
47 vars['new'] = True
5d680e84
NC
48
49 if request.POST:
3ed49093 50 data.update(dict(request.POST.items()))
5d680e84 51 form = PosteForm(data, instance=poste)
3ed49093 52 if 'save' in data and form.is_valid():
5d680e84 53 poste = form.save()
24d44b1b 54 return redirect('poste', key='dae-%s' % poste.id)
5d680e84
NC
55 else:
56 # 'initial' évite la validation prémature lors d'une copie de poste de
57 # rh_v1 vers dae.
58 form = PosteForm(initial=data, instance=poste)
59
3ed49093 60 vars.update(dict(form=form, poste=poste, poste_key=key))
5d680e84
NC
61
62 return render_to_response('dae/poste.html', vars, RequestContext(request))
3ed49093 63
98d51b59 64
498881f4 65def postes_liste(request):
0f23302a 66 """ Liste des postes. """
498881f4 67 vars = dict()
0f23302a 68 vars['postes'] = dae.Poste.objects.all().order_by('-date_creation')
98d51b59
NC
69 return render_to_response('dae/postes_liste.html', vars,
70 RequestContext(request))
71
3ed49093
NC
72
73def financement(request, key=None, id=None):
74 """ Formulaire pour une source de financement pour un poste. """
75 poste, financement, data, vars = None, None, dict(), dict()
76
77 if request.POST:
78 data.update(dict(request.POST.items()))
79
80 if key:
139686f2 81 source, poste_id = key.split('-')
703e5cfb 82 vars['poste_key'] = key
139686f2 83 if source == 'dae':
3ed49093
NC
84 poste = get_object_or_404(dae.Poste, pk=poste_id)
85 if id:
86 # Financement existant
87 financement = get_object_or_404(dae.PosteFinancement, pk=id)
703e5cfb 88 vars['financement_id'] = id
3ed49093
NC
89 else:
90 # Nouveau financement
91 financement = dae.PosteFinancement(poste_id=poste_id)
92 vars['new'] = True
93
94 if not financement:
95 return Http404
96
97 if request.POST:
98 form = PosteFinancementForm(data, instance=financement)
99 if 'delete' in data:
100 financement.delete()
101 elif 'save' in data and form.is_valid():
102 financement = form.save()
103 return redirect('poste', key='dae-%s' % poste.id)
104 else:
105 form = PosteFinancementForm(initial=data, instance=financement)
106
107 vars.update(dict(form=form, financement=financement))
108
703e5cfb
NC
109 if 'ajax' in request.GET:
110 template = 'dae/financement.html'
111 else:
112 template = 'dae/financement-full.html'
113 return render_to_response(template, vars, RequestContext(request))
139686f2
NC
114
115
cb1d62b5
NC
116def filtered_type_remun():
117 # Exclusion de "Indemnité de fonction" des types de rémun utilisés
118 return rh.TypeRemuneration.objects.exclude(pk=7)
119
ed1982f3 120def embauche(request, key=None, dossier=None):
139686f2
NC
121 """ Formulaire d'autorisation d'embauche. """
122 if not key:
123 vars = dict(step='poste', form=ChoosePosteForm())
124 else:
cb1d62b5
NC
125 type_remun = filtered_type_remun()
126 vars = dict(type_remun=type_remun)
139686f2
NC
127 source, id = key.split('-')
128 if source != 'dae':
129 return Http404
130 poste = get_object_or_404(dae.Poste, pk=id)
cb1d62b5
NC
131 if not dossier:
132 vars['new'] = True
139686f2
NC
133
134 if request.POST:
768d7e1b
NC
135 if request.POST['employe'] == '':
136 # Nouvel employé
137 employe = dae.Employe()
139686f2 138 else:
768d7e1b
NC
139 employe_source, id = request.POST['employe'].split('-')
140 if employe_source == 'dae':
141 # Employé DAE
142 employe = get_object_or_404(dae.Employe, pk=id)
143 elif employe_source == 'rh':
144 # Employé RH, on le copie dans DAE
145 e = get_object_or_404(rh.Employe, pk=id)
146 employe = dae.Employe(id_rh=e, prenom=e.prenom, nom=e.nom,
147 genre=e.genre)
148 else:
149 raise Http404
150
139686f2 151 employe_form = EmployeForm(request.POST, instance=employe)
768d7e1b
NC
152
153 if 'save' in request.POST:
154 if employe_form.is_valid():
155 data = dict(request.POST.items())
156 with warnings.catch_warnings():
157 warnings.simplefilter('ignore')
158 employe = employe_form.save()
159 data['employe'] = 'dae-%s' % employe.id
160 employe_form = EmployeForm(data, instance=employe)
cb1d62b5 161
ed1982f3
NC
162 if not dossier:
163 dossier = dae.Dossier(poste=poste, employe=employe)
164 else:
165 dossier = get_object_or_404(dae.Dossier, pk=dossier)
166 dossier_form = DossierForm(request.POST, instance=dossier)
cb1d62b5 167
768d7e1b
NC
168 if dossier_form.is_valid():
169 dossier = dossier_form.save()
cb1d62b5
NC
170 if not dossier.remuneration_set.all():
171 # Pré-peuplement des entrées de la section "coût
172 # global", à l'exclusion de "Indemnité de fonction"
173 for type in type_remun.all():
174 dae.Remuneration(dossier=dossier, type=type,
175 devise=dossier.devise).save()
176
177 else:
178 # Sauvegarde du coût global
179 cg_lines = defaultdict(dict)
180 for k, v in request.POST.items():
181 if k.startswith('cg-'):
182 prefix, field_name, cg_id = k.split('-')
183 cg_lines[int(cg_id)][unicode(field_name)] = v
184
185 for r in dossier.remuneration_set.all():
186 print 'trying %r' % r
187 if r.id in cg_lines:
188 if cg_lines[r.id]['montant'] == '':
189 r.delete()
190 else:
191 for k, v in cg_lines[r.id].items():
192 setattr(r, k, v)
193 r.save()
194
768d7e1b
NC
195 return redirect('embauche', key='dae-%s' % poste.id,
196 dossier=dossier.id)
197 else:
198 dossier_form = DossierForm(instance=dossier)
ed1982f3 199 else:
768d7e1b 200 # Initialisation d'un formulaire vide
ed1982f3
NC
201 dossier_rh = rh.Dossier()
202 poste_rh = poste.id_rh
768d7e1b
NC
203 if dossier:
204 dossier = get_object_or_404(dae.Dossier, pk=dossier)
205 employe = dossier.employe
206 data = dict(employe='dae-%s' % employe.id)
207 employe_form = EmployeForm(initial=data, instance=employe)
208 else:
209 dossier = pre_filled_dossier(dossier_rh, 'new', poste_rh)
210 employe_form = EmployeForm()
ed1982f3
NC
211 dossier_form = DossierForm(instance=dossier)
212
cb1d62b5 213 vars.update(step='employe', poste=poste, dossier=dossier,
ed1982f3 214 forms=dict(employe=employe_form, dossier=dossier_form))
139686f2 215
139686f2
NC
216 return render_to_response('dae/embauche.html', vars,
217 RequestContext(request))
218
219
220def employe(request, key):
221 """ Récupération AJAX de l'employé pour la page d'embauche. """
222 data = dict(employe=key)
223
224 if key == '':
225 # Nouvel employé
226 employe = dae.Employe()
227 else:
228 # Employé existant
229 source, id = key.split('-')
230
231 if source == 'dae':
232 employe = get_object_or_404(dae.Employe, pk=id)
233 elif source == 'rh':
234 e = get_object_or_404(rh.Employe, id=id)
235 # Initialisation avec les valeurs de l'employé de rh_v1
236 employe = dae.Employe(id_rh=e)
237 for field in ('prenom', 'nom', 'genre'):
238 setattr(employe, field, getattr(e, field))
239
240 return HttpResponse(EmployeForm(initial=data, instance=employe).as_table())
241
242
243def dossier(request, poste_key, employe_key):
244 """ Récupération AJAX du dossier pour la page d'embauche. """
245 data = dict()
246
247 poste_source, poste_id = poste_key.split('-')
248 poste = get_object_or_404(dae.Poste, pk=poste_id)
249 poste_rh = get_object_or_404(rh.Poste, pk=poste.id_rh_id)
250
251 if employe_key == '':
252 employe_source = 'new'
253 dossier_rh = rh.Dossier()
254 else:
255 # Récupération des données de RH v1
256 employe_source, employe_id = employe_key.split('-')
257 if employe_source == 'dae':
258 employe = get_object_or_404(dae.Employe, pk=employe_id)
259 employe_source, employe_id = 'rh', employe.id_rh_id
260 if employe_source == 'rh':
261 employe_rh = get_object_or_404(rh.Employe, pk=employe_id)
262 try:
263 dossier_rh = rh.Dossier.objects.get(employe=employe_rh,
264 mandat_date_fin=None)
265 except (rh.Dossier.DoesNotExist):
266 dossier_rh = rh.Dossier()
267
139686f2
NC
268 # Récupération du dossier dae existant ou pré-remplissage
269 # des valeurs par défaut
270 if employe_source == 'dae':
271 try:
272 dossier = dae.Dossier.objects.get(employe=employe, poste=poste)
273 except (dae.Dossier.DoesNotExist):
ed1982f3 274 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
139686f2 275 else:
ed1982f3 276 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
139686f2
NC
277
278 return HttpResponse(DossierForm(initial=data, instance=dossier).as_table())
279
280
281def salaire(request, implantation, devise, classement):
282 if not devise or not classement:
283 raise Http404
284
285 taux_impl = rh.TauxChange.objects.filter(implantation=implantation) \
286 .order_by('-annee')
287 taux = rh.TauxChange.objects.filter(devise=devise).order_by('-annee')
288 vp = rh.ValeurPoint.objects.filter(implantation=implantation) \
289 .order_by('-annee')
290 if vp.count() * taux.count() * taux_impl.count() == 0:
291 raise Http404
292
293 classement = get_object_or_404(rh.Classement, pk=classement)
294 taux, taux_impl, vp = taux[0].taux, taux_impl[0].taux, vp[0].valeur
295
296 salaire_euro = round(vp * classement.coefficient * taux_impl, 2)
297 data = dict(salaire_euro=salaire_euro, taux=taux,
298 salaire_devise=round(salaire_euro / taux, 2))
299
300 return HttpResponse(dumps(data))
ed1982f3
NC
301
302
303def pre_filled_dossier(dossier_rh, employe_source, poste_rh):
304 dossier = dae.Dossier()
305
306 if employe_source != 'new' and dossier_rh.id:
307 dossier.statut_anterieur = dossier_rh.statut
308
309 # Certains dossiers ont un classement à zéro
310 if dossier_rh.classement_id > 0:
311 dossier.classement_anterieur = dossier_rh.classement
312
313 # Récupération du salaire de base
314 remun = dossier_rh.remuneration_set.filter(type=1)
315 if remun:
316 dossier.salaire_anterieur = remun[0].montant
317
318 # Récupération du titulaire précédent
319 try:
320 dossiers = rh.Dossier.objects.order_by('-mandat_date_fin')
321 dossiers = dossiers.filter(poste1=poste_rh) \
322 | dossiers.filter(poste2=poste_rh)
323 if len(dossiers):
324 # Ce bloc ignore toutes les erreurs, car les données de rh
325 # manquantes peuvent en générer
326 d = dossiers[0]
327 try:
328 titulaire = d.employe
329 dossier.employe_anterieur = titulaire
330 dossier.classement_titulaire_anterieur = d.classement
331 dossier.statut_titulaire_anterieur = d.statut
332 dossier.salaire_titulaire_anterieur = \
333 d.remuneration_set.all()[0].montant
334 except:
335 pass
336 # TODO: afficher l'info, les champs ne sont pas dans le
337 # modèle dae.Dossier: nom, prenom, classement, salaire
338 pass
339
340 except (rh.Dossier.DoesNotExist):
341 dossier_rh = rh.Dossier()
342
343 return dossier
344
b50b0cd3 345def coefficient(request):
3d627bfd 346 """ Appel AJAX :
347 input : classement
348 output : coefficient
349 """
b50b0cd3 350 data = dict()
351 if request.POST and 'classement' in request.POST:
352 classement = request.POST.get('classement')
353 classement = rh.Classement.objects.get(pk=classement)
354 data['coefficient'] = classement.coefficient
355 return HttpResponse(dumps(data))
356
85668061 357def valeur(request):
3d627bfd 358 """ Appel AJAX :
359 input : valeur_point
360 output : valeur
361 """
85668061 362 data = dict()
363 if request.POST and 'valeur_point' in request.POST:
364 valeur_point = request.POST.get('valeur_point')
365 valeur_point = rh.ValeurPoint.objects.get(pk=valeur_point)
366 data['valeur'] = valeur_point.valeur
367 return HttpResponse(dumps(data))
3d627bfd 368
369def devise(request):
370 """ Appel AJAX :
371 input : valeur_point
8e30e17f 372 output : devise, devise_code, taux_euro
3d627bfd 373 """
374 data = dict()
375 if request.POST and 'valeur_point' in request.POST:
376 valeur_point = request.POST.get('valeur_point')
377 valeur_point = rh.ValeurPoint.objects.get(pk=valeur_point)
378 annee = valeur_point.annee
379 implantation = valeur_point.implantation
380 taux = rh.TauxChange.objects.get(annee=annee,
381 implantation=implantation)
382 data['devise'] = taux.devise.id
383 data['devise_code'] = taux.devise.code
8e30e17f 384 data['taux_euro'] = taux.taux
3d627bfd 385 return HttpResponse(dumps(data))
386
387def devise_code(request):
388 """ Appel AJAX :
389 input : devise
8e30e17f 390 output : devise_code, taux_euro
3d627bfd 391 """
392 data = dict()
393 if request.POST and 'devise' in request.POST:
394 devise = request.POST.get('devise')
395 devise = rh.Devise.objects.get(pk=devise)
8e30e17f 396 annee = date.today().year
397 taux = rh.TauxChange.objects.filter(annee=annee, devise=devise)
3d627bfd 398 data['devise_code'] = devise.code
8e30e17f 399 data['taux_euro'] = taux[0].taux
3d627bfd 400 return HttpResponse(dumps(data))
85668061 401
cb1d62b5
NC
402
403def add_remun(request, dossier, type_remun):
404 dossier = get_object_or_404(dae.Dossier, pk=dossier)
405 type_remun = get_object_or_404(rh.TypeRemuneration, pk=type_remun)
406 dae.Remuneration(dossier=dossier, devise=dossier.devise,
407 type=type_remun).save()
408
409 return render_to_response('dae/embauche-remun.html', dict(dossier=dossier),
410 RequestContext(request))