From 98334f4c6bddf774ea8e69b268ce13aa373b4424 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 30 Aug 2016 17:29:09 -0300 Subject: [PATCH 01/41] Cria as regras para criacao e edicao de tramitacao de uma materia --- sapl/materia/forms.py | 77 ++++++++++++++++++++++++++--- sapl/materia/views.py | 14 ++++-- sapl/templates/materia/layouts.yaml | 6 +++ sapl/utils.py | 4 +- 4 files changed, 89 insertions(+), 12 deletions(-) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index a91567a7f..53549e822 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -216,22 +216,87 @@ class TramitacaoForm(ModelForm): 'texto'] def clean(self): + data_enc_form = self.cleaned_data['data_encaminhamento'] + data_prazo_form = self.cleaned_data['data_fim_prazo'] + data_tram_form = self.cleaned_data['data_tramitacao'] + if self.errors: return self.errors ultima_tramitacao = Tramitacao.objects.filter( - materia_id=self.instance.materia.id).last() + materia_id=self.instance.materia_id).exclude( + id=self.instance.id).last() + + if not self.instance.data_tramitacao: + + if ultima_tramitacao: + destino = ultima_tramitacao.unidade_tramitacao_destino + if (destino != self.cleaned_data['unidade_tramitacao_local']): + msg = _('A origem da nova tramitação deve ser igual ao ' + 'destino da última adicionada!') + raise ValidationError(msg) + + if self.cleaned_data['data_tramitacao'] > datetime.now().date(): + msg = _( + 'A data de tramitação deve ser ' + + 'menor ou igual a data de hoje!') + raise ValidationError(msg) + + if (ultima_tramitacao and + data_tram_form < ultima_tramitacao.data_tramitacao): + msg = _('A data da nova tramitação deve ser ' + + 'maior que a data da última tramitação!') + raise ValidationError(msg) - if ultima_tramitacao: - destino = ultima_tramitacao.unidade_tramitacao_destino - if (destino != self.cleaned_data['unidade_tramitacao_local']): - msg = _('A origem da nova tramitação deve ser igual ao ' - 'destino da última adicionada!') + if data_enc_form: + if data_enc_form < data_tram_form: + msg = _('A data de encaminhamento deve ser ' + + 'maior que a data de tramitação!') + raise ValidationError(msg) + + if data_prazo_form: + if data_prazo_form < data_tram_form: + msg = _('A data fim de prazo deve ser ' + + 'maior que a data de tramitação!') raise ValidationError(msg) return self.cleaned_data +class TramitacaoUpdateForm(TramitacaoForm): + unidade_tramitacao_local = forms.ModelChoiceField( + queryset=UnidadeTramitacao.objects.all(), + widget=forms.HiddenInput()) + + data_tramitacao = forms.DateField(widget=forms.HiddenInput()) + + class Meta: + model = Tramitacao + fields = ['data_tramitacao', + 'unidade_tramitacao_local', + 'status', + 'turno', + 'urgente', + 'unidade_tramitacao_destino', + 'data_encaminhamento', + 'data_fim_prazo', + 'texto', + ] + + widgets = { + 'data_encaminhamento': forms.DateInput(format='%d/%m/%Y'), + 'data_fim_prazo': forms.DateInput(format='%d/%m/%Y'), + } + + def clean(self): + local = self.instance.unidade_tramitacao_local + data_tram = self.instance.data_tramitacao + + self.cleaned_data['data_tramitacao'] = data_tram + self.cleaned_data['unidade_tramitacao_local'] = local + return super(TramitacaoUpdateForm, self).clean() + + class LegislacaoCitadaForm(ModelForm): tipo = forms.ModelChoiceField( diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 35f4eef50..52c2711c5 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -37,7 +37,8 @@ from .forms import (AcompanhamentoMateriaForm, AnexadaForm, AutorForm, AutoriaForm, ConfirmarProposicaoForm, DespachoInicialForm, DocumentoAcessorioForm, LegislacaoCitadaForm, MateriaLegislativaFilterSet, NumeracaoForm, ProposicaoForm, - ReceberProposicaoForm, RelatoriaForm, TramitacaoForm, + ReceberProposicaoForm, RelatoriaForm, + TramitacaoForm, TramitacaoUpdateForm, UnidadeTramitacaoForm, filtra_tramitacao_destino, filtra_tramitacao_destino_and_status, filtra_tramitacao_status) @@ -573,14 +574,19 @@ class TramitacaoCrud(MasterDetailCrud): return super(CreateView, self).post(request, *args, **kwargs) class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView): - form_class = TramitacaoForm + form_class = TramitacaoUpdateForm permission_required = permissoes_materia() def post(self, request, *args, **kwargs): - materia = MateriaLegislativa.objects.get(id=kwargs['pk']) + materia = MateriaLegislativa.objects.get( + tramitacao__id=kwargs['pk']) do_envia_email_tramitacao(request, materia) return super(UpdateView, self).post(request, *args, **kwargs) + @property + def layout_key(self): + return 'TramitacaoUpdate' + class ListView(MasterDetailCrud.ListView): def get_queryset(self): @@ -598,7 +604,7 @@ class TramitacaoCrud(MasterDetailCrud): kwargs={'pk': tramitacao.materia.id}) if tramitacao.pk != materia.tramitacao_set.last().pk: - msg = _('Somente a útlima tramitação pode ser deletada!') + msg = _('Somente a última tramitação pode ser deletada!') messages.add_message(request, messages.ERROR, msg) return HttpResponseRedirect(url) else: diff --git a/sapl/templates/materia/layouts.yaml b/sapl/templates/materia/layouts.yaml index 19c5fcdbd..d5ade5b8c 100644 --- a/sapl/templates/materia/layouts.yaml +++ b/sapl/templates/materia/layouts.yaml @@ -129,6 +129,12 @@ Tramitacao: - status turno urgente - texto +TramitacaoUpdate: + {% trans 'Tramitação' %}: + - unidade_tramitacao_destino data_encaminhamento data_fim_prazo + - status turno urgente + - texto + DespachoInicial: {% trans 'Despacho Inicial' %}: - comissao diff --git a/sapl/utils.py b/sapl/utils.py index 34aa2ce8c..8ae38f863 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -225,8 +225,8 @@ def intervalos_tem_intersecao(a_inicio, a_fim, b_inicio, b_fim): def permissoes_materia(): lista_permissoes = [] try: - cts = ContentType.objects.filter(app_label='materia') - perms_materia = list(Permission.objects.filter(content_type__in=cts)) + perms_materia = Permission.objects.filter( + group__name='Operador de Matéria') for p in perms_materia: lista_permissoes.append('materia.' + p.codename) except: From f68cfa19122d9a25483d684af8634da14455bfb7 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Mon, 5 Sep 2016 09:28:54 -0300 Subject: [PATCH 02/41] Resolve problemas nos testes --- sapl/materia/forms.py | 10 +++++++--- sapl/materia/tests/test_materia.py | 2 ++ sapl/materia/views.py | 6 +++--- sapl/protocoloadm/tests/test_protocoloadm.py | 1 + 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 53549e822..851dd51ba 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -216,9 +216,13 @@ class TramitacaoForm(ModelForm): 'texto'] def clean(self): - data_enc_form = self.cleaned_data['data_encaminhamento'] - data_prazo_form = self.cleaned_data['data_fim_prazo'] - data_tram_form = self.cleaned_data['data_tramitacao'] + + if 'data_encaminhamento' in self.data: + data_enc_form = self.cleaned_data['data_encaminhamento'] + if 'data_fim_prazo' in self.data: + data_prazo_form = self.cleaned_data['data_fim_prazo'] + if 'data_tramitacao' in self.data: + data_tram_form = self.cleaned_data['data_tramitacao'] if self.errors: return self.errors diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py index f400a453e..d3a9573c9 100644 --- a/sapl/materia/tests/test_materia.py +++ b/sapl/materia/tests/test_materia.py @@ -276,6 +276,8 @@ def test_tramitacao_submit(admin_client): 'urgente': True, 'status': status_tramitacao.pk, 'data_tramitacao': '2016-03-21', + 'data_fim_prazo': '2016-03-22', + 'data_encaminhamento': '2016-03-22', 'texto': 'Texto_Teste', 'salvar': 'salvar'}, follow=True) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index f4b76dfea..239384030 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -37,9 +37,9 @@ from .forms import (AcompanhamentoMateriaForm, AnexadaForm, AutorForm, AutoriaForm, ConfirmarProposicaoForm, DespachoInicialForm, DocumentoAcessorioForm, LegislacaoCitadaForm, MateriaLegislativaFilterSet, NumeracaoForm, ProposicaoForm, - ReceberProposicaoForm, RelatoriaForm, - TramitacaoForm, TramitacaoUpdateForm, - UnidadeTramitacaoForm, filtra_tramitacao_destino, + ReceberProposicaoForm, RelatoriaForm, TramitacaoForm, + TramitacaoUpdateForm, UnidadeTramitacaoForm, + filtra_tramitacao_destino, filtra_tramitacao_destino_and_status, filtra_tramitacao_status) from .models import (AcompanhamentoMateria, Anexada, Autor, Autoria, diff --git a/sapl/protocoloadm/tests/test_protocoloadm.py b/sapl/protocoloadm/tests/test_protocoloadm.py index 6f9e0ad19..e249a3312 100644 --- a/sapl/protocoloadm/tests/test_protocoloadm.py +++ b/sapl/protocoloadm/tests/test_protocoloadm.py @@ -1,4 +1,5 @@ import datetime + import pytest from django.core.urlresolvers import reverse from django.utils.translation import ugettext_lazy as _ From a8cbe4c4ea2fb23473e9494a6d8b6985df00eb49 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Thu, 8 Sep 2016 14:45:13 -0300 Subject: [PATCH 03/41] =?UTF-8?q?Adiciona=20mensagem=20ao=20detail.html,?= =?UTF-8?q?=20quando=20o=20campo=20=C3=A9=20vazio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/templates/crud/detail.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sapl/templates/crud/detail.html b/sapl/templates/crud/detail.html index e4ce60e14..c981cd9ac 100644 --- a/sapl/templates/crud/detail.html +++ b/sapl/templates/crud/detail.html @@ -28,7 +28,11 @@

{{ column.verbose_name }}

-

{{ column.text|safe }}

+ {% if column.text %} +

{{ column.text|safe }}

+ {% else %} +

Não informado

+ {% endif %}
From 900c2611444717c8260b18ea4726830cd7543ef0 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Thu, 8 Sep 2016 14:58:39 -0300 Subject: [PATCH 04/41] Adiciona sistema a url de coligacao, para manter o padrao e eliminar bug --- sapl/parlamentares/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/parlamentares/urls.py b/sapl/parlamentares/urls.py index 97f2a0347..09bc8bf3f 100644 --- a/sapl/parlamentares/urls.py +++ b/sapl/parlamentares/urls.py @@ -24,7 +24,7 @@ urlpatterns = [ ProposicaoParlamentarCrud.get_urls() + RelatoriaParlamentarCrud.get_urls() )), - url(r'^coligacao/', + url(r'^sistema/coligacao/', include(ColigacaoCrud.get_urls() + ComposicaoColigacaoCrud.get_urls())), From 4fbe0a95dff5d53c608be7c9c61ba27acccb41d8 Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Fri, 2 Sep 2016 15:09:26 -0300 Subject: [PATCH 05/41] =?UTF-8?q?Implementa=20view=20e=20form=20para=20pes?= =?UTF-8?q?quisa=20de=20presen=C3=A7a=20em=20sess=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/forms.py | 30 ++++++++++++++ sapl/base/urls.py | 6 ++- sapl/base/views.py | 18 ++++++++- .../base/RelatorioPresencaSessao_filter.html | 40 +++++++++++++++++++ sapl/templates/base/relatorios_list.html | 2 +- 5 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 sapl/templates/base/RelatorioPresencaSessao_filter.html diff --git a/sapl/base/forms.py b/sapl/base/forms.py index 5af6ee179..0c11a7a63 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -10,6 +10,7 @@ from django.utils.translation import ugettext_lazy as _ from sapl.crispy_layout_mixin import form_actions, to_row from sapl.materia.models import MateriaLegislativa +from sapl.sessao.models import SessaoPlenaria from sapl.settings import MAX_IMAGE_UPLOAD_SIZE from sapl.utils import (RANGE_ANOS, ImageThumbnailFileInput, autor_label, autor_modal) @@ -37,6 +38,35 @@ class RangeWidgetOverride(forms.MultiWidget): return ''.join(rendered_widgets) +class RelatorioPresencaSessaoFilterSet(django_filters.FilterSet): + + filter_overrides = {models.DateField: { + 'filter_class': django_filters.DateFromToRangeFilter, + 'extra': lambda f: { + 'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')), + 'widget': RangeWidgetOverride} + }} + + class Meta: + model = SessaoPlenaria + fields = ['data_inicio'] + + def __init__(self, *args, **kwargs): + super(RelatorioPresencaSessaoFilterSet, self).__init__( + *args, **kwargs) + + self.filters['data_inicio'].label = 'Período' + + row1 = to_row([('data_inicio', 12)]) + + self.form.helper = FormHelper() + self.form.helper.form_method = 'GET' + self.form.helper.layout = Layout( + Fieldset(_('Presença dos parlamentares nas sessões plenárias'), + row1, form_actions(save_label='Pesquisar')) + ) + + class RelatorioHistoricoTramitacaoFilterSet(django_filters.FilterSet): filter_overrides = {models.DateField: { diff --git a/sapl/base/urls.py b/sapl/base/urls.py index b3dcac6ea..88ab866b1 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -8,7 +8,8 @@ from .views import (CasaLegislativaCrud, HelpView, RelatorioHistoricoTramitacaoView, RelatorioMateriasPorAnoAutorTipoView, RelatorioMateriasPorAutorView, - RelatorioMateriasTramitacaoView) + RelatorioMateriasTramitacaoView, + RelatorioPresencaSessaoView) app_name = AppConfig.name @@ -39,5 +40,8 @@ urlpatterns = [ url(r'^relatorio/historico-tramitacoes$', RelatorioHistoricoTramitacaoView.as_view(), name='historico_tramitacoes'), + url(r'^relatorio/presenca$', + RelatorioPresencaSessaoView.as_view(), + name='presenca_sessao'), ] diff --git a/sapl/base/views.py b/sapl/base/views.py index ca5d735a3..cdaf77e19 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -9,11 +9,13 @@ from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, CrudDetailView, CrudUpdateView) from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.utils import permissao_tb_aux +from sapl.sessao.models import SessaoPlenaria from .forms import (CasaLegislativaForm, RelatorioHistoricoTramitacaoFilterSet, RelatorioMateriasPorAnoAutorTipoFilterSet, RelatorioMateriasPorAutorFilterSet, - RelatorioMateriasTramitacaoilterSet) + RelatorioMateriasTramitacaoilterSet, + RelatorioPresencaSessaoFilterSet) from .models import CasaLegislativa @@ -21,6 +23,20 @@ def get_casalegislativa(): return CasaLegislativa.objects.first() +class RelatorioPresencaSessaoView(FilterView): + model = SessaoPlenaria + filterset_class = RelatorioPresencaSessaoFilterSet + template_name = 'base/RelatorioPresencaSessao_filter.html' + + def get_context_data(self, **kwargs): + context = super(RelatorioPresencaSessaoView, + self).get_context_data(**kwargs) + context['title'] = _('Presença dos parlamentares nas sessões') + qr = self.request.GET.copy() + context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + return context + + class RelatorioHistoricoTramitacaoView(FilterView): model = MateriaLegislativa filterset_class = RelatorioHistoricoTramitacaoFilterSet diff --git a/sapl/templates/base/RelatorioPresencaSessao_filter.html b/sapl/templates/base/RelatorioPresencaSessao_filter.html new file mode 100644 index 000000000..1a8792174 --- /dev/null +++ b/sapl/templates/base/RelatorioPresencaSessao_filter.html @@ -0,0 +1,40 @@ +{% extends "crud/list.html" %} +{% load i18n %} +{% load crispy_forms_tags %} + +{% block base_content %} + {% if not filter_url %} + {% crispy filter.form %} + {% endif %} + + {% if filter_url %} + +



