From 1b5ee6cf22ac0325d34161eaa89d3431e0b5b72c Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Fri, 11 Aug 2017 11:01:42 -0300 Subject: [PATCH 001/237] =?UTF-8?q?Inicia=20simplifica=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 179 +++++++++++++++------------------------ sapl/materia/models.py | 7 +- 2 files changed, 73 insertions(+), 113 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index fcf2f0837..b0599bcce 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -12,7 +12,7 @@ from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.db import OperationalError, ProgrammingError, connections, models -from django.db.models import CharField, Max, ProtectedError, TextField, Count +from django.db.models import CharField, Count, Max, ProtectedError, TextField from django.db.models.base import ModelBase from django.db.models.signals import post_delete, post_save from model_mommy import mommy @@ -26,11 +26,11 @@ from sapl.materia.models import (AcompanhamentoMateria, DocumentoAcessorio, StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, TipoProposicao, Tramitacao) -from sapl.norma.models import (AssuntoNorma, NormaJuridica, - TipoVinculoNormaJuridica, NormaRelacionada) -from sapl.parlamentares.models import (Legislatura,Mandato, Parlamentar, +from sapl.norma.models import (AssuntoNorma, NormaJuridica, NormaRelacionada, + TipoVinculoNormaJuridica) +from sapl.parlamentares.models import (Legislatura, Mandato, Parlamentar, TipoAfastamento) -from sapl.protocoloadm.models import (DocumentoAdministrativo,Protocolo, +from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, StatusTramitacaoAdministrativo) from sapl.sessao.models import ExpedienteMateria, OrdemDia, RegistroVotacao from sapl.settings import PROJECT_DIR @@ -119,63 +119,22 @@ def erro(msg): print('ERRO: ' + msg) +class ForeignKeyFaltando(ObjectDoesNotExist): + 'Uma FK aponta para um registro inexistente' + pass + + def get_fk_related(field, value, label=None): - if value is None and field.null is False: - value = 0 - if value is not None: + if value is None: + return value + else: try: - value = field.related_model.objects.get(id=value) - except ObjectDoesNotExist: - msg = 'FK [%s] não encontrada para valor %s ' \ - '(em %s %s)' % ( - field.name, value, - field.model.__name__, label or '---') - if value == 0: - if not field.null: - fields_dict = get_fields_dict(field.related_model) - # Cria stub ao final da tabela para evitar erros - pk = get_last_value(field.related_model) - with reversion.create_revision(): - reversion.set_comment('Stub criado pela migração') - value = mommy.make( - field.related_model, **fields_dict, - pk=(pk + 1 or 1)) - descricao = 'stub criado para campos não nuláveis!' - save_relation(value, [field.name], msg, descricao, - eh_stub=True) - warn(msg + ' => ' + descricao) - else: - value = None - else: - if field.model._meta.label == 'sessao.RegistroVotacao' and \ - field.name == 'ordem': - return value - # Caso TipoProposicao não exista, um objeto será criado então - # com content_type=13 (ProblemaMigracao) - if field.related_model.__name__ == 'TipoProposicao': - tipo = TipoProposicao.objects.filter(descricao='Erro') - if not tipo: - with reversion.create_revision(): - reversion.set_comment( - 'TipoProposicao "Erro" criado') - ct = ContentType.objects.get(pk=13) - value = TipoProposicao.objects.create( - id=value, descricao='Erro', content_type=ct) - ultimo_valor = get_last_value(type(value)) - alter_sequence(type(value), ultimo_valor+1) - else: - value = tipo[0] - else: - with reversion.create_revision(): - reversion.set_comment('Stub criado pela migração') - value = make_stub(field.related_model, value) - descricao = 'stub criado para entrada orfã!' - warn(msg + ' => ' + descricao) - save_relation(value, [field.name], msg, descricao, - eh_stub=True) - else: - assert value - return value + return field.related_model.objects.get(id=value) + except ObjectDoesNotExist as ex: + msg = 'FK [%s] não encontrada para o valor %s (em %s %s)' % ( + field.name, value, field.model.__name__, label or '---') + warn(msg) + raise ForeignKeyFaltando(msg) def get_field(model, fieldname): @@ -252,7 +211,7 @@ def problema_duplicatas(model, lista_duplicatas, argumentos): string_pks = "" problema = "%s de PK %s não é único." % (model.__name__, obj.pk) args_dict = {k: obj.__dict__[k] - for k in set(argumentos) & set(obj.__dict__.keys())} + for k in set(argumentos) & set(obj.__dict__.keys())} for dup in model.objects.filter(**args_dict): pks.append(dup.pk) string_pks = "(" + ", ".join(map(str, pks)) + ")" @@ -321,6 +280,7 @@ def recria_constraints(): (problema[0], problema[1])) +# TODO o que é isso? #################################################### def obj_desnecessario(obj): relacoes = [ f for f in obj._meta.get_fields() @@ -335,7 +295,7 @@ def obj_desnecessario(obj): def get_last_value(model): last_value = model.objects.all().aggregate(Max('pk')) - return last_value['pk__max'] if last_value['pk__max'] else 0 + return last_value['pk__max'] or 0 def alter_sequence(model, id): @@ -360,11 +320,11 @@ def save_relation(obj, nome_campo='', problema='', descricao='', link.save() +# TODO NECESSÁRIO AINDA??????????? def make_stub(model, id): fields_dict = get_fields_dict(model) new = mommy.prepare(model, **fields_dict, pk=id) save_with_id(new, id) - return new @@ -407,7 +367,7 @@ def fill_vinculo_norma_juridica(): 'Julgada parcialmente inconstitucional')] lista_objs = [TipoVinculoNormaJuridica( sigla=item[0], descricao_ativa=item[1], descricao_passiva=item[2]) - for item in lista] + for item in lista] TipoVinculoNormaJuridica.objects.bulk_create(lista_objs) @@ -452,8 +412,6 @@ class DataMigrator: for field in new._meta.fields: old_field_name = renames.get(field.name) field_type = field.get_internal_type() - msg = ("O valor do campo %s (%s) da model %s era inválido" % - (field.name, field_type, field.model.__name__)) if old_field_name: old_value = getattr(old, old_field_name) if isinstance(field, models.ForeignKey): @@ -466,38 +424,36 @@ class DataMigrator: value = get_fk_related(field, old_value, label) else: value = getattr(old, old_field_name) + # TODO rever esse DateField após as mudança para datas com + # timezone if field_type == 'DateField' and \ not field.null and value is None: + # TODO REVER ISSO descricao = 'A data 1111-11-11 foi colocada no lugar' problema = 'O valor da data era nulo ou inválido' - warn(msg + - ' => ' + descricao) + warn("O valor do campo %s (%s) do model %s " + "era inválido => %s" % ( + field.name, field_type, + field.model.__name__, descricao)) value = date(1111, 11, 11) self.data_mudada['obj'] = new self.data_mudada['descricao'] = descricao self.data_mudada['problema'] = problema self.data_mudada.setdefault('nome_campo', []).\ append(field.name) - if field_type == 'CharField' or field_type == 'TextField': - if value is None or value == 'None': - value = '' - setattr(new, field.name, value) - elif field.model.__name__ == 'TipoAutor' and \ - field.name == 'content_type': - - model = normalize(new.descricao.lower()).replace(' ', '') - content_types = field.related_model.objects.filter( - model=model).exclude(app_label='legacy') - assert len(content_types) <= 1 - - value = content_types[0] if content_types else None + if field_type in ['CharField', 'TextField'] \ + and value in [None, 'None']: + if value == 'None': + # TODO quero saber como é que pode ser 'None' !!!! + import ipdb + ipdb.set_trace() + value = '' setattr(new, field.name, value) def migrate(self, obj=appconfs, interativo=True): # warning: model/app migration order is of utmost importance exec_sql_file(PROJECT_DIR.child( 'sapl', 'legacy', 'scripts', 'fix_tables.sql'), 'legacy') - self.to_delete = [] # excluindo database antigo. if interativo: @@ -593,8 +549,17 @@ class DataMigrator: # convert old records to new ones for old in old_records: + if getattr(old, 'ind_excluido', False): + # não migramos registros marcados como excluídos + continue new = model() - self.populate_renamed_fields(new, old) + try: + self.populate_renamed_fields(new, old) + except ForeignKeyFaltando: + # tentamos preencher uma FK e o ojeto relacionado não existe + # então este é um objeo órfão: simplesmente ignoramos + continue + if ajuste_antes_salvar: ajuste_antes_salvar(new, old) save(new, old) @@ -605,26 +570,10 @@ class DataMigrator: save_relation(**self.data_mudada) self.data_mudada.clear() reversion.set_comment('Ajuste de data pela migração') - if getattr(old, 'ind_excluido', False): - self.to_delete.append(new) # necessário para ajustar sequence da tabela para o ultimo valor de id ultimo_valor = get_last_value(model) - alter_sequence(model, ultimo_valor+1) - - def delete_ind_excluido(self): - excluidos = 0 - for obj in self.to_delete: - if obj_desnecessario(obj): - try: - obj.delete() - except ProtectedError: - pass - else: - self.to_delete.remove(obj) - excluidos += 1 - - return excluidos + alter_sequence(model, ultimo_valor + 1) def delete_stubs(self): excluidos = 0 @@ -665,15 +614,15 @@ def adjust_documentoadministrativo(new, old): except Exception: try: protocolo = Protocolo.objects.get(numero=new.numero_protocolo, - ano=new.ano+1) + ano=new.ano + 1) new.protocolo = protocolo except Exception: protocolo = mommy.make(Protocolo, numero=new.numero_protocolo, ano=new.ano) with reversion.create_revision(): problema = 'Protocolo Vinculado [numero_protocolo=%s, '\ - 'ano=%s] não existe' % (new.numero_protocolo, - new.ano) + 'ano=%s] não existe' % (new.numero_protocolo, + new.ano) descricao = 'O protocolo inexistente foi criado' warn(problema + ' => ' + descricao) save_relation(obj=protocolo, problema=problema, @@ -751,7 +700,7 @@ def adjust_proposicao_antes_salvar(new, old): def adjust_proposicao_depois_salvar(new, old): if not hasattr(old.dat_envio, 'year') or old.dat_envio.year == 1800: msg = "O valor do campo data_envio (DateField) da model Proposicao"\ - " era inválido" + " era inválido" descricao = 'A data 1111-11-11 foi colocada no lugar' problema = 'O valor da data era nulo ou inválido' warn(msg + ' => ' + descricao) @@ -816,7 +765,6 @@ def adjust_tipoafastamento(new, old): new.indicador = 'A' - def adjust_tipoproposicao(new, old): if old.ind_mat_ou_doc == 'M': new.tipo_conteudo_related = TipoMateriaLegislativa.objects.get( @@ -844,6 +792,14 @@ def adjust_tramitacao(new, old): new.turno = 'U' +def adjust_tipo_autor(new, old): + model_apontado = normalize(new.descricao.lower()).replace(' ', '') + content_types = ContentType.objects.filter( + model=model_apontado).exclude(app_label='legacy') + assert len(content_types) <= 1 + new.content_type = content_types[0] if content_types else None + + def adjust_normajuridica_antes_salvar(new, old): # Ajusta choice de esfera_federacao # O 'S' vem de 'Selecionar'. Na versão antiga do SAPL, quando uma opção do @@ -870,7 +826,7 @@ def adjust_autor(new, old): except Exception: with reversion.create_revision(): msg = 'Um parlamentar relacionado de PK [%s] não existia' \ - % old.cod_parlamentar + % old.cod_parlamentar reversion.set_comment('Stub criado pela migração') value = make_stub(Parlamentar, old.cod_parlamentar) descricao = 'stub criado para entrada orfã!' @@ -909,6 +865,7 @@ def adjust_comissao(new, old): AJUSTE_ANTES_SALVAR = { Autor: adjust_autor, + TipoAutor: adjust_tipo_autor, AcompanhamentoMateria: adjust_acompanhamentomateria, Comissao: adjust_comissao, DocumentoAdministrativo: adjust_documentoadministrativo, @@ -939,15 +896,15 @@ AJUSTE_DEPOIS_SALVAR = { # CHECKS #################################################################### -def get_ind_excluido(obj): - legacy_model = legacy_app.get_model(type(obj).__name__) - return getattr(legacy_model.objects.get( - **{legacy_model._meta.pk.name: obj.id}), 'ind_excluido', False) +def get_ind_excluido(new): + legacy_model = legacy_app.get_model(type(new).__name__) + old = legacy_model.objects.get(**{legacy_model._meta.pk.name: new.id}) + return getattr(old, 'ind_excluido', False) def check_app_no_ind_excluido(app): for model in app.models.values(): - assert not any(get_ind_excluido(obj) for obj in model.objects.all()) + assert not any(get_ind_excluido(new) for new in model.objects.all()) print('OK!') # MOMMY MAKE WITH LOG ###################################################### diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 36d375068..1408bd445 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -1,5 +1,6 @@ from datetime import datetime +import reversion from django.contrib.auth.models import Group from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.models import ContentType @@ -8,7 +9,6 @@ from django.db import models from django.utils import formats from django.utils.translation import ugettext_lazy as _ from model_utils import Choices -import reversion from sapl.base.models import Autor from sapl.comissoes.models import Comissao @@ -19,7 +19,6 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, SaplGenericForeignKey, SaplGenericRelation, restringe_tipos_de_arquivo_txt, texto_upload_path) - EM_TRAMITACAO = [(1, 'Sim'), (0, 'Não')] @@ -620,6 +619,10 @@ class Proposicao(models.Model): blank=True, on_delete=models.PROTECT) tipo = models.ForeignKey(TipoProposicao, on_delete=models.PROTECT, + # TODO PÓS MIGRACAO INICIAL (vide #1381) + # não nulo quando todas as + # bases tiverem sido corrigidas + null=True, verbose_name=_('Tipo')) # XXX data_envio was not null, but actual data said otherwise!!! From ecd366ee85e4d59a94ab187cbf1d8052869a1dde Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 15 Aug 2017 11:26:05 -0300 Subject: [PATCH 002/237] =?UTF-8?q?Retirado=20c=C3=B3digo=20de=20debug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index b0599bcce..6075dccee 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -18,7 +18,8 @@ from django.db.models.signals import post_delete, post_save from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make -from sapl.base.models import Argumento, Autor, Constraint, ProblemaMigracao +from sapl.base.models import (Argumento, Autor, Constraint, ProblemaMigracao, + TipoAutor) from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.legacy.models import Protocolo as ProtocoloLegado from sapl.materia.models import (AcompanhamentoMateria, DocumentoAcessorio, @@ -441,12 +442,8 @@ class DataMigrator: self.data_mudada['problema'] = problema self.data_mudada.setdefault('nome_campo', []).\ append(field.name) - if field_type in ['CharField', 'TextField'] \ - and value in [None, 'None']: - if value == 'None': - # TODO quero saber como é que pode ser 'None' !!!! - import ipdb - ipdb.set_trace() + if (field_type in ['CharField', 'TextField'] + and value in [None, 'None']): value = '' setattr(new, field.name, value) From c26cb3b5fb32b5caee285bdac161854c9a088840 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 15 Aug 2017 12:33:33 -0300 Subject: [PATCH 003/237] Ignora autor c ref a parlamentar ou comissao faltante --- sapl/legacy/migration.py | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 6075dccee..7c1311362 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -552,16 +552,16 @@ class DataMigrator: new = model() try: self.populate_renamed_fields(new, old) + if ajuste_antes_salvar: + ajuste_antes_salvar(new, old) + save(new, old) except ForeignKeyFaltando: # tentamos preencher uma FK e o ojeto relacionado não existe # então este é um objeo órfão: simplesmente ignoramos continue - - if ajuste_antes_salvar: - ajuste_antes_salvar(new, old) - save(new, old) if ajuste_depois_salvar: ajuste_depois_salvar(new, old) + if self.data_mudada: with reversion.create_revision(): save_relation(**self.data_mudada) @@ -820,32 +820,32 @@ def adjust_autor(new, old): if old.cod_parlamentar: try: new.autor_related = Parlamentar.objects.get(pk=old.cod_parlamentar) - except Exception: - with reversion.create_revision(): - msg = 'Um parlamentar relacionado de PK [%s] não existia' \ - % old.cod_parlamentar - reversion.set_comment('Stub criado pela migração') - value = make_stub(Parlamentar, old.cod_parlamentar) - descricao = 'stub criado para entrada orfã!' - warn(msg + ' => ' + descricao) - save_relation(value, [], msg, descricao, - eh_stub=True) - new.autor_related = value - new.nome = new.autor_related.nome_parlamentar + except ObjectDoesNotExist: + # ignoramos o autor órfão + raise ForeignKeyFaltando('Parlamentar inexiste para autor') + else: + new.nome = new.autor_related.nome_parlamentar elif old.cod_comissao: - new.autor_related = Comissao.objects.get(pk=old.cod_comissao) - new.nome = new.autor_related.nome + try: + new.autor_related = Comissao.objects.get(pk=old.cod_comissao) + except ObjectDoesNotExist: + # ignoramos o autor órfão + raise ForeignKeyFaltando('Comissao inexiste para autor') + else: + new.nome = new.autor_related.nome if old.col_username: - if not get_user_model().objects.filter( - username=old.col_username).exists(): - user = get_user_model()(username=old.col_username) + user_model = get_user_model() + if not user_model.objects.filter(username=old.col_username).exists(): + # cria um novo ususaŕio para o autor + user = user_model(username=old.col_username) user.set_password(12345) with reversion.create_revision(): user.save() - reversion.set_comment('Objeto criado pela migração') - + reversion.set_comment( + 'Usuário criado pela migração para o autor {}'.format( + old.cod_autor)) grupo_autor = Group.objects.get(name="Autor") user.groups.add(grupo_autor) From be55fc450ca0b1025e49f559f084e825f4e42464 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 15 Aug 2017 15:49:18 -0300 Subject: [PATCH 004/237] adicionar order_by para evitar erro no distinct Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 7c1311362..47c2c934b 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -256,7 +256,7 @@ def recria_constraints(): args_string = '' args_string += "(" + ', '.join(map(str, args)) + ")" - distintos = model.objects.distinct(*args) + distintos = model.objects.order_by(*args).distinct(*args) todos = model.objects.all() if hasattr(model, "content_type"): distintos = distintos.exclude(content_type_id=None, From b4a527ccf9831501bd62b82af00caee3c6e35b4a Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 15 Aug 2017 15:50:12 -0300 Subject: [PATCH 005/237] Muda campo status para poder aceitar valores nulos Signed-off-by: Luciano Almeida --- .../migrations/0012_auto_20170815_1238.py | 26 +++++++++++++++++++ sapl/materia/models.py | 4 +++ 2 files changed, 30 insertions(+) create mode 100644 sapl/materia/migrations/0012_auto_20170815_1238.py diff --git a/sapl/materia/migrations/0012_auto_20170815_1238.py b/sapl/materia/migrations/0012_auto_20170815_1238.py new file mode 100644 index 000000000..5f62c1670 --- /dev/null +++ b/sapl/materia/migrations/0012_auto_20170815_1238.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.12 on 2017-08-15 12:38 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0011_auto_20170808_1034'), + ] + + operations = [ + migrations.AlterField( + model_name='proposicao', + name='tipo', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='materia.TipoProposicao', verbose_name='Tipo'), + ), + migrations.AlterField( + model_name='tramitacao', + name='status', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='materia.StatusTramitacao', verbose_name='Status'), + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 1408bd445..c1cabfe18 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -846,6 +846,10 @@ class Tramitacao(models.Model): ) status = models.ForeignKey(StatusTramitacao, on_delete=models.PROTECT, + # TODO PÓS MIGRACAO INICIAL (vide #1381) + # não nulo quando todas as + # bases tiverem sido corrigidas + null=True, verbose_name=_('Status')) materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT) data_tramitacao = models.DateField(verbose_name=_('Data Tramitação')) From a6dc54f84cf78f47d82a083991955f13c928b8c9 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 15 Aug 2017 15:27:00 -0300 Subject: [PATCH 006/237] =?UTF-8?q?Reformata=20arquivo=20de=20sqls=20pr?= =?UTF-8?q?=C3=A9-migra=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 10 ++- sapl/legacy/scripts/fix_tables.sql | 109 +++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 13 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 47c2c934b..ec6188ebd 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -143,12 +143,10 @@ def get_field(model, fieldname): def exec_sql_file(path, db='default'): - cursor = connections[db].cursor() - for line in open(path): - try: - cursor.execute(line) - except (OperationalError, ProgrammingError) as e: - print("Args: '%s'" % (str(e.args))) + with open(path) as arq: + sql = arq.read() + with connections[db].cursor() as cursor: + cursor.execute(sql) def exec_sql(sql, db='default'): diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql index 1f8cdb63b..3d239e1ae 100644 --- a/sapl/legacy/scripts/fix_tables.sql +++ b/sapl/legacy/scripts/fix_tables.sql @@ -1,5 +1,6 @@ -- Apaga as restrições somente para essa sessão -SELECT REPLACE(@@sql_mode,'STRICT_TRANS_TABLES,','ALLOW_INVALID_DATES'); +SELECT replace(@@sql_mode,'STRICT_TRANS_TABLES,','ALLOW_INVALID_DATES'); + -- Exclui procedures caso já existam DROP PROCEDURE IF EXISTS verifica_campos_proposicao; DROP PROCEDURE IF EXISTS verifica_campos_tipo_materia_legislativa; @@ -7,18 +8,111 @@ DROP PROCEDURE IF EXISTS verifica_campos_sessao_plenaria_presenca; DROP PROCEDURE IF EXISTS cria_lexml_registro_provedor_e_publicador; DROP PROCEDURE IF EXISTS cria_tipo_situacao_militar; DROP PROCEDURE IF EXISTS muda_vinculo_norma_juridica_ind_excluido; + -- Procedure para criar campo num_proposicao em proposicao -CREATE PROCEDURE verifica_campos_proposicao() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='proposicao' AND column_name='num_proposicao') THEN UPDATE proposicao SET dat_envio = '1800-01-01' WHERE CAST(dat_envio AS CHAR(20)) = '0000-00-00 00:00:00'; ALTER TABLE proposicao ADD COLUMN num_proposicao INT(11) NULL after txt_justif_devolucao; END IF; END; +CREATE PROCEDURE verifica_campos_proposicao() BEGIN IF NOT EXISTS + (SELECT * + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME='proposicao' + AND COLUMN_NAME='num_proposicao') THEN +UPDATE proposicao +SET dat_envio = '1800-01-01' +WHERE cast(dat_envio AS char(20)) = '0000-00-00 00:00:00'; + ALTER TABLE proposicao ADD COLUMN num_proposicao int(11) NULL AFTER txt_justif_devolucao; +END IF; END; + -- Procedure para criar campo iind_num_automatica em tipo_materia_legislativa -CREATE PROCEDURE verifica_campos_tipo_materia_legislativa() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='tipo_materia_legislativa' AND column_name='ind_num_automatica') THEN ALTER TABLE tipo_materia_legislativa ADD COLUMN ind_num_automatica BOOLEAN NULL DEFAULT FALSE after des_tipo_materia; END IF; IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='tipo_materia_legislativa' AND column_name='quorum_minimo_votacao') THEN ALTER TABLE tipo_materia_legislativa ADD COLUMN quorum_minimo_votacao INT(11) NULL after ind_num_automatica; END IF; END; +CREATE PROCEDURE verifica_campos_tipo_materia_legislativa() +BEGIN IF NOT EXISTS + (SELECT * + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME='tipo_materia_legislativa' + AND COLUMN_NAME='ind_num_automatica') THEN +ALTER TABLE tipo_materia_legislativa ADD COLUMN ind_num_automatica BOOLEAN NULL DEFAULT FALSE AFTER des_tipo_materia; +END IF; +IF NOT EXISTS + (SELECT * + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME='tipo_materia_legislativa' + AND COLUMN_NAME='quorum_minimo_votacao') THEN +ALTER TABLE tipo_materia_legislativa ADD COLUMN quorum_minimo_votacao int(11) NULL AFTER ind_num_automatica; +END IF; END; + -- Procedure para criar campos cod_presenca_sessao (sendo a nova PK da tabela) e dat_sessao em sessao_plenaria_presenca -CREATE PROCEDURE verifica_campos_sessao_plenaria_presenca() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='sessao_plenaria_presenca' AND column_name='cod_presenca_sessao') THEN ALTER TABLE sessao_plenaria_presenca DROP PRIMARY KEY, ADD cod_presenca_sessao INT AUTO_INCREMENT PRIMARY KEY FIRST; END IF; IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='sessao_plenaria_presenca' AND column_name='dat_sessao') THEN ALTER TABLE sessao_plenaria_presenca ADD COLUMN dat_sessao DATE NULL after cod_parlamentar; END IF; END; +CREATE PROCEDURE verifica_campos_sessao_plenaria_presenca() BEGIN IF NOT EXISTS + (SELECT * + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME='sessao_plenaria_presenca' + AND COLUMN_NAME='cod_presenca_sessao') THEN +ALTER TABLE sessao_plenaria_presenca +DROP PRIMARY KEY, + ADD cod_presenca_sessao INT auto_increment PRIMARY KEY FIRST; +END IF; +IF NOT EXISTS + (SELECT * + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME='sessao_plenaria_presenca' + AND COLUMN_NAME='dat_sessao') THEN +ALTER TABLE sessao_plenaria_presenca ADD COLUMN dat_sessao DATE NULL AFTER cod_parlamentar; +END IF; END; + + -- Procedure para criar tabela lexml_registro_provedor e lexml_registro_publicador -CREATE PROCEDURE cria_lexml_registro_provedor_e_publicador() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='lexml_registro_publicador') THEN CREATE TABLE lexml_registro_publicador (cod_publicador INT AUTO_INCREMENT NOT NULL, id_publicador INT, nom_publicador VARCHAR(255), adm_email VARCHAR(50), sigla VARCHAR(255), nom_responsavel VARCHAR(255), tipo VARCHAR(50), id_responsavel INT, PRIMARY KEY (cod_publicador)); END IF; IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='lexml_registro_provedor') THEN CREATE TABLE lexml_registro_provedor (cod_provedor INT AUTO_INCREMENT NOT NULL, id_provedor INT, nom_provedor VARCHAR(255), sgl_provedor VARCHAR(15), adm_email VARCHAR(50), nom_responsavel VARCHAR(255), tipo VARCHAR(50), id_responsavel INT, xml_provedor LONGTEXT, PRIMARY KEY (cod_provedor)); END IF; END; +CREATE PROCEDURE cria_lexml_registro_provedor_e_publicador() +BEGIN IF NOT EXISTS + (SELECT * + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME='lexml_registro_publicador') THEN +CREATE TABLE lexml_registro_publicador ( + cod_publicador INT auto_increment NOT NULL, + id_publicador INT, nom_publicador varchar(255), + adm_email varchar(50), + sigla varchar(255), + nom_responsavel varchar(255), + tipo varchar(50), + id_responsavel INT, PRIMARY KEY (cod_publicador)); +END IF; +IF NOT EXISTS + (SELECT * + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME='lexml_registro_provedor') THEN +CREATE TABLE lexml_registro_provedor ( + cod_provedor INT auto_increment NOT NULL, + id_provedor INT, nom_provedor varchar(255), + sgl_provedor varchar(15), + adm_email varchar(50), + nom_responsavel varchar(255), + tipo varchar(50), + id_responsavel INT, xml_provedor longtext, + PRIMARY KEY (cod_provedor)); +END IF; END; + -- Procedure para criar tabela tipo_situacao_militar -CREATE PROCEDURE cria_tipo_situacao_militar() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='tipo_situacao_militar') THEN CREATE TABLE tipo_situacao_militar (tip_situacao_militar INT AUTO_INCREMENT NOT NULL, des_tipo_situacao VARCHAR(50), ind_excluido INT, PRIMARY KEY (tip_situacao_militar)); END IF; END; +CREATE PROCEDURE cria_tipo_situacao_militar() BEGIN IF NOT EXISTS + (SELECT * + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME='tipo_situacao_militar') THEN +CREATE TABLE tipo_situacao_militar ( + tip_situacao_militar INT auto_increment NOT NULL, + des_tipo_situacao varchar(50), + ind_excluido INT, PRIMARY KEY (tip_situacao_militar)); +END IF; END; + -- Procedure para mudar valor do campo ind_excluido da tabela vinculo_norma_juridica de 0 para string vazia '' -CREATE PROCEDURE muda_vinculo_norma_juridica_ind_excluido() BEGIN UPDATE vinculo_norma_juridica SET ind_excluido = '' WHERE trim(ind_excluido) = '0'; END; +CREATE PROCEDURE muda_vinculo_norma_juridica_ind_excluido() BEGIN +UPDATE vinculo_norma_juridica +SET ind_excluido = '' +WHERE trim(ind_excluido) = '0'; +END; + -- Executa as procedures criadas acima CALL verifica_campos_proposicao; CALL verifica_campos_tipo_materia_legislativa; @@ -26,3 +120,4 @@ CALL verifica_campos_sessao_plenaria_presenca; CALL cria_lexml_registro_provedor_e_publicador; CALL cria_tipo_situacao_militar; CALL muda_vinculo_norma_juridica_ind_excluido; + From 2381da463763b182bd7458f730215bd6da4b901d Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 15 Aug 2017 15:29:25 -0300 Subject: [PATCH 007/237] =?UTF-8?q?Corrige=20parlamentar=20zero=20em=20uni?= =?UTF-8?q?dade=20de=20tramita=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (script pré-migração) --- sapl/legacy/scripts/fix_tables.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql index 3d239e1ae..27cb39c1b 100644 --- a/sapl/legacy/scripts/fix_tables.sql +++ b/sapl/legacy/scripts/fix_tables.sql @@ -121,3 +121,5 @@ CALL cria_lexml_registro_provedor_e_publicador; CALL cria_tipo_situacao_militar; CALL muda_vinculo_norma_juridica_ind_excluido; +-- Corrige cod_parlamentar zero em unidade de tramitação +update unidade_tramitacao set cod_parlamentar = NULL where cod_parlamentar = 0; From 08da4924b0ce853a8f940e90e078b68209fabd53 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 15 Aug 2017 15:31:04 -0300 Subject: [PATCH 008/237] Ignora assuntos inexistentes em Norma --- sapl/legacy/migration.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index ec6188ebd..34c8ddc09 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -807,11 +807,15 @@ def adjust_normajuridica_antes_salvar(new, old): def adjust_normajuridica_depois_salvar(new, old): # Ajusta relação M2M - lista_pks_assunto = old.cod_assunto.split(',') - # list(filter(..)) usado para retirar strings vazias da lista - for pk_assunto in list(filter(None, lista_pks_assunto)): - new.assuntos.add(AssuntoNorma.objects.get(pk=pk_assunto)) + # lista de pks separadas por vírgulas (ignorando strings vazias) + lista_pks_assunto = [int(pk) for pk in old.cod_assunto.split(',') if pk] + + for pk_assunto in lista_pks_assunto: + try: + new.assuntos.add(AssuntoNorma.objects.get(pk=pk_assunto)) + except ObjectDoesNotExist: + pass # ignora assuntos inexistentes def adjust_autor(new, old): From 5b92aae76321c8477425353a742549a875794b5c Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 15 Aug 2017 16:32:41 -0300 Subject: [PATCH 009/237] =?UTF-8?q?Ignora=20docs=20administrativos=20orf?= =?UTF-8?q?=C3=A3os=20de=20protocolo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 34c8ddc09..05ea4a03c 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -602,27 +602,22 @@ def adjust_acompanhamentomateria(new, old): def adjust_documentoadministrativo(new, old): if new.numero_protocolo: - try: - protocolo = Protocolo.objects.get(numero=new.numero_protocolo, - ano=new.ano) - new.protocolo = protocolo - except Exception: - try: - protocolo = Protocolo.objects.get(numero=new.numero_protocolo, - ano=new.ano + 1) - new.protocolo = protocolo - except Exception: - protocolo = mommy.make(Protocolo, numero=new.numero_protocolo, - ano=new.ano) - with reversion.create_revision(): - problema = 'Protocolo Vinculado [numero_protocolo=%s, '\ - 'ano=%s] não existe' % (new.numero_protocolo, - new.ano) - descricao = 'O protocolo inexistente foi criado' - warn(problema + ' => ' + descricao) - save_relation(obj=protocolo, problema=problema, - descricao=descricao, eh_stub=True) - reversion.set_comment('Protocolo não existia.') + protocolo = Protocolo.objects.filter( + numero=new.numero_protocolo, ano=new.ano) + if not protocolo: + protocolo = Protocolo.objects.filter( + numero=new.numero_protocolo, ano=new.ano + 1) + print('PROTOCOLO ENCONTRADO APENAS PARA O ANO SEGUINTE!!!!! ' + 'DocumentoAdministrativo: {}, numero_protocolo: {}, ' + 'ano doc adm: {}'.format( + old.cod_documento, new.numero_protocolo, new.ano)) + if not protocolo: + raise ForeignKeyFaltando( + 'Protocolo {} faltando ' + '(referenciado no documento administrativo {}'.format( + new.numero_protocolo, old.cod_documento)) + assert len(protocolo) == 1 + new.protocolo = protocolo[0] def adjust_mandato(new, old): From 703162388d97ec2b040d1089af1b72cd0add2ca0 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 15 Aug 2017 17:00:09 -0300 Subject: [PATCH 010/237] Muda valores de cod_parlamentar=0 em unidade_tramitacao Signed-off-by: Luciano Almeida --- sapl/legacy/scripts/fix_tables.sql | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql index 27cb39c1b..a8862a721 100644 --- a/sapl/legacy/scripts/fix_tables.sql +++ b/sapl/legacy/scripts/fix_tables.sql @@ -8,6 +8,7 @@ DROP PROCEDURE IF EXISTS verifica_campos_sessao_plenaria_presenca; DROP PROCEDURE IF EXISTS cria_lexml_registro_provedor_e_publicador; DROP PROCEDURE IF EXISTS cria_tipo_situacao_militar; DROP PROCEDURE IF EXISTS muda_vinculo_norma_juridica_ind_excluido; +DROP PROCEDURE IF EXISTS muda_unidade_tramitacao_cod_parlamentar; -- Procedure para criar campo num_proposicao em proposicao CREATE PROCEDURE verifica_campos_proposicao() BEGIN IF NOT EXISTS @@ -113,6 +114,13 @@ SET ind_excluido = '' WHERE trim(ind_excluido) = '0'; END; +-- Procedure para mudar valor do campo cod_parlamentar da tabela unidade_tramitacao de 0 para string vazia NULL +CREATE PROCEDURE muda_unidade_tramitacao_cod_parlamentar() BEGIN +UPDATE unidade_tramitacao +SET cod_parlamentar = NULL +WHERE cod_parlamentar = 0; +END; + -- Executa as procedures criadas acima CALL verifica_campos_proposicao; CALL verifica_campos_tipo_materia_legislativa; @@ -120,6 +128,7 @@ CALL verifica_campos_sessao_plenaria_presenca; CALL cria_lexml_registro_provedor_e_publicador; CALL cria_tipo_situacao_militar; CALL muda_vinculo_norma_juridica_ind_excluido; +CALL muda_unidade_tramitacao_cod_parlamentar; -- Corrige cod_parlamentar zero em unidade de tramitação update unidade_tramitacao set cod_parlamentar = NULL where cod_parlamentar = 0; From 8aaae3f8da6bc9180bb2105ab24b4c4a5be1a5eb Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 16 Aug 2017 12:02:54 -0300 Subject: [PATCH 011/237] Atualiza unidade_tramitacao_destino para aceitar valores nulos Signed-off-by: Luciano Almeida --- .../migrations/0013_auto_20170816_1136.py | 21 +++++++++++++++++++ sapl/materia/models.py | 4 ++++ 2 files changed, 25 insertions(+) create mode 100644 sapl/materia/migrations/0013_auto_20170816_1136.py diff --git a/sapl/materia/migrations/0013_auto_20170816_1136.py b/sapl/materia/migrations/0013_auto_20170816_1136.py new file mode 100644 index 000000000..e6804e8e1 --- /dev/null +++ b/sapl/materia/migrations/0013_auto_20170816_1136.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.12 on 2017-08-16 11:36 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0012_auto_20170815_1238'), + ] + + operations = [ + migrations.AlterField( + model_name='tramitacao', + name='unidade_tramitacao_destino', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tramitacoes_destino', to='materia.UnidadeTramitacao', verbose_name='Unidade Destino'), + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index c1cabfe18..193b182da 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -862,6 +862,10 @@ class Tramitacao(models.Model): blank=True, null=True, verbose_name=_('Data Encaminhamento')) unidade_tramitacao_destino = models.ForeignKey( UnidadeTramitacao, + # TODO PÓS MIGRACAO INICIAL (vide #1381) + # não nulo quando todas as + # bases tiverem sido corrigidas + null=True, related_name='tramitacoes_destino', on_delete=models.PROTECT, verbose_name=_('Unidade Destino')) From 3a136412b7a7b35d14aeefa261418710b8b59bad Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 16 Aug 2017 11:57:11 -0300 Subject: [PATCH 012/237] Organize imports --- sapl/legacy/migration.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 05ea4a03c..6e24eb987 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -11,19 +11,16 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist -from django.db import OperationalError, ProgrammingError, connections, models -from django.db.models import CharField, Count, Max, ProtectedError, TextField +from django.db import ProgrammingError, connections, models +from django.db.models import CharField, Count, Max, TextField from django.db.models.base import ModelBase -from django.db.models.signals import post_delete, post_save from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make from sapl.base.models import (Argumento, Autor, Constraint, ProblemaMigracao, TipoAutor) from sapl.comissoes.models import Comissao, Composicao, Participacao -from sapl.legacy.models import Protocolo as ProtocoloLegado -from sapl.materia.models import (AcompanhamentoMateria, DocumentoAcessorio, - MateriaLegislativa, Proposicao, +from sapl.materia.models import (AcompanhamentoMateria, Proposicao, StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, TipoProposicao, Tramitacao) From 0445988802f4977c09c1fd1c54ffbf519fc8a73f Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 16 Aug 2017 12:27:14 -0300 Subject: [PATCH 013/237] =?UTF-8?q?Limpa=20c=C3=B3digo=20de=20exclus=C3=A3?= =?UTF-8?q?o=20de=20ind=5Fexcluido=20n=C3=A3o=20mais=20usada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 6e24eb987..e8d837ddf 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -467,19 +467,6 @@ class DataMigrator: info('Começando migração: %s...' % obj) self._do_migrate(obj) - # Itera várias vezes na lista excluindo o que for possível - info('Deletando models com ind_excluido...') - while self.delete_ind_excluido(): - pass - # Salva o que não pôde ser excluido da lista no problema da migração - for obj in self.to_delete: - msg = 'A entrada de PK %s da model %s não pode ser ' \ - 'excluida' % (obj.pk, obj._meta.model_name) - descricao = 'Um ou mais objetos protegidos' - warn(msg + ' => ' + descricao) - save_relation(obj=obj, problema=msg, - descricao=descricao, eh_stub=False) - info('Excluindo possíveis duplicações em RegistroVotacao...') excluir_registrovotacao_duplicados() From 54ef9b7fc1afae319aa3314f3b5bed790f493ffb Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 16 Aug 2017 13:09:44 -0300 Subject: [PATCH 014/237] =?UTF-8?q?Atualiza=20sql=20para=20campos=20situa?= =?UTF-8?q?=C3=A7=C3=A3o=20militar=20e=20nivel=20de=20instru=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/scripts/fix_tables.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql index a8862a721..3fa095e78 100644 --- a/sapl/legacy/scripts/fix_tables.sql +++ b/sapl/legacy/scripts/fix_tables.sql @@ -132,3 +132,5 @@ CALL muda_unidade_tramitacao_cod_parlamentar; -- Corrige cod_parlamentar zero em unidade de tramitação update unidade_tramitacao set cod_parlamentar = NULL where cod_parlamentar = 0; +update parlamentar set cod_nivel_instrucao = NULL where cod_nivel_instrucao = 0; +update parlamentar set tip_situacao_militar = NULL where tip_situacao_militar = 0; From defc00a7dd12b8a41e3a8972607a9dbc914cc8bc Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 17 Aug 2017 13:56:18 -0300 Subject: [PATCH 015/237] Corrige tabelas de mandato e relatoria Signed-off-by: Luciano Almeida --- sapl/legacy/scripts/fix_tables.sql | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql index 3fa095e78..ba1a34efc 100644 --- a/sapl/legacy/scripts/fix_tables.sql +++ b/sapl/legacy/scripts/fix_tables.sql @@ -132,5 +132,13 @@ CALL muda_unidade_tramitacao_cod_parlamentar; -- Corrige cod_parlamentar zero em unidade de tramitação update unidade_tramitacao set cod_parlamentar = NULL where cod_parlamentar = 0; + +-- Corrige cod_nivel_instrucao e tip_situacao_militar zero em parlamentar update parlamentar set cod_nivel_instrucao = NULL where cod_nivel_instrucao = 0; update parlamentar set tip_situacao_militar = NULL where tip_situacao_militar = 0; + +-- Corrige tip_afastamento zero em mandato +update mandato set tip_afastamento = NULL where tip_afastamento = 0; + +-- Corrige tip_fim_relatoria zero em relatoria +update relatoria set tip_fim_relatoria = NULL where tip_fim_relatoria = 0; From 57063e81dffd98b9ecf1be156badcc7fd26353a4 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 22 Aug 2017 13:51:19 -0300 Subject: [PATCH 016/237] Arruma problema com MateriaAssunto Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 2 +- sapl/legacy/scripts/fix_tables.sql | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index e8d837ddf..06fe7e800 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -123,7 +123,7 @@ class ForeignKeyFaltando(ObjectDoesNotExist): def get_fk_related(field, value, label=None): - if value is None: + if value is None and field.null: return value else: try: diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql index ba1a34efc..d8a71bca4 100644 --- a/sapl/legacy/scripts/fix_tables.sql +++ b/sapl/legacy/scripts/fix_tables.sql @@ -130,15 +130,15 @@ CALL cria_tipo_situacao_militar; CALL muda_vinculo_norma_juridica_ind_excluido; CALL muda_unidade_tramitacao_cod_parlamentar; --- Corrige cod_parlamentar zero em unidade de tramitação +-- Corrige cod_parlamentar igual a zero em unidade de tramitação update unidade_tramitacao set cod_parlamentar = NULL where cod_parlamentar = 0; -- Corrige cod_nivel_instrucao e tip_situacao_militar zero em parlamentar update parlamentar set cod_nivel_instrucao = NULL where cod_nivel_instrucao = 0; update parlamentar set tip_situacao_militar = NULL where tip_situacao_militar = 0; --- Corrige tip_afastamento zero em mandato +-- Corrige tip_afastamento igual a zero em mandato update mandato set tip_afastamento = NULL where tip_afastamento = 0; --- Corrige tip_fim_relatoria zero em relatoria +-- Corrige tip_fim_relatoria igual a zero em relatoria update relatoria set tip_fim_relatoria = NULL where tip_fim_relatoria = 0; From d9006c85bee4aef138be15864b497d363205e339 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 4 Sep 2017 16:59:10 -0300 Subject: [PATCH 017/237] Pin mysqlclient version --- requirements/migration-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/migration-requirements.txt b/requirements/migration-requirements.txt index 25d226602..d5793dad8 100644 --- a/requirements/migration-requirements.txt +++ b/requirements/migration-requirements.txt @@ -1,2 +1,2 @@ -r dev-requirements.txt -mysqlclient +mysqlclient==1.3.12 From 0fc1b94d743f8b2e89ecbec309717d465bce52e4 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 4 Sep 2017 17:24:38 -0300 Subject: [PATCH 018/237] =?UTF-8?q?Verifica=20se=20norma.cod=5Fassunto=20?= =?UTF-8?q?=C3=A9=20nulo=20antes=20de=20ajustar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 06fe7e800..d7744418a 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -787,6 +787,9 @@ def adjust_normajuridica_antes_salvar(new, old): def adjust_normajuridica_depois_salvar(new, old): # Ajusta relação M2M + if not old.cod_assunto: # it can be null or empty + return + # lista de pks separadas por vírgulas (ignorando strings vazias) lista_pks_assunto = [int(pk) for pk in old.cod_assunto.split(',') if pk] From 41c26979e1c40c11cc5a440821d751c387047467 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 5 Sep 2017 11:16:20 -0300 Subject: [PATCH 019/237] =?UTF-8?q?Ajusta=20depois=20de=20salvar=20apenas?= =?UTF-8?q?=20se=20n=C3=A3o=20ignorado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index d7744418a..733f4c3d4 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -536,19 +536,20 @@ class DataMigrator: self.populate_renamed_fields(new, old) if ajuste_antes_salvar: ajuste_antes_salvar(new, old) - save(new, old) except ForeignKeyFaltando: # tentamos preencher uma FK e o ojeto relacionado não existe # então este é um objeo órfão: simplesmente ignoramos continue - if ajuste_depois_salvar: - ajuste_depois_salvar(new, old) - - if self.data_mudada: - with reversion.create_revision(): - save_relation(**self.data_mudada) - self.data_mudada.clear() - reversion.set_comment('Ajuste de data pela migração') + else: + save(new, old) + if ajuste_depois_salvar: + ajuste_depois_salvar(new, old) + + if self.data_mudada: + with reversion.create_revision(): + save_relation(**self.data_mudada) + self.data_mudada.clear() + reversion.set_comment('Ajuste de data pela migração') # necessário para ajustar sequence da tabela para o ultimo valor de id ultimo_valor = get_last_value(model) From 43784ffd5065c2ea5dc010fc418edcbbb45ca0b3 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 4 Sep 2017 19:48:56 -0300 Subject: [PATCH 020/237] Apaga registros migrados --- sapl/legacy/migration.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 733f4c3d4..fdd05899d 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -395,6 +395,21 @@ def excluir_registrovotacao_duplicados(): assert 0 +def delete_old(legacy_model, cols_values): + + def eq_clause(col, value): + if value is None: + return '{} IS NULL'.format(col) + else: + return '{}="{}"'.format(col, value) + + delete_sql = 'delete from {} where {}'.format( + legacy_model._meta.db_table, + ' and '.join([eq_clause(col, value) + for col, value in cols_values.items()])) + exec_sql(delete_sql, 'legacy') + + class DataMigrator: def __init__(self): @@ -513,14 +528,22 @@ class DataMigrator: with reversion.create_revision(): new.save() reversion.set_comment('Objeto criado pela migração') + + # apaga registro do legado + delete_old(legacy_model, old.__dict__) + old_records = iter_sql_records( 'select * from ' + legacy_model._meta.db_table, 'legacy') else: def save(new, old): with reversion.create_revision(): - save_with_id(new, getattr(old, legacy_pk_name)) + pk_value = getattr(old, legacy_pk_name) + save_with_id(new, pk_value) reversion.set_comment('Objeto criado pela migração') + # apaga registro do legado + delete_old(legacy_model, {legacy_pk_name: pk_value}) + old_records = legacy_model.objects.all().order_by(legacy_pk_name) ajuste_antes_salvar = AJUSTE_ANTES_SALVAR.get(model) From c0227e6ed4361fc7d2ac7cd98852383142adb69c Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 5 Sep 2017 14:15:23 -0300 Subject: [PATCH 021/237] Novo release: 3.1.21-BETA --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7a13998d9..69123ab5c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ sapldb: ports: - "5532:5432" sapl: - image: interlegis/sapl:3.1.20-BETA + image: interlegis/sapl:3.1.21-BETA volumes: - sapl_data:/var/interlegis/sapl/data - sapl_media:/var/interlegis/sapl/media From 9144ff69995b25c59a9ad441554c920247885276 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 5 Sep 2017 16:56:55 -0300 Subject: [PATCH 022/237] Fix #1435 (#1454) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove código desnecessário e faz ajustes na lógica * Melhorias no codigo do Painel --- sapl/painel/views.py | 303 +++++++------------------------ sapl/templates/painel/index.html | 67 +++---- 2 files changed, 90 insertions(+), 280 deletions(-) diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 3183c61db..1b1678833 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -16,7 +16,7 @@ from sapl.parlamentares.models import Filiacao, Votante from sapl.sessao.models import (ExpedienteMateria, OrdemDia, PresencaOrdemDia, RegistroVotacao, SessaoPlenaria, SessaoPlenariaPresenca, VotoParlamentar) -from sapl.utils import get_client_ip +from sapl.utils import filiacao_data, get_client_ip, parlamentares_ativos from .models import Cronometro @@ -252,8 +252,6 @@ def get_cronometro_status(request, name): cronometro = '' return cronometro -# ##############################ORDEM DO DIA################################## - def get_materia_aberta(pk): return OrdemDia.objects.filter( @@ -261,56 +259,43 @@ def get_materia_aberta(pk): def get_presentes(pk, response, materia): - filiacao = Filiacao.objects.filter( - data_desfiliacao__isnull=True, parlamentar__ativo=True) - parlamentar_partido = {} - for f in filiacao: - parlamentar_partido[ - f.parlamentar.nome_parlamentar] = f.partido.sigla - - sessao_plenaria_presenca = SessaoPlenariaPresenca.objects.filter( + if type(materia) == OrdemDia: + presentes = PresencaOrdemDia.objects.filter( sessao_plenaria_id=pk) - presentes_sessao_plenaria = [ - p.parlamentar.nome_parlamentar for p in sessao_plenaria_presenca] - num_presentes_sessao_plen = len(presentes_sessao_plenaria) + elif type(materia) == ExpedienteMateria: + presentes = SessaoPlenariaPresenca.objects.filter( + sessao_plenaria_id=pk) - presenca_ordem_dia = PresencaOrdemDia.objects.filter( - sessao_plenaria_id=pk) - presentes_ordem_dia = [] - for p in presenca_ordem_dia: - nome_parlamentar = p.parlamentar.nome_parlamentar - - try: - parlamentar_partido[nome_parlamentar] - except KeyError: - presentes_ordem_dia.append( - {'id': p.id, - 'nome': nome_parlamentar, - 'partido': str(_('Sem Registro')), - }) + num_presentes = len(presentes) + data_sessao = materia.sessao_plenaria.data_inicio + + presentes_list = [] + for p in presentes: + filiacao = filiacao_data(p.parlamentar, data_sessao, data_sessao) + + if not filiacao: + partido = _('Sem Registro') else: - presentes_ordem_dia.append( - {'id': p.id, - 'nome': nome_parlamentar, - 'partido': parlamentar_partido[nome_parlamentar], - }) - num_presentes_ordem_dia = len(presentes_ordem_dia) + partido = filiacao + + presentes_list.append( + {'id': p.id, + 'parlamentar_id': p.parlamentar.id, + 'nome': p.parlamentar.nome_parlamentar, + 'partido': partido, + 'voto': '' + }) if materia.tipo_votacao == 1: - tipo_votacao = str(_('Simbólica')) - response = get_votos(response, materia) + tipo_votacao = 'Simbólica' elif materia.tipo_votacao == 2: tipo_votacao = 'Nominal' - response = get_votos_nominal(response, materia) elif materia.tipo_votacao == 3: tipo_votacao = 'Secreta' - response = get_votos(response, materia) response.update({ - 'presentes_ordem_dia': presentes_ordem_dia, - 'num_presentes_ordem_dia': num_presentes_ordem_dia, - 'presentes_sessao_plenaria': presentes_sessao_plenaria, - 'num_presentes_sessao_plenaria': num_presentes_sessao_plen, + 'presentes': presentes_list, + 'num_presentes': num_presentes, 'status_painel': 'ABERTO', 'msg_painel': str(_('Votação aberta!')), 'tipo_resultado': materia.resultado, @@ -321,76 +306,11 @@ def get_presentes(pk, response, materia): return response -# ########################EXPEDIENTE############################################ - - def get_materia_expediente_aberta(pk): return ExpedienteMateria.objects.filter( sessao_plenaria_id=pk, votacao_aberta=True).last() -def get_presentes_expediente(pk, response, materia): - filiacao = Filiacao.objects.filter( - data_desfiliacao__isnull=True, parlamentar__ativo=True) - parlamentar_partido = {} - for f in filiacao: - parlamentar_partido[ - f.parlamentar.nome_parlamentar] = f.partido.sigla - - sessao_plenaria_presenca = SessaoPlenariaPresenca.objects.filter( - sessao_plenaria_id=pk) - presentes_sessao_plenaria = [ - p.parlamentar.nome_parlamentar for p in sessao_plenaria_presenca] - num_presentes_sessao_plen = len(presentes_sessao_plenaria) - - presenca_expediente = SessaoPlenariaPresenca.objects.filter( - sessao_plenaria_id=pk) - presentes_expediente = [] - for p in presenca_expediente: - nome_parlamentar = p.parlamentar.nome_parlamentar - - try: - parlamentar_partido[nome_parlamentar] - except KeyError: - presentes_expediente.append( - {'id': p.id, - 'nome': nome_parlamentar, - 'partido': str(_('Sem Registro')), - }) - else: - presentes_expediente.append( - {'id': p.id, - 'nome': nome_parlamentar, - 'partido': parlamentar_partido[nome_parlamentar], - }) - num_presentes_expediente = len(presentes_expediente) - - if materia.tipo_votacao == 1: - tipo_votacao = 'Simbólica' - response = get_votos(response, materia) - elif materia.tipo_votacao == 2: - tipo_votacao = 'Nominal' - response = get_votos_nominal(response, materia) - elif materia.tipo_votacao == 3: - tipo_votacao = 'Secreta' - response = get_votos(response, materia) - - response.update({ - 'presentes_expediente': presentes_expediente, - 'num_presentes_expediente': num_presentes_expediente, - 'presentes_sessao_plenaria': presentes_sessao_plenaria, - 'num_presentes_sessao_plenaria': num_presentes_sessao_plen, - 'status_painel': str(_('ABERTO')), - 'msg_painel': str(_('Votação aberta!')), - 'tipo_resultado': tipo_votacao, - 'observacao_materia': materia.observacao, - 'materia_legislativa_texto': str(materia.materia)}) - - return response - - -# ##########################GENERAL FUNCTIONS############################# - def response_nenhuma_materia(response): response.update({ 'status_painel': 'FECHADO', @@ -399,60 +319,10 @@ def response_nenhuma_materia(response): def get_votos(response, materia): - if materia.tipo_votacao == 1: - tipo_votacao = 'Simbólica' - elif materia.tipo_votacao == 2: - tipo_votacao = 'Nominal' - elif materia.tipo_votacao == 3: - tipo_votacao = 'Secreta' - if type(materia) == OrdemDia: registro = RegistroVotacao.objects.filter( ordem=materia, materia=materia.materia).last() - else: - registro = RegistroVotacao.objects.filter( - expediente=materia, materia=materia.materia).last() - - if registro: - total = (registro.numero_votos_sim + - registro.numero_votos_nao + - registro.numero_abstencoes) - response.update({ - 'numero_votos_sim': registro.numero_votos_sim, - 'numero_votos_nao': registro.numero_votos_nao, - 'numero_abstencoes': registro.numero_abstencoes, - 'total_votos': total, - 'tipo_votacao': tipo_votacao, - 'tipo_resultado': registro.tipo_resultado_votacao.nome, - 'natureza_resultado': registro.tipo_resultado_votacao.natureza, - }) - else: - response.update({ - 'numero_votos_sim': 0, - 'numero_votos_nao': 0, - 'numero_abstencoes': 0, - 'total_votos': 0, - 'tipo_votacao': tipo_votacao, - 'tipo_resultado': 'Ainda não foi votada.', - 'natureza_resultado': None, - }) - return response - - -def get_votos_nominal(response, materia): - votos = [] - - if materia.tipo_votacao == 1: - tipo_votacao = 'Simbólica' - elif materia.tipo_votacao == 2: - tipo_votacao = 'Nominal' - elif materia.tipo_votacao == 3: - tipo_votacao = 'Secreta' - - if type(materia) == OrdemDia: - registro = RegistroVotacao.objects.filter( - ordem=materia, materia=materia.materia).last() - else: + elif type(materia) == ExpedienteMateria: registro = RegistroVotacao.objects.filter( expediente=materia, materia=materia.materia).last() @@ -461,54 +331,34 @@ def get_votos_nominal(response, materia): 'numero_votos_sim': 0, 'numero_votos_nao': 0, 'numero_abstencoes': 0, + 'registro': None, 'total_votos': 0, - 'tipo_votacao': tipo_votacao, - 'tipo_resultado': 'Não foi votado ainda', - 'natureza_resultado': None, - 'votos': None + 'tipo_resultado': 'Ainda não foi votada.', }) else: - votos_parlamentares = VotoParlamentar.objects.filter( - votacao_id=registro.id).order_by('parlamentar__nome_parlamentar') - - filiacao = Filiacao.objects.filter( - data_desfiliacao__isnull=True, parlamentar__ativo=True) - parlamentar_partido = {} - for f in filiacao: - parlamentar_partido[ - f.parlamentar.nome_parlamentar] = f.partido.sigla - - for v in votos_parlamentares: - try: - parlamentar_partido[v.parlamentar.nome_parlamentar] - except KeyError: - votos.append({ - 'parlamentar': v.parlamentar.nome_parlamentar, - 'voto': str(v.voto), - 'partido': str(_('Sem Registro')) - }) - else: - votos.append({ - 'parlamentar': v.parlamentar.nome_parlamentar, - 'voto': str(v.voto), - 'partido': parlamentar_partido[ - v.parlamentar.nome_parlamentar] - }) - total = (registro.numero_votos_sim + registro.numero_votos_nao + registro.numero_abstencoes) + if materia.tipo_votacao == 2: + votos_parlamentares = VotoParlamentar.objects.filter( + votacao_id=registro.id).order_by('parlamentar__nome_parlamentar') + + for i, p in enumerate(response['presentes']): + try: + response['presentes'][i]['voto'] = votos_parlamentares.get( + parlamentar_id=p['parlamentar_id']).voto + except ObjectDoesNotExist: + response['presentes'][i]['voto'] = None + response.update({ 'numero_votos_sim': registro.numero_votos_sim, 'numero_votos_nao': registro.numero_votos_nao, 'numero_abstencoes': registro.numero_abstencoes, + 'registro': True, 'total_votos': total, - 'tipo_votacao': tipo_votacao, 'tipo_resultado': registro.tipo_resultado_votacao.nome, - 'natureza_resultado': registro.tipo_resultado_votacao.natureza, - 'votos': votos }) return response @@ -517,79 +367,60 @@ def get_votos_nominal(response, materia): @user_passes_test(check_permission) def get_dados_painel(request, pk): sessao = SessaoPlenaria.objects.get(id=pk) - cronometro_discurso = get_cronometro_status(request, 'discurso') - cronometro_aparte = get_cronometro_status(request, 'aparte') - cronometro_ordem = get_cronometro_status(request, 'ordem') response = { 'sessao_plenaria': str(sessao), 'sessao_plenaria_data': sessao.data_inicio.strftime('%d/%m/%Y'), 'sessao_plenaria_hora_inicio': sessao.hora_inicio, - "cronometro_aparte": cronometro_aparte, - "cronometro_discurso": cronometro_discurso, - "cronometro_ordem": cronometro_ordem, + 'cronometro_aparte': get_cronometro_status(request, 'aparte'), + 'cronometro_discurso': get_cronometro_status(request, 'discurso'), + 'cronometro_ordem': get_cronometro_status(request, 'ordem'), } ordem_dia = get_materia_aberta(pk) expediente = get_materia_expediente_aberta(pk) + # Caso tenha alguma matéria com votação aberta, ela é mostrada no painel + # com prioridade para Ordem do Dia. if ordem_dia: - return JsonResponse(get_presentes(pk, response, ordem_dia)) + return JsonResponse(get_votos( + get_presentes(pk, response, ordem_dia), + ordem_dia)) elif expediente: - return JsonResponse(get_presentes_expediente(pk, response, expediente)) + return JsonResponse(get_votos( + get_presentes(pk, response, expediente), + expediente)) - # Ultimo voto em ordem e ultimo voto em expediente + # Caso não tenha nenhuma aberta, a matéria a ser mostrada no Painel deve ser + # a última votada last_ordem_voto = RegistroVotacao.objects.filter( ordem__sessao_plenaria=sessao).last() last_expediente_voto = RegistroVotacao.objects.filter( expediente__sessao_plenaria=sessao).last() - # Ultimas materias votadas if last_ordem_voto: ultima_ordem_votada = last_ordem_voto.ordem if last_expediente_voto: ultimo_expediente_votado = last_expediente_voto.expediente - # Caso não tenha nenhuma votação aberta if last_ordem_voto or last_expediente_voto: - # Se alguma ordem E algum expediente já tiver sido votado... if last_ordem_voto and last_expediente_voto: - # Verifica se o último resultado é um uma ordem do dia - if last_ordem_voto.pk >= last_expediente_voto.pk: - if ultima_ordem_votada.tipo_votacao in [1, 3]: - return JsonResponse( - get_votos(get_presentes( - pk, response, ultima_ordem_votada), - ultima_ordem_votada)) - elif ultima_ordem_votada.tipo_votacao == 2: - return JsonResponse( - get_votos_nominal(get_presentes( - pk, response, ultima_ordem_votada), - ultima_ordem_votada)) - # Caso não seja, verifica se é um expediente - else: - if ultimo_expediente_votado.tipo_votacao in [1, 3]: - return JsonResponse( - get_votos(get_presentes_expediente( - pk, response, ultimo_expediente_votado), - ultimo_expediente_votado)) - elif ultimo_expediente_votado.tipo_votacao == 2: - return JsonResponse( - get_votos_nominal(get_presentes_expediente( - pk, response, - ultimo_expediente_votado), - ultimo_expediente_votado)) + materia = ultima_ordem_votada\ + if last_ordem_voto.pk >= last_expediente_voto.pk\ + else ultimo_expediente_votado # Caso somente um deles tenha resultado, prioriza a Ordem do Dia - if last_ordem_voto: - return JsonResponse(get_presentes( - pk, response, ultima_ordem_votada)) + elif last_ordem_voto: + materia = ultima_ordem_votada + # Caso a Ordem do dia não tenha resultado, mostra o último expediente - if last_expediente_voto: - return JsonResponse(get_presentes_expediente( - pk, response, - ultimo_expediente_votado)) + elif last_expediente_voto: + materia = ultimo_expediente_votado + + return JsonResponse(get_votos( + get_presentes(pk, response, materia), + materia)) # Retorna que não há nenhuma matéria já votada ou aberta return response_nenhuma_materia(response) diff --git a/sapl/templates/painel/index.html b/sapl/templates/painel/index.html index 85fdf3050..68e5cdf78 100644 --- a/sapl/templates/painel/index.html +++ b/sapl/templates/painel/index.html @@ -174,58 +174,37 @@ presentes.children().remove(); votacao.children().remove() + var presentes_list = data["presentes"]; + + if (presentes_list) { + presentes.append(''); + jQuery.each(presentes_list, function (index, parlamentar) { + $('#parlamentares_list').append('') + }); + presentes.append('
' + + parlamentar.nome + + ' ' + + parlamentar.partido + ' ' + + show_voto(parlamentar.voto) + '
'); + } + else{ + presentes.append(''); + $('#parlamentares_list').append( + '
A listagem de parlamentares só aparecerá quando alguma matéria estiver em votação ou já tiver sido votada.
') + presentes.append('
'); + } + if (data['materia_legislativa_texto']){ - if (data["presentes_ordem_dia"] != null) { - presentes_ordem_dia = data["presentes_ordem_dia"]; - } - else if (data["presentes_expediente"] != null){ - presentes_ordem_dia = data["presentes_expediente"] - } - presentes.append(''); - if( data["natureza_resultado"] == "A" || data["natureza_resultado"] == "R" ) { - if (data["tipo_votacao"] == "Nominal") { - jQuery.each(data["votos"], function (index, parlamentar) { - $('#parlamentares_list').append('') - }); - } - else { - jQuery.each(data["votos"], function (index, parlamentar) { - $('#parlamentares_list').append('') - }); - } - } - - else{ - jQuery.each(presentes_ordem_dia, function (index, parlamentar) { - $('#parlamentares_list').append('') - }); - } - - presentes.append('
' + - parlamentar.parlamentar + - ' ' + - parlamentar.partido + ' ' - + show_voto(parlamentar.voto) + '
' + - parlamentar.parlamentar + - ' ' + - parlamentar.partido + '
' + - parlamentar.nome + - ' ' + - parlamentar.partido + '
'); //console.debug(presentes_ordem_dia) var votacao = $("#votacao") - if (data["num_presentes_ordem_dia"] != null) { - num_presentes_ordem_dia = data["num_presentes_ordem_dia"]; - } - else if (data["num_presentes_expediente"] != null){ - num_presentes_ordem_dia = data["num_presentes_expediente"] - } + + var num_presentes = data["num_presentes"]; votacao.append("
  • Sim: " + data["numero_votos_sim"] + "
  • ") votacao.append("
  • Não: " + data["numero_votos_nao"] + "
  • ") votacao.append("
  • Abstenções: " + data["numero_abstencoes"] + "
  • ") - votacao.append("
  • Presentes: " + num_presentes_ordem_dia + "
  • ") + votacao.append("
  • Presentes: " + num_presentes + "
  • ") votacao.append("
  • Total votos: " + data["total_votos"] + "
  • ") } From 54fee5f5383fa2cbfe5680b0d886a892b131e182 Mon Sep 17 00:00:00 2001 From: Eliseu Egewarth Date: Wed, 6 Sep 2017 09:00:14 -0300 Subject: [PATCH 023/237] HOTFIX #1452 (#1458) * Ordena unidade tramitacao * Define ordering na model * HOTFIX: Corrige problema de makemigrations --merge ocasionado por git rebase Signed-off-by: Eliseu Egewarth --- .../migrations/0014_auto_20170905_0818.py | 19 +++++++++++++ sapl/materia/models.py | 1 + .../migrations/0009_auto_20170905_1617.py | 27 +++++++++++++++++++ sapl/parlamentares/models.py | 3 +++ .../migrations/0014_auto_20170905_1617.py | 23 ++++++++++++++++ sapl/sessao/models.py | 2 ++ 6 files changed, 75 insertions(+) create mode 100644 sapl/materia/migrations/0014_auto_20170905_0818.py create mode 100644 sapl/parlamentares/migrations/0009_auto_20170905_1617.py create mode 100644 sapl/sessao/migrations/0014_auto_20170905_1617.py diff --git a/sapl/materia/migrations/0014_auto_20170905_0818.py b/sapl/materia/migrations/0014_auto_20170905_0818.py new file mode 100644 index 000000000..afe266c58 --- /dev/null +++ b/sapl/materia/migrations/0014_auto_20170905_0818.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-09-05 08:18 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0013_adiciona_status_tramitacao'), + ] + + operations = [ + migrations.AlterModelOptions( + name='unidadetramitacao', + options={'ordering': ['orgao', 'comissao', 'parlamentar'], 'verbose_name': 'Unidade de Tramitação', 'verbose_name_plural': 'Unidades de Tramitação'}, + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 9c95e1c44..e244fde60 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -803,6 +803,7 @@ class UnidadeTramitacao(models.Model): class Meta: verbose_name = _('Unidade de Tramitação') verbose_name_plural = _('Unidades de Tramitação') + ordering = ['orgao','comissao','parlamentar'] def __str__(self): if self.orgao and self.comissao and self.parlamentar: diff --git a/sapl/parlamentares/migrations/0009_auto_20170905_1617.py b/sapl/parlamentares/migrations/0009_auto_20170905_1617.py new file mode 100644 index 000000000..1290f069a --- /dev/null +++ b/sapl/parlamentares/migrations/0009_auto_20170905_1617.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-09-05 16:17 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('parlamentares', '0008_adiciona_cargos_mesa'), + ] + + operations = [ + migrations.AlterModelOptions( + name='situacaomilitar', + options={'ordering': ['descricao'], 'verbose_name': 'Tipo Situação Militar', 'verbose_name_plural': 'Tipos Situações Militares'}, + ), + migrations.AlterModelOptions( + name='tipoafastamento', + options={'ordering': ['descricao'], 'verbose_name': 'Tipo de Afastamento', 'verbose_name_plural': 'Tipos de Afastamento'}, + ), + migrations.AlterModelOptions( + name='tipodependente', + options={'ordering': ['descricao'], 'verbose_name': 'Tipo de Dependente', 'verbose_name_plural': 'Tipos de Dependente'}, + ), + ] diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index db8ea8242..5d81dd33b 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -190,6 +190,7 @@ class SituacaoMilitar(models.Model): class Meta: verbose_name = _('Tipo Situação Militar') verbose_name_plural = _('Tipos Situações Militares') + ordering = ['descricao'] def __str__(self): return self.descricao @@ -360,6 +361,7 @@ class TipoDependente(models.Model): class Meta: verbose_name = _('Tipo de Dependente') verbose_name_plural = _('Tipos de Dependente') + ordering = ['descricao'] def __str__(self): return self.descricao @@ -432,6 +434,7 @@ class TipoAfastamento(models.Model): class Meta: verbose_name = _('Tipo de Afastamento') verbose_name_plural = _('Tipos de Afastamento') + ordering = ['descricao'] def __str__(self): return self.descricao diff --git a/sapl/sessao/migrations/0014_auto_20170905_1617.py b/sapl/sessao/migrations/0014_auto_20170905_1617.py new file mode 100644 index 000000000..6568001ee --- /dev/null +++ b/sapl/sessao/migrations/0014_auto_20170905_1617.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-09-05 16:17 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('sessao', '0013_merge'), + ] + + operations = [ + migrations.AlterModelOptions( + name='tipoexpediente', + options={'ordering': ['nome'], 'verbose_name': 'Tipo de Expediente', 'verbose_name_plural': 'Tipos de Expediente'}, + ), + migrations.AlterModelOptions( + name='tiposessaoplenaria', + options={'ordering': ['nome'], 'verbose_name': 'Tipo de Sessão Plenária', 'verbose_name_plural': 'Tipos de Sessão Plenária'}, + ), + ] diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index dd136d3fd..a874fb5f4 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -76,6 +76,7 @@ class TipoSessaoPlenaria(models.Model): class Meta: verbose_name = _('Tipo de Sessão Plenária') verbose_name_plural = _('Tipos de Sessão Plenária') + ordering = ['nome'] def __str__(self): return self.nome @@ -264,6 +265,7 @@ class TipoExpediente(models.Model): class Meta: verbose_name = _('Tipo de Expediente') verbose_name_plural = _('Tipos de Expediente') + ordering = ['nome'] def __str__(self): return self.nome From d4aeea3255be739bd6178625530437ff91eb1ca1 Mon Sep 17 00:00:00 2001 From: Eliseu Egewarth Date: Wed, 6 Sep 2017 09:01:13 -0300 Subject: [PATCH 024/237] =?UTF-8?q?Corrige=20implementa=C3=A7=C3=A3o=20par?= =?UTF-8?q?a=20problemas=20apontados=20na=20issue=20#1387=20(#1456)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eliseu Egewarth --- sapl/decorators.py | 27 +++++++++++++++------------ sapl/parlamentares/views.py | 12 ++++++------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/sapl/decorators.py b/sapl/decorators.py index 6bf61d81b..97f9af7a6 100644 --- a/sapl/decorators.py +++ b/sapl/decorators.py @@ -1,6 +1,8 @@ from datetime import date from functools import wraps +from django.utils.translation import ugettext_lazy as _ + def vigencia_atual(decorated_method): """ @@ -13,10 +15,7 @@ def vigencia_atual(decorated_method): """ @wraps(decorated_method) def display_atual(self): - try: - string_displayed = decorated_method(self) - except TypeError: - string_displayed = "" + string_displayed = decorated_method(self) if hasattr(self, 'data_inicio') and hasattr(self, 'data_fim'): today = date.today() @@ -24,16 +23,20 @@ def vigencia_atual(decorated_method): string_displayed = "{} {}".format( string_displayed, "(Atual)" if e_atual else "") else: - print('{} {}'.format( - "Instance does not have the attributes [{}, {}].".format( - 'data_inicio', - 'data_fim' - ), - "Decorator @{} has been disabled.".format( - vigencia_atual.__name__() - ) + instancia_sem_atributo = "{} [{}, {}].".format( + 'Instância não possui os atributos', + 'data_inicio', + 'data_fim') + + mensagem_decorator = "Decorator @{} foi desabilitado.".format( + vigencia_atual.__name__() + ) + print(_('{} {}'.format( + _(instancia_sem_atributo), + _(mensagem_decorator) ) ) + ) return string_displayed diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index fff00b775..75e1494c0 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -661,8 +661,8 @@ class MesaDiretoraView(FormView): sessoes = SessaoLegislativa.objects.filter( legislatura=legislatura).order_by("data_inicio") - today = datetime.now() - sessao_atual = sessoes.filter(data_inicio__year=today.year).first() + year = datetime.now().year + sessao_atual = sessoes.filter(data_inicio__year=year).first() mesa = sessao_atual.composicaomesa_set.all() if sessao_atual else [] @@ -716,9 +716,9 @@ def altera_field_mesa(request): # Caso a mudança tenha sido no campo legislatura, a sessão # atual deve ser a primeira daquela legislatura else: - today = datetime.now() + year = datetime.now().year try: - sessao_selecionada = sessoes.get(data_inicio__year=today.year).id + sessao_selecionada = sessoes.get(data_inicio__year=year).id except ObjectDoesNotExist: sessao_selecionada = sessoes.first().id @@ -884,8 +884,8 @@ def altera_field_mesa_public_view(request): # atual deve ser a primeira daquela legislatura else: try: - today = datetime.now() - sessao_selecionada = sessoes.get(data_inicio__year=today.year).id + year = datetime.now().year + sessao_selecionada = sessoes.get(data_inicio__year=year).id except ObjectDoesNotExist as e: sessao_selecionada = sessoes.first().id From ac03224316619049a56848f1cf79831a92d9f3a8 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 6 Sep 2017 10:36:53 -0300 Subject: [PATCH 025/237] Melhora desempenho da migracao --- sapl/legacy/migration.py | 125 +++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 56 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 733f4c3d4..634d9aaf3 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -1,5 +1,6 @@ import re from datetime import date +from functools import lru_cache from subprocess import PIPE, call import pkg_resources @@ -11,7 +12,7 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist -from django.db import ProgrammingError, connections, models +from django.db import ProgrammingError, connections, models, transaction from django.db.models import CharField, Count, Max, TextField from django.db.models.base import ModelBase from model_mommy import mommy @@ -122,17 +123,24 @@ class ForeignKeyFaltando(ObjectDoesNotExist): pass +@lru_cache() +def _get_all_ids_from_model(model): + # esta função para uso apenas em get_fk_related + return set(model.objects.values_list('id', flat=True)) + + def get_fk_related(field, value, label=None): if value is None and field.null: + return None + + # if field.related_model.objects.filter(id=value).exists(): + if value in _get_all_ids_from_model(field.related_model): return value else: - try: - return field.related_model.objects.get(id=value) - except ObjectDoesNotExist as ex: - msg = 'FK [%s] não encontrada para o valor %s (em %s %s)' % ( - field.name, value, field.model.__name__, label or '---') - warn(msg) - raise ForeignKeyFaltando(msg) + msg = 'FK [%s] não encontrada para o valor %s (em %s %s)' % ( + field.name, value, field.model.__name__, label or '---') + warn(msg) + raise ForeignKeyFaltando(msg) def get_field(model, fieldname): @@ -410,37 +418,39 @@ class DataMigrator: field_type = field.get_internal_type() if old_field_name: old_value = getattr(old, old_field_name) - if isinstance(field, models.ForeignKey): - old_type = type(old) # not necessarily a model - if hasattr(old_type, '_meta') and \ - old_type._meta.pk.name != 'id': + + if field_type == 'ForeignKey': + # not necessarily a model + if hasattr(old, '_meta') and old._meta.pk.name != 'id': label = old.pk else: label = '-- SEM PK --' + fk_field_name = '{}_id'.format(field.name) value = get_fk_related(field, old_value, label) + setattr(new, fk_field_name, value) else: value = getattr(old, old_field_name) - # TODO rever esse DateField após as mudança para datas com - # timezone - if field_type == 'DateField' and \ - not field.null and value is None: - # TODO REVER ISSO - descricao = 'A data 1111-11-11 foi colocada no lugar' - problema = 'O valor da data era nulo ou inválido' - warn("O valor do campo %s (%s) do model %s " - "era inválido => %s" % ( - field.name, field_type, - field.model.__name__, descricao)) - value = date(1111, 11, 11) - self.data_mudada['obj'] = new - self.data_mudada['descricao'] = descricao - self.data_mudada['problema'] = problema - self.data_mudada.setdefault('nome_campo', []).\ - append(field.name) - if (field_type in ['CharField', 'TextField'] - and value in [None, 'None']): - value = '' - setattr(new, field.name, value) + # TODO rever esse DateField após as mudança para datas com + # timezone + if field_type == 'DateField' and \ + not field.null and value is None: + # TODO REVER ISSO + descricao = 'A data 1111-11-11 foi colocada no lugar' + problema = 'O valor da data era nulo ou inválido' + warn("O valor do campo %s (%s) do model %s " + "era inválido => %s" % ( + field.name, field_type, + field.model.__name__, descricao)) + value = date(1111, 11, 11) + self.data_mudada['obj'] = new + self.data_mudada['descricao'] = descricao + self.data_mudada['problema'] = problema + self.data_mudada.setdefault('nome_campo', []).\ + append(field.name) + if (field_type in ['CharField', 'TextField'] + and value in [None, 'None']): + value = '' + setattr(new, field.name, value) def migrate(self, obj=appconfs, interativo=True): # warning: model/app migration order is of utmost importance @@ -527,29 +537,32 @@ class DataMigrator: ajuste_depois_salvar = AJUSTE_DEPOIS_SALVAR.get(model) # convert old records to new ones - for old in old_records: - if getattr(old, 'ind_excluido', False): - # não migramos registros marcados como excluídos - continue - new = model() - try: - self.populate_renamed_fields(new, old) - if ajuste_antes_salvar: - ajuste_antes_salvar(new, old) - except ForeignKeyFaltando: - # tentamos preencher uma FK e o ojeto relacionado não existe - # então este é um objeo órfão: simplesmente ignoramos - continue - else: - save(new, old) - if ajuste_depois_salvar: - ajuste_depois_salvar(new, old) + with transaction.atomic(): + for old in old_records: + if getattr(old, 'ind_excluido', False): + # não migramos registros marcados como excluídos + continue + new = model() + try: + self.populate_renamed_fields(new, old) + if ajuste_antes_salvar: + ajuste_antes_salvar(new, old) + except ForeignKeyFaltando: + # tentamos preencher uma FK e o ojeto relacionado + # não existe + # então este é um objeo órfão: simplesmente ignoramos + continue + else: + save(new, old) + if ajuste_depois_salvar: + ajuste_depois_salvar(new, old) - if self.data_mudada: - with reversion.create_revision(): - save_relation(**self.data_mudada) - self.data_mudada.clear() - reversion.set_comment('Ajuste de data pela migração') + if self.data_mudada: + with reversion.create_revision(): + save_relation(**self.data_mudada) + self.data_mudada.clear() + reversion.set_comment( + 'Ajuste de data pela migração') # necessário para ajustar sequence da tabela para o ultimo valor de id ultimo_valor = get_last_value(model) @@ -650,7 +663,7 @@ def adjust_parlamentar(new, old): def adjust_participacao(new, old): composicao = Composicao() - composicao.comissao, composicao.periodo = [ + composicao.comissao_id, composicao.periodo_id = [ get_fk_related(Composicao._meta.get_field(name), value) for name, value in (('comissao', old.cod_comissao), ('periodo', old.cod_periodo_comp))] From 14615b647d28474423a11cc3c708fa2a320823d8 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 6 Sep 2017 16:19:54 -0300 Subject: [PATCH 026/237] Corrige problemas de PEP 8 --- sapl/base/tests/teststub_urls.py | 6 +-- .../tests/test_tipo_texto_articulado_form.py | 3 +- sapl/decorators.py | 2 +- sapl/materia/forms.py | 11 +++-- sapl/materia/models.py | 2 +- sapl/materia/urls.py | 2 +- sapl/materia/views.py | 17 ++++---- sapl/norma/tests/test_norma.py | 4 +- sapl/norma/views.py | 2 +- sapl/painel/views.py | 14 +++---- .../parlamentares/tests/test_parlamentares.py | 2 +- sapl/parlamentares/views.py | 2 +- sapl/protocoloadm/forms.py | 5 +-- sapl/protocoloadm/tests/test_protocoloadm.py | 3 +- sapl/protocoloadm/views.py | 5 +-- sapl/test_urls.py | 40 +++++++++---------- 16 files changed, 55 insertions(+), 65 deletions(-) diff --git a/sapl/base/tests/teststub_urls.py b/sapl/base/tests/teststub_urls.py index 4ad6c6d9e..fbdcbb443 100644 --- a/sapl/base/tests/teststub_urls.py +++ b/sapl/base/tests/teststub_urls.py @@ -4,6 +4,6 @@ from django.views.generic.base import TemplateView from sapl.urls import urlpatterns as original_patterns urlpatterns = original_patterns + patterns('', url(r'^zzzz$', - TemplateView.as_view( - template_name='index.html'), - name='zzzz')) + TemplateView.as_view( + template_name='index.html'), + name='zzzz')) diff --git a/sapl/compilacao/tests/test_tipo_texto_articulado_form.py b/sapl/compilacao/tests/test_tipo_texto_articulado_form.py index e121d771f..d9db055e3 100644 --- a/sapl/compilacao/tests/test_tipo_texto_articulado_form.py +++ b/sapl/compilacao/tests/test_tipo_texto_articulado_form.py @@ -3,8 +3,7 @@ from django.utils.translation import ugettext as _ from model_mommy import mommy from sapl.compilacao import forms -from sapl.compilacao.models import (PerfilEstruturalTextoArticulado, - TipoNota) +from sapl.compilacao.models import PerfilEstruturalTextoArticulado, TipoNota from sapl.compilacao.views import choice_models_in_extenal_views diff --git a/sapl/decorators.py b/sapl/decorators.py index 97f9af7a6..0e301565c 100644 --- a/sapl/decorators.py +++ b/sapl/decorators.py @@ -34,7 +34,7 @@ def vigencia_atual(decorated_method): print(_('{} {}'.format( _(instancia_sem_atributo), _(mensagem_decorator) - ) + ) ) ) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index e2ff7f535..678264194 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1653,7 +1653,7 @@ class EtiquetaPesquisaForm(forms.Form): # Então verifica se o usuário preencheu o Incial e mas não # preencheu o Final, ou vice-versa if (not cleaned_data['data_inicial'] or - not cleaned_data['data_final']): + not cleaned_data['data_final']): raise ValidationError(_( 'Caso pesquise por data, os campos de Data Incial e ' + 'Data Final devem ser preenchidos obrigatoriamente')) @@ -1665,17 +1665,16 @@ class EtiquetaPesquisaForm(forms.Form): # O mesmo processo anterior é feito com o processo if (cleaned_data['processo_inicial'] or - cleaned_data['processo_final']): + cleaned_data['processo_final']): if (not cleaned_data['processo_inicial'] or - not cleaned_data['processo_final']): + not cleaned_data['processo_final']): raise ValidationError(_( 'Caso pesquise por número de processo, os campos de ' + 'Processo Inicial e Processo Final ' + 'devem ser preenchidos obrigatoriamente')) elif (cleaned_data['processo_final'] < cleaned_data['processo_inicial']): - raise ValidationError(_( - 'O processo final não pode ser menor que o inicial')) + raise ValidationError(_( + 'O processo final não pode ser menor que o inicial')) return cleaned_data - diff --git a/sapl/materia/models.py b/sapl/materia/models.py index e244fde60..43027bea9 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -803,7 +803,7 @@ class UnidadeTramitacao(models.Model): class Meta: verbose_name = _('Unidade de Tramitação') verbose_name_plural = _('Unidades de Tramitação') - ordering = ['orgao','comissao','parlamentar'] + ordering = ['orgao', 'comissao', 'parlamentar'] def __str__(self): if self.orgao and self.comissao and self.parlamentar: diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index e803f18e0..e0a056011 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -8,7 +8,7 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, CriarProtocoloMateriaView, DespachoInicialCrud, DocumentoAcessorioCrud, DocumentoAcessorioEmLoteView, - ImpressosView, EtiquetaPesquisaView, + EtiquetaPesquisaView, ImpressosView, LegislacaoCitadaCrud, MateriaAssuntoCrud, MateriaLegislativaCrud, MateriaLegislativaPesquisaView, MateriaTaView, diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 2d11ecf67..80e5e9a1d 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -12,7 +12,7 @@ from django.core.urlresolvers import reverse from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect -from django.template import Context, loader, RequestContext +from django.template import Context, RequestContext, loader from django.utils import formats from django.utils.translation import ugettext_lazy as _ from django.views.generic import CreateView, ListView, TemplateView, UpdateView @@ -21,6 +21,7 @@ from django.views.generic.edit import FormView from django_filters.views import FilterView import sapl +import weasyprint from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Comissao, Participacao from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT, @@ -46,11 +47,10 @@ from .email_utils import do_envia_email_confirmacao from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, AdicionarVariasAutoriasFilterSet, DespachoInicialForm, DocumentoAcessorioForm, EtiquetaPesquisaForm, - MateriaAssuntoForm, - MateriaLegislativaFilterSet, MateriaSimplificadaForm, - PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm, - RelatoriaForm, TramitacaoEmLoteFilterSet, - filtra_tramitacao_destino, + MateriaAssuntoForm, MateriaLegislativaFilterSet, + MateriaSimplificadaForm, PrimeiraTramitacaoEmLoteFilterSet, + ReceberProposicaoForm, RelatoriaForm, + TramitacaoEmLoteFilterSet, filtra_tramitacao_destino, filtra_tramitacao_destino_and_status, filtra_tramitacao_status) from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, @@ -61,8 +61,6 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, TipoProposicao, Tramitacao, UnidadeTramitacao) from .signals import tramitacao_signal -import weasyprint - AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia') OrigemCrud = Crud.build(Origem, '') @@ -1751,6 +1749,7 @@ class ImpressosView(PermissionRequiredMixin, TemplateView): template_name = 'materia/impressos/impressos.html' permission_required = ('materia.can_access_impressos', ) + def gerar_pdf_impressos(request, context): template = loader.get_template('materia/impressos/pdf.html') html = template.render(RequestContext(request, context)) @@ -1797,5 +1796,3 @@ class EtiquetaPesquisaView(PermissionRequiredMixin, FormView): context['materias'] = materias return gerar_pdf_impressos(self.request, context) - - diff --git a/sapl/norma/tests/test_norma.py b/sapl/norma/tests/test_norma.py index fa8214e58..72c27b22a 100644 --- a/sapl/norma/tests/test_norma.py +++ b/sapl/norma/tests/test_norma.py @@ -1,13 +1,11 @@ import pytest - from django.core.urlresolvers import reverse from django.utils.translation import ugettext_lazy as _ - from model_mommy import mommy from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.norma.forms import NormaJuridicaForm, NormaRelacionadaForm -from sapl.norma.models import (NormaJuridica, TipoNormaJuridica) +from sapl.norma.models import NormaJuridica, TipoNormaJuridica @pytest.mark.django_db(transaction=False) diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 28835a2a0..8e70bd8e1 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -1,4 +1,5 @@ from datetime import datetime + from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse from django.http import JsonResponse @@ -146,7 +147,6 @@ class NormaCrud(Crud): def layout_key(self): return 'NormaJuridicaCreate' - class ListView(Crud.ListView, RedirectView): def get_redirect_url(self, *args, **kwargs): diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 1b1678833..64deab910 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -261,7 +261,7 @@ def get_materia_aberta(pk): def get_presentes(pk, response, materia): if type(materia) == OrdemDia: presentes = PresencaOrdemDia.objects.filter( - sessao_plenaria_id=pk) + sessao_plenaria_id=pk) elif type(materia) == ExpedienteMateria: presentes = SessaoPlenariaPresenca.objects.filter( sessao_plenaria_id=pk) @@ -384,12 +384,12 @@ def get_dados_painel(request, pk): # com prioridade para Ordem do Dia. if ordem_dia: return JsonResponse(get_votos( - get_presentes(pk, response, ordem_dia), - ordem_dia)) + get_presentes(pk, response, ordem_dia), + ordem_dia)) elif expediente: return JsonResponse(get_votos( - get_presentes(pk, response, expediente), - expediente)) + get_presentes(pk, response, expediente), + expediente)) # Caso não tenha nenhuma aberta, a matéria a ser mostrada no Painel deve ser # a última votada @@ -407,8 +407,8 @@ def get_dados_painel(request, pk): # Se alguma ordem E algum expediente já tiver sido votado... if last_ordem_voto and last_expediente_voto: materia = ultima_ordem_votada\ - if last_ordem_voto.pk >= last_expediente_voto.pk\ - else ultimo_expediente_votado + if last_ordem_voto.pk >= last_expediente_voto.pk\ + else ultimo_expediente_votado # Caso somente um deles tenha resultado, prioriza a Ordem do Dia elif last_ordem_voto: diff --git a/sapl/parlamentares/tests/test_parlamentares.py b/sapl/parlamentares/tests/test_parlamentares.py index a10d235e5..3793d400d 100644 --- a/sapl/parlamentares/tests/test_parlamentares.py +++ b/sapl/parlamentares/tests/test_parlamentares.py @@ -3,7 +3,7 @@ from django.core.urlresolvers import reverse from django.utils.translation import ugettext_lazy as _ from model_mommy import mommy -from sapl.parlamentares.forms import (FrenteForm, LegislaturaForm, MandatoForm) +from sapl.parlamentares.forms import FrenteForm, LegislaturaForm, MandatoForm from sapl.parlamentares.models import (Dependente, Filiacao, Legislatura, Mandato, Parlamentar, Partido, TipoDependente) diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 75e1494c0..1879f5f5d 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -1,5 +1,5 @@ -from datetime import datetime import json +from datetime import datetime from django.contrib import messages from django.contrib.contenttypes.models import ContentType diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index 626c25186..aa40f9d71 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -1,5 +1,6 @@ from datetime import datetime +import django_filters from crispy_forms.bootstrap import InlineRadios from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Button, Fieldset, Layout, Submit @@ -8,10 +9,9 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import models from django.forms import ModelForm from django.utils.translation import ugettext_lazy as _ -import django_filters from sapl.base.models import Autor, TipoAutor -from sapl.crispy_layout_mixin import form_actions, to_row, SaplFormLayout +from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa, UnidadeTramitacao) from sapl.utils import (RANGE_ANOS, AnoNumeroOrderingFilter, @@ -21,7 +21,6 @@ from .models import (DocumentoAcessorioAdministrativo, DocumentoAdministrativo, Protocolo, TipoDocumentoAdministrativo, TramitacaoAdministrativo) - TIPOS_PROTOCOLO = [('0', 'Recebido'), ('1', 'Enviado'), ('', 'Ambos')] TIPOS_PROTOCOLO_CREATE = [('0', 'Recebido'), ('1', 'Enviado')] diff --git a/sapl/protocoloadm/tests/test_protocoloadm.py b/sapl/protocoloadm/tests/test_protocoloadm.py index 0ffbb5e4b..aa0da3b52 100644 --- a/sapl/protocoloadm/tests/test_protocoloadm.py +++ b/sapl/protocoloadm/tests/test_protocoloadm.py @@ -9,8 +9,7 @@ from model_mommy import mommy from sapl.materia.models import UnidadeTramitacao from sapl.protocoloadm.forms import (AnularProcoloAdmForm, DocumentoAdministrativoForm, - MateriaLegislativa, - ProtocoloDocumentForm, + MateriaLegislativa, ProtocoloDocumentForm, ProtocoloMateriaForm) from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, StatusTramitacaoAdministrativo, diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 043333323..82de1d73d 100644 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -11,9 +11,10 @@ from django.http import Http404, HttpResponse, JsonResponse from django.shortcuts import redirect from django.utils.translation import ugettext_lazy as _ from django.views.generic import CreateView, ListView -from django.views.generic.base import TemplateView, RedirectView +from django.views.generic.base import RedirectView, TemplateView from django_filters.views import FilterView +import sapl from sapl.base.models import Autor from sapl.comissoes.models import Comissao from sapl.crud.base import Crud, CrudAux, MasterDetailCrud, make_pagination @@ -21,7 +22,6 @@ from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.parlamentares.models import Legislatura, Parlamentar from sapl.protocoloadm.models import Protocolo from sapl.utils import create_barcode, get_client_ip -import sapl from .forms import (AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoFilterSet, @@ -32,7 +32,6 @@ from .models import (DocumentoAcessorioAdministrativo, DocumentoAdministrativo, StatusTramitacaoAdministrativo, TipoDocumentoAdministrativo, TramitacaoAdministrativo) - TipoDocumentoAdministrativoCrud = CrudAux.build( TipoDocumentoAdministrativo, '') diff --git a/sapl/test_urls.py b/sapl/test_urls.py index bfccb3672..8b5207276 100644 --- a/sapl/test_urls.py +++ b/sapl/test_urls.py @@ -173,26 +173,26 @@ apps_url_patterns_prefixs_and_users = { '/ta', ]}, 'redireciona_urls': { - 'prefixs': [ - '/default_index_html', - '/consultas/parlamentar/parlamentar_', - '/consultas/comissao/comissao_', - '/consultas/pauta_sessao/pauta_sessao_', - '/consultas/sessao_plenaria/', - '/relatorios_administrativos/relatorios_administrativos_index_html', - '/tramitacaoMaterias/tramitacaoMaterias', - '/tramitacaoMaterias/materia_mostrar_proc', - '/generico/materia_pesquisar_', - '/consultas/mesa_diretora/mesa_diretora_index_html', - '/consultas/mesa_diretora/parlamentar/parlamentar_', - '/generico/norma_juridica_pesquisar_', - '/consultas/norma_juridica/norma_juridica_mostrar_proc', - '/historicoTramitacoes/historicoTramitacoes', - '/atasSessao', - '/presencaSessao', - '/resumoPropositurasAutor', - '/propositurasAnoAutorTipo', - ]}, + 'prefixs': [ + '/default_index_html', + '/consultas/parlamentar/parlamentar_', + '/consultas/comissao/comissao_', + '/consultas/pauta_sessao/pauta_sessao_', + '/consultas/sessao_plenaria/', + '/relatorios_administrativos/relatorios_administrativos_index_html', + '/tramitacaoMaterias/tramitacaoMaterias', + '/tramitacaoMaterias/materia_mostrar_proc', + '/generico/materia_pesquisar_', + '/consultas/mesa_diretora/mesa_diretora_index_html', + '/consultas/mesa_diretora/parlamentar/parlamentar_', + '/generico/norma_juridica_pesquisar_', + '/consultas/norma_juridica/norma_juridica_mostrar_proc', + '/historicoTramitacoes/historicoTramitacoes', + '/atasSessao', + '/presencaSessao', + '/resumoPropositurasAutor', + '/propositurasAnoAutorTipo', + ]}, 'lexml': { 'prefixs': [ '/lexml', From 7fd678f45f38129399bd2d84ca2b413842eef432 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 6 Sep 2017 16:21:14 -0300 Subject: [PATCH 027/237] Corrige problemas de PEP 8 --- sapl/test_urls.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sapl/test_urls.py b/sapl/test_urls.py index 8b5207276..590bbc689 100644 --- a/sapl/test_urls.py +++ b/sapl/test_urls.py @@ -179,7 +179,10 @@ apps_url_patterns_prefixs_and_users = { '/consultas/comissao/comissao_', '/consultas/pauta_sessao/pauta_sessao_', '/consultas/sessao_plenaria/', - '/relatorios_administrativos/relatorios_administrativos_index_html', + + '/relatorios_administrativos/' + 'relatorios_administrativos_index_html', + '/tramitacaoMaterias/tramitacaoMaterias', '/tramitacaoMaterias/materia_mostrar_proc', '/generico/materia_pesquisar_', From 8687b87050e9b73d120834d135c648770dbb5ea5 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 6 Sep 2017 16:55:14 -0300 Subject: [PATCH 028/237] Ajusta mais uns PEP8 --- sapl/materia/views.py | 4 ++-- sapl/norma/tests/test_norma.py | 8 +++---- sapl/painel/views.py | 4 ++-- sapl/protocoloadm/forms.py | 2 +- sapl/protocoloadm/tests/test_protocoloadm.py | 22 ++++++++++---------- sapl/sessao/tests/test_sessao.py | 10 ++++----- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 80e5e9a1d..aa5aff472 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -2,6 +2,7 @@ from datetime import datetime from random import choice from string import ascii_letters, digits +import weasyprint from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML from django.contrib import messages @@ -12,7 +13,7 @@ from django.core.urlresolvers import reverse from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect -from django.template import Context, RequestContext, loader +from django.template import RequestContext, loader from django.utils import formats from django.utils.translation import ugettext_lazy as _ from django.views.generic import CreateView, ListView, TemplateView, UpdateView @@ -21,7 +22,6 @@ from django.views.generic.edit import FormView from django_filters.views import FilterView import sapl -import weasyprint from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Comissao, Participacao from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT, diff --git a/sapl/norma/tests/test_norma.py b/sapl/norma/tests/test_norma.py index 72c27b22a..58816be48 100644 --- a/sapl/norma/tests/test_norma.py +++ b/sapl/norma/tests/test_norma.py @@ -98,10 +98,10 @@ def test_norma_juridica_materia_inexistente(): def test_norma_juridica_materia_existente(): tipo = mommy.make(TipoNormaJuridica) tipo_materia = mommy.make(TipoMateriaLegislativa) - materia = mommy.make(MateriaLegislativa, - numero=2, - ano=2017, - tipo=tipo_materia) + mommy.make(MateriaLegislativa, + numero=2, + ano=2017, + tipo=tipo_materia) form = NormaJuridicaForm(data={'tipo': str(tipo.pk), 'numero': '1', diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 64deab910..5cb707181 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -12,11 +12,11 @@ from django.utils.translation import ugettext_lazy as _ from sapl.crud.base import Crud from sapl.painel.apps import AppConfig -from sapl.parlamentares.models import Filiacao, Votante +from sapl.parlamentares.models import Votante from sapl.sessao.models import (ExpedienteMateria, OrdemDia, PresencaOrdemDia, RegistroVotacao, SessaoPlenaria, SessaoPlenariaPresenca, VotoParlamentar) -from sapl.utils import filiacao_data, get_client_ip, parlamentares_ativos +from sapl.utils import filiacao_data, get_client_ip from .models import Cronometro diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index aa40f9d71..433212094 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -3,7 +3,7 @@ from datetime import datetime import django_filters from crispy_forms.bootstrap import InlineRadios from crispy_forms.helper import FormHelper -from crispy_forms.layout import HTML, Button, Fieldset, Layout, Submit +from crispy_forms.layout import HTML, Button, Fieldset, Layout from django import forms from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import models diff --git a/sapl/protocoloadm/tests/test_protocoloadm.py b/sapl/protocoloadm/tests/test_protocoloadm.py index aa0da3b52..abf95666c 100644 --- a/sapl/protocoloadm/tests/test_protocoloadm.py +++ b/sapl/protocoloadm/tests/test_protocoloadm.py @@ -287,7 +287,7 @@ def test_anular_protocolo_form_anula_protocolo_inexistente(): @pytest.mark.django_db(transaction=False) def test_anular_protocolo_form_anula_protocolo_anulado(): - protocolo = mommy.make(Protocolo, numero=1, ano=2017, anulado=True) + mommy.make(Protocolo, numero=1, ano=2017, anulado=True) form = AnularProcoloAdmForm(data={'numero': '1', 'ano': '2017', @@ -304,15 +304,15 @@ def test_anular_protocolo_form_anula_protocolo_anulado(): def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado(): tipo_materia = mommy.make(TipoMateriaLegislativa) - protocolo_materia = mommy.make(Protocolo, - numero=1, - ano=2017, - tipo_materia=tipo_materia, - anulado=False) + mommy.make(Protocolo, + numero=1, + ano=2017, + tipo_materia=tipo_materia, + anulado=False) - materia_legislativa = mommy.make(MateriaLegislativa, - ano=2017, - numero_protocolo=1) + mommy.make(MateriaLegislativa, + ano=2017, + numero_protocolo=1) form = AnularProcoloAdmForm(data={'numero': '1', 'ano': '2017', @@ -333,8 +333,8 @@ def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado(): tipo_documento=tipo_documento, anulado=False) - documento_administrativo = mommy.make(DocumentoAdministrativo, - protocolo=protocolo_documento) + mommy.make(DocumentoAdministrativo, + protocolo=protocolo_documento) form = AnularProcoloAdmForm(data={'numero': '2', 'ano': '2017', diff --git a/sapl/sessao/tests/test_sessao.py b/sapl/sessao/tests/test_sessao.py index 7142aa48f..d92f7cabb 100644 --- a/sapl/sessao/tests/test_sessao.py +++ b/sapl/sessao/tests/test_sessao.py @@ -46,11 +46,11 @@ def test_numero_duplicado_sessao_plenaria_form(): legislatura = mommy.make(Legislatura) sessao = mommy.make(SessaoLegislativa) tipo = mommy.make(TipoSessaoPlenaria) - sessao_plenaria = mommy.make(SessaoPlenaria, - legislatura=legislatura, - sessao_legislativa=sessao, - tipo=tipo, - numero=1) + mommy.make(SessaoPlenaria, + legislatura=legislatura, + sessao_legislativa=sessao, + tipo=tipo, + numero=1) form = forms.SessaoPlenariaForm(data={'legislatura': str(legislatura.pk), 'numero': '1', From 7ef87399f6bd7178ba9514bbbc55f2c2c90f6bc1 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 6 Sep 2017 16:59:06 -0300 Subject: [PATCH 029/237] Ajusta PEP8 --- sapl/base/tests/teststub_urls.py | 10 ++++++---- sapl/painel/views.py | 7 ++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sapl/base/tests/teststub_urls.py b/sapl/base/tests/teststub_urls.py index fbdcbb443..9796768f2 100644 --- a/sapl/base/tests/teststub_urls.py +++ b/sapl/base/tests/teststub_urls.py @@ -3,7 +3,9 @@ from django.views.generic.base import TemplateView from sapl.urls import urlpatterns as original_patterns -urlpatterns = original_patterns + patterns('', url(r'^zzzz$', - TemplateView.as_view( - template_name='index.html'), - name='zzzz')) +ptrn = patterns('', + url(r'^zzzz$', + TemplateView.as_view( + template_name='index.html'), name='zzzz')) + +urlpatterns = original_patterns + ptrn diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 5cb707181..23d7f871c 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -343,7 +343,8 @@ def get_votos(response, materia): if materia.tipo_votacao == 2: votos_parlamentares = VotoParlamentar.objects.filter( - votacao_id=registro.id).order_by('parlamentar__nome_parlamentar') + votacao_id=registro.id).order_by( + 'parlamentar__nome_parlamentar') for i, p in enumerate(response['presentes']): try: @@ -391,8 +392,8 @@ def get_dados_painel(request, pk): get_presentes(pk, response, expediente), expediente)) - # Caso não tenha nenhuma aberta, a matéria a ser mostrada no Painel deve ser - # a última votada + # Caso não tenha nenhuma aberta, + # a matéria a ser mostrada no Painel deve ser a última votada last_ordem_voto = RegistroVotacao.objects.filter( ordem__sessao_plenaria=sessao).last() last_expediente_voto = RegistroVotacao.objects.filter( From d26b65345e541bf3de14d575d5cc4f58d06dc2ed Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 6 Sep 2017 17:01:42 -0300 Subject: [PATCH 030/237] Bump beautifulsoup --- requirements/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 666075b6f..11d6a2509 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -1,6 +1,6 @@ -r test-requirements.txt autopep8==1.2.4 -beautifulsoup4==4.4.1 +beautifulsoup4==4.6.0 django-debug-toolbar==1.5 ipdb==0.10.1 pip-review==0.4 From 4776d4a514fac14ac95570434e33061c04f171d3 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Fri, 8 Sep 2017 10:28:23 -0300 Subject: [PATCH 031/237] Remove unique_together de TipoProposicao --- .../migrations/0015_auto_20170908_1024.py | 37 +++++++++++++++++++ sapl/materia/models.py | 1 - 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 sapl/materia/migrations/0015_auto_20170908_1024.py diff --git a/sapl/materia/migrations/0015_auto_20170908_1024.py b/sapl/materia/migrations/0015_auto_20170908_1024.py new file mode 100644 index 000000000..3332b6504 --- /dev/null +++ b/sapl/materia/migrations/0015_auto_20170908_1024.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-09-08 10:24 +from __future__ import unicode_literals + +from django.db import migrations + +from sapl.materia.models import TipoProposicao + + +class AlterUniqueTogetherFixConstraintInexistente( + migrations.AlterUniqueTogether): + + def database_forwards(self, + app_label, schema_editor, from_state, to_state): + constraint_names = schema_editor._constraint_names( + TipoProposicao, ['content_type_id', 'object_id'], unique=True) + if constraint_names: + # por alguma razão a constraint não existe em alguns bancos + # se ela existir continua a exetução normal + super(AlterUniqueTogetherFixConstraintInexistente, + self).database_forwards( + app_label, schema_editor, from_state, to_state + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0014_auto_20170905_0818'), + ] + + operations = [ + AlterUniqueTogetherFixConstraintInexistente( + name='tipoproposicao', + unique_together=set([]), + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 43027bea9..fda53d192 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -66,7 +66,6 @@ class TipoProposicao(models.Model): class Meta: verbose_name = _('Tipo de Proposição') verbose_name_plural = _('Tipos de Proposições') - unique_together = (('content_type', 'object_id'), ) def __str__(self): return self.descricao From 22867959bb3750876b340772a13b9a28a204f7b1 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Fri, 8 Sep 2017 13:55:38 -0300 Subject: [PATCH 032/237] Fix #1460 (#1461) * Fix #1460 * Update forms.py Readiciona o operador de igualdade. --- sapl/parlamentares/forms.py | 48 +++++-------------------------------- sapl/parlamentares/views.py | 6 ++--- 2 files changed, 9 insertions(+), 45 deletions(-) diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py index 59069aca5..40a8bdb25 100644 --- a/sapl/parlamentares/forms.py +++ b/sapl/parlamentares/forms.py @@ -108,52 +108,16 @@ class LegislaturaForm(ModelForm): data_fim = data['data_fim'] data_eleicao = data['data_eleicao'] - if data_eleicao.year >= data_inicio.year: - raise ValidationError(_("Data eleição não pode ser inferior a " - "data início da legislatura")) + pk = self.instance.pk - if data_inicio > data_fim or (data_fim.year - data_inicio.year != 4): - raise ValidationError(_("Intervalo de início e fim inválido para " - "legislatura.")) - - return data - - -class LegislaturaCreateForm(LegislaturaForm): - - def clean(self): - super(LegislaturaCreateForm, self).clean() - - cleaned_data = self.cleaned_data - - if not self.is_valid(): - return cleaned_data - - eleicao = cleaned_data['data_eleicao'] - inicio = cleaned_data['data_inicio'] - fim = cleaned_data['data_fim'] - - valida_datas = validar_datas_legislatura(eleicao, inicio, fim) + valida_datas = validar_datas_legislatura(data_eleicao, + data_inicio, + data_fim, + pk=pk) if not valida_datas[0]: raise ValidationError(valida_datas[1]) - return cleaned_data - - -class LegislaturaUpdateForm(LegislaturaCreateForm): - - def clean(self): - super(LegislaturaUpdateForm, self).clean() - - cleaned_data = super(LegislaturaCreateForm, self).clean() - eleicao = cleaned_data['data_eleicao'] - inicio = cleaned_data['data_inicio'] - fim = cleaned_data['data_fim'] - valida_datas = validar_datas_legislatura( - eleicao, inicio, fim, pk=self.instance.pk) - if not valida_datas[0]: - raise ValidationError(valida_datas[1]) - return cleaned_data + return data class ParlamentarForm(ModelForm): diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 1879f5f5d..0a27e8c4e 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -25,7 +25,7 @@ from sapl.materia.models import Autoria, Proposicao, Relatoria from sapl.parlamentares.apps import AppConfig from sapl.utils import parlamentares_ativos -from .forms import (FiliacaoForm, LegislaturaCreateForm, LegislaturaUpdateForm, +from .forms import (FiliacaoForm, LegislaturaForm, MandatoForm, ParlamentarCreateForm, ParlamentarForm, VotanteForm) from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, @@ -358,7 +358,7 @@ class LegislaturaCrud(CrudAux): help_path = 'tabelas_auxiliares#legislatura' class CreateView(CrudAux.CreateView): - form_class = LegislaturaCreateForm + form_class = LegislaturaForm def get_initial(self): try: @@ -369,7 +369,7 @@ class LegislaturaCrud(CrudAux): return {'numero': numero} class UpdateView(CrudAux.UpdateView): - form_class = LegislaturaUpdateForm + form_class = LegislaturaForm class DetailView(CrudAux.DetailView): From f006cfc76e94e12cbf2fd750a9d6c53d5bd289da Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 8 Sep 2017 13:56:14 -0300 Subject: [PATCH 033/237] HOT-FIX: conserta teste de parlamentares --- sapl/parlamentares/tests/test_parlamentares.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sapl/parlamentares/tests/test_parlamentares.py b/sapl/parlamentares/tests/test_parlamentares.py index 3793d400d..ded876653 100644 --- a/sapl/parlamentares/tests/test_parlamentares.py +++ b/sapl/parlamentares/tests/test_parlamentares.py @@ -244,7 +244,8 @@ def test_legislatura_form_datas_invalidas(): assert not legislatura_form.is_valid() expected = \ - _("Data eleição não pode ser inferior a data início da legislatura") + _("A data início deve ser menor que a data fim, " + "e a data eleição deve ser menor que a data início") assert legislatura_form.errors['__all__'] == [expected] legislatura_form = LegislaturaForm(data={'numero': '1', @@ -255,8 +256,7 @@ def test_legislatura_form_datas_invalidas(): assert not legislatura_form.is_valid() - assert legislatura_form.errors['__all__'] == \ - [_("Intervalo de início e fim inválido para legislatura.")] + assert legislatura_form.errors['__all__'] == [expected] @pytest.mark.django_db(transaction=False) From 231700f823c2187394a5d4a702111ccdd9a2754b Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Sat, 9 Sep 2017 08:16:16 -0300 Subject: [PATCH 034/237] Remove delete e recria constraints --- sapl/legacy/migration.py | 104 +-------------------------------------- 1 file changed, 2 insertions(+), 102 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 634d9aaf3..87412394c 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -12,14 +12,13 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist -from django.db import ProgrammingError, connections, models, transaction +from django.db import connections, transaction from django.db.models import CharField, Count, Max, TextField from django.db.models.base import ModelBase from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make -from sapl.base.models import (Argumento, Autor, Constraint, ProblemaMigracao, - TipoAutor) +from sapl.base.models import Autor, ProblemaMigracao, TipoAutor from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.materia.models import (AcompanhamentoMateria, Proposicao, StatusTramitacao, TipoDocumento, @@ -170,44 +169,6 @@ def iter_sql_records(sql, db): record.__dict__.update(zip(fieldnames, row)) yield record -# Todos os models têm no máximo uma constraint unique together -# Isso é necessário para que o método delete_constraints funcione corretamente -assert all(len(model._meta.unique_together) <= 1 - for app in appconfs - for model in app.models.values()) - - -def delete_constraints(model): - # pega nome da unique constraint dado o nome da tabela - table = model._meta.db_table - cursor = exec_sql("SELECT conname FROM pg_constraint WHERE conrelid = " - "(SELECT oid FROM pg_class WHERE relname LIKE " - "'%s') and contype = 'u';" % (table)) - result = () - result = cursor.fetchall() - # se existir um resultado, unique constraint será deletado - for r in result: - if r[0].endswith('key'): - words_list = r[0].split('_') - constraint = Constraint.objects.create( - nome_tabela=table, nome_constraint=r[0], - nome_model=model.__name__, tipo_constraint='one_to_one') - for w in words_list: - Argumento.objects.create(constraint=constraint, argumento=w) - else: - if model._meta.unique_together: - args_list = model._meta.unique_together[0] - constraint = Constraint.objects.create( - nome_tabela=table, nome_constraint=r[0], - nome_model=model.__name__, - tipo_constraint='unique_together') - for a in args_list: - Argumento.objects.create(constraint=constraint, - argumento=a) - warn('Excluindo unique constraint de nome %s' % r[0]) - exec_sql("ALTER TABLE %s DROP CONSTRAINT %s;" % - (table, r[0])) - def problema_duplicatas(model, lista_duplicatas, argumentos): for obj in lista_duplicatas: @@ -228,62 +189,6 @@ def problema_duplicatas(model, lista_duplicatas, argumentos): reversion.set_comment('%s não é único.' % model.__name__) -def recria_constraints(): - constraints = Constraint.objects.all() - for con in constraints: - if con.tipo_constraint == 'one_to_one': - nome_tabela = con.nome_tabela - nome_constraint = con.nome_constraint - args = [a.argumento for a in con.argumento_set.all()] - args_string = '' - args_string = "(" + "_".join(map(str, args[2:-1])) + ")" - model = ContentType.objects.filter( - model=con.nome_model.lower())[0].model_class() - try: - exec_sql("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE %s;" % - (nome_tabela, nome_constraint, args_string)) - except ProgrammingError: - info('A constraint %s já foi recriada!' % nome_constraint) - if con.tipo_constraint == 'unique_together': - nome_tabela = con.nome_tabela - nome_constraint = con.nome_constraint - # Pegando explicitamente o primeiro valor do filter, - # pois pode ser que haja mais de uma ocorrência - model = ContentType.objects.filter( - model=con.nome_model.lower())[0].model_class() - args = [a.argumento for a in con.argumento_set.all()] - for i in range(len(args)): - if isinstance(model._meta.get_field(args[i]), - models.ForeignKey): - args[i] = args[i] + '_id' - args_string = '' - args_string += "(" + ', '.join(map(str, args)) + ")" - - distintos = model.objects.order_by(*args).distinct(*args) - todos = model.objects.all() - if hasattr(model, "content_type"): - distintos = distintos.exclude(content_type_id=None, - object_id=None) - todos = todos.exclude(content_type_id=None, object_id=None) - - lista_duplicatas = list(set(todos).difference(set(distintos))) - if lista_duplicatas: - problema_duplicatas(model, lista_duplicatas, args) - else: - try: - exec_sql("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE %s;" % - (nome_tabela, nome_constraint, args_string)) - except ProgrammingError: - info('A constraint %s já foi recriada!' % nome_constraint) - except Exception as err: - problema = re.findall('\(.*?\)', err.args[0]) - erro('A constraint [%s] da tabela [%s] não pode ser" \ - recriada' % (nome_constraint, nome_tabela)) - erro('Os dados %s = %s estão duplicados. ' - 'Arrume antes de recriar as constraints!' % - (problema[0], problema[1])) - - # TODO o que é isso? #################################################### def obj_desnecessario(obj): relacoes = [ @@ -484,9 +389,6 @@ class DataMigrator: while self.delete_stubs(): pass - info('Recriando constraints...') - recria_constraints() - def _do_migrate(self, obj): if isinstance(obj, AppConfig): models_to_migrate = (model for model in obj.models.values() @@ -514,8 +416,6 @@ class DataMigrator: legacy_model = legacy_app.get_model(legacy_model_name) legacy_pk_name = legacy_model._meta.pk.name - delete_constraints(model) - # setup migration strategy for tables with or without a pk if legacy_pk_name == 'id': # There is no pk in the legacy table From a06984861a23ecb31acb9355a11203ed750ddecc Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 8 Sep 2017 14:16:08 -0300 Subject: [PATCH 035/237] Fixes #1457 --- sapl/templates/parlamentares/subnav.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/sapl/templates/parlamentares/subnav.yaml b/sapl/templates/parlamentares/subnav.yaml index 07632e5ca..9199589fc 100644 --- a/sapl/templates/parlamentares/subnav.yaml +++ b/sapl/templates/parlamentares/subnav.yaml @@ -21,3 +21,4 @@ url: frente_parlamentar_list - title: {% trans 'Usuário' %} url: votante_list + check_permission: parlamentares.add_parlamentar From 3a393771fd656400f617a71563a549b03c6ef622 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 11 Sep 2017 08:36:45 -0300 Subject: [PATCH 036/237] =?UTF-8?q?Retira=20c=C3=B3digo=20desnecess=C3=A1r?= =?UTF-8?q?io?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 103 +-------------------------------------- 1 file changed, 1 insertion(+), 102 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 87412394c..d45b9ee75 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -13,10 +13,8 @@ from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.db import connections, transaction -from django.db.models import CharField, Count, Max, TextField +from django.db.models import Count, Max from django.db.models.base import ModelBase -from model_mommy import mommy -from model_mommy.mommy import foreign_key_required, make from sapl.base.models import Autor, ProblemaMigracao, TipoAutor from sapl.comissoes.models import Comissao, Composicao, Participacao @@ -113,10 +111,6 @@ def warn(msg): print('CUIDADO! ' + msg) -def erro(msg): - print('ERRO: ' + msg) - - class ForeignKeyFaltando(ObjectDoesNotExist): 'Uma FK aponta para um registro inexistente' pass @@ -142,10 +136,6 @@ def get_fk_related(field, value, label=None): raise ForeignKeyFaltando(msg) -def get_field(model, fieldname): - return model._meta.get_field(fieldname) - - def exec_sql_file(path, db='default'): with open(path) as arq: sql = arq.read() @@ -170,38 +160,6 @@ def iter_sql_records(sql, db): yield record -def problema_duplicatas(model, lista_duplicatas, argumentos): - for obj in lista_duplicatas: - pks = [] - string_pks = "" - problema = "%s de PK %s não é único." % (model.__name__, obj.pk) - args_dict = {k: obj.__dict__[k] - for k in set(argumentos) & set(obj.__dict__.keys())} - for dup in model.objects.filter(**args_dict): - pks.append(dup.pk) - string_pks = "(" + ", ".join(map(str, pks)) + ")" - descricao = "As entradas de PK %s são idênticas, mas " \ - "apenas uma deve existir" % string_pks - with reversion.create_revision(): - warn(problema + ' => ' + descricao) - save_relation(obj=obj, problema=problema, - descricao=descricao, eh_stub=False, critico=True) - reversion.set_comment('%s não é único.' % model.__name__) - - -# TODO o que é isso? #################################################### -def obj_desnecessario(obj): - relacoes = [ - f for f in obj._meta.get_fields() - if (f.one_to_many or f.one_to_one) and f.auto_created] - sem_referencia = not any(rr.related_model.objects.filter( - **{rr.field.name: obj}).exists() for rr in relacoes) - if type(obj).__name__ == 'Parlamentar' and sem_referencia and \ - obj.autor.all(): - sem_referencia = False - return sem_referencia - - def get_last_value(model): last_value = model.objects.all().aggregate(Max('pk')) return last_value['pk__max'] or 0 @@ -229,24 +187,6 @@ def save_relation(obj, nome_campo='', problema='', descricao='', link.save() -# TODO NECESSÁRIO AINDA??????????? -def make_stub(model, id): - fields_dict = get_fields_dict(model) - new = mommy.prepare(model, **fields_dict, pk=id) - save_with_id(new, id) - return new - - -def get_fields_dict(model): - all_fields = model._meta.get_fields() - fields_dict = {} - fields_dict = {f.name: '????????????'[:f.max_length] - for f in all_fields - if isinstance(f, (CharField, TextField)) and - not f.choices and not f.blank} - return fields_dict - - def fill_vinculo_norma_juridica(): lista = [('A', 'Altera o(a)', 'Alterado(a) pelo(a)'), @@ -385,10 +325,6 @@ class DataMigrator: info('Excluindo possíveis duplicações em RegistroVotacao...') excluir_registrovotacao_duplicados() - info('Deletando stubs desnecessários...') - while self.delete_stubs(): - pass - def _do_migrate(self, obj): if isinstance(obj, AppConfig): models_to_migrate = (model for model in obj.models.values() @@ -468,24 +404,6 @@ class DataMigrator: ultimo_valor = get_last_value(model) alter_sequence(model, ultimo_valor + 1) - def delete_stubs(self): - excluidos = 0 - for obj in ProblemaMigracao.objects.all(): - if obj.content_object and obj.eh_stub: - original = obj.content_type.get_all_objects_for_this_type( - id=obj.object_id) - if obj_desnecessario(original[0]): - qtd_exclusoes, *_ = original.delete() - assert qtd_exclusoes == 1 - qtd_exclusoes, *_ = obj.delete() - assert qtd_exclusoes == 1 - excluidos = excluidos + 1 - elif not obj.content_object and not obj.eh_stub: - qtd_exclusoes, *_ = obj.delete() - assert qtd_exclusoes == 1 - excluidos = excluidos + 1 - return excluidos - def migrate(obj=appconfs, interativo=True): dm = DataMigrator() @@ -547,7 +465,6 @@ def adjust_ordemdia_depois_salvar(new, old): save_relation(obj=new, problema=problema, descricao=descricao, eh_stub=False) reversion.set_comment('OrdemDia sem número da ordem.') - pass def adjust_parlamentar(new, old): @@ -801,21 +718,3 @@ def check_app_no_ind_excluido(app): for model in app.models.values(): assert not any(get_ind_excluido(new) for new in model.objects.all()) print('OK!') - -# MOMMY MAKE WITH LOG ###################################################### - - -def make_with_log(model, _quantity=None, make_m2m=False, **attrs): - last_value = get_last_value(model) - alter_sequence(model, last_value + 1) - fields_dict = get_fields_dict(model) - stub = make(model, _quantity, make_m2m, **fields_dict) - problema = 'Um stub foi necessário durante a criação de um outro stub' - descricao = 'Essa entrada é necessária para um dos stubs criados' - ' anteriormente' - warn(problema) - save_relation(obj=stub, problema=problema, - descricao=descricao, eh_stub=True) - return stub - -make_with_log.required = foreign_key_required From da4c12a392d939c086b5401e7279ad832822695b Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 11 Sep 2017 10:26:05 -0300 Subject: [PATCH 037/237] =?UTF-8?q?Desliga=20indexa=C3=A7=C3=A3o=20fulltex?= =?UTF-8?q?t=20em=20tempo=20real=20na=20migra=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy_migration_settings.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sapl/legacy_migration_settings.py b/sapl/legacy_migration_settings.py index b9d2cefc2..2501a44dc 100644 --- a/sapl/legacy_migration_settings.py +++ b/sapl/legacy_migration_settings.py @@ -28,3 +28,6 @@ DEBUG = True MOMMY_CUSTOM_FIELDS_GEN = { 'django.db.models.ForeignKey': 'sapl.legacy.migration.make_with_log' } + +# delisga indexação fulltext em tempo real +HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.BaseSignalProcessor' From 101184e746e749aebf27ffc88015f696b1394049 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 11 Sep 2017 10:46:23 -0300 Subject: [PATCH 038/237] =?UTF-8?q?Retira=20resqu=C3=ADcios=20de=20recria?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20constraints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/management/commands/recria_constraints.py | 4 +--- sapl/legacy/scripts/migra_um_db.sh | 6 ------ 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/sapl/legacy/management/commands/recria_constraints.py b/sapl/legacy/management/commands/recria_constraints.py index 9e999e5f6..d1d8d606d 100644 --- a/sapl/legacy/management/commands/recria_constraints.py +++ b/sapl/legacy/management/commands/recria_constraints.py @@ -1,7 +1,5 @@ from django.core.management.base import BaseCommand -from sapl.legacy.migration import recria_constraints - class Command(BaseCommand): @@ -9,4 +7,4 @@ class Command(BaseCommand): 'migração de dados') def handle(self, *args, **options): - recria_constraints() + pass diff --git a/sapl/legacy/scripts/migra_um_db.sh b/sapl/legacy/scripts/migra_um_db.sh index f55dfb53a..26240d8d4 100755 --- a/sapl/legacy/scripts/migra_um_db.sh +++ b/sapl/legacy/scripts/migra_um_db.sh @@ -23,9 +23,3 @@ echo "--- MIGRACAO DE DADOS ---" | tee -a $LOG echo >> $LOG DATABASE_NAME=$1 ./manage.py migracao_25_31 -f --settings sapl.legacy_migration_settings |& tee -a $LOG echo >> $LOG - - -echo "--- RECRIANDO CONSTRAINTS ---" | tee -a $LOG -echo >> $LOG -DATABASE_NAME=$1 ./manage.py recria_constraints --settings sapl.legacy_migration_settings |& tee -a $LOG -echo >> $LOG From 1d2d104b8e4f2b7737d1c2933099664849248e05 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 11 Sep 2017 16:09:56 -0300 Subject: [PATCH 039/237] =?UTF-8?q?Restringe=20an=C3=A1lise=20de=20cobertu?= =?UTF-8?q?ra=20ao=20dir=20de=20fontes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index ac3d44b96..7baf22129 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,4 +1,5 @@ [run] +source = sapl omit = sapl/wsgi.py manage.py From 157c2271d6129b833018061a85448995882f83f6 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 11 Sep 2017 16:11:04 -0300 Subject: [PATCH 040/237] Simplifica salvar com id --- sapl/legacy/migration.py | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index d45b9ee75..b03514366 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -165,20 +165,6 @@ def get_last_value(model): return last_value['pk__max'] or 0 -def alter_sequence(model, id): - sequence_name = '%s_id_seq' % model._meta.db_table - exec_sql('ALTER SEQUENCE %s RESTART WITH %s MINVALUE -1;' % ( - sequence_name, id)) - - -def save_with_id(new, id): - last_value = get_last_value(type(new)) - alter_sequence(type(new), id) - new.save() - alter_sequence(type(new), last_value + 1) - assert new.id == id, 'New id is different from provided!' - - def save_relation(obj, nome_campo='', problema='', descricao='', eh_stub=False, critico=False): link = ProblemaMigracao( @@ -364,7 +350,9 @@ class DataMigrator: else: def save(new, old): with reversion.create_revision(): - save_with_id(new, getattr(old, legacy_pk_name)) + # salva new com id de old + new.id = getattr(old, legacy_pk_name) + new.save() reversion.set_comment('Objeto criado pela migração') old_records = legacy_model.objects.all().order_by(legacy_pk_name) @@ -400,10 +388,6 @@ class DataMigrator: reversion.set_comment( 'Ajuste de data pela migração') - # necessário para ajustar sequence da tabela para o ultimo valor de id - ultimo_valor = get_last_value(model) - alter_sequence(model, ultimo_valor + 1) - def migrate(obj=appconfs, interativo=True): dm = DataMigrator() From 847a28721a7b1b86f49c590e3f7d21e44b54db62 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 11 Sep 2017 16:46:28 -0300 Subject: [PATCH 041/237] =?UTF-8?q?Criar=20usu=C3=A1rios=20padr=C3=A3o=20s?= =?UTF-8?q?omente=20de=20forma=20expl=C3=ADcita?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/rules/apps.py | 50 +++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index ab8c6322c..ad4ec1864 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -3,7 +3,6 @@ from builtins import LookupError import django import reversion from django.apps import apps -from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.management import _get_all_permissions from django.core import exceptions @@ -116,7 +115,8 @@ def create_proxy_permissions( def update_groups(app_config, verbosity=2, interactive=True, - using=DEFAULT_DB_ALIAS, **kwargs): + using=DEFAULT_DB_ALIAS, cria_usuarios_padrao=False, + **kwargs): if app_config != AppConfig and not isinstance(app_config, AppConfig): return @@ -149,41 +149,16 @@ def update_groups(app_config, verbosity=2, interactive=True, if not group_name: return - g = Group.objects.get_or_create(name=group_name) - if not isinstance(g, Group): - g = g[0] - g.permissions.clear() + group, created = Group.objects.get_or_create(name=group_name) + group.permissions.clear() try: - print(' ', group_name) for model, perms in rules_list: - self.associar(g, model, perms) + self.associar(group, model, perms) except Exception as e: print(group_name, e) - if settings.DEBUG: - user = '' - if group_name == SAPL_GROUP_ADMINISTRATIVO: - user = 'operador_administrativo' - elif group_name == SAPL_GROUP_PROTOCOLO: - user = 'operador_protocoloadm' - elif group_name == SAPL_GROUP_COMISSOES: - user = 'operador_comissoes' - elif group_name == SAPL_GROUP_MATERIA: - user = 'operador_materia' - elif group_name == SAPL_GROUP_NORMA: - user = 'operador_norma' - elif group_name == SAPL_GROUP_SESSAO: - user = 'operador_sessao' - elif group_name == SAPL_GROUP_PAINEL: - user = 'operador_painel' - elif group_name == SAPL_GROUP_GERAL: - user = 'operador_geral' - - if user: - self.cria_usuario(user, g) - def groups_add_user(self, user, groups_name): if not isinstance(groups_name, list): groups_name = [groups_name, ] @@ -213,6 +188,19 @@ def update_groups(app_config, verbosity=2, interactive=True, usuario.save() grupo.user_set.add(usuario) + def cria_usuarios_padrao(self): + for group, user in ( + (SAPL_GROUP_ADMINISTRATIVO, 'operador_administrativo'), + (SAPL_GROUP_PROTOCOLO, 'operador_protocoloadm'), + (SAPL_GROUP_COMISSOES, 'operador_comissoes'), + (SAPL_GROUP_MATERIA, 'operador_materia'), + (SAPL_GROUP_NORMA, 'operador_norma'), + (SAPL_GROUP_SESSAO, 'operador_sessao'), + (SAPL_GROUP_PAINEL, 'operador_painel'), + (SAPL_GROUP_GERAL, 'operador_geral'), + ): + self.cria_usuario(user, group) + def update_groups(self): print('') print(string_concat('\033[93m\033[1m', @@ -225,6 +213,8 @@ def update_groups(app_config, verbosity=2, interactive=True, rules = Rules(rules_patterns) rules.update_groups() + if cria_usuarios_padrao: + rules.cria_usuarios_padrao() def revision_pre_delete_signal(sender, **kwargs): From 057acefa79abbec7f5666fa4933bdf576672fc3a Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 11 Sep 2017 16:50:21 -0300 Subject: [PATCH 042/237] Roda migrate junto com comando migracao_25_31 --- sapl/legacy/management/commands/migracao_25_31.py | 2 ++ sapl/legacy/scripts/migra_um_db.sh | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/sapl/legacy/management/commands/migracao_25_31.py b/sapl/legacy/management/commands/migracao_25_31.py index bddb26a8c..c0e2fa352 100644 --- a/sapl/legacy/management/commands/migracao_25_31.py +++ b/sapl/legacy/management/commands/migracao_25_31.py @@ -1,3 +1,4 @@ +from django.core import management from django.core.management.base import BaseCommand from sapl.legacy import migration @@ -17,4 +18,5 @@ class Command(BaseCommand): ) def handle(self, *args, **options): + management.call_command('migrate') migration.migrate(interativo=not options['force']) diff --git a/sapl/legacy/scripts/migra_um_db.sh b/sapl/legacy/scripts/migra_um_db.sh index 26240d8d4..18f233414 100755 --- a/sapl/legacy/scripts/migra_um_db.sh +++ b/sapl/legacy/scripts/migra_um_db.sh @@ -14,11 +14,6 @@ echo "########################################" | tee -a $LOG echo >> $LOG -echo "--- DJANGO MIGRATE ---" | tee -a $LOG -echo >> $LOG -DATABASE_NAME=$1 ./manage.py migrate --settings sapl.legacy_migration_settings -echo >> $LOG - echo "--- MIGRACAO DE DADOS ---" | tee -a $LOG echo >> $LOG DATABASE_NAME=$1 ./manage.py migracao_25_31 -f --settings sapl.legacy_migration_settings |& tee -a $LOG From 96c61dd5cdce051252e87d93071f62be78475f0c Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 11 Sep 2017 17:16:05 -0300 Subject: [PATCH 043/237] Configura fonte de destino da migracao em .env --- sapl/legacy_migration_settings.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sapl/legacy_migration_settings.py b/sapl/legacy_migration_settings.py index 2501a44dc..221ea9d48 100644 --- a/sapl/legacy_migration_settings.py +++ b/sapl/legacy_migration_settings.py @@ -12,14 +12,18 @@ INSTALLED_APPS += ( 'sapl.legacy', # legacy reversed model definitions ) -DATABASES['legacy'] = config('DATABASE_URL', cast=db_url,) +DATABASES['legacy'] = config('DATABASE_URL_FONTE', cast=db_url,) +DATABASES['default'] = config('DATABASE_URL_DESTINO', cast=db_url, + default=DATABASES['default']) # Sobrescreve o nome dos bancos caso a variável de ambiente seja definida # Útil para migração em lote de vários bancos DATABASE_NAME_OVERRIDE = os.environ.get('DATABASE_NAME') if DATABASE_NAME_OVERRIDE: - for db in DATABASES.values(): - db['NAME'] = DATABASE_NAME_OVERRIDE + DATABASES['legacy']['NAME'] = DATABASE_NAME_OVERRIDE + # não altera o nome se o destino é um banco em memória + if not DATABASES['default']['NAME'] == ':memory:': + DATABASES['default']['NAME'] = DATABASE_NAME_OVERRIDE DATABASE_ROUTERS = ['sapl.legacy.router.LegacyRouter', ] From 63d76ec6dcbbca73f258402664ecf7f8a5a4bebf Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 12 Sep 2017 11:31:22 -0300 Subject: [PATCH 044/237] =?UTF-8?q?Ajusta=20campo=20Proposicao.tipo=20para?= =?UTF-8?q?=20obrigat=C3=B3rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/materia/models.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 8f8bdca31..28634b225 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -620,9 +620,7 @@ class Proposicao(models.Model): blank=True, on_delete=models.PROTECT) tipo = models.ForeignKey(TipoProposicao, on_delete=models.PROTECT, - # TODO PÓS MIGRACAO INICIAL (vide #1381) - # não nulo quando todas as - # bases tiverem sido corrigidas + blank=False, null=True, verbose_name=_('Tipo')) From 8e9ba6c62ac949dbb32b18c75638e035760e2c7d Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 12 Sep 2017 12:51:35 -0300 Subject: [PATCH 045/237] =?UTF-8?q?Melhoria=20no=20c=C3=B3digo=20de=20Abri?= =?UTF-8?q?r=20Mat=C3=A9ria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/urls.py | 10 +++------ sapl/sessao/views.py | 48 ++++++++++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index a28d5eb38..3edf60104 100644 --- a/sapl/sessao/urls.py +++ b/sapl/sessao/urls.py @@ -20,8 +20,7 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente, VotacaoNominalExpedienteEditView, VotacaoNominalExpedienteView, VotacaoNominalView, VotacaoView, - abrir_votacao_expediente_view, - abrir_votacao_ordem_view, atualizar_mesa, + abrir_votacao, atualizar_mesa, insere_parlamentar_composicao, mudar_ordem_materia_sessao, recuperar_materia, recuperar_numero_sessao, @@ -60,11 +59,8 @@ urlpatterns = [ url(r'^sessao/sessao-legislativa-legislatura-ajax/', sessao_legislativa_legislatura_ajax), - url(r'^sessao/(?P\d+)/(?P\d+)/abrir-votacao-expediente$', - abrir_votacao_expediente_view, - name="abrir_votacao_exp"), - url(r'^sessao/(?P\d+)/(?P\d+)/abrir-votacao-ordem$', - abrir_votacao_ordem_view, + url(r'^sessao/(?P\d+)/(?P\d+)/abrir-votacao$', + abrir_votacao, name="abrir_votacao"), url(r'^sessao/(?P\d+)/reordenar-expediente$', reordernar_materias_expediente, diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 2d8e2faea..fdf2bc6b5 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -90,7 +90,7 @@ def verifica_presenca(request, model, spk): return True -def verifica_votacoes_abertas(request, model, pk): +def verifica_votacoes_abertas(request): votacoes_abertas = SessaoPlenaria.objects.filter( Q(ordemdia__votacao_aberta=True) | Q(expedientemateria__votacao_aberta=True)).distinct() @@ -108,26 +108,36 @@ def verifica_votacoes_abertas(request, model, pk): 'outra, termine ou feche as votações abertas.') messages.add_message(request, messages.INFO, msg) - else: - materia_votacao = model.objects.get(id=pk) - materia_votacao.votacao_aberta = True - materia_votacao.save() + return False + return True -@permission_required('sessao.change_expedientemateria') -def abrir_votacao_expediente_view(request, pk, spk): - if verifica_presenca(request, SessaoPlenariaPresenca, spk): - verifica_votacoes_abertas(request, ExpedienteMateria, pk) - return HttpResponseRedirect( - reverse('sapl.sessao:expedientemateria_list', kwargs={'pk': spk})) +@permission_required('sessao.change_expedientemateria', + 'sessao.change_ordemdia') +def abrir_votacao(request, pk, spk): + model = None + + if 'tipo_materia' in request.GET: + if request.GET['tipo_materia'] == 'ordem': + model = OrdemDia + presenca_model = PresencaOrdemDia + redirect_url = 'ordemdia_list' + elif request.GET['tipo_materia'] == 'expediente': + model = ExpedienteMateria + presenca_model = SessaoPlenariaPresenca + redirect_url = 'expedientemateria_list' + if not model: + raise Http404 + + if (verifica_presenca(request, presenca_model, spk) and + verifica_votacoes_abertas(request)): + materia_votacao = model.objects.get(id=pk) + materia_votacao.votacao_aberta = True + materia_votacao.save() -@permission_required('sessao.change_ordemdia') -def abrir_votacao_ordem_view(request, pk, spk): - if verifica_presenca(request, PresencaOrdemDia, spk): - verifica_votacoes_abertas(request, OrdemDia, pk) return HttpResponseRedirect( - reverse('sapl.sessao:ordemdia_list', kwargs={'pk': spk})) + reverse('sapl.sessao:' + redirect_url, kwargs={'pk': spk})) def put_link_materia(context): @@ -243,7 +253,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): obj.resultado = '''Não há resultado''' else: url = reverse('sapl.sessao:abrir_votacao', kwargs={ - 'pk': obj.pk, 'spk': obj.sessao_plenaria_id}) + 'pk': obj.pk, 'spk': obj.sessao_plenaria_id}) + '?tipo_materia=ordem' if self.request.user.has_module_perms(AppConfig.label): btn_abrir = ''' @@ -361,8 +371,8 @@ class ExpedienteMateriaCrud(MasterDetailCrud): Registrar Votação''' % (url) obj.resultado = btn_registrar else: - url = reverse('sapl.sessao:abrir_votacao_exp', kwargs={ - 'pk': obj.pk, 'spk': obj.sessao_plenaria_id}) + url = reverse('sapl.sessao:abrir_votacao', kwargs={ + 'pk': obj.pk, 'spk': obj.sessao_plenaria_id}) + '?tipo_materia=expediente' btn_abrir = '''Matéria não votada
    ''' if self.request.user.has_module_perms(AppConfig.label): From b90341824f95bd7474ef61de7d1dd00eb699d451 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 12 Sep 2017 13:10:39 -0300 Subject: [PATCH 046/237] Fix #1433 --- sapl/sessao/views.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index fdf2bc6b5..c3775f3dd 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -113,6 +113,18 @@ def verifica_votacoes_abertas(request): return True +def verifica_sessao_iniciada(request, spk): + sessao = SessaoPlenaria.objects.get(id=spk) + + if not sessao.iniciada or sessao.finalizada: + msg = _('Não é possível abrir matérias para votação. '\ + 'Esta Sessão Plenária não foi iniciada ou está finalizada.') + messages.add_message(request, messages.INFO, msg) + return False + + return True + + @permission_required('sessao.change_expedientemateria', 'sessao.change_ordemdia') def abrir_votacao(request, pk, spk): @@ -131,7 +143,8 @@ def abrir_votacao(request, pk, spk): raise Http404 if (verifica_presenca(request, presenca_model, spk) and - verifica_votacoes_abertas(request)): + verifica_votacoes_abertas(request) and + verifica_sessao_iniciada(request, spk)): materia_votacao = model.objects.get(id=pk) materia_votacao.votacao_aberta = True materia_votacao.save() @@ -253,7 +266,9 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): obj.resultado = '''Não há resultado''' else: url = reverse('sapl.sessao:abrir_votacao', kwargs={ - 'pk': obj.pk, 'spk': obj.sessao_plenaria_id}) + '?tipo_materia=ordem' + 'pk': obj.pk, + 'spk': obj.sessao_plenaria_id + }) + '?tipo_materia=ordem' if self.request.user.has_module_perms(AppConfig.label): btn_abrir = ''' @@ -372,7 +387,9 @@ class ExpedienteMateriaCrud(MasterDetailCrud): obj.resultado = btn_registrar else: url = reverse('sapl.sessao:abrir_votacao', kwargs={ - 'pk': obj.pk, 'spk': obj.sessao_plenaria_id}) + '?tipo_materia=expediente' + 'pk': obj.pk, + 'spk': obj.sessao_plenaria_id + }) + '?tipo_materia=expediente' btn_abrir = '''Matéria não votada
    ''' if self.request.user.has_module_perms(AppConfig.label): From 8bd525606da91829c204cd00fef874af5c1efca1 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Tue, 12 Sep 2017 16:22:00 -0300 Subject: [PATCH 047/237] FIx #1436 - impressos (#1469) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Cria página de pesquisa referente a ficha * Fix #1436 * Corrige choicefield para modelfield * Fix #1436 -Adiciona teste ao form de materia -Corrige alguns erros --- sapl/materia/forms.py | 68 +++++++++ sapl/materia/tests/test_materia.py | 2 +- sapl/materia/tests/test_materia_form.py | 66 ++++++++ sapl/materia/urls.py | 9 +- sapl/materia/views.py | 91 ++++++++++- .../materia/impressos/etiqueta_pdf.html | 82 ++++++++++ sapl/templates/materia/impressos/ficha.html | 7 + .../materia/impressos/ficha_pdf.html | 144 ++++++++++++++++++ .../materia/impressos/ficha_seleciona.html | 6 + .../materia/impressos/impressos.html | 10 +- 10 files changed, 470 insertions(+), 15 deletions(-) create mode 100644 sapl/materia/tests/test_materia_form.py create mode 100644 sapl/templates/materia/impressos/etiqueta_pdf.html create mode 100644 sapl/templates/materia/impressos/ficha.html create mode 100644 sapl/templates/materia/impressos/ficha_pdf.html create mode 100644 sapl/templates/materia/impressos/ficha_seleciona.html diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 678264194..950dac3c1 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1678,3 +1678,71 @@ class EtiquetaPesquisaForm(forms.Form): 'O processo final não pode ser menor que o inicial')) return cleaned_data + + +class FichaPesquisaForm(forms.Form): + tipo_materia = forms.ModelChoiceField( + label=TipoMateriaLegislativa._meta.verbose_name, + queryset=TipoMateriaLegislativa.objects.all(), + empty_label='Selecione') + + data_inicial = forms.DateField( + label='Data Inicial', + widget=forms.DateInput(format='%d/%m/%Y') + ) + + data_final = forms.DateField( + label='Data Final', + widget=forms.DateInput(format='%d/%m/%Y') + ) + + def __init__(self, *args, **kwargs): + super(FichaPesquisaForm, self).__init__(*args, **kwargs) + + row1 = to_row( + [('tipo_materia', 6), + ('data_inicial', 3), + ('data_final', 3)]) + + self.helper = FormHelper() + self.helper.layout = Layout( + Fieldset( + ('Formulário de Ficha'), + row1, + form_actions(save_label='Pesquisar') + ) + ) + + def clean(self): + cleaned_data = super(FichaPesquisaForm, self).clean() + + if not self.is_valid(): + return cleaned_data + + if cleaned_data['data_final'] < cleaned_data['data_inicial']: + raise ValidationError(_( + 'A Data Final não pode ser menor que a Data Inicial')) + + return cleaned_data + + +class FichaSelecionaForm(forms.Form): + materia = forms.ModelChoiceField( + widget=forms.RadioSelect, + queryset=MateriaLegislativa.objects.all(), + label='') + + def __init__(self, *args, **kwargs): + super(FichaSelecionaForm, self).__init__(*args, **kwargs) + + row1 = to_row( + [('materia', 12)]) + + self.helper = FormHelper() + self.helper.layout = Layout( + Fieldset( + ('Selecione a ficha que deseja imprimir'), + row1, + form_actions(save_label='Gerar Impresso') + ) + ) diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py index 071d51d4c..39c17020b 100644 --- a/sapl/materia/tests/test_materia.py +++ b/sapl/materia/tests/test_materia.py @@ -17,7 +17,7 @@ from sapl.norma.models import (LegislacaoCitada, NormaJuridica, TipoNormaJuridica) from sapl.utils import models_with_gr_for_model - +@pytest.mark.django_db(transaction=False) def make_unidade_tramitacao(descricao): # Cria uma comissão para ser a unidade de tramitação tipo_comissao = mommy.make(TipoComissao) diff --git a/sapl/materia/tests/test_materia_form.py b/sapl/materia/tests/test_materia_form.py new file mode 100644 index 000000000..a700ee45a --- /dev/null +++ b/sapl/materia/tests/test_materia_form.py @@ -0,0 +1,66 @@ +import pytest +from django.utils.translation import ugettext as _ +from model_mommy import mommy + +from sapl.materia import forms +from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa) + +@pytest.mark.django_db(transaction=False) +def test_valida_campos_obrigatorios_ficha_pesquisa_form(): + form = forms.FichaPesquisaForm(data={}) + + assert not form.is_valid() + + errors = form.errors + + assert errors['tipo_materia'] == [_('Este campo é obrigatório.')] + assert errors['data_inicial'] == [_('Este campo é obrigatório.')] + assert errors['data_final'] == [_('Este campo é obrigatório.')] + + assert len(errors) == 3 + +@pytest.mark.django_db(transaction=False) +def test_ficha_pesquisa_form_datas_invalidas(): + tipo = mommy.make(TipoMateriaLegislativa) + + form = forms.FichaPesquisaForm(data={'tipo_materia': str(tipo.pk), + 'data_inicial': '10/11/2017', + 'data_final': '09/11/2017' + }) + assert not form.is_valid() + assert form.errors['__all__'] == [_('A Data Final não pode ser menor que ' + 'a Data Inicial')] + + +@pytest.mark.django_db(transaction=False) +def test_ficha_pesquisa_form_invalido(): + tipo = mommy.make(TipoMateriaLegislativa) + + form = forms.FichaPesquisaForm(data={'tipo_materia': str(tipo.pk), + 'data_inicial': '10/11/2017', + 'data_final': '09/11/2017' + }) + + assert not form.is_valid() + + +@pytest.mark.django_db(transaction=False) +def test_valida_campos_obrigatorios_ficha_seleciona_form(): + form = forms.FichaSelecionaForm(data={}) + + assert not form.is_valid() + + errors = form.errors + + assert errors['materia'] == [_('Este campo é obrigatório.')] + + assert len(errors) == 1 + + +@pytest.mark.django_db(transaction=False) +def test_ficha_seleciona_form_valido(): + materia = mommy.make(MateriaLegislativa) + + form = forms.FichaSelecionaForm(data={'materia': str(materia.pk)}) + + assert form.is_valid() diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index e0a056011..a59dc8592 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -8,7 +8,8 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, CriarProtocoloMateriaView, DespachoInicialCrud, DocumentoAcessorioCrud, DocumentoAcessorioEmLoteView, - EtiquetaPesquisaView, ImpressosView, + ImpressosView, EtiquetaPesquisaView, + FichaPesquisaView, FichaSelecionaView, LegislacaoCitadaCrud, MateriaAssuntoCrud, MateriaLegislativaCrud, MateriaLegislativaPesquisaView, MateriaTaView, @@ -35,6 +36,12 @@ urlpatterns_impressos = [ url(r'^materia/impressos/etiqueta-pesquisa/$', EtiquetaPesquisaView.as_view(), name='impressos_etiqueta'), + url(r'^materia/impressos/ficha-pesquisa/$', + FichaPesquisaView.as_view(), + name='impressos_ficha_pesquisa'), + url(r'^materia/impressos/ficha-seleciona/$', + FichaSelecionaView.as_view(), + name='impressos_ficha_seleciona'), ] urlpatterns_materia = [ diff --git a/sapl/materia/views.py b/sapl/materia/views.py index aa5aff472..f3aafb662 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -1,3 +1,4 @@ +import datetime as dt_generator from datetime import datetime from random import choice from string import ascii_letters, digits @@ -13,7 +14,7 @@ from django.core.urlresolvers import reverse from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect -from django.template import RequestContext, loader +from django.template import loader, RequestContext from django.utils import formats from django.utils.translation import ugettext_lazy as _ from django.views.generic import CreateView, ListView, TemplateView, UpdateView @@ -47,10 +48,11 @@ from .email_utils import do_envia_email_confirmacao from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, AdicionarVariasAutoriasFilterSet, DespachoInicialForm, DocumentoAcessorioForm, EtiquetaPesquisaForm, - MateriaAssuntoForm, MateriaLegislativaFilterSet, - MateriaSimplificadaForm, PrimeiraTramitacaoEmLoteFilterSet, - ReceberProposicaoForm, RelatoriaForm, - TramitacaoEmLoteFilterSet, filtra_tramitacao_destino, + FichaPesquisaForm, FichaSelecionaForm, MateriaAssuntoForm, + MateriaLegislativaFilterSet, MateriaSimplificadaForm, + PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm, + RelatoriaForm, TramitacaoEmLoteFilterSet, + filtra_tramitacao_destino, filtra_tramitacao_destino_and_status, filtra_tramitacao_status) from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, @@ -1750,8 +1752,8 @@ class ImpressosView(PermissionRequiredMixin, TemplateView): permission_required = ('materia.can_access_impressos', ) -def gerar_pdf_impressos(request, context): - template = loader.get_template('materia/impressos/pdf.html') +def gerar_pdf_impressos(request, context, template_name): + template = loader.get_template(template_name) html = template.render(RequestContext(request, context)) response = HttpResponse(content_type="application/pdf") weasyprint.HTML( @@ -1795,4 +1797,77 @@ class EtiquetaPesquisaView(PermissionRequiredMixin, FormView): context['materias'] = materias - return gerar_pdf_impressos(self.request, context) + return gerar_pdf_impressos(self.request, context, + 'materia/impressos/etiqueta_pdf.html') + + +class FichaPesquisaView(PermissionRequiredMixin, FormView): + form_class = FichaPesquisaForm + template_name = 'materia/impressos/ficha.html' + permission_required = ('materia.can_access_impressos', ) + + def form_valid(self, form): + tipo_materia = form.data['tipo_materia'] + data_inicial = form.data['data_inicial'] + data_final = form.data['data_final'] + + url = reverse('sapl.materia:impressos_ficha_seleciona') + url = url + '?tipo=%s&data_inicial=%s&data_final=%s' % ( + tipo_materia, data_inicial, data_final) + + return HttpResponseRedirect(url) + +class FichaSelecionaView(PermissionRequiredMixin, FormView): + form_class = FichaSelecionaForm + template_name = 'materia/impressos/ficha_seleciona.html' + permission_required = ('materia.can_access_impressos', ) + + def get_context_data(self, **kwargs): + if ('tipo' not in self.request.GET or + 'data_inicial' not in self.request.GET or + 'data_final' not in self.request.GET): + return HttpResponseRedirect(reverse( + 'sapl.materia:impressos_ficha_pesquisa')) + + context = super(FichaSelecionaView, self).get_context_data( + **kwargs) + + tipo = self.request.GET['tipo'] + data_inicial = datetime.strptime( + self.request.GET['data_inicial'], "%d/%m/%Y").date() + data_final = datetime.strptime( + self.request.GET['data_final'], "%d/%m/%Y").date() + + materia_list = MateriaLegislativa.objects.filter( + tipo=tipo, + data_apresentacao__range=(data_inicial, data_final)) + context['quantidade'] = len(materia_list) + materia_list = materia_list[:20] + + context['form'].fields['materia'].choices = [(m.id, str(m)) for m in materia_list] + + if context['quantidade'] > 20: + messages.info(self.request, _('Sua pesquisa retornou mais do que ' + '20 impressos. Por questões de performance, foram retornados ' + 'apenas os 20 primeiros. Caso queira outros, tente fazer uma ' + 'pesquisa mais específica')) + + return context + + def form_valid(self, form): + context = {} + + try: + materia = MateriaLegislativa.objects.get( + id=form.data['materia']) + except ObjectDoesNotExist: + mensagem = _('Esta Máteria não existe!') + self.messages.add_message(request, messages.INFO, mensagem) + + return self.render_to_response(context) + + context['materia'] = materia + context['despachos'] = materia.despachoinicial_set.all().values_list( + 'comissao__nome', flat=True) + + return gerar_pdf_impressos(self.request, context, 'materia/impressos/ficha_pdf.html') diff --git a/sapl/templates/materia/impressos/etiqueta_pdf.html b/sapl/templates/materia/impressos/etiqueta_pdf.html new file mode 100644 index 000000000..2f4ea2270 --- /dev/null +++ b/sapl/templates/materia/impressos/etiqueta_pdf.html @@ -0,0 +1,82 @@ + + + + + Impressos + + + + + + + +{% if quantidade > 30 %} +

    Sua pesquisa retornou mais do que 20 impressos.

    Por questões de performance, foram retornados apenas os 20 primeiros. Caso queira outros, tente fazer uma pesquisa mais específica

    +


    +{% endif %} + +{% for m in materias %} +
    + + + {% if m.numeracao_set.first %} + PROCESSO: {{ m.numeracao_set.first.numero_materia }} +   + {% else %} + PROCESSO: {{ m.numero }} +   + {% endif %} + + + {{m.tipo.sigla}}: {{m.numero}}/{{m.ano}}   + + + Pref: + {% if m.numeracao_set.first %} + {{ m.numeracao_set.first.numero_materia }} + {% endif %}
    + DATA DE ENTRADA: {{m.data_apresentacao}}
    + + + {% if m.autoria_set.all %} + Autores: + {% for a in m.autoria_set.all %} + {% if not forloop.first %} + ,    {{a.autor}} + {% else %} +  {{a.autor}} + {% endif %} + {% endfor %} +
    + {% endif %} + + + EMENTA: {{m.ementa}} + +
    + +
    +
    +
    +
    +
    + +{% endfor %} + + diff --git a/sapl/templates/materia/impressos/ficha.html b/sapl/templates/materia/impressos/ficha.html new file mode 100644 index 000000000..03d1c8580 --- /dev/null +++ b/sapl/templates/materia/impressos/ficha.html @@ -0,0 +1,7 @@ +{% extends "crud/form.html" %} +{% load i18n crispy_forms_tags %} + +{% block base_content %} +

    Impressos

    + {% crispy form %} +{% endblock base_content %} diff --git a/sapl/templates/materia/impressos/ficha_pdf.html b/sapl/templates/materia/impressos/ficha_pdf.html new file mode 100644 index 000000000..405d9a2f5 --- /dev/null +++ b/sapl/templates/materia/impressos/ficha_pdf.html @@ -0,0 +1,144 @@ + + + + + + + + + + +
    + +
    + + {% if materia.numeracao_set.first %} + PROCESSO Nº: {{ materia.numeracao_set.first.numero_materia }}

    +   + {% else %} + PROCESSO Nº: {{ materia.numero }}

    +   + {% endif %} +
    + + + {{materia.tipo}}: {{materia.numero}}/{{materia.ano}}
    + + + Data de entrada: {{materia.data_apresentacao}}
    + + + +
    +
    + + {% if materia.autoria_set.all %} + Autor: + {% for a in materia.autoria_set.all %} + {% if not forloop.first %} + {{a.autor}}
    + {% else %} + {{a.autor}}
    + {% endif %} + {% endfor %} +
    + {% endif %} +
    +
    + + +


    + + + +
    +
    + Ementa: {{materia.ementa}} +
    +
    + +


    + + +
    +
    + Despacho Inicial: + {% for despacho in despachos %} +
    {{despacho}} + {% endfor %} +
    +
    +
    +
    + ________________NORMA JURIDICA_________________

    + _________________________________________________ + +
    + + + diff --git a/sapl/templates/materia/impressos/ficha_seleciona.html b/sapl/templates/materia/impressos/ficha_seleciona.html new file mode 100644 index 000000000..818b7c3a3 --- /dev/null +++ b/sapl/templates/materia/impressos/ficha_seleciona.html @@ -0,0 +1,6 @@ +{% extends "crud/form.html" %} +{% load i18n crispy_forms_tags %} + +{% block base_content %} + {% crispy form %} +{% endblock base_content %} diff --git a/sapl/templates/materia/impressos/impressos.html b/sapl/templates/materia/impressos/impressos.html index 6f48dfddd..beb92862c 100644 --- a/sapl/templates/materia/impressos/impressos.html +++ b/sapl/templates/materia/impressos/impressos.html @@ -15,11 +15,11 @@
  • Pesquisar
  • -{#

    Ficha

    #} -{# #} -{##} +

    Ficha

    + + {#

    Guia de Remessa

    #} {#
      #} {#
    • Pesquisar
    • #} From 610ef7236789aa2e06cdfaa790dec36eb6a5a7af Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Wed, 13 Sep 2017 15:59:16 -0300 Subject: [PATCH 048/237] ref filt de autores para recup mandatos sem data_fim_mandato --- sapl/api/forms.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/sapl/api/forms.py b/sapl/api/forms.py index e9900e0c0..94bc80de4 100644 --- a/sapl/api/forms.py +++ b/sapl/api/forms.py @@ -179,18 +179,16 @@ class AutoresPossiveisFilterSet(FilterSet): data_inicio__lte=data_relativa, data_fim__gte=data_relativa).first() - params = { - 'parlamentar_set__mandato__data_inicio_mandato__lte': - data_relativa, - 'parlamentar_set__mandato__data_fim_mandato__gte': data_relativa - } + q = Q( + parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, + parlamentar_set__mandato__data_fim_mandato__isnull=True) | Q( + parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, + parlamentar_set__mandato__data_fim_mandato__gte=data_relativa) if legislatura_relativa.atual(): - params['parlamentar_set__ativo'] = True + q = q & Q(parlamentar_set__ativo=True) - qs = queryset.filter(**params) - - return qs + return queryset.filter(q) def filter_comissao(self, queryset, data_relativa): return queryset.filter( From 6959b741de03b27b4b49a43fe67180851ad17d4b Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Wed, 13 Sep 2017 18:33:05 -0300 Subject: [PATCH 049/237] Fix #1471 (#1477) --- sapl/materia/forms.py | 47 ++++++++++++++++++++++++++++--------------- sapl/materia/views.py | 6 ++++-- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 950dac3c1..909be865a 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -215,24 +215,26 @@ class TramitacaoForm(ModelForm): def __init__(self, *args, **kwargs): super(TramitacaoForm, self).__init__(*args, **kwargs) - self.fields['data_tramitacao'].initial = datetime.now() + self.fields['data_tramitacao'].initial = datetime.now().date() def clean(self): - super(TramitacaoForm, self).clean() + cleaned_data = super(TramitacaoForm, self).clean() - if 'data_encaminhamento' in self.data: - data_enc_form = self.cleaned_data['data_encaminhamento'] - if 'data_fim_prazo' in self.data: - data_prazo_form = self.cleaned_data['data_fim_prazo'] - if 'data_tramitacao' in self.data: - data_tram_form = self.cleaned_data['data_tramitacao'] + if 'data_encaminhamento' in cleaned_data: + data_enc_form = cleaned_data['data_encaminhamento'] + if 'data_fim_prazo' in cleaned_data: + data_prazo_form = cleaned_data['data_fim_prazo'] + if 'data_tramitacao' in cleaned_data: + data_tram_form = cleaned_data['data_tramitacao'] if self.errors: return self.errors ultima_tramitacao = Tramitacao.objects.filter( materia_id=self.instance.materia_id).exclude( - id=self.instance.id).last() + id=self.instance.id).order_by( + '-data_tramitacao', + '-id').first() if not self.instance.data_tramitacao: @@ -243,7 +245,7 @@ class TramitacaoForm(ModelForm): 'destino da última adicionada!') raise ValidationError(msg) - if self.cleaned_data['data_tramitacao'] > datetime.now().date(): + if cleaned_data['data_tramitacao'] > datetime.now().date(): msg = _( 'A data de tramitação deve ser ' + 'menor ou igual a data de hoje!') @@ -267,7 +269,7 @@ class TramitacaoForm(ModelForm): 'maior que a data de tramitação!') raise ValidationError(msg) - return self.cleaned_data + return cleaned_data class TramitacaoUpdateForm(TramitacaoForm): @@ -296,13 +298,26 @@ class TramitacaoUpdateForm(TramitacaoForm): } def clean(self): - super(TramitacaoUpdateForm, self).clean() + ultima_tramitacao = Tramitacao.objects.filter( + materia_id=self.instance.materia_id).order_by( + '-data_tramitacao', + '-id').first() + + # Se a Tramitação que está sendo editada não for a mais recente, + # ela não pode ter seu destino alterado. + if ultima_tramitacao != self.instance: + if self.cleaned_data['unidade_tramitacao_destino'] != \ + self.instance.unidade_tramitacao_destino: + raise ValidationError( + 'Você não pode mudar a Unidade de Destino desta '\ + 'tramitação, pois irá conflitar com a Unidade ' \ + 'Local da tramitação seguinte') - local = self.instance.unidade_tramitacao_local - data_tram = self.instance.data_tramitacao + self.cleaned_data['data_tramitacao'] = \ + self.instance.data_tramitacao + self.cleaned_data['unidade_tramitacao_local'] = \ + self.instance.unidade_tramitacao_local - self.cleaned_data['data_tramitacao'] = data_tram - self.cleaned_data['unidade_tramitacao_local'] = local return super(TramitacaoUpdateForm, self).clean() diff --git a/sapl/materia/views.py b/sapl/materia/views.py index f3aafb662..8ef6e625b 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -930,7 +930,8 @@ class TramitacaoCrud(MasterDetailCrud): def get_initial(self): local = MateriaLegislativa.objects.get( pk=self.kwargs['pk']).tramitacao_set.order_by( - '-data_tramitacao').first() + '-data_tramitacao', + '-id').first() if local: self.initial['unidade_tramitacao_local' @@ -1009,7 +1010,8 @@ class TramitacaoCrud(MasterDetailCrud): def get_queryset(self): qs = super(MasterDetailCrud.ListView, self).get_queryset() kwargs = {self.crud.parent_field: self.kwargs['pk']} - return qs.filter(**kwargs).order_by('-data_tramitacao', '-id') + return qs.filter(**kwargs).order_by('-data_tramitacao', + '-id') class DeleteView(MasterDetailCrud.DeleteView): From 74556027403d9edee3f64df7d54964c24df72f9e Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Wed, 13 Sep 2017 19:41:31 -0300 Subject: [PATCH 050/237] Fix #1474 bug iframe telas pesquisa (#1478) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #1474 * Conserta PEP8 * Melhoria no código --- sapl/base/views.py | 18 +++++++++++- sapl/materia/tests/test_materia.py | 1 + sapl/materia/tests/test_materia_form.py | 6 ++-- sapl/materia/urls.py | 4 +-- sapl/materia/views.py | 29 ++++++++++++++----- sapl/norma/views.py | 3 ++ sapl/parlamentares/views.py | 5 ++-- sapl/protocoloadm/views.py | 8 ++++- sapl/sessao/urls.py | 5 ++-- sapl/sessao/views.py | 9 ++++-- .../RelatorioHistoricoTramitacao_filter.html | 4 +-- ...latorioMateriasPorAnoAutorTipo_filter.html | 4 +-- .../RelatorioMateriasPorAutor_filter.html | 4 +-- .../base/RelatorioPresencaSessao_filter.html | 4 +-- sapl/templates/materia/em_lote/acessorio.html | 4 +-- .../templates/materia/em_lote/tramitacao.html | 4 +-- .../materia/materialegislativa_filter.html | 6 ++-- .../templates/norma/normajuridica_filter.html | 6 ++-- .../documentoadministrativo_filter.html | 6 ++-- .../protocoloadm/protocolo_filter.html | 8 ++--- .../sessao/sessaoplenaria_filter.html | 2 +- sapl/utils.py | 9 ++++++ 22 files changed, 100 insertions(+), 49 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index cae2052c9..3edc7a99c 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -23,7 +23,8 @@ from sapl.materia.models import (Autoria, MateriaLegislativa, TipoMateriaLegislativa) from sapl.sessao.models import (PresencaOrdemDia, SessaoPlenaria, SessaoPlenariaPresenca) -from sapl.utils import parlamentares_ativos, sapl_logger +from sapl.utils import (parlamentares_ativos, sapl_logger,\ + show_results_filter_set) from .forms import (CasaLegislativaForm, ConfiguracoesAppForm, RelatorioAtasFilterSet, @@ -202,6 +203,9 @@ class RelatorioAtasView(FilterView): context['object_list'] = context['object_list'].exclude(upload_ata='') qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + + context['show_results'] = show_results_filter_set(qr) + return context @@ -294,6 +298,9 @@ class RelatorioPresencaSessaoView(FilterView): # ===================================================================== qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + + context['show_results'] = show_results_filter_set(qr) + return context @@ -308,6 +315,9 @@ class RelatorioHistoricoTramitacaoView(FilterView): context['title'] = _('Histórico de Tramitações') qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + + context['show_results'] = show_results_filter_set(qr) + return context @@ -337,6 +347,8 @@ class RelatorioMateriasTramitacaoView(FilterView): qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context['show_results'] = show_results_filter_set(qr) + return context @@ -409,6 +421,8 @@ class RelatorioMateriasPorAnoAutorTipoView(FilterView): qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context['show_results'] = show_results_filter_set(qr) + if 'ano' in self.request.GET and self.request.GET['ano']: ano = int(self.request.GET['ano']) context['relatorio'] = self.get_materias_autor_ano(ano) @@ -447,6 +461,8 @@ class RelatorioMateriasPorAutorView(FilterView): qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context['show_results'] = show_results_filter_set(qr) + return context diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py index 39c17020b..c7a773a9c 100644 --- a/sapl/materia/tests/test_materia.py +++ b/sapl/materia/tests/test_materia.py @@ -17,6 +17,7 @@ from sapl.norma.models import (LegislacaoCitada, NormaJuridica, TipoNormaJuridica) from sapl.utils import models_with_gr_for_model + @pytest.mark.django_db(transaction=False) def make_unidade_tramitacao(descricao): # Cria uma comissão para ser a unidade de tramitação diff --git a/sapl/materia/tests/test_materia_form.py b/sapl/materia/tests/test_materia_form.py index a700ee45a..41ad04837 100644 --- a/sapl/materia/tests/test_materia_form.py +++ b/sapl/materia/tests/test_materia_form.py @@ -3,7 +3,8 @@ from django.utils.translation import ugettext as _ from model_mommy import mommy from sapl.materia import forms -from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa) +from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa + @pytest.mark.django_db(transaction=False) def test_valida_campos_obrigatorios_ficha_pesquisa_form(): @@ -19,6 +20,7 @@ def test_valida_campos_obrigatorios_ficha_pesquisa_form(): assert len(errors) == 3 + @pytest.mark.django_db(transaction=False) def test_ficha_pesquisa_form_datas_invalidas(): tipo = mommy.make(TipoMateriaLegislativa) @@ -29,7 +31,7 @@ def test_ficha_pesquisa_form_datas_invalidas(): }) assert not form.is_valid() assert form.errors['__all__'] == [_('A Data Final não pode ser menor que ' - 'a Data Inicial')] + 'a Data Inicial')] @pytest.mark.django_db(transaction=False) diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index a59dc8592..b6a87cd5f 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -8,8 +8,8 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, CriarProtocoloMateriaView, DespachoInicialCrud, DocumentoAcessorioCrud, DocumentoAcessorioEmLoteView, - ImpressosView, EtiquetaPesquisaView, - FichaPesquisaView, FichaSelecionaView, + EtiquetaPesquisaView, FichaPesquisaView, + FichaSelecionaView, ImpressosView, LegislacaoCitadaCrud, MateriaAssuntoCrud, MateriaLegislativaCrud, MateriaLegislativaPesquisaView, MateriaTaView, diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 8ef6e625b..9a35204b1 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -14,7 +14,7 @@ from django.core.urlresolvers import reverse from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect -from django.template import loader, RequestContext +from django.template import RequestContext, loader from django.utils import formats from django.utils.translation import ugettext_lazy as _ from django.views.generic import CreateView, ListView, TemplateView, UpdateView @@ -42,7 +42,7 @@ from sapl.norma.models import LegislacaoCitada from sapl.protocoloadm.models import Protocolo from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label, autor_modal, gerar_hash_arquivo, get_base_url, - montar_row_autor) + montar_row_autor, show_results_filter_set) from .email_utils import do_envia_email_confirmacao from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, @@ -138,6 +138,9 @@ class AdicionarVariasAutorias(PermissionRequiredForAppCrudMixin, FilterView): context['title'] = _('Pesquisar Autores') qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + + context['show_results'] = show_results_filter_set(qr) + context['pk_materia'] = self.kwargs['pk'] return context @@ -1509,6 +1512,8 @@ class MateriaLegislativaPesquisaView(FilterView): context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context['show_results'] = show_results_filter_set(qr) + return context @@ -1610,6 +1615,9 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView): context['object_list'] = context['object_list'].order_by( 'ano', 'numero') 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): @@ -1677,6 +1685,9 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): 'ano', 'numero') 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): @@ -1819,6 +1830,7 @@ class FichaPesquisaView(PermissionRequiredMixin, FormView): return HttpResponseRedirect(url) + class FichaSelecionaView(PermissionRequiredMixin, FormView): form_class = FichaSelecionaForm template_name = 'materia/impressos/ficha_seleciona.html' @@ -1827,7 +1839,7 @@ class FichaSelecionaView(PermissionRequiredMixin, FormView): def get_context_data(self, **kwargs): if ('tipo' not in self.request.GET or 'data_inicial' not in self.request.GET or - 'data_final' not in self.request.GET): + 'data_final' not in self.request.GET): return HttpResponseRedirect(reverse( 'sapl.materia:impressos_ficha_pesquisa')) @@ -1846,13 +1858,14 @@ class FichaSelecionaView(PermissionRequiredMixin, FormView): context['quantidade'] = len(materia_list) materia_list = materia_list[:20] - context['form'].fields['materia'].choices = [(m.id, str(m)) for m in materia_list] + context['form'].fields['materia'].choices = [ + (m.id, str(m)) for m in materia_list] if context['quantidade'] > 20: messages.info(self.request, _('Sua pesquisa retornou mais do que ' - '20 impressos. Por questões de performance, foram retornados ' - 'apenas os 20 primeiros. Caso queira outros, tente fazer uma ' - 'pesquisa mais específica')) + '20 impressos. Por questões de performance, foram retornados ' + 'apenas os 20 primeiros. Caso queira outros, tente fazer uma ' + 'pesquisa mais específica')) return context @@ -1870,6 +1883,6 @@ class FichaSelecionaView(PermissionRequiredMixin, FormView): context['materia'] = materia context['despachos'] = materia.despachoinicial_set.all().values_list( - 'comissao__nome', flat=True) + 'comissao__nome', flat=True) return gerar_pdf_impressos(self.request, context, 'materia/impressos/ficha_pdf.html') diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 8e70bd8e1..33589f243 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -11,6 +11,7 @@ from sapl.base.models import AppConfig from sapl.compilacao.views import IntegracaoTaView from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, MasterDetailCrud, make_pagination) +from sapl.utils import show_results_filter_set from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm from .models import (AssuntoNorma, NormaJuridica, NormaRelacionada, @@ -81,6 +82,8 @@ class NormaPesquisaView(FilterView): context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context['show_results'] = show_results_filter_set(qr) + return context diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 0a27e8c4e..6f4cf4265 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -25,9 +25,8 @@ from sapl.materia.models import Autoria, Proposicao, Relatoria from sapl.parlamentares.apps import AppConfig from sapl.utils import parlamentares_ativos -from .forms import (FiliacaoForm, LegislaturaForm, - MandatoForm, ParlamentarCreateForm, ParlamentarForm, - VotanteForm) +from .forms import (FiliacaoForm, LegislaturaForm, MandatoForm, + ParlamentarCreateForm, ParlamentarForm, VotanteForm) from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, Dependente, Filiacao, Frente, Legislatura, Mandato, NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 82de1d73d..c2ff10189 100644 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -21,7 +21,7 @@ from sapl.crud.base import Crud, CrudAux, MasterDetailCrud, make_pagination from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.parlamentares.models import Legislatura, Parlamentar from sapl.protocoloadm.models import Protocolo -from sapl.utils import create_barcode, get_client_ip +from sapl.utils import create_barcode, get_client_ip, show_results_filter_set from .forms import (AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoFilterSet, @@ -212,6 +212,9 @@ class ProtocoloPesquisaView(PermissionRequiredMixin, FilterView): numero_res=len(self.object_list) ) + context['show_results'] = show_results_filter_set( + self.request.GET.copy()) + return self.render_to_response(context) @@ -564,6 +567,9 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, numero_res=len(self.object_list) ) + context['show_results'] = show_results_filter_set( + self.request.GET.copy()) + return self.render_to_response(context) diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index 3edf60104..e454a9eee 100644 --- a/sapl/sessao/urls.py +++ b/sapl/sessao/urls.py @@ -19,9 +19,8 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente, VotacaoNominalExpedienteDetailView, VotacaoNominalExpedienteEditView, VotacaoNominalExpedienteView, - VotacaoNominalView, VotacaoView, - abrir_votacao, atualizar_mesa, - insere_parlamentar_composicao, + VotacaoNominalView, VotacaoView, abrir_votacao, + atualizar_mesa, insere_parlamentar_composicao, mudar_ordem_materia_sessao, recuperar_materia, recuperar_numero_sessao, remove_parlamentar_composicao, diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index c3775f3dd..c68987bc6 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -34,6 +34,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 from .forms import (AdicionarVariasMateriasFilterSet, ExpedienteForm, ListMateriaForm, MesaForm, OradorExpedienteForm, @@ -117,7 +118,7 @@ def verifica_sessao_iniciada(request, spk): sessao = SessaoPlenaria.objects.get(id=spk) if not sessao.iniciada or sessao.finalizada: - msg = _('Não é possível abrir matérias para votação. '\ + msg = _('Não é possível abrir matérias para votação. ' 'Esta Sessão Plenária não foi iniciada ou está finalizada.') messages.add_message(request, messages.INFO, msg) return False @@ -143,8 +144,8 @@ def abrir_votacao(request, pk, spk): raise Http404 if (verifica_presenca(request, presenca_model, spk) and - verifica_votacoes_abertas(request) and - verifica_sessao_iniciada(request, spk)): + verifica_votacoes_abertas(request) and + verifica_sessao_iniciada(request, spk)): materia_votacao = model.objects.get(id=pk) materia_votacao.votacao_aberta = True materia_votacao.save() @@ -2455,6 +2456,8 @@ class PesquisarSessaoPlenariaView(FilterView): numero_res=len(self.object_list) ) + context['show_results'] = show_results_filter_set(self.request.GET.copy()) + return self.render_to_response(context) diff --git a/sapl/templates/base/RelatorioHistoricoTramitacao_filter.html b/sapl/templates/base/RelatorioHistoricoTramitacao_filter.html index 8cba5d186..421be8d06 100644 --- a/sapl/templates/base/RelatorioHistoricoTramitacao_filter.html +++ b/sapl/templates/base/RelatorioHistoricoTramitacao_filter.html @@ -3,11 +3,11 @@ {% load crispy_forms_tags %} {% block base_content %} - {% if not filter_url %} + {% if not show_results %} {% crispy filter.form %} {% endif %} - {% if filter_url %} + {% if show_results %} diff --git a/sapl/templates/base/RelatorioMateriasPorAnoAutorTipo_filter.html b/sapl/templates/base/RelatorioMateriasPorAnoAutorTipo_filter.html index 23ef5e275..43deac36b 100644 --- a/sapl/templates/base/RelatorioMateriasPorAnoAutorTipo_filter.html +++ b/sapl/templates/base/RelatorioMateriasPorAnoAutorTipo_filter.html @@ -3,11 +3,11 @@ {% load crispy_forms_tags %} {% block base_content %} - {% if not filter_url %} + {% if not show_results %} {% crispy filter.form %} {% endif %} - {% if filter_url %} + {% if show_results %} diff --git a/sapl/templates/base/RelatorioMateriasPorAutor_filter.html b/sapl/templates/base/RelatorioMateriasPorAutor_filter.html index 889caf0f1..c75aad42b 100644 --- a/sapl/templates/base/RelatorioMateriasPorAutor_filter.html +++ b/sapl/templates/base/RelatorioMateriasPorAutor_filter.html @@ -3,11 +3,11 @@ {% load crispy_forms_tags %} {% block base_content %} - {% if not filter_url %} + {% if not show_results %} {% crispy filter.form %} {% endif %} - {% if filter_url %} + {% if show_results %} diff --git a/sapl/templates/base/RelatorioPresencaSessao_filter.html b/sapl/templates/base/RelatorioPresencaSessao_filter.html index ea3b1fca2..e3e447f8d 100644 --- a/sapl/templates/base/RelatorioPresencaSessao_filter.html +++ b/sapl/templates/base/RelatorioPresencaSessao_filter.html @@ -4,11 +4,11 @@ {% load common_tags %} {% block base_content %} - {% if not filter_url %} + {% if not show_results %} {% crispy filter.form %} {% endif %} - {% if filter_url %} + {% if show_results %} - +
      {% if materia.numeracao_set.first %} - PROCESSO Nº: {{ materia.numeracao_set.first.numero_materia }}

      + PROCESSO Nº {{ materia.numeracao_set.first.numero_materia }} / {{ materia.numeracao_set.first.ano_materia }}
        {% else %} - PROCESSO Nº: {{ materia.numero }}

      + PROCESSO Nº: {{ materia.numero }}
        {% endif %}
      - - - {{materia.tipo}}: {{materia.numero}}/{{materia.ano}}
      - - - Data de entrada: {{materia.data_apresentacao}}
      + + +
      + + {{materia.tipo}}: {{materia.numero}} / {{materia.ano}}
      +
      + + + +
      + + Data de entrada: {{materia.data_apresentacao}}
      +
      -
      +
      + {% if materia.autoria_set.all %} Autor: @@ -111,18 +104,16 @@ body
      - -


      -
      +
      Ementa: {{materia.ementa}}
      -


      +
      @@ -134,8 +125,8 @@ body

      -
      - ________________NORMA JURIDICA_________________

      + + ________________NORMA JURIDICA_________________


      _________________________________________________
      From ba5c7a8ae3d8ffff33403a1e4fa419dde082344b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Fr=C3=A1?= Date: Wed, 4 Oct 2017 13:14:57 -0300 Subject: [PATCH 086/237] Retira campo Data protocolo duplicado #1518 --- sapl/templates/protocoloadm/protocolo_filter.html | 1 - 1 file changed, 1 deletion(-) diff --git a/sapl/templates/protocoloadm/protocolo_filter.html b/sapl/templates/protocoloadm/protocolo_filter.html index d50439ae8..6d9150fa6 100644 --- a/sapl/templates/protocoloadm/protocolo_filter.html +++ b/sapl/templates/protocoloadm/protocolo_filter.html @@ -44,7 +44,6 @@ {% if p.anulado %}  ** NULO **{% endif %}
      Assunto: {{ p.assunto_ementa|default_if_none:"Não informado"}}
      - Data Protocolo: {{ p.data|date:"d/m/Y"|default_if_none:"Não informado" }} - Horário: {{ p.hora|date:"G:i:s" }}
      Data Protocolo: {{ p.data|date:"d/m/Y"|default_if_none:"Não informado" }} - Horário: {{ p.timestamp|localtime|date:"G:i:s" }}
      {% if p.tipo_processo == 0 %} From 6d5bbcba5cd2866427b8139cae9a1915e3a328e5 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Thu, 5 Oct 2017 15:30:13 -0300 Subject: [PATCH 087/237] Fix #1514 --- sapl/templates/materia/materialegislativa_filter.html | 2 +- sapl/templates/protocoloadm/documentoadministrativo_filter.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/templates/materia/materialegislativa_filter.html b/sapl/templates/materia/materialegislativa_filter.html index 5fe9fd04a..391de56c7 100644 --- a/sapl/templates/materia/materialegislativa_filter.html +++ b/sapl/templates/materia/materialegislativa_filter.html @@ -8,7 +8,7 @@ Pesquisa Textual - {% if perms.materia %} + {% if perms.materia.add_materialegislativa %} {% blocktrans with verbose_name=view.verbose_name %} Adicionar Matéria Legislativa {% endblocktrans %} diff --git a/sapl/templates/protocoloadm/documentoadministrativo_filter.html b/sapl/templates/protocoloadm/documentoadministrativo_filter.html index 354565c28..a69b27073 100644 --- a/sapl/templates/protocoloadm/documentoadministrativo_filter.html +++ b/sapl/templates/protocoloadm/documentoadministrativo_filter.html @@ -7,7 +7,7 @@ {% block actions %}
      - {% if perms.protocoloadm %} + {% if perms.protocoloadm.add_documentoadministrativo %} {% blocktrans with verbose_name=view.verbose_name %} Adicionar Documento Administrativo {% endblocktrans %} From 699758645e45ae74b4e11cd16e75ec4f81be3dfa Mon Sep 17 00:00:00 2001 From: Fabio Rauber Date: Mon, 9 Oct 2017 10:48:14 -0300 Subject: [PATCH 088/237] Included restart always and more env vars in docker-compose.yml --- docker-compose.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 68218665d..3b388dc7d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,6 @@ sapldb: image: postgres + restart: always environment: POSTGRES_PASSWORD: sapl POSTGRES_USER: sapl @@ -8,9 +9,19 @@ sapldb: volumes: - sapldb_data:/var/lib/postgresql/data/ ports: - - "5532:5432" + - "5432:5432" sapl: image: interlegis/sapl:3.1.24-BETA + restart: always + environment: + ADMIN_PASSWORD: interlegis + ADMIN_EMAIL: email@dominio.net + DEBUG: 'False' + USE_TLS: 'False' + EMAIL_PORT: 587 + EMAIL_HOST: smtp.dominio.net + EMAIL_HOST_USER: usuariosmtp + EMAIL_HOST_PASSWORD: senhasmtp volumes: - sapl_data:/var/interlegis/sapl/data - sapl_media:/var/interlegis/sapl/media From 6c21a9b41b73afe1cd043951ccd3221e8fad1ca8 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Mon, 9 Oct 2017 13:48:26 -0300 Subject: [PATCH 089/237] Pina requirements --- requirements/dev-requirements.txt | 2 +- requirements/requirements.txt | 4 ++-- requirements/test-requirements.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 11d6a2509..674994ffa 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -6,4 +6,4 @@ ipdb==0.10.1 pip-review==0.4 pygraphviz==1.3.1 pytest-ipdb==0.1-prerelease2 -pipdeptree +pipdeptree==0.10.1 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index e64eb97dc..f0f3573cc 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -16,8 +16,8 @@ django-filter==0.15.3 django-floppyforms==1.6.2 django-model-utils==2.5 django-sass-processor==0.5.4 -djangorestframework -drfdocs +djangorestframework==3.4.0 +drfdocs==0.0.11 easy-thumbnails==2.3 git+git://github.com/interlegis/trml2pdf.git libsass==0.11.1 diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index 7dd6def90..5599b6d80 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -1,6 +1,6 @@ -r requirements.txt coverage==4.1 -django-webtest +django-webtest==1.7.8 flake8==2.6.2 isort==4.2.5 model-mommy==1.2.6 From 52cb5f9ad3c16a9383f46bd607a0da663276b0e4 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Mon, 9 Oct 2017 13:56:37 -0300 Subject: [PATCH 090/237] Fix #1058 redundancia doc adm v2 (#1510) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Inicia refatoração * Inicia a resolução da issue * Remove ipdb --- sapl/protocoloadm/forms.py | 20 ++++++++++++++----- ...ocumentoadministrativo_numero_protocolo.py | 19 ++++++++++++++++++ sapl/protocoloadm/models.py | 3 +-- sapl/protocoloadm/views.py | 2 +- sapl/relatorios/views.py | 2 +- 5 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 sapl/protocoloadm/migrations/0002_remove_documentoadministrativo_numero_protocolo.py diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index 692a2c4f2..e3874181f 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -4,7 +4,8 @@ from crispy_forms.bootstrap import InlineRadios from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Button, Fieldset, Layout from django import forms -from django.core.exceptions import ObjectDoesNotExist, ValidationError +from django.core.exceptions import (MultipleObjectsReturned, + ObjectDoesNotExist, ValidationError) from django.db import models from django.forms import ModelForm from django.utils import timezone @@ -153,7 +154,7 @@ class DocumentoAdministrativoFilterSet(django_filters.FilterSet): model = DocumentoAdministrativo fields = ['tipo', 'numero', - 'numero_protocolo', + 'protocolo__numero', 'data', 'tramitacaoadministrativo__unidade_tramitacao_destino', 'tramitacaoadministrativo__status'] @@ -172,7 +173,7 @@ class DocumentoAdministrativoFilterSet(django_filters.FilterSet): row2 = to_row( [('ano', 4), - ('numero_protocolo', 4), + ('protocolo__numero', 4), ('data', 4)]) row3 = to_row( @@ -549,6 +550,10 @@ class DocumentoAdministrativoForm(ModelForm): widget=forms.Select( attrs={'class': 'selector'})) + numero_protocolo = forms.IntegerField(required=False, + label=Protocolo._meta. + get_field('numero').verbose_name) + class Meta: model = DocumentoAdministrativo fields = ['tipo', @@ -577,8 +582,8 @@ class DocumentoAdministrativoForm(ModelForm): if not self.is_valid(): return cleaned_data - numero_protocolo = cleaned_data['numero_protocolo'] - ano_protocolo = cleaned_data['ano_protocolo'] + numero_protocolo = self.data['numero_protocolo'] + ano_protocolo = self.data['ano_protocolo'] # campos opcionais, mas que se informados devem ser válidos if numero_protocolo and ano_protocolo: @@ -590,6 +595,11 @@ class DocumentoAdministrativoForm(ModelForm): msg = _('Protocolo %s/%s inexistente.' % ( numero_protocolo, ano_protocolo)) raise ValidationError(msg) + except MultipleObjectsReturned: + msg = _( + 'Existe mais de um Protocolo com este ano e número.' % ( + numero_protocolo, ano_protocolo)) + raise ValidationError(msg) return self.cleaned_data diff --git a/sapl/protocoloadm/migrations/0002_remove_documentoadministrativo_numero_protocolo.py b/sapl/protocoloadm/migrations/0002_remove_documentoadministrativo_numero_protocolo.py new file mode 100644 index 000000000..de12f4139 --- /dev/null +++ b/sapl/protocoloadm/migrations/0002_remove_documentoadministrativo_numero_protocolo.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.3 on 2017-09-20 21:52 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='documentoadministrativo', + name='numero_protocolo', + ), + ] diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py index 6294399f8..d4d45b3ad 100644 --- a/sapl/protocoloadm/models.py +++ b/sapl/protocoloadm/models.py @@ -120,8 +120,7 @@ class DocumentoAdministrativo(models.Model): on_delete=models.PROTECT, verbose_name=_('Protocolo')) data = models.DateField(verbose_name=_('Data')) - numero_protocolo = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Núm. Protocolo')) + interessado = models.CharField( max_length=50, blank=True, verbose_name=_('Interessado')) autor = models.ForeignKey(Autor, blank=True, null=True, diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 348f79229..3384e4934 100644 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -88,7 +88,7 @@ class DocumentoAdministrativoCrud(Crud): class BaseMixin(Crud.BaseMixin): list_field_names = ['tipo', 'numero', 'ano', 'data', - 'numero_protocolo', 'assunto', + 'protocolo__numero', 'assunto', 'interessado', 'tramitacao', 'texto_integral'] @property diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 01a3b06b2..7719e6d2d 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -956,7 +956,7 @@ def get_etiqueta_protocolos(prots): dic['num_documento'] = '' for documento in DocumentoAdministrativo.objects.filter( - numero_protocolo=p.numero): + protocolo=p): dic['num_documento'] = str(documento) dic['ident_processo'] = dic['num_materia'] or dic['num_documento'] From 71e55a43516e6d477c47ad40d08187fcfb043985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Fr=C3=A1?= Date: Mon, 9 Oct 2017 13:58:07 -0300 Subject: [PATCH 091/237] Carrega form com ano atual incluir materia na ordem dia (#1523) --- sapl/sessao/forms.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index ee7b2f9de..f767cb5d4 100644 --- a/sapl/sessao/forms.py +++ b/sapl/sessao/forms.py @@ -116,6 +116,7 @@ class BancadaForm(ModelForm): class ExpedienteMateriaForm(ModelForm): _model = ExpedienteMateria + data_atual = timezone.now() tipo_materia = forms.ModelChoiceField( label=_('Tipo Matéria'), @@ -128,7 +129,9 @@ class ExpedienteMateriaForm(ModelForm): label='Número Matéria', required=True) ano_materia = forms.CharField( - label='Ano Matéria', required=True) + label='Ano Matéria', + initial=int(data_atual.year), + required=True) data_ordem = forms.CharField( label='Data Sessão', From ad110ab24c65d55ca90d260a51fb29b16e204b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Mon, 9 Oct 2017 13:58:34 -0300 Subject: [PATCH 092/237] =?UTF-8?q?Fix=20#1502=20ordem=20alfab=C3=A9tica?= =?UTF-8?q?=20no=20painel=20(#1509)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Corrige #1502 para listar em ordem alfabética no painel * Reordena a lista de parlamentares #1502 * Move a função para utils onde pode ser utilizada em diversas parte do sistema --- sapl/painel/views.py | 5 ++++- sapl/utils.py | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 3f31e430d..4be056640 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -1,4 +1,3 @@ - from django.contrib import messages from django.contrib.auth.decorators import user_passes_test from django.core.exceptions import ObjectDoesNotExist @@ -8,6 +7,8 @@ from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import render from django.utils.translation import ugettext_lazy as _ +from operator import itemgetter +from sapl.utils import sort_lista_chave from sapl.crud.base import Crud from sapl.painel.apps import AppConfig @@ -292,6 +293,8 @@ def get_presentes(pk, response, materia): elif materia.tipo_votacao == 3: tipo_votacao = 'Secreta' + presentes_list = sort_lista_chave(presentes_list, 'nome') + response.update({ 'presentes': presentes_list, 'num_presentes': num_presentes, diff --git a/sapl/utils.py b/sapl/utils.py index 7afa00d1a..37e5711d3 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -4,6 +4,7 @@ import os import re from functools import wraps from unicodedata import normalize as unicodedata_normalize +from operator import itemgetter import django_filters import magic @@ -651,3 +652,14 @@ def show_results_filter_set(qr): return False return True + + +def sort_lista_chave(lista, chave): + """ + :param lista: Uma list a ser ordenada . + :param chave: Algum atributo (chave) que está presente na lista e qual deve ser usado para a ordenação da nova + lista. + :return: A lista ordenada pela chave passada. + """ + lista_ordenada = sorted(lista, key=itemgetter(chave)) + return lista_ordenada From d1c60ea10095e88b09f37f43445c604c7b19d8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Mon, 9 Oct 2017 13:59:20 -0300 Subject: [PATCH 093/237] Fix #1487 abertura do painel (#1499) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adiciona teste de vie em SessaoPlenaria * Adiciona teste de view no CasaLegislativa e TipoAutor * Corrigi erros relacionados a PEP8 * Adiciona teste ao ExpedienteMateriaForm * Fix erro * Adicionando o atributo de painel aberto e a função para alterar o status pela view * Verificação do status do painel na abertura da página * Pequena correção * Mudando a estrutura do painel para que seja possível a abertura em dias que não haja matérias para votação (#1487) Signed-off-by: João Pedro Sconetto * Modifica a lógica para quando abrir a matéria, abrir o painel * Pequena correção * Pequena correção --- sapl/painel/urls.py | 7 ++- sapl/painel/views.py | 58 ++++++++++++++----- .../0015_sessaoplenaria_painel_aberto.py | 20 +++++++ sapl/sessao/models.py | 1 + sapl/sessao/tests/test_sessao.py | 3 +- sapl/sessao/tests/test_sessao_view.py | 4 +- sapl/sessao/views.py | 3 + sapl/templates/painel/index.html | 8 +-- sapl/templates/sessao/painel.html | 52 +++++++++++++++++ 9 files changed, 133 insertions(+), 23 deletions(-) create mode 100644 sapl/sessao/migrations/0015_sessaoplenaria_painel_aberto.py diff --git a/sapl/painel/urls.py b/sapl/painel/urls.py index 66ef92ac1..2dc5dcdb9 100644 --- a/sapl/painel/urls.py +++ b/sapl/painel/urls.py @@ -3,7 +3,7 @@ from django.conf.urls import url from .apps import AppConfig from .views import (cronometro_painel, get_dados_painel, painel_mensagem_view, painel_parlamentar_view, painel_view, painel_votacao_view, - votante_view) + switch_painel, verifica_painel, votante_view) app_name = AppConfig.name @@ -14,10 +14,15 @@ urlpatterns = [ url(r'^painel/mensagem$', painel_mensagem_view, name="painel_mensagem"), url(r'^painel/parlamentar$', painel_parlamentar_view, name='painel_parlamentar'), + url(r'^painel/switch-painel$', switch_painel, + name="switch_painel"), url(r'^painel/votacao$', painel_votacao_view, name='painel_votacao'), + url(r'^painel/verifica-painel$', verifica_painel, + name="verifica_painel"), url(r'^painel/cronometro$', cronometro_painel, name='cronometro_painel'), # url(r'^painel/cronometro$', include(CronometroPainelCrud.get_urls())), url(r'^voto-individual/$', votante_view, name='voto_individual'), ] + diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 4be056640..cc01cbf34 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -1,3 +1,4 @@ +import json from django.contrib import messages from django.contrib.auth.decorators import user_passes_test from django.core.exceptions import ObjectDoesNotExist @@ -224,6 +225,27 @@ def painel_view(request, pk): return render(request, 'painel/index.html', context) +@user_passes_test(check_permission) +def switch_painel(request): + sessao = SessaoPlenaria.objects.get(id=request.POST['pk_sessao']) + switch = json.loads(request.POST['aberto']) + + if switch: + sessao.painel_aberto = True + else: + sessao.painel_aberto = False + + sessao.save() + return JsonResponse({}) + +@user_passes_test(check_permission) +def verifica_painel(request): + sessao = SessaoPlenaria.objects.get(id=request.GET['pk_sessao']) + status = sessao.painel_aberto + resposta = JsonResponse(dict(status=status)) + return resposta + + @user_passes_test(check_permission) def painel_mensagem_view(request): return render(request, 'painel/mensagem.html') @@ -262,12 +284,13 @@ def get_presentes(pk, response, materia): if type(materia) == OrdemDia: presentes = PresencaOrdemDia.objects.filter( sessao_plenaria_id=pk) - elif type(materia) == ExpedienteMateria: + else: presentes = SessaoPlenariaPresenca.objects.filter( sessao_plenaria_id=pk) + sessao = SessaoPlenaria.objects.get(id=pk) num_presentes = len(presentes) - data_sessao = materia.sessao_plenaria.data_inicio + data_sessao = sessao.data_inicio presentes_list = [] for p in presentes: @@ -286,24 +309,29 @@ def get_presentes(pk, response, materia): 'voto': '' }) - if materia.tipo_votacao == 1: - tipo_votacao = 'Simbólica' - elif materia.tipo_votacao == 2: - tipo_votacao = 'Nominal' - elif materia.tipo_votacao == 3: - tipo_votacao = 'Secreta' + if materia: + if materia.tipo_votacao == 1: + tipo_votacao = 'Simbólica' + elif materia.tipo_votacao == 2: + tipo_votacao = 'Nominal' + elif materia.tipo_votacao == 3: + tipo_votacao = 'Secreta' + + response.update({ + 'tipo_resultado': materia.resultado, + 'observacao_materia': materia.observacao, + 'tipo_votacao': tipo_votacao, + 'materia_legislativa_texto': str(materia.materia) + }) + presentes_list = sort_lista_chave(presentes_list, 'nome') response.update({ 'presentes': presentes_list, 'num_presentes': num_presentes, - 'status_painel': 'ABERTO', 'msg_painel': str(_('Votação aberta!')), - 'tipo_resultado': materia.resultado, - 'tipo_votacao': tipo_votacao, - 'observacao_materia': materia.observacao, - 'materia_legislativa_texto': str(materia.materia)}) + }) return response @@ -315,7 +343,6 @@ def get_materia_expediente_aberta(pk): def response_nenhuma_materia(response): response.update({ - 'status_painel': 'FECHADO', 'msg_painel': str(_('Nenhuma matéria disponivel para votação.'))}) return JsonResponse(response) @@ -378,6 +405,7 @@ def get_dados_painel(request, pk): 'cronometro_aparte': get_cronometro_status(request, 'aparte'), 'cronometro_discurso': get_cronometro_status(request, 'discurso'), 'cronometro_ordem': get_cronometro_status(request, 'ordem'), + 'status_painel': sessao.painel_aberto } ordem_dia = get_materia_aberta(pk) @@ -426,4 +454,4 @@ def get_dados_painel(request, pk): materia)) # Retorna que não há nenhuma matéria já votada ou aberta - return response_nenhuma_materia(response) + return response_nenhuma_materia(get_presentes(pk, response, None)) diff --git a/sapl/sessao/migrations/0015_sessaoplenaria_painel_aberto.py b/sapl/sessao/migrations/0015_sessaoplenaria_painel_aberto.py new file mode 100644 index 000000000..73f7b1cc2 --- /dev/null +++ b/sapl/sessao/migrations/0015_sessaoplenaria_painel_aberto.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-09-21 17:44 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sessao', '0014_auto_20170905_1617'), + ] + + operations = [ + migrations.AddField( + model_name='sessaoplenaria', + name='painel_aberto', + field=models.BooleanField(default=False, verbose_name='Painel está aberto?'), + ), + ] diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index a874fb5f4..b5d31fff7 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -111,6 +111,7 @@ class SessaoPlenaria(models.Model): # TODO analyze querying all hosted databases ! cod_andamento_sessao = models.PositiveIntegerField(blank=True, null=True) + painel_aberto = models.BooleanField(blank=True, default=False, verbose_name=_('Painel está aberto?')) tipo = models.ForeignKey(TipoSessaoPlenaria, on_delete=models.PROTECT, verbose_name=_('Tipo')) diff --git a/sapl/sessao/tests/test_sessao.py b/sapl/sessao/tests/test_sessao.py index ed28bf6ef..b0258312c 100644 --- a/sapl/sessao/tests/test_sessao.py +++ b/sapl/sessao/tests/test_sessao.py @@ -37,7 +37,8 @@ def test_sessao_plenaria_form_valido(): 'tipo': str(tipo.pk), 'sessao_legislativa': str(sessao.pk), 'data_inicio': '10/11/2017', - 'hora_inicio': '10:10' + 'hora_inicio': '10:10', + 'painel_aberto': False }) assert form.is_valid() diff --git a/sapl/sessao/tests/test_sessao_view.py b/sapl/sessao/tests/test_sessao_view.py index 50a94d970..8868d7abd 100644 --- a/sapl/sessao/tests/test_sessao_view.py +++ b/sapl/sessao/tests/test_sessao_view.py @@ -11,7 +11,7 @@ from sapl.sessao.models import SessaoPlenaria, TipoSessaoPlenaria def test_incluir_sessao_plenaria_submit(admin_client): legislatura = mommy.make(Legislatura) sessao = mommy.make(SessaoLegislativa) - tipo = mommy.make(TipoSessaoPlenaria) + tipo = mommy.make(TipoSessaoPlenaria, id=1) response = admin_client.post(reverse('sapl.sessao:sessaoplenaria_create'), {'legislatura': str(legislatura.pk), @@ -46,4 +46,4 @@ def test_incluir_sessao_errors(admin_client): assert (response.context_data['form'].errors['data_inicio'] == [_('Este campo é obrigatório.')]) assert (response.context_data['form'].errors['hora_inicio'] == - [_('Este campo é obrigatório.')]) + [_('Este campo é obrigatório.')]) \ No newline at end of file diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 6fe3087f1..1d92772d4 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -148,6 +148,9 @@ def abrir_votacao(request, pk, spk): verifica_sessao_iniciada(request, spk)): materia_votacao = model.objects.get(id=pk) materia_votacao.votacao_aberta = True + sessao = SessaoPlenaria.objects.get(id=spk) + sessao.painel_aberto = True + sessao.save() materia_votacao.save() return HttpResponseRedirect( diff --git a/sapl/templates/painel/index.html b/sapl/templates/painel/index.html index 68e5cdf78..c6701b462 100644 --- a/sapl/templates/painel/index.html +++ b/sapl/templates/painel/index.html @@ -161,10 +161,10 @@ $("#sessao_plenaria").text(data["sessao_plenaria"]) $("#sessao_plenaria_data").text("Data Início: " + data["sessao_plenaria_data"]) $("#sessao_plenaria_hora_inicio").text("Hora Início: " + data["sessao_plenaria_hora_inicio"]) - if (data["status_painel"] == "FECHADO") { + if (data["status_painel"] == false) { $("#message").text("PAINEL ENCONTRA-SE FECHADO"); } - else{ + else { $("#message").text(""); } @@ -176,7 +176,7 @@ var presentes_list = data["presentes"]; - if (presentes_list) { + if (data["status_painel"] == true) { presentes.append(''); jQuery.each(presentes_list, function (index, parlamentar) { $('#parlamentares_list').append('
      ' + @@ -190,7 +190,7 @@ else{ presentes.append(''); $('#parlamentares_list').append( - '
      A listagem de parlamentares só aparecerá quando alguma matéria estiver em votação ou já tiver sido votada.
      ') + '
      A listagem de parlamentares só aparecerá quando o painel estiver aberto.
      ') presentes.append('
      '); } diff --git a/sapl/templates/sessao/painel.html b/sapl/templates/sessao/painel.html index 5cd84ec32..005e5a27d 100644 --- a/sapl/templates/sessao/painel.html +++ b/sapl/templates/sessao/painel.html @@ -14,6 +14,8 @@
      +
      +

      @@ -257,6 +259,56 @@ $(function() { }); }); + +function switch_painel(aberto) { + var pk_sessao = {{root_pk}}; + var botao_abrir = $('#id_abrir_painel'); + var botao_fechar = $('#id_fechar_painel'); + + + $.ajax({ + data: {pk_sessao: pk_sessao, aberto: aberto}, + type: 'POST', + url: "{% url 'sapl.painel:switch_painel' %}", + headers: {'X-CSRFToken': getCookie('csrftoken')}, + }); + + if (aberto) { + botao_abrir.hide(); + botao_fechar.show(); + } else { + botao_abrir.show(); + botao_fechar.hide(); + } +} + +$(document).ready(function(){ + var pk_sessao = {{root_pk}}; + var botao_abrir = $('#id_abrir_painel'); + var botao_fechar = $('#id_fechar_painel'); + + $.ajax({ + data: {pk_sessao: pk_sessao}, + type: 'GET', + dataType: 'json', + url: "{% url 'sapl.painel:verifica_painel' %}", + error: function () { + alert("Erro ao verificar o Painel"); + }, + success: function (data) { + if (data['status']) { + botao_abrir.hide(); + botao_fechar.show(); + } else { + botao_abrir.show(); + botao_fechar.hide(); + } + }, + }); + + +}); + {% endblock %} From 4d9d47e7578dd14fa0fb710f2ee538f4a6882f97 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Tue, 3 Oct 2017 11:45:38 -0300 Subject: [PATCH 094/237] Corrige a url do help_path e adiciona parte das urls no template. --- sapl/base/urls.py | 9 ++-- sapl/base/views.py | 9 ++-- sapl/templates/ajuda.html | 50 +++++++++---------- .../templates/ajuda/modulo_parlamentares.html | 16 +++--- 4 files changed, 43 insertions(+), 41 deletions(-) diff --git a/sapl/base/urls.py b/sapl/base/urls.py index ed55f1767..6273b9912 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -11,7 +11,7 @@ from sapl.settings import EMAIL_SEND_USER from .apps import AppConfig from .forms import LoginForm, NovaSenhaForm, RecuperarSenhaForm -from .views import (AppConfigCrud, CasaLegislativaCrud, HelpView, +from .views import (AppConfigCrud, CasaLegislativaCrud, HelpTopicView, RelatorioAtasView, RelatorioHistoricoTramitacaoView, RelatorioMateriasPorAnoAutorTipoView, RelatorioMateriasPorAutorView, @@ -54,9 +54,10 @@ urlpatterns = [ url(r'^sistema/autor/tipo/', include(TipoAutorCrud.get_urls())), url(r'^sistema/autor/', include(AutorCrud.get_urls())), - url(r'^sistema/ajuda/', TemplateView.as_view(template_name='ajuda.html')), - url(r'^sistema/ajuda/(?P\w+)$', - HelpView.as_view(), name='help_topic'), + url(r'^sistema/ajuda/', TemplateView.as_view(template_name='ajuda.html'), + name='help'), + url(r'^sistema/ajuda-topico/$', + HelpTopicView.as_view(), name='help_topic'), url(r'^sistema/ajuda/', TemplateView.as_view(template_name='ajuda/index.html'), name='help_base'), diff --git a/sapl/base/views.py b/sapl/base/views.py index ebfd0f573..f87db51a6 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -492,11 +492,12 @@ class CasaLegislativaCrud(CrudAux): kwargs={'pk': self.kwargs['pk']})) -class HelpView(PermissionRequiredMixin, TemplateView): - # XXX treat non existing template as a 404!!!! - +class HelpTopicView(TemplateView): def get_template_names(self): - return ['ajuda/%s.html' % self.kwargs['topic']] + if 'topic' in self.request.GET and self.request.GET['topic']: + return ['ajuda/%s.html' % self.request.GET['topic']] + else: + return HttpResponseRedirect(reverse('sapl.base:help')) class AppConfigCrud(CrudAux): diff --git a/sapl/templates/ajuda.html b/sapl/templates/ajuda.html index b90f4db25..482240b70 100644 --- a/sapl/templates/ajuda.html +++ b/sapl/templates/ajuda.html @@ -7,44 +7,44 @@


      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/mandatos_parlamentar.html b/sapl/templates/ajuda/mandatos_parlamentar.html index b885aa444..c36f8aecc 100644 --- a/sapl/templates/ajuda/mandatos_parlamentar.html +++ b/sapl/templates/ajuda/mandatos_parlamentar.html @@ -194,11 +194,11 @@ A função “Início” retorna a tela com os dados básicos do parlamentar.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/materia_anexada.html b/sapl/templates/ajuda/materia_anexada.html index fd549549a..99167678d 100644 --- a/sapl/templates/ajuda/materia_anexada.html +++ b/sapl/templates/ajuda/materia_anexada.html @@ -177,11 +177,11 @@ retorna a tela com os dados da matéria legislativa selecionada.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/modulo_comissoes.html b/sapl/templates/ajuda/modulo_comissoes.html index 1b5e72448..e9a3884b1 100644 --- a/sapl/templates/ajuda/modulo_comissoes.html +++ b/sapl/templates/ajuda/modulo_comissoes.html @@ -17,14 +17,14 @@ esta transação, que são:
      - Tabelas Auxiliares



      @@ -37,11 +37,11 @@ data a partir da qual ela ficou inativa; devendo, nesse caso, ser posterior a da A exclusão da comissão somente será possível se não tiver havido qualquer tramitação de matéria para ela. Então, deve-se exclui-la antes da tabela de unidades de tramitação.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/modulo_mesa_diretora.html b/sapl/templates/ajuda/modulo_mesa_diretora.html index 09e9bbe7c..c29e97648 100644 --- a/sapl/templates/ajuda/modulo_mesa_diretora.html +++ b/sapl/templates/ajuda/modulo_mesa_diretora.html @@ -16,20 +16,20 @@ transação, que são:
      - Tabelas Auxiliares



      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/modulo_norma_juridica.html b/sapl/templates/ajuda/modulo_norma_juridica.html index d84e09851..03dc7d8d5 100644 --- a/sapl/templates/ajuda/modulo_norma_juridica.html +++ b/sapl/templates/ajuda/modulo_norma_juridica.html @@ -16,16 +16,16 @@ transação, que são:

      - Tabela Auxiliar


      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/modulo_tramitacao_materias.html b/sapl/templates/ajuda/modulo_tramitacao_materias.html index fb70c7b05..439b9896a 100644 --- a/sapl/templates/ajuda/modulo_tramitacao_materias.html +++ b/sapl/templates/ajuda/modulo_tramitacao_materias.html @@ -19,40 +19,40 @@ esta transação, que são:
      - Tabelas Auxiliares



      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/nivel_instrucao.html b/sapl/templates/ajuda/nivel_instrucao.html index d8875f61c..709accfee 100644 --- a/sapl/templates/ajuda/nivel_instrucao.html +++ b/sapl/templates/ajuda/nivel_instrucao.html @@ -43,11 +43,11 @@ instrução  foi excluído com sucesso sem pergunta de confirmação.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/norma_juridica.html b/sapl/templates/ajuda/norma_juridica.html index 8d434029a..979ee0cf5 100644 --- a/sapl/templates/ajuda/norma_juridica.html +++ b/sapl/templates/ajuda/norma_juridica.html @@ -331,11 +331,11 @@ Quando for informado OK será enviada a mensagem !Norma Jurídica excluída com sucesso!

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/numeracao_docsacess.html b/sapl/templates/ajuda/numeracao_docsacess.html index 7291cd56c..24e37d451 100644 --- a/sapl/templates/ajuda/numeracao_docsacess.html +++ b/sapl/templates/ajuda/numeracao_docsacess.html @@ -544,11 +544,11 @@ Acessórios, acione a função “Documentos Acessórios”.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/ordem_dia.html b/sapl/templates/ajuda/ordem_dia.html index 29436c082..adf2fcdcf 100644 --- a/sapl/templates/ajuda/ordem_dia.html +++ b/sapl/templates/ajuda/ordem_dia.html @@ -162,11 +162,11 @@ Quando for informado OK será enviada a mensagem !Matéria excluída com sucesso da ordem do dia!

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/orgao.html b/sapl/templates/ajuda/orgao.html index d1fa8a9c9..8e1a723c3 100644 --- a/sapl/templates/ajuda/orgao.html +++ b/sapl/templates/ajuda/orgao.html @@ -1,4 +1,4 @@ -{% extends "base.html% } +{% extends "base.html" %} {% load i18n %} {% block base_content %} @@ -141,11 +141,11 @@ retorna a tela com a relação de órgãos já cadastrados.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/origem.html b/sapl/templates/ajuda/origem.html index 0313b4bf8..69ae44abc 100644 --- a/sapl/templates/ajuda/origem.html +++ b/sapl/templates/ajuda/origem.html @@ -89,11 +89,11 @@ retorna a tela com a relação de origem já cadastrada.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/partidos.html b/sapl/templates/ajuda/partidos.html index fc3f1651d..1f3bf6740 100644 --- a/sapl/templates/ajuda/partidos.html +++ b/sapl/templates/ajuda/partidos.html @@ -124,11 +124,11 @@ retorna à tela com a relação de Partidos já cadastrados.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/periodo_composicao_comissao.html b/sapl/templates/ajuda/periodo_composicao_comissao.html index 4b7d05b94..5d449d1d9 100644 --- a/sapl/templates/ajuda/periodo_composicao_comissao.html +++ b/sapl/templates/ajuda/periodo_composicao_comissao.html @@ -103,11 +103,11 @@ retorna a tela com a relação de períodos de comissão já cadastradas.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/proposicao.html b/sapl/templates/ajuda/proposicao.html index 9e3dc2e45..8d43c2726 100644 --- a/sapl/templates/ajuda/proposicao.html +++ b/sapl/templates/ajuda/proposicao.html @@ -10,11 +10,11 @@

      Proposição - elaboração / atualização

      A tela exibe um conjunto de dados básicos para a elaboração de uma nova proposição ou de um documento acessório. No caso de uma proposição ou se um documento estiver sido consultado, o sapl permitirá a sua atualização . Os dados básicos são os seguintes:

      Tipo - combo para a seleção do tipo de proposição legislativa ou documento acessório.

      Descrição - deve conter uma breve descrição sobre a proposição ou documento que está sendo elaborado ou atualizado.

      Matéria Legislativa, número e ano - essas informações somente deverão ser indicadas quando tratar-se de um documento do tipo parecer, caso contrário, o sistema mantém os respectivos campos inibidos, ou seja, sem acesso. Caso tenham que ser informados, a matéria legislativa já deverá ter sido cadastrada no sistema.

      Criar texto em XML ou Carregar Arquivo Externo - indicar assinalando uma das opções. Caso seja indicada a opção - Criar texto em XML - o sapl irá disponibilizar um editor de textos - orientado por um modelo próprio, o qual deve ter sido previamente associado - para o tipo de documento a ser digitado, ou seja, com a formatação final que foi previamente ajustada para o tipo de documento. Se a segunda opção for a indicada, então o sapl irá habilitar o botão Arquivo de modo a permitir realizar a carga de um documento previamente digitado; e, neste caso, não entrará no mérito do modelo e nem da respectiva folha de estilo - formato final - do documento uploaded.

      Ao final, deve ser acionado o botão salvar dados básicos e criar texto integral para dar seguimento a execução da função. Se a opção foi a de criar o texto, o sapl abrirá o editor de textos para que o documento seja digitado. No caso do upload de documento já digitado, a função emitirá mensagem de finalização e de envio para protocolo informando o número de identificação gerado de modo automático.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/proposicao_editor.html b/sapl/templates/ajuda/proposicao_editor.html index 2ad5faa31..098af1883 100644 --- a/sapl/templates/ajuda/proposicao_editor.html +++ b/sapl/templates/ajuda/proposicao_editor.html @@ -10,11 +10,11 @@

      Proposição - edição / atualização

      A tela exibe um conjunto de dados básicos para a atualização da proposição ou documento acessório. A seguir, as situações possíveis:

      - Proposição ainda não enviada - Neste caso o autor tem disponível as seguintes ações: Editar o Texto Integral, sendo que, antes da edição, os dados básicos eventualmente modificados devem ser salvos; retornar a tela anterior, clicando em Início; clicar em Salvar para salvar os dados básicos; ou, clicar em Excluir para excluir a proposição ou o documento acessório, conforme o caso.

      - Proposição já enviada, porém, ainda não recebida - Neste estado, as ações disponíveis são: clicar em Imprimir Recibo para imprimir o recibo referente ao envio para protocolo; clicar em Imprimir Texto Integral para imprimir a proposição ou documento; clicar em Início para retornar a tela anterior; ou, ainda, clicar em retomar a proposição enviada para retomar a proposição e realizar modificações no seu texto. Neste caso, o Sapl irá desprezar o número anteriormente gerado, no momento do envio, e ao ser reenviada a proposição, gerar nova numeração. Após essa ação, a proposição ou documento retorna a situação de proposição ainda não enviada.

      - Proposição já enviada e recebida - Nesta situação, todas as ações relativas a situação anterior - de recebida - estão disponíveis, exceto que não será permitida retomar a proposição e nem realizar alterações nos dados básicos.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/proposicao_legislativa.html b/sapl/templates/ajuda/proposicao_legislativa.html index 2c107fe46..96d9b8980 100644 --- a/sapl/templates/ajuda/proposicao_legislativa.html +++ b/sapl/templates/ajuda/proposicao_legislativa.html @@ -11,11 +11,11 @@ Esta tela exibe uma lista de proposições legislativas, que foram, ou estão sendo, elaboradas por um usuário com perfil de autor. Contém as seguintes colunas de dados:

      Data de envio - refere-se a data na qual o autor enviou a proposição para protocolo. Caso ainda, a mesma não tenha sido enviada, o sistema exibe a palavra em elaboração. Essa coluna possui um link para a tela que contém o detalhamento da proposição referida, o qual é acionado quando se clica sobre o mesmo.

      Tipo - indica o tipo de proposição.

      Descrição - contém a descrição da proposição.

      Recebida - sim ou não, indicando a informação de recebimento ou não da proposição pela Secretaria Legislativa da Casa, para que seja protocolada, no caso da Proposição já ter sido enviada.

      Além das colunas de dados acima, possui os seguintes links de acionamento de funcionalidades:

      Próxima página - avança para apresentar mais 8 proposições - paginando para frente, no caso de haver mais proposições.

      Página anterior - retrocede para apresentar as 8 proposições anteriores - paginando para trás, se houver.

      Elaborar nova proposição - link que, ao ser acionado, direciona o usuário para a tela de inclusão de nova proposição.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/protocolo_administrativo.html b/sapl/templates/ajuda/protocolo_administrativo.html index ef4248d49..8715beb51 100644 --- a/sapl/templates/ajuda/protocolo_administrativo.html +++ b/sapl/templates/ajuda/protocolo_administrativo.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



      @@ -50,9 +50,9 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

      - Anterior | + Anterior | - Índice + Índice | Próxima diff --git a/sapl/templates/ajuda/protocolo_anular.html b/sapl/templates/ajuda/protocolo_anular.html index ef4248d49..8715beb51 100644 --- a/sapl/templates/ajuda/protocolo_anular.html +++ b/sapl/templates/ajuda/protocolo_anular.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



      @@ -50,9 +50,9 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

      - Anterior | + Anterior | - Índice + Índice | Próxima diff --git a/sapl/templates/ajuda/protocolo_geral.html b/sapl/templates/ajuda/protocolo_geral.html index b89fe5472..f7bc6b4dd 100644 --- a/sapl/templates/ajuda/protocolo_geral.html +++ b/sapl/templates/ajuda/protocolo_geral.html @@ -162,11 +162,11 @@ Quando for informado OK será enviada a mensagem !Matéria excluída com sucesso da ordem do dia!

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/protocolo_gerar_etiqueta_processo.html b/sapl/templates/ajuda/protocolo_gerar_etiqueta_processo.html index ef4248d49..8715beb51 100644 --- a/sapl/templates/ajuda/protocolo_gerar_etiqueta_processo.html +++ b/sapl/templates/ajuda/protocolo_gerar_etiqueta_processo.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



      @@ -50,9 +50,9 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

      - Anterior | + Anterior | - Índice + Índice | Próxima diff --git a/sapl/templates/ajuda/protocolo_gerar_etiqueta_protocolo.html b/sapl/templates/ajuda/protocolo_gerar_etiqueta_protocolo.html index ef4248d49..8715beb51 100644 --- a/sapl/templates/ajuda/protocolo_gerar_etiqueta_protocolo.html +++ b/sapl/templates/ajuda/protocolo_gerar_etiqueta_protocolo.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



      @@ -50,9 +50,9 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

      - Anterior | + Anterior | - Índice + Índice | Próxima diff --git a/sapl/templates/ajuda/protocolo_legislativo.html b/sapl/templates/ajuda/protocolo_legislativo.html index ef4248d49..8715beb51 100644 --- a/sapl/templates/ajuda/protocolo_legislativo.html +++ b/sapl/templates/ajuda/protocolo_legislativo.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



      @@ -50,9 +50,9 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

      - Anterior | + Anterior | - Índice + Índice | Próxima diff --git a/sapl/templates/ajuda/recebimento_proposicao.html b/sapl/templates/ajuda/recebimento_proposicao.html index 09b0d1f67..54680bb6b 100644 --- a/sapl/templates/ajuda/recebimento_proposicao.html +++ b/sapl/templates/ajuda/recebimento_proposicao.html @@ -75,11 +75,11 @@ acessório.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/regime_tramitacao.html b/sapl/templates/ajuda/regime_tramitacao.html index 63291ea80..21ebc0dd1 100644 --- a/sapl/templates/ajuda/regime_tramitacao.html +++ b/sapl/templates/ajuda/regime_tramitacao.html @@ -39,11 +39,11 @@ tramitação foi excluído com sucesso sem pergunta de confirmação.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/sessao_legislativa.html b/sapl/templates/ajuda/sessao_legislativa.html index 4f2cb7f2d..5af333853 100644 --- a/sapl/templates/ajuda/sessao_legislativa.html +++ b/sapl/templates/ajuda/sessao_legislativa.html @@ -162,11 +162,11 @@ A função “Início” retorna a tela de cadastramento de Sessão Legislativa.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/sessao_plenaria.html b/sapl/templates/ajuda/sessao_plenaria.html index ffe971a2e..e339c65f2 100644 --- a/sapl/templates/ajuda/sessao_plenaria.html +++ b/sapl/templates/ajuda/sessao_plenaria.html @@ -1,4 +1,4 @@ -{% extends "base.html" % +{% extends "base.html" %} {% load i18n %} {% block base_content %} @@ -14,26 +14,26 @@
      Além das informações básicas de identificaçáo da Sessão é possível acessar o áudio num dos formatos mp3 e aac e o video num dos formatos: mp4, flv e webM por meio das respectivas URL's, caso tenham sido gerados. Ao selecionar uma sessão específica, o sistema irá apresentar o seguinte menu de opçóes, relativo a sessão plenária:

      Menu de Opções


      Ao ter acesso, para cadastro, será exibida a opção de Incluir, para a inclusão de novas Sessões. Ao ser acionada essa função, será exibida a tela Formulário de Cadastro.

      Para a efetivação do cadastramento serão necessários dados das seguintes tabelas auxiliares:

      Tabelas Auxiliares

      Os seguintes campos deverão ser preenchidos:

      @@ -131,11 +131,11 @@ a data de encerramento da sessão plenária no formato dd/mm/aaaa e
      Acione a função “Salvar” para que as informações sejam salvas no arquivo.

      Será enviada a mensagem !Sessão Plenária salva com sucesso!

      Acione a função “Sair” para sair do cadastramento de Sessões e voltar a tela anterior.
      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_ata.html b/sapl/templates/ajuda/sessao_plenaria_ata.html index 5a76f4cb7..bd4b854df 100644 --- a/sapl/templates/ajuda/sessao_plenaria_ata.html +++ b/sapl/templates/ajuda/sessao_plenaria_ata.html @@ -17,11 +17,11 @@
      6. Expedientes - Constam os registros dos fatos ocorridos em cada parte/expediente da Sessão.

      Clique no botão retornar para retornar a tela de cadastro da Sessão Plenária.
      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_expedientes.html b/sapl/templates/ajuda/sessao_plenaria_expedientes.html index 5b178b14f..34070119b 100644 --- a/sapl/templates/ajuda/sessao_plenaria_expedientes.html +++ b/sapl/templates/ajuda/sessao_plenaria_expedientes.html @@ -14,11 +14,11 @@
      Após digitar os textos dentro da caixa, acione o botão 'Salvar' para grava-los.

      Nota: Deve-se evitar copiar textos de outros editores MS Word, etc (Crtl-C e Crtl-V) para dentro da caixa de texto, uma vez que juntamente com o texto vem tags inseridas pelo Editor de Textos, as quais nem sempre são reconhecidas ou passíveis de tradução para o html, que é a linguagem do Navegador Web. Esta sugestão é feita, pois sempre que uma tag existente no texto e não reconhecida pela função de conversão, o relatório em PDF deixa de ser gerado devido a ocorrências de erros decorrentes dessas tags não traduzidas.

      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_lista_presenca_sessao.html b/sapl/templates/ajuda/sessao_plenaria_lista_presenca_sessao.html index 3d14c8724..e16f9d228 100644 --- a/sapl/templates/ajuda/sessao_plenaria_lista_presenca_sessao.html +++ b/sapl/templates/ajuda/sessao_plenaria_lista_presenca_sessao.html @@ -17,11 +17,11 @@
      A informação, sobre o quórum, foi previamente cadastrada quando do cadastro do tipo de sessão no sistema.

      Para a execução desta função serão necessários que os Parlamentares bem como os Tipos de Sessão Plenária - em tabelas auxiliares, estejam previamente cadastrados.

      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_materias_expediente.html b/sapl/templates/ajuda/sessao_plenaria_materias_expediente.html index 32f12d5bf..384fc1218 100644 --- a/sapl/templates/ajuda/sessao_plenaria_materias_expediente.html +++ b/sapl/templates/ajuda/sessao_plenaria_materias_expediente.html @@ -15,11 +15,11 @@
      Na identificação da matéria há um link que, quando acionado, permite o acesso aos meta dados da matéria propriamente.

      As matérias legislativas são inseridas no Expediente, por meio da função Matérias no Expediente, da Sessão Plenária.

      O retorno a tela anterior é feito ao acionar o botão 'Retornar', que se encontra na parte inferior da tela.
      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_materias_ordem_dia.html b/sapl/templates/ajuda/sessao_plenaria_materias_ordem_dia.html index 9505abd97..98358919b 100644 --- a/sapl/templates/ajuda/sessao_plenaria_materias_ordem_dia.html +++ b/sapl/templates/ajuda/sessao_plenaria_materias_ordem_dia.html @@ -15,11 +15,11 @@
      Esta função permite o acesso as funções inclusão individual ou de várias matérias na mesma transação, conforme o botão que for acionado, via clique do mouse.

      Também, é possível ajustar as matérias na Ordem do Dia, de modo a restaurar o número de ordem sequencial, bastando para isso, clicar no botão 'Ajustar Ordenação na Ordem do Dia', as quais serão renumeradas em ordem de tipo, ano e número.

      O retorno a tela anterior é feito ao acionar o botão 'Retornar', que se encontra na parte inferior da tela.
      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_mesa.html b/sapl/templates/ajuda/sessao_plenaria_mesa.html index 53872b5de..1d563e7ac 100644 --- a/sapl/templates/ajuda/sessao_plenaria_mesa.html +++ b/sapl/templates/ajuda/sessao_plenaria_mesa.html @@ -14,11 +14,11 @@
      Para excluir o parlamentar da Mesa da Sessão, basta seleciona-lo e acionar o botão 'Excluir'. O sistema, antes de efetivar, irá perguntar se deseja realmente excluir e, caso afirmativo, efetivará a exclusão e emitirá a mensagem: !Parlamentar excluído com sucesso da composição da mesa.

      Para a execução desta função serão necessários que os Parlamentares bem como os Cargos - em tabelas auxiliares, estejam previamente cadastrados.

      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_oradores.html b/sapl/templates/ajuda/sessao_plenaria_oradores.html index 15f352076..8f64f31f8 100644 --- a/sapl/templates/ajuda/sessao_plenaria_oradores.html +++ b/sapl/templates/ajuda/sessao_plenaria_oradores.html @@ -14,11 +14,11 @@ Essa função possui 3 caixas: Oradores Cadastrados, Cadastro de Ora
      Em Cadastro de Oradores consta no combo box os parlamentares ativos que ainda podem ser selecionados e incluídos na lista de oradores com a indicação da ordem de pronunciamento. Ao acionar o botão incluir orador o sistema irá emitir a mensagem ! Parlamentar incluído com sucesso na lista de oradores!

      A última caixa, Cadastro de Discurso permite a inclusão do discurso do parlamentar. Para tanto, é necessário selecionar o parlamentar no combo box, clicar em arquivo para obter o discurso e, em seguida, clicar no botão Incluir Discurso. O sistema irá emitir a mensagem !Discurso incluído com sucesso! e o link continuar que ao pressionado retorna a tela anterior.

      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_oradores_expediente.html b/sapl/templates/ajuda/sessao_plenaria_oradores_expediente.html index 15f352076..8f64f31f8 100644 --- a/sapl/templates/ajuda/sessao_plenaria_oradores_expediente.html +++ b/sapl/templates/ajuda/sessao_plenaria_oradores_expediente.html @@ -14,11 +14,11 @@ Essa função possui 3 caixas: Oradores Cadastrados, Cadastro de Ora
      Em Cadastro de Oradores consta no combo box os parlamentares ativos que ainda podem ser selecionados e incluídos na lista de oradores com a indicação da ordem de pronunciamento. Ao acionar o botão incluir orador o sistema irá emitir a mensagem ! Parlamentar incluído com sucesso na lista de oradores!

      A última caixa, Cadastro de Discurso permite a inclusão do discurso do parlamentar. Para tanto, é necessário selecionar o parlamentar no combo box, clicar em arquivo para obter o discurso e, em seguida, clicar no botão Incluir Discurso. O sistema irá emitir a mensagem !Discurso incluído com sucesso! e o link continuar que ao pressionado retorna a tela anterior.

      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_oradores_explicacoes_pessoais.html b/sapl/templates/ajuda/sessao_plenaria_oradores_explicacoes_pessoais.html index 15f352076..8f64f31f8 100644 --- a/sapl/templates/ajuda/sessao_plenaria_oradores_explicacoes_pessoais.html +++ b/sapl/templates/ajuda/sessao_plenaria_oradores_explicacoes_pessoais.html @@ -14,11 +14,11 @@ Essa função possui 3 caixas: Oradores Cadastrados, Cadastro de Ora
      Em Cadastro de Oradores consta no combo box os parlamentares ativos que ainda podem ser selecionados e incluídos na lista de oradores com a indicação da ordem de pronunciamento. Ao acionar o botão incluir orador o sistema irá emitir a mensagem ! Parlamentar incluído com sucesso na lista de oradores!

      A última caixa, Cadastro de Discurso permite a inclusão do discurso do parlamentar. Para tanto, é necessário selecionar o parlamentar no combo box, clicar em arquivo para obter o discurso e, em seguida, clicar no botão Incluir Discurso. O sistema irá emitir a mensagem !Discurso incluído com sucesso! e o link continuar que ao pressionado retorna a tela anterior.

      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html b/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html index ac691c689..b25990eb9 100644 --- a/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html +++ b/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html @@ -15,11 +15,11 @@
      O sistema irá exibir a mensagem !Lista de presença da Ordem do Dia cadastrada com sucesso!.

      Para a execução desta função serão necessários que os Parlamentares bem como os Tipos de Sessão Plenária - em tabelas auxiliares, estejam previamente cadastrados.

      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/sessao_plenaria_votacao.html b/sapl/templates/ajuda/sessao_plenaria_votacao.html index 0f5159afb..a89db3be3 100644 --- a/sapl/templates/ajuda/sessao_plenaria_votacao.html +++ b/sapl/templates/ajuda/sessao_plenaria_votacao.html @@ -16,11 +16,11 @@
      O campo observações deve ser preenchido, quando for o caso, com as informações que forem julgadas oportunas e de esclarecimentos adicionais.

      Após preenchidas todas as informações, clicar no botão 'Salvar'. O sistema deverá emitir a mensagem: !Votação salva com sucesso! caso todos os dados estejam corretos, devendo clicar em continuar para retomar o registro da votação de outras matérias.

      Entretanto, emitirá a mensagem: !Quantidade de Votos é diferente do número de parlamentares presentes na Ordem do Dia! caso o total de votantes esteja diferente da lista de presença indicada na Ordem do Dia. Neste caso, clique em voltar para retornar a tela anterior e efetuar as correções.
      -
      Anterior | +
      Anterior | - Índice + Índice - | Próxima + | Próxima

      diff --git a/sapl/templates/ajuda/status_tramitacao.html b/sapl/templates/ajuda/status_tramitacao.html index 5d72ddd83..ae39969b6 100644 --- a/sapl/templates/ajuda/status_tramitacao.html +++ b/sapl/templates/ajuda/status_tramitacao.html @@ -116,11 +116,11 @@ retorna a tela com a relação de Status de tramitação já cadastradas.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_afastamento.html b/sapl/templates/ajuda/tipo_afastamento.html index e01e62490..9751b6c4b 100644 --- a/sapl/templates/ajuda/tipo_afastamento.html +++ b/sapl/templates/ajuda/tipo_afastamento.html @@ -112,11 +112,11 @@ Quando for informado OK será enviada a mensagem !Tipo de Afastamento excluído com sucesso!

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_autor.html b/sapl/templates/ajuda/tipo_autor.html index 0062e95c8..d5765b9dd 100644 --- a/sapl/templates/ajuda/tipo_autor.html +++ b/sapl/templates/ajuda/tipo_autor.html @@ -95,11 +95,11 @@ retorna a tela com a relação de tipo de autor já cadastrado.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_comissao.html b/sapl/templates/ajuda/tipo_comissao.html index a51591252..3fc7989cc 100644 --- a/sapl/templates/ajuda/tipo_comissao.html +++ b/sapl/templates/ajuda/tipo_comissao.html @@ -132,11 +132,11 @@ retorna a tela com a relação de Tipo de comissões já cadastradas.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_dependente.html b/sapl/templates/ajuda/tipo_dependente.html index 1ae7a8005..81f51eda9 100644 --- a/sapl/templates/ajuda/tipo_dependente.html +++ b/sapl/templates/ajuda/tipo_dependente.html @@ -38,11 +38,11 @@ excluído com sucesso sem pergunta de confirmação.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_documento.html b/sapl/templates/ajuda/tipo_documento.html index 0438566de..8f533697f 100644 --- a/sapl/templates/ajuda/tipo_documento.html +++ b/sapl/templates/ajuda/tipo_documento.html @@ -33,11 +33,11 @@ excluído com sucesso sem pergunta de confirmação.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_materia_legislativa.html b/sapl/templates/ajuda/tipo_materia_legislativa.html index 9f40d93c6..46b40cdfa 100644 --- a/sapl/templates/ajuda/tipo_materia_legislativa.html +++ b/sapl/templates/ajuda/tipo_materia_legislativa.html @@ -96,11 +96,11 @@ retorna a tela com a relação de tipo de Matéria Legislatura.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_norma_juridica.html b/sapl/templates/ajuda/tipo_norma_juridica.html index 82d69dbd4..a8c8c6f67 100644 --- a/sapl/templates/ajuda/tipo_norma_juridica.html +++ b/sapl/templates/ajuda/tipo_norma_juridica.html @@ -162,11 +162,11 @@ retorna aa tela com os dados da norma jurídica selecionada.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_proposicao.html b/sapl/templates/ajuda/tipo_proposicao.html index 8153d2f6e..258ce40ee 100644 --- a/sapl/templates/ajuda/tipo_proposicao.html +++ b/sapl/templates/ajuda/tipo_proposicao.html @@ -107,11 +107,11 @@ retorna a tela com a relação de tipo de proposições já cadastradas.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tipo_situa_militar.html b/sapl/templates/ajuda/tipo_situa_militar.html index 1135bfd3c..aaace410b 100644 --- a/sapl/templates/ajuda/tipo_situa_militar.html +++ b/sapl/templates/ajuda/tipo_situa_militar.html @@ -39,11 +39,11 @@ militar foi excluído com sucesso sem pergunta de confirmação.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tramitacao_lote.html b/sapl/templates/ajuda/tramitacao_lote.html index 098834116..198104f4d 100644 --- a/sapl/templates/ajuda/tramitacao_lote.html +++ b/sapl/templates/ajuda/tramitacao_lote.html @@ -273,11 +273,11 @@ Será enviada a mensagem Tramitação efetivada com sucesso!
      Acione a função Continuar repetir a operação para outras tramitações ou Voltar para retornar para tela inicial do sistema.


      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/tramitacao_relatoria.html b/sapl/templates/ajuda/tramitacao_relatoria.html index 394232ada..e6afd58d7 100644 --- a/sapl/templates/ajuda/tramitacao_relatoria.html +++ b/sapl/templates/ajuda/tramitacao_relatoria.html @@ -370,11 +370,11 @@ retorna à tela com os dados da matéria legislativa selecionada.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/troca_senha.html b/sapl/templates/ajuda/troca_senha.html index 8b4edf79b..54e807205 100644 --- a/sapl/templates/ajuda/troca_senha.html +++ b/sapl/templates/ajuda/troca_senha.html @@ -70,11 +70,11 @@ informações sejam salvas no arquivo.
      Será enviada a mensagem !Senha salva com sucesso!

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      diff --git a/sapl/templates/ajuda/unidade_tramitacao.html b/sapl/templates/ajuda/unidade_tramitacao.html index 71aa1d0cd..982007dd1 100644 --- a/sapl/templates/ajuda/unidade_tramitacao.html +++ b/sapl/templates/ajuda/unidade_tramitacao.html @@ -1,5 +1,5 @@ {% extends "base.html" %} -{% load "i18n" %} +{% load i18n %} {% block base_content %} From a2f768fb9f407a497e9e4afbd3b7d7bc33fc88a4 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Thu, 5 Oct 2017 16:15:57 -0300 Subject: [PATCH 097/237] Corrige imports --- sapl/base/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index 7c80dcbc3..8bf64b8e9 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -7,12 +7,13 @@ from django.core.exceptions import ObjectDoesNotExist from django.core.mail import send_mail from django.core.urlresolvers import reverse from django.db.models import Count -from django.http import HttpResponseRedirect +from django.http import HttpResponseRedirect, Http404 from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import TemplateView from django_filters.views import FilterView +from django.template import TemplateDoesNotExist from django.template.loader import get_template from haystack.views import SearchView From a70fdd8b0d1ae9aba22da40b5e8973414181f887 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Mon, 9 Oct 2017 14:52:41 -0300 Subject: [PATCH 098/237] =?UTF-8?q?Corrige=20os=20links=20em=20unidade=20d?= =?UTF-8?q?e=20tramita=C3=A7=C3=A3o=20e=20numera=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/templates/ajuda/numeracao_docsacess.html | 2 +- sapl/templates/ajuda/unidade_tramitacao.html | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sapl/templates/ajuda/numeracao_docsacess.html b/sapl/templates/ajuda/numeracao_docsacess.html index 24e37d451..be184de3f 100644 --- a/sapl/templates/ajuda/numeracao_docsacess.html +++ b/sapl/templates/ajuda/numeracao_docsacess.html @@ -546,7 +546,7 @@ Acessórios, acione a função
      Anterior | - Índice + Índice | Próxima diff --git a/sapl/templates/ajuda/unidade_tramitacao.html b/sapl/templates/ajuda/unidade_tramitacao.html index 982007dd1..00f03cbfd 100644 --- a/sapl/templates/ajuda/unidade_tramitacao.html +++ b/sapl/templates/ajuda/unidade_tramitacao.html @@ -120,11 +120,11 @@ retorna a tela com a relação de unidade de tramitação já cadastrada.

      - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
      From 3ee55df65e3bdda5adc1fd8a48d1732f52929df5 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Mon, 9 Oct 2017 15:21:50 -0300 Subject: [PATCH 099/237] =?UTF-8?q?Corrige=20links=20de=20sessao=20plenari?= =?UTF-8?q?a=20vota=C3=A7=C3=A3o=20e=20sess=C3=A3o=20plenaria=20presen?= =?UTF-8?q?=C3=A7a=20ordem=20do=20dia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html | 2 +- sapl/templates/ajuda/sessao_plenaria_votacao.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html b/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html index b25990eb9..7f40eed53 100644 --- a/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html +++ b/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html @@ -13,7 +13,7 @@
      Para isso, o sistema apresenta uma lista dos parlamentares bastando assinalar - com um clique do mouse - no quadro, que se encontra a esquerda do nome de cada parlamentar, a presença na Ordem do Dia e, ao final, acionar o botão 'Salvar'.

      Para excluir o parlamentar da lista de presenças basta desmarcar - com um clique do mouse - o quadro correspondente ao nome do parlamentar e acionar o botão 'Salvar'.

      O sistema irá exibir a mensagem !Lista de presença da Ordem do Dia cadastrada com sucesso!.
      -
      Para a execução desta função serão necessários que os Parlamentares bem como os Tipos de Sessão Plenária - em tabelas auxiliares, estejam previamente cadastrados.
      +
      Para a execução desta função serão necessários que os Parlamentares bem como os Tipos de Sessão Plenária - em tabelas auxiliares, estejam previamente cadastrados.


      Anterior | diff --git a/sapl/templates/ajuda/sessao_plenaria_votacao.html b/sapl/templates/ajuda/sessao_plenaria_votacao.html index a89db3be3..ac0a913b6 100644 --- a/sapl/templates/ajuda/sessao_plenaria_votacao.html +++ b/sapl/templates/ajuda/sessao_plenaria_votacao.html @@ -20,7 +20,7 @@ Índice - | Próxima + | Próxima

      From dee5744d92daa0414d47bad3874548b24b2a39be Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Mon, 9 Oct 2017 16:14:24 -0300 Subject: [PATCH 100/237] Bug fix --- sapl/sessao/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 1d92772d4..5588bccfc 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -165,8 +165,7 @@ def customize_link_materia(context): numeracao = materia.numeracao_set.first() autoria = materia.autoria_set.filter( primeiro_autor=True).first() - if autoria: - autor = autoria.autor + autor = autoria.autor if autoria else None num_protocolo = materia.numero_protocolo title_materia = '''%s
      From 2154a15a704f2087e4d0f77fdb94da1ca8e441a0 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 9 Oct 2017 16:17:22 -0300 Subject: [PATCH 101/237] Novo release: 3.1.25-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3b388dc7d..ef3470595 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.24-BETA + image: interlegis/sapl:3.1.25-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index 8fa9eef5c..efa274375 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.24-BETA', + version='3.1.25-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From f7d531004f7b2921dafa7013923aebe8ed329b2e Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Mon, 9 Oct 2017 18:16:09 -0300 Subject: [PATCH 102/237] =?UTF-8?q?Conserta=20bug=20em=20Pauta=20de=20Sess?= =?UTF-8?q?=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/views.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 5588bccfc..44174abde 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -2291,7 +2291,11 @@ class PautaSessaoDetailView(DetailView): ementa = m.materia.ementa titulo = m.materia numero = m.numero_ordem - situacao = m.materia.tramitacao_set.last().status + + ultima_tramitacao = m.materia.tramitacao_set.last() + + situacao = ultima_tramitacao.status if ultima_tramitacao else None + if situacao is None: situacao = _("Não informada") rv = m.registrovotacao_set.all() @@ -2348,7 +2352,11 @@ class PautaSessaoDetailView(DetailView): ementa = o.materia.ementa titulo = o.materia numero = o.numero_ordem - situacao = o.materia.tramitacao_set.last().status + + ultima_tramitacao = o.materia.tramitacao_set.last() + + situacao = ultima_tramitacao.status if ultima_tramitacao else None + if situacao is None: situacao = _("Não informada") # Verificar resultado From ca7a7c61472a3ce59d9da859f8ebc24cf17cb40d Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 9 Oct 2017 19:25:56 -0300 Subject: [PATCH 103/237] Adiciona logs a gunicorn (#1526) --- Dockerfile | 3 ++- gunicorn_start.sh | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 42ed97c71..cb4713a31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ RUN apk add --no-cache python3 nginx tzdata && \ rm -f /etc/nginx/conf.d/* RUN mkdir -p /var/interlegis/sapl && \ + mkdir /var/log/gunicorn \ apk add --update --no-cache $BUILD_PACKAGES && \ npm install -g bower && \ npm cache clean @@ -41,7 +42,7 @@ RUN python3 manage.py bower_install -- --allow-root --no-input && \ python3 manage.py compilescss RUN python3 manage.py collectstatic --noinput --clear - + # Remove .env(fake) e sapl.db da imagem RUN rm -rf /var/interlegis/sapl/sapl/.env && \ rm -rf /var/interlegis/sapl/sapl.db diff --git a/gunicorn_start.sh b/gunicorn_start.sh index 79666cf19..dd05a3a0e 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -23,7 +23,7 @@ DJANGO_WSGI_MODULE=sapl.wsgi # WSGI module name (*) echo "Starting $NAME as `whoami` on base dir $SAPL_DIR" -# parameter can be passed to run without virtualenv +# parameter can be passed to run without virtualenv if [[ "$@" != "no-venv" ]]; then # Activate the virtual environment cd $DJANGODIR @@ -42,4 +42,6 @@ exec gunicorn ${DJANGO_WSGI_MODULE}:application \ --name $NAME \ --workers $NUM_WORKERS \ --user $USER \ + --access-logfile /var/log/gunicorn/gunicorn-access.log \ + --error-logfile /var/log/gunicorn/gunicorn-error.log \ --bind=unix:$SOCKFILE From 31ff21f748a1ab7282935d54770514236d448dd3 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 10 Oct 2017 12:53:18 -0300 Subject: [PATCH 104/237] Remove temporariamente links de ajuda --- sapl/templates/base.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sapl/templates/base.html b/sapl/templates/base.html index 554f08756..09f49c3a5 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -55,7 +55,7 @@
    -
  • +{#
  • #} {% if not user.is_authenticated %}
  • {% else %} @@ -135,9 +135,9 @@
    {% block help %} - {% if view.help_path %} - {% trans 'Ajuda' %} - {% endif %} +{# {% if view.help_path %}#} +{# {% trans 'Ajuda' %}#} +{# {% endif %}#} {% endblock %} {% block title %} From e4cb078e0e65ec1a843f6e5e5a7fdb8ed361cbeb Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 10 Oct 2017 14:42:10 -0300 Subject: [PATCH 105/237] Fix #1525 --- .../migrations/0011_auto_20171010_1433.py | 20 +++++++++++++++++++ sapl/parlamentares/models.py | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 sapl/parlamentares/migrations/0011_auto_20171010_1433.py diff --git a/sapl/parlamentares/migrations/0011_auto_20171010_1433.py b/sapl/parlamentares/migrations/0011_auto_20171010_1433.py new file mode 100644 index 000000000..bba5cfc99 --- /dev/null +++ b/sapl/parlamentares/migrations/0011_auto_20171010_1433.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.3 on 2017-10-10 17:33 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('parlamentares', '0010_corrige_data_inicio_mandato'), + ] + + operations = [ + migrations.AlterField( + model_name='mandato', + name='data_inicio_mandato', + field=models.DateField(null=True, verbose_name='Início do Mandato'), + ), + ] diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index 64ae92c8e..36b19158b 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -453,7 +453,7 @@ class Mandato(models.Model): # TODO what is this field?????? tipo_causa_fim_mandato = models.PositiveIntegerField(blank=True, null=True) data_inicio_mandato = models.DateField(verbose_name=_('Início do Mandato'), - blank=True, + blank=False, null=True) data_fim_mandato = models.DateField(verbose_name=_('Fim do Mandato'), blank=True, From c6e9091cc4b2b60ad5a029371146a42b5df40fd5 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 10 Oct 2017 15:20:50 -0300 Subject: [PATCH 106/237] Retira redirect para arquivo e conserta erro em Dockerfile --- Dockerfile | 4 +++- gunicorn_start.sh | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index cb4713a31..7ffb05c30 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,11 +12,13 @@ RUN apk add --no-cache python3 nginx tzdata && \ rm -f /etc/nginx/conf.d/* RUN mkdir -p /var/interlegis/sapl && \ - mkdir /var/log/gunicorn \ apk add --update --no-cache $BUILD_PACKAGES && \ npm install -g bower && \ npm cache clean +#RUN ln -sf /proc/self/fd/1 /var/log/gunicorn/gunicorn-access.log && \ +# ln -sf /proc/self/fd/1 /var/log/gunicorn/gunicorn-error.log + WORKDIR /var/interlegis/sapl/ ADD . /var/interlegis/sapl/ diff --git a/gunicorn_start.sh b/gunicorn_start.sh index dd05a3a0e..6b5c98676 100755 --- a/gunicorn_start.sh +++ b/gunicorn_start.sh @@ -42,6 +42,6 @@ exec gunicorn ${DJANGO_WSGI_MODULE}:application \ --name $NAME \ --workers $NUM_WORKERS \ --user $USER \ - --access-logfile /var/log/gunicorn/gunicorn-access.log \ - --error-logfile /var/log/gunicorn/gunicorn-error.log \ + --access-logfile - \ + --error-logfile - \ --bind=unix:$SOCKFILE From be472437a707e1ba8668d6d07cf9e559a3af2f32 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 10 Oct 2017 15:22:58 -0300 Subject: [PATCH 107/237] =?UTF-8?q?Retira=20linha=20desnecess=C3=A1ria=20e?= =?UTF-8?q?m=20Dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7ffb05c30..fbbd8575d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,9 +16,6 @@ RUN mkdir -p /var/interlegis/sapl && \ npm install -g bower && \ npm cache clean -#RUN ln -sf /proc/self/fd/1 /var/log/gunicorn/gunicorn-access.log && \ -# ln -sf /proc/self/fd/1 /var/log/gunicorn/gunicorn-error.log - WORKDIR /var/interlegis/sapl/ ADD . /var/interlegis/sapl/ From 9bcd62520ac60189437b083208c097be4593a7e2 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 10 Oct 2017 15:17:23 -0300 Subject: [PATCH 108/237] =?UTF-8?q?Ajusta=20urls=20de=20ajuda=20para=20pad?= =?UTF-8?q?r=C3=A3o=20rest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #470 Retorna 404 para páginas de ajuda inexistentes --- sapl/base/urls.py | 9 +- sapl/base/views.py | 25 ++- sapl/templates/ajuda.html | 172 +++++++++--------- sapl/templates/ajuda/acessando_alimenta.html | 30 +-- sapl/templates/ajuda/acomp_materia.html | 4 +- sapl/templates/ajuda/anexos.html | 2 +- sapl/templates/ajuda/autor.html | 4 +- sapl/templates/ajuda/cadastro_comissoes.html | 4 +- sapl/templates/ajuda/cadastro_materia.html | 20 +- .../ajuda/cadastro_mesa_diretora.html | 4 +- .../ajuda/cadastro_parlamentares.html | 10 +- sapl/templates/ajuda/cargo_comissao.html | 4 +- sapl/templates/ajuda/cargo_mesa.html | 4 +- sapl/templates/ajuda/casa_legislativa.html | 4 +- sapl/templates/ajuda/coligacao.html | 4 +- sapl/templates/ajuda/consultas.html | 18 +- sapl/templates/ajuda/dependentes.html | 4 +- sapl/templates/ajuda/despacho_autoria.html | 4 +- sapl/templates/ajuda/envio_proposicao.html | 4 +- .../ajuda/filiacoes_partidarias.html | 4 +- sapl/templates/ajuda/fim_relatoria.html | 4 +- .../ajuda/gerenciamento_usuarios.html | 4 +- sapl/templates/ajuda/glossario.html | 4 +- .../ajuda/legislacao_cita_matanexada.html | 4 +- sapl/templates/ajuda/legislatura.html | 4 +- sapl/templates/ajuda/lexml.html | 2 +- .../templates/ajuda/mandatos_parlamentar.html | 4 +- sapl/templates/ajuda/materia_anexada.html | 4 +- sapl/templates/ajuda/modulo_comissoes.html | 18 +- .../templates/ajuda/modulo_mesa_diretora.html | 14 +- .../ajuda/modulo_norma_juridica.html | 6 +- .../templates/ajuda/modulo_parlamentares.html | 16 +- .../ajuda/modulo_tramitacao_materias.html | 30 +-- sapl/templates/ajuda/nivel_instrucao.html | 4 +- sapl/templates/ajuda/norma_juridica.html | 4 +- sapl/templates/ajuda/numeracao_docsacess.html | 4 +- sapl/templates/ajuda/ordem_dia.html | 4 +- sapl/templates/ajuda/orgao.html | 4 +- sapl/templates/ajuda/origem.html | 4 +- sapl/templates/ajuda/partidos.html | 4 +- .../ajuda/periodo_composicao_comissao.html | 4 +- sapl/templates/ajuda/proposicao.html | 4 +- sapl/templates/ajuda/proposicao_editor.html | 4 +- .../ajuda/proposicao_legislativa.html | 4 +- .../ajuda/protocolo_administrativo.html | 30 +-- sapl/templates/ajuda/protocolo_anular.html | 30 +-- sapl/templates/ajuda/protocolo_geral.html | 6 +- .../protocolo_gerar_etiqueta_processo.html | 30 +-- .../protocolo_gerar_etiqueta_protocolo.html | 30 +-- .../ajuda/protocolo_legislativo.html | 30 +-- .../ajuda/recebimento_proposicao.html | 4 +- sapl/templates/ajuda/regime_tramitacao.html | 4 +- sapl/templates/ajuda/sessao_legislativa.html | 4 +- sapl/templates/ajuda/sessao_plenaria.html | 32 ++-- sapl/templates/ajuda/sessao_plenaria_ata.html | 4 +- .../ajuda/sessao_plenaria_expedientes.html | 4 +- ...sessao_plenaria_lista_presenca_sessao.html | 4 +- .../sessao_plenaria_materias_expediente.html | 4 +- .../sessao_plenaria_materias_ordem_dia.html | 4 +- .../templates/ajuda/sessao_plenaria_mesa.html | 4 +- .../ajuda/sessao_plenaria_oradores.html | 4 +- .../sessao_plenaria_oradores_expediente.html | 4 +- ...lenaria_oradores_explicacoes_pessoais.html | 4 +- .../sessao_plenaria_presenca_ordem_dia.html | 6 +- .../ajuda/sessao_plenaria_votacao.html | 4 +- sapl/templates/ajuda/status_tramitacao.html | 4 +- sapl/templates/ajuda/tipo_afastamento.html | 4 +- sapl/templates/ajuda/tipo_autor.html | 4 +- sapl/templates/ajuda/tipo_comissao.html | 4 +- sapl/templates/ajuda/tipo_dependente.html | 4 +- sapl/templates/ajuda/tipo_documento.html | 4 +- .../ajuda/tipo_materia_legislativa.html | 4 +- sapl/templates/ajuda/tipo_norma_juridica.html | 4 +- sapl/templates/ajuda/tipo_proposicao.html | 4 +- sapl/templates/ajuda/tipo_situa_militar.html | 4 +- sapl/templates/ajuda/tramitacao_lote.html | 4 +- .../templates/ajuda/tramitacao_relatoria.html | 4 +- sapl/templates/ajuda/troca_senha.html | 4 +- sapl/templates/ajuda/unidade_tramitacao.html | 4 +- sapl/templates/base.html | 2 +- 80 files changed, 395 insertions(+), 401 deletions(-) diff --git a/sapl/base/urls.py b/sapl/base/urls.py index 6273b9912..d45532d0a 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -54,13 +54,10 @@ urlpatterns = [ url(r'^sistema/autor/tipo/', include(TipoAutorCrud.get_urls())), url(r'^sistema/autor/', include(AutorCrud.get_urls())), - url(r'^sistema/ajuda/', TemplateView.as_view(template_name='ajuda.html'), - name='help'), - url(r'^sistema/ajuda-topico/$', + url(r'^sistema/ajuda/(?P\w+)$', HelpTopicView.as_view(), name='help_topic'), - url(r'^sistema/ajuda/', - TemplateView.as_view(template_name='ajuda/index.html'), - name='help_base'), + url(r'^sistema/ajuda/$', TemplateView.as_view(template_name='ajuda.html'), + name='help'), url(r'^sistema/casa-legislativa/', include(CasaLegislativaCrud.get_urls()), name="casa_legislativa"), url(r'^sistema/app-config/', include(AppConfigCrud.get_urls())), diff --git a/sapl/base/views.py b/sapl/base/views.py index 8bf64b8e9..f1474ae4a 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -7,14 +7,14 @@ from django.core.exceptions import ObjectDoesNotExist from django.core.mail import send_mail from django.core.urlresolvers import reverse from django.db.models import Count -from django.http import HttpResponseRedirect, Http404 +from django.http import Http404, HttpResponseRedirect +from django.template import TemplateDoesNotExist +from django.template.loader import get_template from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import TemplateView from django_filters.views import FilterView -from django.template import TemplateDoesNotExist -from django.template.loader import get_template from haystack.views import SearchView from sapl.base.forms import AutorForm, AutorFormForAdmin, TipoAutorForm @@ -475,6 +475,7 @@ class CasaLegislativaCrud(CrudAux): form_class = CasaLegislativaForm class ListView(CrudAux.ListView): + def get(self, request, *args, **kwargs): casa = get_casalegislativa() if casa: @@ -494,18 +495,14 @@ class CasaLegislativaCrud(CrudAux): class HelpTopicView(TemplateView): - def get_template_names(self): - if 'topic' in self.request.GET and self.request.GET['topic']: - return ['ajuda/%s.html' % self.request.GET['topic']] - else: - return HttpResponseRedirect(reverse('sapl.base:help')) - def get_template(self): - if 'topic' in self.request.GET and self.request.GET['topic']: - try: - get_template('ajuda/%s.html' % self.request.GET['topic']) - except TemplateDoesNotExist: - raise Http404() + def get_template_names(self): + topico = self.kwargs['topic'] + try: + get_template('ajuda/%s.html' % topico) + except TemplateDoesNotExist: + raise Http404() + return ['ajuda/%s.html' % topico] class AppConfigCrud(CrudAux): diff --git a/sapl/templates/ajuda.html b/sapl/templates/ajuda.html index 2256f8f05..f98ef61b8 100644 --- a/sapl/templates/ajuda.html +++ b/sapl/templates/ajuda.html @@ -7,141 +7,141 @@
    diff --git a/sapl/templates/ajuda/acessando_alimenta.html b/sapl/templates/ajuda/acessando_alimenta.html index 278f346f9..4f888bb30 100644 --- a/sapl/templates/ajuda/acessando_alimenta.html +++ b/sapl/templates/ajuda/acessando_alimenta.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



    @@ -50,7 +50,7 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

    - Anterior | + Anterior | Índice diff --git a/sapl/templates/ajuda/acomp_materia.html b/sapl/templates/ajuda/acomp_materia.html index c53123a8a..766e40c94 100644 --- a/sapl/templates/ajuda/acomp_materia.html +++ b/sapl/templates/ajuda/acomp_materia.html @@ -24,11 +24,11 @@ poderá ser feito clicando-se no link apropriado, que consta no e-mail rec informando sobre a movimentação da matéria.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/anexos.html b/sapl/templates/ajuda/anexos.html index e387b97ab..cb073465e 100644 --- a/sapl/templates/ajuda/anexos.html +++ b/sapl/templates/ajuda/anexos.html @@ -90,7 +90,7 @@ banco de dados.
    Qualquer dúvida, entre em contato conosco.

    - Anterior | + Anterior | Índice diff --git a/sapl/templates/ajuda/autor.html b/sapl/templates/ajuda/autor.html index b174e392d..13efa4e29 100644 --- a/sapl/templates/ajuda/autor.html +++ b/sapl/templates/ajuda/autor.html @@ -163,11 +163,11 @@ retorna a tela com a relação de autores já cadastrado.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/cadastro_comissoes.html b/sapl/templates/ajuda/cadastro_comissoes.html index 787c42d5e..76b2b68b2 100644 --- a/sapl/templates/ajuda/cadastro_comissoes.html +++ b/sapl/templates/ajuda/cadastro_comissoes.html @@ -601,11 +601,11 @@ A função “Início” retorna a tela de cadastramento da Comissão.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/cadastro_materia.html b/sapl/templates/ajuda/cadastro_materia.html index 030fbb264..aaaaaf062 100644 --- a/sapl/templates/ajuda/cadastro_materia.html +++ b/sapl/templates/ajuda/cadastro_materia.html @@ -504,22 +504,22 @@ inicial do sistema.
    Selecione a Matéria já cadastrada para continuar alimentando as outras informações sobre a matéria tais como: - Despacho Inicial, -Autoria, -Legislação Citada, -Anexada, -Tramitação, -Relatoria, -Numeração e - Documentos Acessórios. + Despacho Inicial, +Autoria, +Legislação Citada, +Anexada, +Tramitação, +Relatoria, +Numeração e + Documentos Acessórios.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/cadastro_mesa_diretora.html b/sapl/templates/ajuda/cadastro_mesa_diretora.html index 075968215..a0b658b78 100644 --- a/sapl/templates/ajuda/cadastro_mesa_diretora.html +++ b/sapl/templates/ajuda/cadastro_mesa_diretora.html @@ -75,11 +75,11 @@ Acione a função Continuar para repetir a operação para outros parlamentares.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/cadastro_parlamentares.html b/sapl/templates/ajuda/cadastro_parlamentares.html index 6aab5c2f1..1818c5218 100644 --- a/sapl/templates/ajuda/cadastro_parlamentares.html +++ b/sapl/templates/ajuda/cadastro_parlamentares.html @@ -463,16 +463,16 @@ Quando for informado OK será enviada a mensagem !Parlamentar excluído com sucesso!
    Selecione um Parlamentar já cadastrado para continuar alimentando outras informações tais como: -Mandato, -Filiação Partidária e -Dependente.
    +Mandato, +Filiação Partidária e +Dependente.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/cargo_comissao.html b/sapl/templates/ajuda/cargo_comissao.html index f780587c0..53db3dbc4 100644 --- a/sapl/templates/ajuda/cargo_comissao.html +++ b/sapl/templates/ajuda/cargo_comissao.html @@ -49,11 +49,11 @@ Quando for informado OK será enviada a mensagem !Cargo Comissão excluído com sucesso!.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/cargo_mesa.html b/sapl/templates/ajuda/cargo_mesa.html index 6ecdbc6e6..2abe38ab7 100644 --- a/sapl/templates/ajuda/cargo_mesa.html +++ b/sapl/templates/ajuda/cargo_mesa.html @@ -51,11 +51,11 @@ Quando for informado OK será enviada a mensagem !Cargo excluído com sucesso!

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/casa_legislativa.html b/sapl/templates/ajuda/casa_legislativa.html index 1504a990f..4472b16a7 100644 --- a/sapl/templates/ajuda/casa_legislativa.html +++ b/sapl/templates/ajuda/casa_legislativa.html @@ -220,11 +220,11 @@ A Busca por palavra chave só pesquisa o cadastro de matérias legis Quando a pesquisa é realizada dentro do módulo de atualização das informações, o operador tem a possibilidade de fazer alterações nas informações das matérias que resultou da pesquisa.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/coligacao.html b/sapl/templates/ajuda/coligacao.html index 4b66b49ab..56c23227b 100644 --- a/sapl/templates/ajuda/coligacao.html +++ b/sapl/templates/ajuda/coligacao.html @@ -173,11 +173,11 @@ retorna a tela com a relação de Coligações já cadastradas.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/consultas.html b/sapl/templates/ajuda/consultas.html index 7008adb52..66e9574b8 100644 --- a/sapl/templates/ajuda/consultas.html +++ b/sapl/templates/ajuda/consultas.html @@ -108,9 +108,9 @@ Parlamentar.
    Ao selecionar este módulo Protocolo Geral é exibida uma tela com o seguinte menu de opções:


    Também, apresenta uma tela com campos a serem preenchidos com argumentos de pesquisa sobre registros de protocolo.

    @@ -176,11 +176,11 @@ Ex: Para que se possa encontrar protocolos que mencionem a palavra 'asfalto' no Apresenta o resultado da pesquisa feita. Além disso, exibe o seguinte menu de opções:


    O conteúdo a seguir é a lista do resultado da pesquisa feita.

    @@ -709,7 +709,7 @@ Preenchimento

    Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/dependentes.html b/sapl/templates/ajuda/dependentes.html index 4913dae26..336408889 100644 --- a/sapl/templates/ajuda/dependentes.html +++ b/sapl/templates/ajuda/dependentes.html @@ -166,11 +166,11 @@ A função “Início” retorna a tela com os dados básicos do parlamentar.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/despacho_autoria.html b/sapl/templates/ajuda/despacho_autoria.html index 771617a6d..f1e2ff2b8 100644 --- a/sapl/templates/ajuda/despacho_autoria.html +++ b/sapl/templates/ajuda/despacho_autoria.html @@ -173,11 +173,11 @@ retorna a tela com a relação de autores já designados para a matéria.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/envio_proposicao.html b/sapl/templates/ajuda/envio_proposicao.html index 36aba5097..b943dc469 100644 --- a/sapl/templates/ajuda/envio_proposicao.html +++ b/sapl/templates/ajuda/envio_proposicao.html @@ -144,11 +144,11 @@ no campo subjacente, ou clique no botão

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/filiacoes_partidarias.html b/sapl/templates/ajuda/filiacoes_partidarias.html index 319ed9fa8..87bdc2e3f 100644 --- a/sapl/templates/ajuda/filiacoes_partidarias.html +++ b/sapl/templates/ajuda/filiacoes_partidarias.html @@ -131,11 +131,11 @@ A função “Início” retorna a tela com os dados básicos do parlamentar.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/fim_relatoria.html b/sapl/templates/ajuda/fim_relatoria.html index 92a71b049..932f576a9 100644 --- a/sapl/templates/ajuda/fim_relatoria.html +++ b/sapl/templates/ajuda/fim_relatoria.html @@ -35,11 +35,11 @@ excluído com sucesso sem pergunta de confirmação.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/gerenciamento_usuarios.html b/sapl/templates/ajuda/gerenciamento_usuarios.html index 735b85ccd..6fd87ce76 100644 --- a/sapl/templates/ajuda/gerenciamento_usuarios.html +++ b/sapl/templates/ajuda/gerenciamento_usuarios.html @@ -249,11 +249,11 @@ manutenção.



    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/glossario.html b/sapl/templates/ajuda/glossario.html index d26671b1d..3a1d6eccd 100644 --- a/sapl/templates/ajuda/glossario.html +++ b/sapl/templates/ajuda/glossario.html @@ -51,11 +51,11 @@ localização de informações específicas. (Dicionário Aurélio).

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/legislacao_cita_matanexada.html b/sapl/templates/ajuda/legislacao_cita_matanexada.html index 7558f26a7..9bc4af6c5 100644 --- a/sapl/templates/ajuda/legislacao_cita_matanexada.html +++ b/sapl/templates/ajuda/legislacao_cita_matanexada.html @@ -292,11 +292,11 @@ A função “Início” retorna a tela com os dados da matéria legislativa selecionada.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/legislatura.html b/sapl/templates/ajuda/legislatura.html index 91a8896a6..2ab59f6ca 100644 --- a/sapl/templates/ajuda/legislatura.html +++ b/sapl/templates/ajuda/legislatura.html @@ -129,11 +129,11 @@ Quando for informado OK será enviada a mensagem !Legislatura excluída com sucesso!

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/lexml.html b/sapl/templates/ajuda/lexml.html index 3fc8d0d16..f37122f66 100644 --- a/sapl/templates/ajuda/lexml.html +++ b/sapl/templates/ajuda/lexml.html @@ -20,7 +20,7 @@ Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/mandatos_parlamentar.html b/sapl/templates/ajuda/mandatos_parlamentar.html index c36f8aecc..66ffc9308 100644 --- a/sapl/templates/ajuda/mandatos_parlamentar.html +++ b/sapl/templates/ajuda/mandatos_parlamentar.html @@ -194,11 +194,11 @@ A função “Início” retorna a tela com os dados básicos do parlamentar.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/materia_anexada.html b/sapl/templates/ajuda/materia_anexada.html index 99167678d..031c43227 100644 --- a/sapl/templates/ajuda/materia_anexada.html +++ b/sapl/templates/ajuda/materia_anexada.html @@ -177,11 +177,11 @@ retorna a tela com os dados da matéria legislativa selecionada.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/modulo_comissoes.html b/sapl/templates/ajuda/modulo_comissoes.html index e9a3884b1..a469e9bef 100644 --- a/sapl/templates/ajuda/modulo_comissoes.html +++ b/sapl/templates/ajuda/modulo_comissoes.html @@ -17,14 +17,14 @@ esta transação, que são:
    - Tabelas Auxiliares



    @@ -37,11 +37,11 @@ data a partir da qual ela ficou inativa; devendo, nesse caso, ser posterior a da A exclusão da comissão somente será possível se não tiver havido qualquer tramitação de matéria para ela. Então, deve-se exclui-la antes da tabela de unidades de tramitação.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/modulo_mesa_diretora.html b/sapl/templates/ajuda/modulo_mesa_diretora.html index c29e97648..5b2cce0ca 100644 --- a/sapl/templates/ajuda/modulo_mesa_diretora.html +++ b/sapl/templates/ajuda/modulo_mesa_diretora.html @@ -16,20 +16,20 @@ transação, que são:
    - Tabelas Auxiliares



    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/modulo_norma_juridica.html b/sapl/templates/ajuda/modulo_norma_juridica.html index 03dc7d8d5..c8662e517 100644 --- a/sapl/templates/ajuda/modulo_norma_juridica.html +++ b/sapl/templates/ajuda/modulo_norma_juridica.html @@ -16,16 +16,16 @@ transação, que são:

    - Tabela Auxiliar


    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/modulo_parlamentares.html b/sapl/templates/ajuda/modulo_parlamentares.html index a007de397..0e5770641 100644 --- a/sapl/templates/ajuda/modulo_parlamentares.html +++ b/sapl/templates/ajuda/modulo_parlamentares.html @@ -17,23 +17,23 @@ transação, que são:
    - Tabelas Auxiliares


    Anterior | - Índice + Índice | Próxima diff --git a/sapl/templates/ajuda/modulo_tramitacao_materias.html b/sapl/templates/ajuda/modulo_tramitacao_materias.html index 439b9896a..81fc0c978 100644 --- a/sapl/templates/ajuda/modulo_tramitacao_materias.html +++ b/sapl/templates/ajuda/modulo_tramitacao_materias.html @@ -19,40 +19,40 @@ esta transação, que são:
    - Tabelas Auxiliares



    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/nivel_instrucao.html b/sapl/templates/ajuda/nivel_instrucao.html index 709accfee..84372818a 100644 --- a/sapl/templates/ajuda/nivel_instrucao.html +++ b/sapl/templates/ajuda/nivel_instrucao.html @@ -43,11 +43,11 @@ instrução  foi excluído com sucesso sem pergunta de confirmação.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/norma_juridica.html b/sapl/templates/ajuda/norma_juridica.html index 979ee0cf5..dd4e84ed8 100644 --- a/sapl/templates/ajuda/norma_juridica.html +++ b/sapl/templates/ajuda/norma_juridica.html @@ -331,11 +331,11 @@ Quando for informado OK será enviada a mensagem !Norma Jurídica excluída com sucesso!

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/numeracao_docsacess.html b/sapl/templates/ajuda/numeracao_docsacess.html index be184de3f..0e932e08c 100644 --- a/sapl/templates/ajuda/numeracao_docsacess.html +++ b/sapl/templates/ajuda/numeracao_docsacess.html @@ -544,11 +544,11 @@ Acessórios, acione a função “Documentos Acessórios”.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/ordem_dia.html b/sapl/templates/ajuda/ordem_dia.html index adf2fcdcf..bdf59ef8c 100644 --- a/sapl/templates/ajuda/ordem_dia.html +++ b/sapl/templates/ajuda/ordem_dia.html @@ -162,11 +162,11 @@ Quando for informado OK será enviada a mensagem !Matéria excluída com sucesso da ordem do dia!

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/orgao.html b/sapl/templates/ajuda/orgao.html index 8e1a723c3..ce3dae02b 100644 --- a/sapl/templates/ajuda/orgao.html +++ b/sapl/templates/ajuda/orgao.html @@ -141,11 +141,11 @@ retorna a tela com a relação de órgãos já cadastrados.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/origem.html b/sapl/templates/ajuda/origem.html index 69ae44abc..f3f4ba5f7 100644 --- a/sapl/templates/ajuda/origem.html +++ b/sapl/templates/ajuda/origem.html @@ -89,11 +89,11 @@ retorna a tela com a relação de origem já cadastrada.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/partidos.html b/sapl/templates/ajuda/partidos.html index 1f3bf6740..ed75351a8 100644 --- a/sapl/templates/ajuda/partidos.html +++ b/sapl/templates/ajuda/partidos.html @@ -124,11 +124,11 @@ retorna à tela com a relação de Partidos já cadastrados.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/periodo_composicao_comissao.html b/sapl/templates/ajuda/periodo_composicao_comissao.html index 5d449d1d9..c93feb4bf 100644 --- a/sapl/templates/ajuda/periodo_composicao_comissao.html +++ b/sapl/templates/ajuda/periodo_composicao_comissao.html @@ -103,11 +103,11 @@ retorna a tela com a relação de períodos de comissão já cadastradas.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/proposicao.html b/sapl/templates/ajuda/proposicao.html index 8d43c2726..bc5f2c926 100644 --- a/sapl/templates/ajuda/proposicao.html +++ b/sapl/templates/ajuda/proposicao.html @@ -10,11 +10,11 @@

    Proposição - elaboração / atualização

    A tela exibe um conjunto de dados básicos para a elaboração de uma nova proposição ou de um documento acessório. No caso de uma proposição ou se um documento estiver sido consultado, o sapl permitirá a sua atualização . Os dados básicos são os seguintes:

    Tipo - combo para a seleção do tipo de proposição legislativa ou documento acessório.

    Descrição - deve conter uma breve descrição sobre a proposição ou documento que está sendo elaborado ou atualizado.

    Matéria Legislativa, número e ano - essas informações somente deverão ser indicadas quando tratar-se de um documento do tipo parecer, caso contrário, o sistema mantém os respectivos campos inibidos, ou seja, sem acesso. Caso tenham que ser informados, a matéria legislativa já deverá ter sido cadastrada no sistema.

    Criar texto em XML ou Carregar Arquivo Externo - indicar assinalando uma das opções. Caso seja indicada a opção - Criar texto em XML - o sapl irá disponibilizar um editor de textos - orientado por um modelo próprio, o qual deve ter sido previamente associado - para o tipo de documento a ser digitado, ou seja, com a formatação final que foi previamente ajustada para o tipo de documento. Se a segunda opção for a indicada, então o sapl irá habilitar o botão Arquivo de modo a permitir realizar a carga de um documento previamente digitado; e, neste caso, não entrará no mérito do modelo e nem da respectiva folha de estilo - formato final - do documento uploaded.

    Ao final, deve ser acionado o botão salvar dados básicos e criar texto integral para dar seguimento a execução da função. Se a opção foi a de criar o texto, o sapl abrirá o editor de textos para que o documento seja digitado. No caso do upload de documento já digitado, a função emitirá mensagem de finalização e de envio para protocolo informando o número de identificação gerado de modo automático.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/proposicao_editor.html b/sapl/templates/ajuda/proposicao_editor.html index 098af1883..054c61aaf 100644 --- a/sapl/templates/ajuda/proposicao_editor.html +++ b/sapl/templates/ajuda/proposicao_editor.html @@ -10,11 +10,11 @@

    Proposição - edição / atualização

    A tela exibe um conjunto de dados básicos para a atualização da proposição ou documento acessório. A seguir, as situações possíveis:

    - Proposição ainda não enviada - Neste caso o autor tem disponível as seguintes ações: Editar o Texto Integral, sendo que, antes da edição, os dados básicos eventualmente modificados devem ser salvos; retornar a tela anterior, clicando em Início; clicar em Salvar para salvar os dados básicos; ou, clicar em Excluir para excluir a proposição ou o documento acessório, conforme o caso.

    - Proposição já enviada, porém, ainda não recebida - Neste estado, as ações disponíveis são: clicar em Imprimir Recibo para imprimir o recibo referente ao envio para protocolo; clicar em Imprimir Texto Integral para imprimir a proposição ou documento; clicar em Início para retornar a tela anterior; ou, ainda, clicar em retomar a proposição enviada para retomar a proposição e realizar modificações no seu texto. Neste caso, o Sapl irá desprezar o número anteriormente gerado, no momento do envio, e ao ser reenviada a proposição, gerar nova numeração. Após essa ação, a proposição ou documento retorna a situação de proposição ainda não enviada.

    - Proposição já enviada e recebida - Nesta situação, todas as ações relativas a situação anterior - de recebida - estão disponíveis, exceto que não será permitida retomar a proposição e nem realizar alterações nos dados básicos.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/proposicao_legislativa.html b/sapl/templates/ajuda/proposicao_legislativa.html index 96d9b8980..b0ca6d600 100644 --- a/sapl/templates/ajuda/proposicao_legislativa.html +++ b/sapl/templates/ajuda/proposicao_legislativa.html @@ -11,11 +11,11 @@ Esta tela exibe uma lista de proposições legislativas, que foram, ou estão sendo, elaboradas por um usuário com perfil de autor. Contém as seguintes colunas de dados:

    Data de envio - refere-se a data na qual o autor enviou a proposição para protocolo. Caso ainda, a mesma não tenha sido enviada, o sistema exibe a palavra em elaboração. Essa coluna possui um link para a tela que contém o detalhamento da proposição referida, o qual é acionado quando se clica sobre o mesmo.

    Tipo - indica o tipo de proposição.

    Descrição - contém a descrição da proposição.

    Recebida - sim ou não, indicando a informação de recebimento ou não da proposição pela Secretaria Legislativa da Casa, para que seja protocolada, no caso da Proposição já ter sido enviada.

    Além das colunas de dados acima, possui os seguintes links de acionamento de funcionalidades:

    Próxima página - avança para apresentar mais 8 proposições - paginando para frente, no caso de haver mais proposições.

    Página anterior - retrocede para apresentar as 8 proposições anteriores - paginando para trás, se houver.

    Elaborar nova proposição - link que, ao ser acionado, direciona o usuário para a tela de inclusão de nova proposição.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/protocolo_administrativo.html b/sapl/templates/ajuda/protocolo_administrativo.html index 8715beb51..5d43134fe 100644 --- a/sapl/templates/ajuda/protocolo_administrativo.html +++ b/sapl/templates/ajuda/protocolo_administrativo.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



    @@ -50,7 +50,7 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

    - Anterior | + Anterior | Índice diff --git a/sapl/templates/ajuda/protocolo_anular.html b/sapl/templates/ajuda/protocolo_anular.html index 8715beb51..5d43134fe 100644 --- a/sapl/templates/ajuda/protocolo_anular.html +++ b/sapl/templates/ajuda/protocolo_anular.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



    @@ -50,7 +50,7 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

    - Anterior | + Anterior | Índice diff --git a/sapl/templates/ajuda/protocolo_geral.html b/sapl/templates/ajuda/protocolo_geral.html index f7bc6b4dd..15393822b 100644 --- a/sapl/templates/ajuda/protocolo_geral.html +++ b/sapl/templates/ajuda/protocolo_geral.html @@ -162,11 +162,11 @@ Quando for informado OK será enviada a mensagem !Matéria excluída com sucesso da ordem do dia!

    - Anterior | + Anterior | - Índice + Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/protocolo_gerar_etiqueta_processo.html b/sapl/templates/ajuda/protocolo_gerar_etiqueta_processo.html index 8715beb51..5d43134fe 100644 --- a/sapl/templates/ajuda/protocolo_gerar_etiqueta_processo.html +++ b/sapl/templates/ajuda/protocolo_gerar_etiqueta_processo.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



    @@ -50,7 +50,7 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

    - Anterior | + Anterior | Índice diff --git a/sapl/templates/ajuda/protocolo_gerar_etiqueta_protocolo.html b/sapl/templates/ajuda/protocolo_gerar_etiqueta_protocolo.html index 8715beb51..5d43134fe 100644 --- a/sapl/templates/ajuda/protocolo_gerar_etiqueta_protocolo.html +++ b/sapl/templates/ajuda/protocolo_gerar_etiqueta_protocolo.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



    @@ -50,7 +50,7 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

    - Anterior | + Anterior | Índice diff --git a/sapl/templates/ajuda/protocolo_legislativo.html b/sapl/templates/ajuda/protocolo_legislativo.html index 8715beb51..5d43134fe 100644 --- a/sapl/templates/ajuda/protocolo_legislativo.html +++ b/sapl/templates/ajuda/protocolo_legislativo.html @@ -22,23 +22,23 @@ informações você tem acesso módulos:



    @@ -50,7 +50,7 @@ informações relativas a casa legislativa, para personalizar as telas do sistema de Apoio ao Processo Legislativo.

    - Anterior | + Anterior | Índice diff --git a/sapl/templates/ajuda/recebimento_proposicao.html b/sapl/templates/ajuda/recebimento_proposicao.html index 54680bb6b..24ad025ea 100644 --- a/sapl/templates/ajuda/recebimento_proposicao.html +++ b/sapl/templates/ajuda/recebimento_proposicao.html @@ -75,11 +75,11 @@ acessório.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/regime_tramitacao.html b/sapl/templates/ajuda/regime_tramitacao.html index 21ebc0dd1..abc94e665 100644 --- a/sapl/templates/ajuda/regime_tramitacao.html +++ b/sapl/templates/ajuda/regime_tramitacao.html @@ -39,11 +39,11 @@ tramitação foi excluído com sucesso sem pergunta de confirmação.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/sessao_legislativa.html b/sapl/templates/ajuda/sessao_legislativa.html index 5af333853..f28e339d9 100644 --- a/sapl/templates/ajuda/sessao_legislativa.html +++ b/sapl/templates/ajuda/sessao_legislativa.html @@ -162,11 +162,11 @@ A função “Início” retorna a tela de cadastramento de Sessão Legislativa.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/sessao_plenaria.html b/sapl/templates/ajuda/sessao_plenaria.html index e339c65f2..3aa513d0b 100644 --- a/sapl/templates/ajuda/sessao_plenaria.html +++ b/sapl/templates/ajuda/sessao_plenaria.html @@ -14,26 +14,26 @@
    Além das informações básicas de identificaçáo da Sessão é possível acessar o áudio num dos formatos mp3 e aac e o video num dos formatos: mp4, flv e webM por meio das respectivas URL's, caso tenham sido gerados. Ao selecionar uma sessão específica, o sistema irá apresentar o seguinte menu de opçóes, relativo a sessão plenária:

    Menu de Opções


    Ao ter acesso, para cadastro, será exibida a opção de Incluir, para a inclusão de novas Sessões. Ao ser acionada essa função, será exibida a tela Formulário de Cadastro.

    Para a efetivação do cadastramento serão necessários dados das seguintes tabelas auxiliares:

    Tabelas Auxiliares

    Os seguintes campos deverão ser preenchidos:

    @@ -131,11 +131,11 @@ a data de encerramento da sessão plenária no formato dd/mm/aaaa e
    Acione a função “Salvar” para que as informações sejam salvas no arquivo.

    Será enviada a mensagem !Sessão Plenária salva com sucesso!

    Acione a função “Sair” para sair do cadastramento de Sessões e voltar a tela anterior.
    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_ata.html b/sapl/templates/ajuda/sessao_plenaria_ata.html index bd4b854df..e5a7a43f7 100644 --- a/sapl/templates/ajuda/sessao_plenaria_ata.html +++ b/sapl/templates/ajuda/sessao_plenaria_ata.html @@ -17,11 +17,11 @@
    6. Expedientes - Constam os registros dos fatos ocorridos em cada parte/expediente da Sessão.

    Clique no botão retornar para retornar a tela de cadastro da Sessão Plenária.
    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_expedientes.html b/sapl/templates/ajuda/sessao_plenaria_expedientes.html index 34070119b..525bbe7bd 100644 --- a/sapl/templates/ajuda/sessao_plenaria_expedientes.html +++ b/sapl/templates/ajuda/sessao_plenaria_expedientes.html @@ -14,11 +14,11 @@
    Após digitar os textos dentro da caixa, acione o botão 'Salvar' para grava-los.

    Nota: Deve-se evitar copiar textos de outros editores MS Word, etc (Crtl-C e Crtl-V) para dentro da caixa de texto, uma vez que juntamente com o texto vem tags inseridas pelo Editor de Textos, as quais nem sempre são reconhecidas ou passíveis de tradução para o html, que é a linguagem do Navegador Web. Esta sugestão é feita, pois sempre que uma tag existente no texto e não reconhecida pela função de conversão, o relatório em PDF deixa de ser gerado devido a ocorrências de erros decorrentes dessas tags não traduzidas.

    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_lista_presenca_sessao.html b/sapl/templates/ajuda/sessao_plenaria_lista_presenca_sessao.html index e16f9d228..d9cfd2354 100644 --- a/sapl/templates/ajuda/sessao_plenaria_lista_presenca_sessao.html +++ b/sapl/templates/ajuda/sessao_plenaria_lista_presenca_sessao.html @@ -17,11 +17,11 @@
    A informação, sobre o quórum, foi previamente cadastrada quando do cadastro do tipo de sessão no sistema.

    Para a execução desta função serão necessários que os Parlamentares bem como os Tipos de Sessão Plenária - em tabelas auxiliares, estejam previamente cadastrados.

    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_materias_expediente.html b/sapl/templates/ajuda/sessao_plenaria_materias_expediente.html index 384fc1218..f19047aa1 100644 --- a/sapl/templates/ajuda/sessao_plenaria_materias_expediente.html +++ b/sapl/templates/ajuda/sessao_plenaria_materias_expediente.html @@ -15,11 +15,11 @@
    Na identificação da matéria há um link que, quando acionado, permite o acesso aos meta dados da matéria propriamente.

    As matérias legislativas são inseridas no Expediente, por meio da função Matérias no Expediente, da Sessão Plenária.

    O retorno a tela anterior é feito ao acionar o botão 'Retornar', que se encontra na parte inferior da tela.
    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_materias_ordem_dia.html b/sapl/templates/ajuda/sessao_plenaria_materias_ordem_dia.html index 98358919b..015e5e3cd 100644 --- a/sapl/templates/ajuda/sessao_plenaria_materias_ordem_dia.html +++ b/sapl/templates/ajuda/sessao_plenaria_materias_ordem_dia.html @@ -15,11 +15,11 @@
    Esta função permite o acesso as funções inclusão individual ou de várias matérias na mesma transação, conforme o botão que for acionado, via clique do mouse.

    Também, é possível ajustar as matérias na Ordem do Dia, de modo a restaurar o número de ordem sequencial, bastando para isso, clicar no botão 'Ajustar Ordenação na Ordem do Dia', as quais serão renumeradas em ordem de tipo, ano e número.

    O retorno a tela anterior é feito ao acionar o botão 'Retornar', que se encontra na parte inferior da tela.
    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_mesa.html b/sapl/templates/ajuda/sessao_plenaria_mesa.html index 1d563e7ac..d90ef647d 100644 --- a/sapl/templates/ajuda/sessao_plenaria_mesa.html +++ b/sapl/templates/ajuda/sessao_plenaria_mesa.html @@ -14,11 +14,11 @@
    Para excluir o parlamentar da Mesa da Sessão, basta seleciona-lo e acionar o botão 'Excluir'. O sistema, antes de efetivar, irá perguntar se deseja realmente excluir e, caso afirmativo, efetivará a exclusão e emitirá a mensagem: !Parlamentar excluído com sucesso da composição da mesa.

    Para a execução desta função serão necessários que os Parlamentares bem como os Cargos - em tabelas auxiliares, estejam previamente cadastrados.

    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_oradores.html b/sapl/templates/ajuda/sessao_plenaria_oradores.html index 8f64f31f8..634eb46a4 100644 --- a/sapl/templates/ajuda/sessao_plenaria_oradores.html +++ b/sapl/templates/ajuda/sessao_plenaria_oradores.html @@ -14,11 +14,11 @@ Essa função possui 3 caixas: Oradores Cadastrados, Cadastro de Ora
    Em Cadastro de Oradores consta no combo box os parlamentares ativos que ainda podem ser selecionados e incluídos na lista de oradores com a indicação da ordem de pronunciamento. Ao acionar o botão incluir orador o sistema irá emitir a mensagem ! Parlamentar incluído com sucesso na lista de oradores!

    A última caixa, Cadastro de Discurso permite a inclusão do discurso do parlamentar. Para tanto, é necessário selecionar o parlamentar no combo box, clicar em arquivo para obter o discurso e, em seguida, clicar no botão Incluir Discurso. O sistema irá emitir a mensagem !Discurso incluído com sucesso! e o link continuar que ao pressionado retorna a tela anterior.

    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_oradores_expediente.html b/sapl/templates/ajuda/sessao_plenaria_oradores_expediente.html index 8f64f31f8..634eb46a4 100644 --- a/sapl/templates/ajuda/sessao_plenaria_oradores_expediente.html +++ b/sapl/templates/ajuda/sessao_plenaria_oradores_expediente.html @@ -14,11 +14,11 @@ Essa função possui 3 caixas: Oradores Cadastrados, Cadastro de Ora
    Em Cadastro de Oradores consta no combo box os parlamentares ativos que ainda podem ser selecionados e incluídos na lista de oradores com a indicação da ordem de pronunciamento. Ao acionar o botão incluir orador o sistema irá emitir a mensagem ! Parlamentar incluído com sucesso na lista de oradores!

    A última caixa, Cadastro de Discurso permite a inclusão do discurso do parlamentar. Para tanto, é necessário selecionar o parlamentar no combo box, clicar em arquivo para obter o discurso e, em seguida, clicar no botão Incluir Discurso. O sistema irá emitir a mensagem !Discurso incluído com sucesso! e o link continuar que ao pressionado retorna a tela anterior.

    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_oradores_explicacoes_pessoais.html b/sapl/templates/ajuda/sessao_plenaria_oradores_explicacoes_pessoais.html index 8f64f31f8..634eb46a4 100644 --- a/sapl/templates/ajuda/sessao_plenaria_oradores_explicacoes_pessoais.html +++ b/sapl/templates/ajuda/sessao_plenaria_oradores_explicacoes_pessoais.html @@ -14,11 +14,11 @@ Essa função possui 3 caixas: Oradores Cadastrados, Cadastro de Ora
    Em Cadastro de Oradores consta no combo box os parlamentares ativos que ainda podem ser selecionados e incluídos na lista de oradores com a indicação da ordem de pronunciamento. Ao acionar o botão incluir orador o sistema irá emitir a mensagem ! Parlamentar incluído com sucesso na lista de oradores!

    A última caixa, Cadastro de Discurso permite a inclusão do discurso do parlamentar. Para tanto, é necessário selecionar o parlamentar no combo box, clicar em arquivo para obter o discurso e, em seguida, clicar no botão Incluir Discurso. O sistema irá emitir a mensagem !Discurso incluído com sucesso! e o link continuar que ao pressionado retorna a tela anterior.

    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html b/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html index 7f40eed53..e0572a4b3 100644 --- a/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html +++ b/sapl/templates/ajuda/sessao_plenaria_presenca_ordem_dia.html @@ -13,13 +13,13 @@
    Para isso, o sistema apresenta uma lista dos parlamentares bastando assinalar - com um clique do mouse - no quadro, que se encontra a esquerda do nome de cada parlamentar, a presença na Ordem do Dia e, ao final, acionar o botão 'Salvar'.

    Para excluir o parlamentar da lista de presenças basta desmarcar - com um clique do mouse - o quadro correspondente ao nome do parlamentar e acionar o botão 'Salvar'.

    O sistema irá exibir a mensagem !Lista de presença da Ordem do Dia cadastrada com sucesso!.
    -
    Para a execução desta função serão necessários que os Parlamentares bem como os Tipos de Sessão Plenária - em tabelas auxiliares, estejam previamente cadastrados.
    +
    Para a execução desta função serão necessários que os Parlamentares bem como os Tipos de Sessão Plenária - em tabelas auxiliares, estejam previamente cadastrados.

    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/sessao_plenaria_votacao.html b/sapl/templates/ajuda/sessao_plenaria_votacao.html index ac0a913b6..4a392d378 100644 --- a/sapl/templates/ajuda/sessao_plenaria_votacao.html +++ b/sapl/templates/ajuda/sessao_plenaria_votacao.html @@ -16,11 +16,11 @@
    O campo observações deve ser preenchido, quando for o caso, com as informações que forem julgadas oportunas e de esclarecimentos adicionais.

    Após preenchidas todas as informações, clicar no botão 'Salvar'. O sistema deverá emitir a mensagem: !Votação salva com sucesso! caso todos os dados estejam corretos, devendo clicar em continuar para retomar o registro da votação de outras matérias.

    Entretanto, emitirá a mensagem: !Quantidade de Votos é diferente do número de parlamentares presentes na Ordem do Dia! caso o total de votantes esteja diferente da lista de presença indicada na Ordem do Dia. Neste caso, clique em voltar para retornar a tela anterior e efetuar as correções.
    -
    Anterior | +
    Anterior | Índice - | Próxima + | Próxima

    diff --git a/sapl/templates/ajuda/status_tramitacao.html b/sapl/templates/ajuda/status_tramitacao.html index ae39969b6..1d26fcb4a 100644 --- a/sapl/templates/ajuda/status_tramitacao.html +++ b/sapl/templates/ajuda/status_tramitacao.html @@ -116,11 +116,11 @@ retorna a tela com a relação de Status de tramitação já cadastradas.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_afastamento.html b/sapl/templates/ajuda/tipo_afastamento.html index 9751b6c4b..91dd33000 100644 --- a/sapl/templates/ajuda/tipo_afastamento.html +++ b/sapl/templates/ajuda/tipo_afastamento.html @@ -112,11 +112,11 @@ Quando for informado OK será enviada a mensagem !Tipo de Afastamento excluído com sucesso!

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_autor.html b/sapl/templates/ajuda/tipo_autor.html index d5765b9dd..d81f74b34 100644 --- a/sapl/templates/ajuda/tipo_autor.html +++ b/sapl/templates/ajuda/tipo_autor.html @@ -95,11 +95,11 @@ retorna a tela com a relação de tipo de autor já cadastrado.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_comissao.html b/sapl/templates/ajuda/tipo_comissao.html index 3fc7989cc..345cbcbac 100644 --- a/sapl/templates/ajuda/tipo_comissao.html +++ b/sapl/templates/ajuda/tipo_comissao.html @@ -132,11 +132,11 @@ retorna a tela com a relação de Tipo de comissões já cadastradas.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_dependente.html b/sapl/templates/ajuda/tipo_dependente.html index 81f51eda9..cc9068f2e 100644 --- a/sapl/templates/ajuda/tipo_dependente.html +++ b/sapl/templates/ajuda/tipo_dependente.html @@ -38,11 +38,11 @@ excluído com sucesso sem pergunta de confirmação.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_documento.html b/sapl/templates/ajuda/tipo_documento.html index 8f533697f..61cd0dd29 100644 --- a/sapl/templates/ajuda/tipo_documento.html +++ b/sapl/templates/ajuda/tipo_documento.html @@ -33,11 +33,11 @@ excluído com sucesso sem pergunta de confirmação.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_materia_legislativa.html b/sapl/templates/ajuda/tipo_materia_legislativa.html index 46b40cdfa..c0ba02ef8 100644 --- a/sapl/templates/ajuda/tipo_materia_legislativa.html +++ b/sapl/templates/ajuda/tipo_materia_legislativa.html @@ -96,11 +96,11 @@ retorna a tela com a relação de tipo de Matéria Legislatura.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_norma_juridica.html b/sapl/templates/ajuda/tipo_norma_juridica.html index a8c8c6f67..20d96269b 100644 --- a/sapl/templates/ajuda/tipo_norma_juridica.html +++ b/sapl/templates/ajuda/tipo_norma_juridica.html @@ -162,11 +162,11 @@ retorna aa tela com os dados da norma jurídica selecionada.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_proposicao.html b/sapl/templates/ajuda/tipo_proposicao.html index 258ce40ee..2008ad7c5 100644 --- a/sapl/templates/ajuda/tipo_proposicao.html +++ b/sapl/templates/ajuda/tipo_proposicao.html @@ -107,11 +107,11 @@ retorna a tela com a relação de tipo de proposições já cadastradas.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tipo_situa_militar.html b/sapl/templates/ajuda/tipo_situa_militar.html index aaace410b..5bbede6ba 100644 --- a/sapl/templates/ajuda/tipo_situa_militar.html +++ b/sapl/templates/ajuda/tipo_situa_militar.html @@ -39,11 +39,11 @@ militar foi excluído com sucesso sem pergunta de confirmação.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tramitacao_lote.html b/sapl/templates/ajuda/tramitacao_lote.html index 198104f4d..a8a8f5450 100644 --- a/sapl/templates/ajuda/tramitacao_lote.html +++ b/sapl/templates/ajuda/tramitacao_lote.html @@ -273,11 +273,11 @@ Será enviada a mensagem Tramitação efetivada com sucesso!
    Acione a função Continuar repetir a operação para outras tramitações ou Voltar para retornar para tela inicial do sistema.


    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/tramitacao_relatoria.html b/sapl/templates/ajuda/tramitacao_relatoria.html index e6afd58d7..373ea3e63 100644 --- a/sapl/templates/ajuda/tramitacao_relatoria.html +++ b/sapl/templates/ajuda/tramitacao_relatoria.html @@ -370,11 +370,11 @@ retorna à tela com os dados da matéria legislativa selecionada.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/troca_senha.html b/sapl/templates/ajuda/troca_senha.html index 54e807205..72be948f4 100644 --- a/sapl/templates/ajuda/troca_senha.html +++ b/sapl/templates/ajuda/troca_senha.html @@ -70,11 +70,11 @@ informações sejam salvas no arquivo.
    Será enviada a mensagem !Senha salva com sucesso!

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/ajuda/unidade_tramitacao.html b/sapl/templates/ajuda/unidade_tramitacao.html index 00f03cbfd..76d3a7a85 100644 --- a/sapl/templates/ajuda/unidade_tramitacao.html +++ b/sapl/templates/ajuda/unidade_tramitacao.html @@ -120,11 +120,11 @@ retorna a tela com a relação de unidade de tramitação já cadastrada.

    - Anterior | + Anterior | Índice - | Próxima + | Próxima
    diff --git a/sapl/templates/base.html b/sapl/templates/base.html index 09f49c3a5..dbecfbd32 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -136,7 +136,7 @@ {% block help %} {# {% if view.help_path %}#} -{# {% trans 'Ajuda' %}#} +{# {% trans 'Ajuda' %}#} {# {% endif %}#} {% endblock %} From c4678db482306b8e7071e01a1372269e67d45de1 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 10 Oct 2017 16:09:40 -0300 Subject: [PATCH 109/237] Conserta testes --- sapl/parlamentares/tests/test_parlamentares.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sapl/parlamentares/tests/test_parlamentares.py b/sapl/parlamentares/tests/test_parlamentares.py index 23d56005b..88644750f 100644 --- a/sapl/parlamentares/tests/test_parlamentares.py +++ b/sapl/parlamentares/tests/test_parlamentares.py @@ -128,6 +128,7 @@ def test_mandato_submit(admin_client): kwargs={'pk': 14}), {'parlamentar': 14, # hidden field 'legislatura': 5, + 'data_inicio_mandato': Legislatura.objects.get(id=5).data_inicio, 'data_expedicao_diploma': '2016-03-22', 'observacao': 'Observação do mandato', 'salvar': 'salvar'}, @@ -171,12 +172,14 @@ def test_mandato_form_duplicado(): Mandato.objects.create(parlamentar=parlamentar, legislatura=legislatura, - data_expedicao_diploma='2017-07-25') + data_expedicao_diploma='2017-07-25', + data_inicio_mandato=legislatura.data_inicio,) form = MandatoForm(data={ 'parlamentar': str(parlamentar.pk), 'legislatura': str(legislatura.pk), - 'data_expedicao_diploma': '01/07/2015' + 'data_expedicao_diploma': '01/07/2015', + 'data_inicio_mandato': legislatura.data_inicio, }) assert not form.is_valid() From e63dfff5fce4cd6f2037cd95e27825ce5793392c Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Tue, 10 Oct 2017 16:52:40 -0300 Subject: [PATCH 110/237] Corrige erros referentes a PEP8 --- sapl/base/views.py | 1 - sapl/materia/email_utils.py | 4 ++-- sapl/materia/views.py | 2 +- sapl/painel/urls.py | 1 - sapl/painel/views.py | 7 +++---- sapl/parlamentares/tests/test_parlamentares.py | 3 ++- sapl/protocoloadm/forms.py | 2 +- sapl/sessao/forms.py | 2 +- sapl/sessao/models.py | 3 ++- sapl/sessao/tests/test_sessao.py | 2 +- sapl/sessao/tests/test_sessao_view.py | 2 +- sapl/utils.py | 5 +++-- scripts/lista_permissions_in_decorators.py | 8 ++++---- 13 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index f1474ae4a..47c3a5318 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -1,6 +1,5 @@ from django.conf import settings from django.contrib.auth import get_user_model -from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.models import Group from django.contrib.auth.tokens import default_token_generator from django.core.exceptions import ObjectDoesNotExist diff --git a/sapl/materia/email_utils.py b/sapl/materia/email_utils.py index 9bfe0b66f..3dc6b220d 100644 --- a/sapl/materia/email_utils.py +++ b/sapl/materia/email_utils.py @@ -152,8 +152,8 @@ def criar_email_tramitacao(base_url, casa_legislativa, materia, status, 'email/tramitacao.html'], {"casa_legislativa": casa_nome, "data_registro": dt.strftime( - timezone.now(), - "%d/%m/%Y"), + timezone.now(), + "%d/%m/%Y"), "cod_materia": materia.id, "logotipo": casa_legislativa.logotipo, "descricao_materia": materia.ementa, diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 9c315be5a..1fa65bd85 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -1642,7 +1642,7 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView): doc.arquivo = request.FILES['arquivo'] doc.nome = request.POST['nome'] doc.data = tz.localize(datetime.strptime( - request.POST['data'], "%d/%m/%Y")) + request.POST['data'], "%d/%m/%Y")) doc.autor = request.POST['autor'] doc.ementa = request.POST['ementa'] doc.save() diff --git a/sapl/painel/urls.py b/sapl/painel/urls.py index 2dc5dcdb9..0795d0a35 100644 --- a/sapl/painel/urls.py +++ b/sapl/painel/urls.py @@ -25,4 +25,3 @@ urlpatterns = [ url(r'^voto-individual/$', votante_view, name='voto_individual'), ] - diff --git a/sapl/painel/views.py b/sapl/painel/views.py index cc01cbf34..eae434de3 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -1,4 +1,5 @@ import json + from django.contrib import messages from django.contrib.auth.decorators import user_passes_test from django.core.exceptions import ObjectDoesNotExist @@ -8,8 +9,6 @@ from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import render from django.utils.translation import ugettext_lazy as _ -from operator import itemgetter -from sapl.utils import sort_lista_chave from sapl.crud.base import Crud from sapl.painel.apps import AppConfig @@ -17,7 +16,7 @@ from sapl.parlamentares.models import Votante from sapl.sessao.models import (ExpedienteMateria, OrdemDia, PresencaOrdemDia, RegistroVotacao, SessaoPlenaria, SessaoPlenariaPresenca, VotoParlamentar) -from sapl.utils import filiacao_data, get_client_ip +from sapl.utils import filiacao_data, get_client_ip, sort_lista_chave from .models import Cronometro @@ -238,6 +237,7 @@ def switch_painel(request): sessao.save() return JsonResponse({}) + @user_passes_test(check_permission) def verifica_painel(request): sessao = SessaoPlenaria.objects.get(id=request.GET['pk_sessao']) @@ -324,7 +324,6 @@ def get_presentes(pk, response, materia): 'materia_legislativa_texto': str(materia.materia) }) - presentes_list = sort_lista_chave(presentes_list, 'nome') response.update({ diff --git a/sapl/parlamentares/tests/test_parlamentares.py b/sapl/parlamentares/tests/test_parlamentares.py index 88644750f..ba1f560b9 100644 --- a/sapl/parlamentares/tests/test_parlamentares.py +++ b/sapl/parlamentares/tests/test_parlamentares.py @@ -128,7 +128,8 @@ def test_mandato_submit(admin_client): kwargs={'pk': 14}), {'parlamentar': 14, # hidden field 'legislatura': 5, - 'data_inicio_mandato': Legislatura.objects.get(id=5).data_inicio, + 'data_inicio_mandato': \ + Legislatura.objects.get(id=5).data_inicio, 'data_expedicao_diploma': '2016-03-22', 'observacao': 'Observação do mandato', 'salvar': 'salvar'}, diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index e3874181f..d7d720315 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -598,7 +598,7 @@ class DocumentoAdministrativoForm(ModelForm): except MultipleObjectsReturned: msg = _( 'Existe mais de um Protocolo com este ano e número.' % ( - numero_protocolo, ano_protocolo)) + numero_protocolo, ano_protocolo)) raise ValidationError(msg) return self.cleaned_data diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index f767cb5d4..6fddc6747 100644 --- a/sapl/sessao/forms.py +++ b/sapl/sessao/forms.py @@ -129,7 +129,7 @@ class ExpedienteMateriaForm(ModelForm): label='Número Matéria', required=True) ano_materia = forms.CharField( - label='Ano Matéria', + label='Ano Matéria', initial=int(data_atual.year), required=True) diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index b5d31fff7..7d87ecef2 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -111,7 +111,8 @@ class SessaoPlenaria(models.Model): # TODO analyze querying all hosted databases ! cod_andamento_sessao = models.PositiveIntegerField(blank=True, null=True) - painel_aberto = models.BooleanField(blank=True, default=False, verbose_name=_('Painel está aberto?')) + painel_aberto = models.BooleanField(blank=True, default=False, + verbose_name=_('Painel está aberto?')) tipo = models.ForeignKey(TipoSessaoPlenaria, on_delete=models.PROTECT, verbose_name=_('Tipo')) diff --git a/sapl/sessao/tests/test_sessao.py b/sapl/sessao/tests/test_sessao.py index b0258312c..038ad7424 100644 --- a/sapl/sessao/tests/test_sessao.py +++ b/sapl/sessao/tests/test_sessao.py @@ -2,7 +2,7 @@ import pytest from django.utils.translation import ugettext_lazy as _ from model_mommy import mommy -from sapl.materia.models import TipoMateriaLegislativa, MateriaLegislativa +from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.parlamentares.models import Legislatura, Partido, SessaoLegislativa from sapl.sessao import forms from sapl.sessao.models import (ExpedienteMateria, SessaoPlenaria, diff --git a/sapl/sessao/tests/test_sessao_view.py b/sapl/sessao/tests/test_sessao_view.py index 8868d7abd..082652c19 100644 --- a/sapl/sessao/tests/test_sessao_view.py +++ b/sapl/sessao/tests/test_sessao_view.py @@ -46,4 +46,4 @@ def test_incluir_sessao_errors(admin_client): assert (response.context_data['form'].errors['data_inicio'] == [_('Este campo é obrigatório.')]) assert (response.context_data['form'].errors['hora_inicio'] == - [_('Este campo é obrigatório.')]) \ No newline at end of file + [_('Este campo é obrigatório.')]) diff --git a/sapl/utils.py b/sapl/utils.py index 37e5711d3..d645cb003 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -3,8 +3,8 @@ import logging import os import re from functools import wraps -from unicodedata import normalize as unicodedata_normalize from operator import itemgetter +from unicodedata import normalize as unicodedata_normalize import django_filters import magic @@ -657,7 +657,8 @@ def show_results_filter_set(qr): def sort_lista_chave(lista, chave): """ :param lista: Uma list a ser ordenada . - :param chave: Algum atributo (chave) que está presente na lista e qual deve ser usado para a ordenação da nova + :param chave: Algum atributo (chave) que está presente na lista e qual + deve ser usado para a ordenação da nova lista. :return: A lista ordenada pela chave passada. """ diff --git a/scripts/lista_permissions_in_decorators.py b/scripts/lista_permissions_in_decorators.py index 4d504e6c0..d20882450 100644 --- a/scripts/lista_permissions_in_decorators.py +++ b/scripts/lista_permissions_in_decorators.py @@ -17,7 +17,7 @@ def get_decorators(cls): target = cls decorators = {} - def visit_FunctionDef(node): + def visit_functionDef(node): decorators[node.name] = [] for n in node.decorator_list: name = '' @@ -30,7 +30,7 @@ def get_decorators(cls): decorators[node.name].append(name) node_iter = ast.NodeVisitor() - node_iter.visit_FunctionDef = visit_FunctionDef + node_iter.visit_functionDef = visit_functionDef node_iter.visit(ast.parse(inspect.getsource(target))) return decorators @@ -77,7 +77,7 @@ def get_permission_requireds(cls): get_permission_required(arg) - def visit_FunctionDef(node): + def visit_functionDef(node): for n in node.decorator_list: if not isinstance(n, ast.Call): continue @@ -98,7 +98,7 @@ def get_permission_requireds(cls): get_method_decorator(n) node_iter = ast.NodeVisitor() - node_iter.visit_FunctionDef = visit_FunctionDef + node_iter.visit_functionDef = visit_functionDef node_iter.visit(ast.parse(inspect.getsource(target))) return decorators From 796ad4c4043f4d4c788b26f35efc8c255dc705c7 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 10 Oct 2017 17:49:39 -0300 Subject: [PATCH 111/237] Fix #1528 --- sapl/templates/protocoloadm/comprovante.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/templates/protocoloadm/comprovante.html b/sapl/templates/protocoloadm/comprovante.html index 4c88ca195..031b096c4 100644 --- a/sapl/templates/protocoloadm/comprovante.html +++ b/sapl/templates/protocoloadm/comprovante.html @@ -31,7 +31,7 @@ class="img-responsive visible-lg-inline-block vcenter">
    {% if nome %} - {{ nome }} {% trans 'de' %} {{ municipio }} - {{ uf }} + {{ nome }} - {{ municipio }} - {{ uf }} {% else %} {% trans 'Sem Nome Cadastrado' %} {% endif %} From 2c02bfcb2aba0d6188acffca11e0a50cc6f5afa9 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 10 Oct 2017 15:25:05 -0300 Subject: [PATCH 112/237] Novo release: 3.1.26-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index ef3470595..0e288ad59 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.25-BETA + image: interlegis/sapl:3.1.26-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index efa274375..41da8192c 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.25-BETA', + version='3.1.26-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From 89d78ba8d032bbf8a88829cf1298c36b20ad2234 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 11 Oct 2017 15:47:18 -0300 Subject: [PATCH 113/237] HOT-FIX: corrige erro em variavel nao atribuida --- sapl/sessao/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 44174abde..0f3d9dec8 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -2362,9 +2362,9 @@ class PautaSessaoDetailView(DetailView): # Verificar resultado rv = o.registrovotacao_set.all() if rv: - resultado = rv[0].tipo_resultado_votacao.nome + resultado_observacao = rv[0].tipo_resultado_votacao.nome else: - resultado = _('Matéria não votada') + resultado_observacao = _('Matéria não votada') autoria = Autoria.objects.filter( materia_id=o.materia_id) From d1581e32b440dcac086567dc70545f4bf9bece6a Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 11 Oct 2017 16:05:44 -0300 Subject: [PATCH 114/237] HOT-FIX: adiciona resultado e resultado_observacao --- sapl/sessao/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 0f3d9dec8..073030a70 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -2362,9 +2362,11 @@ class PautaSessaoDetailView(DetailView): # Verificar resultado rv = o.registrovotacao_set.all() if rv: - resultado_observacao = rv[0].tipo_resultado_votacao.nome + resultado = rv[0].tipo_resultado_votacao.nome + resultado_observacao = rv[0].observacao else: - resultado_observacao = _('Matéria não votada') + resultado = _('Matéria não votada') + resultado_observacao = _(' ') autoria = Autoria.objects.filter( materia_id=o.materia_id) From f6d13728aa52b7d5d460b2e909617fe80f25c8c7 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 11 Oct 2017 16:06:53 -0300 Subject: [PATCH 115/237] Novo release: 3.1.27-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0e288ad59..654323927 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.26-BETA + image: interlegis/sapl:3.1.27-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index 41da8192c..36b5d5afe 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.26-BETA', + version='3.1.27-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From 24917a6ae32a4fa862f15b7d93b8ec222b1cd7ea Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Fri, 13 Oct 2017 08:38:04 -0300 Subject: [PATCH 116/237] Troca os help_paths por help_topics e corrige a url do link de ajuda --- sapl/base/views.py | 4 ++-- sapl/comissoes/views.py | 2 +- sapl/crud/base.py | 18 +++++++++--------- sapl/crud/tests/stub_app/views.py | 4 ++-- sapl/materia/views.py | 24 ++++++++++++------------ sapl/norma/views.py | 4 ++-- sapl/parlamentares/views.py | 12 ++++++------ sapl/protocoloadm/views.py | 8 ++++---- sapl/sessao/views.py | 8 ++++---- sapl/templates/base.html | 8 ++++---- 10 files changed, 46 insertions(+), 46 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index 47c3a5318..ebd22d626 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -54,7 +54,7 @@ class ConfirmarEmailView(TemplateView): class TipoAutorCrud(CrudAux): model = TipoAutor - help_path = 'tipo-autor' + help_topic = 'tipo-autor' class BaseMixin(CrudAux.BaseMixin): list_field_names = ['descricao', 'content_type'] @@ -63,7 +63,7 @@ class TipoAutorCrud(CrudAux): class AutorCrud(CrudAux): model = Autor - help_path = 'autor' + help_topic = 'autor' class BaseMixin(CrudAux.BaseMixin): list_field_names = ['tipo', 'nome', 'user'] diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py index 713c8f03e..22147aae6 100644 --- a/sapl/comissoes/views.py +++ b/sapl/comissoes/views.py @@ -78,7 +78,7 @@ class ComposicaoCrud(MasterDetailCrud): class ComissaoCrud(Crud): model = Comissao - help_path = 'modulo_comissoes' + help_topic = 'modulo_comissoes' public = [RP_LIST, RP_DETAIL, ] class BaseMixin(Crud.BaseMixin): diff --git a/sapl/crud/base.py b/sapl/crud/base.py index 836af8925..d53125249 100644 --- a/sapl/crud/base.py +++ b/sapl/crud/base.py @@ -81,7 +81,7 @@ def make_pagination(index, num_pages): """ variáveis do crud: - help_path + help_topic container_field container_field_set is_m2m @@ -865,7 +865,7 @@ class Crud: DetailView = CrudDetailView UpdateView = CrudUpdateView DeleteView = CrudDeleteView - help_path = '' + help_topic = '' class PublicMixin: permission_required = [] @@ -877,7 +877,7 @@ class Crud: if view: class CrudViewWithBase(cls.BaseMixin, view): model = cls.model - help_path = cls.help_path + help_topic = cls.help_topic crud = cls CrudViewWithBase.__name__ = view.__name__ return CrudViewWithBase @@ -909,13 +909,13 @@ class Crud: for regex, view, suffix in cruds] @classonlymethod - def build(cls, _model, _help_path, _model_set=None, list_field_names=[]): + def build(cls, _model, _help_topic, _model_set=None, list_field_names=[]): def create_class(_list_field_names): class ModelCrud(cls): model = _model model_set = _model_set - help_path = _help_path + help_topic = _help_topic list_field_names = _list_field_names return ModelCrud @@ -950,10 +950,10 @@ class CrudAux(Crud): return context @classonlymethod - def build(cls, _model, _help_path, _model_set=None, list_field_names=[]): + def build(cls, _model, _help_topic, _model_set=None, list_field_names=[]): ModelCrud = Crud.build( - _model, _help_path, _model_set, list_field_names) + _model, _help_topic, _model_set, list_field_names) class ModelCrudAux(CrudAux, ModelCrud): pass @@ -1405,10 +1405,10 @@ class MasterDetailCrud(Crud): return '' @classonlymethod - def build(cls, model, parent_field, help_path, + def build(cls, model, parent_field, help_topic, _model_set=None, list_field_names=[]): crud = super(MasterDetailCrud, cls).build( - model, help_path, _model_set=_model_set, + model, help_topic, _model_set=_model_set, list_field_names=list_field_names) crud.parent_field = parent_field return crud diff --git a/sapl/crud/tests/stub_app/views.py b/sapl/crud/tests/stub_app/views.py index 81c6b834d..11d4e3d9f 100644 --- a/sapl/crud/tests/stub_app/views.py +++ b/sapl/crud/tests/stub_app/views.py @@ -6,7 +6,7 @@ from .models import City, Country class CountryCrud(Crud): model = Country - help_path = 'help_path', + help_topic = 'help_topic', class ListView(CrudListView): paginate_by = 10 @@ -14,4 +14,4 @@ class CountryCrud(Crud): class CityCrud(MasterDetailCrud): model = City - help_path = 'help_path', + help_topic = 'help_topic', diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 1fa65bd85..69a4c3eab 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -525,7 +525,7 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): class UnidadeTramitacaoCrud(CrudAux): model = UnidadeTramitacao - help_path = 'unidade_tramitacao' + help_topic = 'unidade_tramitacao' class BaseMixin(Crud.BaseMixin): list_field_names = ['comissao', 'orgao', 'parlamentar'] @@ -551,7 +551,7 @@ class UnidadeTramitacaoCrud(CrudAux): class ProposicaoCrud(Crud): model = Proposicao - help_path = '' + help_topic = '' container_field = 'autor__user' class BaseMixin(Crud.BaseMixin): @@ -838,7 +838,7 @@ class ReciboProposicaoView(TemplateView): class RelatoriaCrud(MasterDetailCrud): model = Relatoria parent_field = 'materia' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class CreateView(MasterDetailCrud.CreateView): @@ -913,7 +913,7 @@ class RelatoriaCrud(MasterDetailCrud): class TramitacaoCrud(MasterDetailCrud): model = Tramitacao parent_field = 'materia' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -1058,7 +1058,7 @@ def montar_helper_documento_acessorio(self): class DocumentoAcessorioCrud(MasterDetailCrud): model = DocumentoAcessorio parent_field = 'materia' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -1094,7 +1094,7 @@ class DocumentoAcessorioCrud(MasterDetailCrud): class AutoriaCrud(MasterDetailCrud): model = Autoria parent_field = 'materia' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] list_field_names = ['autor', 'autor__tipo__descricao', 'primeiro_autor'] @@ -1169,7 +1169,7 @@ class AutoriaMultiCreateView(PermissionRequiredForAppCrudMixin, FormView): class DespachoInicialCrud(MasterDetailCrud): model = DespachoInicial parent_field = 'materia' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class CreateView(MasterDetailCrud.CreateView): @@ -1182,7 +1182,7 @@ class DespachoInicialCrud(MasterDetailCrud): class LegislacaoCitadaCrud(MasterDetailCrud): model = LegislacaoCitada parent_field = 'materia' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -1267,14 +1267,14 @@ class LegislacaoCitadaCrud(MasterDetailCrud): class NumeracaoCrud(MasterDetailCrud): model = Numeracao parent_field = 'materia' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class AnexadaCrud(MasterDetailCrud): model = Anexada parent_field = 'materia_principal' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -1302,7 +1302,7 @@ class AnexadaCrud(MasterDetailCrud): class MateriaAssuntoCrud(MasterDetailCrud): model = MateriaAssunto parent_field = 'materia' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -1326,7 +1326,7 @@ class MateriaAssuntoCrud(MasterDetailCrud): class MateriaLegislativaCrud(Crud): model = MateriaLegislativa - help_path = 'materia_legislativa' + help_topic = 'materia_legislativa' public = [RP_LIST, RP_DETAIL] class BaseMixin(Crud.BaseMixin): diff --git a/sapl/norma/views.py b/sapl/norma/views.py index c374537ed..3bfb256f2 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -33,7 +33,7 @@ TipoVinculoNormaJuridicaCrud = CrudAux.build( class NormaRelacionadaCrud(MasterDetailCrud): model = NormaRelacionada parent_field = 'norma_principal' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -123,7 +123,7 @@ class NormaTaView(IntegracaoTaView): class NormaCrud(Crud): model = NormaJuridica - help_path = 'norma_juridica' + help_topic = 'norma_juridica' public = [RP_LIST, RP_DETAIL] class BaseMixin(Crud.BaseMixin): diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 02bbfae30..5432e70ef 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -89,7 +89,7 @@ class FrenteList(MasterDetailCrud): class RelatoriaParlamentarCrud(CrudBaseForListAndDetailExternalAppView): model = Relatoria parent_field = 'parlamentar' - help_path = 'relatoria_parlamentar' + help_topic = 'relatoria_parlamentar' namespace = AppConfig.name class BaseMixin(CrudBaseForListAndDetailExternalAppView.BaseMixin): @@ -181,7 +181,7 @@ class ParticipacaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView): class ColigacaoCrud(CrudAux): model = Coligacao - help_path = 'tabelas_auxiliares#coligacao' + help_topic = 'tabelas_auxiliares#coligacao' class ListView(CrudAux.ListView): ordering = ('-numero_votos', 'nome') @@ -272,7 +272,7 @@ def parlamentares_frente_selected(request): class FrenteCrud(CrudAux): model = Frente - help_path = 'tabelas_auxiliares#tipo_situa_militar' + help_topic = 'tabelas_auxiliares#tipo_situa_militar' list_field_names = ['nome', 'data_criacao', 'parlamentares'] class CreateView(CrudAux.CreateView): @@ -337,7 +337,7 @@ class MandatoCrud(MasterDetailCrud): class ComposicaoColigacaoCrud(MasterDetailCrud): model = ComposicaoColigacao parent_field = 'coligacao' - help_path = '' + help_topic = '' class BaseMixin(MasterDetailCrud.BaseMixin): @@ -353,7 +353,7 @@ class ComposicaoColigacaoCrud(MasterDetailCrud): class LegislaturaCrud(CrudAux): model = Legislatura - help_path = 'tabelas_auxiliares#legislatura' + help_topic = 'tabelas_auxiliares#legislatura' class CreateView(CrudAux.CreateView): form_class = LegislaturaForm @@ -391,7 +391,7 @@ class LegislaturaCrud(CrudAux): class FiliacaoCrud(MasterDetailCrud): model = Filiacao parent_field = 'parlamentar' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 3384e4934..bce99118d 100644 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -84,7 +84,7 @@ class DocumentoAdministrativoMixin: class DocumentoAdministrativoCrud(Crud): model = DocumentoAdministrativo - help_path = '' + help_topic = '' class BaseMixin(Crud.BaseMixin): list_field_names = ['tipo', 'numero', 'ano', 'data', @@ -142,7 +142,7 @@ class DocumentoAdministrativoCrud(Crud): class StatusTramitacaoAdministrativoCrud(CrudAux): model = StatusTramitacaoAdministrativo - help_path = '' + help_topic = '' class BaseMixin(CrudAux.BaseMixin): list_field_names = ['sigla', 'indicador', 'descricao'] @@ -577,7 +577,7 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, class TramitacaoAdmCrud(MasterDetailCrud): model = TramitacaoAdministrativo parent_field = 'documento' - help_path = '' + help_topic = '' class BaseMixin(MasterDetailCrud.BaseMixin): list_field_names = ['data_tramitacao', 'unidade_tramitacao_local', @@ -656,7 +656,7 @@ class TramitacaoAdmCrud(MasterDetailCrud): class DocumentoAcessorioAdministrativoCrud(MasterDetailCrud): model = DocumentoAcessorioAdministrativo parent_field = 'documento' - help_path = '' + help_topic = '' class BaseMixin(MasterDetailCrud.BaseMixin): list_field_names = ['nome', 'tipo', diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 073030a70..df2e3e06a 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -203,7 +203,7 @@ def get_presencas_generic(model, sessao, legislatura): class MateriaOrdemDiaCrud(MasterDetailCrud): model = OrdemDia parent_field = 'sessao_plenaria' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -358,7 +358,7 @@ def recuperar_materia(request): class ExpedienteMateriaCrud(MasterDetailCrud): model = ExpedienteMateria parent_field = 'sessao_plenaria' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -504,7 +504,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud): class OradorCrud(MasterDetailCrud): model = '' parent_field = 'sessao_plenaria' - help_path = '' + help_topic = '' public = [RP_LIST, RP_DETAIL] class ListView(MasterDetailCrud.ListView): @@ -571,7 +571,7 @@ def sessao_legislativa_legislatura_ajax(request): class SessaoCrud(Crud): model = SessaoPlenaria - help_path = 'sessao_plenaria' + help_topic = 'sessao_plenaria' public = [RP_DETAIL] class BaseMixin(Crud.BaseMixin): diff --git a/sapl/templates/base.html b/sapl/templates/base.html index dbecfbd32..98be3f87d 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -55,7 +55,7 @@ -{#
  • #} +
  • {% if not user.is_authenticated %}
  • {% else %} @@ -135,9 +135,9 @@
    {% block help %} -{# {% if view.help_path %}#} -{# {% trans 'Ajuda' %}#} -{# {% endif %}#} + {% if view.help_topic %} + {% trans 'Ajuda' %} + {% endif %} {% endblock %} {% block title %} From b9fdd5496a06676aea58367601cd53ccdad6c5f5 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Fri, 13 Oct 2017 09:24:15 -0300 Subject: [PATCH 117/237] Corrige links de ajuda --- sapl/materia/views.py | 18 +++++++++--------- sapl/norma/views.py | 2 +- sapl/parlamentares/views.py | 12 ++++++------ sapl/protocoloadm/views.py | 8 ++++---- sapl/sessao/views.py | 8 ++++---- sapl/templates/ajuda.html | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 69a4c3eab..05120f616 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -551,7 +551,7 @@ class UnidadeTramitacaoCrud(CrudAux): class ProposicaoCrud(Crud): model = Proposicao - help_topic = '' + help_topic = 'proposicao' container_field = 'autor__user' class BaseMixin(Crud.BaseMixin): @@ -838,7 +838,7 @@ class ReciboProposicaoView(TemplateView): class RelatoriaCrud(MasterDetailCrud): model = Relatoria parent_field = 'materia' - help_topic = '' + help_topic = 'tramitacao_relatoria' public = [RP_LIST, RP_DETAIL] class CreateView(MasterDetailCrud.CreateView): @@ -913,7 +913,7 @@ class RelatoriaCrud(MasterDetailCrud): class TramitacaoCrud(MasterDetailCrud): model = Tramitacao parent_field = 'materia' - help_topic = '' + help_topic = 'tramitacao_relatoria' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -1058,7 +1058,7 @@ def montar_helper_documento_acessorio(self): class DocumentoAcessorioCrud(MasterDetailCrud): model = DocumentoAcessorio parent_field = 'materia' - help_topic = '' + help_topic = 'despacho_autoria' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -1094,7 +1094,7 @@ class DocumentoAcessorioCrud(MasterDetailCrud): class AutoriaCrud(MasterDetailCrud): model = Autoria parent_field = 'materia' - help_topic = '' + help_topic = 'despacho_autoria' public = [RP_LIST, RP_DETAIL] list_field_names = ['autor', 'autor__tipo__descricao', 'primeiro_autor'] @@ -1169,7 +1169,7 @@ class AutoriaMultiCreateView(PermissionRequiredForAppCrudMixin, FormView): class DespachoInicialCrud(MasterDetailCrud): model = DespachoInicial parent_field = 'materia' - help_topic = '' + help_topic = 'despacho_autoria' public = [RP_LIST, RP_DETAIL] class CreateView(MasterDetailCrud.CreateView): @@ -1182,7 +1182,7 @@ class DespachoInicialCrud(MasterDetailCrud): class LegislacaoCitadaCrud(MasterDetailCrud): model = LegislacaoCitada parent_field = 'materia' - help_topic = '' + help_topic = 'legislacao_cita_matanexada' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -1267,14 +1267,14 @@ class LegislacaoCitadaCrud(MasterDetailCrud): class NumeracaoCrud(MasterDetailCrud): model = Numeracao parent_field = 'materia' - help_topic = '' + help_topic = 'numeracao_docsacess' public = [RP_LIST, RP_DETAIL] class AnexadaCrud(MasterDetailCrud): model = Anexada parent_field = 'materia_principal' - help_topic = '' + help_topic = 'materia_anexada' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 3bfb256f2..f7ee34baf 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -33,7 +33,7 @@ TipoVinculoNormaJuridicaCrud = CrudAux.build( class NormaRelacionadaCrud(MasterDetailCrud): model = NormaRelacionada parent_field = 'norma_principal' - help_topic = '' + help_topic = 'norma_juridica' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 5432e70ef..ae4d3844b 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -89,7 +89,7 @@ class FrenteList(MasterDetailCrud): class RelatoriaParlamentarCrud(CrudBaseForListAndDetailExternalAppView): model = Relatoria parent_field = 'parlamentar' - help_topic = 'relatoria_parlamentar' + help_topic = 'tramitacao_relatoria' namespace = AppConfig.name class BaseMixin(CrudBaseForListAndDetailExternalAppView.BaseMixin): @@ -181,7 +181,7 @@ class ParticipacaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView): class ColigacaoCrud(CrudAux): model = Coligacao - help_topic = 'tabelas_auxiliares#coligacao' + help_topic = 'coligacao' class ListView(CrudAux.ListView): ordering = ('-numero_votos', 'nome') @@ -272,7 +272,7 @@ def parlamentares_frente_selected(request): class FrenteCrud(CrudAux): model = Frente - help_topic = 'tabelas_auxiliares#tipo_situa_militar' + help_topic = 'tipo_situa_militar' list_field_names = ['nome', 'data_criacao', 'parlamentares'] class CreateView(CrudAux.CreateView): @@ -337,7 +337,7 @@ class MandatoCrud(MasterDetailCrud): class ComposicaoColigacaoCrud(MasterDetailCrud): model = ComposicaoColigacao parent_field = 'coligacao' - help_topic = '' + help_topic = 'coligacao' class BaseMixin(MasterDetailCrud.BaseMixin): @@ -353,7 +353,7 @@ class ComposicaoColigacaoCrud(MasterDetailCrud): class LegislaturaCrud(CrudAux): model = Legislatura - help_topic = 'tabelas_auxiliares#legislatura' + help_topic = 'legislatura' class CreateView(CrudAux.CreateView): form_class = LegislaturaForm @@ -391,7 +391,7 @@ class LegislaturaCrud(CrudAux): class FiliacaoCrud(MasterDetailCrud): model = Filiacao parent_field = 'parlamentar' - help_topic = '' + help_topic = 'filiacoes_partidarias' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index bce99118d..9a924c45e 100644 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -84,7 +84,7 @@ class DocumentoAdministrativoMixin: class DocumentoAdministrativoCrud(Crud): model = DocumentoAdministrativo - help_topic = '' + help_topic = 'numeracao_docsacess' class BaseMixin(Crud.BaseMixin): list_field_names = ['tipo', 'numero', 'ano', 'data', @@ -142,7 +142,7 @@ class DocumentoAdministrativoCrud(Crud): class StatusTramitacaoAdministrativoCrud(CrudAux): model = StatusTramitacaoAdministrativo - help_topic = '' + help_topic = 'status_tramitacao' class BaseMixin(CrudAux.BaseMixin): list_field_names = ['sigla', 'indicador', 'descricao'] @@ -577,7 +577,7 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, class TramitacaoAdmCrud(MasterDetailCrud): model = TramitacaoAdministrativo parent_field = 'documento' - help_topic = '' + help_topic = 'unidade_tramitacao' class BaseMixin(MasterDetailCrud.BaseMixin): list_field_names = ['data_tramitacao', 'unidade_tramitacao_local', @@ -656,7 +656,7 @@ class TramitacaoAdmCrud(MasterDetailCrud): class DocumentoAcessorioAdministrativoCrud(MasterDetailCrud): model = DocumentoAcessorioAdministrativo parent_field = 'documento' - help_topic = '' + help_topic = 'numeracao_docsacess' class BaseMixin(MasterDetailCrud.BaseMixin): list_field_names = ['nome', 'tipo', diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index df2e3e06a..7db713905 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -203,7 +203,7 @@ def get_presencas_generic(model, sessao, legislatura): class MateriaOrdemDiaCrud(MasterDetailCrud): model = OrdemDia parent_field = 'sessao_plenaria' - help_topic = '' + help_topic = 'sessao_plenaria_materias_ordem_dia' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -358,7 +358,7 @@ def recuperar_materia(request): class ExpedienteMateriaCrud(MasterDetailCrud): model = ExpedienteMateria parent_field = 'sessao_plenaria' - help_topic = '' + help_topic = 'sessao_plenaria_materia_expediente' public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): @@ -504,7 +504,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud): class OradorCrud(MasterDetailCrud): model = '' parent_field = 'sessao_plenaria' - help_topic = '' + help_topic = 'sessao_plenaria_oradores' public = [RP_LIST, RP_DETAIL] class ListView(MasterDetailCrud.ListView): @@ -571,7 +571,7 @@ def sessao_legislativa_legislatura_ajax(request): class SessaoCrud(Crud): model = SessaoPlenaria - help_topic = 'sessao_plenaria' + help_topic = 'sessao_legislativa' public = [RP_DETAIL] class BaseMixin(Crud.BaseMixin): diff --git a/sapl/templates/ajuda.html b/sapl/templates/ajuda.html index f98ef61b8..df849303d 100644 --- a/sapl/templates/ajuda.html +++ b/sapl/templates/ajuda.html @@ -96,7 +96,7 @@
  • Para inclusão de Tramitação, acione a função "Tramitação"
  • Para inclusão da Relatoria, acione a função "Relatoria"
  • Para inclusão de Numeração, acione a função "Numeração"
  • -
  • Para inclusão de Documentos Acessórios, acione a função "Documentos Acessórios"
  • +
  • Para inclusão de Documentos Acessórios, acione a função "Documentos Acessórios"
  • From 23dfd96227c8f84f2cf50a7f74f05c70d1ac1973 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Fri, 13 Oct 2017 09:32:32 -0300 Subject: [PATCH 118/237] Remove temporariamente links de ajuda --- sapl/templates/base.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sapl/templates/base.html b/sapl/templates/base.html index 98be3f87d..ad3d2b228 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -55,7 +55,7 @@ -
  • +{#
  • #} {% if not user.is_authenticated %}
  • {% else %} @@ -135,9 +135,9 @@
    {% block help %} - {% if view.help_topic %} - {% trans 'Ajuda' %} - {% endif %} +{# {% if view.help_topic %}#} +{# {% trans 'Ajuda' %}#} +{# {% endif %}#} {% endblock %} {% block title %} From fb93b484520a22171d1d7316c606065f527509e1 Mon Sep 17 00:00:00 2001 From: Edward Date: Tue, 17 Oct 2017 14:13:47 -0200 Subject: [PATCH 119/237] Fixes #1533 (#1537) --- .../pre_popula_tipo_vinculo_norma.json | 119 ++++++++++++++++++ ...normajuridica_popula_tipo_vinculo_norma.py | 39 ++++++ 2 files changed, 158 insertions(+) create mode 100644 sapl/norma/fixtures/pre_popula_tipo_vinculo_norma.json create mode 100644 sapl/norma/migrations/0008_normajuridica_popula_tipo_vinculo_norma.py diff --git a/sapl/norma/fixtures/pre_popula_tipo_vinculo_norma.json b/sapl/norma/fixtures/pre_popula_tipo_vinculo_norma.json new file mode 100644 index 000000000..50c6ad647 --- /dev/null +++ b/sapl/norma/fixtures/pre_popula_tipo_vinculo_norma.json @@ -0,0 +1,119 @@ +[ + { + "fields": { + "descricao_ativa": "Altera o(a)", + "descricao_passiva": "Alterado(a) pelo(a)", + "sigla": "A" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "1" + }, + { + "fields": { + "descricao_ativa": "Revoga integralmente o(a)", + "descricao_passiva": "Revogado(a) integralmente pelo(a)", + "sigla": "R" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "2" + }, + { + "fields": { + "descricao_ativa": "Revoga parcialmente o(a)", + "descricao_passiva": "Revogado(a) parcialmente pelo(a)", + "sigla": "P" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "3" + }, + { + "fields": { + "descricao_ativa": "Revoga integralmente por consolida\u00e7\u00e3o", + "descricao_passiva": "Revogado(a) integralmente por consolida\u00e7\u00e3o", + "sigla": "T" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "4" + }, + { + "fields": { + "descricao_ativa": "Norma correlata", + "descricao_passiva": "Norma correlata", + "sigla": "C" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "5" + }, + { + "fields": { + "descricao_ativa": "Ressalva o(a)", + "descricao_passiva": "Ressalvada pelo(a)", + "sigla": "S" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "6" + }, + { + "fields": { + "descricao_ativa": "Reedita o(a)", + "descricao_passiva": "Reeditada pelo(a)", + "sigla": "E" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "7" + }, + { + "fields": { + "descricao_ativa": "Reedita com altera\u00e7\u00e3o o(a)", + "descricao_passiva": "Reeditada com altera\u00e7\u00e3o pelo(a)", + "sigla": "I" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "8" + }, + { + "fields": { + "descricao_ativa": "Regulamenta o(a)", + "descricao_passiva": "Regulamentada pelo(a)", + "sigla": "G" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "9" + }, + { + "fields": { + "descricao_ativa": "Suspende parcialmente o(a)", + "descricao_passiva": "Suspenso(a) parcialmente pelo(a)", + "sigla": "K" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "10" + }, + { + "fields": { + "descricao_ativa": "Suspende integralmente o(a)", + "descricao_passiva": "Suspenso(a) integralmente pelo(a)", + "sigla": "L" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "11" + }, + { + "fields": { + "descricao_ativa": "Julga integralmente inconstitucional", + "descricao_passiva": "Julgada integralmente inconstitucional", + "sigla": "N" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "12" + }, + { + "fields": { + "descricao_ativa": "Julga parcialmente inconstitucional", + "descricao_passiva": "Julgada parcialmente inconstitucional", + "sigla": "O" + }, + "model": "norma.TipoVinculoNormaJuridica", + "pk": "13" + } +] \ No newline at end of file diff --git a/sapl/norma/migrations/0008_normajuridica_popula_tipo_vinculo_norma.py b/sapl/norma/migrations/0008_normajuridica_popula_tipo_vinculo_norma.py new file mode 100644 index 000000000..3bfb90132 --- /dev/null +++ b/sapl/norma/migrations/0008_normajuridica_popula_tipo_vinculo_norma.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import os + +from django.core.management import call_command +from django.db import migrations + + +def gera_tipo_vinculo(apps, schema_editor): + TipoVinculoNormaJuridica = apps.get_model("norma", "TipoVinculoNormaJuridica") + + db_alias = schema_editor.connection.alias + tipo_vinculos = TipoVinculoNormaJuridica.objects.all().exists() + + if tipo_vinculos: + # Caso haja algum TipoVinculoNormaJuridica cadastrado na base de dados, + # a migração não deve ser carregada para evitar duplicações de dados. + print("Carga de {} não efetuada. Já Existem {} cadastrados...".format( + TipoVinculoNormaJuridica._meta.verbose_name, + TipoVinculoNormaJuridica._meta.verbose_name_plural + ) + ) + else: + fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures')) + # pega tipo_vinculo_norma_juridica listados em fixtures/pre_popula_tipo_vinculo_norma.json + fixture_filename = 'pre_popula_tipo_vinculo_norma.json' + fixture_file = os.path.join(fixture_dir, fixture_filename) + call_command('loaddata', fixture_file) + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0007_auto_20170904_1708'), + ] + + operations = [ + migrations.RunPython(gera_tipo_vinculo), + ] \ No newline at end of file From 5d750ef557f3b19eb32d92458ec2c196b360241d Mon Sep 17 00:00:00 2001 From: Edward Date: Wed, 18 Oct 2017 13:35:43 -0200 Subject: [PATCH 120/237] =?UTF-8?q?Inclui=20a=20extens=C3=A3o=20.zip=20aos?= =?UTF-8?q?=20tipos=20de=20textos=20permitidos=20(#1542)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sapl/utils.py b/sapl/utils.py index d645cb003..37565148d 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -328,6 +328,7 @@ TIPOS_TEXTO_PERMITIDOS = ( 'application/x-vnd.oasis.opendocument.text', 'application/pdf', 'application/x-pdf', + 'application/zip', 'application/acrobat', 'applications/vnd.pdf', 'text/pdf', From 46d4eadd9e3a09cfcc2dfe9aab3fcba234c5a2df Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Wed, 18 Oct 2017 13:52:17 -0200 Subject: [PATCH 121/237] FIX #1319 customizar painel (#1536) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adiciona teste de vie em SessaoPlenaria * Adiciona teste de view no CasaLegislativa e TipoAutor * Corrigi erros relacionados a PEP8 * Adiciona logotipo no painel * Arruma o tamanho do logo * Fix 1319 Adiciona opção para o usuário decidir se quer ou não mostrar o brasão no painel * Corrige erros referente a PEP8 * Corrige validação da configuração do brasão da Casa Legislativa Signed-off-by: João Pedro Sconetto Signed-off-by: Mariana Mendes * Adiciona verificação de existência de casa legislativa Signed-off-by: Mariana Mendes --- sapl/base/forms.py | 25 +++++++++++++++++-- .../0009_appconfig_mostrar_brasao_painel.py | 20 +++++++++++++++ sapl/base/models.py | 4 +++ sapl/painel/views.py | 14 ++++++++++- sapl/templates/base/layouts.yaml | 3 +++ sapl/templates/painel/index.html | 15 ++++++++++- 6 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 sapl/base/migrations/0009_appconfig_mostrar_brasao_painel.py diff --git a/sapl/base/forms.py b/sapl/base/forms.py index 7e64c33cd..1c47b2877 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -623,7 +623,7 @@ class CasaLegislativaForm(ModelForm): logotipo = self.cleaned_data.get('logotipo', False) if logotipo: if logotipo.size > MAX_IMAGE_UPLOAD_SIZE: - raise ValidationError("Imagem muito grande. ( > 2mb )") + raise ValidationError("Imagem muito grande. ( > 2MB )") return logotipo @@ -642,6 +642,12 @@ class LoginForm(AuthenticationForm): class ConfiguracoesAppForm(ModelForm): + mostrar_brasao_painel = forms.BooleanField( + help_text=_('Sugerimos fortemente que faça o upload de imagens com '\ + 'o fundo transparente.'), + label=_('Mostrar brasão da Casa no painel?'), + required=False) + class Meta: model = AppConfig fields = ['documentos_administrativos', @@ -653,7 +659,8 @@ class ConfiguracoesAppForm(ModelForm): 'proposicao_incorporacao_obrigatoria', 'cronometro_discurso', 'cronometro_aparte', - 'cronometro_ordem'] + 'cronometro_ordem', + 'mostrar_brasao_painel'] def __init__(self, *args, **kwargs): super(ConfiguracoesAppForm, self).__init__(*args, **kwargs) @@ -661,6 +668,20 @@ class ConfiguracoesAppForm(ModelForm): self.fields['cronometro_aparte'].widget.attrs['class'] = 'cronometro' self.fields['cronometro_ordem'].widget.attrs['class'] = 'cronometro' + def clean_mostrar_brasao_painel(self): + mostrar_brasao_painel = self.cleaned_data.get('mostrar_brasao_painel', + False) + casa = CasaLegislativa.objects.first() + + if not casa: + raise ValidationError("Não há casa legislativa relacionada") + + if (not bool(casa.logotipo) and mostrar_brasao_painel): + raise ValidationError("Não há logitipo configurado para esta " + "Casa legislativa.") + + return mostrar_brasao_painel + class RecuperarSenhaForm(PasswordResetForm): diff --git a/sapl/base/migrations/0009_appconfig_mostrar_brasao_painel.py b/sapl/base/migrations/0009_appconfig_mostrar_brasao_painel.py new file mode 100644 index 000000000..9fb469da7 --- /dev/null +++ b/sapl/base/migrations/0009_appconfig_mostrar_brasao_painel.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-10-16 20:06 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0008_auto_20170814_1409'), + ] + + operations = [ + migrations.AddField( + model_name='appconfig', + name='mostrar_brasao_painel', + field=models.BooleanField(default=False, verbose_name='Mostrar brasão da Casa no painel?'), + ), + ] diff --git a/sapl/base/models.py b/sapl/base/models.py index c75091341..03278a5af 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -157,6 +157,10 @@ class AppConfig(models.Model): blank=True, null=True) + mostrar_brasao_painel = models.BooleanField( + default=False, + verbose_name=_('Mostrar brasão da Casa no painel?')) + class Meta: verbose_name = _('Configurações da Aplicação') verbose_name_plural = _('Configurações da Aplicação') diff --git a/sapl/painel/views.py b/sapl/painel/views.py index eae434de3..4285545ab 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -10,6 +10,8 @@ from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import render from django.utils.translation import ugettext_lazy as _ +from sapl.base.models import AppConfig as ConfiguracoesAplicacao +from sapl.base.models import CasaLegislativa from sapl.crud.base import Crud from sapl.painel.apps import AppConfig from sapl.parlamentares.models import Votante @@ -397,6 +399,15 @@ def get_votos(response, materia): def get_dados_painel(request, pk): sessao = SessaoPlenaria.objects.get(id=pk) + casa = CasaLegislativa.objects.first() + + app_config = ConfiguracoesAplicacao.objects.first() + + brasao = None + if casa and app_config and (bool(casa.logotipo)): + brasao = casa.logotipo.url \ + if app_config.mostrar_brasao_painel else None + response = { 'sessao_plenaria': str(sessao), 'sessao_plenaria_data': sessao.data_inicio.strftime('%d/%m/%Y'), @@ -404,7 +415,8 @@ def get_dados_painel(request, pk): 'cronometro_aparte': get_cronometro_status(request, 'aparte'), 'cronometro_discurso': get_cronometro_status(request, 'discurso'), 'cronometro_ordem': get_cronometro_status(request, 'ordem'), - 'status_painel': sessao.painel_aberto + 'status_painel': sessao.painel_aberto, + 'brasao': brasao } ordem_dia = get_materia_aberta(pk) diff --git a/sapl/templates/base/layouts.yaml b/sapl/templates/base/layouts.yaml index cfa78b435..cef9615d6 100644 --- a/sapl/templates/base/layouts.yaml +++ b/sapl/templates/base/layouts.yaml @@ -23,6 +23,9 @@ AppConfig: {% trans 'Cronômetros do Painel' %}: - cronometro_discurso cronometro_aparte cronometro_ordem + {% trans 'Configurações do Painel' %}: + - mostrar_brasao_painel + TipoAutor: {% trans 'Tipo Autor' %}: - content_type:4 descricao diff --git a/sapl/templates/painel/index.html b/sapl/templates/painel/index.html index c6701b462..bfe6ade37 100644 --- a/sapl/templates/painel/index.html +++ b/sapl/templates/painel/index.html @@ -27,10 +27,16 @@ font-family: Verdana; } } + .center { + margin: auto; + width: 15%; + + } + - +

    @@ -45,6 +51,10 @@ +
    + +
    +

    @@ -168,6 +178,9 @@ $("#message").text(""); } + if (data["brasao"] != null) + $("#logo-painel").attr("src", data["brasao"]); + var presentes = $("#parlamentares"); var votacao = $("#votacao"); $("#votacao").text(''); From ec4de358f8aab0513672aba0324ad9c0f9f648d4 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 18 Oct 2017 14:51:17 -0200 Subject: [PATCH 122/237] =?UTF-8?q?HOT-FIX:=20desabilita=20possibilidade?= =?UTF-8?q?=20de=20visualizar=20painel=20por=20usu=C3=A1rio=20an=C3=B4nimo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/forms.py | 2 +- .../0010_remove_appconfig_painel_aberto.py | 19 +++++++++++++++++++ sapl/base/models.py | 7 ++++--- sapl/templates/base/layouts.yaml | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 sapl/base/migrations/0010_remove_appconfig_painel_aberto.py diff --git a/sapl/base/forms.py b/sapl/base/forms.py index 1c47b2877..6043c6c37 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -652,7 +652,7 @@ class ConfiguracoesAppForm(ModelForm): model = AppConfig fields = ['documentos_administrativos', 'sequencia_numeracao', - 'painel_aberto', + #'painel_aberto', # TODO: a ser implementado na versão 3.2 'texto_articulado_proposicao', 'texto_articulado_materia', 'texto_articulado_norma', diff --git a/sapl/base/migrations/0010_remove_appconfig_painel_aberto.py b/sapl/base/migrations/0010_remove_appconfig_painel_aberto.py new file mode 100644 index 000000000..cfe5f5c43 --- /dev/null +++ b/sapl/base/migrations/0010_remove_appconfig_painel_aberto.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2017-10-18 16:50 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0009_appconfig_mostrar_brasao_painel'), + ] + + operations = [ + migrations.RemoveField( + model_name='appconfig', + name='painel_aberto', + ), + ] diff --git a/sapl/base/models.py b/sapl/base/models.py index 03278a5af..29c0fa1cc 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -122,9 +122,10 @@ class AppConfig(models.Model): verbose_name=_('Sequência de numeração'), choices=SEQUENCIA_NUMERACAO, default='A') - painel_aberto = models.BooleanField( - verbose_name=_('Painel aberto para usuário anônimo'), - choices=YES_NO_CHOICES, default=False) + # TODO: a ser implementado na versão 3.2 + # painel_aberto = models.BooleanField( + # verbose_name=_('Painel aberto para usuário anônimo'), + # choices=YES_NO_CHOICES, default=False) texto_articulado_proposicao = models.BooleanField( verbose_name=_('Usar Textos Articulados para Proposições'), diff --git a/sapl/templates/base/layouts.yaml b/sapl/templates/base/layouts.yaml index cef9615d6..0b4b07b27 100644 --- a/sapl/templates/base/layouts.yaml +++ b/sapl/templates/base/layouts.yaml @@ -12,7 +12,7 @@ CasaLegislativa: AppConfig: {% trans 'Configurações da Aplicação' %}: - - documentos_administrativos painel_aberto + - documentos_administrativos {% trans 'Proposições e Protocolo' %}: - sequencia_numeracao proposicao_incorporacao_obrigatoria From 7d7429f89654b84660a7eb83a1b284c2e5fab0be Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 18 Oct 2017 14:57:11 -0200 Subject: [PATCH 123/237] =?UTF-8?q?Remove=20refer=C3=AAncia=20a=20painel-a?= =?UTF-8?q?berto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/views.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 7db713905..93cd3402c 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -708,14 +708,6 @@ class PainelView(PermissionRequiredForAppCrudMixin, TemplateView): template_name = 'sessao/painel.html' app_label = 'painel' - def has_permission(self): - painel_aberto = AppsAppConfig.attr('painel_aberto') - - if painel_aberto and self.request.user.is_anonymous(): - return True - - return PermissionRequiredForAppCrudMixin.has_permission(self) - def get(self, request, *args, **kwargs): if request.user.is_anonymous(): self.template_name = 'painel/index.html' From 038313b0fbbb4a56f202c570e3e5aac92074d6a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 19 Oct 2017 14:26:33 -0200 Subject: [PATCH 124/237] Corrige #1541 (#1543) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Aproxima a seleção do voto ao nome do parlamentar * Modifica a listagem de parlamentares mantendo conformidade solicitada na #1541 * Minor fix Fixes #1541 --- sapl/static/styles/app.scss | 22 ++++++++++++++++++++++ sapl/templates/sessao/votacao/nominal.html | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sapl/static/styles/app.scss b/sapl/static/styles/app.scss index 56b5a002f..7ca2d652a 100644 --- a/sapl/static/styles/app.scss +++ b/sapl/static/styles/app.scss @@ -493,3 +493,25 @@ p { width: 1070px; } } + +/* Estilização da Listagem de Votos em sessões plenárias */ + +#styleparlamentar { + border: 1px solid #d6e1e5; + border-top-color: rgb(214, 225, 229); + border-right-color: rgb(214, 225, 229); + border-bottom-color: rgb(214, 225, 229); + border-left-color: rgb(214, 225, 229); + border-image-source: initial; + border-image-slice: initial; + border-image-repeat: initial; + font-size: 16px; + line-height: 1.467; + padding: 7px 12px; + height: 40px; + -webkit-appearance: none; + border-radius: 4px; + -webkit-box-shadow: none; + box-shadow: none; + margin-left: 1.0em; +} diff --git a/sapl/templates/sessao/votacao/nominal.html b/sapl/templates/sessao/votacao/nominal.html index 576608e9c..8df750eef 100644 --- a/sapl/templates/sessao/votacao/nominal.html +++ b/sapl/templates/sessao/votacao/nominal.html @@ -28,8 +28,8 @@ Votos
    {% for parlamentar in parlamentares %} -
    {{parlamentar.0.nome_parlamentar}}
    -
    +
    {{parlamentar.0.nome_parlamentar}}
    +
    {% if parlamentar.1 %} {% endif %} - {% for tipo in tipos %} - - {% endfor %} - + {{ form.resultado_votacao|as_crispy_field }}
    From dd869383ce2c59a30fec62d9ba660430abeccfa1 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 25 Oct 2017 14:51:05 -0200 Subject: [PATCH 141/237] Novo release: 3.1.29-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 27ea387f1..155ff3a81 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.28-BETA + image: interlegis/sapl:3.1.29-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index 98b24a2c3..de6cfd646 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.28-BETA', + version='3.1.29-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From dbfdd4d3c1cd9e700c7c2142c955527d90f55aa9 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 25 Oct 2017 19:43:16 -0200 Subject: [PATCH 142/237] =?UTF-8?q?Refatora=20uniformiza=C3=A7=C3=A3o=20do?= =?UTF-8?q?=20banco=20antes=20da=20migra=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #1555 --- sapl/legacy/migration.py | 130 +++++++++++++++++++++++-- sapl/legacy/scripts/fix_tables.sql | 147 ----------------------------- 2 files changed, 120 insertions(+), 157 deletions(-) delete mode 100644 sapl/legacy/scripts/fix_tables.sql diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 176044f52..758091c75 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -1,6 +1,6 @@ import re from datetime import date -from functools import lru_cache +from functools import lru_cache, partial from subprocess import PIPE, call import pkg_resources @@ -139,18 +139,128 @@ def get_fk_related(field, value, label=None): raise ForeignKeyFaltando(msg) -def exec_sql_file(path, db='default'): - with open(path) as arq: - sql = arq.read() - with connections[db].cursor() as cursor: - cursor.execute(sql) - - def exec_sql(sql, db='default'): cursor = connections[db].cursor() cursor.execute(sql) return cursor +# UNIFORMIZAÇÃO DO BANCO ANTES DA MIGRAÇÃO ############################### + +SQL_NAO_TEM_TABELA = ''' + SELECT count(*) + FROM information_schema.columns + WHERE table_schema=database() + AND TABLE_NAME="{}" +''' +SQL_NAO_TEM_COLUNA = SQL_NAO_TEM_TABELA + ' AND COLUMN_NAME="{}"' + +exec_legado = partial(exec_sql, db='legacy') + + +def existe_tabela_no_legado(tabela): + sql = SQL_NAO_TEM_TABELA.format(tabela) + return exec_legado(sql).fetchone()[0] + + +def existe_coluna_no_legado(tabela, coluna): + sql = SQL_NAO_TEM_COLUNA.format(tabela, coluna) + return exec_legado(sql).fetchone()[0] > 0 + + +def garante_coluna_no_legado(tabela, spec_coluna): + coluna = spec_coluna.split()[0] + if not existe_coluna_no_legado(tabela, coluna): + exec_legado('ALTER TABLE {} ADD COLUMN {}'.format(tabela, spec_coluna)) + assert existe_coluna_no_legado(tabela, coluna) + + +def garante_tabela_no_legado(create_table): + tabela = create_table.strip().splitlines()[0].split()[2] + if not existe_tabela_no_legado(tabela): + exec_legado(create_table) + assert existe_tabela_no_legado(tabela) + + +def uniformiza_banco(): + exec_legado(''' + SELECT replace(@@sql_mode,"STRICT_TRANS_TABLES,","ALLOW_INVALID_DATES"); + ''') + + # ajusta data zero em proposicao + # isso é necessário para poder alterar a tabela a seguir + exec_legado(''' + UPDATE proposicao SET dat_envio = "1800-01-01" WHERE dat_envio = 0; + alter table proposicao modify dat_envio datetime; + UPDATE proposicao SET dat_envio = NULL where dat_envio = "1800-01-01"; + ''') + + garante_coluna_no_legado('proposicao', + 'num_proposicao int(11) NULL') + + garante_coluna_no_legado('tipo_materia_legislativa', + 'ind_num_automatica BOOLEAN NULL DEFAULT FALSE') + + garante_coluna_no_legado('tipo_materia_legislativa', + 'quorum_minimo_votacao int(11) NULL') + + # Cria campos cod_presenca_sessao (sendo a nova PK da tabela) + # e dat_sessao em sessao_plenaria_presenca + if not existe_coluna_no_legado('sessao_plenaria_presenca', + 'cod_presenca_sessao'): + exec_legado(''' + ALTER TABLE sessao_plenaria_presenca + DROP PRIMARY KEY, + ADD cod_presenca_sessao INT auto_increment PRIMARY KEY FIRST; + ''') + assert existe_coluna_no_legado('sessao_plenaria_presenca', + 'cod_presenca_sessao') + + garante_coluna_no_legado('sessao_plenaria_presenca', + 'dat_sessao DATE NULL') + + garante_tabela_no_legado(''' + CREATE TABLE lexml_registro_publicador ( + cod_publicador INT auto_increment NOT NULL, + id_publicador INT, nom_publicador varchar(255), + adm_email varchar(50), + sigla varchar(255), + nom_responsavel varchar(255), + tipo varchar(50), + id_responsavel INT, PRIMARY KEY (cod_publicador)); + ''') + + garante_tabela_no_legado(''' + CREATE TABLE lexml_registro_provedor ( + cod_provedor INT auto_increment NOT NULL, + id_provedor INT, nom_provedor varchar(255), + sgl_provedor varchar(15), + adm_email varchar(50), + nom_responsavel varchar(255), + tipo varchar(50), + id_responsavel INT, xml_provedor longtext, + PRIMARY KEY (cod_provedor)); + ''') + + garante_tabela_no_legado(''' + CREATE TABLE tipo_situacao_militar ( + tip_situacao_militar INT auto_increment NOT NULL, + des_tipo_situacao varchar(50), + ind_excluido INT, PRIMARY KEY (tip_situacao_militar)); + ''') + + update_specs = ''' +vinculo_norma_juridica| ind_excluido = '' | trim(ind_excluido) = '0' +unidade_tramitacao | cod_parlamentar = NULL | cod_parlamentar = 0 +parlamentar | cod_nivel_instrucao = NULL | cod_nivel_instrucao = 0 +parlamentar | tip_situacao_militar = NULL | tip_situacao_militar = 0 +mandato | tip_afastamento = NULL | tip_afastamento = 0 +relatoria | tip_fim_relatoria = NULL | tip_fim_relatoria = 0 + '''.strip().splitlines() + + for spec in update_specs: + spec = spec.split('|') + exec_legado('UPDATE {} SET {} WHERE {}'.format(*spec)) + def iter_sql_records(sql, db): class Record: @@ -333,8 +443,8 @@ class DataMigrator: def migrate(self, obj=appconfs, interativo=True): # warning: model/app migration order is of utmost importance - exec_sql_file(PROJECT_DIR.child( - 'sapl', 'legacy', 'scripts', 'fix_tables.sql'), 'legacy') + + uniformiza_banco() # excluindo database antigo. if interativo: diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql deleted file mode 100644 index 6146d7435..000000000 --- a/sapl/legacy/scripts/fix_tables.sql +++ /dev/null @@ -1,147 +0,0 @@ --- Apaga as restrições somente para essa sessão -SELECT replace(@@sql_mode,'STRICT_TRANS_TABLES,','ALLOW_INVALID_DATES'); - --- Exclui procedures caso já existam -DROP PROCEDURE IF EXISTS verifica_campos_proposicao; -DROP PROCEDURE IF EXISTS verifica_campos_tipo_materia_legislativa; -DROP PROCEDURE IF EXISTS verifica_campos_sessao_plenaria_presenca; -DROP PROCEDURE IF EXISTS cria_lexml_registro_provedor_e_publicador; -DROP PROCEDURE IF EXISTS cria_tipo_situacao_militar; -DROP PROCEDURE IF EXISTS muda_vinculo_norma_juridica_ind_excluido; -DROP PROCEDURE IF EXISTS muda_unidade_tramitacao_cod_parlamentar; - --- Procedure para criar campo num_proposicao em proposicao -CREATE PROCEDURE verifica_campos_proposicao() BEGIN IF NOT EXISTS - (SELECT * - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME='proposicao' - AND COLUMN_NAME='num_proposicao') THEN - - -- ajusta data zero para poder alterar a tabela - UPDATE proposicao SET dat_envio = '1800-01-01' WHERE dat_envio = 0; - alter table proposicao modify dat_envio datetime; - UPDATE proposicao SET dat_envio = NULL where dat_envio = '1800-01-01'; - - ALTER TABLE proposicao ADD COLUMN num_proposicao int(11) NULL AFTER txt_justif_devolucao; -END IF; END; - --- Procedure para criar campo iind_num_automatica em tipo_materia_legislativa -CREATE PROCEDURE verifica_campos_tipo_materia_legislativa() -BEGIN IF NOT EXISTS - (SELECT * - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME='tipo_materia_legislativa' - AND COLUMN_NAME='ind_num_automatica') THEN -ALTER TABLE tipo_materia_legislativa ADD COLUMN ind_num_automatica BOOLEAN NULL DEFAULT FALSE AFTER des_tipo_materia; -END IF; -IF NOT EXISTS - (SELECT * - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME='tipo_materia_legislativa' - AND COLUMN_NAME='quorum_minimo_votacao') THEN -ALTER TABLE tipo_materia_legislativa ADD COLUMN quorum_minimo_votacao int(11) NULL AFTER ind_num_automatica; -END IF; END; - --- Procedure para criar campos cod_presenca_sessao (sendo a nova PK da tabela) e dat_sessao em sessao_plenaria_presenca -CREATE PROCEDURE verifica_campos_sessao_plenaria_presenca() BEGIN IF NOT EXISTS - (SELECT * - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME='sessao_plenaria_presenca' - AND COLUMN_NAME='cod_presenca_sessao') THEN -ALTER TABLE sessao_plenaria_presenca -DROP PRIMARY KEY, - ADD cod_presenca_sessao INT auto_increment PRIMARY KEY FIRST; -END IF; -IF NOT EXISTS - (SELECT * - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME='sessao_plenaria_presenca' - AND COLUMN_NAME='dat_sessao') THEN -ALTER TABLE sessao_plenaria_presenca ADD COLUMN dat_sessao DATE NULL AFTER cod_parlamentar; -END IF; END; - - --- Procedure para criar tabela lexml_registro_provedor e lexml_registro_publicador -CREATE PROCEDURE cria_lexml_registro_provedor_e_publicador() -BEGIN IF NOT EXISTS - (SELECT * - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME='lexml_registro_publicador') THEN -CREATE TABLE lexml_registro_publicador ( - cod_publicador INT auto_increment NOT NULL, - id_publicador INT, nom_publicador varchar(255), - adm_email varchar(50), - sigla varchar(255), - nom_responsavel varchar(255), - tipo varchar(50), - id_responsavel INT, PRIMARY KEY (cod_publicador)); -END IF; -IF NOT EXISTS - (SELECT * - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME='lexml_registro_provedor') THEN -CREATE TABLE lexml_registro_provedor ( - cod_provedor INT auto_increment NOT NULL, - id_provedor INT, nom_provedor varchar(255), - sgl_provedor varchar(15), - adm_email varchar(50), - nom_responsavel varchar(255), - tipo varchar(50), - id_responsavel INT, xml_provedor longtext, - PRIMARY KEY (cod_provedor)); -END IF; END; - --- Procedure para criar tabela tipo_situacao_militar -CREATE PROCEDURE cria_tipo_situacao_militar() BEGIN IF NOT EXISTS - (SELECT * - FROM information_schema.columns - WHERE table_schema=database() - AND TABLE_NAME='tipo_situacao_militar') THEN -CREATE TABLE tipo_situacao_militar ( - tip_situacao_militar INT auto_increment NOT NULL, - des_tipo_situacao varchar(50), - ind_excluido INT, PRIMARY KEY (tip_situacao_militar)); -END IF; END; - --- Procedure para mudar valor do campo ind_excluido da tabela vinculo_norma_juridica de 0 para string vazia '' -CREATE PROCEDURE muda_vinculo_norma_juridica_ind_excluido() BEGIN -UPDATE vinculo_norma_juridica -SET ind_excluido = '' -WHERE trim(ind_excluido) = '0'; -END; - --- Procedure para mudar valor do campo cod_parlamentar da tabela unidade_tramitacao de 0 para string vazia NULL -CREATE PROCEDURE muda_unidade_tramitacao_cod_parlamentar() BEGIN -UPDATE unidade_tramitacao -SET cod_parlamentar = NULL -WHERE cod_parlamentar = 0; -END; - --- Executa as procedures criadas acima -CALL verifica_campos_proposicao; -CALL verifica_campos_tipo_materia_legislativa; -CALL verifica_campos_sessao_plenaria_presenca; -CALL cria_lexml_registro_provedor_e_publicador; -CALL cria_tipo_situacao_militar; -CALL muda_vinculo_norma_juridica_ind_excluido; -CALL muda_unidade_tramitacao_cod_parlamentar; - --- Corrige cod_parlamentar igual a zero em unidade de tramitação -update unidade_tramitacao set cod_parlamentar = NULL where cod_parlamentar = 0; - --- Corrige cod_nivel_instrucao e tip_situacao_militar zero em parlamentar -update parlamentar set cod_nivel_instrucao = NULL where cod_nivel_instrucao = 0; -update parlamentar set tip_situacao_militar = NULL where tip_situacao_militar = 0; - --- Corrige tip_afastamento igual a zero em mandato -update mandato set tip_afastamento = NULL where tip_afastamento = 0; - --- Corrige tip_fim_relatoria igual a zero em relatoria -update relatoria set tip_fim_relatoria = NULL where tip_fim_relatoria = 0; From c6484af4355d558c6156a67f2bcafde02f2c6be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 26 Oct 2017 10:10:20 -0200 Subject: [PATCH 143/237] Exibe o resultado da contagem de votos --- sapl/sessao/views.py | 18 +++++++++++++++++- .../templates/sessao/votacao/nominal_edit.html | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index c5d19eedc..94626b000 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -1931,11 +1931,27 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): ' ', ' ', strip_tags(ementa))} context.update({'materia': materia}) + votosSim = votosNao = abstencoes = naoRegistrados = 0 + for v in votos: + if v.voto == 'Sim': + votosSim += 1 + elif v.voto == 'Não': + votosNao += 1 + elif v.voto == 'Abstenção': + abstencoes += 1 + elif v.voto == '-1': + naoRegistrados += 1 + + list_contagem = {'votosSim': votosSim, 'votosNao': votosNao, 'abstencoes': abstencoes, + 'naoRegistrados': naoRegistrados} + + context.update({'contagem': list_contagem}) + votacao_existente = {'observacao': sub( ' ', ' ', strip_tags(votacao.observacao)), 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': - votacao.tipo_resultado_votacao_id} + votacao.tipo_resultado_votacao_id} context.update({'votacao': votacao_existente, 'tipos': self.get_tipos_votacao()}) diff --git a/sapl/templates/sessao/votacao/nominal_edit.html b/sapl/templates/sessao/votacao/nominal_edit.html index 35297e36c..af0629984 100644 --- a/sapl/templates/sessao/votacao/nominal_edit.html +++ b/sapl/templates/sessao/votacao/nominal_edit.html @@ -54,6 +54,21 @@
    +
    +
    +
    + Contagem do Resultado: +
    + Votos Sim: {{ contagem.votosSim }} +
    + Votos Não: {{ contagem.votosNao }} +
    + Abstenções: {{ contagem.abstencoes }} +
    + Votos Não Registrados: {{ contagem.naoRegistrados }} +
    +
    +
    From 70ac2fd0c4d8291597ea8a1f8df31811bb6ffe4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 26 Oct 2017 10:10:20 -0200 Subject: [PATCH 144/237] Exibe o resultado da contagem de votos --- sapl/sessao/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 94626b000..db25a1c90 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -1939,7 +1939,7 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): votosNao += 1 elif v.voto == 'Abstenção': abstencoes += 1 - elif v.voto == '-1': + elif v.voto == 'Não Votou': naoRegistrados += 1 list_contagem = {'votosSim': votosSim, 'votosNao': votosNao, 'abstencoes': abstencoes, From 3e77c3286f3dcaf1c4834077a34f57e0972b3bb5 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 26 Oct 2017 17:35:01 -0200 Subject: [PATCH 145/237] Fixes #1559 --- sapl/sessao/views.py | 18 ++++++++++++++++++ .../blocos_resumo/materias_expediente.html | 4 ++++ .../blocos_resumo/materias_ordem_dia.html | 4 ++++ 3 files changed, 26 insertions(+) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index c5d19eedc..9a1ef6d5e 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -1124,6 +1124,14 @@ class ResumoOrdenacaoView(PermissionRequiredMixin, FormView): return HttpResponseRedirect(self.get_success_url()) +def get_turno(turno): + for i in Tramitacao.TURNO_CHOICES: + if i[0] == turno: + return str(i[1]) + else: + return '' + + class ResumoView(DetailView): template_name = 'sessao/resumo.html' model = SessaoPlenaria @@ -1211,6 +1219,10 @@ class ResumoView(DetailView): ementa = m.materia.ementa titulo = m.materia numero = m.numero_ordem + tramitacao = m.materia.tramitacao_set.last() + turno = None + if tramitacao: + turno = get_turno(tramitacao.turno) rv = m.registrovotacao_set.first() if rv: @@ -1227,6 +1239,7 @@ class ResumoView(DetailView): mat = {'ementa': ementa, 'titulo': titulo, 'numero': numero, + 'turno': turno, 'resultado': resultado, 'resultado_observacao': resultado_observacao, 'autor': autor @@ -1271,6 +1284,10 @@ class ResumoView(DetailView): ementa = o.materia.ementa titulo = o.materia numero = o.numero_ordem + tramitacao = o.materia.tramitacao_set.last() + turno = None + if tramitacao: + turno = get_turno(tramitacao.turno) # Verificar resultado rv = o.registrovotacao_set.filter(materia=o.materia).first() @@ -1288,6 +1305,7 @@ class ResumoView(DetailView): mat = {'ementa': ementa, 'titulo': titulo, 'numero': numero, + 'turno': turno, 'resultado': resultado, 'resultado_observacao': resultado_observacao, 'autor': autor diff --git a/sapl/templates/sessao/blocos_resumo/materias_expediente.html b/sapl/templates/sessao/blocos_resumo/materias_expediente.html index 00f385bdd..2d1281b7c 100644 --- a/sapl/templates/sessao/blocos_resumo/materias_expediente.html +++ b/sapl/templates/sessao/blocos_resumo/materias_expediente.html @@ -14,6 +14,10 @@ {{m.numero}} - {{m.titulo}}
    + {% if m.turno %} + Turno: {{m.turno}} +
    + {% endif %} Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} {{m.ementa|safe}} diff --git a/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html b/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html index 7e3fd4af9..58dd7988f 100644 --- a/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html +++ b/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html @@ -13,7 +13,11 @@ {{m.numero}} - {{m.titulo}} +
    + {% if m.turno %} + Turno: {{m.turno}}
    + {% endif %} Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} {{m.ementa|safe}} From 221e61d8d5b3af5557c7dd5af976be965a4d4ec9 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Fri, 27 Oct 2017 15:13:36 -0200 Subject: [PATCH 146/237] =?UTF-8?q?Bloqueia=20ressubmiss=C3=A3o=20de=20for?= =?UTF-8?q?ms=20do=20crud=20(via=20JS)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/crispy_layout_mixin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index eec259190..c7421287a 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -36,7 +36,10 @@ def to_fieldsets(fields): def form_actions(more=[], save_label=_('Salvar')): return FormActions( - Submit('salvar', save_label, css_class='pull-right'), *more) + Submit('salvar', save_label, css_class='pull-right', + # para impedir resubmissão do form + onclick='this.disabled=true;'), + *more) class SaplFormLayout(Layout): From 97454480d3eea87550180db82f361d651f07e448 Mon Sep 17 00:00:00 2001 From: Eliseu Egewarth Date: Mon, 30 Oct 2017 13:50:15 -0200 Subject: [PATCH 147/237] 1557 fix registro duplicado (#1564) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bloqueia ressubmissão de votação nominal (via JS) * Fix #1563 --- sapl/crispy_layout_mixin.py | 2 +- sapl/templates/sessao/votacao/nominal.html | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index c7421287a..06808e5c3 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -38,7 +38,7 @@ def form_actions(more=[], save_label=_('Salvar')): return FormActions( Submit('salvar', save_label, css_class='pull-right', # para impedir resubmissão do form - onclick='this.disabled=true;'), + onclick='this.form.submit();this.disabled=true;'), *more) diff --git a/sapl/templates/sessao/votacao/nominal.html b/sapl/templates/sessao/votacao/nominal.html index 838747999..ad494dae5 100644 --- a/sapl/templates/sessao/votacao/nominal.html +++ b/sapl/templates/sessao/votacao/nominal.html @@ -69,5 +69,10 @@ function voltar() { window.history.back(); } + + $(window).on('beforeunload', function () { + $("input[type=submit], input[type=button]").prop("disabled", "disabled"); + }); + {% endblock extra_js%} From eaa8d447e6a6e1ad2493b4dc0caf15b14f7b6d69 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 30 Oct 2017 18:31:32 -0200 Subject: [PATCH 148/237] =?UTF-8?q?Insere=20quebra=20de=20linhas=20em=20re?= =?UTF-8?q?lat=C3=B3rio.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/templates/sessao/pauta/ordem.html | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sapl/templates/sessao/pauta/ordem.html b/sapl/templates/sessao/pauta/ordem.html index 8c0040c08..4bf5e6589 100644 --- a/sapl/templates/sessao/pauta/ordem.html +++ b/sapl/templates/sessao/pauta/ordem.html @@ -20,27 +20,26 @@ Norma Juridica Vinculada {% for n in norma %} - {{n}} + {{n}}
    {% endfor %}

    Outras Informações - Em Tramitação? {{ordem.materia.em_tramitacao|yesno:"Sim,Não"}}       - Matéria Polêmica? {{ordem.materia.polemica|yesno:"Sim,Não"}}       - Regime Tramitação: {{ordem.materia.regime_tramitacao}} + Em Tramitação? {{ordem.materia.em_tramitacao|yesno:"Sim,Não"}}      
    + Matéria Polêmica? {{ordem.materia.polemica|yesno:"Sim,Não"}}      
    + Regime Tramitação: {{ordem.materia.regime_tramitacao}}


    Documentos Acessórios {% for d in doc_ace %} - Nome: {{d.nome}}      - Tipo: {{d.tipo}}      - Data: {{d.data}}      - Autor: {{d.autor}}      - + Nome: {{d.nome}}     
    + Tipo: {{d.tipo}}     
    + Data: {{d.data}}     
    + Autor: {{d.autor}}     


    {% endfor %}
    From 3b9dd0753fd28c0e7cbceeb1c6d168f959f4e49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Fr=C3=A1?= Date: Tue, 31 Oct 2017 10:08:55 -0200 Subject: [PATCH 149/237] =?UTF-8?q?Ordena=20pela=20ordem=20de=20inclus?= =?UTF-8?q?=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/interlegis/sapl/issues/1568 --- 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 22147aae6..aa16b6a15 100644 --- a/sapl/comissoes/views.py +++ b/sapl/comissoes/views.py @@ -72,7 +72,7 @@ class ComposicaoCrud(MasterDetailCrud): context['participacao_set'] = Participacao.objects.filter( composicao__pk=context['composicao_pk'] - ).order_by('parlamentar') + ).order_by('id') return context From 0a5f342de82b7af79d0c07bc46c7fb5526da3ba7 Mon Sep 17 00:00:00 2001 From: Edward Date: Tue, 31 Oct 2017 13:11:39 -0200 Subject: [PATCH 150/237] Fixes #1559 (#1565) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes #1559 * Insere informações de processo e número de protocolo em Resumo * Hot fix --- .../templates/pdf_sessao_plenaria_gerar.py | 4 +- sapl/relatorios/views.py | 110 ++++++------------ sapl/sessao/views.py | 24 +++- .../blocos_resumo/materias_expediente.html | 10 +- .../blocos_resumo/materias_ordem_dia.html | 3 +- 5 files changed, 66 insertions(+), 85 deletions(-) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index e659d169e..a8677c5e1 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -243,8 +243,8 @@ def votacao(lst_votacao): tmp += '\n' tmp += 'MatériaEmentaResultado da Votação\n' for votacao in lst_votacao: - tmp += '' + str(votacao['num_ordem']) + ' - ' + votacao['id_materia'] + '\n' + 'Turno: ' + votacao[ - 'des_turno'] + '\n' + 'Autor: ' + votacao['nom_autor'] + '\n' + tmp += '' + str(votacao['num_ordem']) + ' - ' + votacao['id_materia'] + '\n' + 'Turno: ' + str(votacao[ + 'des_turno']) + '\n' + 'Autor: ' + str(votacao['nom_autor']) + '\n' txt_ementa = votacao['txt_ementa'].replace('&', '&') tmp += '' + txt_ementa + '\n' tmp += '' + \ diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 7719e6d2d..b5e0b4de2 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -563,21 +563,9 @@ def get_sessao_plenaria(sessao, casa): str(numeracao.numero_materia) + '/' + str( numeracao.ano_materia)) - dic_expediente_materia["des_turno"] = ' ' - tram = Tramitacao.objects.filter( - materia=materia).first() - if tram is not None: - if tram.turno != '': - for turno in [("P", _("Primeiro")), - ("S", _("Segundo")), - ("U", _("Único")), - ("L", _("Suplementar")), - ("A", _("Votação Única em Regime de Urgência")), - ("B", _("1ª Votação")), - ("C", _("2ª e 3ª Votações")), - ("F", "Final")]: - if tram.turno == turno[0]: - dic_expediente_materia["des_turno"] = turno[1] + turno, _ = get_turno(dic_expediente_materia, materia) + + dic_expediente_materia["des_turno"] = turno dic_expediente_materia["txt_ementa"] = str(materia.ementa) dic_expediente_materia["ordem_observacao"] = ' ' # TODO @@ -615,8 +603,8 @@ def get_sessao_plenaria(sessao, casa): dic_expediente_materia["votacao_observacao"] = ( i.observacao) else: - dic_expediente_materia["nom_resultado"] = _("Matéria não votada") - dic_expediente_materia["votacao_observacao"] = _(" ") + dic_expediente_materia["nom_resultado"] = 'Matéria não votada' + dic_expediente_materia["votacao_observacao"] = ' ' lst_expediente_materia.append(dic_expediente_materia) # Lista dos oradores do Expediente @@ -677,22 +665,10 @@ def get_sessao_plenaria(sessao, casa): str(numeracao.numero_materia) + '/' + str(numeracao.ano_materia)) - dic_votacao["des_turno"] = ' ' - - tramitacao = Tramitacao.objects.filter( - materia=materia).first() - if tramitacao is not None: - if not tramitacao.turno: - for turno in [("P", _("Primeiro")), - ("S", _("Segundo")), - ("U", _("Único")), - ("L", _("Suplementar")), - ("F", _("Final")), - ("A", _("Votação Única em Regime de Urgência")), - ("B", _("1ª Votação")), - ("C", _("2ª e 3ª Votações"))]: - if tramitacao.turno == turno[0]: - dic_votacao["des_turno"] = turno[1] + + turno, _ = get_turno(dic_votacao, materia) + + dic_votacao["des_turno"] = turno # https://github.com/interlegis/sapl/issues/1009 dic_votacao["txt_ementa"] = html.unescape(materia.ementa) @@ -728,8 +704,8 @@ def get_sessao_plenaria(sessao, casa): if votacao.observacao: dic_votacao["votacao_observacao"] = i.observacao else: - dic_votacao["nom_resultado"] = _("Matéria não votada") - dic_votacao["votacao_observacao"] = _(" ") + dic_votacao["nom_resultado"] = "Matéria não votada" + dic_votacao["votacao_observacao"] = " " lst_votacao.append(dic_votacao) # Lista dos oradores nas Explicações Pessoais @@ -761,6 +737,20 @@ def get_sessao_plenaria(sessao, casa): lst_oradores) +def get_turno(dic, materia): + descricao_turno = ' ' + descricao_tramitacao = ' ' + tramitacao = Tramitacao.objects.filter(materia=materia).order_by( + '-data_tramitacao').first() + if tramitacao is not None: + for t in Tramitacao.TURNO_CHOICES: + if t[0] == tramitacao.turno: + descricao_turno = t[1] + break + descricao_tramitacao = tramitacao.status.descricao if tramitacao.status else ' ' + return (descricao_turno, descricao_tramitacao) + + def relatorio_sessao_plenaria(request, pk): ''' pdf_sessao_plenaria_gerar.py @@ -1064,28 +1054,12 @@ def get_pauta_sessao(sessao, casa): elif autoria is None: dic_expediente_materia["nom_autor"] = 'Desconhecido' - dic_expediente_materia["des_turno"] = ' ' - dic_expediente_materia["des_situacao"] = ' ' - - tramitacao = Tramitacao.objects.filter(materia=materia) - if tramitacao is not None: - tramitacao = tramitacao.first() - - if tramitacao.turno != '': - for turno in [("P", _("Primeiro")), - ("S", _("Segundo")), - ("U", _("Único")), - ("F", _("Final")), - ("L", _("Suplementar")), - ("A", _("Votação Única em Regime de Urgência")), - ("B", _("1ª Votação")), - ("C", _("2ª e 3ª Votações"))]: - if tramitacao.turno == turno.first(): - dic_expediente_materia["des_turno"] = turno.first() - - dic_expediente_materia["des_situacao"] = tramitacao.status - if dic_expediente_materia["des_situacao"] is None: - dic_expediente_materia["des_situacao"] = ' ' + turno, tramitacao = get_turno(dic_expediente_materia, materia) + + dic_expediente_materia["des_turno"] = turno + dic_expediente_materia["des_situacao"] = tramitacao + + lst_expediente_materia.append(dic_expediente_materia) lst_votacao = [] @@ -1129,25 +1103,9 @@ def get_pauta_sessao(sessao, casa): elif autoria is None: dic_votacao["nom_autor"] = 'Desconhecido' - dic_votacao["des_turno"] = ' ' - dic_votacao["des_situacao"] = ' ' - tramitacao = Tramitacao.objects.filter(materia=materia) - if tramitacao is not None: - tramitacao = tramitacao.first() - if tramitacao.turno != '': - for turno in [("P", _("Primeiro")), - ("S", _("Segundo")), - ("U", _("Único")), - ("L", _("Suplementar")), - ("A", _("Votação Única em Regime de Urgência")), - ("B", _("1ª Votação")), - ("C", _("2ª e 3ª Votações"))]: - if tramitacao.turno == turno.first(): - dic_votacao["des_turno"] = turno.first() - - dic_votacao["des_situacao"] = tramitacao.status - if dic_votacao["des_situacao"] is None: - dic_votacao["des_situacao"] = ' ' + turno, tramitacao = get_turno(dic_expediente_materia, materia) + dic_votacao["des_turno"] = turno + dic_votacao["des_situacao"] = tramitacao lst_votacao.append(dic_votacao) return (lst_expediente_materia, diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 9a1ef6d5e..b691415ea 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -168,15 +168,25 @@ def customize_link_materia(context): autor = autoria.autor if autoria else None num_protocolo = materia.numero_protocolo + tramitacao = Tramitacao.objects.filter(materia=materia).last() + turno = ' ' + if tramitacao is not None: + for t in Tramitacao.TURNO_CHOICES: + if t[0] == tramitacao.turno: + turno = t[1] + break + title_materia = '''%s
    - Número de Processo: %s
    + Processo: %s
    Autor: %s
    - Número de Protocolo: %s
    + Protocolo: %s
    + Turno: %s
    ''' % (url_materia, row[1][0], numeracao if numeracao else '', autor if autor else '', - num_protocolo if num_protocolo else '') + num_protocolo if num_protocolo else '', + turno) # Na linha abaixo, o segundo argumento é None para não colocar # url em toda a string de title_materia @@ -1242,7 +1252,9 @@ class ResumoView(DetailView): 'turno': turno, 'resultado': resultado, 'resultado_observacao': resultado_observacao, - 'autor': autor + 'autor': autor, + 'numero_protocolo': m.materia.numero_protocolo, + 'numero_processo': m.materia.numeracao_set.last() } materias_expediente.append(mat) @@ -1308,7 +1320,9 @@ class ResumoView(DetailView): 'turno': turno, 'resultado': resultado, 'resultado_observacao': resultado_observacao, - 'autor': autor + 'autor': autor, + 'numero_protocolo': o.materia.numero_protocolo, + 'numero_processo': o.materia.numeracao_set.last() } materias_ordem.append(mat) diff --git a/sapl/templates/sessao/blocos_resumo/materias_expediente.html b/sapl/templates/sessao/blocos_resumo/materias_expediente.html index 2d1281b7c..e50b7129b 100644 --- a/sapl/templates/sessao/blocos_resumo/materias_expediente.html +++ b/sapl/templates/sessao/blocos_resumo/materias_expediente.html @@ -11,7 +11,7 @@ {% for m in materia_expediente %} - +
    {{m.numero}} - {{m.titulo}}
    {% if m.turno %} @@ -19,6 +19,14 @@
    {% endif %} Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} + {% if m.numero_protocolo %} +
    + Número de Protocolo: {{ m.numero_protocolo }} + {% endif %} + {% if m.numero_processo %} +
    + Processo: {{ m.numero_processo }} + {% endif %} {{m.ementa|safe}} {{m.resultado}}
    {{m.resultado_observacao}} diff --git a/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html b/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html index 58dd7988f..9951e5436 100644 --- a/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html +++ b/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html @@ -18,7 +18,8 @@ Turno: {{m.turno}}
    {% endif %} - Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} + Autor: {{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} + Protocolo: {{ m.autor|length|pluralize:"es" }} {{m.ementa|safe}} {{m.resultado}}
    {{m.resultado_observacao}} From bfb455195580206f6fba3a9160097e28a8d910fc Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 31 Oct 2017 13:44:19 -0200 Subject: [PATCH 151/237] HOT FIX --- .../blocos_resumo/materias_expediente.html | 13 ++++++++---- .../blocos_resumo/materias_ordem_dia.html | 20 +++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/sapl/templates/sessao/blocos_resumo/materias_expediente.html b/sapl/templates/sessao/blocos_resumo/materias_expediente.html index e50b7129b..556b53039 100644 --- a/sapl/templates/sessao/blocos_resumo/materias_expediente.html +++ b/sapl/templates/sessao/blocos_resumo/materias_expediente.html @@ -11,18 +11,23 @@ {% for m in materia_expediente %} -
    + {{m.numero}} - {{m.titulo}} -
    + {% if m.turno %} - Turno: {{m.turno}} -
    +
    + Turno: {{m.turno}} {% endif %} + +
    + Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} + {% if m.numero_protocolo %}
    Número de Protocolo: {{ m.numero_protocolo }} {% endif %} + {% if m.numero_processo %}
    Processo: {{ m.numero_processo }} diff --git a/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html b/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html index 9951e5436..593c908c7 100644 --- a/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html +++ b/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html @@ -13,13 +13,25 @@ {{m.numero}} - {{m.titulo}} -
    + {% if m.turno %} - Turno: {{m.turno}} +
    + Turno: {{m.turno}} + {% endif %} +
    + + Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} + + {% if m.numero_protocolo %} +
    + Número de Protocolo: {{ m.numero_protocolo }} + {% endif %} + + {% if m.numero_processo %} +
    + Processo: {{ m.numero_processo }} {% endif %} - Autor: {{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} - Protocolo: {{ m.autor|length|pluralize:"es" }} {{m.ementa|safe}} {{m.resultado}}
    {{m.resultado_observacao}} From 2b6d1eb3de91362657a15a52d18b4f6626039cc5 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 31 Oct 2017 13:47:00 -0200 Subject: [PATCH 152/237] =?UTF-8?q?Add=20valor=20padr=C3=A3o=20em=20model?= =?UTF-8?q?=20da=20app=20compila=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0004_auto_20171031_1327.py | 25 +++++++++++++++++++ sapl/compilacao/models.py | 6 ++--- 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 sapl/compilacao/migrations/0004_auto_20171031_1327.py diff --git a/sapl/compilacao/migrations/0004_auto_20171031_1327.py b/sapl/compilacao/migrations/0004_auto_20171031_1327.py new file mode 100644 index 000000000..f5820c6a8 --- /dev/null +++ b/sapl/compilacao/migrations/0004_auto_20171031_1327.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-10-31 15:27 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0003_auto_20170825_1136'), + ] + + operations = [ + migrations.AlterField( + model_name='tipotextoarticulado', + name='participacao_social', + field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Participação Social'), + ), + migrations.AlterField( + model_name='tipotextoarticulado', + name='publicacao_func', + field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Histórico de Publicação'), + ), + ] diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index 9f38b5def..e4be0762b 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -1,5 +1,4 @@ -import reversion from django.contrib import messages from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType @@ -13,6 +12,7 @@ from django.utils import timezone from django.utils.decorators import classonlymethod from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ +import reversion from sapl.compilacao.utils import (get_integrations_view_names, int_to_letter, int_to_roman) @@ -115,13 +115,13 @@ class TipoTextoArticulado(models.Model): on_delete=models.SET_NULL, verbose_name=_('Modelo Integrado')) participacao_social = models.BooleanField( - blank=False, + blank=False, default=False, choices=YES_NO_CHOICES, verbose_name=_('Participação Social')) publicacao_func = models.BooleanField( choices=YES_NO_CHOICES, - blank=False, + blank=False, default=False, verbose_name=_('Histórico de Publicação')) perfis = models.ManyToManyField( From b2feb505c14d318946241dfd93fc07de8e613b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Tue, 31 Oct 2017 17:18:39 -0200 Subject: [PATCH 153/237] Fix #1572 (#1573) --- sapl/templates/comissoes/composicao_list.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sapl/templates/comissoes/composicao_list.html b/sapl/templates/comissoes/composicao_list.html index 4e1c5c691..49dd07768 100644 --- a/sapl/templates/comissoes/composicao_list.html +++ b/sapl/templates/comissoes/composicao_list.html @@ -29,11 +29,13 @@
    - + {% if user.is_authenticated %} + + {% endif %}
    From c05659ae096b4b38cbe271518ce9a84fa0584371 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 1 Nov 2017 16:10:57 -0200 Subject: [PATCH 154/237] =?UTF-8?q?Retorna=20o=20=C3=BAltimo=20turno=20de?= =?UTF-8?q?=20uma=20tramita=C3=A7=C3=A3o=20onde=20turno=20n=C3=A3o=20?= =?UTF-8?q?=C3=A9=20vazio.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/relatorios/views.py | 10 ++++++++-- sapl/sessao/views.py | 9 ++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index b5e0b4de2..c6e429afe 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -740,8 +740,14 @@ def get_sessao_plenaria(sessao, casa): def get_turno(dic, materia): descricao_turno = ' ' descricao_tramitacao = ' ' - tramitacao = Tramitacao.objects.filter(materia=materia).order_by( - '-data_tramitacao').first() + tramitacao = Tramitacao.objects.filter(materia=materia, turno__isnull=False + ).exclude(turno__exact='' + ).select_related( + 'materia', + 'status', + 'materia__tipo').order_by( + '-data_tramitacao' + ).first() if tramitacao is not None: for t in Tramitacao.TURNO_CHOICES: if t[0] == tramitacao.turno: diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 536e13b67..acbe413a2 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -168,7 +168,14 @@ def customize_link_materia(context): autor = autoria.autor if autoria else None num_protocolo = materia.numero_protocolo - tramitacao = Tramitacao.objects.filter(materia=materia).last() + tramitacao = Tramitacao.objects.filter(materia=materia, turno__isnull=False + ).exclude(turno__exact='' + ).select_related( + 'materia', + 'status', + 'materia__tipo').order_by( + '-data_tramitacao' + ).first() turno = ' ' if tramitacao is not None: for t in Tramitacao.TURNO_CHOICES: From bec1f7ed55f3ad8b9eaac3384fc6ad887e4b6723 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 1 Nov 2017 18:51:52 -0200 Subject: [PATCH 155/237] Novo release: 3.1.30-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 155ff3a81..2f69ff36c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.29-BETA + image: interlegis/sapl:3.1.30-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index de6cfd646..2d69d9906 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.29-BETA', + version='3.1.30-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From 93a352d0db778d1f312de1e3ddce5832b7c236a5 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 31 Oct 2017 18:45:05 -0200 Subject: [PATCH 156/237] Adiciona hasher para senhas migradas do zope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (com utilitário para migrar para o novo formato) --- sapl/hashers.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ sapl/settings.py | 5 +++++ test_hashers.py | 11 ++++++++++ 3 files changed, 70 insertions(+) create mode 100644 sapl/hashers.py create mode 100644 test_hashers.py diff --git a/sapl/hashers.py b/sapl/hashers.py new file mode 100644 index 000000000..a514f8f19 --- /dev/null +++ b/sapl/hashers.py @@ -0,0 +1,54 @@ +import base64 +import hashlib + +from django.contrib.auth.hashers import PBKDF2PasswordHasher, make_password +from django.utils.encoding import force_bytes + + +def to_base64(source): + return base64.b64encode(source).decode('utf-8') + + +class ZopeSHA1PasswordHasher(PBKDF2PasswordHasher): + """ + The SHA1 password hashing algorithm used by Zope. + Zope uses `password + salt`, Django has `salt + password`. + Pre encode with SHA1 in this order and PBKDF2 afterwards. + + based on https://www.fourdigits.nl/blog/converting-plone-data-to-django/ + """ + + algorithm = "zope_sha1_pbkdf2" + + def encode(self, password, salt, iterations=None): + assert password is not None + assert salt + password = force_bytes(password) + decoded_salt = base64.b64decode(salt) + + # this is what is stored in zope + hashed = hashlib.sha1(password + decoded_salt).digest() + decoded_salt + hashed = to_base64(hashed) + + # encode again with the standard method + return super().encode(hashed, salt, iterations) + + +def get_salt_from_zope_sha1(data): + intermediate = base64.b64decode(data) + salt = intermediate[20:].strip() + return to_base64(salt) + + +ZOPE_SHA1_PREFIX = '{SSHA}' + + +def zope_encoded_password_to_django(encoded): + if encoded.startswith(ZOPE_SHA1_PREFIX): + data = encoded[len(ZOPE_SHA1_PREFIX):] + salt = get_salt_from_zope_sha1(data) + hasher = ZopeSHA1PasswordHasher() + return super(ZopeSHA1PasswordHasher, hasher).encode(data, salt) + else: + # assume it's a plain password and use the default hashing + return make_password(encoded) diff --git a/sapl/settings.py b/sapl/settings.py index 4598023bd..5c933d57f 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -299,3 +299,8 @@ def excepthook(*args): 'Uncaught exception:', exc_info=args) # sys.excepthook = excepthook + +PASSWORD_HASHERS = [ + 'django.contrib.auth.hashers.PBKDF2PasswordHasher', # default + 'sapl.hashers.ZopeSHA1PasswordHasher', +] diff --git a/test_hashers.py b/test_hashers.py new file mode 100644 index 000000000..c21f13af7 --- /dev/null +++ b/test_hashers.py @@ -0,0 +1,11 @@ +from sapl.hashers import (ZopeSHA1PasswordHasher, + zope_encoded_password_to_django) + + +def test_zope_encoded_password_to_django(): + password = 'saploper' + encoded = '{SSHA}Swzvwt/2lSJfA8KUOl6cRjkpmHLkLkmsKu28' + salt = '5C5JrCrtvA==' + migrated = zope_encoded_password_to_django(encoded) + encoded = ZopeSHA1PasswordHasher().encode(password, salt) + assert migrated == encoded From 19a7ed99773444cf65cc346913aeed78536886c0 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 6 Nov 2017 14:03:24 -0200 Subject: [PATCH 157/237] =?UTF-8?q?Ajusta=20migra=C3=A7=C3=A3o=20de=20usu?= =?UTF-8?q?=C3=A1rios=20p=20nova=20forma=20de=20dump?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migracao_usuarios.py | 80 ++++++++++++++++++-------------- sapl/legacy/migration.py | 3 +- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/sapl/legacy/migracao_usuarios.py b/sapl/legacy/migracao_usuarios.py index 7131dfca8..88fb77343 100644 --- a/sapl/legacy/migracao_usuarios.py +++ b/sapl/legacy/migracao_usuarios.py @@ -1,14 +1,9 @@ -import yaml -from django.conf import settings from django.contrib.auth.models import Group, User +from sapl.settings import MEDIA_ROOT -def le_yaml_dados_zope(caminho_yaml): - with open(caminho_yaml, 'r') as f: - dados = yaml.load(f.read()) - return dados - -PERFIL_LEGADO_PARA_NOVO = [ +PERFIL_LEGADO_PARA_NOVO = {legado: Group.objects.get(name=novo) + for legado, novo in [ ('Autor', 'Autor'), ('Operador', 'Operador Geral'), ('Operador Comissao', 'Operador de Comissões'), @@ -18,32 +13,40 @@ PERFIL_LEGADO_PARA_NOVO = [ ('Operador Parlamentar', 'Parlamentar'), ('Operador Protocolo', 'Operador de Protocolo Administrativo'), ('Operador Sessao Plenaria', 'Operador de Sessão Plenária'), + ('Parlamentar', 'Votante'), ] +} -ADMINISTRADORES = ['Administrador', 'Manager'] +ADMINISTRADORES = {'Administrador', 'Manager'} -VOTANTE = Group.objects.get(name='Votante') +IGNORADOS = { + # sem significado fora do zope + 'Alterar Senha', 'Authenticated', 'Owner', + # obsoletos (vide docs a seguir) + 'Operador Mesa Diretora', + 'Operador Ordem Dia', + 'Operador Tabela Auxiliar', + 'Operador Lexml', +} -def migra_usuarios(caminho_yaml): - """ - Existe um método em nosso projeto interno de **consulta a todos os sapls** - que exporta os dados de usuários (e nome da casa e url interna) - como um yaml. - Esse yaml é lido por essa rotina e os usuários são criados se necessário - e seus perfis ajustados. +def migra_usuarios(): + """ + Lê o arquivo media/USERS e importa os usuários nele listados, + com senhas e perfis. + Os usuários são criados se necessário e seus perfis ajustados. Os seguintes perfis no legado não correspondem a nenhum no código atual e estão sendo **ignorados**: * Operador Mesa Diretora - Contei apenas **8 usuários**, em todas as bases, que tem esse perfil - e não tem nem "Operador" nem "Operador Sessao Plenaria" + Apenas **8 usuários**, em todas as bases, têm esse perfil + e não têm nem "Operador" nem "Operador Sessao Plenaria" * Operador Ordem Dia - Contei apenas **16 usuários**, em todas as bases, que tem esse perfil - e não tem nem "Operador" nem "Operador Sessao Plenaria" + Apenas **16 usuários**, em todas as bases, têm esse perfil + e não têm nem "Operador" nem "Operador Sessao Plenaria" * Operador Tabela Auxiliar A edição das tabelas auxiliares deve ser feita por um administrador @@ -51,19 +54,26 @@ def migra_usuarios(caminho_yaml): * Operador Lexml Também podemos assumir que essa é uma tarefa de um administrador """ - dados = le_yaml_dados_zope(caminho_yaml) - db = settings.DATABASES['legacy']['NAME'] - nome, url, usuarios_perfis = dados[db] - for nome, perfis in usuarios_perfis: - usuario, _ = User.objects.get_or_create(username=nome) - for legado, novo in PERFIL_LEGADO_PARA_NOVO: - if legado in perfis: - grupo = Group.objects.get(name=novo) - usuario.groups.add(grupo) - # Manager - if any(a in perfis for a in ADMINISTRADORES): + + ARQUIVO_USUARIOS = MEDIA_ROOT.child('USERS') + with open(ARQUIVO_USUARIOS, 'r') as f: + usuarios = eval(f.read()) + usuarios = [ + (nome, + # troca senha "inicial" por uma inutilizável + senha if senha != 'inicial' else None, + # filtra perfis ignorados + {p for p in perfis if p not in IGNORADOS}) + for nome, senha, perfis in usuarios] + + for nome, senha, perfis in usuarios: + usuario = User.objects.get_or_create(username=nome)[0] + for perfil in perfis: + if perfil in ADMINISTRADORES: + # Manager usuario.is_staff = True usuario.save() - # Votante - if 'Parlamentar' in perfis: - usuario.groups.add(VOTANTE) + else: + usuario.groups.add(PERFIL_LEGADO_PARA_NOVO[perfil]) + # apaga arquivo (importante pois contém senhas) + ARQUIVO_USUARIOS.remove() diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 758091c75..f61f564ff 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -825,7 +825,8 @@ def adjust_autor(new, old): if not user_model.objects.filter(username=old.col_username).exists(): # cria um novo ususaŕio para o autor user = user_model(username=old.col_username) - user.set_password(12345) + # gera uma senha inutilizável, que precisará ser trocada + user.set_password(None) with reversion.create_revision(): user.save() reversion.set_comment( From fb01920999713467897fae2f6938703ba233779e Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Mon, 6 Nov 2017 18:44:53 -0200 Subject: [PATCH 158/237] Fix #1577 (#1579) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #1577 * Adiciona verificação de mandato com legislatura --- sapl/painel/views.py | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 4285545ab..9682b5b01 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -8,13 +8,14 @@ from django.db.models import Q from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import render +from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from sapl.base.models import AppConfig as ConfiguracoesAplicacao from sapl.base.models import CasaLegislativa from sapl.crud.base import Crud from sapl.painel.apps import AppConfig -from sapl.parlamentares.models import Votante +from sapl.parlamentares.models import Legislatura, Parlamentar, Votante from sapl.sessao.models import (ExpedienteMateria, OrdemDia, PresencaOrdemDia, RegistroVotacao, SessaoPlenaria, SessaoPlenariaPresenca, VotoParlamentar) @@ -296,20 +297,27 @@ def get_presentes(pk, response, materia): presentes_list = [] for p in presentes: - filiacao = filiacao_data(p.parlamentar, data_sessao, data_sessao) - - if not filiacao: - partido = 'Sem Registro' - else: - partido = filiacao - - presentes_list.append( - {'id': p.id, - 'parlamentar_id': p.parlamentar.id, - 'nome': p.parlamentar.nome_parlamentar, - 'partido': partido, - 'voto': '' - }) + now_year = timezone.now().year + # Recupera a legislatura vigente + legislatura = Legislatura.objects.get(data_inicio__year__lte = now_year, + data_fim__year__gte = now_year) + # Recupera os mandatos daquele parlamentar + mandatos = p.parlamentar.mandato_set.filter(legislatura=legislatura) + + if p.parlamentar.ativo and mandatos: + filiacao = filiacao_data(p.parlamentar, data_sessao, data_sessao) + if not filiacao: + partido = 'Sem Registro' + else: + partido = filiacao + + presentes_list.append( + {'id': p.id, + 'parlamentar_id': p.parlamentar.id, + 'nome': p.parlamentar.nome_parlamentar, + 'partido': partido, + 'voto': '' + }) if materia: if materia.tipo_votacao == 1: From 279945a64fa027a5ea36add635f7aaa0d21567f8 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Mon, 6 Nov 2017 18:45:03 -0200 Subject: [PATCH 159/237] Fix #1535 (#1574) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #1535 * HOT-FIX * Retira espaços em branco --- sapl/sessao/urls.py | 7 +- sapl/sessao/views.py | 59 +++++++++++++++-- .../sessao/votacao/nominal_edit.html | 12 ++-- .../sessao/votacao/nominal_transparencia.html | 65 +++++++++++++++++++ 4 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 sapl/templates/sessao/votacao/nominal_transparencia.html diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index e454a9eee..5f2f5ef4f 100644 --- a/sapl/sessao/urls.py +++ b/sapl/sessao/urls.py @@ -19,7 +19,9 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente, VotacaoNominalExpedienteDetailView, VotacaoNominalExpedienteEditView, VotacaoNominalExpedienteView, - VotacaoNominalView, VotacaoView, abrir_votacao, + VotacaoNominalView, + VotacaoNominalTransparenciaDetailView, + VotacaoView, abrir_votacao, atualizar_mesa, insere_parlamentar_composicao, mudar_ordem_materia_sessao, recuperar_materia, recuperar_numero_sessao, @@ -145,6 +147,9 @@ urlpatterns = [ VotacaoExpedienteView.as_view(), name='votacaosecretaexp'), url(r'^sessao/(?P\d+)/matexp/votsec/view/(?P\d+)/(?P\d+)$', VotacaoExpedienteEditView.as_view(), name='votacaosecretaexpedit'), + url(r'^sessao/(?P\d+)/votacao-nominal-transparencia/(?P\d+)/(?P\d+)$', + VotacaoNominalTransparenciaDetailView.as_view(), + name='votacao_nominal_transparencia'), url(r'^sessao/mudar-ordem-materia-sessao/', mudar_ordem_materia_sessao, diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index acbe413a2..affc07d4a 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -348,9 +348,17 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): resultado_descricao, resultado_observacao)) else: - obj.resultado = ('%s
    %s' % - (resultado_descricao, - resultado_observacao)) + if obj.tipo_votacao == 2: + url = reverse('sapl.sessao:votacao_nominal_transparencia', + kwargs={ + 'pk': obj.sessao_plenaria_id, + 'oid': obj.pk, + 'mid': obj.materia_id}) +\ + '?&materia=expediente' + else: + obj.resultado = ('%s
    %s' % + (resultado_descricao, + resultado_observacao)) return [self._as_row(obj) for obj in object_list] @@ -395,6 +403,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud): for obj in object_list: exist_resultado = obj.registrovotacao_set.filter( materia=obj.materia).exists() + if not exist_resultado: if obj.votacao_aberta: url = '' @@ -470,11 +479,12 @@ class ExpedienteMateriaCrud(MasterDetailCrud): else: if obj.tipo_votacao == 2: url = reverse( - 'sapl.sessao:votacaonominalexpdetail', + 'sapl.sessao:votacao_nominal_transparencia', kwargs={ 'pk': obj.sessao_plenaria_id, 'oid': obj.pk, - 'mid': obj.materia_id}) + 'mid': obj.materia_id}) +\ + '?&materia=expediente' obj.resultado = ('%s
    %s' % (url, resultado_descricao, @@ -2057,6 +2067,45 @@ class VotacaoNominalExpedienteEditView(VotacaoNominalEditAbstract): ordem = False +class VotacaoNominalTransparenciaDetailView(TemplateView): + template_name = 'sessao/votacao/nominal_transparencia.html' + + def get_context_data(self, **kwargs): + context = super(VotacaoNominalTransparenciaDetailView, + self).get_context_data(**kwargs) + + materia_votacao = self.request.GET.get('materia', None) + + if materia_votacao == 'ordem': + votacao = RegistroVotacao.objects.get(ordem=self.kwargs['oid']) + if materia_votacao == 'expediente': + votacao = RegistroVotacao.objects.get(expediente=self.kwargs['oid']) + else: + raise Http404() + + context['votacao'] = votacao + + voto_parlamentar = VotoParlamentar.objects.filter( + votacao=votacao) + + context['voto_parlamentar'] = voto_parlamentar + + votacao_existente = {'observacao': sub( + ' ', ' ', strip_tags(votacao.observacao)), + 'resultado': votacao.tipo_resultado_votacao.nome, + 'tipo_resultado': + votacao.tipo_resultado_votacao_id} + context.update({'resultado_votacao': votacao_existente, + 'tipos': self.get_tipos_votacao()}) + + return context + + def get_tipos_votacao(self): + for tipo in TipoResultadoVotacao.objects.all(): + yield tipo + + + class VotacaoNominalExpedienteDetailView(DetailView): template_name = 'sessao/votacao/nominal_detail.html' diff --git a/sapl/templates/sessao/votacao/nominal_edit.html b/sapl/templates/sessao/votacao/nominal_edit.html index af0629984..f751e21d9 100644 --- a/sapl/templates/sessao/votacao/nominal_edit.html +++ b/sapl/templates/sessao/votacao/nominal_edit.html @@ -34,11 +34,11 @@
    - Anular Votação - + Anular Votação +
    @@ -78,7 +78,7 @@


    - + {% endblock detail_content %} diff --git a/sapl/templates/sessao/votacao/nominal_transparencia.html b/sapl/templates/sessao/votacao/nominal_transparencia.html new file mode 100644 index 000000000..cb0bb25e2 --- /dev/null +++ b/sapl/templates/sessao/votacao/nominal_transparencia.html @@ -0,0 +1,65 @@ +{% extends "crud/detail.html" %} +{% load i18n %} + +{% block detail_content %} +
    + {% csrf_token %} + +
    + Votação Nominal +
    + Matéria: {{votacao.materia}} +
    + Ementa: {{votacao.materia.ementa}} +
    + +
    +
    + Votos +
    + {% for v in voto_parlamentar %} + +
    {{v.parlamentar}} - + {% if v.voto == '-1'%} + Voto não Registrado + {% else %} + {{v.voto}} + {% endif %} +
    + + {% endfor %} +
    +
    + +
    + +
    +
    +
    + Resultado da Votação: + {% for tipo in tipos %} + {% if resultado_votacao.tipo_resultado == tipo.id %} + {{ tipo.nome }} + {% endif %} + {% endfor %} +
    +
    + +
    +
    +
    + Observações + +
    +
    + +

    +
    +
    +{% endblock detail_content %} + +{% block foot_js %} + +{% endblock %} From df4d1f11869666966fe16f037efe6277e81f1f16 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 7 Nov 2017 10:01:22 -0200 Subject: [PATCH 160/237] Ajst leitura de default database em legacy settings --- sapl/legacy_migration_settings.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sapl/legacy_migration_settings.py b/sapl/legacy_migration_settings.py index 221ea9d48..5d2faae00 100644 --- a/sapl/legacy_migration_settings.py +++ b/sapl/legacy_migration_settings.py @@ -13,8 +13,10 @@ INSTALLED_APPS += ( ) DATABASES['legacy'] = config('DATABASE_URL_FONTE', cast=db_url,) -DATABASES['default'] = config('DATABASE_URL_DESTINO', cast=db_url, - default=DATABASES['default']) +DATABASES['default'] = config( + 'DATABASE_URL_DESTINO', + cast=lambda v: v if isinstance(v, dict) else db_url, + default=DATABASES['default']) # Sobrescreve o nome dos bancos caso a variável de ambiente seja definida # Útil para migração em lote de vários bancos From 90526f8bb92cbcd3112ff8c820a7f0c71ead5647 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 7 Nov 2017 10:06:13 -0200 Subject: [PATCH 161/237] corrige lambda function em legacy settings --- sapl/legacy_migration_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/legacy_migration_settings.py b/sapl/legacy_migration_settings.py index 5d2faae00..c8b1fe3a7 100644 --- a/sapl/legacy_migration_settings.py +++ b/sapl/legacy_migration_settings.py @@ -15,7 +15,7 @@ INSTALLED_APPS += ( DATABASES['legacy'] = config('DATABASE_URL_FONTE', cast=db_url,) DATABASES['default'] = config( 'DATABASE_URL_DESTINO', - cast=lambda v: v if isinstance(v, dict) else db_url, + cast=lambda v: v if isinstance(v, dict) else db_url(v), default=DATABASES['default']) # Sobrescreve o nome dos bancos caso a variável de ambiente seja definida From 0cc9ee7d07c3e88a7249c8236c88536c93396f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Tue, 7 Nov 2017 14:41:58 -0200 Subject: [PATCH 162/237] =?UTF-8?q?Remo=C3=A7=C3=A3o=20da=20view=20exceden?= =?UTF-8?q?te=20de=20detalhes=20da=20mat=C3=A9ria=20e=20mudan=C3=A7a=20nas?= =?UTF-8?q?=20p=C3=A1ginas=20relacionadas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: João Pedro Sconetto Signed-off-by: Mariana Mendes --- sapl/sessao/urls.py | 5 -- sapl/sessao/views.py | 40 ------------- sapl/templates/sessao/pauta/expediente.html | 52 ---------------- sapl/templates/sessao/pauta/ordem.html | 59 ------------------- .../templates/sessao/pauta_sessao_detail.html | 4 +- 5 files changed, 2 insertions(+), 158 deletions(-) delete mode 100644 sapl/templates/sessao/pauta/expediente.html delete mode 100644 sapl/templates/sessao/pauta/ordem.html diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index 5f2f5ef4f..d9a611ba8 100644 --- a/sapl/sessao/urls.py +++ b/sapl/sessao/urls.py @@ -6,7 +6,6 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente, ExpedienteMateriaCrud, ExpedienteView, MateriaOrdemDiaCrud, MesaView, OradorCrud, OradorExpedienteCrud, PainelView, - PautaExpedienteDetail, PautaOrdemDetail, PautaSessaoDetailView, PautaSessaoListView, PesquisarPautaSessaoView, PesquisarSessaoPlenariaView, @@ -97,10 +96,6 @@ urlpatterns = [ PesquisarPautaSessaoView.as_view(), name='pesquisar_pauta'), url(r'^sessao/pauta-sessao/(?P\d+)$', PautaSessaoDetailView.as_view(), name='pauta_sessao_detail'), - url(r'^sessao/pauta-sessao/(?P\d+)/expediente/$', - PautaExpedienteDetail.as_view(), name='pauta_expediente_detail'), - url(r'^sessao/pauta-sessao/(?P\d+)/ordem/$', - PautaOrdemDetail.as_view(), name='pauta_ordem_detail'), # Subnav sessão url(r'^sessao/(?P\d+)/expediente$', diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index affc07d4a..a633cead0 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -2507,46 +2507,6 @@ class PautaSessaoDetailView(DetailView): return self.render_to_response(context) -class PautaExpedienteDetail(DetailView): - template_name = "sessao/pauta/expediente.html" - model = SessaoPlenaria - - def get(self, request, *args, **kwargs): - pk = self.kwargs['pk'] - - expediente = ExpedienteMateria.objects.get(id=pk) - doc_ace = DocumentoAcessorio.objects.filter( - materia=expediente.materia) - tramitacao = Tramitacao.objects.filter( - materia=expediente.materia) - - return self.render_to_response( - {'expediente': expediente, - 'doc_ace': doc_ace, - 'tramitacao': tramitacao}) - - -class PautaOrdemDetail(DetailView): - template_name = "sessao/pauta/ordem.html" - model = SessaoPlenaria - - def get(self, request, *args, **kwargs): - pk = self.kwargs['pk'] - - ordem = OrdemDia.objects.get(id=pk) - norma = NormaJuridica.objects.filter( - materia=ordem.materia) - doc_ace = DocumentoAcessorio.objects.filter( - materia=ordem.materia) - tramitacao = Tramitacao.objects.filter( - materia=ordem.materia) - - return self.render_to_response( - {'ordem': ordem, - 'norma': norma, - 'doc_ace': doc_ace, - 'tramitacao': tramitacao}) - class PesquisarSessaoPlenariaView(FilterView): model = SessaoPlenaria diff --git a/sapl/templates/sessao/pauta/expediente.html b/sapl/templates/sessao/pauta/expediente.html deleted file mode 100644 index 38e0360bf..000000000 --- a/sapl/templates/sessao/pauta/expediente.html +++ /dev/null @@ -1,52 +0,0 @@ -{% extends "crud/detail.html" %} -{% load i18n %} -{% load crispy_forms_tags %} -{% block actions %} {% endblock %} -{% block detail_content %} - -

    {{expediente.materia}}

    -
    -
    - Identificação Básica - - Tipo: {{expediente.materia.tipo.sigla}} - {{expediente.materia.tipo.descricao}}
    - Número: {{expediente.materia.numero}}
    - Data: {{expediente.materia.data_apresentacao}}
    - Ementa: {{expediente.materia.ementa|safe}}
    - Indexação: {{expediente.materia.indexacao}}
    -
    -

    -
    - Outras Informações - - Em Tramitação? {{expediente.materia.em_tramitacao|yesno:"Sim,Não"}}       - Matéria Polêmica? {{expediente.materia.polemica|yesno:"Sim,Não"}}       - Regime Tramitação: {{expediente.materia.regime_tramitacao}} -
    -

    -
    - Documentos Acessórios - - {% for d in doc_ace %} - Nome: {{d.nome}}      - Tipo: {{d.tipo}}      - Data: {{d.data}}      - Autor: {{d.autor}}      - -

    - {% endfor %} -
    -

    -
    - Tramitação{% if expediente.materia.em_tramitacao %} >>> Acompanhar matéria <<<{% endif %} - - {% for t in tramitacao %} - Data: {{t.data_tramitacao}}
    - Origem: {{t.unidade_tramitacao_destino}} - Destino: {{t.unidade_tramitacao_local}}
    - Situação: {{t.status}}
    - Última Ação: {{t.texto}}
    - -
    - {% endfor %} -
    -{% endblock %} diff --git a/sapl/templates/sessao/pauta/ordem.html b/sapl/templates/sessao/pauta/ordem.html deleted file mode 100644 index 4bf5e6589..000000000 --- a/sapl/templates/sessao/pauta/ordem.html +++ /dev/null @@ -1,59 +0,0 @@ -{% extends "crud/detail.html" %} -{% load i18n %} -{% load crispy_forms_tags %} -{% block actions %} {% endblock %} -{% block detail_content %} - -

    {{ordem.materia}}

    -
    -
    - Identificação Básica - - Tipo: {{ordem.materia.tipo.sigla}} - {{ordem.materia.tipo.descricao}}
    - Número: {{ordem.materia.numero}}
    - Data: {{ordem.materia.data_apresentacao}}
    - Ementa: {{ordem.materia.ementa|safe}}
    - Indexação: {{ordem.materia.indexacao}}
    -
    -

    -
    - Norma Juridica Vinculada - - {% for n in norma %} - {{n}}
    - {% endfor %} -
    -

    -
    - Outras Informações - - Em Tramitação? {{ordem.materia.em_tramitacao|yesno:"Sim,Não"}}      
    - Matéria Polêmica? {{ordem.materia.polemica|yesno:"Sim,Não"}}      
    - Regime Tramitação: {{ordem.materia.regime_tramitacao}}
    -
    -

    -
    - Documentos Acessórios - - {% for d in doc_ace %} - Nome: {{d.nome}}     
    - Tipo: {{d.tipo}}     
    - Data: {{d.data}}     
    - Autor: {{d.autor}}     
    -

    - {% endfor %} -
    -

    -
    - Tramitação{% if ordem.materia.em_tramitacao %} >>> Acompanhar matéria <<<{% endif %} - - {% for t in tramitacao %} - Data: {{t.data_tramitacao}}
    - Origem: {{t.unidade_tramitacao_destino}} - Destino: {{t.unidade_tramitacao_local}}
    - Situação: {{t.status}}
    - Última Ação: {{t.texto}}
    - -
    - {% endfor %} -
    -{% endblock %} diff --git a/sapl/templates/sessao/pauta_sessao_detail.html b/sapl/templates/sessao/pauta_sessao_detail.html index 82cbb686a..5c1e97c40 100644 --- a/sapl/templates/sessao/pauta_sessao_detail.html +++ b/sapl/templates/sessao/pauta_sessao_detail.html @@ -46,7 +46,7 @@ {% for m in materia_expediente %} - {{m.numero}} - {{m.titulo}} + {{m.numero}} - {{m.titulo}}
    Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} @@ -88,7 +88,7 @@ {% for m in materias_ordem %} - {{m.numero}} - {{m.titulo}} + {{m.numero}} - {{m.titulo}}
    Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} From 78900707436b44fe181cb8d3bcef5645952d8b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Fr=C3=A1?= Date: Tue, 7 Nov 2017 18:11:07 -0200 Subject: [PATCH 163/237] Lista so primeiro_autor (#1582) #1581 --- .../materia/impressos/ficha_pdf.html | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/sapl/templates/materia/impressos/ficha_pdf.html b/sapl/templates/materia/impressos/ficha_pdf.html index 99ded497e..07ad4092a 100644 --- a/sapl/templates/materia/impressos/ficha_pdf.html +++ b/sapl/templates/materia/impressos/ficha_pdf.html @@ -45,9 +45,13 @@ body #despacho_inicial { font-family: Arial; + line-height: 150%; border-style: none; text-align: justify; font-size: small; + height:130px; + padding: 0pt 5pt 0pt 0pt; + margin-right:100px; } @media print { @@ -88,19 +92,8 @@ body
    - - {% if materia.autoria_set.all %} - Autor: - {% for a in materia.autoria_set.all %} - {% if not forloop.first %} - {{a.autor}}
    - {% else %} - {{a.autor}}
    - {% endif %} - {% endfor %} -
    - {% endif %} -
    + + Autor: {{materia.autoria_set.first.autor.nome}}
    From cc36af2f450d06045dffdf4989ad8ce6aa616ecd Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 6 Nov 2017 17:12:10 -0200 Subject: [PATCH 164/237] Mostra Tramitacao anterior ou igual a data da sessao plenaria --- sapl/relatorios/views.py | 14 ++++++++------ sapl/sessao/views.py | 15 +++++++++------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index c6e429afe..f4ffb03a0 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -563,7 +563,7 @@ def get_sessao_plenaria(sessao, casa): str(numeracao.numero_materia) + '/' + str( numeracao.ano_materia)) - turno, _ = get_turno(dic_expediente_materia, materia) + turno, _ = get_turno(dic_expediente_materia, materia, sessao.data_inicio) dic_expediente_materia["des_turno"] = turno @@ -666,7 +666,7 @@ def get_sessao_plenaria(sessao, casa): '/' + str(numeracao.ano_materia)) - turno, _ = get_turno(dic_votacao, materia) + turno, _ = get_turno(dic_votacao, materia, sessao.data_inicio) dic_votacao["des_turno"] = turno @@ -737,10 +737,12 @@ def get_sessao_plenaria(sessao, casa): lst_oradores) -def get_turno(dic, materia): +def get_turno(dic, materia, sessao_data_inicio): descricao_turno = ' ' descricao_tramitacao = ' ' - tramitacao = Tramitacao.objects.filter(materia=materia, turno__isnull=False + tramitacao = Tramitacao.objects.filter(materia=materia, + turno__isnull=False, + data_tramitacao__lte=sessao_data_inicio, ).exclude(turno__exact='' ).select_related( 'materia', @@ -1060,7 +1062,7 @@ def get_pauta_sessao(sessao, casa): elif autoria is None: dic_expediente_materia["nom_autor"] = 'Desconhecido' - turno, tramitacao = get_turno(dic_expediente_materia, materia) + turno, tramitacao = get_turno(dic_expediente_materia, materia, sessao.data_inicio) dic_expediente_materia["des_turno"] = turno dic_expediente_materia["des_situacao"] = tramitacao @@ -1109,7 +1111,7 @@ def get_pauta_sessao(sessao, casa): elif autoria is None: dic_votacao["nom_autor"] = 'Desconhecido' - turno, tramitacao = get_turno(dic_expediente_materia, materia) + turno, tramitacao = get_turno(dic_expediente_materia, materia, sessao.data_inicio) dic_votacao["des_turno"] = turno dic_votacao["des_situacao"] = tramitacao lst_votacao.append(dic_votacao) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index a633cead0..cdbd0a18d 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -157,7 +157,7 @@ def abrir_votacao(request, pk, spk): reverse('sapl.sessao:' + redirect_url, kwargs={'pk': spk})) -def customize_link_materia(context): +def customize_link_materia(context, pk): for i, row in enumerate(context['rows']): materia = context['object_list'][i].materia url_materia = reverse('sapl.materia:materialegislativa_detail', @@ -168,7 +168,11 @@ def customize_link_materia(context): autor = autoria.autor if autoria else None num_protocolo = materia.numero_protocolo - tramitacao = Tramitacao.objects.filter(materia=materia, turno__isnull=False + data_inicio_sessao = SessaoPlenaria.objects.get(id=pk).data_inicio + + tramitacao = Tramitacao.objects.filter(materia=materia, + turno__isnull=False, + data_tramitacao__lte=data_inicio_sessao ).exclude(turno__exact='' ).select_related( 'materia', @@ -179,7 +183,7 @@ def customize_link_materia(context): turno = ' ' if tramitacao is not None: for t in Tramitacao.TURNO_CHOICES: - if t[0] == tramitacao.turno: + if t[0] == tramitacao.turno: turno = t[1] break @@ -265,8 +269,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - - return customize_link_materia(context) + return customize_link_materia(context, self.kwargs['pk']) def get_rows(self, object_list): for obj in object_list: @@ -397,7 +400,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - return customize_link_materia(context) + return customize_link_materia(context, self.kwargs['pk']) def get_rows(self, object_list): for obj in object_list: From f8bb54d9938d24c596ff2a2b46a5f26453e44eb4 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 8 Nov 2017 12:18:19 -0200 Subject: [PATCH 165/237] Novo release: 3.1.31-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2f69ff36c..d579f992e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.30-BETA + image: interlegis/sapl:3.1.31-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index 2d69d9906..dee937e73 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.30-BETA', + version='3.1.31-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From 62103891d6c7f29e756bd2cef9b4dcfd0f0a3210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 9 Nov 2017 12:15:00 -0200 Subject: [PATCH 166/237] HOT FIX --- sapl/painel/views.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 9682b5b01..500f4b8ac 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -319,6 +319,9 @@ def get_presentes(pk, response, materia): 'voto': '' }) + elif not p.parlamentar.ativo or not mandatos: + num_presentes += -1 + if materia: if materia.tipo_votacao == 1: tipo_votacao = 'Simbólica' From b17061178cdb4df1beee045a0b7aa0dc1b42e906 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 9 Nov 2017 15:19:41 -0200 Subject: [PATCH 167/237] =?UTF-8?q?Remove=20arquivo=20desnecess=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/scripts/street_sweeper.py | 150 -------------------------- 1 file changed, 150 deletions(-) delete mode 100644 sapl/legacy/scripts/street_sweeper.py diff --git a/sapl/legacy/scripts/street_sweeper.py b/sapl/legacy/scripts/street_sweeper.py deleted file mode 100644 index d01fd3b52..000000000 --- a/sapl/legacy/scripts/street_sweeper.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/python - -# requisito: pip install PyMySQL - -import pymysql.cursors - -HOST = 'localhost' -USER = 'root' -PASSWORD = '' -DB = '' - - -SELECT_EXCLUIDOS = "SELECT %s FROM %s WHERE ind_excluido = 1 ORDER BY %s" - -REGISTROS_INCONSISTENTES = "DELETE FROM %s WHERE %s " -"in (%s) AND ind_excluido = 0 " - -EXCLUI_REGISTRO = "DELETE FROM %s WHERE ind_excluido=1" - -NORMA_DEP = "DELETE FROM vinculo_norma_juridica WHERE cod_norma_referente in (%s) OR \ - cod_norma_referida in (%s) AND ind_excluido = 0 " - -mapa = {} # mapa com tabela principal -> tabelas dependentes - -mapa['tipo_autor'] = ['autor'] -mapa['materia_legislativa'] = ['acomp_materia', 'autoria', 'despacho_inicial', - 'documento_acessorio', 'expediente_materia', - 'legislacao_citada', 'materia_assunto', - 'numeracao', 'ordem_dia', 'parecer', - 'proposicao', 'registro_votacao', - 'relatoria', 'tramitacao'] -mapa['norma_juridica'] = ['vinculo_norma_juridica'] -mapa['comissao'] = ['composicao_comissao'] -mapa['sessao_legislativa'] = ['composicao_mesa'] -mapa['tipo_expediente'] = ['expediente_sessao_plenaria'] - -""" -mapa['autor'] = ['tipo_autor', 'partido', 'comissao', 'parlamentar'] -mapa['parlamentar'] = ['autor', 'autoria', 'composicao_comissao', - 'composicao_mesa', 'dependente', 'filiacao', - 'mandato', 'mesa_sessao_plenaria', 'oradores', - 'oradores_expediente', 'ordem_dia_presenca', - 'registro_votacao_parlamentar', 'relatoria', - 'sessao_plenaria_presenca', 'unidade_tramitacao'] -""" - - -def get_ids_excluidos(cursor, query): - """ - recupera as PKs de registros com ind_excluido = 1 da tabela principal - """ - cursor.execute(query) - excluidos = cursor.fetchall() - # flat tuple of tuples with map transformation into string - excluidos = [str(val) for sublist in excluidos for val in sublist] - return excluidos - - -def remove_tabelas(cursor, tabela_principal, pk, query_dependentes=None): - - QUERY = SELECT_EXCLUIDOS % (pk, tabela_principal, pk) - ids_excluidos = get_ids_excluidos(cursor, QUERY) - print("\nRegistros da tabela '%s' com ind_excluido = 1: %s" % - (tabela_principal.upper(), len(ids_excluidos))) - - """ - Remove registros de tabelas que dependem da tabela principal, - e que se encontram com ind_excluido = 0 (nao excluidas), se - tais registros existirem. - """ - if ids_excluidos: - print("Dependencias inconsistentes") - for tabela in mapa[tabela_principal]: - - QUERY_DEP = REGISTROS_INCONSISTENTES % ( - tabela, pk, ','.join(ids_excluidos)) - - # Trata caso especifico de norma_juridica - if query_dependentes: - QUERY_DEP = query_dependentes % (','.join(ids_excluidos), - ','.join(ids_excluidos)) - - print(tabela.upper(), cursor.execute(QUERY_DEP)) - - """ - Remove todos os registros com ind_excluido = 1 das tabelas - dependentes e da tabela principal, nesta ordem. - """ - print("\n\nRegistros com ind_excluido = 1") - for tabela in mapa[tabela_principal] + [tabela_principal]: - QUERY = EXCLUI_REGISTRO % tabela - print(tabela.upper(), cursor.execute(QUERY)) - - -def remove_excluidas(cursor): - cursor.execute("SHOW_TABLES") - for row in cursor.fetchall(): - print(row) - - -def remove_proposicao_invalida(cursor): - return cursor.execute( - "DELETE FROM proposicao WHERE cod_mat_ou_doc is null") - - -def remove_materia_assunto_invalida(cursor): - return cursor.execute( - "DELETE FROM materia_assunto WHERE cod_assunto = 0") - - -def shotgun_remove(cursor): - for tabela in get_ids_excluidos(cursor, "SHOW TABLES"): - try: - cursor.execute("DELETE FROM %s WHERE ind_excluido = 1" % tabela) - except: - pass - - -if __name__ == '__main__': - connection = pymysql.connect(host=HOST, - user=USER, - password=PASSWORD, - db=DB) - cursor = connection.cursor() - # TIPO AUTOR - remove_tabelas(cursor, 'tipo_autor', 'tip_autor') - # MATERIA LEGISLATIVA - remove_tabelas(cursor, 'materia_legislativa', 'cod_materia') - # NORMA JURIDICA - remove_tabelas(cursor, 'norma_juridica', 'cod_norma', NORMA_DEP) - # COMISSAO - remove_tabelas(cursor, 'comissao', 'cod_comissao') - # SESSAO LEGISLATIVA - remove_tabelas(cursor, 'sessao_legislativa', 'cod_sessao_leg') - # EXPEDIENTE SESSAO - remove_tabelas(cursor, 'tipo_expediente', 'cod_expediente') - # AUTOR - remove_tabelas(cursor, 'autor', 'cod_autor') - # PARLAMENTAR - remove_tabelas(cursor, 'parlamentar', 'cod_parlamentar') - - # PROPOSICAO - remove_proposicao_invalida(cursor) - - # MATERIA_ASSUNTO - remove_materia_assunto_invalida(cursor) - - # shotgun_remove(cursor) - - cursor.close() From ce1c75860062da34a70753a1e845530fb218c494 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Fri, 10 Nov 2017 11:58:53 -0200 Subject: [PATCH 168/237] =?UTF-8?q?Adiciona=20script=20de=20exporta=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20docs=20do=20zope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/scripts/exporta_zope/.gitignore | 2 + .../scripts/exporta_zope/exporta_zope.py | 151 ++++++++++++++++++ .../scripts/exporta_zope/requirements.txt | 2 + 3 files changed, 155 insertions(+) create mode 100644 sapl/legacy/scripts/exporta_zope/.gitignore create mode 100644 sapl/legacy/scripts/exporta_zope/exporta_zope.py create mode 100644 sapl/legacy/scripts/exporta_zope/requirements.txt diff --git a/sapl/legacy/scripts/exporta_zope/.gitignore b/sapl/legacy/scripts/exporta_zope/.gitignore new file mode 100644 index 000000000..98561c589 --- /dev/null +++ b/sapl/legacy/scripts/exporta_zope/.gitignore @@ -0,0 +1,2 @@ +Data*.fs* +sapl_documentos diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py new file mode 100644 index 000000000..618c9ec5c --- /dev/null +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -0,0 +1,151 @@ +# -*- coding: utf-8 -*- + +# IMPORTANTE: +# Esse script precisa rodar em python 2 +# e depende apenas do descrito no arquivo requiments.txt + +import os.path +from collections import defaultdict +from functools import partial + +import ZODB.DB +import ZODB.FileStorage +from ZODB.broken import Broken + +EXTENSOES = { + 'application/msword': '.doc', + 'application/pdf': '.pdf', + 'application/vnd.oasis.opendocument.text': '.odt', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx', # noqa + 'application/xml': '.xml', + 'text/xml': '.xml', + 'application/zip': '.zip', + 'image/jpeg': '.jpeg', + 'image/png': '.png', + 'image/gif': '.gif', + 'text/html': '.html', + 'text/rtf': '.rtf', + 'text/x-python': '.py', + 'text/plain': '.txt', + 'SDE-Document': 'xml', + + # TODO rever... + 'text/richtext': '.rtf', + + # sem extensao + 'application/octet-stream': '', # binario + 'inode/x-empty': '', # vazio + 'text/x-unknown-content-type': '', +} + + +def br(obj): + if isinstance(obj, Broken): + return obj.__Broken_state__ + else: + return obj + + +def dump_file(doc, path): + name = doc['__name__'] + extension = EXTENSOES[doc['content_type']] + fullname = os.path.join(path, name + extension) + print(fullname) + + pdata = br(doc['data']) + if isinstance(pdata, str): + # Retrocedemos se pdata ja eh uma str (necessario em Images) + pdata = doc + + with open(fullname, 'w') as arq: + while pdata: + arq.write(pdata['data']) + pdata = br(pdata.get('next', None)) + return name + + +nao_identificados = defaultdict(list) + + +def enumerate_folder(folder): + # folder vazio nao tem _objects + for entry in folder.get('_objects', []): + id, meta_type = entry['id'], entry['meta_type'] + obj = br(folder[id]) + yield id, obj, meta_type + + +def enumerate_btree(folder): + tree = folder['_tree'] + for id, obj in tree.iteritems(): + obj, meta_type = br(obj), type(obj).__name__ + yield id, obj, meta_type + + +def dump_folder(folder, path='', enum=enumerate_folder): + name = folder['id'] + path = os.path.join(path, name) + if not os.path.exists(path): + os.makedirs(path) + for id, obj, meta_type in enum(folder): + dump = DUMP_FUNCTIONS.get(meta_type, '?') + if dump == '?': + nao_identificados[meta_type].append(path + '/' + id) + elif dump: + id_interno = dump(obj, path) + assert id == id_interno + return name + + +DUMP_FUNCTIONS = { + 'File': dump_file, + 'Image': dump_file, + 'Folder': partial(dump_folder, enum=enumerate_folder), + 'BTreeFolder2': partial(dump_folder, enum=enumerate_btree), + + # explicitamente ignorados + 'ZCatalog': None, + 'Dumper': None, +} + + +def get_app(data_fs_path): + storage = ZODB.FileStorage.FileStorage(data_fs_path) + db = ZODB.DB(storage) + connection = db.open() + root = connection.root() + app = br(root['Application']) + + def close_db(): + db.close() + + return app, close_db + + +def find_sapl(app): + [id] = [e['id'] for e in app['_objects'] + if e['id'].startswith('cm_') + and e['meta_type'] == 'Folder'] + cm_zzz = br(app[id]) + sapl = br(cm_zzz['sapl']) + return sapl + + +def dump_sapl(data_fs_path): + app, close_db = get_app(data_fs_path) + try: + sapl = find_sapl(app) + docs = br(sapl['sapl_documentos']) + + nao_identificados.clear() + dump_folder(docs) + if nao_identificados: + print('#' * 80) + print('#' * 80) + print(u'FORAM ENCONTRADOS ARQUIVOS DE FORMATO NÃO IDENTIFICADO!!!') + print(u'REFAÇA A EXPORTAÇÃO\n') + print(nao_identificados) + print('#' * 80) + print('#' * 80) + finally: + close_db() diff --git a/sapl/legacy/scripts/exporta_zope/requirements.txt b/sapl/legacy/scripts/exporta_zope/requirements.txt new file mode 100644 index 000000000..9b1afa6fb --- /dev/null +++ b/sapl/legacy/scripts/exporta_zope/requirements.txt @@ -0,0 +1,2 @@ +# ZODB version 3.7.4 +git+git://github.com/zopefoundation/ZODB.git@d6f3c3ce5e6df1060de7a3#egg=ZODB3 From b73d3f99d293701ff76cfb047e79eaed7ff3d736 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 10 Nov 2017 15:25:21 -0200 Subject: [PATCH 169/237] =?UTF-8?q?HOT-FIX:=20pauta=20de=20sess=C3=A3o=20r?= =?UTF-8?q?etornava=20IDs=20errados.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index cdbd0a18d..18c379ff2 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -2430,7 +2430,7 @@ class PautaSessaoDetailView(DetailView): autoria = Autoria.objects.filter(materia_id=m.materia_id) autor = [str(x.autor) for x in autoria] - mat = {'id': m.id, + mat = {'id': m.materia_id, 'ementa': ementa, 'titulo': titulo, 'numero': numero, @@ -2493,7 +2493,7 @@ class PautaSessaoDetailView(DetailView): materia_id=o.materia_id) autor = [str(x.autor) for x in autoria] - mat = {'id': o.id, + mat = {'id': o.materia_id, 'ementa': ementa, 'titulo': titulo, 'numero': numero, From 4082d496236113d70ad384b12f2a65a71272fffb Mon Sep 17 00:00:00 2001 From: Eliseu Egewarth Date: Fri, 10 Nov 2017 17:13:21 -0200 Subject: [PATCH 170/237] Fix #1587 Adiciona pre popula TipoAutor Signed-off-by: Eliseu Egewarth --- sapl/base/models.py | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/sapl/base/models.py b/sapl/base/models.py index 29c0fa1cc..b1edf8b64 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -2,9 +2,16 @@ import reversion from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models +from django.db.models.signals import post_migrate +from django.db.utils import DEFAULT_DB_ALIAS from django.utils.translation import ugettext_lazy as _ -from sapl.utils import UF, YES_NO_CHOICES, get_settings_auth_user_model +from sapl.utils import ( + UF, + YES_NO_CHOICES, + get_settings_auth_user_model, + models_with_gr_for_model + ) TIPO_DOCUMENTO_ADMINISTRATIVO = (('O', _('Ostensivo')), ('R', _('Restritivo'))) @@ -247,3 +254,39 @@ class Autor(models.Model): return str(self.partido) else: """ + + +def cria_models_tipo_autor(app_config, verbosity=2, interactive=True, + using=DEFAULT_DB_ALIAS, **kwargs): + + models = models_with_gr_for_model(Autor) + + print("\n\033[93m\033[1m{}\033[0m".format( + _('Atualizando registros TipoAutor do SAPL:'))) + for model in models: + content_type = ContentType.objects.get_for_model(model) + tipo_autor = TipoAutor.objects.filter( + content_type=content_type.id).exists() + + if tipo_autor: + msg1 = "Carga de {} não efetuada.".format( + TipoAutor._meta.verbose_name) + msg2 = " Já Existe um {} {} relacionado...".format( + TipoAutor._meta.verbose_name, + model._meta.verbose_name) + msg = " {}{}".format(msg1, msg2) + else: + novo_autor = TipoAutor() + novo_autor.content_type_id = content_type.id + novo_autor.descricao = model._meta.verbose_name + novo_autor.save() + msg1 = "Carga de {} efetuada.".format( + TipoAutor._meta.verbose_name) + msg2 = " {} {} criado...".format( + TipoAutor._meta.verbose_name, content_type.model) + msg = " {}{}".format(msg1, msg2) + print(msg) + # Disconecta função para evitar a chamada repetidas vezes. + post_migrate.disconnect(receiver=cria_models_tipo_autor) + +post_migrate.connect(receiver=cria_models_tipo_autor) From 9c63bd688617ee95e420808f1089f5584649bb2a Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Sat, 11 Nov 2017 17:34:27 -0200 Subject: [PATCH 171/237] Confere tamanho da btree exportada --- sapl/legacy/scripts/exporta_zope/exporta_zope.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index 618c9ec5c..3ebe40b4a 100644 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -76,10 +76,13 @@ def enumerate_folder(folder): def enumerate_btree(folder): + contagem_esperada = folder['_count'].value tree = folder['_tree'] - for id, obj in tree.iteritems(): + for contagem_real, (id, obj) in enumerate(tree.iteritems(), start=1): obj, meta_type = br(obj), type(obj).__name__ yield id, obj, meta_type + # verificação de consistência + assert contagem_esperada == contagem_real def dump_folder(folder, path='', enum=enumerate_folder): From 80d20175e7f1d435726f2f33c0b5aa050af3bd7d Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 13 Nov 2017 11:22:17 -0200 Subject: [PATCH 172/237] Adiciona dump de propriedades do site --- sapl/legacy/scripts/exporta_zope/exporta_zope.py | 10 ++++++++++ sapl/legacy/scripts/exporta_zope/requirements.txt | 1 + 2 files changed, 11 insertions(+) diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index 3ebe40b4a..1a39247bb 100644 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -152,3 +152,13 @@ def dump_sapl(data_fs_path): print('#' * 80) finally: close_db() + + +def dump_propriedades(docs): + props_sapl = br(docs['props_sapl']) + ids = [p['id'] for p in props_sapl['_properties']] + props = {id: props_sapl[id] for id in ids} + props = {id: p.decode('iso-8859-1') if isinstance(p, str) else p + for id, p in props.items()} + with open('sapl_documentos/propriedades.yaml', 'w') as f: + f.write(yaml.safe_dump(props)) diff --git a/sapl/legacy/scripts/exporta_zope/requirements.txt b/sapl/legacy/scripts/exporta_zope/requirements.txt index 9b1afa6fb..1770426da 100644 --- a/sapl/legacy/scripts/exporta_zope/requirements.txt +++ b/sapl/legacy/scripts/exporta_zope/requirements.txt @@ -1,2 +1,3 @@ # ZODB version 3.7.4 git+git://github.com/zopefoundation/ZODB.git@d6f3c3ce5e6df1060de7a3#egg=ZODB3 +PyYAML==3.12 From ced44d4dad5eaa350ce1a9371b06b978b83ac5c2 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 13 Nov 2017 12:41:37 -0200 Subject: [PATCH 173/237] Adiciona CRUD de Municipio --- sapl/parlamentares/urls.py | 3 ++- sapl/parlamentares/views.py | 3 ++- sapl/templates/parlamentares/layouts.yaml | 4 ++++ sapl/templates/sistema.html | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sapl/parlamentares/urls.py b/sapl/parlamentares/urls.py index e383421c4..552257c61 100644 --- a/sapl/parlamentares/urls.py +++ b/sapl/parlamentares/urls.py @@ -17,7 +17,7 @@ from sapl.parlamentares.views import (CargoMesaCrud, ColigacaoCrud, frente_atualiza_lista_parlamentares, insere_parlamentar_composicao, parlamentares_frente_selected, - remove_parlamentar_composicao) + remove_parlamentar_composicao, MunicipioCrud) from .apps import AppConfig @@ -60,6 +60,7 @@ urlpatterns = [ url(r'^sistema/parlamentar/tipo-militar/', include(TipoMilitarCrud.get_urls())), url(r'^sistema/parlamentar/partido/', include(PartidoCrud.get_urls())), + url(r'^sistema/parlamentar/municipio/', include(MunicipioCrud.get_urls())), url(r'^sistema/mesa-diretora/sessao-legislativa/', include(SessaoLegislativaCrud.get_urls())), diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index ae4d3844b..e7b37f358 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -31,7 +31,7 @@ from .forms import (FiliacaoForm, LegislaturaForm, MandatoForm, from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, Dependente, Filiacao, Frente, Legislatura, Mandato, NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, - SituacaoMilitar, TipoAfastamento, TipoDependente, Votante) + SituacaoMilitar, TipoAfastamento, TipoDependente, Votante, Municipio) CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa') PartidoCrud = CrudAux.build(Partido, 'partidos') @@ -40,6 +40,7 @@ TipoDependenteCrud = CrudAux.build(TipoDependente, 'tipo_dependente') NivelInstrucaoCrud = CrudAux.build(NivelInstrucao, 'nivel_instrucao') TipoAfastamentoCrud = CrudAux.build(TipoAfastamento, 'tipo_afastamento') TipoMilitarCrud = CrudAux.build(SituacaoMilitar, 'tipo_situa_militar') +MunicipioCrud = CrudAux.build(Municipio, 'municipio') DependenteCrud = MasterDetailCrud.build( Dependente, 'parlamentar', 'dependente') diff --git a/sapl/templates/parlamentares/layouts.yaml b/sapl/templates/parlamentares/layouts.yaml index 57a3b86ba..583835bfd 100644 --- a/sapl/templates/parlamentares/layouts.yaml +++ b/sapl/templates/parlamentares/layouts.yaml @@ -92,6 +92,10 @@ SituacaoMilitar: {% trans 'Tipo Situação Militar' %}: - descricao +Municipio: + {% trans 'Município' %}: + - nome uf regiao + ComposicaoColigacao: {% trans 'Nome do Partido' %}: - partido diff --git a/sapl/templates/sistema.html b/sapl/templates/sistema.html index c8d31c179..366b9a26a 100644 --- a/sapl/templates/sistema.html +++ b/sapl/templates/sistema.html @@ -19,6 +19,7 @@ +
    From 208f4990c17ce3e3fa3b32a8aa6350e88ecfd7bf Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 13 Nov 2017 12:42:54 -0200 Subject: [PATCH 174/237] Novo release: 3.1.32-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index d579f992e..9fc25a3a6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.31-BETA + image: interlegis/sapl:3.1.32-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index dee937e73..d2eae0df6 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.31-BETA', + version='3.1.32-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From 9a3a2da4d51ffe10962c3681687ca6f042587a6f Mon Sep 17 00:00:00 2001 From: cristian-longhi Date: Mon, 13 Nov 2017 13:48:52 -0200 Subject: [PATCH 175/237] =?UTF-8?q?Ajustes=20de=20exibi=C3=A7=C3=A3o=20e?= =?UTF-8?q?=20controle=20dos=20votos=20computados=20(#1583)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Ajustes no Painel e na Votação * Ajustes no Painel e na Votação * Ajustes no código --- sapl/painel/views.py | 20 ++++++++++ sapl/static/styles/app.scss | 2 +- sapl/templates/painel/index.html | 31 ++++++++++++--- sapl/templates/sessao/votacao/nominal.html | 45 +++++++++++++++++++++- 4 files changed, 90 insertions(+), 8 deletions(-) diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 500f4b8ac..93feedd4e 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -363,9 +363,11 @@ def get_votos(response, materia): if type(materia) == OrdemDia: registro = RegistroVotacao.objects.filter( ordem=materia, materia=materia.materia).last() + tipo = 'ordem' elif type(materia) == ExpedienteMateria: registro = RegistroVotacao.objects.filter( expediente=materia, materia=materia.materia).last() + tipo = 'expediente' if not registro: response.update({ @@ -377,6 +379,24 @@ def get_votos(response, materia): 'tipo_resultado': 'Ainda não foi votada.', }) + if materia.tipo_votacao == 2: + if tipo == 'ordem': + votos_parlamentares = VotoParlamentar.objects.filter( + ordem_id=materia.id).order_by( + 'parlamentar__nome_parlamentar') + else: + votos_parlamentares = VotoParlamentar.objects.filter( + expediente_id=materia.id).order_by( + 'parlamentar__nome_parlamentar') + + + for i, p in enumerate(response['presentes']): + try: + if votos_parlamentares.get(parlamentar_id=p['parlamentar_id']).voto: + response['presentes'][i]['voto'] = 'Voto Informado' + except ObjectDoesNotExist: + response['presentes'][i]['voto'] = '' + else: total = (registro.numero_votos_sim + registro.numero_votos_nao + diff --git a/sapl/static/styles/app.scss b/sapl/static/styles/app.scss index 7ca2d652a..74fcd42b4 100644 --- a/sapl/static/styles/app.scss +++ b/sapl/static/styles/app.scss @@ -497,7 +497,7 @@ p { /* Estilização da Listagem de Votos em sessões plenárias */ #styleparlamentar { - border: 1px solid #d6e1e5; + border: 0px solid #d6e1e5; border-top-color: rgb(214, 225, 229); border-right-color: rgb(214, 225, 229); border-bottom-color: rgb(214, 225, 229); diff --git a/sapl/templates/painel/index.html b/sapl/templates/painel/index.html index bfe6ade37..6be08b115 100644 --- a/sapl/templates/painel/index.html +++ b/sapl/templates/painel/index.html @@ -99,9 +99,9 @@

    Matéria em Votação

    - - - + + +

    @@ -185,18 +185,29 @@ var votacao = $("#votacao"); $("#votacao").text(''); presentes.children().remove(); - votacao.children().remove() + votacao.children().remove(); var presentes_list = data["presentes"]; if (data["status_painel"] == true) { presentes.append(''); jQuery.each(presentes_list, function (index, parlamentar) { + + if (parlamentar.voto == 'Voto Informado'){ + $('#parlamentares_list').append('') + } + else{ $('#parlamentares_list').append('') + + show_voto(parlamentar.voto) + '') + } + }); presentes.append('
    ' + + parlamentar.nome + + ' ' + + parlamentar.partido + ' ' + + '
    ' + parlamentar.nome + ' ' + parlamentar.partido + ' ' - + show_voto(parlamentar.voto) + '
    '); } @@ -269,8 +280,16 @@ $("#observacao_materia").text(''); } - if (data['resultado_votacao']){ + if (data['tipo_resultado']){ $("#resultado_votacao").text(data["tipo_resultado"]); + $("#resultado_votacao").css("color", "#45919D"); + var resultado_votacao_upper = $("#resultado_votacao").text().toUpperCase(); + if (resultado_votacao_upper.search("APROV") != -1){ + $("#resultado_votacao").css("color", "green"); + } + if (resultado_votacao_upper.search("REJEIT") != -1){ + $("#resultado_votacao").css("color", "red"); + } } else{ $("#resultado_votacao").text(''); diff --git a/sapl/templates/sessao/votacao/nominal.html b/sapl/templates/sessao/votacao/nominal.html index ad494dae5..940f00396 100644 --- a/sapl/templates/sessao/votacao/nominal.html +++ b/sapl/templates/sessao/votacao/nominal.html @@ -40,7 +40,16 @@
    {% endfor %}
    - + + Situação da Votação: + +
    +
    +
    +
    +
    + +
    @@ -70,6 +79,40 @@ window.history.back(); } + function conta_votos() { + var votos_sim = 0; + var votos_nao = 0; + var votos_abstencao = 0; + var nao_votou = 0; + $('[name=voto_parlamentar]').each(function() { + if (($(this).is(':hidden')) == false) { + switch ($(this).val().substring(0,4)) { + case "Sim:": + votos_sim = votos_sim + 1; + break; + case "Não:": + votos_nao = votos_nao + 1; + break; + case "Abst": + votos_abstencao = votos_abstencao + 1; + break; + case "Não ": + nao_votou = nao_votou + 1; + break; + }; + }; + }); + + $("#soma_votos").empty(); + $("#soma_votos").append("
    Sim: " + votos_sim + "
    "); + $("#soma_votos").append("
    Não: " + votos_nao + "
    "); + $("#soma_votos").append("
    Abstenções: " + votos_abstencao + "
    "); + $("#soma_votos").append("
    Ainda não votaram: " + nao_votou + "
    "); + + } + + window.onload = conta_votos(); + $(window).on('beforeunload', function () { $("input[type=submit], input[type=button]").prop("disabled", "disabled"); }); From af5fa36b9f3fdb75aae2598870b10200b65639e1 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 13 Nov 2017 14:46:01 -0200 Subject: [PATCH 176/237] =?UTF-8?q?Adiciona=20a=20op=C3=A7=C3=A3o=20'Admin?= =?UTF-8?q?istra=C3=A7=C3=A3o'=20no=20menu=20dropdown=20do=20usu=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/templates/base.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sapl/templates/base.html b/sapl/templates/base.html index efcd0a647..19f70e4f9 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -69,6 +69,9 @@ Votar Matéria {% endif %} + {% if request.user.is_superuser %} +
  • Administração
  • + {% endif %}
  • Sair
  • From 5743f5f0b92b0cbdfc6acc6aaa9cc1b24a12f276 Mon Sep 17 00:00:00 2001 From: Eliseu Egewarth Date: Mon, 13 Nov 2017 16:39:40 -0200 Subject: [PATCH 177/237] Minor Update docker-compose.yml (#1591) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Espaço único gerava erro na execução do comando ```docker-compose up``` --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9fc25a3a6..8d234b4d9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.32-BETA + image: interlegis/sapl:3.1.32-BETA restart: always environment: ADMIN_PASSWORD: interlegis From dc5666155f0b90fd55cc64ff942f7d6b5de0df86 Mon Sep 17 00:00:00 2001 From: Leandro Roberto da Silva Date: Tue, 14 Nov 2017 10:50:17 -0200 Subject: [PATCH 178/237] adiciona Textos Articulados na pesquisa textual (#1594) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * adiciona Textos Articulados na pesquisa textual * separa extrações em funções individuais * apl sugestões de rev e outras ideias surgidas a partir daí --- sapl/base/search_indexes.py | 187 ++++++++++++++++++------------ sapl/compilacao/views.py | 16 ++- sapl/materia/views.py | 5 +- sapl/templates/search/search.html | 8 +- 4 files changed, 136 insertions(+), 80 deletions(-) diff --git a/sapl/base/search_indexes.py b/sapl/base/search_indexes.py index cee126dd2..e925de8c8 100644 --- a/sapl/base/search_indexes.py +++ b/sapl/base/search_indexes.py @@ -3,33 +3,36 @@ import os.path import re import string -import textract +from django.db.models import Q, F, Value +from django.db.models.fields import TextField +from django.db.models.fields.files import FieldFile +from django.db.models.functions import Concat from django.template import loader -from haystack import indexes +from haystack.constants import Indexable +from haystack.fields import CharField +from haystack.indexes import SearchIndex +from haystack.utils import get_model_ct_tuple from textract.exceptions import ExtensionNotSupported +import textract +from sapl.compilacao.models import TextoArticulado, Dispositivo,\ + STATUS_TA_PUBLIC, STATUS_TA_IMMUTABLE_PUBLIC from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa from sapl.norma.models import NormaJuridica from sapl.settings import BASE_DIR, SOLR_URL -logger = logging.getLogger(BASE_DIR.name) +logger = logging.getLogger(BASE_DIR.name) -class DocumentoAcessorioIndex(indexes.SearchIndex, indexes.Indexable): - text = indexes.CharField(document=True, use_template=True) - filename = 'arquivo' - model = DocumentoAcessorio - template_name = 'materia/documentoacessorio_text.txt' +class TextExtractField(CharField): - def get_model(self): - return self.model - - def index_queryset(self, using=None): - return self.get_model().objects.all() + def __init__(self, **kwargs): + super().__init__(**kwargs) + assert self.model_attr - def get_updated_field(self): - return 'data_ultima_atualizacao' + if not isinstance(self.model_attr, (list, tuple)): + self.model_attr = (self.model_attr, ) def solr_extraction(self, arquivo): extracted_data = self._get_backend(None).extract_file_contents( @@ -59,71 +62,109 @@ class DocumentoAcessorioIndex(indexes.SearchIndex, indexes.Indexable): print(msg) logger.error(msg) - def prepare(self, obj): - if not self.filename or not self.model or not self.template_name: - raise Exception - - data = super(DocumentoAcessorioIndex, self).prepare(obj) - - arquivo = getattr(obj, self.filename) - - if arquivo: - if not os.path.exists(arquivo.path): - return self.prepared_data - - if not os.path.splitext(arquivo.path)[1][:1]: - return self.prepared_data - - # Em ambiente de produção utiliza-se o SOLR - if SOLR_URL: - try: - extracted_data = self.solr_extraction(arquivo) - except Exception: - self.print_error(arquivo) - return self.prepared_data - - # Em ambiente de DEV utiliza-se o Whoosh - # Como ele não possui extração, faz-se uso do textract - else: - try: - extracted_data = self.whoosh_extraction(arquivo) - except ExtensionNotSupported as e: - print(str(e)) - logger.error(str(e)) - return self.prepared_data - except Exception: - self.print_error(arquivo) - return self.prepared_data - - # Now we'll finally perform the template processing to render the - # text field with *all* of our metadata visible for templating: - t = loader.select_template(( - 'search/indexes/' + self.template_name, )) - data['text'] = t.render({'object': obj, - 'extracted': extracted_data}) - - return data - - return self.prepared_data - + def file_extractor(self, arquivo): + if not os.path.exists(arquivo.path) or \ + not os.path.splitext(arquivo.path)[1][:1]: + return '' + + # Em ambiente de produção utiliza-se o SOLR + if SOLR_URL: + try: + return self.solr_extraction(arquivo) + except Exception: + self.print_error(arquivo) + + # Em ambiente de DEV utiliza-se o Whoosh + # Como ele não possui extração, faz-se uso do textract + else: + try: + return self.whoosh_extraction(arquivo) + except ExtensionNotSupported as e: + print(str(e)) + logger.error(str(e)) + except Exception: + self.print_error(arquivo) + return '' + + def ta_extractor(self, value): + r = [] + for ta in value.filter(privacidade__in=[ + STATUS_TA_PUBLIC, + STATUS_TA_IMMUTABLE_PUBLIC]): + dispositivos = Dispositivo.objects.filter( + Q(ta=ta) | Q(ta_publicado=ta) + ).order_by( + 'ordem' + ).annotate( + rotulo_texto=Concat( + F('rotulo'), Value(' '), F('texto'), + output_field=TextField(), + ) + ).values_list( + 'rotulo_texto', flat=True) + r += list(filter(lambda x: x.strip(), dispositivos)) + return ' '.join(r) + + def extract_data(self, obj): + + data = '' + + for attr, func in self.model_attr: + if not hasattr(obj, attr) or not hasattr(self, func): + raise Exception + + value = getattr(obj, attr) + if not value: + continue + data += getattr(self, func)(value) + + return data + + def prepare_template(self, obj): + app_label, model_name = get_model_ct_tuple(obj) + template_names = ['search/indexes/%s/%s_%s.txt' % + (app_label, model_name, self.instance_name)] + + t = loader.select_template(template_names) + + return t.render({'object': obj, + 'extracted': self.extract_data(obj)}) + + +class DocumentoAcessorioIndex(SearchIndex, Indexable): + model = DocumentoAcessorio + text = TextExtractField( + document=True, use_template=True, + model_attr=(('arquivo', 'file_extractor'), ) + ) -class MateriaLegislativaIndex(DocumentoAcessorioIndex): - text = indexes.CharField(document=True, use_template=True) + def get_model(self): + return self.model - filename = 'texto_original' - model = MateriaLegislativa - template_name = 'materia/materialegislativa_text.txt' + def index_queryset(self, using=None): + return self.get_model().objects.all() def get_updated_field(self): return 'data_ultima_atualizacao' class NormaJuridicaIndex(DocumentoAcessorioIndex): - text = indexes.CharField(document=True, use_template=True) - - filename = 'texto_integral' model = NormaJuridica - template_name = 'norma/normajuridica_text.txt' + text = TextExtractField( + document=True, use_template=True, + model_attr=( + ('texto_integral', 'file_extractor'), + ('texto_articulado', 'ta_extractor') + ) + ) - def get_updated_field(self): - return 'data_ultima_atualizacao' + +class MateriaLegislativaIndex(DocumentoAcessorioIndex): + model = MateriaLegislativa + text = TextExtractField( + document=True, use_template=True, + model_attr=( + ('texto_original', 'file_extractor'), + ('texto_articulado', 'ta_extractor') + ) + ) diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index 4dfad8e99..9a763f3b2 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -1,7 +1,7 @@ -import logging -import sys from collections import OrderedDict from datetime import timedelta +import logging +import sys from braces.views import FormMessagesMixin from django import forms @@ -19,8 +19,8 @@ from django.http.response import (HttpResponse, HttpResponseRedirect, from django.shortcuts import get_object_or_404, redirect from django.utils.dateparse import parse_date from django.utils.encoding import force_text -from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat +from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import TemplateView from django.views.generic.detail import DetailView from django.views.generic.edit import (CreateView, DeleteView, FormView, @@ -50,6 +50,7 @@ from sapl.compilacao.utils import (DISPOSITIVO_SELECT_RELATED, from sapl.crud.base import Crud, CrudListView, make_pagination from sapl.settings import BASE_DIR + TipoNotaCrud = Crud.build(TipoNota, 'tipo_nota') TipoVideCrud = Crud.build(TipoVide, 'tipo_vide') TipoPublicacaoCrud = Crud.build(TipoPublicacao, 'tipo_publicacao') @@ -1157,10 +1158,14 @@ class TextEditView(CompMixin, TemplateView): self.object.save() messages.success(request, _( 'Texto Articulado desbloqueado com sucesso.')) + + if self.object.content_object: + self.object.content_object.save() + else: if 'lock' in request.GET: - # TODO - implementar logging de ação de usuário + # TODO - implementar logging de ação de usuário notificacoes = self.get_notificacoes( object_list=self.object.dispositivos_set.all(), type_notificacoes=['danger', ]) @@ -1183,6 +1188,9 @@ class TextEditView(CompMixin, TemplateView): messages.success(request, _( 'Texto Articulado bloqueado com sucesso.')) + if self.object.content_object: + self.object.content_object.save() + return redirect(to=reverse_lazy( 'sapl.compilacao:ta_text', kwargs={ 'ta_id': self.object.id})) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 05120f616..d478a8589 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -2,7 +2,6 @@ from datetime import datetime from random import choice from string import ascii_letters, digits -import weasyprint from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML from django.contrib import messages @@ -20,8 +19,8 @@ from django.views.generic import CreateView, ListView, TemplateView, UpdateView from django.views.generic.base import RedirectView from django.views.generic.edit import FormView from django_filters.views import FilterView +import weasyprint -import sapl from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Comissao, Participacao from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT, @@ -42,6 +41,7 @@ from sapl.protocoloadm.models import Protocolo from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label, autor_modal, gerar_hash_arquivo, get_base_url, montar_row_autor, show_results_filter_set) +import sapl from .email_utils import do_envia_email_confirmacao from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, @@ -62,6 +62,7 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, TipoProposicao, Tramitacao, UnidadeTramitacao) from .signals import tramitacao_signal + AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia') OrigemCrud = Crud.build(Origem, '') diff --git a/sapl/templates/search/search.html b/sapl/templates/search/search.html index 3ea67cc86..e3b430f40 100644 --- a/sapl/templates/search/search.html +++ b/sapl/templates/search/search.html @@ -54,11 +54,14 @@ {% if result.object.texto_original %} Texto Original: Clique aqui
    + {% endif %} + {% if result.object.texto_articulado.first %} + Texto Articulado: Clique aqui
    {% else %} O texto desta matéria foi removido recentemente. Em breve ela sairá desta listagem.
    {% endif %}

    - + {% elif result.object|search_get_model == 'd' %}

    Documento Acessório: {{ result.object }}
    @@ -74,6 +77,9 @@ Norma Jurídica: {{ result.object }}
    {% if result.object.texto_integral %} Texto Original: Clique aqui
    + {% endif %} + {% if result.object.texto_articulado.first %} + Texto Articulado: Clique aqui
    {% else %} O texto desta norma foi removido recentemente. Em breve ela sairá desta listagem.
    {% endif %} From ffc34c3ed347a03ffa0d4ce8fcdded46e8e62518 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 14 Nov 2017 11:26:13 -0200 Subject: [PATCH 179/237] Especifica melhor o objeto sapl dentro do zodb --- sapl/legacy/scripts/exporta_zope/exporta_zope.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index 1a39247bb..9d43ce4f2 100644 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -126,12 +126,13 @@ def get_app(data_fs_path): def find_sapl(app): - [id] = [e['id'] for e in app['_objects'] - if e['id'].startswith('cm_') - and e['meta_type'] == 'Folder'] - cm_zzz = br(app[id]) - sapl = br(cm_zzz['sapl']) - return sapl + for obj in app['_objects']: + id, meta_type = obj['id'], obj['meta_type'] + if id.startswith('cm_') and meta_type == 'Folder': + cm_zzz = br(app[id]) + sapl = br(cm_zzz.get('sapl', None)) + if sapl and 'sapl_documentos' in sapl and 'acl_users' in sapl: + return sapl def dump_sapl(data_fs_path): From 82de14e686df5ed8078aaa05de939cd7e62f39ea Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 14 Nov 2017 11:36:11 -0200 Subject: [PATCH 180/237] Estrutura dump de docs como script --- .../scripts/exporta_zope/exporta_zope.py | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) mode change 100644 => 100755 sapl/legacy/scripts/exporta_zope/exporta_zope.py diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py old mode 100644 new mode 100755 index 9d43ce4f2..2ac6eaad2 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- # IMPORTANTE: @@ -5,9 +6,11 @@ # e depende apenas do descrito no arquivo requiments.txt import os.path +import sys from collections import defaultdict from functools import partial +import yaml import ZODB.DB import ZODB.FileStorage from ZODB.broken import Broken @@ -64,7 +67,6 @@ def dump_file(doc, path): return name -nao_identificados = defaultdict(list) def enumerate_folder(folder): @@ -85,6 +87,9 @@ def enumerate_btree(folder): assert contagem_esperada == contagem_real +nao_identificados = defaultdict(list) + + def dump_folder(folder, path='', enum=enumerate_folder): name = folder['id'] path = os.path.join(path, name) @@ -135,6 +140,16 @@ def find_sapl(app): return sapl +def dump_propriedades(docs): + props_sapl = br(docs['props_sapl']) + ids = [p['id'] for p in props_sapl['_properties']] + props = {id: props_sapl[id] for id in ids} + props = {id: p.decode('iso-8859-1') if isinstance(p, str) else p + for id, p in props.items()} + with open('sapl_documentos/propriedades.yaml', 'w') as f: + f.write(yaml.safe_dump(props)) + + def dump_sapl(data_fs_path): app, close_db = get_app(data_fs_path) try: @@ -143,6 +158,7 @@ def dump_sapl(data_fs_path): nao_identificados.clear() dump_folder(docs) + dump_propriedades(docs) if nao_identificados: print('#' * 80) print('#' * 80) @@ -155,11 +171,9 @@ def dump_sapl(data_fs_path): close_db() -def dump_propriedades(docs): - props_sapl = br(docs['props_sapl']) - ids = [p['id'] for p in props_sapl['_properties']] - props = {id: props_sapl[id] for id in ids} - props = {id: p.decode('iso-8859-1') if isinstance(p, str) else p - for id, p in props.items()} - with open('sapl_documentos/propriedades.yaml', 'w') as f: - f.write(yaml.safe_dump(props)) +if __name__ == "__main__": + if len(sys.argv) == 2: + data_fs_path = sys.argv[1] + dump_sapl(data_fs_path) + else: + print('Uso: python exporta_zope ') From f66b69c16b4e6082bd73e316d31ac21288a19493 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 14 Nov 2017 11:40:36 -0200 Subject: [PATCH 181/237] =?UTF-8?q?HOT-FIX:=20por=20enquanto=20ser=C3=A1?= =?UTF-8?q?=20date()=20e=20n=C3=A3o=20now()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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 d478a8589..a1359c160 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -941,7 +941,7 @@ class TramitacaoCrud(MasterDetailCrud): ] = local.unidade_tramitacao_destino.pk else: self.initial['unidade_tramitacao_local'] = '' - self.initial['data_tramitacao'] = timezone.now() + self.initial['data_tramitacao'] = timezone.now().date() return self.initial def get_context_data(self, **kwargs): From d0c62ea8b841e7c4dbd42b2a385dade8bd47f501 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 14 Nov 2017 12:04:54 -0200 Subject: [PATCH 182/237] =?UTF-8?q?Contorna=20vazamento=20de=20mem=C3=B3ri?= =?UTF-8?q?a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scripts/exporta_zope/exporta_zope.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index 2ac6eaad2..d8498266a 100755 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -55,18 +55,28 @@ def dump_file(doc, path): fullname = os.path.join(path, name + extension) print(fullname) - pdata = br(doc['data']) + # A partir daqui usamos dict.pop('...') nos __Broken_state__ + # para contornar um "vazamento" de memória que ocorre + # ao percorrer a árvore de objetos + # + # Imaginamos que, internamente, o ZODB está guardando referências + # para os objetos Broken criados e não conseguimos identificar como. + # + # Essa medida descarta quase todos os dados retornados + # e só funciona na primeira passagem + + pdata = br(doc.pop('data')) if isinstance(pdata, str): # Retrocedemos se pdata ja eh uma str (necessario em Images) + doc['data'] = pdata pdata = doc with open(fullname, 'w') as arq: while pdata: - arq.write(pdata['data']) - pdata = br(pdata.get('next', None)) - return name - + arq.write(pdata.pop('data')) + pdata = br(pdata.pop('next', None)) + return name def enumerate_folder(folder): From 37f83d0a4131390a566565a49184223c8f2ac878 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 14 Nov 2017 12:40:36 -0200 Subject: [PATCH 183/237] =?UTF-8?q?Registra=20extens=C3=B5es=20desconhecid?= =?UTF-8?q?as=20p=20inspe=C3=A7=C3=A3o=20posterior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/scripts/exporta_zope/exporta_zope.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index d8498266a..f6ebb5748 100755 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -49,12 +49,20 @@ def br(obj): return obj +extensoes_desconhecidas = defaultdict(list) + + def dump_file(doc, path): name = doc['__name__'] - extension = EXTENSOES[doc['content_type']] + content_type = doc['content_type'] + extension = EXTENSOES.get(content_type, 'ZZZZ') + fullname = os.path.join(path, name + extension) print(fullname) + if extension == 'ZZZZ': + extensoes_desconhecidas[content_type].append(fullname) + # A partir daqui usamos dict.pop('...') nos __Broken_state__ # para contornar um "vazamento" de memória que ocorre # ao percorrer a árvore de objetos From 09124f70ad4d76911886184566f103420e047eb3 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 14 Nov 2017 12:57:34 -0200 Subject: [PATCH 184/237] =?UTF-8?q?Usa=20=C3=BAltima=20vers=C3=A3o=20do=20?= =?UTF-8?q?ZODB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/scripts/exporta_zope/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/legacy/scripts/exporta_zope/requirements.txt b/sapl/legacy/scripts/exporta_zope/requirements.txt index 1770426da..4794267ae 100644 --- a/sapl/legacy/scripts/exporta_zope/requirements.txt +++ b/sapl/legacy/scripts/exporta_zope/requirements.txt @@ -1,3 +1,3 @@ # ZODB version 3.7.4 -git+git://github.com/zopefoundation/ZODB.git@d6f3c3ce5e6df1060de7a3#egg=ZODB3 PyYAML==3.12 +ZODB==5.3.0 From 036d9aa9b194dcab205140636d0639a0c086923f Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 14 Nov 2017 14:04:08 -0200 Subject: [PATCH 185/237] Fixes #1595 --- sapl/materia/views.py | 15 +++++++++------ sapl/templates/materia/tramitacao_form.html | 9 ++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index a1359c160..f3543d412 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -947,16 +947,19 @@ class TramitacaoCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - primeira_tramitacao = not(Tramitacao.objects.filter( - materia_id=int(kwargs['root_pk'])).exists()) + ultima_tramitacao = Tramitacao.objects.filter( + materia_id=self.kwargs['pk']).order_by( + '-data_tramitacao', + '-id').first() - # Se não for a primeira tramitação daquela matéria, o campo - # não pode ser modificado - if not primeira_tramitacao: + if ultima_tramitacao: context['form'].fields[ - 'unidade_tramitacao_local'].widget.attrs['disabled'] = True + 'unidade_tramitacao_local'].choices = [ + (ultima_tramitacao.unidade_tramitacao_destino.pk, + ultima_tramitacao.unidade_tramitacao_destino)] return context + def form_valid(self, form): self.object = form.save() diff --git a/sapl/templates/materia/tramitacao_form.html b/sapl/templates/materia/tramitacao_form.html index 2129dba5a..6346a4f37 100644 --- a/sapl/templates/materia/tramitacao_form.html +++ b/sapl/templates/materia/tramitacao_form.html @@ -7,9 +7,12 @@ // Caso o campo esteja desabilitado (quando não é a primeira tramitação), // habilita ele no momento do submit para que o valor de unidade local // não seja enviado como vazio - $('form').submit(function(){ - $('#id_unidade_tramitacao_local').prop('disabled', false); - }); + + // ESTA SOLUCAO NAO FUNCIONOU NO CHROME, SOMENTE NO FIREFOX + // NO CHROME NAO E DISPARADO A FUNCAO DE HABILITACAO NO SUBMIT DO FORM + + + {% endblock %} From 3d6c67d655c7d2d21f6704647c3dfb56fa894ff1 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Mon, 20 Nov 2017 09:46:59 -0200 Subject: [PATCH 186/237] =?UTF-8?q?add=20campos=20para=20indexa=C3=A7?= =?UTF-8?q?=C3=A3o=20em=20full=20text=20search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit inclui os campos (ementa, indexação e observação) na busca FTS. Este procedimento é relevante para que documentos digitalizados sem OCR tenham condições mínimas de serem catalogados na busca textual. --- sapl/base/search_indexes.py | 19 ++++++++++++++++--- sapl/templates/search/search.html | 3 +++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/sapl/base/search_indexes.py b/sapl/base/search_indexes.py index e925de8c8..9c11f304f 100644 --- a/sapl/base/search_indexes.py +++ b/sapl/base/search_indexes.py @@ -105,6 +105,9 @@ class TextExtractField(CharField): r += list(filter(lambda x: x.strip(), dispositivos)) return ' '.join(r) + def string_extractor(self, value): + return value + def extract_data(self, obj): data = '' @@ -135,7 +138,11 @@ class DocumentoAcessorioIndex(SearchIndex, Indexable): model = DocumentoAcessorio text = TextExtractField( document=True, use_template=True, - model_attr=(('arquivo', 'file_extractor'), ) + model_attr=( + ('arquivo', 'file_extractor'), + ('ementa', 'string_extractor'), + ('indexacao', 'string_extractor'), + ) ) def get_model(self): @@ -154,7 +161,10 @@ class NormaJuridicaIndex(DocumentoAcessorioIndex): document=True, use_template=True, model_attr=( ('texto_integral', 'file_extractor'), - ('texto_articulado', 'ta_extractor') + ('texto_articulado', 'ta_extractor'), + ('ementa', 'string_extractor'), + ('indexacao', 'string_extractor'), + ('observacao', 'string_extractor'), ) ) @@ -165,6 +175,9 @@ class MateriaLegislativaIndex(DocumentoAcessorioIndex): document=True, use_template=True, model_attr=( ('texto_original', 'file_extractor'), - ('texto_articulado', 'ta_extractor') + ('texto_articulado', 'ta_extractor'), + ('ementa', 'string_extractor'), + ('indexacao', 'string_extractor'), + ('observacao', 'string_extractor'), ) ) diff --git a/sapl/templates/search/search.html b/sapl/templates/search/search.html index e3b430f40..f55688255 100644 --- a/sapl/templates/search/search.html +++ b/sapl/templates/search/search.html @@ -51,6 +51,7 @@ {% if result.object|search_get_model == 'm' %}

    Matéria Legislativa: {{ result.object }}
    + {{result.object.ementa}}
    {% if result.object.texto_original %} Texto Original: Clique aqui
    @@ -65,6 +66,7 @@ {% elif result.object|search_get_model == 'd' %}

    Documento Acessório: {{ result.object }}
    + {{result.object.ementa}}
    {% if result.object.arquivo %} Texto Original: Clique aqui
    {% else %} @@ -75,6 +77,7 @@ {% elif result.object|search_get_model == 'n' %}

    Norma Jurídica: {{ result.object }}
    + {{result.object.ementa}}
    {% if result.object.texto_integral %} Texto Original: Clique aqui
    {% endif %} From c48542991f819d33f51e8b7bab665c01bafde129 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 20 Nov 2017 16:19:18 -0200 Subject: [PATCH 187/237] [by Mari] Fixes #1595 --- sapl/templates/materia/em_lote/tramitacao.html | 7 ++++--- sapl/templates/materia/tramitacao_form.html | 9 ++++----- .../protocoloadm/tramitacaoadministrativo_form.html | 8 +++++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sapl/templates/materia/em_lote/tramitacao.html b/sapl/templates/materia/em_lote/tramitacao.html index d385bd74e..c60bcdda6 100644 --- a/sapl/templates/materia/em_lote/tramitacao.html +++ b/sapl/templates/materia/em_lote/tramitacao.html @@ -141,8 +141,9 @@ }); // Reabilita o campo, no momento do Submit, para que seu dado seja enviado - $('form').submit(function(){ - $('#id_unidade_tramitacao_local').prop('disabled', false); - }); + $('input[type=submit]').click(function() { + $('#id_unidade_tramitacao_local').attr('disabled', false); + $('#id_unidade_tramitacao_local').parents('form').submit(); + } {% endblock %} diff --git a/sapl/templates/materia/tramitacao_form.html b/sapl/templates/materia/tramitacao_form.html index 6346a4f37..82b24036a 100644 --- a/sapl/templates/materia/tramitacao_form.html +++ b/sapl/templates/materia/tramitacao_form.html @@ -8,11 +8,10 @@ // habilita ele no momento do submit para que o valor de unidade local // não seja enviado como vazio - // ESTA SOLUCAO NAO FUNCIONOU NO CHROME, SOMENTE NO FIREFOX - // NO CHROME NAO E DISPARADO A FUNCAO DE HABILITACAO NO SUBMIT DO FORM - - - + $('input[type=submit]').click(function() { + $('#id_unidade_tramitacao_local').attr('disabled', false); + $('#id_unidade_tramitacao_local').parents('form').submit(); + } {% endblock %} diff --git a/sapl/templates/protocoloadm/tramitacaoadministrativo_form.html b/sapl/templates/protocoloadm/tramitacaoadministrativo_form.html index 5be26dd5c..7de9f8af0 100644 --- a/sapl/templates/protocoloadm/tramitacaoadministrativo_form.html +++ b/sapl/templates/protocoloadm/tramitacaoadministrativo_form.html @@ -5,8 +5,10 @@ // Caso o campo esteja desabilitado (quando não é a primeira tramitação), // habilita ele no momento do submit para que o valor de unidade local // não seja enviado como vazio - $('form').submit(function(){ - $('#id_unidade_tramitacao_local').prop('disabled', false); - }); + + $('input[type=submit]').click(function() { + $('#id_unidade_tramitacao_local').attr('disabled', false); + $('#id_unidade_tramitacao_local').parents('form').submit(); + } {% endblock extra_js %} \ No newline at end of file From c463ad5b79ab007d135de9187d06c3a3ce07ce43 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 20 Nov 2017 16:22:03 -0200 Subject: [PATCH 188/237] Novo release: 3.1.33-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8d234b4d9..318feb493 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.32-BETA + image: interlegis/sapl:3.1.33-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index d2eae0df6..6e910d433 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.32-BETA', + version='3.1.33-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From ac1ea1cea041d0c8fc0145a1687773f667b5b724 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 20 Nov 2017 16:25:52 -0200 Subject: [PATCH 189/237] Novo release: 3.1.34-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 318feb493..954a12b0d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.33-BETA + image: interlegis/sapl:3.1.34-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index 6e910d433..745cfdc47 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.33-BETA', + version='3.1.34-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From caebc86da9eb5d280b23516e69bc940beb99c7d2 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 21 Nov 2017 09:58:32 -0200 Subject: [PATCH 190/237] =?UTF-8?q?HOT-FIX:=20falha=20na=20unicidade=20das?= =?UTF-8?q?=20configura=C3=A7=C3=B5es=20da=20app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit havia possibilidade de um POST criar mais um registro do model base.models.AppConfig. Em uma base de teste especifica foi identifica 'n' registros, possivelmente causados por clique duplo no botão de salvar (problema já resolvido tb)... --- sapl/base/models.py | 15 +++++++++------ sapl/base/views.py | 21 ++++++++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/sapl/base/models.py b/sapl/base/models.py index b1edf8b64..640616fa9 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -1,17 +1,18 @@ -import reversion from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models from django.db.models.signals import post_migrate from django.db.utils import DEFAULT_DB_ALIAS from django.utils.translation import ugettext_lazy as _ +import reversion from sapl.utils import ( UF, YES_NO_CHOICES, get_settings_auth_user_model, models_with_gr_for_model - ) +) + TIPO_DOCUMENTO_ADMINISTRATIVO = (('O', _('Ostensivo')), ('R', _('Restritivo'))) @@ -176,6 +177,7 @@ class AppConfig(models.Model): ('menu_sistemas', _('Renderizar Menu Sistemas')), ('view_tabelas_auxiliares', _('Visualizar Tabelas Auxiliares')), ) + ordering = ('-id',) @classmethod def attr(cls, attr): @@ -262,7 +264,7 @@ def cria_models_tipo_autor(app_config, verbosity=2, interactive=True, models = models_with_gr_for_model(Autor) print("\n\033[93m\033[1m{}\033[0m".format( - _('Atualizando registros TipoAutor do SAPL:'))) + _('Atualizando registros TipoAutor do SAPL:'))) for model in models: content_type = ContentType.objects.get_for_model(model) tipo_autor = TipoAutor.objects.filter( @@ -272,8 +274,8 @@ def cria_models_tipo_autor(app_config, verbosity=2, interactive=True, msg1 = "Carga de {} não efetuada.".format( TipoAutor._meta.verbose_name) msg2 = " Já Existe um {} {} relacionado...".format( - TipoAutor._meta.verbose_name, - model._meta.verbose_name) + TipoAutor._meta.verbose_name, + model._meta.verbose_name) msg = " {}{}".format(msg1, msg2) else: novo_autor = TipoAutor() @@ -283,10 +285,11 @@ def cria_models_tipo_autor(app_config, verbosity=2, interactive=True, msg1 = "Carga de {} efetuada.".format( TipoAutor._meta.verbose_name) msg2 = " {} {} criado...".format( - TipoAutor._meta.verbose_name, content_type.model) + TipoAutor._meta.verbose_name, content_type.model) msg = " {}{}".format(msg1, msg2) print(msg) # Disconecta função para evitar a chamada repetidas vezes. post_migrate.disconnect(receiver=cria_models_tipo_autor) + post_migrate.connect(receiver=cria_models_tipo_autor) diff --git a/sapl/base/views.py b/sapl/base/views.py index ebd22d626..4154cfe4b 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -521,15 +521,18 @@ class AppConfigCrud(CrudAux): class CreateView(CrudAux.CreateView): def get(self, request, *args, **kwargs): - app_config = AppConfig.objects.last() - if app_config: - return HttpResponseRedirect( - reverse('sapl.base:appconfig_update', - kwargs={'pk': app_config.pk})) - else: - self.object = None - return super(CrudAux.CreateView, self).get( - request, *args, **kwargs) + app_config = AppConfig.objects.first() + + if not app_config: + app_config = AppConfig() + app_config.save() + + return HttpResponseRedirect( + reverse('sapl.base:appconfig_update', + kwargs={'pk': app_config.pk})) + + def post(self, request, *args, **kwargs): + return self.get(request, *args, **kwargs) class ListView(CrudAux.ListView): From 7bc9eac972938bf1742a30bdb00baa37821593a0 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 21 Nov 2017 10:28:15 -0200 Subject: [PATCH 191/237] Fix #1448 --- sapl/compilacao/views.py | 2 +- sapl/templates/compilacao/publicacao_detail.html | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index 9a763f3b2..e6c402a77 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -877,7 +877,7 @@ class PublicacaoCreateView(PublicacaoMixin, FormMessagesMixin, CreateView): class PublicacaoDetailView(PublicacaoMixin, DetailView): model = Publicacao - permission_required = 'compilacao.detail_publicacao' + permission_required = [] class PublicacaoUpdateView(PublicacaoMixin, UpdateView): diff --git a/sapl/templates/compilacao/publicacao_detail.html b/sapl/templates/compilacao/publicacao_detail.html index d157e49f5..985ceed05 100644 --- a/sapl/templates/compilacao/publicacao_detail.html +++ b/sapl/templates/compilacao/publicacao_detail.html @@ -81,8 +81,9 @@

    - -

    {{ object.url_externa|default:''}}

    + {% if object.url_externa %} + + {% endif %}
    From c9f05e6a742d1e7144bde7f7020b66cf3558f25b Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 21 Nov 2017 11:09:38 -0200 Subject: [PATCH 192/237] Fix #1447 --- sapl/compilacao/views.py | 14 ++++++++- .../compilacao/publicacao_detail.html | 30 +++++++++---------- .../templates/compilacao/publicacao_list.html | 6 ++++ sapl/templates/crud/confirm_delete.html | 5 ++-- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index e6c402a77..878c21b06 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -830,7 +830,7 @@ class PublicacaoListView(PublicacaoMixin, ListView): @property def title(self): - return _('%s de %s' % ( + return _('%s (%s)' % ( self.model._meta.verbose_name_plural, self.ta)) @@ -846,6 +846,8 @@ class PublicacaoListView(PublicacaoMixin, ListView): def get_context_data(self, **kwargs): context = super(PublicacaoListView, self).get_context_data(**kwargs) + context['title'] = self.title + context['object'] = self.ta context['NO_ENTRIES_MSG'] = CrudListView.no_entries_msg return context @@ -879,6 +881,16 @@ class PublicacaoDetailView(PublicacaoMixin, DetailView): model = Publicacao permission_required = [] + @property + def list_url(self): + return reverse_lazy('sapl.compilacao:ta_pub_list', + kwargs={ + 'ta_id': self.kwargs['ta_id']}) + + @property + def verbose_name_plural(self): + return self.model._meta.verbose_name_plural + class PublicacaoUpdateView(PublicacaoMixin, UpdateView): model = Publicacao diff --git a/sapl/templates/compilacao/publicacao_detail.html b/sapl/templates/compilacao/publicacao_detail.html index 985ceed05..949eb668b 100644 --- a/sapl/templates/compilacao/publicacao_detail.html +++ b/sapl/templates/compilacao/publicacao_detail.html @@ -1,22 +1,23 @@ -{% extends "base.html" %} +{% extends "crud/detail.html" %} {% load i18n %} {% load compilacao_filters %} {% load common_tags %} -{% block base_content %} -
    - {% block actions %} - - {% endblock actions %} -
    -
    - {% block sections_nav %} - {% endblock %} -
    +{% block sections_nav %} + +{% endblock %} +{% block editions %} + +{% endblock editions %} + +
    {% block detail_content %} {# TODO replace fieldset for something semantically correct, but with similar visual grouping style #}
    {%trans 'Identificação Básica'%} @@ -89,4 +90,3 @@
    {% endblock detail_content %} -{% endblock base_content %} diff --git a/sapl/templates/compilacao/publicacao_list.html b/sapl/templates/compilacao/publicacao_list.html index 975fbf1f4..11c5e452a 100644 --- a/sapl/templates/compilacao/publicacao_list.html +++ b/sapl/templates/compilacao/publicacao_list.html @@ -3,6 +3,12 @@ {% load compilacao_filters %} {% load common_tags %} +{% block sections_nav %} + +{% endblock %} + {% block base_content %} {% if perms.compilacao.add_publicacao %} diff --git a/sapl/templates/crud/confirm_delete.html b/sapl/templates/crud/confirm_delete.html index af680112b..f41a4c76a 100644 --- a/sapl/templates/crud/confirm_delete.html +++ b/sapl/templates/crud/confirm_delete.html @@ -7,8 +7,9 @@
    {% blocktrans %} - Confirma exclusão de "{{ object }}"? - {% endblocktrans %} + Confirma exclusão de + {% endblocktrans %}
    + "{{ object|safe }}"?
    {% trans 'Cancelar' %} From e5d774da8665d936a3874cc9e1a17a1bdc42ab81 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 21 Nov 2017 11:31:59 -0200 Subject: [PATCH 193/237] add arquivo de makemigrations --- .../migrations/0011_auto_20171121_0958.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 sapl/base/migrations/0011_auto_20171121_0958.py diff --git a/sapl/base/migrations/0011_auto_20171121_0958.py b/sapl/base/migrations/0011_auto_20171121_0958.py new file mode 100644 index 000000000..6178bd950 --- /dev/null +++ b/sapl/base/migrations/0011_auto_20171121_0958.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-11-21 11:58 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0010_remove_appconfig_painel_aberto'), + ] + + operations = [ + migrations.AlterModelOptions( + name='appconfig', + options={'ordering': ('-id',), 'permissions': (('menu_sistemas', 'Renderizar Menu Sistemas'), ('view_tabelas_auxiliares', 'Visualizar Tabelas Auxiliares')), 'verbose_name': 'Configurações da Aplicação', 'verbose_name_plural': 'Configurações da Aplicação'}, + ), + ] From f27d0d5ed54611172efffa3cdf0478a93b8a907e Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 21 Nov 2017 11:41:51 -0200 Subject: [PATCH 194/237] =?UTF-8?q?adiciona=20coment=C3=A1rio=20a=20checag?= =?UTF-8?q?em=20de=20makemigrations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- check_migrations.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/check_migrations.sh b/check_migrations.sh index ff545a3c5..2933bdbcd 100755 --- a/check_migrations.sh +++ b/check_migrations.sh @@ -21,6 +21,7 @@ if [ $MIGRATIONS -eq 0 ]; then echo echo -e "${RED}ALGUMAS ALTERAÇÕES EXIGEM MIGRAÇÃO.${NC}" echo -e "${RED}RODE 'python manage.py makemigrations' ANTES DE SUBMETER SEU CÓDIGO...${NC}" + echo -e "${RED}lembre de adicionar os arquivos criados ao git com 'git add .' ou semelhante.${NC}" echo exit 1 fi \ No newline at end of file From 614f92fce7faea485503329b58e3c61ecc6afefc Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 21 Nov 2017 13:12:59 -0200 Subject: [PATCH 195/237] =?UTF-8?q?Mant=C3=A9m=20extens=C3=A3o=20original?= =?UTF-8?q?=20dos=20arquivos=20que=20tiverem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/scripts/exporta_zope/exporta_zope.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index f6ebb5748..b09d2e812 100755 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -9,6 +9,7 @@ import os.path import sys from collections import defaultdict from functools import partial +from os.path import splitext import yaml import ZODB.DB @@ -53,9 +54,10 @@ extensoes_desconhecidas = defaultdict(list) def dump_file(doc, path): - name = doc['__name__'] + id = doc['__name__'] + name, extension = splitext(id) content_type = doc['content_type'] - extension = EXTENSOES.get(content_type, 'ZZZZ') + extension = extension or EXTENSOES.get(content_type, 'ZZZZ') fullname = os.path.join(path, name + extension) print(fullname) @@ -84,7 +86,7 @@ def dump_file(doc, path): arq.write(pdata.pop('data')) pdata = br(pdata.pop('next', None)) - return name + return id def enumerate_folder(folder): From 2cca1c67bce9a22f9eaf441cf82514a2418d57b5 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 21 Nov 2017 15:03:38 -0200 Subject: [PATCH 196/237] =?UTF-8?q?Descreve=20o=20tipo=20de=20mat=C3=A9ria?= =?UTF-8?q?=20quando=20inexistente=20no=20cadastro=20de=20norma?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/norma/forms.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index f5be3f918..1ea6812fd 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -131,11 +131,13 @@ class NormaJuridicaForm(ModelForm): tipo_id=cleaned_data['tipo_materia'], numero=cleaned_data['numero_materia'], ano=cleaned_data['ano_materia']) + except ObjectDoesNotExist: raise forms.ValidationError( - _("Matéria %s/%s é inexistente." % ( + _("Matéria Legislativa %s/%s (%s) é inexistente." % ( self.cleaned_data['numero_materia'], - self.cleaned_data['ano_materia']))) + self.cleaned_data['ano_materia'], + cleaned_data['tipo_materia'].descricao))) else: cleaned_data['materia'] = materia From e51585135de2fb5d333475e50511b651039f102a Mon Sep 17 00:00:00 2001 From: Eliseu Egewarth Date: Tue, 21 Nov 2017 15:54:01 -0200 Subject: [PATCH 197/237] Fix #1599 Signed-off-by: Eliseu Egewarth --- sapl/templates/base.html | 3 --- sapl/templates/navbar.yaml | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sapl/templates/base.html b/sapl/templates/base.html index 19f70e4f9..efcd0a647 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -69,9 +69,6 @@ Votar Matéria {% endif %} - {% if request.user.is_superuser %} -
  • Administração
  • - {% endif %}
  • Sair
  • diff --git a/sapl/templates/navbar.yaml b/sapl/templates/navbar.yaml index 9bcb12e2d..b0836341b 100644 --- a/sapl/templates/navbar.yaml +++ b/sapl/templates/navbar.yaml @@ -65,6 +65,9 @@ - title: {% trans 'Tabelas Auxiliares' %} url: '/sistema' check_permission: base.view_tabelas_auxiliares + - title: {% trans 'Administração de Usuários' %} + url: '/admin' + check_permission: user.is_superuser {% comment %} From d3eca775168f1471d3f0bd53e5ae803b9f3949db Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 21 Nov 2017 16:08:11 -0200 Subject: [PATCH 198/237] HOT-FIX: conserta teste de norma --- sapl/norma/tests/test_norma.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sapl/norma/tests/test_norma.py b/sapl/norma/tests/test_norma.py index 58816be48..6db0df672 100644 --- a/sapl/norma/tests/test_norma.py +++ b/sapl/norma/tests/test_norma.py @@ -76,7 +76,7 @@ def test_norma_form_invalida(): def test_norma_juridica_materia_inexistente(): tipo = mommy.make(TipoNormaJuridica) - tipo_materia = mommy.make(TipoMateriaLegislativa) + tipo_materia = mommy.make(TipoMateriaLegislativa, descricao='VETO') form = NormaJuridicaForm(data={'tipo': str(tipo.pk), 'numero': '1', @@ -91,7 +91,9 @@ def test_norma_juridica_materia_inexistente(): assert not form.is_valid() - assert form.errors['__all__'] == [_("Matéria 2/2017 é inexistente.")] + import ipdb; ipdb.set_trace() + + assert form.errors['__all__'] == [_("Matéria Legislativa 2/2017 (VETO) é inexistente.")] @pytest.mark.django_db(transaction=False) From 2fa01839a2955ebbf3d6f831c11a0a793425c543 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 21 Nov 2017 16:16:15 -0200 Subject: [PATCH 199/237] Retira chamada a ipdb --- sapl/norma/tests/test_norma.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/sapl/norma/tests/test_norma.py b/sapl/norma/tests/test_norma.py index 6db0df672..1857f0966 100644 --- a/sapl/norma/tests/test_norma.py +++ b/sapl/norma/tests/test_norma.py @@ -91,8 +91,6 @@ def test_norma_juridica_materia_inexistente(): assert not form.is_valid() - import ipdb; ipdb.set_trace() - assert form.errors['__all__'] == [_("Matéria Legislativa 2/2017 (VETO) é inexistente.")] From 5f87c02003d7b7d9fda2ec9356cd74d2260fdb79 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 13 Nov 2017 13:42:27 -0200 Subject: [PATCH 200/237] Fixes #1589 --- .../migrations/0018_auto_20171113_1339.py | 101 ++++++++++++++++++ sapl/materia/models.py | 38 +++---- .../migrations/0009_auto_20171113_1339.py | 26 +++++ sapl/norma/models.py | 4 +- 4 files changed, 148 insertions(+), 21 deletions(-) create mode 100644 sapl/materia/migrations/0018_auto_20171113_1339.py create mode 100644 sapl/norma/migrations/0009_auto_20171113_1339.py diff --git a/sapl/materia/migrations/0018_auto_20171113_1339.py b/sapl/materia/migrations/0018_auto_20171113_1339.py new file mode 100644 index 000000000..a84b1c6d8 --- /dev/null +++ b/sapl/materia/migrations/0018_auto_20171113_1339.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2017-11-13 15:39 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0017_auto_20170918_1257'), + ] + + operations = [ + migrations.AlterField( + model_name='anexada', + name='materia_anexada', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materia_anexada_set', to='materia.MateriaLegislativa'), + ), + migrations.AlterField( + model_name='anexada', + name='materia_principal', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materia_principal_set', to='materia.MateriaLegislativa'), + ), + migrations.AlterField( + model_name='autoria', + name='autor', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.Autor', verbose_name='Autor'), + ), + migrations.AlterField( + model_name='autoria', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa', verbose_name='Matéria Legislativa'), + ), + migrations.AlterField( + model_name='despachoinicial', + name='comissao', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='comissoes.Comissao'), + ), + migrations.AlterField( + model_name='despachoinicial', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa'), + ), + migrations.AlterField( + model_name='documentoacessorio', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa'), + ), + migrations.AlterField( + model_name='materiaassunto', + name='assunto', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.AssuntoMateria', verbose_name='Assunto'), + ), + migrations.AlterField( + model_name='materiaassunto', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa', verbose_name='Matéria'), + ), + migrations.AlterField( + model_name='numeracao', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa'), + ), + migrations.AlterField( + model_name='parecer', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa'), + ), + migrations.AlterField( + model_name='parecer', + name='relatoria', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.Relatoria'), + ), + migrations.AlterField( + model_name='proposicao', + name='materia_de_vinculo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='proposicao_set', to='materia.MateriaLegislativa', verbose_name='Matéria anexadora'), + ), + migrations.AlterField( + model_name='relatoria', + name='comissao', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comissoes.Comissao', verbose_name='Comissão'), + ), + migrations.AlterField( + model_name='relatoria', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa'), + ), + migrations.AlterField( + model_name='relatoria', + name='parlamentar', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parlamentares.Parlamentar', verbose_name='Parlamentar'), + ), + migrations.AlterField( + model_name='tramitacao', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa'), + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 7859b52d7..c374b7474 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -287,9 +287,9 @@ class MateriaLegislativa(models.Model): class Autoria(models.Model): autor = models.ForeignKey(Autor, verbose_name=_('Autor'), - on_delete=models.PROTECT) + on_delete=models.CASCADE) materia = models.ForeignKey( - MateriaLegislativa, on_delete=models.PROTECT, + MateriaLegislativa, on_delete=models.CASCADE, verbose_name=_('Matéria Legislativa')) primeiro_autor = models.BooleanField(verbose_name=_('Primeiro Autor'), choices=YES_NO_CHOICES, @@ -302,14 +302,14 @@ class Autoria(models.Model): ordering = ('-primeiro_autor', 'autor__nome') def __str__(self): - return _('%(autor)s - %(materia)s') % { + return _('Autoria: %(autor)s - %(materia)s') % { 'autor': self.autor, 'materia': self.materia} @reversion.register() class AcompanhamentoMateria(models.Model): usuario = models.CharField(max_length=50) - materia = models.ForeignKey(MateriaLegislativa) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) email = models.EmailField( max_length=100, verbose_name=_('E-mail')) data_cadastro = models.DateField(auto_now_add=True) @@ -330,10 +330,10 @@ class AcompanhamentoMateria(models.Model): class Anexada(models.Model): materia_principal = models.ForeignKey( MateriaLegislativa, related_name='materia_principal_set', - on_delete=models.PROTECT) + on_delete=models.CASCADE) materia_anexada = models.ForeignKey( MateriaLegislativa, related_name='materia_anexada_set', - on_delete=models.PROTECT) + on_delete=models.CASCADE) data_anexacao = models.DateField(verbose_name=_('Data Anexação')) data_desanexacao = models.DateField( blank=True, null=True, verbose_name=_('Data Desanexação')) @@ -372,8 +372,8 @@ class DespachoInicial(models.Model): # TODO M2M? # TODO Despachos não são necessáriamente comissoes, podem ser outros # órgãos, ex: procuradorias - materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT) - comissao = models.ForeignKey(Comissao, on_delete=models.PROTECT) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) + comissao = models.ForeignKey(Comissao, on_delete=models.CASCADE) class Meta: verbose_name = _('Despacho Inicial') @@ -407,7 +407,7 @@ class TipoDocumento(models.Model): @reversion.register() class DocumentoAcessorio(models.Model): - materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) tipo = models.ForeignKey(TipoDocumento, on_delete=models.PROTECT, verbose_name=_('Tipo')) @@ -477,11 +477,11 @@ class MateriaAssunto(models.Model): # TODO M2M ?? assunto = models.ForeignKey( AssuntoMateria, - on_delete=models.PROTECT, + on_delete=models.CASCADE, verbose_name=_('Assunto')) materia = models.ForeignKey( MateriaLegislativa, - on_delete=models.PROTECT, + on_delete=models.CASCADE, verbose_name=_('Matéria')) class Meta: @@ -495,7 +495,7 @@ class MateriaAssunto(models.Model): @reversion.register() class Numeracao(models.Model): - materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) tipo_materia = models.ForeignKey( TipoMateriaLegislativa, on_delete=models.PROTECT, @@ -564,9 +564,9 @@ class TipoFimRelatoria(models.Model): @reversion.register() class Relatoria(models.Model): - materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) parlamentar = models.ForeignKey(Parlamentar, - on_delete=models.PROTECT, + on_delete=models.CASCADE, verbose_name=_('Parlamentar')) tipo_fim_relatoria = models.ForeignKey( TipoFimRelatoria, @@ -576,7 +576,7 @@ class Relatoria(models.Model): verbose_name=_('Motivo Fim Relatoria')) comissao = models.ForeignKey( Comissao, blank=True, null=True, - on_delete=models.PROTECT, verbose_name=_('Comissão')) + on_delete=models.CASCADE, verbose_name=_('Comissão')) data_designacao_relator = models.DateField( verbose_name=_('Data Designação')) data_destituicao_relator = models.DateField( @@ -595,8 +595,8 @@ class Relatoria(models.Model): @reversion.register() class Parecer(models.Model): - relatoria = models.ForeignKey(Relatoria, on_delete=models.PROTECT) - materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT) + relatoria = models.ForeignKey(Relatoria, on_delete=models.CASCADE) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) tipo_conclusao = models.CharField(max_length=3, blank=True) tipo_apresentacao = models.CharField( max_length=1, choices=TIPO_APRESENTACAO_CHOICES) @@ -680,7 +680,7 @@ class Proposicao(models.Model): # retire o comentário quando resolver materia_de_vinculo = models.ForeignKey( MateriaLegislativa, blank=True, null=True, - on_delete=models.PROTECT, + on_delete=models.CASCADE, verbose_name=_('Matéria anexadora'), related_name=_('proposicao_set')) @@ -850,7 +850,7 @@ class Tramitacao(models.Model): # bases tiverem sido corrigidas null=True, verbose_name=_('Status')) - materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) data_tramitacao = models.DateField(verbose_name=_('Data Tramitação')) unidade_tramitacao_local = models.ForeignKey( UnidadeTramitacao, diff --git a/sapl/norma/migrations/0009_auto_20171113_1339.py b/sapl/norma/migrations/0009_auto_20171113_1339.py new file mode 100644 index 000000000..672d87c94 --- /dev/null +++ b/sapl/norma/migrations/0009_auto_20171113_1339.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2017-11-13 15:39 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0008_normajuridica_popula_tipo_vinculo_norma'), + ] + + operations = [ + migrations.AlterField( + model_name='legislacaocitada', + name='materia', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa'), + ), + migrations.AlterField( + model_name='legislacaocitada', + name='norma', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='norma.NormaJuridica'), + ), + ] diff --git a/sapl/norma/models.py b/sapl/norma/models.py index d00be8ce7..0836ed506 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -174,8 +174,8 @@ class NormaJuridica(models.Model): @reversion.register() class LegislacaoCitada(models.Model): - materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT) - norma = models.ForeignKey(NormaJuridica, on_delete=models.PROTECT) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) + norma = models.ForeignKey(NormaJuridica, on_delete=models.CASCADE) disposicoes = models.CharField( max_length=15, blank=True, verbose_name=_('Disposição')) parte = models.CharField( From 1bb97e79299f3bd8a0127a4a16aae6ee9cb4b0a6 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 21 Nov 2017 18:06:02 -0200 Subject: [PATCH 201/237] Fixes #1602 --- sapl/base/views.py | 142 ++++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index 4154cfe4b..f0ae926e5 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -224,77 +224,77 @@ class RelatorioPresencaSessaoView(FilterView): return context # ===================================================================== - if 'salvar' in self.request.GET: - where = context['object_list'].query.where - _range = where.children[0].rhs - - sufixo = 'sessao_plenaria__data_inicio__range' - param0 = {'%s' % sufixo: _range} - - # Parlamentares com Mandato no intervalo de tempo (Ativos) - parlamentares_qs = parlamentares_ativos( - _range[0], _range[1]).order_by('nome_parlamentar') - parlamentares_id = parlamentares_qs.values_list( - 'id', flat=True) - - # Presenças de cada Parlamentar em Sessões - presenca_sessao = SessaoPlenariaPresenca.objects.filter( - parlamentar_id__in=parlamentares_id, - sessao_plenaria__data_inicio__range=_range).values_list( - 'parlamentar_id').annotate( - sessao_count=Count('id')) - - # Presenças de cada Ordem do Dia - presenca_ordem = PresencaOrdemDia.objects.filter( - parlamentar_id__in=parlamentares_id, - sessao_plenaria__data_inicio__range=_range).values_list( - 'parlamentar_id').annotate( - sessao_count=Count('id')) - - total_ordemdia = PresencaOrdemDia.objects.filter( - **param0).distinct('sessao_plenaria__id').order_by( - 'sessao_plenaria__id').count() - - total_sessao = context['object_list'].count() - - # Completa o dicionario as informacoes parlamentar/sessao/ordem - parlamentares_presencas = [] - for i, p in enumerate(parlamentares_qs): - parlamentares_presencas.append({ - 'parlamentar': p, - 'sessao_porc': 0, - 'ordemdia_porc': 0 - }) - try: - sessao_count = presenca_sessao.get(parlamentar_id=p.id)[1] - except ObjectDoesNotExist: - sessao_count = 0 - try: - ordemdia_count = presenca_ordem.get(parlamentar_id=p.id)[1] - except ObjectDoesNotExist: - ordemdia_count = 0 - - parlamentares_presencas[i].update({ - 'sessao_count': sessao_count, - 'ordemdia_count': ordemdia_count - }) - - if total_sessao != 0: - parlamentares_presencas[i].update( - {'sessao_porc': round( - sessao_count * 100 / total_sessao, 2)}) - if total_ordemdia != 0: - parlamentares_presencas[i].update( - {'ordemdia_porc': round( - ordemdia_count * 100 / total_ordemdia, 2)}) - - context['date_range'] = _range - context['total_ordemdia'] = total_ordemdia - context['total_sessao'] = context['object_list'].count() - context['parlamentares'] = parlamentares_presencas - context['periodo'] = ( - self.request.GET['data_inicio_0'] + - ' - ' + self.request.GET['data_inicio_1']) + # if 'salvar' not in self.request.GET: + where = context['object_list'].query.where + _range = where.children[0].rhs + + sufixo = 'sessao_plenaria__data_inicio__range' + param0 = {'%s' % sufixo: _range} + + # Parlamentares com Mandato no intervalo de tempo (Ativos) + parlamentares_qs = parlamentares_ativos( + _range[0], _range[1]).order_by('nome_parlamentar') + parlamentares_id = parlamentares_qs.values_list( + 'id', flat=True) + + # Presenças de cada Parlamentar em Sessões + presenca_sessao = SessaoPlenariaPresenca.objects.filter( + parlamentar_id__in=parlamentares_id, + sessao_plenaria__data_inicio__range=_range).values_list( + 'parlamentar_id').annotate( + sessao_count=Count('id')) + + # Presenças de cada Ordem do Dia + presenca_ordem = PresencaOrdemDia.objects.filter( + parlamentar_id__in=parlamentares_id, + sessao_plenaria__data_inicio__range=_range).values_list( + 'parlamentar_id').annotate( + sessao_count=Count('id')) + + total_ordemdia = PresencaOrdemDia.objects.filter( + **param0).distinct('sessao_plenaria__id').order_by( + 'sessao_plenaria__id').count() + + total_sessao = context['object_list'].count() + + # Completa o dicionario as informacoes parlamentar/sessao/ordem + parlamentares_presencas = [] + for i, p in enumerate(parlamentares_qs): + parlamentares_presencas.append({ + 'parlamentar': p, + 'sessao_porc': 0, + 'ordemdia_porc': 0 + }) + try: + sessao_count = presenca_sessao.get(parlamentar_id=p.id)[1] + except ObjectDoesNotExist: + sessao_count = 0 + try: + ordemdia_count = presenca_ordem.get(parlamentar_id=p.id)[1] + except ObjectDoesNotExist: + ordemdia_count = 0 + + parlamentares_presencas[i].update({ + 'sessao_count': sessao_count, + 'ordemdia_count': ordemdia_count + }) + + if total_sessao != 0: + parlamentares_presencas[i].update( + {'sessao_porc': round( + sessao_count * 100 / total_sessao, 2)}) + if total_ordemdia != 0: + parlamentares_presencas[i].update( + {'ordemdia_porc': round( + ordemdia_count * 100 / total_ordemdia, 2)}) + + context['date_range'] = _range + context['total_ordemdia'] = total_ordemdia + context['total_sessao'] = context['object_list'].count() + context['parlamentares'] = parlamentares_presencas + context['periodo'] = ( + self.request.GET['data_inicio_0'] + + ' - ' + self.request.GET['data_inicio_1']) # ===================================================================== qr = self.request.GET.copy() context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' From 4657692ec6e147eb57b89a133dcc3ae9ad3005b1 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 21 Nov 2017 18:07:55 -0200 Subject: [PATCH 202/237] Novo release: 3.1.35-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 954a12b0d..190180ae6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.34-BETA + image: interlegis/sapl:3.1.35-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index 745cfdc47..4e35578a1 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.34-BETA', + version='3.1.35-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From 9bf85eac02e20bf4158563bb223dc3f85a0b2229 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Wed, 22 Nov 2017 11:05:30 -0200 Subject: [PATCH 203/237] Fix #1592 ajuste de docs sobre collectstatic --- docs/deploy.rst | 2 +- docs/instalacao31.rst | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/docs/deploy.rst b/docs/deploy.rst index 101b7bb43..7e5e1cc5e 100644 --- a/docs/deploy.rst +++ b/docs/deploy.rst @@ -30,7 +30,7 @@ Com o ambiente em produção, os arquivos estáticos devem ser servidos pelo web para que os arquivos SASS/SCSS sejam compilados em arquivos .css em ambiente de produção, e em seguida rode:: - ./manage.py collectstatic --no-input + ./manage.py collectstatic --no-input --clear para coletar todos os arquivos estáticos do projeto e guarda-los no diretório definido em `STATIC_ROOT`, que será também o diretório no qual o `NGINX` irá referenciar para a aplicação. diff --git a/docs/instalacao31.rst b/docs/instalacao31.rst index a7f9e3060..83bd34d60 100644 --- a/docs/instalacao31.rst +++ b/docs/instalacao31.rst @@ -145,7 +145,7 @@ Criação da `SECRET_KEY Date: Wed, 22 Nov 2017 13:01:48 -0200 Subject: [PATCH 204/237] Novo release: 3.1.36-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 190180ae6..ade7b5ed9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.35-BETA + image: interlegis/sapl:3.1.36-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index 4e35578a1..104b33fc2 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.35-BETA', + version='3.1.36-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From eadc0042774349afd42c5795bb4158d8d1ac5d96 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 22 Nov 2017 13:36:55 -0200 Subject: [PATCH 205/237] Fixes #1603 --- sapl/templates/sessao/mesa.html | 97 +++++++++++++++++---------------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/sapl/templates/sessao/mesa.html b/sapl/templates/sessao/mesa.html index 9e046761d..02f313656 100644 --- a/sapl/templates/sessao/mesa.html +++ b/sapl/templates/sessao/mesa.html @@ -4,12 +4,62 @@ {% block detail_content %} +{% if user.is_authenticated or composicao_mesa %} +
    + {% if perms.sessao.add_integrantemesa %} + Escolha da Composição da Mesa Diretora da Sessão Plenária + {% endif %} +
    +
    + + +
    + + +
    +

    + {% if perms.sessao.add_integrantemesa %} + + {% endif %} +
    +
    + {% if perms.sessao.add_integrantemesa %} + + {% endif %} +
    + {% if user.is_authenticated and cargos_vagos %} +
    + + +
    + +
    + {% endif %} +
    +
    +{% endif %} + + - - -
    - {% if perms.sessao.add_integrantemesa %} - Escolha da Composição da Mesa Diretora da Sessão Plenária - {% endif %} -
    -
    - - -
    - -
    -

    - {% if perms.sessao.add_integrantemesa %} - - {% endif %} -
    -
    - {% if perms.sessao.add_integrantemesa %} - - {% endif %} -
    - -
    - - -
    - -
    - -
    -
    {% endblock detail_content %} From f1518cbd999872536a07a3d1c1fd48893a2d05d0 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Wed, 22 Nov 2017 14:44:58 -0200 Subject: [PATCH 206/237] Fixes #1605 --- sapl/materia/views.py | 6 ++++++ sapl/templates/materia/em_lote/tramitacao.html | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index f3543d412..2b4ef8348 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -1743,6 +1743,12 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): texto=request.POST['texto'] ) t.save() + + if request.POST['turno'] == 'F': + for materia in MateriaLegislativa.objects.filter(id__in=marcadas): + materia.em_tramitacao = False + materia.save() + msg = _('Tramitação completa.') messages.add_message(request, messages.SUCCESS, msg) return self.get(request, self.kwargs) diff --git a/sapl/templates/materia/em_lote/tramitacao.html b/sapl/templates/materia/em_lote/tramitacao.html index c60bcdda6..333050875 100644 --- a/sapl/templates/materia/em_lote/tramitacao.html +++ b/sapl/templates/materia/em_lote/tramitacao.html @@ -138,12 +138,12 @@ if (primeira_tramitacao == false){ $('#id_unidade_tramitacao_local').prop('disabled', true); } - }); - // Reabilita o campo, no momento do Submit, para que seu dado seja enviado - $('input[type=submit]').click(function() { + // Reabilita o campo, no momento do Submit, para que seu dado seja enviado + $('input[type=submit]').click(function() { $('#id_unidade_tramitacao_local').attr('disabled', false); $('#id_unidade_tramitacao_local').parents('form').submit(); - } + }) + }); {% endblock %} From 22de81d16ae9b6f82367e31ee523eda10b9a63d2 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Thu, 23 Nov 2017 15:24:25 -0200 Subject: [PATCH 207/237] Adiciona dump de documentos do SDE --- sapl/legacy/scripts/exporta_zope/.gitignore | 1 + .../scripts/exporta_zope/exporta_zope.py | 54 +++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/sapl/legacy/scripts/exporta_zope/.gitignore b/sapl/legacy/scripts/exporta_zope/.gitignore index 98561c589..11c2f1d6b 100644 --- a/sapl/legacy/scripts/exporta_zope/.gitignore +++ b/sapl/legacy/scripts/exporta_zope/.gitignore @@ -1,2 +1,3 @@ Data*.fs* sapl_documentos +XSLT diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index b09d2e812..e0ae23f7a 100755 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -89,14 +89,20 @@ def dump_file(doc, path): return id -def enumerate_folder(folder): - # folder vazio nao tem _objects - for entry in folder.get('_objects', []): - id, meta_type = entry['id'], entry['meta_type'] - obj = br(folder[id]) +def enumerate_by_key_list(folder, key_list, type_key): + for entry in folder.get(key_list, []): + id, meta_type = entry['id'], entry[type_key] + obj = br(folder.get(id, None)) yield id, obj, meta_type +enumerate_folder = partial(enumerate_by_key_list, + key_list='_objects', type_key='meta_type') + +enumerate_properties = partial(enumerate_by_key_list, + key_list='_properties', type_key='type') + + def enumerate_btree(folder): contagem_esperada = folder['_count'].value tree = folder['_tree'] @@ -125,11 +131,49 @@ def dump_folder(folder, path='', enum=enumerate_folder): return name +def decode_iso8859(obj): + return obj.decode('iso8859-1') if isinstance(obj, str) else obj + + +def read_sde(element): + + def read_properties(): + for id, obj, meta_type in enumerate_properties(element): + assert meta_type == 'string' + if id == 'title': + assert not obj + else: + yield id, decode_iso8859(obj) + + def read_children(): + for id, obj, meta_type in enumerate_folder(element): + assert meta_type == 'SDE-Document-Element' + yield id, read_sde(obj) + + data = dict(read_properties()) + children = list(read_children()) + if children: + assert all(k.startswith('SDE') for k, v in children) + data['children'] = children + return data + + +def dump_sde(strdoc, path): + id = strdoc['id'] + fullname = os.path.join(path, id + '.sde.yaml') + print(fullname) + sde = read_sde(strdoc) + with open(fullname, 'w') as arquivo: + yaml.safe_dump(sde, arquivo) + return id + + DUMP_FUNCTIONS = { 'File': dump_file, 'Image': dump_file, 'Folder': partial(dump_folder, enum=enumerate_folder), 'BTreeFolder2': partial(dump_folder, enum=enumerate_btree), + 'SDE-Document': dump_sde, # explicitamente ignorados 'ZCatalog': None, From 203d7493b4c45bcfa9d2ac9e5e0237c62ae2c310 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Fri, 24 Nov 2017 12:02:21 -0200 Subject: [PATCH 208/237] Adiciona dump de templates do SDE --- .../scripts/exporta_zope/exporta_zope.py | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index e0ae23f7a..8faf30c34 100755 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -139,28 +139,30 @@ def read_sde(element): def read_properties(): for id, obj, meta_type in enumerate_properties(element): - assert meta_type == 'string' - if id == 'title': - assert not obj - else: - yield id, decode_iso8859(obj) + yield id, decode_iso8859(obj) def read_children(): for id, obj, meta_type in enumerate_folder(element): - assert meta_type == 'SDE-Document-Element' - yield id, read_sde(obj) + assert meta_type in ['SDE-Document-Element', + 'SDE-Template-Element', + 'SDE-Template-Link', + 'SDE-Template-Attribute', + 'Script (Python)', + ] + if meta_type != 'Script (Python)': + # ignoramos os scrips python de eventos dos templates + yield id, read_sde(obj) data = dict(read_properties()) children = list(read_children()) if children: - assert all(k.startswith('SDE') for k, v in children) data['children'] = children return data -def dump_sde(strdoc, path): +def dump_sde(strdoc, path, tipo): id = strdoc['id'] - fullname = os.path.join(path, id + '.sde.yaml') + fullname = os.path.join(path, '{}.{}.yaml'.format(id, tipo)) print(fullname) sde = read_sde(strdoc) with open(fullname, 'w') as arquivo: @@ -173,7 +175,8 @@ DUMP_FUNCTIONS = { 'Image': dump_file, 'Folder': partial(dump_folder, enum=enumerate_folder), 'BTreeFolder2': partial(dump_folder, enum=enumerate_btree), - 'SDE-Document': dump_sde, + 'SDE-Document': partial(dump_sde, tipo='sde.document'), + 'SDE-Template': partial(dump_sde, tipo='sde.template'), # explicitamente ignorados 'ZCatalog': None, From a58d61e6ea3b0b53e6e12c01e2d6439487c85566 Mon Sep 17 00:00:00 2001 From: Leandro Roberto da Silva Date: Fri, 24 Nov 2017 13:22:35 -0200 Subject: [PATCH 209/237] Fix #1550 (#1607) --- sapl/base/forms.py | 16 ++++++------ sapl/crispy_layout_mixin.py | 9 ++++--- sapl/materia/forms.py | 50 +++++++++++++++++++++---------------- sapl/norma/forms.py | 2 +- sapl/parlamentares/forms.py | 2 +- sapl/protocoloadm/forms.py | 10 ++++---- sapl/sessao/forms.py | 6 ++--- 7 files changed, 52 insertions(+), 43 deletions(-) diff --git a/sapl/base/forms.py b/sapl/base/forms.py index b2063e6fe..ffd49c735 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -409,7 +409,7 @@ class RelatorioAtasFilterSet(django_filters.FilterSet): self.form.helper.form_method = 'GET' self.form.helper.layout = Layout( Fieldset(_('Atas das Sessões Plenárias'), - row1, form_actions(save_label='Pesquisar')) + row1, form_actions(label='Pesquisar')) ) @@ -439,7 +439,7 @@ class RelatorioPresencaSessaoFilterSet(django_filters.FilterSet): self.form.helper.form_method = 'GET' self.form.helper.layout = Layout( Fieldset(_('Presença dos parlamentares nas sessões plenárias'), - row1, form_actions(save_label='Pesquisar')) + row1, form_actions(label='Pesquisar')) ) @property @@ -483,7 +483,7 @@ class RelatorioHistoricoTramitacaoFilterSet(django_filters.FilterSet): self.form.helper.layout = Layout( Fieldset(_('Histórico de Tramita'), row1, row2, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @@ -514,7 +514,7 @@ class RelatorioMateriasTramitacaoilterSet(django_filters.FilterSet): self.form.helper.layout = Layout( Fieldset(_('Pesquisa de Matéria em Tramitação'), row1, row2, row3, row4, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @@ -540,7 +540,7 @@ class RelatorioMateriasPorAnoAutorTipoFilterSet(django_filters.FilterSet): self.form.helper.layout = Layout( Fieldset(_('Pesquisar'), row1, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @@ -586,7 +586,7 @@ class RelatorioMateriasPorAutorFilterSet(django_filters.FilterSet): HTML(autor_label), HTML(autor_modal), row3, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @@ -692,7 +692,7 @@ class RecuperarSenhaForm(PasswordResetForm): self.helper.layout = Layout( Fieldset(_('Insira o e-mail cadastrado com a sua conta'), row1, - form_actions(save_label='Enviar')) + form_actions(label='Enviar')) ) super(RecuperarSenhaForm, self).__init__(*args, **kwargs) @@ -723,4 +723,4 @@ class NovaSenhaForm(SetPasswordForm): self.helper = FormHelper() self.helper.layout = Layout( row1, - form_actions(save_label='Enviar')) + form_actions(label='Enviar')) diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index 06808e5c3..82092c696 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -1,6 +1,5 @@ from math import ceil -import rtyaml from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit @@ -8,6 +7,7 @@ from django import template from django.core.urlresolvers import reverse from django.utils import formats from django.utils.translation import ugettext as _ +import rtyaml def heads_and_tails(list_of_lists): @@ -34,9 +34,10 @@ def to_fieldsets(fields): yield field -def form_actions(more=[], save_label=_('Salvar')): +def form_actions(more=[], + label=_('Salvar'), name='salvar', css_class='pull-right'): return FormActions( - Submit('salvar', save_label, css_class='pull-right', + Submit(name, label, css_class=css_class, # para impedir resubmissão do form onclick='this.form.submit();this.disabled=true;'), *more) @@ -49,7 +50,7 @@ class SaplFormLayout(Layout): buttons = actions if not buttons: - buttons = form_actions(save_label=save_label, more=[ + buttons = form_actions(label=save_label, more=[ HTML('%s' % cancel_label) if cancel_label else None]) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 0f9d56ee2..2e79a4348 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1,7 +1,6 @@ import os -import django_filters from crispy_forms.bootstrap import Alert, FormActions, InlineRadios from crispy_forms.helper import FormHelper from crispy_forms.layout import (HTML, Button, Column, Div, Field, Fieldset, @@ -22,8 +21,8 @@ from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ +import django_filters -import sapl from sapl.base.models import Autor, TipoAutor from sapl.comissoes.models import Comissao from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC, @@ -42,6 +41,7 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, MateriaPesquisaOrderingFilter, RangeWidgetOverride, autor_label, autor_modal, models_with_gr_for_model, qs_override_django_filter) +import sapl from .models import (AcompanhamentoMateria, Anexada, Autoria, DespachoInicial, DocumentoAcessorio, Numeracao, Proposicao, Relatoria, @@ -73,7 +73,7 @@ class AdicionarVariasAutoriasFilterSet(django_filters.FilterSet): self.form.helper.form_method = 'GET' self.form.helper.layout = Layout( Fieldset(_('Filtrar Autores'), - row1, form_actions(save_label='Filtrar')) + row1, form_actions(label='Filtrar')) ) @@ -86,7 +86,7 @@ class ReceberProposicaoForm(Form): self.helper.layout = Layout( Fieldset( _('Incorporar Proposição'), row1, - form_actions(save_label='Buscar Proposição') + form_actions(label='Buscar Proposição') ) ) super(ReceberProposicaoForm, self).__init__(*args, **kwargs) @@ -113,7 +113,7 @@ class MateriaSimplificadaForm(ModelForm): Fieldset( _('Formulário Simplificado'), row1, row2, row3, row4, row5, - form_actions(save_label='Salvar') + form_actions(label='Salvar') ) ) super(MateriaSimplificadaForm, self).__init__(*args, **kwargs) @@ -151,7 +151,7 @@ class AcompanhamentoMateriaForm(ModelForm): row1 = to_row([('email', 10)]) row1.append( - Column(form_actions(save_label='Cadastrar'), css_class='col-md-2') + Column(form_actions(label='Cadastrar'), css_class='col-md-2') ) self.helper = FormHelper() @@ -602,7 +602,7 @@ class MateriaLegislativaFilterSet(django_filters.FilterSet): HTML(autor_label), HTML(autor_modal), row4, row5, row6, row7, row8, row9, row10, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @property @@ -689,7 +689,7 @@ class AutoriaForm(ModelForm): self.helper = FormHelper() self.helper.layout = Layout( Fieldset(_('Autoria'), - row1, 'data_relativa', form_actions(save_label='Salvar'))) + row1, 'data_relativa', form_actions(label='Salvar'))) if not kwargs['instance']: self.fields['autor'].choices = [] @@ -747,7 +747,7 @@ class AutoriaMultiCreateForm(Form): self.helper.layout = Layout( Fieldset( _('Autorias'), row1, row2, 'data_relativa', 'autores', - form_actions(save_label='Incluir Autores Selecionados'))) + form_actions(label='Incluir Autores Selecionados'))) self.fields['autor'].choices = [] @@ -792,7 +792,7 @@ class AcessorioEmLoteFilterSet(django_filters.FilterSet): self.form.helper.form_method = 'GET' self.form.helper.layout = Layout( Fieldset(_('Documentos Acessórios em Lote'), - row1, row2, form_actions(save_label='Pesquisar'))) + row1, row2, form_actions(label='Pesquisar'))) class PrimeiraTramitacaoEmLoteFilterSet(django_filters.FilterSet): @@ -824,7 +824,7 @@ class PrimeiraTramitacaoEmLoteFilterSet(django_filters.FilterSet): self.form.helper.form_method = 'GET' self.form.helper.layout = Layout( Fieldset(_('Primeira Tramitação'), - row1, row2, form_actions(save_label='Pesquisar'))) + row1, row2, form_actions(label='Pesquisar'))) class TramitacaoEmLoteFilterSet(django_filters.FilterSet): @@ -865,7 +865,7 @@ class TramitacaoEmLoteFilterSet(django_filters.FilterSet): self.form.helper.form_method = 'GET' self.form.helper.layout = Layout( Fieldset(_('Tramitação em Lote'), - row1, row2, form_actions(save_label='Pesquisar'))) + row1, row2, form_actions(label='Pesquisar'))) class TipoProposicaoForm(ModelForm): @@ -1303,8 +1303,12 @@ class ConfirmarProposicaoForm(ProposicaoForm): if self.proposicao_incorporacao_obrigatoria != 'N': itens_incorporacao.append(to_column(('numero_de_paginas', 4))) - itens_incorporacao.append(to_column((FormActions(Submit( - 'incorporar', _('Incorporar'), css_class='pull-right')), 12))) + itens_incorporacao.append( + to_column( + (form_actions(label=_('Incorporar'), + name='incorporar'), 12) + ) + ) fields.append( Fieldset(_('Registro de Incorporação'), *itens_incorporacao)) @@ -1313,10 +1317,14 @@ class ConfirmarProposicaoForm(ProposicaoForm): Fieldset( _('Registro de Devolução'), to_column(('justificativa_devolucao', 12)), - to_column((FormActions(Submit( - 'devolver', _('Devolver'), - css_class='btn-danger pull-right')), 12)) - )) + to_column( + (form_actions(label=_('Devolver'), + name='devolver', + css_class='btn-danger pull-right'), 12) + ) + ) + ) + self.helper = FormHelper() self.helper.layout = Layout(*fields) @@ -1662,7 +1670,7 @@ class EtiquetaPesquisaForm(forms.Form): Fieldset( ('Formulário de Etiqueta'), row1, row2, - form_actions(save_label='Pesquisar') + form_actions(label='Pesquisar') ) ) @@ -1730,7 +1738,7 @@ class FichaPesquisaForm(forms.Form): Fieldset( ('Formulário de Ficha'), row1, - form_actions(save_label='Pesquisar') + form_actions(label='Pesquisar') ) ) @@ -1764,6 +1772,6 @@ class FichaSelecionaForm(forms.Form): Fieldset( ('Selecione a ficha que deseja imprimir'), row1, - form_actions(save_label='Gerar Impresso') + form_actions(label='Gerar Impresso') ) ) diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index 1ea6812fd..fa849171a 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -72,7 +72,7 @@ class NormaFilterSet(django_filters.FilterSet): self.form.helper.layout = Layout( Fieldset(_('Pesquisa de Norma'), row1, row2, row3, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py index efbf6f592..0f004be14 100644 --- a/sapl/parlamentares/forms.py +++ b/sapl/parlamentares/forms.py @@ -298,7 +298,7 @@ class VotanteForm(ModelForm): self.helper = FormHelper() self.helper.layout = Layout( Fieldset(_('Votante'), - row1, form_actions(save_label='Salvar')) + row1, form_actions(label='Salvar')) ) super(VotanteForm, self).__init__(*args, **kwargs) diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index d7d720315..6a0dc1b9a 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -123,7 +123,7 @@ class ProtocoloFilterSet(django_filters.FilterSet): HTML(autor_label), HTML(autor_modal), row4, row5, row6, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @@ -194,7 +194,7 @@ class DocumentoAdministrativoFilterSet(django_filters.FilterSet): Fieldset(_('Pesquisar Documento'), row1, row2, row3, row4, row5, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @@ -276,7 +276,7 @@ class AnularProcoloAdmForm(ModelForm): row1, row2, HTML(" "), - form_actions(save_label='Anular') + form_actions(label='Anular') ) ) super(AnularProcoloAdmForm, self).__init__( @@ -339,7 +339,7 @@ class ProtocoloDocumentForm(ModelForm): row4, row5, HTML(" "), - form_actions(save_label=_('Protocolar Documento')) + form_actions(label=_('Protocolar Documento')) ) ) super(ProtocoloDocumentForm, self).__init__( @@ -407,7 +407,7 @@ class ProtocoloMateriaForm(ModelForm): self.helper.layout = Layout( Fieldset(_('Identificação da Matéria'), row1, row3, - row4, form_actions(save_label='Protocolar Matéria'))) + row4, form_actions(label='Protocolar Matéria'))) super(ProtocoloMateriaForm, self).__init__( *args, **kwargs) diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index 1e7410639..a9c0bc164 100644 --- a/sapl/sessao/forms.py +++ b/sapl/sessao/forms.py @@ -300,7 +300,7 @@ class SessaoPlenariaFilterSet(django_filters.FilterSet): self.form.helper.layout = Layout( Fieldset(self.titulo, row1, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @@ -376,7 +376,7 @@ class AdicionarVariasMateriasFilterSet(MateriaLegislativaFilterSet): HTML(autor_label), HTML(autor_modal), row4, row5, row6, row7, row8, row9, - form_actions(save_label='Pesquisar')) + form_actions(label='Pesquisar')) ) @@ -467,7 +467,7 @@ class ResumoOrdenacaoForm(forms.Form): Fieldset(_(''), row1, row2, row3, row4, row5, row6, row7, row8, row9, row10, - form_actions(save_label='Atualizar')) + form_actions(label='Atualizar')) ) def clean(self): From bba3b3ab9bd68a4395ef58cf16355eca995b0979 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 24 Nov 2017 13:27:10 -0200 Subject: [PATCH 210/237] Novo release: 3.1.37-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index ade7b5ed9..bf361037e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.36-BETA + image: interlegis/sapl:3.1.37-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index 104b33fc2..c6de6b709 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.36-BETA', + version='3.1.37-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From 93cd99ea800e585baac04bd77dad862d652f169e Mon Sep 17 00:00:00 2001 From: Edward Date: Fri, 24 Nov 2017 13:31:00 -0200 Subject: [PATCH 211/237] Fixes #1604 (#1606) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes #1604 * adiciona receivers de matéria na app --- sapl/materia/apps.py | 3 +++ sapl/materia/receivers.py | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/sapl/materia/apps.py b/sapl/materia/apps.py index 3ac053d1b..883109d31 100644 --- a/sapl/materia/apps.py +++ b/sapl/materia/apps.py @@ -6,3 +6,6 @@ class AppConfig(apps.AppConfig): name = 'sapl.materia' label = 'materia' verbose_name = _('Matéria') + + def ready(self): + from . import receivers \ No newline at end of file diff --git a/sapl/materia/receivers.py b/sapl/materia/receivers.py index 31f353fe0..37dc43131 100644 --- a/sapl/materia/receivers.py +++ b/sapl/materia/receivers.py @@ -1,5 +1,7 @@ +from django.db.models.signals import post_delete, post_save from django.dispatch import receiver +from sapl.materia.models import Tramitacao from sapl.materia.signals import tramitacao_signal from sapl.utils import get_base_url @@ -17,3 +19,11 @@ def handle_tramitacao_signal(sender, **kwargs): materia, tramitacao.status, tramitacao.unidade_tramitacao_destino) + + +@receiver(post_delete, sender=Tramitacao) +def status_tramitacao_materia(sender, instance, **kwargs): + if instance.turno == 'F': + materia = instance.materia + materia.em_tramitacao = True + materia.save() From b1e74192ccb16a65a99850d74ffabe901c34aef9 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 27 Nov 2017 13:38:55 -0200 Subject: [PATCH 212/237] HOT-FIX: #1604 --- sapl/materia/receivers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/materia/receivers.py b/sapl/materia/receivers.py index 37dc43131..945c6636e 100644 --- a/sapl/materia/receivers.py +++ b/sapl/materia/receivers.py @@ -23,7 +23,7 @@ def handle_tramitacao_signal(sender, **kwargs): @receiver(post_delete, sender=Tramitacao) def status_tramitacao_materia(sender, instance, **kwargs): - if instance.turno == 'F': + if instance.status.indicador == 'F': materia = instance.materia materia.em_tramitacao = True materia.save() From c0b14461ff79254c98e2c4aba60c59b0d86ac660 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 27 Nov 2017 14:17:59 -0200 Subject: [PATCH 213/237] =?UTF-8?q?HOT-FIX:=20op=C3=A7=C3=B5es=20de=20em?= =?UTF-8?q?=5Ftramitacao=20como=200=20e=201=20e=20n=C3=A3o=20True=20e=20Fa?= =?UTF-8?q?lse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/materia/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/materia/models.py b/sapl/materia/models.py index c374b7474..45e95c919 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -18,8 +18,8 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, SaplGenericForeignKey, SaplGenericRelation, restringe_tipos_de_arquivo_txt, texto_upload_path) -EM_TRAMITACAO = [(1, 'Sim'), - (0, 'Não')] +EM_TRAMITACAO = [(True, 'Sim'), + (False, 'Não')] def grupo_autor(): From b932d1e629381580ee2087ace4f7d41c08d37d8f Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Mon, 27 Nov 2017 15:01:18 -0200 Subject: [PATCH 214/237] =?UTF-8?q?Adiciona=20verbosa=20name=20em=20mat?= =?UTF-8?q?=C3=A9ria=20anexada=20e=20mat=C3=A9ria=20principal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0019_auto_20171127_1500.py | 26 +++++++++++++++++++ sapl/materia/models.py | 6 +++-- 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 sapl/materia/migrations/0019_auto_20171127_1500.py diff --git a/sapl/materia/migrations/0019_auto_20171127_1500.py b/sapl/materia/migrations/0019_auto_20171127_1500.py new file mode 100644 index 000000000..2bd2c02a9 --- /dev/null +++ b/sapl/materia/migrations/0019_auto_20171127_1500.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-11-27 17:00 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0018_auto_20171113_1339'), + ] + + operations = [ + migrations.AlterField( + model_name='anexada', + name='materia_anexada', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materia_anexada_set', to='materia.MateriaLegislativa', verbose_name='Matéria Anexada'), + ), + migrations.AlterField( + model_name='anexada', + name='materia_principal', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materia_principal_set', to='materia.MateriaLegislativa', verbose_name='Matéria Principal'), + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 45e95c919..d3cfebd28 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -330,10 +330,12 @@ class AcompanhamentoMateria(models.Model): class Anexada(models.Model): materia_principal = models.ForeignKey( MateriaLegislativa, related_name='materia_principal_set', - on_delete=models.CASCADE) + on_delete=models.CASCADE, + verbose_name=_('Matéria Principal')) materia_anexada = models.ForeignKey( MateriaLegislativa, related_name='materia_anexada_set', - on_delete=models.CASCADE) + on_delete=models.CASCADE, + verbose_name=_('Matéria Anexada')) data_anexacao = models.DateField(verbose_name=_('Data Anexação')) data_desanexacao = models.DateField( blank=True, null=True, verbose_name=_('Data Desanexação')) From 87b2f9290b4e60dec38e3329de30da9af03fed41 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Mon, 27 Nov 2017 16:52:08 -0200 Subject: [PATCH 215/237] Fix #1608 --- sapl/crispy_layout_mixin.py | 59 ++++++++++++++++++++++++++++- sapl/templates/crud/detail.html | 23 +++++------ sapl/templates/materia/layouts.yaml | 6 ++- 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index 82092c696..1569ed6ba 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -4,7 +4,7 @@ from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit from django import template -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse, reverse_lazy from django.utils import formats from django.utils.translation import ugettext as _ import rtyaml @@ -206,7 +206,16 @@ class CrispyLayoutFormMixin: def get_column(self, fieldname, span): obj = self.get_object() - verbose_name, text = get_field_display(obj, fieldname) + + func = None + if '|' in fieldname: + fieldname, func = tuple(fieldname.split('|')) + + if func: + verbose_name, text = getattr(self, func)(obj, fieldname) + else: + verbose_name, text = get_field_display(obj, fieldname) + return { 'id': fieldname, 'span': span, @@ -214,6 +223,52 @@ class CrispyLayoutFormMixin: 'text': text, } + def fk_urlize_for_detail(self, obj, fieldname): + + field = obj._meta.get_field(fieldname) + value = getattr(obj, fieldname) + + display = '{}'.format( + reverse( + '%s:%s_detail' % ( + value._meta.app_config.name, value._meta.model_name), + args=(value.id,)), + value) + + return field.verbose_name, display + + def m2m_urlize_for_detail(self, obj, fieldname): + + manager, fieldname = tuple(fieldname.split('__')) + + manager = getattr(obj, manager) + + verbose_name = manager.model._meta.verbose_name + display = '' + for item in manager.all(): + obj_m2m = getattr(item, fieldname) + + if obj == obj_m2m: + continue + + verbose_name = item._meta.get_field(fieldname).verbose_name + + display += '
  • {}
  • '.format( + reverse( + '%s:%s_detail' % ( + obj_m2m._meta.app_config.name, obj_m2m._meta.model_name), + args=(obj_m2m.id,)), + obj_m2m) + + display += '' + + if display: + display = '
      %s
    ' % display + else: + verbose_name = '' + + return verbose_name, display + @property def layout_display(self): diff --git a/sapl/templates/crud/detail.html b/sapl/templates/crud/detail.html index 1653a11e4..513c67bbf 100644 --- a/sapl/templates/crud/detail.html +++ b/sapl/templates/crud/detail.html @@ -60,19 +60,20 @@ {% for row in fieldset.rows %}
    {% for column in row %} -
    -
    -

    {{ column.verbose_name }}

    -
    - {% comment %}TODO Transformar os links em URLs diretamente no CRUD{% endcomment %} - {% if column.text|url %} - - {% else %} -
    {{ column.text|safe|default:"" }}
    - {% endif %} + {% if column.verbose_name or column.text %} +
    +
    +

    {{ column.verbose_name }}

    +
    + {% if column.text|url %} + + {% else %} +
    {{ column.text|safe|default:"" }}
    + {% endif %} +
    -
    + {% endif %} {% endfor %}
    {% endfor %} diff --git a/sapl/templates/materia/layouts.yaml b/sapl/templates/materia/layouts.yaml index 4a86fe945..3dc086026 100644 --- a/sapl/templates/materia/layouts.yaml +++ b/sapl/templates/materia/layouts.yaml @@ -53,8 +53,8 @@ Anexada: AnexadaDetail: {% trans 'Matéria Anexada' %}: - - materia_principal - - materia_anexada + - materia_principal|fk_urlize_for_detail + - materia_anexada|fk_urlize_for_detail - data_anexacao data_desanexacao Autoria: @@ -137,6 +137,8 @@ MateriaLegislativaDetail: - data_apresentacao numero_protocolo tipo_apresentacao - texto_original - numeracao_set + - materia_anexada_set__materia_principal|m2m_urlize_for_detail + - materia_principal_set__materia_anexada|m2m_urlize_for_detail {% trans 'Outras Informações' %}: - apelido dias_prazo polemica - objeto regime_tramitacao em_tramitacao From 079ce5ecf2ab8f8926d437c271754fecccb253e5 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Mon, 27 Nov 2017 17:33:51 -0200 Subject: [PATCH 216/237] Corrige erro em update_groups --- sapl/rules/apps.py | 3 ++- sapl/rules/map_rules.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index ad4ec1864..f599db55d 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -186,7 +186,8 @@ def update_groups(app_config, verbosity=2, interactive=True, **param_username)[0] usuario.set_password('interlegis') usuario.save() - grupo.user_set.add(usuario) + g = Group.objects.get_or_create(name=grupo)[0] + g.user_set.add(usuario) def cria_usuarios_padrao(self): for group, user in ( diff --git a/sapl/rules/map_rules.py b/sapl/rules/map_rules.py index 6702a1f27..02c6c0dfa 100644 --- a/sapl/rules/map_rules.py +++ b/sapl/rules/map_rules.py @@ -195,7 +195,7 @@ rules_group_geral = { 'view_tabelas_auxiliares' ]), - (base.CasaLegislativa, __listdetailchange__), + (base.CasaLegislativa, __listdetailchange__ + [RP_ADD]), (base.ProblemaMigracao, []), (base.Argumento, []), (base.Constraint, []), From 18e12cce004117dd1ea55d7ca4a2f88cee2ff38c Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 27 Nov 2017 17:46:02 -0200 Subject: [PATCH 217/237] Novo release: 3.1.38-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index bf361037e..9f1b8a3c9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.37-BETA + image: interlegis/sapl:3.1.38-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index c6de6b709..d0a142296 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.37-BETA', + version='3.1.38-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From 4294c9fc0778d908f6ec17dfa4b5b5157ec10b14 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 27 Nov 2017 19:04:40 -0200 Subject: [PATCH 218/237] HOT-FIX: substituir 0 e 1 por False e True --- sapl/materia/forms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 2e79a4348..a9f081855 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -54,8 +54,8 @@ def ANO_CHOICES(): def em_tramitacao(): return [('', 'Tanto Faz'), - (1, 'Sim'), - (0, 'Não')] + (True, 'Sim'), + (False, 'Não')] class AdicionarVariasAutoriasFilterSet(django_filters.FilterSet): From 3168a2957687d5288150e289e80ab0d4e9893276 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Tue, 28 Nov 2017 08:53:08 -0200 Subject: [PATCH 219/237] Inverte no layout o campo numero por ano --- sapl/templates/norma/layouts.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapl/templates/norma/layouts.yaml b/sapl/templates/norma/layouts.yaml index a613415bc..e1ca61084 100644 --- a/sapl/templates/norma/layouts.yaml +++ b/sapl/templates/norma/layouts.yaml @@ -26,7 +26,7 @@ NormaJuridica: NormaJuridicaCreate: {% trans 'Identificação Básica' %}: - - tipo numero ano + - tipo ano numero - data esfera_federacao complemento - tipo_materia numero_materia ano_materia - data_publicacao veiculo_publicacao pagina_inicio_publicacao pagina_fim_publicacao From b94c91a530614993ace9214e57bfae287ec8bdcb Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 30 Nov 2017 15:53:41 -0200 Subject: [PATCH 220/237] =?UTF-8?q?Avisa=20ao=20usu=C3=A1rio=20quando=20el?= =?UTF-8?q?e=20n=C3=A3o=20digita=20nada=20na=20caixa=20de=20busca=20textua?= =?UTF-8?q?l?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/templates/search/search.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sapl/templates/search/search.html b/sapl/templates/search/search.html index f55688255..19c4cb150 100644 --- a/sapl/templates/search/search.html +++ b/sapl/templates/search/search.html @@ -112,7 +112,10 @@
    {% endif %} {% else %} - {# Show some example queries to run, maybe query syntax, something else? #} + {% if 'q=' in request.get_full_path %} +

    Favor informar um conjunto de caracteres na caixa 'Pesquisar' para realizar a busca

    + {% endif %} {% endif %} + {% endblock %} From 24a38a69c9489402d9e1c9c413b3e47438289b5f Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Fri, 1 Dec 2017 17:47:48 -0200 Subject: [PATCH 221/237] Fixes #1619 --- sapl/templates/materia/materialegislativa_filter.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sapl/templates/materia/materialegislativa_filter.html b/sapl/templates/materia/materialegislativa_filter.html index 391de56c7..96a7eb55a 100644 --- a/sapl/templates/materia/materialegislativa_filter.html +++ b/sapl/templates/materia/materialegislativa_filter.html @@ -117,7 +117,10 @@ {% endfor %} {% endif %} {% if m.documentoacessorio_set.all.exists %} - Documentos Acessórios: {{ m.documentoacessorio_set.all.count }} + Documentos Acessórios: + + {{ m.documentoacessorio_set.all.count }} +
    {% endif %} {% if m.texto_original %}Texto Original
    {% endif %} From bad6638e4cdcdbabbcb0d543a0f51f7017e8b226 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Sat, 2 Dec 2017 15:56:09 -0200 Subject: [PATCH 222/237] =?UTF-8?q?adiciona=20try=20except=20para=20incomp?= =?UTF-8?q?atibilidade=20de=20vers=C3=B5es=20do=20django?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/rules/apps.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index f599db55d..3b6e9d271 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -1,15 +1,15 @@ from builtins import LookupError -import django -import reversion from django.apps import apps from django.contrib.auth import get_user_model from django.contrib.auth.management import _get_all_permissions from django.core import exceptions from django.db import models, router from django.db.utils import DEFAULT_DB_ALIAS -from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat +from django.utils.translation import ugettext_lazy as _ +import django +import reversion from sapl.rules import (SAPL_GROUP_ADMINISTRATIVO, SAPL_GROUP_COMISSOES, SAPL_GROUP_GERAL, SAPL_GROUP_MATERIA, SAPL_GROUP_NORMA, @@ -78,7 +78,19 @@ def create_proxy_permissions( ctype = ContentType.objects.db_manager(using).get_for_model(klass) ctypes.add(ctype) - for perm in _get_all_permissions(klass._meta, ctype): + + # FIXME: Retirar try except quando sapl passar a usar django 1.11 + try: + # Função não existe mais em Django 1.11 + # como sapl ainda não foi para Django 1.11 + # esta excessão foi adicionada para caso o + # Sapl esteja rodando em um projeto 1.11 não ocorra erros + _all_perms_of_klass = _get_all_permissions(klass._meta, ctype) + except: + # Nova função usada em projetos com Django 1.11 e o sapl é uma app + _all_perms_of_klass = _get_all_permissions(klass._meta) + + for perm in _all_perms_of_klass: searched_perms.append((ctype, perm)) # Find all the Permissions that have a content_type for a model we're From 44ad5f0124c7c9ee6ab060088aa37a77b6e91635 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 4 Dec 2017 17:08:24 -0200 Subject: [PATCH 223/237] Fixes #1619 (#1622) --- .../migrations/0003_auto_20171204_1658.py | 19 +++++++++++++ sapl/comissoes/models.py | 1 + .../migrations/0020_auto_20171204_1658.py | 27 +++++++++++++++++++ sapl/materia/models.py | 19 ++++++++++++- 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 sapl/comissoes/migrations/0003_auto_20171204_1658.py create mode 100644 sapl/materia/migrations/0020_auto_20171204_1658.py diff --git a/sapl/comissoes/migrations/0003_auto_20171204_1658.py b/sapl/comissoes/migrations/0003_auto_20171204_1658.py new file mode 100644 index 000000000..340249cfa --- /dev/null +++ b/sapl/comissoes/migrations/0003_auto_20171204_1658.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2017-12-04 18:58 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('comissoes', '0002_auto_20170809_1236'), + ] + + operations = [ + migrations.AlterModelOptions( + name='comissao', + options={'ordering': ['nome'], 'verbose_name': 'Comissão', 'verbose_name_plural': 'Comissões'}, + ), + ] diff --git a/sapl/comissoes/models.py b/sapl/comissoes/models.py index 0b3c664ee..510071d4f 100644 --- a/sapl/comissoes/models.py +++ b/sapl/comissoes/models.py @@ -95,6 +95,7 @@ class Comissao(models.Model): class Meta: verbose_name = _('Comissão') verbose_name_plural = _('Comissões') + ordering = ['nome'] def __str__(self): return self.sigla + ' - ' + self.nome diff --git a/sapl/materia/migrations/0020_auto_20171204_1658.py b/sapl/materia/migrations/0020_auto_20171204_1658.py new file mode 100644 index 000000000..dce162b47 --- /dev/null +++ b/sapl/materia/migrations/0020_auto_20171204_1658.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2017-12-04 18:58 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0019_auto_20171127_1500'), + ] + + operations = [ + migrations.AlterModelOptions( + name='orgao', + options={'ordering': ['nome'], 'verbose_name': 'Órgão', 'verbose_name_plural': 'Órgãos'}, + ), + migrations.AlterModelOptions( + name='tipodocumento', + options={'ordering': ['descricao'], 'verbose_name': 'Tipo de Documento', 'verbose_name_plural': 'Tipos de Documento'}, + ), + migrations.AlterModelOptions( + name='unidadetramitacao', + options={'verbose_name': 'Unidade de Tramitação', 'verbose_name_plural': 'Unidades de Tramitação'}, + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index d3cfebd28..0aade9df3 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -5,6 +5,7 @@ from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.db import models +from django.db.models.functions import Concat from django.utils import formats, timezone from django.utils.translation import ugettext_lazy as _ from model_utils import Choices @@ -402,6 +403,7 @@ class TipoDocumento(models.Model): class Meta: verbose_name = _('Tipo de Documento') verbose_name_plural = _('Tipos de Documento') + ordering = ['descricao'] def __str__(self): return self.descricao @@ -545,6 +547,7 @@ class Orgao(models.Model): class Meta: verbose_name = _('Órgão') verbose_name_plural = _('Órgãos') + ordering = ['nome'] def __str__(self): return _( @@ -790,6 +793,19 @@ class StatusTramitacao(models.Model): 'descricao': self.descricao} +class UnidadeTramitacaoManager(models.Manager): + """ + Esta classe permite ordenar alfabeticamente a unidade de tramitacao + através da concatenação de 3 fields + """ + def get_queryset(self): + return super(UnidadeTramitacaoManager, self).get_queryset().annotate( + nome_composto=Concat('orgao__nome', + 'comissao__sigla', + 'parlamentar__nome_parlamentar') + ).order_by('nome_composto') + + @reversion.register() class UnidadeTramitacao(models.Model): comissao = models.ForeignKey( @@ -802,10 +818,11 @@ class UnidadeTramitacao(models.Model): Parlamentar, blank=True, null=True, on_delete=models.PROTECT, verbose_name=_('Parlamentar')) + objects = UnidadeTramitacaoManager() + class Meta: verbose_name = _('Unidade de Tramitação') verbose_name_plural = _('Unidades de Tramitação') - ordering = ['orgao', 'comissao', 'parlamentar'] def __str__(self): if self.orgao and self.comissao and self.parlamentar: From 8c440b6228b697ffa10e179fef174efaa19539fb Mon Sep 17 00:00:00 2001 From: Leandro Roberto da Silva Date: Tue, 5 Dec 2017 13:02:24 -0200 Subject: [PATCH 224/237] =?UTF-8?q?limita=20edi=C3=A7=C3=A3o=20de=20tipoau?= =?UTF-8?q?tor=20a=20tipos=20externos=20a=20modelagem=20do=20sapl=20(#1623?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/forms.py | 20 +--- .../migrations/0012_auto_20171205_0917.py | 20 ++++ sapl/base/models.py | 5 +- sapl/base/templatetags/base_tags.py | 9 ++ sapl/base/views.py | 24 ++++- sapl/static/styles/app.scss | 7 ++ sapl/templates/base/layouts.yaml | 2 +- sapl/templates/base/tipoautor_form.html | 20 ---- sapl/templates/base/tipoautor_list.html | 34 +++++++ sapl/templates/crud/list.html | 92 +++++++++---------- 10 files changed, 147 insertions(+), 86 deletions(-) create mode 100644 sapl/base/migrations/0012_auto_20171205_0917.py create mode 100644 sapl/base/templatetags/base_tags.py delete mode 100644 sapl/templates/base/tipoautor_form.html create mode 100644 sapl/templates/base/tipoautor_list.html diff --git a/sapl/base/forms.py b/sapl/base/forms.py index ffd49c735..d0bef23cd 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -1,4 +1,3 @@ -import django_filters from crispy_forms.bootstrap import FieldWithButtons, InlineRadios, StrictButton from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Button, Div, Field, Fieldset, Layout, Row @@ -12,8 +11,9 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.db import models, transaction from django.forms import ModelForm -from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat +from django.utils.translation import ugettext_lazy as _ +import django_filters from sapl.base.models import Autor, TipoAutor from sapl.crispy_layout_mixin import (SaplFormLayout, form_actions, to_column, @@ -28,6 +28,7 @@ from sapl.utils import (RANGE_ANOS, ChoiceWithoutValidationField, from .models import AppConfig, CasaLegislativa + ACTION_CREATE_USERS_AUTOR_CHOICE = [ ('A', _('Associar um usuário existente')), ('N', _('Autor sem Usuário de Acesso ao Sapl')), @@ -45,27 +46,14 @@ STATUS_USER_CHOICE = [ class TipoAutorForm(ModelForm): - content_type = forms.ModelChoiceField( - queryset=ContentType.objects.all(), - label=TipoAutor._meta.get_field('content_type').verbose_name, - required=False) - class Meta: model = TipoAutor - fields = ['descricao', - 'content_type'] + fields = ['descricao'] def __init__(self, *args, **kwargs): super(TipoAutorForm, self).__init__(*args, **kwargs) - content_types = ContentType.objects.get_for_models( - *models_with_gr_for_model(Autor)) - - self.fields['content_type'].choices = [ - ('', _('Outros (Especifique)'))] + [ - (ct.pk, ct) for key, ct in content_types.items()] - class AutorForm(ModelForm): senha = forms.CharField( diff --git a/sapl/base/migrations/0012_auto_20171205_0917.py b/sapl/base/migrations/0012_auto_20171205_0917.py new file mode 100644 index 000000000..4080818fa --- /dev/null +++ b/sapl/base/migrations/0012_auto_20171205_0917.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-12-05 11:17 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0011_auto_20171121_0958'), + ] + + operations = [ + migrations.AlterField( + model_name='tipoautor', + name='descricao', + field=models.CharField(help_text='Obs: Não crie tipos de autores semelhante aos tipos fixos. ', max_length=50, verbose_name='Descrição'), + ), + ] diff --git a/sapl/base/models.py b/sapl/base/models.py index 640616fa9..033812735 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -195,7 +195,10 @@ class AppConfig(models.Model): @reversion.register() class TipoAutor(models.Model): - descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) + descricao = models.CharField( + max_length=50, verbose_name=_('Descrição'), + help_text=_('Obs: Não crie tipos de autores ' + 'semelhante aos tipos fixos. ')) content_type = models.OneToOneField( ContentType, diff --git a/sapl/base/templatetags/base_tags.py b/sapl/base/templatetags/base_tags.py new file mode 100644 index 000000000..22f0aa4b1 --- /dev/null +++ b/sapl/base/templatetags/base_tags.py @@ -0,0 +1,9 @@ + +from django import template + +register = template.Library() + + +@register.filter +def tipoautor_contenttype_list(tipo): + return 'sapl.'+tipo.content_type.app_label+':'+tipo.content_type.model+'_list' diff --git a/sapl/base/views.py b/sapl/base/views.py index f0ae926e5..4bb6cb580 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -11,7 +11,7 @@ from django.template import TemplateDoesNotExist from django.template.loader import get_template from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import ugettext_lazy as _, string_concat from django.views.generic.base import TemplateView from django_filters.views import FilterView from haystack.views import SearchView @@ -57,9 +57,29 @@ class TipoAutorCrud(CrudAux): help_topic = 'tipo-autor' class BaseMixin(CrudAux.BaseMixin): - list_field_names = ['descricao', 'content_type'] + list_field_names = ['descricao'] form_class = TipoAutorForm + @property + def verbose_name(self): + vn = super().verbose_name + vn = string_concat(vn, ' ', _('Externo ao SAPL')) + return vn + + class ListView(CrudAux.ListView): + def get_queryset(self): + qs = CrudAux.ListView.get_queryset(self) + qs = qs.filter(content_type__isnull=True) + return qs + + def get_context_data(self, **kwargs): + context = CrudAux.ListView.get_context_data(self, **kwargs) + + context['tipos_sapl'] = TipoAutor.objects.filter( + content_type__isnull=False) + + return context + class AutorCrud(CrudAux): model = Autor diff --git a/sapl/static/styles/app.scss b/sapl/static/styles/app.scss index 74fcd42b4..170310313 100644 --- a/sapl/static/styles/app.scss +++ b/sapl/static/styles/app.scss @@ -123,6 +123,13 @@ h6, .h6 { display: block; } } + +.help-block-danger { + margin: $grid-gutter-width / 2; + padding: $grid-gutter-width / 2; + border: 2px dashed #f00; +} + .controls-radio-checkbox { padding: 0px; border: 1px solid #d6e1e5; diff --git a/sapl/templates/base/layouts.yaml b/sapl/templates/base/layouts.yaml index 0b4b07b27..68da1cd70 100644 --- a/sapl/templates/base/layouts.yaml +++ b/sapl/templates/base/layouts.yaml @@ -28,7 +28,7 @@ AppConfig: TipoAutor: {% trans 'Tipo Autor' %}: - - content_type:4 descricao + - descricao Autor: {% trans 'Autor' %}: diff --git a/sapl/templates/base/tipoautor_form.html b/sapl/templates/base/tipoautor_form.html deleted file mode 100644 index 01f771246..000000000 --- a/sapl/templates/base/tipoautor_form.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "crud/form.html" %} -{% load i18n %} -{% block extra_js %} - - - -{% endblock %} diff --git a/sapl/templates/base/tipoautor_list.html b/sapl/templates/base/tipoautor_list.html new file mode 100644 index 000000000..e7aaf98db --- /dev/null +++ b/sapl/templates/base/tipoautor_list.html @@ -0,0 +1,34 @@ +{% extends "crud/list.html" %} +{% load i18n base_tags %} + + +{% block container_table_list %} +
    +
    +
    + Tipos de Autores do SAPL + {% for tipo in tipos_sapl %} + {{tipo}} + {% endfor %} + + +
    +
    +
    + {{block.super}} +
    + Atenção!!! - Não cadastre tipos de autores semelhantes + aos "Tipos de Autores do SAPL" que estão na tabela ao lado. Esses tipos + são fixos no SAPL pois representam seus cadastros no local apropriado.
    +
    +
    + Novamente, NÃO cadastre "Tipos de Autor" semelhantes aos tipos do SAPL.
    + Veja como exemplo: No Sapl existe o tipo Parlamentar. + Não use tipos semelhantes, como cadastrar um tipo com a descrição "Vereador", + ou mesmo cadastrar outro como "Parlamentar".
    + Se está ali na tabela da lateral esquerda, talvez não exatamente igual, + mas tem o mesmo sentido de sua intenção, não deve ser adicionado. +
    +
    +
    +{% endblock container_table_list %} diff --git a/sapl/templates/crud/list.html b/sapl/templates/crud/list.html index 614389235..9debc332b 100644 --- a/sapl/templates/crud/list.html +++ b/sapl/templates/crud/list.html @@ -22,58 +22,58 @@ {% endblock actions %}
    -{% block extra_content %} {% endblock %} - -{% if not rows %} -

    {{ NO_ENTRIES_MSG }}

    -{% else %} -
    -
    {% blocktrans with verbose_name_plural=view.verbose_name_plural %}Total de {{ verbose_name_plural }}: {{count}}{% endblocktrans %}
    - - - - {% for name in headers %} - +
    + {% endif %} +{% endblock container_table_list %} {% include "paginacao.html" %} From 1104bb1268e4ebba13c4cb40d7030cdd120adfdd Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Tue, 5 Dec 2017 13:12:15 -0200 Subject: [PATCH 225/237] Novo release: 3.1.39-BETA --- docker-compose.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9f1b8a3c9..f7602b1f6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ sapldb: ports: - "5432:5432" sapl: - image: interlegis/sapl:3.1.38-BETA + image: interlegis/sapl:3.1.39-BETA restart: always environment: ADMIN_PASSWORD: interlegis diff --git a/setup.py b/setup.py index d0a142296..c4672ee3c 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ install_requires = [ ] setup( name='interlegis-sapl', - version='3.1.38-BETA', + version='3.1.39-BETA', packages=find_packages(), include_package_data=True, license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007', From adac6e3b7ee6c47668c06ef8c56e09321a45f9f9 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Tue, 5 Dec 2017 13:36:16 -0200 Subject: [PATCH 226/237] =?UTF-8?q?remove=20acesso=20n=C3=A3o=20permitido?= =?UTF-8?q?=20via=20url=20ao=20crud=20tipoautor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 18 +++++++++++++++++- sapl/test_urls.py | 7 ++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index 4bb6cb580..6b666da0d 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -2,7 +2,7 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.contrib.auth.tokens import default_token_generator -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.core.mail import send_mail from django.core.urlresolvers import reverse from django.db.models import Count @@ -80,6 +80,22 @@ class TipoAutorCrud(CrudAux): return context + class TipoAutorMixin: + def dispatch(self, request, *args, **kwargs): + object = self.get_object() + if object.content_type: + raise PermissionDenied() + return super().get(request, *args, **kwargs) + + class UpdateView(TipoAutorMixin, CrudAux.UpdateView): + pass + + class DetailView(TipoAutorMixin, CrudAux.DetailView): + pass + + class DeleteView(TipoAutorMixin, CrudAux.DeleteView): + pass + class AutorCrud(CrudAux): model = Autor diff --git a/sapl/test_urls.py b/sapl/test_urls.py index 590bbc689..bffb59c18 100644 --- a/sapl/test_urls.py +++ b/sapl/test_urls.py @@ -1,12 +1,12 @@ -import pytest from django.apps import apps from django.contrib.auth import get_user_model from django.contrib.auth.management import _get_all_permissions from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.db import transaction -from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat +from django.utils.translation import ugettext_lazy as _ +import pytest from sapl.crud.base import PermissionRequiredForAppCrudMixin from sapl.rules.apps import AppConfig, update_groups @@ -14,6 +14,7 @@ from scripts.lista_urls import lista_urls from .settings import SAPL_APPS + pytestmark = pytest.mark.django_db sapl_appconfs = [apps.get_app_config(n[5:]) for n in SAPL_APPS] @@ -72,6 +73,7 @@ def create_perms_post_migrate(sapl_app_config): ] Permission.objects.bulk_create(perms) + btn_login = ('') @@ -259,7 +261,6 @@ apps_url_patterns_prefixs_and_users = { } -@pytest.mark.skip(reason="TODO: Lento demais. Precisa ser refatorado") @pytest.mark.parametrize('url_item', _lista_urls) def test_urlpatterns(url_item, admin_client): From 47412eb1019c4b348ced6577ce0c82c39e080b79 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Tue, 5 Dec 2017 16:30:16 -0200 Subject: [PATCH 227/237] Adiciona dump de usuarios e consolida dump_sapl --- .../scripts/exporta_zope/exporta_zope.py | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/sapl/legacy/scripts/exporta_zope/exporta_zope.py b/sapl/legacy/scripts/exporta_zope/exporta_zope.py index 8faf30c34..d1dcc4736 100755 --- a/sapl/legacy/scripts/exporta_zope/exporta_zope.py +++ b/sapl/legacy/scripts/exporta_zope/exporta_zope.py @@ -160,13 +160,18 @@ def read_sde(element): return data +def save_as_yaml(path, name, obj): + fullname = os.path.join(path, name) + with open(fullname, 'w') as arquivo: + yaml.safe_dump(obj, arquivo) + print(fullname) + return fullname + + def dump_sde(strdoc, path, tipo): id = strdoc['id'] - fullname = os.path.join(path, '{}.{}.yaml'.format(id, tipo)) - print(fullname) sde = read_sde(strdoc) - with open(fullname, 'w') as arquivo: - yaml.safe_dump(sde, arquivo) + save_as_yaml(path, '{}.{}.yaml'.format(id, tipo), sde) return id @@ -207,25 +212,35 @@ def find_sapl(app): return sapl -def dump_propriedades(docs): +def dump_propriedades(docs, path): props_sapl = br(docs['props_sapl']) ids = [p['id'] for p in props_sapl['_properties']] props = {id: props_sapl[id] for id in ids} props = {id: p.decode('iso-8859-1') if isinstance(p, str) else p for id, p in props.items()} - with open('sapl_documentos/propriedades.yaml', 'w') as f: - f.write(yaml.safe_dump(props)) + save_as_yaml(path, 'sapl_documentos/propriedades.yaml', props) + + +def dump_usuarios(sapl, path): + users = br(br(sapl['acl_users'])['data']) + users = {k: br(v) for k, v in users['data'].items()} + save_as_yaml(path, 'usuarios.yaml', users) -def dump_sapl(data_fs_path): +def dump_sapl(data_fs_path, destino='../../../../media'): app, close_db = get_app(data_fs_path) try: sapl = find_sapl(app) - docs = br(sapl['sapl_documentos']) + # extrai folhas XSLT + dump_folder(br(sapl['XSLT']), destino) + # extrai usuários com suas senhas e perfis + dump_usuarios(sapl, destino) + # extrai documentos + docs = br(sapl['sapl_documentos']) nao_identificados.clear() - dump_folder(docs) - dump_propriedades(docs) + dump_folder(docs, destino) + dump_propriedades(docs, destino) if nao_identificados: print('#' * 80) print('#' * 80) From e097e567f5f17d296aea7539f6ea98798014797b Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Thu, 7 Dec 2017 12:03:34 -0200 Subject: [PATCH 228/237] =?UTF-8?q?reduz=20dist=C3=A2ncias=20verticais=20d?= =?UTF-8?q?os=20elementos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/static/styles/app.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sapl/static/styles/app.scss b/sapl/static/styles/app.scss index 170310313..8d50f217d 100644 --- a/sapl/static/styles/app.scss +++ b/sapl/static/styles/app.scss @@ -219,6 +219,18 @@ body { } } +label { + margin-bottom: 0; + line-height: 1; +} +.control-label { + margin: 0; +} +.form-control-static { + padding-top: 0; + min-height: auto; +} + // #### pagination ######################################## .pagination { padding-top: 25px; From bf6e60d23bdf463e5034d03fa1bea7a0dce72795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Fr=C3=A1?= Date: Thu, 7 Dec 2017 12:55:20 -0200 Subject: [PATCH 229/237] cria impresso de indice de normas (#1625) * cria impresso de indice de normas * ajustes * ajustes * Ordena Resultado * Ordena Resultado --- sapl/materia/urls.py | 5 ++ sapl/norma/forms.py | 58 +++++++++++++++++++ sapl/norma/views.py | 57 +++++++++++++++++- .../materia/impressos/impressos.html | 10 +++- .../materia/impressos/normas_pdf.html | 41 +++++++++++++ 5 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 sapl/templates/materia/impressos/normas_pdf.html diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index b6a87cd5f..44051342f 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -25,6 +25,8 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, TramitacaoEmLoteView, UnidadeTramitacaoCrud, proposicao_texto, recuperar_materia) +from sapl.norma.views import NormaPesquisaView + from .apps import AppConfig app_name = AppConfig.name @@ -42,6 +44,9 @@ urlpatterns_impressos = [ url(r'^materia/impressos/ficha-seleciona/$', FichaSelecionaView.as_view(), name='impressos_ficha_seleciona'), + url(r'^materia/impressos/norma-pesquisa/$', + NormaPesquisaView.as_view(), + name='impressos_norma_pesquisa'), ] urlpatterns_materia = [ diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index fa849171a..c21650513 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -208,3 +208,61 @@ class NormaRelacionadaForm(ModelForm): relacionada.norma_relacionada = self.cleaned_data['norma_relacionada'] relacionada.save() return relacionada + +class NormaPesquisaForm(forms.Form): + tipo_norma = forms.ModelChoiceField( + label=TipoNormaJuridica._meta.verbose_name, + queryset=TipoNormaJuridica.objects.all(), + required=False, + empty_label='Selecione') + + data_inicial = forms.DateField( + label='Data Inicial', + required=False, + widget=forms.DateInput(format='%d/%m/%Y') + ) + + data_final = forms.DateField( + label='Data Final', + required=False, + widget=forms.DateInput(format='%d/%m/%Y') + ) + + def __init__(self, *args, **kwargs): + super(NormaPesquisaForm, self).__init__(*args, **kwargs) + + row1 = to_row( + [('tipo_norma', 6), + ('data_inicial', 3), + ('data_final', 3)]) + + self.helper = FormHelper() + self.helper.layout = Layout( + Fieldset( + ('Índice de Normas'), + row1, + form_actions(label='Pesquisar') + ) + ) + + def clean(self): + super(NormaPesquisaForm, self).clean() + cleaned_data = self.cleaned_data + + data_inicial = cleaned_data['data_inicial'] + data_final = cleaned_data['data_final'] + + if (data_inicial and data_final and + data_inicial > data_final): + raise ValidationError(_( + 'A Data Final não pode ser menor que a Data Inicial')) + else: + condicao1 = data_inicial and not data_final + condicao2 = not data_inicial and data_final + if condicao1 or condicao2: + raise ValidationError(_('Caso pesquise por data, os campos de Data Inicial e ' + + 'Data Final devem ser preenchidos obrigatoriamente')) + + + return cleaned_data + diff --git a/sapl/norma/views.py b/sapl/norma/views.py index f7ee34baf..8cf8469d2 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -6,6 +6,13 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import RedirectView from django_filters.views import FilterView +from django.contrib.auth.mixins import PermissionRequiredMixin + +from django.http import HttpResponse, JsonResponse +from django.views.generic.edit import FormView +from django.views.generic import CreateView, ListView, TemplateView, UpdateView +from django.template import RequestContext, loader +import weasyprint from sapl.base.models import AppConfig from sapl.compilacao.views import IntegracaoTaView @@ -13,7 +20,7 @@ from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, MasterDetailCrud, make_pagination) from sapl.utils import show_results_filter_set -from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm +from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm, NormaPesquisaForm from .models import (AssuntoNorma, NormaJuridica, NormaRelacionada, TipoNormaJuridica, TipoVinculoNormaJuridica) @@ -216,3 +223,51 @@ def recuperar_numero_norma(request): {'numero': 1, 'ano': ano}) return response + + +class ImpressosView(PermissionRequiredMixin, TemplateView): + template_name = 'materia/impressos/impressos.html' + permission_required = ('materia.can_access_impressos', ) + + +def gerar_pdf_impressos(request, context, template_name): + template = loader.get_template(template_name) + html = template.render(RequestContext(request, context)) + response = HttpResponse(content_type="application/pdf") + weasyprint.HTML( + string=html, + base_url=request.build_absolute_uri()).write_pdf( + response) + + return response + +class NormaPesquisaView(PermissionRequiredMixin, FormView): + form_class = NormaPesquisaForm + template_name = 'materia/impressos/norma.html' + permission_required = ('materia.can_access_impressos', ) + + + def form_valid(self, form): + context = {} + + normas = NormaJuridica.objects.all().order_by( + '-numero') + template_norma = 'materia/impressos/normas_pdf.html' + + if form.cleaned_data['tipo_norma']: + normas = normas.filter(tipo=form.cleaned_data['tipo_norma']) + + if form.cleaned_data['data_inicial']: + normas = normas.filter( + data__gte=form.cleaned_data['data_inicial'], + data__lte=form.cleaned_data['data_final']) + + + context['quantidade'] = len(normas) + + if context['quantidade'] > 2000: + normas = normas[:2000] + + context['normas'] = normas + + return gerar_pdf_impressos(self.request, context, template_norma) diff --git a/sapl/templates/materia/impressos/impressos.html b/sapl/templates/materia/impressos/impressos.html index beb92862c..71f9f6f6f 100644 --- a/sapl/templates/materia/impressos/impressos.html +++ b/sapl/templates/materia/impressos/impressos.html @@ -10,15 +10,23 @@

    Impressos

    +

    Etiqueta

    -

    Ficha

    +
    +

    Capa Processo

    +
    +

    Índice de Normas Jurídicas

    + + {#

    Guia de Remessa

    #} {#
      #} diff --git a/sapl/templates/materia/impressos/normas_pdf.html b/sapl/templates/materia/impressos/normas_pdf.html new file mode 100644 index 000000000..1732b682b --- /dev/null +++ b/sapl/templates/materia/impressos/normas_pdf.html @@ -0,0 +1,41 @@ + + + + + Impressos + + + + + + + +{% if quantidade > 30 %} +

      Sua pesquisa retornou mais do que 2000 impressos.

      Por questões de performance, foram retornados apenas os 2000 primeiros.

      +


      +{% endif %} + + +{% for m in normas %} + + + + + + +
      {{m.tipo}} nº {{m.numero}}, de {{m.data|date:"d/m/Y" }} + + {{m.ementa}} +
      +
      + +{% endfor %} + + + + From ae26147c0d9d5a18ce3d6de11f4070ca60a27127 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Thu, 7 Dec 2017 12:57:57 -0200 Subject: [PATCH 230/237] Adiciona o orador ao painel (#1631) --- sapl/painel/views.py | 17 ++++++++++++-- sapl/templates/painel/index.html | 39 ++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 93feedd4e..a1faee91c 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -16,7 +16,8 @@ from sapl.base.models import CasaLegislativa from sapl.crud.base import Crud from sapl.painel.apps import AppConfig from sapl.parlamentares.models import Legislatura, Parlamentar, Votante -from sapl.sessao.models import (ExpedienteMateria, OrdemDia, PresencaOrdemDia, +from sapl.sessao.models import (ExpedienteMateria, OrdemDia, OradorExpediente, + PresencaOrdemDia, RegistroVotacao, SessaoPlenaria, SessaoPlenariaPresenca, VotoParlamentar) from sapl.utils import filiacao_data, get_client_ip, sort_lista_chave @@ -294,6 +295,17 @@ def get_presentes(pk, response, materia): sessao = SessaoPlenaria.objects.get(id=pk) num_presentes = len(presentes) data_sessao = sessao.data_inicio + oradores = OradorExpediente.objects.filter( + sessao_plenaria_id=pk).order_by('numero_ordem') + + oradores_list = [] + for o in oradores: + + oradores_list.append( + { + 'nome': o.parlamentar.nome_parlamentar, + 'numero': o.numero_ordem + }) presentes_list = [] for p in presentes: @@ -334,7 +346,8 @@ def get_presentes(pk, response, materia): 'tipo_resultado': materia.resultado, 'observacao_materia': materia.observacao, 'tipo_votacao': tipo_votacao, - 'materia_legislativa_texto': str(materia.materia) + 'materia_legislativa_texto': str(materia.materia), + 'oradores': oradores_list }) presentes_list = sort_lista_chave(presentes_list, 'nome') diff --git a/sapl/templates/painel/index.html b/sapl/templates/painel/index.html index 6be08b115..77751f92e 100644 --- a/sapl/templates/painel/index.html +++ b/sapl/templates/painel/index.html @@ -23,7 +23,7 @@ ul, li { list-style-type: none; } - #sessao_plenaria, #sessao_plenaria_data, #sessao_plenaria_hora_inicio, #message, #cronometro_discurso, #cronometro_aparte, #cronometro_ordem, #relogio, #parlamentares, #votacao, #materia_legislativa_texto, #observacao_materia, #resultado_votacao{ + #sessao_plenaria, #sessao_plenaria_data, #sessao_plenaria_hora_inicio, #message, #cronometro_discurso, #cronometro_aparte, #cronometro_ordem, #relogio, #parlamentares, #votacao, #materia_legislativa_texto, #observacao_materia, #resultado_votacao, #orador { font-family: Verdana; } } @@ -70,7 +70,18 @@
    -
    +
    +
    +
    +

    Oradores

    + + + + +

    +
    + +

    Cronômetros

    @@ -183,16 +194,20 @@ var presentes = $("#parlamentares"); var votacao = $("#votacao"); + var oradores = $("#orador") $("#votacao").text(''); presentes.children().remove(); votacao.children().remove(); + oradores.children().remove(); + var oradores_list = data["oradores"]; var presentes_list = data["presentes"]; if (data["status_painel"] == true) { presentes.append('
    '); jQuery.each(presentes_list, function (index, parlamentar) { + if (parlamentar.voto == 'Voto Informado'){ $('#parlamentares_list').append('') - } + } + + }); + presentes.append('
    ' + parlamentar.nome + @@ -206,16 +221,30 @@ ' ' + parlamentar.partido + ' ' + show_voto(parlamentar.voto) + '
    ') + oradores.append(''); + jQuery.each(oradores_list, function (index, orador) { + $('#oradores_list').append('') }); - presentes.append('
    ' + + orador.numero + 'º  ' + + orador.nome +'
    '); + oradores.append(''); + } else{ presentes.append(''); $('#parlamentares_list').append( '
    A listagem de parlamentares só aparecerá quando o painel estiver aberto.
    ') presentes.append('
    '); + + oradores.append(''); + $('#oradores_list').append( + '
    A listagem de oradores só aparecerá quando o painel estiver aberto.
    ') + oradores.append('
    '); } if (data['materia_legislativa_texto']){ @@ -288,7 +317,7 @@ $("#resultado_votacao").css("color", "green"); } if (resultado_votacao_upper.search("REJEIT") != -1){ - $("#resultado_votacao").css("color", "red"); + $("#resultado_votacao").css("color", "red"); } } else{ From 4a8d00917cd867ddd45d97137fde90f40cdc0750 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Thu, 7 Dec 2017 14:02:07 -0200 Subject: [PATCH 231/237] Revert "cria impresso de indice de normas (#1625)" This reverts commit bf6e60d23bdf463e5034d03fa1bea7a0dce72795. --- sapl/materia/urls.py | 5 -- sapl/norma/forms.py | 58 ------------------- sapl/norma/views.py | 57 +----------------- .../materia/impressos/impressos.html | 10 +--- .../materia/impressos/normas_pdf.html | 41 ------------- 5 files changed, 2 insertions(+), 169 deletions(-) delete mode 100644 sapl/templates/materia/impressos/normas_pdf.html diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index 44051342f..b6a87cd5f 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -25,8 +25,6 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, TramitacaoEmLoteView, UnidadeTramitacaoCrud, proposicao_texto, recuperar_materia) -from sapl.norma.views import NormaPesquisaView - from .apps import AppConfig app_name = AppConfig.name @@ -44,9 +42,6 @@ urlpatterns_impressos = [ url(r'^materia/impressos/ficha-seleciona/$', FichaSelecionaView.as_view(), name='impressos_ficha_seleciona'), - url(r'^materia/impressos/norma-pesquisa/$', - NormaPesquisaView.as_view(), - name='impressos_norma_pesquisa'), ] urlpatterns_materia = [ diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index c21650513..fa849171a 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -208,61 +208,3 @@ class NormaRelacionadaForm(ModelForm): relacionada.norma_relacionada = self.cleaned_data['norma_relacionada'] relacionada.save() return relacionada - -class NormaPesquisaForm(forms.Form): - tipo_norma = forms.ModelChoiceField( - label=TipoNormaJuridica._meta.verbose_name, - queryset=TipoNormaJuridica.objects.all(), - required=False, - empty_label='Selecione') - - data_inicial = forms.DateField( - label='Data Inicial', - required=False, - widget=forms.DateInput(format='%d/%m/%Y') - ) - - data_final = forms.DateField( - label='Data Final', - required=False, - widget=forms.DateInput(format='%d/%m/%Y') - ) - - def __init__(self, *args, **kwargs): - super(NormaPesquisaForm, self).__init__(*args, **kwargs) - - row1 = to_row( - [('tipo_norma', 6), - ('data_inicial', 3), - ('data_final', 3)]) - - self.helper = FormHelper() - self.helper.layout = Layout( - Fieldset( - ('Índice de Normas'), - row1, - form_actions(label='Pesquisar') - ) - ) - - def clean(self): - super(NormaPesquisaForm, self).clean() - cleaned_data = self.cleaned_data - - data_inicial = cleaned_data['data_inicial'] - data_final = cleaned_data['data_final'] - - if (data_inicial and data_final and - data_inicial > data_final): - raise ValidationError(_( - 'A Data Final não pode ser menor que a Data Inicial')) - else: - condicao1 = data_inicial and not data_final - condicao2 = not data_inicial and data_final - if condicao1 or condicao2: - raise ValidationError(_('Caso pesquise por data, os campos de Data Inicial e ' + - 'Data Final devem ser preenchidos obrigatoriamente')) - - - return cleaned_data - diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 8cf8469d2..f7ee34baf 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -6,13 +6,6 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import RedirectView from django_filters.views import FilterView -from django.contrib.auth.mixins import PermissionRequiredMixin - -from django.http import HttpResponse, JsonResponse -from django.views.generic.edit import FormView -from django.views.generic import CreateView, ListView, TemplateView, UpdateView -from django.template import RequestContext, loader -import weasyprint from sapl.base.models import AppConfig from sapl.compilacao.views import IntegracaoTaView @@ -20,7 +13,7 @@ from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, MasterDetailCrud, make_pagination) from sapl.utils import show_results_filter_set -from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm, NormaPesquisaForm +from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm from .models import (AssuntoNorma, NormaJuridica, NormaRelacionada, TipoNormaJuridica, TipoVinculoNormaJuridica) @@ -223,51 +216,3 @@ def recuperar_numero_norma(request): {'numero': 1, 'ano': ano}) return response - - -class ImpressosView(PermissionRequiredMixin, TemplateView): - template_name = 'materia/impressos/impressos.html' - permission_required = ('materia.can_access_impressos', ) - - -def gerar_pdf_impressos(request, context, template_name): - template = loader.get_template(template_name) - html = template.render(RequestContext(request, context)) - response = HttpResponse(content_type="application/pdf") - weasyprint.HTML( - string=html, - base_url=request.build_absolute_uri()).write_pdf( - response) - - return response - -class NormaPesquisaView(PermissionRequiredMixin, FormView): - form_class = NormaPesquisaForm - template_name = 'materia/impressos/norma.html' - permission_required = ('materia.can_access_impressos', ) - - - def form_valid(self, form): - context = {} - - normas = NormaJuridica.objects.all().order_by( - '-numero') - template_norma = 'materia/impressos/normas_pdf.html' - - if form.cleaned_data['tipo_norma']: - normas = normas.filter(tipo=form.cleaned_data['tipo_norma']) - - if form.cleaned_data['data_inicial']: - normas = normas.filter( - data__gte=form.cleaned_data['data_inicial'], - data__lte=form.cleaned_data['data_final']) - - - context['quantidade'] = len(normas) - - if context['quantidade'] > 2000: - normas = normas[:2000] - - context['normas'] = normas - - return gerar_pdf_impressos(self.request, context, template_norma) diff --git a/sapl/templates/materia/impressos/impressos.html b/sapl/templates/materia/impressos/impressos.html index 71f9f6f6f..beb92862c 100644 --- a/sapl/templates/materia/impressos/impressos.html +++ b/sapl/templates/materia/impressos/impressos.html @@ -10,23 +10,15 @@

    Impressos

    -

    Etiqueta

    -
    -

    Capa Processo

    +

    Ficha

    -
    -

    Índice de Normas Jurídicas

    - - {#

    Guia de Remessa

    #} {#
      #} diff --git a/sapl/templates/materia/impressos/normas_pdf.html b/sapl/templates/materia/impressos/normas_pdf.html deleted file mode 100644 index 1732b682b..000000000 --- a/sapl/templates/materia/impressos/normas_pdf.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - Impressos - - - - - - - -{% if quantidade > 30 %} -

      Sua pesquisa retornou mais do que 2000 impressos.

      Por questões de performance, foram retornados apenas os 2000 primeiros.

      -


      -{% endif %} - - -{% for m in normas %} - - - - - - -
      {{m.tipo}} nº {{m.numero}}, de {{m.data|date:"d/m/Y" }} - - {{m.ementa}} -
      -
      - -{% endfor %} - - - - From 2332706ffc3bb3cebf4644a6ce98e374514037ff Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Fri, 8 Dec 2017 13:04:29 -0200 Subject: [PATCH 232/237] =?UTF-8?q?HOT-FIX=20problema=20com=20permiss?= =?UTF-8?q?=C3=A3o=20em=20legisla=C3=A7=C3=A3o=20citada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foi apresentado na lista GITEC um problema com permissão na aba Legislação Citada de matérias legislativas. O código removido neste commit se tornou irrelevante depois que o mapa de regras foi criado (app rule) --- sapl/materia/views.py | 50 ------------------------------------------- sapl/rules/apps.py | 2 +- 2 files changed, 1 insertion(+), 51 deletions(-) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 2b4ef8348..299532733 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -959,7 +959,6 @@ class TramitacaoCrud(MasterDetailCrud): ultima_tramitacao.unidade_tramitacao_destino)] return context - def form_valid(self, form): self.object = form.save() @@ -1197,55 +1196,6 @@ class LegislacaoCitadaCrud(MasterDetailCrud): return reverse('%s:%s' % (namespace, self.url_name(suffix)), args=args) - def has_permission(self): - perms = self.get_permission_required() - # Torna a view pública se não possuir conteudo - # no atributo permission_required - return self.request.user.has_module_perms('materia')\ - if len(perms) else True - - def permission(self, rad): - return '%s%s%s' % ('norma' if rad.endswith('_') else '', - rad, - self.model_name if rad.endswith('_') else '') - - @property - def detail_create_url(self): - obj = self.crud if hasattr(self, 'crud') else self - if self.request.user.has_module_perms('materia'): - parent_field = obj.parent_field.split('__')[0] - parent_object = getattr(self.object, parent_field) - - root_pk = parent_object.pk - - return self.resolve_url(ACTION_CREATE, args=(root_pk,)) - return '' - - @property - def list_url(self): - return self.resolve_url(ACTION_LIST, args=(self.kwargs['pk'],))\ - if self.request.user.has_module_perms('materia') else '' - - @property - def create_url(self): - return self.resolve_url(ACTION_CREATE, args=(self.kwargs['pk'],))\ - if self.request.user.has_module_perms('materia') else '' - - @property - def detail_url(self): - return self.resolve_url(ACTION_DETAIL, args=(self.object.id,))\ - if self.request.user.has_module_perms('materia') else '' - - @property - def update_url(self): - return self.resolve_url(ACTION_UPDATE, args=(self.kwargs['pk'],))\ - if self.request.user.has_module_perms('materia') else '' - - @property - def delete_url(self): - return self.resolve_url(ACTION_DELETE, args=(self.object.id,))\ - if self.request.user.has_module_perms('materia') else '' - class CreateView(MasterDetailCrud.CreateView): form_class = LegislacaoCitadaForm diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index 3b6e9d271..b16f45905 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -127,7 +127,7 @@ def create_proxy_permissions( def update_groups(app_config, verbosity=2, interactive=True, - using=DEFAULT_DB_ALIAS, cria_usuarios_padrao=False, + using=DEFAULT_DB_ALIAS, cria_usuarios_padrao=True, **kwargs): if app_config != AppConfig and not isinstance(app_config, AppConfig): From 3a59eeb92359a036da33902e0d18a0006c4d7acf Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Fri, 8 Dec 2017 13:54:22 -0200 Subject: [PATCH 233/237] =?UTF-8?q?ajusta=20cria=C3=A7=C3=A3o=20de=20confi?= =?UTF-8?q?g=20da=20app=20e=20retorna=20valor=20de=20post=5Fmigrate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/models.py | 3 ++- sapl/materia/tests/test_materia.py | 2 +- sapl/rules/apps.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sapl/base/models.py b/sapl/base/models.py index 033812735..15e14e39c 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -184,7 +184,8 @@ class AppConfig(models.Model): config = AppConfig.objects.first() if not config: - return '' + config = AppConfig() + config.save() return getattr(config, attr) diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py index c7a773a9c..a538cfb87 100644 --- a/sapl/materia/tests/test_materia.py +++ b/sapl/materia/tests/test_materia.py @@ -1,9 +1,9 @@ -import pytest from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType from django.core.files.uploadedfile import SimpleUploadedFile from django.core.urlresolvers import reverse from model_mommy import mommy +import pytest from sapl.base.models import Autor, TipoAutor from sapl.comissoes.models import Comissao, TipoComissao diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index b16f45905..3b6e9d271 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -127,7 +127,7 @@ def create_proxy_permissions( def update_groups(app_config, verbosity=2, interactive=True, - using=DEFAULT_DB_ALIAS, cria_usuarios_padrao=True, + using=DEFAULT_DB_ALIAS, cria_usuarios_padrao=False, **kwargs): if app_config != AppConfig and not isinstance(app_config, AppConfig): From 9bee9ed6ff71a9fee152ebe5c53a0fc1c284e61e Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 11 Dec 2017 14:17:47 -0200 Subject: [PATCH 234/237] WIP - minor refactorings. (#1630) --- sapl/comissoes/views.py | 3 --- sapl/materia/views.py | 48 ++++++++++++++++--------------------- sapl/parlamentares/views.py | 16 ++++++------- sapl/protocoloadm/views.py | 18 ++++---------- sapl/sessao/views.py | 27 +++++++++------------ sapl/utils.py | 9 +++++++ 6 files changed, 53 insertions(+), 68 deletions(-) diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py index aa16b6a15..0c315f0d9 100644 --- a/sapl/comissoes/views.py +++ b/sapl/comissoes/views.py @@ -55,9 +55,6 @@ class ComposicaoCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) -# context['composicao_pk'] = context['composicao_list'].last( -# ).pk if self.take_composicao_pk( -# ) == 0 else self.take_composicao_pk() composicao_pk = self.take_composicao_pk() diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 299532733..f123a57c3 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -2,6 +2,7 @@ from datetime import datetime from random import choice from string import ascii_letters, digits +import weasyprint from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML from django.contrib import messages @@ -19,8 +20,8 @@ from django.views.generic import CreateView, ListView, TemplateView, UpdateView from django.views.generic.base import RedirectView from django.views.generic.edit import FormView from django_filters.views import FilterView -import weasyprint +import sapl from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Comissao, Participacao from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT, @@ -40,9 +41,7 @@ from sapl.norma.models import LegislacaoCitada from sapl.protocoloadm.models import Protocolo from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label, autor_modal, gerar_hash_arquivo, get_base_url, - montar_row_autor, show_results_filter_set) -import sapl - + montar_row_autor, show_results_filter_set, get_mime_type_from_file_extension) from .email_utils import do_envia_email_confirmacao from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, AdicionarVariasAutoriasFilterSet, DespachoInicialForm, @@ -62,7 +61,6 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, TipoProposicao, Tramitacao, UnidadeTramitacao) from .signals import tramitacao_signal - AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia') OrigemCrud = Crud.build(Origem, '') @@ -81,9 +79,9 @@ TipoFimRelatoriaCrud = CrudAux.build( def autores_ja_adicionados(materia_pk): - autorias = Autoria.objects.filter(materia_id=materia_pk) - pks = [a.autor.pk for a in autorias] - return pks + autorias = Autoria.objects.filter(materia_id=materia_pk).values_list( + 'autor_id', flat=True) + return autorias def proposicao_texto(request, pk): @@ -96,12 +94,7 @@ def proposicao_texto(request, pk): arquivo = proposicao.texto_original - ext = arquivo.name.split('.')[-1] - mime = '' - if ext == 'odt': - mime = 'application/vnd.oasis.opendocument.text' - else: - mime = "application/%s" % (ext,) + mime = get_mime_type_from_file_extension(arquivo.name) with open(arquivo.path, 'rb') as f: data = f.read() @@ -176,14 +169,14 @@ class CriarProtocoloMateriaView(CreateView): except ObjectDoesNotExist: raise Http404() - materias_ano = MateriaLegislativa.objects.filter( - ano=protocolo.ano, - tipo=protocolo.tipo_materia).order_by('-numero') - - if materias_ano: - numero = materias_ano.first().numero + 1 - else: - numero = 1 + numero = 1 + try: + materias_ano = MateriaLegislativa.objects.filter( + ano=protocolo.ano, + tipo=protocolo.tipo_materia).latest('numero') + numero = materias_ano.numero + 1 + except ObjectDoesNotExist: + pass # numero ficou com o valor padrão 1 acima context['form'].fields['tipo'].initial = protocolo.tipo_materia context['form'].fields['numero'].initial = numero @@ -489,7 +482,8 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): def get_object(self, queryset=None): try: - """Não deve haver acesso na rotina de confirmação a proposições: + """ + Não deve haver acesso na rotina de confirmação a proposições: já recebidas -> data_recebimento != None não enviadas -> data_envio == None """ @@ -901,11 +895,9 @@ class RelatoriaCrud(MasterDetailCrud): participacao = Participacao.objects.filter( composicao=composicao) - parlamentares = [] - for p in participacao: - if p.titular: - parlamentares.append( - [p.parlamentar.id, p.parlamentar.nome_parlamentar]) + parlamentares = [[p.parlamentar.id, p.parlamentar.nome_parlamentar] for + p in participacao if p.titular] + context['form'].fields['parlamentar'].choices = parlamentares return context diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index e7b37f358..9a289cc20 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -223,20 +223,20 @@ class ColigacaoCrud(CrudAux): def json_date_convert(date): - ''' + """ :param date: recebe a data de uma chamada ajax no formato de string "dd/mm/yyyy" :return: - ''' + """ return datetime.strptime(date, "%d/%m/%Y").date() def frente_atualiza_lista_parlamentares(request): - ''' + """ :param request: recebe os parâmetros do GET da chamada Ajax :return: retorna a lista atualizada dos parlamentares - ''' + """ ativos = json.loads(request.GET['ativos']) parlamentares = Parlamentar.objects.all() @@ -258,9 +258,9 @@ def frente_atualiza_lista_parlamentares(request): def parlamentares_frente_selected(request): - ''' + """ :return: Lista com o id dos parlamentares em uma frente - ''' + """ try: frente = Frente.objects.get(id=int(request.GET['frente_id'])) except ObjectDoesNotExist: @@ -445,12 +445,12 @@ class ParlamentarCrud(Crud): return 'ParlamentarCreate' def form_valid(self, form): - ''' + """ Reimplementa form_valid devido ao save de ParlamentarCreateForm ser específico, sendo necessário isolar padrão do crud que aciona form.save(commit=False) para registrar dados de auditoria se o model implementá-los, bem como de container se também implement. - ''' + """ return super(Crud.CreateView, self).form_valid(form) class ListView(Crud.ListView): diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 9a924c45e..eb2a18852 100644 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -22,8 +22,7 @@ from sapl.crud.base import Crud, CrudAux, MasterDetailCrud, make_pagination from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.parlamentares.models import Legislatura, Parlamentar from sapl.protocoloadm.models import Protocolo -from sapl.utils import create_barcode, get_client_ip, show_results_filter_set - +from sapl.utils import create_barcode, get_client_ip, show_results_filter_set, get_mime_type_from_file_extension from .forms import (AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoFilterSet, DocumentoAdministrativoForm, ProtocoloDocumentForm, @@ -55,12 +54,7 @@ def doc_texto_integral(request, pk): if documento.texto_integral: arquivo = documento.texto_integral - ext = arquivo.name.split('.')[-1] - mime = '' - if ext == 'odt': - mime = 'application/vnd.oasis.opendocument.text' - else: - mime = "application/%s" % (ext,) + mime = get_mime_type_from_file_extension(arquivo.name) with open(arquivo.path, 'rb') as f: data = f.read() @@ -163,9 +157,7 @@ class ProtocoloPesquisaView(PermissionRequiredMixin, FilterView): kwargs = {'data': self.request.GET or None} - qs = self.get_queryset().order_by('ano', 'numero') - - qs = qs.distinct() + qs = self.get_queryset().order_by('ano', 'numero').distinct() if 'o' in self.request.GET and not self.request.GET['o']: qs = qs.order_by('-ano', '-numero') @@ -197,7 +189,7 @@ class ProtocoloPesquisaView(PermissionRequiredMixin, FilterView): # Provavelmente você criou um novo campo no Form/FilterSet # Então a ordem da URL está diferente data = self.filterset.data - if (data and data.get('numero') is not None): + if data and data.get('numero') is not None: url = "&" + str(self.request.environ['QUERY_STRING']) if url.startswith("&page"): ponto_comeco = url.find('numero=') - 1 @@ -552,7 +544,7 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, # Provavelmente você criou um novo campo no Form/FilterSet # Então a ordem da URL está diferente data = self.filterset.data - if (data and data.get('tipo') is not None): + if data and data.get('tipo') is not None: url = "&" + str(self.request.environ['QUERY_STRING']) if url.startswith("&page"): ponto_comeco = url.find('tipo=') - 1 diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 18c379ff2..887ade0fc 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -577,14 +577,14 @@ def recuperar_numero_sessao(request): tipo__pk=request.GET['tipo'], sessao_legislativa=request.GET['sessao_legislativa']).last() except ObjectDoesNotExist: - response = JsonResponse({'numero': 1}) + numero = 1 else: if sessao: - response = JsonResponse({'numero': sessao.numero + 1}) + numero = sessao.numero + 1 else: - response = JsonResponse({'numero': 1}) + numero = 1 - return response + return JsonResponse({'numero': numero}) def sessao_legislativa_legislatura_ajax(request): @@ -1764,21 +1764,16 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): if self.ordem: ordem_id = kwargs['oid'] try: - ordem = OrdemDia.objects.get(id=ordem_id) + materia_votacao = OrdemDia.objects.get(id=ordem_id) except ObjectDoesNotExist: raise Http404() - - materia_votacao = ordem - elif self.expediente: expediente_id = kwargs['oid'] try: - expediente = ExpedienteMateria.objects.get(id=expediente_id) + materia_votacao = ExpedienteMateria.objects.get(id=expediente_id) except ObjectDoesNotExist: raise Http404() - materia_votacao = expediente - if 'cancelar-votacao' in request.POST: fechar_votacao_materia(materia_votacao) @@ -2157,9 +2152,9 @@ class VotacaoNominalExpedienteDetailView(DetailView): class VotacaoExpedienteView(SessaoPermissionMixin): - ''' + """ Votação Simbólica e Secreta - ''' + """ template_name = 'sessao/votacao/votacao.html' form_class = VotacaoForm @@ -2278,9 +2273,9 @@ class VotacaoExpedienteView(SessaoPermissionMixin): class VotacaoExpedienteEditView(SessaoPermissionMixin): - ''' + """ Votação Simbólica e Secreta - ''' + """ template_name = 'sessao/votacao/votacao_edit.html' form_class = VotacaoEditForm @@ -2554,7 +2549,7 @@ class PesquisarSessaoPlenariaView(FilterView): # Provavelmente você criou um novo campo no Form/FilterSet # Então a ordem da URL está diferente data = self.filterset.data - if (data and data.get('data_inicio__year') is not None): + if data and data.get('data_inicio__year') is not None: url = "&" + str(self.request.environ['QUERY_STRING']) if url.startswith("&page"): ponto_comeco = url.find('data_inicio__year=') - 1 diff --git a/sapl/utils.py b/sapl/utils.py index 37565148d..6e690eb5e 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -665,3 +665,12 @@ def sort_lista_chave(lista, chave): """ lista_ordenada = sorted(lista, key=itemgetter(chave)) return lista_ordenada + + +def get_mime_type_from_file_extension(filename): + ext = filename.split('.')[-1] + if ext == 'odt': + mime = 'application/vnd.oasis.opendocument.text' + else: + mime = "application/%s" % (ext,) + return mime \ No newline at end of file From d263bc657ad7151be7164b001076a83aefcc843f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Fr=C3=A1?= Date: Mon, 11 Dec 2017 14:25:45 -0200 Subject: [PATCH 235/237] Impresso indice normas (#1633) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * cria impresso de indice de normas * ajustes * ajustes * Ordena Resultado * Ordena Resultado * arquivo faltando * altera nome classe de pesquisa * Update views.py Substitui criação explícita de dict por um literal. --- sapl/materia/urls.py | 5 ++ sapl/norma/forms.py | 58 +++++++++++++++++++ sapl/norma/views.py | 54 ++++++++++++++++- .../materia/impressos/impressos.html | 10 +++- sapl/templates/materia/impressos/norma.html | 7 +++ .../materia/impressos/normas_pdf.html | 41 +++++++++++++ 6 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 sapl/templates/materia/impressos/norma.html create mode 100644 sapl/templates/materia/impressos/normas_pdf.html diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index b6a87cd5f..611bdf080 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -25,6 +25,8 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, TramitacaoEmLoteView, UnidadeTramitacaoCrud, proposicao_texto, recuperar_materia) +from sapl.norma.views import NormaPesquisaSimplesView + from .apps import AppConfig app_name = AppConfig.name @@ -42,6 +44,9 @@ urlpatterns_impressos = [ url(r'^materia/impressos/ficha-seleciona/$', FichaSelecionaView.as_view(), name='impressos_ficha_seleciona'), + url(r'^materia/impressos/norma-pesquisa/$', + NormaPesquisaSimplesView.as_view(), + name='impressos_norma_pesquisa'), ] urlpatterns_materia = [ diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index fa849171a..e72b41f26 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -208,3 +208,61 @@ class NormaRelacionadaForm(ModelForm): relacionada.norma_relacionada = self.cleaned_data['norma_relacionada'] relacionada.save() return relacionada + +class NormaPesquisaSimplesForm(forms.Form): + tipo_norma = forms.ModelChoiceField( + label=TipoNormaJuridica._meta.verbose_name, + queryset=TipoNormaJuridica.objects.all(), + required=False, + empty_label='Selecione') + + data_inicial = forms.DateField( + label='Data Inicial', + required=False, + widget=forms.DateInput(format='%d/%m/%Y') + ) + + data_final = forms.DateField( + label='Data Final', + required=False, + widget=forms.DateInput(format='%d/%m/%Y') + ) + + def __init__(self, *args, **kwargs): + super(NormaPesquisaSimplesForm, self).__init__(*args, **kwargs) + + row1 = to_row( + [('tipo_norma', 6), + ('data_inicial', 3), + ('data_final', 3)]) + + self.helper = FormHelper() + self.helper.layout = Layout( + Fieldset( + ('Índice de Normas'), + row1, + form_actions(label='Pesquisar') + ) + ) + + def clean(self): + super(NormaPesquisaSimplesForm, self).clean() + cleaned_data = self.cleaned_data + + data_inicial = cleaned_data['data_inicial'] + data_final = cleaned_data['data_final'] + + if (data_inicial and data_final and + data_inicial > data_final): + raise ValidationError(_( + 'A Data Final não pode ser menor que a Data Inicial')) + else: + condicao1 = data_inicial and not data_final + condicao2 = not data_inicial and data_final + if condicao1 or condicao2: + raise ValidationError(_('Caso pesquise por data, os campos de Data Inicial e ' + + 'Data Final devem ser preenchidos obrigatoriamente')) + + + return cleaned_data + diff --git a/sapl/norma/views.py b/sapl/norma/views.py index f7ee34baf..7ff408983 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -6,6 +6,13 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from django.views.generic.base import RedirectView from django_filters.views import FilterView +from django.contrib.auth.mixins import PermissionRequiredMixin + +from django.http import HttpResponse, JsonResponse +from django.views.generic.edit import FormView +from django.views.generic import CreateView, ListView, TemplateView, UpdateView +from django.template import RequestContext, loader +import weasyprint from sapl.base.models import AppConfig from sapl.compilacao.views import IntegracaoTaView @@ -13,7 +20,7 @@ from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, MasterDetailCrud, make_pagination) from sapl.utils import show_results_filter_set -from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm +from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm, NormaPesquisaSimplesForm from .models import (AssuntoNorma, NormaJuridica, NormaRelacionada, TipoNormaJuridica, TipoVinculoNormaJuridica) @@ -216,3 +223,48 @@ def recuperar_numero_norma(request): {'numero': 1, 'ano': ano}) return response + + +class ImpressosView(PermissionRequiredMixin, TemplateView): + template_name = 'materia/impressos/impressos.html' + permission_required = ('materia.can_access_impressos', ) + + +def gerar_pdf_impressos(request, context, template_name): + template = loader.get_template(template_name) + html = template.render(RequestContext(request, context)) + response = HttpResponse(content_type="application/pdf") + weasyprint.HTML( + string=html, + base_url=request.build_absolute_uri()).write_pdf( + response) + + return response + +class NormaPesquisaSimplesView(PermissionRequiredMixin, FormView): + form_class = NormaPesquisaSimplesForm + template_name = 'materia/impressos/norma.html' + permission_required = ('materia.can_access_impressos', ) + + + def form_valid(self, form): + normas = NormaJuridica.objects.all().order_by( + '-numero') + template_norma = 'materia/impressos/normas_pdf.html' + + if form.cleaned_data['tipo_norma']: + normas = normas.filter(tipo=form.cleaned_data['tipo_norma']) + + if form.cleaned_data['data_inicial']: + normas = normas.filter( + data__gte=form.cleaned_data['data_inicial'], + data__lte=form.cleaned_data['data_final']) + + qtd_resultados = len(normas) + if qtd_resultados > 2000: + normas = normas[:2000] + + context = {'quantidade': qtd_resultados, + 'normas': normas} + + return gerar_pdf_impressos(self.request, context, template_norma) diff --git a/sapl/templates/materia/impressos/impressos.html b/sapl/templates/materia/impressos/impressos.html index beb92862c..71f9f6f6f 100644 --- a/sapl/templates/materia/impressos/impressos.html +++ b/sapl/templates/materia/impressos/impressos.html @@ -10,15 +10,23 @@

      Impressos

      +

      Etiqueta

      -

      Ficha

      +
      +

      Capa Processo

      +
      +

      Índice de Normas Jurídicas

      + + {#

      Guia de Remessa

      #} {#
        #} diff --git a/sapl/templates/materia/impressos/norma.html b/sapl/templates/materia/impressos/norma.html new file mode 100644 index 000000000..03d1c8580 --- /dev/null +++ b/sapl/templates/materia/impressos/norma.html @@ -0,0 +1,7 @@ +{% extends "crud/form.html" %} +{% load i18n crispy_forms_tags %} + +{% block base_content %} +

        Impressos

        + {% crispy form %} +{% endblock base_content %} diff --git a/sapl/templates/materia/impressos/normas_pdf.html b/sapl/templates/materia/impressos/normas_pdf.html new file mode 100644 index 000000000..1732b682b --- /dev/null +++ b/sapl/templates/materia/impressos/normas_pdf.html @@ -0,0 +1,41 @@ + + + + + Impressos + + + + + + + +{% if quantidade > 30 %} +

        Sua pesquisa retornou mais do que 2000 impressos.

        Por questões de performance, foram retornados apenas os 2000 primeiros.

        +


        +{% endif %} + + +{% for m in normas %} + + + + + + +
        {{m.tipo}} nº {{m.numero}}, de {{m.data|date:"d/m/Y" }} + + {{m.ementa}} +
        +
        + +{% endfor %} + + + + From fff13710af9874c804ad72a23733b1639d211422 Mon Sep 17 00:00:00 2001 From: Edward Ribeiro Date: Mon, 11 Dec 2017 14:49:43 -0200 Subject: [PATCH 236/237] Fixes #1628 --- sapl/crispy_layout_mixin.py | 10 ++++++++-- sapl/materia/forms.py | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index 1569ed6ba..0b8541a58 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -35,11 +35,17 @@ def to_fieldsets(fields): def form_actions(more=[], - label=_('Salvar'), name='salvar', css_class='pull-right'): + label=_('Salvar'), name='salvar', css_class='pull-right', disabled=True): + + if disabled: + doubleclick = 'this.form.submit();this.disabled=true;' + else: + doubleclick = 'return true;' + return FormActions( Submit(name, label, css_class=css_class, # para impedir resubmissão do form - onclick='this.form.submit();this.disabled=true;'), + onclick=doubleclick), *more) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index a9f081855..3f5ad4869 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1306,7 +1306,8 @@ class ConfirmarProposicaoForm(ProposicaoForm): itens_incorporacao.append( to_column( (form_actions(label=_('Incorporar'), - name='incorporar'), 12) + name='incorporar', + disabled=False), 12) ) ) @@ -1320,6 +1321,7 @@ class ConfirmarProposicaoForm(ProposicaoForm): to_column( (form_actions(label=_('Devolver'), name='devolver', + disabled=False, css_class='btn-danger pull-right'), 12) ) ) From 53b9b932e296973121e960d49eacfda137031383 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Mon, 11 Dec 2017 17:18:00 -0200 Subject: [PATCH 237/237] =?UTF-8?q?separa=20o=20form=20de=20incorp=20e=20d?= =?UTF-8?q?evol=20de=20proposi=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/materia/forms.py | 170 ++++++++++-------- sapl/materia/views.py | 30 +++- .../materia/confirmar_proposicao.html | 9 +- 3 files changed, 127 insertions(+), 82 deletions(-) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 3f5ad4869..bb4b64706 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1183,6 +1183,84 @@ class ProposicaoForm(forms.ModelForm): return inst +class DevolverProposicaoForm(ProposicaoForm): + + justificativa_devolucao = forms.CharField( + required=False, widget=widgets.Textarea(attrs={'rows': 5})) + + class Meta: + model = Proposicao + fields = [ + 'justificativa_devolucao', + ] + + def __init__(self, *args, **kwargs): + + # esta chamada isola o __init__ de ProposicaoForm + super(ProposicaoForm, self).__init__(*args, **kwargs) + fields = [] + + fields.append( + Fieldset( + _('Registro de Devolução'), + to_column(('justificativa_devolucao', 12)), + to_column( + (form_actions(label=_('Devolver'), + name='devolver', + css_class='btn-danger pull-right'), 12) + ) + ) + ) + + self.helper = FormHelper() + self.helper.layout = Layout(*fields) + + def clean(self): + super(DevolverProposicaoForm, self).clean() + + numeracao = sapl.base.models.AppConfig.attr('sequencia_numeracao') + + if not numeracao: + raise ValidationError("A sequência de numeração (por ano ou geral)" + " não foi configurada para a aplicação em " + "tabelas auxiliares") + + cd = ProposicaoForm.clean(self) + + cd = self.cleaned_data + + if 'justificativa_devolucao' not in cd or\ + not cd['justificativa_devolucao']: + # TODO Implementar notificação ao autor por email + raise ValidationError( + _('Adicione uma Justificativa para devolução.')) + return cd + + @transaction.atomic + def save(self, commit=False): + # TODO Implementar workflow entre protocolo e autores + cd = self.cleaned_data + + self.instance.data_devolucao = timezone.now() + self.instance.data_recebimento = None + self.instance.data_envio = None + self.instance.save() + + if self.instance.texto_articulado.exists(): + ta = self.instance.texto_articulado.first() + ta.privacidade = STATUS_TA_PRIVATE + ta.editing_locked = False + ta.save() + + self.instance.results = { + 'messages': { + 'success': [_('Devolução efetuada com sucesso.'), ] + }, + 'url': reverse('sapl.materia:receber-proposicao') + } + return self.instance + + class ConfirmarProposicaoForm(ProposicaoForm): tipo_readonly = forms.CharField( @@ -1195,9 +1273,6 @@ class ConfirmarProposicaoForm(ProposicaoForm): required=False, widget=widgets.TextInput( attrs={'readonly': 'readonly'})) - justificativa_devolucao = forms.CharField( - required=False, widget=widgets.Textarea(attrs={'rows': 5})) - regime_tramitacao = forms.ModelChoiceField( required=False, queryset=RegimeTramitacao.objects.all()) @@ -1216,7 +1291,6 @@ class ConfirmarProposicaoForm(ProposicaoForm): fields = [ 'data_envio', 'descricao', - 'justificativa_devolucao', 'gerar_protocolo', 'numero_de_paginas' ] @@ -1306,27 +1380,13 @@ class ConfirmarProposicaoForm(ProposicaoForm): itens_incorporacao.append( to_column( (form_actions(label=_('Incorporar'), - name='incorporar', - disabled=False), 12) + name='incorporar'), 12) ) ) fields.append( Fieldset(_('Registro de Incorporação'), *itens_incorporacao)) - fields.append( - Fieldset( - _('Registro de Devolução'), - to_column(('justificativa_devolucao', 12)), - to_column( - (form_actions(label=_('Devolver'), - name='devolver', - disabled=False, - css_class='btn-danger pull-right'), 12) - ) - ) - ) - self.helper = FormHelper() self.helper.layout = Layout(*fields) @@ -1356,34 +1416,23 @@ class ConfirmarProposicaoForm(ProposicaoForm): raise ValidationError("A sequência de numeração (por ano ou geral)" " não foi configurada para a aplicação em " "tabelas auxiliares") - if 'incorporar' in self.data: - cd = ProposicaoForm.clean(self) - - if self.instance.tipo.content_type.model_class() ==\ - TipoMateriaLegislativa: - if 'regime_tramitacao' not in cd or\ - not cd['regime_tramitacao']: - raise ValidationError( - _('Regime de Tramitação deve ser informado.')) - elif self.instance.tipo.content_type.model_class( - ) == TipoDocumento and not cd['materia_de_vinculo']: + cd = ProposicaoForm.clean(self) + if self.instance.tipo.content_type.model_class() ==\ + TipoMateriaLegislativa: + if 'regime_tramitacao' not in cd or\ + not cd['regime_tramitacao']: raise ValidationError( - _('Documentos não podem ser incorporados sem definir ' - 'para qual Matéria Legislativa ele se destina.')) + _('Regime de Tramitação deve ser informado.')) - elif 'devolver' in self.data: - cd = self.cleaned_data + elif self.instance.tipo.content_type.model_class( + ) == TipoDocumento and not cd['materia_de_vinculo']: - if 'justificativa_devolucao' not in cd or\ - not cd['justificativa_devolucao']: - # TODO Implementar notificação ao autor por email - raise ValidationError( - _('Adicione uma Justificativa para devolução.')) - else: raise ValidationError( - _('Dados de Confirmação invalidos.')) + _('Documentos não podem ser incorporados sem definir ' + 'para qual Matéria Legislativa ele se destina.')) + return cd @transaction.atomic @@ -1391,37 +1440,16 @@ class ConfirmarProposicaoForm(ProposicaoForm): # TODO Implementar workflow entre protocolo e autores cd = self.cleaned_data - if 'devolver' in self.data: - self.instance.data_devolucao = timezone.now() - self.instance.data_recebimento = None - self.instance.data_envio = None - self.instance.save() - - if self.instance.texto_articulado.exists(): - ta = self.instance.texto_articulado.first() - ta.privacidade = STATUS_TA_PRIVATE - ta.editing_locked = False - ta.save() - - self.instance.results = { - 'messages': { - 'success': [_('Devolução efetuada com sucesso.'), ] - }, - 'url': reverse('sapl.materia:receber-proposicao') - } - return self.instance + self.instance.justificativa_devolucao = '' + self.instance.data_devolucao = None + self.instance.data_recebimento = timezone.now() + self.instance.materia_de_vinculo = cd['materia_de_vinculo'] - elif 'incorporar' in self.data: - self.instance.justificativa_devolucao = '' - self.instance.data_devolucao = None - self.instance.data_recebimento = timezone.now() - self.instance.materia_de_vinculo = cd['materia_de_vinculo'] - - if self.instance.texto_articulado.exists(): - ta = self.instance.texto_articulado.first() - ta.privacidade = STATUS_TA_IMMUTABLE_PUBLIC - ta.editing_locked = True - ta.save() + if self.instance.texto_articulado.exists(): + ta = self.instance.texto_articulado.first() + ta.privacidade = STATUS_TA_IMMUTABLE_PUBLIC + ta.editing_locked = True + ta.save() self.instance.save() diff --git a/sapl/materia/views.py b/sapl/materia/views.py index f123a57c3..df26a31ca 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -2,7 +2,6 @@ from datetime import datetime from random import choice from string import ascii_letters, digits -import weasyprint from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML from django.contrib import messages @@ -20,8 +19,8 @@ from django.views.generic import CreateView, ListView, TemplateView, UpdateView from django.views.generic.base import RedirectView from django.views.generic.edit import FormView from django_filters.views import FilterView +import weasyprint -import sapl from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Comissao, Participacao from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT, @@ -36,12 +35,15 @@ from sapl.materia.forms import (AnexadaForm, AutoriaForm, AutoriaMultiCreateForm, ConfirmarProposicaoForm, LegislacaoCitadaForm, ProposicaoForm, TipoProposicaoForm, - TramitacaoForm, TramitacaoUpdateForm) + TramitacaoForm, TramitacaoUpdateForm, + DevolverProposicaoForm) from sapl.norma.models import LegislacaoCitada from sapl.protocoloadm.models import Protocolo from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label, autor_modal, gerar_hash_arquivo, get_base_url, montar_row_autor, show_results_filter_set, get_mime_type_from_file_extension) +import sapl + from .email_utils import do_envia_email_confirmacao from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, AdicionarVariasAutoriasFilterSet, DespachoInicialForm, @@ -61,6 +63,7 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, TipoProposicao, Tramitacao, UnidadeTramitacao) from .signals import tramitacao_signal + AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia') OrigemCrud = Crud.build(Origem, '') @@ -469,7 +472,7 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): app_label = sapl.protocoloadm.apps.AppConfig.label template_name = "materia/confirmar_proposicao.html" model = Proposicao - form_class = ConfirmarProposicaoForm + form_class = ConfirmarProposicaoForm, DevolverProposicaoForm def get_success_url(self): msgs = self.object.results['messages'] @@ -491,11 +494,9 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): data_envio__isnull=False, data_recebimento__isnull=True) self.object = None - # FIXME implementar hash para texto eletrônico if proposicao.texto_articulado.exists(): ta = proposicao.texto_articulado.first() - # FIXME hash para textos articulados hasher = 'P' + ta.hash() + '/' + str(proposicao.id) else: hasher = gerar_hash_arquivo( @@ -517,6 +518,21 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): context['subnav_template_name'] = '' return context + def get_form(self, form_class=None): + if form_class is None: + form_class = self.get_form_class() + + if self.request.POST: + if 'justificativa_devolucao' in self.request.POST: + return form_class[1](**self.get_form_kwargs()) + else: + return form_class[0](**self.get_form_kwargs()) + else: + forms = [] + for form in form_class: + forms.append(form(**self.get_form_kwargs())) + return forms + class UnidadeTramitacaoCrud(CrudAux): model = UnidadeTramitacao @@ -896,7 +912,7 @@ class RelatoriaCrud(MasterDetailCrud): composicao=composicao) parlamentares = [[p.parlamentar.id, p.parlamentar.nome_parlamentar] for - p in participacao if p.titular] + p in participacao if p.titular] context['form'].fields['parlamentar'].choices = parlamentares diff --git a/sapl/templates/materia/confirmar_proposicao.html b/sapl/templates/materia/confirmar_proposicao.html index 0c66c1f0a..f3193aeec 100644 --- a/sapl/templates/materia/confirmar_proposicao.html +++ b/sapl/templates/materia/confirmar_proposicao.html @@ -1,4 +1,4 @@ -{% extends "materia/proposicao_form.html" %} +{% extends "base.html" %} {% load i18n crispy_forms_tags common_tags %} {% block base_content %} @@ -17,8 +17,9 @@
    {% endblock actions%}
    -
    - -{{block.super}} + {% for f in form %} + {% crispy f %} + {% endfor %} + {% endblock %}