Browse Source

Merge branch '3.1.x' of https://github.com/interlegis/sapl into 2313-geracao-relatorios-estatisticas

pull/2429/head
Cesar Carvalho 7 years ago
parent
commit
b48b7b3129
  1. 2
      docker-compose.yml
  2. 35
      sapl/base/migrations/0024_auto_20181126_1534.py
  3. 21
      sapl/base/migrations/0025_auto_20181126_1648.py
  4. 20
      sapl/base/migrations/0026_auto_20181126_1727.py
  5. 8
      sapl/base/models.py
  6. 7
      sapl/base/templatetags/common_tags.py
  7. 26
      sapl/legacy/migracao_documentos.py
  8. 2
      sapl/legacy/scripts/exporta_zope/exporta_zope.py
  9. 7
      sapl/materia/views.py
  10. 15
      sapl/norma/fixtures/pre_popula_tipo_vinculo_norma.json
  11. 10
      sapl/norma/forms.py
  12. 2
      sapl/norma/migrations/0009_auto_20171113_1339.py
  13. 20
      sapl/norma/migrations/0015_auto_20181109_1422.py
  14. 26
      sapl/norma/migrations/0016_tipovinculonormajuridica_revoga_integramente.py
  15. 5
      sapl/norma/models.py
  16. 19
      sapl/norma/views.py
  17. 1
      sapl/painel/views.py
  18. 2
      sapl/parlamentares/forms.py
  19. 1
      sapl/parlamentares/tests/test_parlamentares.py
  20. 2
      sapl/parlamentares/views.py
  21. 12
      sapl/relatorios/templates/pdf_pauta_sessao_gerar.py
  22. 1
      sapl/relatorios/templates/pdf_pauta_sessao_preparar_pysc.py
  23. 38
      sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py
  24. 230
      sapl/relatorios/views.py
  25. 2
      sapl/rules/map_rules.py
  26. 111
      sapl/sessao/forms.py
  27. 50
      sapl/sessao/migrations/0028_auto_20181031_0902.py
  28. 27
      sapl/sessao/migrations/0030_auto_20181113_1149.py
  29. 20
      sapl/sessao/migrations/0030_resumoordenacao_decimo_primeiro.py
  30. 21
      sapl/sessao/migrations/0031_auto_20181116_1849.py
  31. 20
      sapl/sessao/migrations/0031_auto_20181119_1103.py
  32. 16
      sapl/sessao/migrations/0032_merge_20181122_1527.py
  33. 66
      sapl/sessao/models.py
  34. 9
      sapl/sessao/urls.py
  35. 137
      sapl/sessao/views.py
  36. 10
      sapl/static/js/app.js
  37. 40
      sapl/static/styles/app.scss
  38. 2
      sapl/templates/base.html
  39. 5
      sapl/templates/materia/proposicao_detail.html
  40. 3
      sapl/templates/menu_tabelas_auxiliares.yaml
  41. 8
      sapl/templates/norma/layouts.yaml
  42. 4
      sapl/templates/protocoloadm/comprovante.html
  43. 12
      sapl/templates/sessao/blocos_ata/lista_presenca.html
  44. 5
      sapl/templates/sessao/blocos_ata/lista_presenca_ordem_dia.html
  45. 27
      sapl/templates/sessao/blocos_resumo/lista_presenca.html
  46. 2
      sapl/templates/sessao/blocos_resumo/materias_expediente.html
  47. 6
      sapl/templates/sessao/expedientemateria_list.html
  48. 12
      sapl/templates/sessao/layouts.yaml
  49. 6
      sapl/templates/sessao/ordemdia_list.html
  50. 4
      sapl/templates/sessao/pauta_sessao_detail.html
  51. 157
      sapl/templates/sessao/presenca.html
  52. 147
      sapl/templates/sessao/presenca_ordemdia.html
  53. 2
      sapl/templates/sessao/resumo_ata.html
  54. 2
      sapl/templates/sessao/resumo_ordenacao.html
  55. 6
      sapl/templates/sessao/retiradapauta_form.html
  56. 2
      sapl/templates/sessao/subnav.yaml
  57. 1
      sapl/templates/sistema.html
  58. 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.132 image: interlegis/sapl:3.1.137
restart: always restart: always
environment: environment:
ADMIN_PASSWORD: interlegis ADMIN_PASSWORD: interlegis

35
sapl/base/migrations/0024_auto_20181126_1534.py

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-26 17:34
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0023_auto_20181105_1804'),
]
operations = [
migrations.AlterField(
model_name='appconfig',
name='cronometro_aparte',
field=models.DurationField(blank=True, null=True, verbose_name='Cronômetro do Aparte'),
),
migrations.AlterField(
model_name='appconfig',
name='cronometro_consideracoes',
field=models.DurationField(blank=True, null=True, verbose_name='Cronômetro de Considerações Finais'),
),
migrations.AlterField(
model_name='appconfig',
name='cronometro_discurso',
field=models.DurationField(blank=True, null=True, verbose_name='Cronômetro do Discurso'),
),
migrations.AlterField(
model_name='appconfig',
name='cronometro_ordem',
field=models.DurationField(blank=True, null=True, verbose_name='Cronômetro da Ordem'),
),
]

21
sapl/base/migrations/0025_auto_20181126_1648.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-26 18:48
from __future__ import unicode_literals
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0024_auto_20181126_1534'),
]
operations = [
migrations.AlterField(
model_name='appconfig',
name='cronometro_discurso',
field=models.DurationField(blank=True, default=datetime.timedelta(0, 2400), null=True, verbose_name='Cronômetro do Discurso'),
),
]

20
sapl/base/migrations/0026_auto_20181126_1727.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-26 19:27
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0025_auto_20181126_1648'),
]
operations = [
migrations.AlterField(
model_name='appconfig',
name='cronometro_discurso',
field=models.DurationField(blank=True, null=True, verbose_name='Cronômetro do Discurso'),
),
]

8
sapl/base/models.py

@ -129,22 +129,22 @@ class AppConfig(models.Model):
verbose_name=_('Quem deve assina a ata'), verbose_name=_('Quem deve assina a ata'),
max_length=1, choices=ASSINATURA_ATA_CHOICES, default='T') max_length=1, choices=ASSINATURA_ATA_CHOICES, default='T')
cronometro_discurso = models.TimeField( cronometro_discurso = models.DurationField(
verbose_name=_('Cronômetro do Discurso'), verbose_name=_('Cronômetro do Discurso'),
blank=True, blank=True,
null=True) null=True)
cronometro_aparte = models.TimeField( cronometro_aparte = models.DurationField(
verbose_name=_('Cronômetro do Aparte'), verbose_name=_('Cronômetro do Aparte'),
blank=True, blank=True,
null=True) null=True)
cronometro_ordem = models.TimeField( cronometro_ordem = models.DurationField(
verbose_name=_('Cronômetro da Ordem'), verbose_name=_('Cronômetro da Ordem'),
blank=True, blank=True,
null=True) null=True)
cronometro_consideracoes = models.TimeField( cronometro_consideracoes = models.DurationField(
verbose_name=_('Cronômetro de Considerações Finais'), verbose_name=_('Cronômetro de Considerações Finais'),
blank=True, blank=True,
null=True) null=True)

7
sapl/base/templatetags/common_tags.py

@ -228,11 +228,8 @@ def file_extension(value):
def cronometro_to_seconds(value): def cronometro_to_seconds(value):
if not AppConfig.attr('cronometro_' + value): if not AppConfig.attr('cronometro_' + value):
return 0 return 0
m, s, x = AppConfig.attr( return AppConfig.attr('cronometro_' + value).seconds
'cronometro_' + value).isoformat().split(':')
return 60 * int(m) + int(s)
@register.filter @register.filter

26
sapl/legacy/migracao_documentos.py

@ -1,6 +1,6 @@
import os import os
import shutil
import re import re
import shutil
from glob import glob from glob import glob
from os.path import join from os.path import join
@ -189,3 +189,27 @@ def migrar_documentos(repo):
print('\n#### Encerrado ####\n\n' print('\n#### Encerrado ####\n\n'
'{} documentos sobraram sem ser migrados!!!'.format( '{} documentos sobraram sem ser migrados!!!'.format(
len(sobrando))) len(sobrando)))
def corrigir_documentos_para_existentes(repo):
for model, campos_bases in DOCS.items():
if model == Parlamentar:
continue
for campo, base_origem in campos_bases:
print('#### Corrigindo {} de {} ####'.format(campo,
model.__name__))
upload_to = model._meta.get_field(campo).upload_to
for obj in model.objects.all():
if getattr(obj, campo):
continue
dir_upload_to = os.path.join(
repo.working_dir, upload_to(obj, ''))
achados = glob(dir_upload_to + '*')
if achados:
assert len(achados) == 1, 'Mais de um doc achado'
[achado] = achados
destino = upload_to(obj, os.path.basename(achado))
print('-- {}'.format(destino))
setattr(obj, campo, destino)
obj.save()

2
sapl/legacy/scripts/exporta_zope/exporta_zope.py

@ -93,7 +93,7 @@ def br(obj):
def guess_extension(fullname, buffer): def guess_extension(fullname, buffer):
# um corte de apenas 1024 impediu a detecção correta de .docx # um corte de apenas 1024 impediu a detecção correta de .docx
mime = magic.from_buffer(buffer[:4096], mime=True) mime = magic.from_buffer(buffer, mime=True)
extensao = EXTENSOES.get(mime) extensao = EXTENSOES.get(mime)
if extensao is not None: if extensao is not None:
return extensao return extensao

7
sapl/materia/views.py

@ -2179,6 +2179,10 @@ class EtiquetaPesquisaView(PermissionRequiredMixin, FormView):
if context['quantidade'] > 20: if context['quantidade'] > 20:
materias = materias[:20] materias = materias[:20]
for m in materias:
if len(m.ementa) > 100:
m.ementa = m.ementa[0:99] + "[...]"
context['materias'] = materias context['materias'] = materias
return gerar_pdf_impressos(self.request, context, return gerar_pdf_impressos(self.request, context,
@ -2267,7 +2271,8 @@ class FichaSelecionaView(PermissionRequiredMixin, FormView):
self.messages.add_message(self.request, messages.INFO, mensagem) self.messages.add_message(self.request, messages.INFO, mensagem)
return self.render_to_response(context) return self.render_to_response(context)
if len(materia.ementa) > 301:
materia.ementa = materia.ementa[0:300] + '[...]'
context['materia'] = materia context['materia'] = materia
context['despachos'] = materia.despachoinicial_set.all().values_list( context['despachos'] = materia.despachoinicial_set.all().values_list(
'comissao__nome', flat=True) 'comissao__nome', flat=True)

15
sapl/norma/fixtures/pre_popula_tipo_vinculo_norma.json

@ -1,6 +1,7 @@
[ [
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Altera o(a)", "descricao_ativa": "Altera o(a)",
"descricao_passiva": "Alterado(a) pelo(a)", "descricao_passiva": "Alterado(a) pelo(a)",
"sigla": "A" "sigla": "A"
@ -10,6 +11,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "True",
"descricao_ativa": "Revoga integralmente o(a)", "descricao_ativa": "Revoga integralmente o(a)",
"descricao_passiva": "Revogado(a) integralmente pelo(a)", "descricao_passiva": "Revogado(a) integralmente pelo(a)",
"sigla": "R" "sigla": "R"
@ -19,6 +21,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Revoga parcialmente o(a)", "descricao_ativa": "Revoga parcialmente o(a)",
"descricao_passiva": "Revogado(a) parcialmente pelo(a)", "descricao_passiva": "Revogado(a) parcialmente pelo(a)",
"sigla": "P" "sigla": "P"
@ -28,6 +31,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "True",
"descricao_ativa": "Revoga integralmente por consolida\u00e7\u00e3o", "descricao_ativa": "Revoga integralmente por consolida\u00e7\u00e3o",
"descricao_passiva": "Revogado(a) integralmente por consolida\u00e7\u00e3o", "descricao_passiva": "Revogado(a) integralmente por consolida\u00e7\u00e3o",
"sigla": "T" "sigla": "T"
@ -37,6 +41,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Norma correlata", "descricao_ativa": "Norma correlata",
"descricao_passiva": "Norma correlata", "descricao_passiva": "Norma correlata",
"sigla": "C" "sigla": "C"
@ -46,6 +51,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Ressalva o(a)", "descricao_ativa": "Ressalva o(a)",
"descricao_passiva": "Ressalvada pelo(a)", "descricao_passiva": "Ressalvada pelo(a)",
"sigla": "S" "sigla": "S"
@ -55,6 +61,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Reedita o(a)", "descricao_ativa": "Reedita o(a)",
"descricao_passiva": "Reeditada pelo(a)", "descricao_passiva": "Reeditada pelo(a)",
"sigla": "E" "sigla": "E"
@ -64,6 +71,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Reedita com altera\u00e7\u00e3o o(a)", "descricao_ativa": "Reedita com altera\u00e7\u00e3o o(a)",
"descricao_passiva": "Reeditada com altera\u00e7\u00e3o pelo(a)", "descricao_passiva": "Reeditada com altera\u00e7\u00e3o pelo(a)",
"sigla": "I" "sigla": "I"
@ -73,6 +81,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Regulamenta o(a)", "descricao_ativa": "Regulamenta o(a)",
"descricao_passiva": "Regulamentada pelo(a)", "descricao_passiva": "Regulamentada pelo(a)",
"sigla": "G" "sigla": "G"
@ -82,6 +91,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Suspende parcialmente o(a)", "descricao_ativa": "Suspende parcialmente o(a)",
"descricao_passiva": "Suspenso(a) parcialmente pelo(a)", "descricao_passiva": "Suspenso(a) parcialmente pelo(a)",
"sigla": "K" "sigla": "K"
@ -91,6 +101,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Suspende integralmente o(a)", "descricao_ativa": "Suspende integralmente o(a)",
"descricao_passiva": "Suspenso(a) integralmente pelo(a)", "descricao_passiva": "Suspenso(a) integralmente pelo(a)",
"sigla": "L" "sigla": "L"
@ -100,6 +111,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Julga integralmente inconstitucional", "descricao_ativa": "Julga integralmente inconstitucional",
"descricao_passiva": "Julgada integralmente inconstitucional", "descricao_passiva": "Julgada integralmente inconstitucional",
"sigla": "N" "sigla": "N"
@ -109,6 +121,7 @@
}, },
{ {
"fields": { "fields": {
"revoga_integralmente": "False",
"descricao_ativa": "Julga parcialmente inconstitucional", "descricao_ativa": "Julga parcialmente inconstitucional",
"descricao_passiva": "Julgada parcialmente inconstitucional", "descricao_passiva": "Julgada parcialmente inconstitucional",
"sigla": "O" "sigla": "O"
@ -116,4 +129,4 @@
"model": "norma.TipoVinculoNormaJuridica", "model": "norma.TipoVinculoNormaJuridica",
"pk": "13" "pk": "13"
} }
] ]

10
sapl/norma/forms.py

@ -64,7 +64,7 @@ class NormaFilterSet(django_filters.FilterSet):
class Meta: class Meta:
model = NormaJuridica model = NormaJuridica
fields = ['tipo', 'numero', 'ano', 'data', fields = ['tipo', 'numero', 'ano', 'data', 'data_vigencia',
'data_publicacao', 'ementa', 'assuntos'] 'data_publicacao', 'ementa', 'assuntos']
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -73,13 +73,14 @@ class NormaFilterSet(django_filters.FilterSet):
row1 = to_row([('tipo', 4), ('numero', 4), ('ano', 4)]) row1 = to_row([('tipo', 4), ('numero', 4), ('ano', 4)])
row2 = to_row([('data', 6), ('data_publicacao', 6)]) row2 = to_row([('data', 6), ('data_publicacao', 6)])
row3 = to_row([('ementa', 6), ('assuntos', 6)]) row3 = to_row([('ementa', 6), ('assuntos', 6)])
row4 = to_row([('o',6), ('indexacao', 6)]) row4 = to_row([('data_vigencia', 12)])
row5 = to_row([('o',6), ('indexacao', 6)])
self.form.helper = FormHelper() self.form.helper = FormHelper()
self.form.helper.form_method = 'GET' self.form.helper.form_method = 'GET'
self.form.helper.layout = Layout( self.form.helper.layout = Layout(
Fieldset(_('Pesquisa de Norma'), Fieldset(_('Pesquisa de Norma'),
row1, row2, row3, row4, row1, row2, row3, row4, row5,
form_actions(label='Pesquisar')) form_actions(label='Pesquisar'))
) )
@ -120,6 +121,7 @@ class NormaJuridicaForm(ModelForm):
'numero_materia', 'numero_materia',
'ano_materia', 'ano_materia',
'data_publicacao', 'data_publicacao',
'data_vigencia',
'veiculo_publicacao', 'veiculo_publicacao',
'pagina_inicio_publicacao', 'pagina_inicio_publicacao',
'pagina_fim_publicacao', 'pagina_fim_publicacao',
@ -342,6 +344,8 @@ class NormaRelacionadaForm(ModelForm):
def save(self, commit=False): def save(self, commit=False):
relacionada = super(NormaRelacionadaForm, self).save(commit) relacionada = super(NormaRelacionadaForm, self).save(commit)
relacionada.norma_relacionada = self.cleaned_data['norma_relacionada'] relacionada.norma_relacionada = self.cleaned_data['norma_relacionada']
relacionada.norma_relacionada.data_vigencia = relacionada.norma_principal.data
relacionada.norma_relacionada.save()
relacionada.save() relacionada.save()
return relacionada return relacionada

2
sapl/norma/migrations/0009_auto_20171113_1339.py

@ -9,7 +9,7 @@ import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('norma', '0008_normajuridica_popula_tipo_vinculo_norma'), ('norma', '0007_auto_20170904_1708'),
] ]
operations = [ operations = [

20
sapl/norma/migrations/0015_auto_20181109_1422.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-09 16:22
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('norma', '0014_auto_20181008_1655'),
]
operations = [
migrations.AlterField(
model_name='normajuridica',
name='data_vigencia',
field=models.DateField(blank=True, null=True, verbose_name='Data Fim Vigência'),
),
]

26
sapl/norma/migrations/0008_normajuridica_popula_tipo_vinculo_norma.py → sapl/norma/migrations/0016_tipovinculonormajuridica_revoga_integramente.py

@ -1,14 +1,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-23 14:51
from __future__ import unicode_literals from __future__ import unicode_literals
import os import os
from django.core.management import call_command from django.core.management import call_command
from django.db import migrations from django.db import migrations, models
def gera_tipo_vinculo(apps, schema_editor): def gera_tipo_vinculo(apps, schema_editor):
TipoVinculoNormaJuridica = apps.get_model("norma", "TipoVinculoNormaJuridica") TipoVinculoNormaJuridica = apps.get_model(
"norma", "TipoVinculoNormaJuridica")
db_alias = schema_editor.connection.alias db_alias = schema_editor.connection.alias
tipo_vinculos = TipoVinculoNormaJuridica.objects.all().exists() tipo_vinculos = TipoVinculoNormaJuridica.objects.all().exists()
@ -19,21 +21,31 @@ def gera_tipo_vinculo(apps, schema_editor):
print("Carga de {} não efetuada. Já Existem {} cadastrados...".format( print("Carga de {} não efetuada. Já Existem {} cadastrados...".format(
TipoVinculoNormaJuridica._meta.verbose_name, TipoVinculoNormaJuridica._meta.verbose_name,
TipoVinculoNormaJuridica._meta.verbose_name_plural TipoVinculoNormaJuridica._meta.verbose_name_plural
) )
) )
else: else:
fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures')) fixture_dir = os.path.abspath(os.path.join(
# pega tipo_vinculo_norma_juridica listados em fixtures/pre_popula_tipo_vinculo_norma.json os.path.dirname(__file__), '../fixtures'))
# pega tipo_vinculo_norma_juridica listados em
# fixtures/pre_popula_tipo_vinculo_norma.json
fixture_filename = 'pre_popula_tipo_vinculo_norma.json' fixture_filename = 'pre_popula_tipo_vinculo_norma.json'
fixture_file = os.path.join(fixture_dir, fixture_filename) fixture_file = os.path.join(fixture_dir, fixture_filename)
call_command('loaddata', fixture_file) call_command('loaddata', fixture_file)
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('norma', '0007_auto_20170904_1708'), ('norma', '0015_auto_20181109_1422'),
] ]
operations = [ operations = [
migrations.AddField(
model_name='tipovinculonormajuridica',
name='revoga_integralmente',
field=models.BooleanField(choices=[(
True, 'Sim'), (False, 'Não')], default=False, verbose_name='Revoga Integralmente?'),
),
migrations.RunPython(gera_tipo_vinculo), migrations.RunPython(gera_tipo_vinculo),
] ]

5
sapl/norma/models.py

@ -119,7 +119,7 @@ class NormaJuridica(models.Model):
assuntos = models.ManyToManyField( assuntos = models.ManyToManyField(
AssuntoNorma, blank=True, AssuntoNorma, blank=True,
verbose_name=_('Assuntos')) verbose_name=_('Assuntos'))
data_vigencia = models.DateField(blank=True, null=True) data_vigencia = models.DateField(blank=True, null=True, verbose_name=_('Data Fim Vigência'))
timestamp = models.DateTimeField(null=True) timestamp = models.DateTimeField(null=True)
texto_articulado = GenericRelation( texto_articulado = GenericRelation(
@ -258,6 +258,9 @@ class TipoVinculoNormaJuridica(models.Model):
max_length=50, blank=True, verbose_name=_('Descrição Ativa')) max_length=50, blank=True, verbose_name=_('Descrição Ativa'))
descricao_passiva = models.CharField( descricao_passiva = models.CharField(
max_length=50, blank=True, verbose_name=_('Descrição Passiva')) max_length=50, blank=True, verbose_name=_('Descrição Passiva'))
revoga_integralmente = models.BooleanField(verbose_name=_('Revoga Integralmente?'),
choices=YES_NO_CHOICES,
default=False)
class Meta: class Meta:
verbose_name = _('Tipo de Vínculo entre Normas Jurídicas') verbose_name = _('Tipo de Vínculo entre Normas Jurídicas')

19
sapl/norma/views.py

@ -37,7 +37,7 @@ TipoNormaCrud = CrudAux.build(
list_field_names=['sigla', 'descricao', 'equivalente_lexml']) list_field_names=['sigla', 'descricao', 'equivalente_lexml'])
TipoVinculoNormaJuridicaCrud = CrudAux.build( TipoVinculoNormaJuridicaCrud = CrudAux.build(
TipoVinculoNormaJuridica, '', TipoVinculoNormaJuridica, '',
list_field_names=['sigla', 'descricao_ativa', 'descricao_passiva']) list_field_names=['sigla', 'descricao_ativa', 'descricao_passiva', 'revoga_integralmente'])
class NormaRelacionadaCrud(MasterDetailCrud): class NormaRelacionadaCrud(MasterDetailCrud):
@ -208,7 +208,7 @@ class NormaCrud(Crud):
def get_initial(self): def get_initial(self):
username = self.request.user.username username = self.request.user.username
try: try:
self.logger.debug('user=' + username + '. Tentando obter objeto de modelo da esfera da federação.') self.logger.debug('user=' + username + '. Tentando obter objeto de modelo da esfera da federação.')
esfera = sapl.base.models.AppConfig.objects.last( esfera = sapl.base.models.AppConfig.objects.last(
@ -274,16 +274,19 @@ def recuperar_norma(request):
def recuperar_numero_norma(request): def recuperar_numero_norma(request):
tipo = TipoNormaJuridica.objects.get(pk=request.GET['tipo']) tipo = TipoNormaJuridica.objects.get(pk=request.GET['tipo'])
ano = request.GET.get('ano', '') ano = request.GET.get('ano', '')
param = {'tipo': tipo} param = {'tipo': tipo,
param['ano'] = ano if ano else timezone.now().year 'ano': ano if ano else timezone.now().year
}
norma = NormaJuridica.objects.filter(**param).order_by( norma = NormaJuridica.objects.filter(**param).order_by(
'tipo', 'ano', 'numero').values_list('numero', 'ano').last() 'tipo', 'ano', 'numero').values_list('numero', flat=True)
if norma: if norma:
response = JsonResponse({'numero': int(re.sub("[^0-9].*", '', norma[0])) + 1, numeros = sorted([int(re.sub("[^0-9].*", '', n)) for n in norma])
'ano': norma[1]}) next_num = numeros.pop() + 1
response = JsonResponse({'numero': next_num,
'ano': param['ano']})
else: else:
response = JsonResponse( response = JsonResponse(
{'numero': 1, 'ano': ano}) {'numero': 1, 'ano': param['ano']})
return response return response

1
sapl/painel/views.py

@ -340,7 +340,6 @@ def cronometro_painel(request):
def get_cronometro_status(request, name): def get_cronometro_status(request, name):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
username = request.user.username username = request.user.username
try: try:
logger.debug("user=" + username + ". Tentando obter cronometro.") logger.debug("user=" + username + ". Tentando obter cronometro.")
cronometro = request.session[name] cronometro = request.session[name]

2
sapl/parlamentares/forms.py

@ -136,7 +136,7 @@ class MandatoForm(ModelForm):
existe_mandato = Mandato.objects.filter( existe_mandato = Mandato.objects.filter(
parlamentar=data['parlamentar'], parlamentar=data['parlamentar'],
legislatura=data['legislatura']).exists() legislatura=data['legislatura']).exists()
if existe_mandato: if existe_mandato and data['titular']:
self.logger.error("Mandato nesta legislatura (parlamentar={}, legislatura={}) já existe." self.logger.error("Mandato nesta legislatura (parlamentar={}, legislatura={}) já existe."
.format(data['parlamentar'], data['legislatura'])) .format(data['parlamentar'], data['legislatura']))
raise ValidationError(_('Mandato nesta legislatura já existe.')) raise ValidationError(_('Mandato nesta legislatura já existe.'))

1
sapl/parlamentares/tests/test_parlamentares.py

@ -178,6 +178,7 @@ def test_mandato_form_duplicado():
'legislatura': str(legislatura.pk), 'legislatura': str(legislatura.pk),
'data_expedicao_diploma': '01/07/2015', 'data_expedicao_diploma': '01/07/2015',
'data_inicio_mandato': legislatura.data_inicio, 'data_inicio_mandato': legislatura.data_inicio,
'titular':True,
}) })
assert not form.is_valid() assert not form.is_valid()

2
sapl/parlamentares/views.py

@ -498,7 +498,7 @@ class ParlamentarCrud(Crud):
if legislatura_id >= 0: if legislatura_id >= 0:
return queryset.filter( return queryset.filter(
mandato__legislatura_id=legislatura_id).annotate( mandato__legislatura_id=legislatura_id).annotate(
mandato_titular=F('mandato__titular')) mandato_titular=F('mandato__titular')).distinct()
else: else:
try: try:
self.logger.debug("user=" + username + ". Tentando obter o mais recente registro do objeto Legislatura.") self.logger.debug("user=" + username + ". Tentando obter o mais recente registro do objeto Legislatura.")

12
sapl/relatorios/templates/pdf_pauta_sessao_gerar.py

@ -124,10 +124,10 @@ def expediente_materia(lst_expediente_materia):
for expediente_materia in lst_expediente_materia: for expediente_materia in lst_expediente_materia:
tmp += '<tr><td><para style="P3"><b>' + str(expediente_materia['num_ordem']) + '</b> - ' + \ tmp += '<tr><td><para style="P3"><b>' + str(expediente_materia['num_ordem']) + '</b> - ' + \
expediente_materia["tipo_materia"] + ' No. ' + \ expediente_materia["tipo_materia"] + ' No. ' + \
expediente_materia['id_materia'] + '</para>\n' + '<para style="P3"><b>Autor: </b>' + \ expediente_materia['id_materia'] + '</para>\n' + '<para style="P3"><b>' + expediente_materia['num_autores'] + ': </b>' + \
expediente_materia['nom_autor'] + '</para></td>\n' expediente_materia['nom_autor'] + '</para></td>\n'
txt_ementa = expediente_materia['txt_ementa'].replace('&', '&amp;') txt_ementa = expediente_materia['txt_ementa'].replace('&', '&amp;')
tmp += '<td><para style="P4">' + txt_ementa + '</para></td>\n' tmp += '<td><para style="P4">' + txt_ementa + '</para>' + '<para style="P4">' + expediente_materia['ordem_observacao'] + '</para></td>\n'
tmp += '<td><para style="P3">' + \ tmp += '<td><para style="P3">' + \
str(expediente_materia['des_situacao']) + '</para></td></tr>\n' str(expediente_materia['des_situacao']) + '</para></td></tr>\n'
@ -151,10 +151,10 @@ def votacao(lst_votacao):
votacao["tipo_materia"] + ' No. ' + \ votacao["tipo_materia"] + ' No. ' + \
str(votacao['id_materia']) + '</para>\n' + '<para style="P3"><b>Processo: </b>' + \ str(votacao['id_materia']) + '</para>\n' + '<para style="P3"><b>Processo: </b>' + \
str(votacao['des_numeracao']) + '</para>\n' + '<para style="P3"><b>Turno: </b>' + \ str(votacao['des_numeracao']) + '</para>\n' + '<para style="P3"><b>Turno: </b>' + \
str(votacao['des_turno']) + '</para>\n' + '<para style="P3"><b>Autor: </b>' + \ str(votacao['des_turno']) + '</para>\n' + '<para style="P3"><b>'+votacao['num_autores']+': </b>' + \
str(votacao['nom_autor']) + '</para></td>\n' str(votacao['nom_autor']) + '</para></td>\n'
tmp += '<td><para style="P4">' + \ txt_ementa = votacao['txt_ementa'].replace('&', '&amp;')
str(votacao['txt_ementa']) + '</para></td>\n' tmp += '<td><para style="P4">' + txt_ementa + '</para>' + '<para style="P4">' + votacao['ordem_observacao'] + '</para></td>\n'
tmp += '<td><para style="P3">' + \ tmp += '<td><para style="P3">' + \
str(votacao['des_situacao']) + '</para></td></tr>\n' str(votacao['des_situacao']) + '</para></td></tr>\n'
@ -162,7 +162,7 @@ def votacao(lst_votacao):
return tmp return tmp
def principal(cabecalho_dic, rodape_dic, sessao, imagem, inf_basicas_dic, lst_expediente_materia, lst_votacao): def principal(rodape_dic, imagem, inf_basicas_dic, lst_expediente_materia, lst_votacao):
""" """
""" """

1
sapl/relatorios/templates/pdf_pauta_sessao_preparar_pysc.py

@ -121,6 +121,7 @@ if context.REQUEST['data'] != '':
autoria = autoria[0] autoria = autoria[0]
autor = context.zsql.autor_obter_zsql( autor = context.zsql.autor_obter_zsql(
cod_autor=autoria.cod_autor) cod_autor=autoria.cod_autor)
if len(autor) > 0: if len(autor) > 0:
autor = autor[0] autor = autor[0]

38
sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py

@ -120,8 +120,6 @@ def inf_basicas(inf_basicas_dic):
tmp += '\t\t<para style="P2" spaceAfter="5"><b>Abertura: </b> ' + \ tmp += '\t\t<para style="P2" spaceAfter="5"><b>Abertura: </b> ' + \
dat_inicio_sessao + ' <b>- </b> ' + hr_inicio_sessao + '</para>\n' dat_inicio_sessao + ' <b>- </b> ' + hr_inicio_sessao + '</para>\n'
data_fim_sessao = dat_fim_sessao + ' <b>- </b> ' if dat_fim_sessao else ''
tmp += '\t\t<para style="P2" spaceAfter="5"><b>Encerramento: </b> ' + \ tmp += '\t\t<para style="P2" spaceAfter="5"><b>Encerramento: </b> ' + \
dat_fim_sessao + ' <b>- </b> ' + hr_fim_sessao + '</para>\n' dat_fim_sessao + ' <b>- </b> ' + hr_fim_sessao + '</para>\n'
@ -144,7 +142,7 @@ def mesa(lst_mesa):
return tmp return tmp
def presenca(lst_presenca_sessao): def presenca(lst_presenca_sessao,lst_ausencia_sessao):
""" """
""" """
@ -157,6 +155,19 @@ def presenca(lst_presenca_sessao):
tmp += '\t\t<para style="P2" spaceAfter="5">' + \ tmp += '\t\t<para style="P2" spaceAfter="5">' + \
str(presenca['nom_parlamentar']) + '/' + \ str(presenca['nom_parlamentar']) + '/' + \
str(presenca['sgl_partido']) + '</para>\n' str(presenca['sgl_partido']) + '</para>\n'
tmp += '\t\t<para style="P1">Justificativas de Ausência da Sessão</para>\n'
tmp += '\t\t<para style="P2">\n'
tmp += '\t\t\t<font color="white"> <br/></font>\n'
tmp += '\t\t</para>\n'
tmp += '<blockTable style="repeater" repeatRows="1">\n'
tmp += '<tr><td >Parlamentar</td><td>Justificativa</td><td>Ausente em</td></tr>\n'
for ausencia in lst_ausencia_sessao:
tmp += '<tr><td>' + \
str(ausencia['parlamentar']) + '</td><td> ' + \
str(ausencia['justificativa']) + '</td><td>' + \
str(ausencia['tipo']) + '</td></tr>\n'
tmp += '</blockTable>'
return tmp return tmp
@ -169,7 +180,7 @@ def expedientes(lst_expedientes):
tmp += '\t\t<para style="P2">\n' tmp += '\t\t<para style="P2">\n'
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 idx, expediente in enumerate(lst_expedientes): for expediente in lst_expedientes:
tmp += '\t\t<para style="P2"><b>' + '<br/> ' + \ tmp += '\t\t<para style="P2"><b>' + '<br/> ' + \
expediente['nom_expediente'] + ': </b></para>\n' + \ expediente['nom_expediente'] + ': </b></para>\n' + \
'<para style="P3">' + \ '<para style="P3">' + \
@ -191,10 +202,10 @@ def expediente_materia(lst_expediente_materia):
tmp += '<blockTable style="repeater" repeatRows="1">\n' tmp += '<blockTable style="repeater" repeatRows="1">\n'
tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n' tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n'
for expediente_materia in lst_expediente_materia: for expediente_materia in lst_expediente_materia:
tmp += '<tr><td><para style="P3"><b>' + str(expediente_materia['num_ordem']) + '</b> - ' + expediente_materia['id_materia'] + '</para>\n' + '<para style="P3"><b>Turno: </b>' + str(expediente_materia[ tmp += '<tr><td><para style="P3"><b>' + str(expediente_materia['num_ordem']) + '</b> - ' + expediente_materia['id_materia'] + '</para>\n' + '<para style="P3"><b>Turno: </b>' + expediente_materia[
'des_turno']) + '</para>\n' + '<para style="P3"><b>Autor: </b>' + str(expediente_materia['nom_autor']) + '</para></td>\n' 'des_turno'] + '</para>\n' + '<para style="P3"><b>'+ expediente_materia['num_autores'] + ': </b>' + str(expediente_materia['nom_autor']) + '</para></td>\n'
txt_ementa = expediente_materia['txt_ementa'].replace('&', '&amp;') txt_ementa = expediente_materia['txt_ementa'].replace('&', '&amp;')
tmp += '<td><para style="P4">' + txt_ementa + '</para></td>\n' tmp += '<td><para style="P4">' + txt_ementa + '</para>' + '<para style="P4">' + expediente_materia['ordem_observacao'] + '</para></td>\n'
tmp += '<td><para style="P3"><b>' + \ tmp += '<td><para style="P3"><b>' + \
str(expediente_materia['nom_resultado']) + \ str(expediente_materia['nom_resultado']) + \
'</b></para>\n' + '<para style="P3">' '</b></para>\n' + '<para style="P3">'
@ -254,8 +265,8 @@ def votacao(lst_votacao):
tmp += '<blockTable style="repeater" repeatRows="1">\n' tmp += '<blockTable style="repeater" repeatRows="1">\n'
tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n' tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n'
for votacao in lst_votacao: for votacao in lst_votacao:
tmp += '<tr><td><para style="P3"><b>' + str(votacao['num_ordem']) + '</b> - ' + votacao['id_materia'] + '</para>\n' + '<para style="P3"><b>Turno:</b> ' + str(votacao[ tmp += '<tr><td><para style="P3"><b>' + str(votacao['num_ordem']) + '</b> - ' + votacao['id_materia'] + '</para>\n' + '<para style="P3"><b>Turno:</b> ' + votacao[
'des_turno']) + '</para>\n' + '<para style="P3"><b>Autor: </b>' + str(votacao['nom_autor']) + '</para></td>\n' 'des_turno'] + '</para>\n' + '<para style="P3"><b>'+ votacao['num_autores'] +': </b>' + str(votacao['nom_autor']) + '</para></td>\n'
txt_ementa = votacao['txt_ementa'].replace('&', '&amp;') txt_ementa = votacao['txt_ementa'].replace('&', '&amp;')
tmp += '<td><para style="P4">' + txt_ementa + '</para>' + '<para style="P4">' + votacao['ordem_observacao'] + '</para></td>\n' tmp += '<td><para style="P4">' + txt_ementa + '</para>' + '<para style="P4">' + votacao['ordem_observacao'] + '</para></td>\n'
tmp += '<td><para style="P3"><b>' + \ tmp += '<td><para style="P3"><b>' + \
@ -296,7 +307,7 @@ def ocorrencias(lst_ocorrencias):
tmp += '\t\t<para style="P2">\n' tmp += '\t\t<para style="P2">\n'
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 idx, ocorrencia in enumerate(lst_ocorrencias): for ocorrencia in lst_ocorrencias:
tmp += '\t\t<para style="P3">' + \ tmp += '\t\t<para style="P3">' + \
str(ocorrencia.conteudo) + '</para>\n' str(ocorrencia.conteudo) + '</para>\n'
tmp += '\t\t<para style="P2">\n' tmp += '\t\t<para style="P2">\n'
@ -305,7 +316,7 @@ def ocorrencias(lst_ocorrencias):
return tmp return tmp
def principal(cabecalho_dic, rodape_dic, imagem, sessao, inf_basicas_dic, lst_mesa, lst_presenca_sessao, lst_expedientes, lst_expediente_materia, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_oradores, lst_ocorrencias): def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, lst_expedientes, lst_expediente_materia, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_oradores, lst_ocorrencias):
""" """
""" """
arquivoPdf = str(int(time.time() * 100)) + ".pdf" arquivoPdf = str(int(time.time() * 100)) + ".pdf"
@ -331,7 +342,7 @@ def principal(cabecalho_dic, rodape_dic, imagem, sessao, inf_basicas_dic, lst_me
'cont_mult': '', 'cont_mult': '',
'exp': expedientes(lst_expedientes), 'exp': expedientes(lst_expedientes),
'id_basica': inf_basicas(inf_basicas_dic), 'id_basica': inf_basicas(inf_basicas_dic),
'lista_p': presenca(lst_presenca_sessao), 'lista_p': presenca(lst_presenca_sessao,lst_ausencia_sessao),
'lista_p_o_d': presenca_ordem_dia(lst_presenca_ordem_dia), 'lista_p_o_d': presenca_ordem_dia(lst_presenca_ordem_dia),
'mat_exp': expediente_materia(lst_expediente_materia), 'mat_exp': expediente_materia(lst_expediente_materia),
'mat_o_d': votacao(lst_votacao), 'mat_o_d': votacao(lst_votacao),
@ -352,11 +363,12 @@ def principal(cabecalho_dic, rodape_dic, imagem, sessao, inf_basicas_dic, lst_me
tmp += dict_ord_template[ordenacao.oitavo] tmp += dict_ord_template[ordenacao.oitavo]
tmp += dict_ord_template[ordenacao.nono] tmp += dict_ord_template[ordenacao.nono]
tmp += dict_ord_template[ordenacao.decimo] tmp += dict_ord_template[ordenacao.decimo]
tmp += dict_ord_template[ordenacao.decimo_primeiro]
else: else:
tmp += inf_basicas(inf_basicas_dic) tmp += inf_basicas(inf_basicas_dic)
tmp += mesa(lst_mesa) tmp += mesa(lst_mesa)
tmp += presenca(lst_presenca_sessao) tmp += presenca(lst_presenca_sessao,lst_ausencia_sessao)
tmp += expedientes(lst_expedientes) tmp += expedientes(lst_expedientes)
tmp += expediente_materia(lst_expediente_materia) tmp += expediente_materia(lst_expediente_materia)
tmp += oradores_expediente(lst_oradores_expediente) tmp += oradores_expediente(lst_oradores_expediente)

230
sapl/relatorios/views.py

@ -16,11 +16,12 @@ from sapl.parlamentares.models import CargoMesa, Filiacao, Parlamentar
from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo,
TramitacaoAdministrativo) TramitacaoAdministrativo)
from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao, from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao,
IntegranteMesa, Orador, OradorExpediente, IntegranteMesa, JustificativaAusencia,
Orador, OradorExpediente,
OrdemDia, PresencaOrdemDia, SessaoPlenaria, OrdemDia, PresencaOrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, OcorrenciaSessao) SessaoPlenariaPresenca, OcorrenciaSessao)
from sapl.settings import STATIC_ROOT from sapl.settings import STATIC_ROOT
from sapl.utils import LISTA_DE_UFS, ExtraiTag, TrocaTag, filiacao_data from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data
from .templates import (pdf_capa_processo_gerar, from .templates import (pdf_capa_processo_gerar,
pdf_documento_administrativo_gerar, pdf_espelho_gerar, pdf_documento_administrativo_gerar, pdf_espelho_gerar,
@ -466,6 +467,29 @@ def get_espelho(mats):
return materias return materias
def remove_html_comments(text):
"""
Assume comentários bem formados <!-- texto --> e
não aninhados como <!-- <!-- texto --> -->
:param text:
:return:
"""
clean_text = text
start = clean_text.find('<!--')
while start > -1:
end = clean_text.find('-->') + 2
output_text = []
for idx, i in enumerate(clean_text):
if not start <= idx <= end:
output_text.append(i)
clean_text = ''.join(output_text)
start = clean_text.find('<!--')
# por algum motivo usar clean_text ao invés de len(clean_text)
# não tava funcionando
return clean_text if len(clean_text) > 0 else text
def get_sessao_plenaria(sessao, casa): def get_sessao_plenaria(sessao, casa):
inf_basicas_dic = {} inf_basicas_dic = {}
@ -515,6 +539,20 @@ def get_sessao_plenaria(sessao, casa):
dic_presenca['sgl_partido'] = partido_sigla dic_presenca['sgl_partido'] = partido_sigla
lst_presenca_sessao.append(dic_presenca) lst_presenca_sessao.append(dic_presenca)
# Lista de ausencias na sessão
lst_ausencia_sessao = []
ausencia = JustificativaAusencia.objects.filter(
sessao_plenaria=sessao).order_by('parlamentar__nome_parlamentar')
for ausente in ausencia:
dic_ausencia = {}
dic_ausencia['parlamentar'] = ausente.parlamentar
dic_ausencia['justificativa'] = ausente.tipo_ausencia
if ausente.ausencia == 1:
dic_ausencia['tipo'] = 'Matéria'
else:
dic_ausencia['tipo'] = 'Sessão'
lst_ausencia_sessao.append(dic_ausencia)
# Exibe os Expedientes # Exibe os Expedientes
lst_expedientes = [] lst_expedientes = []
@ -535,6 +573,9 @@ def get_sessao_plenaria(sessao, casa):
# https://github.com/interlegis/sapl/issues/1009 # https://github.com/interlegis/sapl/issues/1009
conteudo = conteudo.replace('&', '&amp;') conteudo = conteudo.replace('&', '&amp;')
# https://github.com/interlegis/sapl/issues/2386
conteudo = remove_html_comments(conteudo)
dic_expedientes["txt_expediente"] = conteudo dic_expedientes["txt_expediente"] = conteudo
if dic_expedientes: if dic_expedientes:
@ -546,9 +587,7 @@ def get_sessao_plenaria(sessao, casa):
for expediente_materia in ExpedienteMateria.objects.filter( for expediente_materia in ExpedienteMateria.objects.filter(
sessao_plenaria=sessao): sessao_plenaria=sessao):
# seleciona os detalhes de uma matéria # seleciona os detalhes de uma matéria
materia = MateriaLegislativa.objects.filter( materia = expediente_materia.materia
id=expediente_materia.materia.id).first()
dic_expediente_materia = {} dic_expediente_materia = {}
dic_expediente_materia["num_ordem"] = expediente_materia.numero_ordem dic_expediente_materia["num_ordem"] = expediente_materia.numero_ordem
dic_expediente_materia["id_materia"] = (materia.tipo.sigla + ' ' + dic_expediente_materia["id_materia"] = (materia.tipo.sigla + ' ' +
@ -559,40 +598,27 @@ def get_sessao_plenaria(sessao, casa):
numeracao = Numeracao.objects.filter( numeracao = Numeracao.objects.filter(
materia=expediente_materia.materia).first() materia=expediente_materia.materia).first()
if numeracao is not None: if numeracao:
dic_expediente_materia["des_numeracao"] = ( dic_expediente_materia["des_numeracao"] = (
str(numeracao.numero_materia) + '/' + str( str(numeracao.numero_materia) + '/' + str(
numeracao.ano_materia)) numeracao.ano_materia))
turno, _ = get_turno(dic_expediente_materia, materia, sessao.data_inicio) turno, _ = get_turno(materia)
dic_expediente_materia["des_turno"] = turno dic_expediente_materia["des_turno"] = turno
dic_expediente_materia["txt_ementa"] = str(materia.ementa) dic_expediente_materia["txt_ementa"] = str(materia.ementa)
dic_expediente_materia["ordem_observacao"] = expediente_materia.observacao dic_expediente_materia["ordem_observacao"] = expediente_materia.observacao
dic_expediente_materia["nom_autor"] = ' '
dic_expediente_materia["nom_resultado"] = '' dic_expediente_materia["nom_resultado"] = ''
autoria = Autoria.objects.filter( dic_expediente_materia["nom_autor"] = ''
materia=materia, primeiro_autor=True).first() autoria = materia.autoria_set.all()
dic_expediente_materia['num_autores'] = 'Autores' if len(autoria) > 1 else 'Autor'
if autoria is not None: if autoria:
autor = Autor.objects.filter(id=autoria.autor.id) for a in autoria:
if a.autor.nome:
if autor is not None: dic_expediente_materia['nom_autor'] += a.autor.nome + ', '
autor = autor.first() dic_expediente_materia['nom_autor'] = dic_expediente_materia['nom_autor'][:-2]
else:
if autor.tipo == 'Parlamentar':
parlamentar = Parlamentar.objects.filter(
id=autor.parlamentar.id)
dic_expediente_materia["nom_autor"] = str(
parlamentar.nome_completo)
elif autor.tipo == 'Comissao':
comissao = Comissao.objects.filter(id=autor.comissao.id)
dic_expediente_materia["nom_autor"] = str(comissao)
else:
dic_expediente_materia["nom_autor"] = str(autor.nome)
elif autoria is None:
dic_expediente_materia["nom_autor"] = 'Desconhecido' dic_expediente_materia["nom_autor"] = 'Desconhecido'
dic_expediente_materia["votacao_observacao"] = ' ' dic_expediente_materia["votacao_observacao"] = ' '
@ -648,9 +674,7 @@ def get_sessao_plenaria(sessao, casa):
for votacao in OrdemDia.objects.filter( for votacao in OrdemDia.objects.filter(
sessao_plenaria=sessao): sessao_plenaria=sessao):
# seleciona os detalhes de uma matéria # seleciona os detalhes de uma matéria
materia = MateriaLegislativa.objects.filter( materia = votacao.materia
id=votacao.materia.id).first()
dic_votacao = {} dic_votacao = {}
dic_votacao["nom_resultado"] = '' dic_votacao["nom_resultado"] = ''
dic_votacao["num_ordem"] = votacao.numero_ordem dic_votacao["num_ordem"] = votacao.numero_ordem
@ -661,15 +685,15 @@ def get_sessao_plenaria(sessao, casa):
str(materia.ano)) str(materia.ano))
dic_votacao["des_numeracao"] = ' ' dic_votacao["des_numeracao"] = ' '
numeracao = Numeracao.objects.filter( numeracao = materia.numeracao_set.first()
materia=votacao.materia).first() if numeracao:
if numeracao is not None:
dic_votacao["des_numeracao"] = ( dic_votacao["des_numeracao"] = (
str(numeracao.numero_materia) + str(numeracao.numero_materia) +
'/' + '/' +
str(numeracao.ano_materia)) str(numeracao.ano_materia))
turno, _ = get_turno(dic_votacao, materia, sessao.data_inicio) turno, _ = get_turno(materia)
dic_votacao["des_turno"] = turno dic_votacao["des_turno"] = turno
@ -677,26 +701,15 @@ def get_sessao_plenaria(sessao, casa):
dic_votacao["txt_ementa"] = html.unescape(materia.ementa) dic_votacao["txt_ementa"] = html.unescape(materia.ementa)
dic_votacao["ordem_observacao"] = html.unescape(votacao.observacao) dic_votacao["ordem_observacao"] = html.unescape(votacao.observacao)
dic_votacao["nom_autor"] = ' ' dic_votacao["nom_autor"] = ''
autoria = Autoria.objects.filter( autoria = materia.autoria_set.all()
materia=materia, primeiro_autor=True).first() dic_votacao['num_autores'] = 'Autores' if len(autoria) > 1 else 'Autor'
if autoria:
if autoria is not None: for a in autoria:
autor = Autor.objects.filter(id=autoria.autor.id) if a.autor.nome:
if autor is not None: dic_votacao['nom_autor'] += a.autor.nome + ', '
autor = autor.first() dic_votacao['nom_autor'] = dic_votacao['nom_autor'][:-2]
else:
if autor.tipo == 'Parlamentar':
parlamentar = Parlamentar.objects.filter(
id=autor.parlamentar.id)
dic_votacao["nom_autor"] = str(parlamentar.nome_completo)
elif autor.tipo == 'Comissao':
comissao = Comissao.objects.filter(
id=autor.comissao.id)
dic_votacao["nom_autor"] = str(comissao)
else:
dic_votacao["nom_autor"] = str(autor.nome)
elif autoria is None:
dic_votacao["nom_autor"] = 'Desconhecido' dic_votacao["nom_autor"] = 'Desconhecido'
dic_votacao["votacao_observacao"] = ' ' dic_votacao["votacao_observacao"] = ' '
@ -704,11 +717,10 @@ def get_sessao_plenaria(sessao, casa):
if resultados: if resultados:
for i in resultados: for i in resultados:
dic_votacao["nom_resultado"] = i.tipo_resultado_votacao.nome dic_votacao["nom_resultado"] = i.tipo_resultado_votacao.nome
if votacao.observacao: if i.observacao:
dic_votacao["votacao_observacao"] = i.observacao dic_votacao["votacao_observacao"] = i.observacao
else: else:
dic_votacao["nom_resultado"] = "Matéria não votada" dic_votacao["nom_resultado"] = "Matéria não votada"
dic_votacao["votacao_observacao"] = " "
lst_votacao.append(dic_votacao) lst_votacao.append(dic_votacao)
# Lista dos oradores nas Explicações Pessoais # Lista dos oradores nas Explicações Pessoais
@ -754,6 +766,7 @@ def get_sessao_plenaria(sessao, casa):
return (inf_basicas_dic, return (inf_basicas_dic,
lst_mesa, lst_mesa,
lst_presenca_sessao, lst_presenca_sessao,
lst_ausencia_sessao,
lst_expedientes, lst_expedientes,
lst_expediente_materia, lst_expediente_materia,
lst_oradores_expediente, lst_oradores_expediente,
@ -763,20 +776,19 @@ def get_sessao_plenaria(sessao, casa):
lst_ocorrencias) lst_ocorrencias)
def get_turno(dic, materia, sessao_data_inicio): def get_turno(materia):
descricao_turno = ' ' descricao_turno = ''
descricao_tramitacao = ' ' descricao_tramitacao = ''
tramitacao = None tramitacao = materia.tramitacao_set.last()
if tramitacao is None:
tramitacao = materia.tramitacao_set.last()
if tramitacao is not None: if tramitacao:
for t in Tramitacao.TURNO_CHOICES: if tramitacao.turno:
if t[0] == tramitacao.turno: for t in Tramitacao.TURNO_CHOICES:
descricao_turno = t[1] if t[0] == tramitacao.turno:
break descricao_turno = str(t[1])
break
descricao_tramitacao = tramitacao.status.descricao if tramitacao.status else 'Não informada' descricao_tramitacao = tramitacao.status.descricao if tramitacao.status else 'Não informada'
return (descricao_turno, descricao_tramitacao) return descricao_turno, descricao_tramitacao
def relatorio_sessao_plenaria(request, pk): def relatorio_sessao_plenaria(request, pk):
@ -794,7 +806,6 @@ def relatorio_sessao_plenaria(request, pk):
if not casa: if not casa:
raise Http404 raise Http404
cabecalho = get_cabecalho(casa)
rodape = get_rodape(casa) rodape = get_rodape(casa)
imagem = get_imagem(casa) imagem = get_imagem(casa)
@ -808,6 +819,7 @@ def relatorio_sessao_plenaria(request, pk):
(inf_basicas_dic, (inf_basicas_dic,
lst_mesa, lst_mesa,
lst_presenca_sessao, lst_presenca_sessao,
lst_ausencia_sessao,
lst_expedientes, lst_expedientes,
lst_expediente_materia, lst_expediente_materia,
lst_oradores_expediente, lst_oradores_expediente,
@ -824,13 +836,12 @@ def relatorio_sessao_plenaria(request, pk):
lst_expedientes[idx]['txt_expediente'] = txt_expedientes lst_expedientes[idx]['txt_expediente'] = txt_expedientes
pdf = pdf_sessao_plenaria_gerar.principal( pdf = pdf_sessao_plenaria_gerar.principal(
cabecalho,
rodape, rodape,
imagem, imagem,
None,
inf_basicas_dic, inf_basicas_dic,
lst_mesa, lst_mesa,
lst_presenca_sessao, lst_presenca_sessao,
lst_ausencia_sessao,
lst_expedientes, lst_expedientes,
lst_expediente_materia, lst_expediente_materia,
lst_oradores_expediente, lst_oradores_expediente,
@ -1023,7 +1034,6 @@ def relatorio_pauta_sessao(request, pk):
casa = CasaLegislativa.objects.first() casa = CasaLegislativa.objects.first()
cabecalho = get_cabecalho(casa)
rodape = get_rodape(casa) rodape = get_rodape(casa)
imagem = get_imagem(casa) imagem = get_imagem(casa)
@ -1031,9 +1041,7 @@ def relatorio_pauta_sessao(request, pk):
lst_expediente_materia, lst_votacao, inf_basicas_dic = get_pauta_sessao( lst_expediente_materia, lst_votacao, inf_basicas_dic = get_pauta_sessao(
sessao, casa) sessao, casa)
pdf = pdf_pauta_sessao_gerar.principal(cabecalho, pdf = pdf_pauta_sessao_gerar.principal(rodape,
rodape,
sessao,
imagem, imagem,
inf_basicas_dic, inf_basicas_dic,
lst_expediente_materia, lst_expediente_materia,
@ -1058,8 +1066,7 @@ def get_pauta_sessao(sessao, casa):
inf_basicas_dic["nom_camara"] = casa.nome inf_basicas_dic["nom_camara"] = casa.nome
lst_expediente_materia = [] lst_expediente_materia = []
for expediente_materia in ExpedienteMateria.objects.filter( for expediente_materia in ExpedienteMateria.objects.filter(sessao_plenaria=sessao):
data_ordem=sessao.data_inicio, sessao_plenaria=sessao):
materia = MateriaLegislativa.objects.filter( materia = MateriaLegislativa.objects.filter(
id=expediente_materia.materia.id).first() id=expediente_materia.materia.id).first()
@ -1077,34 +1084,22 @@ def get_pauta_sessao(sessao, casa):
dic_expediente_materia["des_numeracao"] = ' ' dic_expediente_materia["des_numeracao"] = ' '
numeracao = Numeracao.objects.filter(materia=materia) numeracao = Numeracao.objects.filter(materia=materia)
if numeracao is not None: if numeracao:
numeracao = numeracao.first() numeracao = numeracao.first()
dic_expediente_materia["des_numeracao"] = str(numeracao) dic_expediente_materia["des_numeracao"] = str(numeracao)
dic_expediente_materia["nom_autor"] = ' ' dic_expediente_materia["nom_autor"] = ''
autoria = Autoria.objects.filter( autoria = materia.autoria_set.all()
materia=materia, primeiro_autor=True).first() dic_expediente_materia['num_autores'] = 'Autores' if len(autoria) > 1 else 'Autor'
if autoria:
if autoria is not None: for a in autoria:
autor = Autor.objects.filter(id=autoria.autor.id) if a.autor.nome:
dic_expediente_materia['nom_autor'] += a.autor.nome + ', '
if autor is not None: dic_expediente_materia['nom_autor'] = dic_expediente_materia['nom_autor'][:-2]
autor = autor.first() else:
if autor.tipo == 'Parlamentar':
parlamentar = Parlamentar.objects.filter(
id=autor.parlamentar.id)
dic_expediente_materia["nom_autor"] = str(
parlamentar.nome_completo)
elif autor.tipo == 'Comissao':
comissao = Comissao.objects.filter(id=autor.comissao.id)
dic_expediente_materia["nom_autor"] = str(comissao)
else:
dic_expediente_materia["nom_autor"] = str(autor.nome)
elif autoria is None:
dic_expediente_materia["nom_autor"] = 'Desconhecido' dic_expediente_materia["nom_autor"] = 'Desconhecido'
turno, tramitacao = get_turno(dic_expediente_materia, materia, sessao.data_inicio) turno, tramitacao = get_turno(materia)
dic_expediente_materia["des_turno"] = turno dic_expediente_materia["des_turno"] = turno
dic_expediente_materia["des_situacao"] = tramitacao dic_expediente_materia["des_situacao"] = tramitacao
@ -1132,30 +1127,19 @@ def get_pauta_sessao(sessao, casa):
dic_votacao["des_numeracao"] = str( dic_votacao["des_numeracao"] = str(
numeracao.numero_materia) + '/' + str(numeracao.ano_materia) numeracao.numero_materia) + '/' + str(numeracao.ano_materia)
turno, tramitacao = get_turno(dic_votacao, materia, sessao.data_inicio) turno, tramitacao = get_turno(materia)
dic_votacao["des_turno"] = turno dic_votacao["des_turno"] = turno
dic_votacao["des_situacao"] = tramitacao dic_votacao["des_situacao"] = tramitacao
dic_votacao["nom_autor"] = ' ' dic_votacao["nom_autor"] = ''
autoria = Autoria.objects.filter( autoria = materia.autoria_set.all()
materia=materia, primeiro_autor=True).first() dic_votacao['num_autores'] = 'Autores' if len(autoria) > 1 else 'Autor'
if autoria:
if autoria is not None: for a in autoria:
autor = Autor.objects.filter(id=autoria.autor.id) if a.autor.nome:
if autor is not None: dic_votacao['nom_autor'] += a.autor.nome + ', '
autor = autor.first() dic_votacao['nom_autor'] = dic_votacao['nom_autor'][:-2]
else:
if autor.tipo == 'Parlamentar':
parlamentar = Parlamentar.objects.filter(
id=autor.parlamentar.id)
dic_votacao["nom_autor"] = str(parlamentar.nome_completo)
elif autor.tipo == 'Comissao':
comissao = Comissao.objects.filter(
id=autor.comissao.id)
dic_votacao["nom_autor"] = str(comissao)
else:
dic_votacao["nom_autor"] = str(autor.nome)
elif autoria is None:
dic_votacao["nom_autor"] = 'Desconhecido' dic_votacao["nom_autor"] = 'Desconhecido'
lst_votacao.append(dic_votacao) lst_votacao.append(dic_votacao)

2
sapl/rules/map_rules.py

@ -172,6 +172,7 @@ rules_group_sessao = {
(sessao.RegistroVotacao, __base__), (sessao.RegistroVotacao, __base__),
(sessao.VotoParlamentar, __base__), (sessao.VotoParlamentar, __base__),
(sessao.JustificativaAusencia, __base__), (sessao.JustificativaAusencia, __base__),
(sessao.RetiradaPauta, __base__)
] ]
} }
@ -269,6 +270,7 @@ rules_group_geral = {
(sessao.JustificativaAusencia, __base__), (sessao.JustificativaAusencia, __base__),
(sessao.Bloco, __base__), (sessao.Bloco, __base__),
(sessao.ResumoOrdenacao, __base__), (sessao.ResumoOrdenacao, __base__),
(sessao.TipoRetiradaPauta, __base__),
(lexml.LexmlProvedor, __base__), (lexml.LexmlProvedor, __base__),
(lexml.LexmlPublicador, __base__), (lexml.LexmlPublicador, __base__),

111
sapl/sessao/forms.py

@ -1,3 +1,4 @@
from datetime import datetime from datetime import datetime
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
@ -22,11 +23,11 @@ from sapl.parlamentares.models import Parlamentar, Legislatura, Mandato
from sapl.utils import (RANGE_DIAS_MES, RANGE_MESES, from sapl.utils import (RANGE_DIAS_MES, RANGE_MESES,
MateriaPesquisaOrderingFilter, autor_label, MateriaPesquisaOrderingFilter, autor_label,
autor_modal, timezone) autor_modal, timezone)
from .models import (Bancada, Bloco, ExpedienteMateria, Orador, JustificativaAusencia,
OradorExpediente, OrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, TipoResultadoVotacao, OcorrenciaSessao,
RetiradaPauta, TipoRetiradaPauta)
from .models import (Bancada, Bloco, ExpedienteMateria, JustificativaAusencia,
Orador, OradorExpediente, OrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, TipoJustificativa, TipoResultadoVotacao,
OcorrenciaSessao)
def recupera_anos(): def recupera_anos():
@ -59,7 +60,7 @@ ORDENACAO_RESUMO = [('cont_mult', 'Conteúdo Multimídia'),
('mesa_d', 'Mesa Diretora'), ('mesa_d', 'Mesa Diretora'),
('oradores_exped', 'Oradores do Expediente'), ('oradores_exped', 'Oradores do Expediente'),
('oradores_expli', 'Oradores das Explicações Pessoais'), ('oradores_expli', 'Oradores das Explicações Pessoais'),
('ocorrencia_sessao', 'Ocorrências da Sessão')] ('ocorr_sessao', 'Ocorrências da Sessão')]
class SessaoPlenariaForm(ModelForm): class SessaoPlenariaForm(ModelForm):
@ -190,6 +191,100 @@ class SessaoPlenariaForm(ModelForm):
return self.cleaned_data return self.cleaned_data
class RetiradaPautaForm(ModelForm):
tipo_de_retirada = forms.ModelChoiceField(required=True,
empty_label='------------',
queryset=TipoRetiradaPauta.objects.all())
expediente = forms.ModelChoiceField(required=False,
label='Matéria do Expediente',
queryset=ExpedienteMateria.objects.all())
ordem = forms.ModelChoiceField(required=False,
label='Matéria da Ordem do Dia',
queryset=OrdemDia.objects.all())
materia = forms.ModelChoiceField(required=False,
widget=forms.HiddenInput(),
queryset=MateriaLegislativa.objects.all())
class Meta:
model = RetiradaPauta
fields = ['ordem',
'expediente',
'parlamentar',
'tipo_de_retirada',
'data',
'observacao',
'materia']
def __init__(self, *args, **kwargs):
row1 = to_row([('tipo_de_retirada', 5),
('parlamentar', 4),
('data', 3)])
row2 = to_row([('ordem', 6),
('expediente', 6)])
row3 = to_row([('observacao',12)])
self.helper = FormHelper()
self.helper.layout = SaplFormLayout(
Fieldset(_('Retirada de Pauta'),
row1, row2, row3))
q = Q(sessao_plenaria=kwargs['initial']['sessao_plenaria'])
ordens = OrdemDia.objects.filter(q)
expedientes = ExpedienteMateria.objects.filter(q)
retiradas_ordem = [r.ordem for r in RetiradaPauta.objects.filter(q, ordem__in=ordens)]
retiradas_expediente = [r.expediente for r in RetiradaPauta.objects.filter(q, expediente__in=expedientes)]
setOrdem = set(ordens) - set(retiradas_ordem)
setExpediente = set(expedientes) - set(retiradas_expediente)
super(RetiradaPautaForm, self).__init__(
*args, **kwargs)
if self.instance.pk:
setOrdem = set(ordens)
setExpediente = set(expedientes)
presencas = SessaoPlenariaPresenca.objects.filter(
q).order_by('parlamentar__nome_parlamentar')
presentes = [p.parlamentar for p in presencas]
self.fields['expediente'].choices = [
(None, "------------")] + [(e.id, e.materia) for e in setExpediente]
self.fields['ordem'].choices = [
(None, "------------")] + [(o.id, o.materia) for o in setOrdem]
self.fields['parlamentar'].choices = [
(None, "------------")] + [(p.id, p) for p in presentes]
def clean(self):
super(RetiradaPautaForm, self).clean()
if not self.is_valid():
return self.cleaned_data
sessao_plenaria = self.instance.sessao_plenaria
if self.cleaned_data['data'] < sessao_plenaria.data_inicio:
raise ValidationError(_("Data de retirada de pauta anterior à abertura da Sessão."))
if sessao_plenaria.data_fim and self.cleaned_data['data'] > sessao_plenaria.data_fim:
raise ValidationError(_("Data de retirada de pauta posterior ao encerramento da Sessão."))
if self.cleaned_data['ordem'] and self.cleaned_data['ordem'].registrovotacao_set.exists():
raise ValidationError(_("Essa matéria já foi votada, portanto não pode ser retirada de pauta."))
elif self.cleaned_data['expediente'] and self.cleaned_data['expediente'].registrovotacao_set.exists():
raise ValidationError(_("Essa matéria já foi votada, portanto não pode ser retirada de pauta."))
return self.cleaned_data
def save(self, commit=False):
retirada = super(RetiradaPautaForm, self).save(commit=False)
if retirada.ordem:
retirada.materia = retirada.ordem.materia
elif retirada.expediente:
retirada.materia = retirada.expediente.materia
retirada.save()
return retirada
class BancadaForm(ModelForm): class BancadaForm(ModelForm):
class Meta: class Meta:
@ -638,6 +733,8 @@ class ResumoOrdenacaoForm(forms.Form):
choices=ORDENACAO_RESUMO) choices=ORDENACAO_RESUMO)
decimo = forms.ChoiceField(label='10°', decimo = forms.ChoiceField(label='10°',
choices=ORDENACAO_RESUMO) choices=ORDENACAO_RESUMO)
decimo_primeiro = forms.ChoiceField(label='11°',
choices=ORDENACAO_RESUMO)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(ResumoOrdenacaoForm, self).__init__(*args, **kwargs) super(ResumoOrdenacaoForm, self).__init__(*args, **kwargs)
@ -662,12 +759,14 @@ class ResumoOrdenacaoForm(forms.Form):
[('nono', 12)]) [('nono', 12)])
row10 = to_row( row10 = to_row(
[('decimo', 12)]) [('decimo', 12)])
row11 = to_row(
[('decimo_primeiro', 12)])
self.helper = FormHelper() self.helper = FormHelper()
self.helper.layout = Layout( self.helper.layout = Layout(
Fieldset(_(''), Fieldset(_(''),
row1, row2, row3, row4, row5, row1, row2, row3, row4, row5,
row6, row7, row8, row9, row10, row6, row7, row8, row9, row10,row11,
form_actions(label='Atualizar')) form_actions(label='Atualizar'))
) )

50
sapl/sessao/migrations/0028_auto_20181031_0902.py

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-10-31 12:02
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('materia', '0032_auto_20181022_1743'),
('parlamentares', '0025_auto_20180924_1724'),
('sessao', '0029_auto_20181024_0952'),
]
operations = [
migrations.CreateModel(
name='RetiradaPauta',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('observacao', models.TextField(blank=True, verbose_name='Observações')),
('expediente', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.ExpedienteMateria')),
('materia', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa')),
('ordem', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.OrdemDia')),
('parlamentar', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Parlamentar', verbose_name='Requerente')),
],
options={
'verbose_name_plural': 'Retirada de Pauta',
'verbose_name': 'Retirada de Pauta',
},
),
migrations.CreateModel(
name='TipoRetiradaPauta',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('descricao', models.CharField(max_length=150, verbose_name='Descrição')),
],
options={
'verbose_name_plural': 'Tipos de Retirada de Pauta',
'verbose_name': 'Tipo de Retidara de Pauta',
'ordering': ['descricao'],
},
),
migrations.AddField(
model_name='retiradapauta',
name='tipo_de_retirada',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.TipoRetiradaPauta', verbose_name='Motivo de Retirada de Pauta'),
),
]

27
sapl/sessao/migrations/0030_auto_20181113_1149.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-13 13:49
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('sessao', '0028_auto_20181031_0902'),
]
operations = [
migrations.AddField(
model_name='retiradapauta',
name='data',
field=models.DateField(default=django.utils.timezone.now, verbose_name='Data'),
),
migrations.AddField(
model_name='retiradapauta',
name='sessao_plenaria',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.SessaoPlenaria', verbose_name='Sessão Plenária'),
),
]

20
sapl/sessao/migrations/0030_resumoordenacao_decimo_primeiro.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-14 12:06
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sessao', '0029_auto_20181024_0952'),
]
operations = [
migrations.AddField(
model_name='resumoordenacao',
name='decimo_primeiro',
field=models.CharField(default='', max_length=30),
),
]

21
sapl/sessao/migrations/0031_auto_20181116_1849.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-16 20:49
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('sessao', '0030_auto_20181113_1149'),
]
operations = [
migrations.AlterField(
model_name='retiradapauta',
name='materia',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa', verbose_name='Matéria'),
),
]

20
sapl/sessao/migrations/0031_auto_20181119_1103.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-19 13:03
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sessao', '0030_resumoordenacao_decimo_primeiro'),
]
operations = [
migrations.AlterField(
model_name='resumoordenacao',
name='decimo_primeiro',
field=models.CharField(default='Ocorrências da Sessão', max_length=30),
),
]

16
sapl/sessao/migrations/0032_merge_20181122_1527.py

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-22 17:27
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('sessao', '0031_auto_20181116_1849'),
('sessao', '0031_auto_20181119_1103'),
]
operations = [
]

66
sapl/sessao/models.py

@ -2,6 +2,7 @@ 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.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
@ -575,6 +576,7 @@ class ResumoOrdenacao(models.Model):
oitavo = models.CharField(max_length=30) oitavo = models.CharField(max_length=30)
nono = models.CharField(max_length=30) nono = models.CharField(max_length=30)
decimo = models.CharField(max_length=30) decimo = models.CharField(max_length=30)
decimo_primeiro = models.CharField(max_length=30,default="Ocorrências da Sessão")
class Meta: class Meta:
verbose_name = _('Ordenação do Resumo de uma Sessão') verbose_name = _('Ordenação do Resumo de uma Sessão')
@ -583,6 +585,18 @@ class ResumoOrdenacao(models.Model):
def __str__(self): def __str__(self):
return 'Ordenação do Resumo de uma Sessão' return 'Ordenação do Resumo de uma Sessão'
@reversion.register()
class TipoRetiradaPauta(models.Model):
descricao = models.CharField(max_length=150, verbose_name=_('Descrição'))
class Meta:
verbose_name = _('Tipo de Retidara de Pauta')
verbose_name_plural = _('Tipos de Retirada de Pauta')
ordering = ['descricao']
def __str__(self):
return self.descricao
@reversion.register() @reversion.register()
class TipoJustificativa(models.Model): class TipoJustificativa(models.Model):
@ -661,3 +675,55 @@ class JustificativaAusencia(models.Model):
force_update=force_update, force_update=force_update,
using=using, using=using,
update_fields=update_fields) update_fields=update_fields)
class RetiradaPauta(models.Model):
materia = models.ForeignKey(MateriaLegislativa,
on_delete=models.CASCADE,
verbose_name=_('Matéria'))
sessao_plenaria = models.ForeignKey(SessaoPlenaria,
on_delete=models.CASCADE,
verbose_name=_('Sessão Plenária'),
blank=True,
null=True)
ordem = models.ForeignKey(OrdemDia,
blank=True,
null=True,
on_delete=models.CASCADE)
expediente = models.ForeignKey(ExpedienteMateria,
blank=True,
null=True,
on_delete=models.CASCADE)
data = models.DateField(verbose_name=_('Data'),
default=timezone.now)
observacao = models.TextField(blank=True,
verbose_name=_('Observações'))
parlamentar = models.ForeignKey(Parlamentar,
on_delete=models.PROTECT,
verbose_name=_('Requerente'),
blank=True,
null=True)
tipo_de_retirada = models.ForeignKey(TipoRetiradaPauta,
on_delete=models.PROTECT,
verbose_name=_('Motivo de Retirada de Pauta'))
class Meta:
verbose_name = _('Retirada de Pauta')
verbose_name_plural = _('Retirada de Pauta')
def __str__(self):
return _('Ordem: %(ordem)s - Requerente: %(requerente)s - '
'Matéria: %(materia)s') % {
'ordem': self.ordem,
'requerente': self.parlamentar,
'materia': self.materia}
def clean(self):
"""Exatamente um dos campos ordem ou expediente deve estar preenchido.
"""
# TODO remover esse método quando OrdemDia e ExpedienteMateria
# forem reestruturados e os campos ordem e expediente forem unificados
if not xor(bool(self.ordem), bool(self.expediente)):
raise ValidationError(
'ReritadaPauta deve ter exatamente um dos campos '
'ordem ou expediente preenchido. Ambos estão preenchidos: '
'{}, {}'. format(self.ordem, self.expediente))

9
sapl/sessao/urls.py

@ -10,8 +10,9 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
PesquisarPautaSessaoView, PesquisarPautaSessaoView,
PesquisarSessaoPlenariaView, PesquisarSessaoPlenariaView,
PresencaOrdemDiaView, PresencaView, PresencaOrdemDiaView, PresencaView,
ResumoOrdenacaoView, ResumoView, ResumoAtaView, SessaoCrud, ResumoOrdenacaoView, ResumoView, ResumoAtaView, RetiradaPautaCrud, SessaoCrud,
TipoJustificativaCrud, TipoExpedienteCrud, TipoResultadoVotacaoCrud, TipoJustificativaCrud, TipoExpedienteCrud, TipoResultadoVotacaoCrud,
TipoExpedienteCrud, TipoResultadoVotacaoCrud,TipoRetiradaPautaCrud,
TipoSessaoCrud, VotacaoEditView, TipoSessaoCrud, VotacaoEditView,
VotacaoExpedienteEditView, VotacaoExpedienteEditView,
VotacaoExpedienteView, VotacaoNominalEditView, VotacaoExpedienteView, VotacaoNominalEditView,
@ -39,7 +40,7 @@ urlpatterns = [
OradorExpedienteCrud.get_urls() + OradorExpedienteCrud.get_urls() +
ExpedienteMateriaCrud.get_urls() + ExpedienteMateriaCrud.get_urls() +
JustificativaAusenciaCrud.get_urls() + JustificativaAusenciaCrud.get_urls() +
MateriaOrdemDiaCrud.get_urls())), MateriaOrdemDiaCrud.get_urls() + RetiradaPautaCrud.get_urls())),
url(r'^sessao/(?P<pk>\d+)/mesa$', MesaView.as_view(), name='mesa'), url(r'^sessao/(?P<pk>\d+)/mesa$', MesaView.as_view(), name='mesa'),
@ -76,6 +77,8 @@ urlpatterns = [
include(TipoExpedienteCrud.get_urls())), include(TipoExpedienteCrud.get_urls())),
url(r'^sistema/sessao-plenaria/tipo-justificativa/', url(r'^sistema/sessao-plenaria/tipo-justificativa/',
include(TipoJustificativaCrud.get_urls())), include(TipoJustificativaCrud.get_urls())),
url(r'^sistema/sessao-plenaria/tipo-retirada-pauta/',
include(TipoRetiradaPautaCrud.get_urls())),
url(r'^sistema/bancada/', url(r'^sistema/bancada/',
include(BancadaCrud.get_urls())), include(BancadaCrud.get_urls())),
url(r'^sistema/bloco/', url(r'^sistema/bloco/',
@ -157,5 +160,5 @@ urlpatterns = [
name='votacao_simbolica_transparencia'), name='votacao_simbolica_transparencia'),
url(r'^sessao/mudar-ordem-materia-sessao/', url(r'^sessao/mudar-ordem-materia-sessao/',
mudar_ordem_materia_sessao, mudar_ordem_materia_sessao,
name='mudar_ordem_materia_sessao'), name='mudar_ordem_materia_sessao'),
] ]

137
sapl/sessao/views.py

@ -1,3 +1,4 @@
from operator import itemgetter from operator import itemgetter
import logging import logging
from re import sub from re import sub
@ -42,24 +43,22 @@ from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, BlocoForm,
MesaForm, OradorExpedienteForm, OradorForm, PautaSessaoFilterSet, MesaForm, OradorExpedienteForm, OradorForm, PautaSessaoFilterSet,
PresencaForm, ResumoOrdenacaoForm, SessaoPlenariaFilterSet, PresencaForm, ResumoOrdenacaoForm, SessaoPlenariaFilterSet,
SessaoPlenariaForm, VotacaoEditForm, VotacaoForm, SessaoPlenariaForm, VotacaoEditForm, VotacaoForm,
VotacaoNominalForm) VotacaoNominalForm, RetiradaPautaForm)
from .models import (Bancada, Bloco, CargoBancada, CargoMesa, ExpedienteMateria, from .models import (Bancada, Bloco, CargoBancada, CargoMesa,
ExpedienteSessao, JustificativaAusencia, OcorrenciaSessao, IntegranteMesa, ExpedienteMateria, ExpedienteSessao, OcorrenciaSessao, IntegranteMesa,
MateriaLegislativa, Orador, OradorExpediente, OrdemDia, MateriaLegislativa, Orador, OradorExpediente, OrdemDia,
PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao, PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao,
SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente, SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente,
TipoJustificativa, TipoResultadoVotacao, TipoSessaoPlenaria, TipoResultadoVotacao, TipoSessaoPlenaria, VotoParlamentar, TipoRetiradaPauta,
VotoParlamentar) RetiradaPauta, TipoJustificativa, JustificativaAusencia)
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria') TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
TipoExpedienteCrud = CrudAux.build(TipoExpediente, 'tipo_expediente') 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(TipoResultadoVotacao, 'tipo_resultado_votacao')
TipoRetiradaPautaCrud = CrudAux.build(TipoRetiradaPauta, 'tipo_retirada_pauta')
TipoResultadoVotacaoCrud = CrudAux.build(
TipoResultadoVotacao, 'tipo_resultado_votacao')
def reordernar_materias_expediente(request, pk): def reordernar_materias_expediente(request, pk):
@ -196,7 +195,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'-data_tramitacao' '-data_tramitacao'
).first() ).first()
turno = ' ' turno = ' '
if tramitacao is not None: if tramitacao:
for t in Tramitacao.TURNO_CHOICES: for t in Tramitacao.TURNO_CHOICES:
if t[0] == tramitacao.turno: if t[0] == tramitacao.turno:
turno = t[1] turno = t[1]
@ -220,7 +219,9 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
exist_resultado = obj.registrovotacao_set.filter( exist_resultado = obj.registrovotacao_set.filter(
materia=obj.materia).exists() materia=obj.materia).exists()
if not exist_resultado: exist_retirada = obj.retiradapauta_set.filter(
materia=obj.materia).exists()
if not exist_resultado and not exist_retirada:
if obj.votacao_aberta: if obj.votacao_aberta:
url = '' url = ''
if is_expediente: if is_expediente:
@ -293,6 +294,19 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
resultado = btn_abrir resultado = btn_abrir
else: else:
resultado = '''Não há resultado''' resultado = '''Não há resultado'''
elif exist_retirada:
retirada = obj.retiradapauta_set.filter(
materia_id=obj.materia_id).last()
retirada_descricao = retirada.tipo_de_retirada.descricao
retirada_observacao = retirada.observacao
url = reverse('sapl.sessao:retiradapauta_detail',
kwargs={'pk': retirada.id})
resultado = ('<a href="%s">%s<br/>%s</a>' %
(url,
retirada_descricao,
retirada_observacao))
else: else:
resultado = obj.registrovotacao_set.filter( resultado = obj.registrovotacao_set.filter(
materia_id=obj.materia_id).last() materia_id=obj.materia_id).last()
@ -707,7 +721,7 @@ class SessaoCrud(Crud):
else: else:
msg = _('Cadastre alguma legislatura antes de adicionar ' + msg = _('Cadastre alguma legislatura antes de adicionar ' +
'uma sessão plenária!') 'uma sessão plenária!')
username = self.request.user.username username = self.request.user.username
self.logger.error('user=' + username + '. Cadastre alguma legislatura antes de adicionar ' self.logger.error('user=' + username + '. Cadastre alguma legislatura antes de adicionar '
'uma sessão plenária!') 'uma sessão plenária!')
@ -783,8 +797,8 @@ class PresencaView(FormMixin, PresencaMixin, DetailView):
sessao.sessao_plenaria = self.object sessao.sessao_plenaria = self.object
sessao.parlamentar = Parlamentar.objects.get(id=p) sessao.parlamentar = Parlamentar.objects.get(id=p)
sessao.save() sessao.save()
username = request.user.username username = request.user.username
self.logger.info("user=" + username + ". SessaoPlenariaPresenca salva com sucesso (parlamentar_id={})!".format(p)) self.logger.info("user=" + username + ". SessaoPlenariaPresenca salva com sucesso (parlamentar_id={})!".format(p))
msg = _('Presença em Sessão salva com sucesso!') msg = _('Presença em Sessão salva com sucesso!')
messages.add_message(request, messages.SUCCESS, msg) messages.add_message(request, messages.SUCCESS, msg)
@ -822,7 +836,7 @@ class PainelView(PermissionRequiredForAppCrudMixin, TemplateView):
if (not cronometro_discurso or not cronometro_aparte if (not cronometro_discurso or not cronometro_aparte
or not cronometro_ordem or not cronometro_consideracoes): or not cronometro_ordem or not cronometro_consideracoes):
username = self.request.user.username username = self.request.user.username
self.logger.error('user=' + username + '. Você precisa primeiro configurar os cronômetros' self.logger.error('user=' + username + '. Você precisa primeiro configurar os cronômetros'
' nas Configurações da Aplicação') ' nas Configurações da Aplicação')
@ -832,18 +846,11 @@ class PainelView(PermissionRequiredForAppCrudMixin, TemplateView):
messages.add_message(self.request, messages.ERROR, msg) messages.add_message(self.request, messages.ERROR, msg)
else: else:
m, s, x = cronometro_discurso.isoformat().split(':') cronometro_discurso = cronometro_discurso.seconds
cronometro_discurso = int(m) * 60 + int(s) cronometro_aparte = cronometro_aparte.seconds
cronometro_ordem = cronometro_ordem.seconds
m, s, x = cronometro_aparte.isoformat().split(':') cronometro_consideracoes = cronometro_consideracoes.seconds
cronometro_aparte = int(m) * 60 + int(s)
m, s, x = cronometro_ordem.isoformat().split(':')
cronometro_ordem = int(m) * 60 + int(s)
m, s, x = cronometro_consideracoes.isoformat().split(':')
cronometro_consideracoes = int(m) * 60 + int(s)
context = TemplateView.get_context_data(self, **kwargs) context = TemplateView.get_context_data(self, **kwargs)
context.update({ context.update({
'head_title': str(_('Painel Plenário')), 'head_title': str(_('Painel Plenário')),
@ -1335,7 +1342,13 @@ class ResumoView(DetailView):
parlamentares_sessao = [p.parlamentar for p in presencas] parlamentares_sessao = [p.parlamentar for p in presencas]
context.update({'presenca_sessao': parlamentares_sessao}) ausentes_sessao = JustificativaAusencia.objects.filter(
sessao_plenaria_id=self.object.id
).order_by('parlamentar__nome_parlamentar')
context.update({'presenca_sessao': parlamentares_sessao,
'justificativa_ausencia': ausentes_sessao})
# ===================================================================== # =====================================================================
# Expedientes # Expedientes
@ -1363,15 +1376,18 @@ class ResumoView(DetailView):
numero = m.numero_ordem numero = m.numero_ordem
tramitacao = m.materia.tramitacao_set.last() tramitacao = m.materia.tramitacao_set.last()
turno = None turno = None
if tramitacao: if tramitacao:
turno = get_turno(tramitacao.turno) turno = get_turno(tramitacao.turno)
rv = m.registrovotacao_set.first() rv = m.registrovotacao_set.first()
rp = m.retiradapauta_set.filter(materia=m.materia).first()
if rv: if rv:
resultado = rv.tipo_resultado_votacao.nome resultado = rv.tipo_resultado_votacao.nome
resultado_observacao = rv.observacao resultado_observacao = rv.observacao
elif rp:
resultado = rp.tipo_de_retirada.descricao
resultado_observacao = rp.observacao
else: else:
resultado = _('Matéria não votada') resultado = _('Matéria não votada')
resultado_observacao = _(' ') resultado_observacao = _(' ')
@ -1387,7 +1403,8 @@ class ResumoView(DetailView):
'resultado_observacao': resultado_observacao, 'resultado_observacao': resultado_observacao,
'autor': autor, 'autor': autor,
'numero_protocolo': m.materia.numero_protocolo, 'numero_protocolo': m.materia.numero_protocolo,
'numero_processo': m.materia.numeracao_set.last() 'numero_processo': m.materia.numeracao_set.last(),
'observacao': m.observacao
} }
materias_expediente.append(mat) materias_expediente.append(mat)
@ -1420,7 +1437,7 @@ class ResumoView(DetailView):
parlamentares_mesa_dia = [m['parlamentar'] for m in context['mesa']] parlamentares_mesa_dia = [m['parlamentar'] for m in context['mesa']]
# composicao_mesa = ComposicaoMesa.objects.filter(sessao_legislativa=sessao) # composicao_mesa = ComposicaoMesa.objects.filter(sessao_legislativa=sessao)
presidente_dia = '' presidente_dia = ''
for m in context['mesa']: for m in context['mesa']:
if m['cargo'].descricao == 'Presidente': if m['cargo'].descricao == 'Presidente':
@ -1430,7 +1447,7 @@ class ResumoView(DetailView):
parlamentares_ordem = [p.parlamentar for p in presencas] parlamentares_ordem = [p.parlamentar for p in presencas]
context.update({'presenca_ordem': parlamentares_ordem}) context.update({'presenca_ordem': parlamentares_ordem})
config_assinatura_ata = AppsAppConfig.objects.first().assinatura_ata config_assinatura_ata = AppsAppConfig.objects.first().assinatura_ata
if config_assinatura_ata == 'T' and parlamentares_ordem: if config_assinatura_ata == 'T' and parlamentares_ordem:
context.update({'texto_assinatura': 'Assinatura de Todos os Parlamentares Presentes na Sessão'}) context.update({'texto_assinatura': 'Assinatura de Todos os Parlamentares Presentes na Sessão'})
@ -1459,9 +1476,13 @@ class ResumoView(DetailView):
# Verificar resultado # Verificar resultado
rv = o.registrovotacao_set.filter(materia=o.materia).first() rv = o.registrovotacao_set.filter(materia=o.materia).first()
rp = o.retiradapauta_set.filter(materia=o.materia).first()
if rv: if rv:
resultado = rv.tipo_resultado_votacao.nome resultado = rv.tipo_resultado_votacao.nome
resultado_observacao = rv.observacao resultado_observacao = rv.observacao
elif rp:
resultado = rp.tipo_de_retirada.descricao
resultado_observacao = rp.observacao
else: else:
resultado = _('Matéria não votada') resultado = _('Matéria não votada')
resultado_observacao = _(' ') resultado_observacao = _(' ')
@ -1541,7 +1562,8 @@ class ResumoView(DetailView):
'setimo_ordenacao': dict_ord_template[ordenacao.setimo], 'setimo_ordenacao': dict_ord_template[ordenacao.setimo],
'oitavo_ordenacao': dict_ord_template[ordenacao.oitavo], 'oitavo_ordenacao': dict_ord_template[ordenacao.oitavo],
'nono_ordenacao': dict_ord_template[ordenacao.nono], 'nono_ordenacao': dict_ord_template[ordenacao.nono],
'decimo_ordenacao': dict_ord_template[ordenacao.decimo]}) 'decimo_ordenacao': dict_ord_template[ordenacao.decimo],
'decimo_primeiro_ordenacao': dict_ord_template[ordenacao.decimo_primeiro]})
else: else:
context.update( context.update(
{'primeiro_ordenacao': dict_ord_template['id_basica'], {'primeiro_ordenacao': dict_ord_template['id_basica'],
@ -1661,7 +1683,7 @@ class OcorrenciaSessaoView(FormMixin, DetailView):
def delete(self): def delete(self):
OcorrenciaSessao.objects.filter(sessao_plenaria=self.object).delete() OcorrenciaSessao.objects.filter(sessao_plenaria=self.object).delete()
username = self.request.user.username username = self.request.user.username
self.logger.info('user=' + username + '. OcorrenciaSessao com SessaoPlenaria de id={} deletada.' self.logger.info('user=' + username + '. OcorrenciaSessao com SessaoPlenaria de id={} deletada.'
.format(self.object.id)) .format(self.object.id))
@ -1681,7 +1703,7 @@ class OcorrenciaSessaoView(FormMixin, DetailView):
msg = _('Registro salvo com sucesso') msg = _('Registro salvo com sucesso')
messages.add_message(self.request, messages.SUCCESS, msg) messages.add_message(self.request, messages.SUCCESS, msg)
username = self.request.user.username username = self.request.user.username
self.logger.info('user=' + username + '. OcorrenciaSessao de sessao_plenaria_id={} atualizada com sucesso.'.format(self.object.id)) self.logger.info('user=' + username + '. OcorrenciaSessao de sessao_plenaria_id={} atualizada com sucesso.'.format(self.object.id))
@ -2744,6 +2766,7 @@ class PautaSessaoDetailView(DetailView):
mat = {'id': m.materia_id, mat = {'id': m.materia_id,
'ementa': ementa, 'ementa': ementa,
'observacao': m.observacao,
'titulo': titulo, 'titulo': titulo,
'numero': numero, 'numero': numero,
'resultado': resultado, 'resultado': resultado,
@ -2807,6 +2830,7 @@ class PautaSessaoDetailView(DetailView):
mat = {'id': o.materia_id, mat = {'id': o.materia_id,
'ementa': ementa, 'ementa': ementa,
'observacao': o.observacao,
'titulo': titulo, 'titulo': titulo,
'numero': numero, 'numero': numero,
'resultado': resultado, 'resultado': resultado,
@ -3052,7 +3076,7 @@ class AdicionarVariasMateriasOrdemDia(AdicionarVariasMateriasExpediente):
messages.add_message(request, messages.ERROR, msg) messages.add_message(request, messages.ERROR, msg)
self.logger.error('user=' + username + '. Formulário Inválido. Você esqueceu de selecionar ' self.logger.error('user=' + username + '. Formulário Inválido. Você esqueceu de selecionar '
'o tipo de votação de MateriaLegislativa com id={}'.format(m)) 'o tipo de votação de MateriaLegislativa com id={}'.format(m))
return self.get(request, self.kwargs) return self.get(request, self.kwargs)
if tipo_votacao: if tipo_votacao:
@ -3096,7 +3120,7 @@ def mudar_ordem_materia_sessao(request):
elif materia == 'ordem': elif materia == 'ordem':
materia = OrdemDia materia = OrdemDia
else: else:
return return JsonResponse({}, safe=False)
# Testa se existe alguma matéria na posição recebida # Testa se existe alguma matéria na posição recebida
try: try:
@ -3135,7 +3159,7 @@ def mudar_ordem_materia_sessao(request):
materia_1.numero_ordem = posicao_final materia_1.numero_ordem = posicao_final
materia_1.save() materia_1.save()
return return JsonResponse({}, safe=False)
class JustificativaAusenciaCrud(MasterDetailCrud): class JustificativaAusenciaCrud(MasterDetailCrud):
@ -3215,3 +3239,38 @@ class JustificativaAusenciaCrud(MasterDetailCrud):
class DeleteView(MasterDetailCrud.DeleteView): class DeleteView(MasterDetailCrud.DeleteView):
pass pass
class RetiradaPautaCrud(MasterDetailCrud):
model = RetiradaPauta
public = [RP_LIST, RP_DETAIL, ]
parent_field = 'sessao_plenaria'
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['tipo_de_retirada', 'materia', 'observacao', 'parlamentar']
class ListView(MasterDetailCrud.ListView):
paginate_by = 10
class CreateView(MasterDetailCrud.CreateView):
form_class = RetiradaPautaForm
layout_key = None
def get_initial(self):
sessao_plenaria = SessaoPlenaria.objects.get(id=self.kwargs['pk'])
return {'sessao_plenaria': sessao_plenaria}
def get_success_url(self):
return reverse('sapl.sessao:retiradapauta_list',
kwargs={'pk': self.kwargs['pk']})
class UpdateView(MasterDetailCrud.UpdateView):
form_class = RetiradaPautaForm
layout_key = None
def get_initial(self):
sessao_plenaria = RetiradaPauta.objects.get(id=self.kwargs['pk']).sessao_plenaria
return {'sessao_plenaria': sessao_plenaria}
class DeleteView(MasterDetailCrud.DeleteView):
pass

10
sapl/static/js/app.js

@ -47,7 +47,7 @@ function refreshMask() {
$('.dateinput').mask('00/00/0000', {placeholder:"__/__/____"}); $('.dateinput').mask('00/00/0000', {placeholder:"__/__/____"});
$('.hora').mask("00:00", {placeholder:"hh:mm"}); $('.hora').mask("00:00", {placeholder:"hh:mm"});
$('.hora_hms').mask("00:00:00", {placeholder:"hh:mm:ss"}); $('.hora_hms').mask("00:00:00", {placeholder:"hh:mm:ss"});
$('.cronometro').mask("00:00", {placeholder:"mm:ss"}); $('.cronometro').mask("00:00:00", {placeholder:"hh:mm:ss"});
} }
function autorModal() { function autorModal() {
@ -192,20 +192,12 @@ function OptionalCustomFrontEnd() {
_label = $('<label[for='+this.id+']/>').insertBefore(this) _label = $('<label[for='+this.id+']/>').insertBefore(this)
} }
} }
/*var _controls = _label.closest('.controls');
if (!_controls.length) {
_controls = $('<div class="controls"/>').insertBefore(_label)
_controls.append(_label)
}*/
if (this.type === "checkbox") { if (this.type === "checkbox") {
_label.addClass('checkbox-inline');
_label.prepend(_this); _label.prepend(_this);
_this.checkbox(); _this.checkbox();
} }
else if (this.type === "radio") { else if (this.type === "radio") {
_label.addClass('radio-inline');
_label.prepend(_this); _label.prepend(_this);
_this.radio(); _this.radio();

40
sapl/static/styles/app.scss

@ -222,21 +222,49 @@ nav {
border: 1px solid #d6e1e5; border: 1px solid #d6e1e5;
border-radius: 4px; border-radius: 4px;
min-height: 20px; min-height: 20px;
.checkbox, .radio, .checkbox-inline, .radio-inline {
padding: 8px 8px 8px 36px;
margin: 0;
line-height: 1.6;
display: block;
&:hover {
background-color: #d6e1e5;
}
.icons {
top: auto;
left: 8px;
}
}
.checkbox-inline, .radio-inline {
display: inline-block;
}
.help-block { .help-block {
margin: $grid-gutter-width / 2; margin: $grid-gutter-width / 2;
padding: $grid-gutter-width / 2; padding: $grid-gutter-width / 2;
border: 2px dashed #d6e1e5; border: 2px dashed #d6e1e5;
} }
}
.controls-radio-checkbox__old {
padding: 0px;
border: 1px solid #d6e1e5;
border-radius: 4px;
min-height: 20px;
label { label {
padding: 5px; padding: 0;
line-height: 2.7;
padding-left: 36px;
.icons { .icons {
top: 5px; top: 8px;
left: 8px; left: 8px;
} }
&.checkbox-inline, &.radio-inline {
padding: 8px; &.checkbox-inline, &.radio-inline, {
padding-left: 36px; padding-right: 8px;
.icons { .icons {
top: 8px; top: 8px;
left: 8px; left: 8px;
@ -244,7 +272,7 @@ nav {
} }
} }
.checkbox, .radio, .checkbox-inline, .radio-inline { .checkbox, .radio, .checkbox-inline, .radio-inline {
margin: 0; margin: 0;
&:hover { &:hover {
background-color: #d6e1e5; background-color: #d6e1e5;
} }

2
sapl/templates/base.html

@ -184,7 +184,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.132</span> <span>Release: 3.1.137</span>
</p> </p>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">

5
sapl/templates/materia/proposicao_detail.html

@ -158,11 +158,12 @@
</br> </br>
Texto Original Texto Original
</br> </br>
&nbsp;&nbsp;&nbsp;&nbsp; {% if object.materia_de_vinculo.texto_original %}
<a href="{{object.materia_de_vinculo.texto_original.url}}"> <a href="{{object.materia_de_vinculo.texto_original.url}}">
{{object.materia_de_vinculo.texto_original| to_str | split:"/" | get_last_item_from_list:-1}} {{object.materia_de_vinculo.texto_original| to_str | split:"/" | get_last_item_from_list:-1}}
</a> </a>
</br> {% endif %}
</br>
</div> </div>
</div> </div>
</div> </div>

3
sapl/templates/menu_tabelas_auxiliares.yaml

@ -152,6 +152,9 @@
- title: {% trans 'Tipo de Expediente' %} - title: {% trans 'Tipo de Expediente' %}
url: sapl.sessao:tipoexpediente_list url: sapl.sessao:tipoexpediente_list
css_class: btn btn-link css_class: btn btn-link
- title: {% trans 'Tipo de Retirada de Pauta' %}
url: sapl.sessao:tiporetiradapauta_list
css_class: btn btn-link
- title: {% trans 'Ordenação do Resumo' %} - title: {% trans 'Ordenação do Resumo' %}
url: sapl.sessao:resumo_ordenacao url: sapl.sessao:resumo_ordenacao
css_class: btn btn-link css_class: btn btn-link

8
sapl/templates/norma/layouts.yaml

@ -17,7 +17,7 @@ NormaJuridica:
- tipo numero ano - tipo numero ano
- data esfera_federacao complemento - data esfera_federacao complemento
- materia - materia
- data_publicacao veiculo_publicacao pagina_inicio_publicacao pagina_fim_publicacao - data_publicacao veiculo_publicacao data_vigencia pagina_inicio_publicacao pagina_fim_publicacao
- texto_integral - texto_integral
- ementa - ementa
- indexacao - indexacao
@ -35,7 +35,7 @@ NormaJuridicaCreate:
- tipo ano numero - tipo ano numero
- data esfera_federacao complemento - data esfera_federacao complemento
- tipo_materia numero_materia ano_materia - tipo_materia numero_materia ano_materia
- data_publicacao veiculo_publicacao pagina_inicio_publicacao pagina_fim_publicacao - data_publicacao veiculo_publicacao data_vigencia pagina_inicio_publicacao pagina_fim_publicacao
- texto_integral - texto_integral
- ementa - ementa
- indexacao - indexacao
@ -58,7 +58,7 @@ LegislacaoCitadaDetail:
TipoVinculoNormaJuridica: TipoVinculoNormaJuridica:
{% trans 'Tipo de Vínculo entre Normas Jurídicas' %}: {% trans 'Tipo de Vínculo entre Normas Jurídicas' %}:
- sigla:2 descricao_ativa descricao_passiva - sigla:2 descricao_ativa descricao_passiva revoga_integralmente
NormaRelacionada: NormaRelacionada:
{% trans 'Norma Relacionada' %}: {% trans 'Norma Relacionada' %}:
@ -73,4 +73,4 @@ NormaRelacionadaDetail:
AutoriaNorma: AutoriaNorma:
{% trans 'Autoria' %}: {% trans 'Autoria' %}:
- autor primeiro_autor - autor primeiro_autor

4
sapl/templates/protocoloadm/comprovante.html

@ -3,7 +3,7 @@
{% load static %} {% load static %}
{% block detail_content %} {% block detail_content %}
<style> <style xmlns:max-width="http://www.w3.org/1999/xhtml">
table { table {
width: 100%; width: 100%;
} }
@ -25,7 +25,7 @@
<table> <table>
<tr><td colspan="2" align="center"> <tr><td colspan="2" align="center">
<img height="150" width="150" <img height="90" width="90"
src="{% if logotipo %}{{ MEDIA_URL }}{{ logotipo }}{% else %}{% static 'img/logo.png' %}{% endif %}" src="{% if logotipo %}{{ MEDIA_URL }}{{ logotipo }}{% else %}{% static 'img/logo.png' %}{% endif %}"
alt="Logotipo" alt="Logotipo"
class="img-responsive visible-lg-inline-block vcenter"> class="img-responsive visible-lg-inline-block vcenter">

12
sapl/templates/sessao/blocos_ata/lista_presenca.html

@ -2,9 +2,15 @@
<fieldset> <fieldset>
<p align="justify"> <p align="justify">
<strong>Lista de Presença na Sessão: </strong> <strong>Lista de Presença na Sessão: </strong>
{% for p in presenca_sessao %} {% for p in presenca_sessao %}
{{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }} ; {{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }} ;
{% endfor %} {% endfor %}
</p> </p>
</fieldset> <p align="justify">
<strong>Justificativas de Ausências na Sessão: </strong>
{% for j in justificativa_ausencia %}
{{j.parlamentar}} / {{ j.tipo_ausencia }} ;
{% endfor %}
</p>
</fieldset>

5
sapl/templates/sessao/blocos_ata/lista_presenca_ordem_dia.html

@ -2,9 +2,10 @@
<fieldset> <fieldset>
<p align="justify"> <p align="justify">
<strong>Lista de Presença na Ordem do Dia: </strong> <strong>Lista de Presença na Ordem do Dia: </strong>
{% for p in presenca_ordem %} {% for p in presenca_ordem %}
{{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }} ; {{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }} ;
{% endfor %} {% endfor %}
</p> </p>
</fieldset>
</fieldset>

27
sapl/templates/sessao/blocos_resumo/lista_presenca.html

@ -7,4 +7,29 @@
<div class="col-md-12">{{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }}</div> <div class="col-md-12">{{p.nome_parlamentar}} / {{ p|filiacao_data_filter:object.data_inicio }}</div>
{% endfor %} {% endfor %}
</div> </div>
</fieldset> </br></br></br>
<div class="row">
<legend>Justificativas de Ausência na Sessão</legend>
<table class="table">
<thead>
<tr>
<th>Parlamentar</th>
<th>Justificativa</th>
<th>Ausente em</th>
</tr>
</thead>
<tbody>
{% for j in justificativa_ausencia %}
<tr>
<td> {{ j.parlamentar }} </td>
<td> {{ j.tipo_ausencia }} </td>
{% if j.ausencia == 1 %}
<td> Matéria </td>
{% else %}
<td> Sessão </td>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</fieldset>

2
sapl/templates/sessao/blocos_resumo/materias_expediente.html

@ -33,7 +33,7 @@
<b>Processo:</b> {{ m.numero_processo }} <b>Processo:</b> {{ m.numero_processo }}
{% endif %} {% endif %}
</td> </td>
<td>{{m.ementa|safe}}</td> <td>{{m.ementa|safe}}<br/>{{m.observacao}}</td>
<td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td> <td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td>
</tr> </tr>
{% endfor %} {% endfor %}

6
sapl/templates/sessao/expedientemateria_list.html

@ -22,6 +22,12 @@
var pk_sessao = {{root_pk}}; var pk_sessao = {{root_pk}};
var pk_list = {{ object_list|to_list_pk|safe }}; var pk_list = {{ object_list|to_list_pk|safe }};
$(document).on('keyup', (e) => {
if (e.keyCode == 86){
window.open("{% url 'sapl.painel:voto_individual' %}",'Voto Individual','width=1000, height=800, scrollbars=yes');
};
});
$('tbody').sortable({ $('tbody').sortable({
start: function(event, ui) { start: function(event, ui) {

12
sapl/templates/sessao/layouts.yaml

@ -91,7 +91,7 @@ TipoJustificativa:
JustificativaAusencia: JustificativaAusencia:
{% trans 'Justificativa de Ausência' %}: {% trans 'Justificativa de Ausência' %}:
- parlamentar - parlamentar
- data hora - data hora
- upload_anexo - upload_anexo
- tipo_ausencia - tipo_ausencia
@ -99,3 +99,13 @@ JustificativaAusencia:
- materias_do_expediente - materias_do_expediente
- materias_da_ordem_do_dia - materias_da_ordem_do_dia
- observacao - observacao
TipoRetiradaPauta:
{% trans 'Tipo Retirada Pauta'%}:
- descricao
RetiradaPauta:
{% trans 'Retirada de Pauta' %}:
- tipo_de_retirada materia
- data parlamentar
- observacao

6
sapl/templates/sessao/ordemdia_list.html

@ -22,6 +22,12 @@
var pk_sessao = {{root_pk}}; var pk_sessao = {{root_pk}};
var pk_list = {{ object_list|to_list_pk|safe }}; var pk_list = {{ object_list|to_list_pk|safe }};
$(document).on('keyup', (e) => {
if (e.keyCode == 86){
window.open("{% url 'sapl.painel:voto_individual' %}",'Voto Individual','width=1000, height=800, scrollbars=yes');
};
});
$('tbody').sortable({ $('tbody').sortable({
start: function(event, ui) { start: function(event, ui) {

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}}</td> <td style="width:70%;">{{m.ementa|safe}}<br>{{m.observacao|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}}</td> <td style="width:70%;">{{m.ementa|safe}}<br>{{m.observacao|safe}}</td>
<td style="width:10%;">{{m.situacao}}</td> <td style="width:10%;">{{m.situacao}}</td>
</tr> </tr>
{% endfor %} {% endfor %}

157
sapl/templates/sessao/presenca.html

@ -5,91 +5,90 @@
{% block actions %}{% endblock %} {% block actions %}{% endblock %}
{% block detail_content %} {% block detail_content %}
{% if perms|get_add_perm:view %} {% if perms|get_add_perm:view %}
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
<div class="controls">
<div class="controls"> <div class="checkbox">
<div class="checkbox"> <label for="id_check_all">
<label for="id_check_all"> <input type="checkbox" id="id_check_all" onchange="checkAll(event)" /> Marcar/Desmarcar Todos
<input type="checkbox" id="id_check_all" onchange="checkAll(event)" /> Marcar/Desmarcar Todos </label>
</label>
</div>
</div>
<br />
<div class="controls">
<div class="checkbox">
<label for="id_ativos">
<input type="checkbox" name="ativos" id="id_ativos" onchange="escondeInativos()" checked /> Exibir somente parlamentares ativos
</label>
</div>
</div>
<br />
<div class="controls">
{% for parlamentar, check in view.get_presencas %}
{% if parlamentar.ativo %}
<div class="checkbox">
<label for="id_presenca_{{forloop.counter}}">
<input type="checkbox" id="id_presenca_{{forloop.counter}}" name="presenca_ativos" value="{{ parlamentar.id }}" {% if check %} checked {% endif %}/>
{{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
{% else %}
<div class="checkbox inativos" style="display:none;">
<label for="id_presenca_{{forloop.counter}}">
<input type="checkbox" id="id_presenca_{{forloop.counter}}" name="presenca_inativos" value="{{ parlamentar.id }}" {% if check %} checked {% endif %}/>
{{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
{% endif %}
{% endfor %}
</div> </div>
</div>
<br /> <br />
<input type="submit" value="Salvar" class="btn btn-primary" /> <div class="controls">
</form> <div class="checkbox">
<label for="id_ativos">
{% else %} <input type="checkbox" name="ativos" id="id_ativos" onchange="escondeInativos()" checked /> Exibir somente
<div class="row"> parlamentares ativos
<div class="col-md-6"><h2>Parlamentares presentes</div> </label>
</div> </div>
</br> </div>
<br />
<div class="controls ">
{% for parlamentar, check in view.get_presencas %} {% for parlamentar, check in view.get_presencas %}
{% if check %} {% if parlamentar.ativo %}
<div class="row"> <div class="checkbox">
<div class="col-md-6"><label for="parlamentar"> - {{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}</label></div> <label for="id_presenca_{{forloop.counter}}">
</div> <input type="checkbox" id="id_presenca_{{forloop.counter}}" name="presenca_ativos" value="{{ parlamentar.id }}"
{% endif %} {% if check %} checked {% endif %}>
{{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
{% else %}
<div class="checkbox inativos" style="display:none;">
<label for="id_presenca_{{forloop.counter}}" class="inativos" style="display:none;">
<input type="checkbox" id="id_presenca_{{forloop.counter}}" name="presenca_inativos" value="{{ parlamentar.id }}"
{% if check %} checked {% endif %}>
{{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
{% endif %}
{% endfor %} {% endfor %}
</div>
<br />
<input type="submit" value="Salvar" class="btn btn-primary" />
</form>
{% endif %} {% else %}
<div class="row">
<div class="col-md-6">
<h2>Parlamentares presentes
</div>
</div>
<br />
{% for parlamentar, check in view.get_presencas %}
{% if check %}
<div class="row">
<div class="col-md-6">
<label for="parlamentar"> - {{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endblock detail_content %} {% endblock detail_content %}
{% block extra_js %} {% block extra_js %}
<script language="JavaScript"> <script language="JavaScript">
function checkAll(event) { function checkAll(event) {
$('[name=presenca_ativos]').each(function() { $('[name=presenca_ativos]').each(function () {
$(this).prop('checked', event.target.checked ? 'checked': null); $(this).prop('checked', event.target.checked ? 'checked' : null);
$(this).trigger('click'); $(this).trigger('click');
}); });
if (($('[name=ativos]').is(':checked')) == false) { if (($('[name=ativos]').is(':checked')) == false) {
$('[name=presenca_inativos]').each(function() { $('[name=presenca_inativos]').each(function () {
$(this).prop('checked', event.target.checked ? 'checked': null); $(this).prop('checked', event.target.checked ? 'checked' : null);
$(this).trigger('click'); $(this).trigger('click');
}); });
} }
}
}
function escondeInativos() {
function escondeInativos() { $(".inativos").toggle();
$(".inativos").toggle(); }
} </script>
</script> {% endblock %}
{% endblock %}

147
sapl/templates/sessao/presenca_ordemdia.html

@ -7,90 +7,93 @@
{% block detail_content %} {% block detail_content %}
{% if perms|get_add_perm:view %} {% if perms|get_add_perm:view %}
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
<div class="controls">
<div class="controls"> <div class="checkbox">
<div class="checkbox"> <label for="id_check_all">
<label for="id_check_all"> <input type="checkbox" id="id_check_all" onchange="checkAll(event)" /> Marcar/Desmarcar Todos
<input type="checkbox" id="id_check_all" onchange="checkAll(event)" /> Marcar/Desmarcar Todos </label>
</label>
</div>
</div> </div>
</div>
<br /> <br />
<div class="controls"> <div class="controls">
<div class="checkbox"> <div class="checkbox">
<label for="id_ativos"> <label for="id_ativos">
<input type="checkbox" name="ativos" id="id_ativos" onchange="escondeInativos()" checked /> Exibir somente parlamentares ativos <input type="checkbox" name="ativos" id="id_ativos" onchange="escondeInativos()" checked /> Exibir somente
</label> parlamentares ativos
</div> </label>
</div> </div>
</div>
<br /> <br />
<div class="controls">
{% for parlamentar, check in view.get_presencas_ordem %}
{% if parlamentar.ativo %}
<div class="checkbox">
<label for="id_presenca_{{forloop.counter}}">
<input type="checkbox" id="id_presenca_{{forloop.counter}}" name="presenca_ativos" value="{{ parlamentar.id }}" {% if check %} checked {% endif %}/>
{{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
{% else %}
<div class="checkbox inativos" style="display:none;">
<label for="id_presenca_{{forloop.counter}}">
<input type="checkbox" id="id_presenca_{{forloop.counter}}" name="presenca_inativos" value="{{ parlamentar.id }}" {% if check %} checked {% endif %}/>
{{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
{% endif %}
{% endfor %}
</div>
<br /> <div class="controls">
<input type="submit" value="Salvar" class="btn btn-primary" /> {% for parlamentar, check in view.get_presencas_ordem %}
</form> {% if parlamentar.ativo %}
<div class="checkbox">
<label for="id_presenca_{{forloop.counter}}">
<input type="checkbox" id="id_presenca_{{forloop.counter}}" name="presenca_ativos" value="{{ parlamentar.id }}"
{% if check %} checked {% endif %} />
{{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
{% else %}
<div class="checkbox inativos" style="display:none;">
<label for="id_presenca_{{forloop.counter}}" >
<input type="checkbox" id="id_presenca_{{forloop.counter}}" name="presenca_inativos" value="{{ parlamentar.id }}"
{% if check %} checked {% endif %} />
{{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}
</label>
</div>
{% endif %}
{% endfor %}
</div>
<br />
<input type="submit" value="Salvar" class="btn btn-primary" />
</form>
{% else %} {% else %}
<div class="row"> <div class="row">
<div class="col-md-6"><h2>Parlamentares presentes</div> <div class="col-md-6">
</div> <h2>Parlamentares presentes
</br> </div>
</div>
{% for parlamentar, check in view.get_presencas_ordem %} <br/>
{% if check %}
<div class="row"> {% for parlamentar, check in view.get_presencas_ordem %}
<div class="col-md-6"><label for="parlamentar"> - {{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}</label></div> {% if check %}
</div> <div class="row">
{% endif %} <div class="col-md-6"><label for="parlamentar"> - {{ parlamentar.nome_parlamentar }} / {{ parlamentar|filiacao_data_filter:object.data_inicio }}</label></div>
{% endfor %} </div>
{% endif %}
{% endfor %}
{% endif %} {% endif %}
{% endblock detail_content %} {% endblock detail_content %}
{% block extra_js %} {% block extra_js %}
<script language="JavaScript"> <script language="JavaScript">
function checkAll(event) { function checkAll(event) {
$('[name=presenca_ativos]').each(function() { $('[name=presenca_ativos]').each(function () {
$(this).prop('checked', event.target.checked ? 'checked': null); $(this).prop('checked', event.target.checked ? 'checked' : null);
$(this).trigger('click'); $(this).trigger('click');
}); });
if (($('[name=ativos]').is(':checked')) == false) { if (($('[name=ativos]').is(':checked')) == false) {
$('[name=presenca_inativos]').each(function() { $('[name=presenca_inativos]').each(function () {
$(this).prop('checked', event.target.checked ? 'checked': null); $(this).prop('checked', event.target.checked ? 'checked' : null);
$(this).trigger('click'); $(this).trigger('click');
}); });
} }
} }
function escondeInativos() { function escondeInativos() {
$(".inativos").toggle(); $(".inativos").toggle();
} }
</script> </script>
{% endblock %} {% endblock %}

2
sapl/templates/sessao/resumo_ata.html

@ -21,4 +21,4 @@
{% include 'sessao/blocos_ata/'|add:decimo_ordenacao %} {% include 'sessao/blocos_ata/'|add:decimo_ordenacao %}
{% include 'sessao/blocos_ata/'|add:decimo_primeiro_ordenacao %} {% include 'sessao/blocos_ata/'|add:decimo_primeiro_ordenacao %}
{% include 'sessao/blocos_ata/assinaturas.html' %} {% include 'sessao/blocos_ata/assinaturas.html' %}
{% endblock detail_content %} {% endblock detail_content %}

2
sapl/templates/sessao/resumo_ordenacao.html

@ -10,4 +10,4 @@
{% crispy form %} {% crispy form %}
{% endblock %} {% endblock %}

6
sapl/templates/sessao/retiradapauta_form.html

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

2
sapl/templates/sessao/subnav.yaml

@ -14,6 +14,8 @@
url: orador_list url: orador_list
- title: {% trans 'Ocorrências da Sessão' %} - title: {% trans 'Ocorrências da Sessão' %}
url: ocorrencia_sessao url: ocorrencia_sessao
- title: {% trans 'Retirada de Pauta'%}
url: retiradapauta_list
- title: {% trans 'Expedientes' %} - title: {% trans 'Expedientes' %}
children: children:

1
sapl/templates/sistema.html

@ -104,6 +104,7 @@
<div class="col-md-6"><a href="{% url 'sapl.sessao:tiposessaoplenaria_list' %}" class="btn btn-link">Tipo de Sessão Plenária</a></div> <div class="col-md-6"><a href="{% url 'sapl.sessao:tiposessaoplenaria_list' %}" class="btn btn-link">Tipo de Sessão Plenária</a></div>
<div class="col-md-6"><a href="{% url 'sapl.sessao:tiporesultadovotacao_list' %}" class="btn btn-link">Tipo de Resultado da Votação</a></div> <div class="col-md-6"><a href="{% url 'sapl.sessao:tiporesultadovotacao_list' %}" class="btn btn-link">Tipo de Resultado da Votação</a></div>
<div class="col-md-6"><a href="{% url 'sapl.sessao:tipoexpediente_list' %}" class="btn btn-link">Tipo de Expediente</a></div> <div class="col-md-6"><a href="{% url 'sapl.sessao:tipoexpediente_list' %}" class="btn btn-link">Tipo de Expediente</a></div>
<div class="col-md-6"><a href="{% url 'sapl.sessao:tiporetiradapauta_list' %}" class="btn btn-link">Tipo de Retirada de Pauta</a></div>
<div class="col-md-6"><a href="{% url 'sapl.sessao:resumo_ordenacao' %}" class="btn btn-link">Ordenação do Resumo</a></div> <div class="col-md-6"><a href="{% url 'sapl.sessao:resumo_ordenacao' %}" class="btn btn-link">Ordenação do Resumo</a></div>
<div class="col-md-6"><a href="{% url 'sapl.sessao:tipojustificativa' %}" class="btn btn-link">Tipo de Justificativa de Ausência</a></div> <div class="col-md-6"><a href="{% url 'sapl.sessao:tipojustificativa' %}" class="btn btn-link">Tipo de Justificativa de Ausência</a></div>
</div> </div>

2
setup.py

@ -52,7 +52,7 @@ install_requires = [
] ]
setup( setup(
name='interlegis-sapl', name='interlegis-sapl',
version='3.1.132', version='3.1.137',
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