Browse Source

Impressão do calendário em PDF

pull/159/head
Sesostris Vieira 3 years ago
parent
commit
afeb5609f1
  1. 20
      sigi/apps/eventos/templates/eventos/calendario.html
  2. 98
      sigi/apps/eventos/templates/eventos/calendario_pdf.html
  3. 30
      sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html
  4. 100
      sigi/apps/eventos/views.py

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

@ -11,15 +11,24 @@
{% block coltype %}colMS{% endblock %} {% block coltype %}colMS{% endblock %}
{% block content %} {% block content %}
<div class="row"> <div class="fixed-action-btn">
<div class="col s1"> <a class="btn-floating">
<i class="large material-icons">mode_edit</i>
</a>
<ul>
<li>
{% if formato == 'cal' %} {% if formato == 'cal' %}
<a class="format-selector" href="?ano={{ ano_pesquisa|safe }}&mes={{ mes_pesquisa|safe }}&fmt=tab" title="{% trans 'Formato de lista' %}"><i class="material-icons">view_list</i></a> <a class="btn-floating btn-small" href="?ano={{ ano_pesquisa|safe }}&mes={{ mes_pesquisa|safe }}&fmt=tab" title="{% trans 'Formato de lista' %}"><i class="material-icons">view_list</i></a>
{% else %} {% else %}
<a class="format-selector" href="?ano={{ ano_pesquisa|safe }}&mes={{ mes_pesquisa|safe }}&fmt=cal" title="{% trans 'Formato de calendário' %}"><i class="material-icons">date_range</i></a> <a class="btn-floating btn-small" href="?ano={{ ano_pesquisa|safe }}&mes={{ mes_pesquisa|safe }}&fmt=cal" title="{% trans 'Formato de calendário' %}"><i class="material-icons">date_range</i></a>
{% endif %} {% endif %}
<li>
<a class="btn-floating btn-small" href="?ano={{ ano_pesquisa|safe }}&mes={{ mes_pesquisa|safe }}&pdf=1"><i class="material-icons">picture_as_pdf</i></a>
</li>
</ul>
</div> </div>
<div class="col s11"> <div class="row">
<div class="col s12">
<ul class="tabs"> <ul class="tabs">
{% for ano in meses %} {% for ano in meses %}
<li class="tab col"><a {% if ano == ano_pesquisa %}class="active"{% endif %} href="#tab-{{ ano|safe }}">{{ ano| safe }}</a></li> <li class="tab col"><a {% if ano == ano_pesquisa %}class="active"{% endif %} href="#tab-{{ ano|safe }}">{{ ano| safe }}</a></li>
@ -48,6 +57,7 @@
$(document).ready(function(){ $(document).ready(function(){
M.Tabs.init($('.tabs'), {}); M.Tabs.init($('.tabs'), {});
M.Modal.init($(".modal"), {}); M.Modal.init($(".modal"), {});
M.FloatingActionButton.init($(".fixed-action-btn"), {hoverEnabled: false});
}); });
</script> </script>
{% endblock %} {% endblock %}

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

