fix decimal
[auf_rh_dae.git] / project / dae / views.py
1 # -*- encoding: utf-8 -*-
2
3 import os
4 import datetime
5 import StringIO
6 from collections import defaultdict
7 from datetime import date
8 from simplejson import dumps
9 import warnings
10
11 from django.core.exceptions import MultipleObjectsReturned
12 from django.core.urlresolvers import reverse
13 from django.core.paginator import Paginator, InvalidPage
14 from django.http import Http404, HttpResponse, HttpResponseGone
15 from django.shortcuts import redirect, render_to_response, get_object_or_404
16 from django.views.static import serve
17 from django.template import Context, RequestContext
18 from django.template.loader import get_template
19 from django.contrib import messages
20 from django.conf import settings
21 from django.contrib.auth.decorators import login_required
22 from django.contrib.contenttypes.models import ContentType
23
24 from reversion.models import Version
25
26 from sendfile import sendfile
27
28 from auf.django.permissions.decorators import get_object
29
30 from dae import models as dae
31 from dae.forms import *
32 from dae.workflow import DOSSIER_ETAT_FINALISE, DOSSIER_ETAT_REGION_FINALISATION, \
33 DOSSIER_ETAT_DRH_FINALISATION, POSTE_ETAT_FINALISE
34 from dae.decorators import redirect_interdiction, dae_groupe_requis, \
35 poste_dans_ma_region_ou_service, \
36 dossier_dans_ma_region_ou_service, \
37 vieux_dossier_dans_ma_region_ou_service, \
38 employe_dans_ma_region_ou_service, \
39 dossier_est_modifiable, \
40 poste_est_modifiable, get_contrat
41 from dae.mail import send_drh_finalisation_mail
42 from rh import models as rh
43
44
45 def devises():
46 liste = []
47 for d in rh.Devise.objects.all():
48 annee = date.today().year
49 taux = rh.TauxChange.objects.filter(annee=annee, devise=d)
50 data = {}
51 if len(taux) == 0:
52 data['taux_euro'] = 0
53 else:
54 data['taux_euro'] = taux[0].taux
55 data['devise_code'] = d.code
56 liste.append(data)
57 return liste
58
59 @dae_groupe_requis
60 def index(request):
61 return render_to_response('dae/index.html', {}, RequestContext(request))
62
63
64 ### POSTE
65
66 @dae_groupe_requis
67 @poste_dans_ma_region_ou_service
68 def poste_consulter(request, key):
69 source, id = key.split('-')
70 poste = get_object_or_404(dae.Poste, pk=id)
71
72 if request.POST:
73 validationForm = PosteWorkflowForm(request.POST, instance=poste, request=request)
74 if validationForm.is_valid():
75 validationForm.save()
76 messages.add_message(request, messages.SUCCESS, "La validation a été enregistrée.")
77 return redirect('dae_postes_liste')
78 else:
79 validationForm = PosteWorkflowForm(instance=poste, request=request)
80
81 comparaisons_internes = poste.dae_comparaisons_internes.ma_region_ou_service(request.user)
82 vars = {
83 'poste': poste,
84 'validationForm': validationForm,
85 'comparaisons_internes': comparaisons_internes
86 }
87
88 return render_to_response('dae/poste_consulter.html', vars, RequestContext(request))
89
90 @dae_groupe_requis
91 @poste_dans_ma_region_ou_service
92 @poste_est_modifiable
93 def poste(request, key=None):
94 """ Formulaire pour un poste.
95
96 Permet de créer ou modifier un poste. Si le poste n'existe que dans rh_v1
97 il est automatiquement copié dans dae.
98
99 """
100 poste, data, vars = None, dict(), dict()
101
102 if key:
103 # Poste existant
104 data['poste'] = key
105 source, id = key.split('-')
106
107 if source == 'dae':
108 poste = get_object_or_404(dae.Poste, pk=id)
109 elif source == 'rh':
110 p = get_object_or_404(rh.Poste, pk=id)
111 # Initialisation avec les valeurs du poste de rh_v1
112 poste = dae.Poste(id_rh=p, nom=p.type_poste.nom)
113 for field in ('implantation', 'type_poste', ):
114 setattr(poste, field, getattr(p, field))
115 else:
116 # Nouveau poste
117 vars['new'] = True
118
119 if request.POST:
120 data.update(dict(request.POST.items()))
121 form = PosteForm(data, instance=poste, request=request)
122 financementForm = FinancementForm(request.POST, instance=poste)
123 piecesForm = PostePieceForm(request.POST, request.FILES, instance=poste)
124 if isinstance(poste, dae.Poste):
125 comparaisons_formset = PosteComparaisonFormSet(
126 request.POST,
127 queryset=poste.dae_comparaisons_internes.ma_region_ou_service(request.user)
128 )
129 else:
130 comparaisons_formset = PosteComparaisonFormSet(
131 request.POST,
132 queryset=dae.PosteComparaison.objects.none()
133 )
134 if form.is_valid() and piecesForm.is_valid() and financementForm.is_valid() and \
135 comparaisons_formset.is_valid():
136 poste = form.save()
137 piecesForm.instance = poste
138 piecesForm.save()
139 financementForm.instance = poste
140 financementForm.save()
141
142 # Ne remplacer que les comparaisons de ma région
143 comparaisons = comparaisons_formset.save(commit=False)
144 for comparaison in comparaisons:
145 comparaison.poste = poste
146 comparaison.save()
147
148 messages.add_message(request, messages.SUCCESS, "Le poste %s a été sauvegardé." % poste)
149 if request.POST.has_key('save'):
150 return redirect('poste_consulter', key='dae-%s' % poste.id)
151 else:
152 return redirect('poste', key='dae-%s' % poste.id)
153
154 else:
155 messages.add_message(request, messages.ERROR, 'Il y a des erreurs dans le formulaire.')
156
157 else:
158 # 'initial' évite la validation prémature lors d'une copie de poste de
159 # rh_v1 vers dae.
160 form = PosteForm(initial=data, instance=poste, request=request)
161 piecesForm = PostePieceForm(instance=poste)
162 financementForm = FinancementForm(instance=poste)
163 if isinstance(poste, dae.Poste):
164 comparaisons_formset = PosteComparaisonFormSet(
165 queryset=poste.dae_comparaisons_internes.ma_region_ou_service(request.user)
166 )
167 else:
168 comparaisons_formset = PosteComparaisonFormSet(
169 queryset=dae.PosteComparaison.objects.none()
170 )
171
172 vars.update(dict(
173 form=form, poste=poste, poste_key=key, piecesForm=piecesForm,
174 financementForm=financementForm,
175 comparaisons_formset=comparaisons_formset
176 ))
177
178 return render_to_response('dae/poste.html', vars, RequestContext(request))
179
180 @dae_groupe_requis
181 def postes_liste(request):
182 """ Liste des postes. """
183 content_type = ContentType.objects.get_for_model(dae.Poste)
184 extra_select = {'derniere_validation': (
185 "SELECT MAX(date) FROM workflow_workflowcommentaire "
186 "WHERE content_type_id = '%s' AND object_id = dae_poste.id" % content_type.id
187 )}
188 postes_a_traiter = dae.Poste.objects.mes_choses_a_faire(request.user) \
189 .extra(select=extra_select).order_by('-date_creation')
190 postes_en_cours = dae.Poste.objects.ma_region_ou_service(request.user) \
191 .extra(select=extra_select).filter(~Q(etat=POSTE_ETAT_FINALISE)).order_by('-date_creation')
192 return render_to_response('dae/postes_liste.html', {
193 'postes_a_traiter': postes_a_traiter,
194 'postes_en_cours': postes_en_cours,
195 }, RequestContext(request))
196
197 @login_required
198 def poste_piece(request, id, filename):
199 """Téléchargement d'une pièce jointe à un poste."""
200 piece = get_object_or_404(dae.PostePiece, pk=id)
201 if dae.Poste.objects.ma_region_ou_service(request.user).filter(id=piece.poste_id).exists():
202 return sendfile(request, piece.fichier.path)
203 else:
204 return redirect_interdiction(request)
205
206
207 ### DOSSIER
208
209 def filtered_type_remun():
210 defaut = (2, 3, 8, 17) # salaire de base, indemnité de fonction, charges patronales
211 return rh.TypeRemuneration.objects.filter(pk__in=defaut)
212
213 @dae_groupe_requis
214 @dossier_dans_ma_region_ou_service
215 def embauche_consulter(request, dossier_id):
216 dossier = get_object_or_404(dae.Dossier, pk=dossier_id)
217 etat_precedent = dossier.etat
218
219 if request.POST:
220 validationForm = DossierWorkflowForm(request.POST, instance=dossier, request=request)
221 if validationForm.is_valid():
222 if etat_precedent == DOSSIER_ETAT_REGION_FINALISATION and \
223 validationForm.cleaned_data['etat'] == DOSSIER_ETAT_DRH_FINALISATION:
224 send_drh_finalisation_mail(request, dossier)
225 validationForm.save()
226 messages.add_message(request, messages.SUCCESS, "La validation a été enregistrée.")
227 return redirect('dae_embauches_liste')
228 else:
229 validationForm = DossierWorkflowForm(instance=dossier, request=request)
230
231 comparaisons_internes = dossier.poste.dae_comparaisons_internes.ma_region_ou_service(request.user)
232 comparaisons = dossier.dae_comparaisons.ma_region_ou_service(request.user)
233 vars = {
234 'dossier': dossier,
235 'validationForm': validationForm,
236 'comparaisons_internes': comparaisons_internes,
237 'comparaisons': comparaisons
238 }
239
240 mode = request.GET.get('mode', None)
241 return render_to_response('dae/embauche_consulter.html', vars, RequestContext(request))
242
243 @dae_groupe_requis
244 def embauche_choisir_poste(request):
245 return render_to_response('dae/embauche-choisir-poste.html', {
246 'form': ChoosePosteForm(request=request)
247 }, RequestContext(request))
248
249 @dae_groupe_requis
250 @dossier_dans_ma_region_ou_service
251 @dossier_est_modifiable
252 def embauche(request, key=None, dossier_id=None):
253 """ Formulaire d'autorisation d'embauche. """
254
255 # Récupérer ou créer un poste et un dossier
256 source, id = key.split('-')
257 if source != 'dae':
258 return Http404
259 poste = get_object_or_404(dae.Poste, pk=id)
260
261 if request.POST:
262 if request.POST['employe'] == '':
263 # Nouvel employé
264 employe = dae.Employe()
265 else:
266 employe_source, id = request.POST['employe'].split('-')
267 if employe_source == 'dae':
268 # Employé DAE
269 employe = get_object_or_404(dae.Employe, pk=id)
270 elif employe_source == 'rh':
271 # Employé RH, on le copie dans DAE
272 e = get_object_or_404(rh.Employe, pk=id)
273 employe = dae.Employe(id_rh=e, prenom=e.prenom, nom=e.nom,
274 genre=e.genre)
275 else:
276 raise Http404
277
278 employe_form = EmployeForm(request.POST, instance=employe, request=request)
279
280 if employe_form.is_valid():
281 data = dict(request.POST.items())
282 employe = employe_form.save()
283 data['employe'] = 'dae-%s' % employe.id
284 employe_form = EmployeForm(data, instance=employe, request=request)
285
286 if not dossier_id:
287 dossier = dae.Dossier(poste=poste, employe=employe)
288 else:
289 dossier = get_object_or_404(dae.Dossier, pk=dossier_id)
290 dossier.employe = employe_form.instance
291
292 dossier_form = DossierForm(request.POST, instance=dossier)
293 piecesForm = DossierPieceForm(request.POST, request.FILES, instance=dossier)
294 comparaisons_formset = DossierComparaisonFormSet(
295 request.POST,
296 queryset=dossier.dae_comparaisons.ma_region_ou_service(request.user)
297 )
298 remunForm = RemunForm(request.POST, instance=dossier)
299
300 if employe_form.is_valid() and \
301 dossier_form.is_valid() and \
302 piecesForm.is_valid() and \
303 comparaisons_formset.is_valid() and \
304 remunForm.is_valid():
305 employe.save()
306 dossier_form.save()
307 piecesForm.save()
308 remunForm.save()
309
310 # Ne remplacer que les comparaisons de ma région
311 comparaisons = comparaisons_formset.save(commit=False)
312 for comparaison in comparaisons:
313 comparaison.dossier = dossier
314 comparaison.save()
315
316 messages.success(request, "Le dossier %s a été sauvegardé." % dossier)
317 if request.POST.has_key('save'):
318 return redirect('embauche_consulter', dossier_id=dossier.id)
319 else:
320 return redirect('embauche', key=dossier.poste.key, dossier_id=dossier.id)
321
322 else:
323 messages.add_message(request, messages.ERROR, 'Il y a des erreurs dans le formulaire.')
324
325 else:
326 # Initialisation d'un formulaire vide
327 if dossier_id:
328 dossier = get_object_or_404(dae.Dossier, pk=dossier_id)
329 employe = dossier.employe
330 data = dict(employe='dae-%s' % employe.id)
331 employe_form = EmployeForm(initial=data, instance=employe, request=request)
332 else:
333 dossier_rh = rh.Dossier()
334 poste_rh = poste.id_rh
335 dossier = pre_filled_dossier(dossier_rh, 'new', poste_rh)
336 employe_form = EmployeForm(request=request)
337
338 dossier_form = DossierForm(instance=dossier)
339 piecesForm = DossierPieceForm(instance=dossier)
340 comparaisons_formset = DossierComparaisonFormSet(
341 queryset=dossier.dae_comparaisons.ma_region_ou_service(request.user)
342 )
343 remunForm = RemunForm(instance=dossier)
344
345 try:
346 comparaisons_internes = dossier.poste.dae_comparaisons_internes.ma_region_ou_service(
347 request.user
348 )
349 except dae.Poste.DoesNotExist:
350 comparaisons_internes = []
351
352 return render_to_response('dae/embauche.html', {
353 'type_remun': filtered_type_remun(),
354 'devises': devises(),
355 'poste': poste,
356 'dossier': dossier,
357 'piecesForm': piecesForm,
358 'remunForm': remunForm,
359 'comparaisons_formset': comparaisons_formset,
360 'forms': dict(employe=employe_form, dossier=dossier_form, ),
361 'comparaisons_internes': comparaisons_internes
362 }, RequestContext(request))
363
364 @dae_groupe_requis
365 @dossier_dans_ma_region_ou_service
366 def embauches_liste(request):
367 """ Liste des embauches. """
368 content_type = ContentType.objects.get_for_model(dae.Dossier)
369 extra_select = {'derniere_validation': (
370 "SELECT MAX(date) FROM workflow_workflowcommentaire "
371 "WHERE content_type_id = '%s' AND object_id = dae_dossier.id" % content_type.id
372 )}
373 embauches_a_traiter = dae.Dossier.objects.mes_choses_a_faire(request.user) \
374 .extra(select=extra_select).order_by('-date_creation')
375 embauches_en_cours = dae.Dossier.objects.ma_region_ou_service(request.user) \
376 .extra(select=extra_select).order_by('-date_creation').exclude(etat=DOSSIER_ETAT_FINALISE)
377 return render_to_response('dae/embauches_liste.html', {
378 'embauches_a_traiter': embauches_a_traiter,
379 'embauches_en_cours': embauches_en_cours,
380 }, RequestContext(request))
381
382 @dae_groupe_requis
383 def embauches_finalisees(request):
384 """Liste des embauches finalisées."""
385 embauches = dae.Dossier.objects.ma_region_ou_service(request.user) \
386 .filter(etat=DOSSIER_ETAT_FINALISE)
387
388 # Tri
389 tri = request.GET.get('tri', None)
390 if tri and tri.startswith('-'):
391 dir = '-'
392 tri = tri[1:]
393 else:
394 dir = ''
395 if tri == 'region':
396 embauches = embauches.order_by(dir + 'poste__implantation__region__nom')
397 elif tri == 'implantation':
398 embauches = embauches.order_by(dir + 'poste__implantation__nom')
399 elif tri == 'poste':
400 embauches = embauches.order_by(dir + 'poste__nom')
401 elif tri == 'personne':
402 embauches = embauches.order_by(dir + 'employe__nom',
403 dir + 'employe__prenom')
404 elif tri == 'date_debut':
405 embauches = embauches.order_by(dir + 'debut_contrat')
406 elif tri == 'date_fin':
407 embauches = embauches.order_by(dir + 'fin_contrat')
408
409 # Pagination
410 paginator = Paginator(embauches, 20)
411 try:
412 page = paginator.page(request.GET.get('page', 1))
413 except InvalidPage:
414 page = paginator.page(1)
415
416 return render_to_response('dae/embauches_finalisees.html', {
417 'embauches': page
418 }, RequestContext(request))
419
420 def employe(request, key):
421 """ Récupération AJAX de l'employé pour la page d'embauche. """
422 data = dict(employe=key)
423
424 if key == '':
425 # Nouvel employé
426 employe = dae.Employe()
427 else:
428 # Employé existant
429 source, id = key.split('-')
430
431 if source == 'dae':
432 employe = get_object_or_404(dae.Employe, pk=id)
433 elif source == 'rh':
434 e = get_object_or_404(rh.Employe, id=id)
435 # Initialisation avec les valeurs de l'employé de rh_v1
436 employe = dae.Employe(id_rh=e)
437 for field in ('prenom', 'nom', 'genre'):
438 setattr(employe, field, getattr(e, field))
439
440 return HttpResponse(EmployeForm(initial=data, instance=employe, request=request).as_table())
441
442 ### CONTRATS
443
444 @dae_groupe_requis
445 @get_contrat
446 def contrat(request, contrat, filename):
447 return sendfile(request, contrat.fichier.path)
448
449 @dae_groupe_requis
450 @get_contrat
451 def contrat_supprimer(request, contrat):
452 if request.method == 'POST':
453 if 'oui' in request.POST:
454 contrat.delete()
455 return redirect('embauche_consulter', dossier_id=contrat.dossier.id)
456 return render_to_response('dae/contrat-supprimer.html', {
457 'contrat': contrat
458 }, RequestContext(request))
459
460 @dae_groupe_requis
461 @dossier_dans_ma_region_ou_service
462 def embauche_ajouter_contrat(request, dossier_id=None):
463 dossier = get_object_or_404(dae.Dossier, pk=dossier_id)
464 if request.method == 'POST':
465 form = ContratForm(request.POST, request.FILES)
466 if form.is_valid():
467 contrat = form.save(commit=False)
468 contrat.dossier = dossier
469 contrat.save()
470 return redirect('embauche_consulter', dossier_id=dossier.id)
471 else:
472 form = ContratForm()
473 return render_to_response('dae/embauche-ajouter-contrat.html', {
474 'form': form
475 }, RequestContext(request))
476
477 ### DAE NUMERISEE
478
479 @get_object(dae.Dossier, 'consulter')
480 def dae_numerisee(request, dossier):
481 return sendfile(request, dossier.dae_numerisee.path)
482
483 @get_object(dae.Dossier, 'modifier_dae_numerisee')
484 def dae_numerisee_modifier(request, dossier):
485 if request.method == 'POST':
486 form = DAENumeriseeForm(request.POST, request.FILES, instance=dossier)
487 if form.is_valid():
488 form.save()
489 return redirect('embauche_consulter', dossier_id=dossier.id)
490 else:
491 form = DAENumeriseeForm(instance=dossier)
492 return render_to_response('dae/dae_numerisee_modifier.html', {
493 'form': form
494 }, RequestContext(request))
495
496 @get_object(dae.Dossier, 'modifier_dae_numerisee')
497 def dae_numerisee_supprimer(request, dossier):
498 if request.method == 'POST':
499 if 'oui' in request.POST:
500 dossier.dae_numerisee = None
501 dossier.save()
502 return redirect('embauche_consulter', dossier_id=dossier.id)
503 return render_to_response('dae/dae_numerisee_supprimer.html', {}, RequestContext(request))
504
505 ################################################################################
506 # AJAX SECURISE
507 ################################################################################
508 @dae_groupe_requis
509 @employe_dans_ma_region_ou_service
510 def dossier(request, poste_key, employe_key):
511 """ Récupération AJAX du dossier pour la page d'embauche. """
512 data = dict()
513
514 poste_source, poste_id = poste_key.split('-')
515 poste = get_object_or_404(dae.Poste, pk=poste_id)
516
517 # Récupérer la devise de l'implantation lié au poste
518 implantation_devise = poste.get_default_devise()
519 data.update({'devise' : implantation_devise})
520
521 if poste.id_rh_id is not None:
522 poste_rh = get_object_or_404(rh.Poste, pk=poste.id_rh_id)
523 else:
524 poste_rh = None
525
526 ##########################################################################################
527 # NOUVEL EMPLOYE
528 ##########################################################################################
529 if employe_key == '':
530 employe_source = 'new'
531 employe = None
532 dossier_rh = rh.Dossier()
533 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
534
535 ##########################################################################################
536 # EMPLOYE DAE
537 ##########################################################################################
538 if employe_key.startswith('dae'):
539 employe_source, employe_id = employe_key.split('-')
540 employe_dae = get_object_or_404(dae.Employe, pk=employe_id)
541
542 # récupération de l'ancien dossier rh v1 pour l'employe DAE
543 try:
544 dossier_rh = rh.Dossier.objects.get(employe=employe_dae.id_rh_id, date_fin=None)
545 except (rh.Dossier.DoesNotExist):
546 dossier_rh = rh.Dossier()
547
548 # on tente de récupérer le dossier DAE, au pire on le contruit en le
549 # prépoluant avec son dossier rh v1.
550 try:
551 dossier = dae.Dossier.objects.get(employe=employe_dae, poste=poste)
552 except (dae.Dossier.DoesNotExist):
553 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
554 employe = employe_dae.id_rh
555 ##########################################################################################
556 # EMPLOYE RH v1
557 ##########################################################################################
558 if employe_key.startswith('rh'):
559 employe_source, employe_id = employe_key.split('-')
560 employe_rh = get_object_or_404(rh.Employe, pk=employe_id)
561
562 # récupération de l'ancien dossier rh v1 pour l'employe rh v1, s'il n'en a pas,
563 # on en fournit un nouveau qui servira uniquement un créer un nouveau dossier DAE.
564 try:
565 dossier_rh = rh.Dossier.objects.get(employe=employe_rh, date_fin=None)
566 except (rh.Dossier.DoesNotExist):
567 dossier_rh = rh.Dossier()
568 dossier = pre_filled_dossier(dossier_rh, employe_source, poste_rh)
569 employe = employe_rh
570
571 dossier_form = DossierForm(initial=data, instance=dossier)
572 vars = dict(form=dossier_form, poste=poste, employe=employe)
573 return render_to_response('dae/embauche-dossier.html', vars,
574 RequestContext(request))
575
576 # @Cette fonction est appelée à partir de fonctions déjà sécurisée
577 def pre_filled_dossier(dossier_rh, employe_source, poste_rh):
578 dossier = dae.Dossier()
579
580 if employe_source != 'new' and dossier_rh.id:
581 dossier.statut_anterieur = dossier_rh.statut
582
583 # Certains dossiers ont un classement à zéro
584 if dossier_rh.classement_id > 0:
585 dossier.classement_anterieur = dossier_rh.classement
586
587 # Récupération du salaire de base
588 remun = dossier_rh.remunerations().filter(type=1).order_by('-date_debut')
589 if remun:
590 dossier.salaire_anterieur = remun[0].montant
591 dossier.devise_anterieur = remun[0].devise
592
593 # Récupération du titulaire précédent
594 try:
595 dossiers = rh.Dossier.objects.order_by('-date_debut')
596 if poste_rh:
597 dossiers = dossiers.filter(poste=poste_rh)
598 else:
599 dossiers = rh.Dossier.objects.none()
600 if len(dossiers):
601 # Ce bloc ignore toutes les erreurs, car les données de rh
602 # manquantes peuvent en générer
603 d = dossiers[0]
604 try:
605 titulaire = d.employe
606 dossier.employe_anterieur = titulaire
607 dossier.classement_titulaire_anterieur = d.classement
608 dossier.statut_titulaire_anterieur = d.statut
609 remun = d.remunerations().filter(type=1).order_by('-date_debut')[0]
610 dossier.salaire_titulaire_anterieur = remun.montant
611 dossier.devise_titulaire_anterieur = remun.devise
612 except:
613 pass
614 # TODO: afficher l'info, les champs ne sont pas dans le
615 # modèle dae.Dossier: nom, prenom, classement, salaire
616 pass
617
618 except (rh.Dossier.DoesNotExist):
619 dossier_rh = rh.Dossier()
620
621 return dossier
622
623 @dae_groupe_requis
624 @vieux_dossier_dans_ma_region_ou_service
625 def dossier_resume(request, dossier_id=None):
626 try:
627 dossier = rh.Dossier.objects.get(id=dossier_id)
628 except:
629 return HttpResponseGone("Ce dossier n'est pas accessible")
630
631 data = {}
632 data['personne'] = unicode(dossier.employe)
633 data['classement'] = dossier.classement.id
634 if dossier.statut is not None:
635 data['statut'] = dossier.statut.id
636 data['implantation'] = dossier.poste.implantation.id
637 data['poste'] = u"%s %s" % (dossier.poste.type_poste.nom, dossier.poste.nom)
638 salaire = dossier.get_salaire()
639 if salaire is not None:
640 data['montant'] = float(salaire.montant)
641 else:
642 data['montant'] = None
643 if salaire is not None and salaire.devise is not None:
644 data['devise'] = salaire.devise.id
645 data['montant_euros'] = salaire.montant_euro()
646 else:
647 data['devise'] = None
648 data['montant_euros'] = 0
649 return HttpResponse(dumps(data))
650
651 @dae_groupe_requis
652 @vieux_dossier_dans_ma_region_ou_service
653 def poste_resume(request, dossier_id=None):
654 """
655 On travaille, en réalité sur le dossier mais on cache
656 l'identité de la personne.
657 """
658 try:
659 dossier = rh.Dossier.objects.get(id=dossier_id)
660 except:
661 return HttpResponseGone("Ce dossier n'est pas accessible")
662
663 salaire = dossier.get_salaire()
664 data = {}
665 data['implantation'] = dossier.poste.implantation.id
666 data['poste'] = u"%s %s" % (dossier.poste.type_poste.nom, dossier.poste.nom)
667 if salaire is not None:
668 data['devise'] = salaire.devise.id
669 data['montant'] = float(salaire.montant)
670 data['montant_euros'] = salaire.montant_euro()
671 else:
672 data['devise'] = None
673 data['montant'] = ""
674 data['montant_euros'] = ""
675 return HttpResponse(dumps(data))
676
677 def liste_postes(request):
678 """ Appel AJAX :
679 input : implantation_id
680 output : JSON liste de valeur point
681 """
682 method = request.method
683 params = getattr(request, method, [])
684 data = []
685
686 # Voir le code de _poste_choices dans forms.py
687 dae_ = dae.Poste.objects.actifs().filter(id_rh__isnull=True)
688 copies = dae.Poste.objects.exclude(id_rh__isnull=True)
689 rh_postes_actifs = rh.Poste.objects.actifs()
690
691 if 'implantation_id' in params and params.get('implantation_id') is not u"":
692 implantation_id = params.get('implantation_id')
693 dae_ = dae_.filter(implantation__id=implantation_id)
694 copies = copies.filter(implantation__id=implantation_id)
695 rh_postes_actifs = rh_postes_actifs.filter(implantation__id=implantation_id)
696
697 id_copies = [p.id_rh_id for p in copies.all()]
698 rhv1 = rh_postes_actifs.exclude(id__in=id_copies)
699 rhv1 = rhv1.select_related(depth=1)
700
701 data = [('', 'Nouveau poste')] + sorted([('dae-%s' % p.id, label_poste_display(p)) for p in dae_ | copies] + [('rh-%s' % p.id, label_poste_display(p)) for p in rhv1], key=lambda t: t[1])
702 return HttpResponse(dumps(data))
703
704 @login_required
705 def dossier_piece(request, id, filename):
706 """Téléchargement d'une pièce jointe à un poste."""
707 piece = get_object_or_404(dae.DossierPiece, pk=id)
708 if dae.Dossier.objects.ma_region_ou_service(request.user).filter(id=piece.dossier_id).exists():
709 return sendfile(request, piece.fichier.path)
710 else:
711 return redirect_interdiction(request)
712
713 @login_required
714 def importer_choix_dossier(request):
715 method = request.method
716 params = getattr(request, method, None)
717 if params:
718 form = DAEImportableForm(params)
719 if form.is_valid():
720 form.importer_poste()
721 messages.add_message(request, messages.SUCCESS, "L'importation a réussie.")
722 else:
723 form = DAEImportableForm()
724
725 vars = dict(form=form, )
726 return render_to_response('admin/dae/importer_choix_dossier.html', vars,
727 RequestContext(request))
728
729 ################################################################################
730 # AJAX SECURITE non nécessaire
731 ################################################################################
732 def coefficient(request):
733 """ Appel AJAX :
734 input : classement
735 output : coefficient
736 """
737 method = request.method
738 params = getattr(request, method, [])
739 data = dict()
740 if 'classement' in params and params.get('classement') is not u"":
741 classement = params.get('classement')
742 classement = rh.Classement.objects.get(pk=classement)
743 data['coefficient'] = classement.coefficient
744 else:
745 data['coefficient'] = 0
746 return HttpResponse(dumps(data))
747
748
749 def devise(request):
750 """ Appel AJAX :
751 input : valeur_point
752 output : devise, devise_code, taux_euro
753 """
754 method = request.method
755 params = getattr(request, method, [])
756 data = dict()
757 if 'valeur_point' in params and params.get('valeur_point') is not u"":
758 valeur_point = params.get('valeur_point')
759 valeur_point = rh.ValeurPoint.objects.get(pk=valeur_point)
760 annee = valeur_point.annee
761 try:
762 taux = rh.TauxChange.objects.get(annee=annee, devise=valeur_point.devise)
763 except MultipleObjectsReturned:
764 return HttpResponseGone(u"Il existe plusieurs taux pour la devise %s cette année-là : %s" % \
765 (valeur_point.devise.code, annee))
766
767 data['devise'] = taux.devise.id
768 data['valeur'] = valeur_point.valeur
769 data['devise_code'] = taux.devise.code
770 data['taux_euro'] = taux.taux
771 else:
772 return HttpResponseGone("Vous devez choisir une valeur de point")
773 return HttpResponse(dumps(data))
774
775 def devise_code(request):
776 """ Appel AJAX :
777 input : devise
778 output : devise_code, taux_euro
779 """
780 method = request.method
781 params = getattr(request, method, [])
782 data = dict()
783 if 'devise' in params:
784 devise = params.get('devise')
785 devise = rh.Devise.objects.get(pk=devise)
786 annee = date.today().year
787 taux = rh.TauxChange.objects.filter(annee=annee, devise=devise)
788 if len(taux) == 0:
789 return HttpResponseGone("Le taux n'est pas disponible")
790 data['devise_code'] = devise.code
791 data['taux_euro'] = taux[0].taux
792 return HttpResponse(dumps(data))
793
794 def add_remun(request, dossier, type_remun):
795 dossier = get_object_or_404(dae.Dossier, pk=dossier)
796 type_remun = get_object_or_404(rh.TypeRemuneration, pk=type_remun)
797 dae.Remuneration(dossier=dossier, devise=dossier.devise,
798 type=type_remun).save()
799
800 return render_to_response('dae/embauche-remun.html', dict(dossier=dossier),
801 RequestContext(request))
802
803 def salaire(request, implantation, devise, classement):
804 if not devise or not classement:
805 raise Http404
806
807 taux_impl = rh.TauxChange.objects.filter(implantation=implantation) \
808 .order_by('-annee')
809 taux = rh.TauxChange.objects.filter(devise=devise).order_by('-annee')
810 vp = rh.ValeurPoint.objects.filter(implantation=implantation) \
811 .order_by('-annee')
812 if vp.count() * taux.count() * taux_impl.count() == 0:
813 raise Http404
814
815 classement = get_object_or_404(rh.Classement, pk=classement)
816 taux, taux_impl, vp = taux[0].taux, taux_impl[0].taux, vp[0].valeur
817
818 salaire_euro = round(vp * classement.coefficient * taux_impl, 2)
819 data = dict(salaire_euro=salaire_euro, taux=taux,
820 salaire_devise=round(salaire_euro / taux, 2))
821
822 return HttpResponse(dumps(data))
823
824 def liste_valeurs_point(request):
825 """ Appel AJAX :
826 input : implantation_id
827 output : JSON liste de valeur point
828 """
829 method = request.method
830 params = getattr(request, method, [])
831 data = []
832 annee_courante = datetime.datetime.now().year
833 if 'implantation_id' in params and params.get('implantation_id') is not u"":
834 implantation_id = params.get('implantation_id')
835 preselectionne = rh.ValeurPoint.objects.filter(implantation=implantation_id, annee__in=(annee_courante,)).order_by("-annee")
836 for o in preselectionne:
837 data.append({'id' : o.id, 'label' : o.__unicode__(), 'devise' : o.devise_id, 'suggestion' : True})
838 else:
839 preselectionne = rh.ValeurPoint.objects.none()
840
841 liste_complete = rh.ValeurPoint.objects.filter(annee__in=(annee_courante,)).order_by("-annee")
842 for o in liste_complete.exclude(id__in=[p.id for p in preselectionne]):
843 data.append({'id' : o.id, 'label' : o.__unicode__(), 'devise' : o.devise_id, 'suggestion' : False})
844 return HttpResponse(dumps(data, indent=4))