Repository: interlegis/sapl

Issue:
Propagar tramitações para matérias anexadas da matéria anexada
<!--- Forneça um resumo geral da _issue_ no título acima -->

## Comportamento Esperado
<!--- Se você está descrevendo um _bug_, conte-nos o que deveria acontecer. -->
<!--- Se você está sugerindo uma mudança/melhoria, conte-nos como deve funcionar. -->
Copiar uma nova tramitação de uma matéria para as suas matérias anexadas (direta ou indiretamente) que não possuam tramitação ou sua última tramitação possua o destino igual ao local dessa nova tramitação.

## Comportamento Atual
<!--- Se está descrevendo um bug, conte-nos o que acontece em vez do comportamento esperado. -->
<!--- Se está sugerindo uma mudança/melhoria, explique a diferença com o comportamento atual. -->
Não são consideradas, as matérias anexadas indiretamente (matérias anexadas das anexadas).





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
@@ -549,17 +549,39 @@ def clean(self):
     def save(self, commit=True):
         tramitacao = super(TramitacaoForm, self).save(commit)
         materia = tramitacao.materia
-        for ma in materia.anexadas.all():
-            if not ma.tramitacao_set.all() \
-                    or ma.tramitacao_set.last().unidade_tramitacao_destino == tramitacao.unidade_tramitacao_local:
+        
+        materia.em_tramitacao = False if tramitacao.status.indicador == "F" else True
+        materia.save()
+
+        anexadas = lista_anexadas(materia)
+        for anexada in anexadas:
+            if not anexada.tramitacao_set.all() \
+                    or anexada.tramitacao_set.last().unidade_tramitacao_destino == tramitacao.unidade_tramitacao_local:
                 tramitacao_nova = tramitacao
                 tramitacao_nova.pk = None
-                tramitacao_nova.materia = ma
+                tramitacao_nova.materia = anexada
                 tramitacao_nova.save()
 
+                anexada.em_tramitacao = False if tramitacao.status.indicador == "F" else True
+                anexada.save()        
+
         return tramitacao
 
 
+def lista_anexadas(materia_principal):
+    materias_anexadas = []
+    anexadas_principal = Anexada.objects.filter(materia_principal=materia_principal)
+    while anexadas_principal:
+        anexadas = []
+        for anexada in anexadas_principal:
+            materias_anexadas.append(anexada.materia_anexada)
+            anexadas_anexada = Anexada.objects.filter(materia_principal=anexada.materia_anexada)
+            anexadas.extend(anexadas_anexada)
+        anexadas_principal = anexadas
+    
+    return materias_anexadas
+
+
 class TramitacaoUpdateForm(TramitacaoForm):
     unidade_tramitacao_local = forms.ModelChoiceField(
         queryset=UnidadeTramitacao.objects.all(),
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -47,7 +47,8 @@
                                 ConfirmarProposicaoForm,
                                 DevolverProposicaoForm, LegislacaoCitadaForm,
                                 OrgaoForm, ProposicaoForm, TipoProposicaoForm,
-                                TramitacaoForm, TramitacaoUpdateForm, MateriaPesquisaSimplesForm)
+                                TramitacaoForm, TramitacaoUpdateForm, MateriaPesquisaSimplesForm,
+                                lista_anexadas)
 from sapl.norma.models import LegislacaoCitada
 from sapl.parlamentares.models import Legislatura
 from sapl.protocoloadm.models import Protocolo
@@ -1221,12 +1222,6 @@ def form_valid(self, form):
             self.object = form.save()
             username = self.request.user.username
 
-            if form.instance.status.indicador == 'F':
-                form.instance.materia.em_tramitacao = False
-            else:
-                form.instance.materia.em_tramitacao = True
-            form.instance.materia.save()
-
             try:
                 self.logger.debug("user=" + username + ". Tentando enviar Tramitacao (sender={}, post={}, request={})."
                                   .format(Tramitacao, self.object, self.request))
@@ -1255,12 +1250,6 @@ def form_valid(self, form):
             self.object = form.save()
             username = self.request.user.username
 
-            if form.instance.status.indicador == 'F':
-                form.instance.materia.em_tramitacao = False
-            else:
-                form.instance.materia.em_tramitacao = True
-            form.instance.materia.save()
-
             try:
                 self.logger.debug("user=" + username + ". Tentando enviar Tramitacao (sender={}, post={}, request={}"
                                   .format(Tramitacao, self.object, self.request))
@@ -1586,6 +1575,20 @@ class UpdateView(Crud.UpdateView):
 
         form_class = MateriaLegislativaForm
 
+        def form_valid(self, form):
+            self.object = form.save()
+            username = self.request.user.username
+
+            if Anexada.objects.filter(materia_principal=self.kwargs['pk']).exists():
+                materia = MateriaLegislativa.objects.get(pk=self.kwargs['pk'])
+                anexadas = lista_anexadas(materia)
+
+                for anexada in anexadas:
+                    anexada.em_tramitacao = True if form.instance.em_tramitacao else False 
+                    anexada.save()
+    
+            return super().form_valid(form)
+
         @property
         def cancel_url(self):
             return self.search_url


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
@@ -14,12 +14,68 @@
                                  StatusTramitacao, TipoDocumento,
                                  TipoMateriaLegislativa, TipoProposicao,
                                  Tramitacao, UnidadeTramitacao)
+from sapl.materia.forms import lista_anexadas
 from sapl.norma.models import (LegislacaoCitada, NormaJuridica,
                                TipoNormaJuridica)
 from sapl.parlamentares.models import Legislatura
 from sapl.utils import models_with_gr_for_model
 
 
+@pytest.mark.django_db(transaction=False)
+def test_lista_anexadas():
+        tipo_materia = mommy.make(
+                TipoMateriaLegislativa,
+                descricao="Tipo_Teste"
+        )
+        regime_tramitacao = mommy.make(
+                RegimeTramitacao,
+                descricao="Regime_Teste"
+        )
+        materia_principal = mommy.make(
+                MateriaLegislativa,
+                numero=20,
+                ano=2018,
+                data_apresentacao="2018-01-04",
+                regime_tramitacao=regime_tramitacao,
+                tipo=tipo_materia
+        )
+        materia_anexada = mommy.make(
+                MateriaLegislativa,
+                numero=21,
+                ano=2019,
+                data_apresentacao="2019-05-04",
+                regime_tramitacao=regime_tramitacao,
+                tipo=tipo_materia
+        )
+        materia_anexada_anexada = mommy.make(
+                MateriaLegislativa,
+                numero=22,
+                ano=2020,
+                data_apresentacao="2020-01-05",
+                regime_tramitacao=regime_tramitacao,
+                tipo=tipo_materia
+        )
+
+        mommy.make(
+                Anexada,
+                materia_principal=materia_principal,
+                materia_anexada=materia_anexada,
+                data_anexacao="2019-05-11"
+        )
+        mommy.make(
+                Anexada,
+                materia_principal=materia_anexada,
+                materia_anexada=materia_anexada_anexada,
+                data_anexacao="2020-11-05"
+        )
+
+        lista = lista_anexadas(materia_principal)
+        
+        assert len(lista) == 2
+        assert lista[0] == materia_anexada
+        assert lista[1] == materia_anexada_anexada
+
+
 @pytest.mark.django_db(transaction=False)
 def make_unidade_tramitacao(descricao):
     # Cria uma comissão para ser a unidade de tramitação