Repository: interlegis/sapl

Issue:
Relatórios básicos para novos itens implementados
Sugiro o desenvolvimento de relatórios para novos itens incluídos no SAPL como por exemplo: Reunião de Comissão e Audiências Públicas. Como sugestão, utilizar os campos data e tipo como chave no caso das Audiências Públicas, e para as Reuniões de Comissão o campo data e nome de comissão.
grato


Discussion:

Resolving patch:
diff --git a/sapl/base/forms.py b/sapl/base/forms.py
--- a/sapl/base/forms.py
+++ b/sapl/base/forms.py
@@ -18,6 +18,8 @@
 from sapl.base.models import Autor, TipoAutor
 from sapl.crispy_layout_mixin import (SaplFormLayout, form_actions, to_column,
                                       to_row)
+from sapl.audiencia.models import AudienciaPublica,TipoAudienciaPublica
+from sapl.comissoes.models import Reuniao, Comissao
 from sapl.materia.models import (MateriaLegislativa, UnidadeTramitacao, StatusTramitacao)
 from sapl.parlamentares.models import SessaoLegislativa
 from sapl.sessao.models import SessaoPlenaria
@@ -177,8 +179,7 @@ def clean(self):
         data_inicio_leg = legislatura.data_inicio
         data_fim_leg = legislatura.data_fim
         pk = self.initial['id'] if self.initial else None
-
-        # Querys para verificar se existem Sessões Legislativas no período selecionado no form
+         # Queries para verificar se existem Sessões Legislativas no período selecionado no form
         # Caso onde a data_inicio e data_fim são iguais a de alguma sessão já criada
         primeiro_caso = Q(data_inicio=data_inicio, data_fim=data_fim)
         # Caso onde a data_inicio está entre o início e o fim de uma Sessão já existente
@@ -206,11 +207,11 @@ def clean(self):
         #     ult = ult.numero
 
         ult = 0
+
         if numero <= ult and flag_edit:
             raise ValidationError('O número da Sessão Legislativa não pode ser menor ou igual '
                                   'que o de Sessões Legislativas passadas')
 
-
         if data_inicio < data_inicio_leg or \
             data_inicio > data_fim_leg:
             raise ValidationError('A data de início da Sessão Legislativa deve estar compreendida '
@@ -240,7 +241,6 @@ def clean(self):
                 raise ValidationError('A data de início do intervalo deve estar compreendida entre '
                                       'as datas de início e fim tanto da Legislatura quanto da '
                                       'própria Sessão Legislativa')
-
         if data_fim_intervalo:
             if data_fim_intervalo > data_fim or \
                     data_fim_intervalo > data_fim_leg or \
@@ -732,6 +732,67 @@ def __init__(self, *args, **kwargs):
         )
 
 
+class RelatorioReuniaoFilterSet(django_filters.FilterSet):
+
+    @property
+    def qs(self):
+        parent = super(RelatorioReuniaoFilterSet, self).qs
+        return parent.distinct().order_by('-data', 'comissao')
+
+    class Meta:
+        model = Reuniao
+        fields = ['comissao', 'data',
+                  'nome','tema']
+
+    def __init__(self, *args, **kwargs):
+        super(RelatorioReuniaoFilterSet, self).__init__(
+            *args, **kwargs)
+
+        row1 = to_row([('data', 12)])
+        row2 = to_row(
+            [('comissao', 4),
+             ('nome', 4),
+             ('tema', 4)])
+
+        self.form.helper = FormHelper()
+        self.form.helper.form_method = 'GET'
+        self.form.helper.layout = Layout(
+            Fieldset(_('Reunião de Comissão'),
+                     row1, row2,
+                     form_actions(label='Pesquisar'))
+        )
+
+class RelatorioAudienciaFilterSet(django_filters.FilterSet):
+
+    @property
+    def qs(self):
+        parent = super(RelatorioAudienciaFilterSet, self).qs
+        return parent.distinct().order_by('-data', 'tipo')
+
+    class Meta:
+        model = AudienciaPublica
+        fields = ['tipo', 'data',
+                  'nome']
+
+    def __init__(self, *args, **kwargs):
+        super(RelatorioAudienciaFilterSet, self).__init__(
+            *args, **kwargs)
+
+        row1 = to_row([('data', 12)])
+        row2 = to_row(
+            [('tipo', 4),
+             ('nome', 4)])
+
+        self.form.helper = FormHelper()
+        self.form.helper.form_method = 'GET'
+        self.form.helper.layout = Layout(
+            Fieldset(_('Audiência Pública'),
+                     row1, row2,
+                     form_actions(label='Pesquisar'))
+        )
+
+
+
 class RelatorioMateriasTramitacaoilterSet(django_filters.FilterSet):
 
     ano = django_filters.ChoiceFilter(required=True,
diff --git a/sapl/base/urls.py b/sapl/base/urls.py
--- a/sapl/base/urls.py
+++ b/sapl/base/urls.py
@@ -16,12 +16,14 @@
 from .views import (AlterarSenha, AppConfigCrud, CasaLegislativaCrud,
                     CreateUsuarioView, DeleteUsuarioView, EditUsuarioView,
                     HelpTopicView, ListarUsuarioView, LogotipoView,
-                    RelatorioAtasView, RelatorioDataFimPrazoTramitacaoView,
+                    RelatorioAtasView, RelatorioAudienciaView, 
+                    RelatorioDataFimPrazoTramitacaoView,
                     RelatorioHistoricoTramitacaoView,
                     RelatorioMateriasPorAnoAutorTipoView,
                     RelatorioMateriasPorAutorView,
                     RelatorioMateriasTramitacaoView,
-                    RelatorioPresencaSessaoView, SaplSearchView)
+                    RelatorioPresencaSessaoView, 
+                    RelatorioReuniaoView, SaplSearchView)
 
 app_name = AppConfig.name
 
