Browse Source

convertendo a função eventos_por_uf(function based view) para class based views herdando reportlistview

pull/186/head
moonshinerd 1 month ago
parent
commit
16e8c5e445
  1. 3
      sigi/apps/eventos/admin_urls.py
  2. 446
      sigi/apps/eventos/views.py
  3. 0
      sigi/templates/admin/dat

3
sigi/apps/eventos/admin_urls.py

@ -1,12 +1,13 @@
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
urlpatterns = [ urlpatterns = [
path("calendario/", views.calendario, name="eventos_calendario"), path("calendario/", views.calendario, name="eventos_calendario"),
path( path(
"alocacaoequipe/", views.alocacao_equipe, name="eventos_alocacaoequipe" "alocacaoequipe/", views.alocacao_equipe, name="eventos_alocacaoequipe"
), ),
path("eventosporuf/", views.eventos_por_uf, name="eventos_eventosporuf"), path("eventosporuf/", EventosPorUfReportView.as_view(), name="eventos_eventosporuf"),
path( path(
"alunosporuf/", "alunosporuf/",
views.AlunosPorUfReportView.as_view(), views.AlunosPorUfReportView.as_view(),

446
sigi/apps/eventos/views.py

@ -493,254 +493,222 @@ def alocacao_equipe(request):
return render(request, "eventos/alocacao_equipe.html", context) return render(request, "eventos/alocacao_equipe.html", context)
@login_required class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView):
@staff_member_required title = _("Eventos por UF")
def eventos_por_uf(request): filter_form = EventosPorUfForm
formato = request.GET.get("fmt", "html") template_name = "eventos/eventos_por_uf.html"
initials = { template_name_pdf = "eventos/eventos_por_uf_pdf.html"
"data_inicio": datetime.date.today().replace(day=1),
"data_fim": datetime.date.today().replace( # Adiciona atributos para satisfazer o ReportListView
day=calendar.monthrange( list_fields = []
datetime.date.today().year, datetime.date.today().month list_labels = []
)[1]
), def get_list_labels(self):
"categoria": [c[0] for c in TipoEvento.CATEGORIA_CHOICES], # Se não precisar exibir colunas de listagem, retorne uma lista vazia.
"virtual": [m[0] for m in EventosPorUfForm.MODO_CHOICES], return []
}
if "data_inicio" in request.GET or "data_fim" in request.GET: def test_func(self):
form = EventosPorUfForm(request.GET) return self.request.user.is_staff
else:
form = EventosPorUfForm(initial=initials) def get_initial(self):
if not form.is_valid(): return {
return render( "data_inicio": datetime.date.today().replace(day=1),
request, "eventos/eventos_por_uf.html", context={"form": form} "data_fim": datetime.date.today().replace(
) day=calendar.monthrange(
data_inicio = form.cleaned_data.get("data_inicio") datetime.date.today().year, datetime.date.today().month
data_fim = form.cleaned_data.get("data_fim") )[1]
categorias = form.cleaned_data.get("categoria", initials["categoria"])
virtual = form.cleaned_data.get("virtual", initials["virtual"])
annotates = dict()
aggfuncs = dict()
if "P" in virtual:
annotates["eventos_presenciais"] = Count(
"municipio__orgao__evento__id",
distinct=True,
filter=Q(municipio__orgao__evento__virtual=False),
)
annotates["participantes_presenciais"] = Sum(
"municipio__orgao__evento__total_participantes",
filter=Q(municipio__orgao__evento__virtual=False),
)
aggfuncs["nº eventos presenciais"] = sum
aggfuncs["participantes presenciais"] = sum
if "V" in virtual:
annotates["eventos_virtuais"] = Count(
"municipio__orgao__evento__id",
distinct=True,
filter=Q(municipio__orgao__evento__virtual=True),
)
annotates["participantes_virtuais"] = Sum(
"municipio__orgao__evento__total_participantes",
filter=Q(municipio__orgao__evento__virtual=True),
)
aggfuncs["nº eventos virtuais"] = sum
aggfuncs["participantes virtuais"] = sum
eventos = (
UnidadeFederativa.objects.filter(
municipio__orgao__evento__status=Evento.STATUS_REALIZADO,
municipio__orgao__evento__data_inicio__range=(
data_inicio,
data_fim,
), ),
municipio__orgao__evento__tipo_evento__categoria__in=categorias, "categoria": [c[0] for c in TipoEvento.CATEGORIA_CHOICES],
"virtual": [m[0] for m in EventosPorUfForm.MODO_CHOICES],
}
def get_queryset(self):
# Retorna um queryset vazio, pois a lógica é toda implementada em get_context_data
return UnidadeFederativa.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():
return context
# Resto da lógica para montar os pivôs e atualizar o contexto...
data_inicio = form.cleaned_data.get("data_inicio")
data_fim = form.cleaned_data.get("data_fim")
initial = self.get_initial()
categorias = form.cleaned_data.get("categoria", initial["categoria"])
virtual = form.cleaned_data.get("virtual", initial["virtual"])
annotates = {}
aggfuncs = {}
if "P" in virtual:
annotates["eventos_presenciais"] = Count(
"municipio__orgao__evento__id",
distinct=True,
filter=Q(municipio__orgao__evento__virtual=False),
)
annotates["participantes_presenciais"] = Sum(
"municipio__orgao__evento__total_participantes",
filter=Q(municipio__orgao__evento__virtual=False),
)
aggfuncs["nº eventos presenciais"] = sum
aggfuncs["participantes presenciais"] = sum
if "V" in virtual:
annotates["eventos_virtuais"] = Count(
"municipio__orgao__evento__id",
distinct=True,
filter=Q(municipio__orgao__evento__virtual=True),
)
annotates["participantes_virtuais"] = Sum(
"municipio__orgao__evento__total_participantes",
filter=Q(municipio__orgao__evento__virtual=True),
)
aggfuncs["nº eventos virtuais"] = sum
aggfuncs["participantes virtuais"] = sum
eventos = (
UnidadeFederativa.objects.filter(
municipio__orgao__evento__status=Evento.STATUS_REALIZADO,
municipio__orgao__evento__data_inicio__range=(data_inicio, data_fim),
municipio__orgao__evento__tipo_evento__categoria__in=categorias,
)
.order_by("regiao", "nome")
.values(
"regiao",
"nome",
"municipio__orgao__evento__tipo_evento__categoria",
)
.annotate(**annotates)
) )
.order_by("regiao", "nome") df = pd.DataFrame(eventos)
.values( if df.empty:
"regiao", messages.error(
"nome", self.request,
"municipio__orgao__evento__tipo_evento__categoria", _("Nenhum evento foi realizado no período solicitado")
)
return context
# Renomeia colunas, substitui códigos por nomes, monta as pivot tables, etc.
df.rename(
columns={
"municipio__orgao__evento__tipo_evento__categoria": "categoria",
"eventos_presenciais": "nº eventos presenciais",
"eventos_virtuais": "nº eventos virtuais",
"participantes_presenciais": "participantes presenciais",
"participantes_virtuais": "participantes virtuais",
},
inplace=True,
) )
.annotate(**annotates) for sigla, nome in UnidadeFederativa.REGIAO_CHOICES:
) df["regiao"].replace(sigla, nome, inplace=True)
df = pd.DataFrame(eventos) for cod, nome in TipoEvento.CATEGORIA_CHOICES:
if df.empty: df["categoria"].replace(cod, nome, inplace=True)
messages.add_message(
request, pivo_uf = df.pivot_table(
messages.ERROR, index=["regiao", "nome"],
_("Nenhum evento foi realizado no período solicitado"), columns="categoria",
aggfunc=aggfuncs,
fill_value=0,
) )
return render( if len(categorias) > 1:
request, "eventos/eventos_por_uf.html", context={"form": form} ix_eventos_presenciais = [i for i in pivo_uf.columns if i[0] == "nº eventos presenciais"]
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:
pivo_uf[("nº eventos presenciais", "total")] = pivo_uf[ix_eventos_presenciais].sum(axis=1)
ix_eventos_presenciais.append(("nº eventos presenciais", "total"))
if ix_eventos_virtuais:
pivo_uf[("nº eventos virtuais", "total")] = pivo_uf[ix_eventos_virtuais].sum(axis=1)
ix_eventos_virtuais.append(("nº eventos virtuais", "total"))
if ix_participantes_presenciais:
pivo_uf[("participantes presenciais", "total")] = pivo_uf[ix_participantes_presenciais].sum(axis=1)
ix_participantes_presenciais.append(("participantes presenciais", "total"))
if ix_participantes_virtuais:
pivo_uf[("participantes virtuais", "total")] = pivo_uf[ix_participantes_virtuais].sum(axis=1)
ix_participantes_virtuais.append(("participantes virtuais", "total"))
pivo_uf = pivo_uf[
ix_eventos_presenciais + ix_eventos_virtuais +
ix_participantes_presenciais + ix_participantes_virtuais
]
pivo_regiao = df.pivot_table(
index="regiao",
columns="categoria",
aggfunc=aggfuncs,
fill_value=0,
) )
# Renomeia colunas if len(categorias) > 1:
df.rename( ix_eventos_presenciais = [i for i in pivo_regiao.columns if i[0] == "nº eventos presenciais"]
columns={ ix_eventos_virtuais = [i for i in pivo_regiao.columns if i[0] == "nº eventos virtuais"]
"municipio__orgao__evento__tipo_evento__categoria": "categoria", ix_participantes_presenciais = [i for i in pivo_regiao.columns if i[0] == "participantes presenciais"]
"eventos_presenciais": "nº eventos presenciais", ix_participantes_virtuais = [i for i in pivo_regiao.columns if i[0] == "participantes virtuais"]
"eventos_virtuais": "nº eventos virtuais", if ix_eventos_presenciais:
"participantes_presenciais": "participantes presenciais", pivo_regiao[("nº eventos presenciais", "total")] = pivo_regiao[ix_eventos_presenciais].sum(axis=1)
"participantes_virtuais": "participantes virtuais", ix_eventos_presenciais.append(("nº eventos presenciais", "total"))
}, if ix_eventos_virtuais:
inplace=True, pivo_regiao[("nº eventos virtuais", "total")] = pivo_regiao[ix_eventos_virtuais].sum(axis=1)
) ix_eventos_virtuais.append(("nº eventos virtuais", "total"))
# Troca a sigla pelo nome da região if ix_participantes_presenciais:
for sigla, nome in UnidadeFederativa.REGIAO_CHOICES: pivo_regiao[("participantes presenciais", "total")] = pivo_regiao[ix_participantes_presenciais].sum(axis=1)
df["regiao"].replace(sigla, nome, inplace=True) ix_participantes_presenciais.append(("participantes presenciais", "total"))
# Troca o código pelo nome da categoria de eventos if ix_participantes_virtuais:
for cod, nome in TipoEvento.CATEGORIA_CHOICES: pivo_regiao[("participantes virtuais", "total")] = pivo_regiao[ix_participantes_virtuais].sum(axis=1)
df["categoria"].replace(cod, nome, inplace=True) ix_participantes_virtuais.append(("participantes virtuais", "total"))
# Cria tabela pivot das UFs pivo_regiao = pivo_regiao[
pivo_uf = df.pivot_table( ix_eventos_presenciais + ix_eventos_virtuais +
index=["regiao", "nome"], ix_participantes_presenciais + ix_participantes_virtuais
columns="categoria", ]
aggfunc=aggfuncs,
fill_value=0, cabecalho_uf = [
) (k, [i[1] for i in v])
if len(categorias) > 1: for k, v in groupby(pivo_uf.columns, lambda x: x[0])
# calcula os totais de eventos e de participantes para as UFs
ix_eventos_presenciais = [
i for i in pivo_uf.columns if i[0] == "nº eventos presenciais"
]
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:
pivo_uf[("nº eventos presenciais", "total")] = pivo_uf[
ix_eventos_presenciais
].sum(axis=1)
ix_eventos_presenciais.append(("nº eventos presenciais", "total"))
if ix_eventos_virtuais:
pivo_uf[("nº eventos virtuais", "total")] = pivo_uf[
ix_eventos_virtuais
].sum(axis=1)
ix_eventos_virtuais.append(("nº eventos virtuais", "total"))
if ix_participantes_presenciais:
pivo_uf[("participantes presenciais", "total")] = pivo_uf[
ix_participantes_presenciais
].sum(axis=1)
ix_participantes_presenciais.append(
("participantes presenciais", "total")
)
if ix_participantes_virtuais:
pivo_uf[("participantes virtuais", "total")] = pivo_uf[
ix_participantes_virtuais
].sum(axis=1)
ix_participantes_virtuais.append(
("participantes virtuais", "total")
)
pivo_uf = pivo_uf[
ix_eventos_presenciais
+ ix_eventos_virtuais
+ ix_participantes_presenciais
+ ix_participantes_virtuais
]
# Cria tabela pivot das regiões
pivo_regiao = df.pivot_table(
index="regiao",
columns="categoria",
aggfunc=aggfuncs,
fill_value=0,
)
# Calcula os totais de eventos e participantes para as regiões
if len(categorias) > 1:
ix_eventos_presenciais = [
i for i in pivo_regiao.columns 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 = [ cabecalho_regiao = [
i for i in pivo_regiao.columns if i[0] == "participantes virtuais" (k, [i[1] for i in v])
for k, v in groupby(pivo_regiao.columns, lambda x: x[0])
] ]
if ix_eventos_presenciais:
pivo_regiao[("nº eventos presenciais", "total")] = pivo_regiao[ pivo_uf = pivo_uf.astype(int)
ix_eventos_presenciais pivo_regiao = pivo_regiao.astype(int)
].sum(axis=1)
ix_eventos_presenciais.append(("nº eventos presenciais", "total")) context.update({
if ix_eventos_virtuais: "data_inicio": data_inicio,
pivo_regiao[("nº eventos virtuais", "total")] = pivo_regiao[ "data_fim": data_fim,
ix_eventos_virtuais "categorias": [c[1] for c in TipoEvento.CATEGORIA_CHOICES if c[0] in categorias],
].sum(axis=1) "virtual": [m[1] for m in EventosPorUfForm.MODO_CHOICES if m[0] in virtual],
ix_eventos_virtuais.append(("nº eventos virtuais", "total")) "pivo_uf": pivo_uf,
if ix_participantes_presenciais: "pivo_regiao": pivo_regiao,
pivo_regiao[("participantes presenciais", "total")] = pivo_regiao[ "cabecalho_uf": cabecalho_uf,
ix_participantes_presenciais "cabecalho_regiao": cabecalho_regiao,
].sum(axis=1) "total_uf": pivo_uf.sum(),
ix_participantes_presenciais.append( "total_regiao": pivo_regiao.sum(),
("participantes presenciais", "total") })
return context
def render_to_response(self, context, **response_kwargs):
fmt = self.request.GET.get("fmt", "html")
if fmt == "pdf":
context["title"] = _("Eventos por Unidade da Federação")
context["pdf"] = True
return WeasyTemplateResponse(
request=self.request,
template=self.template_name_pdf,
context=context,
content_type="application/pdf",
) )
if ix_participantes_virtuais: elif fmt == "csv":
pivo_regiao[("participantes virtuais", "total")] = pivo_regiao[ response = HttpResponse(content_type="text/csv")
ix_participantes_virtuais data_inicio = context.get("data_inicio")
].sum(axis=1) data_fim = context.get("data_fim")
ix_participantes_virtuais.append( response["Content-Disposition"] = (
("participantes virtuais", "total") f'attachment; filename="eventos_por_uf-{data_inicio}-{data_fim}.csv"'
) )
pivo_regiao = pivo_regiao[ pivo_uf = context.get("pivo_uf")
ix_eventos_presenciais pivo_uf.to_csv(response)
+ ix_eventos_virtuais return response
+ ix_participantes_presenciais return super().render_to_response(context, **response_kwargs)
+ ix_participantes_virtuais
]
# Cabeçalhos para impressão
cabecalho_uf = [
(k, [i[1] for i in v])
for k, v in groupby(pivo_uf.columns, lambda x: x[0])
]
cabecalho_regiao = [
(k, [i[1] for i in v])
for k, v in groupby(pivo_regiao.columns, lambda x: x[0])
]
# Fixar tudo em int
pivo_uf = pivo_uf.astype(int)
pivo_regiao = pivo_regiao.astype(int)
# Imprimir
context = {
"form": form,
"data_inicio": data_inicio,
"data_fim": data_fim,
"categorias": [
c[1] for c in TipoEvento.CATEGORIA_CHOICES if c[0] in categorias
],
"virtual": [
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(),
}
if formato == "pdf":
context["title"] = _("Eventos por Unidade da Federação")
context["pdf"] = True
return WeasyTemplateResponse(
# filename=f"eventos_por_uf-{data_inicio}-{data_fim}.pdf",
request=request,
template="eventos/eventos_por_uf_pdf.html",
context=context,
content_type="application/pdf",
)
elif formato == "csv":
response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = (
f'attachment; filename="eventos_por_uf-{data_inicio}-{data_fim}.csv"'
)
pivo_uf.to_csv(response)
return response
return render(request, "eventos/eventos_por_uf.html", context=context)
@login_required @login_required

0
sigi/templates/admin/dat

Loading…
Cancel
Save