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: ports:
- "5432:5432" - "5432:5432"
sapl: sapl:
image: interlegis/sapl:3.1.157-RC5 image: interlegis/sapl:3.1.158
# build: . # build: .
restart: always restart: always
environment: environment:

24
sapl/compilacao/views.py

@ -2147,8 +2147,11 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
return self.json_add_next(context, local_add='json_add_in') return self.json_add_next(context, local_add='json_add_in')
def json_add_next( def json_add_next(
self, self,
context, local_add='json_add_next', create_auto_inserts=True): context, local_add='json_add_next',
create_auto_inserts=True,
registro_inclusao=False
):
try: try:
@ -2249,7 +2252,9 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
dp.rotulo = dp.rotulo_padrao() dp.rotulo = dp.rotulo_padrao()
dp.ordem = ordem 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.publicacao = pub_last
dp.save() dp.save()
@ -2380,9 +2385,10 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
filho.save() filho.save()
''' Renumerar dispositivos de ''' 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() proxima_articulacao = dp.select_next_root()
@ -2522,7 +2528,8 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
data = self.json_add_next(context, data = self.json_add_next(context,
local_add=local_add, local_add=local_add,
create_auto_inserts=True) create_auto_inserts=True,
registro_inclusao=True)
if data and data['pk']: if data and data['pk']:
@ -2554,6 +2561,11 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
else: else:
data.update({'pk': bloco_alteracao.pk, data.update({'pk': bloco_alteracao.pk,
'pai': [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 return data

25
sapl/materia/forms.py

@ -285,7 +285,7 @@ class MateriaLegislativaForm(FileFieldCheckMixin, ModelForm):
materia = super(MateriaLegislativaForm, self).save(commit) materia = super(MateriaLegislativaForm, self).save(commit)
materia.save() materia.save()
if self.cleaned_data['autor']: if self.cleaned_data['autor']:
autoria = Autoria() autoria = Autoria()
autoria.primeiro_autor = primeiro_autor autoria.primeiro_autor = primeiro_autor
@ -1168,7 +1168,7 @@ class DespachoInicialForm(ModelForm):
class AutoriaForm(ModelForm): class AutoriaForm(ModelForm):
tipo_autor = ModelChoiceField(label=_('Tipo Autor'), tipo_autor = ModelChoiceField(label=_('Tipo Autor'),
required=False, required=True,
queryset=TipoAutor.objects.all(), queryset=TipoAutor.objects.all(),
empty_label=_('Selecione'),) empty_label=_('Selecione'),)
@ -1180,6 +1180,12 @@ class AutoriaForm(ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(AutoriaForm, self).__init__(*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), row1 = to_row([('tipo_autor', 4),
('autor', 4), ('autor', 4),
('primeiro_autor', 4)]) ('primeiro_autor', 4)])
@ -1220,7 +1226,7 @@ class AutoriaMultiCreateForm(Form):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
tipo_autor = ModelChoiceField(label=_('Tipo Autor'), tipo_autor = ModelChoiceField(label=_('Tipo Autor'),
required=False, required=True,
queryset=TipoAutor.objects.all(), queryset=TipoAutor.objects.all(),
empty_label=_('Selecione'),) empty_label=_('Selecione'),)
@ -1230,7 +1236,7 @@ class AutoriaMultiCreateForm(Form):
autor = ModelMultipleChoiceField( autor = ModelMultipleChoiceField(
queryset=Autor.objects.all(), queryset=Autor.objects.all(),
label=_('Possiveis Autores'), label=_('Possiveis Autores'),
required=False, required=True,
widget=CheckboxSelectMultiple) widget=CheckboxSelectMultiple)
autores = ModelMultipleChoiceField( autores = ModelMultipleChoiceField(
@ -1238,10 +1244,19 @@ class AutoriaMultiCreateForm(Form):
required=False, required=False,
widget=HiddenInput) widget=HiddenInput)
primeiro_autor = forms.ChoiceField(
required=True,
choices=YES_NO_CHOICES,
label="Primeiro Autor?"
)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*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), ]) 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', reverse('sapl.materia:autoria_create',
kwargs={'pk': materia_principal.pk}), kwargs={'pk': materia_principal.pk}),
{'autor': autor.pk, {'autor': autor.pk,
'tipo_autor': tipo_autor.pk,
'primeiro_autor': True, 'primeiro_autor': True,
'materia_id': materia_principal.pk, }, 'materia_id': materia_principal.pk, },
follow=True) follow=True)

13
sapl/materia/tests/test_materia_form.py

@ -129,9 +129,11 @@ def test_valida_campos_obrigatorios_autoria_form():
errors = form.errors 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) @pytest.mark.django_db(transaction=False)
@ -142,9 +144,12 @@ def test_valida_campos_obrigatorios_autoria_multicreate_form():
errors = form.errors 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) @pytest.mark.django_db(transaction=False)

20
sapl/materia/views.py

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

4
sapl/protocoloadm/views.py

@ -1160,7 +1160,7 @@ class TramitacaoAdmCrud(MasterDetailCrud):
# não pode ser modificado # não pode ser modificado
if not primeira_tramitacao: if not primeira_tramitacao:
context['form'].fields[ context['form'].fields[
'unidade_tramitacao_local'].widget.attrs['disabled'] = True 'unidade_tramitacao_local'].widget.attrs['readonly'] = True
return context return context
def form_valid(self, form): def form_valid(self, form):
@ -1455,7 +1455,7 @@ class FichaSelecionaAdmView(PermissionRequiredMixin, FormView):
class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView): class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView):
filterset_class = PrimeiraTramitacaoEmLoteAdmFilterSet filterset_class = PrimeiraTramitacaoEmLoteAdmFilterSet
template_name = 'protocoloadm/em_lote/tramitacaoadm.html' template_name = 'protocoloadm/em_lote/tramitacaoadm.html'
permission_required = ('materia.add_tramitacao', ) permission_required = ('protocoloadm.add_tramitacaoadministrativo', )
primeira_tramitacao = True 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\t<font color="white"> </font>\n'
tmp += '\t\t</para>\n' tmp += '\t\t</para>\n'
for expediente in lst_expedientes: for expediente in lst_expedientes:
tmp += '\t\t<para style="P2"><b>' + '<br/> ' + \ if expediente['txt_expediente']:
expediente['nom_expediente'] + ': </b></para>\n' + \ tmp += '\t\t<para style="P2"><b>' + '<br/> ' + \
'<para style="P3">' + \ expediente['nom_expediente'] + ': </b></para>\n' + \
expediente['txt_expediente'] + '</para>\n' '<para style="P3">' + \
tmp += '\t\t<para style="P2">\n' expediente['txt_expediente'] + '</para>\n'
tmp += '\t\t\t<font color="white"> </font>\n' tmp += '\t\t<para style="P2">\n'
tmp += '\t\t</para>\n' tmp += '\t\t\t<font color="white"> </font>\n'
tmp += '\t\t</para>\n'
return tmp return tmp

48
sapl/sessao/forms.py

