Repository: interlegis/sapl

Issue:
Corrigir problemas relacionados a listagem de parlamentares  
<!--- Forneça um resumo geral da _issue_ no título acima -->
Corrigir problemas relacionados a listagem de parlamentares. Ao passar a tela de parlamentares para vuejs pode ter gerados bugs no modo que são pegos os campos de mandato e filiação.

## 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. -->

## 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. -->

## Possível Solução
<!--- Não é obrigatório, mas sugira uma possível correção/razão para o bug -->
<!--- ou ideias de como implementar a adição/mudança. -->

## Passos para Reproduzir (para bugs)
<!--- Forneça um link para um exemplo, ou um conjunto de passos inequívocos -->
<!--- para reproduzir esse bug. Inclua código para reproduzir, se relevante. -->
1.
2.
3.
4.

## Contexto
<!--- Como esse problema o afeta? O que você está tentando realizar? -->
<!--- Fornecer o contexto nos ajuda a encontrar uma solução que seja mais útil no mundo real -->

## Imagens do Ocorrido
<!--- Representação visual em vídeo ou imagem do ocorrido -->
<!--- Se está descrevendo um bug poste imagens ou vídeos na reprodução do bug citado, caso se aplique -->

## Seu Ambiente
<!--- Inclua detalhes relevantes sobre o ambiente em que você presenciou/experienciou o bug. -->
* Versão usada (_Release_):
* Nome e versão do navegador:
* Nome e versão do Sistema Operacional (desktop ou mobile):
* Link para o seu projeto (Caso de fork deste projeto):



Discussion:

Resolving patch:
diff --git a/sapl/api/serializers.py b/sapl/api/serializers.py
--- a/sapl/api/serializers.py
+++ b/sapl/api/serializers.py
@@ -1,10 +1,14 @@
+import logging
 from django.conf import settings
+from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
+from django.db.models import F, Q
 from rest_framework import serializers
 from rest_framework.relations import StringRelatedField
 from sapl.parlamentares.models import Parlamentar, Mandato, Filiacao, Legislatura
 from sapl.base.models import Autor, CasaLegislativa
 from sapl.utils import filiacao_data
 
+
 class IntRelatedField(StringRelatedField):
     def to_representation(self, value):
         return int(value)
@@ -60,24 +64,77 @@ class Meta:
 class ParlamentarResumeSerializer(serializers.ModelSerializer):
     titular = serializers.SerializerMethodField('check_titular')
     partido = serializers.SerializerMethodField('check_partido')
+    logger = logging.getLogger(__name__)
+
 
     def check_titular(self,obj):
         is_titular = None
-        if Legislatura.objects.exists():
-            legislatura = self.context.get('legislatura')
-            if not legislatura:
-                legislatura = Legislatura.objects.first()
-            mandato = Mandato.objects.filter(legislatura=legislatura,parlamentar=obj).first()
-            is_titular = mandato.titular if mandato else False
+        if not Legislatura.objects.exists():
+            self.logger.error("Não há legislaturas cadastradas.")
+            return ""
+        
+        try:
+            legislatura = Legislatura.objects.get(id=self.context.get('legislatura'))
+        except ObjectDoesNotExist:
+            legislatura = Legislatura.objects.first()
+        mandato = Mandato.objects.filter(
+            parlamentar=obj,
+            data_inicio_mandato__gte=legislatura.data_inicio,
+            data_fim_mandato__lte=legislatura.data_fim
+        ).order_by('-data_inicio_mandato').first()
+        if mandato:
+            is_titular = 'Sim' if mandato.titular else 'Não'
+        else:
+            is_titular = '-'        
         return is_titular
 
     def check_partido(self,obj):
-        legislatura_id = self.context.get('legislatura')
-        if not legislatura_id:
+        # Coloca a filiação atual ao invés da última
+        # As condições para mostrar a filiação são:
+        # A data de filiacao deve ser menor que a data de fim
+        # da legislatura e data de desfiliação deve nula, ou maior,
+        # ou igual a data de fim da legislatura
+        
+        username =  self.context['request'].user.username
+        if not Legislatura.objects.exists():
+            self.logger.error("Não há legislaturas cadastradas.")
+            return ""
+        try:
+            legislatura = Legislatura.objects.get(id=self.context.get('legislatura'))
+        except ObjectDoesNotExist:
             legislatura = Legislatura.objects.first()
