From 196915d337599c852c92c16391a8a12f39e718f8 Mon Sep 17 00:00:00 2001 From: Victor Fabre Date: Wed, 13 Feb 2019 08:17:36 -0200 Subject: [PATCH] =?UTF-8?q?Fix=20#=202488=20Co-authored-by:=20ulyssesBML?= =?UTF-8?q?=20=20sobe=20altera=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Iniciando relatorio com weasyprint Atualizando informaçoes do relatorio de reunião Arrumando logo e topicos incompletos Refatorando codigo para gerar relatorio Adicionando butão para novo estilo de relatorio Arrumando erros relatados noPR Arrumando margens das tabelas e dos headers --- sapl/relatorios/urls.py | 5 +- sapl/relatorios/views.py | 104 +++++++++- sapl/static/css/header-relatorio.css | 30 +++ sapl/static/css/relatorio.css | 55 ++++++ sapl/templates/relatorios/header.html | 39 ++++ .../relatorios/relatorio_sessao_plenaria.html | 182 ++++++++++++++++++ sapl/templates/sessao/resumo.html | 4 + 7 files changed, 417 insertions(+), 2 deletions(-) create mode 100644 sapl/static/css/header-relatorio.css create mode 100644 sapl/static/css/relatorio.css create mode 100644 sapl/templates/relatorios/header.html create mode 100644 sapl/templates/relatorios/relatorio_sessao_plenaria.html diff --git a/sapl/relatorios/urls.py b/sapl/relatorios/urls.py index e31f5dcab..18dc284a6 100644 --- a/sapl/relatorios/urls.py +++ b/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, + relatorio_sessao_plenaria_pdf) app_name = AppConfig.name @@ -28,4 +29,6 @@ urlpatterns = [ relatorio_etiqueta_protocolo, name='relatorio_etiqueta_protocolo'), url(r'^relatorios/pauta-sessao/(?P\d+)/$', relatorio_pauta_sessao, name='relatorio_pauta_sessao'), + url(r'^relatorios/(?P\d+)/sessao-plenaria-pdf$', + relatorio_sessao_plenaria_pdf, name='relatorio_sessao_plenaria_pdf'), ] diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 53331eadd..45d48cfd2 100755 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -7,7 +7,9 @@ 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, @@ -21,7 +23,7 @@ from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao, OrdemDia, PresencaOrdemDia, SessaoPlenaria, SessaoPlenariaPresenca, OcorrenciaSessao, RegistroVotacao, VotoParlamentar) -from sapl.settings import STATIC_ROOT +from sapl.settings import STATIC_ROOT, STATIC_URL from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data from .templates import (pdf_capa_processo_gerar, @@ -30,6 +32,9 @@ from .templates import (pdf_capa_processo_gerar, pdf_ordem_dia_gerar, pdf_pauta_sessao_gerar, pdf_protocolo_gerar, pdf_sessao_plenaria_gerar) +from weasyprint import HTML, CSS + +from sapl.settings import MEDIA_URL def get_kwargs_params(request, fields): kwargs = {} @@ -904,6 +909,103 @@ def relatorio_sessao_plenaria(request, pk): return response +def relatorio_sessao_plenaria_pdf(request, pk): + base_url=request.build_absolute_uri() + logger = logging.getLogger(__name__) + username = request.user.username + casa = CasaLegislativa.objects.first() + if not casa: + raise Http404 + + rodape = get_rodape(casa) + rodape = ' '.join(rodape) + + try: + logger.debug("user=" + username + + ". Tentando obter SessaoPlenaria com id={}.".format(pk)) + sessao = SessaoPlenaria.objects.get(id=pk) + except ObjectDoesNotExist as e: + logger.error("user=" + username + + ". Essa SessaoPlenaria não existe (pk={}). ".format(pk) + str(e)) + raise Http404('Essa página não existe') + + (inf_basicas_dic, + lst_mesa, + lst_presenca_sessao, + lst_ausencia_sessao, + lst_expedientes, + lst_expediente_materia, + lst_expediente_materia_vot_nom, + lst_oradores_expediente, + lst_presenca_ordem_dia, + lst_votacao, + lst_votacao_vot_nom, + lst_oradores, + lst_ocorrencias) = get_sessao_plenaria(sessao, casa) + + html_template = render_to_string('relatorios/relatorio_sessao_plenaria.html', + { + "inf_basicas_dic":inf_basicas_dic, + "lst_mesa":lst_mesa, + "lst_presenca_sessao":lst_presenca_sessao, + "lst_ausencia_sessao":lst_ausencia_sessao, + "lst_expedientes":lst_expedientes, + "lst_expediente_materia":lst_expediente_materia, + "lst_oradores_expediente":lst_oradores_expediente, + "lst_presenca_ordem_dia":lst_presenca_ordem_dia, + "lst_votacao":lst_votacao, + "lst_oradores":lst_oradores, + "lst_ocorrencias":lst_ocorrencias, + "rodape":rodape, + "data": dt.today().strftime('%d/%m/%Y') + }) + + html_header = render_to_string('relatorios/header.html',{"info":inf_basicas_dic, + "MEDIA_URL": MEDIA_URL, + "logotipo": casa.logotipo}) + + 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 + + +def make_pdf(base_url, main_template, header_template): + # Main template + html = HTML(base_url=base_url, string=main_template) + main_doc = html.render() + exists_links = False + + 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='div {position: fixed; top: 0cm; left: 0cm;}')]) + + header_page = header.pages[0] + exists_links = exists_links or header_page.links + 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() + if exists_links: + page.links.extend(header_page.links) + + pdf_file = main_doc.write_pdf() + + return pdf_file + + def get_protocolos(prots): protocolos = [] diff --git a/sapl/static/css/header-relatorio.css b/sapl/static/css/header-relatorio.css new file mode 100644 index 000000000..2503714a7 --- /dev/null +++ b/sapl/static/css/header-relatorio.css @@ -0,0 +1,30 @@ +html body p { + border-top: 1px solid black; + text-align: center; + font-size: 11pt; + padding: 5px; +} +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: 50px; +} +h3 { + font-size: 12pt; + color: #6e6e6e; +} diff --git a/sapl/static/css/relatorio.css b/sapl/static/css/relatorio.css new file mode 100644 index 000000000..19c03ff21 --- /dev/null +++ b/sapl/static/css/relatorio.css @@ -0,0 +1,55 @@ +@page{ + margin-top: 8cm; + 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; +} +table { + max-width: 520px; +} +table.grayTable { + border: 1px solid #6e6e6e; + width: 100%; + text-align: left; + border-collapse: collapse; +} +table.grayTable td, table.grayTable th { + border: 1px solid #000000; +} +table.grayTable tbody td { + font-size: 10px; + max-width: 80px; + overflow-wrap: break-word; + word-wrap: break-word; + text-align: justify; +} +table.grayTable tr:nth-child(even) { + background: #dddddd; +} +table.grayTable thead { + background: #BBBBBB; + border-bottom: 2px solid #000000; +} +table.grayTable thead th { + font-size:10px; + color: rgb(0, 0, 0); + border-left: 1px solid #000000; + +} +table.grayTable thead th:first-child { + border-left: none; +} \ No newline at end of file diff --git a/sapl/templates/relatorios/header.html b/sapl/templates/relatorios/header.html new file mode 100644 index 000000000..17a326cfa --- /dev/null +++ b/sapl/templates/relatorios/header.html @@ -0,0 +1,39 @@ +{% load i18n staticfiles menus %} +{% load common_tags %} +{% load render_bundle from webpack_loader %} +{% load webpack_static from webpack_loader %} +{% load static %} + + + + + + + + + + +
+ +
+
+ Logo +
+
+
    +
  • {{ info.nom_camara }}

  • +
  • Sistema de Apoio ao Processo Legislativo

  • +
+
+
+ + +
+

Resumo da {{ info.num_sessao_plen }} Reunião {{nom_sessao}} da {{ info.num_sessao_leg}} Sessão Legislativa da + {{info.num_legislatura}} Legislatura

+ + + + + \ No newline at end of file diff --git a/sapl/templates/relatorios/relatorio_sessao_plenaria.html b/sapl/templates/relatorios/relatorio_sessao_plenaria.html new file mode 100644 index 000000000..3a7bf5778 --- /dev/null +++ b/sapl/templates/relatorios/relatorio_sessao_plenaria.html @@ -0,0 +1,182 @@ +{% load static %} + + + + + + + + + + + +
+

Informações Básicas

+

Tipo da Sessão: {{inf_basicas_dic.nom_sessao}}

+

Abertura: {{inf_basicas_dic.dat_inicio_sessao}} - {{inf_basicas_dic.hr_inicio_sessao}}

+

Encerramento: {{inf_basicas_dic.dat_fim_sessao}} - {{inf_basicas_dic.hr_fim_sessao}}

+ +

Mesa Diretora

+ {% for membro in lst_mesa%} +

{{membro.des_cargo}}: {{membro.nom_parlamentar}}/{{membro.sgl_partido}}

+ {% endfor%} + +

Lista de Presença da Sessão

+ {% for membro in lst_presenca_sessao%} +

{{membro.nom_parlamentar}}/{{membro.sgl_partido}}

+ {% endfor%} + +

Justificativas de Ausência da Sessão

+ + + + + + + + + + + {% for ausencia in lst_ausencia_sessao%} + + + + + + {% endfor %} + + +
ParlamentarJustificativaAusente em
{{ausencia.parlamentar}}{{ausencia.justificativa}}{{ausencia.tipo}}
+ +

Expedientes

+ {% for expediente in lst_expedientes%} +

{{expediente.nom_expediente}}

+

{{expediente.txt_expediente|safe}}

+ {% endfor%} + + +

Matérias do Expediente

+ + + + + + + + + + + {% for materia in lst_expediente_materia%} + + + + + + {% endfor %} + + +
MatériaEmentaResultado da Votação
+
+
{{materia.num_ordem}} - {{materia.id_materia}}
+
Turno: {{materia.des_turno}}
+
{{materia.num_autores}}: {{materia.nom_autor}}
+
+
{{materia.txt_ementa}}
{{materia.nom_resultado}}
+ +

Oradores do Expediente

+ + {% for orador in lst_oradores_expediente%} + +

{{orador.num_ordem}} - {{orador.nom_parlamentar}}/{{orador.sgl_partido}}

+ + {% endfor %} + +

Lista de Presença da Ordem do Dia

+ + {% for orador in lst_presenca_ordem_dia%} + +

{{orador.nom_parlamentar}}/{{orador.sgl_partido}}

+ + {% endfor %} + +

Matérias da Ordem do Dia

+ + + + + + + + + + + {% for materia in lst_votacao%} + + + + + + {% endfor %} + + +
MatériaEmentaResultado da Votação
+
+
{{materia.num_ordem}} - {{materia.id_materia}}
+
Turno: {{materia.des_turno}}
+
{{materia.num_autores}}: {{materia.nom_autor}}
+
+
{{materia.txt_ementa}}
{{materia.nom_resultado}}
+ +
+

Oradores das Explicações Pessoais

+ {% for orador in lst_oradores%} + +

{{orador.num_ordem}} - {{orador.nom_parlamentar}}/{{orador.sgl_partido}}

+ + {% endfor %} +
+ + +

Ocorrências da Sessão

+ {% for ocorrencia in lst_ocorrencias%} +

{{ocorrencia}}

+ {% endfor %} +
+ + + + + \ No newline at end of file diff --git a/sapl/templates/sessao/resumo.html b/sapl/templates/sessao/resumo.html index bcedeedb8..3d1028d09 100644 --- a/sapl/templates/sessao/resumo.html +++ b/sapl/templates/sessao/resumo.html @@ -16,6 +16,10 @@ Impressão PDF +
+ + Impressão PDF (Novo) +