Browse Source

Merge tag '3.1.158' into migracao

migracao
Marcio Mazza 6 years ago
parent
commit
9fa615d73c
  1. 2
      docker-compose.yml
  2. 24
      sapl/compilacao/views.py
  3. 25
      sapl/materia/forms.py
  4. 1
      sapl/materia/tests/test_materia.py
  5. 13
      sapl/materia/tests/test_materia_form.py
  6. 20
      sapl/materia/views.py
  7. 19
      sapl/parlamentares/migrations/0030_auto_20190613_1133.py
  8. 1
      sapl/parlamentares/models.py
  9. 2
      sapl/protocoloadm/forms.py
  10. 4
      sapl/protocoloadm/views.py
  11. 15
      sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py
  12. 48
      sapl/sessao/forms.py
  13. 27
      sapl/sessao/migrations/0041_auto_20190610_1300.py
  14. 72
      sapl/sessao/models.py
  15. 6
      sapl/sessao/urls.py
  16. 239
      sapl/sessao/views.py
  17. 2
      sapl/settings.py
  18. 26
      sapl/templates/base.html
  19. 14
      sapl/templates/materia/em_lote/tramitacao.html
  20. 36
      sapl/templates/materia/materia_detail.html
  21. 30
      sapl/templates/materia/materialegislativa_detail.html
  22. 19
      sapl/templates/materia/tramitacao_form.html
  23. 2
      sapl/templates/navbar.yaml
  24. 52
      sapl/templates/painel/index.html
  25. 16
      sapl/templates/protocoloadm/em_lote/tramitacaoadm.html
  26. 15
      sapl/templates/protocoloadm/tramitacaoadministrativo_form.html
  27. 10
      sapl/templates/sessao/blocos_ata/expedientes.html
  28. 18
      sapl/templates/sessao/blocos_resumo/expedientes.html
  29. 4
      sapl/templates/sessao/layouts.yaml
  30. 44
      sapl/templates/sessao/painel.html
  31. 4
      sapl/templates/sessao/pauta_sessao_detail.html
  32. 45
      sapl/templates/sessao/sessaoplenaria_form.html
  33. 14
      sapl/templates/sessao/votacao/votacao.html
  34. 7
      sapl/templates/sessao/votacao/votacao_simbolica_bloco.html
  35. 2
      setup.py

2
docker-compose.yml

@ -11,7 +11,7 @@ sapldb:
ports:
- "5432:5432"
sapl:
image: interlegis/sapl:3.1.157-RC5
image: interlegis/sapl:3.1.158
# build: .
restart: always
environment:

24
sapl/compilacao/views.py

