Merge branch 'reversion'
authorOlivier Larchevêque <olivier.larcheveque@auf.org>
Thu, 5 Jul 2012 18:27:48 +0000 (14:27 -0400)
committerOlivier Larchevêque <olivier.larcheveque@auf.org>
Thu, 5 Jul 2012 18:27:48 +0000 (14:27 -0400)
1  2 
project/dae/forms.py
project/dae/views.py
project/dae/workflow.py

diff --combined project/dae/forms.py
@@@ -3,7 -3,6 +3,7 @@@
  import datetime
  
  from django import forms
 +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
@@@ -18,71 -17,8 +18,71 @@@ from project.groups import 
          get_employe_from_user, is_user_dans_services_centraux
  
  from project.dae import models as dae
 -from project.dae.workflow import \
 -        grp_drh, POSTE_ETATS_BOUTONS, POSTE_ETAT_FINALISE
 +from project.dae.workflow import grp_drh, POSTE_ETATS_BOUTONS
 +
 +
 +class BaseInlineFormSetWithInitial(BaseInlineFormSet):
 +    """
 +    Cette classe permet de fournir l'option initial aux inlineformsets.
 +    Elle devient désuette en django 1.4.
 +    """
 +    def __init__(self, data=None, files=None, instance=None,
 +                 save_as_new=False, prefix=None, queryset=None, **kwargs):
 +
 +        self.initial_extra = kwargs.pop('initial', None)
 +
 +        from django.db.models.fields.related import RelatedObject
 +        if instance is None:
 +            self.instance = self.fk.rel.to()
 +        else:
 +            self.instance = instance
 +        self.save_as_new = save_as_new
 +        # is there a better way to get the object descriptor?
 +        self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
 +        if queryset is None:
 +            queryset = self.model._default_manager
 +        qs = queryset.filter(**{self.fk.name: self.instance})
 +        super(BaseInlineFormSetWithInitial, self).__init__(data, files, prefix=prefix,
 +                                                queryset=qs, **kwargs)
 +
 +    def _construct_form(self, i, **kwargs):
 +        if self.is_bound and i < self.initial_form_count():
 +            # Import goes here instead of module-level because importing
 +            # django.db has side effects.
 +            from django.db import connections
 +            pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name)
 +            pk = self.data[pk_key]
 +            pk_field = self.model._meta.pk
 +            pk = pk_field.get_db_prep_lookup('exact', pk,
 +                connection=connections[self.get_queryset().db])
 +            if isinstance(pk, list):
 +                pk = pk[0]
 +            kwargs['instance'] = self._existing_object(pk)
 +        if i < self.initial_form_count() and not kwargs.get('instance'):
 +            kwargs['instance'] = self.get_queryset()[i]
 +        if i >= self.initial_form_count() and self.initial_extra:
 +            # Set initial values for extra forms
 +            try:
 +                kwargs['initial'] = self.initial_extra[i-self.initial_form_count()]
 +            except IndexError:
 +                pass
 +
 +        defaults = {'auto_id': self.auto_id, 'prefix': self.add_prefix(i)}
 +        if self.is_bound:
 +            defaults['data'] = self.data
 +            defaults['files'] = self.files
 +        if self.initial:
 +            try:
 +                defaults['initial'] = self.initial[i]
 +            except IndexError:
 +                pass
 +        # Allow extra forms to be empty.
 +        if i >= self.initial_form_count():
 +            defaults['empty_permitted'] = True
 +        defaults.update(kwargs)
 +        form = self.form(**defaults)
 +        self.add_fields(form, i)
 +        return form
  
  
  def _implantation_choices(obj, request):
