From 9c3d22a44591048fa75478001a53b0869039be0c Mon Sep 17 00:00:00 2001
From: Edward Ribeiro
Date: Wed, 28 Aug 2019 16:31:13 -0300
Subject: [PATCH 01/17] Trata URL mal formada do YouTube
---
sapl/base/templatetags/common_tags.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sapl/base/templatetags/common_tags.py b/sapl/base/templatetags/common_tags.py
index 12192ab6f..048778d8d 100644
--- a/sapl/base/templatetags/common_tags.py
+++ b/sapl/base/templatetags/common_tags.py
@@ -249,8 +249,10 @@ def facebook_url(value):
def youtube_id(value):
from urllib.parse import urlparse, parse_qs
u_pars = urlparse(value)
- quer_v = parse_qs(u_pars.query).get('v')[0]
- return quer_v
+ quer_v = parse_qs(u_pars.query).get('v')
+ if quer_v:
+ return quer_v[0]
+ return ''
@register.filter
From 5f32c0ebd254a4b4fc85392cbc962873f2b6df85 Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Wed, 28 Aug 2019 17:02:30 -0300
Subject: [PATCH 02/17] add __str__ nos resultados da api
---
sapl/api/views.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sapl/api/views.py b/sapl/api/views.py
index 6f4e9219a..9ddafb9ec 100644
--- a/sapl/api/views.py
+++ b/sapl/api/views.py
@@ -15,6 +15,7 @@ from django_filters.rest_framework.filterset import FilterSet
from django_filters.utils import resolve_field
from rest_framework import serializers as rest_serializers
from rest_framework.decorators import action
+from rest_framework.fields import SerializerMethodField
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
@@ -94,10 +95,15 @@ class SaplApiViewSetConstrutor():
# Define uma classe padrão para serializer caso não tenha sido
# criada a classe sapl.api.serializers.{model}Serializer
class SaplSerializer(rest_serializers.ModelSerializer):
+ __str__ = SerializerMethodField()
+
class Meta:
model = _model
fields = '__all__'
+ def get___str__(self, obj):
+ return str(obj)
+
# Define uma classe padrão para filtro caso não tenha sido
# criada a classe sapl.api.forms.{model}FilterSet
class SaplFilterSet(SaplFilterSetMixin):
From ac340918076d516f237a31d85358f2db0ee675cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?=
Date: Thu, 29 Aug 2019 11:42:56 -0300
Subject: [PATCH 03/17] Fix #2943 (#2944)
---
sapl/base/tests/test_view_base.py | 6 +++---
sapl/base/views.py | 2 +-
sapl/templates/base/parlamentares_duplicados.html | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/sapl/base/tests/test_view_base.py b/sapl/base/tests/test_view_base.py
index 6655317b3..44d7a3632 100644
--- a/sapl/base/tests/test_view_base.py
+++ b/sapl/base/tests/test_view_base.py
@@ -194,13 +194,13 @@ def test_lista_parlamentares_duplicados():
sexo='M'
)
- lista_dict_values_parlamentares_duplicados = parlamentares_duplicados()
+ lista_dict_parlamentares_duplicados = parlamentares_duplicados()
parlamentar_duplicado = list(
- lista_dict_values_parlamentares_duplicados[0]
+ lista_dict_parlamentares_duplicados[0].values()
)
parlamentar_duplicado.sort(key=str)
- assert len(lista_dict_values_parlamentares_duplicados) == 1
+ assert len(lista_dict_parlamentares_duplicados) == 1
assert parlamentar_duplicado == [2, "Nome_Parlamentar_Teste"]
diff --git a/sapl/base/views.py b/sapl/base/views.py
index 8fec1a305..da9698702 100644
--- a/sapl/base/views.py
+++ b/sapl/base/views.py
@@ -1430,7 +1430,7 @@ class ListarParlMandatosIntersecaoView(PermissionRequiredMixin, ListView):
def parlamentares_duplicados():
- return [parlamentar.values() for parlamentar in Parlamentar.objects.values(
+ return [parlamentar for parlamentar in Parlamentar.objects.values(
'nome_parlamentar').order_by('nome_parlamentar').annotate(count=Count(
'nome_parlamentar')).filter(count__gt=1)]
diff --git a/sapl/templates/base/parlamentares_duplicados.html b/sapl/templates/base/parlamentares_duplicados.html
index 0bb86e2ce..a7727f342 100644
--- a/sapl/templates/base/parlamentares_duplicados.html
+++ b/sapl/templates/base/parlamentares_duplicados.html
@@ -15,12 +15,12 @@
- {% for quantidade, parlamentar in parlamentares_duplicados %}
+ {% for parlamentar in parlamentares_duplicados %}
|
- {{ parlamentar }}
+ {{ parlamentar.nome_parlamentar }}
|
- {{ quantidade }} |
+ {{ parlamentar.count }} |
{% endfor %}
From 4211cff3a647cb9d717d00f6c36d34fa6673d14d Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Fri, 30 Aug 2019 14:32:34 -0300
Subject: [PATCH 04/17] HOT-FIX: mantem query_string em redirect app comp
---
sapl/compilacao/views.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py
index 671e5bcf1..d27d85f1a 100644
--- a/sapl/compilacao/views.py
+++ b/sapl/compilacao/views.py
@@ -195,8 +195,13 @@ class IntegracaoTaView(TemplateView):
return redirect(to=reverse_lazy('sapl.compilacao:ta_text_edit',
kwargs={'ta_id': ta.pk}))
else:
- return redirect(to=reverse_lazy('sapl.compilacao:ta_text',
- kwargs={'ta_id': ta.pk}))
+ return redirect(
+ to='%s?%s' % (
+ reverse_lazy('sapl.compilacao:ta_text',
+ kwargs={'ta_id': ta.pk}),
+ request.META['QUERY_STRING']
+ )
+ )
class Meta:
abstract = True
From 7f819997c4329c1a7aa0935c73eb6ab3692b55dd Mon Sep 17 00:00:00 2001
From: Edward <9326037+edwardoliveira@users.noreply.github.com>
Date: Fri, 30 Aug 2019 14:54:23 -0300
Subject: [PATCH 05/17] =?UTF-8?q?Adiciona=20n=C3=BAmero=20protocolo=20a=20?=
=?UTF-8?q?comprovante=20de=20protocolo=20(OSTicket=20Ticket=20#730379)=20?=
=?UTF-8?q?(#2950)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/protocoloadm/views.py | 7 +++++++
sapl/templates/protocoloadm/comprovante.html | 15 ++++++++++++---
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py
index a1a8b05d4..358b057ab 100755
--- a/sapl/protocoloadm/views.py
+++ b/sapl/protocoloadm/views.py
@@ -700,6 +700,13 @@ class ComprovanteProtocoloView(PermissionRequiredMixin, TemplateView):
autenticacao = str(protocolo.tipo_processo) + \
data + str(protocolo.numero).zfill(6)
+ if protocolo.tipo_materia:
+ materia = MateriaLegislativa.objects.filter(
+ numero_protocolo=protocolo.numero,
+ ano=protocolo.ano).first()
+ if materia:
+ context['materia'] = materia.numero
+
context.update({"protocolo": protocolo,
"barcode": barcode,
"autenticacao": autenticacao})
diff --git a/sapl/templates/protocoloadm/comprovante.html b/sapl/templates/protocoloadm/comprovante.html
index 2e1c3ce89..3289e2632 100644
--- a/sapl/templates/protocoloadm/comprovante.html
+++ b/sapl/templates/protocoloadm/comprovante.html
@@ -18,6 +18,9 @@
.hide-print {
display : none;
}
+ .downsize {
+ font-size: 12px;
+ }
}
@page {
size: auto; /* auto is the initial value */
@@ -74,7 +77,7 @@
{% if protocolo.tipo_processo == 1 %}
| Ementa |
- {{ protocolo.assunto_ementa }} |
+ {{ protocolo.assunto_ementa }} |
| Autor |
@@ -102,10 +105,16 @@
| Número Páginas |
- {{ protocolo.numero_paginas }} |
+ {{ protocolo.numero_paginas|default_if_none:"0" }} |
+ {% if materia %}
- | Comprovante emitido por |
+ Número da Matéria |
+ {{ materia }} |
+
+ {% endif %}
+
+ | Emitido por |
{{ request.user.username }} |
From 4e0a99bf5edd3a38af29c2563119adfb2b8ba63c Mon Sep 17 00:00:00 2001
From: ulyssesBML
Date: Mon, 2 Sep 2019 12:16:06 -0300
Subject: [PATCH 06/17] =?UTF-8?q?HOT-FIX=20-=20Concertando=20erro=20pagina?=
=?UTF-8?q?=20de=20tramita=C3=A7=C3=A3o=20em=20comissoes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/comissoes/views.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py
index 5fa132eab..0b5ca756d 100644
--- a/sapl/comissoes/views.py
+++ b/sapl/comissoes/views.py
@@ -167,7 +167,7 @@ class ComissaoCrud(Crud):
def lista_materias_comissao(comissao_pk):
ts = Tramitacao.objects.order_by(
- 'materia', '-data_tramitacao', '-id').annotate(
+ 'materia_id', '-data_tramitacao', '-id').annotate(
comissao=F('unidade_tramitacao_destino__comissao')).distinct(
'materia').values_list('materia', 'comissao')
From 5f5f8f64ed79baa6e6b0fa168bb1ae0bd13facc9 Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Mon, 2 Sep 2019 17:02:45 -0300
Subject: [PATCH 07/17] HOT-FIX: autopep8 by IDE
---
sapl/protocoloadm/views.py | 103 +++++++++++++++++++------------------
1 file changed, 52 insertions(+), 51 deletions(-)
diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py
index 358b057ab..71b8d4734 100755
--- a/sapl/protocoloadm/views.py
+++ b/sapl/protocoloadm/views.py
@@ -34,10 +34,10 @@ from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa, Unid
from sapl.materia.views import gerar_pdf_impressos
from sapl.parlamentares.models import Legislatura, Parlamentar
from sapl.protocoloadm.models import Protocolo
+from sapl.relatorios.views import relatorio_doc_administrativos
from sapl.utils import (create_barcode, get_base_url, get_client_ip,
get_mime_type_from_file_extension, lista_anexados,
show_results_filter_set, mail_service_configured)
-from sapl.relatorios.views import relatorio_doc_administrativos
from .forms import (AcompanhamentoDocumentoForm, AnularProtocoloAdmForm,
DocumentoAcessorioAdministrativoForm,
@@ -290,7 +290,7 @@ class AcompanhamentoDocumentoView(CreateView):
de mensagens e clique no link que nós enviamos para \
confirmar o acompanhamento deste documento.')
messages.add_message(request, messages.SUCCESS, msg)
-
+
# Caso esse Acompanhamento já exista
# avisa ao usuário que esse documento já está sendo acompanhado
else:
@@ -302,7 +302,7 @@ class AcompanhamentoDocumentoView(CreateView):
return self.render_to_response(
{'form': form,
'documento': documento,
- })
+ })
return HttpResponseRedirect(self.get_success_url())
else:
return self.render_to_response(
@@ -917,7 +917,7 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin,
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
-
+
return context
def get(self, request, *args, **kwargs):
@@ -942,21 +942,22 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin,
length = self.object_list.filter(restrito=False).count()
else:
length = self.object_list.count()
-
- is_relatorio = url!='' and request.GET.get('relatorio',None)
- self.paginate_by = None if is_relatorio else self.paginate_by
+
+ is_relatorio = url != '' and request.GET.get('relatorio', None)
+ self.paginate_by = None if is_relatorio else self.paginate_by
context = self.get_context_data(filter=self.filterset,
filter_url=url,
numero_res=length
)
context['show_results'] = show_results_filter_set(
self.request.GET.copy())
-
+
if is_relatorio:
- return relatorio_doc_administrativos(request,context)
- else:
+ return relatorio_doc_administrativos(request, context)
+ else:
return self.render_to_response(context)
-
+
+
class AnexadoCrud(MasterDetailCrud):
model = Anexado
parent_field = 'documento_principal'
@@ -994,7 +995,7 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
def get_context_data(self, **kwargs):
context = super(
DocumentoAnexadoEmLoteView, self
- ).get_context_data(**kwargs)
+ ).get_context_data(**kwargs)
context['root_pk'] = self.kwargs['pk']
@@ -1004,17 +1005,17 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
# Verifica se os campos foram preenchidos
if not self.request.GET.get('tipo', " "):
- msg =_('Por favor, selecione um tipo de documento.')
+ msg = _('Por favor, selecione um tipo de documento.')
messages.add_message(self.request, messages.ERROR, msg)
-
+
if not self.request.GET.get('data_0', " ") or not self.request.GET.get('data_1', " "):
- msg =_('Por favor, preencha as datas.')
+ msg = _('Por favor, preencha as datas.')
messages.add_message(self.request, messages.ERROR, msg)
return context
if not self.request.GET.get('data_0', " ") or not self.request.GET.get('data_1', " "):
- msg =_('Por favor, preencha as datas.')
+ msg = _('Por favor, preencha as datas.')
messages.add_message(self.request, messages.ERROR, msg)
return context
@@ -1026,17 +1027,19 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
context['object_list'] = []
for obj in context['temp_object_list']:
if not obj.pk == int(context['root_pk']):
- documento_principal = DocumentoAdministrativo.objects.get(id=context['root_pk'])
+ documento_principal = DocumentoAdministrativo.objects.get(
+ id=context['root_pk'])
documento_anexado = obj
is_anexado = Anexado.objects.filter(documento_principal=documento_principal,
documento_anexado=documento_anexado).exists()
if not is_anexado:
ciclico = False
- anexados_anexado = Anexado.objects.filter(documento_principal=documento_anexado)
+ anexados_anexado = Anexado.objects.filter(
+ documento_principal=documento_anexado)
while anexados_anexado and not ciclico:
anexados = []
-
+
for anexo in anexados_anexado:
if documento_principal == anexo.documento_anexado:
@@ -1049,18 +1052,18 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
if not ciclico:
context['object_list'].append(obj)
-
+
context['numero_res'] = len(context['object_list'])
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
-
+
context['show_results'] = show_results_filter_set(qr)
return context
def post(self, request, *args, **kwargs):
marcados = request.POST.getlist('documento_id')
-
+
data_anexacao = datetime.strptime(
request.POST['data_anexacao'], "%d/%m/%Y"
).date()
@@ -1075,22 +1078,22 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
v_data_desanexacao = data_desanexacao
if len(marcados) == 0:
- msg =_('Nenhum documento foi selecionado')
+ msg = _('Nenhum documento foi selecionado')
messages.add_message(request, messages.ERROR, msg)
-
+
if data_anexacao > v_data_desanexacao:
- msg=_('Data de anexação posterior à data de desanexação.')
+ msg = _('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
-
+
return self.get(request, self.kwargs)
if data_anexacao > v_data_desanexacao:
- msg =_('Data de anexação posterior à data de desanexação.')
+ msg = _('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, messages.ERROR, msg)
- principal = DocumentoAdministrativo.objects.get(pk = kwargs['pk'])
- for documento in DocumentoAdministrativo.objects.filter(id__in = marcados):
+ principal = DocumentoAdministrativo.objects.get(pk=kwargs['pk'])
+ for documento in DocumentoAdministrativo.objects.filter(id__in=marcados):
anexado = Anexado()
anexado.documento_principal = principal
anexado.documento_anexado = documento
@@ -1101,7 +1104,8 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
msg = _('Documento(s) anexado(s).')
messages.add_message(request, messages.SUCCESS, msg)
- success_url = reverse('sapl.protocoloadm:anexado_list', kwargs={'pk': kwargs['pk']})
+ success_url = reverse('sapl.protocoloadm:anexado_list', kwargs={
+ 'pk': kwargs['pk']})
return HttpResponseRedirect(success_url)
@@ -1149,7 +1153,8 @@ class TramitacaoAdmCrud(MasterDetailCrud):
'-timestamp',
'-id').first()
- #TODO: Esta checagem foi inserida na issue #2027, mas é mesmo necessária?
+ # TODO: Esta checagem foi inserida na issue #2027, mas é mesmo
+ # necessária?
if ultima_tramitacao:
if ultima_tramitacao.unidade_tramitacao_destino:
context['form'].fields[
@@ -1231,13 +1236,12 @@ class TramitacaoAdmCrud(MasterDetailCrud):
MasterDetailCrud.DetailView):
template_name = 'protocoloadm/tramitacaoadministrativo_detail.html'
-
+
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['user'] = self.request.user
return context
-
class DeleteView(MasterDetailCrud.DeleteView):
logger = logging.getLogger(__name__)
@@ -1278,7 +1282,8 @@ class TramitacaoAdmCrud(MasterDetailCrud):
if da.tramitacaoadministrativo_set.count() == 0:
da.tramitacao = False
da.save()
- TramitacaoAdministrativo.objects.filter(id__in=tramitacoes_deletar).delete()
+ TramitacaoAdministrativo.objects.filter(
+ id__in=tramitacoes_deletar).delete()
return HttpResponseRedirect(url)
@@ -1471,7 +1476,6 @@ class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView):
logger = logging.getLogger(__name__)
-
def get_context_data(self, **kwargs):
context = super(PrimeiraTramitacaoEmLoteAdmView,
self).get_context_data(**kwargs)
@@ -1493,8 +1497,8 @@ class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView):
if self.primeira_tramitacao:
context['title'] = _('Primeira Tramitação em Lote')
# Pega somente documentos que não possuem tramitação
- context['object_list'] = [obj for obj in context['object_list']
- if obj.tramitacaoadministrativo_set.all().count() == 0]
+ context['object_list'] = [obj for obj in context['object_list']
+ if obj.tramitacaoadministrativo_set.all().count() == 0]
else:
context['title'] = _('Tramitação em Lote')
context['form'].fields['unidade_tramitacao_local'].initial = UnidadeTramitacao.objects.get(
@@ -1516,32 +1520,33 @@ class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView):
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
- form = TramitacaoEmLoteAdmForm(request.POST,
- initial= {'documentos': documentos_ids,
- 'user': user, 'ip':ip})
+ form = TramitacaoEmLoteAdmForm(request.POST,
+ initial={'documentos': documentos_ids,
+ 'user': user, 'ip': ip})
if form.is_valid():
form.save()
msg = _('Tramitação completa.')
- self.logger.info('user=' + user.username + '. Tramitação completa.')
+ self.logger.info('user=' + user.username +
+ '. Tramitação completa.')
messages.add_message(request, messages.SUCCESS, msg)
return self.get_success_url()
return self.form_invalid(form)
-
def get_success_url(self):
return HttpResponseRedirect(reverse('sapl.protocoloadm:primeira_tramitacao_em_lote_docadm'))
-
def form_invalid(self, form, *args, **kwargs):
for key, erros in form.errors.items():
- if not key=='__all__':
- [messages.add_message(self.request, messages.ERROR, form.fields[key].label + ": " + e) for e in erros]
+ if not key == '__all__':
+ [messages.add_message(
+ self.request, messages.ERROR, form.fields[key].label + ": " + e) for e in erros]
else:
- [messages.add_message(self.request, messages.ERROR, e) for e in erros]
- return self.get(self.request, kwargs, {'form':form})
+ [messages.add_message(self.request, messages.ERROR, e)
+ for e in erros]
+ return self.get(self.request, kwargs, {'form': form})
class TramitacaoEmLoteAdmView(PrimeiraTramitacaoEmLoteAdmView):
@@ -1569,21 +1574,18 @@ class TramitacaoEmLoteAdmView(PrimeiraTramitacaoEmLoteAdmView):
return context
-
def pega_ultima_tramitacao(self):
return TramitacaoAdministrativo.objects.values(
'documento_id').annotate(data_encaminhamento=Max(
'data_encaminhamento'),
id=Max('id')).values_list('id', flat=True)
-
def filtra_tramitacao_status(self, status):
lista = self.pega_ultima_tramitacao()
return TramitacaoAdministrativo.objects.filter(
id__in=lista,
status=status).distinct().values_list('documento_id', flat=True)
-
def filtra_tramitacao_destino(self, destino):
lista = self.pega_ultima_tramitacao()
return TramitacaoAdministrativo.objects.filter(
@@ -1591,7 +1593,6 @@ class TramitacaoEmLoteAdmView(PrimeiraTramitacaoEmLoteAdmView):
unidade_tramitacao_destino=destino).distinct().values_list(
'documento_id', flat=True)
-
def filtra_tramitacao_destino_and_status(self, status, destino):
lista = self.pega_ultima_tramitacao()
return TramitacaoAdministrativo.objects.filter(
From bc016c465e369b16b4359d8eef004082489976bc Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Mon, 2 Sep 2019 17:05:23 -0300
Subject: [PATCH 08/17] HOT-FIX: rem trans incor de link p texto_integral
---
sapl/protocoloadm/views.py | 12 ++++++------
sapl/templates/protocoloadm/layouts.yaml | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py
index 71b8d4734..f8135e1bc 100755
--- a/sapl/protocoloadm/views.py
+++ b/sapl/protocoloadm/views.py
@@ -373,13 +373,13 @@ class DocumentoAdministrativoCrud(Crud):
return redirect('/')
return super(Crud.DetailView, self).get(args, kwargs)
- def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
- self.layout_display[0]['rows'][-1][0]['text'] = (
- '' % reverse(
+ def urlize(self, obj, fieldname):
+ a = '%s' % (
+ reverse(
'sapl.protocoloadm:doc_texto_integral',
- kwargs={'pk': self.object.pk}))
- return context
+ kwargs={'pk': obj.pk}),
+ obj.texto_integral.name.split('/')[-1])
+ return obj.texto_integral.field.verbose_name, a
class DeleteView(Crud.DeleteView):
diff --git a/sapl/templates/protocoloadm/layouts.yaml b/sapl/templates/protocoloadm/layouts.yaml
index d87a99b56..3f78f676e 100644
--- a/sapl/templates/protocoloadm/layouts.yaml
+++ b/sapl/templates/protocoloadm/layouts.yaml
@@ -9,7 +9,7 @@ DocumentoAdministrativo:
- data protocolo
- assunto
- interessado tramitacao
- - texto_integral
+ - texto_integral|urlize
- documento_anexado_set__documento_principal|m2m_urlize_for_detail
- documento_principal_set__documento_anexado|m2m_urlize_for_detail
{% trans 'Outras Informações' %}:
From f0e78b4e9006bb1b66e3be446537531b0c15cdbc Mon Sep 17 00:00:00 2001
From: Cesar Carvalho
Date: Thu, 5 Sep 2019 14:11:57 -0300
Subject: [PATCH 09/17] =?UTF-8?q?HOT-FIX:=20Melhora=20HTML=20de=20Vota?=
=?UTF-8?q?=C3=A7=C3=B5es=20Nominal=20e=20Simb=C3=B3lica?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/templates/sessao/votacao/nominal.html | 80 ++++++++++++----------
sapl/templates/sessao/votacao/votacao.html | 66 ++++++++++--------
2 files changed, 78 insertions(+), 68 deletions(-)
diff --git a/sapl/templates/sessao/votacao/nominal.html b/sapl/templates/sessao/votacao/nominal.html
index 470b02228..540e0f3da 100644
--- a/sapl/templates/sessao/votacao/nominal.html
+++ b/sapl/templates/sessao/votacao/nominal.html
@@ -21,49 +21,53 @@
{% else %}
-
-
-
- {{ form.resultado_votacao|as_crispy_field }}
-
-
+
+ {% for parlamentar in parlamentares %}
+
{{parlamentar.0.nome_parlamentar}}
+
+ {% if parlamentar.1 %} {% endif %}
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+ {{ form.resultado_votacao|as_crispy_field }}
+
+
-
+
-
-
-
-
- {% endif %}
+
+ {% endif %}
+
+
{% endblock detail_content %}
{% block extra_js %}
diff --git a/sapl/templates/sessao/votacao/votacao.html b/sapl/templates/sessao/votacao/votacao.html
index d7320c5b1..3a74413cc 100644
--- a/sapl/templates/sessao/votacao/votacao.html
+++ b/sapl/templates/sessao/votacao/votacao.html
@@ -38,41 +38,47 @@
-
+
-
-
- A totalização inclui o voto do Presidente?*
-
-
+
+
+ A totalização inclui o voto do Presidente?*
+
+
-
- Resultado da Votação*
-
-
-
+
+ Resultado da Votação*
+
+
+
-
+
-
-
+
{% endblock detail_content %}
From 3607486546c0a309d0f71a14bd6f376b21623446 Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Fri, 6 Sep 2019 12:59:51 -0300
Subject: [PATCH 10/17] corrige crud para container_fields
---
sapl/crud/base.py | 39 ++++++++++++++++++++++++++++-----------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/sapl/crud/base.py b/sapl/crud/base.py
index 98af2a3bb..18f3d5c29 100644
--- a/sapl/crud/base.py
+++ b/sapl/crud/base.py
@@ -4,13 +4,14 @@ from braces.views import FormMessagesMixin
from crispy_forms.bootstrap import FieldWithButtons, StrictButton
from crispy_forms.layout import Field, Layout
from django import forms
+from django.conf import settings
from django.conf.urls import url
from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.db import models
-from django.db.models.fields.related import ForeignKey
+from django.db.models.fields.related import ForeignKey, ManyToManyField
from django.http.response import Http404
from django.shortcuts import redirect
from django.utils.decorators import classonlymethod
@@ -27,10 +28,12 @@ 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
from sapl.utils import normalize
+logger = logging.getLogger(settings.BASE_DIR.name)
+
+
ACTION_LIST, ACTION_CREATE, ACTION_DETAIL, ACTION_UPDATE, ACTION_DELETE = \
'list', 'create', 'detail', 'update', 'delete'
@@ -122,7 +125,6 @@ class SearchMixin(models.Model):
except Exception as e:
username = self.request.user.username
self.logger.error("user=" + username + ". " + str(e))
- pass
else:
_self = self
for field in fields:
@@ -206,6 +208,7 @@ class PermissionRequiredContainerCrudMixin(PermissionRequiredMixin):
if not self.model.objects.filter(**params).exists():
raise Http404()
+
elif self.container_field:
container = self.container_field.split('__')
@@ -230,14 +233,14 @@ class PermissionRequiredContainerCrudMixin(PermissionRequiredMixin):
return super(PermissionRequiredMixin, self).dispatch(
request, *args, **kwargs)
- @cached_property
+ @property
def container_field(self):
if hasattr(self, 'crud') and not hasattr(self.crud, 'container_field'):
self.crud.container_field = ''
if hasattr(self, 'crud'):
return self.crud.container_field
- @cached_property
+ @property
def container_field_set(self):
if hasattr(self, 'crud') and\
not hasattr(self.crud, 'container_field_set'):
@@ -245,7 +248,7 @@ class PermissionRequiredContainerCrudMixin(PermissionRequiredMixin):
if hasattr(self, 'crud'):
return self.crud.container_field_set
- @cached_property
+ @property
def is_contained(self):
return self.container_field_set or self.container_field
@@ -600,7 +603,7 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView):
# print(ordering)
except Exception as e:
- print(string_concat(_(
+ logger.error(string_concat(_(
'ERRO: construção da tupla de ordenação.'), str(e)))
# print(queryset.query)
@@ -1108,12 +1111,14 @@ class MasterDetailCrud(Crud):
permission_required = RP_LIST,
logger = logging.getLogger(__name__)
+ def get(self, request, *args, **kwargs):
+ return Crud.ListView.get(self, request, *args, **kwargs)
+
@classmethod
def get_url_regex(cls):
return r'^(?P\d+)/%s$' % cls.model._meta.model_name
def get_context_data(self, **kwargs):
-
obj = self.crud if hasattr(self, 'crud') else self
context = CrudListView.get_context_data(self, **kwargs)
@@ -1133,7 +1138,12 @@ class MasterDetailCrud(Crud):
else:
parent_model = getattr(
- self.model, obj.parent_field).field.related_model
+ self.model, obj.parent_field)
+ if isinstance(parent_model.field, (
+ ForeignKey, ManyToManyField)):
+ parent_model = parent_model.field.related_model
+ else:
+ parent_model = parent_model.rel.related_model
params = {'pk': kwargs['root_pk']}
@@ -1165,6 +1175,9 @@ class MasterDetailCrud(Crud):
return qs.filter(**kwargs)
+ def dispatch(self, request, *args, **kwargs):
+ return PermissionRequiredMixin.dispatch(self, request, *args, **kwargs)
+
class CreateView(Crud.CreateView):
permission_required = RP_ADD,
logger = logging.getLogger(__name__)
@@ -1229,8 +1242,12 @@ class MasterDetailCrud(Crud):
parent_object = getattr(parent_object, field)
else:
- parent_model = getattr(
- parent_model, obj.parent_field).field.related_model
+ parent_model = getattr(self.model, obj.parent_field)
+ if isinstance(parent_model.field, ForeignKey):
+ parent_model = parent_model.field.related_model
+ else:
+ parent_model = parent_model.rel.related_model
+
parent_object = parent_model.objects.get(**params)
context['root_pk'] = parent_object.pk
From c08e0a69d388ece393c26b41e0d64aec41485005 Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Sat, 14 Sep 2019 01:44:02 -0300
Subject: [PATCH 11/17] =?UTF-8?q?HOT-FIX:=20corrige=20signal=20de=20ajuste?=
=?UTF-8?q?=20de=20indicador=20de=20tramita=C3=A7=C3=A3o?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/base/receivers.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sapl/base/receivers.py b/sapl/base/receivers.py
index b2176be14..1e402ffb0 100644
--- a/sapl/base/receivers.py
+++ b/sapl/base/receivers.py
@@ -1,6 +1,5 @@
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
-
from sapl.materia.models import Tramitacao
from sapl.protocoloadm.models import TramitacaoAdministrativo
from sapl.base.signals import tramitacao_signal
@@ -30,7 +29,7 @@ def handle_tramitacao_signal(sender, **kwargs):
@receiver(post_delete)
def status_tramitacao_materia(sender, instance, **kwargs):
- if isinstance(sender, TramitacaoAdministrativo):
+ if isinstance(sender, Tramitacao):
if instance.status.indicador == 'F':
materia = instance.materia
materia.em_tramitacao = True
From 9f29a46df487e64e0fb68ba528108fc4cd6b7bf8 Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Sat, 14 Sep 2019 02:16:56 -0300
Subject: [PATCH 12/17] HOT-FIX: corrige teste de classes em post_delete
---
sapl/base/receivers.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sapl/base/receivers.py b/sapl/base/receivers.py
index 1e402ffb0..f5f19f1f3 100644
--- a/sapl/base/receivers.py
+++ b/sapl/base/receivers.py
@@ -29,12 +29,12 @@ def handle_tramitacao_signal(sender, **kwargs):
@receiver(post_delete)
def status_tramitacao_materia(sender, instance, **kwargs):
- if isinstance(sender, Tramitacao):
+ if sender == Tramitacao:
if instance.status.indicador == 'F':
materia = instance.materia
materia.em_tramitacao = True
materia.save()
- elif isinstance(sender, TramitacaoAdministrativo):
+ elif sender == TramitacaoAdministrativo:
if instance.status.indicador == 'F':
documento = instance.documento
documento.tramitacao = True
From 51aefc6798c8a39abac37b88512f33359d379e80 Mon Sep 17 00:00:00 2001
From: Cesar Carvalho
Date: Thu, 19 Sep 2019 09:50:39 -0300
Subject: [PATCH 13/17] Release: 3.1.160-RC1
---
docker-compose.yml | 2 +-
sapl/settings.py | 2 +-
sapl/templates/base.html | 2 +-
setup.py | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docker-compose.yml b/docker-compose.yml
index 3f4eb46b3..5eb35418d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -11,7 +11,7 @@ sapldb:
ports:
- "5432:5432"
sapl:
- image: interlegis/sapl:3.1.160-RC0
+ image: interlegis/sapl:3.1.160-RC1
restart: always
environment:
ADMIN_PASSWORD: interlegis
diff --git a/sapl/settings.py b/sapl/settings.py
index c9764545c..c97f2311a 100644
--- a/sapl/settings.py
+++ b/sapl/settings.py
@@ -41,7 +41,7 @@ ALLOWED_HOSTS = ['*']
LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/login/?next='
-SAPL_VERSION = '3.1.160-RC0'
+SAPL_VERSION = '3.1.160-RC1'
if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
diff --git a/sapl/templates/base.html b/sapl/templates/base.html
index d9f63f74f..64d296c94 100644
--- a/sapl/templates/base.html
+++ b/sapl/templates/base.html
@@ -179,7 +179,7 @@
Desenvolvido pelo Interlegis em software livre e aberto.
- Release: 3.1.160-RC0
+ Release: 3.1.160-RC1
diff --git a/setup.py b/setup.py
index d15324dd6..b2fb9b1d9 100644
--- a/setup.py
+++ b/setup.py
@@ -43,7 +43,7 @@ install_requires = [
]
setup(
name='interlegis-sapl',
- version='3.1.160-RC0',
+ version='3.1.160-RC1',
packages=find_packages(),
include_package_data=True,
license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007',
From 8829879f74d14bd1a4abed6d4873a331b56a3652 Mon Sep 17 00:00:00 2001
From: Edward Ribeiro
Date: Wed, 25 Sep 2019 15:46:08 -0300
Subject: [PATCH 14/17] Evita que se criem autores com nomes repetidos
---
sapl/base/forms.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sapl/base/forms.py b/sapl/base/forms.py
index d51e0e321..e3ec2b6a9 100644
--- a/sapl/base/forms.py
+++ b/sapl/base/forms.py
@@ -618,6 +618,10 @@ class AutorForm(ModelForm):
tipo = cd['tipo']
+ if 'nome' in cd and \
+ Autor.objects.filter(nome=cd['nome']).exists():
+ raise ValidationError("Autor '%s' já existente!" % cd['nome'])
+
if not tipo.content_type:
if 'nome' not in cd or not cd['nome']:
self.logger.error('Nome do Autor não informado.')
From 55c070b5776f6cb331a5f9be3fd9f8a2f7a575c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?=
Date: Wed, 25 Sep 2019 15:57:30 -0300
Subject: [PATCH 15/17] =?UTF-8?q?Fix=20Ticket=20#923744=20-=20Tempo=20de?=
=?UTF-8?q?=20resposta=20do=20relat=C3=B3rio=20de=20mat=C3=A9rias=20em=20t?=
=?UTF-8?q?ramita=C3=A7=C3=A3o=20(#2955)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Otimiza relatório de matérias em tramitação
* Refatoração
* HOT-FIX: corrige erro apontado pelo travis
* Adicionar nova model
* Adicionar on_delete nos campos da model
* Acelera pesquisa do relatório
* Refatoração
---
sapl/base/forms.py | 55 +++---
sapl/base/views.py | 158 +++++++++++-------
.../0056_popula_materiaemtramitacao.py | 23 +++
.../migrations/0057_materiaemtramitacao.py | 25 +++
sapl/materia/models.py | 12 ++
sapl/rules/map_rules.py | 1 +
...RelatorioMateriasPorTramitacao_filter.html | 17 +-
7 files changed, 197 insertions(+), 94 deletions(-)
create mode 100644 sapl/materia/migrations/0056_popula_materiaemtramitacao.py
create mode 100644 sapl/materia/migrations/0057_materiaemtramitacao.py
diff --git a/sapl/base/forms.py b/sapl/base/forms.py
index e3ec2b6a9..d111e7f4c 100644
--- a/sapl/base/forms.py
+++ b/sapl/base/forms.py
@@ -18,27 +18,25 @@ from django.utils.translation import string_concat
from django.utils.translation import ugettext_lazy as _
import django_filters
-from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica
-from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica
+from sapl.audiencia.models import AudienciaPublica
from sapl.base.models import Autor, TipoAutor
-from sapl.comissoes.models import Reuniao, Comissao
-from sapl.comissoes.models import Reuniao, Comissao
-from sapl.crispy_layout_mixin import (SaplFormLayout, form_actions, to_column,
- to_row)
-from sapl.crispy_layout_mixin import SaplFormHelper
-from sapl.materia.models import (MateriaLegislativa, UnidadeTramitacao, StatusTramitacao,
- DocumentoAcessorio, TipoMateriaLegislativa)
-from sapl.norma.models import (NormaJuridica, NormaEstatisticas)
-from sapl.parlamentares.models import SessaoLegislativa, Partido
+from sapl.comissoes.models import Reuniao
+from sapl.crispy_layout_mixin import (form_actions, to_column, to_row,
+ SaplFormHelper, SaplFormLayout)
+from sapl.materia.models import (DocumentoAcessorio, MateriaEmTramitacao,
+ MateriaLegislativa, UnidadeTramitacao,
+ StatusTramitacao)
+from sapl.norma.models import NormaJuridica
+from sapl.parlamentares.models import Partido, SessaoLegislativa
from sapl.protocoloadm.models import DocumentoAdministrativo
from sapl.sessao.models import SessaoPlenaria
from sapl.settings import MAX_IMAGE_UPLOAD_SIZE
-from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES,
- ChoiceWithoutValidationField, ImageThumbnailFileInput,
- RangeWidgetOverride, autor_label, autor_modal,
- models_with_gr_for_model, qs_override_django_filter,
+from sapl.utils import (autor_label, autor_modal, ChoiceWithoutValidationField,
choice_anos_com_normas, choice_anos_com_materias,
- FilterOverridesMetaMixin, FileFieldCheckMixin)
+ FilterOverridesMetaMixin, FileFieldCheckMixin,
+ ImageThumbnailFileInput, models_with_gr_for_model,
+ qs_override_django_filter, RangeWidgetOverride,
+ RANGE_ANOS, YES_NO_CHOICES)
from .models import AppConfig, CasaLegislativa
@@ -1089,9 +1087,9 @@ class RelatorioAudienciaFilterSet(django_filters.FilterSet):
)
-class RelatorioMateriasTramitacaoilterSet(django_filters.FilterSet):
+class RelatorioMateriasTramitacaoFilterSet(django_filters.FilterSet):
- ano = django_filters.ChoiceFilter(required=True,
+ materia__ano = django_filters.ChoiceFilter(required=True,
label='Ano da Matéria',
choices=choice_anos_com_materias)
@@ -1105,22 +1103,25 @@ class RelatorioMateriasTramitacaoilterSet(django_filters.FilterSet):
@property
def qs(self):
- parent = super(RelatorioMateriasTramitacaoilterSet, self).qs
- return parent.distinct().order_by('-ano', 'tipo', '-numero')
+ parent = super(RelatorioMateriasTramitacaoFilterSet, self).qs
+ return parent.distinct().order_by(
+ '-materia__ano', 'materia__tipo', '-materia__numero'
+ )
class Meta:
- model = MateriaLegislativa
- fields = ['ano', 'tipo', 'tramitacao__unidade_tramitacao_destino',
+ model = MateriaEmTramitacao
+ fields = ['materia__ano', 'materia__tipo',
+ 'tramitacao__unidade_tramitacao_destino',
'tramitacao__status']
def __init__(self, *args, **kwargs):
- super(RelatorioMateriasTramitacaoilterSet, self).__init__(
+ super(RelatorioMateriasTramitacaoFilterSet, self).__init__(
*args, **kwargs)
- self.filters['tipo'].label = 'Tipo de Matéria'
+ self.filters['materia__tipo'].label = 'Tipo de Matéria'
- row1 = to_row([('ano', 12)])
- row2 = to_row([('tipo', 12)])
+ row1 = to_row([('materia__ano', 12)])
+ row2 = to_row([('materia__tipo', 12)])
row3 = to_row([('tramitacao__unidade_tramitacao_destino', 12)])
row4 = to_row([('tramitacao__status', 12)])
@@ -1576,4 +1577,4 @@ class RelatorioNormasPorAutorFilterSet(django_filters.FilterSet):
HTML(autor_modal),
row3,
form_actions(label='Pesquisar'))
- )
\ No newline at end of file
+ )
diff --git a/sapl/base/views.py b/sapl/base/views.py
index da9698702..c54dc34cd 100644
--- a/sapl/base/views.py
+++ b/sapl/base/views.py
@@ -13,7 +13,8 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, Validat
from django.core.mail import send_mail
from django.core.urlresolvers import reverse, reverse_lazy
from django.db import connection
-from django.db.models import Count, Q, ProtectedError
+from django.db.models import Count, Q, ProtectedError, Max
+from django.shortcuts import render
from django.http import Http404, HttpResponseRedirect, JsonResponse
from django.template import TemplateDoesNotExist
from django.template.loader import get_template
@@ -31,23 +32,26 @@ from haystack.query import SearchQuerySet
from sapl import settings
from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica
-from sapl.base.forms import AutorForm, AutorFormForAdmin, TipoAutorForm
from sapl.base.models import Autor, TipoAutor
-from sapl.comissoes.models import Reuniao, Comissao
+from sapl.base.forms import AutorForm, AutorFormForAdmin, TipoAutorForm
+from sapl.comissoes.models import Comissao, Reuniao
from sapl.crud.base import CrudAux, make_pagination
-from sapl.materia.models import (Autoria, MateriaLegislativa, Proposicao, Anexada,
- TipoMateriaLegislativa, StatusTramitacao, UnidadeTramitacao,
- DocumentoAcessorio, TipoDocumento)
-from sapl.norma.models import (NormaJuridica, TipoNormaJuridica, NormaEstatisticas)
-from sapl.parlamentares.models import Parlamentar, Legislatura, Mandato, Filiacao, SessaoLegislativa
-from sapl.protocoloadm.models import (Protocolo, TipoDocumentoAdministrativo,
- StatusTramitacaoAdministrativo,
- DocumentoAdministrativo, Anexado)
-from sapl.sessao.models import (PresencaOrdemDia, SessaoPlenaria,
- SessaoPlenariaPresenca, Bancada, TipoSessaoPlenaria)
-from sapl.utils import (parlamentares_ativos, gerar_hash_arquivo, SEPARADOR_HASH_PROPOSICAO,
- show_results_filter_set, mail_service_configured,
- intervalos_tem_intersecao, remover_acentos)
+from sapl.materia.models import (Anexada, Autoria, DocumentoAcessorio,
+ MateriaEmTramitacao, MateriaLegislativa, Proposicao,
+ StatusTramitacao, TipoDocumento,
+ TipoMateriaLegislativa, UnidadeTramitacao, Tramitacao)
+from sapl.norma.models import NormaJuridica, TipoNormaJuridica
+from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato, Parlamentar,
+ SessaoLegislativa)
+from sapl.protocoloadm.models import (Anexado, DocumentoAdministrativo, Protocolo,
+ StatusTramitacaoAdministrativo,
+ TipoDocumentoAdministrativo)
+from sapl.sessao.models import (Bancada, PresencaOrdemDia, SessaoPlenaria,
+ SessaoPlenariaPresenca, TipoSessaoPlenaria)
+from sapl.utils import (gerar_hash_arquivo, intervalos_tem_intersecao,
+ mail_service_configured, parlamentares_ativos,
+ SEPARADOR_HASH_PROPOSICAO, show_results_filter_set)
+
from .forms import (AlterarSenhaForm, CasaLegislativaForm,
ConfiguracoesAppForm, RelatorioAtasFilterSet,
RelatorioAudienciaFilterSet,
@@ -55,7 +59,7 @@ from .forms import (AlterarSenhaForm, CasaLegislativaForm,
RelatorioHistoricoTramitacaoFilterSet,
RelatorioMateriasPorAnoAutorTipoFilterSet,
RelatorioMateriasPorAutorFilterSet,
- RelatorioMateriasTramitacaoilterSet,
+ RelatorioMateriasTramitacaoFilterSet,
RelatorioPresencaSessaoFilterSet,
RelatorioReuniaoFilterSet, UsuarioCreateForm,
UsuarioEditForm, RelatorioNormasMesFilterSet,
@@ -67,19 +71,6 @@ from .forms import (AlterarSenhaForm, CasaLegislativaForm,
from .models import AppConfig, CasaLegislativa
-def filtra_url_materias_em_tramitacao(qr, qs, campo_url, local_ou_status):
- id_materias = []
- filtro_url = qr[campo_url]
- if local_ou_status == 'local':
- id_materias = [item.id for item in qs if item.tramitacao_set.order_by(
- '-id').first().unidade_tramitacao_destino_id == int(filtro_url)]
- elif local_ou_status == 'status':
- id_materias = [item.id for item in qs if item.tramitacao_set.order_by(
- '-id').first().status_id == int(filtro_url)]
-
- return qs.filter(em_tramitacao=True, id__in=id_materias)
-
-
def get_casalegislativa():
return CasaLegislativa.objects.first()
@@ -703,61 +694,108 @@ class RelatorioAudienciaView(FilterView):
class RelatorioMateriasTramitacaoView(FilterView):
- model = MateriaLegislativa
- filterset_class = RelatorioMateriasTramitacaoilterSet
+ model = MateriaEmTramitacao
+ filterset_class = RelatorioMateriasTramitacaoFilterSet
template_name = 'base/RelatorioMateriasPorTramitacao_filter.html'
+ paginate_by = 100
+
+ total_resultados_tipos = {}
+
+ def get_filterset_kwargs(self, filterset_class):
+ data = super().get_filterset_kwargs(filterset_class)
+
+ if data['data']:
+ qs = data['queryset']
+
+ ano_materia = data['data']['materia__ano']
+ tipo_materia = data['data']['materia__tipo']
+ unidade_tramitacao_destino = data['data']['tramitacao__unidade_tramitacao_destino']
+ status_tramitacao = data['data']['tramitacao__status']
+
+ kwargs = {}
+ if ano_materia:
+ kwargs['materia__ano'] = ano_materia
+ if tipo_materia:
+ kwargs['materia__tipo'] = tipo_materia
+ if unidade_tramitacao_destino:
+ kwargs['tramitacao__unidade_tramitacao_destino'] = unidade_tramitacao_destino
+ if status_tramitacao:
+ kwargs['tramitacao__status'] = status_tramitacao
+ qs = qs.filter(**kwargs)
+
+ data['queryset'] = qs
+
+ qtdes = { tipo:0 for tipo in TipoMateriaLegislativa.objects.all() }
+ for i in qs:
+ qtdes[i.materia.tipo] += 1
+
+ # remove as entradas de valor igual a zero
+ qtdes = {k:v for k,v in qtdes.items() if v > 0}
+ self.total_resultados_tipos = qtdes
+
+ return data
+
+ def get_queryset(self):
+ qs = super().get_queryset()
+ qs = qs.select_related('materia__tipo').filter(
+ materia__em_tramitacao=True
+ ).exclude(
+ tramitacao__status__indicador='F'
+ ).order_by('-materia__ano', '-materia__numero')
+ return qs
+
def get_context_data(self, **kwargs):
- context = super(RelatorioMateriasTramitacaoView,
- self).get_context_data(**kwargs)
+ context = super(
+ RelatorioMateriasTramitacaoView, self
+ ).get_context_data(**kwargs)
context['title'] = _('Matérias em Tramitação')
+
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
- qs = context['object_list']
- qs = qs.filter(em_tramitacao=True)
-
- if qr.get('tramitacao__unidade_tramitacao_destino'):
- qs = filtra_url_materias_em_tramitacao(
- qr, qs, 'tramitacao__unidade_tramitacao_destino', 'local')
- if qr.get('tramitacao__status'):
- qs = filtra_url_materias_em_tramitacao(
- qr, qs, 'tramitacao__status', 'status')
- li = [li1 for li1 in qs if li1.tramitacao_set.last() and li1.tramitacao_set.last().status.indicador != 'F']
- context['object_list'] = li
+ context['qtdes'] = self.total_resultados_tipos
+ context['ano'] = (self.request.GET['materia__ano'])
- qtdes = {}
- for tipo in TipoMateriaLegislativa.objects.all():
- li = context['object_list']
- qtde = sum(1 for i in li if i.tipo_id==tipo.id)
- if qtde > 0:
- qtdes[tipo] = qtde
- context['qtdes'] = qtdes
- context['ano'] = (self.request.GET['ano'])
- if self.request.GET['tipo']:
- tipo = self.request.GET['tipo']
+ if self.request.GET['materia__tipo']:
+ tipo = self.request.GET['materia__tipo']
context['tipo'] = (
- str(TipoMateriaLegislativa.objects.get(id=tipo)))
+ str(TipoMateriaLegislativa.objects.get(id=tipo))
+ )
else:
context['tipo'] = ''
+
if self.request.GET['tramitacao__status']:
tramitacao_status = self.request.GET['tramitacao__status']
context['tramitacao__status'] = (
- str(StatusTramitacao.objects.get(id=tramitacao_status)))
+ str(StatusTramitacao.objects.get(id=tramitacao_status))
+ )
else:
context['tramitacao__status'] = ''
+
if self.request.GET['tramitacao__unidade_tramitacao_destino']:
- context['tramitacao__unidade_tramitacao_destino'] = (str(UnidadeTramitacao.objects.get(
- id=self.request.GET['tramitacao__unidade_tramitacao_destino'])))
+ context['tramitacao__unidade_tramitacao_destino'] = (
+ str(UnidadeTramitacao.objects.get(
+ id=self.request.GET['tramitacao__unidade_tramitacao_destino']
+ ))
+ )
else:
context['tramitacao__unidade_tramitacao_destino'] = ''
+
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
-
context['show_results'] = show_results_filter_set(qr)
+ paginator = context['paginator']
+ page_obj = context['page_obj']
+
+ context['page_range'] = make_pagination(
+ page_obj.number, paginator.num_pages
+ )
+ context['NO_ENTRIES_MSG'] = 'Nenhum encontrado.'
+
return context
diff --git a/sapl/materia/migrations/0056_popula_materiaemtramitacao.py b/sapl/materia/migrations/0056_popula_materiaemtramitacao.py
new file mode 100644
index 000000000..dfa4c0175
--- /dev/null
+++ b/sapl/materia/migrations/0056_popula_materiaemtramitacao.py
@@ -0,0 +1,23 @@
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('materia', '0055_auto_20190816_0943'),
+ ]
+
+ operations = [
+ migrations.RunSQL("""
+ create or replace view materia_materiaemtramitacao as
+ select m.id as id,
+ m.id as materia_id,
+ t.id as tramitacao_id
+ from materia_materialegislativa m
+ inner join materia_tramitacao t on (m.id = t.materia_id)
+ where t.id = (select max(id) from materia_tramitacao where materia_id = m.id)
+ order by m.id DESC
+ """),
+ ]
\ No newline at end of file
diff --git a/sapl/materia/migrations/0057_materiaemtramitacao.py b/sapl/materia/migrations/0057_materiaemtramitacao.py
new file mode 100644
index 000000000..95953f50b
--- /dev/null
+++ b/sapl/materia/migrations/0057_materiaemtramitacao.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-08-27 20:13
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('materia', '0056_popula_materiaemtramitacao'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='MateriaEmTramitacao',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ],
+ options={
+ 'db_table': 'materia_materiaemtramitacao',
+ 'managed': False,
+ },
+ ),
+ ]
diff --git a/sapl/materia/models.py b/sapl/materia/models.py
index b641377de..77203e0e4 100644
--- a/sapl/materia/models.py
+++ b/sapl/materia/models.py
@@ -1084,3 +1084,15 @@ class Tramitacao(models.Model):
'materia': self.materia,
'status': self.status,
'data': self.data_tramitacao.strftime("%d/%m/%Y")}
+
+
+class MateriaEmTramitacao(models.Model):
+ materia = models.ForeignKey(MateriaLegislativa, on_delete=models.DO_NOTHING)
+ tramitacao = models.ForeignKey(Tramitacao, on_delete=models.DO_NOTHING)
+
+ class Meta:
+ managed = False
+ db_table = "materia_materiaemtramitacao"
+
+ def __str__(self):
+ return '{}/{}'.format(self.materia, self.tramitacao)
diff --git a/sapl/rules/map_rules.py b/sapl/rules/map_rules.py
index 4f1b4b515..aa187477d 100644
--- a/sapl/rules/map_rules.py
+++ b/sapl/rules/map_rules.py
@@ -127,6 +127,7 @@ rules_group_materia = {
['can_access_impressos'], __perms_publicas__),
(materia.Numeracao, __base__, __perms_publicas__),
(materia.Tramitacao, __base__, __perms_publicas__),
+ (materia.MateriaEmTramitacao, __base__, __perms_publicas__),
(norma.LegislacaoCitada, __base__, __perms_publicas__),
(norma.AutoriaNorma, __base__, __perms_publicas__),
(compilacao.Dispositivo, __base__ + [
diff --git a/sapl/templates/base/RelatorioMateriasPorTramitacao_filter.html b/sapl/templates/base/RelatorioMateriasPorTramitacao_filter.html
index 02cad5e43..738e615b8 100644
--- a/sapl/templates/base/RelatorioMateriasPorTramitacao_filter.html
+++ b/sapl/templates/base/RelatorioMateriasPorTramitacao_filter.html
@@ -44,17 +44,20 @@
- {% for materia in object_list %}
+ {% for materia_em_tramitacao in object_list %}
- |
- {{materia.tipo.descricao}} {{materia.numero}}/{{materia.ano}}
- |
- {{materia.tramitacao_set.last.unidade_tramitacao_destino}} |
- {{materia.tramitacao_set.last.status}} |
+
+
+ {{ materia_em_tramitacao.materia.tipo.descricao }} {{ materia_em_tramitacao.materia.numero }}/{{ materia_em_tramitacao.materia.ano }}
+
+ |
+ {{ materia_em_tramitacao.materia.tramitacao_set.last.unidade_tramitacao_destino }} |
+ {{ materia_em_tramitacao.materia.tramitacao_set.last.status }} |
{% endfor %}
{% endif %}
-
+ {% include 'paginacao.html' %}
+
{% endblock base_content %}
From c7d5259d4d21cc739f441ab6d952ee1d8cd25469 Mon Sep 17 00:00:00 2001
From: Cesar Augusto de Carvalho
Date: Wed, 25 Sep 2019 15:58:09 -0300
Subject: [PATCH 16/17] =?UTF-8?q?Fix=20#2910=20-=20Usu=C3=A1rio=20sem=20pe?=
=?UTF-8?q?rmiss=C3=A3o=20acessa=20Proposi=C3=A7=C3=A3o=20pela=20url=20(#2?=
=?UTF-8?q?963)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/materia/views.py | 7 +-
sapl/templates/materia/proposicao_detail.html | 309 +++++++++---------
2 files changed, 163 insertions(+), 153 deletions(-)
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
index 2b5dc5697..94f10f539 100644
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -772,7 +772,7 @@ class ProposicaoCrud(Crud):
context['title'] = '%s (%s)' % (
self.object, self.object.autor)
-
+
context['user'] = self.request.user
context['proposicao'] = Proposicao.objects.get(
pk=self.kwargs['pk']
@@ -782,7 +782,8 @@ class ProposicaoCrud(Crud):
def get(self, request, *args, **kwargs):
action = request.GET.get('action', '')
- username = request.user.username
+ user = request.user
+ username = user.username
if not action:
return Crud.DetailView.get(self, request, *args, **kwargs)
@@ -790,7 +791,7 @@ class ProposicaoCrud(Crud):
p = Proposicao.objects.get(id=kwargs['pk'])
msg_error = ''
- if p:
+ if p and p.autor.user == user:
if action == 'send':
if p.data_envio and p.data_recebimento:
msg_error = _('Proposição já foi enviada e recebida.')
diff --git a/sapl/templates/materia/proposicao_detail.html b/sapl/templates/materia/proposicao_detail.html
index b35d3de8b..487cc8600 100644
--- a/sapl/templates/materia/proposicao_detail.html
+++ b/sapl/templates/materia/proposicao_detail.html
@@ -3,204 +3,213 @@
{% load tz %}
{% block sub_actions %}
{{block.super}}
-
+ {% if user == object.autor.user %}
+
+ {% endif %}
{% endblock sub_actions%}
{% block editions %}
- {% if object.data_envio %}
- {% if user == object.autor.user %}
- {% block editions_actions_return %}
+ {% if user == object.autor.user %}
+ {% if object.data_envio %}
+ {% block editions_actions_return %}
+
+ {% endblock %}
+ {% else %}
+ {% block editions_actions_send %}
+
{% endblock %}
{% endif %}
- {% else %}
- {% block editions_actions_send %}
-
-
- {% endblock %}
{% endif %}
{% endblock editions %}
{% block detail_content %}
- {% model_verbose_name 'sapl.materia.models.Proposicao' %}
-