Browse Source

Alocação das equipes em eventos

pull/159/head
Sesostris Vieira 3 years ago
parent
commit
65a7247597
  1. 83
      sigi/apps/eventos/templates/eventos/alocacao_equipe.html
  2. 73
      sigi/apps/eventos/templates/eventos/alocacao_equipe_pdf.html
  3. 17
      sigi/apps/eventos/templates/eventos/alocacao_equipe_snippet.html
  4. 44
      sigi/apps/eventos/templates/eventos/snippets/alocacao_equipe_snippet.html
  5. 3
      sigi/apps/eventos/urls.py
  6. 269
      sigi/apps/eventos/views.py
  7. 2
      sigi/menu_conf.yaml

83
sigi/apps/eventos/templates/eventos/alocacao_equipe.html

@ -1,16 +1,21 @@
{% extends "admin/base_site.html" %} {% extends "admin/base_site.html" %}
{% load i18n admin_static %} {% load static i18n %}
{% load static from staticfiles %}
{% load thumbnail %}
{% block extrastyle %} {% block extrastyle %}
<style type="text/css"> {{ block.super }}
th { vertical-align: bottom !important; text-align: center !important; background-color: #f1f1f1; } <style type="text/css">
td { width: 6%; vertical-align: bottom !important; } .table-responsive {
td:first-child { width: 22%; font-weight: bolder; } overflow: auto;
td:last-child { font-weight: bolder; } width: 100%;
</style> }
{{ block.super }} table {
width: auto;
}
table.fixed {
table-layout: fixed;
}
</style>
<link rel="stylesheet" type="text/css" href="/static/css/calendario.css">
{% endblock %} {% endblock %}
{% block extrahead %} {% block extrahead %}
@ -19,20 +24,56 @@
{% block coltype %}colMS{% endblock %} {% block coltype %}colMS{% endblock %}
{% block content_title %}<h1>{% blocktrans %}Alocação de equipe em {{ ano_pesquisa }}{% endblocktrans %}</h1>{% endblock %} {% block content_title %}
{% if mes_pesquisa %}
{% block object-tools-items %} {% for mes in meses %}
{% if prev_button %} {% if forloop.counter == mes_pesquisa %}
<li><a href="?ano={{ prev_button.ano|safe }}">{% trans "Ano anterior" %}</a></li> <h5>{% blocktrans with ano=ano_pesquisa|safe mes=mes %}Alocação de equipe em {{ mes }} de {{ ano }}{% endblocktrans %}</h5>
{% endif %}
{% endfor %}
{% else %}
<h5>{% blocktrans with ano=ano_pesquisa|safe %}Alocação de equipe em {{ ano }}{% endblocktrans %}</h5>
{% endif %} {% endif %}
{% if next_button %} {% endblock %}
<li><a href="?ano={{ next_button.ano|safe }}">{% trans "Próximo ano" %}</a></li>
{% block breadcrumbs %}
<div class="breadcrumbs">
{% for ano in anos %}
<a class="btn-flat btn-small{% if ano == ano_pesquisa and not mes_pesquisa %} disabled{% endif %}" href="?ano={{ ano|safe }}">{{ ano|safe }}</a>
{% endfor %}
</div>
{% if mes_pesquisa %}
<div class="breadcrumbs">
{% for mes in meses %}
<a class="btn-flat btn-small" href="?ano={{ ano_pesquisa|safe }}&mes={{ forloop.counter|safe }}">{{ mes|safe }}</a>
{% endfor %}
</div>
{% endif %} {% endif %}
<li><a href="?ano={{ ano_pesquisa|safe }}&fmt=pdf" target="_blank">{% trans "Exportar para PDF" %}</a></li>
<li><a href="?ano={{ ano_pesquisa|safe }}&fmt=csv">{% trans "Exportar para CSV" %}</a></li>
<li><a href="?ano={{ ano_pesquisa|safe }}&fmt=json" target="_blank">{% trans "Exportar para Json" %}</a></li>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% include "eventos/alocacao_equipe_snippet.html" %} <div class="fixed-action-btn">
<a class="btn-floating">
<i class="large material-icons">print</i>
</a>
<ul>
<li><a class="btn-floating" href="?ano={{ ano_pesquisa|safe }}{% if mes_pesquisa %}&mes={{ mes_pesquisa|safe }}{% endif %}{% if semana_pesquisa %}&semana={{ semana_pesquisa|safe }}{% endif %}&fmt=pdf" title="{% trans "Exportar para PDF" %}"><i class="material-icons">picture_as_pdf</i></a></li>
<li><a class="btn-floating" href="?ano={{ ano_pesquisa|safe }}{% if mes_pesquisa %}&mes={{ mes_pesquisa|safe }}{% endif %}{% if semana_pesquisa %}&semana={{ semana_pesquisa|safe }}{% endif %}&fmt=csv" title="{% trans "Exportar para CSV" %}"><i class="material-icons">file_download</i></a></li>
</ul>
</div>
{% include "eventos/snippets/alocacao_equipe_snippet.html" with mode="html" %}
{% if semana_pesquisa %}
{% include "eventos/snippets/calendario_modals.html" %}
{% endif %}
{% endblock %}
{% block footer %}
{{ block.super }}
<script>
$(document).ready(function(){
M.FloatingActionButton.init($('.fixed-action-btn'), {hoverEnabled: false});
M.Modal.init($(".modal"));
})
</script>
{% endblock %} {% endblock %}

