From 6e0c6ada02812c23a4fadc2da0e0b5748f3503c4 Mon Sep 17 00:00:00 2001
From: Victor Fabre
$r(l6Oon1-&{YfEzvJ1pS5Yno!-q~{Wo!qX}6Yt zXz0REB1gBH)w}I=^fypT0|b*_br`d?F;dTP0k8-v9yD_uO{>{6CRYal0Ei#}015yc0CQt#Wo=HMpCCgzPli(_am~C zOgj@_EP%j=-TihK3!wGOJeTmE8!NPG$KN-uV)*4cYJGKi8Nr=MxUxJ2r@>7*bPAT> zzk!~(88aMib*WP3a3*}y8Qgvg*yIL(wBn!* nhIK$Ne~J<@=6H9GiFkuGF-J- z7?DjK=$S(0rlM#>FeDuYx3wI$LiH=6hHrEk6j;+WnBW5btV{%t8dni~LnGpU@GbuK zXIS9eoGn0U2c_j}zU3 z=ZeS8=4>`=FfVCCo2*$Y*1SVg_6AQcN!kehP?B4V=6P2NgC-p>fE6f9!p10}WHX}6 zlj5ny)n^9ntFjBQf$M04la-l&YQa$5^#N!orXcPNpgV}+*Uq3jxQO6&clf;j#}Hn3 zUcKt{hTW$F=)Zy|{oYM?*zNbQbqk%|8~Cl;ySV_4M#5G2yf7p^iYUl{JVhpJr>U1G zr=Yeicp@euL8VkyvW!Ef(YY1*M8QoiERkqYxHLjH$c6KsV|O)bM3 J93r}yNX@peZmH{jXi}5QuY=uT&;77cT_P=;Xg9v^7#{h}AwYDKEjaA? zAmPXfJ1|6+V9aQ9B&^_$g7VM=g8*}h@7^R8vrZVz5>ENG;`K1G_B>`!gxn6-_FS^h zSb*raXYzjreB}{;_FR`ZYYAj(dx29 jE6E&DTv6jabVV2RdLI#FC4%F`LwQ)Z`|pwGB|j-6YXdRrjJ=Wdj7 zEXA1IoIk`b!J37(zN+i0#Q5^?87pvyy}F98L%M7+%*Km ~<`0*PbuG(k`su zawTZM=2nZ5hn3;5{(8$2tVb8Mra@%scIN5g)_2zvKx7Kb+9w$JHRYJ8Q<{Kd{m+J* zyJfamW(?d>d`-yb42u}7CudXzN{N+{T= NPoWm=hGuHvg=B3)p3ip0lXh}7>!DDtR4sVj z!f1zorz=Wf^mCQ`w}Yr(RCi6dQP=l8Go~C}l`QXiwgL^4BhT^3he;EEv6Sv{su0-m z&BtqYJYs+&q4~iZ_5lh0OFQ;w+*iLu$d?FtaD?nBw)SovGy7Repx0A@ht`56{BY#m zLj{!?mLF8$fjeCAz|T{)^`4<7TW+2UMZE)mT)Z9sfNeHkwZH#ytt$Iy`SBC!d=F}Q zn(@(beh)b4Lo1sjzIx9@d1~5gH2Dqp*Zw=XuDYCXoW{Il##z#E+1o4gF*mFJ1p8DN zjXhVZo@(S~Uq?#cwuKa~uSoDGQ@R->tW((?`8nydk3Ngjej#j=u%ppN&G04^)nQkE zzYo!t87{-NF7`uEinKm{*H1@VhwqKE_vWo*b&a!p?Av!fuV1tNLY4F=aSvVW2>8P_ z*#|xf?{A|TJiIpS#fBp$puKtLrsHf|SJ$3_{y;c!9Nwrx5u_pIj@}>@_b&mQUak{P zm&he$RVbCfNK{xK)$cv6stb3EYmv5Onyc2<67}=v?-a=B^p--qT6Q+&{w)?OV<{5h zsu`p`z1gy{rIo{K>ExP>&}!n3 v#v3GLk%=@9Zjp*GbUFD004-SH+3YFRCX1UaCImF bnUk4yQvq0$?R8QCW0OF3HwF-M00000<(t}` diff --git a/solr/sapl_configset/conf/schema.xml b/solr/sapl_configset/conf/schema.xml index e230533e5..7bf3fc428 100644 --- a/solr/sapl_configset/conf/schema.xml +++ b/solr/sapl_configset/conf/schema.xml @@ -151,7 +151,7 @@ - + From bf93a52e154c309d99606c38fbb455c6d81f63d8 Mon Sep 17 00:00:00 2001 From: Ulysses Lara Date: Wed, 20 Mar 2019 13:33:40 -0300 Subject: [PATCH 16/39] Fix #2639 (#2641) --- sapl/templates/relatorios/relatorio_ata.html | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sapl/templates/relatorios/relatorio_ata.html b/sapl/templates/relatorios/relatorio_ata.html index 581343677..df927ba7f 100644 --- a/sapl/templates/relatorios/relatorio_ata.html +++ b/sapl/templates/relatorios/relatorio_ata.html @@ -50,7 +50,7 @@ {% if assinatura_mesa or assinatura_presentes %} - +@@ -60,14 +60,14 @@ {% for p in assinatura_mesa %} {% if forloop.counter0|divisibleby:2 %} -
+ - ____________________ +____________________{% else %} -{{p.cargo}}: {{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}
____________________ +____________________@@ -78,15 +78,15 @@ {% for p in assinatura_presentes %} {% if forloop.counter0|divisibleby:2 %} -{{p.cargo}}: {{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}
+ - From ef62ebf35087abb6f470298a2b6dc5741df7ede8 Mon Sep 17 00:00:00 2001 From: Ulysses Lara_____________________ -{{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}
- +_____________________ +{% else %} -{{p.cargo}}: {{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}
+_____________________ -{{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}
+_____________________ +{{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}
Date: Wed, 20 Mar 2019 13:34:42 -0300 Subject: [PATCH 17/39] Adiciona contagem de materias legislativas, sessoes, parlamentares e normas juridicas (#2640) --- sapl/base/urls.py | 4 ++-- sapl/base/views.py | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/sapl/base/urls.py b/sapl/base/urls.py index 317862f18..5d12b3586 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -8,7 +8,7 @@ from django.contrib.auth.views import (password_reset, password_reset_complete, password_reset_done) from django.views.generic.base import RedirectView, TemplateView -from sapl.base.views import AutorCrud, ConfirmarEmailView, TipoAutorCrud, get_data_ultima_atualizacao +from sapl.base.views import AutorCrud, ConfirmarEmailView, TipoAutorCrud, get_estatistica from sapl.settings import EMAIL_SEND_USER, MEDIA_URL from .apps import AppConfig @@ -176,7 +176,7 @@ urlpatterns = [ ListarLegislaturaInfindavelView.as_view(), name='lista_legislatura_infindavel'), - url(r'^sistema/data_ultima_atualizacao', get_data_ultima_atualizacao), + url(r'^sistema/estatisticas', get_estatistica), # todos os sublinks de sistema devem vir acima deste url(r'^sistema/$', permission_required('base.view_tabelas_auxiliares') diff --git a/sapl/base/views.py b/sapl/base/views.py index 1afd1fee0..ee4c77fe0 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -1234,7 +1234,9 @@ def mandato_sem_data_inicio(): return Mandato.objects.filter(data_inicio_mandato__isnull=True).order_by('parlamentar') -def get_data_ultima_atualizacao(request): +def get_estatistica(request): + + json_dict = {} datas = [MateriaLegislativa.objects.all(). order_by('-data_ultima_atualizacao'). @@ -1251,7 +1253,14 @@ def get_data_ultima_atualizacao(request): max_data = max(datas) else: max_data = next(iter([i for i in datas if i is not None]), '') - return JsonResponse({'data_ultima_atualizacao': max_data}) + + json_dict["data_ultima_atualizacao"] = max_data + json_dict["num_materias_legislativas"] = MateriaLegislativa.objects.all().count() + json_dict["num_normas_juridicas "] = NormaJuridica.objects.all().count() + json_dict["num_parlamentares"] = Parlamentar.objects.all().count() + json_dict["num_sessoes_plenarias"] = SessaoPlenaria.objects.all().count() + + return JsonResponse(json_dict) class ListarMandatoSemDataInicioView(PermissionRequiredMixin, ListView): From b617f05c2566058a69428b2801a987eaf4e369dc Mon Sep 17 00:00:00 2001 From: Cesar Carvalho Date: Wed, 20 Mar 2019 13:59:17 -0300 Subject: [PATCH 18/39] HOTFIX - Corrige layout dos cronometros do painel --- sapl/templates/sessao/painel.html | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/sapl/templates/sessao/painel.html b/sapl/templates/sessao/painel.html index 1efb65854..9e1ed742b 100644 --- a/sapl/templates/sessao/painel.html +++ b/sapl/templates/sessao/painel.html @@ -26,11 +26,11 @@
-+Cronômetro do Discurso
Cronômetro do Discurso
- +
@@ -41,11 +41,11 @@
-+Cronômetro do Aparte
Cronômetro do Aparte
- +
@@ -56,11 +56,11 @@
-+Cronômetro da Questão de Ordem
Cronômetro da Questão de Ordem
- +
@@ -68,25 +68,28 @@ -
-
--+ +Cronômetro de Considerações Finais
+
+ ++Cronômetro de Considerações Finais
- +-
+
-+ +{% endblock detail_content %} From 1dd9f553dbac0a40e058c6b67ae18d7b5c1efbcf Mon Sep 17 00:00:00 2001 From: Leandro Roberto Silva-+Date: Thu, 21 Mar 2019 13:26:50 -0300 Subject: [PATCH 19/39] Fix #2559 reordenacao materia em sessao (#2646) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add sequencial_regimental no model tipo de matéria legislativa * applica pep * converte TipoMateriaCrud para classe * inclui hooks no crud list * altera ordering de TipoMateriaLegislativa * define layout diferente para detail e list * define estratégia para iniciar sequencia em tipos já existentes * add template custom para listagem de tipo de matérias * altera call hook * impl a reordenação no list dos tipos de matéria * add file migrate * autopep in sessao/views.py * ref views functions acionadas pelo botão 'Ajustar Ordenação' --- sapl/api/views.py | 20 ++- sapl/crud/base.py | 12 +- ...materialegislativa_sequencia_regimental.py | 21 +++ .../migrations/0043_auto_20190320_1749.py | 19 +++ sapl/materia/models.py | 41 +++++- sapl/materia/views.py | 93 +++++++++--- sapl/sessao/views.py | 139 ++++++++++-------- sapl/templates/materia/layouts.yaml | 6 +- .../materia/tipomaterialegislativa_list.html | 55 +++++++ 9 files changed, 322 insertions(+), 84 deletions(-) create mode 100644 sapl/materia/migrations/0042_tipomaterialegislativa_sequencia_regimental.py create mode 100644 sapl/materia/migrations/0043_auto_20190320_1749.py create mode 100644 sapl/templates/materia/tipomaterialegislativa_list.html diff --git a/sapl/api/views.py b/sapl/api/views.py index 769196c76..f2f146e24 100644 --- a/sapl/api/views.py +++ b/sapl/api/views.py @@ -22,7 +22,7 @@ from sapl.api.forms import SaplFilterSetMixin from sapl.api.permissions import SaplModelPermissions from sapl.api.serializers import ChoiceSerializer from sapl.base.models import Autor, AppConfig, DOC_ADM_OSTENSIVO -from sapl.materia.models import Proposicao +from sapl.materia.models import Proposicao, TipoMateriaLegislativa from sapl.parlamentares.models import Parlamentar from sapl.utils import models_with_gr_for_model, choice_anos_com_sessaoplenaria @@ -349,6 +349,23 @@ class _ProposicaoViewSet(SaplSetViews['materia']['proposicao']): return qs +class _TipoMateriaLegislativaViewSet(SaplSetViews['materia']['tipomaterialegislativa']): + + @action(detail=True, methods=['POST']) + def change_position(self, request, *args, **kwargs): + result = { + 'status': 200, + 'message': 'OK' + } + d = request.data + if 'pos_ini' in d and 'pos_fim' in d: + if d['pos_ini'] != d['pos_fim']: + pk = kwargs['pk'] + TipoMateriaLegislativa.objects.reposicione(pk, d['pos_fim']) + + return Response(result) + + class _DocumentoAdministrativoViewSet(SaplSetViews['protocoloadm']['documentoadministrativo']): class DocumentoAdministrativoPermission(SaplModelPermissions): @@ -427,6 +444,7 @@ class _SessaoPlenariaViewSet( SaplSetViews['base']['autor'] = _AutorViewSet.build_class_with_actions() SaplSetViews['materia']['proposicao'] = _ProposicaoViewSet +SaplSetViews['materia']['tipomaterialegislativa'] = _TipoMateriaLegislativaViewSet SaplSetViews['parlamentares']['parlamentar'] = _ParlamentarViewSet diff --git a/sapl/crud/base.py b/sapl/crud/base.py index 5fa4f70e5..0dc11ea5c 100644 --- a/sapl/crud/base.py +++ b/sapl/crud/base.py @@ -2,7 +2,6 @@ import logging from braces.views import FormMessagesMixin from crispy_forms.bootstrap import FieldWithButtons, StrictButton -from sapl.crispy_layout_mixin import SaplFormHelper from crispy_forms.layout import Field, Layout from django import forms from django.conf.urls import url @@ -25,6 +24,7 @@ from django.views.generic.base import ContextMixin from django.views.generic.list import MultipleObjectMixin from sapl.crispy_layout_mixin import CrispyLayoutFormMixin, get_field_display +from sapl.crispy_layout_mixin import SaplFormHelper from sapl.rules.map_rules import (RP_ADD, RP_CHANGE, RP_DELETE, RP_DETAIL, RP_LIST) from sapl.settings import BASE_DIR @@ -449,18 +449,28 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): if not n: s += '
' continue + m = obj n = n.split('__') for f in n[:-1]: m = getattr(m, f) if not m: break + + ss = '' if m: ss = get_field_display(m, n[-1])[1] ss = ( ('
' if '' in ss else ' - ') + ss)\ if ss and j != 0 and s else ss + + hook = 'hook_{}'.format(''.join(n)) + if hasattr(self, hook): + hs, url = getattr(self, hook)(obj, ss, url) + s += str(hs) + else: s += ss + r.append((s, url)) return r diff --git a/sapl/materia/migrations/0042_tipomaterialegislativa_sequencia_regimental.py b/sapl/materia/migrations/0042_tipomaterialegislativa_sequencia_regimental.py new file mode 100644 index 000000000..81d1ccbcb --- /dev/null +++ b/sapl/materia/migrations/0042_tipomaterialegislativa_sequencia_regimental.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-03-20 11:26 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0041_proposicao_numero_materia_futuro'), + ] + + operations = [ + migrations.AddField( + model_name='tipomaterialegislativa', + name='sequencia_regimental', + field=models.PositiveIntegerField( + default=0, help_text='A sequência regimental diz respeito ao que define o regimento da Casa Legislativa sobre qual a ordem de entrada das proposições nas Sessões Plenárias.', verbose_name='Sequência Regimental'), + ), + ] diff --git a/sapl/materia/migrations/0043_auto_20190320_1749.py b/sapl/materia/migrations/0043_auto_20190320_1749.py new file mode 100644 index 000000000..16c05e21b --- /dev/null +++ b/sapl/materia/migrations/0043_auto_20190320_1749.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-03-20 20:49 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0042_tipomaterialegislativa_sequencia_regimental'), + ] + + operations = [ + migrations.AlterModelOptions( + name='tipomaterialegislativa', + options={'ordering': ['sequencia_regimental', 'descricao'], 'verbose_name': 'Tipo de Matéria Legislativa', 'verbose_name_plural': 'Tipos de Matérias Legislativas'}, + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index e4ae436b9..452a01d6f 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -78,8 +78,37 @@ class TipoProposicao(models.Model): return self.descricao +class TipoMateriaManager(models.Manager): + + def reordene(self, exclude_pk=None): + tipos = self.get_queryset() + if exclude_pk: + tipos = tipos.exclude(pk=exclude_pk) + for sr, t in enumerate(tipos, 1): + t.sequencia_regimental = sr + t.save() + + def reposicione(self, pk, idx): + tipos = self.reordene(exclude_pk=pk) + + self.get_queryset( + ).filter( + sequencia_regimental__gte=idx + ).update( + sequencia_regimental=models.F('sequencia_regimental') + 1 + ) + + self.get_queryset( + ).filter( + pk=pk + ).update( + sequencia_regimental=idx + ) + + @reversion.register() class TipoMateriaLegislativa(models.Model): + objects = TipoMateriaManager() sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição ')) # XXX o que é isso ? @@ -101,10 +130,17 @@ class TipoMateriaLegislativa(models.Model): verbose_name=_('Sequência de numeração'), choices=SEQUENCIA_NUMERACAO) + sequencia_regimental = models.PositiveIntegerField( + default=0, + verbose_name=_('Sequência Regimental'), + help_text=_('A sequência regimental diz respeito ao que define ' + 'o regimento da Casa Legislativa sobre qual a ordem ' + 'de entrada das proposições nas Sessões Plenárias.')) + class Meta: verbose_name = _('Tipo de Matéria Legislativa') verbose_name_plural = _('Tipos de Matérias Legislativas') - ordering = ['descricao'] + ordering = ['sequencia_regimental', 'descricao'] def __str__(self): return self.descricao @@ -920,7 +956,8 @@ class Tramitacao(models.Model): ('B', 'primeira_votacao', _('1ª Votação')), ('C', 'segunda_terceira_votacao', _('2ª e 3ª Votação')), ('D', 'deliberacao', _('Deliberação')), - ('E', 'primeira_segunda_votacao_urgencia', _('1ª e 2ª votações em regime de urgência')) + ('E', 'primeira_segunda_votacao_urgencia', _( + '1ª e 2ª votações em regime de urgência')) ) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index d5be4770d..e727fe0c7 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -3,7 +3,6 @@ import logging from random import choice from string import ascii_letters, digits -from sapl.crispy_layout_mixin import SaplFormHelper from crispy_forms.layout import HTML from django.conf import settings from django.contrib import messages @@ -32,6 +31,7 @@ from sapl.comissoes.models import Comissao, Participacao from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT, STATUS_TA_PRIVATE) from sapl.compilacao.views import IntegracaoTaView +from sapl.crispy_layout_mixin import SaplFormHelper from sapl.crispy_layout_mixin import SaplFormLayout, form_actions from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, MasterDetailCrud, @@ -75,9 +75,6 @@ AssuntoMateriaCrud = CrudAux.build(AssuntoMateria, 'assunto_materia') OrigemCrud = CrudAux.build(Origem, '') -TipoMateriaCrud = CrudAux.build( - TipoMateriaLegislativa, 'tipo_materia_legislativa') - RegimeTramitacaoCrud = CrudAux.build( RegimeTramitacao, 'regime_tramitacao') @@ -214,7 +211,8 @@ class CriarProtocoloMateriaView(CreateView): context['form'].fields['ano'].initial = protocolo.ano if protocolo: if protocolo.timestamp: - context['form'].fields['data_apresentacao'].initial = protocolo.timestamp.date() + context['form'].fields['data_apresentacao'].initial = protocolo.timestamp.date( + ) elif protocolo.timestamp_data_hora_manual: context['form'].fields['data_apresentacao'].initial = protocolo.timestamp_data_hora_manual.date() elif protocolo.data: @@ -1115,7 +1113,8 @@ class RelatoriaCrud(MasterDetailCrud): try: self.logger.debug("user=" + username + ". Tentando obter objeto Comissao de pk={}.".format( context['form'].initial['comissao'])) - comissao = Comissao.objects.get(pk=context['form'].initial['comissao']) + comissao = Comissao.objects.get( + pk=context['form'].initial['comissao']) except: self.logger.error("user=" + username + ". Objeto Comissão de pk={} não encontrado.".format( context['form'].initial['comissao'])) @@ -1125,12 +1124,15 @@ class RelatoriaCrud(MasterDetailCrud): self.logger.info("user=" + username + ". Objeto Comissao de pk={} obtido com sucesso.".format( context['form'].initial['comissao'])) - materia = MateriaLegislativa.objects.get(pk=self.kwargs.get('pk')) + materia = MateriaLegislativa.objects.get( + pk=self.kwargs.get('pk')) ano_materia = materia.ano - comissao = Comissao.objects.get(pk=context['form'].initial['comissao']) + comissao = Comissao.objects.get( + pk=context['form'].initial['comissao']) composicoes = comissao.composicao_set.all() - composicao = comissao.composicao_set.filter(periodo__data_inicio__year=ano_materia) + composicao = comissao.composicao_set.filter( + periodo__data_inicio__year=ano_materia) participacoes = Participacao.objects.select_related().filter(composicao=composicao) @@ -1182,12 +1184,15 @@ class RelatoriaCrud(MasterDetailCrud): self.logger.info("user=" + username + ". Objeto Comissao de pk={} obtido com sucesso.".format( context['form'].initial['comissao'])) - relatoria = Relatoria.objects.select_related('materia').get(pk=self.kwargs.get('pk')) + relatoria = Relatoria.objects.select_related( + 'materia').get(pk=self.kwargs.get('pk')) ano_materia = relatoria.materia.ano - comissao = Comissao.objects.get(pk=context['form'].initial['comissao']) + comissao = Comissao.objects.get( + pk=context['form'].initial['comissao']) composicoes = comissao.composicao_set.all() - composicao = comissao.composicao_set.filter(periodo__data_inicio__year=ano_materia) + composicao = comissao.composicao_set.filter( + periodo__data_inicio__year=ano_materia) participacoes = Participacao.objects.select_related().filter(composicao=composicao) @@ -1952,11 +1957,11 @@ class AcompanhamentoMateriaView(CreateView): "materia", materia, destinatario) - + self.logger.debug('user=' + usuario.username + '. Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ confirmar o acompanhamento desta matéria.') - + msg = _('Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ confirmar o acompanhamento desta matéria.') @@ -1973,7 +1978,7 @@ class AcompanhamentoMateriaView(CreateView): return self.render_to_response( {'form': form, 'materia': materia - }) + }) return HttpResponseRedirect(self.get_success_url()) else: return self.render_to_response( @@ -2041,6 +2046,7 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView): messages.add_message(request, messages.SUCCESS, msg) return self.get(request, self.kwargs) + class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView): filterset_class = AnexadaEmLoteFilterSet template_name = 'materia/em_lote/anexada.html' @@ -2054,7 +2060,6 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView): context['subnav_template_name'] = 'materia/subnav.yaml' - context['title'] = _('Matérias Anexadas em Lote') # Verifica se os campos foram preenchidos if not self.filterset.form.is_valid(): @@ -2084,10 +2089,10 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView): data_desanexacao = None else: data_desanexacao = datetime.strptime( - request.POST['data_desanexacao'], "%d/%m/%Y").date() + request.POST['data_desanexacao'], "%d/%m/%Y").date() - principal = MateriaLegislativa.objects.get(pk = kwargs['pk']) - for materia in MateriaLegislativa.objects.filter(id__in = marcadas): + principal = MateriaLegislativa.objects.get(pk=kwargs['pk']) + for materia in MateriaLegislativa.objects.filter(id__in=marcadas): anexada = Anexada() anexada.materia_principal = principal @@ -2291,7 +2296,8 @@ class ImpressosView(PermissionRequiredMixin, TemplateView): def gerar_pdf_impressos(request, context, template_name): template = loader.get_template(template_name) html = template.render(context, request) - pdf = weasyprint.HTML(string=html, base_url=request.build_absolute_uri()).write_pdf() + pdf = weasyprint.HTML( + string=html, base_url=request.build_absolute_uri()).write_pdf() response = HttpResponse(pdf, content_type='application/pdf') response['Content-Disposition'] = 'inline; filename="relatorio_impressos.pdf"' @@ -2476,7 +2482,8 @@ class MateriaPesquisaSimplesView(PermissionRequiredMixin, FormView): kwargs.update({'data__gte': form.cleaned_data['data_inicial'], 'data__lte': form.cleaned_data['data_final']}) - materias = MateriaLegislativa.objects.filter(**kwargs).order_by('-numero', 'ano') + materias = MateriaLegislativa.objects.filter( + **kwargs).order_by('-numero', 'ano') quantidade_materias = materias.count() materias = materias[:2000] if quantidade_materias > 2000 else materias @@ -2486,3 +2493,47 @@ class MateriaPesquisaSimplesView(PermissionRequiredMixin, FormView): 'materias': materias} return gerar_pdf_impressos(self.request, context, template_materia) + + +class TipoMateriaCrud(CrudAux): + model = TipoMateriaLegislativa + + class DetailView(CrudAux.DetailView): + layout_key = 'TipoMateriaLegislativaDetail' + + class DeleteView(CrudAux.DeleteView): + def delete(self, request, *args, **kwargs): + d = CrudAux.DeleteView.delete(self, request, *args, **kwargs) + TipoMateriaLegislativa.objects.reordene() + return d + + class ListView(CrudAux.ListView): + paginate_by = None + layout_key = 'TipoMateriaLegislativaDetail' + template_name = "materia/tipomaterialegislativa_list.html" + + def hook_sigla(self, obj, default, url): + return '{}'.format( + url, obj.id, obj.sigla), '' + + def get(self, request, *args, **kwargs): + if TipoMateriaLegislativa.objects.filter( + sequencia_regimental=0).exists(): + TipoMateriaLegislativa.objects.reordene() + return CrudAux.ListView.get(self, request, *args, **kwargs) + + class CreateView(CrudAux.CreateView): + + def form_valid(self, form): + fv = super().form_valid(form) + + if not TipoMateriaLegislativa.objects.exclude( + sequencia_regimental=0).exists(): + TipoMateriaLegislativa.objects.reordene() + else: + sr__max = TipoMateriaLegislativa.objects.all().aggregate( + Max('sequencia_regimental')) + self.object.sequencia_regimental = sr__max['sequencia_regimental__max'] + 1 + self.object.save() + + return fv diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index dd9dcc1e2..fe0e12d77 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -63,18 +63,29 @@ TipoRetiradaPautaCrud = CrudAux.build(TipoRetiradaPauta, 'tipo_retirada_pauta') def reordernar_materias_expediente(request, pk): expedientes = ExpedienteMateria.objects.filter( - sessao_plenaria_id=pk) + sessao_plenaria_id=pk + ).order_by( + 'materia__tipo__sequencia_regimental', + 'materia__ano', + 'materia__numero' + ) for exp_num, e in enumerate(expedientes, 1): e.numero_ordem = exp_num e.save() + return HttpResponseRedirect( reverse('sapl.sessao:expedientemateria_list', kwargs={'pk': pk})) def reordernar_materias_ordem(request, pk): ordens = OrdemDia.objects.filter( - sessao_plenaria_id=pk) + sessao_plenaria_id=pk + ).order_by( + 'materia__tipo__sequencia_regimental', + 'materia__ano', + 'materia__numero' + ) for ordem_num, o in enumerate(ordens, 1): o.numero_ordem = ordem_num o.save() @@ -1294,6 +1305,7 @@ def get_turno(turno): else: return '' + def get_identificação_basica(sessao_plenaria): # ===================================================================== # Identificação Básica @@ -1309,18 +1321,22 @@ def get_identificação_basica(sessao_plenaria): 'encerramento': encerramento, 'hora_fim': sessao_plenaria.hora_fim} ]}) + def get_conteudo_multimidia(sessao_plenaria): context = {} if sessao_plenaria.url_audio: - context['multimidia_audio'] = _('Audio: ') + str(sessao_plenaria.url_audio) + context['multimidia_audio'] = _( + 'Audio: ') + str(sessao_plenaria.url_audio) else: - context['multimidia_audio'] = _('Audio: Indisponível') + context['multimidia_audio'] = _('Audio: Indisponível') if sessao_plenaria.url_video: - context['multimidia_video'] = _('Video: ') + str(sessao_plenaria.url_video) + context['multimidia_video'] = _( + 'Video: ') + str(sessao_plenaria.url_video) else: context['multimidia_video'] = _('Video: Indisponível') return context + def get_mesa_diretora(sessao_plenaria): mesa = IntegranteMesa.objects.filter(sessao_plenaria=sessao_plenaria) integrantes = [] @@ -1333,6 +1349,7 @@ def get_mesa_diretora(sessao_plenaria): integrantes.append(integrante) return ({'mesa': ordenar_integrantes_por_cargo(integrantes)}) + def get_presenca_sessao(sessao_plenaria): presencas = SessaoPlenariaPresenca.objects.filter( sessao_plenaria_id=sessao_plenaria.id @@ -1345,11 +1362,12 @@ def get_presenca_sessao(sessao_plenaria): ).order_by('parlamentar__nome_parlamentar') return ({'presenca_sessao': parlamentares_sessao, - 'justificativa_ausencia': ausentes_sessao}) + 'justificativa_ausencia': ausentes_sessao}) + def get_expedientes(sessao_plenaria): expediente = ExpedienteSessao.objects.filter( - sessao_plenaria_id=sessao_plenaria.id).order_by('tipo__nome') + sessao_plenaria_id=sessao_plenaria.id).order_by('tipo__nome') expedientes = [] for e in expediente: tipo = TipoExpediente.objects.get(id=e.tipo_id) @@ -1358,9 +1376,10 @@ def get_expedientes(sessao_plenaria): expedientes.append(ex) return ({'expedientes': expedientes}) + def get_materias_expediente(sessao_plenaria): materias = ExpedienteMateria.objects.filter( - sessao_plenaria_id=sessao_plenaria.id) + sessao_plenaria_id=sessao_plenaria.id) materias_expediente = [] for m in materias: @@ -1405,6 +1424,7 @@ def get_materias_expediente(sessao_plenaria): context = {'materia_expediente': materias_expediente} return context + def get_oradores_expediente(sessao_plenaria): oradores = [] for orador in OradorExpediente.objects.filter( @@ -1423,6 +1443,7 @@ def get_oradores_expediente(sessao_plenaria): context = {'oradores': oradores} return context + def get_presenca_ordem_do_dia(sessao_plenaria): mesa_aux = get_mesa_diretora(sessao_plenaria) presencas = PresencaOrdemDia.objects.filter( @@ -1430,7 +1451,7 @@ def get_presenca_ordem_do_dia(sessao_plenaria): ).order_by('parlamentar__nome_parlamentar') parlamentares_mesa_dia = [m for m in mesa_aux['mesa']] - + presidente_dia = '' for m in mesa_aux['mesa']: if m['cargo'].descricao == 'Presidente': @@ -1448,14 +1469,15 @@ def get_presenca_ordem_do_dia(sessao_plenaria): except IndexError: pass - context ={} + context = {} context.update({'presenca_ordem': parlamentares_ordem}) config_assinatura_ata = AppsAppConfig.objects.first().assinatura_ata if config_assinatura_ata == 'T' and parlamentares_ordem: context.update( {'texto_assinatura': 'Assinatura de Todos os Parlamentares Presentes na Sessão'}) - context.update({'assinatura_mesa':parlamentares_mesa_dia,'assinatura_presentes': parlamentares_ordem}) + context.update({'assinatura_mesa': parlamentares_mesa_dia, + 'assinatura_presentes': parlamentares_ordem}) elif config_assinatura_ata == 'M' and parlamentares_mesa_dia: context.update( {'texto_assinatura': 'Assinatura da Mesa Diretora da Sessão'}) @@ -1464,9 +1486,10 @@ def get_presenca_ordem_do_dia(sessao_plenaria): context.update( {'texto_assinatura': 'Assinatura do Presidente da Sessão'}) context.update({'assinatura_presentes': presidente_dia}) - + return context + def get_materias_ordem_do_dia(sessao_plenaria): ordem = OrdemDia.objects.filter(sessao_plenaria_id=sessao_plenaria.id) materias_ordem = [] @@ -1494,12 +1517,12 @@ def get_materias_ordem_do_dia(sessao_plenaria): else: resultado = _('Matéria não votada') resultado_observacao = _(' ') - + voto_sim = "" voto_nao = "" voto_abstencoes = "" voto_nominal = [] - + if o.tipo_votacao == 2: votos = VotoParlamentar.objects.filter(ordem=o.id) for voto in votos: @@ -1529,9 +1552,9 @@ def get_materias_ordem_do_dia(sessao_plenaria): 'numero_protocolo': o.materia.numero_protocolo, 'numero_processo': o.materia.numeracao_set.last(), 'tipo_votacao': o.TIPO_VOTACAO_CHOICES[o.tipo_votacao], - 'voto_sim':voto_sim, - 'voto_nao':voto_nao, - 'voto_abstencoes':voto_abstencoes, + 'voto_sim': voto_sim, + 'voto_nao': voto_nao, + 'voto_abstencoes': voto_abstencoes, 'voto_nominal': voto_nominal, } materias_ordem.append(mat) @@ -1539,6 +1562,7 @@ def get_materias_ordem_do_dia(sessao_plenaria): context = {'materias_ordem': materias_ordem} return context + def get_oradores_explicações_pessoais(sessao_plenaria): oradores_explicacoes = [] for orador in Orador.objects.filter( @@ -1560,20 +1584,20 @@ def get_oradores_explicações_pessoais(sessao_plenaria): context = {'oradores_explicacoes': oradores_explicacoes} return context + def get_ocorrencias_da_sessão(sessao_plenaria): ocorrencias_sessao = OcorrenciaSessao.objects.filter( - sessao_plenaria_id=sessao_plenaria.id) + sessao_plenaria_id=sessao_plenaria.id) context = {'ocorrencias_da_sessao': ocorrencias_sessao} return context - - + class ResumoView(DetailView): template_name = 'sessao/resumo.html' model = SessaoPlenaria logger = logging.getLogger(__name__) - def get_context(self,*args, **kwargs): + def get_context(self, *args, **kwargs): self.object = self.get_object() context = self.get_context_data(object=self.object) @@ -1581,23 +1605,23 @@ class ResumoView(DetailView): materias_expediente_votacao_nominal = ExpedienteMateria.objects.filter( sessao_plenaria_id=self.object.id, tipo_votacao=2).order_by('-materia') - + votacoes = [] - for mevn in materias_expediente_votacao_nominal: - + for mevn in materias_expediente_votacao_nominal: + votos_materia = [] titulo_materia = mevn.materia registro = RegistroVotacao.objects.filter(expediente=mevn) - if registro: + if registro: for vp in VotoParlamentar.objects.filter(votacao=registro).order_by('parlamentar'): votos_materia.append(vp) dados_votacao = { 'titulo': titulo_materia, 'votos': votos_materia - } + } votacoes.append(dados_votacao) - + context.update({'votos_nominais_materia_expediente': votacoes}) # ===================================================================== @@ -1645,7 +1669,7 @@ class ResumoView(DetailView): 'votos': votos_materia_od } votacoes_od.append(dados_votacao_od) - + context.update({'votos_nominais_materia_ordem_dia': votacoes_od}) context.update(get_materias_ordem_do_dia(self.object)) @@ -1678,36 +1702,36 @@ class ResumoView(DetailView): try: context.update( {'primeiro_ordenacao': dict_ord_template[ordenacao.primeiro], - 'segundo_ordenacao': dict_ord_template[ordenacao.segundo], - 'terceiro_ordenacao': dict_ord_template[ordenacao.terceiro], - 'quarto_ordenacao': dict_ord_template[ordenacao.quarto], - 'quinto_ordenacao': dict_ord_template[ordenacao.quinto], - 'sexto_ordenacao': dict_ord_template[ordenacao.sexto], - 'setimo_ordenacao': dict_ord_template[ordenacao.setimo], - 'oitavo_ordenacao': dict_ord_template[ordenacao.oitavo], - 'nono_ordenacao': dict_ord_template[ordenacao.nono], - 'decimo_ordenacao': dict_ord_template[ordenacao.decimo], - 'decimo_primeiro_ordenacao': dict_ord_template[ordenacao.decimo_primeiro], - 'decimo_segundo_ordenacao': dict_ord_template[ordenacao.decimo_segundo], - 'decimo_terceiro_ordenacao': dict_ord_template[ordenacao.decimo_terceiro]}) + 'segundo_ordenacao': dict_ord_template[ordenacao.segundo], + 'terceiro_ordenacao': dict_ord_template[ordenacao.terceiro], + 'quarto_ordenacao': dict_ord_template[ordenacao.quarto], + 'quinto_ordenacao': dict_ord_template[ordenacao.quinto], + 'sexto_ordenacao': dict_ord_template[ordenacao.sexto], + 'setimo_ordenacao': dict_ord_template[ordenacao.setimo], + 'oitavo_ordenacao': dict_ord_template[ordenacao.oitavo], + 'nono_ordenacao': dict_ord_template[ordenacao.nono], + 'decimo_ordenacao': dict_ord_template[ordenacao.decimo], + 'decimo_primeiro_ordenacao': dict_ord_template[ordenacao.decimo_primeiro], + 'decimo_segundo_ordenacao': dict_ord_template[ordenacao.decimo_segundo], + 'decimo_terceiro_ordenacao': dict_ord_template[ordenacao.decimo_terceiro]}) except KeyError as e: self.logger.error('user=' + self.request.user.username + '. ' + "KeyError: " + str(e) + ". Erro " "ao tentar utilizar configuração de ordenação. Utilizando ordenação padrão.") context.update( - {'primeiro_ordenacao': dict_ord_template['id_basica'], - 'segundo_ordenacao': dict_ord_template['cont_mult'], - 'terceiro_ordenacao': dict_ord_template['mesa_d'], - 'quarto_ordenacao': dict_ord_template['lista_p'], - 'quinto_ordenacao': dict_ord_template['exp'], - 'sexto_ordenacao': dict_ord_template['mat_exp'], - 'setimo_ordenacao': dict_ord_template['v_n_mat_exp'], - 'oitavo_ordenacao': dict_ord_template['oradores_exped'], - 'nono_ordenacao': dict_ord_template['lista_p_o_d'], - 'decimo_ordenacao': dict_ord_template['mat_o_d'], - 'decimo_primeiro_ordenacao': dict_ord_template['v_n_mat_o_d'], - 'decimo_segundo_ordenacao': dict_ord_template['oradores_expli'], - 'decimo_terceiro_ordenacao': dict_ord_template['ocorr_sessao'] - }) + {'primeiro_ordenacao': dict_ord_template['id_basica'], + 'segundo_ordenacao': dict_ord_template['cont_mult'], + 'terceiro_ordenacao': dict_ord_template['mesa_d'], + 'quarto_ordenacao': dict_ord_template['lista_p'], + 'quinto_ordenacao': dict_ord_template['exp'], + 'sexto_ordenacao': dict_ord_template['mat_exp'], + 'setimo_ordenacao': dict_ord_template['v_n_mat_exp'], + 'oitavo_ordenacao': dict_ord_template['oradores_exped'], + 'nono_ordenacao': dict_ord_template['lista_p_o_d'], + 'decimo_ordenacao': dict_ord_template['mat_o_d'], + 'decimo_primeiro_ordenacao': dict_ord_template['v_n_mat_o_d'], + 'decimo_segundo_ordenacao': dict_ord_template['oradores_expli'], + 'decimo_terceiro_ordenacao': dict_ord_template['ocorr_sessao'] + }) else: context.update( {'primeiro_ordenacao': dict_ord_template['id_basica'], @@ -1725,14 +1749,13 @@ class ResumoView(DetailView): 'decimo_terceiro_ordenacao': dict_ord_template['ocorr_sessao'] }) - return context + return context def get(self, request, *args, **kwargs): context = self.get_context() return self.render_to_response(context) - class ResumoAtaView(ResumoView): template_name = 'sessao/resumo_ata.html' logger = logging.getLogger(__name__) @@ -3142,7 +3165,7 @@ class AdicionarVariasMateriasExpediente(PermissionRequiredForAppCrudMixin, def get_context_data(self, **kwargs): context = super(MateriaLegislativaPesquisaView, self).get_context_data(**kwargs) - + context['title'] = _('Pesquisar Matéria Legislativa') context['root_pk'] = self.kwargs['pk'] @@ -3478,7 +3501,7 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie 'origem': request.POST['origem'], 'subnav_template_name': 'sessao/subnav.yaml' } - + if 'marcadas_1' in request.POST: context.update({'resultado_votacao': TipoResultadoVotacao.objects.all(), diff --git a/sapl/templates/materia/layouts.yaml b/sapl/templates/materia/layouts.yaml index 26d603f99..44090e522 100644 --- a/sapl/templates/materia/layouts.yaml +++ b/sapl/templates/materia/layouts.yaml @@ -3,9 +3,13 @@ Origem: {% trans 'Origem' %}: - nome:8 sigla +TipoMateriaLegislativaDetail: + {% trans 'Tipo Matéria Legislativa' %}: + - sigla:2 descricao sequencia_numeracao:2 sequencia_regimental:2 + TipoMateriaLegislativa: {% trans 'Tipo Matéria Legislativa' %}: - - sigla:4 descricao sequencia_numeracao + - sigla:2 descricao sequencia_numeracao:3 RegimeTramitacao: {% trans 'Tipo de Documento' %}: diff --git a/sapl/templates/materia/tipomaterialegislativa_list.html b/sapl/templates/materia/tipomaterialegislativa_list.html new file mode 100644 index 000000000..1680e89e7 --- /dev/null +++ b/sapl/templates/materia/tipomaterialegislativa_list.html @@ -0,0 +1,55 @@ +{% extends "crud/list_tabaux.html" %} +{% load i18n %} +{% load common_tags %} + +{% block container_table_list %} +
+ {{ block.super }} ++{% endblock %} + +{% block extra_js %} + + + +{% endblock %} From 7bf8f657770b0efaf5af7eccd70a9e8ef1bcf158 Mon Sep 17 00:00:00 2001 From: Victor FabreDate: Thu, 21 Mar 2019 13:28:28 -0300 Subject: [PATCH 20/39] Fix #2634 (#2645) --- sapl/comissoes/views.py | 1 + sapl/templates/comissoes/materias_em_tramitacao.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py index 743eaa58f..d6d129b11 100644 --- a/sapl/comissoes/views.py +++ b/sapl/comissoes/views.py @@ -186,6 +186,7 @@ class MateriasTramitacaoListView(ListView): context = super( MateriasTramitacaoListView, self).get_context_data(**kwargs) context['object'] = Comissao.objects.get(id=self.kwargs['pk']) + context['qtde'] = self.object_list.count() return context diff --git a/sapl/templates/comissoes/materias_em_tramitacao.html b/sapl/templates/comissoes/materias_em_tramitacao.html index 9f197d1ce..32860df54 100644 --- a/sapl/templates/comissoes/materias_em_tramitacao.html +++ b/sapl/templates/comissoes/materias_em_tramitacao.html @@ -12,7 +12,7 @@ {% block detail_content %}