Browse Source

Fix #2506 aprimorar extrato titulos e nome (#2539)

* Gerar e aprimorar pdf de extrato

Colocando nome completo nos extratos e acresentando cargos nas assinaturas.
Fix #2514
Fix #2506

Refatorando classe ResumoView (extraindo metodos)

Adicionando testes a refatoração feita na classe ResumoView

Iniciando a geração do pdf de extrato da reunião

Aprimorando relatorio do extrato da reunião;
Fix #2514

Colocando numero de votos

Arrumando header e tabelas do relatorio de extrato

Colocando rodape no documento de extrato

Melhorando formatação da documentação de extrato de reunião

Melhorando assinaturas e removendo codigo morto

Adicionando nome de parlaentares nos votos nominais Fix #2514 Fix #2502 Fix #2506

* Melhorando visualização do documento de extrato da reunião

* Gerar e aprimorar pdf de extrato

Colocando nome completo nos extratos e acresentando cargos nas assinaturas.
Fix #2514
Fix #2506

Refatorando classe ResumoView (extraindo metodos)

Adicionando testes a refatoração feita na classe ResumoView

Iniciando a geração do pdf de extrato da reunião

Aprimorando relatorio do extrato da reunião;
Fix #2514

Colocando numero de votos

Arrumando header e tabelas do relatorio de extrato

Colocando rodape no documento de extrato

Melhorando formatação da documentação de extrato de reunião

Melhorando assinaturas e removendo codigo morto

Adicionando nome de parlaentares nos votos nominais Fix #2514 Fix #2502 Fix #2506

* Melhorando visualização do documento de extrato da reunião

* Arruma assinatura presentes

* Colocando pagina de assinaturas em uma folha separado
pull/2636/head
Ulysses Lara 6 years ago
committed by Edward
parent
commit
6abe23936d
  1. 5
      sapl/relatorios/urls.py
  2. 73
      sapl/relatorios/views.py
  3. 103
      sapl/sessao/tests/test_sessao_view.py
  4. 524
      sapl/sessao/views.py
  5. 62
      sapl/static/sapl/css/header-relatorio.css
  6. 56
      sapl/static/sapl/css/relatorio.css
  7. 31
      sapl/templates/relatorios/header_ata.html
  8. 101
      sapl/templates/relatorios/relatorio_ata.html
  9. 12
      sapl/templates/sessao/blocos_ata/assinaturas.html
  10. 4
      sapl/templates/sessao/blocos_ata/lista_presenca.html
  11. 2
      sapl/templates/sessao/blocos_ata/lista_presenca_ordem_dia.html
  12. 52
      sapl/templates/sessao/blocos_ata/materias_ordem_dia.html
  13. 2
      sapl/templates/sessao/blocos_ata/mesa_diretora.html
  14. 2
      sapl/templates/sessao/blocos_ata/oradores_expediente.html
  15. 2
      sapl/templates/sessao/blocos_ata/oradores_explicacoes.html
  16. 12
      sapl/templates/sessao/resumo_ata.html

5
sapl/relatorios/urls.py

@ -5,7 +5,8 @@ from .views import (relatorio_capa_processo,
relatorio_documento_administrativo, relatorio_espelho,
relatorio_etiqueta_protocolo, relatorio_materia,
relatorio_ordem_dia, relatorio_pauta_sessao,
relatorio_protocolo, relatorio_sessao_plenaria)
relatorio_protocolo, relatorio_sessao_plenaria,
resumo_ata_pdf)
app_name = AppConfig.name
@ -28,4 +29,6 @@ urlpatterns = [
relatorio_etiqueta_protocolo, name='relatorio_etiqueta_protocolo'),
url(r'^relatorios/pauta-sessao/(?P<pk>\d+)/$',
relatorio_pauta_sessao, name='relatorio_pauta_sessao'),
url(r'^relatorios/(?P<pk>\d+)/resumo_ata$',
resumo_ata_pdf, name='resumo_ata_pdf'),
]

73
sapl/relatorios/views.py