+    
+        try:
+            self.logger.debug("user=" + username + ". Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) "
+                              "ou (data<={} e data_desfiliacao=Null))."
+                              .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim))
+            filiacao = obj.filiacao_set.get(Q(
+                data__lte=legislatura.data_fim,
+                data_desfiliacao__gte=legislatura.data_fim) | Q(
+                data__lte=legislatura.data_fim,
+                data_desfiliacao__isnull=True))
+
+        # Caso não exista filiação com essas condições
+        except ObjectDoesNotExist:
+            self.logger.error("user=" + username + ". Parlamentar com (data<={} e data_desfiliacao>={}) "
+                              "ou (data<={} e data_desfiliacao=Null)) não possui filiação."
+                              .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim))
+            filiacao = 'Não possui filiação'
+
+        # Caso exista mais de uma filiação nesse intervalo
+        # Entretanto, NÃO DEVE OCORRER
+        except MultipleObjectsReturned:
+            self.logger.error("user=" + username + ". O Parlamentar com (data<={} e data_desfiliacao>={}) "
+                              "ou (data<={} e data_desfiliacao=Null)) possui duas filiações conflitantes"
+                              .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim))
+            filiacao = 'O Parlamentar possui duas filiações conflitantes'
+
+        # Caso encontre UMA filiação nessas condições
         else:
-            legislatura = Legislatura.objects.get(id=legislatura_id)
-        filiacao = filiacao_data(obj, legislatura.data_inicio, legislatura.data_fim)
+            self.logger.debug("user=" + username +
+                              ". Filiação encontrada com sucesso.")
+            filiacao = filiacao.partido.sigla
+        
         return filiacao
 
     class Meta:
diff --git a/sapl/api/views.py b/sapl/api/views.py
--- a/sapl/api/views.py
+++ b/sapl/api/views.py
@@ -13,6 +13,8 @@
 from django_filters.rest_framework.backends import DjangoFilterBackend
 from django_filters.rest_framework.filterset import FilterSet
 from django_filters.utils import resolve_field
+from django.utils import timezone
+from django.core.exceptions import ObjectDoesNotExist
 from rest_framework import serializers as rest_serializers
 from rest_framework.decorators import action
 from rest_framework.fields import SerializerMethodField
@@ -31,7 +33,7 @@
     DocumentoAcessorioAdministrativo, TramitacaoAdministrativo, Anexado
 from sapl.sessao.models import SessaoPlenaria, ExpedienteSessao
 from sapl.utils import models_with_gr_for_model, choice_anos_com_sessaoplenaria
-from sapl.parlamentares.models import Mandato, Parlamentar
+from sapl.parlamentares.models import Mandato, Parlamentar, Legislatura
 
 
 class BusinessRulesNotImplementedMixin:
@@ -350,15 +352,33 @@ def parlamentares_by_legislatura(self,request,*args,**kwargs):
         """
         Pega lista de parlamentares pelo id da legislatura.
         """
-        parlamentares = Parlamentar.objects.filter(mandato__legislatura=kwargs['pk'])
-        serializer_class = ParlamentarResumeSerializer(parlamentares,many=True,context={'legislatura':kwargs['pk']})
+        try:
+            legislatura = Legislatura.objects.get(pk=kwargs['pk'])
+        except ObjectDoesNotExist:
+            return Response("") 
+        data_atual = timezone.now().date()
+
+        filter_params = {
+            'legislatura':legislatura,
+            'data_inicio_mandato__gte':legislatura.data_inicio,
+            'data_fim_mandato__gte':legislatura.data_fim,
+        }
+
+        if legislatura.data_inicio < data_atual < legislatura.data_fim:
+            filter_params['data_fim_mandato__gte'] = data_atual
+
+        mandatos = Mandato.objects.filter(**filter_params).order_by('-data_inicio_mandato')  
+        parlamentares = Parlamentar.objects.filter(mandato__in=mandatos).distinct()
+        serializer_class = ParlamentarResumeSerializer(parlamentares,
+                                                        many=True,
+                                                        context={'request':request,'legislatura':kwargs['pk']})
         return Response(serializer_class.data)
 
     @action(detail=False,methods=['GET'])
     def search_parlamentares(self,request,*args,**kwargs):
         nome = request.query_params.get('nome_parlamentar','')
         parlamentares = Parlamentar.objects.filter(nome_parlamentar__icontains=nome)
-        serializer_class= ParlamentarResumeSerializer(parlamentares,many=True)
+        serializer_class= ParlamentarResumeSerializer(parlamentares,many=True,context={'request':request})
         return Response(serializer_class.data)
 
 
diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py
--- a/sapl/parlamentares/views.py
+++ b/sapl/parlamentares/views.py
@@ -615,90 +615,6 @@ def get_headers(self):
             return [_('Parlamentar'), _('Partido'),
                     _('Ativo?'), _('Titular?')]
 
-        def get_context_data(self, **kwargs):
-            context = super().get_context_data(**kwargs)
-            username = self.request.user.username
-
-            # Adiciona legislatura para filtrar parlamentares
-            legislaturas = Legislatura.objects.all().order_by('-numero')
-            context['legislaturas'] = legislaturas
-            context['legislatura_id'] = self.take_legislatura_id()
-
-            # Pega a Legislatura
-            try:
-                legislatura = Legislatura.objects.get(id=context['legislatura_id'])
-            except ObjectDoesNotExist:
-                self.logger.error("user={}. Não há nenhuma legislação cadastrada.".format(username))
-                return context
-
-            for row in context['rows']:
-
-                # Pega o Parlamentar por meio da pk
-                parlamentar = Parlamentar.objects.get(
-                    id=(row[0][1].split('/')[-1]))
-
-                # Conserta a issue do github https://github.com/interlegis/sapl/issues/3028
-                # Inicialmente a titularidade era conseguida através do código
-                # queryset.filter(mandato__legislatura_id=legislatura_id).annotate(
-                #                 mandato_titular=F('mandato__titular')).distinct()
-                # em get_queryset(), MAS não funciona se o parlamentar tem vários
-                # mandatos na mesma legislatura, sendo ao menos um titular e outro não,
-                # pois isso gera entradas repetidas. Este código corrige essa situação.
-                mandato = Mandato.objects.filter(
-                    parlamentar=parlamentar,
-                    data_inicio_mandato__gte=legislatura.data_inicio,
-                    data_fim_mandato__lte=legislatura.data_fim
-                ).order_by('-data_inicio_mandato').first()
-
-                if mandato:
-                    titular = 'Sim' if mandato.titular else 'Não'
-                    row.append((titular, None))
-                else:
-                    row.append(('-', None))
-
-                for index, value in enumerate(row):
-                    row[index] += (None if index else parlamentar,)
-
-                # Coloca a filiação atual ao invés da última
-                # As condições para mostrar a filiação são:
-                # A data de filiacao deve ser menor que a data de fim
-                # da legislatura e data de desfiliação deve nula, ou maior,
-                # ou igual a data de fim da legislatura
-                try:
-                    self.logger.debug("user=" + username + ". Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) "
-                                      "ou (data<={} e data_desfiliacao=Null))."
-                                      .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim))
-                    filiacao = parlamentar.filiacao_set.get(Q(
-                        data__lte=legislatura.data_fim,
-                        data_desfiliacao__gte=legislatura.data_fim) | Q(
-                        data__lte=legislatura.data_fim,
-                        data_desfiliacao__isnull=True))
-
-                # Caso não exista filiação com essas condições
-                except ObjectDoesNotExist:
-                    self.logger.error("user=" + username + ". Parlamentar com (data<={} e data_desfiliacao>={}) "
-                                      "ou (data<={} e data_desfiliacao=Null)) não possui filiação."
-                                      .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim))
-                    row[1] = ('Não possui filiação', None, None)
-
-                # Caso exista mais de uma filiação nesse intervalo
-                # Entretanto, NÃO DEVE OCORRER
-                except MultipleObjectsReturned:
-                    self.logger.error("user=" + username + ". O Parlamentar com (data<={} e data_desfiliacao>={}) "
-                                      "ou (data<={} e data_desfiliacao=Null)) possui duas filiações conflitantes"
-                                      .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim))
-                    row[1] = (
-                        'O Parlamentar possui duas filiações conflitantes',
-                        None, None)
-
-                # Caso encontre UMA filiação nessas condições
-                else:
-                    self.logger.debug("user=" + username +
-                                      ". Filiação encontrada com sucesso.")
-                    row[1] = (filiacao.partido.sigla, None, None)
-
-            return context
-
 
 class ParlamentarMateriasView(FormView):
     template_name = "parlamentares/materias.html"


Test patch: