diff --git a/sigi/apps/eventos/forms.py b/sigi/apps/eventos/forms.py index d4b528e..24a44cd 100644 --- a/sigi/apps/eventos/forms.py +++ b/sigi/apps/eventos/forms.py @@ -10,6 +10,7 @@ from sigi.apps.eventos.models import ( Solicitacao, ) from sigi.apps.parlamentares.models import Parlamentar +from sigi.apps.utils.forms.fields import MonthField class EventoAdminForm(forms.ModelForm): @@ -236,3 +237,19 @@ class ParlamentarForm(forms.ModelForm): "nome_completo": forms.HiddenInput, "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, + ) diff --git a/sigi/apps/eventos/static/css/calendario.css b/sigi/apps/eventos/static/css/calendario.css index 8c644b2..177e17a 100644 --- a/sigi/apps/eventos/static/css/calendario.css +++ b/sigi/apps/eventos/static/css/calendario.css @@ -1,9 +1,50 @@ -#content { - display: block; +.categoria_C { + --bs-table-bg: #ffcdd2; + background-color: #ffcdd2 !important; } -.evento { - padding: 0 6px; +.categoria_E { + --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 { @@ -19,22 +60,8 @@ 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 { border-bottom: none; @@ -48,15 +75,21 @@ tr.linha-dias { background: var(--darkened-bg); } - -span.numero-dia { - font-size: 1em; -} - tr.linha-evento { background: var(--body-bg); } .calendar-wrapper { width: 100%; -} \ No newline at end of file +} + +.evento { + padding: 0 6px; +} + + +span.numero-dia { + font-size: 1em; +} + +---------------------------------------------------*/ \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/calendario.html b/sigi/apps/eventos/templates/eventos/calendario.html new file mode 100644 index 0000000..0354a80 --- /dev/null +++ b/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 }} + +{% endblock %} + +{% block breadcrumbs %} + + +{% endblock %} + +{% block content %} + {% if not eventos is None and not eventos.exists %} + + {% endif %} + +
+
+ +
+ {{ form }} +
+ +
+
+ + {% if eventos.exists %} +
+
+

+ +

+
+
+ {% include "eventos/snippets/calendario_legenda.html" %} +
+
+
+
+

+ +

+
+
+ {% include "eventos/snippets/calendario_cal.html" %} +
+
+
+
+

+ +

+
+
+ {% include "eventos/snippets/calendario_lista.html" %} +
+
+
+
+ {% include "eventos/snippets/calendario_modals.html" %} + {% endif %} + +{% endblock %} \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/calendario_pdf.html b/sigi/apps/eventos/templates/eventos/calendario_pdf.html new file mode 100644 index 0000000..c5909f2 --- /dev/null +++ b/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 %} +

+ {% blocktrans with month=mes_pesquisa|stringformat:"02d" year=ano_pesquisa|stringformat:"04d" %}Mês: {{ month }}/{{year}}{% endblocktrans %} +

+
+ {% include "eventos/snippets/calendario_legenda.html" %} +
+
+ {% include "eventos/snippets/calendario_cal.html" %} +
+
+ {% include "eventos/snippets/calendario_lista.html" %} +
+{% endblock main_content %} \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/eventos_por_uf.html b/sigi/apps/eventos/templates/eventos/eventos_por_uf.html new file mode 100644 index 0000000..5d9eef5 --- /dev/null +++ b/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 %} +
{% trans 'Eventos por Unidade da Federação' %}
+ {% if data_inicio %} +
+ {% blocktranslate with inicio=data_inicio|date:"SHORT_DATE_FORMAT" fim=data_fim|date:"SHORT_DATE_FORMAT" %} + Período: {{ inicio }} a {{ fim }} + {% endblocktranslate %} +
+ {% endif %} +{% endblock %} + +{% block content %} +
+
+ +
+ {{ form }} +
+ +
+
+ + {% if not pivo_uf is None %} +
+
+

+ +

+
+
+ {% include "eventos/snippets/resumo_por_regiao_snippet.html" with mode="html" %} +
+
+
+
+

