From 0ca04861f11a52168c00d4d9b54f8d2b00160876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 20 Mar 2024 10:32:58 -0300 Subject: [PATCH] =?UTF-8?q?Adiciona=20minimapa=20de=20servi=C3=A7os=20Inte?= =?UTF-8?q?rlegis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/home/static/home/css/minimapa.css | 22 ++ sigi/apps/home/templates/home/minimapa.html | 14 + sigi/apps/home/templates/home/minimapa.svg | 324 ++++++++++++++++++ sigi/apps/home/urls.py | 2 + sigi/apps/home/views.py | 56 ++- .../templates/servicos/casas_atendidas.html | 258 +++++++------- sigi/apps/servicos/views.py | 81 +++-- 7 files changed, 589 insertions(+), 168 deletions(-) create mode 100644 sigi/apps/home/static/home/css/minimapa.css create mode 100644 sigi/apps/home/templates/home/minimapa.html create mode 100644 sigi/apps/home/templates/home/minimapa.svg diff --git a/sigi/apps/home/static/home/css/minimapa.css b/sigi/apps/home/static/home/css/minimapa.css new file mode 100644 index 0000000..40152f0 --- /dev/null +++ b/sigi/apps/home/static/home/css/minimapa.css @@ -0,0 +1,22 @@ +#svg-map path { + fill: #0094d9; +} +#svg-map a:hover { + cursor: pointer; + text-decoration: none; +} +#svg-map a:hover path, #svg-map a:hover circle { + fill: #003399 !important; +} +#svg-map text { + fill: #fff; + font: 12px Arial-BoldMT, sans-serif; + cursor: pointer; +} +#svg-map text.uf-nome { + font-weight: bold; +} + +#svg-map circle { + fill: #66ccff; +} diff --git a/sigi/apps/home/templates/home/minimapa.html b/sigi/apps/home/templates/home/minimapa.html new file mode 100644 index 0000000..ba3bde6 --- /dev/null +++ b/sigi/apps/home/templates/home/minimapa.html @@ -0,0 +1,14 @@ +{% load static i18n %} + + + + + + {% trans "Mapa de órgãos legislativos atendidos pelo Interlegis" %} + + +
+ {% include 'home/minimapa.svg' %} +
+ + \ No newline at end of file diff --git a/sigi/apps/home/templates/home/minimapa.svg b/sigi/apps/home/templates/home/minimapa.svg new file mode 100644 index 0000000..2300410 --- /dev/null +++ b/sigi/apps/home/templates/home/minimapa.svg @@ -0,0 +1,324 @@ + + + + + TO + {{ mapa_valores.TO }} + + + BA + {{ mapa_valores.BA }} + + + + + SE + {{ mapa_valores.SE }} + + + + + + PE + {{ mapa_valores.PE }} + + + + + + AL + {{ mapa_valores.AL }} + + + + + + RN + {{ mapa_valores.RN }} + + + + CE + {{ mapa_valores.CE }} + + + PI + {{ mapa_valores.PI }} + + + MA + {{ mapa_valores.MA }} + + + AP + {{ mapa_valores.AP }} + + + PA + {{ mapa_valores.PA }} + + + RR + {{ mapa_valores.RR }} + + + AM + {{ mapa_valores.AM }} + + + + + AC + {{ mapa_valores.AC }} + + + + RO + {{ mapa_valores.RO }} + + + MT + {{ mapa_valores.MT }} + + + MS + {{ mapa_valores.MS }} + + + GO + {{ mapa_valores.GO }} + + + PR + {{ mapa_valores.PR }} + + + + + SC + {{ mapa_valores.SC }} + + + RS + {{ mapa_valores.RS }} + + + SP + {{ mapa_valores.SP }} + + + MG + {{ mapa_valores.MG }} + + + + + RJ + {{ mapa_valores.RJ }} + + + + + ES + {{ mapa_valores.ES }} + + + + DF + {{ mapa_valores.DF }} + + + + + PB + {{ mapa_valores.PB }} + + \ No newline at end of file diff --git a/sigi/apps/home/urls.py b/sigi/apps/home/urls.py index b989559..803bdf0 100644 --- a/sigi/apps/home/urls.py +++ b/sigi/apps/home/urls.py @@ -86,4 +86,6 @@ urlpatterns = [ views.report_sem_convenio, name="home_reportsemconvenio", ), + path("minimapa/", views.minimapa, name="home_minimapa"), + path("minimapa.svg", views.minimapa_svg, name="home_minimapa_svg"), ] diff --git a/sigi/apps/home/views.py b/sigi/apps/home/views.py index 3dcfaee..e754c2e 100644 --- a/sigi/apps/home/views.py +++ b/sigi/apps/home/views.py @@ -16,7 +16,7 @@ from django.contrib.auth import views as auth_views from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from django.core.exceptions import PermissionDenied -from django.db.models import Q, Count +from django.db.models import Q, Count, F from django.http import ( HttpResponse, HttpResponseForbidden, @@ -51,17 +51,15 @@ from sigi.apps.servidores.models import Servidor from sigi.apps.utils import to_ascii -getcolor = ( - lambda s=None: f"#{randint(32,255):02x}{randint(32,255):02x}" - f"{randint(32,255):02x}" +getcolor = lambda s=None: ( + f"#{randint(32,255):02x}{randint(32,255):02x}{randint(32,255):02x}" if s is None else f"{seed(s) or ''}#{randint(32,255):02x}{randint(32,255):02x}" f"{randint(32,255):02x}" ) -gethighlight = ( - lambda s=None: f"#{randint(32,255):02x}{randint(32,255):02x}" - f"{randint(32,255):02x}c0" +gethighlight = lambda s=None: ( + f"#{randint(32,255):02x}{randint(32,255):02x}{randint(32,255):02x}c0" if s is None else f"{seed(s) or ''}#{randint(32,255):02x}{randint(32,255):02x}" f"{randint(32,255):02x}c0" @@ -374,6 +372,44 @@ def openmapsearch(request): return JsonResponse(list(dados), safe=False) +@xframe_options_exempt +def minimapa(request): + return render( + request, + "home/minimapa.html", + context={ + "mapa_valores": dict( + Orgao.objects.exclude(municipio__uf__sigla="ZZ") + .exclude(servico=None) + .exclude(~Q(servico__data_desativacao=None)) + .filter(tipo__legislativo=True) + .order_by("municipio__uf__sigla") + .values_list("municipio__uf__sigla") + .annotate(orgaos_atendidos=Count("id", distinct=True)) + ) + }, + ) + + +@xframe_options_exempt +def minimapa_svg(request): + return render( + request, + "home/minimapa.svg", + context={ + "mapa_valores": dict( + Orgao.objects.exclude(municipio__uf__sigla="ZZ") + .exclude(servico=None) + .exclude(~Q(servico__data_desativacao=None)) + .filter(tipo__legislativo=True) + .order_by("municipio__uf__sigla") + .values_list("municipio__uf__sigla") + .annotate(orgaos_atendidos=Count("id", distinct=True)) + ) + }, + ) + + ################################################################################ # Views de visualização e edição do dashboard ################################################################################ @@ -1095,9 +1131,9 @@ def report_sem_convenio(request): if fmt == "csv": response = HttpResponse(content_type="text/csv") - response[ - "Content-Disposition" - ] = f"attachment; filename={ titulo }.csv" + response["Content-Disposition"] = ( + f"attachment; filename={ titulo }.csv" + ) writer = csv.writer(response) writer.writerow([titulo]) writer.writerow([""]) diff --git a/sigi/apps/servicos/templates/servicos/casas_atendidas.html b/sigi/apps/servicos/templates/servicos/casas_atendidas.html index 86c9e75..3c0c2fd 100644 --- a/sigi/apps/servicos/templates/servicos/casas_atendidas.html +++ b/sigi/apps/servicos/templates/servicos/casas_atendidas.html @@ -5,6 +5,7 @@ + + {% include 'home/minimapa.svg' %} + + + {% include "servicos/navigator_snippet.html" %} - {% for srv in page_obj %} - {% ifchanged srv.casa_legislativa %} - {% if not forloop.first %} - - {% endif %} - - {% ifchanged srv.casa_legislativa.municipio.uf %} -
{% blocktranslate with nome_uf=srv.casa_legislativa.municipio.uf.nome%}Unidade da Federação: {{ nome_uf }}{% endblocktranslate %}
- {% endifchanged %} - -
-
-
-
- {% if srv.casa_legislativa.foto %} - - {% else %} - - {% endif %} -
-
- {{ srv.casa_legislativa.nome }}
- {{ srv.casa_legislativa.cnpj}} - {{ srv.casa_legislativa.tipo.nome }} -
- {{ srv.casa_legislativa.logradouro }} {{ srv.casa_legislativa.bairro }}
- {{ srv.casa_legislativa.cep }} - {{ srv.casa_legislativa.municipio.nome }}, {{ srv.casa_legislativa.municipio.uf.sigla }}
- {{ srv.casa_legislativa.email }} - {{ srv.casa_legislativa.telefone }} -
-
+ {% for orgao in page_obj %} + {% ifchanged orgao.municipio.uf %} +
{% blocktranslate with nome_uf=orgao.municipio.uf.nome %}Unidade da Federação: {{ nome_uf }}{% endblocktranslate %}
+ {% endifchanged %} +
+
+
+
+ {% if orgao.foto %} + + {% else %} + + {% endif %} +
+
+ {{ orgao.nome }}
+ {{ orgao.cnpj}} - {{ orgao.tipo.nome }} +
+ {{ orgao.logradouro }} {{ orgao.bairro }}
+ {{ orgao.cep }} - {{ orgao.municipio.nome }}, {{ orgao.municipio.uf.sigla }}
+ {{ orgao.email }} - {{ orgao.telefone }} +
-
- {% if srv.casa_legislativa.convenio_set.all %} -
{% trans "Convênios" %}
-
- + +
+ {% if orgao.convenios %} +
{% trans "Convênios" %}
+
+
+ + + + + + + + + {% for convenio in orgao.convenios %} - - - - - - - - {% for convenio in srv.casa_legislativa.convenio_set.all %} - - - - - - - + + + + + - - {% endfor %} -
{% trans "Tipo de convênio" %}{% trans "Número" %}{% trans "Status" %}{% trans "Início da vigência" %}{% trans "Término da vigência" %}{% trans "Documentos" %}
{% trans "Tipo de convênio" %}{% trans "Número" %}{% trans "Status" %}{% trans "Início da vigência" %}{% trans "Término da vigência" %}{% trans "Documentos" %}
{{ convenio.projeto.nome }}{{ convenio.num_convenio|default:"-" }}{{ convenio.get_status }}{{ convenio.data_retorno_assinatura|default:"-" }}{{ convenio.data_termino_vigencia|default:"-" }} - {{ convenio.projeto.nome }}{{ convenio.num_convenio|default:"-" }}{{ convenio.get_status }}{{ convenio.data_retorno_assinatura|default:"-" }}{{ convenio.data_termino_vigencia|default:"-" }} + -
-
- {% endif %} - {% if srv.casa_legislativa.oficinas %} -
{% trans "Oficinas realizadas" %}
-
- + {% endif %} + {% for anexo in convenio.anexo_set.all %} +
  • + {{ anexo.descricao }} +
  • + {% endfor %} + + + + {% endfor %} +
    +
    + {% endif %} + {% if orgao.oficinas %} +
    {% trans "Oficinas realizadas" %}
    +
    + + + + + + + + {% for oficina in orgao.oficinas %} - - - - + + + + - {% for oficina in srv.casa_legislativa.oficinas %} - - - - - - - {% endfor %} -
    {% trans "Período" %}{% trans "Nome" %}{% trans "Processo administrativo" %}{% trans "Participantes" %}
    {% trans "Período" %}{% trans "Nome" %}{% trans "Processo administrativo" %}{% trans "Participantes" %} + {% blocktranslate with inicio=oficina.data_inicio|date:"SHORT_DATE_FORMAT" termino=oficina.data_termino|date:"SHORT_DATE_FORMAT" %} + {{ inicio }} a {{ termino}} + {% endblocktranslate %} + {{ oficina.nome }}{{ oficina.num_processo|default:"-" }}{{ oficina.total_participantes|default:"-" }}
    - {% blocktranslate with inicio=oficina.data_inicio|date:"SHORT_DATE_FORMAT" termino=oficina.data_termino|date:"SHORT_DATE_FORMAT" %} - {{ inicio }} a {{ termino}} - {% endblocktranslate %} - {{ oficina.nome }}{{ oficina.num_processo|default:"-" }}{{ oficina.total_participantes|default:"-" }}
    -
    - {% endif %} - + {% endfor %} + +
    + {% endif %} + {% if orgao.servicos %}
    {% trans "Serviços Interlegis" %}
    @@ -184,23 +193,28 @@ - {% endifchanged %} - - - - + + + + + + + + {% endfor %} +
    {% trans "Data" %} {% trans "Resultado" %}
    {{ srv.tipo_servico.nome }}{{ srv.data_ativacao|date:"SHORT_DATE_FORMAT" }} - {% if srv.url %} - {{ srv.url}} - {% else %} -

    -

    + {% for srv in orgao.servicos %} +
    {{ srv.tipo_servico.nome }}{{ srv.data_ativacao|date:"SHORT_DATE_FORMAT" }} + {% if srv.url %} + {{ srv.url}} + {% else %} +

    -

    + {% endif %} +
    {{ srv.data_verificacao|default:"-" }}{{ srv.get_resultado_verificacao_display }}{{ srv.data_ultimo_uso|default:"-" }}
    +
    {% endif %} - - {{ srv.data_verificacao|default:"-" }} - {{ srv.get_resultado_verificacao_display }} - {{ srv.data_ultimo_uso|default:"-" }} - +
    +
    {% endfor %} -
    {% include "servicos/navigator_snippet.html" %} diff --git a/sigi/apps/servicos/views.py b/sigi/apps/servicos/views.py index caadb6a..4562a4f 100644 --- a/sigi/apps/servicos/views.py +++ b/sigi/apps/servicos/views.py @@ -1,5 +1,5 @@ import csv -from django.db.models import Q, Prefetch +from django.db.models import Q, Prefetch, Count from django.http import HttpResponse from django.shortcuts import render from django.utils.translation import gettext as _ @@ -9,7 +9,8 @@ from import_export import resources from import_export.fields import Field from sigi.apps.casas.models import Orgao from sigi.apps.contatos.models import UnidadeFederativa -from sigi.apps.eventos.models import Evento +from sigi.apps.convenios.models import Convenio +from sigi.apps.eventos.models import Evento, TipoEvento from sigi.apps.servicos.models import Servico from sigi.apps.utils import to_ascii @@ -41,7 +42,7 @@ class ServicoResource(resources.ModelResource): class CasasAtendidasListView(ListView): - model = Servico + model = Orgao template_name = "servicos/casas_atendidas.html" paginate_by = 100 @@ -49,61 +50,66 @@ class CasasAtendidasListView(ListView): param = self.kwargs["param"] search_param = self.request.GET.get("search", None) - oficinas_qs = ( + sq_servicos = Servico.objects.filter(data_desativacao=None) + sq_eventos = ( Evento.objects.exclude(data_inicio=None) .exclude(data_termino=None) + .exclude(tipo_evento__categoria=TipoEvento.CATEGORIA_VISITA) .filter(status=Evento.STATUS_REALIZADO) ) - queryset = super().get_queryset() queryset = ( - queryset.filter( - data_desativacao=None, casa_legislativa__tipo__legislativo=True - ) - .select_related( - "tipo_servico", - "casa_legislativa", - "casa_legislativa__municipio", - "casa_legislativa__municipio__uf", - "casa_legislativa__tipo", + queryset.filter(tipo__legislativo=True) + .filter( + Q( + id__in=sq_eventos.order_by() + .distinct("casa_anfitria") + .values("casa_anfitria_id") + ) + | Q( + id__in=sq_servicos.order_by() + .distinct("casa_legislativa") + .values("casa_legislativa_id") + ) ) + .select_related("municipio", "municipio__uf", "tipo") .prefetch_related( - "casa_legislativa__convenio_set", Prefetch( - "casa_legislativa__evento_set", - oficinas_qs, - to_attr="oficinas", + "servico_set", queryset=sq_servicos, to_attr="servicos" + ), + Prefetch("evento_set", queryset=sq_eventos, to_attr="eventos"), + Prefetch( + "convenio_set", + queryset=Convenio.objects.select_related("projeto"), + to_attr="convenios", ), ) - .order_by( - "casa_legislativa__municipio__uf__nome", - "casa_legislativa__tipo__nome", - "casa_legislativa__nome", - "tipo_servico__nome", - ) - ) + ).order_by("municipio__uf__nome", "tipo__nome", "nome") + if search_param: filter = [ - Q(casa_legislativa__search_text__icontains=to_ascii(t.lower())) + Q(search_text__icontains=to_ascii(t.lower())) for t in search_param.split() ] queryset = queryset.filter(*filter) if param.isdigit(): - queryset = queryset.filter(casa_legislativa__id=param) + queryset = queryset.filter(id=param) elif param != "_all_": - queryset = queryset.filter( - casa_legislativa__municipio__uf__sigla=param - ) + queryset = queryset.filter(municipio__uf__sigla=param) return queryset def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) param = self.kwargs["param"] - context["tot_orgaos"] = ( - self.get_queryset() - .order_by() - .distinct("casa_legislativa__id") - .count() + context["tot_orgaos"] = self.get_queryset().count() + context["mapa_valores"] = dict( + Orgao.objects.exclude(municipio__uf__sigla="ZZ") + .exclude(servico=None, evento=None) + .exclude(~Q(servico__data_desativacao=None)) + .filter(tipo__legislativo=True) + .order_by("municipio__uf__sigla") + .values_list("municipio__uf__sigla") + .annotate(Count("id", distinct=True)) ) context["regioes"] = [ ( @@ -120,7 +126,10 @@ class CasasAtendidasListView(ListView): def render_to_response(self, context, **response_kwargs): format = self.request.GET.get("format", "html") if format == "csv": - servicos = self.get_queryset() + orgaos = self.get_queryset().values_list("id") + servicos = Servico.objects.filter( + data_desativacao=None, casa_legislativa_id__in=orgaos + ) data = ServicoResource().export(servicos) return HttpResponse( data.csv,