Browse Source

Permite ordenação da lista de eventos

master 4.0.13
Sesóstris Vieira 6 hours ago
parent
commit
1f1d8555c1
  1. 402
      sigi/apps/eventos/views.py

402
sigi/apps/eventos/views.py

@ -5,7 +5,7 @@ import locale
import pandas as pd import pandas as pd
from functools import reduce from functools import reduce
from itertools import groupby from itertools import groupby
from rest_framework import generics from rest_framework import generics, filters
from typing import OrderedDict from typing import OrderedDict
from django.contrib import messages from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required from django.contrib.admin.views.decorators import staff_member_required
@ -190,14 +190,14 @@ class AlunosPorUfReportView(
return context return context
class CalendarioReportView(
class CalendarioReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView): LoginRequiredMixin, UserPassesTestMixin, ReportListView
):
title = _("Calendário de eventos") title = _("Calendário de eventos")
filter_form = CalendarioForm filter_form = CalendarioForm
template_name = "eventos/calendario.html" template_name = "eventos/calendario.html"
template_name_pdf = "eventos/calendario_pdf.html" template_name_pdf = "eventos/calendario_pdf.html"
list_fields = [] list_fields = []
list_labels = [] list_labels = []
@ -236,7 +236,6 @@ class CalendarioReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListVi
sel_categorias = form.cleaned_data["categorias"] sel_categorias = form.cleaned_data["categorias"]
sel_status = form.cleaned_data["status"] sel_status = form.cleaned_data["status"]
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)
@ -254,35 +253,44 @@ class CalendarioReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListVi
semanas = [ semanas = [
{"datas": s, "eventos": []} {"datas": s, "eventos": []}
for s in calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa) 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 (e.data_termino < s["datas"][0] or e.data_inicio > s["datas"][-1]): if not (
e.data_termino < s["datas"][0]
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,
( (
start.weekday(), e,
end.weekday() - start.weekday() + 1, (
6 - end.weekday(), start.weekday(),
), end.weekday() - start.weekday() + 1,
)) 6 - end.weekday(),
),
context.update({ )
"ano_pesquisa": ano_pesquisa, )
"mes_pesquisa": mes_pesquisa,
"sel_categorias": sel_categorias, context.update(
"sel_status": sel_status, {
"day_names": calendar.day_abbr, "ano_pesquisa": ano_pesquisa,
"categorias": TipoEvento.CATEGORIA_CHOICES, "mes_pesquisa": mes_pesquisa,
"status": Evento.STATUS_CHOICES, "sel_categorias": sel_categorias,
"eventos": eventos, "sel_status": sel_status,
"semanas": semanas, "day_names": calendar.day_abbr,
}) "categorias": TipoEvento.CATEGORIA_CHOICES,
"status": Evento.STATUS_CHOICES,
"eventos": eventos,
"semanas": semanas,
}
)
return context return context
def render_to_response(self, context, **response_kwargs): def render_to_response(self, context, **response_kwargs):
@ -299,6 +307,7 @@ class CalendarioReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListVi
) )
return super().render_to_response(context, **response_kwargs) return super().render_to_response(context, **response_kwargs)
class EventoListView(ListView): class EventoListView(ListView):
model = Evento model = Evento
paginate_by = 100 paginate_by = 100
@ -319,12 +328,14 @@ class EventoListView(ListView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView):
class AlocacaoEquipeReportView(
LoginRequiredMixin, UserPassesTestMixin, ReportListView
):
title = _("Alocação de equipe") title = _("Alocação de equipe")
template_name = "eventos/alocacao_equipe.html" template_name = "eventos/alocacao_equipe.html"
template_name_pdf = "eventos/alocacao_equipe_pdf.html" template_name_pdf = "eventos/alocacao_equipe_pdf.html"
list_fields = [] list_fields = []
list_labels = [] list_labels = []
@ -344,36 +355,35 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
"""Reproduz a lógica original da FBV, populando o contexto com dados.""" """Reproduz a lógica original da FBV, populando o contexto com dados."""
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
ano_pesquisa = int(
ano_pesquisa = int(self.request.GET.get("ano", timezone.localdate().year)) self.request.GET.get("ano", timezone.localdate().year)
)
mes_pesquisa = int(self.request.GET.get("mes", 0)) mes_pesquisa = int(self.request.GET.get("mes", 0))
semana_pesquisa = int(self.request.GET.get("semana", 0)) semana_pesquisa = int(self.request.GET.get("semana", 0))
formato = self.request.GET.get("fmt", "html") formato = self.request.GET.get("fmt", "html")
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)
eventos = Evento.objects.exclude(
eventos = ( status__in=(Evento.STATUS_CANCELADO, Evento.STATUS_SOBRESTADO)
Evento.objects.exclude( ).prefetch_related("equipe_set")
status__in=(Evento.STATUS_CANCELADO, Evento.STATUS_SOBRESTADO)
)
.prefetch_related("equipe_set")
)
num_cols = 12 num_cols = 12
if mes_pesquisa > 0: if mes_pesquisa > 0:
semanas = [ semanas = [
[s[0], s[-1]] [s[0], s[-1]]
for s in calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa) for s in calendar.Calendar().monthdatescalendar(
ano_pesquisa, mes_pesquisa
)
] ]
num_cols = len(semanas) num_cols = len(semanas)
if semana_pesquisa > 0: if semana_pesquisa > 0:
dias = calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa)[semana_pesquisa - 1] dias = calendar.Calendar().monthdatescalendar(
ano_pesquisa, mes_pesquisa
)[semana_pesquisa - 1]
num_cols = len(dias) num_cols = len(dias)
eventos = eventos.filter( eventos = eventos.filter(
data_inicio__gte=dias[0], data_inicio__lte=dias[-1] data_inicio__gte=dias[0], data_inicio__lte=dias[-1]
@ -388,7 +398,6 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
eventos = eventos.filter(data_inicio__year=ano_pesquisa) eventos = eventos.filter(data_inicio__year=ano_pesquisa)
dados = [] dados = []
for evento in eventos: for evento in eventos:
for equipe in evento.equipe_set.all(): for equipe in evento.equipe_set.all():
@ -410,11 +419,13 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
registro = [ registro = [
equipe.membro.pk, equipe.membro.pk,
equipe.membro.get_apelido(), equipe.membro.get_apelido(),
[{"dias": 0, "eventos": 0} for __ in range(num_cols)], [
{"dias": 0, "eventos": 0}
for __ in range(num_cols)
],
] ]
dados.append(registro) dados.append(registro)
if mes_pesquisa > 0: if mes_pesquisa > 0:
if semana_pesquisa > 0: if semana_pesquisa > 0:
for dia in dias: for dia in dias:
@ -425,13 +436,15 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
if inicio <= evento.data_inicio <= fim: if inicio <= evento.data_inicio <= fim:
registro[2][idx]["dias"] += ( registro[2][idx]["dias"] += (
min(fim, evento.data_termino) - evento.data_inicio min(fim, evento.data_termino)
- evento.data_inicio
).days + 1 ).days + 1
registro[2][idx]["eventos"] += 1 registro[2][idx]["eventos"] += 1
elif inicio <= evento.data_termino <= fim: elif inicio <= evento.data_termino <= fim:
registro[2][idx]["dias"] += ( registro[2][idx]["dias"] += (
min(fim, evento.data_termino) - evento.data_inicio min(fim, evento.data_termino)
- evento.data_inicio
).days + 1 ).days + 1
registro[2][idx]["eventos"] += 1 registro[2][idx]["eventos"] += 1
else: else:
@ -441,18 +454,15 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
).days + 1 ).days + 1
registro[2][evento.data_inicio.month - 1]["eventos"] += 1 registro[2][evento.data_inicio.month - 1]["eventos"] += 1
dados.sort(key=lambda x: x[1]) dados.sort(key=lambda x: x[1])
meses = list(calendar.month_abbr)[1:] meses = list(calendar.month_abbr)[1:]
linhas = [] linhas = []
if semana_pesquisa: if semana_pesquisa:
linhas = [ linhas = [
[registro[1]] + list(registro[2].values()) [registro[1]] + list(registro[2].values()) for registro in dados
for registro in dados
] ]
else: else:
@ -473,7 +483,9 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
texto = ( texto = (
_( _(
ngettext("%(dias)s dia", "%(dias)s dias", d["dias"]) ngettext(
"%(dias)s dia", "%(dias)s dias", d["dias"]
)
+ " em " + " em "
+ ngettext( + ngettext(
"%(eventos)s evento", "%(eventos)s evento",
@ -488,30 +500,31 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
row.append("") row.append("")
linhas.append(row) linhas.append(row)
context.update(
context.update({ {
"anos": ( "anos": (
Evento.objects.exclude(data_inicio=None) Evento.objects.exclude(data_inicio=None)
.order_by("data_inicio__year") .order_by("data_inicio__year")
.distinct("data_inicio__year") .distinct("data_inicio__year")
.values_list("data_inicio__year", flat=True) .values_list("data_inicio__year", flat=True)
), ),
"ano_pesquisa": ano_pesquisa, "ano_pesquisa": ano_pesquisa,
"linhas": linhas, "linhas": linhas,
"meses": meses, "meses": meses,
}) }
)
if mes_pesquisa > 0: if mes_pesquisa > 0:
context["mes_pesquisa"] = mes_pesquisa context["mes_pesquisa"] = mes_pesquisa
semanas = [ semanas = [
[s[0], s[-1]] [s[0], s[-1]]
for s in calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa) for s in calendar.Calendar().monthdatescalendar(
ano_pesquisa, mes_pesquisa
)
] ]
context["semanas"] = [ context["semanas"] = [
_(f"de {inicio:%d/%m} a {fim:%d/%m}") _(f"de {inicio:%d/%m} a {fim:%d/%m}") for inicio, fim in semanas
for inicio, fim in semanas
] ]
if semana_pesquisa > 0: if semana_pesquisa > 0:
@ -543,7 +556,9 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
if fmt == "pdf": if fmt == "pdf":
context["pdf"] = True context["pdf"] = True
context["title"] = self.title context["title"] = self.title
ano_pesquisa = context.get("ano_pesquisa", timezone.localdate().year) ano_pesquisa = context.get(
"ano_pesquisa", timezone.localdate().year
)
return WeasyTemplateResponse( return WeasyTemplateResponse(
filename=f"alocacao_equipe_{ano_pesquisa}.pdf", filename=f"alocacao_equipe_{ano_pesquisa}.pdf",
request=self.request, request=self.request,
@ -552,9 +567,13 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
content_type="application/pdf", content_type="application/pdf",
) )
elif fmt == "csv": elif fmt == "csv":
ano_pesquisa = context.get("ano_pesquisa", timezone.localdate().year) ano_pesquisa = context.get(
"ano_pesquisa", timezone.localdate().year
)
response = HttpResponse(content_type="text/csv") response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = f'attachment; filename="alocacao_equipe_{ano_pesquisa}.csv"' response["Content-Disposition"] = (
f'attachment; filename="alocacao_equipe_{ano_pesquisa}.csv"'
)
writer = csv.writer(response) writer = csv.writer(response)
writer.writerow(context["cabecalho"]) writer.writerow(context["cabecalho"])
writer.writerows(context["linhas"]) writer.writerows(context["linhas"])
@ -563,13 +582,14 @@ class AlocacaoEquipeReportView(LoginRequiredMixin, UserPassesTestMixin, ReportLi
return super().render_to_response(context, **response_kwargs) return super().render_to_response(context, **response_kwargs)
class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView): class EventosPorUfReportView(
LoginRequiredMixin, UserPassesTestMixin, ReportListView
):
title = _("Eventos por UF") title = _("Eventos por UF")
filter_form = EventosPorUfForm filter_form = EventosPorUfForm
template_name = "eventos/eventos_por_uf.html" template_name = "eventos/eventos_por_uf.html"
template_name_pdf = "eventos/eventos_por_uf_pdf.html" template_name_pdf = "eventos/eventos_por_uf_pdf.html"
list_fields = [] list_fields = []
list_labels = [] list_labels = []
@ -603,7 +623,6 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
if not form.is_valid(): if not form.is_valid():
return context return context
data_inicio = form.cleaned_data.get("data_inicio") data_inicio = form.cleaned_data.get("data_inicio")
data_fim = form.cleaned_data.get("data_fim") data_fim = form.cleaned_data.get("data_fim")
initial = self.get_initial() initial = self.get_initial()
@ -640,7 +659,10 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
eventos = ( eventos = (
UnidadeFederativa.objects.filter( UnidadeFederativa.objects.filter(
municipio__orgao__evento__status=Evento.STATUS_REALIZADO, municipio__orgao__evento__status=Evento.STATUS_REALIZADO,
municipio__orgao__evento__data_inicio__range=(data_inicio, data_fim), municipio__orgao__evento__data_inicio__range=(
data_inicio,
data_fim,
),
municipio__orgao__evento__tipo_evento__categoria__in=categorias, municipio__orgao__evento__tipo_evento__categoria__in=categorias,
) )
.order_by("regiao", "nome") .order_by("regiao", "nome")
@ -655,11 +677,10 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
if df.empty: if df.empty:
messages.error( messages.error(
self.request, self.request,
_("Nenhum evento foi realizado no período solicitado") _("Nenhum evento foi realizado no período solicitado"),
) )
return context return context
df.rename( df.rename(
columns={ columns={
"municipio__orgao__evento__tipo_evento__categoria": "categoria", "municipio__orgao__evento__tipo_evento__categoria": "categoria",
@ -682,25 +703,51 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
fill_value=0, fill_value=0,
) )
if len(categorias) > 1: if len(categorias) > 1:
ix_eventos_presenciais = [i for i in pivo_uf.columns if i[0] == "nº eventos presenciais"] ix_eventos_presenciais = [
ix_eventos_virtuais = [i for i in pivo_uf.columns if i[0] == "nº eventos virtuais"] i for i in pivo_uf.columns if i[0] == "nº eventos presenciais"
ix_participantes_presenciais = [i for i in pivo_uf.columns if i[0] == "participantes presenciais"] ]
ix_participantes_virtuais = [i for i in pivo_uf.columns if i[0] == "participantes virtuais"] ix_eventos_virtuais = [
i for i in pivo_uf.columns if i[0] == "nº eventos virtuais"
]
ix_participantes_presenciais = [
i
for i in pivo_uf.columns
if i[0] == "participantes presenciais"
]
ix_participantes_virtuais = [
i for i in pivo_uf.columns if i[0] == "participantes virtuais"
]
if ix_eventos_presenciais: if ix_eventos_presenciais:
pivo_uf[("nº eventos presenciais", "total")] = pivo_uf[ix_eventos_presenciais].sum(axis=1) pivo_uf[("nº eventos presenciais", "total")] = pivo_uf[
ix_eventos_presenciais.append(("nº eventos presenciais", "total")) ix_eventos_presenciais
].sum(axis=1)
ix_eventos_presenciais.append(
("nº eventos presenciais", "total")
)
if ix_eventos_virtuais: if ix_eventos_virtuais:
pivo_uf[("nº eventos virtuais", "total")] = pivo_uf[ix_eventos_virtuais].sum(axis=1) pivo_uf[("nº eventos virtuais", "total")] = pivo_uf[
ix_eventos_virtuais
].sum(axis=1)
ix_eventos_virtuais.append(("nº eventos virtuais", "total")) ix_eventos_virtuais.append(("nº eventos virtuais", "total"))
if ix_participantes_presenciais: if ix_participantes_presenciais:
pivo_uf[("participantes presenciais", "total")] = pivo_uf[ix_participantes_presenciais].sum(axis=1) pivo_uf[("participantes presenciais", "total")] = pivo_uf[
ix_participantes_presenciais.append(("participantes presenciais", "total")) ix_participantes_presenciais
].sum(axis=1)
ix_participantes_presenciais.append(
("participantes presenciais", "total")
)
if ix_participantes_virtuais: if ix_participantes_virtuais:
pivo_uf[("participantes virtuais", "total")] = pivo_uf[ix_participantes_virtuais].sum(axis=1) pivo_uf[("participantes virtuais", "total")] = pivo_uf[
ix_participantes_virtuais.append(("participantes virtuais", "total")) ix_participantes_virtuais
].sum(axis=1)
ix_participantes_virtuais.append(
("participantes virtuais", "total")
)
pivo_uf = pivo_uf[ pivo_uf = pivo_uf[
ix_eventos_presenciais + ix_eventos_virtuais + ix_eventos_presenciais
ix_participantes_presenciais + ix_participantes_virtuais + ix_eventos_virtuais
+ ix_participantes_presenciais
+ ix_participantes_virtuais
] ]
pivo_regiao = df.pivot_table( pivo_regiao = df.pivot_table(
@ -710,25 +757,55 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
fill_value=0, fill_value=0,
) )
if len(categorias) > 1: if len(categorias) > 1:
ix_eventos_presenciais = [i for i in pivo_regiao.columns if i[0] == "nº eventos presenciais"] ix_eventos_presenciais = [
ix_eventos_virtuais = [i for i in pivo_regiao.columns if i[0] == "nº eventos virtuais"] i
ix_participantes_presenciais = [i for i in pivo_regiao.columns if i[0] == "participantes presenciais"] for i in pivo_regiao.columns
ix_participantes_virtuais = [i for i in pivo_regiao.columns if i[0] == "participantes virtuais"] if i[0] == "nº eventos presenciais"
]
ix_eventos_virtuais = [
i for i in pivo_regiao.columns if i[0] == "nº eventos virtuais"
]
ix_participantes_presenciais = [
i
for i in pivo_regiao.columns
if i[0] == "participantes presenciais"
]
ix_participantes_virtuais = [
i
for i in pivo_regiao.columns
if i[0] == "participantes virtuais"
]
if ix_eventos_presenciais: if ix_eventos_presenciais:
pivo_regiao[("nº eventos presenciais", "total")] = pivo_regiao[ix_eventos_presenciais].sum(axis=1) pivo_regiao[("nº eventos presenciais", "total")] = pivo_regiao[
ix_eventos_presenciais.append(("nº eventos presenciais", "total")) ix_eventos_presenciais
].sum(axis=1)
ix_eventos_presenciais.append(
("nº eventos presenciais", "total")
)
if ix_eventos_virtuais: if ix_eventos_virtuais:
pivo_regiao[("nº eventos virtuais", "total")] = pivo_regiao[ix_eventos_virtuais].sum(axis=1) pivo_regiao[("nº eventos virtuais", "total")] = pivo_regiao[
ix_eventos_virtuais
].sum(axis=1)
ix_eventos_virtuais.append(("nº eventos virtuais", "total")) ix_eventos_virtuais.append(("nº eventos virtuais", "total"))
if ix_participantes_presenciais: if ix_participantes_presenciais:
pivo_regiao[("participantes presenciais", "total")] = pivo_regiao[ix_participantes_presenciais].sum(axis=1) pivo_regiao[("participantes presenciais", "total")] = (
ix_participantes_presenciais.append(("participantes presenciais", "total")) pivo_regiao[ix_participantes_presenciais].sum(axis=1)
)
ix_participantes_presenciais.append(
("participantes presenciais", "total")
)
if ix_participantes_virtuais: if ix_participantes_virtuais:
pivo_regiao[("participantes virtuais", "total")] = pivo_regiao[ix_participantes_virtuais].sum(axis=1) pivo_regiao[("participantes virtuais", "total")] = pivo_regiao[
ix_participantes_virtuais.append(("participantes virtuais", "total")) ix_participantes_virtuais
].sum(axis=1)
ix_participantes_virtuais.append(
("participantes virtuais", "total")
)
pivo_regiao = pivo_regiao[ pivo_regiao = pivo_regiao[
ix_eventos_presenciais + ix_eventos_virtuais + ix_eventos_presenciais
ix_participantes_presenciais + ix_participantes_virtuais + ix_eventos_virtuais
+ ix_participantes_presenciais
+ ix_participantes_virtuais
] ]
cabecalho_uf = [ cabecalho_uf = [
@ -743,18 +820,28 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
pivo_uf = pivo_uf.astype(int) pivo_uf = pivo_uf.astype(int)
pivo_regiao = pivo_regiao.astype(int) pivo_regiao = pivo_regiao.astype(int)
context.update({ context.update(
"data_inicio": data_inicio, {
"data_fim": data_fim, "data_inicio": data_inicio,
"categorias": [c[1] for c in TipoEvento.CATEGORIA_CHOICES if c[0] in categorias], "data_fim": data_fim,
"virtual": [m[1] for m in EventosPorUfForm.MODO_CHOICES if m[0] in virtual], "categorias": [
"pivo_uf": pivo_uf, c[1]
"pivo_regiao": pivo_regiao, for c in TipoEvento.CATEGORIA_CHOICES
"cabecalho_uf": cabecalho_uf, if c[0] in categorias
"cabecalho_regiao": cabecalho_regiao, ],
"total_uf": pivo_uf.sum(), "virtual": [
"total_regiao": pivo_regiao.sum(), m[1]
}) for m in EventosPorUfForm.MODO_CHOICES
if m[0] in virtual
],
"pivo_uf": pivo_uf,
"pivo_regiao": pivo_regiao,
"cabecalho_uf": cabecalho_uf,
"cabecalho_regiao": cabecalho_regiao,
"total_uf": pivo_uf.sum(),
"total_regiao": pivo_regiao.sum(),
}
)
return context return context
def render_to_response(self, context, **response_kwargs): def render_to_response(self, context, **response_kwargs):
@ -780,13 +867,15 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
return response return response
return super().render_to_response(context, **response_kwargs) return super().render_to_response(context, **response_kwargs)
class SolicitacoesPorPeriodoReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView):
class SolicitacoesPorPeriodoReportView(
LoginRequiredMixin, UserPassesTestMixin, ReportListView
):
title = _("Solicitações por período") title = _("Solicitações por período")
filter_form = SolicitacoesPorPeriodoForm filter_form = SolicitacoesPorPeriodoForm
template_name = "eventos/solicitacoes_por_periodo.html" template_name = "eventos/solicitacoes_por_periodo.html"
template_name_pdf = "eventos/solicitacoes_por_periodo_pdf.html" template_name_pdf = "eventos/solicitacoes_por_periodo_pdf.html"
list_fields = [] list_fields = []
list_labels = [] list_labels = []
@ -801,7 +890,9 @@ class SolicitacoesPorPeriodoReportView(LoginRequiredMixin, UserPassesTestMixin,
return { return {
"data_inicio": datetime.date.today().replace(day=1), "data_inicio": datetime.date.today().replace(day=1),
"data_fim": datetime.date.today().replace( "data_fim": datetime.date.today().replace(
day=calendar.monthrange(datetime.date.today().year, datetime.date.today().month)[1] day=calendar.monthrange(
datetime.date.today().year, datetime.date.today().month
)[1]
), ),
"tipos_evento": TipoEvento.objects.all(), "tipos_evento": TipoEvento.objects.all(),
"virtual": [m[0] for m in SolicitacoesPorPeriodoForm.MODO_CHOICES], "virtual": [m[0] for m in SolicitacoesPorPeriodoForm.MODO_CHOICES],
@ -823,15 +914,18 @@ class SolicitacoesPorPeriodoReportView(LoginRequiredMixin, UserPassesTestMixin,
data_inicio = form.cleaned_data.get("data_inicio") data_inicio = form.cleaned_data.get("data_inicio")
data_fim = form.cleaned_data.get("data_fim") data_fim = form.cleaned_data.get("data_fim")
initial = self.get_initial() initial = self.get_initial()
tipos_evento = form.cleaned_data.get("tipos_evento", initial["tipos_evento"]) tipos_evento = form.cleaned_data.get(
"tipos_evento", initial["tipos_evento"]
)
virtual = form.cleaned_data.get("virtual", initial["virtual"]) virtual = form.cleaned_data.get("virtual", initial["virtual"])
status = form.cleaned_data.get("status", initial["status"]) status = form.cleaned_data.get("status", initial["status"])
sq_equipe = ( sq_equipe = (
Equipe.objects.order_by() Equipe.objects.order_by()
.annotate( .annotate(
tot=Sum(F("qtde_diarias") * F("valor_diaria") + F("total_passagens")) tot=Sum(
F("qtde_diarias") * F("valor_diaria") + F("total_passagens")
)
) )
.values("tot") .values("tot")
) )
@ -864,15 +958,23 @@ class SolicitacoesPorPeriodoReportView(LoginRequiredMixin, UserPassesTestMixin,
qtde_solicitadas=Count("itemsolicitado__id"), qtde_solicitadas=Count("itemsolicitado__id"),
qtde_atendidas=Count( qtde_atendidas=Count(
"itemsolicitado__id", "itemsolicitado__id",
filter=Q(itemsolicitado__status=ItemSolicitado.STATUS_AUTORIZADO) filter=Q(
itemsolicitado__status=ItemSolicitado.STATUS_AUTORIZADO
),
), ),
qtde_rejeitadas=Count( qtde_rejeitadas=Count(
"itemsolicitado__id", "itemsolicitado__id",
filter=Q(itemsolicitado__status=ItemSolicitado.STATUS_REJEITADO) filter=Q(
itemsolicitado__status=ItemSolicitado.STATUS_REJEITADO
),
),
participantes=Sum(
"itemsolicitado__evento__total_participantes"
), ),
participantes=Sum("itemsolicitado__evento__total_participantes"),
custo_total=Subquery( custo_total=Subquery(
sq_equipe.filter(evento__itemsolicitado__solicitacao=OuterRef("pk"))[:1] sq_equipe.filter(
evento__itemsolicitado__solicitacao=OuterRef("pk")
)[:1]
), ),
) )
.select_related( .select_related(
@ -923,7 +1025,9 @@ class SolicitacoesPorPeriodoReportView(LoginRequiredMixin, UserPassesTestMixin,
.groupby(["regiao", "senador", "uf"], as_index=False) .groupby(["regiao", "senador", "uf"], as_index=False)
.sum() .sum()
) )
resumo_uf["participantes"] = resumo_uf["participantes"].astype("int") resumo_uf["participantes"] = resumo_uf["participantes"].astype(
"int"
)
resumo_regiao = resumo_uf.groupby(["regiao"], as_index=False)[ resumo_regiao = resumo_uf.groupby(["regiao"], as_index=False)[
[ [
"qtde_solicitadas", "qtde_solicitadas",
@ -942,8 +1046,12 @@ class SolicitacoesPorPeriodoReportView(LoginRequiredMixin, UserPassesTestMixin,
.values("tipo_evento__sigla", "tipo_evento__nome") .values("tipo_evento__sigla", "tipo_evento__nome")
.annotate( .annotate(
qtde_solicitadas=Count("id"), qtde_solicitadas=Count("id"),
qtde_atendidas=Count("id", filter=Q(status=ItemSolicitado.STATUS_AUTORIZADO)), qtde_atendidas=Count(
qtde_rejeitadas=Count("id", filter=Q(status=ItemSolicitado.STATUS_REJEITADO)), "id", filter=Q(status=ItemSolicitado.STATUS_AUTORIZADO)
),
qtde_rejeitadas=Count(
"id", filter=Q(status=ItemSolicitado.STATUS_REJEITADO)
),
participantes=Sum("evento__total_participantes"), participantes=Sum("evento__total_participantes"),
custo_total=Subquery( custo_total=Subquery(
sq_equipe.filter(evento__itemsolicitado=OuterRef("pk"))[:1] sq_equipe.filter(evento__itemsolicitado=OuterRef("pk"))[:1]
@ -962,22 +1070,30 @@ class SolicitacoesPorPeriodoReportView(LoginRequiredMixin, UserPassesTestMixin,
.sum() .sum()
.fillna(0) .fillna(0)
) )
resumo_tipo_evento["participantes"] = resumo_tipo_evento["participantes"].astype("int") resumo_tipo_evento["participantes"] = resumo_tipo_evento[
"participantes"
].astype("int")
resumo_tipo_evento.replace([0], [None], inplace=True) resumo_tipo_evento.replace([0], [None], inplace=True)
context.update({ context.update(
"data_inicio": data_inicio, {
"data_fim": data_fim, "data_inicio": data_inicio,
"status_choices": ItemSolicitado.STATUS_CHOICES, "data_fim": data_fim,
"legenda_oficinas": legenda_oficinas, "status_choices": ItemSolicitado.STATUS_CHOICES,
"tipos_evento": tipos_evento, "legenda_oficinas": legenda_oficinas,
"virtual": [m[1] for m in SolicitacoesPorPeriodoForm.MODO_CHOICES if m[0] in virtual], "tipos_evento": tipos_evento,
"solicitacoes": solicitacoes, "virtual": [
"sumario": sumario, m[1]
"resumo_uf": resumo_uf, for m in SolicitacoesPorPeriodoForm.MODO_CHOICES
"resumo_regiao": resumo_regiao, if m[0] in virtual
"resumo_tipo_evento": resumo_tipo_evento, ],
}) "solicitacoes": solicitacoes,
"sumario": sumario,
"resumo_uf": resumo_uf,
"resumo_regiao": resumo_regiao,
"resumo_tipo_evento": resumo_tipo_evento,
}
)
return context return context
def render_to_response(self, context, **response_kwargs): def render_to_response(self, context, **response_kwargs):
@ -1018,6 +1134,7 @@ class SolicitacoesPorPeriodoReportView(LoginRequiredMixin, UserPassesTestMixin,
return response return response
return super().render_to_response(context, **response_kwargs) return super().render_to_response(context, **response_kwargs)
class ApiEventoAbstract: class ApiEventoAbstract:
queryset = ( queryset = (
Evento.objects.filter(publicar=True) Evento.objects.filter(publicar=True)
@ -1034,6 +1151,9 @@ class ApiEventoList(ApiEventoAbstract, generics.ListAPIView):
""" """
serializer_class = EventoListSerializer serializer_class = EventoListSerializer
filter_backends = [filters.OrderingFilter]
ordering_fields = "__all__"
ordering = ["-data_inicio"]
class ApiEventoRetrieve(ApiEventoAbstract, generics.RetrieveAPIView): class ApiEventoRetrieve(ApiEventoAbstract, generics.RetrieveAPIView):

Loading…
Cancel
Save