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