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.
1001 lines
39 KiB
1001 lines
39 KiB
import json
|
|
import logging
|
|
from datetime import datetime
|
|
|
|
from django.contrib import messages
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
|
|
from django.core.urlresolvers import reverse, reverse_lazy
|
|
from django.db.models import F, Q
|
|
from django.db.models.aggregates import Count
|
|
from django.http import JsonResponse
|
|
from django.http.response import HttpResponseRedirect
|
|
from django.templatetags.static import static
|
|
from django.utils import timezone
|
|
from django.utils.datastructures import MultiValueDictKeyError
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from django.views.decorators.clickjacking import xframe_options_exempt
|
|
from django.views.generic import FormView
|
|
from django.views.generic.edit import UpdateView
|
|
|
|
from sapl.base.forms import SessaoLegislativaForm
|
|
from sapl.base.models import Autor
|
|
from sapl.comissoes.models import Participacao
|
|
from sapl.crud.base import (RP_CHANGE, RP_DETAIL, RP_LIST, Crud, CrudAux,
|
|
CrudBaseForListAndDetailExternalAppView,
|
|
MasterDetailCrud)
|
|
from sapl.materia.models import Autoria, Proposicao, Relatoria
|
|
from sapl.parlamentares.apps import AppConfig
|
|
from sapl.utils import parlamentares_ativos
|
|
|
|
from .forms import (FiliacaoForm, FrenteForm, LegislaturaForm, MandatoForm,
|
|
ParlamentarCreateForm, ParlamentarForm, VotanteForm)
|
|
from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa,
|
|
Dependente, Filiacao, Frente, Legislatura, Mandato,
|
|
NivelInstrucao, Parlamentar, Partido, SessaoLegislativa,
|
|
SituacaoMilitar, TipoAfastamento, TipoDependente, Votante)
|
|
|
|
CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa')
|
|
PartidoCrud = CrudAux.build(Partido, 'partidos')
|
|
TipoDependenteCrud = CrudAux.build(TipoDependente, 'tipo_dependente')
|
|
NivelInstrucaoCrud = CrudAux.build(NivelInstrucao, 'nivel_instrucao')
|
|
TipoAfastamentoCrud = CrudAux.build(TipoAfastamento, 'tipo_afastamento')
|
|
TipoMilitarCrud = CrudAux.build(SituacaoMilitar, 'tipo_situa_militar')
|
|
|
|
DependenteCrud = MasterDetailCrud.build(
|
|
Dependente, 'parlamentar', 'dependente')
|
|
|
|
class SessaoLegislativaCrud(CrudAux):
|
|
model = SessaoLegislativa
|
|
|
|
class CreateView(CrudAux.CreateView):
|
|
form_class = SessaoLegislativaForm
|
|
|
|
class UpdateView(CrudAux.UpdateView):
|
|
form_class = SessaoLegislativaForm
|
|
|
|
class VotanteView(MasterDetailCrud):
|
|
model = Votante
|
|
parent_field = 'parlamentar'
|
|
UpdateView = None
|
|
|
|
class BaseMixin(MasterDetailCrud.BaseMixin):
|
|
list_field_names = ['user']
|
|
|
|
class CreateView(MasterDetailCrud.CreateView):
|
|
form_class = VotanteForm
|
|
layout_key = None
|
|
|
|
class DetailView(MasterDetailCrud.DetailView):
|
|
|
|
def detail_create_url(self):
|
|
return None
|
|
|
|
class DeleteView(MasterDetailCrud.DeleteView):
|
|
|
|
def delete(self, *args, **kwargs):
|
|
obj = self.get_object()
|
|
obj.delete()
|
|
return HttpResponseRedirect(
|
|
reverse('sapl.parlamentares:votante_list',
|
|
kwargs={'pk': obj.parlamentar.pk}))
|
|
|
|
|
|
class FrenteList(MasterDetailCrud):
|
|
model = Frente
|
|
is_m2m = True
|
|
parent_field = 'parlamentares'
|
|
CreateView, UpdateView, DeleteView = None, None, None
|
|
|
|
class BaseMixin(Crud.PublicMixin, MasterDetailCrud.BaseMixin):
|
|
list_field_names = ['nome', 'data_criacao', 'data_extincao']
|
|
@classmethod
|
|
def url_name(cls, suffix):
|
|
return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix)
|
|
|
|
|
|
class RelatoriaParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
|
|
model = Relatoria
|
|
parent_field = 'parlamentar'
|
|
help_topic = 'tramitacao_relatoria'
|
|
namespace = AppConfig.name
|
|
|
|
class BaseMixin(CrudBaseForListAndDetailExternalAppView.BaseMixin):
|
|
|
|
@classmethod
|
|
def url_name(cls, suffix):
|
|
return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix)
|
|
|
|
|
|
class ProposicaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
|
|
model = Proposicao
|
|
list_field_names = ['tipo', 'descricao']
|
|
parent_field = 'autor__parlamentar_set'
|
|
namespace = AppConfig.name
|
|
|
|
class BaseMixin(CrudBaseForListAndDetailExternalAppView.BaseMixin):
|
|
|
|
@classmethod
|
|
def url_name(cls, suffix):
|
|
return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix)
|
|
|
|
class ListView(CrudBaseForListAndDetailExternalAppView.ListView):
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = CrudBaseForListAndDetailExternalAppView\
|
|
.ListView.get_context_data(self, **kwargs)
|
|
return context
|
|
|
|
def get_queryset(self):
|
|
return super().get_queryset().filter(
|
|
data_envio__isnull=False,
|
|
data_recebimento__isnull=False,
|
|
cancelado=False)
|
|
|
|
class DetailView(CrudBaseForListAndDetailExternalAppView.DetailView):
|
|
|
|
def get_queryset(self):
|
|
return super().get_queryset().filter(
|
|
cancelado=False)
|
|
|
|
@property
|
|
def extras_url(self):
|
|
|
|
if self.object.texto_articulado.exists():
|
|
ta = self.object.texto_articulado.first()
|
|
yield (str(reverse_lazy(
|
|
'sapl.compilacao:ta_text',
|
|
kwargs={'ta_id': ta.pk})) + '?back_type=history',
|
|
'btn-success',
|
|
_('Texto Eletrônico'))
|
|
|
|
|
|
class ParticipacaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
|
|
model = Participacao
|
|
parent_field = 'parlamentar'
|
|
namespace = AppConfig.name
|
|
list_field_names = ['composicao__comissao__nome', 'cargo__nome', (
|
|
'composicao__periodo__data_inicio', 'composicao__periodo__data_fim')]
|
|
|
|
class BaseMixin(CrudBaseForListAndDetailExternalAppView.BaseMixin):
|
|
|
|
@classmethod
|
|
def url_name(cls, suffix):
|
|
return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix)
|
|
|
|
class ListView(CrudBaseForListAndDetailExternalAppView.ListView):
|
|
ordering = ('-composicao__periodo')
|
|
|
|
def get_rows(self, object_list):
|
|
"""
|
|
FIXME:
|
|
Este metodo não será necessário quando get_rows for refatorada
|
|
"""
|
|
|
|
comissoes = []
|
|
for p in object_list:
|
|
if p.cargo.nome != 'Relator':
|
|
comissao = [
|
|
(p.composicao.comissao.nome, reverse(
|
|
'sapl.comissoes:comissao_detail', kwargs={
|
|
'pk': p.composicao.comissao.pk})),
|
|
(p.cargo.nome, None),
|
|
(p.composicao.periodo.data_inicio.strftime(
|
|
"%d/%m/%Y") + ' a ' +
|
|
p.composicao.periodo.data_fim.strftime("%d/%m/%Y"),
|
|
None)
|
|
]
|
|
comissoes.append(comissao)
|
|
return comissoes
|
|
|
|
def get_headers(self):
|
|
return [_('Comissão'), _('Cargo'), _('Período de participação'), ]
|
|
|
|
|
|
class ColigacaoCrud(CrudAux):
|
|
model = Coligacao
|
|
help_topic = 'coligacao'
|
|
|
|
class ListView(CrudAux.ListView):
|
|
ordering = ('legislatura', '-nome')
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(ColigacaoCrud.ListView, self).get_context_data(
|
|
kwargs=kwargs)
|
|
rows = context['rows']
|
|
coluna_votos_recebidos = 2
|
|
for row in rows:
|
|
if not row[coluna_votos_recebidos][0]:
|
|
row[coluna_votos_recebidos] = ('0', None)
|
|
|
|
return context
|
|
|
|
class DetailView(CrudAux.DetailView):
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(kwargs=kwargs)
|
|
coligacao = context['coligacao']
|
|
if not coligacao.numero_votos:
|
|
coligacao.numero_votos = '0'
|
|
|
|
context['subnav_template_name'] = \
|
|
'parlamentares/subnav_coligacao.yaml'
|
|
|
|
return context
|
|
|
|
class UpdateView(CrudAux.UpdateView):
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(UpdateView, self).get_context_data(kwargs=kwargs)
|
|
|
|
context['subnav_template_name'] = \
|
|
'parlamentares/subnav_coligacao.yaml'
|
|
|
|
return context
|
|
|
|
|
|
def json_date_convert(date):
|
|
"""
|
|
:param date: recebe a data de uma chamada ajax no formato de
|
|
string "dd/mm/yyyy"
|
|
:return:
|
|
"""
|
|
|
|
return datetime.strptime(date, "%d/%m/%Y").date()
|
|
|
|
|
|
def frente_atualiza_lista_parlamentares(request):
|
|
"""
|
|
:param request: recebe os parâmetros do GET da chamada Ajax
|
|
:return: retorna a lista atualizada dos parlamentares
|
|
"""
|
|
ativos = json.loads(request.GET['ativos'])
|
|
|
|
parlamentares = Parlamentar.objects.all()
|
|
|
|
if ativos:
|
|
if 'data_criacao' in request.GET and request.GET['data_criacao']:
|
|
data_criacao = json_date_convert(request.GET['data_criacao'])
|
|
|
|
if 'data_extincao' in request.GET and request.GET['data_extincao']:
|
|
data_extincao = json_date_convert(request.GET['data_extincao'])
|
|
parlamentares = parlamentares_ativos(data_criacao,
|
|
data_extincao)
|
|
else:
|
|
parlamentares = parlamentares_ativos(data_criacao)
|
|
|
|
parlamentares_list = [(p.id, p.__str__()) for p in parlamentares]
|
|
|
|
return JsonResponse({'parlamentares_list': parlamentares_list})
|
|
|
|
|
|
def parlamentares_frente_selected(request):
|
|
"""
|
|
:return: Lista com o id dos parlamentares em uma frente
|
|
"""
|
|
logger = logging.getLogger(__name__)
|
|
username = request.user.username
|
|
try:
|
|
logger.info("user=" + username + ". Tentando objet objeto Frente com id={}.".format(request.GET['frente_id']))
|
|
frente = Frente.objects.get(id=int(request.GET['frente_id']))
|
|
except ObjectDoesNotExist:
|
|
logger.error("user=" + username + ". Frente buscada (id={}) não existe. Retornada lista vazia.".format(request.GET['frente_id']))
|
|
lista_parlamentar_id = []
|
|
else:
|
|
logger.info("user=" + username + ". Frente (id={}) encontrada com sucesso.".format(request.GET['frente_id']))
|
|
lista_parlamentar_id = frente.parlamentares.all().values_list(
|
|
'id', flat=True)
|
|
return JsonResponse({'id_list': list(lista_parlamentar_id)})
|
|
|
|
|
|
class FrenteCrud(CrudAux):
|
|
model = Frente
|
|
help_topic = 'tipo_situa_militar'
|
|
public = [RP_DETAIL, RP_LIST]
|
|
list_field_names = ['nome', 'data_criacao', 'data_extincao', 'parlamentares']
|
|
|
|
|
|
class CreateView(Crud.CreateView):
|
|
form_class = FrenteForm
|
|
|
|
def form_valid(self, form):
|
|
return super(Crud.CreateView, self).form_valid(form)
|
|
|
|
class UpdateView(Crud.UpdateView):
|
|
form_class = FrenteForm
|
|
|
|
|
|
|
|
class MandatoCrud(MasterDetailCrud):
|
|
model = Mandato
|
|
parent_field = 'parlamentar'
|
|
public = [RP_DETAIL, RP_LIST]
|
|
list_field_names = ['legislatura',
|
|
'votos_recebidos',
|
|
'coligacao',
|
|
'coligacao__numero_votos',
|
|
'titular']
|
|
|
|
class ListView(MasterDetailCrud.ListView):
|
|
ordering = ('-legislatura__numero')
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
rows = context['rows']
|
|
|
|
coluna_coligacao = 2
|
|
coluna_votos_recebidos = 3
|
|
for row in rows:
|
|
if not row[coluna_coligacao][0]:
|
|
row[coluna_coligacao] = (' ', None)
|
|
|
|
if not row[coluna_votos_recebidos][0]:
|
|
row[coluna_votos_recebidos] = (' ', None)
|
|
|
|
return context
|
|
|
|
class CreateView(MasterDetailCrud.CreateView):
|
|
form_class = MandatoForm
|
|
|
|
def get_initial(self):
|
|
return {'parlamentar': Parlamentar.objects.get(
|
|
pk=self.kwargs['pk'])}
|
|
|
|
|
|
class ComposicaoColigacaoCrud(MasterDetailCrud):
|
|
model = ComposicaoColigacao
|
|
parent_field = 'coligacao'
|
|
help_topic = 'coligacao'
|
|
|
|
class BaseMixin(MasterDetailCrud.BaseMixin):
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data()
|
|
context['subnav_template_name'] = \
|
|
'parlamentares/subnav_coligacao.yaml'
|
|
return context
|
|
|
|
class ListView(MasterDetailCrud.ListView):
|
|
ordering = '-partido__sigla'
|
|
|
|
|
|
class LegislaturaCrud(CrudAux):
|
|
|
|
model = Legislatura
|
|
help_topic = 'legislatura'
|
|
|
|
class CreateView(CrudAux.CreateView):
|
|
logger = logging.getLogger(__name__)
|
|
form_class = LegislaturaForm
|
|
|
|
def get_initial(self):
|
|
username = self.request.user.username
|
|
try:
|
|
self.logger.error("user=" + username + ". Tentando obter última Legislatura.")
|
|
ultima_legislatura = Legislatura.objects.latest('numero')
|
|
numero = ultima_legislatura.numero + 1
|
|
except Legislatura.DoesNotExist:
|
|
self.logger.error("user=" + username + ". Legislatura não encontrada. Número definido como 1.")
|
|
numero = 1
|
|
return {'numero': numero}
|
|
|
|
class UpdateView(CrudAux.UpdateView):
|
|
form_class = LegislaturaForm
|
|
|
|
class DetailView(CrudAux.DetailView):
|
|
|
|
def has_permission(self):
|
|
return True
|
|
|
|
@xframe_options_exempt
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
class ListView(CrudAux.ListView):
|
|
|
|
def has_permission(self):
|
|
return True
|
|
|
|
@xframe_options_exempt
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
|
|
class FiliacaoCrud(MasterDetailCrud):
|
|
model = Filiacao
|
|
parent_field = 'parlamentar'
|
|
help_topic = 'filiacoes_partidarias'
|
|
public = [RP_LIST, RP_DETAIL]
|
|
|
|
class BaseMixin(MasterDetailCrud.BaseMixin):
|
|
ordering = '-data'
|
|
|
|
class UpdateView(MasterDetailCrud.UpdateView):
|
|
form_class = FiliacaoForm
|
|
|
|
class CreateView(MasterDetailCrud.CreateView):
|
|
form_class = FiliacaoForm
|
|
|
|
|
|
class ParlamentarCrud(Crud):
|
|
model = Parlamentar
|
|
public = [RP_LIST, RP_DETAIL]
|
|
|
|
class BaseMixin(Crud.BaseMixin):
|
|
ordered_list = False
|
|
list_field_names = [
|
|
'nome_parlamentar',
|
|
'filiacao_atual',
|
|
'ativo',
|
|
'mandato_titular']
|
|
|
|
class DetailView(Crud.DetailView):
|
|
|
|
def get_template_names(self):
|
|
if self.request.user.has_perm(self.permission(RP_CHANGE)):
|
|
if 'iframe' not in self.request.GET:
|
|
if not self.request.session.get('iframe'):
|
|
return ['crud/detail.html']
|
|
elif self.request.GET['iframe'] == '0':
|
|
return ['crud/detail.html']
|
|
|
|
return ['parlamentares/parlamentar_perfil_publico.html']
|
|
|
|
@xframe_options_exempt
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
class UpdateView(Crud.UpdateView):
|
|
form_class = ParlamentarForm
|
|
|
|
layout_key = 'ParlamentarUpdate'
|
|
|
|
class CreateView(Crud.CreateView):
|
|
form_class = ParlamentarCreateForm
|
|
|
|
layout_key = 'ParlamentarCreate'
|
|
|
|
def form_valid(self, form):
|
|
"""
|
|
Reimplementa form_valid devido ao save de ParlamentarCreateForm
|
|
ser específico, sendo necessário isolar padrão do crud que aciona
|
|
form.save(commit=False) para registrar dados de auditoria se
|
|
o model implementá-los, bem como de container se também implement.
|
|
"""
|
|
return super(Crud.CreateView, self).form_valid(form)
|
|
|
|
class ListView(Crud.ListView):
|
|
template_name = "parlamentares/parlamentares_list.html"
|
|
paginate_by = None
|
|
logger = logging.getLogger(__name__)
|
|
|
|
@xframe_options_exempt
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
def take_legislatura_id(self):
|
|
username = self.request.user.username
|
|
try:
|
|
self.logger.debug("user=" + username + ". Tentando obter id da legislatura.")
|
|
return int(self.request.GET['pk'])
|
|
except:
|
|
self.logger.error("user=" + username + ". Legislatura não possui ID. Buscando em todas as entradas.")
|
|
legislaturas = Legislatura.objects.all()
|
|
for l in legislaturas:
|
|
if l.atual():
|
|
return l.id
|
|
if legislaturas:
|
|
return legislaturas[0].id
|
|
return -1
|
|
|
|
def get_queryset(self):
|
|
self.logger = logging.getLogger(__name__)
|
|
queryset = super().get_queryset()
|
|
legislatura_id = self.take_legislatura_id()
|
|
# Pelo menos uma casa legislativa criou uma
|
|
# legislatura de numero zero, o que é um absurdo
|
|
username = self.request.user.username
|
|
if legislatura_id >= 0:
|
|
return queryset.filter(
|
|
mandato__legislatura_id=legislatura_id).annotate(
|
|
mandato_titular=F('mandato__titular'))
|
|
else:
|
|
try:
|
|
self.logger.debug("user=" + username + ". Tentando obter o mais recente registro do objeto Legislatura.")
|
|
l = Legislatura.objects.all().order_by(
|
|
'-data_inicio').first()
|
|
except ObjectDoesNotExist:
|
|
self.logger.error("user=" + username + ". Objeto não encontrado. Retornando todos os registros.")
|
|
return Legislatura.objects.all()
|
|
else:
|
|
self.logger.info("user=" + username + ". Objeto encontrado com sucesso.")
|
|
if l is None:
|
|
return Legislatura.objects.all()
|
|
return queryset.filter(mandato__legislatura_id=l).annotate(
|
|
mandato_titular=F('mandato__titular'))
|
|
|
|
def get_headers(self):
|
|
return [_('Parlamentar'), _('Partido'),
|
|
_('Ativo?'), _('Titular?')]
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
username = self.request.user.username
|
|
|
|
# Adiciona legislatura para filtrar parlamentares
|
|
legislaturas = Legislatura.objects.all().order_by('-numero')
|
|
context['legislaturas'] = legislaturas
|
|
context['legislatura_id'] = self.take_legislatura_id()
|
|
|
|
for row in context['rows']:
|
|
|
|
# Pega o Parlamentar por meio da pk
|
|
parlamentar = Parlamentar.objects.get(
|
|
id=(row[0][1].split('/')[-1]))
|
|
|
|
for index, value in enumerate(row):
|
|
row[index] += (None if index else parlamentar,)
|
|
|
|
# Pega a Legislatura
|
|
legislatura = Legislatura.objects.get(
|
|
id=context['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
|
|
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)
|
|
|
|
# Caso encontre UMA filiação nessas condições
|
|
else:
|
|
self.logger.info("user=" + username + ". Filiação encontrada com sucesso.")
|
|
row[1] = (filiacao.partido.sigla, None, None)
|
|
|
|
return context
|
|
|
|
|
|
class ParlamentarMateriasView(FormView):
|
|
template_name = "parlamentares/materias.html"
|
|
success_url = reverse_lazy('sapl.parlamentares:parlamentar_materia')
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def get_autoria(self, resultset):
|
|
autoria = {}
|
|
total_autoria = 0
|
|
|
|
for i in resultset:
|
|
row = autoria.get(i['materia__ano'], [])
|
|
columns = (i['materia__tipo__pk'],
|
|
i['materia__tipo__sigla'],
|
|
i['materia__tipo__descricao'],
|
|
int(i['total']))
|
|
row.append(columns)
|
|
autoria[i['materia__ano']] = row
|
|
total_autoria += columns[3]
|
|
autoria = sorted(autoria.items(), reverse=True)
|
|
return autoria, total_autoria
|
|
|
|
@xframe_options_exempt
|
|
def get(self, request, *args, **kwargs):
|
|
parlamentar_pk = kwargs['pk']
|
|
username = request.user.username
|
|
try:
|
|
self.logger.debug("user=" + username + ". Tentando obter Autor (object_id={}).".format(parlamentar_pk))
|
|
autor = Autor.objects.get(
|
|
content_type=ContentType.objects.get_for_model(Parlamentar),
|
|
object_id=parlamentar_pk)
|
|
except ObjectDoesNotExist:
|
|
mensagem = _('Este Parlamentar (pk={}) não é Autor de matéria.'.format(parlamentar_pk))
|
|
self.logger.error("user=" + username + ". Este Parlamentar (pk={}) não é Autor de matéria.".format(parlamentar_pk))
|
|
messages.add_message(request, messages.ERROR, mensagem)
|
|
return HttpResponseRedirect(
|
|
reverse(
|
|
'sapl.parlamentares:parlamentar_detail',
|
|
kwargs={'pk': parlamentar_pk}))
|
|
|
|
autoria = Autoria.objects.filter(
|
|
autor=autor, primeiro_autor=True).values(
|
|
'materia__ano',
|
|
'materia__tipo__pk',
|
|
'materia__tipo__sigla',
|
|
'materia__tipo__descricao').annotate(
|
|
total=Count('materia__tipo__pk')).order_by(
|
|
'-materia__ano', 'materia__tipo')
|
|
|
|
coautoria = Autoria.objects.filter(
|
|
autor=autor, primeiro_autor=False).values(
|
|
'materia__ano',
|
|
'materia__tipo__pk',
|
|
'materia__tipo__sigla',
|
|
'materia__tipo__descricao').annotate(
|
|
total=Count('materia__tipo__pk')).order_by(
|
|
'-materia__ano', 'materia__tipo')
|
|
|
|
autor_list = self.get_autoria(autoria)
|
|
coautor_list = self.get_autoria(coautoria)
|
|
|
|
parlamentar_pk = autor.autor_related.pk
|
|
nome_parlamentar = autor.autor_related.nome_parlamentar
|
|
|
|
return self.render_to_response({'autor_pk': autor.pk,
|
|
'root_pk': parlamentar_pk,
|
|
'autoria': autor_list,
|
|
'coautoria': coautor_list,
|
|
'nome_parlamentar': nome_parlamentar
|
|
})
|
|
|
|
|
|
class MesaDiretoraView(FormView):
|
|
template_name = 'parlamentares/composicaomesa_form.html'
|
|
success_url = reverse_lazy('sapl.parlamentares:mesa_diretora')
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def get_template_names(self):
|
|
if self.request.user.has_perm('parlamentares.change_composicaomesa'):
|
|
if 'iframe' not in self.request.GET:
|
|
if not self.request.session.get('iframe'):
|
|
return 'parlamentares/composicaomesa_form.html'
|
|
elif self.request.GET['iframe'] == '0':
|
|
return 'parlamentares/composicaomesa_form.html'
|
|
|
|
return 'parlamentares/public_composicaomesa_form.html'
|
|
|
|
# Essa função avisa quando se pode compor uma Mesa Legislativa
|
|
def validation(self, request):
|
|
username = request.user.username
|
|
self.logger.info('user=' + username + '. Não há nenhuma Sessão Legislativa cadastrada. ' +
|
|
'Só é possível compor uma Mesa Diretora quando ' +
|
|
'há uma Sessão Legislativa cadastrada.')
|
|
mensagem = _('Não há nenhuma Sessão Legislativa cadastrada. ' +
|
|
'Só é possível compor uma Mesa Diretora quando ' +
|
|
'há uma Sessão Legislativa cadastrada.')
|
|
messages.add_message(request, messages.INFO, mensagem)
|
|
|
|
return self.render_to_response(
|
|
{'legislaturas': Legislatura.objects.all(
|
|
).order_by('-numero'),
|
|
'legislatura_selecionada': Legislatura.objects.last(),
|
|
'cargos_vagos': CargoMesa.objects.all()})
|
|
|
|
@xframe_options_exempt
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
if (not Legislatura.objects.exists() or
|
|
not SessaoLegislativa.objects.exists()):
|
|
return self.validation(request)
|
|
|
|
legislatura = Legislatura.objects.first()
|
|
sessoes = SessaoLegislativa.objects.filter(
|
|
legislatura=legislatura).order_by("data_inicio")
|
|
|
|
year = timezone.now().year
|
|
month = timezone.now().month
|
|
|
|
sessao_atual = sessoes.filter(data_inicio__year__lte=year).exclude(
|
|
data_inicio__gt=timezone.now()).order_by('-data_inicio').first()
|
|
|
|
mesa = sessao_atual.composicaomesa_set.all().order_by('cargo_id') if sessao_atual else []
|
|
|
|
cargos_ocupados = [m.cargo for m in mesa]
|
|
cargos = CargoMesa.objects.all()
|
|
cargos_vagos = list(set(cargos) - set(cargos_ocupados))
|
|
|
|
parlamentares = legislatura.mandato_set.all()
|
|
parlamentares_ocupados = [m.parlamentar for m in mesa]
|
|
parlamentares_vagos = list(
|
|
set(
|
|
[p.parlamentar for p in parlamentares]) - set(
|
|
parlamentares_ocupados))
|
|
|
|
# Se todos os cargos estiverem ocupados, a listagem de parlamentares
|
|
# deve ser renderizada vazia
|
|
if not cargos_vagos:
|
|
parlamentares_vagos = []
|
|
|
|
return self.render_to_response(
|
|
{'legislaturas': Legislatura.objects.all(
|
|
).order_by('-numero'),
|
|
'legislatura_selecionada': legislatura,
|
|
'sessoes': sessoes,
|
|
'sessao_selecionada': sessao_atual,
|
|
'composicao_mesa': mesa,
|
|
'parlamentares': parlamentares_vagos,
|
|
'cargos_vagos': cargos_vagos
|
|
})
|
|
|
|
|
|
def altera_field_mesa(request):
|
|
"""
|
|
Essa função lida com qualquer alteração nos campos
|
|
da Mesa Diretora, após qualquer
|
|
operação (Legislatura/Sessão/Inclusão/Remoção),
|
|
atualizando os campos após cada alteração
|
|
"""
|
|
logger = logging.getLogger(__name__)
|
|
legislatura = request.GET['legislatura']
|
|
sessoes = SessaoLegislativa.objects.filter(
|
|
legislatura=legislatura).order_by('-data_inicio')
|
|
username = request.user.username
|
|
|
|
if not sessoes:
|
|
return JsonResponse({'msg': ('Nenhuma sessão encontrada!', 0)})
|
|
|
|
# Verifica se já tem uma sessão selecionada. Ocorre quando
|
|
# é alterado o campo de sessão ou feita alguma operação
|
|
# de inclusão/remoção.
|
|
if request.GET['sessao']:
|
|
sessao_selecionada = request.GET['sessao']
|
|
# Caso a mudança tenha sido no campo legislatura, a sessão
|
|
# atual deve ser a primeira daquela legislatura
|
|
else:
|
|
year = timezone.now().year
|
|
try:
|
|
logger.debug("user=" + username + ". Tentando obter id de sessoes com data_inicio.ano={}.".format(year))
|
|
sessao_selecionada = sessoes.get(data_inicio__year=year).id
|
|
except ObjectDoesNotExist:
|
|
logger.error("user=" + username + ". Id de sessoes com data_inicio.ano={} não encontrado. "
|
|
"Selecionado o ID da primeira sessão.".format(year))
|
|
sessao_selecionada = sessoes.first().id
|
|
|
|
# Atualiza os componentes da view após a mudança
|
|
composicao_mesa = ComposicaoMesa.objects.filter(
|
|
sessao_legislativa=sessao_selecionada).order_by('cargo_id')
|
|
|
|
cargos_ocupados = [m.cargo for m in composicao_mesa]
|
|
cargos = CargoMesa.objects.all()
|
|
cargos_vagos = list(set(cargos) - set(cargos_ocupados))
|
|
|
|
parlamentares = Legislatura.objects.get(
|
|
id=legislatura).mandato_set.all()
|
|
parlamentares_ocupados = [m.parlamentar for m in composicao_mesa]
|
|
parlamentares_vagos = list(
|
|
set(
|
|
[p.parlamentar for p in parlamentares]) - set(
|
|
parlamentares_ocupados))
|
|
|
|
lista_sessoes = [(s.id, s.__str__()) for s in sessoes]
|
|
lista_composicao = [(c.id, c.parlamentar.__str__(),
|
|
c.cargo.__str__()) for c in composicao_mesa]
|
|
lista_parlamentares = [(
|
|
p.id, p.__str__()) for p in parlamentares_vagos]
|
|
lista_cargos = [(c.id, c.__str__()) for c in cargos_vagos]
|
|
|
|
return JsonResponse(
|
|
{'lista_sessoes': lista_sessoes,
|
|
'lista_composicao': lista_composicao,
|
|
'lista_parlamentares': lista_parlamentares,
|
|
'lista_cargos': lista_cargos,
|
|
'sessao_selecionada': sessao_selecionada,
|
|
'msg': ('', 1)})
|
|
|
|
|
|
def insere_parlamentar_composicao(request):
|
|
"""
|
|
Essa função lida com qualquer operação de inserção
|
|
na composição da Mesa Diretora
|
|
"""
|
|
logger = logging.getLogger(__name__)
|
|
username = request.user.username
|
|
if request.user.has_perm(
|
|
'%s.add_%s' % (
|
|
AppConfig.label, ComposicaoMesa._meta.model_name)):
|
|
|
|
composicao = ComposicaoMesa()
|
|
|
|
try:
|
|
logger.debug("user=" + username + ". Tentando obter SessaoLegislativa com id={}.".format(request.POST['sessao']))
|
|
composicao.sessao_legislativa = SessaoLegislativa.objects.get(
|
|
id=int(request.POST['sessao']))
|
|
except MultiValueDictKeyError:
|
|
logger.error("user=" + username + ". 'MultiValueDictKeyError', nenhuma sessão foi inserida!")
|
|
return JsonResponse({'msg': ('Nenhuma sessão foi inserida!', 0)})
|
|
|
|
try:
|
|
logger.debug("user=" + username + ". Tentando obter Parlamentar com id={}.".format(request.POST['parlamentar']))
|
|
composicao.parlamentar = Parlamentar.objects.get(
|
|
id=int(request.POST['parlamentar']))
|
|
except MultiValueDictKeyError:
|
|
logger.error("user=" + username + ". 'MultiValueDictKeyError', nenhum parlamentar foi inserido!")
|
|
return JsonResponse({
|
|
'msg': ('Nenhum parlamentar foi inserido!', 0)})
|
|
|
|
try:
|
|
logger.info("user=" + username + ". Tentando obter CargoMesa com id={}.".format(request.POST['cargo']))
|
|
composicao.cargo = CargoMesa.objects.get(
|
|
id=int(request.POST['cargo']))
|
|
parlamentar_ja_inserido = ComposicaoMesa.objects.filter(
|
|
sessao_legislativa_id=composicao.sessao_legislativa.id,
|
|
cargo_id=composicao.cargo.id).exists()
|
|
|
|
if parlamentar_ja_inserido:
|
|
return JsonResponse({'msg': ('Parlamentar já inserido!', 0)})
|
|
|
|
composicao.save()
|
|
|
|
except MultiValueDictKeyError:
|
|
logger.error("user=" + username + ". 'MultiValueDictKeyError', nenhum cargo foi inserido!")
|
|
return JsonResponse({'msg': ('Nenhum cargo foi inserido!', 0)})
|
|
|
|
logger.info("user=" + username + ". Parlamentar inserido com sucesso!")
|
|
return JsonResponse({'msg': ('Parlamentar inserido com sucesso!', 1)})
|
|
|
|
else:
|
|
logger.error("user=" + username + " não tem permissão para esta operação!")
|
|
return JsonResponse(
|
|
{'msg': ('Você não tem permissão para esta operação!', 0)})
|
|
|
|
|
|
def remove_parlamentar_composicao(request):
|
|
"""
|
|
Essa função lida com qualquer operação de remoção
|
|
na composição da Mesa Diretora
|
|
"""
|
|
logger = logging.getLogger(__name__)
|
|
username = request.user.username
|
|
if request.POST and request.user.has_perm(
|
|
'%s.delete_%s' % (
|
|
AppConfig.label, ComposicaoMesa._meta.model_name)):
|
|
|
|
if 'composicao_mesa' in request.POST:
|
|
try:
|
|
logger.debug("user=" + username + ". Tentando obter ComposicaoMesa com id={}.".format(request.POST['composicao_mesa']))
|
|
composicao = ComposicaoMesa.objects.get(
|
|
id=request.POST['composicao_mesa'])
|
|
except ObjectDoesNotExist:
|
|
logger.error("user=" + username + ". ComposicaoMesa com id={} não encontrada, portanto não pode ser removida."
|
|
.format(request.POST['composicao_mesa']))
|
|
return JsonResponse(
|
|
{'msg': (
|
|
'Composição da Mesa não pôde ser removida!', 0)})
|
|
|
|
composicao.delete()
|
|
|
|
logger.info("user=" + username + ". ComposicaoMesa com id={} excluido com sucesso!".format(request.POST['composicao_mesa']))
|
|
return JsonResponse(
|
|
{'msg': (
|
|
'Parlamentar excluido com sucesso!', 1)})
|
|
else:
|
|
logger.info("user=" + username + ". Nenhum parlamentar escolhido para ser excluído.")
|
|
return JsonResponse(
|
|
{'msg': (
|
|
'Selecione algum parlamentar para ser excluido!', 0)})
|
|
|
|
|
|
def partido_parlamentar_sessao_legislativa(sessao, parlamentar):
|
|
"""
|
|
Função para descobrir o partido do parlamentar durante
|
|
o período de uma dada Sessão Legislativa
|
|
"""
|
|
|
|
# As condições para mostrar a filiação são:
|
|
# A data de filiacao deve ser menor que a data de fim
|
|
# da sessao legislativa e data de desfiliação deve nula, ou maior,
|
|
# ou igual a data de fim da sessao
|
|
logger = logging.getLogger(__name__)
|
|
try:
|
|
logger.debug("Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) "
|
|
"ou (data<={} e data_desfiliacao=Null))."
|
|
.format(sessao.data_fim, sessao.data_fim, sessao.data_fim))
|
|
|
|
logger.info("Tentando obter filiação correspondente.")
|
|
filiacao = parlamentar.filiacao_set.get(Q(
|
|
data__lte=sessao.data_fim,
|
|
data_desfiliacao__gte=sessao.data_fim) | Q(
|
|
data__lte=sessao.data_fim,
|
|
data_desfiliacao__isnull=True))
|
|
|
|
# Caso não exista filiação com essas condições
|
|
except ObjectDoesNotExist:
|
|
logger.error("Filiação do parlamentar com (data<={} e data_desfiliacao>={}) "
|
|
"ou (data<={} e data_desfiliacao=Null não encontrada. Retornando vazio."
|
|
.format(sessao.data_fim, sessao.data_fim, sessao.data_fim))
|
|
return ''
|
|
|
|
# Caso exista mais de uma filiação nesse intervalo
|
|
# Entretanto, NÃO DEVE OCORRER
|
|
except MultipleObjectsReturned:
|
|
logger.error("O Parlamentar com (data<={} e data_desfiliacao>={}) "
|
|
"ou (data<={} e data_desfiliacao=Null possui duas filiações conflitantes."
|
|
.format(sessao.data_fim, sessao.data_fim, sessao.data_fim))
|
|
return 'O Parlamentar possui duas filiações conflitantes'
|
|
|
|
# Caso encontre UMA filiação nessas condições
|
|
else:
|
|
logger.info("Filiação do parlamentar com (data<={} e data_desfiliacao>={}) "
|
|
"ou (data<={} e data_desfiliacao=Null encontrada com sucesso."
|
|
.format(sessao.data_fim, sessao.data_fim, sessao.data_fim))
|
|
return filiacao.partido.sigla
|
|
|
|
|
|
def altera_field_mesa_public_view(request):
|
|
"""
|
|
Essa função lida com qualquer alteração nos campos
|
|
da Mesa Diretora para usuários anônimos,
|
|
atualizando os campos após cada alteração
|
|
"""
|
|
logger = logging.getLogger(__name__)
|
|
username = request.user.username
|
|
legislatura = request.GET['legislatura']
|
|
sessoes = SessaoLegislativa.objects.filter(
|
|
legislatura=legislatura).order_by('-data_inicio')
|
|
|
|
if not sessoes:
|
|
return JsonResponse({'msg': ('Nenhuma sessão encontrada!', 0)})
|
|
|
|
# Verifica se já tem uma sessão selecionada. Ocorre quando
|
|
# é alterado o campo de sessão
|
|
if request.GET['sessao']:
|
|
sessao_selecionada = request.GET['sessao']
|
|
# Caso a mudança tenha sido no campo legislatura, a sessão
|
|
# atual deve ser a primeira daquela legislatura
|
|
else:
|
|
try:
|
|
year = timezone.now().year
|
|
logger.info("user=" + username + ". Tentando obter sessões com data_inicio.ano = {}.".format(year))
|
|
sessao_selecionada = sessoes.get(data_inicio__year=year).id
|
|
except ObjectDoesNotExist:
|
|
logger.error("user=" + username + ". Sessões não encontradas com com data_inicio.ano = {}. "
|
|
"Selecionado o id da primeira sessão.".format(year))
|
|
sessao_selecionada = sessoes.first().id
|
|
|
|
# Atualiza os componentes da view após a mudança
|
|
lista_sessoes = [(s.id, s.__str__()) for s in sessoes]
|
|
|
|
composicao_mesa = ComposicaoMesa.objects.filter(
|
|
sessao_legislativa=sessao_selecionada).order_by('cargo_id')
|
|
|
|
cargos_ocupados = [(m.cargo.id,
|
|
m.cargo.__str__()) for m in composicao_mesa]
|
|
|
|
parlamentares_ocupados = [(m.parlamentar.id,
|
|
m.parlamentar.__str__()
|
|
) for m in composicao_mesa]
|
|
|
|
lista_fotos = []
|
|
lista_partidos = []
|
|
|
|
sessao = SessaoLegislativa.objects.get(id=sessao_selecionada)
|
|
for p in parlamentares_ocupados:
|
|
parlamentar = Parlamentar.objects.get(id=p[0])
|
|
lista_partidos.append(
|
|
partido_parlamentar_sessao_legislativa(sessao,
|
|
parlamentar))
|
|
if parlamentar.fotografia:
|
|
lista_fotos.append(parlamentar.fotografia.url)
|
|
else:
|
|
lista_fotos.append(None)
|
|
|
|
return JsonResponse(
|
|
{'lista_parlamentares': parlamentares_ocupados,
|
|
'lista_partidos': lista_partidos,
|
|
'lista_cargos': cargos_ocupados,
|
|
'lista_sessoes': lista_sessoes,
|
|
'lista_fotos': lista_fotos,
|
|
'sessao_selecionada': sessao_selecionada,
|
|
'msg': ('', 1)})
|
|
|