1 # -*- encoding: utf-8 -*-
4 from collections
import defaultdict
5 from datetime
import date
6 from simplejson
import dumps
9 from django
.core
.urlresolvers
import reverse
10 from django
.http
import Http404
, HttpResponse
, HttpResponseGone
11 from django
.shortcuts
import redirect
, render_to_response
, get_object_or_404
12 from django
.template
import RequestContext
13 from django
.contrib
import messages
15 from reversion
.models
import Version
17 from project
.dae
import models
as dae
18 from project
.rh_v1
import models
as rh
20 from project
.decorators
import admin_required
25 return render_to_response('dae/index.html', {}, RequestContext(request
))
28 def poste(request
, key
=None):
29 """ Formulaire pour un poste.
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.
35 poste
, data
, vars = None, dict(), dict()
40 source
, id = key
.split('-')
43 poste
= get_object_or_404(dae
.Poste
, pk
=id)
45 p
= get_object_or_404(rh
.Poste
, pk
=id)
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
))
55 data
.update(dict(request
.POST
.items()))
56 form
= PosteForm(data
, instance
=poste
)
57 financementForm
= FinancementForm(request
.POST
, instance
=poste
)
58 piecesForm
= PostePieceForm(request
.POST
, request
.FILES
, instance
=poste
)
59 if 'save' in data
and form
.is_valid() and piecesForm
.is_valid() and financementForm
.is_valid():
61 piecesForm
.instance
= poste
63 financementForm
.instance
= poste
64 financementForm
.save()
65 messages
.add_message(request
, messages
.SUCCESS
, "Le poste %s a été sauvegardé." % poste
)
66 return redirect('poste', key
='dae-%s' % poste
.id)
68 messages
.add_message(request
, messages
.ERROR
, 'Il y a des erreurs dans le formulaire.')
71 # 'initial' évite la validation prémature lors d'une copie de poste de
73 form
= PosteForm(initial
=data
, instance
=poste
)
74 piecesForm
= PostePieceForm(instance
=poste
)
75 financementForm
= FinancementForm(instance
=poste
)
77 vars.update(dict(form
=form
, poste
=poste
, poste_key
=key
, piecesForm
=piecesForm
, financementForm
=financementForm
))
79 return render_to_response('dae/poste.html', vars, RequestContext(request
))
82 def postes_liste(request
):
83 """ Liste des postes. """
87 for p
in dae
.Poste
.objects
.all().order_by('-date_creation'):
88 versions
= Version
.objects
.get_for_object(p
)
90 premiere_revision
= versions
[0].revision
92 premiere_revision
= None
95 validationForm
= PosteValidationForm(request
.POST
, instance
=p
, prefix
=p
.id)
96 if validationForm
.is_valid():
97 p
= validationForm
.save()
99 validationForm
= PosteValidationForm(instance
=p
, prefix
=p
.id)
101 vars['postes'].append((p
, premiere_revision
, validationForm
))
104 return redirect(reverse('dae_postes_liste'))
106 return render_to_response('dae/postes_liste.html', vars,
107 RequestContext(request
))
109 def filtered_type_remun():
110 # Exclusion de "Indemnité de fonction" des types de rémun utilisés
111 return rh
.TypeRemuneration
.objects
.exclude(pk
=7)
114 def embauche(request
, key
=None, dossier
=None):
115 """ Formulaire d'autorisation d'embauche. """
117 vars = dict(step
='poste', form
=ChoosePosteForm())
119 type_remun
= filtered_type_remun()
120 vars = dict(type_remun
=type_remun
)
121 source
, id = key
.split('-')
124 poste
= get_object_or_404(dae
.Poste
, pk
=id)
129 if request
.POST
['employe'] == '':
131 employe
= dae
.Employe()
133 employe_source
, id = request
.POST
['employe'].split('-')
134 if employe_source
== 'dae':
136 employe
= get_object_or_404(dae
.Employe
, pk
=id)
137 elif employe_source
== 'rh':
138 # Employé RH, on le copie dans DAE
139 e
= get_object_or_404(rh
.Employe
, pk
=id)
140 employe
= dae
.Employe(id_rh
=e
, prenom
=e
.prenom
, nom
=e
.nom
,
145 employe_form
= EmployeForm(request
.POST
, instance
=employe
)
147 if 'save' in request
.POST
:
148 if employe_form
.is_valid():
149 data
= dict(request
.POST
.items())
150 #with warnings.catch_warnings():
151 # warnings.simplefilter('ignore')
152 employe
= employe_form
.save()
153 data
['employe'] = 'dae-%s' % employe
.id
154 employe_form
= EmployeForm(data
, instance
=employe
)
157 dossier
= dae
.Dossier(poste
=poste
, employe
=employe
)
159 dossier
= get_object_or_404(dae
.Dossier
, pk
=dossier
)
160 dossier_form
= DossierForm(request
.POST
, instance
=dossier
)
161 piecesForm
= DossierPieceForm(request
.POST
, request
.FILES
, instance
=dossier
)
163 if dossier_form
.is_valid() and piecesForm
.is_valid():
164 dossier
= dossier_form
.save()
165 piecesForm
.instance
= dossier
167 if not dossier
.remuneration_set
.all():
168 # Pré-peuplement des entrées de la section "coût
169 # global", à l'exclusion de "Indemnité de fonction"
170 for type in type_remun
.all():
171 dae
.Remuneration(dossier
=dossier
, type=type,
172 devise
=dossier
.devise
).save()
175 # Sauvegarde du coût global
176 cg_lines
= defaultdict(dict)
177 for k
, v
in request
.POST
.items():
178 if k
.startswith('cg-'):
179 prefix
, field_name
, cg_id
= k
.split('-')
180 cg_lines
[int(cg_id
)][unicode(field_name
)] = v
182 for r
in dossier
.remuneration_set
.all():
183 print 'trying %r' % r
185 if cg_lines
[r
.id]['montant'] == '':
188 for k
, v
in cg_lines
[r
.id].items():
192 messages
.add_message(request
, messages
.SUCCESS
, "Le dossier %s a été sauvegardé." % dossier
)
193 return redirect('embauche', key
='dae-%s' % poste
.id,
196 messages
.add_message(request
, messages
.ERROR
, 'Il y a des erreurs dans le formulaire.')
199 dossier_form
= DossierForm(instance
=dossier
)
200 piecesForm
= DossierPieceForm(instance
=dossier
)
202 # Initialisation d'un formulaire vide
203 dossier_rh
= rh
.Dossier()
204 poste_rh
= poste
.id_rh
206 dossier
= get_object_or_404(dae
.Dossier
, pk
=dossier
)
207 employe
= dossier
.employe
208 data
= dict(employe
='dae-%s' % employe
.id)
209 employe_form
= EmployeForm(initial
=data
, instance
=employe
)
211 dossier
= pre_filled_dossier(dossier_rh
, 'new', poste_rh
)
212 employe_form
= EmployeForm()
214 dossier_form
= DossierForm(instance
=dossier
)
215 piecesForm
= DossierPieceForm(instance
=dossier
)
217 vars = dict(step
='employe', poste
=poste
, dossier
=dossier
, piecesForm
=piecesForm
,
218 forms
=dict(employe
=employe_form
, dossier
=dossier_form
, ))
220 return render_to_response('dae/embauche.html', vars,
221 RequestContext(request
))
223 def embauches_liste(request
):
224 """ Liste des embauches. """
226 vars['embauches'] = []
227 for d
in dae
.Dossier
.objects
.all().order_by('-date_creation'):
228 versions
= Version
.objects
.get_for_object(d
)
229 if len(versions
) > 0:
230 premiere_revision
= versions
[0].revision
232 premiere_revision
= None
233 vars['embauches'].append((d
, premiere_revision
))
234 return render_to_response('dae/embauches_liste.html', vars,
235 RequestContext(request
))
237 def employe(request
, key
):
238 """ Récupération AJAX de l'employé pour la page d'embauche. """
239 data
= dict(employe
=key
)
243 employe
= dae
.Employe()
246 source
, id = key
.split('-')
249 employe
= get_object_or_404(dae
.Employe
, pk
=id)
251 e
= get_object_or_404(rh
.Employe
, id=id)
252 # Initialisation avec les valeurs de l'employé de rh_v1
253 employe
= dae
.Employe(id_rh
=e
)
254 for field
in ('prenom', 'nom', 'genre'):
255 setattr(employe
, field
, getattr(e
, field
))
257 return HttpResponse(EmployeForm(initial
=data
, instance
=employe
).as_table())
259 def dossier(request
, poste_key
, employe_key
):
260 """ Récupération AJAX du dossier pour la page d'embauche. """
263 poste_source
, poste_id
= poste_key
.split('-')
264 poste
= get_object_or_404(dae
.Poste
, pk
=poste_id
)
266 # Récupérer la devise de l'implantation lié au poste
267 implantation_devise
= poste
.get_default_devise()
268 data
.update({'devise' : implantation_devise
.id})
270 if poste
.id_rh_id
is not None:
271 poste_rh
= get_object_or_404(rh
.Poste
, pk
=poste
.id_rh_id
)
275 ##########################################################################################
277 ##########################################################################################
278 if employe_key
== '':
279 employe_source
= 'new'
281 dossier_rh
= rh
.Dossier()
282 dossier
= pre_filled_dossier(dossier_rh
, employe_source
, poste_rh
)
284 ##########################################################################################
286 ##########################################################################################
287 if employe_key
.startswith('dae'):
288 employe_source
, employe_id
= employe_key
.split('-')
289 employe_dae
= get_object_or_404(dae
.Employe
, pk
=employe_id
)
291 # récupération de l'ancien dossier rh v1 pour l'employe DAE
293 dossier_rh
= rh
.Dossier
.objects
.get(employe
=employe_dae
.id_rh_id
, mandat_date_fin
=None)
294 except (rh
.Dossier
.DoesNotExist
):
295 dossier_rh
= rh
.Dossier()
297 # on tente de récupérer le dossier DAE, au pire on le contruit en le
298 # prépoluant avec son dossier rh v1.
300 dossier
= dae
.Dossier
.objects
.get(employe
=employe_dae
, poste
=poste
)
301 except (dae
.Dossier
.DoesNotExist
):
302 dossier
= pre_filled_dossier(dossier_rh
, employe_source
, poste_rh
)
303 employe
= employe_dae
.id_rh
304 ##########################################################################################
306 ##########################################################################################
307 if employe_key
.startswith('rh'):
308 employe_source
, employe_id
= employe_key
.split('-')
309 employe_rh
= get_object_or_404(rh
.Employe
, pk
=employe_id
)
311 # récupération de l'ancien dossier rh v1 pour l'employe rh v1, s'il n'en a pas,
312 # on en fournit un nouveau qui servira uniquement un créer un nouveau dossier DAE.
314 dossier_rh
= rh
.Dossier
.objects
.get(employe
=employe_rh
, mandat_date_fin
=None)
315 except (rh
.Dossier
.DoesNotExist
):
316 dossier_rh
= rh
.Dossier()
317 dossier
= pre_filled_dossier(dossier_rh
, employe_source
, poste_rh
)
320 dossier_form
= DossierForm(initial
=data
, instance
=dossier
)
321 vars = dict(form
=dossier_form
, poste
=poste
, employe
=employe
)
322 return render_to_response('dae/embauche-dossier.html', vars,
323 RequestContext(request
))
325 def salaire(request
, implantation
, devise
, classement
):
326 if not devise
or not classement
:
329 taux_impl
= rh
.TauxChange
.objects
.filter(implantation
=implantation
) \
331 taux
= rh
.TauxChange
.objects
.filter(devise
=devise
).order_by('-annee')
332 vp
= rh
.ValeurPoint
.objects
.filter(implantation
=implantation
) \
334 if vp
.count() * taux
.count() * taux_impl
.count() == 0:
337 classement
= get_object_or_404(rh
.Classement
, pk
=classement
)
338 taux
, taux_impl
, vp
= taux
[0].taux
, taux_impl
[0].taux
, vp
[0].valeur
340 salaire_euro
= round(vp
* classement
.coefficient
* taux_impl
, 2)
341 data
= dict(salaire_euro
=salaire_euro
, taux
=taux
,
342 salaire_devise
=round(salaire_euro
/ taux
, 2))
344 return HttpResponse(dumps(data
))
346 def pre_filled_dossier(dossier_rh
, employe_source
, poste_rh
):
347 dossier
= dae
.Dossier()
349 if employe_source
!= 'new' and dossier_rh
.id:
350 dossier
.statut_anterieur
= dossier_rh
.statut
352 # Certains dossiers ont un classement à zéro
353 if dossier_rh
.classement_id
> 0:
354 dossier
.classement_anterieur
= dossier_rh
.classement
356 # Récupération du salaire de base
357 remun
= dossier_rh
.remuneration_set
.filter(type=1)
359 dossier
.salaire_anterieur
= remun
[0].montant
361 # Récupération du titulaire précédent
363 dossiers
= rh
.Dossier
.objects
.order_by('-mandat_date_fin')
364 dossiers
= dossiers
.filter(poste1
=poste_rh
) | dossiers
.filter(poste2
=poste_rh
)
366 # Ce bloc ignore toutes les erreurs, car les données de rh
367 # manquantes peuvent en générer
370 titulaire
= d
.employe
371 dossier
.employe_anterieur
= titulaire
372 dossier
.classement_titulaire_anterieur
= d
.classement
373 dossier
.statut_titulaire_anterieur
= d
.statut
374 dossier
.salaire_titulaire_anterieur
= \
375 d
.remuneration_set
.all()[0].montant
378 # TODO: afficher l'info, les champs ne sont pas dans le
379 # modèle dae.Dossier: nom, prenom, classement, salaire
382 except (rh
.Dossier
.DoesNotExist
):
383 dossier_rh
= rh
.Dossier()
387 def coefficient(request
):
392 method
= request
.method
393 params
= getattr(request
, method
, [])
395 if 'classement' in params
and params
.get('classement') is not u
"":
396 classement
= params
.get('classement')
397 classement
= rh
.Classement
.objects
.get(pk
=classement
)
398 data
['coefficient'] = classement
.coefficient
400 data
['coefficient'] = 0
401 return HttpResponse(dumps(data
))
404 def liste_valeurs_point(request
):
406 input : implantation_id
407 output : JSON liste de valeur point
409 method
= request
.method
410 params
= getattr(request
, method
, [])
412 annee_courante
= datetime
.datetime
.now().year
413 if 'implantation_id' in params
and params
.get('implantation_id') is not u
"":
414 implantation_id
= params
.get('implantation_id')
415 objects
= rh
.ValeurPoint
.objects
.filter(implantation
=implantation_id
, annee__in
=(annee_courante
-1, annee_courante
)).order_by("-annee")
417 objects
= rh
.ValeurPoint
.objects
.filter(annee__in
=(annee_courante
-1, annee_courante
)).order_by("-annee")
419 data
.append({'id' : o
.id, 'label' : o
.__unicode__(), })
420 return HttpResponse(dumps(data
))
425 output : devise, devise_code, taux_euro
427 method
= request
.method
428 params
= getattr(request
, method
, [])
430 if 'valeur_point' in params
and params
.get('valeur_point') is not u
"":
431 valeur_point
= params
.get('valeur_point')
432 valeur_point
= rh
.ValeurPoint
.objects
.get(pk
=valeur_point
)
433 annee
= valeur_point
.annee
434 implantation
= valeur_point
.implantation
435 taux
= rh
.TauxChange
.objects
.get(annee
=annee
,
436 implantation
=implantation
)
437 data
['devise'] = taux
.devise
.id
438 data
['valeur'] = valeur_point
.valeur
439 data
['devise_code'] = taux
.devise
.code
440 data
['taux_euro'] = taux
.taux
442 return HttpResponseGone("Vous devez choisir une valeur de point")
443 return HttpResponse(dumps(data
))
445 def devise_code(request
):
448 output : devise_code, taux_euro
450 method
= request
.method
451 params
= getattr(request
, method
, [])
453 if 'devise' in params
:
454 devise
= params
.get('devise')
455 devise
= rh
.Devise
.objects
.get(pk
=devise
)
456 annee
= date
.today().year
457 taux
= rh
.TauxChange
.objects
.filter(annee
=annee
, devise
=devise
)
459 return HttpResponseGone("Le taux n'est pas disponible")
460 data
['devise_code'] = devise
.code
461 data
['taux_euro'] = taux
[0].taux
462 return HttpResponse(dumps(data
))
464 def add_remun(request
, dossier
, type_remun
):
465 dossier
= get_object_or_404(dae
.Dossier
, pk
=dossier
)
466 type_remun
= get_object_or_404(rh
.TypeRemuneration
, pk
=type_remun
)
467 dae
.Remuneration(dossier
=dossier
, devise
=dossier
.devise
,
468 type=type_remun
).save()
470 return render_to_response('dae/embauche-remun.html', dict(dossier
=dossier
),
471 RequestContext(request
))