From 399458c15868eea3dc65cb151ab233185e432a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Mon, 8 Jul 2019 15:15:21 -0300 Subject: [PATCH] =?UTF-8?q?Transfere=20migra=C3=A7=C3=B5es=20de=20Bancada?= =?UTF-8?q?=20e=20CargoBancada=20(#2761)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #1798 --- sapl/base/tests/test_view_base.py | 3 +- sapl/base/views.py | 29 +++++----- sapl/legacy/test_renames.py | 9 ++- sapl/parlamentares/forms.py | 57 +++++++++++++++++- .../migrations/0032_auto_20190619_1509.py | 58 +++++++++++++++++++ sapl/parlamentares/models.py | 57 ++++++++++++++++++ .../parlamentares/tests/test_parlamentares.py | 58 +++++++++++++++++++ sapl/parlamentares/urls.py | 22 ++++--- sapl/parlamentares/views.py | 21 +++++-- sapl/rules/map_rules.py | 5 +- sapl/sessao/forms.py | 55 +----------------- .../migrations/0043_auto_20190506_1452.py | 34 +++++++++++ sapl/sessao/models.py | 55 ------------------ sapl/sessao/tests/test_sessao.py | 58 +------------------ sapl/sessao/urls.py | 9 +-- sapl/sessao/views.py | 46 ++++++--------- sapl/templates/menu_tabelas_auxiliares.yaml | 4 +- sapl/templates/parlamentares/layouts.yaml | 11 ++++ sapl/templates/sessao/layouts.yaml | 11 ---- sapl/templates/sistema.html | 4 +- 20 files changed, 350 insertions(+), 256 deletions(-) create mode 100644 sapl/parlamentares/migrations/0032_auto_20190619_1509.py create mode 100644 sapl/sessao/migrations/0043_auto_20190506_1452.py diff --git a/sapl/base/tests/test_view_base.py b/sapl/base/tests/test_view_base.py index 6655317b3..209035396 100644 --- a/sapl/base/tests/test_view_base.py +++ b/sapl/base/tests/test_view_base.py @@ -7,12 +7,11 @@ from model_mommy import mommy from sapl.base.models import Autor, TipoAutor from sapl.comissoes.models import Comissao, TipoComissao -from sapl.sessao.models import Bancada from sapl.protocoloadm.models import (Protocolo, DocumentoAdministrativo, TipoDocumentoAdministrativo, Anexado) from sapl.materia.models import (TipoMateriaLegislativa, RegimeTramitacao, MateriaLegislativa, Anexada) -from sapl.parlamentares.models import (Parlamentar, Partido, Filiacao, +from sapl.parlamentares.models import (Bancada, Parlamentar, Partido, Filiacao, Legislatura, Mandato) from sapl.base.views import (protocolos_duplicados, protocolos_com_materias, diff --git a/sapl/base/views.py b/sapl/base/views.py index 185042f1c..122694cb6 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -41,12 +41,13 @@ from sapl.crud.base import CrudAux, make_pagination from sapl.materia.models import (Autoria, MateriaLegislativa, Proposicao, Anexada, TipoMateriaLegislativa, StatusTramitacao, UnidadeTramitacao) from sapl.norma.models import (NormaJuridica, NormaEstatisticas) -from sapl.parlamentares.models import Parlamentar, Legislatura, Mandato, Filiacao, SessaoLegislativa -from sapl.protocoloadm.models import (Protocolo, TipoDocumentoAdministrativo, - StatusTramitacaoAdministrativo, +from sapl.parlamentares.models import (Parlamentar, Legislatura, Mandato, + Filiacao, SessaoLegislativa, Bancada) +from sapl.protocoloadm.models import (Protocolo, TipoDocumentoAdministrativo, + StatusTramitacaoAdministrativo, DocumentoAdministrativo, Anexado) from sapl.sessao.models import (PresencaOrdemDia, SessaoPlenaria, - SessaoPlenariaPresenca, Bancada) + SessaoPlenariaPresenca) from sapl.utils import (parlamentares_ativos, gerar_hash_arquivo, SEPARADOR_HASH_PROPOSICAO, show_results_filter_set, mail_service_configured, intervalos_tem_intersecao, remover_acentos) @@ -320,7 +321,7 @@ class RelatoriosListView(TemplateView): context = super(TemplateView, self).get_context_data(**kwargs) estatisticas_acesso_normas = AppConfig.objects.first().estatisticas_acesso_normas context['estatisticas_acesso_normas'] = True if estatisticas_acesso_normas == 'S' else False - + return context @@ -364,7 +365,7 @@ class RelatorioPresencaSessaoView(FilterView): # Verifica se os campos foram preenchidos if not self.filterset.form.is_valid(): return context - + cd = self.filterset.form.cleaned_data if not cd['data_inicio'] and not cd['sessao_legislativa'] \ and not cd['legislatura']: @@ -408,13 +409,13 @@ class RelatorioPresencaSessaoView(FilterView): elif legislatura_pk and not sessao_legislativa_pk: _range = [legislatura.data_inicio, legislatura.data_fim] - + elif sessao_legislativa_pk: _range = [sessao_legislativa.data_inicio, sessao_legislativa.data_fim] param0 = {'sessao_plenaria__data_inicio__range': _range} - + # Parlamentares com Mandato no intervalo de tempo (Ativos) parlamentares_qs = parlamentares_ativos( _range[0], _range[1]).order_by('nome_parlamentar') @@ -1105,7 +1106,7 @@ class ListarInconsistenciasView(PermissionRequiredMixin, ListView): def anexados_ciclicos(ofMateriaLegislativa): ciclicos = [] - + if ofMateriaLegislativa: principais = Anexada.objects.values( 'materia_principal' @@ -1201,7 +1202,7 @@ class ListarAnexadasCiclicasView(PermissionRequiredMixin, ListView): paginator = context['paginator'] page_obj = context['page_obj'] - + context['page_range'] = make_pagination( page_obj.number, paginator.num_pages ) @@ -1357,7 +1358,7 @@ class ListarParlFiliacoesIntersecaoView(PermissionRequiredMixin, ListView): context[ 'NO_ENTRIES_MSG' ] = 'Nenhum encontrado.' - return context + return context def parlamentares_mandatos_intersecao(): @@ -1508,7 +1509,7 @@ class ListarFiliacoesSemDataFiliacaoView(PermissionRequiredMixin, ListView): def get_queryset(self): return filiacoes_sem_data_filiacao() - + def get_context_data(self, **kwargs): context = super( ListarFiliacoesSemDataFiliacaoView, self @@ -2004,7 +2005,7 @@ def pesquisa_textual(request): # Index and db are out of sync. Object has been deleted from database continue dici = filtro_campos(e.object.__dict__) - sec_dict['objeto'] = str(dici) + sec_dict['objeto'] = str(dici) sec_dict['text'] = str(e.object.ementa) sec_dict['model'] = str(type(e.object)) @@ -2060,4 +2061,4 @@ class RelatorioHistoricoTramitacaoAdmView(FilterView): else: context['tramitacaoadministrativo__unidade_tramitacao_destino'] = '' - return context \ No newline at end of file + return context diff --git a/sapl/legacy/test_renames.py b/sapl/legacy/test_renames.py index 9a5c4ebaf..b8f409b49 100644 --- a/sapl/legacy/test_renames.py +++ b/sapl/legacy/test_renames.py @@ -12,20 +12,19 @@ from sapl.materia.models import (AcompanhamentoMateria, DocumentoAcessorio, Tramitacao) from sapl.norma.models import (AnexoNormaJuridica, NormaJuridica, NormaRelacionada, TipoVinculoNormaJuridica) -from sapl.parlamentares.models import (Frente, Mandato, Parlamentar, Partido, +from sapl.parlamentares.models import (Bancada, CargoBancada, Frente, Mandato, Parlamentar, Partido, TipoAfastamento, Votante, Bloco) from sapl.protocoloadm.models import DocumentoAdministrativo -from sapl.sessao.models import (Bancada, CargoBancada, - ExpedienteMateria, Orador, OradorExpediente, +from sapl.sessao.models import (ExpedienteMateria, Orador, OradorExpediente, OrdemDia, RegistroVotacao, ResumoOrdenacao, SessaoPlenaria, TipoResultadoVotacao, VotoParlamentar) RENAMING_IGNORED_MODELS = [ - Votante, Frente, Bancada, Bloco, Votante, # parlamentares + Votante, Frente, Bancada, CargoBancada, Bloco, Votante, # parlamentares Composicao, Reuniao, DocumentoAcessorioComissoes, # commissoes AppConfig, CasaLegislativa, # base - CargoBancada, ResumoOrdenacao, # sessao + ResumoOrdenacao, # sessao AnexoNormaJuridica, TipoVinculoNormaJuridica, # norma ] diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py index 2003a4679..6f8b47c85 100755 --- a/sapl/parlamentares/forms.py +++ b/sapl/parlamentares/forms.py @@ -23,7 +23,7 @@ from sapl.rules import SAPL_GROUP_VOTANTE import django_filters from .models import (ComposicaoColigacao, Filiacao, Frente, Legislatura, - Mandato, Parlamentar, Votante, Bloco) + Mandato, Parlamentar, Votante, Bloco, Bancada) class ImageThumbnailFileInput(ClearableFileInput): @@ -617,4 +617,57 @@ class BlocoForm(ModelForm): tipo=tipo, nome=bloco.nome ) - return bloco \ No newline at end of file + return bloco + + +class BancadaForm(ModelForm): + + class Meta: + model = Bancada + fields = ['legislatura', 'nome', 'partido', 'data_criacao', + 'data_extincao', 'descricao'] + + def clean(self): + super(BancadaForm, self).clean() + + if not self.is_valid(): + return self.cleaned_data + + data = self.cleaned_data + + legislatura = data['legislatura'] + + data_criacao = data['data_criacao'] + if data_criacao: + if (data_criacao < legislatura.data_inicio or + data_criacao > legislatura.data_fim): + raise ValidationError(_("Data de criação da bancada fora do intervalo" + " de legislatura informada")) + + data_extincao = data['data_extincao'] + if data_extincao: + if (data_extincao < legislatura.data_inicio or + data_extincao > legislatura.data_fim): + raise ValidationError(_("Data fim da bancada fora do intervalo de" + " legislatura informada")) + + if self.cleaned_data['data_extincao']: + if (self.cleaned_data['data_extincao'] < + self.cleaned_data['data_criacao']): + msg = _('Data de extinção não pode ser menor que a de criação') + raise ValidationError(msg) + return self.cleaned_data + + @transaction.atomic + def save(self, commit=True): + bancada = super(BancadaForm, self).save(commit) + content_type = ContentType.objects.get_for_model(Bancada) + object_id = bancada.pk + tipo = TipoAutor.objects.get(content_type=content_type) + Autor.objects.create( + content_type=content_type, + object_id=object_id, + tipo=tipo, + nome=bancada.nome + ) + return bancada diff --git a/sapl/parlamentares/migrations/0032_auto_20190619_1509.py b/sapl/parlamentares/migrations/0032_auto_20190619_1509.py new file mode 100644 index 000000000..3dd56e096 --- /dev/null +++ b/sapl/parlamentares/migrations/0032_auto_20190619_1509.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.21 on 2019-06-19 18:09 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('parlamentares', '0031_auto_20190614_1203'), + ('sessao', '0043_auto_20190506_1452'), + ] + + state_operations = [ + migrations.CreateModel( + name='Bancada', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nome', models.CharField(max_length=80, verbose_name='Nome da Bancada')), + ('data_criacao', models.DateField(null=True, verbose_name='Data Criação')), + ('data_extincao', models.DateField(blank=True, null=True, verbose_name='Data Extinção')), + ('descricao', models.TextField(blank=True, verbose_name='Descrição')), + ('legislatura', + models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Legislatura', + verbose_name='Legislatura')), + ('partido', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, + to='parlamentares.Partido', verbose_name='Partido')), + ], + options={ + 'db_table': 'parlamentares_bancada', + 'verbose_name': 'Bancada Parlamentar', + 'verbose_name_plural': 'Bancadas Parlamentares', + 'ordering': ('-legislatura__numero',), + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='CargoBancada', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nome_cargo', models.CharField(max_length=80, verbose_name='Cargo de Bancada')), + ('cargo_unico', models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, + verbose_name='Cargo Único ?')), + ], + options={ + 'db_table': 'parlamentares_cargobancada', + 'verbose_name': 'Cargo de Bancada', + 'verbose_name_plural': 'Cargos de Bancada', + }, + bases=(models.Model,), + ), + ] + + operations = [ + migrations.SeparateDatabaseAndState(state_operations=state_operations) + ] diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index 84dc06d06..e3b5de74d 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -657,3 +657,60 @@ class Bloco(models.Model): def __str__(self): return self.nome + + +@reversion.register() +class Bancada(models.Model): + legislatura = models.ForeignKey(Legislatura, + on_delete=models.PROTECT, + verbose_name=_('Legislatura')) + nome = models.CharField( + max_length=80, + verbose_name=_('Nome da Bancada')) + partido = models.ForeignKey(Partido, + blank=True, + null=True, + on_delete=models.PROTECT, + verbose_name=_('Partido')) + data_criacao = models.DateField(blank=False, null=True, + verbose_name=_('Data Criação')) + data_extincao = models.DateField(blank=True, null=True, + verbose_name=_('Data Extinção')) + descricao = models.TextField(blank=True, verbose_name=_('Descrição')) + + # campo conceitual de reversão genérica para o model Autor que dá a + # o meio possível de localização de tipos de autores. + autor = SaplGenericRelation(Autor, related_query_name='bancada_set', + fields_search=( + ('nome', '__icontains'), + ('descricao', '__icontains'), + ('partido__sigla', '__icontains'), + ('partido__nome', '__icontains'), + )) + + class Meta: + db_table = 'parlamentares_bancada' + verbose_name = _('Bancada Parlamentar') + verbose_name_plural = _('Bancadas Parlamentares') + ordering = ('-legislatura__numero', ) + + def __str__(self): + return self.nome + + +@reversion.register() +class CargoBancada(models.Model): + nome_cargo = models.CharField(max_length=80, + verbose_name=_('Cargo de Bancada')) + + cargo_unico = models.BooleanField(default=False, + choices=YES_NO_CHOICES, + verbose_name=_('Cargo Único ?')) + + class Meta: + db_table = 'parlamentares_cargobancada' + verbose_name = _('Cargo de Bancada') + verbose_name_plural = _('Cargos de Bancada') + + def __str__(self): + return self.nome_cargo diff --git a/sapl/parlamentares/tests/test_parlamentares.py b/sapl/parlamentares/tests/test_parlamentares.py index 7d29caebf..92fdbff54 100644 --- a/sapl/parlamentares/tests/test_parlamentares.py +++ b/sapl/parlamentares/tests/test_parlamentares.py @@ -2,7 +2,9 @@ import pytest from django.core.urlresolvers import reverse from django.utils.translation import ugettext_lazy as _ from model_mommy import mommy +from datetime import datetime +from sapl.parlamentares import forms from sapl.parlamentares.forms import FrenteForm, LegislaturaForm, MandatoForm from sapl.parlamentares.models import (Dependente, Filiacao, Legislatura, Mandato, Parlamentar, Partido, @@ -350,3 +352,59 @@ def test_frente_form_valido(): }) assert form.is_valid() + + +@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 errors['data_criacao'] == [_('Este campo é obrigatório.')] + + assert len(errors) == 3 + + +def data(valor): + return datetime.strptime(valor, '%Y-%m-%d').date() + + +@pytest.mark.django_db(transaction=False) +def test_bancada_form_valido(): + legislatura = mommy.make(Legislatura, + data_inicio=data('2017-11-10'), + data_fim=data('2017-12-31'), + ) + 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, + data_inicio=data('2017-11-10'), + data_fim=data('2017-12-31'), + ) + 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() diff --git a/sapl/parlamentares/urls.py b/sapl/parlamentares/urls.py index 7de476912..0c9a89ca6 100644 --- a/sapl/parlamentares/urls.py +++ b/sapl/parlamentares/urls.py @@ -2,6 +2,7 @@ from django.conf.urls import include, url from sapl.parlamentares.views import (CargoMesaCrud, ColigacaoCrud, ComposicaoColigacaoCrud, DependenteCrud, + BancadaCrud, CargoBancadaCrud, FiliacaoCrud, FrenteCrud, FrenteList, LegislaturaCrud, MandatoCrud, MesaDiretoraView, NivelInstrucaoCrud, @@ -21,7 +22,7 @@ from sapl.parlamentares.views import (CargoMesaCrud, ColigacaoCrud, lista_parlamentares, parlamentares_filiados, BlocoCrud, - PesquisarParlamentarView, + PesquisarParlamentarView, VincularParlamentarView, deleta_historico_partido, get_sessoes_legislatura) @@ -41,13 +42,13 @@ urlpatterns = [ )), url(r'^parlamentar/lista$', lista_parlamentares, name='lista_parlamentares'), - + url(r'^parlamentar/pesquisar-parlamentar/', PesquisarParlamentarView.as_view(), name='pesquisar_parlamentar'), - + url(r'^parlamentar/deleta_partido/(?P\d+)/$', deleta_historico_partido, name='deleta_historico_partido'), - + url(r'^parlamentar/(?P\d+)/materias$', ParlamentarMateriasView.as_view(), name='parlamentar_materias'), @@ -56,9 +57,16 @@ urlpatterns = [ url(r'^sistema/coligacao/', include(ColigacaoCrud.get_urls() + - ComposicaoColigacaoCrud.get_urls())), + ComposicaoColigacaoCrud.get_urls())), + + url(r'^sistema/bancada/', + include(BancadaCrud.get_urls())), + url(r'^sistema/cargo-bancada/', + include(CargoBancadaCrud.get_urls())), + url(r'^sistema/bloco/', include(BlocoCrud.get_urls())), + url(r'^sistema/frente/', include(FrenteCrud.get_urls())), url(r'^sistema/frente/atualiza-lista-parlamentares', @@ -101,7 +109,7 @@ urlpatterns = [ url(r'^mesa-diretora/remove-parlamentar-composicao/$', remove_parlamentar_composicao, name='remove_parlamentar_composicao'), - url(r'^parlamentar/get-sessoes-legislatura/$', + url(r'^parlamentar/get-sessoes-legislatura/$', get_sessoes_legislatura, name='get_sessoes_legislatura'), - + ] diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 7267f87b6..db2865052 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -33,18 +33,17 @@ from sapl.materia.models import Autoria, Proposicao, Relatoria from sapl.parlamentares.apps import AppConfig from sapl.utils import (parlamentares_ativos, show_results_filter_set) -from .forms import (FiliacaoForm, FrenteForm, LegislaturaForm, MandatoForm, - ParlamentarCreateForm, ParlamentarForm, VotanteForm, - ParlamentarFilterSet, VincularParlamentarForm, - BlocoForm) - -from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, +from .forms import (BancadaForm, FiliacaoForm, FrenteForm, LegislaturaForm, MandatoForm, + ParlamentarCreateForm, ParlamentarForm, VotanteForm, ParlamentarFilterSet, + VincularParlamentarForm, BlocoForm) +from .models import (Bancada, CargoBancada, CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, Dependente, Filiacao, Frente, Legislatura, Mandato, NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, SituacaoMilitar, TipoAfastamento, TipoDependente, Votante, Bloco, HistoricoPartido) +CargoBancadaCrud = CrudAux.build(CargoBancada, '') CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa') TipoDependenteCrud = CrudAux.build(TipoDependente, 'tipo_dependente') NivelInstrucaoCrud = CrudAux.build(NivelInstrucao, 'nivel_instrucao') @@ -109,6 +108,16 @@ class VotanteView(MasterDetailCrud): kwargs={'pk': obj.parlamentar.pk})) +class BancadaCrud(CrudAux): + model = Bancada + + class CreateView(CrudAux.CreateView): + form_class = BancadaForm + + def get_success_url(self): + return reverse('sapl.parlamentares:bancada_list') + + class FrenteList(MasterDetailCrud): model = Frente is_m2m = True diff --git a/sapl/rules/map_rules.py b/sapl/rules/map_rules.py index 88637ddf2..20da36fe6 100644 --- a/sapl/rules/map_rules.py +++ b/sapl/rules/map_rules.py @@ -282,11 +282,10 @@ rules_group_geral = { (parlamentares.ComposicaoMesa, __base__, __perms_publicas__), (parlamentares.Frente, __base__, __perms_publicas__), (parlamentares.Votante, __base__, __perms_publicas__), + (parlamentares.Bancada, __base__, __perms_publicas__), + (parlamentares.CargoBancada, __base__, __perms_publicas__), (parlamentares.Bloco, __base__, __perms_publicas__), - - (sessao.CargoBancada, __base__, __perms_publicas__), - (sessao.Bancada, __base__, __perms_publicas__), (sessao.TipoSessaoPlenaria, __base__, __perms_publicas__), (sessao.TipoResultadoVotacao, __base__, __perms_publicas__), (sessao.TipoExpediente, __base__, __perms_publicas__), diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index 8ea9d4c98..ec9ab1267 100644 --- a/sapl/sessao/forms.py +++ b/sapl/sessao/forms.py @@ -23,7 +23,7 @@ from sapl.utils import (RANGE_DIAS_MES, RANGE_MESES, autor_modal, timezone, choice_anos_com_sessaoplenaria, FileFieldCheckMixin) -from .models import (Bancada, ExpedienteMateria, JustificativaAusencia, +from .models import (ExpedienteMateria, JustificativaAusencia, Orador, OradorExpediente, OrdemDia, PresencaOrdemDia, SessaoPlenaria, SessaoPlenariaPresenca, TipoResultadoVotacao, OcorrenciaSessao, RetiradaPauta, TipoRetiradaPauta, OradorOrdemDia, ORDENACAO_RESUMO, @@ -259,59 +259,6 @@ class RetiradaPautaForm(ModelForm): return retirada -class BancadaForm(ModelForm): - - class Meta: - model = Bancada - fields = ['legislatura', 'nome', 'partido', 'data_criacao', - 'data_extincao', 'descricao'] - - def clean(self): - super(BancadaForm, self).clean() - - if not self.is_valid(): - return self.cleaned_data - - data = self.cleaned_data - - legislatura = data['legislatura'] - - data_criacao = data['data_criacao'] - if data_criacao: - if (data_criacao < legislatura.data_inicio or - data_criacao > legislatura.data_fim): - raise ValidationError(_("Data de criação da bancada fora do intervalo" - " de legislatura informada")) - - data_extincao = data['data_extincao'] - if data_extincao: - if (data_extincao < legislatura.data_inicio or - data_extincao > legislatura.data_fim): - raise ValidationError(_("Data fim da bancada fora do intervalo de" - " legislatura informada")) - - if self.cleaned_data['data_extincao']: - if (self.cleaned_data['data_extincao'] < - self.cleaned_data['data_criacao']): - msg = _('Data de extinção não pode ser menor que a de criação') - raise ValidationError(msg) - return self.cleaned_data - - @transaction.atomic - def save(self, commit=True): - bancada = super(BancadaForm, self).save(commit) - content_type = ContentType.objects.get_for_model(Bancada) - object_id = bancada.pk - tipo = TipoAutor.objects.get(content_type=content_type) - Autor.objects.create( - content_type=content_type, - object_id=object_id, - tipo=tipo, - nome=bancada.nome - ) - return bancada - - class ExpedienteMateriaForm(ModelForm): _model = ExpedienteMateria diff --git a/sapl/sessao/migrations/0043_auto_20190506_1452.py b/sapl/sessao/migrations/0043_auto_20190506_1452.py new file mode 100644 index 000000000..8827e906b --- /dev/null +++ b/sapl/sessao/migrations/0043_auto_20190506_1452.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-06 17:52 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('sessao', '0042_merge_20190612_0925'), + ] + + database_operations = [ + migrations.AlterModelTable('Bancada', 'parlamentares_bancada'), + migrations.AlterModelTable('CargoBancada', 'parlamentares_cargobancada') + ] + + state_operations = [ + migrations.DeleteModel('Bancada'), + migrations.DeleteModel('CargoBancada') + ] + + operations = [ + migrations.SeparateDatabaseAndState( + database_operations=database_operations, + state_operations=state_operations + ), + migrations.RunSQL( + """UPDATE django_content_type SET app_label = 'parlamentares' + WHERE app_label = 'sessao' + AND (model = 'bancada' OR model = 'cargobancada');""" + ), + ] diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index d438caa9a..04c08ec16 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -17,61 +17,6 @@ from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation, restringe_tipos_de_arquivo_txt, texto_upload_path) -@reversion.register() -class CargoBancada(models.Model): - nome_cargo = models.CharField(max_length=80, - verbose_name=_('Cargo de Bancada')) - - cargo_unico = models.BooleanField(default=False, - choices=YES_NO_CHOICES, - verbose_name=_('Cargo Único ?')) - - class Meta: - verbose_name = _('Cargo de Bancada') - verbose_name_plural = _('Cargos de Bancada') - - def __str__(self): - return self.nome_cargo - - -@reversion.register() -class Bancada(models.Model): - legislatura = models.ForeignKey(Legislatura, - on_delete=models.PROTECT, - verbose_name=_('Legislatura')) - nome = models.CharField( - max_length=80, - verbose_name=_('Nome da Bancada')) - partido = models.ForeignKey(Partido, - blank=True, - null=True, - on_delete=models.PROTECT, - verbose_name=_('Partido')) - data_criacao = models.DateField(blank=False, null=True, - verbose_name=_('Data Criação')) - data_extincao = models.DateField(blank=True, null=True, - verbose_name=_('Data Extinção')) - descricao = models.TextField(blank=True, verbose_name=_('Descrição')) - - # campo conceitual de reversão genérica para o model Autor que dá a - # o meio possível de localização de tipos de autores. - autor = SaplGenericRelation(Autor, related_query_name='bancada_set', - fields_search=( - ('nome', '__icontains'), - ('descricao', '__icontains'), - ('partido__sigla', '__icontains'), - ('partido__nome', '__icontains'), - )) - - class Meta: - verbose_name = _('Bancada Parlamentar') - verbose_name_plural = _('Bancadas Parlamentares') - ordering = ('-legislatura__numero', ) - - def __str__(self): - return self.nome - - @reversion.register() class TipoSessaoPlenaria(models.Model): diff --git a/sapl/sessao/tests/test_sessao.py b/sapl/sessao/tests/test_sessao.py index 3ed1e47f6..4e5282038 100644 --- a/sapl/sessao/tests/test_sessao.py +++ b/sapl/sessao/tests/test_sessao.py @@ -1,11 +1,10 @@ import pytest -from datetime import datetime from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ from model_mommy import mommy from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa -from sapl.parlamentares.models import Legislatura, Parlamentar, Partido,SessaoLegislativa +from sapl.parlamentares.models import Legislatura, Parlamentar, Partido, SessaoLegislativa from sapl.sessao import forms from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao, IntegranteMesa, Orador, OrdemDia, @@ -76,61 +75,6 @@ def test_numero_duplicado_sessao_plenaria_form(): "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 errors['data_criacao'] == [_('Este campo é obrigatório.')] - - assert len(errors) == 3 - - -def data(valor): - return datetime.strptime(valor, '%Y-%m-%d').date() - - -@pytest.mark.django_db(transaction=False) -def test_bancada_form_valido(): - legislatura = mommy.make(Legislatura, - data_inicio=data('2017-11-10'), - data_fim=data('2017-12-31'), - ) - 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, - data_inicio=data('2017-11-10'), - data_fim=data('2017-12-31'), - ) - 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() - @pytest.mark.django_db(transaction=False) def test_expediente_materia_form_valido(): tipo_materia = mommy.make(TipoMateriaLegislativa) diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index ec8eea9f0..19e5a37e7 100644 --- a/sapl/sessao/urls.py +++ b/sapl/sessao/urls.py @@ -1,9 +1,8 @@ from django.conf.urls import include, url from sapl.sessao.views import (AdicionarVariasMateriasExpediente, - AdicionarVariasMateriasOrdemDia, BancadaCrud, - CargoBancadaCrud, ExpedienteMateriaCrud, - ExpedienteView, JustificativaAusenciaCrud, + AdicionarVariasMateriasOrdemDia, + ExpedienteMateriaCrud, ExpedienteView, JustificativaAusenciaCrud, OcorrenciaSessaoView, MateriaOrdemDiaCrud, OradorOrdemDiaCrud, MesaView, OradorCrud, OradorExpedienteCrud, PainelView, @@ -99,10 +98,6 @@ urlpatterns = [ include(TipoJustificativaCrud.get_urls())), url(r'^sistema/sessao-plenaria/tipo-retirada-pauta/', include(TipoRetiradaPautaCrud.get_urls())), - url(r'^sistema/bancada/', - include(BancadaCrud.get_urls())), - url(r'^sistema/cargo-bancada/', - include(CargoBancadaCrud.get_urls())), url(r'^sistema/resumo-ordenacao/', resumo_ordenacao, name='resumo_ordenacao'), diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index f8911a880..3cbddee5a 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -40,14 +40,13 @@ from sapl.sessao.apps import AppConfig from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm from sapl.utils import show_results_filter_set, remover_acentos, get_client_ip, filiacao_data -from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, - ExpedienteForm, JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm, +from .forms import (AdicionarVariasMateriasFilterSet, ExpedienteForm, + JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm, MesaForm, OradorExpedienteForm, OradorForm, PautaSessaoFilterSet, PresencaForm, SessaoPlenariaFilterSet, SessaoPlenariaForm, VotacaoEditForm, VotacaoForm, VotacaoNominalForm, RetiradaPautaForm, OradorOrdemDiaForm) -from .models import (Bancada, CargoBancada, CargoMesa, - ExpedienteMateria, ExpedienteSessao, OcorrenciaSessao, IntegranteMesa, +from .models import (CargoMesa, ExpedienteMateria, ExpedienteSessao, OcorrenciaSessao, IntegranteMesa, MateriaLegislativa, Orador, OradorExpediente, OrdemDia, PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao, SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente, @@ -57,7 +56,6 @@ from .models import (Bancada, CargoBancada, CargoMesa, TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria') TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa') -CargoBancadaCrud = CrudAux.build(CargoBancada, '') TipoResultadoVotacaoCrud = CrudAux.build( TipoResultadoVotacao, 'tipo_resultado_votacao') TipoRetiradaPautaCrud = CrudAux.build(TipoRetiradaPauta, 'tipo_retirada_pauta') @@ -473,11 +471,11 @@ class TipoExpedienteCrud(CrudAux): model = TipoExpediente class DeleteView(CrudAux.DeleteView): - + def delete(self, *args, **kwargs): self.object = self.get_object() - - # Se todas as referências a este tipo forem de conteúdo vazio, + + # Se todas as referências a este tipo forem de conteúdo vazio, # significa que pode ser apagado if self.object.expedientesessao_set.filter(conteudo='').count() == \ self.object.expedientesessao_set.all().count(): @@ -693,7 +691,7 @@ class OradorExpedienteCrud(OradorCrud): context.update({'subnav_template_name': 'sessao/subnav-solene.yaml'}) return context - + class DetailView(MasterDetailCrud.DetailView): def get_context_data(self, **kwargs): @@ -737,7 +735,7 @@ class OradorExpedienteCrud(OradorCrud): if tipo_sessao.nome == "Solene": context.update({'subnav_template_name': 'sessao/subnav-solene.yaml'}) return context - + def get_success_url(self): return reverse('sapl.sessao:oradorexpediente_list', @@ -810,16 +808,6 @@ class OradorOrdemDiaCrud(OradorCrud): return initial -class BancadaCrud(CrudAux): - model = Bancada - - class CreateView(CrudAux.CreateView): - form_class = BancadaForm - - def get_success_url(self): - return reverse('sapl.sessao:bancada_list') - - def recuperar_numero_sessao_view(request): try: tipo = TipoSessaoPlenaria.objects.get(pk=request.GET.get('tipo', '0')) @@ -1331,7 +1319,7 @@ class MesaView(FormMixin, DetailView): if tipo_sessao.nome == "Solene": context.update({'subnav_template_name': 'sessao/subnav-solene.yaml'}) return context - + def get_success_url(self): pk = self.kwargs['pk'] return reverse('sapl.sessao:mesa', kwargs={'pk': pk}) @@ -1513,7 +1501,7 @@ def resumo_ordenacao(request): } if request.method == 'GET': return render(request, 'sessao/resumo_ordenacao.html', context) - elif request.method == 'POST': + elif request.method == 'POST': ordenacao.primeiro = ast.literal_eval(request.POST['0'])[0] ordenacao.segundo = ast.literal_eval(request.POST['1'])[0] ordenacao.terceiro = ast.literal_eval(request.POST['2'])[0] @@ -2328,7 +2316,7 @@ class VotacaoView(SessaoPermissionMixin): ordem_id = kwargs['oid'] ordem = OrdemDia.objects.get(id=ordem_id) - + presentes_id = [ presente.parlamentar.id for presente in PresencaOrdemDia.objects.filter( sessao_plenaria_id=self.kwargs['pk'] @@ -3013,7 +3001,7 @@ class VotacaoExpedienteView(SessaoPermissionMixin): expediente_id = kwargs['oid'] expediente = ExpedienteMateria.objects.get(id=expediente_id) - + presentes_id = [ presente.parlamentar.id for presente in SessaoPlenariaPresenca.objects.filter( sessao_plenaria_id=self.kwargs['pk'] @@ -3834,7 +3822,7 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie if request.POST['origem'] == 'ordem': ordens = OrdemDia.objects.filter( id__in=request.POST.getlist('marcadas_1')) - + presentes_id = [ presente.parlamentar.id for presente in PresencaOrdemDia.objects.filter( sessao_plenaria_id=self.kwargs['pk'] @@ -3853,7 +3841,7 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie else: expedientes = ExpedienteMateria.objects.filter( id__in=request.POST.getlist('marcadas_1')) - + presentes_id = [ presente.parlamentar.id for presente in SessaoPlenariaPresenca.objects.filter( sessao_plenaria_id=self.kwargs['pk'] @@ -3993,7 +3981,7 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie if self.request.POST['origem'] == 'ordem': ordens = OrdemDia.objects.filter( id__in=self.request.POST.getlist('ordens')) - + presentes_id = [ presente.parlamentar.id for presente in PresencaOrdemDia.objects.filter( sessao_plenaria_id=self.kwargs['pk'] @@ -4007,12 +3995,12 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie qtde_ativos = len(presenca_ativos) context.update({'ordens': ordens, - 'total_presentes': qtde_presentes, + 'total_presentes': qtde_presentes, 'total_votantes': qtde_ativos}) elif self.request.POST['origem'] == 'expediente': expedientes = ExpedienteMateria.objects.filter( id__in=self.request.POST.getlist('expedientes')) - + presentes_id = [ presente.parlamentar.id for presente in SessaoPlenariaPresenca.objects.filter( sessao_plenaria_id=self.kwargs['pk'] diff --git a/sapl/templates/menu_tabelas_auxiliares.yaml b/sapl/templates/menu_tabelas_auxiliares.yaml index 45d3638a9..bb0abff74 100644 --- a/sapl/templates/menu_tabelas_auxiliares.yaml +++ b/sapl/templates/menu_tabelas_auxiliares.yaml @@ -69,10 +69,10 @@ css_class: head_title children: - title: {% trans 'Bancadas Parlamentares' %} - url: sapl.sessao:bancada_list + url: sapl.parlamentares:bancada_list css_class: btn btn-link - title: {% trans 'Cargo de Bancada Parlamentar' %} - url: sapl.sessao:cargobancada_list + url: sapl.parlamentares:cargobancada_list css_class: btn btn-link - title: {% trans 'Frente Parlamentar' %} url: sapl.parlamentares:frente_list diff --git a/sapl/templates/parlamentares/layouts.yaml b/sapl/templates/parlamentares/layouts.yaml index 7c3e59908..a2a1b3aab 100644 --- a/sapl/templates/parlamentares/layouts.yaml +++ b/sapl/templates/parlamentares/layouts.yaml @@ -116,6 +116,17 @@ ComposicaoColigacao: {% trans 'Nome do Partido' %}: - partido +Bancada: + {% trans 'Bancada' %}: + - legislatura + - nome partido + - data_criacao data_extincao + - descricao + +CargoBancada: + {% trans 'Cargo de Bancada' %}: + - nome_cargo:8 cargo_unico + Frente: {% trans 'Frente' %}: - nome diff --git a/sapl/templates/sessao/layouts.yaml b/sapl/templates/sessao/layouts.yaml index caeafc963..661a65554 100644 --- a/sapl/templates/sessao/layouts.yaml +++ b/sapl/templates/sessao/layouts.yaml @@ -82,17 +82,6 @@ OrdemDiaDetail: - tipo_votacao - observacao -Bancada: - {% trans 'Bancada' %}: - - legislatura - - nome partido - - data_criacao data_extincao - - descricao - -CargoBancada: - {% trans 'Cargo de Bancada' %}: - - nome_cargo:8 cargo_unico - TipoJustificativa: {% trans 'Tipo de Justificativa' %}: - descricao diff --git a/sapl/templates/sistema.html b/sapl/templates/sistema.html index a3e56780e..5f4e84884 100644 --- a/sapl/templates/sistema.html +++ b/sapl/templates/sistema.html @@ -50,8 +50,8 @@

Módulo Bancadas Parlamentares