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