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