mirror of https://github.com/interlegis/sigi.git
5 changed files with 843 additions and 0 deletions
@ -0,0 +1,73 @@ |
|||
import django_filters |
|||
from dashboard import Dashcard, getcolor |
|||
from django.db.models import Count |
|||
from django.utils.translation import gettext as _ |
|||
from sigi.apps.casas.models import Orgao |
|||
from sigi.apps.servidores.models import Servidor |
|||
|
|||
|
|||
class GerenteFilter(django_filters.FilterSet): |
|||
servidor = django_filters.ModelChoiceFilter( |
|||
field_name="gerentes_interlegis", |
|||
label="Gerente", |
|||
queryset=Servidor.objects.exclude(casas_que_gerencia=None), |
|||
) |
|||
|
|||
class Meta: |
|||
model = Orgao |
|||
fields = ["servidor"] |
|||
|
|||
|
|||
class CasasGerente(Dashcard): |
|||
chart_type = Dashcard.TYPE_DOUGHNUT |
|||
title = _("Distribuição de Casas por Gerente") |
|||
model = Servidor |
|||
label_field = "nome_completo" |
|||
datasets = [{"data_field": ("casas_que_gerencia", Count)}] |
|||
|
|||
def apply_filters(self, request, queryset): |
|||
return ( |
|||
super() |
|||
.apply_filters(request, queryset) |
|||
.exclude(casas_que_gerencia=None) |
|||
) |
|||
|
|||
|
|||
class PerformanceCarteira(Dashcard): |
|||
chart_type = Dashcard.TYPE_DOUGHNUT |
|||
title = _("Performance da gerência de carteiras") |
|||
model = Orgao |
|||
filterset = GerenteFilter |
|||
|
|||
LABEL_USAM = _("Utilizam serviços") |
|||
LABEL_NAO_USAM = _("Não utilizam servços") |
|||
|
|||
def apply_filters(self, request, queryset): |
|||
filter = self.filterset(request.GET, queryset=queryset) |
|||
valid = filter.is_valid() |
|||
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): |
|||
return [self.LABEL_USAM, self.LABEL_NAO_USAM] |
|||
|
|||
def get_datasets(self, request, queryset=None): |
|||
if queryset is None: |
|||
queryset = self.get_queryset(request) |
|||
return [ |
|||
{ |
|||
"data": [ |
|||
queryset.exclude(servico=None).count(), |
|||
queryset.filter(servico=None).count(), |
|||
] |
|||
} |
|||
] |
@ -0,0 +1,194 @@ |
|||
import numpy as np |
|||
import pandas as pd |
|||
import django_filters |
|||
from dashboard import Dashcard |
|||
from django.db.models import Q, Count |
|||
from django.utils import timezone |
|||
from django.utils.translation import gettext as _ |
|||
from sigi.apps.casas.models import TipoOrgao, Orgao |
|||
from sigi.apps.convenios.models import Convenio, Projeto |
|||
|
|||
|
|||
def get_tipos(): |
|||
tipos = list( |
|||
TipoOrgao.objects.filter(sigla__in=["CM", "AL"]).values_list( |
|||
"sigla", "nome" |
|||
) |
|||
) |
|||
tipos.extend( |
|||
[ |
|||
("_legislativo", _("Todo o legislativo")), |
|||
("_outros", _("Demais órgãos")), |
|||
] |
|||
) |
|||
return tipos |
|||
|
|||
|
|||
class ResumoConveniosFilter(django_filters.FilterSet): |
|||
tipo = django_filters.ChoiceFilter( |
|||
field_name="casa_legislativa__tipo__sigla", |
|||
label=_("Tipo"), |
|||
choices=get_tipos, |
|||
method="filter_tipo", |
|||
empty_label=None, |
|||
initial="CM", |
|||
) |
|||
|
|||
class Meta: |
|||
model = Convenio |
|||
fields = ["tipo"] |
|||
|
|||
def filter_tipo(self, queryset, name, value): |
|||
if value == "_legislativo": |
|||
tipos = TipoOrgao.objects.filter(legislativo=True).values_list( |
|||
"sigla", flat=True |
|||
) |
|||
elif value == "_outros": |
|||
tipos = TipoOrgao.objects.filter(legislativo=False).values_list( |
|||
"sigla", flat=True |
|||
) |
|||
else: |
|||
tipos = [value] |
|||
return queryset.filter(**{f"{name}__in": tipos}) |
|||
|
|||
|
|||
class ResumoConvenios(Dashcard): |
|||
chart_type = Dashcard.TYPE_TABLE |
|||
title = _("Resumo de informações") |
|||
model = Convenio |
|||
filterset = ResumoConveniosFilter |
|||
template_table = "convenios/dashboard/resumo_convenios.html" |
|||
|
|||
def apply_filters(self, request, queryset): |
|||
if "tipo" not in request.GET: |
|||
request.GET = request.GET.copy() |
|||
request.GET["tipo"] = "CM" |
|||
return super().apply_filters(request, queryset) |
|||
|
|||
def get_labels(self, request, queryset=None): |
|||
return [] |
|||
|
|||
def get_datasets(self, request, queryset=None): |
|||
if queryset is None: |
|||
queryset = self.get_queryset(request) |
|||
filter = self.get_filter(request.GET, queryset) |
|||
if filter and filter.is_valid(): |
|||
label_tipo = dict(get_tipos())[filter.form.cleaned_data["tipo"]] |
|||
else: |
|||
label_tipo = dict(get_tipos())["CM"] |
|||
convenios = queryset |
|||
camaras = filter.filter_tipo( |
|||
Orgao.objects.all(), |
|||
"tipo__sigla", |
|||
filter.form.cleaned_data["tipo"], |
|||
) |
|||
convenios_vigentes = convenios.exclude( |
|||
data_retorno_assinatura=None |
|||
).filter( |
|||
Q(data_termino_vigencia__gte=timezone.localdate()) |
|||
| Q(data_termino_vigencia=None) |
|||
) |
|||
convenios_andando = convenios.filter(data_retorno_assinatura=None) |
|||
convenios_vencidos = convenios.exclude( |
|||
Q(data_retorno_assinatura=None) | Q(data_termino_vigencia=None) |
|||
).filter(data_termino_vigencia__lt=timezone.localdate()) |
|||
dataset = { |
|||
_(f"{label_tipo} com convênios vigentes"): { |
|||
k: v |
|||
for k, v in convenios_vigentes.values_list( |
|||
"projeto__sigla" |
|||
).annotate(Count("casa_legislativa_id", distinct=True)) |
|||
}, |
|||
_(f"{label_tipo} com convênios em andamento"): { |
|||
k: v |
|||
for k, v in convenios_andando.values_list( |
|||
"projeto__sigla" |
|||
).annotate(Count("casa_legislativa_id", distinct=True)) |
|||
}, |
|||
_(f"{label_tipo} com convênios vencidos"): { |
|||
k: v |
|||
for k, v in convenios_vencidos.values_list( |
|||
"projeto__sigla" |
|||
).annotate(Count("casa_legislativa_id", distinct=True)) |
|||
}, |
|||
} |
|||
|
|||
ds_totais = ( |
|||
(_(f"Total de {label_tipo} do país"), camaras.count()), |
|||
( |
|||
_(f"Total de {label_tipo} com convênio vigente"), |
|||
convenios_vigentes.order_by("casa_legislativa_id") |
|||
.distinct("casa_legislativa_id") |
|||
.count(), |
|||
), |
|||
( |
|||
_(f"Total de {label_tipo} com convênio em andamento"), |
|||
convenios_andando.order_by("casa_legislativa_id") |
|||
.distinct("casa_legislativa_id") |
|||
.count(), |
|||
), |
|||
( |
|||
_(f"Total de {label_tipo} com convênio vencido"), |
|||
convenios_vencidos.order_by("casa_legislativa_id") |
|||
.distinct("casa_legislativa_id") |
|||
.count(), |
|||
), |
|||
) |
|||
|
|||
df = ( |
|||
pd.DataFrame.from_dict(dataset, orient="index") |
|||
.replace(np.nan, 0) |
|||
.convert_dtypes() |
|||
) |
|||
|
|||
return {"data_frame": df, "totais": ds_totais} |
|||
|
|||
|
|||
class ConvenioServico(Dashcard): |
|||
chart_type = Dashcard.TYPE_TABLE |
|||
title = _("Convenios e serviços") |
|||
model = Orgao |
|||
label_name = _("Situação") |
|||
|
|||
def get_queryset(self, request): |
|||
return ( |
|||
Orgao.objects.exclude(servico=None) |
|||
.filter(servico__data_desativacao=None, convenio=None) |
|||
.aggregate( |
|||
total=Count("id", distinct=True), |
|||
hospedagem=Count( |
|||
"id", |
|||
filter=Q(servico__tipo_servico__modo="H"), |
|||
distinct=True, |
|||
), |
|||
) |
|||
) |
|||
|
|||
def get_labels(self, request, queryset=None): |
|||
return [_("Total")] |
|||
|
|||
def get_datasets(self, request, queryset=None): |
|||
if queryset is None: |
|||
queryset = self.get_queryset(request) |
|||
values = dict(queryset) |
|||
datasets = [ |
|||
{ |
|||
"label": _( |
|||
"Casas sem convenio que utilizam algum serviço de hospedagem" |
|||
), |
|||
"data": [values["hospedagem"]], |
|||
}, |
|||
{ |
|||
"label": _( |
|||
"Casas sem convenio que utilizam somente serviço de registro" |
|||
), |
|||
"data": [values["total"] - values["hospedagem"]], |
|||
}, |
|||
{ |
|||
"label": _( |
|||
"Casas sem convenio que utilizam algum serviço de registro e/ou hospedagem" |
|||
), |
|||
"data": [values["total"]], |
|||
}, |
|||
] |
|||
return datasets |
@ -0,0 +1,30 @@ |
|||
{% load i18n %} |
|||
<table class="table table-hover table-sm"> |
|||
<thead> |
|||
<tr> |
|||
<th> </th> |
|||
{% for item in datasets.data_frame.columns %} |
|||
<th>{{ item }}</th> |
|||
{% endfor %} |
|||
</tr> |
|||
</thead> |
|||
<tbody class="table-group-divider"> |
|||
{% for label, values in datasets.data_frame.iterrows %} |
|||
<tr> |
|||
<th>{{ label }}</th> |
|||
{% for value in values %} |
|||
<td>{{ value }}</td> |
|||
{% endfor %} |
|||
</tr> |
|||
{% endfor %} |
|||
</tbody> |
|||
</table> |
|||
|
|||
<table class="table table-hover table-sm"> |
|||
{% for label, value in datasets.totais %} |
|||
<tr> |
|||
<th>{{ label }}</th> |
|||
<td>{{ value }}</td> |
|||
</tr> |
|||
{% endfor %} |
|||
</table> |
@ -0,0 +1,153 @@ |
|||
import calendar |
|||
import datetime |
|||
import django_filters |
|||
from dashboard import Dashcard, getcolor |
|||
from django.db.models import F, Count, Q |
|||
from django.utils import timezone |
|||
from django.utils.translation import gettext as _ |
|||
from sigi.apps.eventos.models import Evento, TipoEvento |
|||
|
|||
|
|||
def get_anos(): |
|||
return [ |
|||
(str(a), str(a)) |
|||
for a in Evento.objects.filter(status=Evento.STATUS_REALIZADO) |
|||
.order_by("data_inicio__year") |
|||
.values_list("data_inicio__year", flat=True) |
|||
.distinct("data_inicio__year") |
|||
] |
|||
|
|||
|
|||
class AnoFilterset(django_filters.FilterSet): |
|||
ano = django_filters.ChoiceFilter( |
|||
field_name="data_inicio", |
|||
lookup_expr="year", |
|||
label=_("Ano"), |
|||
distinct=True, |
|||
choices=get_anos, |
|||
) |
|||
|
|||
class Meta: |
|||
model = Evento |
|||
fields = ["ano"] |
|||
|
|||
|
|||
class EventosStatus(Dashcard): |
|||
chart_type = Dashcard.TYPE_DOUGHNUT |
|||
title = _("Eventos por status") |
|||
model = Evento |
|||
label_field = ("status", F, lambda s: dict(Evento.STATUS_CHOICES)[s]) |
|||
datasets = [{"data_field": ("id", Count)}] |
|||
|
|||
def get_dataset_color(self, dataset_label): |
|||
return getcolor(dataset_label) |
|||
|
|||
|
|||
class EventosAno(Dashcard): |
|||
chart_type = Dashcard.TYPE_LINE |
|||
title = _("Eventos nos últimos 12 meses") |
|||
model = TipoEvento |
|||
|
|||
def get_dataset_color(self, dataset_label): |
|||
print(f"EventosAno: {dataset_label}, {getcolor(dataset_label)}") |
|||
return getcolor(dataset_label) |
|||
|
|||
def get_meses(self, request=None): |
|||
if request is None: |
|||
mes = timezone.localdate().month |
|||
ano = timezone.localdate().year |
|||
else: |
|||
mes = int(request.GET.get("mes", timezone.localdate().month)) |
|||
ano = int(request.GET.get("ano", timezone.localdate().year)) |
|||
|
|||
mes_ano = datetime.date( |
|||
year=ano, month=mes, day=1 |
|||
) + datetime.timedelta(days=calendar.monthrange(ano, mes)[1]) |
|||
|
|||
meses = [] |
|||
|
|||
for i in range(13): |
|||
meses.append(mes_ano) |
|||
mes_ano = (mes_ano - datetime.timedelta(days=1)).replace(day=1) |
|||
meses.reverse() |
|||
|
|||
return meses |
|||
|
|||
def get_labels(self, request, queryset=None): |
|||
return [f"{m:%m/%Y}" for m in self.get_meses(request)[:-1]] |
|||
|
|||
def get_counters(self, request): |
|||
counts = {} |
|||
for mes in self.get_meses(request)[:-1]: |
|||
counts[f"count_{mes:%Y_%m}"] = Count( |
|||
"evento", |
|||
Q( |
|||
evento__data_inicio__year=mes.year, |
|||
evento__data_inicio__month=mes.month, |
|||
), |
|||
) |
|||
return counts |
|||
|
|||
def apply_filters(self, request, queryset): |
|||
return ( |
|||
super() |
|||
.apply_filters(request, queryset) |
|||
.filter(evento__status=Evento.STATUS_REALIZADO) |
|||
) |
|||
|
|||
def get_queryset(self, request): |
|||
counts = self.get_counters(request) |
|||
return ( |
|||
super() |
|||
.get_queryset(request) |
|||
.values("categoria") |
|||
.annotate(**counts) |
|||
) |
|||
|
|||
def get_dataset_color(self, dataset_label): |
|||
return getcolor(dataset_label) |
|||
|
|||
def get_datasets(self, request, queryset=None): |
|||
if queryset is None: |
|||
queryset = self.get_queryset(request) |
|||
categorias = dict(TipoEvento.CATEGORIA_CHOICES) |
|||
counters = self.get_counters(request).keys() |
|||
return [ |
|||
{ |
|||
"label": categorias[r["categoria"]], |
|||
"data": [r[c] for c in counters], |
|||
"backgroundColor": self.get_dataset_color(r["categoria"]), |
|||
} |
|||
for r in queryset |
|||
] |
|||
|
|||
def get_next_page(self, request=None, queryset=None): |
|||
mes = self.get_meses(request)[-1] |
|||
return f"ano={mes.year}&mes={mes.month}" |
|||
|
|||
def get_prev_page(self, request=None, queryset=None): |
|||
mes = self.get_meses(request)[-3] |
|||
return f"ano={mes.year}&mes={mes.month}" |
|||
|
|||
|
|||
class EventosCategoria(Dashcard): |
|||
chart_type = Dashcard.TYPE_DOUGHNUT |
|||
title = _("Eventos por categoria") |
|||
filterset = AnoFilterset |
|||
model = Evento |
|||
label_field = ( |
|||
"tipo_evento__categoria", |
|||
F, |
|||
lambda x: dict(TipoEvento.CATEGORIA_CHOICES)[x], |
|||
) |
|||
datasets = [{"data_field": ("id", Count)}] |
|||
|
|||
def apply_filters(self, request, queryset): |
|||
return ( |
|||
super() |
|||
.apply_filters(request, queryset) |
|||
.filter(status=Evento.STATUS_REALIZADO) |
|||
) |
|||
|
|||
def get_dataset_color(self, dataset_label): |
|||
return getcolor(dataset_label) |
@ -0,0 +1,393 @@ |
|||
import calendar |
|||
import datetime |
|||
import locale |
|||
from dashboard import Dashcard, getcolor |
|||
from random import randint, seed |
|||
from django.db.models import Count, F, Q |
|||
from django.db.models.functions import TruncMonth |
|||
from django.http import QueryDict |
|||
from django.utils import timezone |
|||
from django.utils.text import slugify |
|||
from django.utils.translation import gettext as _, to_locale, get_language |
|||
import django_filters |
|||
from sigi.apps.servicos.models import Servico, TipoServico |
|||
from sigi.apps.contatos.models import UnidadeFederativa |
|||
|
|||
|
|||
class UsoServicosFilter(django_filters.FilterSet): |
|||
uf = django_filters.ModelChoiceFilter( |
|||
field_name="servico__casa_legislativa__municipio__uf", |
|||
label=_("UF"), |
|||
queryset=UnidadeFederativa.objects.all(), |
|||
) |
|||
|
|||
class Meta: |
|||
model = TipoServico |
|||
fields = ["uf"] |
|||
|
|||
|
|||
class AnoServicoFilter(django_filters.FilterSet): |
|||
ano = django_filters.ModelChoiceFilter( |
|||
field_name="data_ativacao__year", |
|||
label=_("Ano"), |
|||
queryset=( |
|||
Servico.objects.filter(hospedagem_interlegis=True) |
|||
.order_by("data_ativacao__year") |
|||
.values_list("data_ativacao__year", flat=True) |
|||
.distinct("data_ativacao__year") |
|||
), |
|||
) |
|||
|
|||
class Meta: |
|||
model = Servico |
|||
fields = ["ano"] |
|||
|
|||
|
|||
class Sazonalidade(Dashcard): |
|||
title = _("Sazonalidade da hospedagem de serviços") |
|||
chart_type = Dashcard.TYPE_LINE |
|||
model = Servico |
|||
label_field = ("data_ativacao", TruncMonth, lambda d: d.strftime("%m/%Y")) |
|||
datasets = [ |
|||
{ |
|||
"label_field": "tipo_servico__sigla", |
|||
"data_field": ("*", Count), |
|||
} |
|||
] |
|||
|
|||
def get_dataset_color(self, dataset_label): |
|||
return getcolor(dataset_label) |
|||
|
|||
def get_queryset(self, request): |
|||
qs = ( |
|||
super() |
|||
.get_queryset(request) |
|||
.filter(data_desativacao=None) |
|||
.order_by("tipo_servico__sigla", "data_ativacao") |
|||
) |
|||
ano = request.GET.get("ano", None) |
|||
if ano is None: |
|||
ano = ( |
|||
qs.dates("data_ativacao", "year") |
|||
.values_list("data_ativacao__year", flat=True) |
|||
.last() |
|||
) |
|||
return qs.filter(data_ativacao__year=ano) |
|||
|
|||
def get_prev_page(self, request=None, queryset=None): |
|||
anos = Servico.objects.dates("data_ativacao", "year").values_list( |
|||
"data_ativacao__year", flat=True |
|||
) |
|||
if request is None: |
|||
params = QueryDict().copy() |
|||
params["ano"] = anos.last() - 1 |
|||
else: |
|||
params = request.GET.copy() |
|||
params["ano"] = int(request.GET.get("ano", anos.last())) - 1 |
|||
if params["ano"] not in anos: |
|||
return None |
|||
return params.urlencode() |
|||
|
|||
def get_next_page(self, request=None, queryset=None): |
|||
if request is None: |
|||
return None |
|||
anos = Servico.objects.dates("data_ativacao", "year").values_list( |
|||
"data_ativacao__year", flat=True |
|||
) |
|||
params = request.GET.copy() |
|||
params["ano"] = int(request.GET.get("ano", anos.last())) + 1 |
|||
if params["ano"] not in anos: |
|||
return None |
|||
return params.urlencode() |
|||
|
|||
|
|||
class ResumoSeit(Dashcard): |
|||
title = _("Serviços hospedados no Interlegis") |
|||
chart_type = Dashcard.TYPE_TABLE |
|||
label_name = _("Serviço") |
|||
model = Servico |
|||
|
|||
def get_meses(self, request=None): |
|||
if request is None: |
|||
mes = datetime.date.today().month |
|||
ano = datetime.date.today().year |
|||
else: |
|||
mes = int(request.GET.get("mes", datetime.date.today().month)) |
|||
ano = int(request.GET.get("ano", datetime.date.today().year)) |
|||
mes_atual = datetime.date(year=ano, month=mes, day=1) |
|||
mes_anterior = (mes_atual - datetime.timedelta(days=1)).replace(day=1) |
|||
mes_proximo = mes_atual + datetime.timedelta( |
|||
days=calendar.monthrange(mes_atual.year, mes_atual.month)[1] |
|||
) |
|||
|
|||
return mes_atual, mes_anterior, mes_proximo |
|||
|
|||
def get_queryset(self, request): |
|||
mes_atual, mes_anterior, mes_proximo = self.get_meses(request) |
|||
return ( |
|||
super() |
|||
.get_queryset(request) |
|||
.filter( |
|||
( |
|||
Q(data_ativacao__year=mes_atual.year) |
|||
& Q(Q(data_ativacao__month=mes_atual.month)) |
|||
) |
|||
| ( |
|||
Q(data_ativacao__year=mes_anterior.year) |
|||
& Q(Q(data_ativacao__month=mes_anterior.month)) |
|||
) |
|||
) |
|||
.values( |
|||
servico=F("tipo_servico__nome"), |
|||
mes=TruncMonth("data_ativacao"), |
|||
) |
|||
.annotate(ativados=Count("casa_legislativa__id", distinct=True)) |
|||
) |
|||
|
|||
def get_labels(self, request, queryset=None): |
|||
mes_atual, mes_anterior, mes_proximo = self.get_meses(request) |
|||
return [ |
|||
_("Total de casas atendidas"), |
|||
_(f"Novas casas em {mes_anterior:%m/%Y}"), |
|||
_(f"Novas casas em {mes_atual:%m/%Y}"), |
|||
] |
|||
|
|||
def get_datasets(self, request, queryset=None): |
|||
mes_atual, mes_anterior, mes_proximo = self.get_meses(request) |
|||
if queryset is None: |
|||
queryset = self.get_queryset(request) |
|||
labels = self.get_labels(request, queryset) |
|||
datasets = { |
|||
s["servico"]: { |
|||
"total": s["total"], |
|||
mes_anterior: 0, |
|||
mes_atual: 0, |
|||
} |
|||
for s in Servico.objects.filter(data_desativacao=None) |
|||
.values(servico=F("tipo_servico__nome")) |
|||
.annotate(total=Count("casa_legislativa", distinct=True)) |
|||
} |
|||
for data in queryset: |
|||
datasets[data["servico"]][data["mes"]] = data["ativados"] |
|||
|
|||
return [ |
|||
{ |
|||
"label": label, |
|||
"data": { |
|||
labels[0]: data["total"], |
|||
labels[1]: data[mes_atual], |
|||
labels[2]: data[mes_anterior], |
|||
}, |
|||
} |
|||
for label, data in datasets.items() |
|||
] |
|||
|
|||
def get_prev_page(self, request=None, queryset=None): |
|||
mes_atual, mes_anterior, mes_proximo = self.get_meses(request) |
|||
params = QueryDict().copy() |
|||
params["ano"] = mes_anterior.year |
|||
params["mes"] = mes_anterior.month |
|||
return params.urlencode() |
|||
|
|||
def get_next_page(self, request=None, queryset=None): |
|||
mes_atual, mes_anterior, mes_proximo = self.get_meses(request) |
|||
params = QueryDict().copy() |
|||
params["ano"] = mes_proximo.year |
|||
params["mes"] = mes_proximo.month |
|||
return params.urlencode() |
|||
|
|||
|
|||
class AtualizacaoServicos(Dashcard): |
|||
title = _("Frequência de atualização") |
|||
chart_type = Dashcard.TYPE_BAR |
|||
model = TipoServico |
|||
|
|||
intervalos = [ |
|||
("Na semana", 7), |
|||
("No mês", 30), |
|||
("No trimestre", 3 * 30), |
|||
("No semestre", 6 * 30), |
|||
("No ano", 365), |
|||
("Mais de ano", None), |
|||
] |
|||
|
|||
def get_queryset(self, request): |
|||
counts = {} |
|||
hoje = timezone.localdate() |
|||
ate = hoje |
|||
|
|||
for label, dias in self.intervalos: |
|||
if dias is not None: |
|||
de = hoje - datetime.timedelta(days=dias) |
|||
counts[slugify(label)] = Count( |
|||
"servico", Q(servico__data_ultimo_uso__range=(de, ate)) |
|||
) |
|||
ate = de - datetime.timedelta(days=1) |
|||
else: |
|||
counts[slugify(label)] = Count( |
|||
"servico", Q(servico__data_ultimo_uso__lte=ate) |
|||
) |
|||
|
|||
return ( |
|||
super() |
|||
.get_queryset(request) |
|||
.exclude(string_pesquisa="") |
|||
.filter(servico__data_desativacao=None) |
|||
.annotate(**counts) |
|||
) |
|||
|
|||
def get_labels(self, request, queryset=None): |
|||
return [label for label, *__ in self.intervalos] |
|||
|
|||
def get_datasets(self, request, queryset=None): |
|||
if queryset is None: |
|||
queryset = self.get_queryset(request) |
|||
return [ |
|||
{ |
|||
"type": "bar", |
|||
"label": ts.sigla, |
|||
"data": { |
|||
label: getattr(ts, slugify(label)) |
|||
for label, *__ in self.intervalos |
|||
}, |
|||
"backgroundColor": getcolor(ts.sigla), |
|||
} |
|||
for ts in queryset |
|||
] |
|||
|
|||
|
|||
class UsoServicos(Dashcard): |
|||
title = _("Uso dos serviços") |
|||
chart_type = Dashcard.TYPE_BAR |
|||
model = TipoServico |
|||
filterset = UsoServicosFilter |
|||
label_field = "sigla" |
|||
|
|||
def get_dataset_color(self, dataset_label): |
|||
return getcolor(dataset_label) |
|||
|
|||
def apply_filters(self, request, queryset): |
|||
queryset = queryset.exclude(string_pesquisa="").filter( |
|||
servico__data_desativacao=None |
|||
) |
|||
return super().apply_filters(request, queryset) |
|||
|
|||
def get_datasets(self, request, queryset=None): |
|||
if queryset is None: |
|||
queryset = self.get_queryset(request) |
|||
|
|||
counts = { |
|||
f"{key}_count": Count( |
|||
"servico", |
|||
distinct=True, |
|||
filter=Q(servico__resultado_verificacao=key), |
|||
) |
|||
for key, *__ in Servico.RESULTADO_CHOICES |
|||
} |
|||
|
|||
queryset = queryset.annotate(**counts) |
|||
|
|||
return [ |
|||
{ |
|||
"label": label, |
|||
"data": { |
|||
r.sigla: getattr(r, f"{key}_count") for r in queryset |
|||
}, |
|||
} |
|||
for key, label in Servico.RESULTADO_CHOICES |
|||
] |
|||
|
|||
|
|||
class ServicosAno(Dashcard): |
|||
title = _("Serviços hospedados por ano") |
|||
chart_type = Dashcard.TYPE_BAR |
|||
model = Servico |
|||
filterset = AnoServicoFilter |
|||
chart_options = { |
|||
"scales": {"x": {"stacked": True}, "y": {"stacked": True}}, |
|||
"plugins": {"tooltip": {"mode": "index"}}, |
|||
} |
|||
|
|||
def get_dataset_color(self, dataset_label): |
|||
return getcolor(dataset_label) |
|||
|
|||
def apply_filters(self, request, queryset): |
|||
return ( |
|||
super() |
|||
.apply_filters(request, queryset) |
|||
.filter(hospedagem_interlegis=True) |
|||
) |
|||
|
|||
def get_queryset(self, request): |
|||
qs = super().get_queryset(request) |
|||
if request.GET.get("ano", None): |
|||
# Usuário informou um ano, então vamos mostrar os meses daquele ano |
|||
qs = ( |
|||
qs.order_by("data_ativacao__month", "tipo_servico__sigla") |
|||
.values( |
|||
label=F("data_ativacao__month"), |
|||
sigla=F("tipo_servico__sigla"), |
|||
) |
|||
.annotate(total=Count("id")) |
|||
) |
|||
else: |
|||
qs = ( |
|||
qs.order_by("data_ativacao__year", "tipo_servico__sigla") |
|||
.values( |
|||
label=F("data_ativacao__year"), |
|||
sigla=F("tipo_servico__sigla"), |
|||
) |
|||
.annotate(total=Count("id")) |
|||
) |
|||
return qs |
|||
|
|||
def get_labels(self, request, queryset=None): |
|||
if queryset is None: |
|||
return list( |
|||
Servico.objects.filter(hospedagem_interlegis=True) |
|||
.order_by("data_ativacao__year") |
|||
.values_list("data_ativacao__year") |
|||
.distinct("data_ativacao__year") |
|||
) |
|||
|
|||
if request.GET.get("ano", None): |
|||
lang = to_locale(get_language()) + ".UTF-8" |
|||
locale.setlocale(locale.LC_ALL, lang) |
|||
map_function = lambda x: _(calendar.month_abbr[x]) |
|||
else: |
|||
map_function = str |
|||
|
|||
labels = list({r["label"] for r in queryset}) |
|||
labels.sort() |
|||
labels = list(map(map_function, labels)) |
|||
|
|||
return labels |
|||
|
|||
def get_datasets(self, request, queryset=None): |
|||
if queryset is None: |
|||
queryset = self.get_queryset(request) |
|||
if request.GET.get("ano", None): |
|||
lang = to_locale(get_language()) + ".UTF-8" |
|||
locale.setlocale(locale.LC_ALL, lang) |
|||
map_function = lambda x: _(calendar.month_abbr[x]) |
|||
else: |
|||
map_function = str |
|||
|
|||
labels = self.get_labels(request, queryset) |
|||
|
|||
series = {} |
|||
for d in queryset: |
|||
sigla = d["sigla"] |
|||
label = map_function(d["label"]) |
|||
if sigla not in series: |
|||
series[sigla] = dict(zip(labels, [0] * len(labels))) |
|||
series[sigla][label] = d["total"] |
|||
|
|||
return [ |
|||
{ |
|||
"label": s, |
|||
"data": series[s], |
|||
"backgroundColor": getcolor(s), |
|||
} |
|||
for s in series |
|||
] |
Loading…
Reference in new issue