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,
SessaoPlenariaPresenca, TipoResultadoVotacao,
OcorrenciaSessao, RetiradaPauta, TipoRetiradaPauta, OradorOrdemDia, ORDENACAO_RESUMO,
ResumoOrdenacao)
ResumoOrdenacao, RegistroLeitura)
MES_CHOICES = RANGE_MESES
@ -1027,32 +1027,45 @@ class JustificativaAusenciaForm(ModelForm):
return justificativa
class ExpedienteLeitura(forms.Form):
materia = forms.CharField(
label='Matéria',
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
materia__ementa = forms.CharField(
label='Ementa',
widget=forms.TextInput(attrs={'readonly': 'readonly'}))
class OrdemExpedienteLeituraForm(forms.ModelForm):
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):
super().__init__(*args, **kwargs)
instance = self.initial['instance']
if instance:
self.instance = instance.first()
self.fields['observacao'].initial = self.instance.observacao
row1 = to_row(
[('materia', 12)])
row2 = to_row(
[('materia__ementa', 12)])
row3 = to_row(
[('observacao', 12)])
actions = [HTML('<a href="{{ view.cancel_url }}"'
' class="btn btn-dark">Cancelar</a>')]
self.helper = SaplFormHelper()
self.helper.form_method = 'POST'
self.helper.layout = Layout(
Fieldset(_('Leitura de Matéria'),
row1, row2, row3,
form_actions(label='Salvar'))
HTML('''
<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 '
'ordem ou expediente preenchido. Ambos estão preenchidos: '
'{}, {}'. 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,
VotacaoEmBlocoSimbolicaView, VotacaoEmBlocoNominalView,
recuperar_nome_tipo_sessao,
ExpedienteLeituraView)
ExpedienteLeituraView,
OrdemDiaLeituraView)
from .apps import AppConfig
@ -151,13 +152,11 @@ urlpatterns = [
PesquisarSessaoPlenariaView.as_view(), name='pesquisar_sessao'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votnom/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoNominalView.as_view(), name='votacaonominal'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votnom'
'/edit/(?P<oid>\d+)/(?P<mid>\d+)$',
url(r'^sessao/(?P<pk>\d+)/matordemdia/votnom/edit/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoNominalEditView.as_view(), name='votacaonominaledit'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsec/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoView.as_view(), name='votacaosecreta'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsec'
'/view/(?P<oid>\d+)/(?P<mid>\d+)$',
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsec/view/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoEditView.as_view(), name='votacaosecretaedit'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimb/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoView.as_view(), name='votacaosimbolica'),
@ -165,8 +164,7 @@ urlpatterns = [
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimbbloco/$',
VotacaoView.as_view(), name='votacaosimbolicabloco'),
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimb'
'/view/(?P<oid>\d+)/(?P<mid>\d+)$',
url(r'^sessao/(?P<pk>\d+)/matordemdia/votsimb/view/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoEditView.as_view(), name='votacaosimbolicaedit'),
url(r'^sessao/(?P<pk>\d+)/matexp/votnom/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoNominalExpedienteView.as_view(), name='votacaonominalexp'),
@ -196,5 +194,7 @@ urlpatterns = [
url(r'^sessao/(?P<pk>\d+)/matexp/leitura/(?P<oid>\d+)/(?P<mid>\d+)$',
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,
Parlamentar, SessaoLegislativa)
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 .forms import (AdicionarVariasMateriasFilterSet, BancadaForm,
@ -49,7 +49,8 @@ from .models import (Bancada, CargoBancada, CargoMesa,
PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao,
SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente,
TipoResultadoVotacao, TipoSessaoPlenaria, VotoParlamentar, TipoRetiradaPauta,
RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia, ORDENACAO_RESUMO)
RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia,
ORDENACAO_RESUMO, RegistroLeitura)
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
@ -142,12 +143,12 @@ def verifica_votacoes_abertas(request):
kwargs={'pk': v.id}),
v.__str__()))
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 '
'outra, termine ou feche as votações abertas.')
msg = _('Já existem votações abertas nas seguintes Sessões: ' +
'outra, termine ou feche as votações ou leituras abertas.')
msg = _('Já existem votações ou leituras abertas nas seguintes Sessões: ' +
', '.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)
return False
@ -254,7 +255,11 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
materia=obj.materia).exists()
exist_retirada = obj.retiradapauta_set.filter(
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:
url = ''
if is_expediente:
@ -302,9 +307,15 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'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 not obj.tipo_votacao == 4:
if obj.tipo_votacao != 4:
btn_registrar = '''
<form action="%s">
<input type="submit" class="btn btn-primary"
@ -365,10 +376,16 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
retirada_observacao))
else:
resultado = obj.registrovotacao_set.filter(
materia_id=obj.materia_id).last()
resultado_descricao = resultado.tipo_resultado_votacao.nome
resultado_observacao = resultado.observacao
if obj.tipo_votacao == 4:
resultado = obj.registroleitura_set.filter(
materia_id=obj.materia_id).last()
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:
url = ''
@ -392,6 +409,12 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'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:
if obj.tipo_votacao == 1:
url = reverse('sapl.sessao:votacaosimbolicaedit',
@ -411,11 +434,17 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'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>' %
(url,
resultado_descricao,
resultado_observacao))
resultado = ('<a href="%s">%s<br/><br/>%s</a>' %
(url,
resultado_descricao,
resultado_observacao))
else:
if obj.tipo_votacao == 2:
@ -4345,26 +4374,63 @@ class RetiradaPautaCrud(MasterDetailCrud):
pass
class ExpedienteLeituraView(FormView):
class AbstractLeituraView(FormView):
template_name = 'sessao/votacao/leitura_form.html'
form_class = ExpedienteLeitura
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):
initial = super().get_initial()
sessao = SessaoPlenaria.objects.get(id=self.kwargs['pk'])
expediente = ExpedienteMateria.objects.get(id=self.kwargs['oid'])
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):
expediente = ExpedienteMateria.objects.get(id=self.kwargs['oid'])
expediente.resultado = "Matéria lida"
expediente.votacao_aberta = False
expediente.save()
if self.expediente:
model = ExpedienteMateria
else:
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)
def get_success_url(self):
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})
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
- tipo_materia numero_materia ano_materia
- tipo_votacao
- apenas_leitura
- observacao
ExpedienteMateriaDetail:

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

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

Loading…
Cancel
Save