@ -2147,8 +2147,11 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
return self.json_add_next(context, local_add='json_add_in')
def json_add_next(
self,
context, local_add='json_add_next', create_auto_inserts=True):
self,
context, local_add='json_add_next',
create_auto_inserts=True,
registro_inclusao=False
):
try:
@ -2249,7 +2252,9 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
dp.rotulo = dp.rotulo_padrao()
dp.ordem = ordem
dp.incrementar_irmaos(variacao, [local_add, ], force=False)
if not registro_inclusao:
dp.incrementar_irmaos(variacao, [local_add, ], force=False)
dp.publicacao = pub_last
dp.save()
@ -2380,9 +2385,10 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
filho.save()
''' Renumerar dispositivos de
contagem continua, caso a inserção seja uma articulação'''
contagem continua, caso a inserção seja uma articulação.
Desde que não seja um registro de inclusão através de compilação'''
if dp.nivel == 0:
if dp.nivel == 0 and not registro_inclusao:
proxima_articulacao = dp.select_next_root()
@ -2522,7 +2528,8 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
data = self.json_add_next(context,
local_add=local_add,
create_auto_inserts=True)
create_auto_inserts=True,
registro_inclusao=True)
if data and data['pk']:
@ -2554,6 +2561,11 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
else:
data.update({'pk': bloco_alteracao.pk,
'pai': [bloco_alteracao.pk, ]})
self.set_message(
data, 'danger',
_('Não é possível incluir seu Registro de Inclusão, '
'verifique a opção escolhida e as variações possíveis!'),
time=10000)
return data

25
sapl/materia/forms.py

@ -285,7 +285,7 @@ class MateriaLegislativaForm(FileFieldCheckMixin, ModelForm):
materia = super(MateriaLegislativaForm, self).save(commit)
materia.save()
if self.cleaned_data['autor']:
autoria = Autoria()
autoria.primeiro_autor = primeiro_autor
@ -1168,7 +1168,7 @@ class DespachoInicialForm(ModelForm):
class AutoriaForm(ModelForm):
tipo_autor = ModelChoiceField(label=_('Tipo Autor'),
required=False,
required=True,
queryset=TipoAutor.objects.all(),
empty_label=_('Selecione'),)
@ -1180,6 +1180,12 @@ class AutoriaForm(ModelForm):
def __init__(self, *args, **kwargs):
super(AutoriaForm, self).__init__(*args, **kwargs)
self.fields['primeiro_autor'].required = True
if 'initial' in kwargs and 'materia' in kwargs['initial']:
materia = kwargs['initial']['materia']
self.fields['primeiro_autor'].initial = Autoria.objects.filter(materia=materia).count() == 0
row1 = to_row([('tipo_autor', 4),
('autor', 4),
('primeiro_autor', 4)])
@ -1220,7 +1226,7 @@ class AutoriaMultiCreateForm(Form):
logger = logging.getLogger(__name__)
tipo_autor = ModelChoiceField(label=_('Tipo Autor'),
required=False,
required=True,
queryset=TipoAutor.objects.all(),
empty_label=_('Selecione'),)
@ -1230,7 +1236,7 @@ class AutoriaMultiCreateForm(Form):
autor = ModelMultipleChoiceField(
queryset=Autor.objects.all(),
label=_('Possiveis Autores'),
required=False,
required=True,
widget=CheckboxSelectMultiple)
autores = ModelMultipleChoiceField(
@ -1238,10 +1244,19 @@ class AutoriaMultiCreateForm(Form):
required=False,
widget=HiddenInput)
primeiro_autor = forms.ChoiceField(
required=True,
choices=YES_NO_CHOICES,
label="Primeiro Autor?"
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
row1 = to_row([('tipo_autor', 12), ])
if 'initial' in kwargs and 'autores' in kwargs['initial']:
self.fields['primeiro_autor'].initial = kwargs['initial']['autores'].count() == 0
row1 = to_row([('tipo_autor', 10), ('primeiro_autor', 2)])
row2 = to_row([('autor', 12), ])

1
sapl/materia/tests/test_materia.py

@ -243,6 +243,7 @@ def test_autoria_submit(admin_client):
reverse('sapl.materia:autoria_create',
kwargs={'pk': materia_principal.pk}),
{'autor': autor.pk,
'tipo_autor': tipo_autor.pk,
'primeiro_autor': True,
'materia_id': materia_principal.pk, },
follow=True)

13
sapl/materia/tests/test_materia_form.py

@ -129,9 +129,11 @@ def test_valida_campos_obrigatorios_autoria_form():
errors = form.errors
assert errors['autor'] == [_('Este campo é obrigatório.')]
assert len(errors) == 3
assert len(errors) == 1
assert errors['tipo_autor'] == [_('Este campo é obrigatório.')]
assert errors['autor'] == [_('Este campo é obrigatório.')]
assert errors['primeiro_autor'] == [_('Este campo é obrigatório.')]
@pytest.mark.django_db(transaction=False)
@ -142,9 +144,12 @@ def test_valida_campos_obrigatorios_autoria_multicreate_form():
errors = form.errors
assert errors['__all__'] == [_('Ao menos um autor deve ser selecionado para inclusão')]
assert len(errors) == 4
assert len(errors) == 1
assert errors['__all__'] == [_('Ao menos um autor deve ser selecionado para inclusão')]
assert errors['tipo_autor'] == [_('Este campo é obrigatório.')]
assert errors['autor'] == [_('Este campo é obrigatório.')]
assert errors['primeiro_autor'] == [_('Este campo é obrigatório.')]
@pytest.mark.django_db(transaction=False)

20
sapl/materia/views.py

@ -1224,7 +1224,7 @@ class TramitacaoCrud(MasterDetailCrud):
# não pode ser modificado
if not primeira_tramitacao:
context['form'].fields[
'unidade_tramitacao_local'].widget.attrs['disabled'] = True
'unidade_tramitacao_local'].widget.attrs['readonly'] = True
return context
@ -1432,6 +1432,7 @@ class AutoriaCrud(MasterDetailCrud):
materia = MateriaLegislativa.objects.get(id=self.kwargs['pk'])
initial['data_relativa'] = materia.data_apresentacao
initial['autor'] = []
initial['materia'] = materia
return initial
class UpdateView(LocalBaseMixin, MasterDetailCrud.UpdateView):
@ -1441,6 +1442,7 @@ class AutoriaCrud(MasterDetailCrud):
initial.update({
'data_relativa': self.object.materia.data_apresentacao,
'tipo_autor': self.object.autor.tipo.id,
'materia': self.object.materia
})
return initial
@ -1480,8 +1482,9 @@ class AutoriaMultiCreateView(PermissionRequiredForAppCrudMixin, FormView):
def form_valid(self, form):
autores_selecionados = form.cleaned_data['autor']
primeiro_autor = form.cleaned_data['primeiro_autor']
for autor in autores_selecionados:
Autoria.objects.create(materia=self.materia, autor=autor)
Autoria.objects.create(materia=self.materia, autor=autor, primeiro_autor=primeiro_autor)
return FormView.form_valid(self, form)
@ -1616,14 +1619,13 @@ class MateriaLegislativaCrud(Crud):
form_class = MateriaLegislativaForm
def form_valid(self, form):
self.object = form.instance
def get_initial(self):
initial = super(CreateView, self).get_initial()
self.object.user = self.request.user
self.object.ip = get_client_ip(self.request)
self.object.save()
initial['user'] = self.request.user
initial['ip'] = get_client_ip(self.request)
return super().form_valid(form)
return initial
@property
def cancel_url(self):
@ -1679,7 +1681,7 @@ class MateriaLegislativaCrud(Crud):
class DetailView(Crud.DetailView):
layout_key = 'MateriaLegislativaDetail'
template_name = "materia/materia_detail.html"
template_name = "materia/materialegislativa_detail.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

19
sapl/parlamentares/migrations/0030_auto_20190613_1133.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.21 on 2019-06-13 14:33
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0029_auto_20190517_1531'),
]
operations = [
migrations.AlterModelOptions(
name='partido',
options={'ordering': ['sigla', 'nome'], 'verbose_name': 'Partido', 'verbose_name_plural': 'Partidos'},
),
]

1
sapl/parlamentares/models.py

@ -122,6 +122,7 @@ class Partido(models.Model):
class Meta:
verbose_name = _('Partido')
verbose_name_plural = _('Partidos')
ordering = ['sigla', 'nome']
def __str__(self):
return _('%(sigla)s - %(nome)s') % {

2
sapl/protocoloadm/forms.py

@ -1331,7 +1331,7 @@ def filtra_tramitacao_adm_status(status):
lista = pega_ultima_tramitacao_adm()
return TramitacaoAdministrativo.objects.filter(
id__in=lista,
status=status).distinct().values_list('materia_id', flat=True)
status=status).distinct().values_list('documento_id', flat=True)
def filtra_tramitacao_adm_destino(destino):

4
sapl/protocoloadm/views.py

@ -1160,7 +1160,7 @@ class TramitacaoAdmCrud(MasterDetailCrud):
# não pode ser modificado
if not primeira_tramitacao:
context['form'].fields[
'unidade_tramitacao_local'].widget.attrs['disabled'] = True
'unidade_tramitacao_local'].widget.attrs['readonly'] = True
return context
def form_valid(self, form):
@ -1455,7 +1455,7 @@ class FichaSelecionaAdmView(PermissionRequiredMixin, FormView):
class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView):
filterset_class = PrimeiraTramitacaoEmLoteAdmFilterSet
template_name = 'protocoloadm/em_lote/tramitacaoadm.html'
permission_required = ('materia.add_tramitacao', )
permission_required = ('protocoloadm.add_tramitacaoadministrativo', )
primeira_tramitacao = True

15
sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py

@ -203,13 +203,14 @@ def expedientes(lst_expedientes):
tmp += '\t\t\t<font color="white"> </font>\n'
tmp += '\t\t</para>\n'
for expediente in lst_expedientes:
tmp += '\t\t<para style="P2"><b>' + '<br/> ' + \
expediente['nom_expediente'] + ': </b></para>\n' + \
'<para style="P3">' + \
expediente['txt_expediente'] + '</para>\n'
tmp += '\t\t<para style="P2">\n'
tmp += '\t\t\t<font color="white"> </font>\n'
tmp += '\t\t</para>\n'
if expediente['txt_expediente']:
tmp += '\t\t<para style="P2"><b>' + '<br/> ' + \
expediente['nom_expediente'] + ': </b></para>\n' + \
'<para style="P3">' + \
expediente['txt_expediente'] + '</para>\n'
tmp += '\t\t<para style="P2">\n'
tmp += '\t\t\t<font color="white"> </font>\n'
tmp += '\t\t</para>\n'
return tmp

48
sapl/sessao/forms.py

@ -1,6 +1,5 @@
from datetime import datetime
from sapl.crispy_layout_mixin import SaplFormHelper
from crispy_forms.layout import HTML, Button, Fieldset, Layout
from django import forms
from django.contrib.contenttypes.models import ContentType
@ -13,6 +12,7 @@ from django.utils.translation import ugettext_lazy as _
import django_filters
from sapl.base.models import Autor, TipoAutor
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,
@ -60,21 +60,11 @@ class SessaoPlenariaForm(FileFieldCheckMixin, ModelForm):
"para a Legislatura, Sessão Legislativa e Tipo informados. "
"Favor escolher um número distinto.")
sessoes = SessaoPlenaria.objects.filter(numero=num,
sessao_legislativa=sl,
legislatura=leg,
tipo=tipo,
data_inicio__year=abertura.year).\
values_list('id', flat=True)
qtd_sessoes = len(sessoes)
qs = tipo.queryset_tipo_numeracao(leg, sl, abertura)
qs &= Q(numero=num)
if qtd_sessoes > 0:
if instance.pk: # update
if instance.pk not in sessoes or qtd_sessoes > 1:
raise error
else: # create
raise error
if SessaoPlenaria.objects.filter(qs).exclude(pk=instance.pk).exists():
raise error
# Condições da verificação
abertura_entre_leg = leg.data_inicio <= abertura <= leg.data_fim
@ -474,6 +464,9 @@ class VotacaoForm(forms.Form):
abstencoes = forms.IntegerField(label='Abstenções')
total_presentes = forms.IntegerField(
required=False, widget=forms.HiddenInput())
total_votantes = forms.IntegerField(
required=False, widget=forms.HiddenInput()
)
voto_presidente = forms.IntegerField(
label='A totalização inclui o voto do Presidente?')
total_votos = forms.IntegerField(required=False, label='total')
@ -489,15 +482,16 @@ class VotacaoForm(forms.Form):
votos_nao = cleaned_data['votos_nao']
abstencoes = cleaned_data['abstencoes']
qtde_presentes = cleaned_data['total_presentes']
qtde_votantes = cleaned_data['total_votantes']
qtde_votos = votos_sim + votos_nao + abstencoes
voto_presidente = cleaned_data['voto_presidente']
if qtde_presentes and not voto_presidente:
qtde_presentes -= 1
if qtde_votantes and not voto_presidente:
qtde_votantes -= 1
if qtde_presentes and qtde_votos != qtde_presentes:
if qtde_votantes and qtde_votos != qtde_votantes:
raise ValidationError(
'O total de votos não corresponde com a quantidade de presentes!')
'O total de votos não corresponde com a quantidade de votantes!')
return cleaned_data
@ -640,7 +634,7 @@ class OradorForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['parlamentar'].queryset = \
Parlamentar.objects.filter(ativo=True).order_by('nome_parlamentar')
Parlamentar.objects.filter(ativo=True).order_by('nome_parlamentar')
def clean(self):
super(OradorForm, self).clean()
@ -662,8 +656,8 @@ class OradorForm(ModelForm):
"Já existe orador nesta posição de ordem de pronunciamento"
))
return self.cleaned_data
class Meta:
model = Orador
exclude = ['sessao_plenaria']
@ -672,8 +666,12 @@ class OradorForm(ModelForm):
class OradorExpedienteForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
id_sessao = int(self.initial['id_sessao'])
sessao = SessaoPlenaria.objects.get(id=id_sessao)
legislatura_vigente = sessao.legislatura
self.fields['parlamentar'].queryset = \
Parlamentar.objects.filter(ativo=True).order_by('nome_parlamentar')
Parlamentar.objects.filter(mandato__legislatura=legislatura_vigente,
ativo=True).order_by('nome_parlamentar')
def clean(self):
super(OradorExpedienteForm, self).clean()
@ -703,8 +701,12 @@ class OradorExpedienteForm(ModelForm):
class OradorOrdemDiaForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
id_sessao = int(self.initial['id_sessao'])
sessao = SessaoPlenaria.objects.get(id=id_sessao)
legislatura_vigente = sessao.legislatura
self.fields['parlamentar'].queryset = \
Parlamentar.objects.filter(ativo=True).order_by('nome_parlamentar')
Parlamentar.objects.filter(mandato__legislatura=legislatura_vigente,
ativo=True).order_by('nome_parlamentar')
def clean(self):
super(OradorOrdemDiaForm, self).clean()

27
sapl/sessao/migrations/0041_auto_20190610_1300.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-10 16:00
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sessao', '0040_auto_20190523_1130'),
]
operations = [
migrations.AddField(
model_name='tiposessaoplenaria',
name='tipo_numeracao',
field=models.PositiveIntegerField(choices=[(1, 'Quinzenal'), (2, 'Mensal'), (10, 'Anual'), (11, 'Sessão Legislativa'), (
12, 'Legislatura'), (99, 'Numeração Única')], default=11, verbose_name='Tipo de Numeração'),
),
migrations.AlterField(
model_name='tiposessaoplenaria',
name='nome',
field=models.CharField(
max_length=30, verbose_name='Descrição do Tipo'),
),
]

72
sapl/sessao/models.py

@ -2,7 +2,8 @@ from operator import xor
from django.core.exceptions import ValidationError
from django.db import models
from django.utils import timezone
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
@ -73,10 +74,24 @@ class Bancada(models.Model):
@reversion.register()
class TipoSessaoPlenaria(models.Model):
nome = models.CharField(max_length=30, verbose_name=_('Tipo'))
TIPO_NUMERACAO_CHOICES = Choices(
(1, 'quizenal', 'Quinzenal'),
(2, 'mensal', 'Mensal'),
(10, 'anual', 'Anual'),
(11, 'sessao_legislativa', 'Sessão Legislativa'),
(12, 'legislatura', 'Legislatura'),
(99, 'unica', 'Numeração Única'),
)
nome = models.CharField(max_length=30, verbose_name=_('Descrição do Tipo'))
quorum_minimo = models.PositiveIntegerField(
verbose_name=_('Quórum mínimo'))
tipo_numeracao = models.PositiveIntegerField(
verbose_name=_('Tipo de Numeração'),
choices=TIPO_NUMERACAO_CHOICES, default=11)
class Meta:
verbose_name = _('Tipo de Sessão Plenária')
verbose_name_plural = _('Tipos de Sessão Plenária')
@ -85,6 +100,29 @@ class TipoSessaoPlenaria(models.Model):
def __str__(self):
return self.nome
def queryset_tipo_numeracao(self, legislatura, sessao_legislativa, data):
qs = Q(tipo=self)
tnc = self.TIPO_NUMERACAO_CHOICES
if self.tipo_numeracao == tnc.unica:
pass
elif self.tipo_numeracao == tnc.legislatura:
qs &= Q(legislatura=legislatura)
elif self.tipo_numeracao == tnc.sessao_legislativa:
qs &= Q(sessao_legislativa=sessao_legislativa)
elif self.tipo_numeracao == tnc.anual:
qs &= Q(data_inicio__year=data.year)
elif self.tipo_numeracao in (tnc.mensal, tnc.quizenal):
qs &= Q(data_inicio__year=data.year, data_inicio__month=data.month)
if self.tipo_numeracao == tnc.quizenal:
if data.day <= 15:
qs &= Q(data_inicio__day__lte=15)
else:
qs &= Q(data_inicio__day__gt=15)
return qs
def get_sessao_media_path(instance, subpath, filename):
return './sapl/sessao/%s/%s/%s' % (instance.numero, subpath, filename)
@ -176,7 +214,34 @@ class SessaoPlenaria(models.Model):
verbose_name_plural = _('Sessões Plenárias')
def __str__(self):
return _('%(numero)sª Sessão %(tipo_nome)s'
tnc = self.tipo.TIPO_NUMERACAO_CHOICES
base = '{}ª {}'.format(self.numero, self.tipo.nome)
if self.tipo.tipo_numeracao == tnc.quizenal:
base += ' da {}ª Quinzena'.format(
1 if self.data_inicio.day > 15 else 2)
if self.tipo.tipo_numeracao <= tnc.mensal:
base += ' do mês de {}'.format(
formats.date_format(self.data_inicio, 'F')
)
if self.tipo.tipo_numeracao <= tnc.anual:
base += ' de {}'.format(self.data_inicio.year)
if self.tipo.tipo_numeracao <= tnc.sessao_legislativa:
base += ' da {}ª Sessão Legislativa'.format(
self.sessao_legislativa.numero)
if self.tipo.tipo_numeracao <= tnc.legislatura:
base += ' da {}ª Legislatura'.format(
self.legislatura.numero)
return base
"""return _('%(numero)sª Sessão %(tipo_nome)s'
' da %(sessao_legislativa_numero)sª Sessão Legislativa'
' da %(legislatura_id)sª Legislatura') % {
@ -185,6 +250,7 @@ class SessaoPlenaria(models.Model):
'sessao_legislativa_numero': self.sessao_legislativa.numero,
# XXX check if it shouldn't be legislatura.numero
'legislatura_id': self.legislatura.numero}
"""
def delete(self, using=None, keep_parents=False):
if self.upload_pauta:

6
sapl/sessao/urls.py

@ -2,7 +2,7 @@ from django.conf.urls import include, url
from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
AdicionarVariasMateriasOrdemDia, BancadaCrud,
CargoBancadaCrud, ExpedienteMateriaCrud,
CargoBancadaCrud, ExpedienteMateriaCrud,
ExpedienteView, JustificativaAusenciaCrud,
OcorrenciaSessaoView, MateriaOrdemDiaCrud, OradorOrdemDiaCrud,
MesaView, OradorCrud,
@ -25,7 +25,7 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
VotacaoNominalView, VotacaoView, abrir_votacao,
atualizar_mesa, insere_parlamentar_composicao,
mudar_ordem_materia_sessao, recuperar_materia,
recuperar_numero_sessao,
recuperar_numero_sessao_view,
remove_parlamentar_composicao,
reordernar_materias_expediente,
reordernar_materias_ordem,
@ -65,7 +65,7 @@ urlpatterns = [
url(r'^sessao/recuperar-materia/', recuperar_materia),
url(r'^sessao/recuperar-numero-sessao/',
recuperar_numero_sessao,
recuperar_numero_sessao_view,
name='recuperar_numero_sessao_view'
),
url(r'^sessao/sessao-legislativa-legislatura-ajax/',

239
sapl/sessao/views.py

@ -53,7 +53,6 @@ from .models import (Bancada, CargoBancada, CargoMesa,
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
TipoExpedienteCrud = CrudAux.build(TipoExpediente, 'tipo_expediente')
TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa')
CargoBancadaCrud = CrudAux.build(CargoBancada, '')
TipoResultadoVotacaoCrud = CrudAux.build(
@ -93,6 +92,7 @@ def reordernar_materias_ordem(request, pk):
return HttpResponseRedirect(
reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk}))
def renumerar_materias_ordem(request, pk):
ordens = OrdemDia.objects.filter(sessao_plenaria_id=pk)
@ -103,6 +103,7 @@ def renumerar_materias_ordem(request, pk):
return HttpResponseRedirect(
reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk}))
def renumerar_materias_expediente(request, pk):
expedientes = ExpedienteMateria.objects.filter(sessao_plenaria_id=pk)
@ -113,6 +114,7 @@ def renumerar_materias_expediente(request, pk):
return HttpResponseRedirect(
reverse('sapl.sessao:expedientemateria_list', kwargs={'pk': pk}))
def verifica_presenca(request, model, spk):
logger = logging.getLogger(__name__)
if not model.objects.filter(sessao_plenaria_id=spk).exists():
@ -464,6 +466,23 @@ def get_presencas_generic(model, sessao, legislatura):
yield (m.parlamentar, False)
class TipoExpedienteCrud(CrudAux):
model = TipoExpediente
class DeleteView(CrudAux.DeleteView):
def delete(self, *args, **kwargs):
self.object = self.get_object()
# Se todas as referências a este tipo forem de conteúdo vazio,
# significa que pode ser apagado
if self.object.expedientesessao_set.filter(conteudo='').count() == \
self.object.expedientesessao_set.all().count():
self.object.expedientesessao_set.all().delete()
return CrudAux.DeleteView.delete(self, *args, **kwargs)
class MateriaOrdemDiaCrud(MasterDetailCrud):
model = OrdemDia
parent_field = 'sessao_plenaria'
@ -595,7 +614,6 @@ class OradorCrud(MasterDetailCrud):
class ListView(MasterDetailCrud.ListView):
ordering = ['numero_ordem', 'parlamentar']
class CreateView(MasterDetailCrud.CreateView):
form_class = OradorForm
@ -607,7 +625,6 @@ class OradorCrud(MasterDetailCrud):
return reverse('sapl.sessao:orador_list',
kwargs={'pk': self.kwargs['pk']})
class UpdateView(MasterDetailCrud.UpdateView):
form_class = OradorForm
@ -615,7 +632,7 @@ class OradorCrud(MasterDetailCrud):
def get_initial(self):
initial = super(UpdateView, self).get_initial()
initial.update({'id_sessao': self.object.sessao_plenaria.id})
initial.update({'numero':self.object.numero_ordem})
initial.update({'numero': self.object.numero_ordem})
return initial
@ -677,11 +694,24 @@ class BancadaCrud(CrudAux):
return reverse('sapl.sessao:bancada_list')
def recuperar_numero_sessao(request):
def recuperar_numero_sessao_view(request):
try:
tipo = TipoSessaoPlenaria.objects.get(pk=request.GET.get('tipo', '0'))
sl = request.GET.get('sessao_legislativa', '0')
l = request.GET.get('legislatura', '0')
data = request.GET.get('data_inicio', timezone.now())
if isinstance(data, str):
if data:
data = timezone.datetime.strptime(data, '%d/%m/%Y').date()
else:
data = timezone.now().date()
sessao = SessaoPlenaria.objects.filter(
tipo__pk=request.GET['tipo'],
sessao_legislativa=request.GET['sessao_legislativa']).last()
tipo.queryset_tipo_numeracao(
l, sl, data
)).last()
except ObjectDoesNotExist:
numero = 1
else:
@ -1066,7 +1096,6 @@ class ListMateriaOrdemDiaView(FormMixin, DetailView):
return self.get(self, request, args, kwargs)
class MesaView(FormMixin, DetailView):
template_name = 'sessao/mesa.html'
form_class = MesaForm
@ -1341,7 +1370,7 @@ def get_identificação_basica(sessao_plenaria):
_('Encerramento: %(encerramento)s %(hora_fim)s') % {
'encerramento': encerramento, 'hora_fim': sessao_plenaria.hora_fim}
],
'sessaoplenaria': sessao_plenaria})
'sessaoplenaria': sessao_plenaria})
def get_conteudo_multimidia(sessao_plenaria):
@ -1360,7 +1389,8 @@ def get_conteudo_multimidia(sessao_plenaria):
def get_mesa_diretora(sessao_plenaria):
mesa = IntegranteMesa.objects.filter(sessao_plenaria=sessao_plenaria).order_by('cargo_id')
mesa = IntegranteMesa.objects.filter(
sessao_plenaria=sessao_plenaria).order_by('cargo_id')
integrantes = [{'parlamentar': m.parlamentar,
'cargo': m.cargo} for m in mesa]
return {'mesa': integrantes}
@ -1369,8 +1399,8 @@ def get_mesa_diretora(sessao_plenaria):
def get_presenca_sessao(sessao_plenaria):
parlamentares_sessao = [p.parlamentar for p in SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')]
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')]
ausentes_sessao = JustificativaAusencia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
@ -1404,7 +1434,8 @@ def get_materias_expediente(sessao_plenaria):
numero = m.numero_ordem
tramitacao = ''
tramitacoes = Tramitacao.objects.filter(materia=m.materia).order_by('-pk')
tramitacoes = Tramitacao.objects.filter(
materia=m.materia).order_by('-pk')
for aux_tramitacao in tramitacoes:
if aux_tramitacao.turno:
tramitacao = aux_tramitacao
@ -1466,8 +1497,8 @@ def get_oradores_expediente(sessao_plenaria):
def get_presenca_ordem_do_dia(sessao_plenaria):
parlamentares_ordem = [p.parlamentar for p in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')]
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')]
return {'presenca_ordem': parlamentares_ordem}
@ -1480,13 +1511,14 @@ def get_assinaturas(sessao_plenaria):
'')]
parlamentares_ordem = [p.parlamentar for p in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')]
sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')]
parlamentares_mesa = [m['parlamentar'] for m in mesa_dia]
# filtra parlamentares retirando os que sao da mesa
parlamentares_ordem = [p for p in parlamentares_ordem if p not in parlamentares_mesa]
parlamentares_ordem = [
p for p in parlamentares_ordem if p not in parlamentares_mesa]
context = {}
config_assinatura_ata = AppsAppConfig.attr('assinatura_ata')
@ -1517,7 +1549,8 @@ def get_materias_ordem_do_dia(sessao_plenaria):
numero = o.numero_ordem
tramitacao = ''
tramitacoes = Tramitacao.objects.filter(materia=o.materia).order_by('-pk')
tramitacoes = Tramitacao.objects.filter(
materia=o.materia).order_by('-pk')
for aux_tramitacao in tramitacoes:
if aux_tramitacao.turno:
tramitacao = aux_tramitacao
@ -1600,7 +1633,7 @@ def get_oradores_ordemdia(sessao_plenaria):
observacao = orador.observacao
parlamentar = Parlamentar.objects.get(
id=orador.parlamentar_id
)
)
o = {
'numero_ordem': numero_ordem,
'url_discurso': url_discurso,
@ -1610,9 +1643,9 @@ def get_oradores_ordemdia(sessao_plenaria):
oradores.append(o)
context = {'oradores_ordemdia': oradores}
return context
return context
def get_oradores_explicações_pessoais(sessao_plenaria):
oradores_explicacoes = []
for orador in Orador.objects.filter(
@ -1729,7 +1762,7 @@ class ResumoView(DetailView):
# =====================================================================
# Oradores Ordem do Dia
context.update(get_oradores_ordemdia(self.object))
# =====================================================================
# =====================================================================
# Oradores nas Explicações Pessoais
context.update(get_oradores_explicações_pessoais(self.object))
# =====================================================================
@ -2051,13 +2084,24 @@ class VotacaoView(SessaoPermissionMixin):
ordem_id = kwargs['oid']
ordem = OrdemDia.objects.get(id=ordem_id)
qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.object.id).count()
presentes_id = [
presente.parlamentar.id for presente in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.kwargs['pk']
)
]
qtde_presentes = len(presentes_id)
presenca_ativos = Parlamentar.objects.filter(
id__in=presentes_id, ativo=True
)
qtde_ativos = len(presenca_ativos)
materia = {'materia': ordem.materia, 'ementa': ordem.materia.ementa}
context.update({'votacao_titulo': titulo,
'materia': materia,
'total_presentes': qtde_presentes})
'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
return self.render_to_response(context)
@ -2077,13 +2121,24 @@ class VotacaoView(SessaoPermissionMixin):
ordem_id = kwargs['oid']
ordem = OrdemDia.objects.get(id=ordem_id)
qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.object.id).count()
presentes_id = [
presente.parlamentar.id for presente in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.kwargs['pk']
)
]
qtde_presentes = len(presentes_id)
presenca_ativos = Parlamentar.objects.filter(
id__in=presentes_id, ativo=True
)
qtde_ativos = len(presenca_ativos)
materia = {'materia': ordem.materia, 'ementa': ordem.materia.ementa}
context.update({'votacao_titulo': titulo,
'materia': materia,
'total_presentes': qtde_presentes})
'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
context.update({'form': form})
# ====================================================
@ -2096,21 +2151,19 @@ class VotacaoView(SessaoPermissionMixin):
materia_id = kwargs['mid']
ordem_id = kwargs['oid']
qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.object.id).count()
qtde_votos = (int(request.POST['votos_sim']) +
int(request.POST['votos_nao']) +
int(request.POST['abstencoes']))
if (int(request.POST['voto_presidente']) == 0):
qtde_presentes -= 1
qtde_ativos -= 1
if (qtde_votos > qtde_presentes or qtde_votos < qtde_presentes):
if qtde_votos != qtde_ativos:
msg = _(
'O total de votos não corresponde com a quantidade de presentes!')
'O total de votos não corresponde com a quantidade de votantes!')
messages.add_message(request, messages.ERROR, msg)
return self.render_to_response(context)
elif (qtde_presentes == qtde_votos):
else:
try:
votacao = RegistroVotacao()
votacao.numero_votos_sim = int(request.POST['votos_sim'])
@ -2755,14 +2808,25 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
expediente_id = kwargs['oid']
expediente = ExpedienteMateria.objects.get(id=expediente_id)
qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id).count()
presentes_id = [
presente.parlamentar.id for presente in SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.kwargs['pk']
)
]
qtde_presentes = len(presentes_id)
presentes_ativos = Parlamentar.objects.filter(
id__in=presentes_id, ativo=True
)
qtde_ativos = len(presentes_ativos)
materia = {'materia': expediente.materia,
'ementa': expediente.materia.ementa}
context.update({'votacao_titulo': titulo,
'materia': materia,
'total_presentes': qtde_presentes})
'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
return self.render_to_response(context)
@ -2782,14 +2846,25 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
expediente_id = kwargs['oid']
expediente = ExpedienteMateria.objects.get(id=expediente_id)
qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id).count()
presentes_id = [
presente.parlamentar.id for presente in SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.kwargs['pk']
)
]
qtde_presentes = len(presentes_id)
presentes_ativos = Parlamentar.objects.filter(
id__in=presentes_id, ativo=True
)
qtde_ativos = len(presentes_ativos)
materia = {'materia': expediente.materia,
'ementa': expediente.materia.ementa}
context.update({'votacao_titulo': titulo,
'materia': materia,
'total_presentes': qtde_presentes})
'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
context.update({'form': form})
# ====================================================
@ -2802,17 +2877,17 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
materia_id = kwargs['mid']
expediente_id = kwargs['oid']
qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id).count()
qtde_votos = (int(request.POST['votos_sim']) +
int(request.POST['votos_nao']) +
int(request.POST['abstencoes']))
if (int(request.POST['voto_presidente']) == 0):
qtde_presentes -= 1
qtde_ativos -= 1
if qtde_votos != qtde_presentes:
form._errors["total_votos"] = ErrorList([u""])
if qtde_votos != qtde_ativos:
msg = _(
'O total de votos não corresponde com a quantidade de votantes!')
messages.add_message(request, messages.ERROR, msg)
return self.render_to_response(context)
else:
try:
@ -3561,17 +3636,41 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie
if request.POST['origem'] == 'ordem':
ordens = OrdemDia.objects.filter(
id__in=request.POST.getlist('marcadas_1'))
qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.kwargs['pk']).count()
presentes_id = [
presente.parlamentar.id for presente in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.kwargs['pk']
)
]
qtde_presentes = len(presentes_id)
presenca_ativos = Parlamentar.objects.filter(
id__in=presentes_id, ativo=True
)
qtde_ativos = len(presenca_ativos)
context.update({'ordens': ordens,
'total_presentes': qtde_presentes})
'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
else:
expedientes = ExpedienteMateria.objects.filter(
id__in=request.POST.getlist('marcadas_1'))
qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.kwargs['pk']).count()
presentes_id = [
presente.parlamentar.id for presente in SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.kwargs['pk']
)
]
qtde_presentes = len(presentes_id)
presenca_ativos = Parlamentar.objects.filter(
id__in=presentes_id, ativo=True
)
qtde_ativos = len(presenca_ativos)
context.update({'expedientes': expedientes,
'total_presentes': qtde_presentes})
'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
if 'salvar-votacao' in request.POST:
form = VotacaoForm(request.POST)
@ -3696,17 +3795,41 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie
if self.request.POST['origem'] == 'ordem':
ordens = OrdemDia.objects.filter(
id__in=self.request.POST.getlist('ordens'))
qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.kwargs['pk']).count()
presentes_id = [
presente.parlamentar.id for presente in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.kwargs['pk']
)
]
qtde_presentes = len(presentes_id)
presenca_ativos = Parlamentar.objects.filter(
id__in=presentes_id, ativo=True
)
qtde_ativos = len(presenca_ativos)
context.update({'ordens': ordens,
'total_presentes': qtde_presentes})
'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
elif self.request.POST['origem'] == 'expediente':
expedientes = ExpedienteMateria.objects.filter(
id__in=self.request.POST.getlist('expedientes'))
qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.kwargs['pk']).count()
presentes_id = [
presente.parlamentar.id for presente in SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.kwargs['pk']
)
]
qtde_presentes = len(presentes_id)
presenca_ativos = Parlamentar.objects.filter(
id__in=presentes_id, ativo=True
)
qtde_ativos = len(presenca_ativos)
context.update({'expedientes': expedientes,
'total_presentes': qtde_presentes})
'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
context.update({'resultado_votacao': TipoResultadoVotacao.objects.all(),
'form': form,

2
sapl/settings.py

@ -41,7 +41,7 @@ ALLOWED_HOSTS = ['*']
LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/login/?next='
SAPL_VERSION = '3.1.157-RC5'
SAPL_VERSION = '3.1.158'
if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

26
sapl/templates/base.html

@ -179,7 +179,7 @@
<small>
Desenvolvido pelo <a href="http://www.interlegis.leg.br/">Interlegis</a> em software livre e aberto.
</small>
<span>Release: 3.1.157-RC5</span>
<span>Release: 3.1.158</span>
</p>
</div>
<div class="col-md-4">
@ -232,11 +232,9 @@
{% block webpack_loader_chunks_js %}
{% endblock webpack_loader_chunks_js %}
{% block extra_js %}{% endblock %}
{% block extra_js %}{% endblock extra_js %}
<script type="text/javascript" >
function inIframe () {
try {
return window.self !== window.top;
@ -249,21 +247,19 @@
if (iframe_set_backend && !inIframe() ) {
location.href = location.origin + '?iframe=0'
}
var form = document.getElementById("formulario-lexml");
$("#input-lexml").change(function(){
let value = $("#input-lexml").val();
let url = "{% url 'sapl.lexml:lexml_search' 'xxx'%}"
url = url.replace('xxx', value)
form.action = url;
});
});
</script>
{% endblock foot_js %}
<script>
$(document).ready(function(){
var form = document.getElementById("formulario-lexml");
$("#input-lexml").change(function(){
let value = $("#input-lexml").val();
let url = "{% url 'sapl.lexml:lexml_search' 'xxx'%}"
url = url.replace('xxx', value)
form.action = url;
});
});
</script>
</body>
</html>

14
sapl/templates/materia/em_lote/tramitacao.html

@ -134,19 +134,5 @@
checkboxes[i].checked = elem.checked;
}
}
$(document).ready(function(){
var primeira_tramitacao = {{primeira_tramitacao|yesno:"true,false"}}
if (primeira_tramitacao == false){
$('#id_unidade_tramitacao_local').prop('disabled', true);
}
// Reabilita o campo, no momento do Submit, para que seu dado seja enviado
$('input[type=submit]').click(function() {
$('#id_unidade_tramitacao_local').attr('disabled', false);
$('#id_unidade_tramitacao_local').parents('form').submit();
});
});
</script>
{% endblock %}

36
sapl/templates/materia/materia_detail.html

@ -1,36 +0,0 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% block detail_content %}
{{ block.super }}
{% if user.is_superuser %}
<div class="row">
{% if materia.user %}
<div class="col-sm-6">
<div id="div_id_user" class="form-group">
<p class="control-label">Usuário</p>
<div class="controls">
<div class="form-control-static">
<div class="dont-break-out">
<a href="{% url 'sapl.base:user_edit' materia.user.pk %}">{{materia.user}}</a>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% if materia.ip %}
<div class="col-sm-6">
<div id="div_ip_user" class="form-group">
<p class="control-label">IP</p>
<div class="controls">
<div class="form-control-static">
<div class="dont-break-out">{{materia.ip}}</div>
</div>
</div>
</div>
</div>
{% endif %}
</div>
{% endif %}
{% endblock detail_content %}

30
sapl/templates/materia/materialegislativa_detail.html

@ -43,4 +43,34 @@
{% endfor %}
</div>
{% endif %}
{% if user.is_superuser %}
<div class="row">
{% if materia.user %}
<div class="col-sm-6">
<div id="div_id_user" class="form-group">
<p class="control-label">Usuário</p>
<div class="controls">
<div class="form-control-static">
<div class="dont-break-out">
<a href="{% url 'sapl.base:user_edit' materia.user.pk %}">{{materia.user}}</a>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% if materia.ip %}
<div class="col-sm-6">
<div id="div_ip_user" class="form-group">
<p class="control-label">IP</p>
<div class="controls">
<div class="form-control-static">
<div class="dont-break-out">{{materia.ip}}</div>
</div>
</div>
</div>
</div>
{% endif %}
</div>
{% endif %}
{% endblock detail_content %}

19
sapl/templates/materia/tramitacao_form.html

@ -1,19 +0,0 @@
{% extends "crud/form.html" %}
{% load i18n %}
{% block extra_js %}
<script type="text/javascript">
// Caso o campo esteja desabilitado (quando não é a primeira tramitação),
// habilita ele no momento do submit para que o valor de unidade local
// não seja enviado como vazio
$(document).ready(function(){
$('input[type=submit]').click(function() {
$('#id_unidade_tramitacao_local').attr('disabled', false);
$('#id_unidade_tramitacao_local').parents('form').submit();
});
});
</script>
{% endblock %}

2
sapl/templates/navbar.yaml

@ -35,7 +35,7 @@
url: sapl.protocoloadm:pesq_doc_adm
- title: {% trans 'Tramitação em Lote' %}
url: sapl.protocoloadm:primeira_tramitacao_em_lote_docadm
check_permission: sapl.documento:add_tramitacao
check_permission: sapl.protocoloadm:add_tramitacaoadministrativo
- title: {% trans 'Atividade Legislativa' %}
children:

52
sapl/templates/painel/index.html

@ -149,7 +149,16 @@
countdown: true,
startAt: {{ 'discurso'|cronometro_to_seconds }} * 1000,
stopAt: 0,
milliseconds: false
milliseconds: false,
format: function(value) {
let h = Math.floor((value/1000) / 3600);
h = checkTime(h);
let m = Math.floor((value/1000) % 3600 / 60);
m = checkTime(m);
let s = Math.floor((value/1000) % 3600 % 60);
s = checkTime(s);
return h.toString() + ":" + m.toString() + ":" + s.toString();
}
}).on('runnerFinish', function(eventObject, info){
audioAlertFinish.play();
});
@ -159,7 +168,16 @@
countdown: true,
startAt: {{ 'aparte'|cronometro_to_seconds }} * 1000,
stopAt: 0,
milliseconds: false
milliseconds: false,
format: function(value) {
let h = Math.floor((value/1000) / 3600);
h = checkTime(h);
let m = Math.floor((value/1000) % 3600 / 60);
m = checkTime(m);
let s = Math.floor((value/1000) % 3600 % 60);
s = checkTime(s);
return h.toString() + ":" + m.toString() + ":" + s.toString();
}
}).on('runnerFinish', function(eventObject, info){
audioAlertFinish.play();
});
@ -169,7 +187,16 @@
countdown: true,
startAt: {{ 'ordem'|cronometro_to_seconds }} * 1000,
stopAt: 0,
milliseconds: false
milliseconds: false,
format: function(value) {
let h = Math.floor((value/1000) / 3600);
h = checkTime(h);
let m = Math.floor((value/1000) % 3600 / 60);
m = checkTime(m);
let s = Math.floor((value/1000) % 3600 % 60);
s = checkTime(s);
return h.toString() + ":" + m.toString() + ":" + s.toString();
}
}).on('runnerFinish', function(eventObject, info){
audioAlertFinish.play();
});
@ -179,7 +206,16 @@
countdown: true,
startAt: {{ 'consideracoes'|cronometro_to_seconds }} * 1000,
stopAt: 0,
milliseconds: false
milliseconds: false,
format: function(value) {
let h = Math.floor((value/1000) / 3600);
h = checkTime(h);
let m = Math.floor((value/1000) % 3600 / 60);
m = checkTime(m);
let s = Math.floor((value/1000) % 3600 % 60);
s = checkTime(s);
return h.toString() + ":" + m.toString() + ":" + s.toString();
}
}).on('runnerFinish', function(eventObject, info){
audioAlertFinish.play();
});
@ -329,19 +365,19 @@
consideracoes_previous = consideracoes_current;
}
if($('#cronometro_discurso').runner('info').formattedTime == 30) {
if($('#cronometro_discurso').runner('info').formattedTime == "00:00:30") {
audioAlertFinish.play();
}
if($('#cronometro_aparte').runner('info').formattedTime == 30) {
if($('#cronometro_aparte').runner('info').formattedTime == "00:00:30") {
audioAlertFinish.play();
}
if($('#cronometro_ordem').runner('info').formattedTime == 30) {
if($('#cronometro_ordem').runner('info').formattedTime == "00:00:30") {
audioAlertFinish.play();
}
if($('#cronometro_consideracoes').runner('info').formattedTime == 30) {
if($('#cronometro_consideracoes').runner('info').formattedTime == "00:00:30") {
audioAlertFinish.play();
}

16
sapl/templates/protocoloadm/em_lote/tramitacaoadm.html

@ -21,26 +21,12 @@
{% block extra_js %}
<script language="JavaScript">
function checkAll(elem) {
function checkAll(elem) {
let checkboxes = document.getElementsByName('documentos');
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].type == 'checkbox')
checkboxes[i].checked = elem.checked;
}
}
$(document).ready(function(){
var primeira_tramitacao = {{primeira_tramitacao|yesno:"true,false"}}
if (primeira_tramitacao == false){
$('#id_unidade_tramitacao_local').prop('disabled', true);
}
// Reabilita o campo, no momento do Submit, para que seu dado seja enviado
$('input[type=submit]').click(function() {
$('#id_unidade_tramitacao_local').attr('disabled', false);
$('#id_unidade_tramitacao_local').parents('form').submit();
});
});
</script>
{% endblock %}

15
sapl/templates/protocoloadm/tramitacaoadministrativo_form.html

@ -1,15 +0,0 @@
{% extends "crud/form.html" %}
{% load i18n %}
{% block extra_js %}
<script language="Javascript">
// Caso o campo esteja desabilitado (quando não é a primeira tramitação),
// habilita ele no momento do submit para que o valor de unidade local
// não seja enviado como vazio
$(document).ready(function(){
$('input[type=submit]').click(function() {
$('#id_unidade_tramitacao_local').attr('disabled', false);
$('#id_unidade_tramitacao_local').parents('form').submit();
});
});
</script>
{% endblock extra_js %}

10
sapl/templates/sessao/blocos_ata/expedientes.html

@ -3,12 +3,10 @@
{% if expedientes %}
<strong>Expedientes: </strong>
{% for e in expedientes %}
<b>{{e.tipo}}</b>:
{% if e.conteudo %}
{{e.conteudo|striptags|safe}}
{% else %}
Sem registro
{% endif %}
{% if e.conteudo %}
<b>{{e.tipo}}</b>:
{{e.conteudo|striptags|safe}}
{% endif %}
{% endfor %}
{% endif %}
</p>

18
sapl/templates/sessao/blocos_resumo/expedientes.html

@ -4,14 +4,16 @@
<table class="table">
<thead class="thead-default">
{% for e in expedientes %}
<tr>
<td>
<b>{{e.tipo}}: </b> <br /><br />
<div style="border:0.5px solid #BAB4B1; border-radius: 10px; background-color: rgba(225, 225, 225, .8);">
<p>{{e.conteudo|safe}}</p>
</div>
</td>
</tr>
{% if e.conteudo %}
<tr>
<td>
<b>{{e.tipo}}: </b> <br /><br />
<div style="border:0.5px solid #BAB4B1; border-radius: 10px; background-color: rgba(225, 225, 225, .8);">
<p>{{e.conteudo|safe}}</p>
</div>
</td>
</tr>
{% endif %}
{% endfor %}
</thead>
</table>

4
sapl/templates/sessao/layouts.yaml

@ -1,11 +1,11 @@
{% load i18n %}
TipoSessaoPlenaria:
{% trans 'Tipo de Sessão Plenária' %}:
- nome quorum_minimo
- nome quorum_minimo tipo_numeracao
SessaoPlenaria:
{% trans 'Dados Básicos' %}:
- legislatura sessao_legislativa tipo:3 numero:1
- legislatura sessao_legislativa tipo numero:2
- data_inicio:5 hora_inicio:5 iniciada
- data_fim:5 hora_fim:5 finalizada
- upload_pauta upload_ata upload_anexo

44
sapl/templates/sessao/painel.html

@ -127,7 +127,16 @@ $(function() {
countdown: true,
startAt: {{cronometro_discurso}} * 1000,
stopAt: 0,
milliseconds: false
milliseconds: false,
format: function(value) {
let h = Math.floor((value/1000) / 3600);
h = checkTime(h);
let m = Math.floor((value/1000) % 3600 / 60);
m = checkTime(m);
let s = Math.floor((value/1000) % 3600 % 60);
s = checkTime(s);
return h.toString() + ":" + m.toString() + ":" + s.toString();
}
}).on('runnerFinish', function(eventObject, info){
$.get('/painel/cronometro', { tipo: 'discurso', action: 'stop' } );
audioAlertFinish.play();
@ -170,7 +179,16 @@ $(function() {
countdown: true,
startAt: {{cronometro_aparte}} * 1000,
stopAt: 0,
milliseconds: false
milliseconds: false,
format: function(value) {
let h = Math.floor((value/1000) / 3600);
h = checkTime(h);
let m = Math.floor((value/1000) % 3600 / 60);
m = checkTime(m);
let s = Math.floor((value/1000) % 3600 % 60);
s = checkTime(s);
return h.toString() + ":" + m.toString() + ":" + s.toString();
}
}).on('runnerFinish', function(eventObject, info){
$.get('/painel/cronometro', { tipo: 'aparte', action: 'stop' } );
audioAlertFinish.play();
@ -213,7 +231,16 @@ $(function() {
countdown: true,
startAt: {{cronometro_ordem}} * 1000,
stopAt: 0,
milliseconds: false
milliseconds: false,
format: function(value) {
let h = Math.floor((value/1000) / 3600);
h = checkTime(h);
let m = Math.floor((value/1000) % 3600 / 60);
m = checkTime(m);
let s = Math.floor((value/1000) % 3600 % 60);
s = checkTime(s);
return h.toString() + ":" + m.toString() + ":" + s.toString();
}
}).on('runnerFinish', function(eventObject, info){
$.get('/painel/cronometro', { tipo: 'ordem', action: 'stop' } );
audioAlertFinish.play();
@ -257,7 +284,16 @@ $(function() {
countdown: true,
startAt: {{cronometro_consideracoes}} * 1000,
stopAt: 0,
milliseconds: false
milliseconds: false,
format: function(value) {
let h = Math.floor((value/1000) / 3600);
h = checkTime(h);
let m = Math.floor((value/1000) % 3600 / 60);
m = checkTime(m);
let s = Math.floor((value/1000) % 3600 % 60);
s = checkTime(s);
return h.toString() + ":" + m.toString() + ":" + s.toString();
}
}).on('runnerFinish', function(eventObject, info){
$.get('/painel/cronometro', { tipo: 'consideracoes', action: 'stop' } );
audioAlertFinish.play();

4
sapl/templates/sessao/pauta_sessao_detail.html

@ -34,7 +34,7 @@
<br />
<b>Autor{{ m.autor|length|pluralize:"es" }}</b>: {{ m.autor|join:', ' }}
</td>
<td style="width:70%;">{{m.ementa|safe}}<br>{{m.observacao|safe}}</td>
<td style="width:70%;">{{m.ementa|safe}}<br>{{m.observacao|linebreaksbr|safe}}</td>
<td style="width:10%;">{{m.situacao}}</td>
</tr>
{% endfor %}
@ -62,7 +62,7 @@
<br />
<b>Autor{{ m.autor|length|pluralize:"es" }}</b>: {{ m.autor|join:', ' }}
</td>
<td style="width:70%;">{{m.ementa|safe}}<br>{{m.observacao|safe}}</td>
<td style="width:70%;">{{m.ementa|safe}}<br>{{m.observacao|linebreaksbr|safe}}</td>
<td style="width:10%;">{{m.situacao}}</td>
</tr>
{% endfor %}

45
sapl/templates/sessao/sessaoplenaria_form.html

@ -7,24 +7,35 @@
<script language="Javascript">
// Seleciona o numero de acordo com o tipo
function recuperar_numero_sessao() {
var tipo = $("#id_tipo").val()
var sessao = $("#id_sessao_legislativa").val()
if (tipo) {
$.get("{% url 'sapl.sessao:recuperar_numero_sessao_view' %}",{tipo: tipo, sessao_legislativa:sessao},
function(data, status) {
$("#id_numero").val(data.numero);
// console.log(data)
});
}
else{
$("#id_numero").val('');
{% if not object %}
// faz recuperação do próximo número apenas em caso de inclusão de sessão plenária
// Seleciona o numero de acordo com o tipo
function recuperar_numero_sessao() {
var tipo = $("#id_tipo").val()
var sessao = $("#id_sessao_legislativa").val()
var legislatura = $("#id_legislatura").val()
var data_ini = $("#id_data_inicio").val()
if (tipo) {
$.get("{% url 'sapl.sessao:recuperar_numero_sessao_view' %}",
{
tipo: tipo,
sessao_legislativa: sessao,
data_inicio: data_ini
},
function(data, status) {
$("#id_numero").val(data.numero);
}
);
}
else{
$("#id_numero").val('');
}
}
}
$("#id_tipo").click(recuperar_numero_sessao);
$("#id_sessao_legislativa").click(recuperar_numero_sessao);
$("#id_tipo").click(recuperar_numero_sessao);
$("#id_sessao_legislativa").click(recuperar_numero_sessao);
$("#id_legislatura").click(recuperar_numero_sessao);
{% endif %}
// Filtra as choices de sessao legislativa pela legislatura

14
sapl/templates/sessao/votacao/votacao.html

@ -15,7 +15,7 @@
{% for field in form %}
{% if field.errors %}
{% if field.label == 'total'%}
<li>O total de votos não corresponde com a quantidade de presentes!</li>
<li>O total de votos não corresponde com a quantidade de votantes!</li>
{% else %}
<li>O campo <b>{{field.label}}</b> é obrigatório!</li>
{% endif %}
@ -32,19 +32,21 @@
<br />
<br />
<b>Total presentes:</b> {{total_presentes}} (com presidente)
<br />
<b>Total votantes:</b> {{total_votantes}} (com presidente)
<input type="hidden" id="total_votos" name="total_votos">
</div>
<br />
<div class="row">
<div class="col-md-4">Sim: <input type="text" id="votos_sim" name="votos_sim" value="" class="form-control"/></div>
<div class="col-md-4">Não: <input type="text" id="votos_nao" name="votos_nao" value="" class="form-control"/></div>
<div class="col-md-4">Abstenções: <input type="text" id="abstencoes" name="abstencoes" value="" class="form-control"/></div>
<div class="col-md-4">Sim*: <input type="text" id="votos_sim" name="votos_sim" value="" class="form-control"/></div>
<div class="col-md-4">Não*: <input type="text" id="votos_nao" name="votos_nao" value="" class="form-control"/></div>
<div class="col-md-4">Abstenções*: <input type="text" id="abstencoes" name="abstencoes" value="" class="form-control"/></div>
</div>
<div class="row">
<div class="col-md-6">
A totalização inclui o voto do Presidente?
A totalização inclui o voto do Presidente?*
<select id="voto_presidente" name="voto_presidente" class="form-control">
<option value="1">Sim</option>
<option value="0" selected>Não</option>
@ -52,7 +54,7 @@
</div>
<div class="col-md-6">
Resultado da Votação
Resultado da Votação*
<select id="resultado_votacao" name="resultado_votacao" class="form-control">
{% for tipo in view.get_tipos_votacao %}
<option value="{{tipo.id}}">{{tipo.nome}}</option>

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

@ -8,9 +8,9 @@
<fieldset class="form-group">
<legend>Votação Simbólica</legend>
{% if ordens or expedientes %}
{% if total_presentes == 0 %}
{% if total_votantes == 0 %}
<div class="alert alert-info alert-dismissible " role="alert">
<div>Não existe nenhum parlamentar presente para que a votação ocorra.</div>
<div>Não existe nenhum parlamentar ativo presente para que a votação ocorra.</div>
</div>
{% if origem == 'ordem' %}
<a href="{% url 'sapl.sessao:votacao_bloco_ordemdia' pk %}" class="btn btn-warning">Voltar</a>
@ -36,7 +36,10 @@
{% endfor %}
{% endif %}
<b>Total presentes:</b> {{total_presentes}} (com presidente)
<br/>
<b>Total votantes:</b> {{total_votantes}} (com presidente)
<input type="hidden" id="total_presentes" name="total_presentes" value="{{total_presentes}}">
<input type="hidden" id="total_votantes" name="total_votantes" value="{{total_votantes}}">
</div>
<br />

2
setup.py

@ -43,7 +43,7 @@ install_requires = [
]
setup(
name='interlegis-sapl',
version='3.1.157-RC5',
version='3.1.158',
packages=find_packages(),
include_package_data=True,
license='GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007',

Loading…
Cancel
Save