Browse Source

Adiciona Leitura para OrdemDia e cria model RegistroLeitura

pull/2953/head
Cesar Carvalho 6 years ago
parent
commit
2008e5d882
  1. 43
      sapl/sessao/forms.py
  2. 62
      sapl/sessao/migrations/0046_auto_20190827_1228.py
  3. 48
      sapl/sessao/models.py
  4. 14
      sapl/sessao/urls.py
  5. 116
      sapl/sessao/views.py
  6. 1
      sapl/templates/sessao/layouts.yaml
  7. 7
      sapl/templates/sessao/votacao/leitura_form.html

43
sapl/sessao/forms.py

@ -28,7 +28,7 @@ from .models import (Bancada, ExpedienteMateria, JustificativaAusencia,
Orador, OradorExpediente, OrdemDia, PresencaOrdemDia, SessaoPlenaria, Orador, OradorExpediente, OrdemDia, PresencaOrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, TipoResultadoVotacao, SessaoPlenariaPresenca, TipoResultadoVotacao,
OcorrenciaSessao, RetiradaPauta, TipoRetiradaPauta, OradorOrdemDia, ORDENACAO_RESUMO, OcorrenciaSessao, RetiradaPauta, TipoRetiradaPauta, OradorOrdemDia, ORDENACAO_RESUMO,
ResumoOrdenacao) ResumoOrdenacao, RegistroLeitura)
MES_CHOICES = RANGE_MESES MES_CHOICES = RANGE_MESES
@ -1027,32 +1027,45 @@ class JustificativaAusenciaForm(ModelForm):
return justificativa return justificativa
class ExpedienteLeitura(forms.Form): class OrdemExpedienteLeituraForm(forms.ModelForm):
materia = forms.CharField(
label='Matéria',
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
materia__ementa = forms.CharField(
label='Ementa',
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
observacao = forms.CharField(required=False, label='Observação', widget=forms.Textarea,) observacao = forms.CharField(required=False, label='Observação', widget=forms.Textarea,)
class Meta:
model = RegistroLeitura
fields = ['materia',
'ordem',
'expediente',
'observacao']
widgets = {'materia': forms.HiddenInput(),
'ordem': forms.HiddenInput(),
'expediente': forms.HiddenInput(),
}
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
instance = self.initial['instance']
if instance:
self.instance = instance.first()
self.fields['observacao'].initial = self.instance.observacao
row1 = to_row( row1 = to_row(
[('materia', 12)])
row2 = to_row(
[('materia__ementa', 12)])
row3 = to_row(
[('observacao', 12)]) [('observacao', 12)])
actions = [HTML('<a href="{{ view.cancel_url }}"'
' class="btn btn-dark">Cancelar</a>')]
self.helper = SaplFormHelper() self.helper = SaplFormHelper()
self.helper.form_method = 'POST' self.helper.form_method = 'POST'
self.helper.layout = Layout( self.helper.layout = Layout(
Fieldset(_('Leitura de Matéria'), Fieldset(_('Leitura de Matéria'),
row1, row2, row3, HTML('''
form_actions(label='Salvar')) <b>Matéria:</b> {{materia}}<br>
<b>Ementa:</b> {{materia.ementa}} <br>
'''),
row1,
form_actions(more=actions),
)
) )

62
sapl/sessao/migrations/0046_auto_20190827_1228.py

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-08-27 15:28
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('materia', '0055_auto_20190816_0943'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('sessao', '0045_auto_20190816_1337'),
]
operations = [
migrations.CreateModel(
name='RegistroLeitura',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('observacao', models.TextField(blank=True, verbose_name='Observações')),
('ip', models.CharField(blank=True, default='', max_length=30, verbose_name='IP')),
('data_hora', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Data/Hora')),
],
options={
'verbose_name': 'Leitura',
'verbose_name_plural': 'Leituras',
},
),
migrations.AlterField(
model_name='expedientemateria',
name='tipo_votacao',
field=models.PositiveIntegerField(choices=[(1, 'Simbólica'), (2, 'Nominal'), (3, 'Secreta'), (4, 'Leitura')], default=1, verbose_name='Tipo de votação'),
),
migrations.AlterField(
model_name='ordemdia',
name='tipo_votacao',
field=models.PositiveIntegerField(choices=[(1, 'Simbólica'), (2, 'Nominal'), (3, 'Secreta'), (4, 'Leitura')], default=1, verbose_name='Tipo de votação'),
),
migrations.AddField(
model_name='registroleitura',
name='expediente',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.ExpedienteMateria'),
),
migrations.AddField(
model_name='registroleitura',
name='materia',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa'),
),
migrations.AddField(
model_name='registroleitura',
name='ordem',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.OrdemDia'),
),
migrations.AddField(
model_name='registroleitura',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
),
]

48
sapl/sessao/models.py

@ -861,3 +861,51 @@ class RetiradaPauta(models.Model):
'ReritadaPauta deve ter exatamente um dos campos ' 'ReritadaPauta deve ter exatamente um dos campos '
'ordem ou expediente preenchido. Ambos estão preenchidos: ' 'ordem ou expediente preenchido. Ambos estão preenchidos: '
'{}, {}'. format(self.ordem, self.expediente)) '{}, {}'. format(self.ordem, self.expediente))
@reversion.register()
class RegistroLeitura(models.Model):
materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE)
ordem = models.ForeignKey(OrdemDia,
blank=True,
null=True,
on_delete=models.CASCADE)
expediente = models.ForeignKey(ExpedienteMateria,
blank=True,
null=True,
on_delete=models.CASCADE)
observacao = models.TextField(
blank=True, verbose_name=_('Observações'))
user = models.ForeignKey(get_settings_auth_user_model(),
on_delete=models.PROTECT,
null=True,
blank=True)
ip = models.CharField(verbose_name=_('IP'),
max_length=30,
blank=True,
default='')
data_hora = models.DateTimeField(
verbose_name=_('Data/Hora'),
auto_now_add=True,
blank=True,
null=True)
class Meta:
verbose_name = _('Leitura')
verbose_name_plural = _('Leituras')
def __str__(self):
return _('Leitura - '
'Matéria: %(materia)s') % {
'materia': self.materia}
def clean(self):
"""Exatamente um dos campos ordem ou expediente deve estar preenchido.
"""
# TODO remover esse método quando OrdemDia e ExpedienteMateria
# forem reestruturados e os campos ordem e expediente forem unificados
if not xor(bool(self.ordem), bool(self.expediente)):
raise ValidationError(
'RegistroVotacao deve ter exatamente um dos campos '
'ordem ou expediente preenchido. Ambos estão preenchidos: '
'{}, {}'. format(self.ordem, self.expediente))

