Browse Source

Ajusta relatórios para novo tema bootstrap

pull/184/head
Sesóstris Vieira 3 weeks ago
parent
commit
8a869a345a
  1. 17
      sigi/apps/eventos/forms.py
  2. 81
      sigi/apps/eventos/static/css/calendario.css
  3. 86
      sigi/apps/eventos/templates/eventos/calendario.html
  4. 97
      sigi/apps/eventos/templates/eventos/calendario_pdf.html
  5. 77
      sigi/apps/eventos/templates/eventos/eventos_por_uf.html
  6. 20
      sigi/apps/eventos/templates/eventos/eventos_por_uf_pdf.html
  7. 40
      sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html
  8. 47
      sigi/apps/eventos/templates/eventos/snippets/calendario_detail.html
  9. 30
      sigi/apps/eventos/templates/eventos/snippets/calendario_legenda.html
  10. 19
      sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html
  11. 25
      sigi/apps/eventos/templates/eventos/snippets/calendario_modals.html
  12. 46
      sigi/apps/eventos/templates/eventos/snippets/eventos_por_uf_snippet.html
  13. 37
      sigi/apps/eventos/templates/eventos/snippets/resumo_por_regiao_snippet.html
  14. 35
      sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html
  15. 28
      sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html
  16. 35
      sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_senador_snippet.html
  17. 70
      sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html
  18. 30
      sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html
  19. 111
      sigi/apps/eventos/templates/eventos/solicitacoes_por_periodo.html
  20. 34
      sigi/apps/eventos/templates/eventos/solicitacoes_por_periodo_pdf.html
  21. 275
      sigi/apps/eventos/views.py
  22. 82
      sigi/templates/pdf/base.html
  23. 137
      sigi/templates/pdf/base_report.html

17
sigi/apps/eventos/forms.py

@ -10,6 +10,7 @@ from sigi.apps.eventos.models import (
Solicitacao, Solicitacao,
) )
from sigi.apps.parlamentares.models import Parlamentar from sigi.apps.parlamentares.models import Parlamentar
from sigi.apps.utils.forms.fields import MonthField
class EventoAdminForm(forms.ModelForm): class EventoAdminForm(forms.ModelForm):
@ -236,3 +237,19 @@ class ParlamentarForm(forms.ModelForm):
"nome_completo": forms.HiddenInput, "nome_completo": forms.HiddenInput,
"status_mandato": forms.RadioSelect, "status_mandato": forms.RadioSelect,
} }
class CalendarioForm(forms.Form):
mes_ano = MonthField(label=_("Mês"), required=True)
categorias = forms.MultipleChoiceField(
required=False,
label=_("Categorias"),
choices=TipoEvento.CATEGORIA_CHOICES,
widget=forms.CheckboxSelectMultiple,
)
status = forms.MultipleChoiceField(
required=False,
label=_("Status"),
choices=Evento.STATUS_CHOICES,
widget=forms.CheckboxSelectMultiple,
)

81
sigi/apps/eventos/static/css/calendario.css

