|
|
@ -190,31 +190,53 @@ class AlunosPorUfReportView( |
|
|
|
return context |
|
|
|
|
|
|
|
|
|
|
|
@login_required |
|
|
|
@staff_member_required |
|
|
|
def calendario(request): |
|
|
|
fmt = request.GET.get("fmt", "html") |
|
|
|
if "mes_ano" in request.GET: |
|
|
|
form = CalendarioForm(request.GET) |
|
|
|
else: |
|
|
|
form = CalendarioForm( |
|
|
|
initial={ |
|
|
|
|
|
|
|
class CalendarioReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView): |
|
|
|
title = _("Calendário de eventos") |
|
|
|
filter_form = CalendarioForm |
|
|
|
template_name = "eventos/calendario.html" |
|
|
|
template_name_pdf = "eventos/calendario_pdf.html" |
|
|
|
|
|
|
|
|
|
|
|
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), |
|
|
|
"categorias": [c[0] for c in TipoEvento.CATEGORIA_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(): |
|
|
|
return render(request, "eventos/calendario.html", context) |
|
|
|
return context |
|
|
|
|
|
|
|
mes_pesquisa = form.cleaned_data["mes_ano"].month |
|
|
|
ano_pesquisa = form.cleaned_data["mes_ano"].year |
|
|
|
sel_categorias = form.cleaned_data["categorias"] |
|
|
|
sel_status = form.cleaned_data["status"] |
|
|
|
|
|
|
|
|
|
|
|
lang = to_locale(get_language()) + ".UTF-8" |
|
|
|
locale.setlocale(locale.LC_ALL, lang) |
|
|
|
|
|
|
@ -232,32 +254,25 @@ def calendario(request): |
|
|
|
|
|
|
|
semanas = [ |
|
|
|
{"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 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) |
|
|
|
end = min(s["datas"][-1], e.data_termino) |
|
|
|
s["eventos"].append( |
|
|
|
( |
|
|
|
s["eventos"].append(( |
|
|
|
e, |
|
|
|
( |
|
|
|
start.weekday(), |
|
|
|
end.weekday() - start.weekday() + 1, |
|
|
|
6 - end.weekday(), |
|
|
|
), |
|
|
|
) |
|
|
|
) |
|
|
|
)) |
|
|
|
|
|
|
|
context.update( |
|
|
|
{ |
|
|
|
context.update({ |
|
|
|
"ano_pesquisa": ano_pesquisa, |
|
|
|
"mes_pesquisa": mes_pesquisa, |
|
|
|
"sel_categorias": sel_categorias, |
|
|
@ -267,21 +282,22 @@ def calendario(request): |
|
|
|
"status": Evento.STATUS_CHOICES, |
|
|
|
"eventos": eventos, |
|
|
|
"semanas": semanas, |
|
|
|
} |
|
|
|
) |
|
|
|
}) |
|
|
|
return context |
|
|
|
|
|
|
|
def render_to_response(self, context, **response_kwargs): |
|
|
|
fmt = self.request.GET.get("fmt", "html") |
|
|
|
if fmt == "pdf": |
|
|
|
context["title"] = _("Calendário de eventos") |
|
|
|
context["pdf"] = True |
|
|
|
return WeasyTemplateResponse( |
|
|
|
filename=f"calendario_{ano_pesquisa:04}{mes_pesquisa:02}.pdf", |
|
|
|
request=request, |
|
|
|
template="eventos/calendario_pdf.html", |
|
|
|
filename=f"calendario_{context.get('ano_pesquisa'):04}{context.get('mes_pesquisa'):02}.pdf", |
|
|
|
request=self.request, |
|
|
|
template=self.template_name_pdf, |
|
|
|
context=context, |
|
|
|
content_type="application/pdf", |
|
|
|
) |
|
|
|
return render(request, "eventos/calendario.html", context) |
|
|
|
|
|
|
|
return super().render_to_response(context, **response_kwargs) |
|
|
|
|
|
|
|
class EventoListView(ListView): |
|
|
|
model = Evento |
|
|
@ -303,107 +319,145 @@ class EventoListView(ListView): |
|
|
|
def get(self, 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" |
|
|
|
locale.setlocale(locale.LC_ALL, lang) |
|
|
|
|
|
|
|
eventos = Evento.objects.exclude( |
|
|
|
|
|
|
|
eventos = ( |
|
|
|
Evento.objects.exclude( |
|
|
|
status__in=(Evento.STATUS_CANCELADO, Evento.STATUS_SOBRESTADO) |
|
|
|
).prefetch_related("equipe_set") |
|
|
|
) |
|
|
|
.prefetch_related("equipe_set") |
|
|
|
) |
|
|
|
|
|
|
|
num_cols = 12 |
|
|
|
|
|
|
|
|
|
|
|
if mes_pesquisa > 0: |
|
|
|
semanas = [ |
|
|
|
[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) |
|
|
|
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) |
|
|
|
eventos = eventos.filter( |
|
|
|
data_inicio__gte=dias[0], data_inicio__lte=dias[-1] |
|
|
|
) |
|
|
|
else: |
|
|
|
|
|
|
|
eventos = eventos.filter( |
|
|
|
data_inicio__gte=semanas[0][0], |
|
|
|
data_inicio__lte=semanas[-1][-1], |
|
|
|
) |
|
|
|
else: |
|
|
|
|
|
|
|
eventos = eventos.filter(data_inicio__year=ano_pesquisa) |
|
|
|
|
|
|
|
|
|
|
|
dados = [] |
|
|
|
for evento in eventos: |
|
|
|
for p in evento.equipe_set.all(): |
|
|
|
for equipe in evento.equipe_set.all(): |
|
|
|
registro = None |
|
|
|
|
|
|
|
for r in dados: |
|
|
|
if r[0] == p.membro.pk: |
|
|
|
if r[0] == equipe.membro.pk: |
|
|
|
registro = r |
|
|
|
break |
|
|
|
|
|
|
|
if not registro: |
|
|
|
if semana_pesquisa > 0: |
|
|
|
registro = [ |
|
|
|
p.membro.pk, |
|
|
|
p.membro.get_apelido(), |
|
|
|
equipe.membro.pk, |
|
|
|
equipe.membro.get_apelido(), |
|
|
|
OrderedDict([(dia, []) for dia in dias]), |
|
|
|
] |
|
|
|
else: |
|
|
|
registro = [ |
|
|
|
p.membro.pk, |
|
|
|
p.membro.get_apelido(), |
|
|
|
equipe.membro.pk, |
|
|
|
equipe.membro.get_apelido(), |
|
|
|
[{"dias": 0, "eventos": 0} for __ in range(num_cols)], |
|
|
|
] |
|
|
|
dados.append(registro) |
|
|
|
|
|
|
|
|
|
|
|
if mes_pesquisa > 0: |
|
|
|
if semana_pesquisa > 0: |
|
|
|
for dia in dias: |
|
|
|
if evento.data_inicio <= dia <= evento.data_termino: |
|
|
|
registro[2][dia].append(evento) |
|
|
|
else: |
|
|
|
for idx, [inicio, fim] in enumerate(semanas): |
|
|
|
for idx, (inicio, fim) in enumerate(semanas): |
|
|
|
|
|
|
|
if inicio <= evento.data_inicio <= fim: |
|
|
|
registro[2][idx]["dias"] += ( |
|
|
|
min(fim, evento.data_termino) |
|
|
|
- evento.data_inicio |
|
|
|
min(fim, evento.data_termino) - evento.data_inicio |
|
|
|
).days + 1 |
|
|
|
registro[2][idx]["eventos"] += 1 |
|
|
|
|
|
|
|
elif inicio <= evento.data_termino <= fim: |
|
|
|
registro[2][idx]["dias"] += ( |
|
|
|
min(fim, evento.data_termino) |
|
|
|
- evento.data_inicio |
|
|
|
min(fim, evento.data_termino) - evento.data_inicio |
|
|
|
).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 |
|
|
|
[registro[1]] + list(registro[2].values()) |
|
|
|
for registro in dados |
|
|
|
] |
|
|
|
else: |
|
|
|
|
|
|
|
for r in dados: |
|
|
|
|
|
|
|
r[2].append( |
|
|
|
reduce( |
|
|
|
lambda x, y: { |
|
|
@ -413,14 +467,13 @@ def alocacao_equipe(request): |
|
|
|
r[2], |
|
|
|
) |
|
|
|
) |
|
|
|
linhas.append( |
|
|
|
[r[1]] |
|
|
|
+ [ |
|
|
|
( |
|
|
|
row = [r[1]] |
|
|
|
for d in r[2]: |
|
|
|
if d["dias"] > 0 or d["eventos"] > 0: |
|
|
|
|
|
|
|
texto = ( |
|
|
|
_( |
|
|
|
ngettext( |
|
|
|
"%(dias)s dia", "%(dias)s dias", d["dias"] |
|
|
|
) |
|
|
|
ngettext("%(dias)s dia", "%(dias)s dias", d["dias"]) |
|
|
|
+ " em " |
|
|
|
+ ngettext( |
|
|
|
"%(eventos)s evento", |
|
|
@ -429,34 +482,44 @@ def alocacao_equipe(request): |
|
|
|
) |
|
|
|
) |
|
|
|
% 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 = { |
|
|
|
"anos": Evento.objects.exclude(data_inicio=None) |
|
|
|
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), |
|
|
|
.values_list("data_inicio__year", flat=True) |
|
|
|
), |
|
|
|
"ano_pesquisa": ano_pesquisa, |
|
|
|
"linhas": linhas, |
|
|
|
"meses": meses, |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
if mes_pesquisa > 0: |
|
|
|
context["mes_pesquisa"] = mes_pesquisa |
|
|
|
|
|
|
|
semanas = [ |
|
|
|
[s[0], s[-1]] |
|
|
|
for s in calendar.Calendar().monthdatescalendar(ano_pesquisa, mes_pesquisa) |
|
|
|
] |
|
|
|
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: |
|
|
|
cabecalho = [_("Servidor")] + dias |
|
|
|
|
|
|
|
context["semana_pesquisa"] = semana_pesquisa |
|
|
|
context["eventos"] = eventos |
|
|
|
cabecalho = [_("Servidor")] + list(dias) |
|
|
|
else: |
|
|
|
|
|
|
|
cabecalho = ( |
|
|
|
[_("Servidor")] |
|
|
|
+ [ |
|
|
@ -466,31 +529,38 @@ def alocacao_equipe(request): |
|
|
|
+ ["total"] |
|
|
|
) |
|
|
|
else: |
|
|
|
|
|
|
|
cabecalho = [_("Servidor")] + meses + ["total"] |
|
|
|
|
|
|
|
context["cabecalho"] = cabecalho |
|
|
|
context["formato"] = formato |
|
|
|
|
|
|
|
if formato == "pdf": |
|
|
|
context["title"] = _("Alocação de equipe") |
|
|
|
return context |
|
|
|
|
|
|
|
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["title"] = self.title |
|
|
|
ano_pesquisa = context.get("ano_pesquisa", timezone.localdate().year) |
|
|
|
return WeasyTemplateResponse( |
|
|
|
filename=f"alocacao_equipe_{ano_pesquisa}.pdf", |
|
|
|
request=request, |
|
|
|
template="eventos/alocacao_equipe_pdf.html", |
|
|
|
request=self.request, |
|
|
|
template=self.template_name_pdf, |
|
|
|
context=context, |
|
|
|
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["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.writerow(cabecalho) |
|
|
|
writer.writerows(linhas) |
|
|
|
writer.writerow(context["cabecalho"]) |
|
|
|
writer.writerows(context["linhas"]) |
|
|
|
return response |
|
|
|
|
|
|
|
return render(request, "eventos/alocacao_equipe.html", context) |
|
|
|
return super().render_to_response(context, **response_kwargs) |
|
|
|
|
|
|
|
|
|
|
|
class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportListView): |
|
|
@ -499,12 +569,12 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList |
|
|
|
template_name = "eventos/eventos_por_uf.html" |
|
|
|
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): |
|
|
@ -523,7 +593,7 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList |
|
|
|
} |
|
|
|
|
|
|
|
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): |
|
|
@ -533,7 +603,7 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList |
|
|
|
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() |
|
|
@ -589,7 +659,7 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList |
|
|
|
) |
|
|
|
return context |
|
|
|
|
|
|
|
# Renomeia colunas, substitui códigos por nomes, monta as pivot tables, etc. |
|
|
|
|
|
|
|
df.rename( |
|
|
|
columns={ |
|
|
|
"municipio__orgao__evento__tipo_evento__categoria": "categoria", |
|
|
@ -710,56 +780,70 @@ class EventosPorUfReportView(LoginRequiredMixin, UserPassesTestMixin, ReportList |
|
|
|
return response |
|
|
|
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 |
|
|
|
@staff_member_required |
|
|
|
def solicitacoes_por_periodo(request): |
|
|
|
formato = request.GET.get("fmt", "html") |
|
|
|
initials = { |
|
|
|
def get_list_labels(self): |
|
|
|
|
|
|
|
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_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(), |
|
|
|
"virtual": [m[0] for m in SolicitacoesPorPeriodoForm.MODO_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) |
|
|
|
else: |
|
|
|
form = SolicitacoesPorPeriodoForm(initial=initials) |
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
|
|
|
|
|
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(): |
|
|
|
return render( |
|
|
|
request, |
|
|
|
"eventos/solicitacoes_por_periodo.html", |
|
|
|
context={"form": form}, |
|
|
|
) |
|
|
|
return context |
|
|
|
|
|
|
|
data_inicio = form.cleaned_data.get("data_inicio") |
|
|
|
data_fim = form.cleaned_data.get("data_fim") |
|
|
|
tipos_evento = form.cleaned_data.get( |
|
|
|
"tipos_evento", initials["tipos_evento"] |
|
|
|
) |
|
|
|
virtual = form.cleaned_data.get("virtual", initials["virtual"]) |
|
|
|
status = form.cleaned_data.get("status", initials["status"]) |
|
|
|
initial = self.get_initial() |
|
|
|
tipos_evento = form.cleaned_data.get("tipos_evento", initial["tipos_evento"]) |
|
|
|
virtual = form.cleaned_data.get("virtual", initial["virtual"]) |
|
|
|
status = form.cleaned_data.get("status", initial["status"]) |
|
|
|
|
|
|
|
|
|
|
|
sq_equipe = ( |
|
|
|
Equipe.objects.order_by() |
|
|
|
.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") |
|
|
|
) |
|
|
|
sq_equipe.query.group_by = [] |
|
|
|
|
|
|
|
solicitacoes = Solicitacao.objects.order_by().filter( |
|
|
|
data_pedido__range=(data_inicio, data_fim), |
|
|
|
itemsolicitado__tipo_evento__in=tipos_evento, |
|
|
|
itemsolicitado__virtual__in=virtual, |
|
|
|
status__in=status, |
|
|
|
) |
|
|
|
|
|
|
|
legenda_oficinas = ( |
|
|
|
solicitacoes.order_by("itemsolicitado__tipo_evento__sigla") |
|
|
|
.values_list( |
|
|
@ -768,6 +852,7 @@ def solicitacoes_por_periodo(request): |
|
|
|
) |
|
|
|
.distinct() |
|
|
|
) |
|
|
|
|
|
|
|
solicitacoes = ( |
|
|
|
solicitacoes.order_by( |
|
|
|
"casa__municipio__uf__regiao", |
|
|
@ -779,21 +864,15 @@ def solicitacoes_por_periodo(request): |
|
|
|
qtde_solicitadas=Count("itemsolicitado__id"), |
|
|
|
qtde_atendidas=Count( |
|
|
|
"itemsolicitado__id", |
|
|
|
filter=Q( |
|
|
|
itemsolicitado__status=ItemSolicitado.STATUS_AUTORIZADO |
|
|
|
), |
|
|
|
filter=Q(itemsolicitado__status=ItemSolicitado.STATUS_AUTORIZADO) |
|
|
|
), |
|
|
|
qtde_rejeitadas=Count( |
|
|
|
"itemsolicitado__id", |
|
|
|
filter=Q( |
|
|
|
itemsolicitado__status=ItemSolicitado.STATUS_REJEITADO |
|
|
|
), |
|
|
|
filter=Q(itemsolicitado__status=ItemSolicitado.STATUS_REJEITADO) |
|
|
|
), |
|
|
|
participantes=Sum("itemsolicitado__evento__total_participantes"), |
|
|
|
custo_total=Subquery( |
|
|
|
sq_equipe.filter( |
|
|
|
evento__itemsolicitado__solicitacao=OuterRef("pk") |
|
|
|
)[:1] |
|
|
|
sq_equipe.filter(evento__itemsolicitado__solicitacao=OuterRef("pk"))[:1] |
|
|
|
), |
|
|
|
) |
|
|
|
.select_related( |
|
|
@ -804,6 +883,7 @@ def solicitacoes_por_periodo(request): |
|
|
|
) |
|
|
|
.prefetch_related("itemsolicitado_set") |
|
|
|
) |
|
|
|
|
|
|
|
sumario = solicitacoes.aggregate( |
|
|
|
Sum("qtde_solicitadas"), |
|
|
|
Sum("qtde_atendidas"), |
|
|
@ -811,6 +891,7 @@ def solicitacoes_por_periodo(request): |
|
|
|
Sum("participantes"), |
|
|
|
Sum("custo_total"), |
|
|
|
).values() |
|
|
|
|
|
|
|
resumo_uf = pd.DataFrame( |
|
|
|
solicitacoes.order_by( |
|
|
|
"casa__municipio__uf__regiao", |
|
|
@ -854,18 +935,15 @@ def solicitacoes_por_periodo(request): |
|
|
|
].sum() |
|
|
|
resumo_uf.replace([0], [None], inplace=True) |
|
|
|
resumo_regiao.replace([0], [None], inplace=True) |
|
|
|
|
|
|
|
resumo_tipo_evento = pd.DataFrame( |
|
|
|
ItemSolicitado.objects.filter(solicitacao__in=solicitacoes) |
|
|
|
.order_by("tipo_evento__sigla", "tipo_evento__nome") |
|
|
|
.values("tipo_evento__sigla", "tipo_evento__nome") |
|
|
|
.annotate( |
|
|
|
qtde_solicitadas=Count("id"), |
|
|
|
qtde_atendidas=Count( |
|
|
|
"id", filter=Q(status=ItemSolicitado.STATUS_AUTORIZADO) |
|
|
|
), |
|
|
|
qtde_rejeitadas=Count( |
|
|
|
"id", filter=Q(status=ItemSolicitado.STATUS_REJEITADO) |
|
|
|
), |
|
|
|
qtde_atendidas=Count("id", filter=Q(status=ItemSolicitado.STATUS_AUTORIZADO)), |
|
|
|
qtde_rejeitadas=Count("id", filter=Q(status=ItemSolicitado.STATUS_REJEITADO)), |
|
|
|
participantes=Sum("evento__total_participantes"), |
|
|
|
custo_total=Subquery( |
|
|
|
sq_equipe.filter(evento__itemsolicitado=OuterRef("pk"))[:1] |
|
|
@ -884,41 +962,39 @@ def solicitacoes_por_periodo(request): |
|
|
|
.sum() |
|
|
|
.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) |
|
|
|
# Imprimir |
|
|
|
context = { |
|
|
|
"form": form, |
|
|
|
|
|
|
|
context.update({ |
|
|
|
"data_inicio": data_inicio, |
|
|
|
"data_fim": data_fim, |
|
|
|
"status_choices": ItemSolicitado.STATUS_CHOICES, |
|
|
|
"legenda_oficinas": legenda_oficinas, |
|
|
|
"tipos_evento": tipos_evento, |
|
|
|
"virtual": [ |
|
|
|
m[1] |
|
|
|
for m in SolicitacoesPorPeriodoForm.MODO_CHOICES |
|
|
|
if m[0] in virtual |
|
|
|
], |
|
|
|
"virtual": [m[1] for m in SolicitacoesPorPeriodoForm.MODO_CHOICES if m[0] in virtual], |
|
|
|
"solicitacoes": solicitacoes, |
|
|
|
"sumario": sumario, |
|
|
|
"resumo_uf": resumo_uf, |
|
|
|
"resumo_regiao": resumo_regiao, |
|
|
|
"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": |
|
|
|
context["title"] = _("Solicitações por período") |
|
|
|
context["pdf"] = True |
|
|
|
return WeasyTemplateResponse( |
|
|
|
filename=f"solicitacoes_por_periodo-{data_inicio}-{data_fim}.pdf", |
|
|
|
request=request, |
|
|
|
template="eventos/solicitacoes_por_periodo_pdf.html", |
|
|
|
filename=f"solicitacoes_por_periodo-{context.get('data_inicio')}-{context.get('data_fim')}.pdf", |
|
|
|
request=self.request, |
|
|
|
template=self.template_name_pdf, |
|
|
|
context=context, |
|
|
|
content_type="application/pdf", |
|
|
|
) |
|
|
|
elif formato == "csv": |
|
|
|
response = HttpResponse(content_type="text/csv") |
|
|
|
data_inicio = context.get("data_inicio") |
|
|
|
data_fim = context.get("data_fim") |
|
|
|
response["Content-Disposition"] = ( |
|
|
|
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.writeheader() |
|
|
|
writer.writerows(solicitacoes.values(*fieldnames)) |
|
|
|
writer.writerows(context["solicitacoes"].values(*fieldnames)) |
|
|
|
return response |
|
|
|
return render( |
|
|
|
request, "eventos/solicitacoes_por_periodo.html", context=context |
|
|
|
) |
|
|
|
|
|
|
|
return super().render_to_response(context, **response_kwargs) |
|
|
|
|
|
|
|
class ApiEventoAbstract: |
|
|
|
queryset = ( |
|
|
|