14
sapl/sessao/urls.py

@ -35,7 +35,8 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
VotacaoEmBlocoOrdemDia, VotacaoEmBlocoExpediente, VotacaoEmBlocoOrdemDia, VotacaoEmBlocoExpediente,
VotacaoEmBlocoSimbolicaView, VotacaoEmBlocoNominalView, VotacaoEmBlocoSimbolicaView, VotacaoEmBlocoNominalView,
recuperar_nome_tipo_sessao, recuperar_nome_tipo_sessao,
ExpedienteLeituraView) ExpedienteLeituraView,
OrdemDiaLeituraView)
from .apps import AppConfig from .apps import AppConfig
@ -151,13 +152,11 @@ urlpatterns = [
PesquisarSessaoPlenariaView.as_view(), name='pesquisar_sessao'), PesquisarSessaoPlenariaView.as_view(), name='pesquisar_sessao'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votnom/(?P<oid>\d+)/(?P<mid>\d+)$', url(r'^sessao/(?P<pk>\d+)/matordemdia/votnom/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoNominalView.as_view(), name='votacaonominal'), VotacaoNominalView.as_view(), name='votacaonominal'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votnom' url(r'^sessao/(?P<pk>\d+)/matordemdia/votnom/edit/(?P<oid>\d+)/(?P<mid>\d+)$',
'/edit/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoNominalEditView.as_view(), name='votacaonominaledit'), VotacaoNominalEditView.as_view(), name='votacaonominaledit'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsec/(?P<oid>\d+)/(?P<mid>\d+)$', url(r'^sessao/(?P<pk>\d+)/matordemdia/votsec/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoView.as_view(), name='votacaosecreta'), VotacaoView.as_view(), name='votacaosecreta'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsec' url(r'^sessao/(?P<pk>\d+)/matordemdia/votsec/view/(?P<oid>\d+)/(?P<mid>\d+)$',
'/view/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoEditView.as_view(), name='votacaosecretaedit'), VotacaoEditView.as_view(), name='votacaosecretaedit'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimb/(?P<oid>\d+)/(?P<mid>\d+)$', url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimb/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoView.as_view(), name='votacaosimbolica'), VotacaoView.as_view(), name='votacaosimbolica'),
@ -165,8 +164,7 @@ urlpatterns = [
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimbbloco/$', url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimbbloco/$',
VotacaoView.as_view(), name='votacaosimbolicabloco'), VotacaoView.as_view(), name='votacaosimbolicabloco'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimb' url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimb/view/(?P<oid>\d+)/(?P<mid>\d+)$',
'/view/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoEditView.as_view(), name='votacaosimbolicaedit'), VotacaoEditView.as_view(), name='votacaosimbolicaedit'),
url(r'^sessao/(?P<pk>\d+)/matexp/votnom/(?P<oid>\d+)/(?P<mid>\d+)$', url(r'^sessao/(?P<pk>\d+)/matexp/votnom/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoNominalExpedienteView.as_view(), name='votacaonominalexp'), VotacaoNominalExpedienteView.as_view(), name='votacaonominalexp'),
@ -196,5 +194,7 @@ urlpatterns = [
url(r'^sessao/(?P<pk>\d+)/matexp/leitura/(?P<oid>\d+)/(?P<mid>\d+)$', url(r'^sessao/(?P<pk>\d+)/matexp/leitura/(?P<oid>\d+)/(?P<mid>\d+)$',
ExpedienteLeituraView.as_view(), name='leituraexp'), ExpedienteLeituraView.as_view(), name='leituraexp'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/leitura/(?P<oid>\d+)/(?P<mid>\d+)$',
OrdemDiaLeituraView.as_view(), name='leituraod'),
] ]

116
sapl/sessao/views.py

@ -34,7 +34,7 @@ from sapl.materia.views import MateriaLegislativaPesquisaView
from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato, from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato,
Parlamentar, SessaoLegislativa) Parlamentar, SessaoLegislativa)
from sapl.sessao.apps import AppConfig from sapl.sessao.apps import AppConfig
from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm, ExpedienteLeitura from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm, OrdemExpedienteLeituraForm
from sapl.utils import show_results_filter_set, remover_acentos, get_client_ip from sapl.utils import show_results_filter_set, remover_acentos, get_client_ip
from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm,
@ -49,7 +49,8 @@ from .models import (Bancada, CargoBancada, CargoMesa,
PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao, PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao,
SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente, SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente,
TipoResultadoVotacao, TipoSessaoPlenaria, VotoParlamentar, TipoRetiradaPauta, TipoResultadoVotacao, TipoSessaoPlenaria, VotoParlamentar, TipoRetiradaPauta,
RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia, ORDENACAO_RESUMO) RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia,
ORDENACAO_RESUMO, RegistroLeitura)
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria') TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
@ -142,12 +143,12 @@ def verifica_votacoes_abertas(request):
kwargs={'pk': v.id}), kwargs={'pk': v.id}),
v.__str__())) v.__str__()))
username = request.user.username username = request.user.username
logger.info('user=' + username + '. Já existem votações abertas nas seguintes Sessões: ' + logger.info('user=' + username + '. Já existem votações ou leituras abertas nas seguintes Sessões: ' +
', '.join(msg_abertas) + '. Para abrir ' ', '.join(msg_abertas) + '. Para abrir '
'outra, termine ou feche as votações abertas.') 'outra, termine ou feche as votações ou leituras abertas.')
msg = _('Já existem votações abertas nas seguintes Sessões: ' + msg = _('Já existem votações ou leituras abertas nas seguintes Sessões: ' +
', '.join(msg_abertas) + '. Para abrir ' ', '.join(msg_abertas) + '. Para abrir '
'outra, termine ou feche as votações abertas.') 'outra, termine ou feche as votações ou leituras abertas.')
messages.add_message(request, messages.INFO, msg) messages.add_message(request, messages.INFO, msg)
return False return False
@ -254,7 +255,11 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
materia=obj.materia).exists() materia=obj.materia).exists()
exist_retirada = obj.retiradapauta_set.filter( exist_retirada = obj.retiradapauta_set.filter(
materia=obj.materia).exists() materia=obj.materia).exists()
if not exist_resultado and not exist_retirada: exist_leitura = obj.registroleitura_set.filter(
materia=obj.materia).exists()
if (obj.tipo_votacao != 4 and not exist_resultado and not exist_retirada) or\
(obj.tipo_votacao == 4 and not exist_leitura):
if obj.votacao_aberta: if obj.votacao_aberta:
url = '' url = ''
if is_expediente: if is_expediente:
@ -302,9 +307,15 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.pk, 'oid': obj.pk,
'mid': obj.materia_id}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 4:
url = reverse('sapl.sessao:leituraod',
kwargs={
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'mid': obj.materia_id})
if has_permission: if has_permission:
if not obj.tipo_votacao == 4: if obj.tipo_votacao != 4:
btn_registrar = ''' btn_registrar = '''
<form action="%s"> <form action="%s">
<input type="submit" class="btn btn-primary" <input type="submit" class="btn btn-primary"
@ -365,10 +376,16 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
retirada_observacao)) retirada_observacao))
else: else:
resultado = obj.registrovotacao_set.filter( if obj.tipo_votacao == 4:
materia_id=obj.materia_id).last() resultado = obj.registroleitura_set.filter(
resultado_descricao = resultado.tipo_resultado_votacao.nome materia_id=obj.materia_id).last()
resultado_observacao = resultado.observacao resultado_descricao = "Matéria lida"
resultado_observacao = resultado.observacao
else:
resultado = obj.registrovotacao_set.filter(
materia_id=obj.materia_id).last()
resultado_descricao = obj.resultado
resultado_observacao = obj.observacao
if has_permission: if has_permission:
url = '' url = ''
@ -392,6 +409,12 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.pk, 'oid': obj.pk,
'mid': obj.materia_id}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 4:
url = reverse('sapl.sessao:leituraexp',
kwargs={
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'mid': obj.materia_id})
else: else:
if obj.tipo_votacao == 1: if obj.tipo_votacao == 1:
url = reverse('sapl.sessao:votacaosimbolicaedit', url = reverse('sapl.sessao:votacaosimbolicaedit',
@ -411,11 +434,17 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.pk, 'oid': obj.pk,
'mid': obj.materia_id}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 4:
url = reverse('sapl.sessao:leituraod',
kwargs={
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'mid': obj.materia_id})
resultado = ('<a href="%s">%s<br/>%s</a>' % resultado = ('<a href="%s">%s<br/><br/>%s</a>' %
(url, (url,
resultado_descricao, resultado_descricao,
resultado_observacao)) resultado_observacao))
else: else:
if obj.tipo_votacao == 2: if obj.tipo_votacao == 2:
@ -4345,26 +4374,63 @@ class RetiradaPautaCrud(MasterDetailCrud):
pass pass
class ExpedienteLeituraView(FormView):
class AbstractLeituraView(FormView):
template_name = 'sessao/votacao/leitura_form.html' template_name = 'sessao/votacao/leitura_form.html'
form_class = ExpedienteLeitura
success_url = '/' success_url = '/'
form_class = OrdemExpedienteLeituraForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['materia'] = MateriaLegislativa.objects.get(id=self.kwargs['mid'])
return context
def get_initial(self): def get_initial(self):
initial = super().get_initial() initial = super().get_initial()
sessao = SessaoPlenaria.objects.get(id=self.kwargs['pk']) sessao = SessaoPlenaria.objects.get(id=self.kwargs['pk'])
expediente = ExpedienteMateria.objects.get(id=self.kwargs['oid'])
materia = MateriaLegislativa.objects.get(id=self.kwargs['mid']) materia = MateriaLegislativa.objects.get(id=self.kwargs['mid'])
return {'materia': materia, 'materia__ementa':materia.ementa} initial['materia'] = materia
initial['materia__ementa'] = materia.ementa
if self.expediente:
expediente = ExpedienteMateria.objects.get(id=self.kwargs['oid'])
instance = RegistroLeitura.objects.filter(materia=materia, expediente=expediente)
initial['expediente'] = expediente
else:
ordem = OrdemDia.objects.get(id=self.kwargs['oid'])
instance = RegistroLeitura.objects.filter(materia=materia, ordem=ordem)
initial['ordem'] = ordem
initial['instance'] = instance
return initial
def form_valid(self, form): def form_valid(self, form):
expediente = ExpedienteMateria.objects.get(id=self.kwargs['oid']) if self.expediente:
expediente.resultado = "Matéria lida" model = ExpedienteMateria
expediente.votacao_aberta = False else:
expediente.save() model = OrdemDia
ordem_expediente = model.objects.get(id=self.kwargs['oid'])
ordem_expediente.resultado = "Matéria lida"
ordem_expediente.votacao_aberta = False
ordem_expediente.save()
form.save()
return super().form_valid(form) return super().form_valid(form)
def get_success_url(self): def get_success_url(self):
pk = self.kwargs['pk'] pk = self.kwargs['pk']
return reverse('sapl.sessao:expedientemateria_list', if self.expediente:
url = reverse('sapl.sessao:expedientemateria_list',
kwargs={'pk': pk})
else:
url = reverse('sapl.sessao:ordemdia_list',
kwargs={'pk': pk}) kwargs={'pk': pk})
return url
def cancel_url(self):
return self.get_success_url()
class ExpedienteLeituraView(AbstractLeituraView):
expediente = True
class OrdemDiaLeituraView(AbstractLeituraView):
expediente = False

1
sapl/templates/sessao/layouts.yaml

@ -67,6 +67,7 @@ OrdemDia:
- data_ordem numero_ordem - data_ordem numero_ordem
- tipo_materia numero_materia ano_materia - tipo_materia numero_materia ano_materia
- tipo_votacao - tipo_votacao
- apenas_leitura
- observacao - observacao
ExpedienteMateriaDetail: ExpedienteMateriaDetail:

7
sapl/templates/sessao/votacao/leitura_form.html

@ -1,3 +1,6 @@
{% extends "crud/form.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n crispy_forms_tags %}
{% block base_content %}
{% crispy form %}
{% endblock base_content %}

Loading…
Cancel
Save