@ -1,6 +1,5 @@
from datetime import datetime from datetime import datetime
from sapl.crispy_layout_mixin import SaplFormHelper
from crispy_forms.layout import HTML, Button, Fieldset, Layout from crispy_forms.layout import HTML, Button, Fieldset, Layout
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -13,6 +12,7 @@ from django.utils.translation import ugettext_lazy as _
import django_filters import django_filters
from sapl.base.models import Autor, TipoAutor 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.crispy_layout_mixin import form_actions, to_row, SaplFormLayout
from sapl.materia.forms import MateriaLegislativaFilterSet from sapl.materia.forms import MateriaLegislativaFilterSet
from sapl.materia.models import (MateriaLegislativa, StatusTramitacao, from sapl.materia.models import (MateriaLegislativa, StatusTramitacao,
@ -60,21 +60,11 @@ class SessaoPlenariaForm(FileFieldCheckMixin, ModelForm):
"para a Legislatura, Sessão Legislativa e Tipo informados. " "para a Legislatura, Sessão Legislativa e Tipo informados. "
"Favor escolher um número distinto.") "Favor escolher um número distinto.")
sessoes = SessaoPlenaria.objects.filter(numero=num, qs = tipo.queryset_tipo_numeracao(leg, sl, abertura)
sessao_legislativa=sl, qs &= Q(numero=num)
legislatura=leg,
tipo=tipo,
data_inicio__year=abertura.year).\
values_list('id', flat=True)
qtd_sessoes = len(sessoes)
if qtd_sessoes > 0: if SessaoPlenaria.objects.filter(qs).exclude(pk=instance.pk).exists():
if instance.pk: # update raise error
if instance.pk not in sessoes or qtd_sessoes > 1:
raise error
else: # create
raise error
# Condições da verificação # Condições da verificação
abertura_entre_leg = leg.data_inicio <= abertura <= leg.data_fim abertura_entre_leg = leg.data_inicio <= abertura <= leg.data_fim
@ -474,6 +464,9 @@ class VotacaoForm(forms.Form):
abstencoes = forms.IntegerField(label='Abstenções') abstencoes = forms.IntegerField(label='Abstenções')
total_presentes = forms.IntegerField( total_presentes = forms.IntegerField(
required=False, widget=forms.HiddenInput()) required=False, widget=forms.HiddenInput())
total_votantes = forms.IntegerField(
required=False, widget=forms.HiddenInput()
)
voto_presidente = forms.IntegerField( voto_presidente = forms.IntegerField(
label='A totalização inclui o voto do Presidente?') label='A totalização inclui o voto do Presidente?')
total_votos = forms.IntegerField(required=False, label='total') total_votos = forms.IntegerField(required=False, label='total')
@ -489,15 +482,16 @@ class VotacaoForm(forms.Form):
votos_nao = cleaned_data['votos_nao'] votos_nao = cleaned_data['votos_nao']
abstencoes = cleaned_data['abstencoes'] abstencoes = cleaned_data['abstencoes']
qtde_presentes = cleaned_data['total_presentes'] qtde_presentes = cleaned_data['total_presentes']
qtde_votantes = cleaned_data['total_votantes']
qtde_votos = votos_sim + votos_nao + abstencoes qtde_votos = votos_sim + votos_nao + abstencoes
voto_presidente = cleaned_data['voto_presidente'] voto_presidente = cleaned_data['voto_presidente']
if qtde_presentes and not voto_presidente: if qtde_votantes and not voto_presidente:
qtde_presentes -= 1 qtde_votantes -= 1
if qtde_presentes and qtde_votos != qtde_presentes: if qtde_votantes and qtde_votos != qtde_votantes:
raise ValidationError( 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 return cleaned_data
@ -640,7 +634,7 @@ class OradorForm(ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['parlamentar'].queryset = \ 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): def clean(self):
super(OradorForm, self).clean() super(OradorForm, self).clean()
@ -662,8 +656,8 @@ class OradorForm(ModelForm):
"Já existe orador nesta posição de ordem de pronunciamento" "Já existe orador nesta posição de ordem de pronunciamento"
)) ))
return self.cleaned_data return self.cleaned_data
class Meta: class Meta:
model = Orador model = Orador
exclude = ['sessao_plenaria'] exclude = ['sessao_plenaria']
@ -672,8 +666,12 @@ class OradorForm(ModelForm):
class OradorExpedienteForm(ModelForm): class OradorExpedienteForm(ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*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 = \ 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): def clean(self):
super(OradorExpedienteForm, self).clean() super(OradorExpedienteForm, self).clean()
@ -703,8 +701,12 @@ class OradorExpedienteForm(ModelForm):
class OradorOrdemDiaForm(ModelForm): class OradorOrdemDiaForm(ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*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 = \ 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): def clean(self):
super(OradorOrdemDiaForm, self).clean() 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.core.exceptions import ValidationError
from django.db import models 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 django.utils.translation import ugettext_lazy as _
from model_utils import Choices from model_utils import Choices
import reversion import reversion
@ -73,10 +74,24 @@ class Bancada(models.Model):
@reversion.register() @reversion.register()
class TipoSessaoPlenaria(models.Model): 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( quorum_minimo = models.PositiveIntegerField(
verbose_name=_('Quórum mínimo')) verbose_name=_('Quórum mínimo'))
tipo_numeracao = models.PositiveIntegerField(
verbose_name=_('Tipo de Numeração'),
choices=TIPO_NUMERACAO_CHOICES, default=11)
class Meta: class Meta:
verbose_name = _('Tipo de Sessão Plenária') verbose_name = _('Tipo de Sessão Plenária')
verbose_name_plural = _('Tipos 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): def __str__(self):
return self.nome 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): def get_sessao_media_path(instance, subpath, filename):
return './sapl/sessao/%s/%s/%s' % (instance.numero, 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') verbose_name_plural = _('Sessões Plenárias')
def __str__(self): 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 %(sessao_legislativa_numero)sª Sessão Legislativa'
' da %(legislatura_id)sª Legislatura') % { ' da %(legislatura_id)sª Legislatura') % {
@ -185,6 +250,7 @@ class SessaoPlenaria(models.Model):
'sessao_legislativa_numero': self.sessao_legislativa.numero, 'sessao_legislativa_numero': self.sessao_legislativa.numero,
# XXX check if it shouldn't be legislatura.numero # XXX check if it shouldn't be legislatura.numero
'legislatura_id': self.legislatura.numero} 'legislatura_id': self.legislatura.numero}
"""
def delete(self, using=None, keep_parents=False): def delete(self, using=None, keep_parents=False):
if self.upload_pauta: 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, from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
AdicionarVariasMateriasOrdemDia, BancadaCrud, AdicionarVariasMateriasOrdemDia, BancadaCrud,
CargoBancadaCrud, ExpedienteMateriaCrud, CargoBancadaCrud, ExpedienteMateriaCrud,
ExpedienteView, JustificativaAusenciaCrud, ExpedienteView, JustificativaAusenciaCrud,
OcorrenciaSessaoView, MateriaOrdemDiaCrud, OradorOrdemDiaCrud, OcorrenciaSessaoView, MateriaOrdemDiaCrud, OradorOrdemDiaCrud,
MesaView, OradorCrud, MesaView, OradorCrud,
@ -25,7 +25,7 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
VotacaoNominalView, VotacaoView, abrir_votacao, VotacaoNominalView, VotacaoView, abrir_votacao,
atualizar_mesa, insere_parlamentar_composicao, atualizar_mesa, insere_parlamentar_composicao,
mudar_ordem_materia_sessao, recuperar_materia, mudar_ordem_materia_sessao, recuperar_materia,
recuperar_numero_sessao, recuperar_numero_sessao_view,
remove_parlamentar_composicao, remove_parlamentar_composicao,
reordernar_materias_expediente, reordernar_materias_expediente,
reordernar_materias_ordem, reordernar_materias_ordem,
@ -65,7 +65,7 @@ urlpatterns = [
url(r'^sessao/recuperar-materia/', recuperar_materia), url(r'^sessao/recuperar-materia/', recuperar_materia),
url(r'^sessao/recuperar-numero-sessao/', url(r'^sessao/recuperar-numero-sessao/',
recuperar_numero_sessao, recuperar_numero_sessao_view,
name='recuperar_numero_sessao_view' name='recuperar_numero_sessao_view'
), ),
url(r'^sessao/sessao-legislativa-legislatura-ajax/', 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') TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
TipoExpedienteCrud = CrudAux.build(TipoExpediente, 'tipo_expediente')
TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa') TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa')
CargoBancadaCrud = CrudAux.build(CargoBancada, '') CargoBancadaCrud = CrudAux.build(CargoBancada, '')
TipoResultadoVotacaoCrud = CrudAux.build( TipoResultadoVotacaoCrud = CrudAux.build(
@ -93,6 +92,7 @@ def reordernar_materias_ordem(request, pk):
return HttpResponseRedirect( return HttpResponseRedirect(
reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk})) reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk}))
def renumerar_materias_ordem(request, pk): def renumerar_materias_ordem(request, pk):
ordens = OrdemDia.objects.filter(sessao_plenaria_id=pk) ordens = OrdemDia.objects.filter(sessao_plenaria_id=pk)
@ -103,6 +103,7 @@ def renumerar_materias_ordem(request, pk):
return HttpResponseRedirect( return HttpResponseRedirect(
reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk})) reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk}))
def renumerar_materias_expediente(request, pk): def renumerar_materias_expediente(request, pk):
expedientes = ExpedienteMateria.objects.filter(sessao_plenaria_id=pk) expedientes = ExpedienteMateria.objects.filter(sessao_plenaria_id=pk)
@ -113,6 +114,7 @@ def renumerar_materias_expediente(request, pk):
return HttpResponseRedirect( return HttpResponseRedirect(
reverse('sapl.sessao:expedientemateria_list', kwargs={'pk': pk})) reverse('sapl.sessao:expedientemateria_list', kwargs={'pk': pk}))
def verifica_presenca(request, model, spk): def verifica_presenca(request, model, spk):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
if not model.objects.filter(sessao_plenaria_id=spk).exists(): 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) 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): class MateriaOrdemDiaCrud(MasterDetailCrud):
model = OrdemDia model = OrdemDia
parent_field = 'sessao_plenaria' parent_field = 'sessao_plenaria'
@ -595,7 +614,6 @@ class OradorCrud(MasterDetailCrud):
class ListView(MasterDetailCrud.ListView): class ListView(MasterDetailCrud.ListView):
ordering = ['numero_ordem', 'parlamentar'] ordering = ['numero_ordem', 'parlamentar']
class CreateView(MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
form_class = OradorForm form_class = OradorForm
@ -607,7 +625,6 @@ class OradorCrud(MasterDetailCrud):
return reverse('sapl.sessao:orador_list', return reverse('sapl.sessao:orador_list',
kwargs={'pk': self.kwargs['pk']}) kwargs={'pk': self.kwargs['pk']})
class UpdateView(MasterDetailCrud.UpdateView): class UpdateView(MasterDetailCrud.UpdateView):
form_class = OradorForm form_class = OradorForm
@ -615,7 +632,7 @@ class OradorCrud(MasterDetailCrud):
def get_initial(self): def get_initial(self):
initial = super(UpdateView, self).get_initial() initial = super(UpdateView, self).get_initial()
initial.update({'id_sessao': self.object.sessao_plenaria.id}) 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 return initial
@ -677,11 +694,24 @@ class BancadaCrud(CrudAux):
return reverse('sapl.sessao:bancada_list') return reverse('sapl.sessao:bancada_list')
def recuperar_numero_sessao(request): def recuperar_numero_sessao_view(request):
try: 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( sessao = SessaoPlenaria.objects.filter(
tipo__pk=request.GET['tipo'], tipo.queryset_tipo_numeracao(
sessao_legislativa=request.GET['sessao_legislativa']).last() l, sl, data
)).last()
except ObjectDoesNotExist: except ObjectDoesNotExist:
numero = 1 numero = 1
else: else:
@ -1066,7 +1096,6 @@ class ListMateriaOrdemDiaView(FormMixin, DetailView):
return self.get(self, request, args, kwargs) return self.get(self, request, args, kwargs)
class MesaView(FormMixin, DetailView): class MesaView(FormMixin, DetailView):
template_name = 'sessao/mesa.html' template_name = 'sessao/mesa.html'
form_class = MesaForm form_class = MesaForm
@ -1341,7 +1370,7 @@ def get_identificação_basica(sessao_plenaria):
_('Encerramento: %(encerramento)s %(hora_fim)s') % { _('Encerramento: %(encerramento)s %(hora_fim)s') % {
'encerramento': encerramento, 'hora_fim': sessao_plenaria.hora_fim} 'encerramento': encerramento, 'hora_fim': sessao_plenaria.hora_fim}
], ],
'sessaoplenaria': sessao_plenaria}) 'sessaoplenaria': sessao_plenaria})
def get_conteudo_multimidia(sessao_plenaria): def get_conteudo_multimidia(sessao_plenaria):
@ -1360,7 +1389,8 @@ def get_conteudo_multimidia(sessao_plenaria):
def get_mesa_diretora(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, integrantes = [{'parlamentar': m.parlamentar,
'cargo': m.cargo} for m in mesa] 'cargo': m.cargo} for m in mesa]
return {'mesa': integrantes} return {'mesa': integrantes}
@ -1369,8 +1399,8 @@ def get_mesa_diretora(sessao_plenaria):
def get_presenca_sessao(sessao_plenaria): def get_presenca_sessao(sessao_plenaria):
parlamentares_sessao = [p.parlamentar for p in SessaoPlenariaPresenca.objects.filter( parlamentares_sessao = [p.parlamentar for p in SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=sessao_plenaria.id sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')] ).order_by('parlamentar__nome_parlamentar')]
ausentes_sessao = JustificativaAusencia.objects.filter( ausentes_sessao = JustificativaAusencia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id sessao_plenaria_id=sessao_plenaria.id
@ -1404,7 +1434,8 @@ def get_materias_expediente(sessao_plenaria):
numero = m.numero_ordem numero = m.numero_ordem
tramitacao = '' 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: for aux_tramitacao in tramitacoes:
if aux_tramitacao.turno: if aux_tramitacao.turno:
tramitacao = aux_tramitacao tramitacao = aux_tramitacao
@ -1466,8 +1497,8 @@ def get_oradores_expediente(sessao_plenaria):
def get_presenca_ordem_do_dia(sessao_plenaria): def get_presenca_ordem_do_dia(sessao_plenaria):
parlamentares_ordem = [p.parlamentar for p in PresencaOrdemDia.objects.filter( parlamentares_ordem = [p.parlamentar for p in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')] ).order_by('parlamentar__nome_parlamentar')]
return {'presenca_ordem': parlamentares_ordem} return {'presenca_ordem': parlamentares_ordem}
@ -1480,13 +1511,14 @@ def get_assinaturas(sessao_plenaria):
'')] '')]
parlamentares_ordem = [p.parlamentar for p in PresencaOrdemDia.objects.filter( parlamentares_ordem = [p.parlamentar for p in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id sessao_plenaria_id=sessao_plenaria.id
).order_by('parlamentar__nome_parlamentar')] ).order_by('parlamentar__nome_parlamentar')]
parlamentares_mesa = [m['parlamentar'] for m in mesa_dia] parlamentares_mesa = [m['parlamentar'] for m in mesa_dia]
# filtra parlamentares retirando os que sao da mesa # 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 = {} context = {}
config_assinatura_ata = AppsAppConfig.attr('assinatura_ata') config_assinatura_ata = AppsAppConfig.attr('assinatura_ata')
@ -1517,7 +1549,8 @@ def get_materias_ordem_do_dia(sessao_plenaria):
numero = o.numero_ordem numero = o.numero_ordem
tramitacao = '' 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: for aux_tramitacao in tramitacoes:
if aux_tramitacao.turno: if aux_tramitacao.turno:
tramitacao = aux_tramitacao tramitacao = aux_tramitacao
@ -1600,7 +1633,7 @@ def get_oradores_ordemdia(sessao_plenaria):
observacao = orador.observacao observacao = orador.observacao
parlamentar = Parlamentar.objects.get( parlamentar = Parlamentar.objects.get(
id=orador.parlamentar_id id=orador.parlamentar_id
) )
o = { o = {
'numero_ordem': numero_ordem, 'numero_ordem': numero_ordem,
'url_discurso': url_discurso, 'url_discurso': url_discurso,
@ -1610,9 +1643,9 @@ def get_oradores_ordemdia(sessao_plenaria):
oradores.append(o) oradores.append(o)
context = {'oradores_ordemdia': oradores} context = {'oradores_ordemdia': oradores}
return context return context
def get_oradores_explicações_pessoais(sessao_plenaria): def get_oradores_explicações_pessoais(sessao_plenaria):
oradores_explicacoes = [] oradores_explicacoes = []
for orador in Orador.objects.filter( for orador in Orador.objects.filter(
@ -1729,7 +1762,7 @@ class ResumoView(DetailView):
# ===================================================================== # =====================================================================
# Oradores Ordem do Dia # Oradores Ordem do Dia
context.update(get_oradores_ordemdia(self.object)) context.update(get_oradores_ordemdia(self.object))
# ===================================================================== # =====================================================================
# Oradores nas Explicações Pessoais # Oradores nas Explicações Pessoais
context.update(get_oradores_explicações_pessoais(self.object)) context.update(get_oradores_explicações_pessoais(self.object))
# ===================================================================== # =====================================================================
@ -2051,13 +2084,24 @@ class VotacaoView(SessaoPermissionMixin):
ordem_id = kwargs['oid'] ordem_id = kwargs['oid']
ordem = OrdemDia.objects.get(id=ordem_id) 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} materia = {'materia': ordem.materia, 'ementa': ordem.materia.ementa}
context.update({'votacao_titulo': titulo, context.update({'votacao_titulo': titulo,
'materia': materia, 'materia': materia,
'total_presentes': qtde_presentes}) 'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
return self.render_to_response(context) return self.render_to_response(context)
@ -2077,13 +2121,24 @@ class VotacaoView(SessaoPermissionMixin):
ordem_id = kwargs['oid'] ordem_id = kwargs['oid']
ordem = OrdemDia.objects.get(id=ordem_id) 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} materia = {'materia': ordem.materia, 'ementa': ordem.materia.ementa}
context.update({'votacao_titulo': titulo, context.update({'votacao_titulo': titulo,
'materia': materia, 'materia': materia,
'total_presentes': qtde_presentes}) 'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
context.update({'form': form}) context.update({'form': form})
# ==================================================== # ====================================================
@ -2096,21 +2151,19 @@ class VotacaoView(SessaoPermissionMixin):
materia_id = kwargs['mid'] materia_id = kwargs['mid']
ordem_id = kwargs['oid'] ordem_id = kwargs['oid']
qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.object.id).count()
qtde_votos = (int(request.POST['votos_sim']) + qtde_votos = (int(request.POST['votos_sim']) +
int(request.POST['votos_nao']) + int(request.POST['votos_nao']) +
int(request.POST['abstencoes'])) int(request.POST['abstencoes']))
if (int(request.POST['voto_presidente']) == 0): 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 = _( 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) messages.add_message(request, messages.ERROR, msg)
return self.render_to_response(context) return self.render_to_response(context)
elif (qtde_presentes == qtde_votos): else:
try: try:
votacao = RegistroVotacao() votacao = RegistroVotacao()
votacao.numero_votos_sim = int(request.POST['votos_sim']) votacao.numero_votos_sim = int(request.POST['votos_sim'])
@ -2755,14 +2808,25 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
expediente_id = kwargs['oid'] expediente_id = kwargs['oid']
expediente = ExpedienteMateria.objects.get(id=expediente_id) 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, materia = {'materia': expediente.materia,
'ementa': expediente.materia.ementa} 'ementa': expediente.materia.ementa}
context.update({'votacao_titulo': titulo, context.update({'votacao_titulo': titulo,
'materia': materia, 'materia': materia,
'total_presentes': qtde_presentes}) 'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
return self.render_to_response(context) return self.render_to_response(context)
@ -2782,14 +2846,25 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
expediente_id = kwargs['oid'] expediente_id = kwargs['oid']
expediente = ExpedienteMateria.objects.get(id=expediente_id) 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, materia = {'materia': expediente.materia,
'ementa': expediente.materia.ementa} 'ementa': expediente.materia.ementa}
context.update({'votacao_titulo': titulo, context.update({'votacao_titulo': titulo,
'materia': materia, 'materia': materia,
'total_presentes': qtde_presentes}) 'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
context.update({'form': form}) context.update({'form': form})
# ==================================================== # ====================================================
@ -2802,17 +2877,17 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
materia_id = kwargs['mid'] materia_id = kwargs['mid']
expediente_id = kwargs['oid'] expediente_id = kwargs['oid']
qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id).count()
qtde_votos = (int(request.POST['votos_sim']) + qtde_votos = (int(request.POST['votos_sim']) +
int(request.POST['votos_nao']) + int(request.POST['votos_nao']) +
int(request.POST['abstencoes'])) int(request.POST['abstencoes']))
if (int(request.POST['voto_presidente']) == 0): if (int(request.POST['voto_presidente']) == 0):
qtde_presentes -= 1 qtde_ativos -= 1
if qtde_votos != qtde_presentes: if qtde_votos != qtde_ativos:
form._errors["total_votos"] = ErrorList([u""]) 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) return self.render_to_response(context)
else: else:
try: try:
@ -3561,17 +3636,41 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie
if request.POST['origem'] == 'ordem': if request.POST['origem'] == 'ordem':
ordens = OrdemDia.objects.filter( ordens = OrdemDia.objects.filter(
id__in=request.POST.getlist('marcadas_1')) 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, context.update({'ordens': ordens,
'total_presentes': qtde_presentes}) 'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
else: else:
expedientes = ExpedienteMateria.objects.filter( expedientes = ExpedienteMateria.objects.filter(
id__in=request.POST.getlist('marcadas_1')) 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, context.update({'expedientes': expedientes,
'total_presentes': qtde_presentes}) 'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
if 'salvar-votacao' in request.POST: if 'salvar-votacao' in request.POST:
form = VotacaoForm(request.POST) form = VotacaoForm(request.POST)
@ -3696,17 +3795,41 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie
if self.request.POST['origem'] == 'ordem': if self.request.POST['origem'] == 'ordem':
ordens = OrdemDia.objects.filter( ordens = OrdemDia.objects.filter(
id__in=self.request.POST.getlist('ordens')) 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, context.update({'ordens': ordens,
'total_presentes': qtde_presentes}) 'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
elif self.request.POST['origem'] == 'expediente': elif self.request.POST['origem'] == 'expediente':
expedientes = ExpedienteMateria.objects.filter( expedientes = ExpedienteMateria.objects.filter(
id__in=self.request.POST.getlist('expedientes')) 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, context.update({'expedientes': expedientes,
'total_presentes': qtde_presentes}) 'total_presentes': qtde_presentes,
'total_votantes': qtde_ativos})
context.update({'resultado_votacao': TipoResultadoVotacao.objects.all(), context.update({'resultado_votacao': TipoResultadoVotacao.objects.all(),
'form': form, 'form': form,

2
sapl/settings.py

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

26
sapl/templates/base.html

@ -179,7 +179,7 @@
<small> <small>
Desenvolvido pelo <a href="http://www.interlegis.leg.br/">Interlegis</a> em software livre e aberto. Desenvolvido pelo <a href="http://www.interlegis.leg.br/">Interlegis</a> em software livre e aberto.
</small> </small>
<span>Release: 3.1.157-RC5</span> <span>Release: 3.1.158</span>
</p> </p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
@ -232,11 +232,9 @@
{% block webpack_loader_chunks_js %} {% block webpack_loader_chunks_js %}
{% endblock webpack_loader_chunks_js %} {% endblock webpack_loader_chunks_js %}
{% block extra_js %}{% endblock %} {% block extra_js %}{% endblock extra_js %}
<script type="text/javascript" > <script type="text/javascript" >
function inIframe () { function inIframe () {
try { try {
return window.self !== window.top; return window.self !== window.top;
@ -249,21 +247,19 @@
if (iframe_set_backend && !inIframe() ) { if (iframe_set_backend && !inIframe() ) {
location.href = location.origin + '?iframe=0' 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> </script>
{% endblock foot_js %} {% 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> </body>
</html> </html>

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

@ -134,19 +134,5 @@
checkboxes[i].checked = elem.checked; 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> </script>
{% endblock %} {% 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 %} {% endfor %}
</div> </div>
{% endif %} {% 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 %} {% 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 url: sapl.protocoloadm:pesq_doc_adm
- title: {% trans 'Tramitação em Lote' %} - title: {% trans 'Tramitação em Lote' %}
url: sapl.protocoloadm:primeira_tramitacao_em_lote_docadm url: sapl.protocoloadm:primeira_tramitacao_em_lote_docadm
check_permission: sapl.documento:add_tramitacao check_permission: sapl.protocoloadm:add_tramitacaoadministrativo
- title: {% trans 'Atividade Legislativa' %} - title: {% trans 'Atividade Legislativa' %}
children: children:

52
sapl/templates/painel/index.html

@ -149,7 +149,16 @@
countdown: true, countdown: true,
startAt: {{ 'discurso'|cronometro_to_seconds }} * 1000, startAt: {{ 'discurso'|cronometro_to_seconds }} * 1000,
stopAt: 0, 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){ }).on('runnerFinish', function(eventObject, info){
audioAlertFinish.play(); audioAlertFinish.play();
}); });
@ -159,7 +168,16 @@
countdown: true, countdown: true,
startAt: {{ 'aparte'|cronometro_to_seconds }} * 1000, startAt: {{ 'aparte'|cronometro_to_seconds }} * 1000,
stopAt: 0, 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){ }).on('runnerFinish', function(eventObject, info){
audioAlertFinish.play(); audioAlertFinish.play();
}); });
@ -169,7 +187,16 @@
countdown: true, countdown: true,
startAt: {{ 'ordem'|cronometro_to_seconds }} * 1000, startAt: {{ 'ordem'|cronometro_to_seconds }} * 1000,
stopAt: 0, 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){ }).on('runnerFinish', function(eventObject, info){
audioAlertFinish.play(); audioAlertFinish.play();
}); });
@ -179,7 +206,16 @@
countdown: true, countdown: true,
startAt: {{ 'consideracoes'|cronometro_to_seconds }} * 1000, startAt: {{ 'consideracoes'|cronometro_to_seconds }} * 1000,
stopAt: 0, 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){ }).on('runnerFinish', function(eventObject, info){
audioAlertFinish.play(); audioAlertFinish.play();
}); });
@ -329,19 +365,19 @@
consideracoes_previous = consideracoes_current; consideracoes_previous = consideracoes_current;
} }
if($('#cronometro_discurso').runner('info').formattedTime == 30) { if($('#cronometro_discurso').runner('info').formattedTime == "00:00:30") {
audioAlertFinish.play(); audioAlertFinish.play();
} }
if($('#cronometro_aparte').runner('info').formattedTime == 30) { if($('#cronometro_aparte').runner('info').formattedTime == "00:00:30") {
audioAlertFinish.play(); audioAlertFinish.play();
} }
if($('#cronometro_ordem').runner('info').formattedTime == 30) { if($('#cronometro_ordem').runner('info').formattedTime == "00:00:30") {
audioAlertFinish.play(); audioAlertFinish.play();
} }
if($('#cronometro_consideracoes').runner('info').formattedTime == 30) { if($('#cronometro_consideracoes').runner('info').formattedTime == "00:00:30") {
audioAlertFinish.play(); audioAlertFinish.play();
} }

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

@ -21,26 +21,12 @@
{% block extra_js %} {% block extra_js %}
<script language="JavaScript"> <script language="JavaScript">
function checkAll(elem) { function checkAll(elem) {
let checkboxes = document.getElementsByName('documentos'); let checkboxes = document.getElementsByName('documentos');
for (let i = 0; i < checkboxes.length; i++) { for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].type == 'checkbox') if (checkboxes[i].type == 'checkbox')
checkboxes[i].checked = elem.checked; 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> </script>
{% endblock %} {% 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 %} {% if expedientes %}
<strong>Expedientes: </strong> <strong>Expedientes: </strong>
{% for e in expedientes %} {% for e in expedientes %}
<b>{{e.tipo}}</b>: {% if e.conteudo %}
{% if e.conteudo %} <b>{{e.tipo}}</b>:
{{e.conteudo|striptags|safe}} {{e.conteudo|striptags|safe}}
{% else %} {% endif %}
Sem registro
{% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</p> </p>

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

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

4
sapl/templates/sessao/layouts.yaml

@ -1,11 +1,11 @@
{% load i18n %} {% load i18n %}
TipoSessaoPlenaria: TipoSessaoPlenaria:
{% trans 'Tipo de Sessão Plenária' %}: {% trans 'Tipo de Sessão Plenária' %}:
- nome quorum_minimo - nome quorum_minimo tipo_numeracao
SessaoPlenaria: SessaoPlenaria:
{% trans 'Dados Básicos' %}: {% 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_inicio:5 hora_inicio:5 iniciada
- data_fim:5 hora_fim:5 finalizada - data_fim:5 hora_fim:5 finalizada
- upload_pauta upload_ata upload_anexo - upload_pauta upload_ata upload_anexo

44
sapl/templates/sessao/painel.html

@ -127,7 +127,16 @@ $(function() {
countdown: true, countdown: true,
startAt: {{cronometro_discurso}} * 1000, startAt: {{cronometro_discurso}} * 1000,
stopAt: 0, 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){ }).on('runnerFinish', function(eventObject, info){
$.get('/painel/cronometro', { tipo: 'discurso', action: 'stop' } ); $.get('/painel/cronometro', { tipo: 'discurso', action: 'stop' } );
audioAlertFinish.play(); audioAlertFinish.play();
@ -170,7 +179,16 @@ $(function() {
countdown: true, countdown: true,
startAt: {{cronometro_aparte}} * 1000, startAt: {{cronometro_aparte}} * 1000,
stopAt: 0, 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){ }).on('runnerFinish', function(eventObject, info){
$.get('/painel/cronometro', { tipo: 'aparte', action: 'stop' } ); $.get('/painel/cronometro', { tipo: 'aparte', action: 'stop' } );
audioAlertFinish.play(); audioAlertFinish.play();
@ -213,7 +231,16 @@ $(function() {
countdown: true, countdown: true,
startAt: {{cronometro_ordem}} * 1000, startAt: {{cronometro_ordem}} * 1000,
stopAt: 0, 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){ }).on('runnerFinish', function(eventObject, info){
$.get('/painel/cronometro', { tipo: 'ordem', action: 'stop' } ); $.get('/painel/cronometro', { tipo: 'ordem', action: 'stop' } );
audioAlertFinish.play(); audioAlertFinish.play();
@ -257,7 +284,16 @@ $(function() {
countdown: true, countdown: true,
startAt: {{cronometro_consideracoes}} * 1000, startAt: {{cronometro_consideracoes}} * 1000,
stopAt: 0, 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){ }).on('runnerFinish', function(eventObject, info){
$.get('/painel/cronometro', { tipo: 'consideracoes', action: 'stop' } ); $.get('/painel/cronometro', { tipo: 'consideracoes', action: 'stop' } );
audioAlertFinish.play(); audioAlertFinish.play();

4
sapl/templates/sessao/pauta_sessao_detail.html

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

45
sapl/templates/sessao/sessaoplenaria_form.html

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

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

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

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

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

2
setup.py

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

Loading…
Cancel
Save