Browse Source

Adiciona link de view nos dashboards

pull/195/head 4.0.16
Sesóstris Vieira 4 weeks ago
parent
commit
3e039d553f
  1. 42
      sigi/apps/casas/dashboards.py
  2. 11
      sigi/apps/casas/filters.py
  3. 5
      sigi/apps/convenios/dashboards.py
  4. 4
      sigi/apps/convenios/templates/convenios/dashboard/resumo_convenios.html
  5. 67
      sigi/apps/eventos/dashboards.py
  6. 106
      sigi/apps/servicos/dashboards.py

42
sigi/apps/casas/dashboards.py

@ -1,3 +1,4 @@
from django.urls import reverse
import django_filters import django_filters
from dashboard import Dashcard, getcolor from dashboard import Dashcard, getcolor
from django.db.models import Count from django.db.models import Count
@ -32,6 +33,16 @@ class CasasGerente(Dashcard):
.exclude(casas_que_gerencia=None) .exclude(casas_que_gerencia=None)
) )
def get_view_link(self, x_axis, y_axis, value):
try:
s = Servidor.objects.exclude(casas_que_gerencia=None).get(
nome_completo=x_axis
)
except:
return None
base_url = reverse("admin:casas_orgao_changelist")
return f"{base_url}?gerentes_interlegis__id__exact={s.id}"
class PerformanceCarteira(Dashcard): class PerformanceCarteira(Dashcard):
chart_type = Dashcard.TYPE_DOUGHNUT chart_type = Dashcard.TYPE_DOUGHNUT
@ -42,20 +53,9 @@ class PerformanceCarteira(Dashcard):
LABEL_USAM = _("Utilizam serviços") LABEL_USAM = _("Utilizam serviços")
LABEL_NAO_USAM = _("Não utilizam servços") LABEL_NAO_USAM = _("Não utilizam servços")
def apply_filters(self, request, queryset): def get_queryset(self, request):
filter = self.filterset(request.GET, queryset=queryset) queryset = super().get_queryset(request)
valid = filter.is_valid() return queryset.exclude(gerentes_interlegis=None)
if filter.form.cleaned_data["servidor"] is None:
if (
request.user.servidor
and request.user.servidor.casas_que_gerencia.exists()
):
return request.user.servidor.casas_que_gerencia.all()
return (
super()
.apply_filters(request, queryset)
.exclude(gerentes_interlegis=None)
)
def get_labels(self, request, queryset=None): def get_labels(self, request, queryset=None):
return [self.LABEL_USAM, self.LABEL_NAO_USAM] return [self.LABEL_USAM, self.LABEL_NAO_USAM]
@ -63,11 +63,23 @@ class PerformanceCarteira(Dashcard):
def get_datasets(self, request, queryset=None): def get_datasets(self, request, queryset=None):
if queryset is None: if queryset is None:
queryset = self.get_queryset(request) queryset = self.get_queryset(request)
base_url = reverse("admin:casas_orgao_changelist")
filter = self.get_filter(request.GET, queryset)
filter.is_valid()
servidor_id = filter.data.get("servidor")
if servidor_id:
servidor_qs = f"&gerentes_interlegis__id__exact={servidor_id}"
else:
servidor_qs = ""
return [ return [
{ {
"data": [ "data": [
queryset.exclude(servico=None).count(), queryset.exclude(servico=None).count(),
queryset.filter(servico=None).count(), queryset.filter(servico=None).count(),
] ],
"links": [
f"{base_url}?tipo__legislativo__exact=1&servico=CS{servidor_qs}",
f"{base_url}?tipo__legislativo__exact=1&servico=SS{servidor_qs}",
],
} }
] ]

11
sigi/apps/casas/filters.py

