liste embauche [part 1]
[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 def embauches_liste(request):
234 """ Liste des embauches. """
235 vars = dict()
236 vars['embauches'] = []
237 for d in dae.Dossier.objects.all().order_by('-date_creation'):
238 premiere_revision = Version.objects.get_for_object(d)[0].revision
239 vars['embauches'].append((d, premiere_revision))
240 return render_to_response('dae/embauches_liste.html', vars,
241 RequestContext(request))
242
243 def employe(request, key):
244 """ Récupération AJAX de l'employé pour la page d'embauche. """
245 data = dict(employe=key)
246
247 if key == '':
248 # Nouvel employé
249 employe = dae.Employe()
250 else:
251 # Employé existant
252 source, id = key.split('-')
253
254 if source == 'dae':
255 employe = get_object_or_404(dae.Employe, pk=id)
256 elif source == 'rh':
257 e = get_object_or_404(rh.Employe, id=id)
258 # Initialisation avec les valeurs de l'employé de rh_v1
259 employe = dae.Employe(id_rh=e)
260 for field in ('prenom', 'nom', 'genre'):
261 setattr(employe, field, getattr(e, field))
262
263 return HttpResponse(EmployeForm(initial=data, instance=employe).as_table())
264
265
266 def dossier(request, poste_key, employe_key):
267 """ Récupération AJAX du dossier pour la page d'embauche. """
268 data = dict()
269
270 poste_source, poste_id = poste_key.split('-')
271 poste = get_object_or_404(dae.Poste, pk=poste_id)
272 poste_rh = get_object_or_404(rh.Poste, pk=poste.id_rh_id)
273
274 if employe_key == '':
275 employe_source = 'new'
276 dossier_rh = rh.Dossier()
277 else:
278 # Récupération des données de RH v1
279 employe_source, employe_id = employe_key.split('-')
280 if employe_source == 'dae':
281 employe = get_object_or_404(dae.Employe, pk=employe_id)
282 employe_source, employe_id = 'rh', employe.id_rh_id
283 if employe_source == 'rh':
284 employe_rh = get_object_or_404(rh.Employe, pk=employe_id)
285 try:
286 dossier_rh = rh.Dossier.objects.get(employe=employe_rh,
287 mandat_date_fin=None)
288 except (rh.Dossier.DoesNotExist):
289 dossier_rh = rh.Dossier()
290
291 # Récupération du dossier dae existant ou pré-remplissage
292 # des valeurs par défaut
293 if employe_source == 'dae':
294 try:
295 dossier = dae.Dossier.objects.get(employe=employe, poste=poste)
296 except (dae.Dossier.DoesNotExist):
297 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
298 else:
299 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
300
301 dossier_form = DossierForm(initial=data, instance=dossier)
302 vars = dict(form=dossier_form)
303
304 return render_to_response('dae/embauche-dossier.html', vars,
305 RequestContext(request))
306
307
308 def salaire(request, implantation, devise, classement):
309 if not devise or not classement:
310 raise Http404
311
312 taux_impl = rh.TauxChange.objects.filter(implantation=implantation) \
313 .order_by('-annee')
314 taux = rh.TauxChange.objects.filter(devise=devise).order_by('-annee')
315 vp = rh.ValeurPoint.objects.filter(implantation=implantation) \
316 .order_by('-annee')
317 if vp.count() * taux.count() * taux_impl.count() == 0:
318 raise Http404
319
320 classement = get_object_or_404(rh.Classement, pk=classement)
321 taux, taux_impl, vp = taux[0].taux, taux_impl[0].taux, vp[0].valeur
322
323 salaire_euro = round(vp * classement.coefficient * taux_impl, 2)
324 data = dict(salaire_euro=salaire_euro, taux=taux,
325 salaire_devise=round(salaire_euro / taux, 2))
326
327 return HttpResponse(dumps(data))
328
329
330 def pre_filled_dossier(dossier_rh, employe_source, poste_rh):
331 dossier = dae.Dossier()
332
333 if employe_source != 'new' and dossier_rh.id:
334 dossier.statut_anterieur = dossier_rh.statut
335
336 # Certains dossiers ont un classement à zéro
337 if dossier_rh.classement_id > 0:
338 dossier.classement_anterieur = dossier_rh.classement
339
340 # Récupération du salaire de base
341 remun = dossier_rh.remuneration_set.filter(type=1)
342 if remun:
343 dossier.salaire_anterieur = remun[0].montant
344
345 # Récupération du titulaire précédent
346 try:
347 dossiers = rh.Dossier.objects.order_by('-mandat_date_fin')
348 dossiers = dossiers.filter(poste1=poste_rh) \
349 | dossiers.filter(poste2=poste_rh)
350 if len(dossiers):
351 # Ce bloc ignore toutes les erreurs, car les données de rh
352 # manquantes peuvent en générer
353 d = dossiers[0]
354 try:
355 titulaire = d.employe
356 dossier.employe_anterieur = titulaire
357 dossier.classement_titulaire_anterieur = d.classement
358 dossier.statut_titulaire_anterieur = d.statut
359 dossier.salaire_titulaire_anterieur = \
360 d.remuneration_set.all()[0].montant
361 except:
362 pass
363 # TODO: afficher l'info, les champs ne sont pas dans le
364 # modèle dae.Dossier: nom, prenom, classement, salaire
365 pass
366
367 except (rh.Dossier.DoesNotExist):
368 dossier_rh = rh.Dossier()
369
370 return dossier
371
372 def coefficient(request):
373 """ Appel AJAX :
374 input : classement
375 output : coefficient
376 """
377 data = dict()
378 if request.POST and 'classement' in request.POST:
379 classement = request.POST.get('classement')
380 classement = rh.Classement.objects.get(pk=classement)
381 data['coefficient'] = classement.coefficient
382 return HttpResponse(dumps(data))
383
384 def valeur(request):
385 """ Appel AJAX :
386 input : valeur_point
387 output : valeur
388 """
389 data = dict()
390 if request.POST and 'valeur_point' in request.POST:
391 valeur_point = request.POST.get('valeur_point')
392 valeur_point = rh.ValeurPoint.objects.get(pk=valeur_point)
393 data['valeur'] = valeur_point.valeur
394 return HttpResponse(dumps(data))
395
396 def devise(request):
397 """ Appel AJAX :
398 input : valeur_point
399 output : devise, devise_code, taux_euro
400 """
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 annee = valeur_point.annee
406 implantation = valeur_point.implantation
407 taux = rh.TauxChange.objects.get(annee=annee,
408 implantation=implantation)
409 data['devise'] = taux.devise.id
410 data['devise_code'] = taux.devise.code
411 data['taux_euro'] = taux.taux
412 return HttpResponse(dumps(data))
413
414 def devise_code(request):
415 """ Appel AJAX :
416 input : devise
417 output : devise_code, taux_euro
418 """
419 data = dict()
420 if request.POST and 'devise' in request.POST:
421 devise = request.POST.get('devise')
422 devise = rh.Devise.objects.get(pk=devise)
423 annee = date.today().year
424 taux = rh.TauxChange.objects.filter(annee=annee, devise=devise)
425 data['devise_code'] = devise.code
426 data['taux_euro'] = taux[0].taux
427 return HttpResponse(dumps(data))
428
429
430 def add_remun(request, dossier, type_remun):
431 dossier = get_object_or_404(dae.Dossier, pk=dossier)
432 type_remun = get_object_or_404(rh.TypeRemuneration, pk=type_remun)
433 dae.Remuneration(dossier=dossier, devise=dossier.devise,
434 type=type_remun).save()
435
436 return render_to_response('dae/embauche-remun.html', dict(dossier=dossier),
437 RequestContext(request))