validation form
[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
246
247def employe(request, key):
248 """ Récupération AJAX de l'employé pour la page d'embauche. """
249 data = dict(employe=key)
250
251 if key == '':
252 # Nouvel employé
253 employe = dae.Employe()
254 else:
255 # Employé existant
256 source, id = key.split('-')
257
258 if source == 'dae':
259 employe = get_object_or_404(dae.Employe, pk=id)
260 elif source == 'rh':
261 e = get_object_or_404(rh.Employe, id=id)
262 # Initialisation avec les valeurs de l'employé de rh_v1
263 employe = dae.Employe(id_rh=e)
264 for field in ('prenom', 'nom', 'genre'):
265 setattr(employe, field, getattr(e, field))
266
267 return HttpResponse(EmployeForm(initial=data, instance=employe).as_table())
268
269
270def dossier(request, poste_key, employe_key):
271 """ Récupération AJAX du dossier pour la page d'embauche. """
272 data = dict()
273
274 poste_source, poste_id = poste_key.split('-')
275 poste = get_object_or_404(dae.Poste, pk=poste_id)
276 poste_rh = get_object_or_404(rh.Poste, pk=poste.id_rh_id)
277
278 if employe_key == '':
279 employe_source = 'new'
280 dossier_rh = rh.Dossier()
281 else:
282 # Récupération des données de RH v1
283 employe_source, employe_id = employe_key.split('-')
284 if employe_source == 'dae':
285 employe = get_object_or_404(dae.Employe, pk=employe_id)
286 employe_source, employe_id = 'rh', employe.id_rh_id
287 if employe_source == 'rh':
288 employe_rh = get_object_or_404(rh.Employe, pk=employe_id)
289 try:
290 dossier_rh = rh.Dossier.objects.get(employe=employe_rh,
291 mandat_date_fin=None)
292 except (rh.Dossier.DoesNotExist):
293 dossier_rh = rh.Dossier()
294
139686f2
NC
295 # Récupération du dossier dae existant ou pré-remplissage
296 # des valeurs par défaut
297 if employe_source == 'dae':
298 try:
299 dossier = dae.Dossier.objects.get(employe=employe, poste=poste)
300 except (dae.Dossier.DoesNotExist):
ed1982f3 301 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
139686f2 302 else:
ed1982f3 303 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
139686f2 304
da3ca955 305 dossier_form = DossierForm(initial=data, instance=dossier)
306 vars = dict(form=dossier_form)
307
308 return render_to_response('dae/embauche-dossier.html', vars,
309 RequestContext(request))
139686f2
NC
310
311
312def salaire(request, implantation, devise, classement):
313 if not devise or not classement:
314 raise Http404
315
316 taux_impl = rh.TauxChange.objects.filter(implantation=implantation) \
317 .order_by('-annee')
318 taux = rh.TauxChange.objects.filter(devise=devise).order_by('-annee')
319 vp = rh.ValeurPoint.objects.filter(implantation=implantation) \
320 .order_by('-annee')
321 if vp.count() * taux.count() * taux_impl.count() == 0:
322 raise Http404
323
324 classement = get_object_or_404(rh.Classement, pk=classement)
325 taux, taux_impl, vp = taux[0].taux, taux_impl[0].taux, vp[0].valeur
326
327 salaire_euro = round(vp * classement.coefficient * taux_impl, 2)
328 data = dict(salaire_euro=salaire_euro, taux=taux,
329 salaire_devise=round(salaire_euro / taux, 2))
330
331 return HttpResponse(dumps(data))
ed1982f3
NC
332
333
334def pre_filled_dossier(dossier_rh, employe_source, poste_rh):
335 dossier = dae.Dossier()
336
337 if employe_source != 'new' and dossier_rh.id:
338 dossier.statut_anterieur = dossier_rh.statut
339
340 # Certains dossiers ont un classement à zéro
341 if dossier_rh.classement_id > 0:
342 dossier.classement_anterieur = dossier_rh.classement
343
344 # Récupération du salaire de base
345 remun = dossier_rh.remuneration_set.filter(type=1)
346 if remun:
347 dossier.salaire_anterieur = remun[0].montant
348
349 # Récupération du titulaire précédent
350 try:
351 dossiers = rh.Dossier.objects.order_by('-mandat_date_fin')
352 dossiers = dossiers.filter(poste1=poste_rh) \
353 | dossiers.filter(poste2=poste_rh)
354 if len(dossiers):
355 # Ce bloc ignore toutes les erreurs, car les données de rh
356 # manquantes peuvent en générer
357 d = dossiers[0]
358 try:
359 titulaire = d.employe
360 dossier.employe_anterieur = titulaire
361 dossier.classement_titulaire_anterieur = d.classement
362 dossier.statut_titulaire_anterieur = d.statut
363 dossier.salaire_titulaire_anterieur = \
364 d.remuneration_set.all()[0].montant
365 except:
366 pass
367 # TODO: afficher l'info, les champs ne sont pas dans le
368 # modèle dae.Dossier: nom, prenom, classement, salaire
369 pass
370
371 except (rh.Dossier.DoesNotExist):
372 dossier_rh = rh.Dossier()
373
374 return dossier
375
b50b0cd3 376def coefficient(request):
3d627bfd 377 """ Appel AJAX :
378 input : classement
379 output : coefficient
380 """
b50b0cd3 381 data = dict()
382 if request.POST and 'classement' in request.POST:
383 classement = request.POST.get('classement')
384 classement = rh.Classement.objects.get(pk=classement)
385 data['coefficient'] = classement.coefficient
386 return HttpResponse(dumps(data))
387
85668061 388def valeur(request):
3d627bfd 389 """ Appel AJAX :
390 input : valeur_point
391 output : valeur
392 """
85668061 393 data = dict()
394 if request.POST and 'valeur_point' in request.POST:
395 valeur_point = request.POST.get('valeur_point')
396 valeur_point = rh.ValeurPoint.objects.get(pk=valeur_point)
397 data['valeur'] = valeur_point.valeur
398 return HttpResponse(dumps(data))
3d627bfd 399
400def devise(request):
401 """ Appel AJAX :
402 input : valeur_point
8e30e17f 403 output : devise, devise_code, taux_euro
3d627bfd 404 """
405 data = dict()
406 if request.POST and 'valeur_point' in request.POST:
407 valeur_point = request.POST.get('valeur_point')
408 valeur_point = rh.ValeurPoint.objects.get(pk=valeur_point)
409 annee = valeur_point.annee
410 implantation = valeur_point.implantation
411 taux = rh.TauxChange.objects.get(annee=annee,
412 implantation=implantation)
413 data['devise'] = taux.devise.id
414 data['devise_code'] = taux.devise.code
8e30e17f 415 data['taux_euro'] = taux.taux
3d627bfd 416 return HttpResponse(dumps(data))
417
418def devise_code(request):
419 """ Appel AJAX :
420 input : devise
8e30e17f 421 output : devise_code, taux_euro
3d627bfd 422 """
423 data = dict()
424 if request.POST and 'devise' in request.POST:
425 devise = request.POST.get('devise')
426 devise = rh.Devise.objects.get(pk=devise)
8e30e17f 427 annee = date.today().year
428 taux = rh.TauxChange.objects.filter(annee=annee, devise=devise)
3d627bfd 429 data['devise_code'] = devise.code
8e30e17f 430 data['taux_euro'] = taux[0].taux
3d627bfd 431 return HttpResponse(dumps(data))
85668061 432
cb1d62b5
NC
433
434def add_remun(request, dossier, type_remun):
435 dossier = get_object_or_404(dae.Dossier, pk=dossier)
436 type_remun = get_object_or_404(rh.TypeRemuneration, pk=type_remun)
437 dae.Remuneration(dossier=dossier, devise=dossier.devise,
438 type=type_remun).save()
439
440 return render_to_response('dae/embauche-remun.html', dict(dossier=dossier),
441 RequestContext(request))