Repository: interlegis/sapl

Issue:
Melhorar o controle de tramitação de matérias
Utilizar a mesma lógica da tramitação de **Documento Administrativo** para garantir as seguintes **regras**:
- A origem da nova tramitação é igual ao destino da última
- A data de tramitação deve ser menor ou igual a data de hoje
- A data de encaminhamento deve ser maior ou igual a data de tramitação
- A data do fim do prazo deve ser maior ou igual a data de tramitação



Discussion:

Resolving patch:
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -216,22 +216,91 @@ class Meta:
                   'texto']
 
     def clean(self):
+
+        if 'data_encaminhamento' in self.data:
+            data_enc_form = self.cleaned_data['data_encaminhamento']
+        if 'data_fim_prazo' in self.data:
+            data_prazo_form = self.cleaned_data['data_fim_prazo']
+        if 'data_tramitacao' in self.data:
+            data_tram_form = self.cleaned_data['data_tramitacao']
+
         if self.errors:
             return self.errors
 
         ultima_tramitacao = Tramitacao.objects.filter(
-            materia_id=self.instance.materia.id).last()
+            materia_id=self.instance.materia_id).exclude(
+            id=self.instance.id).last()
+
+        if not self.instance.data_tramitacao:
+
+            if ultima_tramitacao:
+                destino = ultima_tramitacao.unidade_tramitacao_destino
+                if (destino != self.cleaned_data['unidade_tramitacao_local']):
+                    msg = _('A origem da nova tramitação deve ser igual ao '
+                            'destino  da última adicionada!')
+                    raise ValidationError(msg)
+
+            if self.cleaned_data['data_tramitacao'] > datetime.now().date():
+                msg = _(
+                    'A data de tramitação deve ser ' +
+                    'menor ou igual a data de hoje!')
+                raise ValidationError(msg)
+
+            if (ultima_tramitacao and
+               data_tram_form < ultima_tramitacao.data_tramitacao):
+                msg = _('A data da nova tramitação deve ser ' +
+                        'maior que a data da última tramitação!')
+                raise ValidationError(msg)
+
+        if data_enc_form:
+            if data_enc_form < data_tram_form:
+                msg = _('A data de encaminhamento deve ser ' +
+                        'maior que a data de tramitação!')
+                raise ValidationError(msg)
 
-        if ultima_tramitacao:
-            destino = ultima_tramitacao.unidade_tramitacao_destino
-            if (destino != self.cleaned_data['unidade_tramitacao_local']):
-                msg = _('A origem da nova tramitação deve ser igual ao '
-                        'destino  da última adicionada!')
+        if data_prazo_form:
+            if data_prazo_form < data_tram_form:
+                msg = _('A data fim de prazo deve ser ' +
+                        'maior que a data de tramitação!')
                 raise ValidationError(msg)
 
         return self.cleaned_data
 
 
+class TramitacaoUpdateForm(TramitacaoForm):
+    unidade_tramitacao_local = forms.ModelChoiceField(
+        queryset=UnidadeTramitacao.objects.all(),
+        widget=forms.HiddenInput())
+
+    data_tramitacao = forms.DateField(widget=forms.HiddenInput())
+
+    class Meta:
+        model = Tramitacao
+        fields = ['data_tramitacao',
+                  'unidade_tramitacao_local',
+                  'status',
+                  'turno',
+                  'urgente',
+                  'unidade_tramitacao_destino',
+                  'data_encaminhamento',
+                  'data_fim_prazo',
+                  'texto',
+                  ]
+
+        widgets = {
+            'data_encaminhamento': forms.DateInput(format='%d/%m/%Y'),
+            'data_fim_prazo': forms.DateInput(format='%d/%m/%Y'),
+        }
+
+    def clean(self):
+        local = self.instance.unidade_tramitacao_local
+        data_tram = self.instance.data_tramitacao
+
+        self.cleaned_data['data_tramitacao'] = data_tram
+        self.cleaned_data['unidade_tramitacao_local'] = local
+        return super(TramitacaoUpdateForm, self).clean()
+
+
 class LegislacaoCitadaForm(ModelForm):
 
     tipo = forms.ModelChoiceField(
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -38,7 +38,8 @@
                     DocumentoAcessorioForm, LegislacaoCitadaForm,
                     MateriaLegislativaFilterSet, NumeracaoForm, ProposicaoForm,
                     ReceberProposicaoForm, RelatoriaForm, TramitacaoForm,
-                    UnidadeTramitacaoForm, filtra_tramitacao_destino,
+                    TramitacaoUpdateForm, UnidadeTramitacaoForm,
+                    filtra_tramitacao_destino,
                     filtra_tramitacao_destino_and_status,
                     filtra_tramitacao_status)
 from .models import (AcompanhamentoMateria, Anexada, Autor, Autoria,
@@ -573,14 +574,19 @@ def post(self, request, *args, **kwargs):
             return super(CreateView, self).post(request, *args, **kwargs)
 
     class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
-        form_class = TramitacaoForm
+        form_class = TramitacaoUpdateForm
         permission_required = permissoes_materia()
 
         def post(self, request, *args, **kwargs):
-            materia = MateriaLegislativa.objects.get(id=kwargs['pk'])
+            materia = MateriaLegislativa.objects.get(
+                tramitacao__id=kwargs['pk'])
             do_envia_email_tramitacao(request, materia)
             return super(UpdateView, self).post(request, *args, **kwargs)
 
+        @property
+        def layout_key(self):
+            return 'TramitacaoUpdate'
+
     class ListView(MasterDetailCrud.ListView):
 
         def get_queryset(self):
@@ -598,7 +604,7 @@ def delete(self, request, *args, **kwargs):
                           kwargs={'pk': tramitacao.materia.id})
 
             if tramitacao.pk != materia.tramitacao_set.last().pk:
-                msg = _('Somente a útlima tramitação pode ser deletada!')
+                msg = _('Somente a última tramitação pode ser deletada!')
                 messages.add_message(request, messages.ERROR, msg)
                 return HttpResponseRedirect(url)
             else:


Test patch:
diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py
--- a/sapl/materia/tests/test_materia.py
+++ b/sapl/materia/tests/test_materia.py
@@ -276,6 +276,8 @@ def test_tramitacao_submit(admin_client):
          'urgente': True,
          'status': status_tramitacao.pk,
          'data_tramitacao': '2016-03-21',
+         'data_fim_prazo': '2016-03-22',
+         'data_encaminhamento': '2016-03-22',
          'texto': 'Texto_Teste',
          'salvar': 'salvar'},
         follow=True)
diff --git a/sapl/protocoloadm/tests/test_protocoloadm.py b/sapl/protocoloadm/tests/test_protocoloadm.py
--- a/sapl/protocoloadm/tests/test_protocoloadm.py
+++ b/sapl/protocoloadm/tests/test_protocoloadm.py
@@ -1,4 +1,5 @@
 import datetime
+
 import pytest
 from django.core.urlresolvers import reverse
 from django.utils.translation import ugettext_lazy as _