diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py
index e5f8576ed..e0215dd60 100644
--- a/sapl/sessao/forms.py
+++ b/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)])
+ [('observacao', 12)])
+
+ actions = [HTML('Cancelar')]
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('''
+ Matéria: {{materia}}
+ Ementa: {{materia.ementa}}
+ '''),
+ row1,
+ form_actions(more=actions),
+ )
)
\ No newline at end of file
diff --git a/sapl/sessao/migrations/0046_auto_20190827_1228.py b/sapl/sessao/migrations/0046_auto_20190827_1228.py
new file mode 100644
index 000000000..d37e2b200
--- /dev/null
+++ b/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),
+ ),
+ ]
diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py
index 7b5743759..84b890296 100644
--- a/sapl/sessao/models.py
+++ b/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))
\ No newline at end of file
diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py
index 686f08bea..3509a5117 100644
--- a/sapl/sessao/urls.py
+++ b/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\d+)/matordemdia/votnom/(?P\d+)/(?P\d+)$',
VotacaoNominalView.as_view(), name='votacaonominal'),
- url(r'^sessao/(?P\d+)/matordemdia/votnom'
- '/edit/(?P\d+)/(?P\d+)$',
+ url(r'^sessao/(?P\d+)/matordemdia/votnom/edit/(?P\d+)/(?P\d+)$',
VotacaoNominalEditView.as_view(), name='votacaonominaledit'),
url(r'^sessao/(?P\d+)/matordemdia/votsec/(?P\d+)/(?P\d+)$',
VotacaoView.as_view(), name='votacaosecreta'),
- url(r'^sessao/(?P\d+)/matordemdia/votsec'
- '/view/(?P\d+)/(?P\d+)$',
+ url(r'^sessao/(?P\d+)/matordemdia/votsec/view/(?P\d+)/(?P\d+)$',
VotacaoEditView.as_view(), name='votacaosecretaedit'),
url(r'^sessao/(?P\d+)/matordemdia/votsimb/(?P\d+)/(?P\d+)$',
VotacaoView.as_view(), name='votacaosimbolica'),
@@ -165,8 +164,7 @@ urlpatterns = [
url(r'^sessao/(?P\d+)/matordemdia/votsimbbloco/$',
VotacaoView.as_view(), name='votacaosimbolicabloco'),
- url(r'^sessao/(?P\d+)/matordemdia/votsimb'
- '/view/(?P\d+)/(?P\d+)$',
+ url(r'^sessao/(?P\d+)/matordemdia/votsimb/view/(?P\d+)/(?P\d+)$',
VotacaoEditView.as_view(), name='votacaosimbolicaedit'),
url(r'^sessao/(?P\d+)/matexp/votnom/(?P\d+)/(?P\d+)$',
VotacaoNominalExpedienteView.as_view(), name='votacaonominalexp'),
@@ -196,5 +194,7 @@ urlpatterns = [
url(r'^sessao/(?P\d+)/matexp/leitura/(?P\d+)/(?P\d+)$',
ExpedienteLeituraView.as_view(), name='leituraexp'),
+ url(r'^sessao/(?P\d+)/matordemdia/leitura/(?P\d+)/(?P\d+)$',
+ OrdemDiaLeituraView.as_view(), name='leituraod'),
]
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index 0504e8064..737406711 100755
--- a/sapl/sessao/views.py
+++ b/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 = '''