Merge branch 'master' into dae_refactoring_process
authorOlivier Larchevêque <olivier.larcheveque@auf.org>
Thu, 15 Nov 2012 15:57:51 +0000 (10:57 -0500)
committerOlivier Larchevêque <olivier.larcheveque@auf.org>
Thu, 15 Nov 2012 15:57:51 +0000 (10:57 -0500)
1  2 
project/dae/forms.py
project/dae/models.py
project/dae/views.py

diff --combined project/dae/forms.py
@@@ -1,23 -1,20 +1,23 @@@
  # -*- encoding: utf-8 -*-
  
  from django import forms
 +from django.core.urlresolvers import reverse
  from django.forms.models import BaseInlineFormSet
 -from django.contrib.admin import widgets as admin_widgets
 -from django.db.models import Q, Max
  from django.forms.models import inlineformset_factory, modelformset_factory
 +from django.db.models import Q, Max, Count
 +from django.shortcuts import redirect
 +from django.contrib.admin import widgets as admin_widgets
  
  from ajax_select.fields import AutoCompleteSelectField
  
  from auf.django.references import models as ref
  from auf.django.workflow.forms import WorkflowFormMixin
 +from auf.django.workflow.models import WorkflowCommentaire
  
  from project import groups
  from project.rh import models as rh
  from project.dae import models as dae
 -from project.dae.workflow import POSTE_ETATS_BOUTONS
 +from project.dae.workflow import POSTE_ETATS_BOUTONS, POSTE_ETAT_FINALISE
  
  
  class BaseInlineFormSetWithInitial(BaseInlineFormSet):
  def _implantation_choices(obj, request):
      # TRAITEMENT NORMAL
      employe = groups.get_employe_from_user(request.user)
-     # SERVICE
-     if groups.is_user_dans_services_centraux(request.user):
-         q = Q(**{'id': employe.implantation_id})
-     # REGION
-     else:
-         q = Q(**{'region': employe.implantation.region})
+     q = Q(**{'zone_administrative': employe.implantation.zone_administrative})
  
      # TRAITEMENT DRH
      user_groupes = [g.name for g in request.user.groups.all()]
-     if groups.DRH_NIVEAU_1 in user_groupes:
+     if groups.DRH_NIVEAU_1 in user_groupes or \
+        groups.DRH_NIVEAU_2 in user_groupes:
          q = Q()
      return [('', '----------')] + \
              [(i.id, unicode(i), )for i in ref.Implantation.objects.filter(q)]
  def _employe_choices(obj, request):
      # TRAITEMENT NORMAL
      employe = groups.get_employe_from_user(request.user)
