Date: Mon, 1 Apr 2019 14:48:45 -0300
Subject: [PATCH 06/15] =?UTF-8?q?Retira=20atributos=20class=20e=20espa?=
=?UTF-8?q?=C3=A7os=20de=20tags=20?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/relatorios/views.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py
index dec1d50b7..9439b1578 100755
--- a/sapl/relatorios/views.py
+++ b/sapl/relatorios/views.py
@@ -578,6 +578,8 @@ def get_sessao_plenaria(sessao, casa):
# unescape HTML codes
# https://github.com/interlegis/sapl/issues/1046
conteudo = re.sub('style=".*?"', '', conteudo)
+ conteudo = re.sub('class=".*?"', '', conteudo)
+ conteudo = re.sub('
', '
', conteudo)
conteudo = html.unescape(conteudo)
# escape special character '&'
From 4b35e6a4fe37ba10d6ac95ae02cc220a14c61e80 Mon Sep 17 00:00:00 2001
From: Ulysses Lara
Date: Mon, 1 Apr 2019 15:09:50 -0300
Subject: [PATCH 07/15] Fix #2663 parte relacionada a turno (#2675)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Fix #2663 parte relacionada a turno
* Retira parênteses desnecessários
---
sapl/sessao/views.py | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index 4e4ad02fa..9300ab9e1 100755
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -1378,9 +1378,15 @@ def get_materias_expediente(sessao_plenaria):
ementa = m.materia.ementa
titulo = m.materia
numero = m.numero_ordem
- tramitacao = m.materia.tramitacao_set.last()
- turno = None
+ tramitacao = ''
+ tramitacoes = Tramitacao.objects.filter(materia=m.materia).order_by('-pk')
+ for aux_tramitacao in tramitacoes:
+ if aux_tramitacao.turno:
+ tramitacao = aux_tramitacao
+ break
+
+ turno = None
if tramitacao:
turno = get_turno(tramitacao.turno)
@@ -1486,7 +1492,14 @@ def get_materias_ordem_do_dia(sessao_plenaria):
ementa_observacao = o.observacao
titulo = o.materia
numero = o.numero_ordem
- tramitacao = o.materia.tramitacao_set.last()
+
+ tramitacao = ''
+ tramitacoes = Tramitacao.objects.filter(materia=o.materia).order_by('-pk')
+ for aux_tramitacao in tramitacoes:
+ if aux_tramitacao.turno:
+ tramitacao = aux_tramitacao
+ break
+
turno = None
if tramitacao:
turno = get_turno(tramitacao.turno)
From 52de1510019bdfbc77a6bcb962868bdf9356686e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?=
Date: Mon, 1 Apr 2019 15:11:33 -0300
Subject: [PATCH 08/15] Fix #2671 (#2673)
* Fix #2671
* Atualizar sessao/forms.py
* Atualizar sessao/forms.py
---
sapl/sessao/forms.py | 22 ++++++++++++++++++++++
sapl/sessao/views.py | 1 +
2 files changed, 23 insertions(+)
diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py
index c2532b4a1..172b37be5 100644
--- a/sapl/sessao/forms.py
+++ b/sapl/sessao/forms.py
@@ -692,7 +692,29 @@ class OradorForm(ModelForm):
self.fields['parlamentar'].queryset = Parlamentar.objects.filter(
id__in=ids).order_by('nome_parlamentar')
+
+ def clean(self):
+ super(OradorForm, self).clean()
+ cleaned_data = self.cleaned_data
+
+ if not self.is_valid():
+ return self.cleaned_data
+ sessao_id = self.initial['id_sessao']
+ numero = self.initial.get('numero')
+ numero_ordem = cleaned_data['numero_ordem']
+ ordem = Orador.objects.filter(
+ sessao_plenaria_id=sessao_id,
+ numero_ordem=numero_ordem
+ ).exists()
+
+ if ordem and numero_ordem != numero:
+ raise ValidationError(_(
+ "Já existe orador nesta posição de ordem de pronunciamento"
+ ))
+
+ return self.cleaned_data
+
class Meta:
model = Orador
exclude = ['sessao_plenaria']
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index 9300ab9e1..c5a6620c4 100755
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -620,6 +620,7 @@ class OradorCrud(OradorCrud):
def get_initial(self):
initial = super(UpdateView, self).get_initial()
initial.update({'id_sessao': self.object.sessao_plenaria.id})
+ initial.update({'numero':self.object.numero_ordem})
return initial
From 31e3cd7b4474c2273a8a8606110ec78bd772dc45 Mon Sep 17 00:00:00 2001
From: Victor Fabre
Date: Mon, 1 Apr 2019 17:29:10 -0300
Subject: [PATCH 09/15] Fix #2679 (#2680)
---
sapl/materia/forms.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
index 4b75e134a..cf200447e 100644
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -727,7 +727,7 @@ class AnexadaForm(ModelForm):
empty_label='Selecione',
)
- numero = forms.CharField(label='Número', required=True)
+ numero = forms.IntegerField(label='Número', required=True)
ano = forms.CharField(label='Ano', required=True)
@@ -751,8 +751,8 @@ class AnexadaForm(ModelForm):
ano=cleaned_data['ano'],
tipo=cleaned_data['tipo'])
except ObjectDoesNotExist:
- msg = _('A MateriaLegislativa a ser anexada (numero={}, ano={}, tipo={}) não existe no cadastro'
- ' de matérias legislativas.'.format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo']))
+ msg = _('A {} {}/{} não existe no cadastro de matérias legislativas.'
+ .format(cleaned_data['tipo'], cleaned_data['numero'], cleaned_data['ano']))
self.logger.error("A matéria a ser anexada não existe no cadastro"
" de matérias legislativas.")
raise ValidationError(msg)
From 0b7ab48218e76a8cfb69e48499ab7b2779391e18 Mon Sep 17 00:00:00 2001
From: Victor Fabre
Date: Mon, 1 Apr 2019 17:29:17 -0300
Subject: [PATCH 10/15] Fix #2678 (#2681)
---
sapl/sessao/urls.py | 6 ++++++
sapl/sessao/views.py | 19 +++++++++++++++++++
.../sessao/expedientemateria_list.html | 5 ++++-
sapl/templates/sessao/ordemdia_list.html | 5 ++++-
4 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py
index 4da3a761a..ba0735ec6 100644
--- a/sapl/sessao/urls.py
+++ b/sapl/sessao/urls.py
@@ -28,6 +28,8 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
remove_parlamentar_composicao,
reordernar_materias_expediente,
reordernar_materias_ordem,
+ renumerar_materias_ordem,
+ renumerar_materias_expediente,
sessao_legislativa_legislatura_ajax,
VotacaoEmBlocoOrdemDia, VotacaoEmBlocoExpediente,
VotacaoEmBlocoSimbolicaView, VotacaoEmBlocoNominalView)
@@ -75,6 +77,10 @@ urlpatterns = [
name="reordenar_expediente"),
url(r'^sessao/(?P\d+)/reordenar-ordem$', reordernar_materias_ordem,
name="reordenar_ordem"),
+ url(r'^sessao/(?P\d+)/renumerar-ordem$', renumerar_materias_ordem,
+ name="renumerar_ordem"),
+ url(r'^sessao/(?P\d+)/renumerar-materias-expediente$', renumerar_materias_expediente,
+ name="renumerar_materias_expediente"),
url(r'^sistema/sessao-plenaria/tipo/',
include(TipoSessaoCrud.get_urls())),
url(r'^sistema/sessao-plenaria/tipo-resultado-votacao/',
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index c5a6620c4..550b231be 100755
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -93,6 +93,25 @@ def reordernar_materias_ordem(request, pk):
return HttpResponseRedirect(
reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk}))
+def renumerar_materias_ordem(request, pk):
+ ordens = OrdemDia.objects.filter(sessao_plenaria_id=pk)
+
+ for ordem_num, o in enumerate(ordens, 1):
+ o.numero_ordem = ordem_num
+ o.save()
+
+ return HttpResponseRedirect(
+ reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk}))
+
+def renumerar_materias_expediente(request, pk):
+ expedientes = ExpedienteMateria.objects.filter(sessao_plenaria_id=pk)
+
+ 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 verifica_presenca(request, model, spk):
logger = logging.getLogger(__name__)
diff --git a/sapl/templates/sessao/expedientemateria_list.html b/sapl/templates/sessao/expedientemateria_list.html
index a2ce5e2ab..e1bd0f781 100644
--- a/sapl/templates/sessao/expedientemateria_list.html
+++ b/sapl/templates/sessao/expedientemateria_list.html
@@ -7,7 +7,10 @@
{% if perms|get_add_perm:view %}
- {% blocktrans with verbose_name=view.verbose_name %} Ajustar Ordenação {% endblocktrans %}
+ {% blocktrans with verbose_name=view.verbose_name %} Reordenar pela precedência {% endblocktrans %}
+
+
+ {% blocktrans with verbose_name=view.verbose_name %} Renumerar Expediente {% endblocktrans %}
{% blocktrans with verbose_name=view.verbose_name %} Adicionar Várias Matérias {% endblocktrans %}
diff --git a/sapl/templates/sessao/ordemdia_list.html b/sapl/templates/sessao/ordemdia_list.html
index d12e3f356..bc95cf1f1 100644
--- a/sapl/templates/sessao/ordemdia_list.html
+++ b/sapl/templates/sessao/ordemdia_list.html
@@ -7,7 +7,10 @@
{% if perms|get_add_perm:view %}
- {% blocktrans with verbose_name=view.verbose_name %} Ajustar Ordenação {% endblocktrans %}
+ {% blocktrans with verbose_name=view.verbose_name %} Reordenar pela precedência {% endblocktrans %}
+
+
+ {% blocktrans with verbose_name=view.verbose_name %} Renumerar Ordem {% endblocktrans %}
{% blocktrans with verbose_name=view.verbose_name %} Adicionar Várias Matérias {% endblocktrans %}
From a64e7dbb093d7beb9f617746fa3b403457500b7f Mon Sep 17 00:00:00 2001
From: Edward Ribeiro
Date: Mon, 1 Apr 2019 17:30:17 -0300
Subject: [PATCH 11/15] HOT-FIX: adiciona assinaturas no extrato do PDF
---
sapl/relatorios/views.py | 17 +++++++++--------
sapl/templates/relatorios/relatorio_ata.html | 5 +++--
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py
index 9439b1578..deb1e885f 100755
--- a/sapl/relatorios/views.py
+++ b/sapl/relatorios/views.py
@@ -28,10 +28,10 @@ from sapl.settings import STATIC_ROOT
from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data
from sapl.sessao.views import (get_identificação_basica, get_mesa_diretora,
- get_presenca_sessao,get_expedientes,
- get_materias_expediente,get_oradores_expediente,
- get_presenca_ordem_do_dia,get_materias_ordem_do_dia,
- get_oradores_explicações_pessoais, get_ocorrencias_da_sessão)
+ get_presenca_sessao, get_expedientes,
+ get_materias_expediente, get_oradores_expediente,
+ get_presenca_ordem_do_dia, get_materias_ordem_do_dia,
+ get_oradores_explicações_pessoais, get_ocorrencias_da_sessão, get_assinaturas)
from .templates import (pdf_capa_processo_gerar,
pdf_documento_administrativo_gerar, pdf_espelho_gerar,
@@ -1258,12 +1258,13 @@ def resumo_ata_pdf(request,pk):
context.update(get_materias_ordem_do_dia(sessao_plenaria))
context.update(get_oradores_explicações_pessoais(sessao_plenaria))
context.update(get_ocorrencias_da_sessão(sessao_plenaria))
- context.update({'object':sessao_plenaria})
+ context.update(get_assinaturas(sessao_plenaria))
+ context.update({'object': sessao_plenaria})
context.update({'data': dt.today().strftime('%d/%m/%Y')})
- context.update({'rodape':rodape})
- header_context = {"casa":casa, 'logotipo':casa.logotipo, 'MEDIA_URL': MEDIA_URL}
+ context.update({'rodape': rodape})
+ header_context = {"casa": casa, 'logotipo':casa.logotipo, 'MEDIA_URL': MEDIA_URL}
- html_template = render_to_string('relatorios/relatorio_ata.html',context)
+ html_template = render_to_string('relatorios/relatorio_ata.html', context)
html_header = render_to_string('relatorios/header_ata.html', header_context)
pdf_file = make_pdf(base_url=base_url,main_template=html_template,header_template=html_header)
diff --git a/sapl/templates/relatorios/relatorio_ata.html b/sapl/templates/relatorios/relatorio_ata.html
index 743e13c82..7d6c45d7b 100644
--- a/sapl/templates/relatorios/relatorio_ata.html
+++ b/sapl/templates/relatorios/relatorio_ata.html
@@ -82,12 +82,13 @@
_____________________
- {{p.cargo}}: {{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}
+
+ {{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}
{% else %}
_____________________
- {{p.parlamentar.nome_completo}} / {{ p.parlamentar|filiacao_data_filter:object.data_inicio }}
+ {{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}
|
From 8068e64be4275300c57fdf9f357350198d9a1e1c Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Tue, 2 Apr 2019 00:07:18 -0300
Subject: [PATCH 12/15] add endpoint get ultima_tramitacao
---
sapl/api/views.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/sapl/api/views.py b/sapl/api/views.py
index f2f146e24..f15232871 100644
--- a/sapl/api/views.py
+++ b/sapl/api/views.py
@@ -349,6 +349,23 @@ class _ProposicaoViewSet(SaplSetViews['materia']['proposicao']):
return qs
+class _MateriaLegislativaViewSet(SaplSetViews['materia']['materialegislativa']):
+
+ @action(detail=True, methods=['GET'])
+ def ultima_tramitacao(self, request, *args, **kwargs):
+
+ materia = self.get_object()
+ if not materia.tramitacao_set.exists():
+ return Response({})
+
+ ultima_tramitacao = materia.tramitacao_set.last()
+
+ serializer_class = SaplSetViews[
+ 'materia']['tramitacao'].serializer_class(ultima_tramitacao)
+
+ return Response(serializer_class.data)
+
+
class _TipoMateriaLegislativaViewSet(SaplSetViews['materia']['tipomaterialegislativa']):
@action(detail=True, methods=['POST'])
@@ -443,6 +460,8 @@ class _SessaoPlenariaViewSet(
SaplSetViews['base']['autor'] = _AutorViewSet.build_class_with_actions()
+
+SaplSetViews['materia']['materialegislativa'] = _MateriaLegislativaViewSet
SaplSetViews['materia']['proposicao'] = _ProposicaoViewSet
SaplSetViews['materia']['tipomaterialegislativa'] = _TipoMateriaLegislativaViewSet
From e523e9b23cc0b29b1e9c74312d5c1dd1a87fbc19 Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Tue, 2 Apr 2019 00:18:05 -0300
Subject: [PATCH 13/15] corrige classe BusinessRulesNotImplementedMixin
---
sapl/api/views.py | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/sapl/api/views.py b/sapl/api/views.py
index f15232871..5d2ca37eb 100644
--- a/sapl/api/views.py
+++ b/sapl/api/views.py
@@ -31,11 +31,8 @@ class BusinessRulesNotImplementedMixin:
def create(self, request, *args, **kwargs):
raise Exception(_("POST Create não implementado"))
- def put(self, request, *args, **kwargs):
- raise Exception(_("PUT Update não implementado"))
-
- def patch(self, request, *args, **kwargs):
- raise Exception(_("PATCH Partial Update não implementado"))
+ def update(self, request, *args, **kwargs):
+ raise Exception(_("PUT and PATCH não implementado"))
def delete(self, request, *args, **kwargs):
raise Exception(_("DELETE Delete não implementado"))
From dfe74c59f706f61547fa9cfb1f2d926b1d5b25f1 Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Tue, 2 Apr 2019 02:02:23 -0300
Subject: [PATCH 14/15] =?UTF-8?q?simplifica=20customiza=C3=A7=C3=A3o=20de?=
=?UTF-8?q?=20viewsets=20da=20api?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/api/urls.py | 7 +--
sapl/api/views.py | 110 ++++++++++++++++++++++++++++------------------
2 files changed, 71 insertions(+), 46 deletions(-)
diff --git a/sapl/api/urls.py b/sapl/api/urls.py
index 3e874add2..27196146d 100644
--- a/sapl/api/urls.py
+++ b/sapl/api/urls.py
@@ -8,7 +8,7 @@ from rest_framework.routers import DefaultRouter
from sapl.api.deprecated import MateriaLegislativaViewSet, SessaoPlenariaViewSet,\
AutoresProvaveisListView, AutoresPossiveisListView, AutorListView,\
ModelChoiceView
-from sapl.api.views import SaplSetViews
+from sapl.api.views import SaplApiViewSetConstrutor
from .apps import AppConfig
@@ -21,9 +21,10 @@ router.register(r'materia$', MateriaLegislativaViewSet)
router.register(r'sessao-plenaria', SessaoPlenariaViewSet)
-for app, built_sets in SaplSetViews.items():
+for app, built_sets in SaplApiViewSetConstrutor._built_sets.items():
for view_prefix, viewset in built_sets.items():
- router.register(app + '/' + view_prefix, viewset)
+ router.register(app.label + '/' +
+ view_prefix._meta.model_name, viewset)
urlpatterns_router = router.urls
diff --git a/sapl/api/views.py b/sapl/api/views.py
index 5d2ca37eb..1cfdd1d44 100644
--- a/sapl/api/views.py
+++ b/sapl/api/views.py
@@ -22,8 +22,12 @@ 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, TipoMateriaLegislativa
+from sapl.materia.models import Proposicao, TipoMateriaLegislativa,\
+ MateriaLegislativa, Tramitacao
from sapl.parlamentares.models import Parlamentar
+from sapl.protocoloadm.models import DocumentoAdministrativo,\
+ DocumentoAcessorioAdministrativo, TramitacaoAdministrativo
+from sapl.sessao.models import SessaoPlenaria
from sapl.utils import models_with_gr_for_model, choice_anos_com_sessaoplenaria
@@ -38,10 +42,18 @@ class BusinessRulesNotImplementedMixin:
raise Exception(_("DELETE Delete não implementado"))
-class SaplApiViewSetConstrutor(ModelViewSet):
-
+class SaplApiViewSet(ModelViewSet):
filter_backends = (DjangoFilterBackend,)
+
+class SaplApiViewSetConstrutor():
+
+ _built_sets = {}
+
+ @classonlymethod
+ def get_class_for_model(cls, model):
+ return cls._built_sets[model._meta.app_config][model]
+
@classonlymethod
def build_class(cls):
import inspect
@@ -92,7 +104,7 @@ class SaplApiViewSetConstrutor(ModelViewSet):
model = _model
# Define uma classe padrão ModelViewSet de DRF
- class ModelSaplViewSet(cls):
+ class ModelSaplViewSet(SaplApiViewSet):
queryset = _model.objects.all()
# Utiliza o filtro customizado pela classe
@@ -116,12 +128,12 @@ class SaplApiViewSetConstrutor(ModelViewSet):
apps_sapl = [apps.apps.get_app_config(
n[5:]) for n in settings.SAPL_APPS]
for app in apps_sapl:
- built_sets[app.label] = {}
+ cls._built_sets[app] = {}
for model in app.get_models():
- built_sets[app.label][model._meta.model_name] = build(model)
+ cls._built_sets[app][model] = build(model)
- return built_sets
+SaplApiViewSetConstrutor.build_class()
"""
1. Constroi uma rest_framework.viewsets.ModelViewSet para
@@ -184,15 +196,39 @@ class SaplApiViewSetConstrutor(ModelViewSet):
}
"""
-SaplSetViews = SaplApiViewSetConstrutor.build_class()
-
# Toda Classe construida acima, pode ser redefinida e aplicado quaisquer
# das possibilidades para uma classe normal criada a partir de
# rest_framework.viewsets.ModelViewSet conforme exemplo para a classe autor
+# decorator para recuperar e transformar o default
+
+
+class customize(object):
+ def __init__(self, model):
+ self.model = model
+
+ def __call__(self, cls):
+
+ class _SaplApiViewSet(
+ cls,
+ SaplApiViewSetConstrutor._built_sets[
+ self.model._meta.app_config][self.model]
+ ):
+ pass
+
+ if hasattr(_SaplApiViewSet, 'build'):
+ _SaplApiViewSet = _SaplApiViewSet.build()
+
+ SaplApiViewSetConstrutor._built_sets[
+ self.model._meta.app_config][self.model] = _SaplApiViewSet
+ return _SaplApiViewSet
+
# Customização para AutorViewSet com implementação de actions específicas
-class _AutorViewSet(SaplSetViews['base']['autor']):
+
+
+@customize(Autor)
+class _AutorViewSet:
"""
Neste exemplo de customização do que foi criado em
SaplApiViewSetConstrutor além do ofertado por
@@ -237,7 +273,7 @@ class _AutorViewSet(SaplSetViews['base']['autor']):
return Response(serializer.data)
@classonlymethod
- def build_class_with_actions(cls):
+ def build(cls):
models_with_gr_for_autor = models_with_gr_for_model(Autor)
@@ -260,7 +296,8 @@ class _AutorViewSet(SaplSetViews['base']['autor']):
return cls
-class _ParlamentarViewSet(SaplSetViews['parlamentares']['parlamentar']):
+@customize(Parlamentar)
+class _ParlamentarViewSet:
@action(detail=True)
def proposicoes(self, request, *args, **kwargs):
"""
@@ -285,15 +322,16 @@ class _ParlamentarViewSet(SaplSetViews['parlamentares']['parlamentar']):
page = self.paginate_queryset(qs)
if page is not None:
- serializer = SaplSetViews[
- 'materia']['proposicao'].serializer_class(page, many=True)
+ serializer = SaplApiViewSetConstrutor.get_class_for_model(
+ Proposicao).serializer_class(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(page, many=True)
return Response(serializer.data)
-class _ProposicaoViewSet(SaplSetViews['materia']['proposicao']):
+@customize(Proposicao)
+class _ProposicaoViewSet():
"""
list:
Retorna lista de Proposições
@@ -346,7 +384,8 @@ class _ProposicaoViewSet(SaplSetViews['materia']['proposicao']):
return qs
-class _MateriaLegislativaViewSet(SaplSetViews['materia']['materialegislativa']):
+@customize(MateriaLegislativa)
+class _MateriaLegislativaViewSet:
@action(detail=True, methods=['GET'])
def ultima_tramitacao(self, request, *args, **kwargs):
@@ -357,13 +396,14 @@ class _MateriaLegislativaViewSet(SaplSetViews['materia']['materialegislativa']):
ultima_tramitacao = materia.tramitacao_set.last()
- serializer_class = SaplSetViews[
- 'materia']['tramitacao'].serializer_class(ultima_tramitacao)
+ serializer_class = SaplApiViewSetConstrutor.get_class_for_model(
+ Tramitacao).serializer_class(ultima_tramitacao)
return Response(serializer_class.data)
-class _TipoMateriaLegislativaViewSet(SaplSetViews['materia']['tipomaterialegislativa']):
+@customize(TipoMateriaLegislativa)
+class _TipoMateriaLegislativaViewSet:
@action(detail=True, methods=['POST'])
def change_position(self, request, *args, **kwargs):
@@ -380,7 +420,8 @@ class _TipoMateriaLegislativaViewSet(SaplSetViews['materia']['tipomaterialegisla
return Response(result)
-class _DocumentoAdministrativoViewSet(SaplSetViews['protocoloadm']['documentoadministrativo']):
+@customize(DocumentoAdministrativo)
+class _DocumentoAdministrativoViewSet:
class DocumentoAdministrativoPermission(SaplModelPermissions):
def has_permission(self, request, view):
@@ -414,8 +455,8 @@ class _DocumentoAdministrativoViewSet(SaplSetViews['protocoloadm']['documentoadm
return qs
-class _DocumentoAcessorioAdministrativoViewSet(
- SaplSetViews['protocoloadm']['documentoacessorioadministrativo']):
+@customize(DocumentoAcessorioAdministrativo)
+class _DocumentoAcessorioAdministrativoViewSet:
permission_classes = (
_DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission, )
@@ -428,9 +469,8 @@ class _DocumentoAcessorioAdministrativoViewSet(
return qs
-class _TramitacaoAdministrativoViewSet(
- SaplSetViews['protocoloadm']['tramitacaoadministrativo'],
- BusinessRulesNotImplementedMixin):
+@customize(TramitacaoAdministrativo)
+class _TramitacaoAdministrativoViewSet(BusinessRulesNotImplementedMixin):
# TODO: Implementar regras de manutenção das tramitações de docs adms
permission_classes = (
@@ -444,8 +484,8 @@ class _TramitacaoAdministrativoViewSet(
return qs
-class _SessaoPlenariaViewSet(
- SaplSetViews['sessao']['sessaoplenaria']):
+@customize(SessaoPlenaria)
+class _SessaoPlenariaViewSet:
@action(detail=False)
def years(self, request, *args, **kwargs):
@@ -453,19 +493,3 @@ class _SessaoPlenariaViewSet(
serializer = ChoiceSerializer(years, many=True)
return Response(serializer.data)
-
-
-SaplSetViews['base']['autor'] = _AutorViewSet.build_class_with_actions()
-
-
-SaplSetViews['materia']['materialegislativa'] = _MateriaLegislativaViewSet
-SaplSetViews['materia']['proposicao'] = _ProposicaoViewSet
-SaplSetViews['materia']['tipomaterialegislativa'] = _TipoMateriaLegislativaViewSet
-
-SaplSetViews['parlamentares']['parlamentar'] = _ParlamentarViewSet
-
-SaplSetViews['protocoloadm']['documentoadministrativo'] = _DocumentoAdministrativoViewSet
-SaplSetViews['protocoloadm']['documentoacessorioadministrativo'] = _DocumentoAcessorioAdministrativoViewSet
-SaplSetViews['protocoloadm']['tramitacaoadministrativo'] = _TramitacaoAdministrativoViewSet
-
-SaplSetViews['sessao']['sessaoplenaria'] = _SessaoPlenariaViewSet
From 8ec54cfe37e47fa0400d7d34e1700abed5f2863d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?=
Date: Wed, 3 Apr 2019 11:38:39 -0300
Subject: [PATCH 15/15] Fix #2653 (#2677)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implementa chamada REST
Remove ipdb
Atualiza testes
Atualiza formatação de estilo do jquery
Co-authored-by: Edward Ribeiro
Co-authored-by: Victor Fabre
---
sapl/comissoes/urls.py | 3 +-
sapl/comissoes/views.py | 16 +++-
sapl/materia/forms.py | 61 +++++++++++----
sapl/materia/tests/test_materia_form.py | 13 +++-
sapl/materia/views.py | 86 +---------------------
sapl/templates/materia/relatoria_form.html | 19 +++++
6 files changed, 94 insertions(+), 104 deletions(-)
diff --git a/sapl/comissoes/urls.py b/sapl/comissoes/urls.py
index 72886f1f1..f22f32e1d 100644
--- a/sapl/comissoes/urls.py
+++ b/sapl/comissoes/urls.py
@@ -1,7 +1,7 @@
from django.conf.urls import include, url
from sapl.comissoes.views import (CargoCrud, ComissaoCrud, ComposicaoCrud,
DocumentoAcessorioCrud, MateriasTramitacaoListView, ParticipacaoCrud,
- PeriodoComposicaoCrud, ReuniaoCrud, TipoComissaoCrud)
+ PeriodoComposicaoCrud, ReuniaoCrud, TipoComissaoCrud, get_participacoes_comissao)
from .apps import AppConfig
@@ -21,4 +21,5 @@ urlpatterns = [
url(r'^sistema/comissao/periodo-composicao/',
include(PeriodoComposicaoCrud.get_urls())),
url(r'^sistema/comissao/tipo/', include(TipoComissaoCrud.get_urls())),
+ url(r'^sistema/comissao/recupera-participacoes', get_participacoes_comissao),
]
diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py
index d6d129b11..7b8a6fd1d 100644
--- a/sapl/comissoes/views.py
+++ b/sapl/comissoes/views.py
@@ -2,7 +2,7 @@ import logging
from django.core.urlresolvers import reverse
from django.db.models import F
-from django.http.response import HttpResponseRedirect
+from django.http.response import HttpResponseRedirect, JsonResponse
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.generic import ListView
from django.views.generic.base import RedirectView
@@ -108,7 +108,7 @@ class ComposicaoCrud(MasterDetailCrud):
paginate_by = None
def take_composicao_pk(self):
-
+
username = self.request.user.username
try:
self.logger.debug('user=' + username + '. Tentando obter pk da composição.')
@@ -278,3 +278,15 @@ class DocumentoAcessorioCrud(MasterDetailCrud):
return HttpResponseRedirect(
reverse('sapl.comissoes:reuniao_detail',
kwargs={'pk': obj.reuniao.pk}))
+
+
+def get_participacoes_comissao(request):
+ parlamentares = []
+
+ composicao_id = request.GET.get('composicao_id')
+ if composicao_id:
+ parlamentares = [{'nome': p.parlamentar.nome_parlamentar, 'id': p.parlamentar.id} for p in
+ Participacao.objects.filter(composicao_id=composicao_id).order_by(
+ 'parlamentar__nome_parlamentar')]
+
+ return JsonResponse(parlamentares, safe=False)
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
index cf200447e..673dfd024 100644
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -26,7 +26,7 @@ import django_filters
import sapl
from sapl.base.models import AppConfig, Autor, TipoAutor
-from sapl.comissoes.models import Comissao, Participacao
+from sapl.comissoes.models import Comissao, Participacao, Composicao
from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC,
STATUS_TA_PRIVATE)
from sapl.crispy_layout_mixin import (SaplFormLayout, form_actions, to_column,
@@ -37,7 +37,7 @@ from sapl.materia.models import (AssuntoMateria, Autoria, MateriaAssunto,
UnidadeTramitacao)
from sapl.norma.models import (LegislacaoCitada, NormaJuridica,
TipoNormaJuridica)
-from sapl.parlamentares.models import Legislatura, Partido
+from sapl.parlamentares.models import Legislatura, Partido, Parlamentar
from sapl.protocoloadm.models import Protocolo, DocumentoAdministrativo
from sapl.settings import MAX_DOC_UPLOAD_SIZE
from sapl.utils import (YES_NO_CHOICES, SEPARADOR_HASH_PROPOSICAO,
@@ -345,7 +345,7 @@ class AcompanhamentoMateriaForm(ModelForm):
self.helper = SaplFormHelper()
self.helper.layout = Layout(
Fieldset(
- _('Acompanhamento de Matéria por e-mail'),
+ _('Acompanhamento de Matéria por e-mail'),
row1,
form_actions(label='Cadastrar')
)
@@ -362,34 +362,63 @@ class DocumentoAcessorioForm(FileFieldCheckMixin, ModelForm):
class RelatoriaForm(ModelForm):
-
logger = logging.getLogger(__name__)
+ composicao = forms.ModelChoiceField(
+ required=True,
+ empty_label='---------',
+ queryset=Composicao.objects.all(),
+ label=_('Composição')
+ )
+
class Meta:
model = Relatoria
- fields = ['data_designacao_relator', 'comissao', 'parlamentar',
- 'data_destituicao_relator', 'tipo_fim_relatoria']
+ fields = [
+ 'comissao',
+ 'data_designacao_relator',
+ 'data_destituicao_relator',
+ 'tipo_fim_relatoria',
+ 'composicao',
+ 'parlamentar'
+ ]
widgets = {'comissao': forms.Select(attrs={'disabled': 'disabled'})}
def __init__(self, *args, **kwargs):
+ row1 = to_row([('comissao', 12)])
+ row2 = to_row([('data_designacao_relator', 4),
+ ('data_destituicao_relator', 4),
+ ('tipo_fim_relatoria', 4)])
+ row3 = to_row([('composicao', 4),
+ ('parlamentar', 8)])
+
+ self.helper = SaplFormHelper()
+ self.helper.layout = SaplFormLayout(
+ Fieldset(_('Relatoria'), row1, row2, row3))
+
super().__init__(*args, **kwargs)
+ comissao_pk = kwargs['initial']['comissao']
+ composicoes = Composicao.objects.filter(comissao_id=comissao_pk)
+ self.fields['composicao'].choices = [('', '---------')] + \
+ [(c.pk, c) for c in composicoes]
- def clean(self):
- super(RelatoriaForm, self).clean()
+ self.fields['parlamentar'].choices = [('', '---------')]
- if not self.is_valid():
- return self.cleaned_data
+ def clean(self):
+ super().clean()
cleaned_data = self.cleaned_data
+ if not self.is_valid():
+ return cleaned_data
+
try:
self.logger.debug("Tentando obter objeto Comissao.")
comissao = Comissao.objects.get(id=self.initial['comissao'])
except ObjectDoesNotExist as e:
- self.logger.error("Objeto Comissao não encontrado com id={} "
- ".A localização atual deve ser uma comissão. "
- .format(self.initial['comissao']) + str(e))
+ self.logger.error(
+ "Objeto Comissao não encontrado com id={}. A localização atual deve ser uma comissão. ".format(
+ self.initial['comissao']) + str(e))
msg = _('A localização atual deve ser uma comissão.')
raise ValidationError(msg)
else:
@@ -1537,7 +1566,7 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
tm, am, nm = (cd.get('tipo_materia', ''),
cd.get('ano_materia', ''),
cd.get('numero_materia', ''))
-
+
if cd['numero_materia_futuro'] and \
'tipo' in cd and \
MateriaLegislativa.objects.filter(tipo=cd['tipo'].tipo_conteudo_related,
@@ -1755,7 +1784,7 @@ class ConfirmarProposicaoForm(ProposicaoForm):
self._meta.fields.remove('regime_tramitacao')
# esta chamada isola o __init__ de ProposicaoForm
- super(ProposicaoForm, self).__init__(*args, **kwargs)
+ super(ProposicaoForm, self).__init__(*args, **kwargs)
fields = [
Fieldset(
@@ -1831,7 +1860,7 @@ class ConfirmarProposicaoForm(ProposicaoForm):
self.fields['tipo_readonly'].initial = self.instance.tipo.descricao
self.fields['autor_readonly'].initial = str(self.instance.autor)
if self.instance.numero_materia_futuro:
- self.fields['numero_materia_futuro'].initial = self.instance.numero_materia_futuro
+ self.fields['numero_materia_futuro'].initial = self.instance.numero_materia_futuro
if self.instance.materia_de_vinculo:
self.fields[
diff --git a/sapl/materia/tests/test_materia_form.py b/sapl/materia/tests/test_materia_form.py
index b67ef2733..e29d89815 100644
--- a/sapl/materia/tests/test_materia_form.py
+++ b/sapl/materia/tests/test_materia_form.py
@@ -2,6 +2,7 @@ import pytest
from django.utils.translation import ugettext as _
from model_mommy import mommy
+from sapl.comissoes.models import Comissao, TipoComissao
from sapl.materia import forms
from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa
@@ -172,15 +173,23 @@ def test_valida_campos_obrigatorios_devolver_proposicao_form():
@pytest.mark.django_db(transaction=False)
def test_valida_campos_obrigatorios_relatoria_form():
- form = forms.RelatoriaForm(data={})
+ tipo_comissao = mommy.make(TipoComissao)
+ comissao = mommy.make(Comissao,
+ tipo=tipo_comissao,
+ nome='Comissao Teste',
+ sigla='T',
+ data_criacao='2016-03-21')
+ form = forms.RelatoriaForm(initial={'comissao':comissao}, data={})
assert not form.is_valid()
errors = form.errors
+
assert errors['parlamentar'] == [_('Este campo é obrigatório.')]
assert errors['data_designacao_relator'] == [_('Este campo é obrigatório.')]
+ assert errors['composicao'] == [_('Este campo é obrigatório.')]
- assert len(errors) == 2
+ assert len(errors) == 3
@pytest.mark.django_db(transaction=False)
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
index a2366c8d9..73dcb3072 100644
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -1111,55 +1111,13 @@ class RelatoriaCrud(MasterDetailCrud):
class CreateView(MasterDetailCrud.CreateView):
form_class = RelatoriaForm
+ layout_key = None
logger = logging.getLogger(__name__)
- def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
- username = self.request.user.username
-
- 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'])
- except:
- self.logger.error("user=" + username + ". Objeto Comissão de pk={} não encontrado.".format(
- context['form'].initial['comissao']))
- pass
-
- else:
- 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'))
- data_materia = materia.data_apresentacao
-
- comissao = Comissao.objects.get(
- pk=context['form'].initial['comissao'])
- composicao = comissao.composicao_set.filter(
- Q(periodo__data_fim__isnull=False,
- periodo__data_inicio__lte=data_materia,
- periodo__data_fim__gte=data_materia) |
- Q(periodo__data_fim__isnull=True,
- periodo__data_inicio__lte=data_materia)
- )
-
- participacoes = Participacao.objects.select_related().filter(composicao=composicao)
-
- parlamentares = [('', '---------')] + [
- (participacao.parlamentar.id, participacao.parlamentar.nome_parlamentar) for participacao in
- participacoes if participacao.titular]
-
- context['form'].fields['parlamentar'].choices = parlamentares
-
- return context
-
def get_initial(self):
materia = MateriaLegislativa.objects.get(id=self.kwargs['pk'])
- loc_atual = Tramitacao.objects.filter(
- materia=materia).last()
+ loc_atual = Tramitacao.objects.filter(materia=materia).last()
if loc_atual is None:
localizacao = 0
@@ -1174,47 +1132,9 @@ class RelatoriaCrud(MasterDetailCrud):
class UpdateView(MasterDetailCrud.UpdateView):
form_class = RelatoriaForm
-
+ layout_key = None
logger = logging.getLogger(__name__)
- def get_context_data(self, **kwargs):
-
- context = super().get_context_data(**kwargs)
- username = self.request.user.username
-
- 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'])
- except ObjectDoesNotExist:
- self.logger.error("user=" + username + ". Objeto Comissão de pk={} não encontrado.".format(
- context['form'].initial['comissao']))
- pass
- else:
- 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'))
- ano_materia = relatoria.materia.ano
-
- 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)
-
- participacoes = Participacao.objects.select_related().filter(composicao=composicao)
-
- parlamentares = [('', '---------')] + [
- (participacao.parlamentar.id, participacao.parlamentar.nome_parlamentar) for participacao in
- participacoes if participacao.titular]
-
- context['form'].fields['parlamentar'].choices = parlamentares
-
- return context
-
class TramitacaoCrud(MasterDetailCrud):
model = Tramitacao
diff --git a/sapl/templates/materia/relatoria_form.html b/sapl/templates/materia/relatoria_form.html
index 5dc3ca9c9..02f9a904a 100644
--- a/sapl/templates/materia/relatoria_form.html
+++ b/sapl/templates/materia/relatoria_form.html
@@ -16,5 +16,24 @@
{% block extra_js %}
{% endblock extra_js %}