Browse Source

Merge branch '3.1.x' into 2712-partidos-errados-extrato-e-resumo

pull/2714/head
Edward 7 years ago
committed by GitHub
parent
commit
794b9c08a3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      Dockerfile
  2. 13
      check_solr.sh
  3. 17
      docker-compose.yml
  4. 20
      sapl/base/migrations/0033_auto_20190415_1050.py
  5. 3
      sapl/base/models.py
  6. 4
      sapl/compilacao/forms.py
  7. 37
      sapl/lexml/OAIServer.py
  8. 20
      sapl/materia/forms.py
  9. 20
      sapl/materia/migrations/0045_auto_20190415_1050.py
  10. 22
      sapl/materia/views.py
  11. 10
      sapl/protocoloadm/forms.py
  12. 32
      sapl/protocoloadm/tests/test_protocoloadm.py
  13. 26
      sapl/protocoloadm/views.py
  14. 24
      sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py
  15. 15
      sapl/relatorios/views.py
  16. 33
      sapl/sessao/migrations/0037_auto_20190415_1324.py
  17. 13
      sapl/sessao/models.py
  18. 36
      sapl/sessao/views.py
  19. 7
      sapl/templates/base/layouts.yaml
  20. 160
      sapl/templates/sessao/votacao/votacao_bloco_expediente.html
  21. 168
      sapl/templates/sessao/votacao/votacao_bloco_ordem.html
  22. 84
      scripts/remove_multiplos_autores.py
  23. 13
      scripts/remove_protocolos_inexistentes_materias.py
  24. 14
      start.sh

1
Dockerfile

@ -39,6 +39,7 @@ RUN rm -rf /var/interlegis/sapl/sapl/.env && \
rm -rf /var/interlegis/sapl/sapl.db
RUN chmod +x /var/interlegis/sapl/start.sh && \
chmod +x /var/interlegis/sapl/check_solr.sh && \
ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log && \
mkdir /var/log/sapl/ && touch /var/interlegis/sapl/sapl.log && \

13
check_solr.sh

@ -4,15 +4,22 @@
SOLR_URL=$1
RETRY_COUNT=1
RETRY_LIMIT=4
echo "Waiting for solr connection at $SOLR_URL ..."
while true; do
while [[ $RETRY_COUNT < $RETRY_LIMIT ]]; do
echo "Attempt to connect to solr: $RETRY_COUNT of $RETRY_LIMIT"
let RETRY_COUNT=RETRY_COUNT+1;
echo "$SOLR_URL/solr/admin/collections?action=LIST"
RESULT=$(curl -s -o /dev/null -I "$SOLR_URL/solr/admin/collections?action=LIST" -w '%{http_code}')
echo $RESULT
if [ "$RESULT" -eq '200' ]; then
if [ $RESULT == 200 ]; then
echo "Solr server is up!"
break
exit 1
else
sleep 3
fi
done
echo "Solr connection failed."
exit 2

17
docker-compose.yml

@ -12,6 +12,7 @@ sapldb:
- "5432:5432"
sapl:
image: interlegis/sapl:3.1.153
# build: .
restart: always
environment:
ADMIN_PASSWORD: interlegis
@ -23,11 +24,27 @@ sapl:
EMAIL_HOST_USER: usuariosmtp
EMAIL_SEND_USER: usuariosmtp
EMAIL_HOST_PASSWORD: senhasmtp
# USE_SOLR: 'True'
# SOLR_COLLECTION: sapl
# SOLR_URL: http://saplsolr:8983
TZ: America/Sao_Paulo
volumes:
- sapl_data:/var/interlegis/sapl/data
- sapl_media:/var/interlegis/sapl/media
links:
- sapldb
# - saplsolr
ports:
- "80:80"
#saplsolr:
# image: solr:7.4-alpine
# restart: always
# command: bin/solr start -c -f
# volumes:
# - solr_data:/opt/solr/server/solr
# - solr_configsets:/opt/solr/server/solr/configsets
# ports:
# - "8983:8983"

20
sapl/base/migrations/0033_auto_20190415_1050.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-04-15 13:50
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0032_merge_20190219_0941'),
]
operations = [
migrations.AlterField(
model_name='appconfig',
name='sequencia_numeracao',
field=models.CharField(choices=[('A', 'Sequencial por ano para cada autor'), ('B', 'Sequencial por ano indepententemente do autor'), ('L', 'Sequencial por legislatura'), ('U', 'Sequencial único')], default='A', max_length=1, verbose_name='Sequência de numeração'),
),
]

3
sapl/base/models.py

