mirror of https://github.com/interlegis/sapl.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
7.1 KiB
210 lines
7.1 KiB
import logging
|
|
|
|
from django.db.models import Q
|
|
from django.utils import timezone
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django_filters.filters import CharFilter, DateFilter, ModelChoiceFilter
|
|
from django_filters.filterset import FilterSet
|
|
from rest_framework import serializers
|
|
|
|
from drfautoapi.drfautoapi import ApiFilterSetMixin
|
|
from sapl.base.models import Autor, TipoAutor
|
|
from sapl.parlamentares.models import Legislatura
|
|
from sapl.utils import generic_relations_for_model
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class SaplFilterSetMixin(ApiFilterSetMixin):
|
|
pass
|
|
|
|
|
|
class AutorFilterSet(SaplFilterSetMixin):
|
|
q = CharFilter(method="filter_q")
|
|
tipo = ModelChoiceFilter(queryset=TipoAutor.objects.all())
|
|
|
|
def filter_q(self, queryset, name, value):
|
|
query = value.split(" ")
|
|
if query:
|
|
q = Q()
|
|
for qtext in query:
|
|
if not qtext:
|
|
continue
|
|
q_fs = Q(nome__icontains=qtext) | Q(tipo__descricao__icontains=qtext)
|
|
|
|
order_by = []
|
|
|
|
for gr in generic_relations_for_model(self._meta.model):
|
|
sgr = gr[1]
|
|
for item in sgr:
|
|
if item.related_model != self._meta.model:
|
|
continue
|
|
flag_order_by = True
|
|
for field in item.fields_search:
|
|
if flag_order_by:
|
|
flag_order_by = False
|
|
order_by.append(
|
|
"%s__%s" % (item.related_query_name(), field[0])
|
|
)
|
|
# if len(field) == 3 and field[2](qtext) is not
|
|
# None:
|
|
q_fs = q_fs | Q(
|
|
**{
|
|
"%s__%s%s"
|
|
% (
|
|
item.related_query_name(),
|
|
field[0],
|
|
field[1],
|
|
): qtext
|
|
if len(field) == 2
|
|
else field[2](qtext)
|
|
}
|
|
)
|
|
|
|
q = q & q_fs
|
|
|
|
if q:
|
|
queryset = queryset.filter(q).order_by(*order_by)
|
|
|
|
return queryset.distinct()
|
|
|
|
|
|
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
|
|
|