diff --git a/sapl/base/urls.py b/sapl/base/urls.py index 39e017bd1..1abfa6a14 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -25,7 +25,8 @@ from .views import (AlterarSenha, AppConfigCrud, CasaLegislativaCrud, RelatorioPresencaSessaoView, RelatorioReuniaoView, SaplSearchView, RelatorioNormasPublicadasMesView, - RelatorioNormasVigenciaView) + RelatorioNormasVigenciaView, + EstatisticasAcessoNormas) app_name = AppConfig.name @@ -94,6 +95,8 @@ urlpatterns = [ RelatorioNormasPublicadasMesView.as_view(), name='normas_por_mes'), url(r'^sistema/relatorios/relatorio-por-vigencia$', RelatorioNormasVigenciaView.as_view(), name='normas_por_vigencia'), + url(r'^sistema/relatorios/estatisticas-acesso$', + EstatisticasAcessoNormas.as_view(), name='estatisticas_acesso'), url(r'^sistema/relatorios/materia-por-ano-autor-tipo$', RelatorioMateriasPorAnoAutorTipoView.as_view(), name='materia_por_ano_autor_tipo'), diff --git a/sapl/base/views.py b/sapl/base/views.py index 6f707a20e..37883a65c 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -32,7 +32,7 @@ from sapl.comissoes.models import Reuniao, Comissao from sapl.crud.base import CrudAux, make_pagination from sapl.materia.models import (Autoria, MateriaLegislativa, TipoMateriaLegislativa, StatusTramitacao, UnidadeTramitacao) -from sapl.norma.models import (NormaJuridica) +from sapl.norma.models import (NormaJuridica, NormaEstatisticas) from sapl.sessao.models import (PresencaOrdemDia, SessaoPlenaria, SessaoPlenariaPresenca) from sapl.utils import (parlamentares_ativos, @@ -777,6 +777,12 @@ class RelatorioNormasPublicadasMesView(FilterView): normas_mes[meses[norma.data.month]].append(norma) context['normas_mes'] = normas_mes + + quant_normas_mes = {} + for key in normas_mes.keys(): + quant_normas_mes[key] = len(normas_mes[key]) + + context['quant_normas_mes'] = quant_normas_mes return context @@ -803,8 +809,6 @@ class RelatorioNormasVigenciaView(FilterView): else: qs = qs.filter(data_vigencia__lt=datetime.datetime.now().date()) - # import ipdb; ipdb.set_trace() - kwargs.update({ 'queryset': qs }) @@ -841,6 +845,50 @@ class RelatorioNormasVigenciaView(FilterView): return context +class EstatisticasAcessoNormas(FilterView): + model = NormaJuridica + filterset_class = RelatorioNormasMesFilterSet + template_name = 'base/EstatisticasAcessoNormas_filter.html' + + def get_context_data(self, **kwargs): + context = super(EstatisticasAcessoNormas, + self).get_context_data(**kwargs) + context['title'] = _('Normas') + + # Verifica se os campos foram preenchidos + if not self.filterset.form.is_valid(): + return context + + qr = self.request.GET.copy() + context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + + context['show_results'] = show_results_filter_set(qr) + context['ano'] = self.request.GET['ano'] + + normas_mes = collections.OrderedDict() + meses = {1: 'Janeiro', 2: 'Fevereiro', 3:'Março', 4: 'Abril', 5: 'Maio', 6:'Junho', + 7: 'Julho', 8: 'Agosto', 9:'Setembro', 10:'Outubro', 11:'Novembro', 12:'Dezembro'} + for norma in context['object_list']: + if not meses[norma.data.month] in normas_mes: + normas_mes[meses[norma.data.month]] = [] + norma_est = [norma, len(NormaEstatisticas.objects.filter(norma=norma))] + normas_mes[meses[norma.data.month]].append(norma_est) + + # Ordena por acesso e limita em 5 + for n in normas_mes: + sorted_by_value = sorted(normas_mes[n], key=lambda kv: kv[1], reverse=True) + normas_mes[n] = sorted_by_value[0:5] + + context['normas_mes'] = normas_mes + + quant_normas_mes = {} + for key in normas_mes.keys(): + quant_normas_mes[key] = len(normas_mes[key]) + + context['quant_normas_mes'] = quant_normas_mes + + return context + class ListarUsuarioView(PermissionRequiredMixin, ListView): model = get_user_model() diff --git a/sapl/norma/migrations/0017_normaestatisticas.py b/sapl/norma/migrations/0017_normaestatisticas.py new file mode 100644 index 000000000..03009eeec --- /dev/null +++ b/sapl/norma/migrations/0017_normaestatisticas.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.8 on 2018-12-17 18:44 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0016_tipovinculonormajuridica_revoga_integramente'), + ] + + operations = [ + migrations.CreateModel( + name='NormaEstatisticas', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('usuario', models.CharField(max_length=50)), + ('horario_acesso', models.DateTimeField(auto_now=True, null=True)), + ('norma', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='norma.NormaJuridica')), + ], + ), + ] diff --git a/sapl/norma/models.py b/sapl/norma/models.py index 6565304ee..80075f113 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -191,6 +191,18 @@ class NormaJuridica(models.Model): update_fields=update_fields) +class NormaEstatisticas(models.Model): + usuario = models.CharField(max_length=50) + horario_acesso = models.DateTimeField( + blank=True, null=True, + auto_now=True) + norma = models.ForeignKey(NormaJuridica, + on_delete=models.CASCADE) + def __str__(self): + return _('Usuário: %(usuario)s, Norma: %(norma)s') % { + 'usuario': self.usuario, 'norma': self.norma} + + @reversion.register() class AutoriaNorma(models.Model): autor = models.ForeignKey(Autor, diff --git a/sapl/norma/views.py b/sapl/norma/views.py index f2dfb6f2e..89aaaee85 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -24,7 +24,7 @@ from sapl.utils import show_results_filter_set from .forms import (AnexoNormaJuridicaForm, NormaFilterSet, NormaJuridicaForm, NormaPesquisaSimplesForm, NormaRelacionadaForm, AutoriaNormaForm) from .models import (AnexoNormaJuridica, AssuntoNorma, NormaJuridica, NormaRelacionada, - TipoNormaJuridica, TipoVinculoNormaJuridica, AutoriaNorma) + TipoNormaJuridica, TipoVinculoNormaJuridica, AutoriaNorma, NormaEstatisticas) # LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '') @@ -190,7 +190,11 @@ class NormaCrud(Crud): return reverse('%s:%s' % (namespace, 'norma_pesquisa')) class DetailView(Crud.DetailView): - pass + def get(self, request, *args, **kwargs): + NormaEstatisticas.objects.create(usuario=str(self.request.user), + norma_id=kwargs['pk']) + return super().get(request, *args, **kwargs) + class DeleteView(Crud.DeleteView): @@ -225,7 +229,7 @@ class NormaCrud(Crud): class ListView(Crud.ListView, RedirectView): def get_redirect_url(self, *args, **kwargs): - namespace = self.model._meta.app_config.name + namespace = self.model._meta.app_config.name return reverse('%s:%s' % (namespace, 'norma_pesquisa')) def get(self, request, *args, **kwargs): diff --git a/sapl/templates/base/EstatisticasAcessoNormas_filter.html b/sapl/templates/base/EstatisticasAcessoNormas_filter.html new file mode 100644 index 000000000..fb4914fb0 --- /dev/null +++ b/sapl/templates/base/EstatisticasAcessoNormas_filter.html @@ -0,0 +1,53 @@ +{% extends "crud/list.html" %} +{% load i18n %} +{% load crispy_forms_tags %} + +{% block base_content %} + {% if not show_results %} + {% crispy filter.form %} + {% endif %} + {% if show_results %} +
+ {% trans 'Fazer nova pesquisa' %} +
+



+ PARÂMETROS DE PESQUISA:
+  Ano: {{ ano }}
+
+ {% if normas_mes|length == 0 %} +
+

{% trans 'Não foi encontrada nenhuma norma com os parâmetros buscados.'%}

+ {% endif %} + {% for mes, normas in normas_mes.items %} +
+ + + + + + +

Mês: {{ mes }}

+ + + + + + + + + + {% for n in normas %} + + + + + + {% endfor %} + +
MatériaNormaAcessos
+ {{n.0.tipo.descricao}} - {{n.0.tipo.sigla}} {{n.0.numero}}/{{n.0.ano}} + {{n.0.ementa}}
{{n.0.observacao}}
{{n.1}}
+
+ {% endfor %} + {% endif %} +{% endblock base_content %} diff --git a/sapl/templates/base/RelatorioNormaMes_filter.html b/sapl/templates/base/RelatorioNormaMes_filter.html index 1b7fce6fa..b035a20dd 100644 --- a/sapl/templates/base/RelatorioNormaMes_filter.html +++ b/sapl/templates/base/RelatorioNormaMes_filter.html @@ -15,6 +15,10 @@ PARÂMETROS DE PESQUISA:
 Ano: {{ ano }}

+ {% if normas_mes|length == 0 %} +
+

{% trans 'Não foi encontrada nenhuma norma com os parâmetros buscados.'%}

+ {% endif %} {% for mes, normas in normas_mes.items %}
@@ -24,7 +28,22 @@
- +
+ + + {% for k, v in quant_normas_mes.items %} + {% if k == mes %} + {% if v > 1 %} + + {% else %} + + {% endif %} + {% endif %} + {% endfor %} + + +
Quantidade encontrada no mês: {{ v }} normas.Quantidade encontrada no mês: 1 norma.
+ diff --git a/sapl/templates/base/RelatorioNormasVigencia_filter.html b/sapl/templates/base/RelatorioNormasVigencia_filter.html index bcbbf8ab3..e88916a3c 100644 --- a/sapl/templates/base/RelatorioNormasVigencia_filter.html +++ b/sapl/templates/base/RelatorioNormasVigencia_filter.html @@ -41,8 +41,6 @@ {% endfor %}
Matéria
-

Estatísticas das normas do ano:


-

{{quant_vigente}} vigente(s) / {{quant_nao_vigente}} não vigente(s)

{% else %} @@ -52,5 +50,8 @@
{% endif %} +
+

Estatísticas das normas do ano:


+

{{quant_vigente}} vigente(s) / {{quant_nao_vigente}} não vigente(s)

{% endif %} {% endblock base_content %} diff --git a/sapl/templates/base/relatorios_list.html b/sapl/templates/base/relatorios_list.html index 461c59f45..9f42a78f6 100644 --- a/sapl/templates/base/relatorios_list.html +++ b/sapl/templates/base/relatorios_list.html @@ -56,6 +56,10 @@ Normas por vigência Normas vigentes ou não vigentes. + + Estatísticas de acesso de Normas. + Normas por acesso. +