@ -2,12 +2,15 @@ from datetime import datetime as dt
import html
import logging
import re
import tempfile
from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404, HttpResponse
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.template.loader import render_to_string
from sapl.settings import MEDIA_URL
from sapl.base.models import Autor, CasaLegislativa
from sapl.comissoes.models import Comissao
from sapl.materia.models import (Autoria, MateriaLegislativa, Numeracao,
@ -24,12 +27,20 @@ from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao,
from sapl.settings import STATIC_ROOT
from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data
from sapl.sessao.views import (get_identificação_basica, get_mesa_diretora,
get_presenca_sessao,get_expedientes,
get_materias_expediente,get_oradores_expediente,
get_presenca_ordem_do_dia,get_materias_ordem_do_dia,
get_oradores_explicações_pessoais, get_ocorrencias_da_sessão)
from .templates import (pdf_capa_processo_gerar,
pdf_documento_administrativo_gerar, pdf_espelho_gerar,
pdf_etiqueta_protocolo_gerar, pdf_materia_gerar,
pdf_ordem_dia_gerar, pdf_pauta_sessao_gerar,
pdf_protocolo_gerar, pdf_sessao_plenaria_gerar)
from weasyprint import HTML, CSS
def get_kwargs_params(request, fields):
kwargs = {}
@ -1199,3 +1210,65 @@ def get_pauta_sessao(sessao, casa):
return (lst_expediente_materia,
lst_votacao,
inf_basicas_dic)
def make_pdf(base_url,main_template,header_template,main_css='',header_css=''):
html = HTML(base_url=base_url, string=main_template)
main_doc = html.render(stylesheets=[])
def get_page_body(boxes):
for box in boxes:
if box.element_tag == 'body':
return box
return get_page_body(box.all_children())
# Template of header
html = HTML(base_url=base_url,string=header_template)
header = html.render(stylesheets=[CSS(string='@page {size:A4; margin:1cm;}')])
header_page = header.pages[0]
header_body = get_page_body(header_page._page_box.all_children())
header_body = header_body.copy_with_children(header_body.all_children())
for page in main_doc.pages:
page_body = get_page_body(page._page_box.all_children())
page_body.children += header_body.all_children()
pdf_file = main_doc.write_pdf()
return pdf_file
def resumo_ata_pdf(request,pk):
base_url = request.build_absolute_uri()
casa = CasaLegislativa.objects.first()
rodape = ' '.join(get_rodape(casa))
sessao_plenaria = SessaoPlenaria.objects.get(pk=pk)
context = {}
context.update(get_identificação_basica(sessao_plenaria))
context.update(get_mesa_diretora(sessao_plenaria))
context.update(get_presenca_sessao(sessao_plenaria))
context.update(get_expedientes(sessao_plenaria))
context.update(get_materias_expediente(sessao_plenaria))
context.update(get_oradores_expediente(sessao_plenaria))
context.update(get_presenca_ordem_do_dia(sessao_plenaria))
context.update(get_materias_ordem_do_dia(sessao_plenaria))
context.update(get_oradores_explicações_pessoais(sessao_plenaria))
context.update(get_ocorrencias_da_sessão(sessao_plenaria))
context.update({'object':sessao_plenaria})
context.update({'data': dt.today().strftime('%d/%m/%Y')})
context.update({'rodape':rodape})
header_context = {"casa":casa, 'logotipo':casa.logotipo, 'MEDIA_URL': MEDIA_URL}
html_template = render_to_string('relatorios/relatorio_ata.html',context)
html_header = render_to_string('relatorios/header_ata.html', header_context)
pdf_file = make_pdf(base_url=base_url,main_template=html_template,header_template=html_header)
response = HttpResponse(content_type='application/pdf;')
response['Content-Disposition'] = 'inline; filename=relatorio.pdf'
response['Content-Transfer-Encoding'] = 'binary'
response.write(pdf_file)
return response

103
sapl/sessao/tests/test_sessao_view.py

@ -4,7 +4,21 @@ from django.utils.translation import ugettext_lazy as _
from model_mommy import mommy
from sapl.parlamentares.models import Legislatura, SessaoLegislativa
from sapl.sessao.models import SessaoPlenaria, TipoSessaoPlenaria
from sapl.sessao.models import (SessaoPlenaria, TipoSessaoPlenaria,
IntegranteMesa, SessaoPlenariaPresenca,
JustificativaAusencia, ExpedienteSessao,
TipoExpediente, ExpedienteMateria,
Orador, OcorrenciaSessao)
from sapl.parlamentares.models import Parlamentar, CargoMesa, Filiacao
from sapl.sessao.views import (get_identificação_basica, get_conteudo_multimidia,
get_mesa_diretora, get_presenca_sessao,
get_expedientes, get_materias_expediente,
get_oradores_expediente, get_presenca_ordem_do_dia,
get_materias_ordem_do_dia, get_oradores_explicações_pessoais,
get_ocorrencias_da_sessão
)
@pytest.mark.django_db(transaction=False)
@ -47,3 +61,90 @@ def test_incluir_sessao_errors(admin_client):
[_('Este campo é obrigatório.')])
assert (response.context_data['form'].errors['hora_inicio'] ==
[_('Este campo é obrigatório.')])
@pytest.mark.django_db(transaction=False)
class TestResumoView():
def setup(self):
self.sessao_plenaria = mommy.make(SessaoPlenaria)
self.parlamentar = mommy.make(Parlamentar)
self.cargo_mesa = mommy.make(CargoMesa)
self.integrante_mesa = IntegranteMesa(sessao_plenaria=self.sessao_plenaria,
parlamentar=self.parlamentar,
cargo=self.cargo_mesa)
self.integrante_mesa.save()
def test_get_identificação_basica(self):
id_basica = get_identificação_basica(self.sessao_plenaria)
info_basica = id_basica['basica']
assert info_basica[0] == 'Tipo de Sessão: ' + str(self.sessao_plenaria.tipo)
data_inicio = self.sessao_plenaria.data_inicio
abertura = data_inicio.strftime('%d/%m/%Y') if data_inicio else ''
assert info_basica[1] == 'Abertura: ' + abertura +' - '+ self.sessao_plenaria.hora_inicio
data_fim = self.sessao_plenaria.data_fim
encerramento = data_fim.strftime('%d/%m/%Y') + ' -' if data_fim else ''
assert info_basica[2] == 'Encerramento: ' + encerramento +' '+ self.sessao_plenaria.hora_fim
def test_get_conteudo_multimidia(self):
multimidia = get_conteudo_multimidia(self.sessao_plenaria)
url_audio = _('Audio: Indisponível')
multimidia_video = _('Video: Indisponível')
if self.sessao_plenaria.url_audio:
url_audio = _('Audio: ') + str(sessao_plenaria.url_audio)
if self.sessao_plenaria.url_video:
multimidia_video = _('Video: ') + str(sessao_plenaria.url_video)
assert multimidia == {'multimidia_audio':url_audio,
'multimidia_video':multimidia_video}
def test_get_mesa_diretora(self):
mesa = get_mesa_diretora(self.sessao_plenaria)
assert mesa == {'mesa':[{
'cargo': self.cargo_mesa,
'parlamentar': self.parlamentar
}]}
def test_get_presenca_sessao(self):
justificativa = mommy.make(JustificativaAusencia,sessao_plenaria=self.sessao_plenaria)
presenca = mommy.make(SessaoPlenariaPresenca,sessao_plenaria=self.sessao_plenaria)
resposta_presenca = get_presenca_sessao(self.sessao_plenaria)
assert resposta_presenca['presenca_sessao'] == [presenca.parlamentar]
assert resposta_presenca['justificativa_ausencia'][0] == justificativa
def test_get_expedientes(self):
tipo_expediente = mommy.make(TipoExpediente)
expediente = mommy.make(ExpedienteSessao,sessao_plenaria=self.sessao_plenaria,tipo=tipo_expediente)
resposta_expediente = get_expedientes(self.sessao_plenaria)
assert resposta_expediente['expedientes'] == [{
'conteudo': expediente.conteudo,
'tipo': tipo_expediente
}]
def test_get_materias_expediente(self):
pass
def test_get_oradores_explicações_pessoais(self):
parlamentar = mommy.make(Parlamentar)
partido_sigla = mommy.make(Filiacao, parlamentar=parlamentar)
orador = mommy.make(Orador,sessao_plenaria=self.sessao_plenaria,parlamentar=parlamentar)
resultado_get_oradores = get_oradores_explicações_pessoais(self.sessao_plenaria)
assert resultado_get_oradores['oradores_explicacoes'] == [{
'numero_ordem': orador.numero_ordem,
'parlamentar': parlamentar,
'sgl_partido': partido_sigla.partido.sigla
}]
def test_get_ocorrencias_da_sessão(self):
ocorrencia = mommy.make(OcorrenciaSessao, sessao_plenaria=self.sessao_plenaria)
resultado_get_ocorrencia = get_ocorrencias_da_sessão(self.sessao_plenaria)
assert resultado_get_ocorrencia['ocorrencias_da_sessao'][0] == ocorrencia

