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