diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py
index 6aea339ff..30089075f 100644
--- a/sapl/sessao/forms.py
+++ b/sapl/sessao/forms.py
@@ -1,7 +1,8 @@
-from datetime import datetime
import re
from crispy_forms.layout import Button, Fieldset, HTML, Layout
+from datetime import datetime
+
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist, ValidationError
@@ -12,6 +13,7 @@ from django.forms.widgets import CheckboxSelectMultiple
from django.utils.translation import ugettext_lazy as _
import django_filters
+import sapl.utils
from sapl.base.models import Autor, TipoAutor
from sapl.crispy_layout_mixin import (form_actions, to_row,
SaplFormHelper, SaplFormLayout)
@@ -33,13 +35,16 @@ from .models import (Bancada, ExpedienteMateria,
ORDENACAO_RESUMO, PresencaOrdemDia,
RegistroLeitura, ResumoOrdenacao, RetiradaPauta,
SessaoPlenaria, SessaoPlenariaPresenca,
- TipoResultadoVotacao, TipoRetiradaPauta)
-
+ TipoResultadoVotacao, TipoRetiradaPauta, Tramitacao)
MES_CHOICES = RANGE_MESES
DIA_CHOICES = RANGE_DIAS_MES
+def tramitacao_select_validation():
+ return True
+
+
class SessaoPlenariaForm(FileFieldCheckMixin, ModelForm):
class Meta:
@@ -109,7 +114,7 @@ class SessaoPlenariaForm(FileFieldCheckMixin, ModelForm):
if upload_pauta:
validar_arquivo(upload_pauta, "Pauta da Sessão")
-
+
if upload_ata:
validar_arquivo(upload_ata, "Ata da Sessão")
@@ -117,12 +122,12 @@ class SessaoPlenariaForm(FileFieldCheckMixin, ModelForm):
validar_arquivo(upload_anexo, "Anexo da Sessão")
hora_inicio = self.cleaned_data['hora_inicio']
- if not re.match(TIME_PATTERN, hora_inicio):
+ if not re.match(sapl.utils.TIME_PATTERN, hora_inicio):
raise ValidationError(f'Formato ou valores de horário de '
f'abertura errados: {hora_inicio}')
hora_fim = self.cleaned_data['hora_fim']
- if hora_fim and not re.match(TIME_PATTERN, hora_fim):
+ if hora_fim and not re.match(sapl.utils.TIME_PATTERN, hora_fim):
raise ValidationError(f'Formato ou valores de horário de '
f'encerramento errados: {hora_fim}.')
@@ -294,6 +299,12 @@ class BancadaForm(ModelForm):
return bancada
+class DependentChoiceField(forms.ChoiceField):
+
+ def validate(self, value):
+ return True
+
+
class ExpedienteMateriaForm(ModelForm):
_model = ExpedienteMateria
@@ -306,6 +317,10 @@ class ExpedienteMateriaForm(ModelForm):
empty_label='Selecione',
widget=forms.Select(attrs={'autocomplete': 'off'}))
+ tramitacao_select = DependentChoiceField(
+ label=_('Situação Atual'),
+ widget=forms.Select())
+
numero_materia = forms.CharField(
label='Número Matéria', required=True,
widget=forms.TextInput(attrs={'autocomplete': 'off'}))
@@ -326,7 +341,7 @@ class ExpedienteMateriaForm(ModelForm):
class Meta:
model = ExpedienteMateria
fields = ['data_ordem', 'numero_ordem', 'tipo_materia', 'observacao',
- 'numero_materia', 'ano_materia', 'tipo_votacao']
+ 'numero_materia', 'ano_materia', 'tramitacao_select', 'tipo_votacao']
def clean_numero_ordem(self):
sessao = self.instance.sessao_plenaria
@@ -363,11 +378,28 @@ class ExpedienteMateriaForm(ModelForm):
else:
cleaned_data['materia'] = materia
+ try:
+ id_t = self.cleaned_data['tramitacao_select'] if self.cleaned_data['tramitacao_select'] != '' else -1
+ tramitacao = materia.tramitacao_set.get(pk=self.cleaned_data['tramitacao_select'] if self.cleaned_data['tramitacao_select'] != '' else -1)
+ except ObjectDoesNotExist:
+ if self.cleaned_data['tramitacao_select'] != '':
+ raise ValidationError(
+ _('Tramitação selecionada não existe para a Matéria: %(value)s'),
+ code='invalid',
+ params={'value': self.cleaned_data['tramitacao_select']},
+ )
+ else:
+ cleaned_data['tramitacao'] = False
+ else:
+ cleaned_data['tramitacao'] = tramitacao
+
return cleaned_data
def save(self, commit=False):
expediente = super(ExpedienteMateriaForm, self).save(commit)
expediente.materia = self.cleaned_data['materia']
+ if self.cleaned_data['tramitacao'] is not False:
+ expediente.tramitacao = self.cleaned_data['tramitacao']
expediente.save()
return expediente
@@ -996,7 +1028,7 @@ class OrdemExpedienteLeituraForm(forms.ModelForm):
'ordem',
'expediente',
'observacao',
- 'user',
+ 'user',
'ip']
widgets = {'materia': forms.HiddenInput(),
'ordem': forms.HiddenInput(),
@@ -1008,14 +1040,14 @@ class OrdemExpedienteLeituraForm(forms.ModelForm):
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(
- [('observacao', 12)])
+ [('observacao', 12)])
actions = [HTML('Cancelar Leitura')]
@@ -1024,11 +1056,11 @@ class OrdemExpedienteLeituraForm(forms.ModelForm):
self.helper.form_method = 'POST'
self.helper.layout = Layout(
Fieldset(_('Leitura de Matéria'),
- HTML('''
+ HTML('''
Matéria: {{materia}}
Ementa: {{materia.ementa}}
'''),
row1,
form_actions(more=actions),
- )
- )
+ )
+ )
\ No newline at end of file
diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py
index 39f144c2c..944c1e81d 100644
--- a/sapl/sessao/models.py
+++ b/sapl/sessao/models.py
@@ -10,6 +10,7 @@ import reversion
from sapl.base.models import Autor
from sapl.materia.models import MateriaLegislativa
+from sapl.materia.models import Tramitacao
from sapl.parlamentares.models import (CargoMesa, Legislatura, Parlamentar,
Partido, SessaoLegislativa)
from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation,
@@ -360,6 +361,12 @@ class AbstractOrdemDia(models.Model):
materia = models.ForeignKey(MateriaLegislativa,
on_delete=models.PROTECT,
verbose_name=_('Matéria'))
+ tramitacao = models.ForeignKey(Tramitacao,
+ on_delete=models.PROTECT,
+ verbose_name=_('Situação Atual'),
+ blank=True,
+ default='',
+ null=True)
data_ordem = models.DateField(verbose_name=_('Data da Sessão'))
observacao = models.TextField(
blank=True, verbose_name=_('Observação'))
diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py
index af66c2d83..a2269972c 100644
--- a/sapl/sessao/urls.py
+++ b/sapl/sessao/urls.py
@@ -36,7 +36,8 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
OrdemDiaLeituraView,
retirar_leitura,
TransferenciaMateriasExpediente, TransferenciaMateriasOrdemDia,
- filtra_materias_copia_sessao_ajax, verifica_materia_sessao_plenaria_ajax)
+ filtra_materias_copia_sessao_ajax, verifica_materia_sessao_plenaria_ajax,
+ recuperar_tramitacao)
from .apps import AppConfig
@@ -68,6 +69,7 @@ urlpatterns = [
name='remove_parlamentar_composicao'),
url(r'^sessao/recuperar-materia/', recuperar_materia),
+ url(r'^sessao/recuperar-tramitacao/', recuperar_tramitacao),
url(r'^sessao/recuperar-numero-sessao/',
recuperar_numero_sessao_view,
name='recuperar_numero_sessao_view'
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index 94e5419a0..932ec0f90 100755
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -1,4 +1,4 @@
-
+import json
from collections import OrderedDict
from datetime import datetime
from re import sub
@@ -754,7 +754,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['numero_ordem', 'materia',
- ('materia__ementa', '', 'observacao'),
+ ('materia__ementa', '', 'tramitacao', 'observacao'),
'resultado']
class CreateView(MasterDetailCrud.CreateView):
@@ -790,6 +790,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
context["tipo_materia_salvo"] = self.object.materia.tipo.id
context["numero_materia_salvo"] = self.object.materia.numero
context["ano_materia_salvo"] = self.object.materia.ano
+ context["tramitacao_salvo"] = None if not self.object.tramitacao else self.object.tramitacao.id
return context
@@ -800,6 +801,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
initial['numero_materia'] = self.object.materia.numero
initial['ano_materia'] = self.object.materia.ano
initial['numero_ordem'] = self.object.numero_ordem
+ initial['tramitacao'] = None if not self.object.tramitacao else self.object.tramitacao.id
return initial
@@ -839,6 +841,23 @@ def recuperar_materia(request):
return response
+def recuperar_tramitacao(request):
+ tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo_materia'])
+ numero = request.GET['numero_materia']
+ ano = request.GET['ano_materia']
+
+ try:
+ materia = MateriaLegislativa.objects.get(tipo=tipo,
+ ano=ano,
+ numero=numero)
+ tramitacao = {}
+ for obj in materia.tramitacao_set.all():
+ tramitacao[obj.id] = obj.status.descricao
+ response = JsonResponse(tramitacao)
+ except ObjectDoesNotExist:
+ response = JsonResponse({'id': 0})
+
+ return response
class ExpedienteMateriaCrud(MasterDetailCrud):
model = ExpedienteMateria
@@ -904,6 +923,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
context["tipo_materia_salvo"] = self.object.materia.tipo.id
context["numero_materia_salvo"] = self.object.materia.numero
context["ano_materia_salvo"] = self.object.materia.ano
+ context["tramitacao_salvo"] = self.object.tramitacao.id if self.object.tramitacao is not None else ''
return context
@@ -914,6 +934,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
initial['numero_materia'] = self.object.materia.numero
initial['ano_materia'] = self.object.materia.ano
initial['numero_ordem'] = self.object.numero_ordem
+ initial['tramitacao'] = self.object.tramitacao.id if self.object.tramitacao is not None else ''
return initial
@@ -3757,8 +3778,8 @@ class PautaSessaoDetailView(DetailView):
data_sessao = sessao_plenaria.data_inicio.strftime("%Y-%m-%d ")
data_hora_sessao = datetime.strptime(data_sessao + sessao_plenaria.hora_inicio, "%Y-%m-%d %H:%M")
data_hora_sessao_utc = pytz.timezone(TIME_ZONE).localize(data_hora_sessao).astimezone(pytz.utc)
- ultima_tramitacao = m.materia.tramitacao_set.filter(timestamp__lt = data_hora_sessao_utc).order_by(
- '-data_tramitacao', '-id').first()
+ ultima_tramitacao = m.materia.tramitacao_set.filter(timestamp__lt=data_hora_sessao_utc).order_by(
+ '-data_tramitacao', '-id').first() if m.tramitacao is None else m.tramitacao
numeracao = m.materia.numeracao_set.first()
materias_expediente.append({
@@ -3813,7 +3834,7 @@ class PautaSessaoDetailView(DetailView):
data_hora_sessao = datetime.strptime(data_sessao + sessao_plenaria.hora_inicio, "%Y-%m-%d %H:%M")
data_hora_sessao_utc = pytz.timezone(TIME_ZONE).localize(data_hora_sessao).astimezone(pytz.utc)
ultima_tramitacao = o.materia.tramitacao_set.filter(timestamp__lt=data_hora_sessao_utc).order_by(
- '-data_tramitacao', '-id').first()
+ '-data_tramitacao', '-id').first() if o.tramitacao is None else o.tramitacao
numeracao = o.materia.numeracao_set.first()
materias_ordem.append({
diff --git a/sapl/templates/sessao/expedientemateria_form.html b/sapl/templates/sessao/expedientemateria_form.html
index 424679dd5..ee992fda3 100644
--- a/sapl/templates/sessao/expedientemateria_form.html
+++ b/sapl/templates/sessao/expedientemateria_form.html
@@ -54,11 +54,40 @@
}
}
+ function recuperar_tramitacao() {
+ let tipo_materia = $("#id_tipo_materia").val()
+ let numero_materia = $("#id_numero_materia").val()
+ let ano_materia = $("#id_ano_materia").val()
+ let tramitacao_salvo = "{{ tramitacao_salvo }}"
+
+ if (tipo_materia && numero_materia && ano_materia) {
+ $.get("/sessao/recuperar-tramitacao",
+ { tipo_materia: tipo_materia, numero_materia: numero_materia, ano_materia: ano_materia },
+ function(data, status) {
+ if (status == 'success') {
+ $('#id_tramitacao_select').find('option').remove()
+ $('#id_tramitacao_select').append('');
+ for (const property in data) {
+ console.log(tramitacao_salvo + "===" + property)
+ $('#id_tramitacao_select').append('');
+ if (property == tramitacao_salvo) {
+ $("#id_tramitacao_select option[value='"+ property +"']").attr("selected", "selected");
+ }
+ }
+ }
+ });
+ }
+ }
+
var fields = ["#id_tipo_materia", "#id_numero_materia", "#id_ano_materia"];
for (i = 0; i < fields.length; i++){
- $(fields[i]).change(recuperar_materia)
+ $(fields[i]).change(function() {
+ recuperar_materia();
+ recuperar_tramitacao();
+ });
}
- recuperar_materia()
+ recuperar_materia();
+ recuperar_tramitacao();
var modal_estilos = 'display: block; width: 85%; max-width: 600px; background: #fff; padding: 15px; border-radius: 5px;'
+'-webkit-box-shadow: 0px 6px 14px -2px rgba(0, 0, 0, 0.75); -moz-box-shadow: 0px 6px 14px -2px rgba(0, 0, 0, 0.75);'
diff --git a/sapl/templates/sessao/layouts.yaml b/sapl/templates/sessao/layouts.yaml
index 814319878..78517b708 100644
--- a/sapl/templates/sessao/layouts.yaml
+++ b/sapl/templates/sessao/layouts.yaml
@@ -60,6 +60,7 @@ ExpedienteMateria:
- tipo_materia numero_materia ano_materia
- tipo_votacao
- apenas_leitura
+ - tramitacao_select
- observacao
OrdemDia:
@@ -68,6 +69,7 @@ OrdemDia:
- tipo_materia numero_materia ano_materia
- tipo_votacao
- apenas_leitura
+ - tramitacao_select
- observacao
ExpedienteMateriaDetail:
@@ -75,6 +77,7 @@ ExpedienteMateriaDetail:
- materia
- ementa
- tipo_votacao
+ - tramitacao
- observacao
OrdemDiaDetail:
@@ -82,6 +85,7 @@ OrdemDiaDetail:
- materia
- ementa
- tipo_votacao
+ - tramitacao
- observacao
Bancada: