From 84b56a37eccf42860916a30850e501baa8ab641e Mon Sep 17 00:00:00 2001
From: Edward Ribeiro
Date: Thu, 4 Apr 2019 15:39:29 -0300
Subject: [PATCH 01/18] HOT-FIX: fixes #2686
---
sapl/materia/views.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
index 73dcb3072..e30b756fb 100644
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -1987,7 +1987,7 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
file_path = os.path.join(diretorio,
request.FILES['arquivo'].name)
shutil.copy2(tmp_name, file_path)
- doc.arquivo.name = file_path.split(MEDIA_ROOT)[1] # Retira MEDIA_ROOT do nome
+ doc.arquivo.name = file_path.split(MEDIA_ROOT + "/")[1] # Retira MEDIA_ROOT do nome
doc.save()
os.remove(tmp_name)
From 008954d9799b9ab1cf94fef66bf3966f6d0fd58e Mon Sep 17 00:00:00 2001
From: Edward
Date: Sun, 7 Apr 2019 10:06:51 -0300
Subject: [PATCH 02/18] fixes #2689 (#2690)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* fixes #2689
* Trata inexistencia de chaves
* Adiciona verificação de data
---
sapl/materia/forms.py | 15 ++++++++++++++-
sapl/materia/views.py | 22 +++++++++++++++++++++-
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
index 673dfd024..d6935b697 100644
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -402,7 +402,16 @@ class RelatoriaForm(ModelForm):
self.fields['composicao'].choices = [('', '---------')] + \
[(c.pk, c) for c in composicoes]
- self.fields['parlamentar'].choices = [('', '---------')]
+ # UPDATE
+ if self.initial.get('composicao') and self.initial.get('parlamentar'):
+ parlamentares = [(p.parlamentar.id, p.parlamentar) for p in
+ Participacao.objects.filter(composicao__comissao_id=comissao_pk,
+ composicao_id=self.initial['composicao'])]
+
+ self.fields['parlamentar'].choices = [('', '---------')] + parlamentares
+ # INSERT
+ else:
+ self.fields['parlamentar'].choices = [('', '---------')]
def clean(self):
super().clean()
@@ -424,6 +433,10 @@ class RelatoriaForm(ModelForm):
else:
cleaned_data['comissao'] = comissao
+ if cleaned_data['data_designacao_relator'] < cleaned_data['composicao'].periodo.data_inicio \
+ or cleaned_data['data_designacao_relator'] > cleaned_data['composicao'].periodo.data_fim:
+ raise ValidationError(_('Data de designação deve estar dentro do período da composição.'))
+
return cleaned_data
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
index e30b756fb..6c0da0ce0 100644
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -33,7 +33,7 @@ import sapl
from sapl.base.email_utils import do_envia_email_confirmacao
from sapl.base.models import Autor, CasaLegislativa, AppConfig as BaseAppConfig
from sapl.base.signals import tramitacao_signal
-from sapl.comissoes.models import Comissao, Participacao
+from sapl.comissoes.models import Comissao, Participacao, Composicao
from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT,
STATUS_TA_PRIVATE)
from sapl.compilacao.views import IntegracaoTaView
@@ -1135,6 +1135,26 @@ class RelatoriaCrud(MasterDetailCrud):
layout_key = None
logger = logging.getLogger(__name__)
+ def get_initial(self):
+ relatoria = Relatoria.objects.get(id=self.kwargs['pk'])
+ parlamentar = relatoria.parlamentar
+ comissao = relatoria.comissao
+ composicoes = [p.composicao for p in
+ Participacao.objects.filter(
+ parlamentar=parlamentar,
+ composicao__comissao=comissao)]
+ data_designacao = relatoria.data_designacao_relator
+ composicao = ''
+ for c in composicoes:
+ data_inicial = c.periodo.data_inicio
+ data_fim = c.periodo.data_fim if c.periodo.data_fim else timezone.now().date()
+ if data_inicial <= data_designacao <= data_fim:
+ composicao = c.id
+ break
+ return {'comissao': relatoria.comissao.id,
+ 'parlamentar': relatoria.parlamentar.id,
+ 'composicao': composicao}
+
class TramitacaoCrud(MasterDetailCrud):
model = Tramitacao
From 988f2bab9e02e230ba1d9b0a4bbaa46545492abf Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Sun, 7 Apr 2019 23:31:47 -0300
Subject: [PATCH 03/18] =?UTF-8?q?add=20a=C3=A7=C3=A3o=20para=20recuperar?=
=?UTF-8?q?=20mat=20anexadas=20de=20uma=20mat=C3=A9ria?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/api/views.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sapl/api/views.py b/sapl/api/views.py
index 1cfdd1d44..2eedb9464 100644
--- a/sapl/api/views.py
+++ b/sapl/api/views.py
@@ -401,6 +401,11 @@ class _MateriaLegislativaViewSet:
return Response(serializer_class.data)
+ @action(detail=True, methods=['GET'])
+ def anexadas(self, request, *args, **kwargs):
+ self.queryset = self.get_object().anexadas.all()
+ return self.list(request, *args, **kwargs)
+
@customize(TipoMateriaLegislativa)
class _TipoMateriaLegislativaViewSet:
From 6c940d96820e7b647ef31ecc128c9e372e01cc7b Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Mon, 8 Apr 2019 09:27:52 -0300
Subject: [PATCH 04/18] update auto pep
---
sapl/materia/forms.py | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
index d6935b697..c91f8c90e 100644
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -3,7 +3,6 @@ import logging
import os
from crispy_forms.bootstrap import Alert, InlineRadios
-from sapl.crispy_layout_mixin import SaplFormHelper
from crispy_forms.layout import (HTML, Button, Column, Div, Field, Fieldset,
Layout, Row)
from django import forms
@@ -31,6 +30,7 @@ from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC,
STATUS_TA_PRIVATE)
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 (AssuntoMateria, Autoria, MateriaAssunto,
MateriaLegislativa, Orgao, RegimeTramitacao,
TipoDocumento, TipoProposicao, StatusTramitacao,
@@ -408,7 +408,8 @@ class RelatoriaForm(ModelForm):
Participacao.objects.filter(composicao__comissao_id=comissao_pk,
composicao_id=self.initial['composicao'])]
- self.fields['parlamentar'].choices = [('', '---------')] + parlamentares
+ self.fields['parlamentar'].choices = [
+ ('', '---------')] + parlamentares
# INSERT
else:
self.fields['parlamentar'].choices = [('', '---------')]
@@ -435,7 +436,8 @@ class RelatoriaForm(ModelForm):
if cleaned_data['data_designacao_relator'] < cleaned_data['composicao'].periodo.data_inicio \
or cleaned_data['data_designacao_relator'] > cleaned_data['composicao'].periodo.data_fim:
- raise ValidationError(_('Data de designação deve estar dentro do período da composição.'))
+ raise ValidationError(
+ _('Data de designação deve estar dentro do período da composição.'))
return cleaned_data
@@ -465,9 +467,12 @@ class TramitacaoForm(ModelForm):
super(TramitacaoForm, self).__init__(*args, **kwargs)
self.fields['data_tramitacao'].initial = timezone.now().date()
ust = UnidadeTramitacao.objects.select_related().all()
- unidade_tramitacao_destino = [('', '---------')]+[(ut.pk, ut) for ut in ust if ut.comissao and ut.comissao.ativa]
- unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.orgao])
- unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.parlamentar])
+ unidade_tramitacao_destino = [('', '---------')] + [(ut.pk, ut)
+ for ut in ust if ut.comissao and ut.comissao.ativa]
+ unidade_tramitacao_destino.extend(
+ [(ut.pk, ut) for ut in ust if ut.orgao])
+ unidade_tramitacao_destino.extend(
+ [(ut.pk, ut) for ut in ust if ut.parlamentar])
self.fields['unidade_tramitacao_destino'].choices = unidade_tramitacao_destino
def clean(self):
@@ -1182,6 +1187,7 @@ class AcessorioEmLoteFilterSet(django_filters.FilterSet):
Fieldset(_('Documentos Acessórios em Lote'),
row1, row2, form_actions(label='Pesquisar')))
+
class AnexadaEmLoteFilterSet(django_filters.FilterSet):
class Meta(FilterOverridesMetaMixin):
@@ -1583,8 +1589,8 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
if cd['numero_materia_futuro'] and \
'tipo' in cd and \
MateriaLegislativa.objects.filter(tipo=cd['tipo'].tipo_conteudo_related,
- ano=timezone.now().year,
- numero=cd['numero_materia_futuro']):
+ ano=timezone.now().year,
+ numero=cd['numero_materia_futuro']):
raise ValidationError(_("A matéria {} {}/{} já existe.".format(cd['tipo'].tipo_conteudo_related.descricao,
cd['numero_materia_futuro'],
timezone.now().year)))
@@ -2003,14 +2009,13 @@ class ConfirmarProposicaoForm(ProposicaoForm):
if numeracao is None:
numero['numero__max'] = 0
-
if cd['numero_materia_futuro'] and not MateriaLegislativa.objects.filter(tipo=tipo,
ano=ano,
numero=cd['numero_materia_futuro']):
max_numero = cd['numero_materia_futuro']
else:
- max_numero = numero['numero__max'] + 1 if numero['numero__max'] else 1
-
+ max_numero = numero['numero__max'] + \
+ 1 if numero['numero__max'] else 1
# dados básicos
materia = MateriaLegislativa()
@@ -2501,7 +2506,9 @@ class MateriaPesquisaSimplesForm(forms.Form):
raise ValidationError(_('Caso pesquise por data, os campos de Data Inicial e '
'Data Final devem ser preenchidos obrigatoriamente'))
elif data_inicial > data_final:
- self.logger.error("Data Final ({}) menor que a Data Inicial ({}).".format(data_final, data_inicial))
- raise ValidationError(_('A Data Final não pode ser menor que a Data Inicial'))
+ self.logger.error("Data Final ({}) menor que a Data Inicial ({}).".format(
+ data_final, data_inicial))
+ raise ValidationError(
+ _('A Data Final não pode ser menor que a Data Inicial'))
return cleaned_data
From a5a5ba5ae6abcf99e2174fcb7eb4e9373453426a Mon Sep 17 00:00:00 2001
From: Leandro Roberto
Date: Mon, 8 Apr 2019 09:30:08 -0300
Subject: [PATCH 05/18] =?UTF-8?q?permite=20edi=C3=A7=C3=A3o=20de=20materia?=
=?UTF-8?q?s=20anexadas?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/materia/forms.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
index c91f8c90e..edbeed810 100644
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -809,9 +809,11 @@ class AnexadaForm(ModelForm):
self.logger.error("Matéria não pode ser anexada a si mesma.")
raise ValidationError(_('Matéria não pode ser anexada a si mesma'))
- is_anexada = Anexada.objects.filter(materia_principal=materia_principal,
- materia_anexada=materia_anexada
- ).exists()
+ is_anexada = Anexada.objects.filter(
+ materia_principal=materia_principal,
+ materia_anexada=materia_anexada
+ ).exclude(pk=self.instance.pk).exists()
+
if is_anexada:
self.logger.error("Matéria já se encontra anexada.")
raise ValidationError(_('Matéria já se encontra anexada'))
From 9a89c863dd811c877311dc19f40bddbddb7c9919 Mon Sep 17 00:00:00 2001
From: Cesar Augusto de Carvalho
Date: Mon, 8 Apr 2019 11:43:00 -0300
Subject: [PATCH 06/18] =?UTF-8?q?Adiciona=20bot=C3=A3o=20Adicionar=20Parla?=
=?UTF-8?q?mentar=20em=20Tabelas=20Auxiliares=20(#2697)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sapl/templates/menu_tabelas_auxiliares.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sapl/templates/menu_tabelas_auxiliares.yaml b/sapl/templates/menu_tabelas_auxiliares.yaml
index ced7bddf3..4f690ca00 100644
--- a/sapl/templates/menu_tabelas_auxiliares.yaml
+++ b/sapl/templates/menu_tabelas_auxiliares.yaml
@@ -20,6 +20,9 @@
- title: {% trans 'Pesquisar Parlamentar' %}
url: sapl.parlamentares:pesquisar_parlamentar
css_class: btn btn-link
+ - title: {% trans 'Adicionar Parlamentar' %}
+ url: sapl.parlamentares:parlamentar_create
+ css_class: btn btn-link
- title: {% trans 'Legislatura' %}
url: sapl.parlamentares:legislatura_list
css_class: btn btn-link
From 6906c620c22f48575fa5e5b438965eab3200c5ca Mon Sep 17 00:00:00 2001
From: Edward
Date: Mon, 8 Apr 2019 12:54:44 -0300
Subject: [PATCH 07/18] =?UTF-8?q?Atualiza=20vers=C3=A3o=20do=20SAPL?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
solr/docker-compose.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/solr/docker-compose.yml b/solr/docker-compose.yml
index 6349c8053..71e25c76c 100644
--- a/solr/docker-compose.yml
+++ b/solr/docker-compose.yml
@@ -24,7 +24,7 @@ services:
- "8983:8983"
sapl:
- image: interlegis/sapl:3.1.144
+ image: interlegis/sapl:3.1.152
# build: .
restart: always
environment:
From 7038d6f4e6f45adf8ee504cfe9f6a1b02ee1389d Mon Sep 17 00:00:00 2001
From: Edward
Date: Mon, 8 Apr 2019 12:55:42 -0300
Subject: [PATCH 08/18] Fix #2656 (#2698)
---
docs/solr.rst | 59 +++++++++++++++++++++++++++++++++++++++------------
1 file changed, 45 insertions(+), 14 deletions(-)
diff --git a/docs/solr.rst b/docs/solr.rst
index 4c82ab68d..d5da6d889 100644
--- a/docs/solr.rst
+++ b/docs/solr.rst
@@ -1,27 +1,58 @@
-**ESTAS INSTRUÇÕES ESTÃO DEFASADAS. EM BREVE IREMOS DISPONIBILIZAR UM TUTORIAL MAIS ATUALIZADO DE COMO INTEGRAR O SOLR AO SAPL**
-
================================
Instruções para instalar o Solr
================================
Solr é a ferramenta utilizada pelo SAPL 3.1 para indexar documentos para que possa ser feita
-a Pesquisa Textual.
+a Pesquisa Textual. Se a execução for mediante containers Docker então use o arquivo docker-compose.yml disponível em
+*https://github.com/interlegis/sapl/blob/3.1.x/solr/docker-compose.yml* (verifique os mapeamentos de volume, e realize o
+backup de seu BD antes de qualquer tentativa de substituição do arquivo docker-compose.yml em uso corrente).
+
+1) Faça o download da distribuição _binária_ do Apache Solr do site oficial do projeto *http://lucene.apache.org/solr* ;
+
+As instalações Solr suportadas até o momento vão da 7.4 à 8;
+
+2) Descompacte o arquivo em uma pasta do diretório (referenciada neste tutorial como $SOLR_HOME)
+
+3) Inicie o Solr com o comando:
+
+ **$SOLR_HOME/bin/solr start -c** ;
+
+4) Por meio do browser, acesse a URL **http://localhost:8983** (ou informe o endereço da máquina onde o Solr foi instalado)
+
+5) Pare o servidor do SAPL;
+
+6) Edite o arquivo .env adicionando as seguintes linhas:
+
+
+
+ USE_SOLR = True
+
+
+ SOLR_COLLECTION = sapl
+
+
+ SOLR_URL = http://localhost:8983
+
+
+
+
+(o valor do campo SOLR_URL deve corresponder à URL acessada no item 3)
+
+7) Entre no diretório raiz do SAPL e digite o comando: **python3 solr_api.py -c sapl -u http://localhost:8983`**
+
+(a URL informada acima deve ser a mesma dos itens 3 e 6)
-Adicione ao arquivo ``.env`` o seguinte atributo:
+8) Enquanto o Solr realiza a indexação da base de dados do SAPL, inicie em uma outra tela o SAPL;
-``SOLR_URL = 'http://127.0.0.1:8983/solr'``
+9) Após realizados os passos com sucesso, nas telas de busca de Matéria Legislativa e Normas deverá aparecer um botão
+de 'Busca Textual' próximo ao botão de busca tradicional.
-Dentro do diretório principal siga os seguintes passos::
+**Observações:**
- curl -LO https://archive.apache.org/dist/lucene/solr/4.10.2/solr-4.10.2.tgz
- tar xvzf solr-4.10.2.tgz
- cd solr-4.10.2
- cd example
- java -jar start.jar
- ./manage.py build_solr_schema --filename solr-4.10.2/example/solr/collection1/conf/schema.xml
+a) Para parar o Solr execute o comando **$SOLR_HOME/bin/solr stop**
+b) Para reindexar os dados do SAPL execute o comando `python3 manage.py rebuild_index` (isso irá apagar todos os dados
+do Solr e indexar tudo novamente).
-Após isso, deve-se parar o servidor do Solr e restartar com ``java -jar start.jar``
-**OBS: Toda vez que o código da pesquisa textual for modificado, os comandos de build_solr_schema e start.jar devem ser rodados, nessa mesma ordem.**
From 2406cff37fb3ea474d5473a13a0f1fec9487cdbf Mon Sep 17 00:00:00 2001
From: Edward
Date: Mon, 8 Apr 2019 13:44:54 -0300
Subject: [PATCH 09/18] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20da=20documenta?=
=?UTF-8?q?=C3=A7=C3=A3o=20Solr.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/solr.rst | 33 +++++++++++++++------------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/docs/solr.rst b/docs/solr.rst
index d5da6d889..ae8bbdb63 100644
--- a/docs/solr.rst
+++ b/docs/solr.rst
@@ -2,20 +2,24 @@
Instruções para instalar o Solr
================================
-Solr é a ferramenta utilizada pelo SAPL 3.1 para indexar documentos para que possa ser feita
-a Pesquisa Textual. Se a execução for mediante containers Docker então use o arquivo docker-compose.yml disponível em
-*https://github.com/interlegis/sapl/blob/3.1.x/solr/docker-compose.yml* (verifique os mapeamentos de volume, e realize o
-backup de seu BD antes de qualquer tentativa de substituição do arquivo docker-compose.yml em uso corrente).
+Solr é uma plataforma open source de indexação e busca textual utilizada pelo SAPL 3.1 para indexar documentos (normas jurídicas, matérias legislativas e documentos acessórios).
-1) Faça o download da distribuição _binária_ do Apache Solr do site oficial do projeto *http://lucene.apache.org/solr* ;
+Observação: Se a execução do SAPL for mediante containers Docker então use o arquivo *docker-compose.yml* disponível em
+*https://github.com/interlegis/sapl/blob/3.1.x/solr/docker-compose.yml* (verifique os mapeamentos de volume estão corretos, a verso do SAPL referenciada no arquivo docker-compose.yml, e realize o backup de seu BD **antes** de qualquer tentativa de substituição do arquivo *docker-compose.yml* em uso corrente);
+
+1) Faça o download da distribuição *binária* do Apache Solr do site oficial do projeto **http://lucene.apache.org/solr**
+
+
+ As instalações Solr suportadas até o momento vão da 7.4 à 8;
-As instalações Solr suportadas até o momento vão da 7.4 à 8;
2) Descompacte o arquivo em uma pasta do diretório (referenciada neste tutorial como $SOLR_HOME)
+
3) Inicie o Solr com o comando:
- **$SOLR_HOME/bin/solr start -c** ;
+ **$SOLR_HOME/bin/solr start -c**
+
4) Por meio do browser, acesse a URL **http://localhost:8983** (ou informe o endereço da máquina onde o Solr foi instalado)
@@ -23,8 +27,6 @@ As instalações Solr suportadas até o momento vão da 7.4 à 8;
6) Edite o arquivo .env adicionando as seguintes linhas:
-
-
USE_SOLR = True
@@ -34,13 +36,11 @@ As instalações Solr suportadas até o momento vão da 7.4 à 8;
SOLR_URL = http://localhost:8983
-
-
-(o valor do campo SOLR_URL deve corresponder à URL acessada no item 3)
+ (o valor do campo SOLR_URL deve corresponder à URL acessada no item 3)
7) Entre no diretório raiz do SAPL e digite o comando: **python3 solr_api.py -c sapl -u http://localhost:8983`**
-(a URL informada acima deve ser a mesma dos itens 3 e 6)
+ (a URL informada acima deve ser a mesma dos itens 3 e 6)
8) Enquanto o Solr realiza a indexação da base de dados do SAPL, inicie em uma outra tela o SAPL;
@@ -49,10 +49,7 @@ de 'Busca Textual' próximo ao botão de busca tradicional.
**Observações:**
-a) Para parar o Solr execute o comando **$SOLR_HOME/bin/solr stop**
+* Para parar o Solr execute o comando **$SOLR_HOME/bin/solr stop**
-b) Para reindexar os dados do SAPL execute o comando `python3 manage.py rebuild_index` (isso irá apagar todos os dados
+* Para reindexar os dados do SAPL execute o comando **python3 manage.py rebuild_index** (isso irá apagar todos os dados
do Solr e indexar tudo novamente).
-
-
-
From 431a8fc294d0a9d5cff9d608198a44c24c66faa4 Mon Sep 17 00:00:00 2001
From: Cesar Augusto de Carvalho
Date: Mon, 8 Apr 2019 13:49:04 -0300
Subject: [PATCH 10/18] fix anexo norma para arquivos grandes (#2699)
---
sapl/norma/forms.py | 3 +--
sapl/norma/models.py | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py
index 12eee547f..5a9e1b3f6 100644
--- a/sapl/norma/forms.py
+++ b/sapl/norma/forms.py
@@ -298,11 +298,10 @@ class AnexoNormaJuridicaForm(FileFieldCheckMixin, ModelForm):
def save(self, commit=False):
anexo = self.instance
anexo.ano = self.cleaned_data['norma'].ano
- anexo = super(AnexoNormaJuridicaForm, self).save(commit=True)
anexo.norma = self.cleaned_data['norma']
anexo.assunto_anexo = self.cleaned_data['assunto_anexo']
anexo.anexo_arquivo = self.cleaned_data['anexo_arquivo']
- anexo.save()
+ anexo = super(AnexoNormaJuridicaForm, self).save(commit=True)
return anexo
diff --git a/sapl/norma/models.py b/sapl/norma/models.py
index f7fcf17e9..5a5557e5b 100644
--- a/sapl/norma/models.py
+++ b/sapl/norma/models.py
@@ -351,3 +351,20 @@ class AnexoNormaJuridica(models.Model):
def __str__(self):
return _('Anexo: %(anexo)s da norma %(norma)s') % {
'anexo': self.anexo_arquivo, 'norma': self.norma}
+
+ def save(self, force_insert=False, force_update=False, using=None,
+ update_fields=None):
+
+ if not self.pk and self.anexo_arquivo:
+ anexo_arquivo = self.anexo_arquivo
+ self.anexo_arquivo = None
+ models.Model.save(self, force_insert=force_insert,
+ force_update=force_update,
+ using=using,
+ update_fields=update_fields)
+ self.anexo_arquivo = anexo_arquivo
+
+ return models.Model.save(self, force_insert=force_insert,
+ force_update=force_update,
+ using=using,
+ update_fields=update_fields)
\ No newline at end of file
From 34786902e63bd9a16b51f7fa3cb3f6b66ef33275 Mon Sep 17 00:00:00 2001
From: Cesar Augusto de Carvalho
Date: Mon, 8 Apr 2019 13:50:14 -0300
Subject: [PATCH 11/18] =?UTF-8?q?Fix=20Verifica=C3=A7=C3=A3o=20de=20Erros?=
=?UTF-8?q?=20do=20Formul=C3=A1rio=20em=20Documento=20Acess=C3=B3rio=20em?=
=?UTF-8?q?=20Lote=20(#2693)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Fix Verificação de Erros do Formulário em Documento Acessorio em Lote
* Altera o logger
---
sapl/materia/views.py | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
index 6c0da0ce0..8d7278e5f 100644
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -14,7 +14,7 @@ from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin
-from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
+from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, ValidationError
from django.core.urlresolvers import reverse
from django.db.models import Max, Q
from django.http import HttpResponse, JsonResponse
@@ -1945,6 +1945,7 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
filterset_class = AcessorioEmLoteFilterSet
template_name = 'materia/em_lote/acessorio.html'
permission_required = ('materia.add_documentoacessorio',)
+ logger = logging.getLogger(__name__)
def get_context_data(self, **kwargs):
context = super(DocumentoAcessorioEmLoteView,
@@ -1966,6 +1967,7 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
return context
def post(self, request, *args, **kwargs):
+ username = request.user.username
marcadas = request.POST.getlist('materia_id')
if len(marcadas) == 0:
@@ -1981,14 +1983,21 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
msg = _('Autor tem que ter menos do que 50 caracteres.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
-
- tmp_name = os.path.join(tempfile.gettempdir(), request.FILES['arquivo'].name)
+
+ tmp_name = os.path.join(MEDIA_ROOT, request.FILES['arquivo'].name)
with open(tmp_name, 'wb') as destination:
for chunk in request.FILES['arquivo'].chunks():
destination.write(chunk)
+ try:
+ doc_data = tz.localize(datetime.strptime(
+ request.POST['data'], "%d/%m/%Y"))
+ except Exception as e:
+ msg = _('Formato da data incorreto. O formato deve ser da forma dd/mm/aaaa.')
+ messages.add_message(request, messages.ERROR, msg)
+ self.logger.error("User={}. {}. Data inserida: {}".format(username, str(msg), request.POST['data']))
+ os.remove(tmp_name)
+ return self.get(request, self.kwargs)
- doc_data = tz.localize(datetime.strptime(
- request.POST['data'], "%d/%m/%Y"))
for materia_id in marcadas:
doc = DocumentoAcessorio()
doc.materia_id = materia_id
@@ -1997,6 +2006,18 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
doc.data = doc_data
doc.autor = request.POST['autor']
doc.ementa = request.POST['ementa']
+ doc.arquivo.name = tmp_name
+ try:
+ doc.clean_fields()
+ except ValidationError as e:
+ for m in [ '%s: %s' % (DocumentoAcessorio()._meta.get_field(k).verbose_name, ''.join(v))
+ for k,v in e.message_dict.items() ]:
+ # Insere as mensagens de erro no formato:
+ # 'verbose_name do nome do campo': 'mensagem de erro'
+ messages.add_message(request, messages.ERROR, m)
+ self.logger.error("User={}. {}. Nome do arquivo: {}.".format(username, str(msg), request.FILES['arquivo'].name))
+ os.remove(tmp_name)
+ return self.get(request, self.kwargs)
doc.save()
diretorio = os.path.join(MEDIA_ROOT,
'sapl/public/documentoacessorio',
From 80babf2b4520af1665603ad2fced2475c28d3b88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rog=C3=A9rio=20Fr=C3=A1?=
Date: Mon, 8 Apr 2019 13:55:49 -0300
Subject: [PATCH 12/18] Fix #2682 (#2684)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Fix #2682
* retira if desnecessário
---
.../blocos_ata/identificacao_basica.html | 3 +-
.../sessao/blocos_ata/lista_presenca.html | 6 ++-
.../blocos_ata/lista_presenca_ordem_dia.html | 3 +-
.../blocos_ata/materias_expediente.html | 51 +++++++++++--------
.../sessao/blocos_ata/materias_ordem_dia.html | 35 +++++++------
.../sessao/blocos_ata/mesa_diretora.html | 3 +-
.../blocos_ata/oradores_expediente.html | 7 ++-
.../blocos_ata/oradores_explicacoes.html | 5 +-
8 files changed, 65 insertions(+), 48 deletions(-)
diff --git a/sapl/templates/sessao/blocos_ata/identificacao_basica.html b/sapl/templates/sessao/blocos_ata/identificacao_basica.html
index a6ec9c8c0..84eeb2a11 100644
--- a/sapl/templates/sessao/blocos_ata/identificacao_basica.html
+++ b/sapl/templates/sessao/blocos_ata/identificacao_basica.html
@@ -2,7 +2,8 @@
Identificação Básica:
{% for b in basica %}
- {{b}} ;
+ {{b}}
+ {% if not forloop.last %} ; {% endif %}
{% endfor %}
\ No newline at end of file
diff --git a/sapl/templates/sessao/blocos_ata/lista_presenca.html b/sapl/templates/sessao/blocos_ata/lista_presenca.html
index 329fde406..1efc2c8ea 100644
--- a/sapl/templates/sessao/blocos_ata/lista_presenca.html
+++ b/sapl/templates/sessao/blocos_ata/lista_presenca.html
@@ -5,7 +5,8 @@
{% if presenca_sessao %}
Lista de Presença na Sessão:
{% for p in presenca_sessao %}
- {{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }} ;
+ {{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}
+ {% if not forloop.last %} ; {% endif %}
{% endfor %}
{% endif %}
@@ -13,7 +14,8 @@
{% if justificativa_ausencia %}
Justificativas de Ausências na Sessão:
{% for j in justificativa_ausencia %}
- {{j.parlamentar.nome_completo}} / {{ j.tipo_ausencia }} ;
+ {{j.parlamentar.nome_completo}} / {{ j.tipo_ausencia }}
+ {% if not forloop.last %} ; {% endif %}
{% endfor %}
{% endif %}
diff --git a/sapl/templates/sessao/blocos_ata/lista_presenca_ordem_dia.html b/sapl/templates/sessao/blocos_ata/lista_presenca_ordem_dia.html
index d6c8014ca..855d1be6f 100644
--- a/sapl/templates/sessao/blocos_ata/lista_presenca_ordem_dia.html
+++ b/sapl/templates/sessao/blocos_ata/lista_presenca_ordem_dia.html
@@ -5,7 +5,8 @@
{% if presenca_ordem %}
Lista de Presença na Ordem do Dia:
{% for p in presenca_ordem %}
- {{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }} ;
+ {{p.nome_completo}} / {{ p|filiacao_data_filter:object.data_inicio }}
+ {% if not forloop.last %} ; {% endif %}
{% endfor %}
{% endif %}
diff --git a/sapl/templates/sessao/blocos_ata/materias_expediente.html b/sapl/templates/sessao/blocos_ata/materias_expediente.html
index 7613448fc..3ccc3fb84 100644
--- a/sapl/templates/sessao/blocos_ata/materias_expediente.html
+++ b/sapl/templates/sessao/blocos_ata/materias_expediente.html
@@ -1,27 +1,36 @@
\ No newline at end of file
diff --git a/sapl/templates/sessao/blocos_ata/materias_ordem_dia.html b/sapl/templates/sessao/blocos_ata/materias_ordem_dia.html
index d894e8a06..a167e01a1 100644
--- a/sapl/templates/sessao/blocos_ata/materias_ordem_dia.html
+++ b/sapl/templates/sessao/blocos_ata/materias_ordem_dia.html
@@ -2,29 +2,32 @@