524
sapl/sessao/views.py

@ -1294,137 +1294,290 @@ def get_turno(turno):
else:
return ''
def get_identificação_basica(sessao_plenaria):
# =====================================================================
# Identificação Básica
data_inicio = sessao_plenaria.data_inicio
abertura = data_inicio.strftime('%d/%m/%Y') if data_inicio else ''
data_fim = sessao_plenaria.data_fim
encerramento = data_fim.strftime('%d/%m/%Y') + ' -' if data_fim else ''
return({'basica': [
_('Tipo de Sessão: %(tipo)s') % {'tipo': sessao_plenaria.tipo},
_('Abertura: %(abertura)s - %(hora_inicio)s') % {
'abertura': abertura, 'hora_inicio': sessao_plenaria.hora_inicio},
_('Encerramento: %(encerramento)s %(hora_fim)s') % {
'encerramento': encerramento, 'hora_fim': sessao_plenaria.hora_fim}
]})
def get_conteudo_multimidia(sessao_plenaria):
context = {}
if sessao_plenaria.url_audio:
context['multimidia_audio'] = _('Audio: ') + str(sessao_plenaria.url_audio)
else:
context['multimidia_audio'] = _('Audio: Indisponível')
if sessao_plenaria.url_video:
context['multimidia_video'] = _('Video: ') + str(sessao_plenaria.url_video)
else:
context['multimidia_video'] = _('Video: Indisponível')
return context
class ResumoView(DetailView):
template_name = 'sessao/resumo.html'
model = SessaoPlenaria
logger = logging.getLogger(__name__)
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
# =====================================================================
# Identificação Básica
data_inicio = self.object.data_inicio
abertura = data_inicio.strftime('%d/%m/%Y') if data_inicio else ''
data_fim = self.object.data_fim
encerramento = data_fim.strftime('%d/%m/%Y') + ' -' if data_fim else ''
def get_mesa_diretora(sessao_plenaria):
mesa = IntegranteMesa.objects.filter(sessao_plenaria=sessao_plenaria)
integrantes = []
for m in mesa:
parlamentar = Parlamentar.objects.get(
id=m.parlamentar_id)
cargo = CargoMesa.objects.get(
id=m.cargo_id)
integrante = {'parlamentar': parlamentar, 'cargo': cargo}
integrantes.append(integrante)
return ({'mesa': ordenar_integrantes_por_cargo(integrantes)})
def get_presenca_sessao(sessao_plenaria):
presencas = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')
parlamentares_sessao = [p.parlamentar for p in presencas]
ausentes_sessao = JustificativaAusencia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')
return ({'presenca_sessao': parlamentares_sessao,
'justificativa_ausencia': ausentes_sessao})
def get_expedientes(sessao_plenaria):
expediente = ExpedienteSessao.objects.filter(
sessao_plenaria_id=sessao_plenaria.id).order_by('tipo__nome')
expedientes = []
for e in expediente:
tipo = TipoExpediente.objects.get(id=e.tipo_id)
conteudo = e.conteudo
ex = {'tipo': tipo, 'conteudo': conteudo}
expedientes.append(ex)
return ({'expedientes': expedientes})
def get_materias_expediente(sessao_plenaria):
materias = ExpedienteMateria.objects.filter(
sessao_plenaria_id=sessao_plenaria.id)
materias_expediente = []
for m in materias:
ementa = m.materia.ementa
titulo = m.materia
numero = m.numero_ordem
tramitacao = m.materia.tramitacao_set.last()
turno = None
context.update({'basica': [
_('Tipo de Sessão: %(tipo)s') % {'tipo': self.object.tipo},
_('Abertura: %(abertura)s - %(hora_inicio)s') % {
'abertura': abertura, 'hora_inicio': self.object.hora_inicio},
_('Encerramento: %(encerramento)s %(hora_fim)s') % {
'encerramento': encerramento, 'hora_fim': self.object.hora_fim}
]})
# =====================================================================
# Conteúdo Multimídia
if self.object.url_audio:
context.update({'multimidia_audio':
_('Audio: ') + str(self.object.url_audio)})
else:
context.update({'multimidia_audio': _('Audio: Indisponível')})
if self.object.url_video:
context.update({'multimidia_video':
_('Video: ') + str(self.object.url_video)})
if tramitacao:
turno = get_turno(tramitacao.turno)
rv = m.registrovotacao_set.first()
rp = m.retiradapauta_set.filter(materia=m.materia).first()
if rv:
resultado = rv.tipo_resultado_votacao.nome
resultado_observacao = rv.observacao
elif rp:
resultado = rp.tipo_de_retirada.descricao
resultado_observacao = rp.observacao
else:
context.update({'multimidia_video': _('Video: Indisponível')})
# =====================================================================
# Mesa Diretora
mesa = IntegranteMesa.objects.filter(
sessao_plenaria=self.object)
resultado = _('Matéria não votada')
resultado_observacao = _(' ')
autoria = Autoria.objects.filter(materia_id=m.materia_id)
autor = [str(x.autor) for x in autoria]
mat = {'ementa': ementa,
'titulo': titulo,
'numero': numero,
'turno': turno,
'resultado': resultado,
'resultado_observacao': resultado_observacao,
'autor': autor,
'numero_protocolo': m.materia.numero_protocolo,
'numero_processo': m.materia.numeracao_set.last(),
'observacao': m.observacao
}
materias_expediente.append(mat)
context = {'materia_expediente': materias_expediente}
return context
integrantes = []
for m in mesa:
parlamentar = Parlamentar.objects.get(
id=m.parlamentar_id)
cargo = CargoMesa.objects.get(
id=m.cargo_id)
integrante = {'parlamentar': parlamentar, 'cargo': cargo}
integrantes.append(integrante)
def get_oradores_expediente(sessao_plenaria):
oradores = []
for orador in OradorExpediente.objects.filter(
sessao_plenaria_id=sessao_plenaria.id).order_by('numero_ordem'):
numero_ordem = orador.numero_ordem
url_discurso = orador.url_discurso
observacao = orador.observacao
parlamentar = Parlamentar.objects.get(
id=orador.parlamentar_id)
ora = {'numero_ordem': numero_ordem,
'url_discurso': url_discurso,
'parlamentar': parlamentar,
'observacao': observacao
}
oradores.append(ora)
context = {'oradores': oradores}
return context
context.update({'mesa': ordenar_integrantes_por_cargo(integrantes)})
def get_presenca_ordem_do_dia(sessao_plenaria):
mesa_aux = get_mesa_diretora(sessao_plenaria)
presencas = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')
# =====================================================================
# Presença Sessão
presencas = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id
).order_by('parlamentar__nome_parlamentar')
parlamentares_mesa_dia = [m for m in mesa_aux['mesa']]
presidente_dia = ''
for m in mesa_aux['mesa']:
if m['cargo'].descricao == 'Presidente':
presidente_dia = [m['parlamentar']]
break
parlamentares_sessao = [p.parlamentar for p in presencas]
parlamentares_ordem = [p.parlamentar for p in presencas]
ausentes_sessao = JustificativaAusencia.objects.filter(
sessao_plenaria_id=self.object.id
).order_by('parlamentar__nome_parlamentar')
cont = 0
for index, parlamentar in enumerate(parlamentares_ordem):
try:
if parlamentar == parlamentares_mesa_dia[cont]["parlamentar"]:
del(parlamentares_ordem[index])
cont += 1
except IndexError:
pass
context.update({'presenca_sessao': parlamentares_sessao,
'justificativa_ausencia': ausentes_sessao})
context ={}
context.update({'presenca_ordem': parlamentares_ordem})
# =====================================================================
# Expedientes
expediente = ExpedienteSessao.objects.filter(
sessao_plenaria_id=self.object.id).order_by('tipo__nome')
config_assinatura_ata = AppsAppConfig.objects.first().assinatura_ata
if config_assinatura_ata == 'T' and parlamentares_ordem:
context.update(
{'texto_assinatura': 'Assinatura de Todos os Parlamentares Presentes na Sessão'})
context.update({'assinatura_mesa':parlamentares_mesa_dia,'assinatura_presentes': parlamentares_ordem})
elif config_assinatura_ata == 'M' and parlamentares_mesa_dia:
context.update(
{'texto_assinatura': 'Assinatura da Mesa Diretora da Sessão'})
context.update({'assinatura_presentes': parlamentares_mesa_dia})
elif config_assinatura_ata == 'P' and presidente_dia:
context.update(
{'texto_assinatura': 'Assinatura do Presidente da Sessão'})
context.update({'assinatura_presentes': presidente_dia})
expedientes = []
for e in expediente:
tipo = TipoExpediente.objects.get(id=e.tipo_id)
conteudo = e.conteudo
ex = {'tipo': tipo, 'conteudo': conteudo}
expedientes.append(ex)
context.update({'expedientes': expedientes})
return context
# =====================================================================
# Matérias Expediente
materias = ExpedienteMateria.objects.filter(
sessao_plenaria_id=self.object.id)
def get_materias_ordem_do_dia(sessao_plenaria):
ordem = OrdemDia.objects.filter(sessao_plenaria_id=sessao_plenaria.id)
materias_ordem = []
for o in ordem:
ementa = o.materia.ementa
ementa_observacao = o.observacao
titulo = o.materia
numero = o.numero_ordem
tramitacao = o.materia.tramitacao_set.last()
turno = None
if tramitacao:
turno = get_turno(tramitacao.turno)
materias_expediente = []
for m in materias:
# Verificar resultado
rv = o.registrovotacao_set.filter(materia=o.materia).first()
rp = o.retiradapauta_set.filter(materia=o.materia).first()
if rv:
resultado = rv.tipo_resultado_votacao.nome
resultado_observacao = rv.observacao
ementa = m.materia.ementa
titulo = m.materia
numero = m.numero_ordem
tramitacao = m.materia.tramitacao_set.last()
turno = None
elif rp:
resultado = rp.tipo_de_retirada.descricao
resultado_observacao = rp.observacao
if tramitacao:
turno = get_turno(tramitacao.turno)
else:
resultado = _('Matéria não votada')
resultado_observacao = _(' ')
voto_sim = ""
voto_nao = ""
voto_abstencoes = ""
voto_nominal = []
if o.tipo_votacao == 2:
votos = VotoParlamentar.objects.filter(ordem=o.id)
for voto in votos:
aux_voto = (voto.parlamentar.nome_completo, voto.voto)
voto_nominal.append(aux_voto)
try:
voto = RegistroVotacao.objects.filter(ordem=o.id).last()
voto_sim = voto.numero_votos_sim
voto_nao = voto.numero_votos_nao
voto_abstencoes = voto.numero_abstencoes
except AttributeError:
voto_sim = " Não Informado"
voto_nao = " Não Informado"
voto_abstencoes = " Não Informado"
autoria = Autoria.objects.filter(
materia_id=o.materia_id)
autor = [str(x.autor) for x in autoria]
mat = {'ementa': ementa,
'ementa_observacao': ementa_observacao,
'titulo': titulo,
'numero': numero,
'turno': turno,
'resultado': resultado,
'resultado_observacao': resultado_observacao,
'autor': autor,
'numero_protocolo': o.materia.numero_protocolo,
'numero_processo': o.materia.numeracao_set.last(),
'tipo_votacao': o.TIPO_VOTACAO_CHOICES[o.tipo_votacao],
'voto_sim':voto_sim,
'voto_nao':voto_nao,
'voto_abstencoes':voto_abstencoes,
'voto_nominal': voto_nominal,
}
materias_ordem.append(mat)
context = {'materias_ordem': materias_ordem}
return context
rv = m.registrovotacao_set.first()
rp = m.retiradapauta_set.filter(materia=m.materia).first()
if rv:
resultado = rv.tipo_resultado_votacao.nome
resultado_observacao = rv.observacao
elif rp:
resultado = rp.tipo_de_retirada.descricao
resultado_observacao = rp.observacao
def get_oradores_explicações_pessoais(sessao_plenaria):
oradores_explicacoes = []
for orador in Orador.objects.filter(
sessao_plenaria_id=sessao_plenaria.id).order_by('numero_ordem'):
for parlamentar in Parlamentar.objects.filter(
id=orador.parlamentar.id):
partido_sigla = Filiacao.objects.filter(
parlamentar=parlamentar).last()
if not partido_sigla:
sigla = ''
else:
resultado = _('Matéria não votada')
resultado_observacao = _(' ')
sigla = partido_sigla.partido.sigla
oradores = {
'numero_ordem': orador.numero_ordem,
'parlamentar': parlamentar,
'sgl_partido': sigla
}
oradores_explicacoes.append(oradores)
context = {'oradores_explicacoes': oradores_explicacoes}
return context
autoria = Autoria.objects.filter(materia_id=m.materia_id)
autor = [str(x.autor) for x in autoria]
def get_ocorrencias_da_sessão(sessao_plenaria):
ocorrencias_sessao = OcorrenciaSessao.objects.filter(
sessao_plenaria_id=sessao_plenaria.id)
context = {'ocorrencias_da_sessao': ocorrencias_sessao}
return context
mat = {'ementa': ementa,
'titulo': titulo,
'numero': numero,
'turno': turno,
'resultado': resultado,
'resultado_observacao': resultado_observacao,
'autor': autor,
'numero_protocolo': m.materia.numero_protocolo,
'numero_processo': m.materia.numeracao_set.last(),
'observacao': m.observacao
}
materias_expediente.append(mat)
class ResumoView(DetailView):
template_name = 'sessao/resumo.html'
model = SessaoPlenaria
logger = logging.getLogger(__name__)
context.update({'materia_expediente': materias_expediente})
# Votos de Votação Nominal de Matérias Expediente
def get_context(self,*args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
# Votos de Votação Nominal de Matérias Expediente
materias_expediente_votacao_nominal = ExpedienteMateria.objects.filter(
sessao_plenaria_id=self.object.id,
tipo_votacao=2).order_by('-materia')
@ -1446,107 +1599,34 @@ class ResumoView(DetailView):
votacoes.append(dados_votacao)
context.update({'votos_nominais_materia_expediente': votacoes})
# =====================================================================
# Identificação Básica
context.update(get_identificação_basica(self.object))
# =====================================================================
# Conteúdo Multimídia
context.update(get_conteudo_multimidia(self.object))
# =====================================================================
# Mesa Diretora
context.update(get_mesa_diretora(self.object))
# =====================================================================
# Presença Sessão
context.update(get_presenca_sessao(self.object))
# =====================================================================
# Expedientes
context.update(get_expedientes(self.object))
# =====================================================================
# Matérias Expediente
context.update(get_materias_expediente(self.object))
# =====================================================================
# Oradores Expediente
oradores = []
for orador in OradorExpediente.objects.filter(
sessao_plenaria_id=self.object.id).order_by('numero_ordem'):
numero_ordem = orador.numero_ordem
url_discurso = orador.url_discurso
observacao = orador.observacao
parlamentar = Parlamentar.objects.get(
id=orador.parlamentar_id)
ora = {'numero_ordem': numero_ordem,
'url_discurso': url_discurso,
'parlamentar': parlamentar,
'observacao': observacao
}
oradores.append(ora)
context.update({'oradores': oradores})
context.update(get_oradores_expediente(self.object))
# =====================================================================
# Presença Ordem do Dia
presencas = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.object.id
).order_by('parlamentar__nome_parlamentar')
parlamentares_mesa_dia = [m['parlamentar'] for m in context['mesa']]
# composicao_mesa = ComposicaoMesa.objects.filter(sessao_legislativa=sessao)
presidente_dia = ''
for m in context['mesa']:
if m['cargo'].descricao == 'Presidente':
presidente_dia = [m['parlamentar']]
break
parlamentares_ordem = [p.parlamentar for p in presencas]
context.update({'presenca_ordem': parlamentares_ordem})
config_assinatura_ata = AppsAppConfig.objects.first().assinatura_ata
if config_assinatura_ata == 'T' and parlamentares_ordem:
context.update(
{'texto_assinatura': 'Assinatura de Todos os Parlamentares Presentes na Sessão'})
context.update({'assinatura_presentes': parlamentares_ordem})
elif config_assinatura_ata == 'M' and parlamentares_mesa_dia:
context.update(
{'texto_assinatura': 'Assinatura da Mesa Diretora da Sessão'})
context.update({'assinatura_presentes': parlamentares_mesa_dia})
elif config_assinatura_ata == 'P' and presidente_dia:
context.update(
{'texto_assinatura': 'Assinatura do Presidente da Sessão'})
context.update({'assinatura_presentes': presidente_dia})
context.update(get_presenca_ordem_do_dia(self.object))
# =====================================================================
# Matérias Ordem do Dia
ordem = OrdemDia.objects.filter(
sessao_plenaria_id=self.object.id)
materias_ordem = []
for o in ordem:
ementa = o.materia.ementa
ementa_observacao = o.observacao
titulo = o.materia
numero = o.numero_ordem
tramitacao = o.materia.tramitacao_set.last()
turno = None
if tramitacao:
turno = get_turno(tramitacao.turno)
# Verificar resultado
rv = o.registrovotacao_set.filter(materia=o.materia).first()
rp = o.retiradapauta_set.filter(materia=o.materia).first()
if rv:
resultado = rv.tipo_resultado_votacao.nome
resultado_observacao = rv.observacao
elif rp:
resultado = rp.tipo_de_retirada.descricao
resultado_observacao = rp.observacao
else:
resultado = _('Matéria não votada')
resultado_observacao = _(' ')
autoria = Autoria.objects.filter(
materia_id=o.materia_id)
autor = [str(x.autor) for x in autoria]
mat = {'ementa': ementa,
'ementa_observacao': ementa_observacao,
'titulo': titulo,
'numero': numero,
'turno': turno,
'resultado': resultado,
'resultado_observacao': resultado_observacao,
'autor': autor,
'numero_protocolo': o.materia.numero_protocolo,
'numero_processo': o.materia.numeracao_set.last()
}
materias_ordem.append(mat)
context.update({'materias_ordem': materias_ordem})
# Votos de Votação Nominal de Matérias Ordem do Dia
# Votos de Votação Nominal de Matérias Ordem do Dia
materias_ordem_dia_votacao_nominal = OrdemDia.objects.filter(
sessao_plenaria_id=self.object.id,
tipo_votacao=2).order_by('-materia')
@ -1569,34 +1649,13 @@ class ResumoView(DetailView):
context.update({'votos_nominais_materia_ordem_dia': votacoes_od})
context.update(get_materias_ordem_do_dia(self.object))
# =====================================================================
# Oradores nas Explicações Pessoais
oradores_explicacoes = []
for orador in Orador.objects.filter(
sessao_plenaria_id=self.object.id).order_by('numero_ordem'):
for parlamentar in Parlamentar.objects.filter(
id=orador.parlamentar.id):
partido_sigla = Filiacao.objects.filter(
parlamentar=parlamentar).last()
if not partido_sigla:
sigla = ''
else:
sigla = partido_sigla.partido.sigla
oradores = {
'numero_ordem': orador.numero_ordem,
'parlamentar': parlamentar,
'sgl_partido': sigla
}
oradores_explicacoes.append(oradores)
context.update({'oradores_explicacoes': oradores_explicacoes})
context.update(get_oradores_explicações_pessoais(self.object))
# =====================================================================
# Ocorrẽncias da Sessão
ocorrencias_sessao = OcorrenciaSessao.objects.filter(
sessao_plenaria_id=self.object.id)
context.update({'ocorrencias_da_sessao': ocorrencias_sessao})
context.update(get_ocorrencias_da_sessão(self.object))
# =====================================================================
# Indica a ordem com a qual o template será renderizado
ordenacao = ResumoOrdenacao.objects.first()
@ -1667,9 +1726,14 @@ class ResumoView(DetailView):
'decimo_terceiro_ordenacao': dict_ord_template['ocorr_sessao']
})
return context
def get(self, request, *args, **kwargs):
context = self.get_context()
return self.render_to_response(context)
class ResumoAtaView(ResumoView):
template_name = 'sessao/resumo_ata.html'
logger = logging.getLogger(__name__)

62
sapl/static/sapl/css/header-relatorio.css

@ -0,0 +1,62 @@
html body p {
border-top: 1px solid black;
text-align: center;
font-size: 11pt;
padding: 5px;
margin-top: -15px;
}
html body section {
box-sizing: border-box;
}
html body section dl {
display: flex;
flex-wrap: wrap;
rows: 2;
columns: 2;
}
html body section dt{
width: 50px;
}
html body section dd {
max-width:550px;
text-align: center;
}
html body section dd ul li {
list-style-type: none;
margin-left: 90px;
margin-bottom: -15px;
}
h2 {
font-size: 14pt;
}
h3 {
font-size: 10pt;
color: #6e6e6e;
}
ul {
padding: 0;
list-style: none;
margin-top:10px;
}
html body section dt img {
max-width:80px;
margin-left: 20px;
margin-left: 50px;
}
h3 {
font-size: 10pt;
color: #6e6e6e;
}
ul {
padding: 0;
list-style: none;
margin-top:10px;
}
html body section dt img {
max-width:80px;
margin-left: 20px;
}

56
sapl/static/sapl/css/relatorio.css

@ -0,0 +1,56 @@
@page{
margin-top: 4.5cm;
size: A4 portrait;
}
h2.gray-title{
color: gray;
font-size: 14pt;
break-after: avoid-page;
page-break-after: avoid;
}
h3 {
font-size: 10pt;
break-after: avoid-page;
page-break-after: avoid;
}
p {
font-size: 10pt;
text-align: justify;
text-justify: inter-word;
}
fieldset {
border: 0;
}
html body section {
box-sizing: border-box;
}
html body section dl {
display: flex;
flex-wrap: wrap;
columns: 5;
}
html body section dt{
width: 50px;
}
html body section dd {
text-align: center;
}
html body section dd ul li {
list-style-type: none;
margin-left: 50px;
}
fieldset {
page-break-after: avoid;
margin:5px;
padding:0px;
}

31
sapl/templates/relatorios/header_ata.html

@ -0,0 +1,31 @@
{% load common_tags %}
{% load render_bundle from webpack_loader %}
{% load webpack_static from webpack_loader %}
{% load static %}
<!DOCTYPE html>
<meta charset="utf-8">
</meta>
<html lang="pt-br">
<head>
<link rel="stylesheet" href="{% static 'sapl/css/header-relatorio.css'%}">
</head>
<body>
<section id="informations">
<dl>
<dt class="image-header">
<img src="{% if logotipo %}{{ MEDIA_URL }}{{ logotipo }}{% else %}{% webpack_static 'img/logo.png' %}{% endif %}">
</dt>
<dd class="title">
<ul>
<li style="margin-top:10px"><h2>{{casa}}</h2></li>
<li><h3>Sistema de Apoio ao Processo Legislativo</h3></li>
</ul>
</dd>
</dl>
</section>
<p></p>
</body>
</html>

101
sapl/templates/relatorios/relatorio_ata.html

@ -0,0 +1,101 @@
{% load common_tags %}
{% load static %}
<head>
<style>
@page{
@bottom-right {
content: "Página" counter(page);
height: 3cm;
font-size: 8pt;
}
@bottom-center {
border-top: 1px solid black;
font-size: 8pt;
height: 1cm;
content: "{{rodape|safe}}";
font-style:italic;
}
@bottom-left {
content: "{{data}}";
height: 3cm;
font-size: 8pt;
}
@top-center {
content: string(title);
}
header {
width: 0;
height: 0;
visibility: hidden;
string-set: title content();
}
}
</style>
<link rel="stylesheet" href="{% static '/sapl/css/relatorio.css'%}">
</head>
<body>
<h3 style="text-align:center;">Extrato Reunião</h3>
{% include 'sessao/blocos_ata/identificacao_basica.html' %}
{% include 'sessao/blocos_ata/mesa_diretora.html' %}
{% include 'sessao/blocos_ata/lista_presenca.html' %}
{% include 'sessao/blocos_ata/expedientes.html' %}
{% include 'sessao/blocos_ata/materias_expediente.html' %}
{% include 'sessao/blocos_ata/oradores_expediente.html' %}
{% include 'sessao/blocos_ata/lista_presenca_ordem_dia.html' %}
{% include 'sessao/blocos_ata/materias_ordem_dia.html' %}
{% include 'sessao/blocos_ata/oradores_explicacoes.html' %}
{% if assinatura_mesa or assinatura_presentes %}
<div style="page-break-before: always;padding:5px;margin-top:80px;border-top: 1px solid black;">
<legend >{{texto_assinatura}}</legend>
<table style="margin-top:80px">
<colgroup>
<col>
</colgroup>
<tbody>
{% for p in assinatura_mesa %}
{% if forloop.counter0|divisibleby:2 %}
<tr style="margin-top:0px">
<td>
<div style="float: left; position: relative; top: -80px; left: 8px; width: 120px">____________________ </br>
<p style="font-size:8pt"><b>{{p.cargo}}: </b> {{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}</p>
</br></br></br>
</div>
{% else %}
<div style="float: left; position: relative; top: -80px; left: 142px; width: 120px; margin-right:-220px;">____________________ </br>
<p style="font-size:8pt"><b>{{p.cargo}}: </b> {{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}</p>
</br></br></br>
</div>
</td>
</tr>
{% endif %}
{% endfor %}
{% for p in assinatura_presentes %}
{% if forloop.counter0|divisibleby:2 %}
<tr style="margin-top:0px">
<td>
<div style="float: left; position: relative;top: -80px; left: 8px; width: 120px;">_____________________</br>
<p style="font-size:8pt">{{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}</p>
</br></br></br>
</div>
{% else %}
<div style="float: left; position: relative; top: -80px;left: 142px; width: 120px; margin-right:-220px;">_____________________ </br>
<p style="font-size:8pt">{{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}</p>
</br></br></br>
</div>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endif%}
</div>
</body>

12
sapl/templates/sessao/blocos_ata/assinaturas.html

@ -1,13 +1,17 @@
{% load common_tags %}
</p>
</p>
<fieldset>
<legend>{{texto_assinatura}}</legend>
<div class="row">
</br></br>
{% for p in assinatura_mesa %}
<div class="col-md-6">___________________________________________ </br>
<b>{{p.cargo}}: </b> {{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}
</br></br></br>
</div>
{% endfor %}
{% for p in assinatura_presentes %}
<div class="col-md-6">___________________________________________ </br>
{{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }}
{{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}
</br></br></br>
</div>
{% endfor %}

4
sapl/templates/sessao/blocos_ata/lista_presenca.html

@ -5,7 +5,7 @@
{% if presenca_sessao %}
<strong>Lista de Presença na Sessão: </strong>
{% for p in presenca_sessao %}
{{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }} ;
{{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }} ;
{% endfor %}
{% endif %}
</p>
@ -13,7 +13,7 @@
{% if justificativa_ausencia %}
<strong>Justificativas de Ausências na Sessão: </strong>
{% for j in justificativa_ausencia %}
{{j.parlamentar}} / {{ j.tipo_ausencia }} ;
{{j.parlamentar.nome_completo}} / {{ j.tipo_ausencia }} ;
{% endfor %}
{% endif %}
</p>

2
sapl/templates/sessao/blocos_ata/lista_presenca_ordem_dia.html

@ -5,7 +5,7 @@
{% if presenca_ordem %}
<strong>Lista de Presença na Ordem do Dia: </strong>
{% for p in presenca_ordem %}
{{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }} ;
{{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }} ;
{% endfor %}
{% endif %}
</p>

52
sapl/templates/sessao/blocos_ata/materias_ordem_dia.html

@ -1,24 +1,34 @@
<fieldset>
<p align="justify">
{% if materias_ordem %}
<strong>Matérias da Ordem do Dia: </strong>
{% for m in materias_ordem %}
<b>{{m.numero}} - {{m.titulo}} </b>
{% if m.turno %}
Turno:{{m.turno}}
</br>
<strong>Matérias da Ordem do Dia: </strong>
</br></br>
{% for m in materias_ordem %}
<fieldset style="border-top: 1px solid black;">
<b>{{m.numero}} - {{m.titulo}} </b></br>
<b>Turno:</b>{{m.turno}}</br>
<b>Autor: </b>{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }}
{% if m.numero_protocolo %}
<b>Número de Protocolo:</b> {{ m.numero_protocolo }}
{% endif %}
{% if m.numero_processo %}
<b>Processo:</b> {{ m.numero_processo }}
{% endif %}
<p><b>Descrição:</b> {{m.ementa|safe}}</p>
<b>Resultado:</b> {{m.resultado}} {{m.resultado_observacao}}
<dl>
<p><b>Tipo:</b> {{m.tipo_votacao}}</p>
<dt>Sim:{{m.voto_sim}}</dt>
<dt>Não:{{m.voto_nao}}</dd>
<dt>Abstenções:{{m.voto_abstencoes}}</dt>
</dl>
{% if m.voto_nominal%}
<b>Votos Nominais</b>
<ul>
{% for voto in m.voto_nominal %}
<li>{{voto.0}} - {{voto.1}}</li>
{% endfor %}
</ul>
{% endif %}
Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }}
{% if m.numero_protocolo %}
Número de Protocolo: {{ m.numero_protocolo }}
{% endif %}
{% if m.numero_processo %}
Processo: {{ m.numero_processo }}
{% endif %}
{{m.ementa|safe}}
{{m.resultado}} {{m.resultado_observacao}}
{% endfor %}
{% endif %}
</p>
</fieldset>
{% endfor %}
</fieldset>

2
sapl/templates/sessao/blocos_ata/mesa_diretora.html

@ -4,7 +4,7 @@
<strong>Mesa Diretora: </strong>
{% for m in mesa %}
{{m.cargo}}:
{{m.parlamentar.nome_parlamentar}} / {{ m.parlamentar.filiacao_atual }} ;
{{m.parlamentar.nome_completo}} / {{ m.parlamentar.filiacao_atual }} ;
{% endfor %}
{% endif %}
</p>

2
sapl/templates/sessao/blocos_ata/oradores_expediente.html

@ -3,7 +3,7 @@
{% if oradores %}
<strong>Oradores do Expediente: </strong>
{% for o in oradores %}
<div><b>{{o.numero_ordem}}</b> - {{o.parlamentar}}</div>
<div><b>{{o.numero_ordem}}</b> - {{o.parlamentar.nome_completo}}</div>
<div>{{o.url_discurso}}</div>
<div>{{o.observacao}}</div>
</br>

2
sapl/templates/sessao/blocos_ata/oradores_explicacoes.html

@ -3,7 +3,7 @@
{% if oradores_explicacoes %}
<strong>Oradores das Explicações Pessoais: </strong>
{% for o in oradores_explicacoes %}
<b>{{o.numero_ordem}}</b> - {{o.parlamentar.nome_parlamentar}} / {{ o.parlamentar.filiacao_atual }} ;
<b>{{o.numero_ordem}}</b> - {{o.parlamentar.nome_completo}} / {{ o.parlamentar.filiacao_atual }} ;
{{o.url_discurso}}
{% endfor %}
{% endif %}

12
sapl/templates/sessao/resumo_ata.html

@ -6,7 +6,17 @@
<h1 class="page-header">
Extrato Eletrônico da {{sessaoplenaria}}
</h1>
{% endblock %}
<div>
<p align="right">
<strong>
<a href="{% url 'sapl.relatorios:resumo_ata_pdf' sessaoplenaria.pk %}">
Impressão PDF
</a>
</strong>
</p>
</div>
{% endblock title %}
{% block detail_content %}
{% include 'sessao/blocos_ata/'|add:primeiro_ordenacao %}

Loading…
Cancel
Save