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 %}
+
+
+ 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 }} |
+
+
+
+
+
+ {% 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 %}
-
+
+
+
+ {% for k, v in quant_normas_mes.items %}
+ {% if k == mes %}
+ {% if v > 1 %}
+ | Quantidade encontrada no mês: {{ v }} normas. |
+ {% else %}
+ Quantidade encontrada no mês: 1 norma. |
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+
+
+
+
| Matéria |
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 %}
- Estatísticas das normas do ano:
- {{quant_vigente}} vigente(s) / {{quant_nao_vigente}} não vigente(s)
{% else %}
{% 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. |
+