73
sigi/apps/eventos/templates/eventos/alocacao_equipe_pdf.html

@ -1,63 +1,22 @@
{% extends "base_report.html" %} {% extends "pdf/base_report.html" %}
{% load static from staticfiles %} {% load static %}
{% load i18n %} {% load i18n %}
{% block extra_head %} {% block page_size %}A4 landscape{% endblock %}
<style> {% block extra_style %}
@page { {{ block.super }}
size: A4 landscape; a {
margin: 1cm; color: black;
} text-decoration: none;
* { font-size: 10px;}
a {
color: black;
text-decoration: none;
}
dt {
font-weight: 700;
}
dd {
margin-left: 2mm;
}
table, th, td {
border: 1px solid #ddd;
}
table {
border-collapse: collapse;
} }
th {
text-align: center;
vertical-align: bottom;
background-color: #f1f1f1;
}
td {
width: 6%;
}
td, th {
padding: 2px;
vertical-align: center;
}
td:first-child { width: 22%; font-weight: bolder; }
td:last-child { font-weight: bolder; }
</style>
<title>{% blocktrans %}Alocação de equipe em {{ ano_pesquisa }}{% endblocktrans %}</title>
{% endblock %} {% endblock %}
{% block report %} {% block main_content %}
<h1>{% blocktrans %}Alocação de equipe em {{ ano_pesquisa }}{% endblocktrans %}</h1> <h4>
{% include "eventos/alocacao_equipe_snippet.html" %} {% if mes_pesquisa %}
{% blocktrans with mes=mes_pesquisa|safe ano=ano_pesquisa|safe %}Alocação de equipe em {{ mes }}/{{ ano }}{% endblocktrans %}</h4>
{% else %}
{% blocktrans with ano=ano_pesquisa|safe %}Alocação de equipe em {{ ano }}{% endblocktrans %}</h4>
{% endif %}
{% include "eventos/snippets/alocacao_equipe_snippet.html" %}
{% endblock %} {% endblock %}
</body>
</html>

17
sigi/apps/eventos/templates/eventos/alocacao_equipe_snippet.html

@ -1,17 +0,0 @@
<div class="table-responsive">
<table class="table table-condensed table-bordered" repeat="1">
{% for linha in linhas %}
<tr>
{% if forloop.first %}
{% for coluna in linha %}
<th>{{ coluna }}</th>
{% endfor %}
{% else %}
{% for coluna in linha %}
<td>{{ coluna }}</td>
{% endfor %}
{% endif %}
</tr>
{% endfor %}
</table>
</div>

44
sigi/apps/eventos/templates/eventos/snippets/alocacao_equipe_snippet.html

@ -0,0 +1,44 @@
<div class="table-responsive">
<table class="striped{% if semana_pesquisa %} fixed{% endif %}">
<thead>
<tr>
{% for coluna in cabecalho %}
<th>
{% if mode == "html" and not semana_pesquisa and forloop.counter0 >= 1 and forloop.counter0 <= cabecalho|length|add:-2 %}
<a href="?ano={{ ano_pesquisa|safe }}&mes={% if mes_pesquisa %}{{ mes_pesquisa|safe }}&semana={% endif %}{{ forloop.counter0 }}">{{ coluna }}</a>
{% else %}
{% if semana_pesquisa and forloop.counter0 >= 1 %}
{{ coluna|date:"SHORT_DATE_FORMAT" }}
{% else %}
{{ coluna }}
{% endif %}
{% endif %}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for linha in linhas %}
<tr>
{% for coluna in linha %}
{% if forloop.first %}
<th>{{ coluna }}</th>
{% elif forloop.last and not semana_pesquisa %}
<th>{{ coluna }}</th>
{% else %}
<td>
{% if semana_pesquisa %}
{% for evento in coluna %}
<p><a class="modal-trigger" href="#modal{{ evento.id }}">{{ evento.nome }}</a></p>
{% endfor %}
{% else %}
{{ coluna }}
{% endif %}
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>

3
sigi/apps/eventos/urls.py

