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