Browse Source

convertendo as demais funções de eventos que são functions based view para class based views herdando reportlistview

pull/186/head
moonshinerd 1 month ago
parent
commit
b6a1149987
  1. 8
      sigi/apps/eventos/admin_urls.py
  2. 383
      sigi/apps/eventos/views.py

8
sigi/apps/eventos/admin_urls.py

@ -1,11 +1,11 @@
from django.urls import path from django.urls import path
from sigi.apps.eventos import views from sigi.apps.eventos import views
from sigi.apps.eventos.views import EventosPorUfReportView from sigi.apps.eventos.views import EventosPorUfReportView, SolicitacoesPorPeriodoReportView, CalendarioReportView, AlocacaoEquipeReportView
urlpatterns = [ urlpatterns = [
path("calendario/", views.calendario, name="eventos_calendario"), path("calendario/", CalendarioReportView.as_view(), name="eventos_calendario"),
path( path(
"alocacaoequipe/", views.alocacao_equipe, name="eventos_alocacaoequipe" "alocacaoequipe/", AlocacaoEquipeReportView.as_view(), name="eventos_alocacaoequipe"
), ),
path("eventosporuf/", EventosPorUfReportView.as_view(), name="eventos_eventosporuf"), path("eventosporuf/", EventosPorUfReportView.as_view(), name="eventos_eventosporuf"),
path( path(
@ -15,7 +15,7 @@ urlpatterns = [
), ),
path( path(
"solicitacoesporperiodo/", "solicitacoesporperiodo/",
views.solicitacoes_por_periodo, SolicitacoesPorPeriodoReportView.as_view(),
name="eventos_solicitacoesporperiodo", name="eventos_solicitacoesporperiodo",
), ),
path( path(

383
sigi/apps/eventos/views.py

@ -190,31 +190,53 @@ class AlunosPorUfReportView(
return context return context
@login_required
@staff_member_required class CalendarioReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView):
def calendario(request): title = _("Calendário de eventos")
fmt = request.GET.get("fmt", "html") filter_form = CalendarioForm
if "mes_ano" in request.GET: template_name = "eventos/calendario.html"
form = CalendarioForm(request.GET) template_name_pdf = "eventos/calendario_pdf.html"
else:
form = CalendarioForm(
initial={ list_fields = []
list_labels = []
def get_list_labels(self):
return []
def test_func(self):
return self.request.user.is_staff
def get_initial(self):
return {
"mes_ano": timezone.localdate().replace(day=1), "mes_ano": timezone.localdate().replace(day=1),
"categorias": [c[0] for c in TipoEvento.CATEGORIA_CHOICES], "categorias": [c[0] for c in TipoEvento.CATEGORIA_CHOICES],
"status": [s[0] for s in Evento.STATUS_CHOICES], "status": [s[0] for s in Evento.STATUS_CHOICES],
} }
)
context = {"form": form} def get_queryset(self):
return Evento.objects.none()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if "mes_ano" in self.request.GET:
form = CalendarioForm(self.request.GET)
else:
form = CalendarioForm(initial=self.get_initial())
context["form"] = form
if not form.is_valid(): if not form.is_valid():
return render(request, "eventos/calendario.html", context) return context
mes_pesquisa = form.cleaned_data["mes_ano"].month mes_pesquisa = form.cleaned_data["mes_ano"].month
ano_pesquisa = form.cleaned_data["mes_ano"].year ano_pesquisa = form.cleaned_data["mes_ano"].year
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)
@ -232,32 +254,25 @@ def calendario(request):
semanas = [ semanas = [
{"datas": s, "eventos": []} {"datas": s, "eventos": []}
for s in calendar.Calendar().monthdatescalendar( for s in calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa)
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]) if not (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(), start.weekday(),
end.weekday() - start.weekday() + 1, end.weekday() - start.weekday() + 1,
6 - end.weekday(), 6 - end.weekday(),
), ),
) ))
)
context.update( context.update({
{
"ano_pesquisa": ano_pesquisa, "ano_pesquisa": ano_pesquisa,
"mes_pesquisa": mes_pesquisa, "mes_pesquisa": mes_pesquisa,
"sel_categorias": sel_categorias, "sel_categorias": sel_categorias,
@ -267,21 +282,22 @@ def calendario(request):
"status": Evento.STATUS_CHOICES, "status": Evento.STATUS_CHOICES,
"eventos": eventos, "eventos": eventos,
"semanas": semanas, "semanas": semanas,
} })
) return context
def render_to_response(self, context, **response_kwargs):
fmt = self.request.GET.get("fmt", "html")
if fmt == "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(
filename=f"calendario_{ano_pesquisa:04}{mes_pesquisa:02}.pdf", filename=f"calendario_{context.get('ano_pesquisa'):04}{context.get('mes_pesquisa'):02}.pdf",
request=request, request=self.request,
template="eventos/calendario_pdf.html", template=self.template_name_pdf,
context=context, context=context,
content_type="application/pdf", content_type="application/pdf",
) )
return render(request, "eventos/calendario.html", context) return super().render_to_response(context, **response_kwargs)
class EventoListView(ListView): class EventoListView(ListView):
model = Evento model = Evento
@ -303,107 +319,145 @@ 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):
title = _("Alocação de equipe")
template_name = "eventos/alocacao_equipe.html"
template_name_pdf = "eventos/alocacao_equipe_pdf.html"
list_fields = []
list_labels = []
def test_func(self):
"""Restringe o acesso a usuários staff."""
return self.request.user.is_staff
def get_list_labels(self):
"""Sobrescreve para não exigir listagem de campos."""
return []
def get_queryset(self):
"""Retorna um queryset vazio, pois toda a lógica está em get_context_data."""
return Evento.objects.none()
def get_context_data(self, **kwargs):
"""Reproduz a lógica original da FBV, populando o contexto com dados."""
context = super().get_context_data(**kwargs)
ano_pesquisa = int(self.request.GET.get("ano", timezone.localdate().year))
mes_pesquisa = int(self.request.GET.get("mes", 0))
semana_pesquisa = int(self.request.GET.get("semana", 0))
formato = self.request.GET.get("fmt", "html")
@login_required
@staff_member_required
def alocacao_equipe(request):
ano_pesquisa = int(request.GET.get("ano", timezone.localdate().year))
mes_pesquisa = int(request.GET.get("mes", 0))
semana_pesquisa = int(request.GET.get("semana", 0))
formato = 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 = (
Evento.objects.exclude(
status__in=(Evento.STATUS_CANCELADO, Evento.STATUS_SOBRESTADO) status__in=(Evento.STATUS_CANCELADO, Evento.STATUS_SOBRESTADO)
).prefetch_related("equipe_set") )
.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( for s in calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa)
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 dias = calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa)[semana_pesquisa - 1]
)[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]
) )
else: else:
eventos = eventos.filter( eventos = eventos.filter(
data_inicio__gte=semanas[0][0], data_inicio__gte=semanas[0][0],
data_inicio__lte=semanas[-1][-1], data_inicio__lte=semanas[-1][-1],
) )
else: else:
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 p in evento.equipe_set.all(): for equipe in evento.equipe_set.all():
registro = None registro = None
for r in dados: for r in dados:
if r[0] == p.membro.pk: if r[0] == equipe.membro.pk:
registro = r registro = r
break break
if not registro: if not registro:
if semana_pesquisa > 0: if semana_pesquisa > 0:
registro = [ registro = [
p.membro.pk, equipe.membro.pk,
p.membro.get_apelido(), equipe.membro.get_apelido(),
OrderedDict([(dia, []) for dia in dias]), OrderedDict([(dia, []) for dia in dias]),
] ]
else: else:
registro = [ registro = [
p.membro.pk, equipe.membro.pk,
p.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:
if evento.data_inicio <= dia <= evento.data_termino: if evento.data_inicio <= dia <= evento.data_termino:
registro[2][dia].append(evento) registro[2][dia].append(evento)
else: else:
for idx, [inicio, fim] in enumerate(semanas): for idx, (inicio, fim) in enumerate(semanas):
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) min(fim, evento.data_termino) - evento.data_inicio
- 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) min(fim, evento.data_termino) - evento.data_inicio
- evento.data_inicio
).days + 1 ).days + 1
registro[2][idx]["eventos"] += 1 registro[2][idx]["eventos"] += 1
else: else:
registro[2][evento.data_inicio.month - 1]["dias"] += ( registro[2][evento.data_inicio.month - 1]["dias"] += (
evento.data_termino - evento.data_inicio evento.data_termino - evento.data_inicio
).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()) for registro in dados [registro[1]] + list(registro[2].values())
for registro in dados
] ]
else: else:
for r in dados: for r in dados:
r[2].append( r[2].append(
reduce( reduce(
lambda x, y: { lambda x, y: {
@ -413,14 +467,13 @@ def alocacao_equipe(request):
r[2], r[2],
) )
) )
linhas.append( row = [r[1]]
[r[1]] for d in r[2]:
+ [ if d["dias"] > 0 or d["eventos"] > 0:
(
texto = (
_( _(
ngettext( ngettext("%(dias)s dia", "%(dias)s dias", d["dias"])
"%(dias)s dia", "%(dias)s dias", d["dias"]
)
+ " em " + " em "
+ ngettext( + ngettext(
"%(eventos)s evento", "%(eventos)s evento",
@ -429,34 +482,44 @@ def alocacao_equipe(request):
) )
) )
% d % d
if d["dias"] > 0 or d["eventos"] > 0
else ""
)
for d in r[2]
]
) )
row.append(texto)
else:
row.append("")
linhas.append(row)
context = { context.update({
"anos": Evento.objects.exclude(data_inicio=None) "anos": (
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 = [
[s[0], s[-1]]
for s in calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa)
]
context["semanas"] = [ context["semanas"] = [
_(f"de {inicio:%d/%m} a {fim:%d/%m}") for inicio, fim in semanas _(f"de {inicio:%d/%m} a {fim:%d/%m}")
for inicio, fim in semanas
] ]
if semana_pesquisa > 0: if semana_pesquisa > 0:
cabecalho = [_("Servidor")] + dias
context["semana_pesquisa"] = semana_pesquisa context["semana_pesquisa"] = semana_pesquisa
context["eventos"] = eventos context["eventos"] = eventos
cabecalho = [_("Servidor")] + list(dias)
else: else:
cabecalho = ( cabecalho = (
[_("Servidor")] [_("Servidor")]
+ [ + [
@ -466,31 +529,38 @@ def alocacao_equipe(request):
+ ["total"] + ["total"]
) )
else: else:
cabecalho = [_("Servidor")] + meses + ["total"] cabecalho = [_("Servidor")] + meses + ["total"]
context["cabecalho"] = cabecalho context["cabecalho"] = cabecalho
context["formato"] = formato
if formato == "pdf": return context
context["title"] = _("Alocação de equipe")
def render_to_response(self, context, **response_kwargs):
"""Decide se retorna HTML, PDF ou CSV."""
fmt = context.get("formato", "html")
if fmt == "pdf":
context["pdf"] = True context["pdf"] = True
context["title"] = self.title
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=request, request=self.request,
template="eventos/alocacao_equipe_pdf.html", template=self.template_name_pdf,
context=context, context=context,
content_type="application/pdf", content_type="application/pdf",
) )
elif formato == "csv": elif fmt == "csv":
ano_pesquisa = context.get("ano_pesquisa", timezone.localdate().year)
response = HttpResponse(content_type="text/csv") response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = ( response["Content-Disposition"] = f'attachment; filename="alocacao_equipe_{ano_pesquisa}.csv"'
f'attachment; filename="alocacao_equipe_{ano_pesquisa}.csv"'
)
writer = csv.writer(response) writer = csv.writer(response)
writer.writerow(cabecalho) writer.writerow(context["cabecalho"])
writer.writerows(linhas) writer.writerows(context["linhas"])
return response return response
return render(request, "eventos/alocacao_equipe.html", context) return super().render_to_response(context, **response_kwargs)
class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView): class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView):
@ -499,12 +569,12 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
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"
# Adiciona atributos para satisfazer o ReportListView
list_fields = [] list_fields = []
list_labels = [] list_labels = []
def get_list_labels(self): def get_list_labels(self):
# Se não precisar exibir colunas de listagem, retorne uma lista vazia.
return [] return []
def test_func(self): def test_func(self):
@ -523,7 +593,7 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
} }
def get_queryset(self): def get_queryset(self):
# Retorna um queryset vazio, pois a lógica é toda implementada em get_context_data
return UnidadeFederativa.objects.none() return UnidadeFederativa.objects.none()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -533,7 +603,7 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
if not form.is_valid(): if not form.is_valid():
return context return context
# Resto da lógica para montar os pivôs e atualizar o contexto...
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()
@ -589,7 +659,7 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList
) )
return context return context
# Renomeia colunas, substitui códigos por nomes, monta as pivot tables, etc.
df.rename( df.rename(
columns={ columns={
"municipio__orgao__evento__tipo_evento__categoria": "categoria", "municipio__orgao__evento__tipo_evento__categoria": "categoria",
@ -710,56 +780,70 @@ 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):
title = _("Solicitações por período")
filter_form = SolicitacoesPorPeriodoForm
template_name = "eventos/solicitacoes_por_periodo.html"
template_name_pdf = "eventos/solicitacoes_por_periodo_pdf.html"
list_fields = []
list_labels = []
@login_required def get_list_labels(self):
@staff_member_required
def solicitacoes_por_periodo(request): return []
formato = request.GET.get("fmt", "html")
initials = { def test_func(self):
return self.request.user.is_staff
def get_initial(self):
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( day=calendar.monthrange(datetime.date.today().year, datetime.date.today().month)[1]
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],
"status": [s[0] for s in Solicitacao.STATUS_CHOICES], "status": [s[0] for s in Solicitacao.STATUS_CHOICES],
} }
if "data_inicio" in request.GET or "data_fim" in request.GET:
form = SolicitacoesPorPeriodoForm(request.GET) def get_queryset(self):
else:
form = SolicitacoesPorPeriodoForm(initial=initials) return Solicitacao.objects.none()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
form = self.get_filter_form_instance()
context["form"] = form
if not form.is_valid(): if not form.is_valid():
return render( return context
request,
"eventos/solicitacoes_por_periodo.html",
context={"form": form},
)
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")
tipos_evento = form.cleaned_data.get( initial = self.get_initial()
"tipos_evento", initials["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", initials["virtual"]) status = form.cleaned_data.get("status", initial["status"])
status = form.cleaned_data.get("status", initials["status"])
sq_equipe = ( sq_equipe = (
Equipe.objects.order_by() Equipe.objects.order_by()
.annotate( .annotate(
tot=Sum( tot=Sum(F("qtde_diarias") * F("valor_diaria") + F("total_passagens"))
F("qtde_diarias") * F("valor_diaria") + F("total_passagens")
)
) )
.values("tot") .values("tot")
) )
sq_equipe.query.group_by = [] sq_equipe.query.group_by = []
solicitacoes = Solicitacao.objects.order_by().filter( solicitacoes = Solicitacao.objects.order_by().filter(
data_pedido__range=(data_inicio, data_fim), data_pedido__range=(data_inicio, data_fim),
itemsolicitado__tipo_evento__in=tipos_evento, itemsolicitado__tipo_evento__in=tipos_evento,
itemsolicitado__virtual__in=virtual, itemsolicitado__virtual__in=virtual,
status__in=status, status__in=status,
) )
legenda_oficinas = ( legenda_oficinas = (
solicitacoes.order_by("itemsolicitado__tipo_evento__sigla") solicitacoes.order_by("itemsolicitado__tipo_evento__sigla")
.values_list( .values_list(
@ -768,6 +852,7 @@ def solicitacoes_por_periodo(request):
) )
.distinct() .distinct()
) )
solicitacoes = ( solicitacoes = (
solicitacoes.order_by( solicitacoes.order_by(
"casa__municipio__uf__regiao", "casa__municipio__uf__regiao",
@ -779,21 +864,15 @@ def solicitacoes_por_periodo(request):
qtde_solicitadas=Count("itemsolicitado__id"), qtde_solicitadas=Count("itemsolicitado__id"),
qtde_atendidas=Count( qtde_atendidas=Count(
"itemsolicitado__id", "itemsolicitado__id",
filter=Q( filter=Q(itemsolicitado__status=ItemSolicitado.STATUS_AUTORIZADO)
itemsolicitado__status=ItemSolicitado.STATUS_AUTORIZADO
),
), ),
qtde_rejeitadas=Count( qtde_rejeitadas=Count(
"itemsolicitado__id", "itemsolicitado__id",
filter=Q( filter=Q(itemsolicitado__status=ItemSolicitado.STATUS_REJEITADO)
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( sq_equipe.filter(evento__itemsolicitado__solicitacao=OuterRef("pk"))[:1]
evento__itemsolicitado__solicitacao=OuterRef("pk")
)[:1]
), ),
) )
.select_related( .select_related(
@ -804,6 +883,7 @@ def solicitacoes_por_periodo(request):
) )
.prefetch_related("itemsolicitado_set") .prefetch_related("itemsolicitado_set")
) )
sumario = solicitacoes.aggregate( sumario = solicitacoes.aggregate(
Sum("qtde_solicitadas"), Sum("qtde_solicitadas"),
Sum("qtde_atendidas"), Sum("qtde_atendidas"),
@ -811,6 +891,7 @@ def solicitacoes_por_periodo(request):
Sum("participantes"), Sum("participantes"),
Sum("custo_total"), Sum("custo_total"),
).values() ).values()
resumo_uf = pd.DataFrame( resumo_uf = pd.DataFrame(
solicitacoes.order_by( solicitacoes.order_by(
"casa__municipio__uf__regiao", "casa__municipio__uf__regiao",
@ -854,18 +935,15 @@ def solicitacoes_por_periodo(request):
].sum() ].sum()
resumo_uf.replace([0], [None], inplace=True) resumo_uf.replace([0], [None], inplace=True)
resumo_regiao.replace([0], [None], inplace=True) resumo_regiao.replace([0], [None], inplace=True)
resumo_tipo_evento = pd.DataFrame( resumo_tipo_evento = pd.DataFrame(
ItemSolicitado.objects.filter(solicitacao__in=solicitacoes) ItemSolicitado.objects.filter(solicitacao__in=solicitacoes)
.order_by("tipo_evento__sigla", "tipo_evento__nome") .order_by("tipo_evento__sigla", "tipo_evento__nome")
.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( qtde_atendidas=Count("id", filter=Q(status=ItemSolicitado.STATUS_AUTORIZADO)),
"id", filter=Q(status=ItemSolicitado.STATUS_AUTORIZADO) qtde_rejeitadas=Count("id", filter=Q(status=ItemSolicitado.STATUS_REJEITADO)),
),
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]
@ -884,41 +962,39 @@ def solicitacoes_por_periodo(request):
.sum() .sum()
.fillna(0) .fillna(0)
) )
resumo_tipo_evento["participantes"] = resumo_tipo_evento[ resumo_tipo_evento["participantes"] = resumo_tipo_evento["participantes"].astype("int")
"participantes"
].astype("int")
resumo_tipo_evento.replace([0], [None], inplace=True) resumo_tipo_evento.replace([0], [None], inplace=True)
# Imprimir
context = { context.update({
"form": form,
"data_inicio": data_inicio, "data_inicio": data_inicio,
"data_fim": data_fim, "data_fim": data_fim,
"status_choices": ItemSolicitado.STATUS_CHOICES, "status_choices": ItemSolicitado.STATUS_CHOICES,
"legenda_oficinas": legenda_oficinas, "legenda_oficinas": legenda_oficinas,
"tipos_evento": tipos_evento, "tipos_evento": tipos_evento,
"virtual": [ "virtual": [m[1] for m in SolicitacoesPorPeriodoForm.MODO_CHOICES if m[0] in virtual],
m[1]
for m in SolicitacoesPorPeriodoForm.MODO_CHOICES
if m[0] in virtual
],
"solicitacoes": solicitacoes, "solicitacoes": solicitacoes,
"sumario": sumario, "sumario": sumario,
"resumo_uf": resumo_uf, "resumo_uf": resumo_uf,
"resumo_regiao": resumo_regiao, "resumo_regiao": resumo_regiao,
"resumo_tipo_evento": resumo_tipo_evento, "resumo_tipo_evento": resumo_tipo_evento,
} })
return context
def render_to_response(self, context, **response_kwargs):
formato = self.request.GET.get("fmt", "html")
if formato == "pdf": if formato == "pdf":
context["title"] = _("Solicitações por período")
context["pdf"] = True context["pdf"] = True
return WeasyTemplateResponse( return WeasyTemplateResponse(
filename=f"solicitacoes_por_periodo-{data_inicio}-{data_fim}.pdf", filename=f"solicitacoes_por_periodo-{context.get('data_inicio')}-{context.get('data_fim')}.pdf",
request=request, request=self.request,
template="eventos/solicitacoes_por_periodo_pdf.html", template=self.template_name_pdf,
context=context, context=context,
content_type="application/pdf", content_type="application/pdf",
) )
elif formato == "csv": elif formato == "csv":
response = HttpResponse(content_type="text/csv") response = HttpResponse(content_type="text/csv")
data_inicio = context.get("data_inicio")
data_fim = context.get("data_fim")
response["Content-Disposition"] = ( response["Content-Disposition"] = (
f'attachment; filename="solicitacoes_por_periodo-{data_inicio}-{data_fim}.csv"' f'attachment; filename="solicitacoes_por_periodo-{data_inicio}-{data_fim}.csv"'
) )
@ -938,12 +1014,9 @@ def solicitacoes_por_periodo(request):
] ]
writer = csv.DictWriter(response, fieldnames) writer = csv.DictWriter(response, fieldnames)
writer.writeheader() writer.writeheader()
writer.writerows(solicitacoes.values(*fieldnames)) writer.writerows(context["solicitacoes"].values(*fieldnames))
return response return response
return render( return super().render_to_response(context, **response_kwargs)
request, "eventos/solicitacoes_por_periodo.html", context=context
)
class ApiEventoAbstract: class ApiEventoAbstract:
queryset = ( queryset = (

Loading…
Cancel
Save