From 111b565ceac5c6a8a6e2036fe551e79f60e322bf Mon Sep 17 00:00:00 2001 From: Ulysses Lara Date: Tue, 28 Jan 2020 16:04:36 -0300 Subject: [PATCH] 3078 corrigir problemas listagem parlamentares (#3079) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Corrigindo erros lista parlamentares Fix #3078 * Adaptando logica para que na legislatura atual não apresentar parlamentares desligados * Resolvendo problemas encomtrados no PR Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com> --- sapl/api/serializers.py | 77 ++++++++++++++--- sapl/api/views.py | 28 ++++++- sapl/parlamentares/views.py | 84 ------------------- .../parlamentares/parlamentares_list.html | 7 +- 4 files changed, 94 insertions(+), 102 deletions(-) diff --git a/sapl/api/serializers.py b/sapl/api/serializers.py index 143948f16..04e7016b4 100644 --- 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 CasaLegislativaSerializer(serializers.ModelSerializer): 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 index 92af46e00..f07710215 100644 --- a/sapl/api/views.py +++ b/sapl/api/views.py @@ -13,6 +13,8 @@ from django_filters.filters import CharFilter 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 @@ from sapl.protocoloadm.models import DocumentoAdministrativo,\ 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 @@ class _ParlamentarViewSet: """ 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 index 80994e66d..b176f056f 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -615,90 +615,6 @@ class ParlamentarCrud(Crud): 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" diff --git a/sapl/templates/parlamentares/parlamentares_list.html b/sapl/templates/parlamentares/parlamentares_list.html index 7a8aeb304..d28dbc471 100644 --- a/sapl/templates/parlamentares/parlamentares_list.html +++ b/sapl/templates/parlamentares/parlamentares_list.html @@ -50,9 +50,9 @@ Parlamentar - Parido + Partido Ativo? - Titlar? + Titular? @@ -71,8 +71,7 @@

Não

-

Sim

-

Não

+

[[ parlamentar.titular]]