@@@ -177,30 -113,16 +177,30 @@@ def label_poste_display(poste)
      annee = ""
      if poste.date_debut:
          annee = poste.date_debut.year
 +
 +    nom = poste.nom
 +    
      label = u"%s %s - %s [%s]" % (
 -        annee, poste.type_poste, poste.type_poste.categorie_emploi.nom,
 -        poste.id
 +        annee, nom, poste.type_poste.categorie_emploi.nom, poste.id
      )
      return label
  
 -PostePieceForm = inlineformset_factory(dae.Poste, dae.PostePiece)
 +
 +PostePieceFormSet = inlineformset_factory(dae.Poste, dae.PostePiece,)
  DossierPieceForm = inlineformset_factory(dae.Dossier, dae.DossierPiece)
 -FinancementForm = inlineformset_factory(
 -    dae.Poste, dae.PosteFinancement, extra=2
 +
 +# Ce formset est utilisé dans le cas de la création de poste prépopulé avec les
 +# données de RH
 +FinancementFormSetInitial = inlineformset_factory(
 +    dae.Poste,
 +    dae.PosteFinancement,
 +    formset=BaseInlineFormSetWithInitial,
 +    extra=2
 +)
 +FinancementFormSet = inlineformset_factory(
 +    dae.Poste,
 +    dae.PosteFinancement,
 +    extra=2
  )
  
  
@@@ -228,22 -150,8 +228,22 @@@ class PosteComparaisonForm(forms.ModelF
          model = dae.PosteComparaison
          exclude = ('poste',)
  
 -PosteComparaisonFormSet = modelformset_factory(
 -    dae.PosteComparaison, extra=3, max_num=3, form=PosteComparaisonForm
 +# Ce formset est utilisé dans le cas de la création de poste prépopulé avec les
 +# données de RH
 +PosteComparaisonFormSetInitial = inlineformset_factory(
 +    dae.Poste,
 +    dae.PosteComparaison,
 +    extra=3,
 +    max_num=3,
 +    form=PosteComparaisonForm,
 +    formset=BaseInlineFormSetWithInitial,
 +)
 +PosteComparaisonFormSet = inlineformset_factory(
 +    dae.Poste,
 +    dae.PosteComparaison,
 +    extra=3,
 +    max_num=3,
 +    form=PosteComparaisonForm,
  )
  
  
@@@ -346,7 -254,6 +346,7 @@@ class PosteForm(forms.ModelForm)
          request = kwargs.pop('request')
          super(PosteForm, self).__init__(*args, **kwargs)
          self.fields['poste'].choices = self._poste_choices(request)
 +        
          self.fields['implantation'].choices = \
                  _implantation_choices(self, request)
  
  
      def _poste_choices(self, request):
          """ Menu déroulant pour les postes.
 -
 -        Constitué des postes de dae et des postes de rh_v1 qui n'ont pas
 -        d'équivalent dans dae.
 -
 +        Constitué des postes de RH
          """
 -        copies = dae.Poste.objects \
 -                .ma_region_ou_service(request.user) \
 -                .exclude(id_rh__isnull=True) \
 -                .filter(etat=POSTE_ETAT_FINALISE)
 -        id_copies = [p.id_rh_id for p in copies.all()]
 -        rhv1 = rh.Poste.objects.ma_region_ou_service(request.user) \
 -                .exclude(id__in=id_copies)
 -        # Optimisation de la requête
 -        rhv1 = rhv1.select_related(depth=1)
 +        postes_rh = rh.Poste.objects.ma_region_ou_service(request.user).all()
 +        postes_rh = postes_rh.select_related(depth=1)
  
          return [('', 'Nouveau poste')] + \
 -               sorted([('rh-%s' % p.id, label_poste_display(p)) for p in rhv1],
 +               sorted([('rh-%s' % p.id, label_poste_display(p)) for p in
 +                   postes_rh],
                        key=lambda t: t[1])
  
      def clean(self):
  
          return cleaned_data
  
-     def save(self, *args, **kwargs):
-         kwargs2 = kwargs.copy()
-         kwargs2['commit'] = False
-         poste = super(PosteForm, self).save(*args, **kwargs2)
-         # id_rh
-         if 'commit' not in kwargs or kwargs['commit']:
-             if poste.id is None:
-                 poste.date_creation = datetime.datetime.now()
-             poste.save()
-         return poste
  
  class ChoosePosteForm(forms.ModelForm):
      class Meta:
@@@ -446,13 -351,6 +435,6 @@@ class DossierForm(forms.ModelForm)
                         contrat_date_fin=admin_widgets.AdminDateWidget(),
                      )
  
-     def save(self, *args, **kwargs):
-         dossier = super(DossierForm, self).save(*args, **kwargs)
-         if dossier.id is None:
-             dossier.date_creation = datetime.datetime.now()
-         dossier.save()
-         return dossier
  WF_HELP_TEXT = ""
  
  
diff --combined project/dae/views.py
@@@ -1,9 -1,8 +1,8 @@@
  # -*- 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.contenttypes.models import ContentType
@@@ -12,10 -11,8 +11,8 @@@ from django.core.paginator import Pagin
  from django.db.models import Q
  from django.http import Http404, HttpResponse, HttpResponseGone
  from django.shortcuts import redirect, render, get_object_or_404
  from sendfile import sendfile
- from auf.django.permissions.decorators import get_object
+ from simplejson import dumps
  
  from project.dae import models as dae
  from project.dae.decorators import \
          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
@@@ -42,6 -37,8 +39,8 @@@ from project.decorators import redirect
  from project.rh import models as rh
  
  
+ # Helpers
  def devises():
      liste = []
      for d in rh.Devise.objects.all():
@@@ -75,7 -72,6 +74,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."
              )
@@@ -119,70 -115,46 +117,70 @@@ 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
 +    # Sans key, c'est un nouveau poste
 +    if key is None:
 +        new = True
 +    else:
 +        new = False
 +
 +    # 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))
 -        if poste.id_rh_id:
 -            data['poste'] = 'rh-' + str(poste.id_rh_id)
 -        else:
 -            data['poste'] = key
 +            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():
                  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
          # '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(request, 'dae/poste.html', vars)
@@@ -255,16 -221,15 +253,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')
-     c = {
+             .order_by('-id')
+     return render(request, 'dae/postes_liste.html', {
          'postes_a_traiter': postes_a_traiter,
          'postes_en_cours': postes_en_cours,
-     }
-     return render(request, 'dae/postes_liste.html', c)
+     })
  
  
  @login_required
@@@ -494,11 -459,11 +491,11 @@@ 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)
      c = {
          'embauches_a_traiter': embauches_a_traiter,
@@@ -878,20 -843,26 +875,20 @@@ def liste_postes(request)
      params = getattr(request, method, [])
      data = []
  
      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))
  
  
@@@ -1024,7 -995,7 +1021,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')
diff --combined project/dae/workflow.py
@@@ -9,6 -9,18 +9,18 @@@ from project.groups import 
  from project.groups import \
          is_user_dans_services_centraux, is_user_dans_region
  
+ dae_groupes = (
+     grp_correspondants_rh,
+     grp_administrateurs,
+     grp_directeurs_bureau,
+     grp_drh,
+     grp_drh2,
+     grp_accior,
+     grp_abf,
+     grp_haute_direction,
+     grp_service_utilisateurs,
+ )
  # codes états
  POSTE_ETAT_BROUILLON = 'BROUILLON'
  POSTE_ETAT_ADMINISTRATEUR = 'ADMINISTRATEUR'
@@@ -123,14 -135,14 +135,14 @@@ POSTE_ACTIONS = 
          'etat_initial': (POSTE_ETAT_DEMANDE_MODIF,),
          'etat_final': POSTE_ETAT_DRH_CONTROLE,
      },
 -    POSTE_ACTION_ENVOYER_ACCIOR: {
 -        'nom': u'Envoyer',
 -        'etat_initial': (POSTE_ETAT_DRH_2,),
 -        'etat_final': POSTE_ETAT_ACCIOR,
 -    },
 +    #POSTE_ACTION_ENVOYER_ACCIOR: {
 +    #    'nom': u'Envoyer',
 +    #    'etat_initial': (POSTE_ETAT_DRH_2,),
 +    #    'etat_final': POSTE_ETAT_ACCIOR,
 +    #},
      POSTE_ACTION_ENVOYER_ABF: {
          'nom': u'Envoyer',
 -        'etat_initial': (POSTE_ETAT_ACCIOR,),
 +        'etat_initial': (POSTE_ETAT_ACCIOR, POSTE_ETAT_DRH_2),
          'etat_final': POSTE_ETAT_ABF,
      },
      POSTE_ACTION_ENVOYER_HAUTE_DIRECTION: {