@ -3,6 +3,9 @@ from sigi.apps.eventos import views
urlpatterns = [ urlpatterns = [
path("calendario/", views.calendario, name="eventos-calendario"), path("calendario/", views.calendario, name="eventos-calendario"),
path(
"alocacaoequipe/", views.alocacao_equipe, name="eventos-alocacao-equipe"
),
path("evento/<int:id>/", views.evento, name="eventos-evento"), path("evento/<int:id>/", views.evento, name="eventos-evento"),
path( path(
"evento/<int:evento_id>/convite/<casa_id>/", "evento/<int:evento_id>/convite/<casa_id>/",

269
sigi/apps/eventos/views.py

@ -1,16 +1,24 @@
from datetime import datetime
import calendar import calendar
import csv
import locale import locale
from datetime import datetime
from functools import reduce
from typing import OrderedDict
from django.contrib import messages from django.contrib import messages
from django.contrib.admin.sites import site from django.contrib.admin.sites import site
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import HttpResponse from django.http import HttpResponse, JsonResponse
from django.shortcuts import redirect, render, get_object_or_404 from django.shortcuts import redirect, render, get_object_or_404
from django.template import Template, Context from django.template import Template, Context
from django.template.exceptions import TemplateSyntaxError from django.template.exceptions import TemplateSyntaxError
from django.utils import timezone from django.utils import timezone
from django.utils.text import slugify 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,
ngettext,
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 django_weasyprint.views import WeasyTemplateResponse
@ -383,79 +391,188 @@ def gerar_anexo(casa, presidente, contato, path, modelo, nome, texto):
return anexo return anexo
# @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))
# formato = request.GET.get('fmt', 'html') mes_pesquisa = int(request.GET.get("mes", 0))
semana_pesquisa = int(request.GET.get("semana", 0))
# data = {'ano_pesquisa': ano_pesquisa} formato = request.GET.get("fmt", "html")
# if Evento.objects.filter(data_inicio__year=ano_pesquisa-1).exists(): lang = to_locale(get_language()) + ".UTF-8"
# data['prev_button'] = {'ano': ano_pesquisa - 1 } locale.setlocale(locale.LC_ALL, lang)
# if Evento.objects.filter(data_inicio__year=ano_pesquisa+1).exists(): dados = []
# data['next_button'] = {'ano': ano_pesquisa + 1 } eventos = Evento.objects.exclude(status="C").prefetch_related("equipe_set")
# dados = [] num_cols = 12
# for evento in Evento.objects.filter(data_inicio__year=ano_pesquisa).exclude(status='C').prefetch_related('equipe_set'): if mes_pesquisa > 0:
# for p in evento.equipe_set.all(): semanas = [
# registro = None [s[0], s[-1]]
# for r in dados: for s in calendar.Calendar().monthdatescalendar(
# if r[0] == p.membro.pk: ano_pesquisa, mes_pesquisa
# registro = r )
# break ]
# if not registro: num_cols = len(semanas)
# registro = [p.membro.pk, p.membro.nome_completo, [{'dias': 0, 'eventos': 0} for x in range(1,13)]] if semana_pesquisa > 0:
# dados.append(registro) dias = calendar.Calendar().monthdatescalendar(
ano_pesquisa, mes_pesquisa
# registro[2][evento.data_inicio.month-1]['dias'] += (evento.data_termino - evento.data_inicio).days + 1 )[semana_pesquisa - 1]
# registro[2][evento.data_inicio.month-1]['eventos'] += 1 num_cols = len(dias)
eventos = eventos.filter(
# dados.sort(lambda x, y: cmp(x[1], y[1])) data_inicio__gte=dias[0], data_inicio__lte=dias[-1]
)
# lang = (translation.to_locale(translation.get_language())+'.utf8').encode() else:
# locale.setlocale(locale.LC_ALL, lang) eventos = eventos.filter(
# meses = [calendar.month_name[m] for m in range(1,13)] data_inicio__gte=semanas[0][0], data_inicio__lte=semanas[-1][-1]
)
# linhas = [[_("Servidor")] + meses + ['total']] else:
eventos = eventos.filter(data_inicio__year=ano_pesquisa)
# for r in dados:
# r[2].append(reduce(lambda x,y:{'dias': x['dias'] + y['dias'], for evento in eventos:
# 'eventos': x['eventos'] + y['eventos']}, r[2])) for p in evento.equipe_set.all():
# linhas.append([r[1]] + registro = None
# [_(ungettext("%(dias)s dia", "%(dias)s dias", d['dias']) + " em " + for r in dados:
# ungettext("%(eventos)s evento", "%(eventos)s eventos", d['eventos']) if r[0] == p.membro.pk:
# ) % d if d['dias'] > 0 or d['eventos'] > 0 else '' for d in r[2]]) registro = r
break
# # for registro in Servidor.objects.filter(equipe_evento__evento__data_inicio__year=ano_pesquisa).exclude(equipe_evento__evento__status='C').distinct(): if not registro:
# # dados = [{'dias': 0, 'eventos': 0} for x in range(1,13)] if semana_pesquisa > 0:
# # for part in registro.equipe_evento.filter(evento__data_inicio__year=ano_pesquisa).exclude(evento__status='C'): registro = [
# # dados[part.evento.data_inicio.month-1]['dias'] += (part.evento.data_termino - p.membro.pk,
# # part.evento.data_inicio).days + 1 p.membro.nome_completo,
# # dados[part.evento.data_inicio.month-1]['eventos'] += 1 OrderedDict([(dia, []) for dia in dias]),
# # dados.append([registro.nome_completo] + [_(ungettext("%(dias)s dia", "%(dias)s dias", d['dias']) + " em " + ungettext("%(eventos)s evento", "%(eventos)s eventos", d['eventos'])) % d if d['dias'] > 0 or d['eventos'] > 0 else '' for d in dados]) ]
else:
# data['linhas'] = linhas registro = [
p.membro.pk,
# if formato == 'pdf': p.membro.nome_completo,
# return render_to_pdf('eventos/alocacao_equipe_pdf.html', data) [{"dias": 0, "eventos": 0} for __ in range(num_cols)],
# elif formato == 'csv': ]
# response = HttpResponse(content_type='text/csv') dados.append(registro)
# response['Content-Disposition'] = 'attachment; filename="alocacao_equipe_%s.csv"' % (ano_pesquisa,)
# writer = csv.writer(response) if mes_pesquisa > 0:
# asc_list = [[s.encode('utf-8') if isinstance(s, unicode) else s for s in l] for l in linhas] if semana_pesquisa > 0:
# writer.writerows(asc_list) for dia in dias:
# return response if (
# elif formato == 'json': evento.data_inicio.date()
# result = {'ano': ano_pesquisa, <= dia
# 'equipe': [{'pk': d[0], <= evento.data_termino.date()
# 'nome_completo': d[1], ):
# 'meses': {m[0]: m[1] for m in zip(meses+['total'], d[2])} registro[2][dia].append(evento)
# } for d in dados]} else:
# return JsonResponse(result) for idx, [inicio, fim] in enumerate(semanas):
if inicio <= evento.data_inicio.date() <= fim:
# return render(request, 'eventos/alocacao_equipe.html', data) registro[2][idx]["dias"] += (
min(fim, evento.data_termino.date())
- evento.data_inicio.date()
).days + 1
registro[2][idx]["eventos"] += 1
elif inicio <= evento.data_termino.date() <= fim:
registro[2][idx]["dias"] += (
min(fim, evento.data_termino.date())
- evento.data_inicio.date()
).days + 1
registro[2][idx]["eventos"] += 1
else:
registro[2][evento.data_inicio.month - 1]["dias"] += (
evento.data_termino - evento.data_inicio
).days + 1
registro[2][evento.data_inicio.month - 1]["eventos"] += 1
dados.sort(key=lambda x: x[1])
meses = list(calendar.month_abbr)[1:]
linhas = []
if semana_pesquisa:
linhas = [
[registro[1]] + list(registro[2].values()) for registro in dados
]
else:
for r in dados:
r[2].append(
reduce(
lambda x, y: {
"dias": x["dias"] + y["dias"],
"eventos": x["eventos"] + y["eventos"],
},
r[2],
)
)
linhas.append(
[r[1]]
+ [
_(
ngettext("%(dias)s dia", "%(dias)s dias", d["dias"])
+ " em "
+ ngettext(
"%(eventos)s evento",
"%(eventos)s eventos",
d["eventos"],
)
)
% d
if d["dias"] > 0 or d["eventos"] > 0
else ""
for d in r[2]
]
)
context = site.each_context(request) or {}
context.update(
{
"anos": Evento.objects.exclude(data_inicio=None)
.order_by("data_inicio__year")
.distinct("data_inicio__year")
.values_list("data_inicio__year", flat=True),
"ano_pesquisa": ano_pesquisa,
"linhas": linhas,
}
)
if mes_pesquisa > 0:
context["mes_pesquisa"] = mes_pesquisa
context["meses"] = meses
if semana_pesquisa > 0:
cabecalho = [_("Servidor")] + dias
context["semana_pesquisa"] = semana_pesquisa
context["eventos"] = eventos
else:
cabecalho = (
[_("Servidor")]
+ [
_(f"de {inicio:%d/%m} a {fim:%d/%m}")
for inicio, fim in semanas
]
+ ["total"]
)
else:
cabecalho = [_("Servidor")] + meses + ["total"]
context["cabecalho"] = cabecalho
if formato == "pdf":
context["title"] = _("Alocação de equipe")
context["pdf"] = True
return WeasyTemplateResponse(
# filename="alocacao_equipe.pdf",
request=request,
template="eventos/alocacao_equipe_pdf.html",
context=context,
content_type="application/pdf",
)
elif formato == "csv":
response = HttpResponse(content_type="text/csv")
response[
"Content-Disposition"
] = 'attachment; filename="alocacao_equipe_%s.csv"' % (ano_pesquisa,)
writer = csv.writer(response)
writer.writerow(cabecalho)
writer.writerows(linhas)
return response
return render(request, "eventos/alocacao_equipe.html", context)
# # Views e functions para carrinho de exportação # # Views e functions para carrinho de exportação

2
sigi/menu_conf.yaml

@ -86,7 +86,7 @@ main_menu:
- title: Calendário mensal - title: Calendário mensal
view_name: eventos-calendario view_name: eventos-calendario
- title: Alocação de equipe - title: Alocação de equipe
view_name: view_name: eventos-alocacao-equipe
- title: Servidores - title: Servidores
icon: account_circle icon: account_circle
children: children:

Loading…
Cancel
Save