dossier comp nom de poste
[auf_rh_dae.git] / project / dae / views.py
index bb40f29..9a52585 100644 (file)
@@ -1,33 +1,33 @@
 # -*- encoding: utf-8 -*-
 
-import datetime
-from datetime import date
-from simplejson import dumps
+from datetime import date, datetime
 
 from auf.django.permissions.decorators import get_object
 from django.contrib import messages
-from django.contrib.auth.decorators import login_required
+from django.contrib.auth.decorators import login_required, user_passes_test
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import MultipleObjectsReturned
 from django.core.paginator import Paginator, InvalidPage
 from django.db.models import Q
 from django.http import Http404, HttpResponse, HttpResponseGone
-from django.shortcuts import redirect, render_to_response, get_object_or_404
-from django.template import RequestContext
+from django.shortcuts import redirect, render, get_object_or_404
 from sendfile import sendfile
+from simplejson import dumps
 
 from project.dae import models as dae
 from project.dae.decorators import \
-        redirect_interdiction, dae_groupe_requis, \
+        dae_groupe_requis, \
         poste_dans_ma_region_ou_service, \
         dossier_dans_ma_region_ou_service, \
         vieux_dossier_dans_ma_region_ou_service, \
         employe_dans_ma_region_ou_service, \
         dossier_est_modifiable, \
         poste_est_modifiable, get_contrat
+from project.dae.forms import FinancementFormSet, FinancementFormSetInitial
+from project.dae.forms import PosteComparaisonFormSet, PosteComparaisonFormSetInitial
 from project.dae.forms import \
-        PosteWorkflowForm, PosteForm, FinancementForm, PostePieceForm, \
-        PosteComparaisonFormSet, DossierWorkflowForm, ChoosePosteForm, \
+        PosteWorkflowForm, PosteForm, PostePieceFormSet, \
+        DossierWorkflowForm, ChoosePosteForm, \
         EmployeForm, DossierForm, DossierPieceForm, \
         DossierComparaisonFormSet, RemunForm, ContratForm, DAENumeriseeForm, \
         label_poste_display, DAEFinaliseesSearchForm
@@ -35,9 +35,13 @@ from project.dae.mail import send_drh_finalisation_mail
 from project.dae.workflow import \
         DOSSIER_ETAT_FINALISE, DOSSIER_ETAT_REGION_FINALISATION, \
         DOSSIER_ETAT_DRH_FINALISATION, POSTE_ETAT_FINALISE
+from project.decorators import \
+        redirect_interdiction, drh_or_admin_required, in_drh_or_admin
 from project.rh import models as rh
 
 
+# Helpers
+
 def devises():
     liste = []
     for d in rh.Devise.objects.all():
@@ -55,7 +59,7 @@ def devises():
 
 @dae_groupe_requis
 def index(request):
-    return render_to_response('dae/index.html', {}, RequestContext(request))
+    return render(request, 'dae/index.html', {})
 
 
 ### POSTE
@@ -71,7 +75,6 @@ def poste_consulter(request, key):
             request.POST, instance=poste, request=request
         )
         if validationForm.is_valid():
-            validationForm.save()
             messages.add_message(
                 request, messages.SUCCESS, "La validation a été enregistrée."
             )
@@ -81,17 +84,16 @@ def poste_consulter(request, key):
 
     comparaisons_internes = \
             poste.dae_comparaisons_internes.ma_region_ou_service(request.user)
-    vars = {
+    return render(request, 'dae/poste_consulter.html', {
         'poste': poste,
         'validationForm': validationForm,
-        'comparaisons_internes': comparaisons_internes
-    }
+        'comparaisons_internes': comparaisons_internes,
+        'importer': in_drh_or_admin(request.user)
+    })
 
-    return render_to_response(
-        'dae/poste_consulter.html', vars, RequestContext(request)
-    )
 
 
+@drh_or_admin_required
 def poste_importer(request, id):
     poste_dae = get_object_or_404(dae.Poste, id=id)
     if request.method == 'POST':
@@ -101,9 +103,10 @@ def poste_importer(request, id):
         else:
             return redirect('poste_consulter', 'dae-' + id)
     else:
-        return render_to_response('dae/poste_importer.html', {
-            'poste': poste_dae
-        }, RequestContext(request))
+        c = {
+            'poste': poste_dae,
+        }
+        return render(request, 'dae/poste_importer.html', c)
 
 
 @dae_groupe_requis