-     # SERVICE
-     if groups.is_user_dans_services_centraux(request.user):
-         q_dae_region_service = Q(poste__implantation=employe.implantation)
-         q_rh_region_service = Q(poste__implantation=employe.implantation)
-     # REGION
-     else:
-         q_dae_region_service = Q(
-             poste__implantation__region=employe.implantation.region
+     q_dae_region_service = Q(
+         poste__implantation__zone_administrative=(
+             employe.implantation.zone_administrative
          )
-         q_rh_region_service = Q(
-             poste__implantation__region=employe.implantation.region
+     )
+     q_rh_region_service = Q(
+         poste__implantation__zone_administrative=(
+             employe.implantation.zone_administrative
          )
+     )
      # TRAITEMENT DRH
      user_groupes = [g.name for g in request.user.groups.all()]
-     if groups.DRH_NIVEAU_1 in user_groupes:
+     if groups.DRH_NIVEAU_1 in user_groupes or \
+        groups.DRH_NIVEAU_2 in user_groupes:
          q_dae_region_service = Q()
          q_rh_region_service = Q()
  
      employes_avec_dae = [d.employe_id for d in dae.Dossier.objects.all()]
      employes_orphelins = dae.Employe.objects.exclude(id__in=employes_avec_dae)
  
-     def option_label(employe):
-         return "%s %s" % (employe.nom.upper(), employe.prenom.title())
+     def option_label(employe, extra=""):
+         if extra:
+             extra = " [%s]" % extra
+         return "%s %s %s" % (employe.nom.upper(), employe.prenom.title(), extra)
  
-     return [('', 'Nouvel employé')] + \
-            sorted(
-                [('dae-%s' % p.id, option_label(p))
-                 for p in dae_ | copies | employes_orphelins] +
-                [('rh-%s' % p.id, option_label(p)) for p in rhv1],
-                key=lambda t: t[1]
-            )
+     lbl_rh = sorted([('rh-%s' % p.id, option_label(p, "existant dans rh")) for p in rhv1],
+             key=lambda t: t[1])
+     lbl_dae = sorted([('dae-%s' % p.id, option_label(p)) for p in dae_ | copies | employes_orphelins],
+             key=lambda t: t[1])
+     return [('', 'Nouvel employé')] + lbl_rh + lbl_dae
  
  
  def label_poste_display(poste):
          annee = poste.date_debut.year
  
      nom = poste.nom
 -    
 -    try:
 -        label = u"%s %s - %s [%s]" % (
 -            annee, nom, poste.type_poste.categorie_emploi.nom, poste.id
 +    label = u"%s (%s) %s - %s [%s]" % (
 +        annee,
 +        poste.implantation.nom_court,
 +        nom,
 +        poste.type_poste.categorie_emploi.nom,
 +        poste.id,
          )
 -    except:
 -        label = unicode(poste)
      return label
  
  
@@@ -389,57 -381,29 +384,57 @@@ class PosteForm(forms.ModelForm)
          return cleaned_data
  
  
 -class ChoosePosteForm(forms.ModelForm):
 +class ChoosePosteForm(forms.Form):
      class Meta:
          fields = ('poste',)
  
      # La liste des choix est laissée vide. Voir PosteForm.__init__.
 -    poste = forms.ChoiceField(choices=(), required=False)
 +    postes_dae = forms.ChoiceField(choices=(), required=False)
 +    postes_rh = forms.ChoiceField(choices=(), required=False)
  
      def __init__(self, request=None, *args, **kwargs):
          super(ChoosePosteForm, self).__init__(*args, **kwargs)
 -        self.fields['poste'].choices = self._poste_choices(request)
 +        self.fields['postes_dae'].choices = self._poste_dae_choices(request)
 +        self.fields['postes_rh'].choices = self._poste_rh_choices(request)
  
 -    def _poste_choices(self, request):
 -        """ Menu déroulant pour les postes. """
 -        dae_ = dae.Poste.objects.ma_region_ou_service(request.user) \
 -                .filter(id_rh__isnull=True)
 -        copies = dae.Poste.objects.ma_region_ou_service(request.user) \
 -                .exclude(id_rh__isnull=True)
 +    def _poste_dae_choices(self, request):
 +        """ Menu déroulant pour les postes."""
 +        postes_dae = dae.Poste.objects.ma_region_ou_service(request.user) \
 +                .exclude(etat__in=(POSTE_ETAT_FINALISE, )) \
 +                .annotate(num_dae=Count('dae_dossiers')) \
 +                .filter(num_dae=0) \
 +                .order_by('-date_debut')
  
          return [('', '----------')] + \
 -               sorted([('dae-%s' % p.id, unicode(p)) for p in dae_ | copies],
 -                      key=lambda t: t[1])
 +               [('dae-%s' % p.id, label_poste_display(p)) for p in postes_dae]
  
 +    def _poste_rh_choices(self, request):
 +        """ Menu déroulant pour les postes."""
 +        postes_dae = dae.Poste.objects.exclude(etat__in=(POSTE_ETAT_FINALISE, ))
 +        id_poste_dae_commences = [p.id_rh_id for p in postes_dae if p.id_rh is not None]
 +        postes_rh = rh.Poste.objects.ma_region_ou_service(request.user) \
 +                .exclude(id__in=id_poste_dae_commences) \
 +                .order_by('-date_debut')
 +
 +        return [('', '----------')] + \
 +               [('rh-%s' % p.id, label_poste_display(p)) for p in postes_rh]
 +
 +    def clean(self):
 +        cleaned_data = super(ChoosePosteForm, self).clean()
 +        postes_dae = cleaned_data.get("postes_dae")
 +        postes_rh = cleaned_data.get("postes_rh")
 +        if (postes_dae is u"" and postes_rh is u"") or \
 +           (postes_dae is not u"" and postes_rh is not u""):
 +                raise forms.ValidationError("Choisissez un poste DAE ou un poste RH")
 +        return cleaned_data
 +
 +    def redirect(self):
 +        poste_dae_key = self.cleaned_data.get("postes_dae")
 +        if poste_dae_key is not u"":
 +            return redirect(reverse('embauche', args=(poste_dae_key,)))
 +        poste_rh_key = self.cleaned_data.get("postes_rh")
 +        if poste_rh_key is not u"":
 +            return redirect("%s?creer_dossier_dae" % reverse('poste', args=(poste_rh_key,)))
  
  class EmployeForm(forms.ModelForm):
      """ Formulaire des employés. """
@@@ -497,24 -461,9 +492,24 @@@ class DossierWorkflowForm(WorkflowFormM
      def save(self):
          super(DossierWorkflowForm, self).save()
          poste = self.instance.poste
 -        if poste.etat == self._etat_initial:
 -            poste.etat = self.instance.etat
 -            poste.save()
 +
 +        # créer le commentaire automatique pour le poste associé
 +        commentaire = WorkflowCommentaire()
 +        commentaire.content_object = poste
 +        texte = u"Validation automatique à travers le dossier [%s] de %s\n%s" %(
 +                self.instance.id,
 +                self.instance,
 +                self.data.get('commentaire', ''),
 +                )
 +        commentaire.texte = texte
 +        commentaire.etat_initial = self.instance._etat_courant
 +        commentaire.etat_final = self.instance.etat
 +        commentaire.owner = self.request.user
 +        commentaire.save()
 +
 +        # force l'état du poste
 +        poste.etat = self.instance.etat
 +        poste.save()
  
  
  class ContratForm(forms.ModelForm):
diff --combined project/dae/models.py
@@@ -657,7 -657,6 +657,6 @@@ class Dossier(DossierWorkflow, rh.Dossi
          dossier_rh.regime_travail_nb_heure_semaine = \
                  self.regime_travail_nb_heure_semaine
          dossier_rh.date_debut = self.contrat_date_debut
-         dossier_rh.date_fin = self.contrat_date_fin
          dossier_rh.save()
  
          rh.DossierComparaison.objects.filter(dossier=dossier_rh).delete()
              dae_numerisee_rh = dossier_rh.rh_dossierpieces.create(
                  nom=u'DAE numérisée'
              )
 -            dae_numerisee_rh.fichier.save(
 -                os.path.basename(self.dae_numerisee.name),
 -                self.dae_numerisee
 -            )
 +            if not settings.DEBUG:
 +                dae_numerisee_rh.fichier.save(
 +                    os.path.basename(self.dae_numerisee.name),
 +                    self.dae_numerisee
 +                )
  
          # Fermer les rémunérations qui commencent avant le début du contrat
          dossier_rh.rh_remunerations.filter(
diff --combined project/dae/views.py
@@@ -8,7 -8,7 +8,7 @@@ from django.contrib.auth.decorators imp
  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.db.models import Q, Count
  from django.http import Http404, HttpResponse, HttpResponseGone
  from django.shortcuts import redirect, render, get_object_or_404
  from sendfile import sendfile
@@@ -35,9 -35,12 +35,12 @@@ from project.dae.mail import send_drh_f
  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.decorators import redirect_interdiction,\
+         drh_or_admin_required,\
+         in_drh_or_admin,\
+         in_one_of_group
  from project.rh import models as rh
+ from project import groups
  
  
  # Helpers
@@@ -75,6 -78,7 +78,7 @@@ 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."
              )
          'poste': poste,
          'validationForm': validationForm,
          'comparaisons_internes': comparaisons_internes,
-         'importer': in_drh_or_admin(request.user)
+         'importer': request.user.is_superuser,
      })
  
  
  
+ @user_passes_test(lambda u: u.is_superuser)
  @drh_or_admin_required
  def poste_importer(request, id):
      poste_dae = get_object_or_404(dae.Poste, id=id)
  @dae_groupe_requis
  @poste_dans_ma_region_ou_service
  @poste_est_modifiable
+ @in_one_of_group((groups.CORRESPONDANT_RH,
+     groups.ADMINISTRATEURS,
+     groups.DIRECTEUR_DE_BUREAU,
+     groups.DRH_NIVEAU_1,
+     groups.DRH_NIVEAU_2))
  def poste(request, key=None):
      """ Formulaire pour un poste.
  
      il est automatiquement copié dans dae.
  
      """
 +    if 'creer_dossier_dae' in request.GET:
 +        creer_dossier_dae = True
 +    else:
 +        creer_dossier_dae = False
  
      def _dupliquer_poste(poste_dae, poste_rh):
          """
                  request, messages.SUCCESS,
                  "Le poste %s a été sauvegardé." % poste
              )
 +            if creer_dossier_dae:
 +                return redirect('embauche', key='dae-%s' % poste.id)
 +
              if 'save' in request.POST:
                  return redirect('poste_consulter', key='dae-%s' % poste.id)
              else:
          financementForm=financementForm,
          comparaisons_formset=comparaisons_formset,
          poste_rh=poste_rh,
 +        creer_dossier_dae=creer_dossier_dae,
      ))
  
      return render(request, 'dae/poste.html', vars)
@@@ -267,12 -269,8 +277,12 @@@ def postes_liste(request)
          content_type.id
      )}
      postes_a_traiter = dae.Poste.objects.mes_choses_a_faire(request.user) \
 +            .annotate(num_dae=Count('dae_dossiers')) \
 +            .filter(num_dae=0) \
              .extra(select=extra_select).order_by('-id')
      postes_en_cours = dae.Poste.objects.ma_region_ou_service(request.user) \
 +            .annotate(num_dae=Count('dae_dossiers')) \
 +            .filter(num_dae=0) \
              .extra(select=extra_select) \
              .filter(~Q(etat=POSTE_ETAT_FINALISE)) \
              .order_by('-id')
@@@ -334,7 -332,7 +344,7 @@@ def embauche_consulter(request, dossier
          'validationForm': validationForm,
          'comparaisons_internes': comparaisons_internes,
          'comparaisons': comparaisons,
-         'importer': in_drh_or_admin(request.user)
+         'importer': request.user.is_superuser,
      })
  
  @user_passes_test(lambda u: u.is_superuser)
@@@ -357,14 -355,8 +367,14 @@@ def embauche_importer(request, dossier_
  
  @dae_groupe_requis
  def embauche_choisir_poste(request):
 +    if request.POST:
 +        form = ChoosePosteForm(data=request.POST, request=request)
 +        if form.is_valid():
 +            return form.redirect()
 +    else:
 +        form = ChoosePosteForm(request=request)
      c = {
 -        'form': ChoosePosteForm(request=request),
 +        'form': form,
      }
      return render(request, 'dae/embauche-choisir-poste.html', c)
  
@@@ -556,8 -548,8 +566,8 @@@ def embauches_finalisees(request)
          importees = search_form.cleaned_data.get('importees')
          if q:
              criteria = [
-                 Q(poste__implantation__region__nom__icontains=word) |
-                 Q(poste__implantation__region__code=word) |
+                 Q(poste__implantation__zone_administrative__nom__icontains=word) |
+                 Q(poste__implantation__zone_administrative__code=word) |
                  Q(poste__implantation__nom__icontains=word) |
                  Q(poste__nom__icontains=word) |
                  Q(employe__nom__icontains=word) |
          dir = ''
      if tri == 'region':
          embauches = embauches.order_by(
-             dir + 'poste__implantation__region__nom'
+             dir + 'poste__implantation__zone_administrative__nom'
          )
      elif tri == 'implantation':
          embauches = embauches.order_by(dir + 'poste__implantation__nom')
@@@ -1028,11 -1020,13 +1038,13 @@@ def salaire(request, implantation, devi
              .order_by('-annee')
  
      if vp.count() == 0:
-         raise Exception(u"pas de valeur de point pour le couple\
-                 implantation/devise (%s/%s)" % (implantation, devise))
+         status = u"pas de valeur de point pour le couple \
+ implantation/devise (%s/%s)" % (implantation, devise)
+         return HttpResponse(dumps(dict(status=status)))
  
      if taux.count() == 0:
-         raise Exception(u"Pas de taux pour la devise %s" % devise)
+         status = u"Pas de taux pour la devise %s" % devise
+         return HttpResponse(dumps(dict(status=status)))
  
      classement = get_object_or_404(rh.Classement, pk=classement)
      if classement.coefficient is None:
      taux, vp = taux[0].taux, vp[0].valeur
  
      salaire_euro = round(vp * classement.coefficient * taux, 2)
-     data = dict(salaire_euro=salaire_euro, taux=taux,
+     data = dict(status='OK',
+                 salaire_euro=salaire_euro, taux=taux,
                  salaire_devise=round(salaire_euro / taux, 2))
  
      return HttpResponse(dumps(data))