diff --git a/docker-compose.yml b/docker-compose.yml index df4e37f2e..7a13998d9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ sapldb: ports: - "5532:5432" sapl: - image: interlegis/sapl:3.1.19-BETA + image: interlegis/sapl:3.1.20-BETA volumes: - sapl_data:/var/interlegis/sapl/data - sapl_media:/var/interlegis/sapl/media diff --git a/sapl/base/tests/test_form.py b/sapl/base/tests/test_form.py new file mode 100644 index 000000000..72e5a69e7 --- /dev/null +++ b/sapl/base/tests/test_form.py @@ -0,0 +1,20 @@ +from django.utils.translation import ugettext_lazy as _ + +from sapl.base.forms import CasaLegislativaForm + + +def test_valida_campos_obrigatorios_casa_legislativa_form(): + form = CasaLegislativaForm(data={}) + + assert not form.is_valid() + + errors = form.errors + + assert errors['nome'] == [_('Este campo é obrigatório.')] + assert errors['sigla'] == [_('Este campo é obrigatório.')] + assert errors['endereco'] == [_('Este campo é obrigatório.')] + assert errors['cep'] == [_('Este campo é obrigatório.')] + assert errors['municipio'] == [_('Este campo é obrigatório.')] + assert errors['uf'] == [_('Este campo é obrigatório.')] + + assert len(errors) == 6 diff --git a/sapl/base/tests/teststub_urls.py b/sapl/base/tests/teststub_urls.py index 33bf55d85..4ad6c6d9e 100644 --- a/sapl/base/tests/teststub_urls.py +++ b/sapl/base/tests/teststub_urls.py @@ -5,5 +5,5 @@ from sapl.urls import urlpatterns as original_patterns urlpatterns = original_patterns + patterns('', url(r'^zzzz$', TemplateView.as_view( - template_name='index.html'), + template_name='index.html'), name='zzzz')) diff --git a/sapl/compilacao/compilacao_data_tables.sql b/sapl/compilacao/compilacao_data_tables.sql index 03d9e93d9..c304b6d1a 100644 --- a/sapl/compilacao/compilacao_data_tables.sql +++ b/sapl/compilacao/compilacao_data_tables.sql @@ -16,17 +16,17 @@ INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (104, 'Disposições Finais', 'disp_finais', '', 'Disposições Finais', 0, '', '
', '', '
', '', '', false, 'N', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (111, 'Anexo', 'anexo', '', 'Anexo ', 0, '', '
', '', '
', '
', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (112, 'Parte', 'parte', '', 'Parte ', 0, '', '
', '', '
', '
', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (113, 'Livro', 'livro', '', 'Livro ', 0, '', '
', '', '
', '
', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (114, 'Título', 'titulo', '', 'Título ', 0, '', '
', '', '
', '
', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (115, 'Capítulo', 'capitulo', '', 'Capítulo ', 0, '', '
', '', '
', '
', '', false, 'I', 'A', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (113, 'Livro', 'livro', '', 'LIVRO ', 0, '', '
', '', '
', '
', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (114, 'Título', 'titulo', '', 'TÍTULO ', 0, '', '
', '', '
', '
', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (115, 'Capítulo', 'capitulo', '', 'CAPÍTULO ', 0, '', '
', '', '
', '
', '', false, 'I', 'A', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (116, 'Seção', 'secao', '', 'Seção ', 0, '', '
', '', '
', '
', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (117, 'SubSeção', 'subsecao', '', 'SubSeção ', 0, '', '
', '', '
', '
', '', false, '1', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (119, 'Artigo', 'artigo', '', 'Art. ', 9, '.', ' – ', '', '', '', '', true, '1', 'A', '1', '1', '1', '1', '-', '-', '-', '-', '-', true, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (117, 'Subseção', 'subsecao', '', 'Subseção ', 0, '', '
', '', '
', '
', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (119, 'Artigo', 'artigo', '', 'Art. ', 9, '.', ' ', '', '', '', '', true, '1', 'A', '1', '1', '1', '1', '-', '-', '-', '-', '-', true, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (120, 'Caput', 'caput', '', '', 0, '', '', '', '', '', '', false, 'N', 'N', 'N', 'N', 'N', 'N', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (121, 'Parágrafo', 'paragrafo indent', '', '§ ;Parágrafo Único ', 9, '', ' – ', '', '', '', '', false, '1', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (121, 'Parágrafo', 'paragrafo indent', '', '§ ;Parágrafo único ', 9, '', ' ', '', '', '', '', false, '1', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (122, 'Inciso', 'inciso indent', '', '', 0, '', ' – ', '', '', '', '', false, 'I', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (123, 'Alinea', 'alinea indent', '', '', 0, ')', ' – ', '', '', '', '', false, 'a', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (124, 'Item', 'item indent', '', '', 0, '', ' – ', '', '', '', '', false, '1', '1', '1', '1', '1', '1', '.', '.', '.', '.', '.', false, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (123, 'Alinea', 'alinea indent', '', '', 0, ')', ' ', '', '', '', '', false, 'a', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (124, 'Item', 'item indent', '', '', 0, '', ' ', '', '', '', '', false, '1', '1', '1', '1', '1', '1', '.', '.', '.', '.', '.', false, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (125, 'Texto Não Estruturado', 'texto_n_estruturado', '', '', 0, '', '', '', '', '', '', true, 'N', 'N', 'N', 'N', 'N', 'N', '-', '-', '-', '-', '-', false, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (126, 'Justificativa', 'justificativa', '', '', 0, '', '', '', '
Justificativa
', '', '', true, 'N', 'N', 'N', 'N', 'N', 'N', '-', '-', '-', '-', '-', false, false); diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index 1426c2908..2d3d80116 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -1,5 +1,6 @@ from datetime import datetime +import reversion from django.contrib import messages from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType @@ -12,7 +13,6 @@ from django.template import defaultfilters 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) diff --git a/sapl/compilacao/tests/test_tipo_texto_articulado_form.py b/sapl/compilacao/tests/test_tipo_texto_articulado_form.py index bb35ef688..e121d771f 100644 --- a/sapl/compilacao/tests/test_tipo_texto_articulado_form.py +++ b/sapl/compilacao/tests/test_tipo_texto_articulado_form.py @@ -1,9 +1,10 @@ -from django.utils.translation import ugettext_lazy as _ -from model_mommy import mommy import pytest +from django.utils.translation import ugettext as _ +from model_mommy import mommy from sapl.compilacao import forms -from sapl.compilacao.models import PerfilEstruturalTextoArticulado +from sapl.compilacao.models import (PerfilEstruturalTextoArticulado, + TipoNota) from sapl.compilacao.views import choice_models_in_extenal_views @@ -39,3 +40,38 @@ def test_tipo_texto_articulado_form_valid(content_type): }) assert form.is_valid(), form.errors + + +def test_valida_campos_obrigatorios_nota_form(): + form = forms.NotaForm(data={}) + + assert not form.is_valid() + + errors = form.errors + + assert errors['texto'] == [_('Este campo é obrigatório')] + assert errors['publicidade'] == [_('Este campo é obrigatório.')] + assert errors['tipo'] == [_('Este campo é obrigatório.')] + assert errors['publicacao'] == [_('Este campo é obrigatório')] + assert errors['efetividade'] == [_('Este campo é obrigatório')] + assert errors['dispositivo'] == [_('Este campo é obrigatório.')] + + assert len(errors) == 6 + + +@pytest.mark.django_db(transaction=False) +def test_nota_form_invalido(): + tipo = mommy.make(TipoNota) + + form = forms.NotaForm(data={'titulo': 'titulo', + 'texto': 'teste', + 'url_externa': 'www.test.com', + 'publicidade': 'publicidade', + 'tipo': str(tipo.pk), + 'publicacao': '10/05/2017', + 'efetividade': '10/05/2017', + 'dispositivo': 'dispositivo', + 'pk': 'pk' + }) + + assert not form.is_valid() diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index ba533072a..4dfad8e99 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -1,7 +1,7 @@ -from collections import OrderedDict -from datetime import timedelta import logging import sys +from collections import OrderedDict +from datetime import timedelta 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 string_concat from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import string_concat from django.views.generic.base import TemplateView from django.views.generic.detail import DetailView from django.views.generic.edit import (CreateView, DeleteView, FormView, @@ -50,7 +50,6 @@ 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') diff --git a/sapl/materia/fixtures/pre_popula_status_tramitacao.json b/sapl/materia/fixtures/pre_popula_status_tramitacao.json new file mode 100644 index 000000000..c6073ea54 --- /dev/null +++ b/sapl/materia/fixtures/pre_popula_status_tramitacao.json @@ -0,0 +1,361 @@ +[{ + "model": "materia.StatusTramitacao", + "pk": 1, + "fields": { + "sigla": "ADIAVOTAC", + "indicador": "R", + "descricao": "Adiada discussão e votação." + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 2, + "fields": { + "sigla": "AGAUTOGR", + "indicador": "R", + "descricao": "Aguardando assinatura do autógrafo" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 3, + "fields": { + "sigla": "AGMENSVET", + "indicador": "R", + "descricao": "Aguardando assinatura da mensagem sobre o veto" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 4, + "fields": { + "sigla": "AGORDIA", + "indicador": "R", + "descricao": "Aguardando a inclusão na ordem do dia" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 5, + "fields": { + "sigla": "AGPARECER", + "indicador": "R", + "descricao": "Aguardando emissão de parecer da comissão" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 6, + "fields": { + "sigla": "AGPROMLEI", + "indicador": "F", + "descricao": "Aguardando promulgação da lei" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 7, + "fields": { + "sigla": "AGPROMNOR", + "indicador": "F", + "descricao": "Aguardando promulgação da norma jurídica" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 8, + "fields": { + "sigla": "AGPROMVET", + "indicador": "R", + "descricao": "Aguardando promulgação de lei com veto rejeitado" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 9, + "fields": { + "sigla": "AGSANCAO", + "indicador": "F", + "descricao": "Aguardando sanção governamental" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 10, + "fields": { + "sigla": "ANEXADA", + "indicador": "R", + "descricao": "Proposição anexada à outra análoga ou conexa mais antiga" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 11, + "fields": { + "sigla": "APRESENT", + "indicador": "R", + "descricao": "Proposição apresentada em Plenário" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 12, + "fields": { + "sigla": "APROV1TUR", + "indicador": "R", + "descricao": "Proposição aprovada em 1º turno" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 13, + "fields": { + "sigla": "APROVADA", + "indicador": "F", + "descricao": "Proposição aprovada" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 14, + "fields": { + "sigla": "ARQUIVADA", + "indicador": "F", + "descricao": "Proposição arquivada" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 15, + "fields": { + "sigla": "AUTUAPAUTA", + "indicador": "R", + "descricao": "Proposição autuada e cumprindo prazo de pauta" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 16, + "fields": { + "sigla": "DESARQUIV", + "indicador": "R", + "descricao": "Proposição desarquivada pelo Autor" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 17, + "fields": { + "sigla": "DISTRCOMIS", + "indicador": "R", + "descricao": "Proposição distribuída às comissões" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 18, + "fields": { + "sigla": "INCLORDIA", + "indicador": "R", + "descricao": "Proposição inclusa na Ordem do Dia" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 19, + "fields": { + "sigla": "LEIPROMUL", + "indicador": "F", + "descricao": "Proposição transformada em lei por promulgação" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 20, + "fields": { + "sigla": "LEIVETPAR", + "indicador": "R", + "descricao": "Transformada em lei com veto parcial" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 21, + "fields": { + "sigla": "MANUTVETO", + "indicador": "R", + "descricao": "Parecer pela manutenção do veto" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 22, + "fields": { + "sigla": "NORMPROMUL", + "indicador": "F", + "descricao": "Norma promulgada" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 23, + "fields": { + "sigla": "PARECCONTR", + "indicador": "R", + "descricao": "Parecer contrário da comissão de mérito" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 24, + "fields": { + "sigla": "PARECERFAV", + "indicador": "R", + "descricao": "Parecer favorável da comissão" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 25, + "fields": { + "sigla": "PARECPLEN", + "indicador": "F", + "descricao": "Parecer em Plenário pelas comissões pertinentes" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 26, + "fields": { + "sigla": "PAREUCONJ", + "indicador": "R", + "descricao": "Parecer em reunião conjunta das Comissões pertinentes" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 27, + "fields": { + "sigla": "PREJUD", + "indicador": "F", + "descricao": "Proposição prejudicada" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 28, + "fields": { + "sigla": "PROMULVETO", + "indicador": "F", + "descricao": "Veto total ou parcial promulgado" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 29, + "fields": { + "sigla": "REJEITADA", + "indicador": "F", + "descricao": "Proposição rejeitada pelo Plenário" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 30, + "fields": { + "sigla": "REJEIVETO", + "indicador": "R", + "descricao": "Parecer pela rejeição do veto" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 31, + "fields": { + "sigla": "RETAUTOR", + "indicador": "F", + "descricao": "Proposição retirada pelo autor" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 32, + "fields": { + "sigla": "RETORDIA", + "indicador": "R", + "descricao": "Proposição retirada da Ordem do Dia" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 33, + "fields": { + "sigla": "TRANSFLEI", + "indicador": "F", + "descricao": "Proposição transformada em lei" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 34, + "fields": { + "sigla": "VETODISTR", + "indicador": "R", + "descricao": "Veto distribuído para emissão de parecer" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 35, + "fields": { + "sigla": "VETOLIDO", + "indicador": "R", + "descricao": "Veto sobre a proposição lido em sessão plenária" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 36, + "fields": { + "sigla": "VETOMANT", + "indicador": "F", + "descricao": "Veto sobre a proposição mantido" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 37, + "fields": { + "sigla": "VETOORDIA", + "indicador": "F", + "descricao": "Veto incluso na ordem do dia" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 38, + "fields": { + "sigla": "VETOPAUTA", + "indicador": "F", + "descricao": "Veto autuado e incluso em pauta" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 39, + "fields": { + "sigla": "VETOREJEI", + "indicador": "F", + "descricao": "Veto sobre a proposição rejeitado" + } + }, + { + "model": "materia.StatusTramitacao", + "pk": 40, + "fields": { + "sigla": "VETOTOTAL", + "indicador": "R", + "descricao": "Proposição com veto tota" + } + } +] diff --git a/sapl/materia/migrations/0013_adiciona_status_tramitacao.py b/sapl/materia/migrations/0013_adiciona_status_tramitacao.py new file mode 100644 index 000000000..5a5ac4e91 --- /dev/null +++ b/sapl/materia/migrations/0013_adiciona_status_tramitacao.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from django.db import migrations +import json +import os + + +from django.core.management import call_command + + + +def gera_status_tramitacao(apps, schema_editor): + StatusTramitacao = apps.get_model("materia", "StatusTramitacao") + db_alias = schema_editor.connection.alias + status_tramitacoes = StatusTramitacao.objects.all().exists() + + if status_tramitacoes: + # Caso haja algum StatusTramitacao 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( + StatusTramitacao._meta.verbose_name, + StatusTramitacao._meta.verbose_name_plural + ) + ) + else: + fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures')) + # pega status_tramitacoes listados em fixtures/pre_popula_status_tramitacao.json + fixture_filename = 'pre_popula_status_tramitacao.json' + fixture_file = os.path.join(fixture_dir, fixture_filename) + call_command('loaddata', fixture_file) + +class Migration(migrations.Migration): + + dependencies = [ + # A dependencia real desse script é o arquivo 0001_initial.py, mas + # isso gera um erro (Conflicting migrations detected; multiple leaf + # nodes in the migration graph). para não ocasionar problemas de migração, + # vamos manter a ordem padrão do django. + ('materia', '0012_auto_20170829_1321'), + ] + + operations = [ + migrations.RunPython(gera_status_tramitacao), + ] diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index ad410c2fb..5149ac926 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -133,9 +133,9 @@ class NormaJuridicaForm(ModelForm): ano=cleaned_data['ano_materia']) except ObjectDoesNotExist: raise forms.ValidationError( - _("Matéria %s/%s é inexistente." % ( - self.cleaned_data['numero_materia'], - self.cleaned_data['ano_materia']))) + _("Matéria %s/%s é inexistente." % ( + self.cleaned_data['numero_materia'], + self.cleaned_data['ano_materia']))) else: cleaned_data['materia'] = materia diff --git a/sapl/norma/migrations/0007_auto_20170904_1708.py b/sapl/norma/migrations/0007_auto_20170904_1708.py new file mode 100644 index 000000000..f353342ff --- /dev/null +++ b/sapl/norma/migrations/0007_auto_20170904_1708.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-09-04 17:08 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0006_normajuridica_data_ultima_atualizacao'), + ] + + operations = [ + migrations.AlterModelOptions( + name='assuntonorma', + options={'ordering': ['assunto'], 'verbose_name': 'Assunto de Norma Jurídica', 'verbose_name_plural': 'Assuntos de Normas Jurídicas'}, + ), + migrations.AlterField( + model_name='normajuridica', + name='esfera_federacao', + field=models.CharField(choices=[('M', 'Municipal'), ('E', 'Estadual'), ('F', 'Federal')], max_length=1, verbose_name='Esfera Federação'), + ), + ] diff --git a/sapl/norma/models.py b/sapl/norma/models.py index 5f92f8a59..d00be8ce7 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -20,6 +20,7 @@ class AssuntoNorma(models.Model): class Meta: verbose_name = _('Assunto de Norma Jurídica') verbose_name_plural = _('Assuntos de Normas Jurídicas') + ordering = ['assunto'] def __str__(self): return self.assunto @@ -67,9 +68,9 @@ def norma_upload_path(instance, filename): @reversion.register() class NormaJuridica(models.Model): ESFERA_FEDERACAO_CHOICES = Choices( + ('M', 'municipal', _('Municipal')), ('E', 'estadual', _('Estadual')), ('F', 'federal', _('Federal')), - ('M', 'municipal', _('Municipal')), ) texto_integral = models.FileField( diff --git a/sapl/norma/tests/test_norma.py b/sapl/norma/tests/test_norma.py index f57167f62..fa8214e58 100644 --- a/sapl/norma/tests/test_norma.py +++ b/sapl/norma/tests/test_norma.py @@ -1,11 +1,13 @@ 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,) -from sapl.norma.models import NormaJuridica, TipoNormaJuridica +from sapl.norma.forms import NormaJuridicaForm, NormaRelacionadaForm +from sapl.norma.models import (NormaJuridica, TipoNormaJuridica) @pytest.mark.django_db(transaction=False) @@ -96,7 +98,6 @@ def test_norma_juridica_materia_inexistente(): @pytest.mark.django_db(transaction=False) def test_norma_juridica_materia_existente(): - tipo = mommy.make(TipoNormaJuridica) tipo_materia = mommy.make(TipoMateriaLegislativa) materia = mommy.make(MateriaLegislativa, @@ -115,3 +116,19 @@ def test_norma_juridica_materia_existente(): 'ano_materia': '2017' }) assert form.is_valid() + + +@pytest.mark.django_db(transaction=False) +def test_norma_relacionada_form_campos_obrigatorios(): + form = NormaRelacionadaForm(data={}) + + assert not form.is_valid() + + errors = form.errors + + assert errors['tipo'] == [_('Este campo é obrigatório.')] + assert errors['numero'] == [_('Este campo é obrigatório.')] + assert errors['ano'] == [_('Este campo é obrigatório.')] + assert errors['tipo_vinculo'] == [_('Este campo é obrigatório.')] + + assert len(errors) == 4 diff --git a/sapl/norma/urls.py b/sapl/norma/urls.py index abf13c276..93081c4fc 100644 --- a/sapl/norma/urls.py +++ b/sapl/norma/urls.py @@ -2,7 +2,8 @@ from django.conf.urls import include, url from sapl.norma.views import (AssuntoNormaCrud, NormaCrud, NormaPesquisaView, NormaRelacionadaCrud, NormaTaView, TipoNormaCrud, - TipoVinculoNormaJuridicaCrud, recuperar_norma) + TipoVinculoNormaJuridicaCrud, recuperar_norma, + recuperar_numero_norma) from .apps import AppConfig @@ -25,5 +26,7 @@ urlpatterns = [ NormaPesquisaView.as_view(), name='norma_pesquisa'), url(r'^norma/recuperar-norma$', recuperar_norma, name="recuperar_norma"), + url(r'^norma/recuperar-numero-norma$', recuperar_numero_norma, + name="recuperar_numero_norma"), ] diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 9120da4e9..28835a2a0 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -1,3 +1,4 @@ +from datetime import datetime from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse from django.http import JsonResponse @@ -145,6 +146,7 @@ class NormaCrud(Crud): def layout_key(self): return 'NormaJuridicaCreate' + class ListView(Crud.ListView, RedirectView): def get_redirect_url(self, *args, **kwargs): @@ -185,3 +187,22 @@ def recuperar_norma(request): response = JsonResponse({'ementa': '', 'id': 0}) return response + + +def recuperar_numero_norma(request): + tipo = TipoNormaJuridica.objects.get(pk=request.GET['tipo']) + ano = request.GET.get('ano', '') + + param = {'tipo': tipo} + param['ano'] = ano if ano else datetime.now().year + + norma = NormaJuridica.objects.filter(**param).order_by( + 'tipo', 'ano', 'numero').values_list('numero', 'ano').last() + if norma: + response = JsonResponse({'numero': int(norma[0]) + 1, + 'ano': norma[1]}) + else: + response = JsonResponse( + {'numero': 1, 'ano': ano}) + + return response diff --git a/sapl/parlamentares/fixtures/pre_popula_cargosmesa.json b/sapl/parlamentares/fixtures/pre_popula_cargosmesa.json new file mode 100644 index 000000000..b93376bc0 --- /dev/null +++ b/sapl/parlamentares/fixtures/pre_popula_cargosmesa.json @@ -0,0 +1,37 @@ +[ + { + "model": "parlamentares.CargoMesa", + "pk": 1, + "fields": { + "descricao": "Presidente", + "unico": true + } + }, + { + "model": "parlamentares.CargoMesa", + "pk": 2, + "fields": { + "descricao": "Vice-Presidente", + "unico": true + } + }, + { + "model": "parlamentares.CargoMesa", + "pk": 3, + "fields": { + "descricao": "Primeiro-Secretário", + "unico": true + } + }, + { + "model": "parlamentares.CargoMesa", + "pk": 4, + "fields": { + "descricao": "Segundo-Secretário", + "unico": true + } + } +] + + + diff --git a/sapl/parlamentares/fixtures/pre_popula_partidos.json b/sapl/parlamentares/fixtures/pre_popula_partidos.json new file mode 100644 index 000000000..8df0001c3 --- /dev/null +++ b/sapl/parlamentares/fixtures/pre_popula_partidos.json @@ -0,0 +1,282 @@ +[ + { + "model": "parlamentares.Partido", + "pk": 1, + "fields": { + "sigla": "PMDB", + "nome": "PARTIDO DO MOVIMENTO DEMOCRÁTICO BRASILEIRO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 2, + "fields": { + "sigla": "PTB", + "nome": "PARTIDO TRABALHISTA BRASILEIRO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 3, + "fields": { + "sigla": "PDT", + "nome": "PARTIDO DEMOCRÁTICO TRABALHISTA" + } + }, + { + "model": "parlamentares.Partido", + "pk": 4, + "fields": { + "sigla": "PT", + "nome": "PARTIDO DOS TRABALHADORES" + } + }, + { + "model": "parlamentares.Partido", + "pk": 5, + "fields": { + "sigla": "DEM", + "nome": "DEMOCRATAS" + } + }, + { + "model": "parlamentares.Partido", + "pk": 6, + "fields": { + "sigla": "PCdoB", + "nome": "PARTIDO COMUNISTA DO BRASIL" + } + }, + { + "model": "parlamentares.Partido", + "pk": 7, + "fields": { + "sigla": "PSB", + "nome": "PARTIDO SOCIALISTA BRASILEIRO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 8, + "fields": { + "sigla": "PSDB", + "nome": "PARTIDO DA SOCIAL DEMOCRACIA BRASILEIRA" + } + }, + { + "model": "parlamentares.Partido", + "pk": 9, + "fields": { + "sigla": "PTC", + "nome": "PARTIDO TRABALHISTA CRISTÃO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 10, + "fields": { + "sigla": "PSC", + "nome": "PARTIDO SOCIAL CRISTÃO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 11, + "fields": { + "sigla": "PMN", + "nome": "PARTIDO DA MOBILIZAÇÃO NACIONAL" + } + }, + { + "model": "parlamentares.Partido", + "pk": 12, + "fields": { + "sigla": "PRP", + "nome": "PARTIDO REPUBLICANO PROGRESSISTA" + } + }, + { + "model": "parlamentares.Partido", + "pk": 13, + "fields": { + "sigla": "PPS", + "nome": "PARTIDO POPULAR SOCIALISTA" + } + }, + { + "model": "parlamentares.Partido", + "pk": 14, + "fields": { + "sigla": "PV", + "nome": "PARTIDO VERDE" + } + }, + { + "model": "parlamentares.Partido", + "pk": 15, + "fields": { + "sigla": "PTdoB", + "nome": "PARTIDO TRABALHISTA DO BRASIL" + } + }, + { + "model": "parlamentares.Partido", + "pk": 16, + "fields": { + "sigla": "PP", + "nome": "PARTIDO PROGRESSISTA" + } + }, + { + "model": "parlamentares.Partido", + "pk": 17, + "fields": { + "sigla": "PSTU", + "nome": "PARTIDO SOCIALISTA DOS TRABALHADORES UNIFICADO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 18, + "fields": { + "sigla": "PCB", + "nome": "PARTIDO COMUNISTA BRASILEIRO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 19, + "fields": { + "sigla": "PRTB", + "nome": "PARTIDO RENOVADOR TRABALHISTA BRASILEIRO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 20, + "fields": { + "sigla": "PHS", + "nome": "PARTIDO HUMANISTA DA SOLIDARIEDADE" + } + }, + { + "model": "parlamentares.Partido", + "pk": 21, + "fields": { + "sigla": "PSDC", + "nome": "PARTIDO SOCIAL DEMOCRATA CRISTÃO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 22, + "fields": { + "sigla": "PCO", + "nome": "PARTIDO DA CAUSA OPERÁRIA" + } + }, + { + "model": "parlamentares.Partido", + "pk": 23, + "fields": { + "sigla": "PODE", + "nome": "PODEMOS" + } + }, + { + "model": "parlamentares.Partido", + "pk": 24, + "fields": { + "sigla": "PSL", + "nome": "PARTIDO SOCIAL LIBERAL" + } + }, + { + "model": "parlamentares.Partido", + "pk": 25, + "fields": { + "sigla": "PRB", + "nome": "PARTIDO REPUBLICANO BRASILEIRO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 26, + "fields": { + "sigla": "PSOL", + "nome": "PARTIDO SOCIALISMO E LIBERDADE" + } + }, + { + "model": "parlamentares.Partido", + "pk": 27, + "fields": { + "sigla": "PR", + "nome": "PARTIDO DA REPÚBLICA" + } + }, + { + "model": "parlamentares.Partido", + "pk": 28, + "fields": { + "sigla": "PSD", + "nome": "PARTIDO SOCIAL DEMOCRÁTICO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 29, + "fields": { + "sigla": "PPL", + "nome": "PARTIDO PÁTRIA LIVRE" + } + }, + { + "model": "parlamentares.Partido", + "pk": 30, + "fields": { + "sigla": "PEN", + "nome": "PARTIDO ECOLÓGICO NACIONAL" + } + }, + { + "model": "parlamentares.Partido", + "pk": 31, + "fields": { + "sigla": "PROS", + "nome": "PARTIDO REPUBLICANO DA ORDEM SOCIAL" + } + }, + { + "model": "parlamentares.Partido", + "pk": 32, + "fields": { + "sigla": "SD", + "nome": "SOLIDARIEDADE" + } + }, + { + "model": "parlamentares.Partido", + "pk": 33, + "fields": { + "sigla": "NOVO", + "nome": "PARTIDO NOVO" + } + }, + { + "model": "parlamentares.Partido", + "pk": 34, + "fields": { + "sigla": "REDE", + "nome": "REDE SUSTENTABILIDADE" + } + }, + { + "model": "parlamentares.Partido", + "pk": 35, + "fields": { + "sigla": "PMB", + "nome": "PARTIDO DA MULHER BRASILEIRA" + } + } +] diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py index e08eb5451..59069aca5 100644 --- a/sapl/parlamentares/forms.py +++ b/sapl/parlamentares/forms.py @@ -72,16 +72,16 @@ class MandatoForm(ModelForm): data_inicio_mandato = data['data_inicio_mandato'] if data_inicio_mandato: if (data_inicio_mandato < legislatura.data_inicio or - data_inicio_mandato > legislatura.data_fim): - raise ValidationError(_("Data início mandato fora do intervalo " - "de legislatura informada")) + data_inicio_mandato > legislatura.data_fim): + raise ValidationError(_("Data início mandato fora do intervalo" + " de legislatura informada")) data_fim_mandato = data['data_fim_mandato'] if data_fim_mandato: if (data_fim_mandato < legislatura.data_inicio or - data_fim_mandato > legislatura.data_fim): - raise ValidationError(_("Data fim mandato fora do intervalo de " - "legislatura informada")) + data_fim_mandato > legislatura.data_fim): + raise ValidationError(_("Data fim mandato fora do intervalo de" + " legislatura informada")) existe_mandato = Mandato.objects.filter( parlamentar=data['parlamentar'], diff --git a/sapl/parlamentares/migrations/0006_auto_20170831_1400.py b/sapl/parlamentares/migrations/0006_auto_20170831_1400.py new file mode 100644 index 000000000..a72cd43df --- /dev/null +++ b/sapl/parlamentares/migrations/0006_auto_20170831_1400.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2017-08-31 14:00 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('parlamentares', '0005_auto_20170814_1615'), + ] + + operations = [ + migrations.AlterModelOptions( + name='votante', + options={'permissions': (('can_vote', 'Can Vote'),), 'verbose_name': 'Usuário Votante', 'verbose_name_plural': 'Usuários Votantes'}, + ), + ] diff --git a/sapl/parlamentares/migrations/0007_adiciona_partidos.py b/sapl/parlamentares/migrations/0007_adiciona_partidos.py new file mode 100644 index 000000000..336e15d09 --- /dev/null +++ b/sapl/parlamentares/migrations/0007_adiciona_partidos.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from django.db import migrations +import json +import os + + +from django.core.management import call_command + + + +def gera_partidos_tse(apps, schema_editor): + Partido = apps.get_model("parlamentares", "Partido") + db_alias = schema_editor.connection.alias + partidos = Partido.objects.all().exists() + + if partidos: + # Caso haja algum partido cadastrado na base de dados, + # a migração não deve ser carregada para evitar duplicações de dados. + print("Carga de Partido não efetuada. Já Existem partidos cadastrados...") + else: + fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures')) + # pega partidos listados em fixtures/pre_popula_partidos.json + fixture_filename = 'pre_popula_partidos.json' + fixture_file = os.path.join(fixture_dir, fixture_filename) + call_command('loaddata', fixture_file) + +class Migration(migrations.Migration): + + dependencies = [ + # A dependencia real desse script é o arquivo 0001_initial.py, mas + # isso gera um erro (Conflicting migrations detected; multiple leaf + # nodes in the migration graph). para não ocasionar problemas de migração, + # vamos manter a ordem padrão do django. + ('parlamentares', '0006_auto_20170831_1400'), + ] + + operations = [ + migrations.RunPython(gera_partidos_tse), + ] diff --git a/sapl/parlamentares/migrations/0008_adiciona_cargos_mesa.py b/sapl/parlamentares/migrations/0008_adiciona_cargos_mesa.py new file mode 100644 index 000000000..fe88e6196 --- /dev/null +++ b/sapl/parlamentares/migrations/0008_adiciona_cargos_mesa.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from django.db import migrations +import json +import os + + +from django.core.management import call_command + + + +def gera_cargos_mesa(apps, schema_editor): + CargoMesa = apps.get_model("parlamentares", "CargoMesa") + db_alias = schema_editor.connection.alias + cargos_mesa = CargoMesa.objects.all().exists() + + if cargos_mesa: + # Caso haja algum CargoMesa 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( + CargoMesa._meta.verbose_name, CargoMesa._meta.verbose_name_plural)) + else: + fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures')) + # pega partidos listados em fixtures/pre_popula_partidos.json + fixture_filename = 'pre_popula_cargosmesa.json' + fixture_file = os.path.join(fixture_dir, fixture_filename) + call_command('loaddata', fixture_file) + +class Migration(migrations.Migration): + + dependencies = [ + # A dependencia real desse script é o arquivo 0001_initial.py, mas + # isso gera um erro (Conflicting migrations detected; multiple leaf + # nodes in the migration graph). para não ocasionar problemas de migração, + # vamos manter a ordem padrão do django. + ('parlamentares', '0007_adiciona_partidos'), + ] + + operations = [ + migrations.RunPython(gera_cargos_mesa), + ] diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index ce825d88d..db8ea8242 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -576,8 +576,8 @@ class Votante(models.Model): max_length=30, null=True, blank=True) class Meta: - verbose_name = _('Usuário') - verbose_name_plural = _('Usuários') + verbose_name = _('Usuário Votante') + verbose_name_plural = _('Usuários Votantes') permissions = ( ('can_vote', _('Can Vote')), ) diff --git a/sapl/parlamentares/tests/test_parlamentares.py b/sapl/parlamentares/tests/test_parlamentares.py index 03e3f08e9..a10d235e5 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 (LegislaturaForm, MandatoForm) +from sapl.parlamentares.forms import (FrenteForm, LegislaturaForm, MandatoForm) from sapl.parlamentares.models import (Dependente, Filiacao, Legislatura, Mandato, Parlamentar, Partido, TipoDependente) @@ -181,7 +181,9 @@ def test_mandato_form_duplicado(): assert not form.is_valid() - assert form.errors['__all__'] == [_('Mandato nesta legislatura já existe.')] + assert form.errors['__all__'] == [ + _('Mandato nesta legislatura já existe.')] + @pytest.mark.django_db(transaction=False) def test_mandato_form_datas_invalidas(): @@ -230,13 +232,14 @@ def test_legislatura_form_invalido(): assert len(errors) == 4 + def test_legislatura_form_datas_invalidas(): legislatura_form = LegislaturaForm(data={'numero': '1', 'data_inicio': '2017-02-01', 'data_fim': '2021-12-31', 'data_eleicao': '2017-02-01' - }) + }) assert not legislatura_form.is_valid() @@ -248,9 +251,37 @@ def test_legislatura_form_datas_invalidas(): 'data_inicio': '2017-02-01', 'data_fim': '2017-01-01', 'data_eleicao': '2016-11-01' - }) + }) assert not legislatura_form.is_valid() assert legislatura_form.errors['__all__'] == \ [_("Intervalo de início e fim inválido para legislatura.")] + + +@pytest.mark.django_db(transaction=False) +def test_valida_campos_obrigatorios_frente_form(): + form = FrenteForm(data={}) + + assert not form.is_valid() + + errors = form.errors + + assert errors['nome'] == [_('Este campo é obrigatório.')] + assert errors['data_criacao'] == [_('Este campo é obrigatório.')] + + assert len(errors) == 2 + + +@pytest.mark.django_db(transaction=False) +def test_frente_form_valido(): + parlamentares = mommy.make(Parlamentar) + + form = FrenteForm(data={'nome': 'Nome da Frente', + 'parlamentar': str(parlamentares.pk), + 'data_criacao': '10/11/2017', + 'data_extincao': '10/12/2017', + 'descricao': 'teste' + }) + + assert form.is_valid() diff --git a/sapl/protocoloadm/tests/test_protocoloadm.py b/sapl/protocoloadm/tests/test_protocoloadm.py index fd3e73df7..0ffbb5e4b 100644 --- a/sapl/protocoloadm/tests/test_protocoloadm.py +++ b/sapl/protocoloadm/tests/test_protocoloadm.py @@ -6,11 +6,12 @@ from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ from model_mommy import mommy -from sapl.materia.models import (MateriaLegislativa, UnidadeTramitacao) +from sapl.materia.models import UnidadeTramitacao from sapl.protocoloadm.forms import (AnularProcoloAdmForm, DocumentoAdministrativoForm, + MateriaLegislativa, ProtocoloDocumentForm, - ProtocoloMateriaForm,) + ProtocoloMateriaForm) from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, StatusTramitacaoAdministrativo, TipoDocumentoAdministrativo, @@ -258,7 +259,6 @@ def test_create_tramitacao(admin_client): @pytest.mark.django_db(transaction=False) def test_anular_protocolo_dados_invalidos(): - protocolo = mommy.make(Protocolo, pk=1, numero=1, ano=2017) form = AnularProcoloAdmForm(data={}) @@ -300,6 +300,7 @@ def test_anular_protocolo_form_anula_protocolo_anulado(): assert form.errors['__all__'] == [_( 'Protocolo 1/2017 já encontra-se anulado')] + @pytest.mark.django_db(transaction=False) def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado(): tipo_materia = mommy.make(TipoMateriaLegislativa) @@ -323,14 +324,15 @@ def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado(): assert form.errors['__all__'] == \ [_("Protocolo 1/2017 não pode ser removido pois existem " - "documentos vinculados a ele.")] + "documentos vinculados a ele.")] tipo_documento = mommy.make(TipoDocumentoAdministrativo) + protocolo_documento = mommy.make(Protocolo, - numero=2, - ano=2017, - tipo_documento=tipo_documento, - anulado=False) + numero=2, + ano=2017, + tipo_documento=tipo_documento, + anulado=False) documento_administrativo = mommy.make(DocumentoAdministrativo, protocolo=protocolo_documento) @@ -344,7 +346,7 @@ def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado(): assert form.errors['__all__'] == \ [_("Protocolo 2/2017 não pode ser removido pois existem " - "documentos vinculados a ele.")] + "documentos vinculados a ele.")] def test_documento_administrativo_invalido(): @@ -397,6 +399,7 @@ def test_protocolo_documento_form_invalido(): assert len(errors) == 5 + def test_protocolo_materia_invalido(): form = ProtocoloMateriaForm(data={}) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index 119cdb761..e659d169e 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -111,8 +111,11 @@ def inf_basicas(inf_basicas_dic): nom_sessao + '\n' tmp += '\t\tAbertura: ' + \ dat_inicio_sessao + ' - ' + hr_inicio_sessao + '\n' + + data_fim_sessao = dat_fim_sessao + ' - ' if dat_fim_sessao else '' + tmp += '\t\tEncerramento: ' + \ - dat_fim_sessao + ' - ' + hr_fim_sessao + '\n' + dat_fim_sessao + hr_fim_sessao + '\n' return tmp diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index b40372d3f..87510089d 100644 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -693,8 +693,9 @@ def get_sessao_plenaria(sessao, casa): if tramitacao.turno == turno[0]: dic_votacao["des_turno"] = turno[1] - dic_votacao["txt_ementa"] = materia.ementa - dic_votacao["ordem_observacao"] = votacao.observacao + # https://github.com/interlegis/sapl/issues/1009 + dic_votacao["txt_ementa"] = html.unescape(materia.ementa) + dic_votacao["ordem_observacao"] = html.unescape(votacao.observacao) dic_votacao["nom_autor"] = ' ' autoria = Autoria.objects.filter( diff --git a/sapl/sessao/tests/test_sessao.py b/sapl/sessao/tests/test_sessao.py index d1a1ab8e6..7142aa48f 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.parlamentares.models import Legislatura, SessaoLegislativa +from sapl.parlamentares.models import Legislatura, Partido, SessaoLegislativa from sapl.sessao import forms from sapl.sessao.models import SessaoPlenaria, TipoSessaoPlenaria @@ -14,12 +14,12 @@ def test_valida_campos_obrigatorios_sessao_plenaria_form(): errors = form.errors - assert errors['legislatura'] == ['Este campo é obrigatório.'] - assert errors['sessao_legislativa'] == ['Este campo é obrigatório.'] - assert errors['tipo'] == ['Este campo é obrigatório.'] - assert errors['numero'] == ['Este campo é obrigatório.'] - assert errors['data_inicio'] == ['Este campo é obrigatório.'] - assert errors['hora_inicio'] == ['Este campo é obrigatório.'] + assert errors['legislatura'] == [_('Este campo é obrigatório.')] + assert errors['sessao_legislativa'] == [_('Este campo é obrigatório.')] + assert errors['tipo'] == [_('Este campo é obrigatório.')] + assert errors['numero'] == [_('Este campo é obrigatório.')] + assert errors['data_inicio'] == [_('Este campo é obrigatório.')] + assert errors['hora_inicio'] == [_('Este campo é obrigatório.')] assert len(errors) == 6 @@ -66,3 +66,50 @@ def test_numero_duplicado_sessao_plenaria_form(): "para a Legislatura, Sessão Legislativa " "e Tipo informados. Favor escolher um " "número distinto."] + + +@pytest.mark.django_db(transaction=False) +def test_valida_campos_obrigatorios_bancada_form(): + form = forms.BancadaForm(data={}) + + assert not form.is_valid() + + errors = form.errors + + assert errors['legislatura'] == [_('Este campo é obrigatório.')] + assert errors['nome'] == [_('Este campo é obrigatório.')] + + assert len(errors) == 2 + + +@pytest.mark.django_db(transaction=False) +def test_bancada_form_valido(): + legislatura = mommy.make(Legislatura) + partido = mommy.make(Partido) + + form = forms.BancadaForm(data={'legislatura': str(legislatura.pk), + 'nome': 'Nome da Bancada', + 'partido': str(partido.pk), + 'data_criacao': '10/11/2017', + 'data_extincao': '10/12/2017', + 'descricao': 'teste' + }) + + assert form.is_valid() + + +@pytest.mark.django_db(transaction=False) +def test_bancada_form_datas_invalidas(): + legislatura = mommy.make(Legislatura) + partido = mommy.make(Partido) + + form = forms.BancadaForm(data={'legislatura': str(legislatura.pk), + 'nome': 'Nome da Bancada', + 'partido': str(partido.pk), + 'data_criacao': '2016-11-01', + 'data_extincao': '2016-10-01', + 'descricao': 'teste' + }) + assert not form.is_valid() + assert form.errors['__all__'] == [_('Data de extinção não pode ser menor ' + 'que a de criação')] diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index aea18ea4c..2d8e2faea 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -1098,13 +1098,13 @@ class ResumoView(DetailView): abertura = data_inicio.strftime('%d/%m/%Y') if data_inicio else '' data_fim = self.object.data_fim - encerramento = data_fim.strftime('%d/%m/%Y') if data_fim else '' + encerramento = data_fim.strftime('%d/%m/%Y') + ' -' if data_fim else '' context.update({'basica': [ _('Tipo de Sessão: %(tipo)s') % {'tipo': self.object.tipo}, _('Abertura: %(abertura)s - %(hora_inicio)s') % { 'abertura': abertura, 'hora_inicio': self.object.hora_inicio}, - _('Encerramento: %(encerramento)s - %(hora_fim)s') % { + _('Encerramento: %(encerramento)s %(hora_fim)s') % { 'encerramento': encerramento, 'hora_fim': self.object.hora_fim} ]}) # ===================================================================== diff --git a/sapl/static/styles/compilacao.scss b/sapl/static/styles/compilacao.scss index 651ec7869..c2e7ed7ad 100644 --- a/sapl/static/styles/compilacao.scss +++ b/sapl/static/styles/compilacao.scss @@ -205,9 +205,8 @@ a:link:after, a:visited:after { .titulo_generico { text-align: center; - font-weight: bold; margin-bottom: 1em; - font-size: 1.5em; + font-size: 1.15em; margin-top: 3em; } @@ -229,14 +228,15 @@ a:link:after, a:visited:after { .capitulo { @extend .titulo_generico; margin-top: 1.5em; - font-size: 1.3em; + font-size: 1.15em; } .secao { @extend .titulo_generico; margin-top: 1.2em; margin-bottom: 0.7em; - font-size: 1.2em; + font-weight: bold; + font-size: 1.15em; } .subsecao, @@ -244,8 +244,8 @@ a:link:after, a:visited:after { @extend .titulo_generico; margin-top: 1em; margin-bottom: 0.6em; - font-size: 1.2em; - font-style: italic; + font-weight: bold; + font-size: 1.15em; } .artigo { @@ -280,6 +280,16 @@ a:link:after, a:visited:after { font-size: 1.0em; margin-top: 2px; } + + .assinatura { + margin-top: 0.6em; + font-size: 1.15em; + } + + .fecho_lei { + margin-top: 0.6em; + font-size: 1.15em; + } .bloco_alteracao { padding-left: 10%; @@ -393,7 +403,7 @@ a:link:after, a:visited:after { .dptt { clear: left; & > a { - color: #444444; + color: #000000; &.nota-alteracao { color: #02baf2; font-size: 0.75em; @@ -1528,4 +1538,4 @@ a:link:after, a:visited:after { .container { width: 100%; } -} +} \ No newline at end of file diff --git a/sapl/templates/norma/normajuridica_form.html b/sapl/templates/norma/normajuridica_form.html index 7a35b05a7..9c4772a80 100644 --- a/sapl/templates/norma/normajuridica_form.html +++ b/sapl/templates/norma/normajuridica_form.html @@ -24,6 +24,23 @@ for (i = 0; i < fields.length; i++) { $(fields[i]).change(recuperar_materia); } + function recuperar_norma() { + var tipo = $("#id_tipo").val() + var ano = $("#id_ano").val() + + if (tipo) { + $.get("/norma/recuperar-numero-norma",{tipo: tipo, + ano: ano}, + function(data, status) { + $("#id_numero").val(data.numero); + $("#id_ano").val(data.ano); + }); + } + } + var fields = ["#id_tipo", "#id_ano"] + for (i = 0; i < fields.length; i++) { + $(fields[i]).change(recuperar_norma); + } {% endblock %} diff --git a/sapl/test_urls.py b/sapl/test_urls.py index 9daa58fab..bfccb3672 100644 --- a/sapl/test_urls.py +++ b/sapl/test_urls.py @@ -173,7 +173,7 @@ apps_url_patterns_prefixs_and_users = { '/ta', ]}, 'redireciona_urls': { - 'prefixs': [ + 'prefixs': [ '/default_index_html', '/consultas/parlamentar/parlamentar_', '/consultas/comissao/comissao_', @@ -192,7 +192,7 @@ apps_url_patterns_prefixs_and_users = { '/presencaSessao', '/resumoPropositurasAutor', '/propositurasAnoAutorTipo', - ]}, + ]}, 'lexml': { 'prefixs': [ '/lexml',