@ -18,7 +18,8 @@ TIPO_DOCUMENTO_ADMINISTRATIVO = ((DOC_ADM_OSTENSIVO, _('Ostensiva')),
RELATORIO_ATOS_ACESSADOS = (('S', _('Sim')),
('N', _('Não')))
SEQUENCIA_NUMERACAO = (('A', _('Sequencial por ano')),
SEQUENCIA_NUMERACAO = (('A', _('Sequencial por ano para cada autor')),
('B', _('Sequencial por ano indepententemente do autor')),
('L', _('Sequencial por legislatura')),
('U', _('Sequencial único')))

4
sapl/compilacao/forms.py

@ -220,7 +220,7 @@ class NotaForm(ModelForm):
publicacao = forms.DateField(
label=Nota._meta.get_field('publicacao').verbose_name,
input_formats=['%d/%m/%Y'],
input_formats=['%d/%m/%Y', '%d%m%Y'],
required=True,
widget=forms.DateInput(
format='%d/%m/%Y'),
@ -228,7 +228,7 @@ class NotaForm(ModelForm):
)
efetividade = forms.DateField(
label=Nota._meta.get_field('efetividade').verbose_name,
input_formats=['%d/%m/%Y'],
input_formats=['%d/%m/%Y', '%d%m%Y'],
required=True,
widget=forms.DateInput(
format='%d/%m/%Y'),

37
sapl/lexml/OAIServer.py

@ -1,3 +1,4 @@
import unicodedata
from datetime import datetime
import oaipmh
@ -11,6 +12,7 @@ from lxml.builder import ElementMaker
from sapl.base.models import AppConfig, CasaLegislativa
from sapl.lexml.models import LexmlPublicador, LexmlProvedor
from sapl.norma.models import NormaJuridica
from sapl.utils import LISTA_DE_UFS
class OAILEXML:
@ -122,22 +124,33 @@ class OAIServer:
else:
return None
@staticmethod
def remove_acentos(linha):
res = unicodedata.normalize('NFKD', linha).encode('ASCII', 'ignore')
res = res.decode("UTF-8")
remove_list = ["\'", "\"", "-"]
for i in remove_list:
res = res.replace(i, "")
return res
def monta_urn(self, norma, esfera):
if norma:
urn = 'urn:lex:br;'
esferas = {'M': 'municipal', 'E': 'estadual'}
municipio = casa.municipio.lower()
uf = casa.uf.lower()
municipio = self.remove_acentos(casa.municipio.lower())
uf_map = dict(LISTA_DE_UFS)
uf_desc = uf_map.get(casa.uf.upper(), '').lower()
uf_desc = self.remove_acentos(uf_desc)
for x in [' ', '.de.', '.da.', '.das.', '.do.', '.dos.']:
municipio = municipio.replace(x, '.')
uf = uf.replace(x, '.')
uf_desc = uf_desc.replace(x, '.')
if esfera == 'M':
urn += '{};{}:'.format(uf, municipio)
urn += '{};{}:'.format(uf_desc, municipio)
if norma.tipo.equivalente_lexml == 'regimento.interno' or norma.tipo.equivalente_lexml == 'resolucao':
urn += 'camara.'
urn += esferas[esfera] + ':'
elif esfera == 'E':
urn += '{}:{}:'.format(uf, esferas[esfera])
urn += '{}:{}:'.format(uf_desc, esferas[esfera])
else:
urn += ':'
if norma.tipo.equivalente_lexml:
@ -166,11 +179,14 @@ class OAIServer:
return ''
def monta_xml(self, urn, norma):
BASE_URL_SAPL = self.config['base_url']
BASE_URL_SAPL = BASE_URL_SAPL[:BASE_URL_SAPL.find('/', 8)]
publicador = LexmlPublicador.objects.first()
if norma and publicador:
LEXML = ElementMaker(namespace=self.ns['lexml'], nsmap=self.ns)
oai_lexml = LEXML.LexML()
oai_lexml.attrib['{{}}schemaLocation'.format(self.XSI_NS)] = '{} {}'.format(
oai_lexml.attrib['{{{pre}}}schemaLocation'.format(pre=self.XSI_NS)] = '{} {}'.format(
'http://www.lexml.gov.br/oai_lexml', 'http://projeto.lexml.gov.br/esquemas/oai_lexml.xsd')
texto_integral = norma.texto_integral
mime_types = {'doc': 'application/msword',
@ -178,20 +194,21 @@ class OAIServer:
'odt': 'application/vnd.oasis.opendocument.text',
'pdf': 'application/pdf',
'rtf': 'application/rtf'}
if texto_integral:
url_conteudo = self.config['base_url'] + texto_integral.url
url_conteudo = BASE_URL_SAPL + texto_integral.url
extensao = texto_integral.url.split('.')[-1]
formato = mime_types.get(extensao, 'application/octet-stream')
else:
formato = 'text/html'
url_conteudo = self.config['base_url'] + reverse('sapl.norma:normajuridica_detail',
kwargs={'pk': norma.numero})
url_conteudo = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail',
kwargs={'pk': norma.pk})
element_maker = ElementMaker()
id_publicador = str(publicador.id_publicador)
item_conteudo = element_maker.Item(url_conteudo, formato=formato, idPublicador=id_publicador,
tipo='conteudo')
oai_lexml.append(item_conteudo)
url = self.config['base_url'] + reverse('sapl.norma:normajuridica_detail', kwargs={'pk': norma.numero})
url = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail', kwargs={'pk': norma.pk})
item_metadado = element_maker.Item(url, formato='text/html', idPublicador=id_publicador, tipo='metadado')
oai_lexml.append(item_metadado)
documento_individual = element_maker.DocumentoIndividual(urn)

20
sapl/materia/forms.py

@ -790,6 +790,13 @@ class AnexadaForm(ModelForm):
cleaned_data = self.cleaned_data
data_anexacao = cleaned_data['data_anexacao']
data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao
if data_anexacao > data_desanexacao:
self.logger.error("Data de anexação posterior à data de desanexação.")
raise ValidationError(_("Data de anexação posterior à data de desanexação."))
try:
self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={})."
.format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo']))
@ -1659,12 +1666,17 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
return super().save(commit)
inst.ano = timezone.now().year
numero__max = Proposicao.objects.filter(
autor=inst.autor,
ano=timezone.now().year).aggregate(Max('numero_proposicao'))
sequencia_numeracao = AppConfig.attr('sequencia_numeracao')
if sequencia_numeracao == 'A':
numero__max = Proposicao.objects.filter(
autor=inst.autor,
ano=timezone.now().year).aggregate(Max('numero_proposicao'))
elif sequencia_numeracao == 'B':
numero__max = Proposicao.objects.filter(
ano=timezone.now().year).aggregate(Max('numero_proposicao'))
numero__max = numero__max['numero_proposicao__max']
inst.numero_proposicao = (
numero__max + 1) if numero__max else 1
numero__max + 1) if numero__max else 1
self.gerar_hash(inst, receber_recibo)

20
sapl/materia/migrations/0045_auto_20190415_1050.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-04-15 13:50
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('materia', '0044_auto_20190327_1409'),
]
operations = [
migrations.AlterField(
model_name='tipomaterialegislativa',
name='sequencia_numeracao',
field=models.CharField(blank=True, choices=[('A', 'Sequencial por ano para cada autor'), ('B', 'Sequencial por ano indepententemente do autor'), ('L', 'Sequencial por legislatura'), ('U', 'Sequencial único')], max_length=1, verbose_name='Sequência de numeração'),
),
]

22
sapl/materia/views.py

@ -2112,19 +2112,31 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView):
def post(self, request, *args, **kwargs):
marcadas = request.POST.getlist('materia_id')
if len(marcadas) == 0:
msg = _('Nenhuma máteria foi selecionada.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
data_anexacao = datetime.strptime(
request.POST['data_anexacao'], "%d/%m/%Y").date()
if request.POST['data_desanexacao'] == '':
data_desanexacao = None
v_data_desanexacao = data_anexacao
else:
data_desanexacao = datetime.strptime(
request.POST['data_desanexacao'], "%d/%m/%Y").date()
v_data_desanexacao = data_desanexacao
if len(marcadas) == 0:
msg = _('Nenhuma máteria foi selecionada.')
messages.add_message(request, messages.ERROR, msg)
if data_anexacao > v_data_desanexacao:
msg = _('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
if data_anexacao > v_data_desanexacao:
msg = _('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
principal = MateriaLegislativa.objects.get(pk=kwargs['pk'])
for materia in MateriaLegislativa.objects.filter(id__in=marcadas):

10
sapl/protocoloadm/forms.py

@ -221,7 +221,7 @@ class DocumentoAdministrativoFilterSet(django_filters.FilterSet):
)
class AnularProcoloAdmForm(ModelForm):
class AnularProtocoloAdmForm(ModelForm):
logger = logging.getLogger(__name__)
@ -240,7 +240,7 @@ class AnularProcoloAdmForm(ModelForm):
widget=forms.Textarea)
def clean(self):
super(AnularProcoloAdmForm, self).clean()
super(AnularProtocoloAdmForm, self).clean()
cleaned_data = self.cleaned_data
@ -313,7 +313,7 @@ class AnularProcoloAdmForm(ModelForm):
form_actions(label='Anular')
)
)
super(AnularProcoloAdmForm, self).__init__(
super(AnularProtocoloAdmForm, self).__init__(
*args, **kwargs)
@ -811,8 +811,8 @@ class AnexadoForm(ModelForm):
data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao
if data_anexacao > data_desanexacao:
self.logger.error("A data de anexação não pode ser posterior a data de desanexação.")
raise ValidationError(_("A data de anexação não pode ser posterior a data de desanexação."))
self.logger.error("Data de anexação posterior à data de desanexação.")
raise ValidationError(_("Data de anexação posterior à data de desanexação."))
try:
self.logger.info(
"Tentando obter objeto DocumentoAdministrativo (numero={}, ano={}, tipo={})."

32
sapl/protocoloadm/tests/test_protocoloadm.py

@ -9,7 +9,7 @@ import pytest
from sapl.base.models import AppConfig
from sapl.materia.models import UnidadeTramitacao
from sapl.protocoloadm.forms import (AnularProcoloAdmForm,
from sapl.protocoloadm.forms import (AnularProtocoloAdmForm,
DocumentoAdministrativoForm,
MateriaLegislativa, ProtocoloDocumentForm,
ProtocoloMateriaForm)
@ -51,7 +51,7 @@ def test_anular_protocolo_submit(admin_client):
@pytest.mark.django_db(transaction=False)
def test_form_anular_protocolo_inexistente():
form = AnularProcoloAdmForm({'numero': '1',
form = AnularProtocoloAdmForm({'numero': '1',
'ano': '2016',
'justificativa_anulacao': 'TESTE'})
@ -64,7 +64,7 @@ def test_form_anular_protocolo_inexistente():
@pytest.mark.django_db(transaction=False)
def test_form_anular_protocolo_valido():
mommy.make(Protocolo, numero='1', ano='2016', anulado=False)
form = AnularProcoloAdmForm({'numero': '1',
form = AnularProtocoloAdmForm({'numero': '1',
'ano': '2016',
'justificativa_anulacao': 'TESTE'})
if not form.is_valid():
@ -74,7 +74,7 @@ def test_form_anular_protocolo_valido():
@pytest.mark.django_db(transaction=False)
def test_form_anular_protocolo_anulado():
mommy.make(Protocolo, numero='1', ano='2016', anulado=True)
form = AnularProcoloAdmForm({'numero': '1',
form = AnularProtocoloAdmForm({'numero': '1',
'ano': '2016',
'justificativa_anulacao': 'TESTE'})
assert form.errors['__all__'] == \
@ -88,7 +88,7 @@ def test_form_anular_protocolo_campos_obrigatorios():
# TODO: generalizar para diminuir o tamanho deste método
# numero ausente
form = AnularProcoloAdmForm({'numero': '',
form = AnularProtocoloAdmForm({'numero': '',
'ano': '2016',
'justificativa_anulacao': 'TESTE'})
if form.is_valid():
@ -98,7 +98,7 @@ def test_form_anular_protocolo_campos_obrigatorios():
assert form.errors['numero'] == [_('Este campo é obrigatório.')]
# ano ausente
form = AnularProcoloAdmForm({'numero': '1',
form = AnularProtocoloAdmForm({'numero': '1',
'ano': '',
'justificativa_anulacao': 'TESTE'})
if form.is_valid():
@ -108,7 +108,7 @@ def test_form_anular_protocolo_campos_obrigatorios():
assert form.errors['ano'] == [_('Este campo é obrigatório.')]
# justificativa_anulacao ausente
form = AnularProcoloAdmForm({'numero': '1',
form = AnularProtocoloAdmForm({'numero': '1',
'ano': '2016',
'justificativa_anulacao': ''})
if form.is_valid():
@ -261,7 +261,7 @@ def test_create_tramitacao(admin_client):
@pytest.mark.django_db(transaction=False)
def test_anular_protocolo_dados_invalidos():
form = AnularProcoloAdmForm(data={})
form = AnularProtocoloAdmForm(data={})
assert not form.is_valid()
@ -276,10 +276,10 @@ def test_anular_protocolo_dados_invalidos():
@pytest.mark.django_db(transaction=False)
def test_anular_protocolo_form_anula_protocolo_inexistente():
form = AnularProcoloAdmForm(data={'numero': '1',
form = AnularProtocoloAdmForm(data={'numero': '1',
'ano': '2017',
'justificativa_anulacao': 'teste'
})
})
assert not form.is_valid()
@ -291,10 +291,10 @@ def test_anular_protocolo_form_anula_protocolo_inexistente():
def test_anular_protocolo_form_anula_protocolo_anulado():
mommy.make(Protocolo, numero=1, ano=2017, anulado=True)
form = AnularProcoloAdmForm(data={'numero': '1',
form = AnularProtocoloAdmForm(data={'numero': '1',
'ano': '2017',
'justificativa_anulacao': 'teste'
})
})
assert not form.is_valid()
@ -316,10 +316,10 @@ def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado():
ano=2017,
numero_protocolo=1)
form = AnularProcoloAdmForm(data={'numero': '1',
form = AnularProtocoloAdmForm(data={'numero': '1',
'ano': '2017',
'justificativa_anulacao': 'teste'
})
})
assert not form.is_valid()
@ -338,10 +338,10 @@ def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado():
mommy.make(DocumentoAdministrativo,
protocolo=protocolo_documento)
form = AnularProcoloAdmForm(data={'numero': '2',
form = AnularProtocoloAdmForm(data={'numero': '2',
'ano': '2017',
'justificativa_anulacao': 'teste'
})
})
assert not form.is_valid()

26
sapl/protocoloadm/views.py

@ -37,7 +37,7 @@ from sapl.utils import (create_barcode, get_base_url, get_client_ip,
get_mime_type_from_file_extension,
show_results_filter_set, mail_service_configured)
from .forms import (AcompanhamentoDocumentoForm, AnularProcoloAdmForm,
from .forms import (AcompanhamentoDocumentoForm, AnularProtocoloAdmForm,
DocumentoAcessorioAdministrativoForm,
DocumentoAdministrativoFilterSet,
DocumentoAdministrativoForm, FichaPesquisaAdmForm, FichaSelecionaAdmForm, ProtocoloDocumentForm,
@ -484,7 +484,7 @@ class ProtocoloListView(PermissionRequiredMixin, ListView):
class AnularProtocoloAdmView(PermissionRequiredMixin, CreateView):
template_name = 'protocoloadm/anular_protocoloadm.html'
form_class = AnularProcoloAdmForm
form_class = AnularProtocoloAdmForm
form_valid_message = _('Protocolo anulado com sucesso!')
permission_required = ('protocoloadm.action_anular_protocolo', )
@ -1046,11 +1046,6 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
def post(self, request, *args, **kwargs):
marcados = request.POST.getlist('documento_id')
if len(marcados) == 0:
msg =_('Nenhum documento foi selecionado')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
data_anexacao = datetime.strptime(
request.POST['data_anexacao'], "%d/%m/%Y"
@ -1058,10 +1053,27 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
if request.POST['data_desanexacao'] == '':
data_desanexacao = None
v_data_desanexacao = data_anexacao
else:
data_desanexacao = datetime.strptime(
request.POST['data_desanexacao'], "%d/%m/%Y"
).date()
v_data_desanexacao = data_desanexacao
if len(marcados) == 0:
msg =_('Nenhum documento foi selecionado')
messages.add_message(request, messages.ERROR, msg)
if data_anexacao > v_data_desanexacao:
msg=_('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
if data_anexacao > v_data_desanexacao:
msg =_('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, messages.ERROR, msg)
principal = DocumentoAdministrativo.objects.get(pk = kwargs['pk'])
for documento in DocumentoAdministrativo.objects.filter(id__in = marcados):

24
sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py

@ -128,6 +128,24 @@ def inf_basicas(inf_basicas_dic):
return tmp
def multimidia(cont_mult_dic):
"""
"""
tmp = ""
mul_audio = cont_mult_dic['multimidia_audio']
mul_video = cont_mult_dic['multimidia_video']
tmp += '\t\t<para style="P1">Conteúdo Multimídia</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 += '\t\t<para style="P2" spaceAfter="5"><b>Audio: </b> ' + mul_audio + '</para>\n'
tmp += '\t\t<para style="P2" spaceAfter="5"><b>Video: </b> ' + mul_video + '</para>\n'
return tmp
def mesa(lst_mesa):
"""
@ -392,7 +410,7 @@ def ocorrencias(lst_ocorrencias):
return tmp
def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, lst_expedientes, lst_expediente_materia, lst_expediente_materia_vot_nom, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_votacao_vot_nom, lst_oradores_ordemdia, lst_oradores, lst_ocorrencias):
def principal(rodape_dic, imagem, inf_basicas_dic, cont_mult_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, lst_expedientes, lst_expediente_materia, lst_expediente_materia_vot_nom, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_votacao_vot_nom, lst_oradores_ordemdia, lst_oradores, lst_ocorrencias):
"""
"""
arquivoPdf = str(int(time.time() * 100)) + ".pdf"
@ -416,7 +434,7 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao
ordenacao = ResumoOrdenacao.objects.first()
dict_ord_template = {
'cont_mult': '',
'cont_mult': multimidia(cont_mult_dic),
'exp': expedientes(lst_expedientes),
'id_basica': inf_basicas(inf_basicas_dic),
'lista_p': presenca(lst_presenca_sessao, lst_ausencia_sessao),
@ -452,6 +470,7 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao
logger.error("KeyError: " + str(e) + ". Erro ao tentar utilizar "
"configuração de ordenação. Utilizando ordenação padrão.")
tmp += inf_basicas(inf_basicas_dic)
tmp += multimidia(cont_mult_dic)
tmp += mesa(lst_mesa)
tmp += presenca(lst_presenca_sessao, lst_ausencia_sessao)
tmp += expedientes(lst_expedientes)
@ -467,6 +486,7 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao
else:
tmp += inf_basicas(inf_basicas_dic)
tmp += multimidia(cont_mult_dic)
tmp += mesa(lst_mesa)
tmp += presenca(lst_presenca_sessao, lst_ausencia_sessao)
tmp += expedientes(lst_expedientes)

15
sapl/relatorios/views.py

@ -519,6 +519,18 @@ def get_sessao_plenaria(sessao, casa):
inf_basicas_dic["dat_fim_sessao"] = ''
inf_basicas_dic["hr_fim_sessao"] = sessao.hora_fim
inf_basicas_dic["nom_camara"] = casa.nome
# Conteudo multimidia
cont_mult_dic = {}
if sessao.url_audio:
cont_mult_dic['multimidia_audio'] = str(sessao.url_audio)
else:
cont_mult_dic['multimidia_audio'] = 'Indisponível'
if sessao.url_video:
cont_mult_dic['multimidia_video'] = str(sessao.url_video)
else:
cont_mult_dic['multimidia_video'] = 'Indisponível'
# Lista da composicao da mesa diretora
lst_mesa = []
@ -852,6 +864,7 @@ def get_sessao_plenaria(sessao, casa):
lst_ocorrencias.append(o)
return (inf_basicas_dic,
cont_mult_dic,
lst_mesa,
lst_presenca_sessao,
lst_ausencia_sessao,
@ -910,6 +923,7 @@ def relatorio_sessao_plenaria(request, pk):
raise Http404('Essa página não existe')
(inf_basicas_dic,
cont_mult_dic,
lst_mesa,
lst_presenca_sessao,
lst_ausencia_sessao,
@ -934,6 +948,7 @@ def relatorio_sessao_plenaria(request, pk):
rodape,
imagem,
inf_basicas_dic,
cont_mult_dic,
lst_mesa,
lst_presenca_sessao,
lst_ausencia_sessao,

33
sapl/sessao/migrations/0037_auto_20190415_1324.py

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-04-15 16:24
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('sessao', '0036_auto_20190412_1106'),
]
operations = [
migrations.AddField(
model_name='registrovotacao',
name='data_hora',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Data/Hora'),
),
migrations.AddField(
model_name='registrovotacao',
name='ip',
field=models.CharField(blank=True, default='', max_length=30, verbose_name='IP'),
),
migrations.AddField(
model_name='registrovotacao',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
),
]

13
sapl/sessao/models.py

@ -456,6 +456,19 @@ class RegistroVotacao(models.Model):
verbose_name=_('Abstenções'))
observacao = models.TextField(
blank=True, verbose_name=_('Observações'))
user = models.ForeignKey(get_settings_auth_user_model(),
on_delete=models.PROTECT,
null=True,
blank=True)
ip = models.CharField(verbose_name=_('IP'),
max_length=30,
blank=True,
default='')
data_hora = models.DateTimeField(
verbose_name=_('Data/Hora'),
auto_now_add=True,
blank=True,
null=True)
class Meta:
verbose_name = _('Votação')

36
sapl/sessao/views.py

@ -35,7 +35,7 @@ from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato,
Parlamentar, SessaoLegislativa)
from sapl.sessao.apps import AppConfig
from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm
from sapl.utils import show_results_filter_set, remover_acentos
from sapl.utils import show_results_filter_set, remover_acentos, get_client_ip
from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, BlocoForm,
ExpedienteForm, JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm,
@ -2163,6 +2163,8 @@ class VotacaoView(SessaoPermissionMixin):
votacao.ordem_id = ordem_id
votacao.tipo_resultado_votacao_id = int(
request.POST['resultado_votacao'])
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save()
except Exception as e:
username = request.user.username
@ -2383,6 +2385,8 @@ class VotacaoNominalAbstract(SessaoPermissionMixin):
votacao.numero_votos_nao = votos_nao
votacao.numero_abstencoes = abstencoes
votacao.observacao = request.POST.get('observacao', None)
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.materia_id = materia_votacao.materia.id
if self.ordem:
@ -2410,6 +2414,8 @@ class VotacaoNominalAbstract(SessaoPermissionMixin):
voto_parlamentar.voto = voto
voto_parlamentar.parlamentar_id = parlamentar_id
voto_parlamentar.votacao_id = votacao.id
voto_parlamentar.user = request.user
voto_parlamentar.ip = get_client_ip(request)
voto_parlamentar.save()
resultado = form.cleaned_data['resultado_votacao']
@ -2847,10 +2853,10 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
if (int(request.POST['voto_presidente']) == 0):
qtde_presentes -= 1
if (qtde_votos > qtde_presentes or qtde_votos < qtde_presentes):
if qtde_votos != qtde_presentes:
form._errors["total_votos"] = ErrorList([u""])
return self.render_to_response(context)
elif (qtde_presentes == qtde_votos):
else:
try:
votacao = RegistroVotacao()
votacao.numero_votos_sim = int(request.POST['votos_sim'])
@ -2861,6 +2867,8 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
votacao.expediente_id = expediente_id
votacao.tipo_resultado_votacao_id = int(
request.POST['resultado_votacao'])
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save()
except Exception as e:
username = request.user.username
@ -3544,9 +3552,13 @@ class VotacaoEmBlocoExpediente(PermissionRequiredForAppCrudMixin, ListView):
def get_context_data(self, **kwargs):
context = super(VotacaoEmBlocoExpediente,
self).get_context_data(**kwargs)
context['turno_choices'] = Tramitacao.TURNO_CHOICES
context['pk'] = self.kwargs['pk']
context['root_pk'] = self.kwargs['pk']
if not verifica_sessao_iniciada(self.request, self.kwargs['pk']):
context['sessao_iniciada'] = False
return context
context['sessao_iniciada'] = True
context['turno_choices'] = Tramitacao.TURNO_CHOICES
context['title'] = SessaoPlenaria.objects.get(id=self.kwargs['pk'])
return context
@ -3566,9 +3578,13 @@ class VotacaoEmBlocoOrdemDia(PermissionRequiredForAppCrudMixin, ListView):
def get_context_data(self, **kwargs):
context = super(VotacaoEmBlocoOrdemDia,
self).get_context_data(**kwargs)
context['turno_choices'] = Tramitacao.TURNO_CHOICES
context['pk'] = self.kwargs['pk']
context['root_pk'] = self.kwargs['pk']
if not verifica_sessao_iniciada(self.request, self.kwargs['pk']):
context['sessao_iniciada'] = False
return context
context['sessao_iniciada'] = True
context['turno_choices'] = Tramitacao.TURNO_CHOICES
context['title'] = SessaoPlenaria.objects.get(id=self.kwargs['pk'])
return context
@ -3640,6 +3656,8 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie
resultado = TipoResultadoVotacao.objects.get(
id=request.POST['resultado_votacao'])
votacao.tipo_resultado_votacao = resultado
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save()
except Exception as e:
username = request.user.username
@ -3671,6 +3689,8 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie
resultado = TipoResultadoVotacao.objects.get(
id=request.POST['resultado_votacao'])
votacao.tipo_resultado_votacao = resultado
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save()
except Exception as e:
username = request.user.username
@ -3862,6 +3882,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView)
voto_parlamentar.voto = voto
voto_parlamentar.parlamentar_id = parlamentar_id
voto_parlamentar.votacao_id = votacao.id
voto_parlamentar.user = request.user
voto_parlamentar.ip = get_client_ip(request)
voto_parlamentar.save()
ordem.resultado = form.cleaned_data['resultado_votacao'].nome
@ -3889,6 +3911,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView)
votacao.materia = expediente.materia
votacao.expediente = expediente
votacao.tipo_resultado_votacao = form.cleaned_data['resultado_votacao']
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save()
# Salva os votos de cada parlamentar
@ -3904,6 +3928,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView)
voto_parlamentar.voto = voto
voto_parlamentar.parlamentar_id = parlamentar_id
voto_parlamentar.votacao_id = votacao.id
voto_parlamentar.user = request.user
voto_parlamentar.ip = get_client_ip(request)
voto_parlamentar.save()
expediente.resultado = form.cleaned_data['resultado_votacao'].nome

7
sapl/templates/base/layouts.yaml

@ -18,8 +18,8 @@ AppConfig:
- esfera_federacao
{% trans 'Proposições e Protocolo' %}:
- sequencia_numeracao proposicao_incorporacao_obrigatoria receber_recibo_proposicao
- escolher_numero_materia_proposicao protocolo_manual
- sequencia_numeracao protocolo_manual receber_recibo_proposicao
- proposicao_incorporacao_obrigatoria escolher_numero_materia_proposicao
{% trans 'Textos Articulados' %}:
- texto_articulado_proposicao texto_articulado_materia texto_articulado_norma
@ -31,7 +31,8 @@ AppConfig:
- assinatura_ata
{% trans 'Cronômetros do Painel' %}:
- cronometro_discurso cronometro_aparte cronometro_ordem cronometro_consideracoes
- cronometro_discurso cronometro_aparte
- cronometro_ordem cronometro_consideracoes
{% trans 'Configurações do Painel' %}:
- mostrar_brasao_painel

160
sapl/templates/sessao/votacao/votacao_bloco_expediente.html

@ -3,94 +3,96 @@
{% block base_content %}
<form method="POST" enctype="application/x-www-form-urlencoded" id="form" action="{% url 'sapl.sessao:votacaoblocosimb' pk %}">
{% csrf_token %}
<br><br>
<table class="table table-striped table-bordered">
<thead class="thead-default">
{% if sessao_iniciada %}
<form method="POST" enctype="application/x-www-form-urlencoded" id="form" action="{% url 'sapl.sessao:votacaoblocosimb' pk %}">
{% csrf_token %}
<br><br>
<table class="table table-striped table-bordered">
<thead class="thead-default">
<tr>
<td><h3>{% trans "Tipo de Votação" %}</h3></td>
</tr>
</thead>
<tr>
<td><h3>{% trans "Tipo de Votação" %}</h3></td>
</tr>
</thead>
<tr>
<td class="col-md-12">
<fieldset id="tipo_votacao" name="tipo">
<input type="radio" name="tipo_votacao" id="tipo_votacao_1" value="1" onchange="alteraTipoVotacao()" checked="checked"> <label for="tipo">Simbólica</label>
</br>
<input type="radio" name="tipo_votacao" id="tipo_votacao_2" value="2" onchange="alteraTipoVotacao()" > <label for="tipo">Nominal</label>
</br>
</fieldset>
</td>
</tr>
</table>
<br>
<h3 id='frase_selecione'>Selecione o(s) expediente(s) desejado(s).</h3>
<table id='tab_ordens' class="table table-striped table-bordered">
<thead class="thead-default">
<tr>
<td><h3>{% trans "Expediente" %}</h3></td>
<td class="col-md-12">
<fieldset id="tipo_votacao" name="tipo">
<input type="radio" name="tipo_votacao" id="tipo_votacao_1" value="1" onchange="alteraTipoVotacao()" checked="checked"> <label for="tipo">Simbólica</label>
</br>
<input type="radio" name="tipo_votacao" id="tipo_votacao_2" value="2" onchange="alteraTipoVotacao()" > <label for="tipo">Nominal</label>
</br>
</fieldset>
</td>
</tr>
</thead>
</table>
<br>
<h3 id='frase_selecione'>Selecione o(s) expediente(s) desejado(s).</h3>
<table id='tab_ordens' class="table table-striped table-bordered">
<thead class="thead-default">
<tr>
<td><h3>{% trans "Expediente" %}</h3></td>
</tr>
</thead>
<div class="checkbox" id="check_all">
<label for="id_check_all">
<input type="checkbox" id="id_check_all" onchange="checkAll(this)" /> Marcar/Desmarcar Todos
</label>
</div>
<div class="checkbox" id="check_all">
<label for="id_check_all">
<input type="checkbox" id="id_check_all" onchange="checkAll(this)" /> Marcar/Desmarcar Todos
</label>
</div>
{% for o in expedientes %}
{% if o.tipo_votacao == 1 or o.tipo_votacao == 2 %}
<tr class="{% if o.tipo_votacao == 1 %}Simbolica{% else %}Nominal{% endif %}" {% if o.tipo_votacao == 2 %} style="display:none;" {% endif %}>
<td>
<input type="checkbox" name="marcadas_{{o.tipo_votacao}}" id="{{o.id}}" value="{{o.id}}" {% if check %} checked {% endif %}>
<strong><a href="{% url 'sapl.materia:materialegislativa_detail' o.id %}">{{o.materia.tipo.sigla}} {{o.materia.numero}}/{{o.materia.ano}} - {{o.materia.tipo}}</strong></a></br>
{% if o.materia.numeracao_set.last %}
<strong>Processo:</strong> &nbsp; {{o.materia.numeracao_set.last}}</br>
{% endif %}
<strong>Autor:</strong>
{% for a in o.materia.autoria_set.all %}
{% if not forloop.first %}
, &nbsp;&nbsp; {{a.autor|default_if_none:""}}
{% else %}
&nbsp;{{a.autor|default_if_none:""}}
{% for o in expedientes %}
{% if o.tipo_votacao == 1 or o.tipo_votacao == 2 %}
<tr class="{% if o.tipo_votacao == 1 %}Simbolica{% else %}Nominal{% endif %}" {% if o.tipo_votacao == 2 %} style="display:none;" {% endif %}>
<td>
<input type="checkbox" name="marcadas_{{o.tipo_votacao}}" id="{{o.id}}" value="{{o.id}}" {% if check %} checked {% endif %}>
<strong><a href="{% url 'sapl.materia:materialegislativa_detail' o.id %}">{{o.materia.tipo.sigla}} {{o.materia.numero}}/{{o.materia.ano}} - {{o.materia.tipo}}</strong></a></br>
{% if o.materia.numeracao_set.last %}
<strong>Processo:</strong> &nbsp; {{o.materia.numeracao_set.last}}</br>
{% endif %}
{% endfor %}
</br>
{% if o.materia.numero_protocolo %}
<strong>Protocolo:</strong> &nbsp; {{o.materia.numero_protocolo}}</br>
{% endif %}
{% if o.materia.tramitacao_set.last %}
{% if o.materia.tramitacao_set.last.turno %}
<strong>Turno:</strong>&nbsp;
{% for t in turno_choices %}
{% if t.0 == o.materia.tramitacao_set.last.turno %}
{{ t.1 }}
{% endif %}
{% endfor %}</br>
<strong>Autor:</strong>
{% for a in o.materia.autoria_set.all %}
{% if not forloop.first %}
, &nbsp;&nbsp; {{a.autor|default_if_none:""}}
{% else %}
&nbsp;{{a.autor|default_if_none:""}}
{% endif %}
{% endfor %}
</br>
{% if o.materia.numero_protocolo %}
<strong>Protocolo:</strong> &nbsp; {{o.materia.numero_protocolo}}</br>
{% endif %}
{% if o.materia.tramitacao_set.last %}
{% if o.materia.tramitacao_set.last.turno %}
<strong>Turno:</strong>&nbsp;
{% for t in turno_choices %}
{% if t.0 == o.materia.tramitacao_set.last.turno %}
{{ t.1 }}
{% endif %}
{% endfor %}</br>
{% endif %}
{% endif %}
{% endif %}
<strong>Ementa:</strong>&nbsp;{{ o.ementa|safe }}</br>
<p></p>
</td>
</tr>
{% endif %}
{% endfor %}
</table>
<strong>Ementa:</strong>&nbsp;{{ o.ementa|safe }}</br>
<p></p>
</td>
</tr>
{% endif %}
{% endfor %}
</table>
<table class="table table-striped table-bordered" style="display:none" id="nenhum_exp">
<tr>
<td>
<h3>Nenhuma matéria do expediente aberta.</h3>
</td>
</tr>
</table>
<table class="table table-striped table-bordered" style="display:none" id="nenhum_exp">
<tr>
<td>
<h3>Nenhuma matéria do expediente aberta.</h3>
</td>
</tr>
</table>
<a href="{% url 'sapl.sessao:expedientemateria_list' pk %}" class="btn btn-warning mb-3" id="but_cancel">Voltar</a>
<input type="submit" value="Registrar votação" class="btn btn-primary mb-3 float-right" id="but_reg">
<a href="{% url 'sapl.sessao:expedientemateria_list' pk %}" class="btn btn-warning mb-3" id="but_cancel">Voltar</a>
<input type="submit" value="Registrar votação" class="btn btn-primary mb-3 float-right" id="but_reg">
<input type="hidden" id="origem" name="origem" value="expediente">
</form>
<input type="hidden" id="origem" name="origem" value="expediente">
</form>
{% endif %}
{% endblock base_content %}

168
sapl/templates/sessao/votacao/votacao_bloco_ordem.html

@ -3,94 +3,96 @@
{% block base_content %}
<form method="POST" enctype="application/x-www-form-urlencoded" id="form" action="{% url 'sapl.sessao:votacaoblocosimb' pk %}">
{% csrf_token %}
<br><br>
<table class="table table-striped table-bordered">
{% if sessao_iniciada %}
<form method="POST" enctype="application/x-www-form-urlencoded" id="form" action="{% url 'sapl.sessao:votacaoblocosimb' pk %}">
{% csrf_token %}
<br><br>
<table class="table table-striped table-bordered">
<thead class="thead-default">
<tr>
<td><h3>{% trans "Tipo de Votação" %}</h3></td>
</tr>
</thead>
<tr>
<td class="col-md-12">
<fieldset id="tipo_votacao" name="tipo">
<input type="radio" name="tipo_votacao" id="tipo_votacao_1" value="1" onchange="alteraTipoVotacao()" checked="checked"> <label for="tipo">Simbólica</label>
</br>
<input type="radio" name="tipo_votacao" id="tipo_votacao_2" value="2" onchange="alteraTipoVotacao()" > <label for="tipo">Nominal</label>
</br>
</fieldset>
</td>
</tr>
</table>
<br>
<h3 id='frase_selecione'>Selecione a(s) ordem(s) do dia desejada(s).</h3>
<table id='tab_ordens' class="table table-striped table-bordered">
<thead class="thead-default">
<tr>
<td><h3>{% trans "Tipo de Votação" %}</h3></td>
</tr>
<tr>
<td><h3>{% trans "Ordem do dia" %}</h3></td>
</tr>
</thead>
<tr>
<td class="col-md-12">
<fieldset id="tipo_votacao" name="tipo">
<input type="radio" name="tipo_votacao" id="tipo_votacao_1" value="1" onchange="alteraTipoVotacao()" checked="checked"> <label for="tipo">Simbólica</label>
</br>
<input type="radio" name="tipo_votacao" id="tipo_votacao_2" value="2" onchange="alteraTipoVotacao()" > <label for="tipo">Nominal</label>
<div class="checkbox" id="check_all">
<label for="id_check_all">
<input type="checkbox" id="id_check_all" onchange="checkAll(this)" /> Marcar/Desmarcar Todos
</label>
</div>
{% for o in ordem_dia %}
{% if o.tipo_votacao == 1 or o.tipo_votacao == 2 %}
<tr class="{% if o.tipo_votacao == 1 %}Simbolica{% else %}Nominal{% endif %}" {% if o.tipo_votacao == 2 %} style="display:none;" {% endif %}>
<td>
<input type="checkbox" name="marcadas_{{o.tipo_votacao}}" id="{{o.id}}" value="{{o.id}}" {% if check %} checked {% endif %}>
<strong><a href="{% url 'sapl.materia:materialegislativa_detail' o.id %}">{{o.materia.tipo.sigla}} {{o.materia.numero}}/{{o.materia.ano}} - {{o.materia.tipo}}</strong></a></br>
{% if o.materia.numeracao_set.last %}
<strong>Processo:</strong> &nbsp; {{o.materia.numeracao_set.last}}</br>
{% endif %}
<strong>Autor:</strong>
{% for a in o.materia.autoria_set.all %}
{% if not forloop.first %}
, &nbsp;&nbsp; {{a.autor|default_if_none:""}}
{% else %}
&nbsp;{{a.autor|default_if_none:""}}
{% endif %}
{% endfor %}
</br>
</fieldset>
</td>
</tr>
</table>
<br>
<h3 id='frase_selecione'>Selecione a(s) ordem(s) do dia desejada(s).</h3>
<table id='tab_ordens' class="table table-striped table-bordered">
<thead class="thead-default">
<tr>
<td><h3>{% trans "Ordem do dia" %}</h3></td>
</tr>
</thead>
<div class="checkbox" id="check_all">
<label for="id_check_all">
<input type="checkbox" id="id_check_all" onchange="checkAll(this)" /> Marcar/Desmarcar Todos
</label>
</div>
{% for o in ordem_dia %}
{% if o.tipo_votacao == 1 or o.tipo_votacao == 2 %}
<tr class="{% if o.tipo_votacao == 1 %}Simbolica{% else %}Nominal{% endif %}" {% if o.tipo_votacao == 2 %} style="display:none;" {% endif %}>
<td>
<input type="checkbox" name="marcadas_{{o.tipo_votacao}}" id="{{o.id}}" value="{{o.id}}" {% if check %} checked {% endif %}>
<strong><a href="{% url 'sapl.materia:materialegislativa_detail' o.id %}">{{o.materia.tipo.sigla}} {{o.materia.numero}}/{{o.materia.ano}} - {{o.materia.tipo}}</strong></a></br>
{% if o.materia.numeracao_set.last %}
<strong>Processo:</strong> &nbsp; {{o.materia.numeracao_set.last}}</br>
{% endif %}
<strong>Autor:</strong>
{% for a in o.materia.autoria_set.all %}
{% if not forloop.first %}
, &nbsp;&nbsp; {{a.autor|default_if_none:""}}
{% else %}
&nbsp;{{a.autor|default_if_none:""}}
{% if o.materia.numero_protocolo %}
<strong>Protocolo:</strong> &nbsp; {{o.materia.numero_protocolo}}</br>
{% endif %}
{% endfor %}
</br>
{% if o.materia.numero_protocolo %}
<strong>Protocolo:</strong> &nbsp; {{o.materia.numero_protocolo}}</br>
{% endif %}
{% if o.materia.tramitacao_set.last %}
{% if o.materia.tramitacao_set.last.turno %}
<strong>Turno:</strong>&nbsp;
{% for t in turno_choices %}
{% if t.0 == o.materia.tramitacao_set.last.turno %}
{{ t.1 }}
{% endif %}
{% endfor %}</br>
{% if o.materia.tramitacao_set.last %}
{% if o.materia.tramitacao_set.last.turno %}
<strong>Turno:</strong>&nbsp;
{% for t in turno_choices %}
{% if t.0 == o.materia.tramitacao_set.last.turno %}
{{ t.1 }}
{% endif %}
{% endfor %}</br>
{% endif %}
{% endif %}
{% endif %}
<strong>Ementa:</strong>&nbsp;{{ o.ementa|safe }}</br>
<p></p>
</td>
</tr>
{% endif %}
{% endfor %}
</table>
<table class="table table-striped table-bordered" style="display:none" id="nenhuma_ordem">
<tr>
<td>
<h3>Nenhuma ordem do dia aberta.</h3>
</td>
</tr>
</table>
<a href="{% url 'sapl.sessao:ordemdia_list' pk %}" class="btn btn-warning mb-3" id="but_cancel">Voltar</a>
<input type="submit" value="Registrar votação" class="btn btn-primary mb-3 float-right" id="but_reg">
<input type="hidden" id="origem" name="origem" value="ordem">
</form>
<strong>Ementa:</strong>&nbsp;{{ o.ementa|safe }}</br>
<p></p>
</td>
</tr>
{% endif %}
{% endfor %}
</table>
<table class="table table-striped table-bordered" style="display:none" id="nenhuma_ordem">
<tr>
<td>
<h3>Nenhuma ordem do dia aberta.</h3>
</td>
</tr>
</table>
<a href="{% url 'sapl.sessao:ordemdia_list' pk %}" class="btn btn-warning mb-3" id="but_cancel">Voltar</a>
<input type="submit" value="Registrar votação" class="btn btn-primary mb-3 float-right" id="but_reg">
<input type="hidden" id="origem" name="origem" value="ordem">
</form>
{% endif %}
{% endblock base_content %}

84
scripts/remove_multiplos_autores.py

@ -0,0 +1,84 @@
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Count
from sapl.base.models import Autor
from sapl.parlamentares.models import Parlamentar
def pega_autores():
return [[autor for autor in Autor.objects.filter(nome=nome)]
for nome in Autor.objects.values_list('nome', flat=True).annotate(qntd=Count('nome')).filter(qntd__gt=1)]
def pega_parlamentares_autores():
parlamentares = [[parlamentar for parlamentar in Parlamentar.objects.filter(nome_parlamentar=nome_parlamentar)]
for nome_parlamentar in Parlamentar.objects.values_list('nome_parlamentar', flat=True)
.annotate(qntd=Count('nome_parlamentar')).filter(qntd__gt=1)]
parlamentares_autores = []
for parlamentar in parlamentares:
parlamentar_autor = []
for clone in parlamentar[1:]:
try:
autor_principal = Autor.objects.get(parlamentar_set=parlamentar[0])
except ObjectDoesNotExist:
try:
autor_clonado = Autor.objects.get(parlamentar_set=clone)
except ObjectDoesNotExist:
pass
else:
autor_clonado.object_id = parlamentar[0].id
autor_clonado.save()
parlamentares_autores.append(autor_clonado)
else:
if len(parlamentar_autor) == 0:
parlamentar_autor.append(autor_principal)
try:
autor_clonado = Autor.objects.get(parlamentar_set=clone)
except ObjectDoesNotExist:
pass
else:
parlamentar_autor.append(autor_clonado)
parlamentares_autores.extend(parlamentar_autor)
return parlamentares_autores
def transfere_valeres(autores):
for autor in autores:
for clone in autor[1:]:
for autoria in clone.autoria_set.all():
autoria.autor_id = autor[0]
autoria.save()
for proposicao in clone.proposicao_set.all():
proposicao.autor_id = autor[0]
proposicao.save()
for autorianorma in clone.autorianorma_set.all():
autorianorma.autor_id = autor[0]
autorianorma.save()
for documentoadministrativo in clone.documentoadministrativo_set.all():
documentoadministrativo.autor_id = autor[0]
documentoadministrativo.save()
for protocolo in clone.protocolo_set.all():
protocolo.autor_id = autor[0]
protocolo.save()
clone.delete()
def main():
autores = pega_autores()
parlamentares_autores = pega_parlamentares_autores()
autores.append(parlamentares_autores)
transfere_valeres(autores)
if __name__ == '__main__':
main()

13
scripts/remove_protocolos_inexistentes_materias.py

@ -0,0 +1,13 @@
from sapl.materia.models import MateriaLegislativa
from sapl.protocoloadm.models import Protocolo
def main():
for materia in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False):
if not Protocolo.objects.filter(ano=materia.ano, numero=materia.numero_protocolo).exists():
materia.numero_protocolo = None
materia.save()
if __name__ == '__main__':
main()

14
start.sh

@ -70,11 +70,19 @@ if [ "${USE_SOLR-False}" == "True" ] || [ "${USE_SOLR-False}" == "true" ]; then
echo "REPLICATION FACTOR: $RF"
echo "MAX SHARDS PER NODE: $MAX_SHARDS_PER_NODE"
echo "========================================="
echo "running solr script"
/bin/bash check_solr.sh $SOLR_URL
CHECK_SOLR_RETURN=$?
if [ $CHECK_SOLR_RETURN == 1 ]; then
echo "Connecting to solr..."
python3 solr_api.py -u $SOLR_URL -c $SOLR_COLLECTION -s $NUM_SHARDS -rf $RF -ms $MAX_SHARDS_PER_NODE &
# python3 manage.py rebuild_index --noinput &
else
echo "Solr is offline, not possible to connect."
fi
python3 solr_api.py -u $SOLR_URL -c $SOLR_COLLECTION -s $NUM_SHARDS -rf $RF -ms $MAX_SHARDS_PER_NODE &
# python3 manage.py rebuild_index --noinput &
else
echo "Suporte a SOLR não inicializado."
fi

Loading…
Cancel
Save