Sistema de Apoio ao Processo Legislativo
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.
 
 
 
 
 

2438 lines
88 KiB

from collections import OrderedDict
import collections
import datetime
import itertools
import logging
import os
import re
from django.apps.registry import apps
from django.contrib import messages
from django.contrib.auth import get_user_model, views
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.models import Group
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.views import (PasswordResetView, PasswordResetConfirmView, PasswordResetCompleteView,
PasswordResetDoneView)
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, ValidationError
from django.core.mail import send_mail
from django.db import connection
from django.db.models import Count, Q, Max, F
from django.forms.utils import ErrorList
from django.http import Http404, HttpResponseRedirect, JsonResponse
from django.shortcuts import redirect
from django.template import TemplateDoesNotExist
from django.template.loader import get_template
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.utils.translation import ugettext_lazy as _
from django.views.generic import (FormView, ListView)
from django.views.generic.base import RedirectView, TemplateView
from django_filters.views import FilterView
from haystack.query import SearchQuerySet
from haystack.views import SearchView
from ratelimit.decorators import ratelimit
from sapl import settings
from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica
from sapl.base.forms import (AutorForm, TipoAutorForm, AutorFilterSet, RecuperarSenhaForm,
NovaSenhaForm, UserAdminForm,
OperadorAutorForm, LoginForm, SaplSearchForm)
from sapl.base.models import Autor, TipoAutor, OperadorAutor
from sapl.comissoes.models import Comissao, Reuniao
from sapl.crud.base import CrudAux, make_pagination, Crud,\
ListWithSearchForm, MasterDetailCrud
from sapl.materia.models import (Anexada, Autoria, DocumentoAcessorio, MateriaEmTramitacao, MateriaLegislativa,
Proposicao, StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, UnidadeTramitacao,
MateriaAssunto)
from sapl.norma.models import NormaJuridica, TipoNormaJuridica,\
NormaEstatisticas, ViewNormasEstatisticas
from sapl.parlamentares.models import (
Filiacao, Legislatura, Mandato, Parlamentar, SessaoLegislativa)
from sapl.protocoloadm.models import (Anexado, DocumentoAdministrativo, Protocolo, StatusTramitacaoAdministrativo,
TipoDocumentoAdministrativo)
from sapl.relatorios.views import (relatorio_materia_em_tramitacao, relatorio_materia_por_autor,
relatorio_materia_por_ano_autor, relatorio_presenca_sessao,
relatorio_historico_tramitacao, relatorio_fim_prazo_tramitacao, relatorio_atas,
relatorio_audiencia, relatorio_normas_mes, relatorio_normas_vigencia,
relatorio_historico_tramitacao_adm, relatorio_reuniao,
relatorio_estatisticas_acesso_normas, relatorio_normas_por_autor,
relatorio_documento_acessorio)
from sapl.sessao.models import (
Bancada, PresencaOrdemDia, SessaoPlenaria, SessaoPlenariaPresenca, TipoSessaoPlenaria)
from sapl.settings import EMAIL_SEND_USER
from sapl.utils import (gerar_hash_arquivo, intervalos_tem_intersecao, mail_service_configured, parlamentares_ativos,
SEPARADOR_HASH_PROPOSICAO, show_results_filter_set, num_materias_por_tipo,
google_recaptcha_configured, sapl_as_sapn,
groups_remove_user, groups_add_user, get_client_ip)
from .forms import (AlterarSenhaForm, CasaLegislativaForm, ConfiguracoesAppForm, RelatorioAtasFilterSet,
RelatorioAudienciaFilterSet, RelatorioDataFimPrazoTramitacaoFilterSet,
RelatorioHistoricoTramitacaoFilterSet, RelatorioMateriasPorAnoAutorTipoFilterSet,
RelatorioMateriasPorAutorFilterSet, RelatorioMateriasTramitacaoFilterSet,
RelatorioPresencaSessaoFilterSet, RelatorioReuniaoFilterSet,
RelatorioNormasMesFilterSet, RelatorioNormasVigenciaFilterSet, EstatisticasAcessoNormasForm,
RelatorioHistoricoTramitacaoAdmFilterSet, RelatorioDocumentosAcessoriosFilterSet,
RelatorioNormasPorAutorFilterSet)
from .models import AppConfig, CasaLegislativa
def get_casalegislativa():
return CasaLegislativa.objects.first()
class IndexView(TemplateView):
def get(self, request, *args, **kwargs):
if sapl_as_sapn():
return redirect('/norma/pesquisar')
return TemplateView.get(self, request, *args, **kwargs)
@method_decorator(ratelimit(key=lambda group, request: get_client_ip(request),
rate='20/m',
method=ratelimit.UNSAFE,
block=True), name='dispatch')
class LoginSapl(views.LoginView):
template_name = 'base/login.html'
authentication_form = LoginForm
class ConfirmarEmailView(TemplateView):
template_name = "email/confirma.html"
def get(self, request, *args, **kwargs):
uid = urlsafe_base64_decode(self.kwargs['uidb64'])
user = get_user_model().objects.get(id=uid)
user.is_active = True
user.save()
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
class RecuperarSenhaEmailView(PasswordResetView):
logger = logging.getLogger(__name__)
success_url = reverse_lazy('sapl.base:recuperar_senha_finalizado')
email_template_name = 'base/recuperar_senha_email.html'
html_email_template_name = 'base/recuperar_senha_email.html'
template_name = 'base/recuperar_senha_email_form.html'
from_email = EMAIL_SEND_USER
form_class = RecuperarSenhaForm
def get(self, request, *args, **kwargs):
if not google_recaptcha_configured():
self.logger.warning(_('Google Recaptcha não configurado!'))
messages.error(request, _('Google Recaptcha não configurado!'))
return redirect(request.META.get('HTTP_REFERER', '/'))
return PasswordResetView.get(self, request, *args, **kwargs)
def post(self, request, *args, **kwargs):
if not google_recaptcha_configured():
self.logger.warning(_('Google Recaptcha não configurado!'))
messages.error(request, _('Google Recaptcha não configurado!'))
return redirect(request.META.get('HTTP_REFERER', '/'))
return PasswordResetView.post(self, request, *args, **kwargs)
class RecuperarSenhaFinalizadoView(PasswordResetDoneView):
template_name = 'base/recupera_senha_email_enviado.html'
class RecuperarSenhaConfirmaView(PasswordResetConfirmView):
success_url = reverse_lazy('sapl.base:recuperar_senha_completo')
template_name = 'base/nova_senha_form.html'
form_class = NovaSenhaForm
class RecuperarSenhaCompletoView(PasswordResetCompleteView):
template_name = 'base/recuperar_senha_completo.html'
class TipoAutorCrud(CrudAux):
model = TipoAutor
help_topic = 'tipo-autor'
class BaseMixin(CrudAux.BaseMixin):
list_field_names = ['descricao']
form_class = TipoAutorForm
@property
def verbose_name(self):
vn = super().verbose_name
vn = "{} {}".format(vn, _('Externo ao SAPL'))
return vn
class ListView(CrudAux.ListView):
template_name = "base/tipoautor_list.html"
def get_queryset(self):
qs = CrudAux.ListView.get_queryset(self)
qs = qs.filter(content_type__isnull=True)
return qs
def get_context_data(self, **kwargs):
context = CrudAux.ListView.get_context_data(self, **kwargs)
context['tipos_sapl'] = TipoAutor.objects.filter(
content_type__isnull=False)
return context
class TipoAutorMixin:
def dispatch(self, request, *args, **kwargs):
object = self.get_object()
if object.content_type:
raise PermissionDenied()
return super().dispatch(request, *args, **kwargs)
class UpdateView(TipoAutorMixin, CrudAux.UpdateView):
pass
class DetailView(TipoAutorMixin, CrudAux.DetailView):
pass
class DeleteView(TipoAutorMixin, CrudAux.DeleteView):
pass
class AutorCrud(CrudAux):
model = Autor
help_topic = 'autor'
class BaseMixin(CrudAux.BaseMixin):
list_field_names = ['nome', 'tipo', 'operadores']
def send_mail_operadores(self):
username = self.request.user.username
if not mail_service_configured():
self.logger.warning(_('Registro de Autor sem envio de email. '
'Servidor de email não configurado.'))
return
try:
self.logger.debug('user=' + username +
'. Enviando email na criação de Autores.')
kwargs = {}
for user in self.object.operadores.all():
if not user.email:
self.logger.warning(
_('Registro de Autor sem envio de email. '
'Usuário sem um email cadastrado.'))
continue
kwargs['token'] = default_token_generator.make_token(user)
kwargs['uidb64'] = urlsafe_base64_encode(
force_bytes(user.pk))
assunto = "SAPL - Confirmação de Conta"
full_url = self.request.get_raw_uri()
url_base = full_url[:full_url.find('sistema') - 1]
mensagem = (
"Este e-mail foi utilizado para fazer cadastro no " +
"SAPL com o perfil de Autor. Agora você pode " +
"criar/editar/enviar Proposições.\n" +
"Seu nome de usuário é: " +
self.request.POST['username'] + "\n"
"Caso você não tenha feito este cadastro, por favor " +
"ignore esta mensagem. Caso tenha, clique " +
"no link abaixo\n" + url_base +
reverse('sapl.base:confirmar_email', kwargs=kwargs))
remetente = settings.EMAIL_SEND_USER
destinatario = [user.email]
send_mail(assunto, mensagem, remetente, destinatario,
fail_silently=False)
except Exception as e:
print(
_('Erro no envio de email na criação de Autores.'))
self.logger.error(
'user=' + username + '. Erro no envio de email na criação de Autores. ' + str(e))
class DeleteView(CrudAux.DeleteView):
def delete(self, *args, **kwargs):
self.object = self.get_object()
grupo = Group.objects.filter(name='Autor')[0]
lista_operadores = list(self.object.operadores.all())
response = CrudAux.DeleteView.delete(self, *args, **kwargs)
if not Autor.objects.filter(pk=kwargs['pk']).exists():
for u in lista_operadores:
u.groups.remove(grupo)
return response
class DetailView(CrudAux.DetailView):
def hook_operadores(self, obj):
r = '<ul>{}</ul>'.format(
''.join(
[
'<li>{} - <i>({})</i> - '
'<small>{}</small>'
'</li>'.format(u.first_name, u, u.email)
for u in obj.operadores.all()
]
)
)
return 'Operadores', r
class UpdateView(CrudAux.UpdateView):
logger = logging.getLogger(__name__)
layout_key = None
form_class = AutorForm
def get_success_url(self):
self.send_mail_operadores()
return super().get_success_url()
class CreateView(CrudAux.CreateView):
logger = logging.getLogger(__name__)
form_class = AutorForm
layout_key = None
def get_success_url(self):
self.send_mail_operadores()
return super().get_success_url()
class ListView(CrudAux.ListView):
form_search_class = ListWithSearchForm
def hook_operadores(self, *args, **kwargs):
r = '<ul>{}</ul>'.format(
''.join(
[
'<li>{} - <i>({})</i></li>'.format(u.first_name, u)
for u in args[0].operadores.all()
]
)
)
return r, ''
def get_queryset(self):
qs = self.model.objects.all()
q_param = self.request.GET.get('q', '')
if q_param:
q = Q(nome__icontains=q_param)
q |= Q(cargo__icontains=q_param)
q |= Q(tipo__descricao__icontains=q_param)
q |= Q(operadores__username__icontains=q_param)
q |= Q(operadores__email__icontains=q_param)
qs = qs.filter(q)
return qs.distinct('nome', 'id').order_by('nome', 'id')
class RelatoriosListView(TemplateView):
template_name = 'base/relatorios_list.html'
def get_context_data(self, **kwargs):
context = super(TemplateView, self).get_context_data(**kwargs)
estatisticas_acesso_normas = AppConfig.objects.first().estatisticas_acesso_normas
context['estatisticas_acesso_normas'] = True if estatisticas_acesso_normas == 'S' else False
return context
class RelatorioMixin:
def get(self, request, *args, **kwargs):
super(RelatorioMixin, self).get(request)
is_relatorio = request.GET.get('relatorio')
context = self.get_context_data(filter=self.filterset)
if is_relatorio:
return self.relatorio(request, context)
else:
return self.render_to_response(context)
class RelatorioDocumentosAcessoriosView(RelatorioMixin, FilterView):
model = DocumentoAcessorio
filterset_class = RelatorioDocumentosAcessoriosFilterSet
template_name = 'base/RelatorioDocumentosAcessorios_filter.html'
relatorio = relatorio_documento_acessorio
def get_context_data(self, **kwargs):
context = super(
RelatorioDocumentosAcessoriosView, self
).get_context_data(**kwargs)
context['title'] = _('Documentos Acessórios das Matérias Legislativas')
if not self.filterset.form.is_valid():
return context
query_dict = self.request.GET.copy()
context['show_results'] = show_results_filter_set(query_dict)
context['tipo_documento'] = str(
TipoDocumento.objects.get(pk=self.request.GET['tipo'])
)
tipo_materia = self.request.GET['materia__tipo']
if tipo_materia:
context['tipo_materia'] = str(
TipoMateriaLegislativa.objects.get(pk=tipo_materia)
)
else:
context['tipo_materia'] = "Não selecionado"
data_inicial = self.request.GET['data_0']
data_final = self.request.GET['data_1']
if not data_inicial:
data_inicial = "Data Inicial não definida"
if not data_final:
data_final = "Data Final não definida"
context['periodo'] = (
data_inicial + ' - ' + data_final
)
return context
class RelatorioAtasView(RelatorioMixin, FilterView):
model = SessaoPlenaria
filterset_class = RelatorioAtasFilterSet
template_name = 'base/RelatorioAtas_filter.html'
relatorio = relatorio_atas
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _('Atas das Sessões Plenárias')
# Verifica se os campos foram preenchidos
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
context['periodo'] = (
self.request.GET['data_inicio_0'] +
' - ' + self.request.GET['data_inicio_1'])
return context
class RelatorioPresencaSessaoView(RelatorioMixin, FilterView):
logger = logging.getLogger(__name__)
model = SessaoPlenaria
filterset_class = RelatorioPresencaSessaoFilterSet
template_name = 'base/RelatorioPresencaSessao_filter.html'
relatorio = relatorio_presenca_sessao
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _('Presença dos parlamentares nas sessões')
# Verifica se os campos foram preenchidos
if not self.filterset.form.is_valid():
return context
cd = self.filterset.form.cleaned_data
if not cd['data_inicio'] and not cd['sessao_legislativa'] \
and not cd['legislatura']:
msg = _(
"Formulário inválido! Preencha pelo menos algum dos campos Período, Legislatura ou Sessão Legislativa.")
messages.error(self.request, msg)
return context
# Caso a data tenha sido preenchida, verifica se foi preenchida
# corretamente
if self.request.GET.get('data_inicio_0') and not self.request.GET.get('data_inicio_1'):
msg = _("Formulário inválido! Preencha a data do Período Final.")
messages.error(self.request, msg)
return context
if not self.request.GET.get('data_inicio_0') and self.request.GET.get('data_inicio_1'):
msg = _("Formulário inválido! Preencha a data do Período Inicial.")
messages.error(self.request, msg)
return context
param0 = {}
legislatura_pk = self.request.GET.get('legislatura')
if legislatura_pk:
param0['sessao_plenaria__legislatura_id'] = legislatura_pk
legislatura = Legislatura.objects.get(id=legislatura_pk)
context['legislatura'] = legislatura
sessao_legislativa_pk = self.request.GET.get('sessao_legislativa')
if sessao_legislativa_pk:
param0['sessao_plenaria__sessao_legislativa_id'] = sessao_legislativa_pk
sessao_legislativa = SessaoLegislativa.objects.get(
id=sessao_legislativa_pk)
context['sessao_legislativa'] = sessao_legislativa
tipo_sessao_plenaria_pk = self.request.GET.get('tipo')
context['tipo'] = ''
if tipo_sessao_plenaria_pk:
param0['sessao_plenaria__tipo_id'] = tipo_sessao_plenaria_pk
context['tipo'] = TipoSessaoPlenaria.objects.get(
id=tipo_sessao_plenaria_pk)
_range = []
if ('data_inicio_0' in self.request.GET) and self.request.GET['data_inicio_0'] and \
('data_inicio_1' in self.request.GET) and self.request.GET['data_inicio_1']:
where = context['object_list'].query.where
_range = where.children[0].rhs
elif legislatura_pk and not sessao_legislativa_pk:
_range = [legislatura.data_inicio, legislatura.data_fim]
elif sessao_legislativa_pk:
_range = [sessao_legislativa.data_inicio,
sessao_legislativa.data_fim]
param0.update({'sessao_plenaria__data_inicio__range': _range})
# Parlamentares com Mandato no intervalo de tempo (Ativos)
parlamentares_qs = parlamentares_ativos(
_range[0], _range[1]).order_by('nome_parlamentar')
parlamentares_id = parlamentares_qs.values_list('id', flat=True)
# Presenças de cada Parlamentar em Sessões
presenca_sessao = SessaoPlenariaPresenca.objects.filter(
**param0).values_list('parlamentar_id').annotate(sessao_count=Count('id'))
# Presenças de cada Ordem do Dia
presenca_ordem = PresencaOrdemDia.objects.filter(
**param0).values_list('parlamentar_id').annotate(sessao_count=Count('id'))
total_ordemdia = PresencaOrdemDia.objects.filter(
**param0).distinct('sessao_plenaria__id').order_by('sessao_plenaria__id').count()
total_sessao = context['object_list'].count()
username = self.request.user.username
context['exibir_somente_titular'] = self.request.GET.get(
'exibir_somente_titular') == 'on'
context['exibir_somente_ativo'] = self.request.GET.get(
'exibir_somente_ativo') == 'on'
# Completa o dicionario as informacoes parlamentar/sessao/ordem
parlamentares_presencas = []
for p in parlamentares_qs:
parlamentar = {}
m = p.mandato_set.filter(Q(data_inicio_mandato__lte=_range[0], data_fim_mandato__gte=_range[1]) |
Q(data_inicio_mandato__lte=_range[0], data_fim_mandato__isnull=True) |
Q(data_inicio_mandato__gte=_range[0], data_fim_mandato__lte=_range[1]) |
# mandato suplente
Q(data_inicio_mandato__gte=_range[0], data_fim_mandato__lte=_range[1]))
m = m.last()
if not context['exibir_somente_titular'] and not context['exibir_somente_ativo']:
parlamentar = {
'parlamentar': p,
'titular': m.titular if m else False,
'sessao_porc': 0,
'ordemdia_porc': 0
}
elif context['exibir_somente_titular'] and not context['exibir_somente_ativo']:
if m and m.titular:
parlamentar = {
'parlamentar': p,
'titular': m.titular if m else False,
'sessao_porc': 0,
'ordemdia_porc': 0
}
else:
continue
elif not context['exibir_somente_titular'] and context['exibir_somente_ativo']:
if p.ativo:
parlamentar = {
'parlamentar': p,
'titular': m.titular if m else False,
'sessao_porc': 0,
'ordemdia_porc': 0
}
else:
continue
elif context['exibir_somente_titular'] and context['exibir_somente_ativo']:
if m and m.titular and p.ativo:
parlamentar = {
'parlamentar': p,
'titular': m.titular if m else False,
'sessao_porc': 0,
'ordemdia_porc': 0
}
else:
continue
else:
continue
try:
self.logger.debug(
F'user={username}. Tentando obter presença do parlamentar (pk={p.id}).')
sessao_count = presenca_sessao.get(parlamentar_id=p.id)[1]
except ObjectDoesNotExist as e:
self.logger.error(
F'user={username}. Erro ao obter presença do parlamentar (pk={p.id}). Definido como 0. {str(e)}')
sessao_count = 0
try:
# Presenças de cada Ordem do Dia
self.logger.info(
F'user={username}. Tentando obter PresencaOrdemDia para o parlamentar pk={p.id}.')
ordemdia_count = presenca_ordem.get(parlamentar_id=p.id)[1]
except ObjectDoesNotExist:
self.logger.error(
F'user={username}. Erro ao obter PresencaOrdemDia para o parlamentar pk={p.id}. Definido como 0.')
ordemdia_count = 0
parlamentar.update({
'sessao_count': sessao_count,
'ordemdia_count': ordemdia_count
})
if total_sessao != 0:
parlamentar.update({'sessao_porc': round(
sessao_count * 100 / total_sessao, 2)})
if total_ordemdia != 0:
parlamentar.update({'ordemdia_porc': round(
ordemdia_count * 100 / total_ordemdia, 2)})
parlamentares_presencas.append(parlamentar)
context['date_range'] = _range
context['total_ordemdia'] = total_ordemdia
context['total_sessao'] = context['object_list'].count()
context['parlamentares'] = parlamentares_presencas
context['periodo'] = f"{self.request.GET['data_inicio_0']} - {self.request.GET['data_inicio_1']}"
context['sessao_legislativa'] = ''
context['legislatura'] = ''
context['exibir_ordem'] = self.request.GET.get(
'exibir_ordem_dia') == 'on'
if sessao_legislativa_pk:
context['sessao_legislativa'] = SessaoLegislativa.objects.get(
id=sessao_legislativa_pk)
if legislatura_pk:
context['legislatura'] = Legislatura.objects.get(id=legislatura_pk)
# =====================================================================
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
return context
class RelatorioHistoricoTramitacaoView(RelatorioMixin, FilterView):
model = MateriaLegislativa
filterset_class = RelatorioHistoricoTramitacaoFilterSet
template_name = 'base/RelatorioHistoricoTramitacao_filter.html'
relatorio = relatorio_historico_tramitacao
def get_context_data(self, **kwargs):
context = super(RelatorioHistoricoTramitacaoView,
self).get_context_data(**kwargs)
context['title'] = _(
'Histórico de Tramitações de Matérias Legislativas')
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
context['data_tramitacao'] = (self.request.GET['tramitacao__data_tramitacao_0'] + ' - ' +
self.request.GET['tramitacao__data_tramitacao_1'])
if self.request.GET['tipo']:
tipo = self.request.GET['tipo']
context['tipo'] = (
str(TipoMateriaLegislativa.objects.get(id=tipo)))
else:
context['tipo'] = ''
if self.request.GET['tramitacao__status']:
tramitacao_status = self.request.GET['tramitacao__status']
context['tramitacao__status'] = (
str(StatusTramitacao.objects.get(id=tramitacao_status)))
else:
context['tramitacao__status'] = ''
if self.request.GET['tramitacao__unidade_tramitacao_local']:
context['tramitacao__unidade_tramitacao_local'] = \
(str(UnidadeTramitacao.objects.get(
id=self.request.GET['tramitacao__unidade_tramitacao_local'])))
else:
context['tramitacao__unidade_tramitacao_local'] = ''
if self.request.GET['tramitacao__unidade_tramitacao_destino']:
context['tramitacao__unidade_tramitacao_destino'] = \
(str(UnidadeTramitacao.objects.get(
id=self.request.GET['tramitacao__unidade_tramitacao_destino'])))
else:
context['tramitacao__unidade_tramitacao_destino'] = ''
if self.request.GET['autoria__autor']:
context['autoria__autor'] = \
(str(Autor.objects.get(
id=self.request.GET['autoria__autor'])))
else:
context['autoria__autor'] = ''
return context
class RelatorioDataFimPrazoTramitacaoView(RelatorioMixin, FilterView):
model = MateriaLegislativa
filterset_class = RelatorioDataFimPrazoTramitacaoFilterSet
template_name = 'base/RelatorioDataFimPrazoTramitacao_filter.html'
relatorio = relatorio_fim_prazo_tramitacao
def get_context_data(self, **kwargs):
context = super(RelatorioDataFimPrazoTramitacaoView,
self).get_context_data(**kwargs)
context['title'] = _('Relatório de Tramitações')
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
context['data_tramitacao'] = (self.request.GET['tramitacao__data_fim_prazo_0'] + ' - ' +
self.request.GET['tramitacao__data_fim_prazo_1'])
if self.request.GET['ano']:
context['ano'] = self.request.GET['ano']
else:
context['ano'] = ''
if self.request.GET['tipo']:
tipo = self.request.GET['tipo']
context['tipo'] = (
str(TipoMateriaLegislativa.objects.get(id=tipo)))
else:
context['tipo'] = ''
if self.request.GET['tramitacao__status']:
tramitacao_status = self.request.GET['tramitacao__status']
context['tramitacao__status'] = (
str(StatusTramitacao.objects.get(id=tramitacao_status)))
else:
context['tramitacao__status'] = ''
if self.request.GET['tramitacao__unidade_tramitacao_local']:
context['tramitacao__unidade_tramitacao_local'] = \
(str(UnidadeTramitacao.objects.get(
id=self.request.GET['tramitacao__unidade_tramitacao_local'])))
else:
context['tramitacao__unidade_tramitacao_local'] = ''
if self.request.GET['tramitacao__unidade_tramitacao_destino']:
context['tramitacao__unidade_tramitacao_destino'] = \
(str(UnidadeTramitacao.objects.get(
id=self.request.GET['tramitacao__unidade_tramitacao_destino'])))
else:
context['tramitacao__unidade_tramitacao_destino'] = ''
return context
class RelatorioReuniaoView(RelatorioMixin, FilterView):
model = Reuniao
filterset_class = RelatorioReuniaoFilterSet
template_name = 'base/RelatorioReuniao_filter.html'
relatorio = relatorio_reuniao
def get_filterset_kwargs(self, filterset_class):
super(RelatorioReuniaoView,
self).get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
return kwargs
def get_context_data(self, **kwargs):
context = super(RelatorioReuniaoView,
self).get_context_data(**kwargs)
context['title'] = _('Reunião de Comissão')
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
if self.request.GET['comissao']:
comissao = self.request.GET['comissao']
context['comissao'] = (str(Comissao.objects.get(id=comissao)))
else:
context['comissao'] = ''
return context
class RelatorioAudienciaView(RelatorioMixin, FilterView):
model = AudienciaPublica
filterset_class = RelatorioAudienciaFilterSet
template_name = 'base/RelatorioAudiencia_filter.html'
relatorio = relatorio_audiencia
def get_filterset_kwargs(self, filterset_class):
super(RelatorioAudienciaView,
self).get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
return kwargs
def get_context_data(self, **kwargs):
context = super(RelatorioAudienciaView,
self).get_context_data(**kwargs)
context['title'] = _('Audiência Pública')
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
if self.request.GET['tipo']:
tipo = self.request.GET['tipo']
context['tipo'] = (str(TipoAudienciaPublica.objects.get(id=tipo)))
else:
context['tipo'] = ''
return context
class RelatorioMateriasTramitacaoView(RelatorioMixin, FilterView):
model = MateriaEmTramitacao
filterset_class = RelatorioMateriasTramitacaoFilterSet
template_name = 'base/RelatorioMateriasPorTramitacao_filter.html'
relatorio = relatorio_materia_em_tramitacao
paginate_by = 100
total_resultados_tipos = {}
def get_filterset_kwargs(self, filterset_class):
data = super().get_filterset_kwargs(filterset_class)
if data['data']:
qs = data['queryset']
ano_materia = data['data']['materia__ano']
tipo_materia = data['data']['materia__tipo']
unidade_tramitacao_destino = data['data']['tramitacao__unidade_tramitacao_destino']
status_tramitacao = data['data']['tramitacao__status']
autor = data['data']['materia__autores']
kwargs = {}
if ano_materia:
kwargs['materia__ano'] = ano_materia
if tipo_materia:
kwargs['materia__tipo'] = tipo_materia
if unidade_tramitacao_destino:
kwargs['tramitacao__unidade_tramitacao_destino'] = unidade_tramitacao_destino
if status_tramitacao:
kwargs['tramitacao__status'] = status_tramitacao
if autor:
kwargs['materia__autores'] = autor
qs = qs.filter(**kwargs)
data['queryset'] = qs
self.total_resultados_tipos = num_materias_por_tipo(
qs, "materia__tipo")
return data
def get_queryset(self):
qs = super().get_queryset()
qs = qs.select_related('materia__tipo').filter(
materia__em_tramitacao=True
).exclude(
tramitacao__status__indicador='F'
).order_by('-materia__ano', '-materia__numero')
return qs
def get_context_data(self, **kwargs):
context = super(
RelatorioMateriasTramitacaoView, self
).get_context_data(**kwargs)
context['title'] = _('Matérias em Tramitação')
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['qtdes'] = self.total_resultados_tipos
context['ano'] = (self.request.GET['materia__ano'])
if self.request.GET['materia__tipo']:
tipo = self.request.GET['materia__tipo']
context['tipo'] = (
str(TipoMateriaLegislativa.objects.get(id=tipo))
)
else:
context['tipo'] = ''
if self.request.GET['tramitacao__status']:
tramitacao_status = self.request.GET['tramitacao__status']
context['tramitacao__status'] = (
str(StatusTramitacao.objects.get(id=tramitacao_status))
)
else:
context['tramitacao__status'] = ''
if self.request.GET['tramitacao__unidade_tramitacao_destino']:
context['tramitacao__unidade_tramitacao_destino'] = (
str(UnidadeTramitacao.objects.get(
id=self.request.GET['tramitacao__unidade_tramitacao_destino']
))
)
else:
context['tramitacao__unidade_tramitacao_destino'] = ''
if self.request.GET['materia__autores']:
autor = self.request.GET['materia__autores']
context['materia__autor'] = (
str(Autor.objects.get(id=autor))
)
else:
context['materia__autor'] = ''
if 'page' in qr:
del qr['page']
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages
)
context['NO_ENTRIES_MSG'] = 'Nenhum encontrado.'
return context
class RelatorioMateriasPorAnoAutorTipoView(RelatorioMixin, FilterView):
model = MateriaLegislativa
filterset_class = RelatorioMateriasPorAnoAutorTipoFilterSet
template_name = 'base/RelatorioMateriasPorAnoAutorTipo_filter.html'
relatorio = relatorio_materia_por_ano_autor
def get_materias_autor_ano(self, ano, primeiro_autor):
autorias = Autoria.objects.filter(materia__ano=ano, primeiro_autor=primeiro_autor).values(
'autor',
'materia__tipo__sigla',
'materia__tipo__descricao').annotate(
total=Count('materia__tipo')).order_by(
'autor',
'materia__tipo')
autores_ids = set([i['autor'] for i in autorias])
autores = dict((a.id, a) for a in Autor.objects.filter(
id__in=autores_ids))
relatorio = []
visitados = set()
curr = None
for a in autorias:
# se mudou autor, salva atual, caso existente, e reinicia `curr`
if a['autor'] not in visitados:
if curr:
relatorio.append(curr)
curr = {}
curr['autor'] = autores[a['autor']]
curr['materia'] = []
curr['total'] = 0
visitados.add(a['autor'])
# atualiza valores
curr['materia'].append((a['materia__tipo__descricao'], a['total']))
curr['total'] += a['total']
# adiciona o ultimo
relatorio.append(curr)
return relatorio
def get_filterset_kwargs(self, filterset_class):
super(RelatorioMateriasPorAnoAutorTipoView,
self).get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
return kwargs
def get_context_data(self, **kwargs):
context = super(RelatorioMateriasPorAnoAutorTipoView,
self).get_context_data(**kwargs)
context['title'] = _('Matérias por Ano, Autor e Tipo')
if not self.filterset.form.is_valid():
return context
qs = context['object_list']
context['qtdes'] = num_materias_por_tipo(qs)
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
context['ano'] = self.request.GET['ano']
if 'ano' in self.request.GET and self.request.GET['ano']:
ano = int(self.request.GET['ano'])
context['relatorio'] = self.get_materias_autor_ano(ano, True)
context['corelatorio'] = self.get_materias_autor_ano(ano, False)
else:
context['relatorio'] = []
return context
class RelatorioMateriasPorAutorView(RelatorioMixin, FilterView):
model = MateriaLegislativa
filterset_class = RelatorioMateriasPorAutorFilterSet
template_name = 'base/RelatorioMateriasPorAutor_filter.html'
relatorio = relatorio_materia_por_autor
def get_filterset_kwargs(self, filterset_class):
super().get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _('Matérias por Autor')
if not self.filterset.form.is_valid():
return context
qs = context['object_list']
context['materias_resultado'] = list(OrderedDict.fromkeys(qs))
context['qtdes'] = num_materias_por_tipo(qs)
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
if self.request.GET['tipo']:
tipo = int(self.request.GET['tipo'])
context['tipo'] = (
str(TipoMateriaLegislativa.objects.get(id=tipo)))
else:
context['tipo'] = ''
if self.request.GET['autoria__autor']:
autor = int(self.request.GET['autoria__autor'])
context['autor'] = (str(Autor.objects.get(id=autor)))
else:
context['autor'] = ''
context['periodo'] = (
self.request.GET['data_apresentacao_0'] +
' - ' + self.request.GET['data_apresentacao_1'])
return context
class RelatorioMateriaAnoAssuntoView(ListView):
template_name = 'base/RelatorioMateriasAnoAssunto.html'
def get_queryset(self):
return MateriaAssunto.objects.all().values(
'assunto_id',
assunto_materia=F('assunto__assunto'),
ano=F('materia__ano')).annotate(
total=Count('assunto_id')).order_by('-materia__ano', 'assunto_id')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _('Matérias por Ano e Assunto')
# In[10]: MateriaAssunto.objects.all().values(
# ...: 'materia__ano').annotate(
# ...: total = Count('materia__ano')).order_by('-materia__ano')
mat = MateriaLegislativa.objects.filter(
materiaassunto__isnull=True).values(
'ano').annotate(
total=Count('ano')).order_by('-ano')
context.update({"materias_sem_assunto": mat})
return context
class RelatorioNormasPublicadasMesView(RelatorioMixin, FilterView):
model = NormaJuridica
filterset_class = RelatorioNormasMesFilterSet
template_name = 'base/RelatorioNormaMes_filter.html'
relatorio = relatorio_normas_mes
def get_context_data(self, **kwargs):
context = super(RelatorioNormasPublicadasMesView,
self).get_context_data(**kwargs)
context['title'] = _('Normas')
# Verifica se os campos foram preenchidos
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
context['ano'] = self.request.GET['ano']
normas_mes = collections.OrderedDict()
meses = {1: 'Janeiro', 2: 'Fevereiro', 3: 'Março', 4: 'Abril', 5: 'Maio', 6: 'Junho',
7: 'Julho', 8: 'Agosto', 9: 'Setembro', 10: 'Outubro', 11: 'Novembro', 12: 'Dezembro'}
for norma in context['object_list']:
if not meses[norma.data.month] in normas_mes:
normas_mes[meses[norma.data.month]] = []
normas_mes[meses[norma.data.month]].append(norma)
context['normas_mes'] = normas_mes
quant_normas_mes = {}
for key in normas_mes.keys():
quant_normas_mes[key] = len(normas_mes[key])
context['quant_normas_mes'] = quant_normas_mes
return context
class RelatorioNormasVigenciaView(RelatorioMixin, FilterView):
model = NormaJuridica
filterset_class = RelatorioNormasVigenciaFilterSet
template_name = 'base/RelatorioNormasVigencia_filter.html'
relatorio = relatorio_normas_vigencia
def get_filterset_kwargs(self, filterset_class):
super(RelatorioNormasVigenciaView,
self).get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
qs = self.get_queryset().order_by('data').distinct()
if kwargs['data']:
ano = kwargs['data']['ano']
vigencia = kwargs['data']['vigencia']
if ano:
qs = qs.filter(ano=ano)
if vigencia == 'True':
qs_dt_not_null = qs.filter(data_vigencia__isnull=True)
qs = (qs_dt_not_null | qs.filter(
data_vigencia__gte=datetime.datetime.now().date())).distinct()
else:
qs = qs.filter(
data_vigencia__lt=datetime.datetime.now().date())
kwargs.update({
'queryset': qs
})
return kwargs
def get_context_data(self, **kwargs):
context = super(RelatorioNormasVigenciaView,
self).get_context_data(**kwargs)
context['title'] = _('Normas por vigência')
# Verifica se os campos foram preenchidos
if not self.filterset.form.is_valid():
return context
normas_totais = NormaJuridica.objects.filter(
ano=self.request.GET['ano'])
context['quant_total'] = len(normas_totais)
if self.request.GET['vigencia'] == 'True':
context['vigencia'] = 'Vigente'
context['quant_vigente'] = len(context['object_list'])
context['quant_nao_vigente'] = context['quant_total'] - \
context['quant_vigente']
else:
context['vigencia'] = 'Não vigente'
context['quant_nao_vigente'] = len(context['object_list'])
context['quant_vigente'] = context['quant_total'] - \
context['quant_nao_vigente']
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
context['ano'] = self.request.GET['ano']
return context
class EstatisticasAcessoNormas(TemplateView):
template_name = 'base/EstatisticasAcessoNormas_filter.html'
def get(self, request, *args, **kwargs):
context = super(EstatisticasAcessoNormas,
self).get_context_data(**kwargs)
context['title'] = _('Estatísticas de Acesso às Normas Jurídicas')
form = EstatisticasAcessoNormasForm(request.GET or None)
context['form'] = form
if not form.is_valid():
return self.render_to_response(context)
context['ano'] = self.request.GET['ano']
context['mes'] = self.request.GET.get('mes', '')
context['mais_acessadas'] = int(
self.request.GET.get('mais_acessadas', 5))
if not context['mes'] and context['mais_acessadas'] > 10:
context['mais_acessadas'] = 10
params = {
'ano_est': context['ano'],
'mais_acessadas__lte': context['mais_acessadas']
}
if context['mes']:
params['mes_est'] = context['mes']
estatisticas = ViewNormasEstatisticas.objects.filter(
**params
)
normas_mes = collections.OrderedDict()
meses = {1: 'Janeiro', 2: 'Fevereiro', 3: 'Março', 4: 'Abril', 5: 'Maio', 6: 'Junho',
7: 'Julho', 8: 'Agosto', 9: 'Setembro', 10: 'Outubro', 11: 'Novembro', 12: 'Dezembro'}
for norma in estatisticas:
if not meses[norma.mes_est] in normas_mes:
normas_mes[meses[norma.mes_est]] = []
normas_mes[meses[norma.mes_est]].append(norma)
context['normas_mes'] = normas_mes
is_relatorio = request.GET.get('relatorio')
context['show_results'] = show_results_filter_set(
self.request.GET.copy())
if is_relatorio:
return relatorio_estatisticas_acesso_normas(self, request, context)
else:
return self.render_to_response(context)
class ListarInconsistenciasView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/lista_inconsistencias.html'
context_object_name = 'tabela_inconsistencias'
permission_required = ('base.list_appconfig',)
def get_queryset(self):
tabela = []
tabela.append(
('protocolos_duplicados',
'Protocolos duplicados',
len(protocolos_duplicados())
)
)
tabela.append(
('protocolos_com_materias',
'Protocolos que excedem o limite de matérias vinculadas',
len(protocolos_com_materias())
)
)
tabela.append(
('materias_protocolo_inexistente',
'Matérias Legislativas com protocolo inexistente',
len(materias_protocolo_inexistente())
)
)
tabela.append(
('filiacoes_sem_data_filiacao',
'Filiações sem data filiação',
len(filiacoes_sem_data_filiacao())
)
)
tabela.append(
('mandato_sem_data_inicio',
'Mandatos sem data inicial',
len(mandato_sem_data_inicio())
)
)
tabela.append(
('parlamentares_duplicados',
'Parlamentares duplicados',
len(parlamentares_duplicados())
)
)
tabela.append(
('parlamentares_mandatos_intersecao',
'Parlamentares com mandatos em interseção',
len(parlamentares_mandatos_intersecao())
)
)
tabela.append(
('parlamentares_filiacoes_intersecao',
'Parlamentares com filiações em interseção',
len(parlamentares_filiacoes_intersecao())
)
)
tabela.append(
('autores_duplicados',
'Autores duplicados',
len(autores_duplicados())
)
)
tabela.append(
('bancada_comissao_autor_externo',
'Bancadas e Comissões com autor externo',
len(bancada_comissao_autor_externo())
)
)
tabela.append(
('legislatura_infindavel',
'Legislaturas sem data fim',
len(legislatura_infindavel())
)
)
tabela.append(
('anexadas_ciclicas',
'Matérias Anexadas cíclicas',
len(materias_anexadas_ciclicas())
)
)
tabela.append(
('anexados_ciclicos',
'Documentos Anexados cíclicos',
len(anexados_ciclicos(False))
)
)
return tabela
def materias_anexadas_ciclicas():
ciclos = []
for a in Anexada.objects.select_related('materia_principal',
'materia_anexada',
'materia_principal__tipo',
'materia_anexada__tipo'):
visitados = [a.materia_principal]
anexadas = [a.materia_anexada]
while len(anexadas) > 0:
ma = anexadas.pop()
if ma not in visitados:
visitados.append(ma)
anexadas.extend(
[a.materia_anexada for a in Anexada.objects.filter(materia_principal=ma)])
else:
ciclo_list = visitados + [ma]
ciclos.append(ciclo_list)
"""
Remove ciclos repetidos (ou semanticamente equivalentes).
Exemplo: A -> B -> A e B -> A -> B
"""
ciclos_set = []
ciclos_unique = [e for e in ciclos if is_ciclo_unique(e, ciclos_set)]
return ciclos_unique
def is_ciclo_unique(ciclo, ciclos_set):
if set(ciclo) not in ciclos_set:
ciclos_set.append(set(ciclo))
return True
else:
return False
def anexados_ciclicos(ofMateriaLegislativa):
ciclicos = []
if ofMateriaLegislativa:
principais = Anexada.objects.values(
'materia_principal'
).annotate(
count=Count('materia_principal')
).filter(count__gt=0).order_by('-data_anexacao')
else:
principais = Anexado.objects.values(
'documento_principal'
).annotate(
count=Count('documento_principal')
).filter(count__gt=0).order_by('-data_anexacao')
for principal in principais:
anexados_total = []
if ofMateriaLegislativa:
anexados = Anexada.objects.filter(
materia_principal=principal['materia_principal']
).order_by('-data_anexacao')
else:
anexados = Anexado.objects.filter(
documento_principal=principal['documento_principal']
).order_by('-data_anexacao')
anexados_temp = list(anexados)
while anexados_temp:
anexado = anexados_temp.pop()
if ofMateriaLegislativa:
if anexado.materia_anexada not in anexados_total:
if not principal['materia_principal'] == anexado.materia_anexada.pk:
anexados_total.append(anexado.materia_anexada)
anexados_anexado = Anexada.objects.filter(
materia_principal=anexado.materia_anexada
)
anexados_temp.extend(anexados_anexado)
else:
ciclicos.append(
(anexado.data_anexacao, anexado.materia_principal, anexado.materia_anexada))
else:
if anexado.documento_anexado not in anexados_total:
if not principal['documento_principal'] == anexado.documento_anexado.pk:
anexados_total.append(anexado.documento_anexado)
anexados_anexado = Anexado.objects.filter(
documento_principal=anexado.documento_anexado
)
anexados_temp.extend(anexados_anexado)
else:
ciclicos.append(
(anexado.data_anexacao, anexado.documento_principal, anexado.documento_anexado))
return ciclicos
class ListarAnexadosCiclicosView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/anexados_ciclicos.html'
context_object_name = 'anexados_ciclicos'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return anexados_ciclicos(False)
def get_context_data(self, **kwargs):
context = super(
ListarAnexadosCiclicosView, self
).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages
)
context['NO_ENTRIES_MSG'] = 'Nenhum encontrado.'
return context
class ListarAnexadasCiclicasView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/anexadas_ciclicas.html'
context_object_name = 'anexadas_ciclicas'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return materias_anexadas_ciclicas()
def get_context_data(self, **kwargs):
context = super(
ListarAnexadasCiclicasView, self
).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages
)
context['NO_ENTRIES_MSG'] = 'Nenhuma encontrada.'
return context
def legislatura_infindavel():
return Legislatura.objects.filter(data_fim__isnull=True).order_by('-numero')
class ListarLegislaturaInfindavelView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/legislatura_infindavel.html'
context_object_name = 'legislatura_infindavel'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return legislatura_infindavel()
def get_context_data(self, **kwargs):
context = super(
ListarLegislaturaInfindavelView, self
).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhuma encontrada.'
return context
def bancada_comissao_autor_externo():
tipo_autor_externo = TipoAutor.objects.filter(descricao='Externo')
lista_bancada_autor_externo = []
for bancada in Bancada.objects.all().order_by('nome'):
autor_externo = bancada.autor.filter(tipo__in=tipo_autor_externo)
if autor_externo:
q_autor_externo = bancada.autor.get(tipo__in=tipo_autor_externo)
lista_bancada_autor_externo.append(
(q_autor_externo, bancada, 'Bancada', 'sistema/bancada')
)
lista_comissao_autor_externo = []
for comissao in Comissao.objects.all().order_by('nome'):
autor_externo = comissao.autor.filter(tipo__in=tipo_autor_externo)
if autor_externo:
q_autor_externo = comissao.autor.get(tipo__in=tipo_autor_externo)
lista_comissao_autor_externo.append(
(q_autor_externo, comissao, 'Comissão', 'comissao')
)
return lista_bancada_autor_externo + lista_comissao_autor_externo
class ListarBancadaComissaoAutorExternoView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/bancada_comissao_autor_externo.html'
context_object_name = 'bancada_comissao_autor_externo'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return bancada_comissao_autor_externo()
def get_context_data(self, **kwargs):
context = super(
ListarBancadaComissaoAutorExternoView, self
).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhuma encontrada.'
return context
def autores_duplicados():
return [autor for autor in Autor.objects.values('nome').annotate(count=Count('nome')).filter(count__gt=1)]
class ListarAutoresDuplicadosView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/autores_duplicados.html'
context_object_name = 'autores_duplicados'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return autores_duplicados()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.'
return context
def parlamentares_filiacoes_intersecao():
intersecoes = []
for parlamentar in Parlamentar.objects.all().order_by('nome_parlamentar'):
filiacoes = parlamentar.filiacao_set.all()
combinacoes = itertools.combinations(filiacoes, 2)
for c in combinacoes:
data_filiacao1 = c[0].data
data_desfiliacao1 = c[0].data_desfiliacao if c[0].data_desfiliacao else timezone.now(
).date()
data_filiacao2 = c[1].data
data_desfiliacao2 = c[1].data_desfiliacao if c[1].data_desfiliacao else timezone.now(
).date()
if data_filiacao1 and data_filiacao2:
exists = intervalos_tem_intersecao(
data_filiacao1, data_desfiliacao1,
data_filiacao2, data_desfiliacao2)
if exists:
intersecoes.append((parlamentar, c[0], c[1]))
return intersecoes
class ListarParlFiliacoesIntersecaoView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/parlamentares_filiacoes_intersecao.html'
context_object_name = 'parlamentares_filiacoes_intersecao'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return parlamentares_filiacoes_intersecao()
def get_context_data(self, **kwargs):
context = super(
ListarParlFiliacoesIntersecaoView, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.'
return context
def parlamentares_mandatos_intersecao():
intersecoes = []
for parlamentar in Parlamentar.objects.all().order_by('nome_parlamentar'):
mandatos = parlamentar.mandato_set.all()
combinacoes = itertools.combinations(mandatos, 2)
for c in combinacoes:
data_inicio_mandato1 = c[0].data_inicio_mandato
data_fim_mandato1 = c[0].data_fim_mandato if c[0].data_fim_mandato else timezone.now(
).date()
data_inicio_mandato2 = c[1].data_inicio_mandato
data_fim_mandato2 = c[1].data_fim_mandato if c[1].data_fim_mandato else timezone.now(
).date()
if data_inicio_mandato1 and data_inicio_mandato2:
exists = intervalos_tem_intersecao(
data_inicio_mandato1, data_fim_mandato1,
data_inicio_mandato2, data_fim_mandato2)
if exists:
intersecoes.append((parlamentar, c[0], c[1]))
return intersecoes
class ListarParlMandatosIntersecaoView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/parlamentares_mandatos_intersecao.html'
context_object_name = 'parlamentares_mandatos_intersecao'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return parlamentares_mandatos_intersecao()
def get_context_data(self, **kwargs):
context = super(
ListarParlMandatosIntersecaoView, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.'
return context
def parlamentares_duplicados():
return [parlamentar for parlamentar in Parlamentar.objects.values(
'nome_parlamentar').order_by('nome_parlamentar').annotate(count=Count(
'nome_parlamentar')).filter(count__gt=1)]
class ListarParlamentaresDuplicadosView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/parlamentares_duplicados.html'
context_object_name = 'parlamentares_duplicados'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return parlamentares_duplicados()
def get_context_data(self, **kwargs):
context = super(
ListarParlamentaresDuplicadosView, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.'
return context
def mandato_sem_data_inicio():
return Mandato.objects.filter(data_inicio_mandato__isnull=True).order_by('parlamentar')
def get_estatistica(request):
materias = MateriaLegislativa.objects.all()
normas = NormaJuridica.objects.all()
datas = [
materias.order_by(
'-data_ultima_atualizacao').values_list('data_ultima_atualizacao', flat=True)
.exclude(data_ultima_atualizacao__isnull=True).first(),
normas.order_by(
'-data_ultima_atualizacao').values_list('data_ultima_atualizacao', flat=True)
.exclude(data_ultima_atualizacao__isnull=True).first()
]
max_data = max(datas) if datas[0] and datas[1] else next(
iter([i for i in datas if i is not None]), '')
return JsonResponse({
"data_ultima_atualizacao": max_data,
"num_materias_legislativas": materias.count(),
"num_normas_juridicas ": normas.count(),
"num_parlamentares": Parlamentar.objects.all().count(),
"num_sessoes_plenarias": SessaoPlenaria.objects.all().count()
})
class ListarMandatoSemDataInicioView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/mandato_sem_data_inicio.html'
context_object_name = 'mandato_sem_data_inicio'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return mandato_sem_data_inicio()
def get_context_data(self, **kwargs):
context = super(
ListarMandatoSemDataInicioView, self
).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.'
return context
def filiacoes_sem_data_filiacao():
return Filiacao.objects.filter(data__isnull=True).order_by('parlamentar')
class ListarFiliacoesSemDataFiliacaoView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/filiacoes_sem_data_filiacao.html'
context_object_name = 'filiacoes_sem_data_filiacao'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return filiacoes_sem_data_filiacao()
def get_context_data(self, **kwargs):
context = super(
ListarFiliacoesSemDataFiliacaoView, self
).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhuma encontrada.'
return context
def materias_protocolo_inexistente():
materias = []
for materia in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False).order_by('-ano', 'numero'):
exists = Protocolo.objects.filter(
ano=materia.ano, numero=materia.numero_protocolo).exists()
if not exists:
materias.append(
(materia, materia.ano, materia.numero_protocolo))
return materias
class ListarMatProtocoloInexistenteView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/materias_protocolo_inexistente.html'
context_object_name = 'materias_protocolo_inexistente'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return materias_protocolo_inexistente()
def get_context_data(self, **kwargs):
context = super(
ListarMatProtocoloInexistenteView, self
).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhuma encontrada.'
return context
def protocolos_com_materias():
protocolos = {}
for m in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False).order_by('-ano', 'numero_protocolo'):
if Protocolo.objects.filter(numero=m.numero_protocolo, ano=m.ano).exists():
key = "{}/{}".format(m.numero_protocolo, m.ano)
val = protocolos.get(key, list())
val.append(m)
protocolos[key] = val
return [(v[0], len(v)) for (k, v) in protocolos.items() if len(v) > 1]
class ListarProtocolosComMateriasView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/protocolos_com_materias.html'
context_object_name = 'protocolos_com_materias'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return protocolos_com_materias()
def get_context_data(self, **kwargs):
context = super(
ListarProtocolosComMateriasView, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.'
return context
def protocolos_duplicados():
return [
protocolo for protocolo in Protocolo.objects.values(
'numero', 'ano').order_by('-ano', 'numero').annotate(total=Count('numero')).filter(total__gt=1)
]
class ListarProtocolosDuplicadosView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'base/protocolos_duplicados.html'
context_object_name = 'protocolos_duplicados'
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
return protocolos_duplicados()
def get_context_data(self, **kwargs):
context = super(
ListarProtocolosDuplicadosView, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context[
'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.'
return context
class UserCrud(Crud):
model = get_user_model()
class BaseMixin(Crud.BaseMixin):
list_field_names = [
'usuario', 'groups', 'is_active'
]
def openapi_url(self):
return ''
def resolve_url(self, suffix, args=None):
return reverse('sapl.base:%s' % self.url_name(suffix),
args=args)
def get_layout(self):
return super().get_layout(
'base/layouts.yaml'
)
def get_context_object_name(self, *args, **kwargs):
return None
class CreateView(Crud.CreateView):
form_class = UserAdminForm
layout_key = None
class UpdateView(Crud.UpdateView):
form_class = UserAdminForm
layout_key = None
def get_form_kwargs(self):
kwargs = Crud.UpdateView.get_form_kwargs(self)
kwargs['user_session'] = self.request.user
granular = self.request.GET.get('granular', None)
if not granular is None:
kwargs['granular'] = granular
return kwargs
class DetailView(Crud.DetailView):
layout_key = 'UserDetail'
def hook_usuario(self, obj):
return 'Usuário', '{}<br><small>{}</small>'.format(
obj.get_full_name() or '...',
obj.email
)
def hook_auth_token(self, obj):
return 'Token', str(obj.auth_token) if hasattr(obj, 'auth_token') else '&nbsp;'
def hook_username(self, obj):
return 'username', obj.username
def get_context_data(self, **kwargs):
context = Crud.DetailView.get_context_data(self, **kwargs)
context['title'] = '{} <i>({})</i><br><small>{}</small>'.format(
self.object.get_full_name() or '...',
self.object.username,
self.object.email
)
return context
@property
def extras_url(self):
btns = [
(
'{}?granular'.format(reverse('sapl.base:user_update',
kwargs={'pk': self.object.pk})),
'btn-outline-primary',
_('Edição granular')
)
]
return btns
class ListView(Crud.ListView):
form_search_class = ListWithSearchForm
paginate_by = 256
def get_context_data(self, **kwargs):
context = Crud.ListView.get_context_data(self, **kwargs)
context['subnav_template_name'] = None
context['title'] = _('Usuários')
return context
def hook_header_usuario(self, *args, **kwargs):
return 'Usuário'
def hook_header_groups(self, *args, **kwargs):
return 'Grupos'
def hook_header_is_active(self, *args, **kwargs):
return 'Ativo'
def hook_usuario(self, *args, **kwargs):
return '{} <i>({})</i><br><small>{}</small>'.format(
args[0].get_full_name() or '...',
args[0].username,
args[0].email
), args[2]
def get_queryset(self):
qs = self.model.objects.all()
q_param = self.request.GET.get('q', '')
if q_param:
q = Q(first_name__icontains=q_param)
q |= Q(last_name__icontains=q_param)
q |= Q(email__icontains=q_param)
q |= Q(username__icontains=q_param)
q |= Q(groups__name__icontains=q_param)
qs = qs.filter(q)
return qs.distinct('id').order_by('-id')
class CasaLegislativaCrud(CrudAux):
model = CasaLegislativa
class BaseMixin(CrudAux.BaseMixin):
list_field_names = ['codigo', 'nome', 'sigla']
form_class = CasaLegislativaForm
class ListView(CrudAux.ListView):
def get(self, request, *args, **kwargs):
casa = get_casalegislativa()
if casa:
return HttpResponseRedirect(
reverse('sapl.base:casalegislativa_detail',
kwargs={'pk': casa.pk}))
else:
return HttpResponseRedirect(
reverse('sapl.base:casalegislativa_create'))
class DetailView(CrudAux.DetailView):
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(
reverse('sapl.base:casalegislativa_update',
kwargs={'pk': self.kwargs['pk']}))
class HelpTopicView(TemplateView):
logger = logging.getLogger(__name__)
def get_template_names(self):
username = self.request.user.username
topico = self.kwargs['topic']
try:
self.logger.debug('user=' + username +
'. Tentando obter template %s.html.' % topico)
get_template('ajuda/%s.html' % topico)
except TemplateDoesNotExist as e:
self.logger.error(
'user=' + username + '. Erro ao obter template {}.html. Template não existe. '.format(topico) + str(e))
raise Http404()
return ['ajuda/%s.html' % topico]
class AppConfigCrud(CrudAux):
model = AppConfig
class BaseMixin(CrudAux.BaseMixin):
form_class = ConfiguracoesAppForm
list_url = ''
create_url = ''
def form_valid(self, form):
recibo_prop_atual = AppConfig.objects.last().receber_recibo_proposicao
recibo_prop_novo = self.request.POST['receber_recibo_proposicao']
if recibo_prop_novo == 'False' and recibo_prop_atual:
props = Proposicao.objects.filter(
hash_code='', data_recebimento__isnull=True).exclude(data_envio__isnull=True)
for prop in props:
try:
self.gerar_hash(prop)
except ValidationError as e:
form.add_error('receber_recibo_proposicao', e)
msg = _(
"Não foi possível mudar a configuração porque a Proposição {} não possui texto original vinculado!".format(prop))
messages.error(self.request, msg)
return super().form_invalid(form)
return super().form_valid(form)
def gerar_hash(self, inst):
if inst.texto_original:
try:
inst.hash_code = gerar_hash_arquivo(
inst.texto_original.path, str(inst.pk))
inst.save()
except IOError:
raise ValidationError(
"Existem proposicoes com arquivos inexistentes.")
elif inst.texto_articulado.exists():
ta = inst.texto_articulado.first()
inst.hash_code = 'P' + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(inst.pk)
inst.save()
class CreateView(CrudAux.CreateView):
def get(self, request, *args, **kwargs):
app_config = AppConfig.objects.first()
if not app_config:
app_config = AppConfig()
app_config.save()
return HttpResponseRedirect(
reverse('sapl.base:appconfig_update',
kwargs={'pk': app_config.pk}))
class UpdateView(CrudAux.UpdateView):
form_class = ConfiguracoesAppForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = self.model._meta.verbose_name
return context
def get(self, request, *args, **kwargs):
if 'jsidd' in request.GET:
return self.json_simular_identificacao_de_documentos(request, *args, **kwargs)
return super().get(request, *args, **kwargs)
def json_simular_identificacao_de_documentos(self, request, *args, **kwargs):
DocumentoAdministrativo = apps.get_model(
'protocoloadm',
'DocumentoAdministrativo'
)
d = DocumentoAdministrativo.objects.order_by('-id').first()
jsidd = request.GET.get('jsidd', '')
values = {
'{sigla}': d.tipo.sigla if d else 'OF',
'{nome}': d.tipo.descricao if d else 'Ofício',
'{numero}': f'{d.numero:0>3}' if d else '001',
'{ano}': f'{d.ano}' if d else str(timezone.now().year),
'{complemento}': d.complemento if d else 'GAB',
'{assunto}': d.assunto if d else 'Simulação de Identificação de Documentos'
}
result = DocumentoAdministrativo.mask_to_str(values, jsidd)
return JsonResponse({
'jsidd': result[0],
'error': list(result[1])
})
def form_valid(self, form):
numeracao = AppConfig.objects.last().sequencia_numeracao_protocolo
numeracao_antiga = AppConfig.objects.last().inicio_numeracao_protocolo
self.object = form.save()
numeracao_nova = self.object.inicio_numeracao_protocolo
if numeracao_nova != numeracao_antiga:
if numeracao == 'A':
numero_max = Protocolo.objects.filter(
ano=timezone.now().year
).aggregate(Max('numero'))['numero__max']
elif numeracao == 'L':
legislatura = Legislatura.objects.filter(
data_inicio__year__lte=timezone.now().year,
data_fim__year__gte=timezone.now().year
).first()
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
data_inicio_utc = from_date_to_datetime_utc(data_inicio)
data_fim_utc = from_date_to_datetime_utc(data_fim)
numero_max = Protocolo.objects.filter(
Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) |
Q(
timestamp__isnull=False, timestamp__gte=data_inicio_utc,
timestamp__lte=data_fim_utc
) | Q(
timestamp_data_hora_manual__isnull=False,
timestamp_data_hora_manual__gte=data_inicio_utc,
timestamp_data_hora_manual__lte=data_fim_utc,
)
).aggregate(Max('numero'))['numero__max']
elif numeracao == 'U':
numero_max = Protocolo.objects.all().aggregate(
Max('numero')
)['numero__max']
ultimo_numero_cadastrado = int(numero_max) if numero_max else 0
if numeracao_nova <= ultimo_numero_cadastrado and numeracao != 'U':
msg = "O novo início da numeração de protocolo entrará em vigor na " \
"próxima sequência, pois já existe protocolo cadastrado com " \
"número superior ou igual ao número inicial definido."
messages.warning(self.request, msg)
return super().form_valid(form)
class ListView(CrudAux.ListView):
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(reverse('sapl.base:appconfig_create'))
class DetailView(CrudAux.DetailView):
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(reverse('sapl.base:appconfig_create'))
class DeleteView(CrudAux.DeleteView):
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(reverse('sapl.base:appconfig_create'))
class SaplSearchView(SearchView):
results_per_page = 10
def __init__(self, template=None, load_all=True, form_class=None, searchqueryset=None, results_per_page=None):
super().__init__(
template=template,
load_all=load_all,
form_class=SaplSearchForm,
searchqueryset=None,
results_per_page=results_per_page
)
def get_context(self):
context = super(SaplSearchView, self).get_context()
data = self.request.GET or self.request.POST
data = data.copy()
if 'models' in self.request.GET:
models = self.request.GET.getlist('models')
else:
models = []
context['models'] = ''
context['is_paginated'] = True
page_obj = context['page']
context['page_obj'] = page_obj
paginator = context['paginator']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
if 'page' in data:
del data['page']
context['filter_url'] = (
'&' + data.urlencode()) if len(data) > 0 else ''
for m in models:
context['models'] = context['models'] + '&models=' + m
return context
class AlterarSenha(FormView):
from sapl.settings import LOGIN_URL
form_class = AlterarSenhaForm
template_name = 'base/alterar_senha.html'
success_url = LOGIN_URL
def get_initial(self):
initial = super(AlterarSenha, self).get_initial()
initial['username'] = self.request.user
return initial
def form_valid(self, form):
new_password = form.cleaned_data['new_password1']
user = self.request.user
user.set_password(new_password)
user.save()
return super().form_valid(form)
STATIC_LOGO = os.path.join(settings.STATIC_URL, 'img/logo.png')
class LogotipoView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
casa = get_casalegislativa()
logo = casa and casa.logotipo and casa.logotipo.name
return os.path.join(settings.MEDIA_URL, logo) if logo else STATIC_LOGO
def filtro_campos(dicionario):
chaves_desejadas = ['ementa',
'ano',
'numero',
'em_tramitacao',
'data_apresentacao',
'apelido',
'indexacao',
'data_publicacao',
'data',
'data_vigencia']
del_list = []
for key in dicionario.keys():
if key not in chaves_desejadas:
del_list = del_list + [key]
for key in del_list:
del dicionario[key]
return dicionario
def pesquisa_textual(request):
if 'q' not in request.GET:
return JsonResponse({'total': 0,
'resultados': []})
results = SearchQuerySet().filter(content=request.GET['q'])
json_dict = {
'total': results.count(),
'parametros': request.GET['q'],
'resultados': [],
}
for e in results:
sec_dict = {}
try:
sec_dict['pk'] = e.object.pk
except:
# Index and db are out of sync. Object has been deleted from
# database
continue
dici = filtro_campos(e.object.__dict__)
sec_dict['objeto'] = str(dici)
sec_dict['text'] = str(e.object.ementa)
sec_dict['model'] = str(type(e.object))
json_dict['resultados'].append(sec_dict)
return JsonResponse(json_dict)
class RelatorioHistoricoTramitacaoAdmView(RelatorioMixin, FilterView):
model = DocumentoAdministrativo
filterset_class = RelatorioHistoricoTramitacaoAdmFilterSet
template_name = 'base/RelatorioHistoricoTramitacaoAdm_filter.html'
relatorio = relatorio_historico_tramitacao_adm
def get_context_data(self, **kwargs):
context = super(RelatorioHistoricoTramitacaoAdmView,
self).get_context_data(**kwargs)
context['title'] = _(
'Histórico de Tramitações de Documento Administrativo')
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
context['data_tramitacao'] = (self.request.GET['tramitacaoadministrativo__data_tramitacao_0'] + ' - ' +
self.request.GET['tramitacaoadministrativo__data_tramitacao_1'])
if self.request.GET['tipo']:
tipo = self.request.GET['tipo']
context['tipo'] = (
str(TipoDocumentoAdministrativo.objects.get(id=tipo)))
else:
context['tipo'] = ''
if self.request.GET['tramitacaoadministrativo__status']:
tramitacao_status = self.request.GET['tramitacaoadministrativo__status']
context['tramitacaoadministrativo__status'] = (
str(StatusTramitacaoAdministrativo.objects.get(id=tramitacao_status)))
else:
context['tramitacaoadministrativo__status'] = ''
if self.request.GET['tramitacaoadministrativo__unidade_tramitacao_local']:
context['tramitacaoadministrativo__unidade_tramitacao_local'] = \
(str(UnidadeTramitacao.objects.get(
id=self.request.GET['tramitacaoadministrativo__unidade_tramitacao_local'])))
else:
context['tramitacaoadministrativo__unidade_tramitacao_local'] = ''
if self.request.GET['tramitacaoadministrativo__unidade_tramitacao_destino']:
context['tramitacaoadministrativo__unidade_tramitacao_destino'] = \
(str(UnidadeTramitacao.objects.get(
id=self.request.GET['tramitacaoadministrativo__unidade_tramitacao_destino'])))
else:
context['tramitacaoadministrativo__unidade_tramitacao_destino'] = ''
return context
class RelatorioNormasPorAutorView(RelatorioMixin, FilterView):
model = NormaJuridica
filterset_class = RelatorioNormasPorAutorFilterSet
template_name = 'base/RelatorioNormasPorAutor_filter.html'
relatorio = relatorio_normas_por_autor
def get_filterset_kwargs(self, filterset_class):
super().get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _('Normas por Autor')
if not self.filterset.form.is_valid():
return context
qtdes = {}
for tipo in TipoNormaJuridica.objects.all():
qs = context['object_list']
qtde = len(qs.filter(tipo_id=tipo.id))
if qtde > 0:
qtdes[tipo] = qtde
context['qtdes'] = qtdes
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
if self.request.GET['tipo']:
tipo = int(self.request.GET['tipo'])
context['tipo'] = (
str(TipoNormaJuridica.objects.get(id=tipo)))
else:
context['tipo'] = ''
if self.request.GET['autorianorma__autor']:
autor = int(self.request.GET['autorianorma__autor'])
context['autor'] = (str(Autor.objects.get(id=autor)))
else:
context['autor'] = ''
context['periodo'] = (
self.request.GET['data_0'] +
' - ' + self.request.GET['data_1'])
return context