From 74540d4a6fff1894369fe3c253cfb3eb333d6312 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 15 Apr 2019 16:25:53 -0300 Subject: [PATCH 01/18] HOT-FIX: corrige erro de grafia --- sapl/protocoloadm/forms.py | 6 ++-- sapl/protocoloadm/tests/test_protocoloadm.py | 32 ++++++++++---------- sapl/protocoloadm/views.py | 4 +-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index b47b093dc..ef013703d 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -221,7 +221,7 @@ class DocumentoAdministrativoFilterSet(django_filters.FilterSet): ) -class AnularProcoloAdmForm(ModelForm): +class AnularProtocoloAdmForm(ModelForm): logger = logging.getLogger(__name__) @@ -240,7 +240,7 @@ class AnularProcoloAdmForm(ModelForm): widget=forms.Textarea) def clean(self): - super(AnularProcoloAdmForm, self).clean() + super(AnularProtocoloAdmForm, self).clean() cleaned_data = self.cleaned_data @@ -313,7 +313,7 @@ class AnularProcoloAdmForm(ModelForm): form_actions(label='Anular') ) ) - super(AnularProcoloAdmForm, self).__init__( + super(AnularProtocoloAdmForm, self).__init__( *args, **kwargs) diff --git a/sapl/protocoloadm/tests/test_protocoloadm.py b/sapl/protocoloadm/tests/test_protocoloadm.py index 0e43aebbe..f3c167288 100644 --- a/sapl/protocoloadm/tests/test_protocoloadm.py +++ b/sapl/protocoloadm/tests/test_protocoloadm.py @@ -9,7 +9,7 @@ import pytest from sapl.base.models import AppConfig from sapl.materia.models import UnidadeTramitacao -from sapl.protocoloadm.forms import (AnularProcoloAdmForm, +from sapl.protocoloadm.forms import (AnularProtocoloAdmForm, DocumentoAdministrativoForm, MateriaLegislativa, ProtocoloDocumentForm, ProtocoloMateriaForm) @@ -51,7 +51,7 @@ def test_anular_protocolo_submit(admin_client): @pytest.mark.django_db(transaction=False) def test_form_anular_protocolo_inexistente(): - form = AnularProcoloAdmForm({'numero': '1', + form = AnularProtocoloAdmForm({'numero': '1', 'ano': '2016', 'justificativa_anulacao': 'TESTE'}) @@ -64,7 +64,7 @@ def test_form_anular_protocolo_inexistente(): @pytest.mark.django_db(transaction=False) def test_form_anular_protocolo_valido(): mommy.make(Protocolo, numero='1', ano='2016', anulado=False) - form = AnularProcoloAdmForm({'numero': '1', + form = AnularProtocoloAdmForm({'numero': '1', 'ano': '2016', 'justificativa_anulacao': 'TESTE'}) if not form.is_valid(): @@ -74,7 +74,7 @@ def test_form_anular_protocolo_valido(): @pytest.mark.django_db(transaction=False) def test_form_anular_protocolo_anulado(): mommy.make(Protocolo, numero='1', ano='2016', anulado=True) - form = AnularProcoloAdmForm({'numero': '1', + form = AnularProtocoloAdmForm({'numero': '1', 'ano': '2016', 'justificativa_anulacao': 'TESTE'}) assert form.errors['__all__'] == \ @@ -88,7 +88,7 @@ def test_form_anular_protocolo_campos_obrigatorios(): # TODO: generalizar para diminuir o tamanho deste método # numero ausente - form = AnularProcoloAdmForm({'numero': '', + form = AnularProtocoloAdmForm({'numero': '', 'ano': '2016', 'justificativa_anulacao': 'TESTE'}) if form.is_valid(): @@ -98,7 +98,7 @@ def test_form_anular_protocolo_campos_obrigatorios(): assert form.errors['numero'] == [_('Este campo é obrigatório.')] # ano ausente - form = AnularProcoloAdmForm({'numero': '1', + form = AnularProtocoloAdmForm({'numero': '1', 'ano': '', 'justificativa_anulacao': 'TESTE'}) if form.is_valid(): @@ -108,7 +108,7 @@ def test_form_anular_protocolo_campos_obrigatorios(): assert form.errors['ano'] == [_('Este campo é obrigatório.')] # justificativa_anulacao ausente - form = AnularProcoloAdmForm({'numero': '1', + form = AnularProtocoloAdmForm({'numero': '1', 'ano': '2016', 'justificativa_anulacao': ''}) if form.is_valid(): @@ -261,7 +261,7 @@ def test_create_tramitacao(admin_client): @pytest.mark.django_db(transaction=False) def test_anular_protocolo_dados_invalidos(): - form = AnularProcoloAdmForm(data={}) + form = AnularProtocoloAdmForm(data={}) assert not form.is_valid() @@ -276,10 +276,10 @@ def test_anular_protocolo_dados_invalidos(): @pytest.mark.django_db(transaction=False) def test_anular_protocolo_form_anula_protocolo_inexistente(): - form = AnularProcoloAdmForm(data={'numero': '1', + form = AnularProtocoloAdmForm(data={'numero': '1', 'ano': '2017', 'justificativa_anulacao': 'teste' - }) + }) assert not form.is_valid() @@ -291,10 +291,10 @@ def test_anular_protocolo_form_anula_protocolo_inexistente(): def test_anular_protocolo_form_anula_protocolo_anulado(): mommy.make(Protocolo, numero=1, ano=2017, anulado=True) - form = AnularProcoloAdmForm(data={'numero': '1', + form = AnularProtocoloAdmForm(data={'numero': '1', 'ano': '2017', 'justificativa_anulacao': 'teste' - }) + }) assert not form.is_valid() @@ -316,10 +316,10 @@ def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado(): ano=2017, numero_protocolo=1) - form = AnularProcoloAdmForm(data={'numero': '1', + form = AnularProtocoloAdmForm(data={'numero': '1', 'ano': '2017', 'justificativa_anulacao': 'teste' - }) + }) assert not form.is_valid() @@ -338,10 +338,10 @@ def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado(): mommy.make(DocumentoAdministrativo, protocolo=protocolo_documento) - form = AnularProcoloAdmForm(data={'numero': '2', + form = AnularProtocoloAdmForm(data={'numero': '2', 'ano': '2017', 'justificativa_anulacao': 'teste' - }) + }) assert not form.is_valid() diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 0c2e13157..6cefc9b0a 100755 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -37,7 +37,7 @@ from sapl.utils import (create_barcode, get_base_url, get_client_ip, get_mime_type_from_file_extension, show_results_filter_set, mail_service_configured) -from .forms import (AcompanhamentoDocumentoForm, AnularProcoloAdmForm, +from .forms import (AcompanhamentoDocumentoForm, AnularProtocoloAdmForm, DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoFilterSet, DocumentoAdministrativoForm, FichaPesquisaAdmForm, FichaSelecionaAdmForm, ProtocoloDocumentForm, @@ -484,7 +484,7 @@ class ProtocoloListView(PermissionRequiredMixin, ListView): class AnularProtocoloAdmView(PermissionRequiredMixin, CreateView): template_name = 'protocoloadm/anular_protocoloadm.html' - form_class = AnularProcoloAdmForm + form_class = AnularProtocoloAdmForm form_valid_message = _('Protocolo anulado com sucesso!') permission_required = ('protocoloadm.action_anular_protocolo', ) From 533353b6be3745914df9f9a18dfddfe0e6d3c8b2 Mon Sep 17 00:00:00 2001 From: Cesar Augusto de Carvalho Date: Mon, 15 Apr 2019 16:46:22 -0300 Subject: [PATCH 02/18] Adiciona IP e User em votacao (#2727) --- .../migrations/0037_auto_20190415_1324.py | 33 +++++++++++++++++++ sapl/sessao/models.py | 13 ++++++++ sapl/sessao/views.py | 24 ++++++++++++-- 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 sapl/sessao/migrations/0037_auto_20190415_1324.py diff --git a/sapl/sessao/migrations/0037_auto_20190415_1324.py b/sapl/sessao/migrations/0037_auto_20190415_1324.py new file mode 100644 index 000000000..ed1137e4b --- /dev/null +++ b/sapl/sessao/migrations/0037_auto_20190415_1324.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-15 16:24 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('sessao', '0036_auto_20190412_1106'), + ] + + operations = [ + migrations.AddField( + model_name='registrovotacao', + name='data_hora', + field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Data/Hora'), + ), + migrations.AddField( + model_name='registrovotacao', + name='ip', + field=models.CharField(blank=True, default='', max_length=30, verbose_name='IP'), + ), + migrations.AddField( + model_name='registrovotacao', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index 725898b57..5d2d1c7cc 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -456,6 +456,19 @@ class RegistroVotacao(models.Model): verbose_name=_('Abstenções')) observacao = models.TextField( blank=True, verbose_name=_('Observações')) + user = models.ForeignKey(get_settings_auth_user_model(), + on_delete=models.PROTECT, + null=True, + blank=True) + ip = models.CharField(verbose_name=_('IP'), + max_length=30, + blank=True, + default='') + data_hora = models.DateTimeField( + verbose_name=_('Data/Hora'), + auto_now_add=True, + blank=True, + null=True) class Meta: verbose_name = _('Votação') diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 08adf1fa0..74c9094e9 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -35,7 +35,7 @@ from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato, Parlamentar, SessaoLegislativa) from sapl.sessao.apps import AppConfig from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm -from sapl.utils import show_results_filter_set, remover_acentos +from sapl.utils import show_results_filter_set, remover_acentos, get_client_ip from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, BlocoForm, ExpedienteForm, JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm, @@ -2163,6 +2163,8 @@ class VotacaoView(SessaoPermissionMixin): votacao.ordem_id = ordem_id votacao.tipo_resultado_votacao_id = int( request.POST['resultado_votacao']) + votacao.user = request.user + votacao.ip = get_client_ip(request) votacao.save() except Exception as e: username = request.user.username @@ -2383,6 +2385,8 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): votacao.numero_votos_nao = votos_nao votacao.numero_abstencoes = abstencoes votacao.observacao = request.POST.get('observacao', None) + votacao.user = request.user + votacao.ip = get_client_ip(request) votacao.materia_id = materia_votacao.materia.id if self.ordem: @@ -2410,6 +2414,8 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): voto_parlamentar.voto = voto voto_parlamentar.parlamentar_id = parlamentar_id voto_parlamentar.votacao_id = votacao.id + voto_parlamentar.user = request.user + voto_parlamentar.ip = get_client_ip(request) voto_parlamentar.save() resultado = form.cleaned_data['resultado_votacao'] @@ -2847,10 +2853,10 @@ class VotacaoExpedienteView(SessaoPermissionMixin): if (int(request.POST['voto_presidente']) == 0): qtde_presentes -= 1 - if (qtde_votos > qtde_presentes or qtde_votos < qtde_presentes): + if qtde_votos != qtde_presentes: form._errors["total_votos"] = ErrorList([u""]) return self.render_to_response(context) - elif (qtde_presentes == qtde_votos): + else: try: votacao = RegistroVotacao() votacao.numero_votos_sim = int(request.POST['votos_sim']) @@ -2861,6 +2867,8 @@ class VotacaoExpedienteView(SessaoPermissionMixin): votacao.expediente_id = expediente_id votacao.tipo_resultado_votacao_id = int( request.POST['resultado_votacao']) + votacao.user = request.user + votacao.ip = get_client_ip(request) votacao.save() except Exception as e: username = request.user.username @@ -3640,6 +3648,8 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie resultado = TipoResultadoVotacao.objects.get( id=request.POST['resultado_votacao']) votacao.tipo_resultado_votacao = resultado + votacao.user = request.user + votacao.ip = get_client_ip(request) votacao.save() except Exception as e: username = request.user.username @@ -3671,6 +3681,8 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie resultado = TipoResultadoVotacao.objects.get( id=request.POST['resultado_votacao']) votacao.tipo_resultado_votacao = resultado + votacao.user = request.user + votacao.ip = get_client_ip(request) votacao.save() except Exception as e: username = request.user.username @@ -3862,6 +3874,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView) voto_parlamentar.voto = voto voto_parlamentar.parlamentar_id = parlamentar_id voto_parlamentar.votacao_id = votacao.id + voto_parlamentar.user = request.user + voto_parlamentar.ip = get_client_ip(request) voto_parlamentar.save() ordem.resultado = form.cleaned_data['resultado_votacao'].nome @@ -3889,6 +3903,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView) votacao.materia = expediente.materia votacao.expediente = expediente votacao.tipo_resultado_votacao = form.cleaned_data['resultado_votacao'] + votacao.user = request.user + votacao.ip = get_client_ip(request) votacao.save() # Salva os votos de cada parlamentar @@ -3904,6 +3920,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView) voto_parlamentar.voto = voto voto_parlamentar.parlamentar_id = parlamentar_id voto_parlamentar.votacao_id = votacao.id + voto_parlamentar.user = request.user + voto_parlamentar.ip = get_client_ip(request) voto_parlamentar.save() expediente.resultado = form.cleaned_data['resultado_votacao'].nome From ee925a11bcb2abc764dad68d768e41636afb0a21 Mon Sep 17 00:00:00 2001 From: Cesar Augusto de Carvalho Date: Mon, 15 Apr 2019 16:46:50 -0300 Subject: [PATCH 03/18] =?UTF-8?q?Reordena=20as=20configura=C3=A7=C3=B5es?= =?UTF-8?q?=20para=20melhorar=20o=20visual=20(#2726)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/templates/base/layouts.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/templates/base/layouts.yaml b/sapl/templates/base/layouts.yaml index c98810b10..91f0cd67e 100644 --- a/sapl/templates/base/layouts.yaml +++ b/sapl/templates/base/layouts.yaml @@ -18,8 +18,8 @@ AppConfig: - esfera_federacao {% trans 'Proposições e Protocolo' %}: - - sequencia_numeracao proposicao_incorporacao_obrigatoria receber_recibo_proposicao - - escolher_numero_materia_proposicao protocolo_manual + - sequencia_numeracao protocolo_manual receber_recibo_proposicao + - proposicao_incorporacao_obrigatoria escolher_numero_materia_proposicao {% trans 'Textos Articulados' %}: - texto_articulado_proposicao texto_articulado_materia texto_articulado_norma From 15be98ea3df0b80c2538ff6f1107692a633fd5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Mon, 15 Apr 2019 16:47:34 -0300 Subject: [PATCH 04/18] Adiciona script para remover multiplos autores (#2715) Co-authored-by: Victor Fabre --- scripts/remove_multiplos_autores.py | 84 +++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 scripts/remove_multiplos_autores.py diff --git a/scripts/remove_multiplos_autores.py b/scripts/remove_multiplos_autores.py new file mode 100644 index 000000000..cf64dc8f5 --- /dev/null +++ b/scripts/remove_multiplos_autores.py @@ -0,0 +1,84 @@ +from django.core.exceptions import ObjectDoesNotExist +from django.db.models import Count +from sapl.base.models import Autor +from sapl.parlamentares.models import Parlamentar + + +def pega_autores(): + return [[autor for autor in Autor.objects.filter(nome=nome)] + for nome in Autor.objects.values_list('nome', flat=True).annotate(qntd=Count('nome')).filter(qntd__gt=1)] + + +def pega_parlamentares_autores(): + parlamentares = [[parlamentar for parlamentar in Parlamentar.objects.filter(nome_parlamentar=nome_parlamentar)] + for nome_parlamentar in Parlamentar.objects.values_list('nome_parlamentar', flat=True) + .annotate(qntd=Count('nome_parlamentar')).filter(qntd__gt=1)] + + parlamentares_autores = [] + + for parlamentar in parlamentares: + parlamentar_autor = [] + for clone in parlamentar[1:]: + try: + autor_principal = Autor.objects.get(parlamentar_set=parlamentar[0]) + except ObjectDoesNotExist: + try: + autor_clonado = Autor.objects.get(parlamentar_set=clone) + except ObjectDoesNotExist: + pass + else: + autor_clonado.object_id = parlamentar[0].id + autor_clonado.save() + parlamentares_autores.append(autor_clonado) + else: + if len(parlamentar_autor) == 0: + parlamentar_autor.append(autor_principal) + + try: + autor_clonado = Autor.objects.get(parlamentar_set=clone) + except ObjectDoesNotExist: + pass + else: + parlamentar_autor.append(autor_clonado) + parlamentares_autores.extend(parlamentar_autor) + + return parlamentares_autores + + +def transfere_valeres(autores): + for autor in autores: + for clone in autor[1:]: + for autoria in clone.autoria_set.all(): + autoria.autor_id = autor[0] + autoria.save() + + for proposicao in clone.proposicao_set.all(): + proposicao.autor_id = autor[0] + proposicao.save() + + for autorianorma in clone.autorianorma_set.all(): + autorianorma.autor_id = autor[0] + autorianorma.save() + + for documentoadministrativo in clone.documentoadministrativo_set.all(): + documentoadministrativo.autor_id = autor[0] + documentoadministrativo.save() + + for protocolo in clone.protocolo_set.all(): + protocolo.autor_id = autor[0] + protocolo.save() + + clone.delete() + + +def main(): + autores = pega_autores() + parlamentares_autores = pega_parlamentares_autores() + + autores.append(parlamentares_autores) + + transfere_valeres(autores) + + +if __name__ == '__main__': + main() From c0536c985e2002be542238a3cba7bdb8dea48107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?= Date: Mon, 15 Apr 2019 16:48:00 -0300 Subject: [PATCH 05/18] Fix #2719 (#2721) * Fix #2719 em Anexada * Fix #2719 em Anexada em Lote --- sapl/materia/forms.py | 7 +++++++ sapl/materia/views.py | 22 +++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index af78b20ff..6a6f59300 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -790,6 +790,13 @@ class AnexadaForm(ModelForm): cleaned_data = self.cleaned_data + data_anexacao = cleaned_data['data_anexacao'] + data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao + + if data_anexacao > data_desanexacao: + self.logger.error("Data de anexação posterior à data de desanexação.") + raise ValidationError(_("Data de anexação posterior à data de desanexação.")) + try: self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={})." .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 464b505ee..e7a730c8f 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -2112,19 +2112,31 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView): def post(self, request, *args, **kwargs): marcadas = request.POST.getlist('materia_id') - if len(marcadas) == 0: - msg = _('Nenhuma máteria foi selecionada.') - messages.add_message(request, messages.ERROR, msg) - return self.get(request, self.kwargs) - data_anexacao = datetime.strptime( request.POST['data_anexacao'], "%d/%m/%Y").date() if request.POST['data_desanexacao'] == '': data_desanexacao = None + v_data_desanexacao = data_anexacao else: data_desanexacao = datetime.strptime( request.POST['data_desanexacao'], "%d/%m/%Y").date() + v_data_desanexacao = data_desanexacao + + if len(marcadas) == 0: + msg = _('Nenhuma máteria foi selecionada.') + messages.add_message(request, messages.ERROR, msg) + + if data_anexacao > v_data_desanexacao: + 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.') + messages.add_message(request, messages.ERROR, msg) + return self.get(request, self.kwargs) principal = MateriaLegislativa.objects.get(pk=kwargs['pk']) for materia in MateriaLegislativa.objects.filter(id__in=marcadas): From bd705ec0fc00f787e2c5e0cd7021c88f4ac854a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?= Date: Mon, 15 Apr 2019 16:48:17 -0300 Subject: [PATCH 06/18] Fix #2722 (#2723) * Corrigir mensagem de erro * Fix #2722 --- sapl/protocoloadm/forms.py | 4 ++-- sapl/protocoloadm/views.py | 22 +++++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index ef013703d..43f410847 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -811,8 +811,8 @@ class AnexadoForm(ModelForm): data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao if data_anexacao > data_desanexacao: - self.logger.error("A data de anexação não pode ser posterior a data de desanexação.") - raise ValidationError(_("A data de anexação não pode ser posterior a data de desanexação.")) + self.logger.error("Data de anexação posterior à data de desanexação.") + raise ValidationError(_("Data de anexação posterior à data de desanexação.")) try: self.logger.info( "Tentando obter objeto DocumentoAdministrativo (numero={}, ano={}, tipo={})." diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 6cefc9b0a..269d69ebc 100755 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -1046,11 +1046,6 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView): def post(self, request, *args, **kwargs): marcados = request.POST.getlist('documento_id') - - if len(marcados) == 0: - msg =_('Nenhum documento foi selecionado') - messages.add_message(request, messages.ERROR, msg) - return self.get(request, self.kwargs) data_anexacao = datetime.strptime( request.POST['data_anexacao'], "%d/%m/%Y" @@ -1058,10 +1053,27 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView): if request.POST['data_desanexacao'] == '': data_desanexacao = None + v_data_desanexacao = data_anexacao else: data_desanexacao = datetime.strptime( request.POST['data_desanexacao'], "%d/%m/%Y" ).date() + v_data_desanexacao = data_desanexacao + + if len(marcados) == 0: + 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.') + 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.') + 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): From a636986716bef64fa870321d23bf126f04ba76b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Mon, 15 Apr 2019 16:51:08 -0300 Subject: [PATCH 07/18] =?UTF-8?q?Adiciona=20script=20para=20remover=20prot?= =?UTF-8?q?ocolos=20inexistentes=20em=20mat=C3=A9rias=20(#2708)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/remove_protocolos_inexistentes_materias.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 scripts/remove_protocolos_inexistentes_materias.py diff --git a/scripts/remove_protocolos_inexistentes_materias.py b/scripts/remove_protocolos_inexistentes_materias.py new file mode 100644 index 000000000..b8881b1c9 --- /dev/null +++ b/scripts/remove_protocolos_inexistentes_materias.py @@ -0,0 +1,13 @@ +from sapl.materia.models import MateriaLegislativa +from sapl.protocoloadm.models import Protocolo + + +def main(): + for materia in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False): + if not Protocolo.objects.filter(ano=materia.ano, numero=materia.numero_protocolo).exists(): + materia.numero_protocolo = None + materia.save() + + +if __name__ == '__main__': + main() From 7f90bd7770f07b0d6398f934a4a8cf5dc6fb9b97 Mon Sep 17 00:00:00 2001 From: Cesar Augusto de Carvalho Date: Mon, 15 Apr 2019 16:51:22 -0300 Subject: [PATCH 08/18] =?UTF-8?q?Fix=202711=20-=20Adiciona=20op=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20numera=C3=A7=C3=A3o=20por=20ano=20independenteme?= =?UTF-8?q?nte=20do=20autor=20(#2725)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0033_auto_20190415_1050.py | 20 +++++++++++++++++++ sapl/base/models.py | 3 ++- sapl/materia/forms.py | 13 ++++++++---- .../migrations/0045_auto_20190415_1050.py | 20 +++++++++++++++++++ 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 sapl/base/migrations/0033_auto_20190415_1050.py create mode 100644 sapl/materia/migrations/0045_auto_20190415_1050.py diff --git a/sapl/base/migrations/0033_auto_20190415_1050.py b/sapl/base/migrations/0033_auto_20190415_1050.py new file mode 100644 index 000000000..8c21764f3 --- /dev/null +++ b/sapl/base/migrations/0033_auto_20190415_1050.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-15 13:50 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0032_merge_20190219_0941'), + ] + + operations = [ + migrations.AlterField( + model_name='appconfig', + name='sequencia_numeracao', + field=models.CharField(choices=[('A', 'Sequencial por ano para cada autor'), ('B', 'Sequencial por ano indepententemente do autor'), ('L', 'Sequencial por legislatura'), ('U', 'Sequencial único')], default='A', max_length=1, verbose_name='Sequência de numeração'), + ), + ] diff --git a/sapl/base/models.py b/sapl/base/models.py index 87e497e84..b4f0a8d74 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -18,7 +18,8 @@ TIPO_DOCUMENTO_ADMINISTRATIVO = ((DOC_ADM_OSTENSIVO, _('Ostensiva')), RELATORIO_ATOS_ACESSADOS = (('S', _('Sim')), ('N', _('Não'))) -SEQUENCIA_NUMERACAO = (('A', _('Sequencial por ano')), +SEQUENCIA_NUMERACAO = (('A', _('Sequencial por ano para cada autor')), + ('B', _('Sequencial por ano indepententemente do autor')), ('L', _('Sequencial por legislatura')), ('U', _('Sequencial único'))) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 6a6f59300..41f3b550a 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1666,12 +1666,17 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm): return super().save(commit) inst.ano = timezone.now().year - numero__max = Proposicao.objects.filter( - autor=inst.autor, - ano=timezone.now().year).aggregate(Max('numero_proposicao')) + sequencia_numeracao = AppConfig.attr('sequencia_numeracao') + if sequencia_numeracao == 'A': + numero__max = Proposicao.objects.filter( + autor=inst.autor, + ano=timezone.now().year).aggregate(Max('numero_proposicao')) + elif sequencia_numeracao == 'B': + numero__max = Proposicao.objects.filter( + ano=timezone.now().year).aggregate(Max('numero_proposicao')) numero__max = numero__max['numero_proposicao__max'] inst.numero_proposicao = ( - numero__max + 1) if numero__max else 1 + numero__max + 1) if numero__max else 1 self.gerar_hash(inst, receber_recibo) diff --git a/sapl/materia/migrations/0045_auto_20190415_1050.py b/sapl/materia/migrations/0045_auto_20190415_1050.py new file mode 100644 index 000000000..55f59dd49 --- /dev/null +++ b/sapl/materia/migrations/0045_auto_20190415_1050.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-15 13:50 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0044_auto_20190327_1409'), + ] + + operations = [ + migrations.AlterField( + model_name='tipomaterialegislativa', + name='sequencia_numeracao', + field=models.CharField(blank=True, choices=[('A', 'Sequencial por ano para cada autor'), ('B', 'Sequencial por ano indepententemente do autor'), ('L', 'Sequencial por legislatura'), ('U', 'Sequencial único')], max_length=1, verbose_name='Sequência de numeração'), + ), + ] From 1708da9dffacea8dfb52197190bc7abd2c54dde5 Mon Sep 17 00:00:00 2001 From: Cesar Augusto de Carvalho Date: Mon, 15 Apr 2019 16:52:50 -0300 Subject: [PATCH 09/18] Verifica se a sessao esta aberta ou finalizada na Votacao em Bloco (#2724) --- sapl/sessao/views.py | 12 +- .../votacao/votacao_bloco_expediente.html | 160 +++++++++-------- .../sessao/votacao/votacao_bloco_ordem.html | 168 +++++++++--------- 3 files changed, 176 insertions(+), 164 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 74c9094e9..602e70ca6 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -3552,9 +3552,13 @@ class VotacaoEmBlocoExpediente(PermissionRequiredForAppCrudMixin, ListView): def get_context_data(self, **kwargs): context = super(VotacaoEmBlocoExpediente, self).get_context_data(**kwargs) - context['turno_choices'] = Tramitacao.TURNO_CHOICES context['pk'] = self.kwargs['pk'] context['root_pk'] = self.kwargs['pk'] + if not verifica_sessao_iniciada(self.request, self.kwargs['pk']): + context['sessao_iniciada'] = False + return context + context['sessao_iniciada'] = True + context['turno_choices'] = Tramitacao.TURNO_CHOICES context['title'] = SessaoPlenaria.objects.get(id=self.kwargs['pk']) return context @@ -3574,9 +3578,13 @@ class VotacaoEmBlocoOrdemDia(PermissionRequiredForAppCrudMixin, ListView): def get_context_data(self, **kwargs): context = super(VotacaoEmBlocoOrdemDia, self).get_context_data(**kwargs) - context['turno_choices'] = Tramitacao.TURNO_CHOICES context['pk'] = self.kwargs['pk'] context['root_pk'] = self.kwargs['pk'] + if not verifica_sessao_iniciada(self.request, self.kwargs['pk']): + context['sessao_iniciada'] = False + return context + context['sessao_iniciada'] = True + context['turno_choices'] = Tramitacao.TURNO_CHOICES context['title'] = SessaoPlenaria.objects.get(id=self.kwargs['pk']) return context diff --git a/sapl/templates/sessao/votacao/votacao_bloco_expediente.html b/sapl/templates/sessao/votacao/votacao_bloco_expediente.html index 7ca074645..589a2397e 100644 --- a/sapl/templates/sessao/votacao/votacao_bloco_expediente.html +++ b/sapl/templates/sessao/votacao/votacao_bloco_expediente.html @@ -3,94 +3,96 @@ {% block base_content %} -
- {% csrf_token %} -

- - + {% if sessao_iniciada %} + + {% csrf_token %} +

+
+ + + + + - - - - - - -

{% trans "Tipo de Votação" %}

{% trans "Tipo de Votação" %}

-
- -
- -
-
-
- -
-

Selecione o(s) expediente(s) desejado(s).

- - - - + - +

{% trans "Expediente" %}

+
+ +
+ +
+
+
+ +
+

Selecione o(s) expediente(s) desejado(s).

+ + + + + + -
- -
+
+ +
- {% for o in expedientes %} - {% if o.tipo_votacao == 1 or o.tipo_votacao == 2 %} - - + - - {% endif %} - {% endfor %} -

{% trans "Expediente" %}

+ Ementa: {{ o.ementa|safe }}
+

+ + + {% endif %} + {% endfor %} + - - - - - + + + + + - Voltar - + Voltar + - -
+ + + {% endif %} {% endblock base_content %} diff --git a/sapl/templates/sessao/votacao/votacao_bloco_ordem.html b/sapl/templates/sessao/votacao/votacao_bloco_ordem.html index e80695d00..8c80d47cc 100644 --- a/sapl/templates/sessao/votacao/votacao_bloco_ordem.html +++ b/sapl/templates/sessao/votacao/votacao_bloco_ordem.html @@ -3,94 +3,96 @@ {% block base_content %} -
- {% csrf_token %} -

- + {% if sessao_iniciada %} + + {% csrf_token %} +

+
+ + + + + + + + +

{% trans "Tipo de Votação" %}

+
+ +
+ +
+
+
+ +
+

Selecione a(s) ordem(s) do dia desejada(s).

+ - - - + + + - - + - -

{% trans "Tipo de Votação" %}

{% trans "Ordem do dia" %}

-
- -
- + +
+ +
+ + {% for o in ordem_dia %} + {% if o.tipo_votacao == 1 or o.tipo_votacao == 2 %} +
- -
-

Selecione a(s) ordem(s) do dia desejada(s).

- - - - - - - -
- -
- - {% for o in ordem_dia %} - {% if o.tipo_votacao == 1 or o.tipo_votacao == 2 %} - - - - {% endif %} - {% endfor %} -

{% trans "Ordem do dia" %}

- - - - - - - - Voltar - - - -
+ Ementa: {{ o.ementa|safe }}
+

+ + + {% endif %} + {% endfor %} + + + + + + + + + Voltar + + + + + {% endif %} {% endblock base_content %} From cb63e5cf9b3e921a9a8a0215c73627d1ecdc82c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Mon, 15 Apr 2019 17:01:19 -0300 Subject: [PATCH 10/18] =?UTF-8?q?Adiciona=20formata=C3=A7=C3=A3o=20alterna?= =?UTF-8?q?tiva=20de=20entrada=20para=20data=20de=20publica=C3=A7=C3=A3o?= =?UTF-8?q?=20e=20efetividade=20(#2707)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/compilacao/forms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/compilacao/forms.py b/sapl/compilacao/forms.py index 222a86aed..e82d58f63 100644 --- a/sapl/compilacao/forms.py +++ b/sapl/compilacao/forms.py @@ -220,7 +220,7 @@ class NotaForm(ModelForm): publicacao = forms.DateField( label=Nota._meta.get_field('publicacao').verbose_name, - input_formats=['%d/%m/%Y'], + input_formats=['%d/%m/%Y', '%d%m%Y'], required=True, widget=forms.DateInput( format='%d/%m/%Y'), @@ -228,7 +228,7 @@ class NotaForm(ModelForm): ) efetividade = forms.DateField( label=Nota._meta.get_field('efetividade').verbose_name, - input_formats=['%d/%m/%Y'], + input_formats=['%d/%m/%Y', '%d%m%Y'], required=True, widget=forms.DateInput( format='%d/%m/%Y'), From 002ed5ab70bea482420308a4af60aacd46703669 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 15 Apr 2019 18:27:34 -0300 Subject: [PATCH 11/18] HOT-FIX: adiciona prefixo xsi a XML do LexML --- sapl/lexml/OAIServer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/lexml/OAIServer.py b/sapl/lexml/OAIServer.py index 4c1d85c19..7972e709a 100644 --- a/sapl/lexml/OAIServer.py +++ b/sapl/lexml/OAIServer.py @@ -170,7 +170,7 @@ class OAIServer: if norma and publicador: LEXML = ElementMaker(namespace=self.ns['lexml'], nsmap=self.ns) oai_lexml = LEXML.LexML() - oai_lexml.attrib['{{}}schemaLocation'.format(self.XSI_NS)] = '{} {}'.format( + oai_lexml.attrib['{{{pre}}}schemaLocation'.format(pre=self.XSI_NS)] = '{} {}'.format( 'http://www.lexml.gov.br/oai_lexml', 'http://projeto.lexml.gov.br/esquemas/oai_lexml.xsd') texto_integral = norma.texto_integral mime_types = {'doc': 'application/msword', From 383e956ae619b7424b3af8250ec96bcc5f2731f7 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 15 Apr 2019 19:01:53 -0300 Subject: [PATCH 12/18] HOT-FIX: conserta URLs LexML --- sapl/lexml/OAIServer.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sapl/lexml/OAIServer.py b/sapl/lexml/OAIServer.py index 7972e709a..8895fea46 100644 --- a/sapl/lexml/OAIServer.py +++ b/sapl/lexml/OAIServer.py @@ -166,6 +166,9 @@ class OAIServer: return '' def monta_xml(self, urn, norma): + BASE_URL_SAPL = self.config['base_url'] + BASE_URL_SAPL = BASE_URL_SAPL[:BASE_URL_SAPL.find('/', 8)] + publicador = LexmlPublicador.objects.first() if norma and publicador: LEXML = ElementMaker(namespace=self.ns['lexml'], nsmap=self.ns) @@ -178,20 +181,21 @@ class OAIServer: 'odt': 'application/vnd.oasis.opendocument.text', 'pdf': 'application/pdf', 'rtf': 'application/rtf'} + if texto_integral: - url_conteudo = self.config['base_url'] + texto_integral.url + url_conteudo = BASE_URL_SAPL + texto_integral.url extensao = texto_integral.url.split('.')[-1] formato = mime_types.get(extensao, 'application/octet-stream') else: formato = 'text/html' - url_conteudo = self.config['base_url'] + reverse('sapl.norma:normajuridica_detail', + url_conteudo = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail', kwargs={'pk': norma.numero}) element_maker = ElementMaker() id_publicador = str(publicador.id_publicador) item_conteudo = element_maker.Item(url_conteudo, formato=formato, idPublicador=id_publicador, tipo='conteudo') oai_lexml.append(item_conteudo) - url = self.config['base_url'] + reverse('sapl.norma:normajuridica_detail', kwargs={'pk': norma.numero}) + url = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail', kwargs={'pk': norma.numero}) item_metadado = element_maker.Item(url, formato='text/html', idPublicador=id_publicador, tipo='metadado') oai_lexml.append(item_metadado) documento_individual = element_maker.DocumentoIndividual(urn) From b967eb295cbdd2c91573ac7a234a8fb3721d2763 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 16 Apr 2019 14:38:43 -0300 Subject: [PATCH 13/18] =?UTF-8?q?HOT-FIX:=20adiciona=20nome=20do=20estado?= =?UTF-8?q?=20ao=20inv=C3=A9s=20de=20sigla=20no=20LexML?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/lexml/OAIServer.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sapl/lexml/OAIServer.py b/sapl/lexml/OAIServer.py index 8895fea46..cf85e4bf8 100644 --- a/sapl/lexml/OAIServer.py +++ b/sapl/lexml/OAIServer.py @@ -11,6 +11,7 @@ from lxml.builder import ElementMaker from sapl.base.models import AppConfig, CasaLegislativa from sapl.lexml.models import LexmlPublicador, LexmlProvedor from sapl.norma.models import NormaJuridica +from sapl.utils import LISTA_DE_UFS class OAILEXML: @@ -127,17 +128,18 @@ class OAIServer: urn = 'urn:lex:br;' esferas = {'M': 'municipal', 'E': 'estadual'} municipio = casa.municipio.lower() - uf = casa.uf.lower() + uf_map = dict(LISTA_DE_UFS) + uf_desc = uf_map.get(casa.uf.upper(), '').lower() for x in [' ', '.de.', '.da.', '.das.', '.do.', '.dos.']: municipio = municipio.replace(x, '.') - uf = uf.replace(x, '.') + uf_desc = uf_desc.replace(x, '.') if esfera == 'M': - urn += '{};{}:'.format(uf, municipio) + urn += '{};{}:'.format(uf_desc, municipio) if norma.tipo.equivalente_lexml == 'regimento.interno' or norma.tipo.equivalente_lexml == 'resolucao': urn += 'camara.' urn += esferas[esfera] + ':' elif esfera == 'E': - urn += '{}:{}:'.format(uf, esferas[esfera]) + urn += '{}:{}:'.format(uf_desc, esferas[esfera]) else: urn += ':' if norma.tipo.equivalente_lexml: From b100694cdae448d9cb1c670e74886299a67a76d0 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 16 Apr 2019 14:59:51 -0300 Subject: [PATCH 14/18] HOT-FIX: corrige erro de pk em LexML --- sapl/lexml/OAIServer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/lexml/OAIServer.py b/sapl/lexml/OAIServer.py index cf85e4bf8..4964dbeb9 100644 --- a/sapl/lexml/OAIServer.py +++ b/sapl/lexml/OAIServer.py @@ -191,13 +191,13 @@ class OAIServer: else: formato = 'text/html' url_conteudo = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail', - kwargs={'pk': norma.numero}) + kwargs={'pk': norma.pk}) element_maker = ElementMaker() id_publicador = str(publicador.id_publicador) item_conteudo = element_maker.Item(url_conteudo, formato=formato, idPublicador=id_publicador, tipo='conteudo') oai_lexml.append(item_conteudo) - url = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail', kwargs={'pk': norma.numero}) + url = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail', kwargs={'pk': norma.pk}) item_metadado = element_maker.Item(url, formato='text/html', idPublicador=id_publicador, tipo='metadado') oai_lexml.append(item_metadado) documento_individual = element_maker.DocumentoIndividual(urn) From c755d90ef0182dffccd9511239517a3f6b2d5d63 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 16 Apr 2019 17:36:10 -0300 Subject: [PATCH 15/18] HOT-FIX: retira acentos de XML do LexML --- sapl/lexml/OAIServer.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sapl/lexml/OAIServer.py b/sapl/lexml/OAIServer.py index 4964dbeb9..9783f2fa6 100644 --- a/sapl/lexml/OAIServer.py +++ b/sapl/lexml/OAIServer.py @@ -1,3 +1,4 @@ +import unicodedata from datetime import datetime import oaipmh @@ -123,13 +124,23 @@ class OAIServer: else: return None + @staticmethod + def remove_acentos(linha): + res = unicodedata.normalize('NFKD', linha).encode('ASCII', 'ignore') + res = res.decode("UTF-8") + remove_list = ["\'", "\"", "-"] + for i in remove_list: + res = res.replace(i, "") + return res + def monta_urn(self, norma, esfera): if norma: urn = 'urn:lex:br;' esferas = {'M': 'municipal', 'E': 'estadual'} - municipio = casa.municipio.lower() + municipio = self.remove_acentos(casa.municipio.lower()) uf_map = dict(LISTA_DE_UFS) uf_desc = uf_map.get(casa.uf.upper(), '').lower() + uf_desc = self.remove_acentos(uf_desc) for x in [' ', '.de.', '.da.', '.das.', '.do.', '.dos.']: municipio = municipio.replace(x, '.') uf_desc = uf_desc.replace(x, '.') From 6408ac90c0dcc7b3e46ea155f8d0c80b63a7e0d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?= Date: Wed, 17 Apr 2019 14:17:48 -0300 Subject: [PATCH 16/18] =?UTF-8?q?Adicionar=20Conte=C3=BAdo=20Multim=C3=ADd?= =?UTF-8?q?ia=20-=20PDF=20Resumo=20(#2731)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/pdf_sessao_plenaria_gerar.py | 24 +++++++++++++++++-- sapl/relatorios/views.py | 15 ++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index 4c388e59a..4bbe31bed 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -128,6 +128,24 @@ def inf_basicas(inf_basicas_dic): return tmp +def multimidia(cont_mult_dic): + """ + """ + tmp = "" + + mul_audio = cont_mult_dic['multimidia_audio'] + mul_video = cont_mult_dic['multimidia_video'] + + tmp += '\t\tConteúdo Multimídia\n' + tmp += '\t\t\n' + tmp += '\t\t\t
\n' + tmp += '\t\t
\n' + tmp += '\t\tAudio: ' + mul_audio + '\n' + tmp += '\t\tVideo: ' + mul_video + '\n' + + return tmp + + def mesa(lst_mesa): """ @@ -392,7 +410,7 @@ def ocorrencias(lst_ocorrencias): return tmp -def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, lst_expedientes, lst_expediente_materia, lst_expediente_materia_vot_nom, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_votacao_vot_nom, lst_oradores_ordemdia, lst_oradores, lst_ocorrencias): +def principal(rodape_dic, imagem, inf_basicas_dic, cont_mult_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, lst_expedientes, lst_expediente_materia, lst_expediente_materia_vot_nom, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_votacao_vot_nom, lst_oradores_ordemdia, lst_oradores, lst_ocorrencias): """ """ arquivoPdf = str(int(time.time() * 100)) + ".pdf" @@ -416,7 +434,7 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao ordenacao = ResumoOrdenacao.objects.first() dict_ord_template = { - 'cont_mult': '', + 'cont_mult': multimidia(cont_mult_dic), 'exp': expedientes(lst_expedientes), 'id_basica': inf_basicas(inf_basicas_dic), 'lista_p': presenca(lst_presenca_sessao, lst_ausencia_sessao), @@ -452,6 +470,7 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao logger.error("KeyError: " + str(e) + ". Erro ao tentar utilizar " "configuração de ordenação. Utilizando ordenação padrão.") tmp += inf_basicas(inf_basicas_dic) + tmp += multimidia(cont_mult_dic) tmp += mesa(lst_mesa) tmp += presenca(lst_presenca_sessao, lst_ausencia_sessao) tmp += expedientes(lst_expedientes) @@ -467,6 +486,7 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao else: tmp += inf_basicas(inf_basicas_dic) + tmp += multimidia(cont_mult_dic) tmp += mesa(lst_mesa) tmp += presenca(lst_presenca_sessao, lst_ausencia_sessao) tmp += expedientes(lst_expedientes) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 5bd3fe6f7..72595b239 100755 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -519,6 +519,18 @@ def get_sessao_plenaria(sessao, casa): inf_basicas_dic["dat_fim_sessao"] = '' inf_basicas_dic["hr_fim_sessao"] = sessao.hora_fim inf_basicas_dic["nom_camara"] = casa.nome + + # Conteudo multimidia + cont_mult_dic = {} + if sessao.url_audio: + cont_mult_dic['multimidia_audio'] = str(sessao.url_audio) + else: + cont_mult_dic['multimidia_audio'] = 'Indisponível' + + if sessao.url_video: + cont_mult_dic['multimidia_video'] = str(sessao.url_video) + else: + cont_mult_dic['multimidia_video'] = 'Indisponível' # Lista da composicao da mesa diretora lst_mesa = [] @@ -852,6 +864,7 @@ def get_sessao_plenaria(sessao, casa): lst_ocorrencias.append(o) return (inf_basicas_dic, + cont_mult_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, @@ -910,6 +923,7 @@ def relatorio_sessao_plenaria(request, pk): raise Http404('Essa página não existe') (inf_basicas_dic, + cont_mult_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, @@ -934,6 +948,7 @@ def relatorio_sessao_plenaria(request, pk): rodape, imagem, inf_basicas_dic, + cont_mult_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, From e4ac60abc9615aa1eb5b11b17876cecd7cf702df Mon Sep 17 00:00:00 2001 From: Cesar Augusto de Carvalho Date: Wed, 17 Apr 2019 14:21:18 -0300 Subject: [PATCH 17/18] =?UTF-8?q?Reordena=20configura=C3=A7oes=20do=20cron?= =?UTF-8?q?ometro=20(#2735)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/templates/base/layouts.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sapl/templates/base/layouts.yaml b/sapl/templates/base/layouts.yaml index 91f0cd67e..3d248c313 100644 --- a/sapl/templates/base/layouts.yaml +++ b/sapl/templates/base/layouts.yaml @@ -31,7 +31,8 @@ AppConfig: - assinatura_ata {% trans 'Cronômetros do Painel' %}: - - cronometro_discurso cronometro_aparte cronometro_ordem cronometro_consideracoes + - cronometro_discurso cronometro_aparte + - cronometro_ordem cronometro_consideracoes {% trans 'Configurações do Painel' %}: - mostrar_brasao_painel From bf024efcf4e16ab2f9d12522da1077e983c7afe5 Mon Sep 17 00:00:00 2001 From: Ricardo Lima Canela Date: Wed, 17 Apr 2019 14:24:50 -0300 Subject: [PATCH 18/18] verifica quatro vezes se solr esta online (#2732) --- Dockerfile | 1 + check_solr.sh | 13 ++++++++++--- docker-compose.yml | 17 +++++++++++++++++ start.sh | 14 +++++++++++--- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 015357a40..9c33fcd0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,6 +39,7 @@ RUN rm -rf /var/interlegis/sapl/sapl/.env && \ rm -rf /var/interlegis/sapl/sapl.db RUN chmod +x /var/interlegis/sapl/start.sh && \ + chmod +x /var/interlegis/sapl/check_solr.sh && \ ln -sf /dev/stdout /var/log/nginx/access.log && \ ln -sf /dev/stderr /var/log/nginx/error.log && \ mkdir /var/log/sapl/ && touch /var/interlegis/sapl/sapl.log && \ diff --git a/check_solr.sh b/check_solr.sh index b3c4760c4..c600466bb 100644 --- a/check_solr.sh +++ b/check_solr.sh @@ -4,15 +4,22 @@ SOLR_URL=$1 +RETRY_COUNT=1 +RETRY_LIMIT=4 + echo "Waiting for solr connection at $SOLR_URL ..." -while true; do +while [[ $RETRY_COUNT < $RETRY_LIMIT ]]; do + echo "Attempt to connect to solr: $RETRY_COUNT of $RETRY_LIMIT" + let RETRY_COUNT=RETRY_COUNT+1; echo "$SOLR_URL/solr/admin/collections?action=LIST" RESULT=$(curl -s -o /dev/null -I "$SOLR_URL/solr/admin/collections?action=LIST" -w '%{http_code}') echo $RESULT - if [ "$RESULT" -eq '200' ]; then + if [ $RESULT == 200 ]; then echo "Solr server is up!" - break + exit 1 else sleep 3 fi done +echo "Solr connection failed." +exit 2 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index e2dfb6824..5fe0b554b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,7 @@ sapldb: - "5432:5432" sapl: image: interlegis/sapl:3.1.153 +# build: . restart: always environment: ADMIN_PASSWORD: interlegis @@ -23,11 +24,27 @@ sapl: EMAIL_HOST_USER: usuariosmtp EMAIL_SEND_USER: usuariosmtp EMAIL_HOST_PASSWORD: senhasmtp +# USE_SOLR: 'True' +# SOLR_COLLECTION: sapl +# SOLR_URL: http://saplsolr:8983 TZ: America/Sao_Paulo volumes: - sapl_data:/var/interlegis/sapl/data - sapl_media:/var/interlegis/sapl/media links: - sapldb +# - saplsolr ports: - "80:80" + +#saplsolr: +# image: solr:7.4-alpine +# restart: always +# command: bin/solr start -c -f +# volumes: +# - solr_data:/opt/solr/server/solr +# - solr_configsets:/opt/solr/server/solr/configsets +# ports: +# - "8983:8983" + + diff --git a/start.sh b/start.sh index 0790c2c24..bea1eb959 100755 --- a/start.sh +++ b/start.sh @@ -70,11 +70,19 @@ if [ "${USE_SOLR-False}" == "True" ] || [ "${USE_SOLR-False}" == "true" ]; then echo "REPLICATION FACTOR: $RF" echo "MAX SHARDS PER NODE: $MAX_SHARDS_PER_NODE" echo "=========================================" - + + echo "running solr script" /bin/bash check_solr.sh $SOLR_URL + CHECK_SOLR_RETURN=$? + + if [ $CHECK_SOLR_RETURN == 1 ]; then + echo "Connecting to solr..." + python3 solr_api.py -u $SOLR_URL -c $SOLR_COLLECTION -s $NUM_SHARDS -rf $RF -ms $MAX_SHARDS_PER_NODE & + # python3 manage.py rebuild_index --noinput & + else + echo "Solr is offline, not possible to connect." + fi - python3 solr_api.py -u $SOLR_URL -c $SOLR_COLLECTION -s $NUM_SHARDS -rf $RF -ms $MAX_SHARDS_PER_NODE & - # python3 manage.py rebuild_index --noinput & else echo "Suporte a SOLR não inicializado." fi