@ -2,7 +2,7 @@ from django.contrib import admin
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from sigi.apps.servidores.models import Servidor from sigi.apps.servidores.models import Servidor
from sigi.apps.convenios.models import Projeto from sigi.apps.convenios.models import Projeto
from sigi.apps.servicos.models import TipoServico from sigi.apps.servicos.models import TipoServico, Servico
class GerentesInterlegisFilter(admin.filters.RelatedFieldListFilter): class GerentesInterlegisFilter(admin.filters.RelatedFieldListFilter):
@ -36,7 +36,14 @@ class ServicoFilter(admin.SimpleListFilter):
) )
elif self.value() == "CR": elif self.value() == "CR":
queryset = queryset.exclude( queryset = queryset.exclude(
servico__tipo_servico__modo="H" id__in=(
Servico.objects.filter(
data_desativacao__isnull=True,
tipo_servico__modo="H",
)
.distinct("casa_legislativa_id")
.values_list("casa_legislativa_id", flat=True)
)
).exclude(servico=None) ).exclude(servico=None)
elif self.value() == "CH": elif self.value() == "CH":
queryset = queryset.filter( queryset = queryset.filter(

5
sigi/apps/convenios/dashboards.py

@ -1,3 +1,4 @@
from django.urls import reverse
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import django_filters import django_filters
@ -171,24 +172,28 @@ class ConvenioServico(Dashcard):
if queryset is None: if queryset is None:
queryset = self.get_queryset(request) queryset = self.get_queryset(request)
values = dict(queryset) values = dict(queryset)
base_url = reverse("admin:casas_orgao_changelist")
datasets = [ datasets = [
{ {
"label": _( "label": _(
"Casas sem convenio que utilizam algum serviço de hospedagem" "Casas sem convenio que utilizam algum serviço de hospedagem"
), ),
"data": [values["hospedagem"]], "data": [values["hospedagem"]],
"links": [f"{base_url}?convenio=SC&servico=CH"],
}, },
{ {
"label": _( "label": _(
"Casas sem convenio que utilizam somente serviço de registro" "Casas sem convenio que utilizam somente serviço de registro"
), ),
"data": [values["total"] - values["hospedagem"]], "data": [values["total"] - values["hospedagem"]],
"links": [f"{base_url}?convenio=SC&servico=CR"],
}, },
{ {
"label": _( "label": _(
"Casas sem convenio que utilizam algum serviço de registro e/ou hospedagem" "Casas sem convenio que utilizam algum serviço de registro e/ou hospedagem"
), ),
"data": [values["total"]], "data": [values["total"]],
"links": [f"{base_url}?convenio=SC&servico=CS"],
}, },
] ]
return datasets return datasets

4
sigi/apps/convenios/templates/convenios/dashboard/resumo_convenios.html

@ -13,7 +13,7 @@
<tr> <tr>
<th>{{ label }}</th> <th>{{ label }}</th>
{% for value in values %} {% for value in values %}
<td>{{ value }}</td> <td class="text-end">{{ value }}</td>
{% endfor %} {% endfor %}
</tr> </tr>
{% endfor %} {% endfor %}
@ -24,7 +24,7 @@
{% for label, value in datasets.totais %} {% for label, value in datasets.totais %}
<tr> <tr>
<th>{{ label }}</th> <th>{{ label }}</th>
<td>{{ value }}</td> <td class="text-end">{{ value }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

67
sigi/apps/eventos/dashboards.py

@ -1,5 +1,6 @@
import calendar import calendar
import datetime import datetime
from django.urls import reverse
import django_filters import django_filters
from dashboard import Dashcard, getcolor from dashboard import Dashcard, getcolor
from django.db.models import F, Count, Q from django.db.models import F, Count, Q
@ -32,9 +33,31 @@ class AnoFilterset(django_filters.FilterSet):
fields = ["ano"] fields = ["ano"]
class AnoCategoriaFilterset(django_filters.FilterSet):
ano = django_filters.ChoiceFilter(
field_name="data_inicio",
lookup_expr="year",
label=_("Ano"),
distinct=True,
choices=get_anos,
)
categoria = django_filters.ChoiceFilter(
field_name="tipo_evento__categoria",
lookup_expr="exact",
label=_("Categoria"),
distinct=True,
choices=TipoEvento.CATEGORIA_CHOICES,
)
class Meta:
model = Evento
fields = ["ano", "categoria"]
class EventosStatus(Dashcard): class EventosStatus(Dashcard):
chart_type = Dashcard.TYPE_DOUGHNUT chart_type = Dashcard.TYPE_DOUGHNUT
title = _("Eventos por status") title = _("Eventos por status")
filterset = AnoCategoriaFilterset
model = Evento model = Evento
label_field = ("status", F, lambda s: dict(Evento.STATUS_CHOICES)[s]) label_field = ("status", F, lambda s: dict(Evento.STATUS_CHOICES)[s])
datasets = [{"data_field": ("id", Count)}] datasets = [{"data_field": ("id", Count)}]
@ -42,6 +65,19 @@ class EventosStatus(Dashcard):
def get_dataset_color(self, dataset_label): def get_dataset_color(self, dataset_label):
return getcolor(dataset_label) return getcolor(dataset_label)
def get_view_link(self, x_axis, y_axis, value):
base_url = reverse("admin:eventos_evento_changelist")
querystrs = [f"status__exact={x_axis}"]
filter = self.get_filter(self.request.GET)
if filter.is_valid():
ano = filter.data.get("ano")
categoria = filter.data.get("categoria")
if ano:
querystrs.append(f"data_inicio__year={ano}")
if categoria:
querystrs.append(f"tipo_evento__categoria__exact={categoria}")
return base_url + "?" + "&".join(querystrs)
class EventosAno(Dashcard): class EventosAno(Dashcard):
chart_type = Dashcard.TYPE_LINE chart_type = Dashcard.TYPE_LINE
@ -98,10 +134,7 @@ class EventosAno(Dashcard):
def get_queryset(self, request): def get_queryset(self, request):
counts = self.get_counters(request) counts = self.get_counters(request)
return ( return (
super() super().get_queryset(request).values("categoria").annotate(**counts)
.get_queryset(request)
.values("categoria")
.annotate(**counts)
) )
def get_dataset_color(self, dataset_label): def get_dataset_color(self, dataset_label):
@ -116,6 +149,10 @@ class EventosAno(Dashcard):
{ {
"label": categorias[r["categoria"]], "label": categorias[r["categoria"]],
"data": [r[c] for c in counters], "data": [r[c] for c in counters],
"links": [
self.get_view_link(r["categoria"], c, r[c])
for c in counters
],
"backgroundColor": self.get_dataset_color(r["categoria"]), "backgroundColor": self.get_dataset_color(r["categoria"]),
} }
for r in queryset for r in queryset
@ -129,6 +166,15 @@ class EventosAno(Dashcard):
mes = self.get_meses(request)[-3] mes = self.get_meses(request)[-3]
return f"ano={mes.year}&mes={mes.month}" return f"ano={mes.year}&mes={mes.month}"
def get_view_link(self, x_axis, y_axis, value):
base_link = reverse("admin:eventos_evento_changelist")
return (
f"{base_link}?status__exact={Evento.STATUS_REALIZADO}"
f"&tipo_evento__categoria__exact={x_axis}"
f'&data_inicio__year={y_axis.split("_")[1]}'
f'&data_inicio__month={y_axis.split("_")[2]}'
)
class EventosCategoria(Dashcard): class EventosCategoria(Dashcard):
chart_type = Dashcard.TYPE_DOUGHNUT chart_type = Dashcard.TYPE_DOUGHNUT
@ -151,3 +197,16 @@ class EventosCategoria(Dashcard):
def get_dataset_color(self, dataset_label): def get_dataset_color(self, dataset_label):
return getcolor(dataset_label) return getcolor(dataset_label)
def get_view_link(self, x_axis, y_axis, value):
base_url = reverse("admin:eventos_evento_changelist")
q_ano = ""
filter = self.get_filter(self.request.GET)
if filter.is_valid():
ano = filter.data.get("ano")
if ano:
q_ano = f"data_inicio__year={ano}&"
return (
f"{base_url}?{q_ano}status__exact={Evento.STATUS_REALIZADO}"
f"&tipo_evento__categoria__exact={x_axis}"
)

106
sigi/apps/servicos/dashboards.py

@ -6,6 +6,7 @@ from random import choice, randint, seed
from django.db.models import Count, F, Q from django.db.models import Count, F, Q
from django.db.models.functions import TruncMonth from django.db.models.functions import TruncMonth
from django.http import QueryDict from django.http import QueryDict
from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.utils.text import slugify from django.utils.text import slugify
from django.utils.translation import gettext as _, to_locale, get_language from django.utils.translation import gettext as _, to_locale, get_language
@ -82,6 +83,18 @@ class Sazonalidade(Dashcard):
) )
return qs.filter(data_ativacao__year=ano) return qs.filter(data_ativacao__year=ano)
def get_view_link(self, x_axis, y_axis, value):
try:
tipo = TipoServico.objects.get(sigla=x_axis)
except TipoServico.DoesNotExist:
return None
mes, ano = y_axis.split("/")
base_url = reverse("admin:servicos_servico_changelist")
return (
f"{base_url}?tipo_servico__id__exact={tipo.pk}"
f"&data_ativacao__year={ano}&data_ativacao__month={mes}"
)
def get_prev_page(self, request=None, queryset=None): def get_prev_page(self, request=None, queryset=None):
anos = Servico.objects.dates("data_ativacao", "year").values_list( anos = Servico.objects.dates("data_ativacao", "year").values_list(
"data_ativacao__year", flat=True "data_ativacao__year", flat=True
@ -170,9 +183,13 @@ class ResumoSeit(Dashcard):
"total": s["total"], "total": s["total"],
mes_anterior: 0, mes_anterior: 0,
mes_atual: 0, mes_atual: 0,
"servico_id": s["servico_id"],
} }
for s in Servico.objects.filter(data_desativacao=None) for s in Servico.objects.filter(data_desativacao=None)
.values(servico=F("tipo_servico__nome")) .values(
servico=F("tipo_servico__nome"),
servico_id=F("tipo_servico__id"),
)
.annotate(total=Count("casa_legislativa", distinct=True)) .annotate(total=Count("casa_legislativa", distinct=True))
} }
for data in queryset: for data in queryset:
@ -186,10 +203,39 @@ class ResumoSeit(Dashcard):
labels[1]: data[mes_atual], labels[1]: data[mes_atual],
labels[2]: data[mes_anterior], labels[2]: data[mes_anterior],
}, },
"links": [
self.get_view_link(
"total", data["servico_id"], data["total"]
),
self.get_view_link(
mes_atual, data["servico_id"], data[mes_atual]
),
self.get_view_link(
mes_anterior, data["servico_id"], data[mes_anterior]
),
],
} }
for label, data in datasets.items() for label, data in datasets.items()
] ]
def get_view_link(self, x_axis, y_axis, value):
if value == 0:
return None
base_url = reverse("admin:servicos_servico_changelist")
qstrs = [
"data_desativacao__isnull=True",
f"tipo_servico__id__exact={y_axis}",
]
if not isinstance(x_axis, str):
qstrs.extend(
[
f"data_ativacao__year={x_axis.year}",
f"data_ativacao__month={x_axis.month}",
]
)
qstrs = "&".join(qstrs)
return f"{base_url}?{qstrs}"
def get_prev_page(self, request=None, queryset=None): def get_prev_page(self, request=None, queryset=None):
mes_atual, mes_anterior, mes_proximo = self.get_meses(request) mes_atual, mes_anterior, mes_proximo = self.get_meses(request)
params = QueryDict().copy() params = QueryDict().copy()
@ -211,12 +257,13 @@ class AtualizacaoServicos(Dashcard):
model = TipoServico model = TipoServico
intervalos = [ intervalos = [
("Na semana", 7), ("Na semana", 7, "updated"),
("No mês", 30), ("No mês", 30, "week"),
("No trimestre", 3 * 30), ("No trimestre", 90, "month"),
("No semestre", 6 * 30), ("No semestre", 182, "quarter"),
("No ano", 365), ("No ano", 365, "semester"),
("Mais de ano", None), ("Mais de ano", 0, "year"),
("Erro na verificação", None, "err"),
] ]
def get_queryset(self, request): def get_queryset(self, request):
@ -224,17 +271,21 @@ class AtualizacaoServicos(Dashcard):
hoje = timezone.localdate() hoje = timezone.localdate()
ate = hoje ate = hoje
for label, dias in self.intervalos: for label, dias, *__ in self.intervalos:
if dias is not None: if dias is None:
counts[slugify(label)] = Count(
"servico", ~Q(servico__erro_atualizacao="")
)
elif dias > 0:
de = hoje - datetime.timedelta(days=dias) de = hoje - datetime.timedelta(days=dias)
counts[slugify(label)] = Count( counts[slugify(label)] = Count(
"servico", Q(servico__data_ultimo_uso__range=(de, ate)) "servico", Q(servico__data_ultimo_uso__range=(de, ate))
) )
ate = de - datetime.timedelta(days=1) ate = de - datetime.timedelta(days=1)
else: else:
counts[slugify(label)] = Count( counts[slugify(label)] = Count(
"servico", Q(servico__data_ultimo_uso__lte=ate) "servico", Q(servico__data_ultimo_uso__lte=ate)
) )
return ( return (
super() super()
@ -259,10 +310,25 @@ class AtualizacaoServicos(Dashcard):
for label, *__ in self.intervalos for label, *__ in self.intervalos
}, },
"backgroundColor": getcolor(ts.sigla), "backgroundColor": getcolor(ts.sigla),
"links": [
self.get_view_link(
ts.id, atualizacao, getattr(ts, slugify(label))
)
for label, dias, atualizacao in self.intervalos
],
} }
for ts in queryset for ts in queryset
] ]
def get_view_link(self, x_axis, y_axis, value):
print(x_axis, y_axis, value)
base_url = reverse("admin:servicos_servico_changelist")
return (
f"{base_url}?data_desativacao__isnull=True"
f"&atualizacao={y_axis}"
f"&tipo_servico__id__exact={x_axis}"
)
class UsoServicos(Dashcard): class UsoServicos(Dashcard):
title = _("Uso dos serviços") title = _("Uso dos serviços")
@ -299,10 +365,22 @@ class UsoServicos(Dashcard):
{ {
"label": label, "label": label,
"data": {r.sigla: getattr(r, f"{key}_count") for r in queryset}, "data": {r.sigla: getattr(r, f"{key}_count") for r in queryset},
"links": [
self.get_view_link(r.id, key, getattr(r, f"{key}_count"))
for r in queryset
],
} }
for key, label in Servico.RESULTADO_CHOICES for key, label in Servico.RESULTADO_CHOICES
] ]
def get_view_link(self, x_axis, y_axis, value):
base_url = reverse("admin:servicos_servico_changelist")
return (
f"{base_url}?data_desativacao__isnull=True"
f"&resultado_verificacao__exact={y_axis}"
f"&tipo_servico__id__exact={x_axis}"
)
class ServicosAno(Dashcard): class ServicosAno(Dashcard):
title = _("Serviços hospedados por ano") title = _("Serviços hospedados por ano")

Loading…
Cancel
Save