From 26efdf6c5b1641c7fd9e25d71b4b4d8d88993377 Mon Sep 17 00:00:00 2001 From: Ricardo Lima Canela Date: Mon, 24 Aug 2020 12:41:11 -0300 Subject: [PATCH] Refatora model de Frente Parlamentar (#3023) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vinícius Cantuária --- sapl/parlamentares/forms.py | 32 +++++-- .../migrations/0032_frente_parlamentar.py | 68 +++++++++++++ sapl/parlamentares/models.py | 57 ++++++++++- sapl/parlamentares/urls.py | 14 ++- sapl/parlamentares/views.py | 69 +++++++++++++- sapl/rules/map_rules.py | 2 + sapl/templates/menu_tabelas_auxiliares.yaml | 3 + .../parlamentares/frente_detail.html | 9 ++ sapl/templates/parlamentares/frente_form.html | 95 +------------------ .../parlamentares/frenteparlamentar_list.html | 9 ++ sapl/templates/parlamentares/layouts.yaml | 19 +++- .../parlamentar_frentes_list.html | 42 ++++++++ sapl/templates/parlamentares/subnav.yaml | 2 +- 13 files changed, 304 insertions(+), 117 deletions(-) create mode 100644 sapl/parlamentares/migrations/0032_frente_parlamentar.py create mode 100644 sapl/templates/parlamentares/frente_detail.html create mode 100644 sapl/templates/parlamentares/frenteparlamentar_list.html create mode 100644 sapl/templates/parlamentares/parlamentar_frentes_list.html diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py index 2f2cd49c3..a8ab4a111 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, FrenteParlamentar) class ImageThumbnailFileInput(ClearableFileInput): @@ -428,11 +428,7 @@ class FrenteForm(ModelForm): logger = logging.getLogger(__name__) def __init__(self, *args, **kwargs): - super(FrenteForm, self).__init__(*args, **kwargs) - self.fields['parlamentares'].queryset = Parlamentar.objects.filter( - ativo=True).order_by('nome_completo') - self.fields['parlamentares'].label = _('Parlamentares \ - (Mantenha CTRL pressionado para selecionar vários)') + super().__init__(*args, **kwargs) class Meta: model = Frente @@ -470,6 +466,30 @@ class FrenteForm(ModelForm): return frente +class FrenteParlamentarForm(ModelForm): + logger = logging.getLogger(__name__) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['frente'].widget = forms.HiddenInput() + + class Meta: + model = FrenteParlamentar + fields = '__all__' + + def clean(self): + cd = super().clean() + if not self.is_valid(): + return self.cleaned_data + + if cd['cargo'].cargo_unico: + frente_parlamentar = FrenteParlamentar.objects.filter(frente=cd['frente'], cargo=cd['cargo']) + if frente_parlamentar and not frente_parlamentar[0].parlamentar == cd['parlamentar']: + raise ValidationError(_("Cargo único já ocupado por outro parlamentar.")) + + return cd + + class VotanteForm(ModelForm): username = forms.CharField( diff --git a/sapl/parlamentares/migrations/0032_frente_parlamentar.py b/sapl/parlamentares/migrations/0032_frente_parlamentar.py new file mode 100644 index 000000000..e2550c64e --- /dev/null +++ b/sapl/parlamentares/migrations/0032_frente_parlamentar.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.29 on 2020-08-07 12:50 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +def cria_parlamentar_em_frente(apps, schema_editor): + Frente = apps.get_model("parlamentares", "Frente") + FrenteCargo = apps.get_model("parlamentares", "FrenteCargo") + FrenteParlamentar = apps.get_model("parlamentares", "FrenteParlamentar") + + cargo_membro = FrenteCargo.objects.create(nome_cargo="membro", cargo_unico=False) + parlamentares_frente = [] + for frente in Frente.objects.all().prefetch_related("parlamentares"): + for parlamentar in frente.parlamentares.all(): + parlamentares_frente.append( + FrenteParlamentar( + frente=frente, + parlamentar=parlamentar, + cargo=cargo_membro, + data_entrada=frente.data_criacao)) + FrenteParlamentar.objects.bulk_create(parlamentares_frente) + + +class Migration(migrations.Migration): + + dependencies = [ + ('parlamentares', '0031_auto_20200407_1406'), + ] + + operations = [ + migrations.CreateModel( + name='FrenteCargo', + 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 frente parlamentar')), + ('cargo_unico', models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Cargo único?')), + ], + options={ + 'verbose_name': 'Cargo de Frente Parlamentar', + 'verbose_name_plural': 'Cargos de Frente Parlamentar', + 'ordering': ('cargo_unico', 'nome_cargo'), + }, + ), + migrations.CreateModel( + name='FrenteParlamentar', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('frente', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parlamentares.Frente',verbose_name='Frente parlamentar')), + ('parlamentar', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parlamentares.Parlamentar', verbose_name='Parlamentar')), + ('cargo', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='parlamentares.FrenteCargo', verbose_name='Cargo na frente parlamentar')), + ('data_entrada', models.DateField(verbose_name='Data Entrada')), + ('data_saida', models.DateField(blank=True, null=True, verbose_name='Data Saída')), + ], + options={ + 'verbose_name': 'Parlamentar de frente parlamentar', + 'verbose_name_plural': 'Parlamentares de frente parlamentar', + 'ordering': ('frente', 'parlamentar', 'cargo'), + }, + ), + migrations.RunPython(cria_parlamentar_em_frente), + migrations.RemoveField( + model_name='frente', + name='parlamentares', + ), + ] diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index 03d374e19..8b01b171d 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -518,13 +518,12 @@ class Frente(models.Model): nome = models.CharField( max_length=80, verbose_name=_('Nome da Frente')) - parlamentares = models.ManyToManyField(Parlamentar, - blank=True, - verbose_name=_('Parlamentares')) + descricao = models.TextField(blank=True, verbose_name=_('Descrição')) data_criacao = models.DateField(verbose_name=_('Data Criação')) data_extincao = models.DateField( - blank=True, null=True, verbose_name=_('Data Dissolução')) - descricao = models.TextField(blank=True, verbose_name=_('Descrição')) + blank=True, + null=True, + verbose_name=_('Data Dissoluçã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. @@ -549,6 +548,54 @@ class Frente(models.Model): return self.nome +@reversion.register() +class FrenteCargo(models.Model): + nome_cargo = models.CharField( + max_length=80, + verbose_name=_('Cargo de frente parlamentar')) + cargo_unico = models.BooleanField( + default=False, + choices=YES_NO_CHOICES, + verbose_name=_('Cargo único?')) + + class Meta: + verbose_name = _('Cargo de Frente Parlamentar') + verbose_name_plural = _('Cargos de Frente Parlamentar') + ordering = ('cargo_unico', 'nome_cargo',) + + def __str__(self): + return f"{self.nome_cargo}" + + +@reversion.register() +class FrenteParlamentar(models.Model): + frente = models.ForeignKey( + Frente, + verbose_name=_('Frente parlamentar'), + on_delete=models.CASCADE) + parlamentar = models.ForeignKey( + Parlamentar, + verbose_name=_('Parlamentar'), + on_delete=models.CASCADE) + cargo = models.ForeignKey( + FrenteCargo, + verbose_name=_('Cargo na frente parlamentar'), + on_delete=models.PROTECT) + data_entrada = models.DateField(verbose_name=_('Data Entrada')) + data_saida = models.DateField( + blank=True, + null=True, + verbose_name=_('Data Saída')) + + class Meta: + verbose_name = _('Parlamentar de frente parlamentar') + verbose_name_plural = _('Parlamentares de frente parlamentar') + ordering = ('frente', 'parlamentar', 'cargo') + + def __str__(self): + return f"{self.parlamentar} - {self.cargo.nome_cargo} - {self.frente}" + + class Votante(models.Model): parlamentar = models.ForeignKey( Parlamentar, verbose_name=_('Parlamentar'), diff --git a/sapl/parlamentares/urls.py b/sapl/parlamentares/urls.py index 60fbf3232..2b50c208c 100644 --- a/sapl/parlamentares/urls.py +++ b/sapl/parlamentares/urls.py @@ -21,7 +21,8 @@ from sapl.parlamentares.views import (CargoMesaCrud, ColigacaoCrud, remove_parlamentar_composicao, parlamentares_filiados, BlocoCrud, PesquisarParlamentarView, VincularParlamentarView, - get_sessoes_legislatura) + get_sessoes_legislatura, FrenteCargoCrud, FrenteParlamentarCrud, + get_parlamentar_frentes) from .apps import AppConfig @@ -33,7 +34,7 @@ urlpatterns = [ FiliacaoCrud.get_urls() + MandatoCrud.get_urls() + ParticipacaoParlamentarCrud.get_urls() + ProposicaoParlamentarCrud.get_urls() + - RelatoriaParlamentarCrud.get_urls() + FrenteList.get_urls() + + RelatoriaParlamentarCrud.get_urls() + VotanteView.get_urls() )), @@ -43,6 +44,8 @@ urlpatterns = [ url(r'^parlamentar/(?P\d+)/materias$', ParlamentarMateriasView.as_view(), name='parlamentar_materias'), + url(r'^parlamentar/(?P\d+)/frentes/$', get_parlamentar_frentes, name='parlamentar_frentes'), + url(r'^parlamentar/vincular-parlamentar/$', VincularParlamentarView.as_view(), name='vincular_parlamentar'), @@ -54,8 +57,11 @@ urlpatterns = [ ComposicaoColigacaoCrud.get_urls())), url(r'^sistema/bloco/', include(BlocoCrud.get_urls())), - url(r'^sistema/frente/', - include(FrenteCrud.get_urls())), + + url(r'^sistema/frente/', include(FrenteCrud.get_urls())), + url(r'^sistema/frente-cargo/', include(FrenteCargoCrud.get_urls())), + url(r'^sistema/frente-parlamentares/', include(FrenteParlamentarCrud.get_urls())), + url(r'^sistema/frente/atualiza-lista-parlamentares', frente_atualiza_lista_parlamentares, name='atualiza_lista_parlamentares'), diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 7ea6a9dc0..d6c52ac3a 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -34,17 +34,18 @@ 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, + ParlamentarCreateForm, ParlamentarForm, VotanteForm, ParlamentarFilterSet, VincularParlamentarForm, - BlocoForm) + BlocoForm, FrenteParlamentarForm) from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, Dependente, Filiacao, Frente, Legislatura, Mandato, NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, SituacaoMilitar, TipoAfastamento, TipoDependente, Votante, - Bloco) + Bloco, FrenteCargo, FrenteParlamentar) +FrenteCargoCrud = CrudAux.build(FrenteCargo, 'frente_cargo') CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa') TipoDependenteCrud = CrudAux.build(TipoDependente, 'tipo_dependente') NivelInstrucaoCrud = CrudAux.build(NivelInstrucao, 'nivel_instrucao') @@ -384,8 +385,7 @@ class FrenteCrud(Crud): model = Frente help_topic = 'tipo_situa_militar' public = [RP_DETAIL, RP_LIST] - list_field_names = ['nome', 'data_criacao', - 'data_extincao', 'parlamentares'] + list_field_names = ['nome', 'data_criacao', 'data_extincao'] class BaseMixin(Crud.BaseMixin): def get_context_data(self, **kwargs): @@ -403,6 +403,65 @@ class FrenteCrud(Crud): form_class = FrenteForm +class FrenteParlamentarCrud(MasterDetailCrud): + model = FrenteParlamentar + parent_field = 'frente' + help_topic = 'frente_parlamentares' + public = [RP_LIST, RP_DETAIL] + + class CreateView(MasterDetailCrud.CreateView): + form_class = FrenteParlamentarForm + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['subnav_template_name'] = '' + return context + + def get_initial(self): + self.initial['frente'] = Frente.objects.get(pk=self.kwargs['pk']) + return self.initial + + class UpdateView(MasterDetailCrud.UpdateView): + form_class = FrenteParlamentarForm + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['subnav_template_name'] = '' + return context + + class DetailView(MasterDetailCrud.DetailView): + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['subnav_template_name'] = '' + return context + + class ListView(MasterDetailCrud.ListView): + layout_key = 'FrenteParlamentarList' + ordering = ('-cargo__cargo_unico', 'parlamentar') + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['subnav_template_name'] = '' + return context + + +def get_parlamentar_frentes(request, pk): + template_name = 'parlamentares/parlamentar_frentes_list.html' + frentes = [f for f in FrenteParlamentar.objects.filter(parlamentar_id=pk) + .select_related('frente', 'cargo') + .order_by('-data_entrada', '-data_saida')] + + context = { + 'subnav_template_name': 'parlamentares/subnav.yaml', + 'root_pk': pk, + 'nome_parlamentar': Parlamentar.objects.get(id=pk).nome_parlamentar, + 'frentes': frentes, + 'num_frentes': len(frentes) + } + + return render(request, template_name, context) + + class MandatoCrud(MasterDetailCrud): model = Mandato parent_field = 'parlamentar' diff --git a/sapl/rules/map_rules.py b/sapl/rules/map_rules.py index 316ce8ce3..ad34fe1b1 100644 --- a/sapl/rules/map_rules.py +++ b/sapl/rules/map_rules.py @@ -282,6 +282,8 @@ rules_group_geral = { (parlamentares.CargoMesa, __base__, __perms_publicas__), (parlamentares.ComposicaoMesa, __base__, __perms_publicas__), (parlamentares.Frente, __base__, __perms_publicas__), + (parlamentares.FrenteCargo, __base__, __perms_publicas__), + (parlamentares.FrenteParlamentar, __base__, __perms_publicas__), (parlamentares.Votante, __base__, __perms_publicas__), (parlamentares.Bloco, __base__, __perms_publicas__), diff --git a/sapl/templates/menu_tabelas_auxiliares.yaml b/sapl/templates/menu_tabelas_auxiliares.yaml index 864b8e5a6..3af2d293e 100644 --- a/sapl/templates/menu_tabelas_auxiliares.yaml +++ b/sapl/templates/menu_tabelas_auxiliares.yaml @@ -80,6 +80,9 @@ - title: {% trans 'Frente Parlamentar' %} url: sapl.parlamentares:frente_list css_class: btn btn-link + - title: {% trans 'Cargo de Frente Parlamentar' %} + url: sapl.parlamentares:frentecargo_list + css_class: btn btn-link - title: {% trans 'Bloco Parlamentar' %} url: sapl.parlamentares:bloco_list css_class: btn btn-link diff --git a/sapl/templates/parlamentares/frente_detail.html b/sapl/templates/parlamentares/frente_detail.html new file mode 100644 index 000000000..175bcd20c --- /dev/null +++ b/sapl/templates/parlamentares/frente_detail.html @@ -0,0 +1,9 @@ +{% extends "crud/detail.html" %} +{% load i18n %} +{% load crispy_forms_tags cropping %} +{% block actions %} + {{ block.super }} + +{% endblock actions %} \ No newline at end of file diff --git a/sapl/templates/parlamentares/frente_form.html b/sapl/templates/parlamentares/frente_form.html index 2e6bdca3e..cb0523070 100644 --- a/sapl/templates/parlamentares/frente_form.html +++ b/sapl/templates/parlamentares/frente_form.html @@ -22,24 +22,6 @@ -
-
-
-
-
-
-
- -
-
- {{ form.parlamentares|as_crispy_field }} -
-
-
-
{{ form.descricao|as_crispy_field }} @@ -50,79 +32,4 @@ -{% endblock base_content %} - -{% block extra_js %} - -{% endblock %} +{% endblock base_content %} \ No newline at end of file diff --git a/sapl/templates/parlamentares/frenteparlamentar_list.html b/sapl/templates/parlamentares/frenteparlamentar_list.html new file mode 100644 index 000000000..308578415 --- /dev/null +++ b/sapl/templates/parlamentares/frenteparlamentar_list.html @@ -0,0 +1,9 @@ +{% extends "crud/list.html" %} +{% load i18n %} +{% load common_tags %} + +{% block more_buttons %} + + Frente Parlamentar + +{% endblock more_buttons %} \ No newline at end of file diff --git a/sapl/templates/parlamentares/layouts.yaml b/sapl/templates/parlamentares/layouts.yaml index 7c3e59908..9d9ee6ce3 100644 --- a/sapl/templates/parlamentares/layouts.yaml +++ b/sapl/templates/parlamentares/layouts.yaml @@ -117,12 +117,27 @@ ComposicaoColigacao: - partido Frente: - {% trans 'Frente' %}: + {% trans 'Frente Parlamentar' %}: - nome - data_criacao data_extincao - - parlamentares - descricao +FrenteCargo: + {% trans 'Cargo' %}: + - nome_cargo cargo_unico:4 + +FrenteParlamentar: + {% trans 'Parlamentar'%}: + - frente + - cargo:4 parlamentar + - data_entrada data_saida + +FrenteParlamentarList: + {% trans 'Parlamentares'%}: + - id + - cargo:4 parlamentar + - data_entrada data_saida + Votante: {% trans 'Votante' %}: - parlamentar user diff --git a/sapl/templates/parlamentares/parlamentar_frentes_list.html b/sapl/templates/parlamentares/parlamentar_frentes_list.html new file mode 100644 index 000000000..d756e6444 --- /dev/null +++ b/sapl/templates/parlamentares/parlamentar_frentes_list.html @@ -0,0 +1,42 @@ +{% extends "crud/list.html" %} +{% load i18n %} +{% load common_tags %} + +{% block actions %} + {{ block.super }} +{% endblock actions %} + +{% block base_content %} + {% if not frentes %} +

O {{ nome_parlamentar }} não têm participações em Frentes Parlamentares.

+ {% else %} +

Frentes ({{ nome_parlamentar }})

+
+ Total de Frentes: {{ num_frentes }} + + + + + + + + + + + {% for frente in frentes %} + + + + + + + {% endfor %} + +
Frent{{ num_frentes|pluralize:"e,es" }}CargoData de EntradaData de Saída
+ {{ frente.frente }} + {{ frente.cargo.nome_cargo }}{{ frente.data_entrada }}{% if frente.data_saida %} {{ frente.data_saida }} {% else %} - {% endif %}
+ {% endif %} +
+ {% include 'paginacao.html'%} +


+{% endblock base_content %} \ No newline at end of file diff --git a/sapl/templates/parlamentares/subnav.yaml b/sapl/templates/parlamentares/subnav.yaml index 9199589fc..023e616b4 100644 --- a/sapl/templates/parlamentares/subnav.yaml +++ b/sapl/templates/parlamentares/subnav.yaml @@ -18,7 +18,7 @@ - title: {% trans 'Relatorias' %} url: relatoria_parlamentar_list - title: {% trans 'Frentes' %} - url: frente_parlamentar_list + url: parlamentar_frentes - title: {% trans 'Usuário' %} url: votante_list check_permission: parlamentares.add_parlamentar