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. 212
      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(),

212
sigi/apps/eventos/views.py

@ -493,11 +493,25 @@ 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"
# Adiciona atributos para satisfazer o ReportListView
list_fields = []
list_labels = []
def get_list_labels(self):
# Se não precisar exibir colunas de listagem, retorne uma lista vazia.
return []
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(
@ -507,20 +521,27 @@ def eventos_por_uf(request):
"categoria": [c[0] for c in TipoEvento.CATEGORIA_CHOICES], "categoria": [c[0] for c in TipoEvento.CATEGORIA_CHOICES],
"virtual": [m[0] for m in EventosPorUfForm.MODO_CHOICES], "virtual": [m[0] for m in EventosPorUfForm.MODO_CHOICES],
} }
if "data_inicio" in request.GET or "data_fim" in request.GET:
form = EventosPorUfForm(request.GET) def get_queryset(self):
else: # Retorna um queryset vazio, pois a lógica é toda implementada em get_context_data
form = EventosPorUfForm(initial=initials) 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(): if not form.is_valid():
return render( return context
request, "eventos/eventos_por_uf.html", context={"form": form}
) # 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")
categorias = form.cleaned_data.get("categoria", initials["categoria"]) initial = self.get_initial()
virtual = form.cleaned_data.get("virtual", initials["virtual"]) categorias = form.cleaned_data.get("categoria", initial["categoria"])
annotates = dict() virtual = form.cleaned_data.get("virtual", initial["virtual"])
aggfuncs = dict()
annotates = {}
aggfuncs = {}
if "P" in virtual: if "P" in virtual:
annotates["eventos_presenciais"] = Count( annotates["eventos_presenciais"] = Count(
"municipio__orgao__evento__id", "municipio__orgao__evento__id",
@ -545,13 +566,11 @@ def eventos_por_uf(request):
) )
aggfuncs["nº eventos virtuais"] = sum aggfuncs["nº eventos virtuais"] = sum
aggfuncs["participantes virtuais"] = sum aggfuncs["participantes virtuais"] = sum
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=( municipio__orgao__evento__data_inicio__range=(data_inicio, data_fim),
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")
@ -564,15 +583,13 @@ def eventos_por_uf(request):
) )
df = pd.DataFrame(eventos) df = pd.DataFrame(eventos)
if df.empty: if df.empty:
messages.add_message( messages.error(
request, self.request,
messages.ERROR, _("Nenhum evento foi realizado no período solicitado")
_("Nenhum evento foi realizado no período solicitado"),
)
return render(
request, "eventos/eventos_por_uf.html", context={"form": form}
) )
# Renomeia colunas 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",
@ -583,13 +600,11 @@ def eventos_por_uf(request):
}, },
inplace=True, inplace=True,
) )
# Troca a sigla pelo nome da região
for sigla, nome in UnidadeFederativa.REGIAO_CHOICES: for sigla, nome in UnidadeFederativa.REGIAO_CHOICES:
df["regiao"].replace(sigla, nome, inplace=True) df["regiao"].replace(sigla, nome, inplace=True)
# Troca o código pelo nome da categoria de eventos
for cod, nome in TipoEvento.CATEGORIA_CHOICES: for cod, nome in TipoEvento.CATEGORIA_CHOICES:
df["categoria"].replace(cod, nome, inplace=True) df["categoria"].replace(cod, nome, inplace=True)
# Cria tabela pivot das UFs
pivo_uf = df.pivot_table( pivo_uf = df.pivot_table(
index=["regiao", "nome"], index=["regiao", "nome"],
columns="categoria", columns="categoria",
@ -597,103 +612,55 @@ def eventos_por_uf(request):
fill_value=0, fill_value=0,
) )
if len(categorias) > 1: if len(categorias) > 1:
# 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_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[ pivo_uf[("nº eventos presenciais", "total")] = pivo_uf[ix_eventos_presenciais].sum(axis=1)
ix_eventos_presenciais
].sum(axis=1)
ix_eventos_presenciais.append(("nº eventos presenciais", "total")) ix_eventos_presenciais.append(("nº eventos presenciais", "total"))
if ix_eventos_virtuais: if ix_eventos_virtuais:
pivo_uf[("nº eventos virtuais", "total")] = pivo_uf[ pivo_uf[("nº eventos virtuais", "total")] = pivo_uf[ix_eventos_virtuais].sum(axis=1)
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[ pivo_uf[("participantes presenciais", "total")] = pivo_uf[ix_participantes_presenciais].sum(axis=1)
ix_participantes_presenciais ix_participantes_presenciais.append(("participantes presenciais", "total"))
].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[ pivo_uf[("participantes virtuais", "total")] = pivo_uf[ix_participantes_virtuais].sum(axis=1)
ix_participantes_virtuais ix_participantes_virtuais.append(("participantes virtuais", "total"))
].sum(axis=1)
ix_participantes_virtuais.append(
("participantes virtuais", "total")
)
pivo_uf = pivo_uf[ pivo_uf = pivo_uf[
ix_eventos_presenciais ix_eventos_presenciais + ix_eventos_virtuais +
+ ix_eventos_virtuais ix_participantes_presenciais + ix_participantes_virtuais
+ ix_participantes_presenciais
+ ix_participantes_virtuais
] ]
# Cria tabela pivot das regiões
pivo_regiao = df.pivot_table( pivo_regiao = df.pivot_table(
index="regiao", index="regiao",
columns="categoria", columns="categoria",
aggfunc=aggfuncs, aggfunc=aggfuncs,
fill_value=0, fill_value=0,
) )
# Calcula os totais de eventos e participantes para as regiões
if len(categorias) > 1: if len(categorias) > 1:
ix_eventos_presenciais = [ ix_eventos_presenciais = [i for i in pivo_regiao.columns if i[0] == "nº 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_eventos_virtuais = [ ix_participantes_virtuais = [i for i in pivo_regiao.columns if i[0] == "participantes 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[ pivo_regiao[("nº eventos presenciais", "total")] = pivo_regiao[ix_eventos_presenciais].sum(axis=1)
ix_eventos_presenciais
].sum(axis=1)
ix_eventos_presenciais.append(("nº eventos presenciais", "total")) ix_eventos_presenciais.append(("nº eventos presenciais", "total"))
if ix_eventos_virtuais: if ix_eventos_virtuais:
pivo_regiao[("nº eventos virtuais", "total")] = pivo_regiao[ pivo_regiao[("nº eventos virtuais", "total")] = pivo_regiao[ix_eventos_virtuais].sum(axis=1)
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[ pivo_regiao[("participantes presenciais", "total")] = pivo_regiao[ix_participantes_presenciais].sum(axis=1)
ix_participantes_presenciais ix_participantes_presenciais.append(("participantes presenciais", "total"))
].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[ pivo_regiao[("participantes virtuais", "total")] = pivo_regiao[ix_participantes_virtuais].sum(axis=1)
ix_participantes_virtuais ix_participantes_virtuais.append(("participantes virtuais", "total"))
].sum(axis=1)
ix_participantes_virtuais.append(
("participantes virtuais", "total")
)
pivo_regiao = pivo_regiao[ pivo_regiao = pivo_regiao[
ix_eventos_presenciais ix_eventos_presenciais + ix_eventos_virtuais +
+ ix_eventos_virtuais ix_participantes_presenciais + ix_participantes_virtuais
+ ix_participantes_presenciais
+ ix_participantes_virtuais
] ]
# Cabeçalhos para impressão
cabecalho_uf = [ cabecalho_uf = [
(k, [i[1] for i in v]) (k, [i[1] for i in v])
for k, v in groupby(pivo_uf.columns, lambda x: x[0]) for k, v in groupby(pivo_uf.columns, lambda x: x[0])
@ -702,45 +669,46 @@ def eventos_por_uf(request):
(k, [i[1] for i in v]) (k, [i[1] for i in v])
for k, v in groupby(pivo_regiao.columns, lambda x: x[0]) for k, v in groupby(pivo_regiao.columns, lambda x: x[0])
] ]
# Fixar tudo em int
pivo_uf = pivo_uf.astype(int) pivo_uf = pivo_uf.astype(int)
pivo_regiao = pivo_regiao.astype(int) pivo_regiao = pivo_regiao.astype(int)
# Imprimir
context = { context.update({
"form": form,
"data_inicio": data_inicio, "data_inicio": data_inicio,
"data_fim": data_fim, "data_fim": data_fim,
"categorias": [ "categorias": [c[1] for c in TipoEvento.CATEGORIA_CHOICES if c[0] in 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],
],
"virtual": [
m[1] for m in EventosPorUfForm.MODO_CHOICES if m[0] in virtual
],
"pivo_uf": pivo_uf, "pivo_uf": pivo_uf,
"pivo_regiao": pivo_regiao, "pivo_regiao": pivo_regiao,
"cabecalho_uf": cabecalho_uf, "cabecalho_uf": cabecalho_uf,
"cabecalho_regiao": cabecalho_regiao, "cabecalho_regiao": cabecalho_regiao,
"total_uf": pivo_uf.sum(), "total_uf": pivo_uf.sum(),
"total_regiao": pivo_regiao.sum(), "total_regiao": pivo_regiao.sum(),
} })
if formato == "pdf": 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["title"] = _("Eventos por Unidade da Federação")
context["pdf"] = True context["pdf"] = True
return WeasyTemplateResponse( return WeasyTemplateResponse(
# filename=f"eventos_por_uf-{data_inicio}-{data_fim}.pdf", request=self.request,
request=request, template=self.template_name_pdf,
template="eventos/eventos_por_uf_pdf.html",
context=context, context=context,
content_type="application/pdf", content_type="application/pdf",
) )
elif formato == "csv": elif fmt == "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="eventos_por_uf-{data_inicio}-{data_fim}.csv"' f'attachment; filename="eventos_por_uf-{data_inicio}-{data_fim}.csv"'
) )
pivo_uf = context.get("pivo_uf")
pivo_uf.to_csv(response) pivo_uf.to_csv(response)
return response return response
return render(request, "eventos/eventos_por_uf.html", context=context) return super().render_to_response(context, **response_kwargs)
@login_required @login_required

0
sigi/templates/admin/dat

Loading…
Cancel
Save