@@ -104,6 +106,12 @@
     url(r'^sistema/relatorios/atas$',
         RelatorioAtasView.as_view(),
         name='atas'),
+    url(r'^sistema/relatorios/reuniao$',
+        RelatorioReuniaoView.as_view(),
+        name='reuniao'),
+    url(r'^sistema/relatorios/audiencia$',
+        RelatorioAudienciaView.as_view(),
+        name='audiencia'),
 
     url(r'^email/validate/(?P<uidb64>[0-9A-Za-z_\-]+)/'
         '(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})$',
diff --git a/sapl/base/views.py b/sapl/base/views.py
--- a/sapl/base/views.py
+++ b/sapl/base/views.py
@@ -25,6 +25,8 @@
 from sapl.base.forms import AutorForm, AutorFormForAdmin, TipoAutorForm
 from sapl.base.models import Autor, TipoAutor
 from sapl.crud.base import CrudAux, make_pagination
+from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica
+from sapl.comissoes.models import Reuniao, Comissao
 from sapl.materia.models import (Autoria, MateriaLegislativa,
                                  TipoMateriaLegislativa, StatusTramitacao, UnidadeTramitacao)
 from sapl.sessao.models import (PresencaOrdemDia, SessaoPlenaria,
@@ -34,12 +36,14 @@
 
 from .forms import (AlterarSenhaForm, CasaLegislativaForm,
                     ConfiguracoesAppForm, RelatorioAtasFilterSet,
+                    RelatorioAudienciaFilterSet,
                     RelatorioDataFimPrazoTramitacaoFilterSet,
                     RelatorioHistoricoTramitacaoFilterSet,
                     RelatorioMateriasPorAnoAutorTipoFilterSet,
                     RelatorioMateriasPorAutorFilterSet,
                     RelatorioMateriasTramitacaoilterSet,
-                    RelatorioPresencaSessaoFilterSet, UsuarioCreateForm,
+                    RelatorioPresencaSessaoFilterSet,
+                    RelatorioReuniaoFilterSet, UsuarioCreateForm,
                     UsuarioEditForm)
 from .models import AppConfig, CasaLegislativa
 
@@ -436,6 +440,71 @@ def get_context_data(self, **kwargs):
 
         return context
 
+class RelatorioReuniaoView(FilterView):
+    model = Reuniao
+    filterset_class = RelatorioReuniaoFilterSet
+    template_name = 'base/RelatorioReuniao_filter.html'
+
+    def get_filterset_kwargs(self, filterset_class):
+        super(RelatorioReuniaoView,
+              self).get_filterset_kwargs(filterset_class)
+
+        kwargs = {'data': self.request.GET or None}
+        return kwargs
+
+    def get_context_data(self, **kwargs):
+        context = super(RelatorioReuniaoView,
+                        self).get_context_data(**kwargs)
+        context['title'] = _('Reunião de Comissão')
+        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)
+
+        if self.request.GET['comissao']:
+            comissao = self.request.GET['comissao']
+            context['comissao'] = (str(Comissao.objects.get(id=comissao)))
+        else:
+            context['comissao'] = ''
+
+        return context
+
+class RelatorioAudienciaView(FilterView):
+    model = AudienciaPublica
+    filterset_class = RelatorioAudienciaFilterSet
+    template_name = 'base/RelatorioAudiencia_filter.html'
+
+    def get_filterset_kwargs(self, filterset_class):
+        super(RelatorioAudienciaView,
+              self).get_filterset_kwargs(filterset_class)
+
+        kwargs = {'data': self.request.GET or None}
+        return kwargs
+
+    def get_context_data(self, **kwargs):
+        context = super(RelatorioAudienciaView,
+                        self).get_context_data(**kwargs)
+        context['title'] = _('Audiência Pública')
+        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)
+
+        if self.request.GET['tipo']:
+            tipo = self.request.GET['tipo']
+            context['tipo'] = (str(TipoAudienciaPublica.objects.get(id=tipo)))
+        else:
+            context['tipo'] = ''
+
+        return context
+
+
 
 class RelatorioMateriasTramitacaoView(FilterView):
     model = MateriaLegislativa


Test patch: