Browse Source

Corrige tramitação na pauta

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
2756-status-materia-pauta
Vinícius Cantuária 5 years ago
parent
commit
eaaeacc259
  1. 23
      sapl/materia/migrations/0055_auto_20190702_1751.py
  2. 1
      sapl/materia/models.py
  3. 18
      sapl/sessao/forms.py
  4. 47
      sapl/sessao/migrations/0045_auto_20190626_1151.py
  5. 37
      sapl/sessao/models.py
  6. 8
      sapl/sessao/urls.py
  7. 82
      sapl/sessao/views.py
  8. 15
      sapl/templates/sessao/pauta_sessao_detail.html
  9. 42
      sapl/templates/sessao/pauta_sessao_situacao_materia.html

23
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'
},
),
]

1
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') % {

18
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

47
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),
]

37
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,
sessao_plenaria = models.ForeignKey(
SessaoPlenaria,
on_delete=models.CASCADE)
materia = models.ForeignKey(MateriaLegislativa,
materia = models.ForeignKey(
MateriaLegislativa,
on_delete=models.PROTECT,
verbose_name=_('Matéria'))
data_ordem = models.DateField(verbose_name=_('Data da Sessão'))
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()

8
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<pk>\d+)$',
PautaSessaoDetailView.as_view(), name='pauta_sessao_detail'),
url(r'^sessao/pauta-sessao/(?P<sessao_id>\d+)/mostra-situacao-(?P<tipo>[\w-]+)/(?P<materia_id>\d+)/$',
mostra_status_materia, name='mostra_status_materia'),
url(r'^sessao/pauta-sessao/(?P<sessao_id>\d+)/atualiza-situacao-(?P<tipo>[\w-]+)/(?P<materia_id>\d+)/$',
atualiza_status_materia, name='atualiza_status_materia'),
# Subnav sessão
url(r'^sessao/(?P<pk>\d+)/expediente$',

82
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(
'&nbsp;', ' ', strip_tags(e.conteudo.replace('<br/>', '\n')))
tipo = TipoExpediente.objects.get(id=e.tipo_id)
conteudo = sub('&nbsp;', ' ', strip_tags(e.conteudo.replace('<br/>', '\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,

15
sapl/templates/sessao/pauta_sessao_detail.html

@ -3,7 +3,8 @@
{% load crispy_forms_tags %}
{% block base_content %}
<div align=right><a href="{% url 'sapl.relatorios:relatorio_pauta_sessao' object.pk %}"> Impressão PDF</a></li></div>
<div align=right><a href="{% url 'sapl.relatorios:relatorio_pauta_sessao' object.pk %}"> Impressão PDF</a></li>
</div>
<fieldset>
<legend>Identificação Básica</legend>
<table class="table">
@ -30,12 +31,13 @@
{% for m in materia_expediente %}
<tr>
<td style="width:20%;">
{{m.numero}} - <a href="{% url 'sapl.materia:materialegislativa_detail' m.id %}">{{m.titulo}}</a>
{{ m.numero }} - <a
href="{% url 'sapl.materia:materialegislativa_detail' m.id %}">{{ m.titulo }}</a>
<br/>
<b>Autor{{ m.autor|length|pluralize:"es" }}</b>: {{ m.autor|join:', ' }}
</td>
<td style="width:70%;">{{ m.ementa|safe }}<br>{{ m.observacao|linebreaksbr|safe }}</td>
<td style="width:10%;">{{m.situacao}}</td>
<td style="width:10%;"><a href="{% url 'sapl.sessao:mostra_status_materia' object.pk 'expediente' m.id %}">{{ m.situacao }}</a></td>
</tr>
{% endfor %}
</table>
@ -57,13 +59,14 @@
</thead>
{% for m in materias_ordem %}
<tr>
<td style="width:20%;">
{{m.numero}} - <a href="{% url 'sapl.materia:materialegislativa_detail' m.id %}">{{m.titulo}}</a>
<td style="width:20%;">¡
{{ m.numero }} - <a
href="{% url 'sapl.materia:materialegislativa_detail' m.id %}">{{ m.titulo }}</a>
<br/>
<b>Autor{{ m.autor|length|pluralize:"es" }}</b>: {{ m.autor|join:', ' }}
</td>
<td style="width:70%;">{{ m.ementa|safe }}<br>{{ m.observacao|linebreaksbr|safe }}</td>
<td style="width:10%;">{{m.situacao}}</td>
<td style="width:10%;"><a href="{% url 'sapl.sessao:mostra_status_materia' object.pk 'ordemdia' m.id %}">{{ m.situacao }}</a></td>
</tr>
{% endfor %}
</table>

42
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 %}
<fieldset>
<legend>Atualização da Situação da Matéria em Pauta</legend>
<table class="table table-striped">
<tr>
{% if tipo == expediente %}
<td><b>Matéria do Expediente</b></td>
{% else %}
<td><b>Matéria da Ordem Dia</b></td>
{% endif %}
<td><a href="{% url 'sapl.materia:materialegislativa_detail' materia_id %}">{{ titulo }}</a></td>
</tr>
<tr>
<td><b>Autor{{ autores|length|pluralize:"es" }}</b></td>
<td>{{ autores|join:', ' }}</td>
</tr>
<tr>
<td><b>Ementa</b></td>
<td>{{ ementa }}</td>
</tr>
<tr>
<td><b>Atual Situação</b></td>
<td><a href="{% url 'sapl.materia:tramitacao_detail' tramitacao_id %}">{{ status }}</a></td>
</tr>
<tr>
<td><b>Nova Situação</b></td>
<td><a href="{% url 'sapl.materia:tramitacao_detail' nova_tramitacao_id %}">{{ novo_status }}</a></td>
</tr>
</table>
</fieldset>
<div><em>Ao apertar em 'Atualizar', não será possível reverter a alteração posteriormente.</em></div>
<div class="actions btn-group btn-group-sm" role="group">
<a href="{% url 'sapl.sessao:pauta_sessao_detail' sessao_id %}" class="btn btn-outline-primary">Voltar</a>
</div>
<div class="actions btn-group btn-group-sm" role="group">
<a href="{% url 'sapl.sessao:atualiza_status_materia' sessao_id tipo materia_id %}" class="btn btn-outline-primary">Atualizar</a>
</div>
{% endblock base_content %}
Loading…
Cancel
Save