@ -1,59 +1,59 @@
{% extends "base_report.html" %} {% extends 'pdf/base_report.html' %}
{% load static from staticfiles %} {% load static i18n %}
{% load i18n %}
{% block extra_head %}
<style>
@page {
size: A4 landscape;
margin: 1cm;
}
* { font-size: 10px;}
{% block extra_style %}
{{ block.super }}
a { a {
color: black; color: black;
text-decoration: none; text-decoration: none;
} }
dt {
font-weight: 700;
}
dd {
margin-left: 2mm;
}
table, th, td {
border: 1px solid #ddd;
}
table { table {
border-collapse: collapse; table-layout: fixed;
} }
table td,
td, th { table td * {
padding: 2px;
vertical-align: top; vertical-align: top;
} }
span.numero-dia {
th { font-size: 0.5em;
text-align: center !important; }
vertical-align: bottom !important; .card {
} background-color: #fff;
padding: 15px;
.status-P { background-color: #ffffb0} margin: 10px 0;
.status-A { background-color: #a6ebff} }
.status-O { background-color: #c2ffc2} .card .card-content .card-title {
.status-R { background-color: #ffdaa6} display: block;
.status-C { background-color: #d98f8d} line-height: 32px;
</style> margin-bottom: 8px;
<title>{% blocktrans %}Eventos de {{ mes_pesquisa }}/{{ ano_pesquisa }}{% endblocktrans %}</title> font-weight: 300;
}
.card-title {
font-size: 20px !important;
margin-bottom: -6px !important;
}
.data-evento {
font-size: 0.7em;
display: block;
}
.tipo-evento {
font-size: 0.7em;
color: var(--body-quiet-color);
display: block;
margin-bottom: 8px;
}
.cyan.lighten-4 { background-color: #b2ebf2 !important; }
.brown.lighten-4 { background-color: #d7ccc8 !important; }
.deep-orange.lighten-4 { background-color: #ffccbc !important; }
.cyan.lighten-4 { background-color: #b2ebf2 !important; }
.green.lighten-4 { background-color: #c8e6c9 !important; }
.lime.lighten-4 { background-color: #f0f4c3 !important; }
{% endblock %} {% endblock %}
{% block report %} {% block main_content %}
<h1>{% blocktrans %}Eventos de {{ mes_pesquisa }}/{{ ano_pesquisa }}{% endblocktrans %}</h1> <h1>
{% include "eventos/calendario_snippet.html" %} {% blocktrans with month=mes_pesquisa|stringformat:"02d" year=ano_pesquisa|stringformat:"04d" %}Ref: {{ month }}/{{year}}{% endblocktrans %}
{% endblock %} </h1>
</body> {% include "eventos/snippets/calendario_cal.html" %}
</html> {% include "eventos/snippets/calendario_lista.html" %}
{% endblock main_content %}

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

@ -26,7 +26,37 @@
{% endfor %} {% endfor %}
</p> </p>
{% endif %} {% endif %}
{% if pdf %}
{% if evento.convite_set %}
<table class="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 %}
{% else %}
<a class="modal-trigger right" href="#modal{{ evento.id|safe }}">{% trans "Ver detalhes" %}</a> <a class="modal-trigger right" href="#modal{{ evento.id|safe }}">{% trans "Ver detalhes" %}</a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

100
sigi/apps/eventos/views.py

@ -13,6 +13,7 @@ from django.utils.text import slugify
from django.utils.translation import to_locale, get_language, gettext as _ from django.utils.translation import to_locale, get_language, gettext as _
from django.urls import reverse from django.urls import reverse
from django_weasyprint.utils import django_url_fetcher from django_weasyprint.utils import django_url_fetcher
from django_weasyprint.views import WeasyTemplateResponse
from docx import Document from docx import Document
from weasyprint import HTML from weasyprint import HTML
from sigi.apps.casas.models import Funcionario, Orgao, Presidente from sigi.apps.casas.models import Funcionario, Orgao, Presidente
@ -32,6 +33,7 @@ def calendario(request):
mes_pesquisa = int(request.GET.get("mes", timezone.localdate().month)) mes_pesquisa = int(request.GET.get("mes", timezone.localdate().month))
ano_pesquisa = int(request.GET.get("ano", timezone.localdate().year)) ano_pesquisa = int(request.GET.get("ano", timezone.localdate().year))
formato = request.GET.get("fmt", "cal") formato = request.GET.get("fmt", "cal")
pdf = bool(request.GET.get("pdf", 0))
meses = {} meses = {}
lang = to_locale(get_language()) + ".UTF-8" lang = to_locale(get_language()) + ".UTF-8"
@ -53,7 +55,7 @@ def calendario(request):
context = site.each_context(request) or {} context = site.each_context(request) or {}
if formato == "cal": if formato == "cal" or pdf:
semanas = calendar.Calendar().monthdatescalendar( semanas = calendar.Calendar().monthdatescalendar(
ano_pesquisa, mes_pesquisa ano_pesquisa, mes_pesquisa
) )
@ -85,6 +87,17 @@ def calendario(request):
} }
) )
if pdf:
context["title"] = _("Calendário de eventos")
context["pdf"] = True
return WeasyTemplateResponse(
filename="calendario_mensal.pdf",
request=request,
template="eventos/calendario_pdf.html",
context=context,
content_type="application/pdf",
)
else:
return render(request, "eventos/calendario.html", context) return render(request, "eventos/calendario.html", context)
@ -369,91 +382,6 @@ def gerar_anexo(casa, presidente, contato, path, modelo, nome, texto):
return anexo return anexo
# @login_required
# def calendario(request):
# mes_pesquisa = int(request.GET.get('mes', timezone.localdate().month))
# ano_pesquisa = int(request.GET.get('ano', timezone.localdate().year))
# formato = request.GET.get('fmt', 'html')
# dia1 = datetime.date(ano_pesquisa, mes_pesquisa, 1)
# mes_anterior = dia1 - datetime.timedelta(days=1)
# mes_seguinte = dia1.replace(day=28) + datetime.timedelta(days=4) # Ugly hack
# mes_seguinte = mes_seguinte.replace(day=1)
# data = {'mes_pesquisa': mes_pesquisa, 'ano_pesquisa': ano_pesquisa}
# if Evento.objects.filter(data_inicio__year=mes_anterior.year,
# data_inicio__month=mes_anterior.month).exists():
# data['prev_button'] = {'mes': mes_anterior.month, 'ano': mes_anterior.year }
# if Evento.objects.filter(data_inicio__year=mes_seguinte.year,
# data_inicio__month=mes_seguinte.month).exists():
# data['next_button'] = {'mes': mes_seguinte.month, 'ano': mes_seguinte.year }
# c = calendar.Calendar(6)
# dates = reduce(lambda x,y: x+y, c.monthdatescalendar(ano_pesquisa, mes_pesquisa))
# eventos = []
# for evento in Evento.objects.filter(data_inicio__year=ano_pesquisa,
# data_inicio__month=mes_pesquisa).order_by('data_inicio'):
# start = dates.index(evento.data_inicio.date())
# if not evento.data_termino.date() in dates:
# lastday = dates[-1]
# while lastday < evento.data_termino.date():
# lastday = lastday + datetime.timedelta(days=1)
# dates.append(lastday)
# eventos.append({'evento': evento, 'start': start})
# # Calcula a distância dos eventos para as bordas do calendário
# for evento in eventos:
# end = dates.index(evento['evento'].data_termino.date())
# evento['duration'] = end-evento['start']+1
# evento['close'] = len(dates)-end-1
# # Agrupa os eventos em linhas para melhorar a visualização
# linhas = []
# for evento in eventos:
# encaixado = False
# for linha in linhas:
# sobrepoe = False
# for e in linha:
# if (((evento['evento'].data_inicio.date() >= e['evento'].data_inicio.date()) and
# (evento['evento'].data_inicio.date() <= e['evento'].data_termino.date())) or
# ((evento['evento'].data_termino.date() >= e['evento'].data_inicio.date()) and
# (evento['evento'].data_termino.date() <= e['evento'].data_termino.date()))):
# sobrepoe = True
# break
# if not sobrepoe:
# # Adiona o evento em uma linha que ele não sobrepoe nenhum outro
# linha.append(evento)
# encaixado = True
# break
# if not encaixado:
# # Adiciona uma nova linha porque este evento não se encaixa em nenhuma existente
# linhas.append([evento])
# # Recalcula as distâncias dos eventos por linha para encaixar no calendário
# for linha in linhas:
# anterior = None
# for evento in linha:
# if anterior is None:
# anterior = evento
# continue
# anterior['close'] = (evento['evento'].data_inicio.date() - anterior['evento'].data_termino.date()).days-1
# evento['start'] = 0
# anterior = evento
# data['dates'] = dates
# data['eventos'] = eventos
# data['linhas'] = linhas
# if formato == 'pdf':
# return render_to_pdf('eventos/calendario_pdf.html', data )
# return render(request, 'eventos/calendario.html', data)
# @login_required # @login_required
# def alocacao_equipe(request): # def alocacao_equipe(request):
# ano_pesquisa = int(request.GET.get('ano', timezone.localdate().year)) # ano_pesquisa = int(request.GET.get('ano', timezone.localdate().year))

Loading…
Cancel
Save