@@ -116,43 +119,74 @@ def poste(request, key=None):
     il est automatiquement copié dans dae.
 
     """
+
+    def _dupliquer_poste(poste_dae, poste_rh):
+        """
+        Recopie les fields d'un poste RH dans un poste DAE
+        avec ceux-ci précédemment crées
+        """
+        exclus = ('id', 'supprime', 'date_creation',
+                'user_creation', 'date_modification',
+                'user_modification', )
+        fields = [f for f in poste_rh._meta.fields if f.name not in exclus]
+        for field in fields:
+            setattr(poste_dae, field.name, getattr(poste_rh, field.name))
+        return poste_dae
+
     poste, data, vars = None, dict(), dict()
 
-    if key:
-        # Poste existant
-        data['poste'] = key
+    # Sans key, c'est un nouveau poste
+    if key is None:
+        new = True
+    else:
+        new = False
+
+    # Type intervention
+    if 'type_intervention' in request.GET:
+        data['type_intervention'] = request.GET['type_intervention']
+
+    # Poste existant
+    poste_rh = None
+    if not new:
         source, id = key.split('-')
 
         if source == 'dae':
             poste = get_object_or_404(dae.Poste, pk=id)
+            data['poste'] = key
         elif source == 'rh':
-            p = get_object_or_404(rh.Poste, pk=id)
+            poste_rh = get_object_or_404(rh.Poste, pk=id)
+            poste = dae.Poste(id_rh=poste_rh)
             # Initialisation avec les valeurs du poste de rh_v1
-            poste = dae.Poste(id_rh=p, nom=p.type_poste.nom)
-            for field in ('implantation', 'type_poste', ):
-                setattr(poste, field, getattr(p, field))
+            poste = _dupliquer_poste(poste, poste_rh)
+            data['poste'] = 'rh-' + str(poste.id_rh_id)
+
+    # prépopuler pour la modification de poste
+    if poste_rh is not None:
+        FinancementForm = FinancementFormSetInitial
+        PosteComparaisonForm = PosteComparaisonFormSetInitial
+
+        qs_financements = poste_rh.rh_financements.all()
+        qs_comparaisons = poste_rh.rh_comparaisons_internes.all()
+        financements = [{'type': f.type, 'pourcentage': f.pourcentage,
+            'commentaire': f.commentaire} for f in qs_financements]
+        comparaisons = [{'implantation': c.implantation, 'nom': c.nom,
+            'montant': c.montant, 'devise': c.devise} for c in qs_comparaisons]
+    # formulaires normaux, avec modifications des objects FK
     else:
-        # Nouveau poste
-        vars['new'] = True
+        FinancementForm = FinancementFormSet
+        PosteComparaisonForm = PosteComparaisonFormSet
+        financements = []
+        comparaisons = []
+
 
     if request.POST:
         data.update(dict(request.POST.items()))
         form = PosteForm(data, instance=poste, request=request)
-        financementForm = FinancementForm(request.POST, instance=poste)
-        piecesForm = PostePieceForm(
-            request.POST, request.FILES, instance=poste
-        )
-        if isinstance(poste, dae.Poste):
-            comparaisons_formset = PosteComparaisonFormSet(
+        financementForm = FinancementForm(request.POST, instance=poste, )
+        piecesForm = PostePieceFormSet(request.POST, request.FILES, instance=poste, )
+        comparaisons_formset = PosteComparaisonForm(
                 request.POST,
-                queryset=poste.dae_comparaisons_internes.ma_region_ou_service(
-                    request.user
-                )
-            )
-        else:
-            comparaisons_formset = PosteComparaisonFormSet(
-                request.POST,
-                queryset=dae.PosteComparaison.objects.none()
+                instance=poste,
             )
         if form.is_valid() and piecesForm.is_valid() and \
            financementForm.is_valid() and comparaisons_formset.is_valid():
@@ -168,6 +202,11 @@ def poste(request, key=None):
                 comparaison.poste = poste
                 comparaison.save()
 
+            # dans le cas d'une modification de poste de RH, on recopie les PJ
+            if poste_rh is not None:
+                for piece in poste_rh.rh_pieces.all():
+                    dae.PostePiece(poste=poste, nom=piece.nom,
+                            fichier=piece.fichier).save()
             messages.add_message(
                 request, messages.SUCCESS,
                 "Le poste %s a été sauvegardé." % poste
@@ -187,26 +226,27 @@ def poste(request, key=None):
         # 'initial' évite la validation prémature lors d'une copie de poste de
         # rh_v1 vers dae.
         form = PosteForm(initial=data, instance=poste, request=request)
-        piecesForm = PostePieceForm(instance=poste)
-        financementForm = FinancementForm(instance=poste)
-        if isinstance(poste, dae.Poste):
-            comparaisons_formset = PosteComparaisonFormSet(
-                queryset=poste.dae_comparaisons_internes.ma_region_ou_service(
-                    request.user
-                )
+        piecesForm = PostePieceFormSet(instance=poste)
+
+        if poste_rh is not None:
+            financementForm = FinancementForm(initial=financements, instance=poste)
+            comparaisons_formset = PosteComparaisonForm(
+                initial=comparaisons,
+                instance=poste,
             )
+        # cas de la création d'un nouveau poste
         else:
-            comparaisons_formset = PosteComparaisonFormSet(
-                queryset=dae.PosteComparaison.objects.none()
-            )
+            financementForm = FinancementForm(instance=poste)
+            comparaisons_formset = PosteComparaisonForm(instance=poste)
 
     vars.update(dict(
         form=form, poste=poste, poste_key=key, piecesForm=piecesForm,
         financementForm=financementForm,
-        comparaisons_formset=comparaisons_formset
+        comparaisons_formset=comparaisons_formset,
+        poste_rh=poste_rh,
     ))
 
-    return render_to_response('dae/poste.html', vars, RequestContext(request))
+    return render(request, 'dae/poste.html', vars)
 
 
 @dae_groupe_requis
@@ -219,15 +259,15 @@ def postes_liste(request):
         content_type.id
     )}
     postes_a_traiter = dae.Poste.objects.mes_choses_a_faire(request.user) \
-            .extra(select=extra_select).order_by('-date_creation')
+            .extra(select=extra_select).order_by('-id')
     postes_en_cours = dae.Poste.objects.ma_region_ou_service(request.user) \
             .extra(select=extra_select) \
             .filter(~Q(etat=POSTE_ETAT_FINALISE)) \
-            .order_by('-date_creation')
-    return render_to_response('dae/postes_liste.html', {
+            .order_by('-id')
+    return render(request, 'dae/postes_liste.html', {
         'postes_a_traiter': postes_a_traiter,
         'postes_en_cours': postes_en_cours,
-    }, RequestContext(request))
+    })
 
 
 @login_required
@@ -277,18 +317,15 @@ def embauche_consulter(request, dossier_id):
                 request.user
             )
     comparaisons = dossier.dae_comparaisons.ma_region_ou_service(request.user)
-    vars = {
+    return render(request, 'dae/embauche_consulter.html', {
         'dossier': dossier,
         'validationForm': validationForm,
         'comparaisons_internes': comparaisons_internes,
-        'comparaisons': comparaisons
-    }
-
-    return render_to_response(
-        'dae/embauche_consulter.html', vars, RequestContext(request)
-    )
-
+        'comparaisons': comparaisons,
+        'importer': in_drh_or_admin(request.user)
+    })
 
+@user_passes_test(lambda u: u.is_superuser)
 @dae_groupe_requis
 @dossier_dans_ma_region_ou_service
 def embauche_importer(request, dossier_id=None):
@@ -300,16 +337,18 @@ def embauche_importer(request, dossier_id=None):
         else:
             return redirect('embauches_finalisees')
     else:
-        return render_to_response('dae/embauche_importer.html', {
-            'dossier': dossier_dae
-        }, RequestContext(request))
+        c = {
+            'dossier': dossier_dae,
+        }
+        return render(request, 'dae/embauche_importer.html', c)
 
 
 @dae_groupe_requis
 def embauche_choisir_poste(request):
-    return render_to_response('dae/embauche-choisir-poste.html', {
-        'form': ChoosePosteForm(request=request)
-    }, RequestContext(request))
+    c = {
+        'form': ChoosePosteForm(request=request),
+    }
+    return render(request, 'dae/embauche-choisir-poste.html', c)
 
 
 @dae_groupe_requis
@@ -432,8 +471,7 @@ def embauche(request, key=None, dossier_id=None):
                 )
     except dae.Poste.DoesNotExist:
         comparaisons_internes = []
-
-    return render_to_response('dae/embauche.html', {
+    c = {
         'type_remun': filtered_type_remun(),
         'devises': devises(),
         'poste': poste,
@@ -442,8 +480,9 @@ def embauche(request, key=None, dossier_id=None):
         'remunForm': remunForm,
         'comparaisons_formset': comparaisons_formset,
         'forms': dict(employe=employe_form, dossier=dossier_form, ),
-        'comparaisons_internes': comparaisons_internes
-    }, RequestContext(request))
+        'comparaisons_internes': comparaisons_internes,
+    }
+    return render(request, 'dae/embauche.html', c)
 
 
 @dae_groupe_requis
@@ -458,21 +497,37 @@ def embauches_liste(request):
     )}
     embauches_a_traiter = dae.Dossier.objects \
             .mes_choses_a_faire(request.user) \
-            .extra(select=extra_select).order_by('-date_creation')
+            .extra(select=extra_select).order_by('-id')
     embauches_en_cours = dae.Dossier.objects \
             .ma_region_ou_service(request.user) \
             .extra(select=extra_select) \
-            .order_by('-date_creation') \
+            .order_by('-id') \
             .exclude(etat=DOSSIER_ETAT_FINALISE)
-    return render_to_response('dae/embauches_liste.html', {
+    c = {
         'embauches_a_traiter': embauches_a_traiter,
         'embauches_en_cours': embauches_en_cours,
-    }, RequestContext(request))
+    }
+    return render(request, 'dae/embauches_liste.html', c)
 
 
 @dae_groupe_requis
 def embauches_finalisees(request):
     """Liste des embauches finalisées."""
+
+    ### POST
+
+    if request.method == 'POST':
+        if 'supprimer' in request.POST:
+            ids = request.POST.getlist('ids')
+            dossiers = dae.Dossier.objects.filter(id__in=ids)
+            count = dossiers.count()
+            if count > 0:
+                dossiers.delete()
+                messages.success(request, u'%d dossiers supprimés' % count)
+        return redirect(request.get_full_path())
+
+    ### GET
+
     embauches = dae.Dossier.objects.ma_region_ou_service(request.user) \
             .filter(etat=DOSSIER_ETAT_FINALISE)
 
@@ -527,10 +582,11 @@ def embauches_finalisees(request):
     except InvalidPage:
         page = paginator.page(1)
 
-    return render_to_response('dae/embauches_finalisees.html', {
+    return render(request, 'dae/embauches_finalisees.html', {
         'embauches': page,
-        'search_form': search_form
-    }, RequestContext(request))
+        'search_form': search_form,
+        'importer': in_drh_or_admin(request.user)
+    })
 
 
 def employe(request, key):
@@ -573,9 +629,10 @@ def contrat_supprimer(request, contrat):
         if 'oui' in request.POST:
             contrat.delete()
         return redirect('embauche_consulter', dossier_id=contrat.dossier.id)
-    return render_to_response('dae/contrat-supprimer.html', {
-        'contrat': contrat
-    }, RequestContext(request))
+    c = {
+        'contrat': contrat,
+    }
+    return render(request, 'dae/contrat-supprimer.html', c)
 
 
 @dae_groupe_requis
@@ -593,9 +650,11 @@ def embauche_ajouter_contrat(request, dossier_id=None):
             return redirect('embauche_consulter', dossier_id=dossier.id)
     else:
         form = ContratForm()
-    return render_to_response('dae/embauche-ajouter-contrat.html', {
-        'form': form
-    }, RequestContext(request))
+
+    c = {
+        'form': form,
+    }
+    return render(request, 'dae/embauche-ajouter-contrat.html', c)
 
 
 ### DAE NUMERISEE
@@ -614,9 +673,11 @@ def dae_numerisee_modifier(request, dossier):
             return redirect('embauche_consulter', dossier_id=dossier.id)
     else:
         form = DAENumeriseeForm(instance=dossier)
-    return render_to_response('dae/dae_numerisee_modifier.html', {
-        'form': form
-    }, RequestContext(request))
+
+    c = {
+        'form': form,
+    }
+    return render(request, 'dae/dae_numerisee_modifier.html', c)
 
 
 @get_object(dae.Dossier, 'modifier_dae_numerisee')
@@ -626,9 +687,7 @@ def dae_numerisee_supprimer(request, dossier):
             dossier.dae_numerisee = None
             dossier.save()
             return redirect('embauche_consulter', dossier_id=dossier.id)
-    return render_to_response(
-        'dae/dae_numerisee_supprimer.html', {}, RequestContext(request)
-    )
+    return render(request, 'dae/dae_numerisee_supprimer.html', {})
 
 
 # AJAX SECURISE
@@ -698,8 +757,7 @@ def dossier(request, poste_key, employe_key):
 
     dossier_form = DossierForm(initial=data, instance=dossier)
     vars = dict(form=dossier_form, poste=poste, employe=employe)
-    return render_to_response('dae/embauche-dossier.html', vars,
-                          RequestContext(request))
+    return render(request, 'dae/embauche-dossier.html', vars)
 
 
 #  Cette fonction est appelée à partir de fonctions déjà sécurisée
@@ -766,9 +824,7 @@ def dossier_resume(request, dossier_id=None):
     if dossier.statut is not None:
         data['statut'] = dossier.statut.id
     data['implantation'] = dossier.poste.implantation.id
-    data['poste'] = u"%s %s" % (
-        dossier.poste.type_poste.nom, dossier.poste.nom
-    )
+    data['poste'] = dossier.poste.nom
     salaire = dossier.get_salaire()
     if salaire is not None:
         data['montant'] = float(salaire.montant)
@@ -798,9 +854,7 @@ def poste_resume(request, dossier_id=None):
     salaire = dossier.get_salaire()
     data = {}
     data['implantation'] = dossier.poste.implantation.id
-    data['poste'] = u"%s %s" % (
-        dossier.poste.type_poste.nom, dossier.poste.nom
-    )
+    data['poste'] = dossier.poste.nom
     if salaire is not None:
         data['devise'] = salaire.devise.id
         data['montant'] = float(salaire.montant)
@@ -823,26 +877,20 @@ def liste_postes(request):
     params = getattr(request, method, [])
     data = []
 
-    # Voir le code de _poste_choices dans forms.py
-    copies = dae.Poste.objects.exclude(id_rh__isnull=True) \
-            .filter(etat=POSTE_ETAT_FINALISE)
-    rh_postes_actifs = rh.Poste.objects.all()
-
     if 'implantation_id' in params \
        and params.get('implantation_id') is not u"":
         implantation_id = params.get('implantation_id')
-        copies = copies.filter(implantation__id=implantation_id)
-        rh_postes_actifs = rh_postes_actifs.filter(
-            implantation__id=implantation_id
-        )
+        q = Q(implantation__id=implantation_id)
+    else:
+        q = Q()
 
-    id_copies = [p.id_rh_id for p in copies.all()]
-    rhv1 = rh_postes_actifs.exclude(id__in=id_copies)
-    rhv1 = rhv1.select_related(depth=1)
+    postes_rh = rh.Poste.objects.ma_region_ou_service(request.user).filter(q)
+    postes_rh = postes_rh.select_related(depth=1)
 
     data = [('', 'Nouveau poste')] + \
-            sorted([('rh-%s' % p.id, label_poste_display(p)) for p in rhv1],
-                   key=lambda t: t[1])
+           sorted([('rh-%s' % p.id, label_poste_display(p)) for p in
+               postes_rh],
+                  key=lambda t: t[1])
     return HttpResponse(dumps(data))
 
 
@@ -933,8 +981,10 @@ def add_remun(request, dossier, type_remun):
     dae.Remuneration(dossier=dossier, devise=dossier.devise,
                      type=type_remun).save()
 
-    return render_to_response('dae/embauche-remun.html', dict(dossier=dossier),
-                              RequestContext(request))
+    c = {
+        'dossier': dossier,
+    }
+    return render(request, 'dae/embauche-remun.html', c)
 
 
 def salaire(request, implantation, devise, classement):
@@ -954,6 +1004,8 @@ def salaire(request, implantation, devise, classement):
         raise Exception(u"Pas de taux pour la devise %s" % devise)
 
     classement = get_object_or_404(rh.Classement, pk=classement)
+    if classement.coefficient is None:
+        raise Http404
     taux, vp = taux[0].taux, vp[0].valeur
 
     salaire_euro = round(vp * classement.coefficient * taux, 2)
@@ -971,7 +1023,7 @@ def liste_valeurs_point(request):
     method = request.method
     params = getattr(request, method, [])
     data = []
-    annee_courante = datetime.datetime.now().year
+    annee_courante = datetime.now().year
     if 'implantation_id' in params \
        and params.get('implantation_id') is not u"":
         implantation_id = params.get('implantation_id')