From eaaeacc2595d10a818039d9f885cbf58aae75388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Wed, 14 Aug 2019 16:14:14 -0300 Subject: [PATCH] =?UTF-8?q?Corrige=20tramita=C3=A7=C3=A3o=20na=20pauta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #2756 Adiciona tramitação da pauta na model abstrata de ordem do dia Adiciona tramitação em expediente matéria Adiciona tramitação em ordem dia Corrige tramitações das matérias na pauta da sessão Adiciona tramitações em expedientes e ordem dias Adiciona html para atualização da situação Complementa html para atualização da situação Finaliza html para atualização da situação --- .../migrations/0055_auto_20190702_1751.py | 23 +++ sapl/materia/models.py | 1 + sapl/sessao/forms.py | 18 ++- .../migrations/0045_auto_20190626_1151.py | 47 ++++++ sapl/sessao/models.py | 43 ++++-- sapl/sessao/urls.py | 8 +- sapl/sessao/views.py | 82 +++++++---- .../templates/sessao/pauta_sessao_detail.html | 137 +++++++++--------- .../sessao/pauta_sessao_situacao_materia.html | 42 ++++++ 9 files changed, 281 insertions(+), 120 deletions(-) create mode 100644 sapl/materia/migrations/0055_auto_20190702_1751.py create mode 100644 sapl/sessao/migrations/0045_auto_20190626_1151.py create mode 100644 sapl/templates/sessao/pauta_sessao_situacao_materia.html diff --git a/sapl/materia/migrations/0055_auto_20190702_1751.py b/sapl/materia/migrations/0055_auto_20190702_1751.py new file mode 100644 index 000000000..7ba7ad215 --- /dev/null +++ b/sapl/materia/migrations/0055_auto_20190702_1751.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.22 on 2019-07-02 20:51 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0054_merge_20190802_1117'), + ] + + operations = [ + migrations.AlterModelOptions( + name='tramitacao', + options={ + 'ordering': ['-id', '-timestamp', '-data_tramitacao'], + 'verbose_name': 'Tramitação', + 'verbose_name_plural': 'Tramitações' + }, + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 219b38971..976ba6d50 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -1076,6 +1076,7 @@ class Tramitacao(models.Model): class Meta: verbose_name = _('Tramitação') verbose_name_plural = _('Tramitações') + ordering = ['-id', '-timestamp', '-data_tramitacao'] def __str__(self): return _('%(materia)s | %(status)s | %(data)s') % { diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index 570a706c4..a6865feb4 100644 --- a/sapl/sessao/forms.py +++ b/sapl/sessao/forms.py @@ -17,7 +17,7 @@ from sapl.crispy_layout_mixin import SaplFormHelper from sapl.crispy_layout_mixin import form_actions, to_row, SaplFormLayout from sapl.materia.forms import MateriaLegislativaFilterSet from sapl.materia.models import (MateriaLegislativa, StatusTramitacao, - TipoMateriaLegislativa) + TipoMateriaLegislativa, Tramitacao) from sapl.parlamentares.models import Parlamentar, Mandato from sapl.utils import (RANGE_DIAS_MES, RANGE_MESES, MateriaPesquisaOrderingFilter, autor_label, @@ -356,9 +356,13 @@ class ExpedienteMateriaForm(ModelForm): return cleaned_data def save(self, commit=False): - expediente = super(ExpedienteMateriaForm, self).save(commit) - expediente.materia = self.cleaned_data['materia'] + expediente = super().save(commit) + materia = self.cleaned_data['materia'] + + expediente.materia = materia + expediente.tramitacao = Tramitacao.objects.filter(materia=materia).first() expediente.save() + return expediente @@ -394,9 +398,13 @@ class OrdemDiaForm(ExpedienteMateriaForm): return self.cleaned_data def save(self, commit=False): - ordem = super(OrdemDiaForm, self).save(commit) - ordem.materia = self.cleaned_data['materia'] + ordem = super().save(commit) + materia = self.cleaned_data['materia'] + + ordem.materia = materia + ordem.tramitacao = Tramitacao.objects.filter(materia=materia).first() ordem.save() + return ordem diff --git a/sapl/sessao/migrations/0045_auto_20190626_1151.py b/sapl/sessao/migrations/0045_auto_20190626_1151.py new file mode 100644 index 000000000..290991cdd --- /dev/null +++ b/sapl/sessao/migrations/0045_auto_20190626_1151.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.21 on 2019-06-26 14:51 +from __future__ import unicode_literals + +import django.db.models.deletion +from django.db import migrations, models + + +def congirura_tramitacoes_pautas(apps, schema_editor): + ExpedienteMateria = apps.get_model('sessao', 'ExpedienteMateria') + OrdemDia = apps.get_model('sessao', 'OrdemDia') + + for expediente in ExpedienteMateria.objects.all(): + expediente.tramitacao = expediente.materia.tramitacao_set.first() + expediente.save() + + for ordemdia in OrdemDia.objects.all(): + ordemdia.tramitacao = ordemdia.materia.tramitacao_set.first() + ordemdia.save() + + +class Migration(migrations.Migration): + dependencies = [ + ('materia', '0051_auto_20190703_1414'), + ('sessao', '0044_merge_20190802_1117'), + ] + + operations = [ + migrations.AddField( + model_name='expedientemateria', + name='tramitacao', + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + to='materia.Tramitacao'), + ), + migrations.AddField( + model_name='ordemdia', + name='tramitacao', + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + to='materia.Tramitacao'), + ), + + migrations.RunPython(congirura_tramitacoes_pautas), + ] diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index e6016895f..8ad01f279 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -1,15 +1,15 @@ from operator import xor +import reversion from django.core.exceptions import ValidationError from django.db import models from django.db.models import Q from django.utils import timezone, formats from django.utils.translation import ugettext_lazy as _ from model_utils import Choices -import reversion from sapl.base.models import Autor -from sapl.materia.models import MateriaLegislativa +from sapl.materia.models import MateriaLegislativa, Tramitacao from sapl.parlamentares.models import (CargoMesa, Legislatura, Parlamentar, Partido, SessaoLegislativa) from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation, @@ -247,21 +247,29 @@ class AbstractOrdemDia(models.Model): TIPO_VOTACAO_CHOICES = Choices( (1, 'simbolica', 'Simbólica'), (2, 'nominal', 'Nominal'), - (3, 'secreta', 'Secreta'), - ) + (3, 'secreta', 'Secreta'),) - sessao_plenaria = models.ForeignKey(SessaoPlenaria, - on_delete=models.CASCADE) - materia = models.ForeignKey(MateriaLegislativa, - on_delete=models.PROTECT, - verbose_name=_('Matéria')) - data_ordem = models.DateField(verbose_name=_('Data da Sessão')) + sessao_plenaria = models.ForeignKey( + SessaoPlenaria, + on_delete=models.CASCADE) + materia = models.ForeignKey( + MateriaLegislativa, + on_delete=models.PROTECT, + verbose_name=_('Matéria')) + data_ordem = models.DateField( + verbose_name=_('Data da Sessão')) observacao = models.TextField( - blank=True, verbose_name=_('Observação')) - numero_ordem = models.PositiveIntegerField(verbose_name=_('Nº Ordem')) - resultado = models.TextField(blank=True, verbose_name=_('Resultado')) + blank=True, + verbose_name=_('Observação')) + numero_ordem = models.PositiveIntegerField( + verbose_name=_('Nº Ordem')) + resultado = models.TextField( + blank=True, + verbose_name=_('Resultado')) tipo_votacao = models.PositiveIntegerField( - verbose_name=_('Tipo de votação'), choices=TIPO_VOTACAO_CHOICES, default=1) + verbose_name=_('Tipo de votação'), + choices=TIPO_VOTACAO_CHOICES, + default=1) votacao_aberta = models.NullBooleanField( blank=True, choices=YES_NO_CHOICES, @@ -270,6 +278,10 @@ class AbstractOrdemDia(models.Model): blank=True, choices=YES_NO_CHOICES, verbose_name=_('Registro de Votação Iniciado?')) + tramitacao = models.ForeignKey( + Tramitacao, + null=True, + on_delete=models.PROTECT) class Meta: abstract = True @@ -279,8 +291,7 @@ class AbstractOrdemDia(models.Model): return self.materia.ementa def __str__(self): - return 'Ordem do Dia/Expediente: %s - %s em %s' % ( - self.numero_ordem, self.materia, self.sessao_plenaria) + return 'Ordem do Dia/Expediente: %s - %s em %s' % (self.numero_ordem, self.materia, self.sessao_plenaria) @reversion.register() diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index 328c1da5e..f050ed15c 100644 --- a/sapl/sessao/urls.py +++ b/sapl/sessao/urls.py @@ -35,7 +35,7 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente, VotacaoEmBlocoSimbolicaView, VotacaoEmBlocoNominalView, resumo_ordenacao, recuperar_nome_tipo_sessao, - voto_nominal_parlamentar) + voto_nominal_parlamentar, mostra_status_materia, atualiza_status_materia) from .apps import AppConfig @@ -116,6 +116,12 @@ urlpatterns = [ PesquisarPautaSessaoView.as_view(), name='pesquisar_pauta'), url(r'^sessao/pauta-sessao/(?P\d+)$', PautaSessaoDetailView.as_view(), name='pauta_sessao_detail'), + url(r'^sessao/pauta-sessao/(?P\d+)/mostra-situacao-(?P[\w-]+)/(?P\d+)/$', + mostra_status_materia, name='mostra_status_materia'), + url(r'^sessao/pauta-sessao/(?P\d+)/atualiza-situacao-(?P[\w-]+)/(?P\d+)/$', + atualiza_status_materia, name='atualiza_status_materia'), + + # Subnav sessão url(r'^sessao/(?P\d+)/expediente$', diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 9560c66e1..98abf1312 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -24,7 +24,6 @@ from django.views.generic.edit import FormMixin from django_filters.views import FilterView from django.shortcuts import render - from sapl.base.models import AppConfig as AppsAppConfig from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, MasterDetailCrud, @@ -3246,21 +3245,15 @@ class PautaSessaoDetailView(DetailView): ]}) # ===================================================================== # Matérias Expediente - materias = ExpedienteMateria.objects.filter( - sessao_plenaria_id=self.object.id) + materias = ExpedienteMateria.objects.filter(sessao_plenaria_id=self.object.id) materias_expediente = [] for m in materias: ementa = m.materia.ementa titulo = m.materia numero = m.numero_ordem + situacao = m.tramitacao.status if m.tramitacao else _("Não informada") - ultima_tramitacao = m.materia.tramitacao_set.last() - - situacao = ultima_tramitacao.status if ultima_tramitacao else None - - if situacao is None: - situacao = _("Não informada") rv = m.registrovotacao_set.all() if rv: resultado = rv[0].tipo_resultado_votacao.nome @@ -3287,15 +3280,12 @@ class PautaSessaoDetailView(DetailView): context.update({'materia_expediente': materias_expediente}) # ===================================================================== # Expedientes - expediente = ExpedienteSessao.objects.filter( - sessao_plenaria_id=self.object.id) + expediente = ExpedienteSessao.objects.filter(sessao_plenaria_id=self.object.id) expedientes = [] for e in expediente: - tipo = TipoExpediente.objects.get( - id=e.tipo_id) - conteudo = sub( - ' ', ' ', strip_tags(e.conteudo.replace('
', '\n'))) + tipo = TipoExpediente.objects.get(id=e.tipo_id) + conteudo = sub(' ', ' ', strip_tags(e.conteudo.replace('
', '\n'))) ex = {'tipo': tipo, 'conteudo': conteudo} expedientes.append(ex) @@ -3303,26 +3293,19 @@ class PautaSessaoDetailView(DetailView): context.update({'expedientes': expedientes}) # ===================================================================== # Orador Expediente - oradores = OradorExpediente.objects.filter( - sessao_plenaria_id=self.object.id).order_by('numero_ordem') + oradores = OradorExpediente.objects.filter(sessao_plenaria_id=self.object.id).order_by('numero_ordem') context.update({'oradores': oradores}) # ===================================================================== # Matérias Ordem do Dia - ordem = OrdemDia.objects.filter( - sessao_plenaria_id=self.object.id) + ordem = OrdemDia.objects.filter(sessao_plenaria_id=self.object.id) materias_ordem = [] for o in ordem: ementa = o.materia.ementa titulo = o.materia numero = o.numero_ordem + situacao = o.tramitacao.status if o.tramitacao else _("Não informada") - ultima_tramitacao = o.materia.tramitacao_set.last() - - situacao = ultima_tramitacao.status if ultima_tramitacao else None - - if situacao is None: - situacao = _("Não informada") # Verificar resultado rv = o.registrovotacao_set.all() if rv: @@ -3332,8 +3315,7 @@ class PautaSessaoDetailView(DetailView): resultado = _('Matéria não votada') resultado_observacao = _(' ') - autoria = Autoria.objects.filter( - materia_id=o.materia_id) + autoria = Autoria.objects.filter(materia_id=o.materia_id) autor = [str(x.autor) for x in autoria] mat = {'id': o.materia_id, @@ -3354,6 +3336,46 @@ class PautaSessaoDetailView(DetailView): return self.render_to_response(context) +def pega_materia_exp_od(sessao_id, tipo, materia_id): + models = { + 'expediente': ExpedienteMateria, + 'ordemdia': OrdemDia + } + exp_od = models[tipo].objects.select_related('materia').get(sessao_plenaria=sessao_id, materia=materia_id) + + return exp_od + + +def mostra_status_materia(request, sessao_id, tipo, materia_id): + template_name = "sessao/pauta_sessao_situacao_materia.html" + exp_od = pega_materia_exp_od(sessao_id, tipo, materia_id) + autores = [a.autor.nome for a in exp_od.materia.autoria_set.all()] + + context = { + 'sessao_id': sessao_id, + 'materia_id': materia_id, + 'titulo': exp_od.materia, + 'exp_od_id': exp_od.id, + 'tipo': tipo, + 'autores': autores, + 'ementa': exp_od.materia.ementa, + 'tramitacao_id': exp_od.tramitacao.id, + 'status': exp_od.tramitacao.status, + 'nova_tramitacao_id': exp_od.materia.tramitacao_set.first().id, + 'novo_status': exp_od.materia.tramitacao_set.first().status + } + + return render(request, template_name, context) + + +def atualiza_status_materia(request, sessao_id, tipo, materia_id): + exp_od = pega_materia_exp_od(sessao_id, tipo, materia_id) + exp_od.tramitacao = exp_od.materia.tramitacao_set.first() + exp_od.save() + + return HttpResponseRedirect(reverse('sapl.sessao:pauta_sessao_detail', kwargs={'pk': sessao_id})) + + class PesquisarSessaoPlenariaView(FilterView): model = SessaoPlenaria filterset_class = SessaoPlenariaFilterSet @@ -3366,11 +3388,9 @@ class PesquisarSessaoPlenariaView(FilterView): kwargs = {'data': self.request.GET or None} - qs = self.get_queryset().select_related( - 'tipo', 'sessao_legislativa', 'legislatura') + qs = self.get_queryset().select_related('tipo', 'sessao_legislativa', 'legislatura') - qs = qs.distinct().order_by( - '-legislatura__numero', '-data_inicio', '-hora_inicio') + qs = qs.distinct().order_by('-legislatura__numero', '-data_inicio', '-hora_inicio') kwargs.update({ 'queryset': qs, diff --git a/sapl/templates/sessao/pauta_sessao_detail.html b/sapl/templates/sessao/pauta_sessao_detail.html index 6b2702f5f..a3fc6e15b 100644 --- a/sapl/templates/sessao/pauta_sessao_detail.html +++ b/sapl/templates/sessao/pauta_sessao_detail.html @@ -3,72 +3,75 @@ {% load crispy_forms_tags %} {% block base_content %} - -
- Identificação Básica - - - - {% for b in basica %} - - {% endfor %} - - -
{{b}}
-
-
- Matérias do Expediente - {% if materia_expediente %} - - - - - - - - - {% for m in materia_expediente %} - - - - - - {% endfor %} -
MatériaEmentaSituação
- {{m.numero}} - {{m.titulo}} -
- Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} -
{{m.ementa|safe}}
{{m.observacao|linebreaksbr|safe}}
{{m.situacao}}
- {% else %} - Não existem Matérias de Expediente para essa Sessão Plenária - {% endif %} + +
+ Identificação Básica + + + + {% for b in basica %} + + {% endfor %} + + +
{{ b }}
+
+
+ Matérias do Expediente + {% if materia_expediente %} + + + + + + + + + {% for m in materia_expediente %} + + + + + + {% endfor %} +
MatériaEmentaSituação
+ {{ m.numero }} - {{ m.titulo }} +
+ Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} +
{{ m.ementa|safe }}
{{ m.observacao|linebreaksbr|safe }}
{{ m.situacao }}
+ {% else %} + Não existem Matérias de Expediente para essa Sessão Plenária + {% endif %} -
-
- Matérias da Ordem do Dia - {% if materias_ordem %} - - - - - - - - - {% for m in materias_ordem %} - - - - - - {% endfor %} -
MatériaEmentaSituação
- {{m.numero}} - {{m.titulo}} -
- Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} -
{{m.ementa|safe}}
{{m.observacao|linebreaksbr|safe}}
{{m.situacao}}
- {% else %} - Não existem Matérias de Ordem do Dia para essa Sessão Plenária - {% endif %} -
+
+
+ Matérias da Ordem do Dia + {% if materias_ordem %} + + + + + + + + + {% for m in materias_ordem %} + + + + + + {% endfor %} +
MatériaEmentaSituação
¡ + {{ m.numero }} - {{ m.titulo }} +
+ Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} +
{{ m.ementa|safe }}
{{ m.observacao|linebreaksbr|safe }}
{{ m.situacao }}
+ {% else %} + Não existem Matérias de Ordem do Dia para essa Sessão Plenária + {% endif %} +
{% endblock base_content %} diff --git a/sapl/templates/sessao/pauta_sessao_situacao_materia.html b/sapl/templates/sessao/pauta_sessao_situacao_materia.html new file mode 100644 index 000000000..73b2e92df --- /dev/null +++ b/sapl/templates/sessao/pauta_sessao_situacao_materia.html @@ -0,0 +1,42 @@ +{% extends "crud/detail.html" %} +{% load i18n %} +{% load crispy_forms_tags %} + +{% block base_content %} +
+ Atualização da Situação da Matéria em Pauta + + + {% if tipo == expediente %} + + {% else %} + + {% endif %} + + + + + + + + + + + + + + + + + + +
Matéria do ExpedienteMatéria da Ordem Dia{{ titulo }}
Autor{{ autores|length|pluralize:"es" }}{{ autores|join:', ' }}
Ementa{{ ementa }}
Atual Situação{{ status }}
Nova Situação{{ novo_status }}
+
+
Ao apertar em 'Atualizar', não será possível reverter a alteração posteriormente.
+
+ Voltar +
+
+ Atualizar +
+{% endblock base_content %}