+ +

+
+
+ {% include "eventos/snippets/eventos_por_uf_snippet.html" with mode="html" %} +
+
+
+
+ {% endif %} +{% endblock %} \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/eventos_por_uf_pdf.html b/sigi/apps/eventos/templates/eventos/eventos_por_uf_pdf.html new file mode 100644 index 0000000..ccb2c7d --- /dev/null +++ b/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 %} +
+

+ {% blocktranslate with inicio=data_inicio|date:"SHORT_DATE_FORMAT" fim=data_fim|date:"SHORT_DATE_FORMAT" %} + Período: {{ inicio }} a {{ fim }} + {% endblocktranslate %} +

+

{% trans 'Categoria(s)' %}: {{ categorias|join:", " }}

+

{% trans 'Modo(s)' %}: {{ virtual|join:", " }}

+
+

{% translate 'Resumo por Região' %}

+ {% include "eventos/snippets/resumo_por_regiao_snippet.html" %} +

{% translate 'Resumo por Unidade da Federação' %}

+ {% include "eventos/snippets/eventos_por_uf_snippet.html" %} +{% endblock %} diff --git a/sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html b/sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html new file mode 100644 index 0000000..f300589 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html @@ -0,0 +1,40 @@ +{% load i18n static dict_get %} + +
+ + + {% for name in day_names %} + + {% endfor %} + + + {% for semana in semanas %} + + {% for dia in semana.datas %} + + {% endfor %} + + {% for evento, tupla in semana.eventos %} + + {% for x in ""|ljust:tupla.0|make_list %}{% endfor %} + + {% for x in ""|ljust:tupla.2|make_list %}{% endfor %} + + {% empty %} + + {% for x in "1234567" %}{% endfor %} + + {% endfor %} + {% endfor %} + +
{{ name }}
+ + {% if dia.month == mes_pesquisa %}{{ dia.day }}{% endif %} + +
+

+ + {{ evento.nome }} +

+
 
+
\ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/snippets/calendario_detail.html b/sigi/apps/eventos/templates/eventos/snippets/calendario_detail.html new file mode 100644 index 0000000..94649d8 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/calendario_detail.html @@ -0,0 +1,47 @@ +{% load i18n %} +{{ evento.data_inicio }} a {{ evento.data_termino }} + + {{ 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 %} + +

{{ evento.descricao }}

+

{% trans "Solicitante" %}: {{ evento.solicitante }}

+{% if evento.equipe_set.all %} +

+ {% trans "Equipe" %}: + {% for membro in evento.equipe_set.all %} + {{ membro.membro }} ({{ membro.funcao }}) + {% if not forloop.last %} - {% endif %} + {% endfor %} +

+{% endif %} +{% if evento.convite_set.exists %} + + + + + + + + + + + + {% for convite in evento.convite_set.all %} + + + + + + + + {% endfor %} +
{% trans "Casas covidadas" %}
CasaUFAceitouParticipouParticipantes
{{ convite.casa.nome }}{{ convite.casa.municipio.uf }}{% if convite.aceite %}check{% endif %}{% if convite.participou %}check{% endif %} + {% for nome in convite.nomes_participantes.splitlines %} + {{ nome }}{% if not forloop.last %}, {% endif %} + {% endfor %} +
+{% endif %} \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/snippets/calendario_legenda.html b/sigi/apps/eventos/templates/eventos/snippets/calendario_legenda.html new file mode 100644 index 0000000..b63a080 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/calendario_legenda.html @@ -0,0 +1,30 @@ +{% load i18n djbs_extras %} + + + + + + + + + + + + + + +
{% trans 'Mês / ano' %} + {{ mes_pesquisa|stringformat:"02d" }} / {{ ano_pesquisa|stringformat:"02d" }} +
{% trans 'Categorias' %} +
+ {% for key, name in categorias %} + {{ name }} + {% endfor %} +
+
{% trans 'Status' %} +
+ {% for key, name in status %} + {{ name }} + {% endfor %} +
+
diff --git a/sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html b/sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html new file mode 100644 index 0000000..5e7d016 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html @@ -0,0 +1,19 @@ +{% load i18n static %} + +{% for evento in eventos %} +
+
+ + {{ evento.nome }} +
+
+ {% include "eventos/snippets/calendario_detail.html" with evento=evento %} +
+ +
+{% endfor %} diff --git a/sigi/apps/eventos/templates/eventos/snippets/calendario_modals.html b/sigi/apps/eventos/templates/eventos/snippets/calendario_modals.html new file mode 100644 index 0000000..894f2b5 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/calendario_modals.html @@ -0,0 +1,25 @@ +{% load i18n %} + +{% for evento in eventos %} + +{% endfor %} \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/snippets/eventos_por_uf_snippet.html b/sigi/apps/eventos/templates/eventos/snippets/eventos_por_uf_snippet.html new file mode 100644 index 0000000..227ee43 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/eventos_por_uf_snippet.html @@ -0,0 +1,46 @@ +{% load i18n %} + + + + + {% for label, items in cabecalho_uf %} + + {% endfor %} + + + {% for top, items in cabecalho_uf %} + {% for label in items %} + + {% endfor %} + {% endfor %} + + + + {% for datarow in pivo_uf.itertuples %} + {% ifchanged datarow.Index.0 %} + + {% 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 %} + + {% endwith %} + + + {% endifchanged %} + + {% for datacol in datarow %} + {% if forloop.first %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + + {% for total in total_uf %} + + {% endfor %} + + +
{% trans 'Unidade Federativa' %}{{ label|capfirst }}
{{ label }}
{{ datarow.Index.0 }}
{{ datacol.1 }}{{ datacol|default:"-" }}
{% trans 'Sumário' %}{{ total }}
+ diff --git a/sigi/apps/eventos/templates/eventos/snippets/resumo_por_regiao_snippet.html b/sigi/apps/eventos/templates/eventos/snippets/resumo_por_regiao_snippet.html new file mode 100644 index 0000000..c61f4ca --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/resumo_por_regiao_snippet.html @@ -0,0 +1,37 @@ +{% load i18n %} + + + + + {% for label, items in cabecalho_regiao %} + + {% endfor %} + + + {% for top, items in cabecalho_regiao %} + {% for label in items %} + + {% endfor %} + {% endfor %} + + + + {% for datarow in pivo_regiao.itertuples %} + + {% for datacol in datarow %} + {% if forloop.first %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + + {% for total in total_regiao %} + + {% endfor %} + + +
{% trans 'Região' %}{{ label|capfirst }}
{{ label }}
{{ datacol }}{{ datacol|default:"-" }}
{% trans 'Sumário' %}{{ total }}
\ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html new file mode 100644 index 0000000..9127fd7 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html @@ -0,0 +1,35 @@ +{% load i18n %} + + + + + + + + + + + + + + + + + +
{% trans 'Período' %} + {% blocktranslate with inicio=data_inicio|date:"SHORT_DATE_FORMAT" fim=data_fim|date:"SHORT_DATE_FORMAT" %} + {{ inicio }} a {{ fim }} + {% endblocktranslate %} +
{% trans 'Status' %} +
    + {% for i, label in status_choices %} +
  • {{ i }}: {{ label }}
  • + {% endfor %} +
+
{% trans 'Oficinas' %} +
    + {% for sigla, nome in legenda_oficinas %} +
  • {{ sigla }}: {{ nome }}
  • + {% endfor %} +
+
diff --git a/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html new file mode 100644 index 0000000..aeeb098 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html @@ -0,0 +1,28 @@ +{% load i18n %} + + + + + + + + + + + + + + + + {% for regiao in resumo_regiao.itertuples %} + + + + + + + + + {% endfor %} + +
{% trans 'Região' %}{% trans 'Quantidade' %}{% trans 'Custo total' %}
{% trans 'Solicitada' %}{% trans 'Atendida' %}{% trans 'Não atendida' %}{% trans 'Participantes' %}
{{ regiao.regiao }}{{ regiao.qtde_solicitadas }}{{ regiao.qtde_atendidas|default:"-" }}{{ regiao.qtde_rejeitadas|default:"-" }}{{ regiao.participantes|default:"-" }}{{ regiao.custo_total|floatformat:2|default:"-" }}
\ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_senador_snippet.html b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_senador_snippet.html new file mode 100644 index 0000000..26d5421 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_senador_snippet.html @@ -0,0 +1,35 @@ +{% load i18n %} + + + + + + + + + + + + + + + + + {% for uf in resumo_uf.itertuples %} + {% ifchanged uf.regiao %} + + + + {% endifchanged %} + + + + + + + + + + {% endfor %} + +
{% trans 'UF' %}{% trans 'Senador' %}{% trans 'Quantidade' %}{% trans 'Custo total' %}
{% trans 'Solicitada' %}{% trans 'Atendida' %}{% trans 'Não atendida' %}{% trans 'Participantes' %}
{{ uf.regiao }}
{{ uf.uf }}{{ uf.senador }}{{ uf.qtde_solicitadas }}{{ uf.qtde_atendidas|default:"-" }}{{ uf.qtde_rejeitadas|default:"-" }}{{ uf.participantes|default:"-" }}{{ uf.custo_total|floatformat:2|default:"-" }}
\ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html new file mode 100644 index 0000000..97359c6 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html @@ -0,0 +1,70 @@ +{% load i18n djbs_extras %} +{% if not solicitacoes.exists %} + +{% else %} + + + + + + + + + + + + + + + + + + + + + {% for sol in solicitacoes.all %} + {% ifchanged sol.casa.municipio.uf.regiao %} + + + + {% endifchanged %} + + + + + + + + + + + + + + {% endfor %} + + + {% for valor in sumario %} + + {% endfor %} + + +
{% trans 'UF' %}{% trans 'Microrregião' %}{% trans 'Casa solicitante' %}{% trans 'Senador' %}{% trans 'Data pedido' %}{% trans 'Oficinas (status)' %}{% trans 'Quantidade' %}{% trans 'Custo total' %}
{% trans 'Solicitada' %}{% trans 'Atendida' %}{% trans 'Não atendida' %}{% trans 'Participantes' %}
+ {{ sol.casa.municipio.uf.get_regiao_display }} +
{{ sol.casa.municipio.uf.sigla }}{{ sol.casa.municipio.microrregiao.nome }}{{ sol.casa.nome }}{{ sol.senador }}{{ sol.data_pedido|date:"SHORT_DATE_FORMAT" }} +
    + {% for item in sol.itemsolicitado_set.all %} +
  • {{ item.tipo_evento.sigla }} ({{ item.status }})
  • + {% endfor %} +
+
{{ sol.qtde_solicitadas }}{{ sol.qtde_atendidas|default:"-" }}{{ sol.qtde_rejeitadas|default:"-" }}{{ sol.participantes|default:"-" }}{{ sol.custo_total|floatformat:2|default:"-" }}
{% trans 'Sumário' %} + {% if forloop.last %} + {{ valor|floatformat:2|default:"-" }} + {% else %} + {{ valor|default:"-" }} + {% endif %} +
+{% endif %} diff --git a/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html new file mode 100644 index 0000000..4a9e2ad --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html @@ -0,0 +1,30 @@ +{% load i18n %} + + + + + + + + + + + + + + + + + {% for tipo in resumo_tipo_evento.itertuples %} + + + + + + + + + + {% endfor %} + +
{% trans 'Sigla' %}{% trans 'Nome' %}{% trans 'Quantidade' %}{% trans 'Custo total' %}
{% trans 'Solicitada' %}{% trans 'Atendida' %}{% trans 'Não atendida' %}{% trans 'Participantes' %}
{{ tipo.sigla }}{{ tipo.nome }}{{ tipo.qtde_solicitadas }}{{ tipo.qtde_atendidas|default:"-" }}{{ tipo.qtde_rejeitadas|default:"-" }}{{ tipo.participantes|default:"-" }}{{ tipo.custo_total|floatformat:2|default:"-" }}
\ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/solicitacoes_por_periodo.html b/sigi/apps/eventos/templates/eventos/solicitacoes_por_periodo.html new file mode 100644 index 0000000..cbcf7dc --- /dev/null +++ b/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 %} +
{% trans 'Solicitações de evento por período' %}
+{% endblock %} + +{% block content %} + {% if not solicitacoes is None and not solicitacoes.exists %} + + {% endif %} +
+
+ +
+ {{ form }} +
+ +
+
+ {% if solicitacoes %} +
+
+

+ +

+
+
+ {% include "eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html" %} +
+
+
+
+

+ +

+
+
+ {% include "eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html" %} +
+
+
+
+

+ +

+
+
+ {% include "eventos/snippets/solicitacoes_por_periodo_senador_snippet.html" %} +
+
+
+
+

+ +

+
+
+ {% include "eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html" %} +
+
+
+
+

+ +

+
+
+ {% include "eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html" %} +
+
+
+
+ {% endif %} +{% endblock %} \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/solicitacoes_por_periodo_pdf.html b/sigi/apps/eventos/templates/eventos/solicitacoes_por_periodo_pdf.html new file mode 100644 index 0000000..7ec0273 --- /dev/null +++ b/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 %} +
+

{% translate "Legenda" %}

+ {% include "eventos/snippets/solicitacoes_por_periodo_legenda_snippet.html" %} +
+ {% if not solicitacoes %} + + {% else %} +
+

{% trans 'Solicitações' %}

+ {% include "eventos/snippets/solicitacoes_por_periodo_solicitacoes_snippet.html" %} +
+
+

{% trans 'Resumo por Senador' %}

+ {% include "eventos/snippets/solicitacoes_por_periodo_senador_snippet.html" %} +
+
+

{% trans 'Resumo por Região' %}

+ {% include "eventos/snippets/solicitacoes_por_periodo_regiao_snippet.html" %} +
+
+

{% trans 'Resumo por tipo de evento' %}

+ {% include "eventos/snippets/solicitacoes_por_periodo_tipo_snippet.html" %} +
+ {% endif %} +{% endblock %} diff --git a/sigi/apps/eventos/views.py b/sigi/apps/eventos/views.py index 38e11ac..a1cec90 100644 --- a/sigi/apps/eventos/views.py +++ b/sigi/apps/eventos/views.py @@ -51,6 +51,7 @@ from sigi.apps.eventos.models import ( from sigi.apps.eventos.forms import ( EventosPorUfForm, SolicitacoesPorPeriodoForm, + CalendarioForm, ) from sigi.apps.eventos.serializers import ( EventoSerializer, @@ -192,32 +193,31 @@ class AlunosPorUfReportView( @login_required @staff_member_required def calendario(request): - mes_pesquisa = int(request.GET.get("mes", timezone.localdate().month)) - ano_pesquisa = int(request.GET.get("ano", timezone.localdate().year)) - sel_categorias = request.GET.getlist( - "categoria", [c[0] for c in TipoEvento.CATEGORIA_CHOICES] - ) - sel_status = request.GET.getlist( - "status", [s[0] for s in Evento.STATUS_CHOICES] - ) - formato = request.GET.get("fmt", "cal") - pdf = bool(request.GET.get("pdf", 0)) + fmt = request.GET.get("fmt", "html") + if "mes_ano" in request.GET: + form = CalendarioForm(request.GET) + else: + form = CalendarioForm( + initial={ + "mes_ano": timezone.localdate().replace(day=1), + "categorias": [c[0] for c in TipoEvento.CATEGORIA_CHOICES], + "status": [s[0] for s in Evento.STATUS_CHOICES], + } + ) + + 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" 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 = ( Evento.objects.exclude(data_inicio=None) .exclude(data_termino=None) @@ -230,67 +230,47 @@ def calendario(request): .order_by("data_inicio") ) - context = { - "ano_pesquisa": ano_pesquisa, - "mes_pesquisa": mes_pesquisa, - "formato": formato, - "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 - ) - ] + semanas = [ + {"datas": s, "eventos": []} + for s in calendar.Calendar().monthdatescalendar( + ano_pesquisa, mes_pesquisa + ) + ] - for e in eventos: - for s in semanas: - if not ( - (e.data_termino < s["datas"][0]) - or (e.data_inicio > s["datas"][-1]) - ): - start = max(s["datas"][0], e.data_inicio) - end = min(s["datas"][-1], e.data_termino) - s["eventos"].append( + for e in eventos: + for s in semanas: + if not ( + (e.data_termino < s["datas"][0]) + or (e.data_inicio > s["datas"][-1]) + ): + start = max(s["datas"][0], e.data_inicio) + end = min(s["datas"][-1], e.data_termino) + s["eventos"].append( + ( + e, ( - e, - ( - start.weekday(), - end.weekday() - start.weekday() + 1, - 6 - end.weekday(), - ), - ) + start.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["pdf"] = True return WeasyTemplateResponse( @@ -300,8 +280,7 @@ def calendario(request): context=context, content_type="application/pdf", ) - else: - return render(request, "eventos/calendario.html", context) + return render(request, "eventos/calendario.html", context) class EventoListView(ListView): @@ -742,7 +721,7 @@ def eventos_por_uf(request): context["title"] = _("Eventos por Unidade da Federação") context["pdf"] = True return WeasyTemplateResponse( - filename=f"eventos_por_uf-{data_inicio}-{data_fim}.pdf", + # filename=f"eventos_por_uf-{data_inicio}-{data_fim}.pdf", request=request, template="eventos/eventos_por_uf_pdf.html", context=context, @@ -858,79 +837,83 @@ def solicitacoes_por_periodo(request): Sum("participantes"), Sum("custo_total"), ).values() - resumo_uf = ( - pd.DataFrame( - solicitacoes.order_by( - "casa__municipio__uf__regiao", - "senador", - "casa__municipio__uf", - ).values( - "casa__municipio__uf__regiao", - "casa__municipio__uf__sigla", - "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)[ - [ + resumo_uf = pd.DataFrame( + solicitacoes.order_by( + "casa__municipio__uf__regiao", + "senador", + "casa__municipio__uf", + ).values( + "casa__municipio__uf__regiao", + "casa__municipio__uf__sigla", + "senador", "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", - } + ).rename( + columns={ + "casa__municipio__uf__regiao": "regiao", + "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) - .sum() - .fillna(0) + resumo_uf["participantes"] = resumo_uf["participantes"].astype("int") + resumo_regiao = resumo_uf.groupby(["regiao"], as_index=False)[ + [ + "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" - ].astype("int") - resumo_tipo_evento.replace([0], [None], inplace=True) + + if not resumo_tipo_evento.empty: + resumo_tipo_evento = ( + 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 context = { "form": form, diff --git a/sigi/templates/pdf/base.html b/sigi/templates/pdf/base.html new file mode 100644 index 0000000..c4939e0 --- /dev/null +++ b/sigi/templates/pdf/base.html @@ -0,0 +1,82 @@ +{% load static i18n %} + + + + + + + + + + + {% block extra_head %}{% endblock extra_head %} + {% block title %}{{ title|default:"SIGI report" }}{% endblock title %} + + + {% block body_content %}{% endblock body_content %} + + diff --git a/sigi/templates/pdf/base_report.html b/sigi/templates/pdf/base_report.html new file mode 100644 index 0000000..490c8e7 --- /dev/null +++ b/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 }} + +{% 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 %} +
+ {% block header %} +

{% trans 'SENADO FEDERAL' %}

+

{% trans 'Instituto Legislativo Brasileiro - ILB - Interlegis' %}

+

{% block report_name %}{{ title|upper }}{% endblock report_name %}

+ {% endblock header %} +
+
+ {% block footer_text %} + {% trans 'Emitido em' %} +
+ {% now "DATETIME_FORMAT" %} + {% endblock footer_text %} +
+ + {% endspaceless %} + + {% block main_content %}{% endblock main_content %} +{% endblock body_content %} \ No newline at end of file