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