From 937d5bc92dff4199a7755f179c61a37c4181f010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Thu, 30 May 2019 16:43:57 -0300 Subject: [PATCH] =?UTF-8?q?Transfere=20migra=C3=A7=C3=B5es=20de=20Bancada?= =?UTF-8?q?=20e=20CargoBancada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 52 ++++++++--------- sapl/legacy/test_renames.py | 9 ++- sapl/parlamentares/forms.py | 57 +++++++++++++++++- .../migrations/0030_auto_20190520_1542.py | 58 +++++++++++++++++++ sapl/parlamentares/models.py | 57 ++++++++++++++++++ .../parlamentares/tests/test_parlamentares.py | 58 +++++++++++++++++++ sapl/parlamentares/urls.py | 11 +++- sapl/parlamentares/views.py | 21 +++++-- sapl/rules/map_rules.py | 5 +- sapl/sessao/forms.py | 55 +----------------- .../migrations/0041_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 | 26 +++------ sapl/templates/menu_tabelas_auxiliares.yaml | 4 +- sapl/templates/parlamentares/layouts.yaml | 11 ++++ sapl/templates/sessao/layouts.yaml | 11 ---- sapl/templates/sistema.html | 4 +- 19 files changed, 344 insertions(+), 251 deletions(-) create mode 100644 sapl/parlamentares/migrations/0030_auto_20190520_1542.py create mode 100644 sapl/sessao/migrations/0041_auto_20190506_1452.py diff --git a/sapl/base/views.py b/sapl/base/views.py index c56b5e880..704ebee50 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -38,12 +38,12 @@ from sapl.crud.base import CrudAux, make_pagination from sapl.materia.models import (Autoria, MateriaLegislativa, Proposicao, TipoMateriaLegislativa, StatusTramitacao, UnidadeTramitacao) from sapl.norma.models import (NormaJuridica, NormaEstatisticas) -from sapl.parlamentares.models import Parlamentar, Legislatura, Mandato, Filiacao -from sapl.protocoloadm.models import (Protocolo, TipoDocumentoAdministrativo, - StatusTramitacaoAdministrativo, +from sapl.parlamentares.models import Parlamentar, Legislatura, Mandato, Filiacao, Bancada +from sapl.protocoloadm.models import (Protocolo, TipoDocumentoAdministrativo, + StatusTramitacaoAdministrativo, DocumentoAdministrativo) 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) @@ -298,7 +298,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 @@ -824,9 +824,9 @@ class RelatorioNormasPublicadasMesView(FilterView): if not meses[norma.data.month] in normas_mes: normas_mes[meses[norma.data.month]] = [] normas_mes[meses[norma.data.month]].append(norma) - + context['normas_mes'] = normas_mes - + quant_normas_mes = {} for key in normas_mes.keys(): quant_normas_mes[key] = len(normas_mes[key]) @@ -852,7 +852,7 @@ class RelatorioNormasVigenciaView(FilterView): vigencia = kwargs['data']['vigencia'] if ano: qs = qs.filter(ano=ano) - + if vigencia == 'True': qs_dt_not_null = qs.filter(data_vigencia__isnull=True) qs = (qs_dt_not_null | qs.filter(data_vigencia__gte=datetime.datetime.now().date())).distinct() @@ -875,7 +875,7 @@ class RelatorioNormasVigenciaView(FilterView): return context normas_totais = NormaJuridica.objects.filter(ano=self.request.GET['ano']) - + context['quant_total'] = len(normas_totais) if self.request.GET['vigencia'] == 'True': context['vigencia'] = 'Vigente' @@ -910,7 +910,7 @@ class EstatisticasAcessoNormas(TemplateView): return self.render_to_response(context) context['ano'] = self.request.GET['ano'] - + query = ''' select norma_id, ano, extract(month from horario_acesso) as mes, count(*) from norma_normaestatisticas @@ -925,18 +925,18 @@ class EstatisticasAcessoNormas(TemplateView): normas_mes = collections.OrderedDict() meses = {1: 'Janeiro', 2: 'Fevereiro', 3:'Março', 4: 'Abril', 5: 'Maio', 6:'Junho', 7: 'Julho', 8: 'Agosto', 9:'Setembro', 10:'Outubro', 11:'Novembro', 12:'Dezembro'} - + for row in rows: if not meses[int(row[2])] in normas_mes: normas_mes[meses[int(row[2])]] = [] norma_est = [NormaJuridica.objects.get(id=row[0]), row[3]] normas_mes[meses[int(row[2])]].append(norma_est) - + # Ordena por acesso e limita em 5 for n in normas_mes: sorted_by_value = sorted(normas_mes[n], key=lambda kv: kv[1], reverse=True) normas_mes[n] = sorted_by_value[0:5] - + context['normas_mes'] = normas_mes return self.render_to_response(context) @@ -995,7 +995,7 @@ class ListarInconsistenciasView(PermissionRequiredMixin, ListView): tabela.append( ('parlamentares_filiacoes_intersecao', 'Parlamentares com filiações em interseção', - len(parlamentares_filiacoes_intersecao()) + len(parlamentares_filiacoes_intersecao()) ) ) tabela.append( @@ -1167,7 +1167,7 @@ class ListarParlFiliacoesIntersecaoView(PermissionRequiredMixin, ListView): context[ 'NO_ENTRIES_MSG' ] = 'Nenhum encontrado.' - return context + return context def parlamentares_mandatos_intersecao(): @@ -1232,7 +1232,7 @@ class ListarParlamentaresDuplicadosView(PermissionRequiredMixin, ListView): def get_queryset(self): return parlamentares_duplicados() - + def get_context_data(self, **kwargs): context = super( ListarParlamentaresDuplicadosView, self).get_context_data(**kwargs) @@ -1244,7 +1244,7 @@ class ListarParlamentaresDuplicadosView(PermissionRequiredMixin, ListView): 'NO_ENTRIES_MSG' ] = 'Nenhum encontrado.' return context - + def mandato_sem_data_inicio(): return Mandato.objects.filter(data_inicio_mandato__isnull=True).order_by('parlamentar') @@ -1316,7 +1316,7 @@ class ListarFiliacoesSemDataFiliacaoView(PermissionRequiredMixin, ListView): def get_queryset(self): return filiacoes_sem_data_filiacao() - + def get_context_data(self, **kwargs): context = super( ListarFiliacoesSemDataFiliacaoView, self @@ -1368,14 +1368,14 @@ class ListarMatProtocoloInexistenteView(PermissionRequiredMixin, ListView): def protocolos_com_materias(): protocolos = {} - + for m in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False).order_by('-ano', 'numero_protocolo'): if Protocolo.objects.filter(numero=m.numero_protocolo, ano=m.ano).exists(): key = "{}/{}".format(m.numero_protocolo, m.ano) val = protocolos.get(key, list()) val.append(m) protocolos[key] = val - + return [(v[0], len(v)) for (k, v) in protocolos.items() if len(v) > 1] @@ -1464,9 +1464,9 @@ class PesquisarUsuarioView(PermissionRequiredMixin, FilterView): context['page_range'] = make_pagination( page_obj.number, paginator.num_pages) - + context['NO_ENTRIES_MSG'] = 'Nenhum usuário encontrado!' - + context['title'] = _('Usuários') return context @@ -1535,9 +1535,9 @@ class DeleteUsuarioView(PermissionRequiredMixin, DeleteView): template_name = "crud/confirm_delete.html" permission_required = ('base.delete_appconfig',) success_url = reverse_lazy('sapl.base:usuario') - success_message = "Usuário removido com sucesso!" + success_message = "Usuário removido com sucesso!" - def delete(self, request, *args, **kwargs): + def delete(self, request, *args, **kwargs): try: super(DeleteUsuarioView, self).delete(request, *args, **kwargs) except ProtectedError as exception: @@ -1811,7 +1811,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)) @@ -1867,4 +1867,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/0030_auto_20190520_1542.py b/sapl/parlamentares/migrations/0030_auto_20190520_1542.py new file mode 100644 index 000000000..f81a42835 --- /dev/null +++ b/sapl/parlamentares/migrations/0030_auto_20190520_1542.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-20 18:42 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('parlamentares', '0029_auto_20190517_1531'), + ('sessao', '0041_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 d50600eba..51e36765c 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -602,3 +602,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 e5f607a09..c640487cd 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, @@ -348,3 +350,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 4c1434333..6bc61a554 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, @@ -46,9 +47,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', @@ -90,5 +98,4 @@ urlpatterns = [ url(r'^mesa-diretora/remove-parlamentar-composicao/$', remove_parlamentar_composicao, name='remove_parlamentar_composicao'), - ] diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 874f53385..fb60807ca 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) +CargoBancadaCrud = CrudAux.build(CargoBancada, '') CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa') TipoDependenteCrud = CrudAux.build(TipoDependente, 'tipo_dependente') NivelInstrucaoCrud = CrudAux.build(NivelInstrucao, 'nivel_instrucao') @@ -102,6 +101,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 4f1b4b515..06e23bf1c 100644 --- a/sapl/rules/map_rules.py +++ b/sapl/rules/map_rules.py @@ -279,11 +279,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 c09d2f220..20be45031 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, @@ -269,59 +269,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/0041_auto_20190506_1452.py b/sapl/sessao/migrations/0041_auto_20190506_1452.py new file mode 100644 index 000000000..a73f9fb69 --- /dev/null +++ b/sapl/sessao/migrations/0041_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', '0040_auto_20190523_1130'), + ] + + 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 53721499b..211a08a89 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -16,61 +16,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): nome = models.CharField(max_length=30, verbose_name=_('Tipo')) 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 d5d709967..6fcc09dd1 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, @@ -94,10 +93,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/', ResumoOrdenacaoView.as_view(), name='resumo_ordenacao'), diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 93dd7fd9e..7625c56a9 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -37,14 +37,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 -from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, - ExpedienteForm, JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm, +from .forms import (AdicionarVariasMateriasFilterSet, ExpedienteForm, + JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm, MesaForm, OradorExpedienteForm, OradorForm, PautaSessaoFilterSet, PresencaForm, ResumoOrdenacaoForm, 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, @@ -55,7 +54,6 @@ from .models import (Bancada, CargoBancada, CargoMesa, TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria') TipoExpedienteCrud = CrudAux.build(TipoExpediente, 'tipo_expediente') TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa') -CargoBancadaCrud = CrudAux.build(CargoBancada, '') TipoResultadoVotacaoCrud = CrudAux.build( TipoResultadoVotacao, 'tipo_resultado_votacao') TipoRetiradaPautaCrud = CrudAux.build(TipoRetiradaPauta, 'tipo_retirada_pauta') @@ -667,16 +665,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(request): try: sessao = SessaoPlenaria.objects.filter( @@ -1600,7 +1588,7 @@ def get_oradores_ordemdia(sessao_plenaria): observacao = orador.observacao parlamentar = Parlamentar.objects.get( id=orador.parlamentar_id - ) + ) o = { 'numero_ordem': numero_ordem, 'url_discurso': url_discurso, @@ -1610,9 +1598,9 @@ def get_oradores_ordemdia(sessao_plenaria): oradores.append(o) context = {'oradores_ordemdia': oradores} - return context + return context + - def get_oradores_explicações_pessoais(sessao_plenaria): oradores_explicacoes = [] for orador in Orador.objects.filter( @@ -1729,7 +1717,7 @@ class ResumoView(DetailView): # ===================================================================== # Oradores Ordem do Dia context.update(get_oradores_ordemdia(self.object)) - # ===================================================================== + # ===================================================================== # Oradores nas Explicações Pessoais context.update(get_oradores_explicações_pessoais(self.object)) # ===================================================================== diff --git a/sapl/templates/menu_tabelas_auxiliares.yaml b/sapl/templates/menu_tabelas_auxiliares.yaml index 9a9c40d8d..1c9fe2505 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 16e353910..0f65d8bc0 100644 --- a/sapl/templates/sessao/layouts.yaml +++ b/sapl/templates/sessao/layouts.yaml @@ -73,17 +73,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

- - + +