+ + + + + + + + + + + + + + + + + + + + + + + +
Nome Parlamentar / PartidoSessãoOrdem do Dia
(Qtd)( % )(Qtd)( % )
Nome Teste / Partido Teste1511%116%
+ {% endif %} +{% endblock base_content %} diff --git a/sapl/templates/base/relatorios_list.html b/sapl/templates/base/relatorios_list.html index 49edf946c..ade7fa1f0 100644 --- a/sapl/templates/base/relatorios_list.html +++ b/sapl/templates/base/relatorios_list.html @@ -25,7 +25,7 @@ Totalização anual de matérias agrupadas por autor e tipo. - Presença nas sessões + Presença nas sessões Presença dos parlamentares nas sessões plenárias. From a7c7baa61b365badfe081fb9ffceb126671b9728 Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Fri, 2 Sep 2016 15:24:08 -0300 Subject: [PATCH 06/41] =?UTF-8?q?Ajuste=20no=20template=20do=20relat=C3=B3?= =?UTF-8?q?rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/RelatorioPresencaSessao_filter.html | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/sapl/templates/base/RelatorioPresencaSessao_filter.html b/sapl/templates/base/RelatorioPresencaSessao_filter.html index 1a8792174..8d0321210 100644 --- a/sapl/templates/base/RelatorioPresencaSessao_filter.html +++ b/sapl/templates/base/RelatorioPresencaSessao_filter.html @@ -8,31 +8,37 @@ {% endif %} {% if filter_url %} + +



- +
- - - + + + - - - - + + + + - - - - - + + + + +
Nome Parlamentar / PartidoSessãoOrdem do DiaNome Parlamentar / PartidoSessãoOrdem do Dia
(Qtd)( % )(Qtd)( % )(Qtd)( % )(Qtd)( % )
Nome Teste / Partido Teste1511%116%Nome Teste | Partido Teste1511%116%
From 0d956c206747f5f1bc06ba407c0aad73d70f0ec8 Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Fri, 2 Sep 2016 15:58:45 -0300 Subject: [PATCH 07/41] =?UTF-8?q?Muda=20label=20do=20campo=20per=C3=ADodo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/base/forms.py b/sapl/base/forms.py index 0c11a7a63..fc37bbc3d 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -55,7 +55,7 @@ class RelatorioPresencaSessaoFilterSet(django_filters.FilterSet): super(RelatorioPresencaSessaoFilterSet, self).__init__( *args, **kwargs) - self.filters['data_inicio'].label = 'Período' + self.filters['data_inicio'].label = 'Período (Inicial - Final)' row1 = to_row([('data_inicio', 12)]) From 698643126cb271fbb057cb0795f5145249ff59f3 Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Mon, 5 Sep 2016 10:27:09 -0300 Subject: [PATCH 08/41] =?UTF-8?q?Mudan=C3=A7as=20no=20template=20e=20tenti?= =?UTF-8?q?va=20de=20consulta=20de=20presen=C3=A7as?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 44 ++++++++++++++++++- .../base/RelatorioPresencaSessao_filter.html | 20 +++++---- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index cdaf77e19..f066e5aa6 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -8,8 +8,10 @@ from django_filters.views import FilterView from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, CrudDetailView, CrudUpdateView) from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa +from sapl.parlamentares.models import Parlamentar +from sapl.sessao.models import (PresencaOrdemDia, SessaoPlenaria, + SessaoPlenariaPresenca) from sapl.utils import permissao_tb_aux -from sapl.sessao.models import SessaoPlenaria from .forms import (CasaLegislativaForm, RelatorioHistoricoTramitacaoFilterSet, RelatorioMateriasPorAnoAutorTipoFilterSet, @@ -32,6 +34,46 @@ class RelatorioPresencaSessaoView(FilterView): context = super(RelatorioPresencaSessaoView, self).get_context_data(**kwargs) context['title'] = _('Presença dos parlamentares nas sessões') + # =================================================================== + # FIXME: Pensar em melhor forma de verificar se formulário está sendo + # submetido. + if 'salvar' in self.request.GET: + if 'data_inicio_0' and 'data_inicio_1' in self.request.GET: + context['periodo'] = ( + self.request.GET['data_inicio_0'] + + ' - ' + self.request.GET['data_inicio_1']) + parlamentares = [] + total_sessao = 0 + total_ordem = 0 + for p in Parlamentar.objects.all(): + parlamentar = {} + qtde_sessao = 0 + qtde_ordem = 0 + + for s in context['object_list']: + if SessaoPlenariaPresenca.objects.filter( + sessao_plenaria_id=s.id, + parlamentar_id=p.id).exists(): + qtde_sessao += 1 + total_sessao += 1 + if PresencaOrdemDia.objects.filter( + sessao_plenaria_id=s.id, + parlamentar_id=p.id).exists(): + qtde_ordem += 1 + total_ordem += 1 + + if qtde_sessao > 1 or qtde_ordem > 1: + parlamentar = { + 'nome': p.nome_parlamentar, + 'partido': p.filiacao_set.first().partido.sigla, + 'qtde_sessao': qtde_sessao, + 'qtde_ordem': qtde_ordem + } + parlamentares.append(parlamentar) + context['total_ordem'] = total_ordem + context['total_sessao'] = total_sessao + context['parlamentares'] = parlamentares + # =================================================================== qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' return context diff --git a/sapl/templates/base/RelatorioPresencaSessao_filter.html b/sapl/templates/base/RelatorioPresencaSessao_filter.html index 8d0321210..220fe9b01 100644 --- a/sapl/templates/base/RelatorioPresencaSessao_filter.html +++ b/sapl/templates/base/RelatorioPresencaSessao_filter.html @@ -18,10 +18,12 @@ {% trans 'Fazer nova pesquisa' %}



+ PERÍODO: {{periodo}}
+ TOTAIS NO PERÍODO - SESSÕES: {{total_sessao}} - ORDENS DO DIA: {{total_ordem}} - + @@ -33,13 +35,15 @@ - - - - - - - + {% for p in parlamentares %} + + + + + + + + {% endfor %}
Nome Parlamentar / PartidoNome Parlamentar | Partido Sessão Ordem do Dia
Nome Teste | Partido Teste1511%116%
{{p.nome}} | {{p.partido}}{{p.qtde_sessao}}--{{p.qtde_ordem}}--
{% endif %} From 0860e5c1b656263f9e2215366398a2d785c3f6cf Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Mon, 5 Sep 2016 10:54:41 -0300 Subject: [PATCH 09/41] Conserta partido --- sapl/base/views.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index f066e5aa6..0d66f8037 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -45,7 +45,7 @@ class RelatorioPresencaSessaoView(FilterView): parlamentares = [] total_sessao = 0 total_ordem = 0 - for p in Parlamentar.objects.all(): + for p in Parlamentar.objects.filter(ativo=True): parlamentar = {} qtde_sessao = 0 qtde_ordem = 0 @@ -62,10 +62,12 @@ class RelatorioPresencaSessaoView(FilterView): qtde_ordem += 1 total_ordem += 1 - if qtde_sessao > 1 or qtde_ordem > 1: + if qtde_sessao >= 1 or qtde_ordem >= 1: parlamentar = { 'nome': p.nome_parlamentar, - 'partido': p.filiacao_set.first().partido.sigla, + 'partido': ( + p.filiacao_set.first().partido.sigla + if p.filiacao_set.first() else 'Sem Partido'), 'qtde_sessao': qtde_sessao, 'qtde_ordem': qtde_ordem } From de6bd0c6a34019db34cea1ec6674005a83fef1bf Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Mon, 5 Sep 2016 11:24:08 -0300 Subject: [PATCH 10/41] =?UTF-8?q?Adiciona=20porcetagem=20de=20presen=C3=A7?= =?UTF-8?q?a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 14 ++++++++++++++ .../base/RelatorioPresencaSessao_filter.html | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index 0d66f8037..c3acdda65 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -30,6 +30,17 @@ class RelatorioPresencaSessaoView(FilterView): filterset_class = RelatorioPresencaSessaoFilterSet template_name = 'base/RelatorioPresencaSessao_filter.html' + def calcular_porcentagem_presenca(self, + parlamentares, + total_sessao, + total_ordem): + for p in parlamentares: + p.update({ + 'porc_sessao': round(p['qtde_sessao'] * 100 / total_sessao, 1), + 'porc_ordem': round(p['qtde_ordem'] * 100 / total_ordem, 1) + }) + return parlamentares + def get_context_data(self, **kwargs): context = super(RelatorioPresencaSessaoView, self).get_context_data(**kwargs) @@ -72,6 +83,9 @@ class RelatorioPresencaSessaoView(FilterView): 'qtde_ordem': qtde_ordem } parlamentares.append(parlamentar) + self.calcular_porcentagem_presenca(parlamentares, + total_sessao, + total_ordem) context['total_ordem'] = total_ordem context['total_sessao'] = total_sessao context['parlamentares'] = parlamentares diff --git a/sapl/templates/base/RelatorioPresencaSessao_filter.html b/sapl/templates/base/RelatorioPresencaSessao_filter.html index 220fe9b01..5d38671bd 100644 --- a/sapl/templates/base/RelatorioPresencaSessao_filter.html +++ b/sapl/templates/base/RelatorioPresencaSessao_filter.html @@ -39,9 +39,9 @@ {{p.nome}} | {{p.partido}} {{p.qtde_sessao}} - -- + {{p.porc_sessao}} {{p.qtde_ordem}} - -- + {{p.porc_ordem}} {% endfor %} From da25d214b4a8e8a28fc97eb6c29beaa628e7f20e Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Mon, 5 Sep 2016 13:37:14 -0300 Subject: [PATCH 11/41] Melhora query --- sapl/base/views.py | 76 ++++++++++--------- .../base/RelatorioPresencaSessao_filter.html | 2 +- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index c3acdda65..f54cd2e84 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -1,3 +1,5 @@ +from itertools import chain + from django.contrib.auth.mixins import PermissionRequiredMixin from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect @@ -34,10 +36,11 @@ class RelatorioPresencaSessaoView(FilterView): parlamentares, total_sessao, total_ordem): - for p in parlamentares: - p.update({ - 'porc_sessao': round(p['qtde_sessao'] * 100 / total_sessao, 1), - 'porc_ordem': round(p['qtde_ordem'] * 100 / total_ordem, 1) + for p in parlamentares.items(): + p[1].update({ + 'porc_sessao': round( + p[1]['qtde_sessao'] * 100 / total_sessao, 1), + 'porc_ordem': round(p[1]['qtde_ordem'] * 100 / total_ordem, 1) }) return parlamentares @@ -45,51 +48,50 @@ class RelatorioPresencaSessaoView(FilterView): context = super(RelatorioPresencaSessaoView, self).get_context_data(**kwargs) context['title'] = _('Presença dos parlamentares nas sessões') - # =================================================================== + # ===================================================================== # FIXME: Pensar em melhor forma de verificar se formulário está sendo # submetido. if 'salvar' in self.request.GET: - if 'data_inicio_0' and 'data_inicio_1' in self.request.GET: - context['periodo'] = ( - self.request.GET['data_inicio_0'] + - ' - ' + self.request.GET['data_inicio_1']) - parlamentares = [] + qs1 = SessaoPlenariaPresenca.objects.filter( + parlamentar__ativo=True, + sessao_plenaria_id__in=context['object_list']) + qs2 = PresencaOrdemDia.objects.filter( + parlamentar__ativo=True, + sessao_plenaria_id__in=context['object_list']) + q = list(chain(list(qs1)+list(qs2))) + + parlamentares = {} total_sessao = 0 total_ordem = 0 - for p in Parlamentar.objects.filter(ativo=True): - parlamentar = {} - qtde_sessao = 0 - qtde_ordem = 0 - - for s in context['object_list']: - if SessaoPlenariaPresenca.objects.filter( - sessao_plenaria_id=s.id, - parlamentar_id=p.id).exists(): - qtde_sessao += 1 - total_sessao += 1 - if PresencaOrdemDia.objects.filter( - sessao_plenaria_id=s.id, - parlamentar_id=p.id).exists(): - qtde_ordem += 1 - total_ordem += 1 - - if qtde_sessao >= 1 or qtde_ordem >= 1: - parlamentar = { - 'nome': p.nome_parlamentar, + for i in q: + pid = i.parlamentar.id + if not pid in parlamentares: + parlamentares[pid] = { + 'nome': i.parlamentar.nome_parlamentar, 'partido': ( - p.filiacao_set.first().partido.sigla - if p.filiacao_set.first() else 'Sem Partido'), - 'qtde_sessao': qtde_sessao, - 'qtde_ordem': qtde_ordem - } - parlamentares.append(parlamentar) + i.parlamentar.filiacao_set.first().partido.sigla + if i.parlamentar.filiacao_set.first() + else 'Sem Partido'), + 'qtde_ordem': 0, + 'qtde_sessao': 0} + if isinstance(i, SessaoPlenariaPresenca): + parlamentares[pid]['qtde_sessao'] += 1 + total_sessao += 1 + elif isinstance(i, PresencaOrdemDia): + parlamentares[pid]['qtde_ordem'] += 1 + total_ordem += 1 + self.calcular_porcentagem_presenca(parlamentares, total_sessao, total_ordem) + sorted(parlamentares.items(), key=lambda x: x[1]['nome']) + context['total_ordem'] = total_ordem context['total_sessao'] = total_sessao context['parlamentares'] = parlamentares - # =================================================================== + context['periodo'] = (self.request.GET['data_inicio_0'] + + ' - ' + self.request.GET['data_inicio_1']) + # ===================================================================== qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' return context diff --git a/sapl/templates/base/RelatorioPresencaSessao_filter.html b/sapl/templates/base/RelatorioPresencaSessao_filter.html index 5d38671bd..71377846c 100644 --- a/sapl/templates/base/RelatorioPresencaSessao_filter.html +++ b/sapl/templates/base/RelatorioPresencaSessao_filter.html @@ -35,7 +35,7 @@ - {% for p in parlamentares %} + {% for pid, p in parlamentares.items %} {{p.nome}} | {{p.partido}} {{p.qtde_sessao}} From bb2ce0f2316ccfc8ac16ba8e09ad0e9135548f62 Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Thu, 8 Sep 2016 16:26:58 -0300 Subject: [PATCH 12/41] =?UTF-8?q?Muda=20forma=20como=20=C3=A9=20calculado?= =?UTF-8?q?=20o=20total=20de=20sess=C3=B5es=20e=20ordens=20do=20dia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index f54cd2e84..fb6b89a41 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -11,7 +11,7 @@ from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, CrudDetailView, CrudUpdateView) from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.parlamentares.models import Parlamentar -from sapl.sessao.models import (PresencaOrdemDia, SessaoPlenaria, +from sapl.sessao.models import (OrdemDia, PresencaOrdemDia, SessaoPlenaria, SessaoPlenariaPresenca) from sapl.utils import permissao_tb_aux @@ -61,8 +61,17 @@ class RelatorioPresencaSessaoView(FilterView): q = list(chain(list(qs1)+list(qs2))) parlamentares = {} - total_sessao = 0 - total_ordem = 0 + + total_sessao = SessaoPlenariaPresenca.objects.filter( + sessao_plenaria_id__in=context['object_list']) + total_sessao = len(total_sessao.order_by().values_list( + 'sessao_plenaria_id', flat=True).distinct()) + + total_ordem = PresencaOrdemDia.objects.filter( + sessao_plenaria_id__in=context['object_list']) + total_ordem = len(total_ordem.order_by().values_list( + 'sessao_plenaria_id', flat=True).distinct()) + for i in q: pid = i.parlamentar.id if not pid in parlamentares: @@ -76,10 +85,8 @@ class RelatorioPresencaSessaoView(FilterView): 'qtde_sessao': 0} if isinstance(i, SessaoPlenariaPresenca): parlamentares[pid]['qtde_sessao'] += 1 - total_sessao += 1 elif isinstance(i, PresencaOrdemDia): parlamentares[pid]['qtde_ordem'] += 1 - total_ordem += 1 self.calcular_porcentagem_presenca(parlamentares, total_sessao, From d137da183111a22f9865255ac684437cea5dd214 Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Thu, 8 Sep 2016 17:45:40 -0300 Subject: [PATCH 13/41] =?UTF-8?q?Muda=20query=20do=20relatorio=20de=20pres?= =?UTF-8?q?en=C3=A7a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 88 ++++++++----------- .../base/RelatorioPresencaSessao_filter.html | 16 ++-- 2 files changed, 43 insertions(+), 61 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index fb6b89a41..c5b41219f 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -2,6 +2,7 @@ from itertools import chain from django.contrib.auth.mixins import PermissionRequiredMixin from django.core.urlresolvers import reverse +from django.db.models import Count, Q from django.http import HttpResponseRedirect from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import TemplateView @@ -35,13 +36,10 @@ class RelatorioPresencaSessaoView(FilterView): def calcular_porcentagem_presenca(self, parlamentares, total_sessao, - total_ordem): - for p in parlamentares.items(): - p[1].update({ - 'porc_sessao': round( - p[1]['qtde_sessao'] * 100 / total_sessao, 1), - 'porc_ordem': round(p[1]['qtde_ordem'] * 100 / total_ordem, 1) - }) + total_ordemdia): + for p in parlamentares: + p.sessao_porc = round(p.sessao_count * 100 / total_sessao, 1) + p.ordemdia_porc = round(p.ordemdia_count * 100 / total_ordemdia, 1) return parlamentares def get_context_data(self, **kwargs): @@ -49,53 +47,37 @@ class RelatorioPresencaSessaoView(FilterView): self).get_context_data(**kwargs) context['title'] = _('Presença dos parlamentares nas sessões') # ===================================================================== - # FIXME: Pensar em melhor forma de verificar se formulário está sendo - # submetido. if 'salvar' in self.request.GET: - qs1 = SessaoPlenariaPresenca.objects.filter( - parlamentar__ativo=True, - sessao_plenaria_id__in=context['object_list']) - qs2 = PresencaOrdemDia.objects.filter( - parlamentar__ativo=True, - sessao_plenaria_id__in=context['object_list']) - q = list(chain(list(qs1)+list(qs2))) - - parlamentares = {} - - total_sessao = SessaoPlenariaPresenca.objects.filter( - sessao_plenaria_id__in=context['object_list']) - total_sessao = len(total_sessao.order_by().values_list( - 'sessao_plenaria_id', flat=True).distinct()) - - total_ordem = PresencaOrdemDia.objects.filter( - sessao_plenaria_id__in=context['object_list']) - total_ordem = len(total_ordem.order_by().values_list( - 'sessao_plenaria_id', flat=True).distinct()) - - for i in q: - pid = i.parlamentar.id - if not pid in parlamentares: - parlamentares[pid] = { - 'nome': i.parlamentar.nome_parlamentar, - 'partido': ( - i.parlamentar.filiacao_set.first().partido.sigla - if i.parlamentar.filiacao_set.first() - else 'Sem Partido'), - 'qtde_ordem': 0, - 'qtde_sessao': 0} - if isinstance(i, SessaoPlenariaPresenca): - parlamentares[pid]['qtde_sessao'] += 1 - elif isinstance(i, PresencaOrdemDia): - parlamentares[pid]['qtde_ordem'] += 1 - - self.calcular_porcentagem_presenca(parlamentares, - total_sessao, - total_ordem) - sorted(parlamentares.items(), key=lambda x: x[1]['nome']) - - context['total_ordem'] = total_ordem - context['total_sessao'] = total_sessao - context['parlamentares'] = parlamentares + where = context['object_list'].query.where + _range = where.children[0].rhs + + sufixo = 'sessao_plenaria__data_inicio__range' + param0 = {'%s' % sufixo: _range} + param1 = {'presencaordemdia__%s' % sufixo: _range} + param2 = {'sessaoplenariapresenca__%s' % sufixo: _range} + + pls = Parlamentar.objects.filter( + Q(**param1) & Q(**param2)).annotate( + sessao_count=Count( + 'sessaoplenariapresenca__sessao_plenaria__data_inicio', + distinct=True), + ordemdia_count=Count( + 'presencaordemdia__sessao_plenaria__data_inicio', + distinct=True), + sessao_porc=Count(0), + ordemdia_porc=Count(0)) + + total_ordemdia = OrdemDia.objects.order_by( + 'sessao_plenaria').filter(**param0).distinct( + 'sessao_plenaria').count() + + self.calcular_porcentagem_presenca(pls, + context['object_list'].count(), + total_ordemdia) + + context['total_ordemdia'] = total_ordemdia + context['total_sessao'] = context['object_list'].count() + context['parlamentares'] = pls context['periodo'] = (self.request.GET['data_inicio_0'] + ' - ' + self.request.GET['data_inicio_1']) # ===================================================================== diff --git a/sapl/templates/base/RelatorioPresencaSessao_filter.html b/sapl/templates/base/RelatorioPresencaSessao_filter.html index 71377846c..8aeae7aa6 100644 --- a/sapl/templates/base/RelatorioPresencaSessao_filter.html +++ b/sapl/templates/base/RelatorioPresencaSessao_filter.html @@ -19,11 +19,11 @@



PERÍODO: {{periodo}}
- TOTAIS NO PERÍODO - SESSÕES: {{total_sessao}} - ORDENS DO DIA: {{total_ordem}} + TOTAIS NO PERÍODO - SESSÕES: {{total_sessao}} - ORDENS DO DIA: {{total_ordemdia}} - + @@ -35,13 +35,13 @@ - {% for pid, p in parlamentares.items %} + {% for p in parlamentares %} - - - - - + + + + + {% endfor %} From 8813fc1fc6a558319b343dd569c37b6d755c921a Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Fri, 9 Sep 2016 13:33:38 -0300 Subject: [PATCH 14/41] =?UTF-8?q?Torna=20os=20campo=20de=20periodo=20obrig?= =?UTF-8?q?at=C3=B3rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/forms.py | 1 + sapl/base/views.py | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sapl/base/forms.py b/sapl/base/forms.py index fc37bbc3d..2e6a65bef 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -56,6 +56,7 @@ class RelatorioPresencaSessaoFilterSet(django_filters.FilterSet): *args, **kwargs) self.filters['data_inicio'].label = 'Período (Inicial - Final)' + self.form.fields['data_inicio'].required = True row1 = to_row([('data_inicio', 12)]) diff --git a/sapl/base/views.py b/sapl/base/views.py index c5b41219f..2f26e67c8 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -46,6 +46,11 @@ class RelatorioPresencaSessaoView(FilterView): context = super(RelatorioPresencaSessaoView, self).get_context_data(**kwargs) context['title'] = _('Presença dos parlamentares nas sessões') + + # Verifica se os campos foram preenchidos + if not self.filterset.form.is_valid(): + return context + # ===================================================================== if 'salvar' in self.request.GET: where = context['object_list'].query.where @@ -71,15 +76,17 @@ class RelatorioPresencaSessaoView(FilterView): 'sessao_plenaria').filter(**param0).distinct( 'sessao_plenaria').count() - self.calcular_porcentagem_presenca(pls, - context['object_list'].count(), - total_ordemdia) + self.calcular_porcentagem_presenca( + pls, + context['object_list'].count(), + total_ordemdia) context['total_ordemdia'] = total_ordemdia context['total_sessao'] = context['object_list'].count() context['parlamentares'] = pls - context['periodo'] = (self.request.GET['data_inicio_0'] + - ' - ' + self.request.GET['data_inicio_1']) + context['periodo'] = ( + self.request.GET['data_inicio_0'] + + ' - ' + self.request.GET['data_inicio_1']) # ===================================================================== qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' From d1a1d102046217b1e103a91b697e4618d4604fa1 Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Fri, 9 Sep 2016 14:12:30 -0300 Subject: [PATCH 15/41] Remove filtro de data na contagem de ordens do dia --- sapl/base/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index 2f26e67c8..bb2161de2 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -67,7 +67,7 @@ class RelatorioPresencaSessaoView(FilterView): 'sessaoplenariapresenca__sessao_plenaria__data_inicio', distinct=True), ordemdia_count=Count( - 'presencaordemdia__sessao_plenaria__data_inicio', + 'presencaordemdia__sessao_plenaria', distinct=True), sessao_porc=Count(0), ordemdia_porc=Count(0)) From e6e1214c88a841f0cb3662054a48f7bc06600c36 Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Fri, 9 Sep 2016 14:45:55 -0300 Subject: [PATCH 16/41] =?UTF-8?q?Adiciona=20pesquisa=20de=20sess=C3=B5es?= =?UTF-8?q?=20com=20ata=20por=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/forms.py | 30 +++++++++++++++ sapl/base/urls.py | 5 ++- sapl/base/views.py | 23 ++++++++++- sapl/templates/base/RelatorioAtas_filter.html | 38 +++++++++++++++++++ sapl/templates/base/relatorios_list.html | 2 +- sapl/templates/sessao/pauta_sessao_list.html | 6 --- 6 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 sapl/templates/base/RelatorioAtas_filter.html diff --git a/sapl/base/forms.py b/sapl/base/forms.py index 2e6a65bef..595814d34 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -38,6 +38,36 @@ class RangeWidgetOverride(forms.MultiWidget): return ''.join(rendered_widgets) +class RelatorioAtasFilterSet(django_filters.FilterSet): + + filter_overrides = {models.DateField: { + 'filter_class': django_filters.DateFromToRangeFilter, + 'extra': lambda f: { + 'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')), + 'widget': RangeWidgetOverride} + }} + + class Meta: + model = SessaoPlenaria + fields = ['data_inicio'] + + def __init__(self, *args, **kwargs): + super(RelatorioAtasFilterSet, self).__init__( + *args, **kwargs) + + self.filters['data_inicio'].label = 'Período (Inicial - Final)' + self.form.fields['data_inicio'].required = True + + row1 = to_row([('data_inicio', 12)]) + + self.form.helper = FormHelper() + self.form.helper.form_method = 'GET' + self.form.helper.layout = Layout( + Fieldset(_('Atas das Sessões Plenárias'), + row1, form_actions(save_label='Pesquisar')) + ) + + class RelatorioPresencaSessaoFilterSet(django_filters.FilterSet): filter_overrides = {models.DateField: { diff --git a/sapl/base/urls.py b/sapl/base/urls.py index 88ab866b1..60804abea 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -4,7 +4,7 @@ from django.views.generic.base import TemplateView from .apps import AppConfig from .forms import LoginForm -from .views import (CasaLegislativaCrud, HelpView, +from .views import (CasaLegislativaCrud, HelpView, RelatorioAtasView, RelatorioHistoricoTramitacaoView, RelatorioMateriasPorAnoAutorTipoView, RelatorioMateriasPorAutorView, @@ -43,5 +43,8 @@ urlpatterns = [ url(r'^relatorio/presenca$', RelatorioPresencaSessaoView.as_view(), name='presenca_sessao'), + url(r'^relatorio/atas$', + RelatorioAtasView.as_view(), + name='atas'), ] diff --git a/sapl/base/views.py b/sapl/base/views.py index bb2161de2..6c51cf22a 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -16,7 +16,8 @@ from sapl.sessao.models import (OrdemDia, PresencaOrdemDia, SessaoPlenaria, SessaoPlenariaPresenca) from sapl.utils import permissao_tb_aux -from .forms import (CasaLegislativaForm, RelatorioHistoricoTramitacaoFilterSet, +from .forms import (CasaLegislativaForm, RelatorioAtasFilterSet, + RelatorioHistoricoTramitacaoFilterSet, RelatorioMateriasPorAnoAutorTipoFilterSet, RelatorioMateriasPorAutorFilterSet, RelatorioMateriasTramitacaoilterSet, @@ -28,6 +29,26 @@ def get_casalegislativa(): return CasaLegislativa.objects.first() +class RelatorioAtasView(FilterView): + model = SessaoPlenaria + filterset_class = RelatorioAtasFilterSet + template_name = 'base/RelatorioAtas_filter.html' + + def get_context_data(self, **kwargs): + context = super(RelatorioAtasView, + self).get_context_data(**kwargs) + context['title'] = _('Atas das Sessões Plenárias') + + # Verifica se os campos foram preenchidos + if not self.filterset.form.is_valid(): + return context + + context['object_list'] = context['object_list'].exclude(upload_ata='') + qr = self.request.GET.copy() + context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + return context + + class RelatorioPresencaSessaoView(FilterView): model = SessaoPlenaria filterset_class = RelatorioPresencaSessaoFilterSet diff --git a/sapl/templates/base/RelatorioAtas_filter.html b/sapl/templates/base/RelatorioAtas_filter.html new file mode 100644 index 000000000..e83971d42 --- /dev/null +++ b/sapl/templates/base/RelatorioAtas_filter.html @@ -0,0 +1,38 @@ +{% extends "crud/list.html" %} +{% load i18n %} +{% load crispy_forms_tags staticfiles %} + +{% block base_content %} + {% if not filter_url %} + {% crispy filter.form %} + {% endif %} + + {% if filter_url %} + +


+ {% if object_list|length > 0 %} +
Nome Parlamentar | PartidoNome Parlamentar / Partido Sessão Ordem do Dia
{{p.nome}} | {{p.partido}}{{p.qtde_sessao}}{{p.porc_sessao}}{{p.qtde_ordem}}{{p.porc_ordem}}{{p}} / {{p.filiacao_set.first.partido.sigla|default:"Sem Partido"}}{{p.sessao_count}}{{p.sessao_porc}}{{p.ordemdia_count}}{{p.ordemdia_porc}}
+ + + + + + + + {% for sessao in object_list %} + + + + + {% endfor %} + +
SessãoAta
{{sessao}} + +
+ {% else %} +

Nenhum sessão com ata foi encontrada!

+ {% endif %} + {% endif %} +{% endblock base_content %} diff --git a/sapl/templates/base/relatorios_list.html b/sapl/templates/base/relatorios_list.html index ade7fa1f0..c7e47bd69 100644 --- a/sapl/templates/base/relatorios_list.html +++ b/sapl/templates/base/relatorios_list.html @@ -29,7 +29,7 @@ Presença dos parlamentares nas sessões plenárias. - Atas + Atas Atas de Sessão Plenária. diff --git a/sapl/templates/sessao/pauta_sessao_list.html b/sapl/templates/sessao/pauta_sessao_list.html index 66566d20b..ce3e5c77b 100644 --- a/sapl/templates/sessao/pauta_sessao_list.html +++ b/sapl/templates/sessao/pauta_sessao_list.html @@ -9,7 +9,6 @@ - @@ -17,9 +16,6 @@ {% for sessao in page_obj %} -
Data Sessão PDF
- {{sessao.data_inicio}} - {{sessao.hora_inicio}} - {{sessao}} @@ -29,6 +25,4 @@
{% endif %} - - {% include "paginacao.html" %} {% endblock %} From 23b435540ed7ed7deb909e4348a1ca56233b9380 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Mon, 12 Sep 2016 10:03:50 -0300 Subject: [PATCH 17/41] Fix #564 --- sapl/base/views.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index ca5d735a3..66267d3e6 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -136,17 +136,12 @@ class CasaLegislativaCrud(Crud): list_field_names = ['codigo', 'nome', 'sigla'] def has_permission(self): - if self.request.user.is_superuser: - return True - else: - return False + return permissao_tb_aux(self) class CreateView(PermissionRequiredMixin, CrudCreateView): - permission_required = {'base.add_casa_legislativa'} form_class = CasaLegislativaForm class UpdateView(PermissionRequiredMixin, CrudUpdateView): - permission_required = {'base.change_casalegislativa'} form_class = CasaLegislativaForm class DetailView(CrudDetailView): From ab56da9604daf8debed9dea27bcadf7aa48f891c Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Mon, 12 Sep 2016 10:16:06 -0300 Subject: [PATCH 18/41] Fix #567 --- sapl/comissoes/views.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py index d4333f63d..81c978081 100644 --- a/sapl/comissoes/views.py +++ b/sapl/comissoes/views.py @@ -3,7 +3,7 @@ from django.core.urlresolvers import reverse from django.views.generic import ListView from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, - CrudDeleteView, CrudUpdateView) + CrudDeleteView, CrudListView, CrudUpdateView) from sapl.crud.masterdetail import MasterDetailCrud from sapl.materia.models import Tramitacao from sapl.utils import permissao_tb_aux, permissoes_comissoes @@ -137,6 +137,10 @@ class ComissaoCrud(Crud): class DeleteView(PermissionRequiredMixin, CrudDeleteView): permission_required = permissoes_comissoes() + class ListView(PermissionRequiredMixin, CrudListView): + permission_required = permissoes_comissoes() + ordering = ['-ativa', 'sigla'] + class BaseMixin(CrudBaseMixin): list_field_names = ['nome', 'sigla', 'tipo', 'data_criacao', 'ativa'] From 32b9e61093c8208c5e0a221b7c853fcccfcdde7e Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Mon, 12 Sep 2016 13:04:42 -0300 Subject: [PATCH 19/41] =?UTF-8?q?Conserta=20a=20l=C3=B3gica=20das=20permis?= =?UTF-8?q?soes=20de=20proposicoes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/materia/views.py | 54 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 239384030..f5005b74f 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -4,6 +4,7 @@ from string import ascii_letters, digits from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Button +from django.db.models import Q from django.conf import settings from django.contrib import messages from django.contrib.auth.mixins import PermissionRequiredMixin @@ -31,7 +32,7 @@ from sapl.crud.masterdetail import MasterDetailCrud from sapl.norma.models import LegislacaoCitada from sapl.utils import (autor_label, autor_modal, gerar_hash_arquivo, get_base_url, permissao_tb_aux, permissoes_autor, - permissoes_materia) + permissoes_materia, permissoes_protocoloadm) from .forms import (AcompanhamentoMateriaForm, AnexadaForm, AutorForm, AutoriaForm, ConfirmarProposicaoForm, DespachoInicialForm, @@ -243,11 +244,12 @@ class UnidadeTramitacaoCrud(Crud): permission_required = permissoes_materia() -class ProposicaoDevolvida(ListView): +class ProposicaoDevolvida(PermissionRequiredMixin, ListView): template_name = 'materia/prop_devolvidas_list.html' model = Proposicao ordering = ['data_envio'] paginate_by = 10 + permission_required = permissoes_protocoloadm() def get_queryset(self): return Proposicao.objects.filter( @@ -265,11 +267,12 @@ class ProposicaoDevolvida(ListView): return context -class ProposicaoPendente(ListView): +class ProposicaoPendente(PermissionRequiredMixin, ListView): template_name = 'materia/prop_pendentes_list.html' model = Proposicao ordering = ['data_envio', 'autor', 'tipo', 'descricao'] paginate_by = 10 + permission_required = permissoes_protocoloadm() def get_queryset(self): return Proposicao.objects.filter( @@ -287,11 +290,12 @@ class ProposicaoPendente(ListView): return context -class ProposicaoRecebida(ListView): +class ProposicaoRecebida(PermissionRequiredMixin, ListView): template_name = 'materia/prop_recebidas_list.html' model = Proposicao ordering = ['data_envio'] paginate_by = 10 + permission_required = permissoes_protocoloadm() def get_queryset(self): return Proposicao.objects.filter( @@ -309,9 +313,10 @@ class ProposicaoRecebida(ListView): return context -class ReceberProposicao(CreateView): +class ReceberProposicao(PermissionRequiredMixin, CreateView): template_name = "materia/receber_proposicao.html" form_class = ReceberProposicaoForm + permission_required = permissoes_protocoloadm() def get_context_data(self, **kwargs): context = super(ReceberProposicao, self).get_context_data(**kwargs) @@ -341,9 +346,10 @@ class ReceberProposicao(CreateView): return reverse('sapl.materia:receber-proposicao') -class ConfirmarProposicao(CreateView): +class ConfirmarProposicao(PermissionRequiredMixin, CreateView): template_name = "materia/confirmar_proposicao.html" form_class = ConfirmarProposicaoForm + permission_required = permissoes_protocoloadm() def get_context_data(self, **kwargs): context = super(ConfirmarProposicao, self).get_context_data(**kwargs) @@ -440,7 +446,8 @@ class ProposicaoCrud(Crud): proposicao = Proposicao.objects.get( id=self.kwargs['pk'], autor__user_id=self.request.user.id) - if not proposicao.data_recebimento: + if (not proposicao.data_recebimento or + proposicao.data_devolucao): return True else: msg = _('Essa proposição já foi recebida. ' + @@ -480,32 +487,59 @@ class ProposicaoCrud(Crud): obj.data_recebimento = 'Não recebida' else: obj.data_recebimento = obj.data_recebimento.strftime( - "%d/%m/%Y %H:%M") + "%d/%m/%Y %H:%M") return [self._as_row(obj) for obj in object_list] def get_queryset(self): + # Só tem acesso as Proposicoes criadas por ele que ainda nao foram + # recebidas ou foram devolvidas lista = Proposicao.objects.filter( autor__user_id=self.request.user.id) + lista = lista.filter( + Q(data_recebimento__isnull=True) | + Q(data_devolucao__isnull=False)) + return lista class DeleteView(PermissionRequiredMixin, CrudDeleteView): permission_required = {'materia.delete_proposicao'} + def has_permission(self): + perms = self.get_permission_required() + if self.request.user.has_perms(perms): + if (Proposicao.objects.filter( + id=self.kwargs['pk'], + autor__user_id=self.request.user.id).exists()): + return True + else: + return False + else: + return False + def delete(self, request, *args, **kwargs): proposicao = Proposicao.objects.get(id=self.kwargs['pk']) - if not proposicao.data_envio: + if not proposicao.data_envio or proposicao.data_devolucao: proposicao.delete() return HttpResponseRedirect( reverse('sapl.materia:proposicao_list')) - else: + + elif not proposicao.data_recebimento: proposicao.data_envio = None proposicao.save() return HttpResponseRedirect( reverse('sapl.materia:proposicao_detail', kwargs={'pk': proposicao.pk})) + else: + msg = _('Essa proposição já foi recebida. ' + + 'Não pode mais ser excluída/recuperada') + messages.add_message(self.request, messages.ERROR, msg) + return HttpResponseRedirect( + reverse('sapl.materia:proposicao_detail', + kwargs={'pk': proposicao.pk})) + class ReciboProposicaoView(TemplateView): template_name = "materia/recibo_proposicao.html" From 005ca63f41560d41fd34c9a810e271738a50e1ae Mon Sep 17 00:00:00 2001 From: Eduardo Edson Batista Cordeiro Alves Date: Mon, 12 Sep 2016 14:54:14 -0300 Subject: [PATCH 20/41] Fix #571 --- sapl/templates/base.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sapl/templates/base.html b/sapl/templates/base.html index df70b2252..eebffba2e 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -42,13 +42,12 @@