diff --git a/sapl/api/deprecated.py b/sapl/api/deprecated.py index e13d612f6..af1e3241b 100644 --- a/sapl/api/deprecated.py +++ b/sapl/api/deprecated.py @@ -137,124 +137,6 @@ class AutorSearchForFieldFilterSet(AutorChoiceFilterSet): return queryset.filter(**params).distinct('nome').order_by('nome') -class AutoresPossiveisFilterSet(FilterSet): - logger = logging.getLogger(__name__) - data_relativa = DateFilter(method='filter_data_relativa') - tipo = CharFilter(method='filter_tipo') - - class Meta: - model = Autor - fields = ['data_relativa', 'tipo', ] - - def filter_data_relativa(self, queryset, name, value): - return queryset - - def filter_tipo(self, queryset, name, value): - - try: - self.logger.debug( - "Tentando obter TipoAutor correspondente à pk {}.".format(value)) - tipo = TipoAutor.objects.get(pk=value) - except: - self.logger.error("TipoAutor(pk={}) inexistente.".format(value)) - raise serializers.ValidationError(_('Tipo de Autor inexistente.')) - - qs = queryset.filter(tipo=tipo) - - return qs - - @property - def qs(self): - qs = super().qs - - data_relativa = self.form.cleaned_data['data_relativa'] \ - if 'data_relativa' in self.form.cleaned_data else None - - tipo = self.form.cleaned_data['tipo'] \ - if 'tipo' in self.form.cleaned_data else None - - if not tipo: - return qs - - tipo = TipoAutor.objects.get(pk=tipo) - if not tipo.content_type: - return qs - - filter_for_model = 'filter_%s' % tipo.content_type.model - - if not hasattr(self, filter_for_model): - return qs - - if not data_relativa: - data_relativa = timezone.now() - - return getattr(self, filter_for_model)(qs, data_relativa).distinct() - - def filter_parlamentar(self, queryset, data_relativa): - # não leva em conta afastamentos - legislatura_relativa = Legislatura.objects.filter( - data_inicio__lte=data_relativa, - data_fim__gte=data_relativa).first() - - q = Q( - parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, - parlamentar_set__mandato__data_fim_mandato__isnull=True) | Q( - parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, - parlamentar_set__mandato__data_fim_mandato__gte=data_relativa) - - if legislatura_relativa.atual(): - q = q & Q(parlamentar_set__ativo=True) - - legislatura_anterior = self.request.GET.get( - 'legislatura_anterior', 'False') - if legislatura_anterior.lower() == 'true': - legislaturas = Legislatura.objects.filter( - data_fim__lte=data_relativa).order_by('-data_fim')[:2] - if len(legislaturas) == 2: - _, leg_anterior = legislaturas - q = q | Q( - parlamentar_set__mandato__data_inicio_mandato__gte=leg_anterior.data_inicio) - - qs = queryset.filter(q) - return qs - - def filter_comissao(self, queryset, data_relativa): - return queryset.filter( - Q(comissao_set__data_extincao__isnull=True, - comissao_set__data_fim_comissao__isnull=True) | - Q(comissao_set__data_extincao__gte=data_relativa, - comissao_set__data_fim_comissao__isnull=True) | - Q(comissao_set__data_extincao__gte=data_relativa, - comissao_set__data_fim_comissao__isnull=True) | - Q(comissao_set__data_extincao__isnull=True, - comissao_set__data_fim_comissao__gte=data_relativa) | - Q(comissao_set__data_extincao__gte=data_relativa, - comissao_set__data_fim_comissao__gte=data_relativa), - comissao_set__data_criacao__lte=data_relativa) - - def filter_frente(self, queryset, data_relativa): - return queryset.filter( - Q(frente_set__data_extincao__isnull=True) | - Q(frente_set__data_extincao__gte=data_relativa), - frente_set__data_criacao__lte=data_relativa) - - def filter_bancada(self, queryset, data_relativa): - return queryset.filter( - Q(bancada_set__data_extincao__isnull=True) | - Q(bancada_set__data_extincao__gte=data_relativa), - bancada_set__data_criacao__lte=data_relativa) - - def filter_bloco(self, queryset, data_relativa): - return queryset.filter( - Q(bloco_set__data_extincao__isnull=True) | - Q(bloco_set__data_extincao__gte=data_relativa), - bloco_set__data_criacao__lte=data_relativa) - - def filter_orgao(self, queryset, data_relativa): - # na implementação, não havia regras a implementar para orgao - return queryset - - class AutorChoiceSerializer(ModelChoiceSerializer): def get_text(self, obj): @@ -475,23 +357,6 @@ class AutoresProvaveisListView(ListAPIView): return r -class AutoresPossiveisListView(ListAPIView): - """ - Deprecated - - TODO Migrar para customização na api automática - """ - - permission_classes = (IsAuthenticatedOrReadOnly,) - queryset = Autor.objects.all() - model = Autor - - pagination_class = None - - filter_class = AutoresPossiveisFilterSet - serializer_class = AutorChoiceSerializer - - class SessaoPlenariaViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): diff --git a/sapl/api/forms.py b/sapl/api/forms.py index ab8e9984f..150898e4d 100644 --- a/sapl/api/forms.py +++ b/sapl/api/forms.py @@ -1,5 +1,135 @@ +import logging + +from django.db.models import Q +from django.utils import timezone +from django.utils.translation import ugettext_lazy as _ +from django_filters.filters import CharFilter, DateFilter +from django_filters.filterset import FilterSet +from rest_framework import serializers + from drfautoapi.drfautoapi import ApiFilterSetMixin +from sapl.base.models import TipoAutor, Autor +from sapl.parlamentares.models import Legislatura + +logger = logging.getLogger(__name__) class SaplFilterSetMixin(ApiFilterSetMixin): pass + + +class AutoresPossiveisFilterSet(SaplFilterSetMixin): + data_relativa = DateFilter(method='filter_data_relativa') + tipo = CharFilter(method='filter_tipo') + + class Meta: + model = Autor + fields = ['data_relativa', 'tipo', ] + + def filter_data_relativa(self, queryset, name, value): + return queryset + + def filter_tipo(self, queryset, name, value): + + try: + logger.debug( + "Tentando obter TipoAutor correspondente à pk {}.".format(value)) + tipo = TipoAutor.objects.get(pk=value) + except: + logger.error("TipoAutor(pk={}) inexistente.".format(value)) + raise serializers.ValidationError(_('Tipo de Autor inexistente.')) + + qs = queryset.filter(tipo=tipo) + + return qs + + @property + def qs(self): + qs = super().qs + + data_relativa = self.form.cleaned_data['data_relativa'] \ + if 'data_relativa' in self.form.cleaned_data else None + + tipo = self.form.cleaned_data['tipo'] \ + if 'tipo' in self.form.cleaned_data else None + + if not tipo: + return qs + + tipo = TipoAutor.objects.get(pk=tipo) + if not tipo.content_type: + return qs + + filter_for_model = 'filter_%s' % tipo.content_type.model + + if not hasattr(self, filter_for_model): + return qs + + if not data_relativa: + data_relativa = timezone.now() + + return getattr(self, filter_for_model)(qs, data_relativa).distinct() + + def filter_parlamentar(self, queryset, data_relativa): + # não leva em conta afastamentos + legislatura_relativa = Legislatura.objects.filter( + data_inicio__lte=data_relativa, + data_fim__gte=data_relativa).first() + + q = Q( + parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, + parlamentar_set__mandato__data_fim_mandato__isnull=True) | Q( + parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, + parlamentar_set__mandato__data_fim_mandato__gte=data_relativa) + + if legislatura_relativa.atual(): + q = q & Q(parlamentar_set__ativo=True) + + legislatura_anterior = self.request.GET.get( + 'legislatura_anterior', 'False') + if legislatura_anterior.lower() == 'true': + legislaturas = Legislatura.objects.filter( + data_fim__lte=data_relativa).order_by('-data_fim')[:2] + if len(legislaturas) == 2: + _, leg_anterior = legislaturas + q = q | Q( + parlamentar_set__mandato__data_inicio_mandato__gte=leg_anterior.data_inicio) + + qs = queryset.filter(q) + return qs + + def filter_comissao(self, queryset, data_relativa): + return queryset.filter( + Q(comissao_set__data_extincao__isnull=True, + comissao_set__data_fim_comissao__isnull=True) | + Q(comissao_set__data_extincao__gte=data_relativa, + comissao_set__data_fim_comissao__isnull=True) | + Q(comissao_set__data_extincao__gte=data_relativa, + comissao_set__data_fim_comissao__isnull=True) | + Q(comissao_set__data_extincao__isnull=True, + comissao_set__data_fim_comissao__gte=data_relativa) | + Q(comissao_set__data_extincao__gte=data_relativa, + comissao_set__data_fim_comissao__gte=data_relativa), + comissao_set__data_criacao__lte=data_relativa) + + def filter_frente(self, queryset, data_relativa): + return queryset.filter( + Q(frente_set__data_extincao__isnull=True) | + Q(frente_set__data_extincao__gte=data_relativa), + frente_set__data_criacao__lte=data_relativa) + + def filter_bancada(self, queryset, data_relativa): + return queryset.filter( + Q(bancada_set__data_extincao__isnull=True) | + Q(bancada_set__data_extincao__gte=data_relativa), + bancada_set__data_criacao__lte=data_relativa) + + def filter_bloco(self, queryset, data_relativa): + return queryset.filter( + Q(bloco_set__data_extincao__isnull=True) | + Q(bloco_set__data_extincao__gte=data_relativa), + bloco_set__data_criacao__lte=data_relativa) + + def filter_orgao(self, queryset, data_relativa): + # na implementação, não havia regras a implementar para orgao + return queryset diff --git a/sapl/api/urls.py b/sapl/api/urls.py index 3032f1707..7db8a1112 100644 --- a/sapl/api/urls.py +++ b/sapl/api/urls.py @@ -5,7 +5,7 @@ from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, \ from rest_framework.authtoken.views import obtain_auth_token from sapl.api.deprecated import SessaoPlenariaViewSet, \ - AutoresProvaveisListView, AutoresPossiveisListView, AutorListView + AutoresProvaveisListView, AutorListView from sapl.api.views import AppVersionView, recria_token,\ SaplApiViewSetConstrutor @@ -39,8 +39,6 @@ urlpatterns_api_doc = [ deprecated_urlpatterns_api = [ url(r'^autor/provaveis', AutoresProvaveisListView.as_view(), name='autores_provaveis_list'), - url(r'^autor/possiveis', - AutoresPossiveisListView.as_view(), name='autores_possiveis_list'), url(r'^autor', AutorListView.as_view(), name='autor_list'), ] diff --git a/sapl/api/views_base.py b/sapl/api/views_base.py index 8d08de92a..7fb21684d 100644 --- a/sapl/api/views_base.py +++ b/sapl/api/views_base.py @@ -4,11 +4,12 @@ from rest_framework.decorators import action from rest_framework.response import Response from drfautoapi.drfautoapi import ApiViewSetConstrutor, customize +from sapl.api.forms import AutoresPossiveisFilterSet from sapl.base.models import Autor from sapl.utils import models_with_gr_for_model -BaseApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('contenttypes'), apps.get_app_config('base') @@ -87,3 +88,8 @@ class _AutorViewSet: setattr(cls, _model._meta.model_name, func) return cls + + @action(detail=False) + def possiveis(self, request, *args, **kwargs): + self.filterset_class = AutoresPossiveisFilterSet + return self.list(request, *args, **kwargs) diff --git a/sapl/api/views_comissoes.py b/sapl/api/views_comissoes.py index 76a9b7baa..2126e93e9 100644 --- a/sapl/api/views_comissoes.py +++ b/sapl/api/views_comissoes.py @@ -5,7 +5,7 @@ from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ customize, wrapper_queryset_response_for_drf_action -ComissoesApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('comissoes') ] diff --git a/sapl/api/views_compilacao.py b/sapl/api/views_compilacao.py index 96225c357..341c0a959 100644 --- a/sapl/api/views_compilacao.py +++ b/sapl/api/views_compilacao.py @@ -5,7 +5,7 @@ from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ customize, wrapper_queryset_response_for_drf_action -CompilacaoApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('compilacao') ] diff --git a/sapl/api/views_materia.py b/sapl/api/views_materia.py index 47ef3a3ca..8c5515d88 100644 --- a/sapl/api/views_materia.py +++ b/sapl/api/views_materia.py @@ -11,7 +11,7 @@ from sapl.materia.models import TipoMateriaLegislativa, Tramitacao,\ MateriaLegislativa, Proposicao -MateriaApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('materia') ] diff --git a/sapl/api/views_norma.py b/sapl/api/views_norma.py index 5810a85aa..1b962f38d 100644 --- a/sapl/api/views_norma.py +++ b/sapl/api/views_norma.py @@ -7,7 +7,7 @@ from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ from sapl.norma.models import NormaJuridica -NormaApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('norma') ] diff --git a/sapl/api/views_painel.py b/sapl/api/views_painel.py index d2c78937b..66f918658 100644 --- a/sapl/api/views_painel.py +++ b/sapl/api/views_painel.py @@ -4,7 +4,7 @@ from django.apps.registry import apps from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ customize, wrapper_queryset_response_for_drf_action -PainelApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('painel') ] diff --git a/sapl/api/views_parlamentares.py b/sapl/api/views_parlamentares.py index e8db3a245..e8888160d 100644 --- a/sapl/api/views_parlamentares.py +++ b/sapl/api/views_parlamentares.py @@ -15,7 +15,7 @@ from sapl.materia.models import Proposicao from sapl.parlamentares.models import Mandato, Legislatura from sapl.parlamentares.models import Parlamentar -ParlamentaresApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('parlamentares') ] diff --git a/sapl/api/views_protocoloadm.py b/sapl/api/views_protocoloadm.py index ac33cabab..5ebe77ec1 100644 --- a/sapl/api/views_protocoloadm.py +++ b/sapl/api/views_protocoloadm.py @@ -9,7 +9,7 @@ from sapl.protocoloadm.models import DocumentoAdministrativo, \ DocumentoAcessorioAdministrativo, TramitacaoAdministrativo, Anexado -ProtocoloAdmApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('protocoloadm') ] diff --git a/sapl/api/views_sessao.py b/sapl/api/views_sessao.py index 44d157773..75807f8cd 100644 --- a/sapl/api/views_sessao.py +++ b/sapl/api/views_sessao.py @@ -11,7 +11,7 @@ from sapl.sessao.models import SessaoPlenaria, ExpedienteSessao from sapl.utils import choice_anos_com_sessaoplenaria -SessaoApiViewSetConstrutor = ApiViewSetConstrutor.build_class( +ApiViewSetConstrutor.build_class( [ apps.get_app_config('sessao') ] diff --git a/sapl/protocoloadm/urls.py b/sapl/protocoloadm/urls.py index 0d0290ac5..ab3dcefeb 100644 --- a/sapl/protocoloadm/urls.py +++ b/sapl/protocoloadm/urls.py @@ -124,12 +124,6 @@ urlpatterns_sistema = [ include(TipoDocumentoAdministrativoCrud.get_urls())), url(r'^sistema/status-tramitacao-adm/', include(StatusTramitacaoAdministrativoCrud.get_urls())), - - # FIXME: Usado para pesquisar autor- SOLUÇÃO-foi transformado em api/autor - # Melhor forma de fazer? - # Deve mudar de app? - # url(r'^protocoloadm/pesquisar-autor', - # pesquisa_autores, name='pesquisar_autor'), ] urlpatterns = (urlpatterns_documento_administrativo + diff --git a/sapl/templates/materia/autoria_form.html b/sapl/templates/materia/autoria_form.html index 9d2e314af..e15cf829b 100644 --- a/sapl/templates/materia/autoria_form.html +++ b/sapl/templates/materia/autoria_form.html @@ -5,15 +5,6 @@ {% block extra_js %} {% endblock %}