@ -1,9 +1,50 @@
#content { .categoria_C {
display: block; --bs-table-bg: #ffcdd2;
background-color: #ffcdd2 !important;
} }
.evento { .categoria_E {
padding: 0 6px; --bs-table-bg: #e1bee7;
background-color: #e1bee7 !important;
}
.categoria_O {
--bs-table-bg: #bbdefb;
background-color: #bbdefb !important;
}
.categoria_S {
--bs-table-bg: #ffe0b2;
background-color: #ffe0b2 !important;
}
.categoria_V {
--bs-table-bg: #d7ccc8;
background-color: #d7ccc8 !important;
}
.status_P::before {
content: "\f293";
}
.status_O::before {
content: "\f417";
}
.status_R::before {
content: "\f360";
}
.status_C::before {
content: "\f368";
}
.status_Q::before {
content: "\f35e";
}
table.calendar-table {
table-layout: fixed;
} }
.data-evento { .data-evento {
@ -19,22 +60,8 @@
margin-bottom: 8px; margin-bottom: 8px;
} }
.card-title {
font-size: 20px !important;
margin-bottom: -6px !important;
}
.card .card-content p {
margin: 12px;
}
a.format-selector .material-icons { /*-------------------------------------------------
line-height: 48px;
}
table {
table-layout: fixed;
}
tr { tr {
border-bottom: none; border-bottom: none;
@ -48,11 +75,6 @@ tr.linha-dias {
background: var(--darkened-bg); background: var(--darkened-bg);
} }
span.numero-dia {
font-size: 1em;
}
tr.linha-evento { tr.linha-evento {
background: var(--body-bg); background: var(--body-bg);
} }
@ -60,3 +82,14 @@ tr.linha-evento {
.calendar-wrapper { .calendar-wrapper {
width: 100%; width: 100%;
} }
.evento {
padding: 0 6px;
}
span.numero-dia {
font-size: 1em;
}
---------------------------------------------------*/

86
sigi/apps/eventos/templates/eventos/calendario.html

@ -0,0 +1,86 @@
{% extends "admin/base_site.html" %}
{% load i18n static djbs_extras %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="/static/css/calendario.css">
{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item">{% translate "Relatórios" %}</li>
<li class="breadcrumb-item">{% translate "Calendário de eventos" %}</li>
{% endblock %}
{% block content %}
{% if not eventos is None and not eventos.exists %}
<div class="alert alert-warning" role="alert">
{% icon "alert" %}
Nenhum evento encontrado para o filtro informado
</div>
{% endif %}
<form>
<div class="card mb-3">
<div class="card-header">
<a class="icon-link" data-bs-toggle="collapse" href="#filterFormCollapse" aria-expanded="{% if eventos is None %}true{% else %}false{% endif %}" aria-controls="filterFormCollapse">
{% icon "filter" %} {% translate "Filtros" %}
</a>
</div>
<div class="card-body collapse{% if eventos is None %} show{% endif %}" id="filterFormCollapse">
{{ form }}
</div>
<div class="card-footer d-flex justify-content-end">
<div>
<button type="submit" class="btn btn-primary">{% trans 'Ver calendário' %}</button>
<button type="submit" name="fmt" value="pdf" class="btn btn-primary" title="{% trans 'Exportar para PDF' %}">
{% icon "pdf" %}
{% trans 'Exportar para PDF' %}
</button>
</div>
</div>
</div>
</form>
{% if eventos.exists %}
<div class="accordion" id="accordionReport">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseLegenda" aria-expanded="true" aria-controls="collapseLegenda">
{% translate "Legenda" %}
</button>
</h2>
<div id="collapseLegenda" class="accordion-collapse collapse show">
<div class="accordion-body">
{% include "eventos/snippets/calendario_legenda.html" %}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseCalendario" aria-expanded="true" aria-controls="collapseCalendario">
{% trans 'Calendário' %}
</button>
</h2>
<div id="collapseCalendario" class="accordion-collapse collapse show">
<div class="accordion-body">
{% include "eventos/snippets/calendario_cal.html" %}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseLista" aria-expanded="false" aria-controls="collapseLista">
{% trans 'Lista' %}
</button>
</h2>
<div id="collapseLista" class="accordion-collapse collapse">
<div class="accordion-body">
{% include "eventos/snippets/calendario_lista.html" %}
</div>
</div>
</div>
</div>
{% include "eventos/snippets/calendario_modals.html" %}
{% endif %}
{% endblock %}

97
sigi/apps/eventos/templates/eventos/calendario_pdf.html

@ -0,0 +1,97 @@
{% extends 'pdf/base_report.html' %}
{% load static i18n %}
{% block extra_style %}
{{ block.super }}
a {
color: black;
text-decoration: none;
}
.calendar-table {
table-layout: fixed;
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #d2d2d2;
}
.calendar-table td+td {
border-left: 1px solid #d2d2d2 !important;
}
table td,
table td * {
vertical-align: top;
}
.calendar-table tr:nth-child(even) {
background-color: white;
}
tr.linha-dias {
background-color: #d2d2d2 !important;
border-top: 1px solid #d2d2d2;
}
span.numero-dia {
font-size: 1em;
}
.d-flex span {
margin-left: 8px;
}
.py-1 {
padding-top: .25rem!important;
padding-bottom: .25rem!important;
}
.px-4 {
padding-right: 1.5rem!important;
padding-left: 1.5rem!important;
}
.mb-3 {
margin-bottom: 1rem!important;
}
.card {
background-color: #fff;
padding: 4px;
margin: 10px 0;
border: 1px solid rgba(0,0,0,0.125);
}
.card-header {
padding: 0.5rem 1rem;
margin-bottom: 1rem;
}
.card-footer {
display: none;
}
.data-evento {
font-size: 1em;
display: block;
}
.tipo-evento {
font-size: 1em;
display: block;
margin-bottom: 8px;
}
.evento {
margin: 0;
padding: 5px 10px;
}
@font-face {
font-style: normal;
font-weight: 400;
}
@media print {
div.card {
break-inside: avoid;
}
}
{% endblock %}
{% block main_content %}
<h1>
{% blocktrans with month=mes_pesquisa|stringformat:"02d" year=ano_pesquisa|stringformat:"04d" %}Mês: {{ month }}/{{year}}{% endblocktrans %}
</h1>
<div class="legenda">
{% include "eventos/snippets/calendario_legenda.html" %}
</div>
<div class="calenario">
{% include "eventos/snippets/calendario_cal.html" %}
</div>
<div class="lista">
{% include "eventos/snippets/calendario_lista.html" %}
</div>
{% endblock main_content %}

77
sigi/apps/eventos/templates/eventos/eventos_por_uf.html

@ -0,0 +1,77 @@
{% extends "admin/base_site.html" %}
{% load static i18n djbs_extras %}
{% block extrastyle %}
{{ block.super }}
{{ form.media }}
{% endblock extrastyle %}
{% block breadcrumbs %}{% trans 'Eventos por Unidade da Federação' %}{% endblock %}
{% block content_title %}
<h5>{% trans 'Eventos por Unidade da Federação' %}</h5>
{% if data_inicio %}
<h6>
{% blocktranslate with inicio=data_inicio|date:"SHORT_DATE_FORMAT" fim=data_fim|date:"SHORT_DATE_FORMAT" %}
Período: {{ inicio }} a {{ fim }}
{% endblocktranslate %}
</h6>
{% endif %}
{% endblock %}
{% block content %}
<form>
<div class="card mb-3">
<div class="card-header">
<a class="icon-link" data-bs-toggle="collapse" href="#filterFormCollapse" aria-expanded="{% if pivo_uf is None %}true{% else %}false{% endif %}" aria-controls="filterFormCollapse">
{% icon "filter" %} {% translate "Filtros" %}
</a>
</div>
<div class="card-body collapse{% if pivo_uf is None %} show{% endif %}" id="filterFormCollapse">
{{ form }}
</div>
<div class="card-footer d-flex justify-content-end">
<div>
<button type="submit" class="btn btn-primary">{% trans 'Ver dados' %}</button>
<button type="submit" name="fmt" value="pdf" class="btn btn-primary" title="{% trans 'Exportar para PDF' %}">
{% icon "pdf" %}
{% trans 'Exportar para PDF' %}
</button>
<button type="submit" name="fmt" value="csv" class="btn btn-primary" title="{% trans 'Exportar para CSV' %}">
{% icon "csv" %}
{% trans 'Exportar para CSV' %}
</button>
</div>
</div>
</div>
</form>
{% if not pivo_uf is None %}
<div class="accordion" id="accordionReport">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseRegiao" aria-expanded="true" aria-controls="collapseRegiao">
{% translate 'Resumo por Região' %}
</button>
</h2>
<div id="collapseRegiao" class="accordion-collapse collapse show">
<div class="accordion-body">
{% include "eventos/snippets/resumo_por_regiao_snippet.html" with mode="html" %}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseData" aria-expanded="true" aria-controls="collapseData">
{% translate 'Resumo por Unidade da Federação' %}
</button>
</h2>
<div id="collapseData" class="accordion-collapse collapse show">
<div class="accordion-body container">
{% include "eventos/snippets/eventos_por_uf_snippet.html" with mode="html" %}
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}

20
sigi/apps/eventos/templates/eventos/eventos_por_uf_pdf.html

@ -0,0 +1,20 @@
{% extends "pdf/base_report.html" %}
{% load static i18n %}
{% block page_size %}A4 landscape{% endblock page_size %}
{% block main_content %}
<div class="filter-panel">
<p>
{% blocktranslate with inicio=data_inicio|date:"SHORT_DATE_FORMAT" fim=data_fim|date:"SHORT_DATE_FORMAT" %}
Período: {{ inicio }} a {{ fim }}
{% endblocktranslate %}
</p>
<p>{% trans 'Categoria(s)' %}: {{ categorias|join:", " }}</p>
<p>{% trans 'Modo(s)' %}: {{ virtual|join:", " }}</p>
</div>
<h4>{% translate 'Resumo por Região' %}</h4>
{% include "eventos/snippets/resumo_por_regiao_snippet.html" %}
<h4>{% translate 'Resumo por Unidade da Federação' %}</h4>
{% include "eventos/snippets/eventos_por_uf_snippet.html" %}
{% endblock %}

40
sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html

@ -0,0 +1,40 @@
{% load i18n static dict_get %}
<div class="calendar-wrapper">
<table class="table table-bordered table-sm calendar-table">
<thead>
{% for name in day_names %}
<th>{{ name }}</th>
{% endfor %}
</thead>
<tbody class="table-group-divider">
{% for semana in semanas %}
<tr class="linha-dias">
{% for dia in semana.datas %}
<td>
<span class="numero-dia">
{% if dia.month == mes_pesquisa %}{{ dia.day }}{% endif %}
</span>
</td>
{% endfor %}
</tr>
{% for evento, tupla in semana.eventos %}
<tr class="linha-evento table-info">
{% for x in ""|ljust:tupla.0|make_list %}<td></td>{% endfor %}
<td colspan="{{ tupla.1 }}" class="categoria_{{ evento.tipo_evento.categoria }}">
<p class="evento">
<i class="bi status_{{ evento.status }}" title="{{ evento.get_status_display }}"></i>
<a class="modal-trigger" data-bs-toggle="modal" data-bs-target="#modal{{ evento.id|safe }}" title="{{ evento.nome }}">{{ evento.nome }}</a>
</p>
</td>
{% for x in ""|ljust:tupla.2|make_list %}<td></td>{% endfor %}
</tr>
{% empty %}
<tr class="table-info">
{% for x in "1234567" %}<td>&nbsp;</td>{% endfor %}
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>

47
sigi/apps/eventos/templates/eventos/snippets/calendario_detail.html

@ -0,0 +1,47 @@
{% load i18n %}
<span class="data-evento">{{ evento.data_inicio }} a {{ evento.data_termino }}</span>
<span class="tipo-evento mb-3">
{{ evento.tipo_evento }} -
{{ evento.tipo_evento.get_categoria_display }} -
{{ evento.get_status_display }}
{% if evento.virtual %} {% trans "na modalidade virtual" %}{% endif %}
{% if evento.casa_anfitria %} {% trans "em" %} {{ evento.casa_anfitria }}{% endif %}
</span>
<p>{{ evento.descricao }}</p>
<p>{% trans "Solicitante" %}: {{ evento.solicitante }}</p>
{% if evento.equipe_set.all %}
<p>
{% trans "Equipe" %}:
{% for membro in evento.equipe_set.all %}
{{ membro.membro }} ({{ membro.funcao }})
{% if not forloop.last %} - {% endif %}
{% endfor %}
</p>
{% endif %}
{% if evento.convite_set.exists %}
<table class="table table-sm table-stripped">
<caption>{% trans "Casas covidadas" %}</caption>
<thead>
<tr>
<td>Casa</td>
<td>UF</td>
<td>Aceitou</td>
<td>Participou</td>
<td>Participantes</td>
</tr>
</thead>
{% for convite in evento.convite_set.all %}
<tr>
<td>{{ convite.casa.nome }}</td>
<td>{{ convite.casa.municipio.uf }}</td>
<td>{% if convite.aceite %}<i class="material-icons tiny">check</i>{% endif %}</td>
<td>{% if convite.participou %}<i class="material-icons tiny">check</i>{% endif %}</td>
<td>
{% for nome in convite.nomes_participantes.splitlines %}
{{ nome }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}

30
sigi/apps/eventos/templates/eventos/snippets/calendario_legenda.html

@ -0,0 +1,30 @@
{% load i18n djbs_extras %}
<table class="table table-sm table-info">
<tr>
<th>{% trans 'Mês / ano' %}</th>
<td>
{{ mes_pesquisa|stringformat:"02d" }} / {{ ano_pesquisa|stringformat:"02d" }}
</td>
</tr>
<tr>
<th>{% trans 'Categorias' %}</th>
<td>
<div class="d-flex justify-content-evenly flex-wrap">
{% for key, name in categorias %}
<span class="categoria_{{ key }} py-1 px-4">{{ name }}</span>
{% endfor %}
</div>
</td>
</tr>
<tr>
<th>{% trans 'Status' %}</th>
<td>
<div class="d-flex justify-content-evenly flex-wrap">
{% for key, name in status %}
<span class="py-1 px-4"><i class="bi status_{{ key }}"></i> {{ name }}</span>
{% endfor %}
</div>
</td>
</tr>
</table>

19
sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html

@ -0,0 +1,19 @@
{% load i18n static %}
{% for evento in eventos %}
<div class="card mb-3">
<div class="card-header categoria_{{ evento.tipo_evento.categoria }}">
<i class="bi status_{{ evento.status }}"></i>
{{ evento.nome }}
</div>
<div class="card-body">
{% include "eventos/snippets/calendario_detail.html" with evento=evento %}
</div>
<div class="card-footer">
<div class="d-flex">
<a class="ms-auto" href="{{ evento.get_absolute_url }}">{% trans "Ver no site" %}</a>
<a class="ms-2" href="{% url 'admin:eventos_evento_change' evento.id %}">{% trans "Editar" %}</a>
</div>
</div>
</div>
{% endfor %}

25
sigi/apps/eventos/templates/eventos/snippets/calendario_modals.html

@ -0,0 +1,25 @@
{% load i18n %}
{% for evento in eventos %}
<div class="modal fade" id="modal{{ evento.id|safe }}" tabindex="-1" aria-labelledby="label{{ evento.id|safe }}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header categoria_{{ evento.tipo_evento.categoria }}">
<h5 class="modal-title" id="label{{ evento.id|safe }}">
<i class="bi status_{{ evento.status }}"></i>
{{ evento.nome }}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate "Close" %}"></button>
</div>
<div class="modal-body">
{% include "eventos/snippets/calendario_detail.html" with evento=evento %}
</div>
<div class="modal-footer">
<a href="{{ evento.get_absolute_url }}">{% trans "Ver no site" %}</a>
<a href="{% url 'admin:eventos_evento_change' evento.id %}">{% trans "Editar" %}</a>
</div>
</div>
</div>
</div>
{% endfor %}

46
sigi/apps/eventos/templates/eventos/snippets/eventos_por_uf_snippet.html

@ -0,0 +1,46 @@
{% load i18n %}
<table class="table table-striped">
<thead>
<tr>
<th rowspan="2">{% trans 'Unidade Federativa' %}</th>
{% for label, items in cabecalho_uf %}
<th colspan="{{ items|length }}" class="center">{{ label|capfirst }}</th>
{% endfor %}
</tr>
<tr>
{% for top, items in cabecalho_uf %}
{% for label in items %}
<th class="numero">{{ label }}</th>
{% endfor %}
{% endfor %}
</tr>
</thead>
<tbody>
{% for datarow in pivo_uf.itertuples %}
{% ifchanged datarow.Index.0 %}
<tr>
{% with l1=cabecalho_uf.0.1|length l2=cabecalho_uf.1.1|length l3=cabecalho_uf.2.1|length l4=cabecalho_uf.3.1|length %}
<th class="sep_regiao" colspan="{{ l1|add:l2|add:l3|add:l4|add:1 }}">{{ datarow.Index.0 }}</th>
{% endwith %}
</th>
</tr>
{% endifchanged %}
<tr>
{% for datacol in datarow %}
{% if forloop.first %}
<th>{{ datacol.1 }}</th>
{% else %}
<td class="numero">{{ datacol|default:"-" }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
<tr>
<th>{% trans 'Sumário' %}</th>
{% for total in total_uf %}
<th class="numero">{{ total }}</th>
{% endfor %}
</tr>
</tbody>
</table>

37
sigi/apps/eventos/templates/eventos/snippets/resumo_por_regiao_snippet.html

@ -0,0 +1,37 @@
{% load i18n %}
<table class="table table-striped">
<thead>
<tr>
<th rowspan="2">{% trans 'Região' %}</th>
{% for label, items in cabecalho_regiao %}
<th colspan="{{ items|length }}" class="center">{{ label|capfirst }}</th>
{% endfor %}
</tr>
<tr>
{% for top, items in cabecalho_regiao %}
{% for label in items %}
<th class="numero">{{ label }}</th>
{% endfor %}
{% endfor %}
</tr>
</thead>
<tbody>
{% for datarow in pivo_regiao.itertuples %}
<tr>
{% for datacol in datarow %}
{% if forloop.first %}
<th>{{ datacol }}</th>
{% else %}
<td class="numero">{{ datacol|default:"-" }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
<tr>
<th>{% trans 'Sumário' %}</th>
{% for total in total_regiao %}
<th class="numero">{{ total }}</th>
{% endfor %}
</tr>
</tbody>
</table>

35
sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html

@ -0,0 +1,35 @@
{% load i18n %}
<table class="table table-sm table-info">
<colgroup>
<col style="width: 20%;"/>
<col/>
</colgroup>
<tr>
<th>{% trans 'Período' %}</th>
<td>
{% blocktranslate with inicio=data_inicio|date:"SHORT_DATE_FORMAT" fim=data_fim|date:"SHORT_DATE_FORMAT" %}
{{ inicio }} a {{ fim }}
{% endblocktranslate %}
</td>
</tr>
<tr>
<th>{% trans 'Status' %}</th>
<td>
<ul>
{% for i, label in status_choices %}
<li><strong>{{ i }}</strong>: {{ label }}</li>
{% endfor %}
</ul>
</td>
</tr>
<tr>
<th>{% trans 'Oficinas' %}</th>
<td>
<ul>
{% for sigla, nome in legenda_oficinas %}
<li><strong>{{ sigla }}</strong>: {{ nome }}</li>
{% endfor %}
</ul>
</td>
</tr>
</table>

28
sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html

@ -0,0 +1,28 @@
{% load i18n %}
<table class="table table-striped">
<thead>
<tr>
<th rowspan="2">{% trans 'Região' %}</th>
<th colspan="4" class="center">{% trans 'Quantidade' %}</th>
<th rowspan="2" class="numero">{% trans 'Custo total' %}</th>
</tr>
<tr>
<th class="numero">{% trans 'Solicitada' %}</th>
<th class="numero">{% trans 'Atendida' %}</th>
<th class="numero">{% trans 'Não atendida' %}</th>
<th class="numero">{% trans 'Participantes' %}</th>
</tr>
</thead>
<tbody>
{% for regiao in resumo_regiao.itertuples %}
<tr>
<td>{{ regiao.regiao }}</td>
<td class="numero">{{ regiao.qtde_solicitadas }}</td>
<td class="numero">{{ regiao.qtde_atendidas|default:"-" }}</td>
<td class="numero">{{ regiao.qtde_rejeitadas|default:"-" }}</td>
<td class="numero">{{ regiao.participantes|default:"-" }}</td>
<td class="numero">{{ regiao.custo_total|floatformat:2|default:"-" }}</td>
</tr>
{% endfor %}
</tbody>
</table>

35
sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_senador_snippet.html

@ -0,0 +1,35 @@
{% load i18n %}
<table class="table table-striped">
<thead>
<tr>
<th rowspan="2">{% trans 'UF' %}</th>
<th rowspan="2">{% trans 'Senador' %}</th>
<th colspan="4" class="center">{% trans 'Quantidade' %}</th>
<th rowspan="2" class="numero">{% trans 'Custo total' %}</th>
</tr>
<tr>
<th class="numero">{% trans 'Solicitada' %}</th>
<th class="numero">{% trans 'Atendida' %}</th>
<th class="numero">{% trans 'Não atendida' %}</th>
<th class="numero">{% trans 'Participantes' %}</th>
</tr>
</thead>
<tbody>
{% for uf in resumo_uf.itertuples %}
{% ifchanged uf.regiao %}
<tr>
<th class="sep_regiao" colspan="7">{{ uf.regiao }}</th>
</tr>
{% endifchanged %}
<tr>
<td>{{ uf.uf }}</td>
<td>{{ uf.senador }}</td>
<td class="numero">{{ uf.qtde_solicitadas }}</td>
<td class="numero">{{ uf.qtde_atendidas|default:"-" }}</td>
<td class="numero">{{ uf.qtde_rejeitadas|default:"-" }}</td>
<td class="numero">{{ uf.participantes|default:"-" }}</td>
<td class="numero">{{ uf.custo_total|floatformat:2|default:"-" }}</td>
</tr>
{% endfor %}
</tbody>
</table>

70
sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html

@ -0,0 +1,70 @@
{% load i18n djbs_extras %}
{% if not solicitacoes.exists %}
<div class="alert alert-warning" role="alert">
{% icon "alert" %}
Nenhuma solicitação encontrada para o filtro informado
</div>
{% else %}
<table class="table table-striped">
<thead>
<tr>
<th rowspan="2">{% trans 'UF' %}</th>
<th rowspan="2">{% trans 'Microrregião' %}</th>
<th rowspan="2">{% trans 'Casa solicitante' %}</th>
<th rowspan="2">{% trans 'Senador' %}</th>
<th rowspan="2">{% trans 'Data pedido' %}</th>
<th rowspan="2">{% trans 'Oficinas (status)' %}</th>
<th colspan="4" class="center">{% trans 'Quantidade' %}</th>
<th rowspan="2" class="numero">{% trans 'Custo total' %}</th>
</tr>
<tr>
<th class="numero">{% trans 'Solicitada' %}</th>
<th class="numero">{% trans 'Atendida' %}</th>
<th class="numero">{% trans 'Não atendida' %}</th>
<th class="numero">{% trans 'Participantes' %}</th>
</tr>
</thead>
<tbody>
{% for sol in solicitacoes.all %}
{% ifchanged sol.casa.municipio.uf.regiao %}
<tr>
<th colspan="11" class="center">
{{ sol.casa.municipio.uf.get_regiao_display }}
</th>
</tr>
{% endifchanged %}
<tr>
<td>{{ sol.casa.municipio.uf.sigla }}</td>
<td>{{ sol.casa.municipio.microrregiao.nome }}</td>
<td>{{ sol.casa.nome }}</td>
<td>{{ sol.senador }}</td>
<td>{{ sol.data_pedido|date:"SHORT_DATE_FORMAT" }}</td>
<td>
<ul class="report-list">
{% for item in sol.itemsolicitado_set.all %}
<li title="{{ item.tipo_evento.nome }} ({{ item.get_status_display }})">{{ item.tipo_evento.sigla }} ({{ item.status }})</li>
{% endfor %}
</ul>
</td>
<td class="numero">{{ sol.qtde_solicitadas }}</td>
<td class="numero">{{ sol.qtde_atendidas|default:"-" }}</td>
<td class="numero">{{ sol.qtde_rejeitadas|default:"-" }}</td>
<td class="numero">{{ sol.participantes|default:"-" }}</td>
<td class="numero">{{ sol.custo_total|floatformat:2|default:"-" }}</td>
</tr>
{% endfor %}
<tr>
<th colspan="6">{% trans 'Sumário' %}</th>
{% for valor in sumario %}
<th class="numero">
{% if forloop.last %}
{{ valor|floatformat:2|default:"-" }}
{% else %}
{{ valor|default:"-" }}
{% endif %}
</th>
{% endfor %}
</tr>
</tbody>
</table>
{% endif %}

30
sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html

@ -0,0 +1,30 @@
{% load i18n %}
<table class="table table-striped">
<thead>
<tr>
<th rowspan="2">{% trans 'Sigla' %}</th>
<th rowspan="2">{% trans 'Nome' %}</th>
<th colspan="4" class="center">{% trans 'Quantidade' %}</th>
<th rowspan="2" class="numero">{% trans 'Custo total' %}</th>
</tr>
<tr>
<th class="numero">{% trans 'Solicitada' %}</th>
<th class="numero">{% trans 'Atendida' %}</th>
<th class="numero">{% trans 'Não atendida' %}</th>
<th class="numero">{% trans 'Participantes' %}</th>
</tr>
</thead>
<tbody>
{% for tipo in resumo_tipo_evento.itertuples %}
<tr>
<td>{{ tipo.sigla }}</td>
<td>{{ tipo.nome }}</td>
<td class="numero">{{ tipo.qtde_solicitadas }}</td>
<td class="numero">{{ tipo.qtde_atendidas|default:"-" }}</td>
<td class="numero">{{ tipo.qtde_rejeitadas|default:"-" }}</td>
<td class="numero">{{ tipo.participantes|default:"-" }}</td>
<td class="numero">{{ tipo.custo_total|floatformat:2|default:"-" }}</td>
</tr>
{% endfor %}
</tbody>
</table>

111
sigi/apps/eventos/templates/eventos/solicitacoes_por_periodo.html

@ -0,0 +1,111 @@
{% extends "admin/base_site.html" %}
{% load static i18n djbs_extras %}
{% block extrastyle %}
{{ block.super }}
{{ form.media }}
{% endblock extrastyle %}
{% block breadcrumbs %}{% trans 'Solicitações de evento por período' %}{% endblock %}
{% block content_title %}
<h5>{% trans 'Solicitações de evento por período' %}</h5>
{% endblock %}
{% block content %}
{% if not solicitacoes is None and not solicitacoes.exists %}
<div class="alert alert-warning" role="alert">
{% icon "alert" %}
Nenhuma solicitação encontrada para o filtro informado
</div>
{% endif %}
<form>
<div class="card mb-3">
<div class="card-header">
<a class="icon-link" data-bs-toggle="collapse" href="#filterFormCollapse" aria-expanded="{% if solicitacoes is None or not solicitacoes.exists %}true{% else %}false{% endif %}" aria-controls="filterFormCollapse">
{% icon "filter" %} {% translate "Filtros" %}
</a>
</div>
<div class="card-body collapse{% if solicitacoes is None or not solicitacoes.exists %} show{% endif %}" id="filterFormCollapse">
{{ form }}
</div>
<div class="card-footer d-flex justify-content-end">
<div>
<button type="submit" class="btn btn-primary">{% trans 'Ver dados' %}</button>
<button type="submit" name="fmt" value="pdf" class="btn btn-primary" title="{% trans 'Exportar para PDF' %}">
{% icon "pdf" %}
{% trans 'Exportar para PDF' %}
</button>
<button type="submit" name="fmt" value="csv" class="btn btn-primary" title="{% trans 'Exportar para CSV' %}">
{% icon "csv" %}
{% trans 'Exportar para CSV' %}
</button>
</div>
</div>
</div>
</form>
{% if solicitacoes %}
<div class="accordion" id="accordionReport">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseLegenda" aria-expanded="true" aria-controls="collapseLegenda">
{% translate "Legenda" %}
</button>
</h2>
<div id="collapseLegenda" class="accordion-collapse collapse show">
<div class="accordion-body">
{% include "eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html" %}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSolicitacoes" aria-expanded="true" aria-controls="collapseSolicitacoes">
{% trans 'Solicitações' %}
</button>
</h2>
<div id="collapseSolicitacoes" class="accordion-collapse collapse show">
<div class="accordion-body">
{% include "eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html" %}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSenador" aria-expanded="true" aria-controls="collapseSenador">
{% trans 'Resumo por Senador' %}
</button>
</h2>
<div id="collapseSenador" class="accordion-collapse collapse show">
<div class="accordion-body">
{% include "eventos/snippets/solicitacoes_por_periodo_senador_snippet.html" %}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseRegiao" aria-expanded="true" aria-controls="collapseRegiao">
{% trans 'Resumo por Região' %}
</button>
</h2>
<div id="collapseRegiao" class="accordion-collapse collapse show">
<div class="accordion-body">
{% include "eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html" %}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTipo" aria-expanded="true" aria-controls="collapseTipo">
{% trans 'Resumo por tipo de evento' %}
</button>
</h2>
<div id="collapseTipo" class="accordion-collapse collapse show">
<div class="accordion-body">
{% include "eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html" %}
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}

34
sigi/apps/eventos/templates/eventos/solicitacoes_por_periodo_pdf.html

@ -0,0 +1,34 @@
{% extends "pdf/base_report.html" %}
{% load i18n static djbs_extras %}
{% block page_size %}A4 landscape{% endblock page_size %}
{% block main_content %}
<div class="legenda">
<h4>{% translate "Legenda" %}</h4>
{% include "eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html" %}
</div>
{% if not solicitacoes %}
<div class="alert alert-warning" role="alert">
{% icon "alert" %}
Nenhuma solicitação encontrada para o filtro informado
</div>
{% else %}
<div class="solicitacoes">
<h4>{% trans 'Solicitações' %}</h4>
{% include "eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html" %}
</div>
<div class="senador new-page">
<h4>{% trans 'Resumo por Senador' %}</h4>
{% include "eventos/snippets/solicitacoes_por_periodo_senador_snippet.html" %}
</div>
<div class="regiao new-page">
<h4>{% trans 'Resumo por Região' %}</h4>
{% include "eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html" %}
</div>
<div class="tipo new-page">
<h4>{% trans 'Resumo por tipo de evento' %}</h4>
{% include "eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html" %}
</div>
{% endif %}
{% endblock %}

275
sigi/apps/eventos/views.py

@ -51,6 +51,7 @@ from sigi.apps.eventos.models import (
from sigi.apps.eventos.forms import ( from sigi.apps.eventos.forms import (
EventosPorUfForm, EventosPorUfForm,
SolicitacoesPorPeriodoForm, SolicitacoesPorPeriodoForm,
CalendarioForm,
) )
from sigi.apps.eventos.serializers import ( from sigi.apps.eventos.serializers import (
EventoSerializer, EventoSerializer,
@ -192,32 +193,31 @@ class AlunosPorUfReportView(
@login_required @login_required
@staff_member_required @staff_member_required
def calendario(request): def calendario(request):
mes_pesquisa = int(request.GET.get("mes", timezone.localdate().month)) fmt = request.GET.get("fmt", "html")
ano_pesquisa = int(request.GET.get("ano", timezone.localdate().year)) if "mes_ano" in request.GET:
sel_categorias = request.GET.getlist( form = CalendarioForm(request.GET)
"categoria", [c[0] for c in TipoEvento.CATEGORIA_CHOICES] else:
) form = CalendarioForm(
sel_status = request.GET.getlist( initial={
"status", [s[0] for s in Evento.STATUS_CHOICES] "mes_ano": timezone.localdate().replace(day=1),
) "categorias": [c[0] for c in TipoEvento.CATEGORIA_CHOICES],
formato = request.GET.get("fmt", "cal") "status": [s[0] for s in Evento.STATUS_CHOICES],
pdf = bool(request.GET.get("pdf", 0)) }
)
context = {"form": form}
if not form.is_valid():
return render(request, "eventos/calendario.html", context)
mes_pesquisa = form.cleaned_data["mes_ano"].month
ano_pesquisa = form.cleaned_data["mes_ano"].year
sel_categorias = form.cleaned_data["categorias"]
sel_status = form.cleaned_data["status"]
meses = {}
lang = to_locale(get_language()) + ".UTF-8" lang = to_locale(get_language()) + ".UTF-8"
locale.setlocale(locale.LC_ALL, lang) locale.setlocale(locale.LC_ALL, lang)
for ano, mes in (
Evento.objects.exclude(data_inicio=None)
.values_list("data_inicio__year", "data_inicio__month")
.order_by("data_inicio__year", "data_inicio__month")
.distinct("data_inicio__year", "data_inicio__month")
):
if ano in meses:
meses[ano][mes] = calendar.month_name[mes]
else:
meses[ano] = {mes: calendar.month_name[mes]}
eventos = ( eventos = (
Evento.objects.exclude(data_inicio=None) Evento.objects.exclude(data_inicio=None)
.exclude(data_termino=None) .exclude(data_termino=None)
@ -230,67 +230,47 @@ def calendario(request):
.order_by("data_inicio") .order_by("data_inicio")
) )
context = { semanas = [
"ano_pesquisa": ano_pesquisa, {"datas": s, "eventos": []}
"mes_pesquisa": mes_pesquisa, for s in calendar.Calendar().monthdatescalendar(
"formato": formato, ano_pesquisa, mes_pesquisa
"sel_categorias": sel_categorias, )
"categorias": dict( ]
map(
lambda x, y: (x[0], {"label": x[1], "color": y}),
TipoEvento.CATEGORIA_CHOICES,
["red", "purple", "blue", "orange", "brown"],
)
),
"sel_status": sel_status,
"status": dict(
map(
lambda x, y: (x[0], {"label": x[1], "icon": y}),
Evento.STATUS_CHOICES,
[
"access_time",
"thumb_up",
"done_all",
"mood_bad",
"archive",
],
)
),
"meses": meses,
"day_names": calendar.day_abbr,
"eventos": eventos,
}
if formato == "cal" or pdf:
semanas = [
{"datas": s, "eventos": []}
for s in calendar.Calendar().monthdatescalendar(
ano_pesquisa, mes_pesquisa
)
]
for e in eventos: for e in eventos:
for s in semanas: for s in semanas:
if not ( if not (
(e.data_termino < s["datas"][0]) (e.data_termino < s["datas"][0])
or (e.data_inicio > s["datas"][-1]) or (e.data_inicio > s["datas"][-1])
): ):
start = max(s["datas"][0], e.data_inicio) start = max(s["datas"][0], e.data_inicio)
end = min(s["datas"][-1], e.data_termino) end = min(s["datas"][-1], e.data_termino)
s["eventos"].append( s["eventos"].append(
(
e,
( (
e, start.weekday(),
( end.weekday() - start.weekday() + 1,
start.weekday(), 6 - end.weekday(),
end.weekday() - start.weekday() + 1, ),
6 - end.weekday(),
),
)
) )
)
context["semanas"] = semanas context.update(
{
"ano_pesquisa": ano_pesquisa,
"mes_pesquisa": mes_pesquisa,
"sel_categorias": sel_categorias,
"sel_status": sel_status,
"day_names": calendar.day_abbr,
"categorias": TipoEvento.CATEGORIA_CHOICES,
"status": Evento.STATUS_CHOICES,
"eventos": eventos,
"semanas": semanas,
}
)
if pdf: if fmt == "pdf":
context["title"] = _("Calendário de eventos") context["title"] = _("Calendário de eventos")
context["pdf"] = True context["pdf"] = True
return WeasyTemplateResponse( return WeasyTemplateResponse(
@ -300,8 +280,7 @@ def calendario(request):
context=context, context=context,
content_type="application/pdf", content_type="application/pdf",
) )
else: return render(request, "eventos/calendario.html", context)
return render(request, "eventos/calendario.html", context)
class EventoListView(ListView): class EventoListView(ListView):
@ -742,7 +721,7 @@ def eventos_por_uf(request):
context["title"] = _("Eventos por Unidade da Federação") context["title"] = _("Eventos por Unidade da Federação")
context["pdf"] = True context["pdf"] = True
return WeasyTemplateResponse( return WeasyTemplateResponse(
filename=f"eventos_por_uf-{data_inicio}-{data_fim}.pdf", # filename=f"eventos_por_uf-{data_inicio}-{data_fim}.pdf",
request=request, request=request,
template="eventos/eventos_por_uf_pdf.html", template="eventos/eventos_por_uf_pdf.html",
context=context, context=context,
@ -858,79 +837,83 @@ def solicitacoes_por_periodo(request):
Sum("participantes"), Sum("participantes"),
Sum("custo_total"), Sum("custo_total"),
).values() ).values()
resumo_uf = ( resumo_uf = pd.DataFrame(
pd.DataFrame( solicitacoes.order_by(
solicitacoes.order_by( "casa__municipio__uf__regiao",
"casa__municipio__uf__regiao", "senador",
"senador", "casa__municipio__uf",
"casa__municipio__uf", ).values(
).values( "casa__municipio__uf__regiao",
"casa__municipio__uf__regiao", "casa__municipio__uf__sigla",
"casa__municipio__uf__sigla", "senador",
"senador",
"qtde_solicitadas",
"qtde_atendidas",
"qtde_rejeitadas",
"participantes",
"custo_total",
)
)
.rename(
columns={
"casa__municipio__uf__regiao": "regiao",
"casa__municipio__uf__sigla": "uf",
}
)
.fillna(0)
.replace({"regiao": dict(UnidadeFederativa.REGIAO_CHOICES)})
.groupby(["regiao", "senador", "uf"], as_index=False)
.sum()
)
resumo_uf["participantes"] = resumo_uf["participantes"].astype("int")
resumo_regiao = resumo_uf.groupby(["regiao"], as_index=False)[
[
"qtde_solicitadas", "qtde_solicitadas",
"qtde_atendidas", "qtde_atendidas",
"qtde_rejeitadas", "qtde_rejeitadas",
"participantes", "participantes",
"custo_total", "custo_total",
]
].sum()
resumo_uf.replace([0], [None], inplace=True)
resumo_regiao.replace([0], [None], inplace=True)
resumo_tipo_evento = (
pd.DataFrame(
ItemSolicitado.objects.filter(solicitacao__in=solicitacoes)
.order_by("tipo_evento__sigla", "tipo_evento__nome")
.values("tipo_evento__sigla", "tipo_evento__nome")
.annotate(
qtde_solicitadas=Count("id"),
qtde_atendidas=Count(
"id", filter=Q(status=ItemSolicitado.STATUS_AUTORIZADO)
),
qtde_rejeitadas=Count(
"id", filter=Q(status=ItemSolicitado.STATUS_REJEITADO)
),
participantes=Sum("evento__total_participantes"),
custo_total=Subquery(
sq_equipe.filter(evento__itemsolicitado=OuterRef("pk"))[:1]
),
)
) )
.rename( ).rename(
columns={ columns={
"tipo_evento__sigla": "sigla", "casa__municipio__uf__regiao": "regiao",
"tipo_evento__nome": "nome", "casa__municipio__uf__sigla": "uf",
} }
)
if resumo_uf.empty:
resumo_regiao = resumo_uf
else:
resumo_uf = (
resumo_uf.fillna(0)
.replace({"regiao": dict(UnidadeFederativa.REGIAO_CHOICES)})
.groupby(["regiao", "senador", "uf"], as_index=False)
.sum()
) )
.groupby(["sigla", "nome"], as_index=False) resumo_uf["participantes"] = resumo_uf["participantes"].astype("int")
.sum() resumo_regiao = resumo_uf.groupby(["regiao"], as_index=False)[
.fillna(0) [
"qtde_solicitadas",
"qtde_atendidas",
"qtde_rejeitadas",
"participantes",
"custo_total",
]
].sum()
resumo_uf.replace([0], [None], inplace=True)
resumo_regiao.replace([0], [None], inplace=True)
resumo_tipo_evento = pd.DataFrame(
ItemSolicitado.objects.filter(solicitacao__in=solicitacoes)
.order_by("tipo_evento__sigla", "tipo_evento__nome")
.values("tipo_evento__sigla", "tipo_evento__nome")
.annotate(
qtde_solicitadas=Count("id"),
qtde_atendidas=Count(
"id", filter=Q(status=ItemSolicitado.STATUS_AUTORIZADO)
),
qtde_rejeitadas=Count(
"id", filter=Q(status=ItemSolicitado.STATUS_REJEITADO)
),
participantes=Sum("evento__total_participantes"),
custo_total=Subquery(
sq_equipe.filter(evento__itemsolicitado=OuterRef("pk"))[:1]
),
)
).rename(
columns={
"tipo_evento__sigla": "sigla",
"tipo_evento__nome": "nome",
}
) )
resumo_tipo_evento["participantes"] = resumo_tipo_evento[
"participantes" if not resumo_tipo_evento.empty:
].astype("int") resumo_tipo_evento = (
resumo_tipo_evento.replace([0], [None], inplace=True) resumo_tipo_evento.groupby(["sigla", "nome"], as_index=False)
.sum()
.fillna(0)
)
resumo_tipo_evento["participantes"] = resumo_tipo_evento[
"participantes"
].astype("int")
resumo_tipo_evento.replace([0], [None], inplace=True)
# Imprimir # Imprimir
context = { context = {
"form": form, "form": form,

82
sigi/templates/pdf/base.html

@ -0,0 +1,82 @@
{% load static i18n %}
<!DOCTYPE HTML>
<html lang="pt-BR">
<head>
<meta charset="utf-8"/>
<meta name="description" content="SIGI reports">
<meta name="author" content="Interlegis">
<style type="text/css">
@page {
size: {% block page_size %}{{ pagesize|default:"A4 portrait" }}{% endblock page_size %};
margin: {% block page_margin %}3cm 2cm 2cm 2cm{% endblock page_margin %};
font-family: "Helvetica", "Arial", "sans-serif";
font-size: 10px;
border-top: 1px solid #037036;
border-bottom: 1px solid #037036;
padding-top: 24px;
padding-bottom: 24px;
{% block page-header-settings %}
@top-left {content: url("{% static 'img/logo-senado.png' %}");}
@top-center { content: element(header); }
{% endblock %}
{% block page-footer-settings %}
@bottom-left { content: element(footerLeft); }
@bottom-center { content: element(footer); }
@bottom-right { content: "{% trans "Página: " %}" counter(page); }
{% endblock %}
{% block extra_page_settings %}{% endblock extra_page_settings %}
}
body {
margin: 0;
}
h1 { bookmark-level: 1 }
h2 { bookmark-level: 2 }
h3 { bookmark-level: 3 }
h4 { bookmark-level: 4 }
h5 { bookmark-level: 5 }
h6 { bookmark-level: 6 }
@media print {
header {position: running(header);}
footer {position: running(footer);}
.footerLeft {
text-align: center;
position: running(footerLeft);
}
}
body {
font-family: "Helvetica", "Arial", "sans-serif";
font-size: 10px;
}
div.new-page {
break-before: always;
}
.left-align {
text-align: left;
}
.right-align {
text-align: right;
}
.center-align {
text-align: center;
}
.justify-align {
text-align: justify;
}
.left {
float: left !important;
}
.right {
float: right !important;
}
{% block extra_style %}{% endblock extra_style %}
</style>
<link rel="stylesheet" href="{{ djbs.ICON_SOURCE|safe }}">
{% block extra_head %}{% endblock extra_head %}
<title>{% block title %}{{ title|default:"SIGI report" }}{% endblock title %}</title>
</head>
<body class="{% block body_class %}{% endblock body_class %}">
{% block body_content %}{% endblock body_content %}
</body>
</html>

137
sigi/templates/pdf/base_report.html

@ -0,0 +1,137 @@
{% extends 'pdf/base.html' %}
{% load static i18n %}
{% block title %}{{ title }}{% endblock title %}
{% block extra_head %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="/static/css/calendario.css">
{% endblock extra_head %}
{% block extra_style %}
h1, h2, h3, h4, h5, h6 {
margin: 24px 0 8px 8px;
}
h1 {font-size: 1.6em;}
h2 {font-size: 1.5em;}
h3 {font-size: 1.4em;}
h4 {font-size: 1.3em;}
h5 {font-size: 1.2em;}
h6 {font-size: 1.1em;}
header {
font-size: 1.4em;
font-weight: bold;
text-align: left;
}
header p {
margin: 0;
}
footer {
text-align: right;
}
footer img {
width: 105mm;
}
.report_name {
font-size: 1.6em;
margin-top: 5px;
}
table {
border: 2px solid white;
width: 100%;
}
th,td {
padding: 4px;
}
th {
background-color: #007433;
color: white;
font-weight: 600;
text-transform: uppercase;
}
tr:nth-child(even) {
background-color: #d2d2d2;
}
.title_row {
background-color: #b2b2b2;
}
.left-align {
text-align: left;
}
.center-align {
text-align: center;
}
.right-align {
text-align: right;
}
.bold {
font-weight: bold;
}
ul {
list-style-type: none;
margin: 0px;
padding: 0px;
}
.filter-panel {
margin: 0 8px 12px;
}
.center {
text-align: center;
}
.numero {
text-align: right;
}
.alert {
--bs-alert-bg: transparent;
--bs-alert-padding-x: 1rem;
--bs-alert-padding-y: 1rem;
--bs-alert-margin-bottom: 1rem;
--bs-alert-color: inherit;
--bs-alert-border-color: transparent;
--bs-alert-border: 1px solid var(--bs-alert-border-color);
--bs-alert-border-radius: 0.375rem;
--bs-alert-link-color: inherit;
position: relative;
padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x);
margin-bottom: var(--bs-alert-margin-bottom);
color: var(--bs-alert-color);
background-color: var(--bs-alert-bg);
border: var(--bs-alert-border);
border-radius: var(--bs-alert-border-radius);
}
.alert-warning {
--bs-alert-color: #8c5a1d;
--bs-alert-bg: #fde9d0;
--bs-alert-border-color: #ffe8a1;
--bs-alert-link-color: #8c5a1d;
}
{% endblock extra_style %}
{% block body_content %}
{% spaceless %}
<header>
{% block header %}
<p>{% trans 'SENADO FEDERAL' %}</p>
<p>{% trans 'Instituto Legislativo Brasileiro - ILB - Interlegis' %}</p>
<p class="report_name">{% block report_name %}{{ title|upper }}{% endblock report_name %}</p>
{% endblock header %}
</header>
<div class="footerLeft">
{% block footer_text %}
{% trans 'Emitido em' %}
<br/>
{% now "DATETIME_FORMAT" %}
{% endblock footer_text %}
</div>
<footer>
{% block footer %}
{% block footer_image %}<img src="{% static 'img/logos_rodape.png' %}" />{% endblock footer_image %}
{% endblock footer %}
</footer>
{% endspaceless %}
{% block main_content %}{% endblock main_content %}
{% endblock body_content %}
Loading…
Cancel
Save