Browse Source

Merge branch '3.1.x' into 2536-criacao-mandato-parlamentar

pull/2551/head
Edward 7 years ago
committed by GitHub
parent
commit
dd0f14caaa
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      requirements/requirements.txt
  2. 55
      sapl/base/forms.py
  3. 13
      sapl/base/templatetags/common_tags.py
  4. 10
      sapl/base/views.py
  5. 1
      sapl/crispy_layout_mixin.py
  6. 24
      sapl/parlamentares/forms.py
  7. 8
      sapl/parlamentares/urls.py
  8. 73
      sapl/parlamentares/views.py
  9. 83
      sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py
  10. 53
      sapl/relatorios/views.py
  11. 66
      sapl/sessao/views.py
  12. 1
      sapl/static/sapl/css/global.e4ae5421.css
  13. BIN
      sapl/static/sapl/css/global.e4ae5421.css.gz
  14. 1
      sapl/static/sapl/js/compilacao.68b9eb03.js
  15. BIN
      sapl/static/sapl/js/compilacao.68b9eb03.js.gz
  16. 7
      sapl/static/sapl/js/global.eb461386.js
  17. BIN
      sapl/static/sapl/js/global.eb461386.js.gz
  18. 17
      sapl/templates/materia/impressos/ficha_adm_pdf.html
  19. 4
      sapl/templates/materia/materialegislativa_filter.html
  20. 31
      sapl/templates/norma/normajuridica_form.html
  21. 49
      sapl/templates/parlamentares/parlamentar_filter.html
  22. 4
      sapl/templates/parlamentares/parlamentares_list.html
  23. 9
      sapl/templates/parlamentares/partido_detail.html
  24. 42
      sapl/templates/parlamentares/partido_filiados.html
  25. 7
      sapl/templates/sessao/blocos_resumo/materias_expediente.html
  26. 4
      sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html
  27. 28
      sapl/templates/sessao/blocos_resumo/votos_nominais_materias_expediente.html
  28. 28
      sapl/templates/sessao/blocos_resumo/votos_nominais_materias_ordem_dia.html
  29. 6
      sapl/templates/sessao/resumo.html
  30. 41
      sapl/utils.py
  31. 2
      sapl/webpack-stats.json

1
requirements/requirements.txt

@ -24,6 +24,7 @@ rtyaml==0.0.5
python-magic==0.4.15
unipath==1.1
WeasyPrint==44
Pillow==5.1.0
gunicorn==19.9.0
textract==1.5.0

55
sapl/base/forms.py

@ -64,19 +64,46 @@ def get_roles():
class UsuarioCreateForm(ModelForm):
logger = logging.getLogger(__name__)
username = forms.CharField(required=True, label="Nome de usuário",
max_length=30)
firstname = forms.CharField(required=True, label="Nome", max_length=30)
lastname = forms.CharField(required=True, label="Sobrenome", max_length=30)
password1 = forms.CharField(required=True, widget=forms.PasswordInput,
label='Senha', max_length=128)
password2 = forms.CharField(required=True, widget=forms.PasswordInput,
label='Confirmar senha', max_length=128)
user_active = forms.ChoiceField(required=False, choices=YES_NO_CHOICES,
label="Usuário ativo?", initial='True')
username = forms.CharField(
required=True,
label="Nome de usuário",
max_length=30
)
firstname = forms.CharField(
required=True,
label="Nome",
max_length=30
)
lastname = forms.CharField(
required=True,
label="Sobrenome",
max_length=30
)
password1 = forms.CharField(
required=True,
widget=forms.PasswordInput,
label='Senha',
min_length=6,
max_length=128
)
password2 = forms.CharField(
required=True,
widget=forms.PasswordInput,
label='Confirmar senha',
min_length=6,
max_length=128
)
user_active = forms.ChoiceField(
required=True,
choices=YES_NO_CHOICES,
label="Usuário ativo?",
initial='True'
)
roles = forms.MultipleChoiceField(
required=True, widget=forms.CheckboxSelectMultiple(), choices=get_roles)
required=True,
widget=forms.CheckboxSelectMultiple(),
choices=get_roles
)
class Meta:
model = get_user_model()
@ -84,7 +111,7 @@ class UsuarioCreateForm(ModelForm):
'password1', 'password2', 'user_active', 'roles']
def clean(self):
super(UsuarioCreateForm, self).clean()
super().clean()
if not self.is_valid():
return self.cleaned_data
@ -99,7 +126,7 @@ class UsuarioCreateForm(ModelForm):
def __init__(self, *args, **kwargs):
super(UsuarioCreateForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
row0 = to_row([('username', 12)])

13
sapl/base/templatetags/common_tags.py

@ -1,3 +1,6 @@
from _functools import reduce
import re
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
@ -9,7 +12,6 @@ from sapl.norma.models import NormaJuridica
from sapl.parlamentares.models import Filiacao
from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO
register = template.Library()
@ -286,3 +288,12 @@ def render_chunk_vendors(extension=None):
return mark_safe('\n'.join(tags))
except:
return ''
@register.filter(is_safe=True)
@stringfilter
def dont_break_out(value):
_safe = '<div class="dont-break-out">{}</div>'.format(value)
_safe = mark_safe(_safe)
return _safe

10
sapl/base/views.py

@ -1329,17 +1329,19 @@ class CreateUsuarioView(PermissionRequiredMixin, CreateView):
model = get_user_model()
form_class = UsuarioCreateForm
success_message = 'Usuário criado com sucesso!'
fail_message = 'Usuário não criado!'
permission_required = ('base.add_appconfig',)
def get_success_url(self):
return reverse('sapl.base:usuario')
def form_valid(self, form):
data = form.cleaned_data
new_user = get_user_model().objects.create(
username=data['username'], email=data['email'])
username=data['username'],
email=data['email']
)
new_user.first_name = data['firstname']
new_user.last_name = data['lastname']
new_user.set_password(data['password1'])
@ -1354,6 +1356,10 @@ class CreateUsuarioView(PermissionRequiredMixin, CreateView):
messages.success(self.request, self.success_message)
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form):
messages.error(self.request, self.fail_message)
return super().form_invalid(form)
class DeleteUsuarioView(PermissionRequiredMixin, DeleteView):
model = get_user_model()

1
sapl/crispy_layout_mixin.py

@ -166,6 +166,7 @@ def get_field_display(obj, fieldname):
value)
elif 'TextField' in str_type_from_field:
display = value.replace('\n', '<br/>')
display = '<div class="dont-break-out">{}</div>'.format(display)
else:
display = str(value)
return verbose_name, display

24
sapl/parlamentares/forms.py

@ -20,6 +20,7 @@ from sapl.utils import FileFieldCheckMixin
from sapl.base.models import Autor, TipoAutor
from sapl.crispy_layout_mixin import form_actions, to_row
from sapl.rules import SAPL_GROUP_VOTANTE
import django_filters
from .models import (ComposicaoColigacao, Filiacao, Frente, Legislatura,
Mandato, Parlamentar, Votante)
@ -210,6 +211,29 @@ class ParlamentarForm(FileFieldCheckMixin, ModelForm):
attrs={'id': 'texto-rico'})}
class ParlamentarFilterSet(django_filters.FilterSet):
nome_parlamentar = django_filters.CharFilter(
label=_('Nome do Parlamentar'),
lookup_expr='icontains')
class Meta:
model = Parlamentar
fields = ['nome_parlamentar']
def __init__(self, *args, **kwargs):
super(ParlamentarFilterSet, self).__init__(*args, **kwargs)
row0 = to_row([('nome_parlamentar', 12)])
self.form.helper = SaplFormHelper()
self.form.helper.form_method = 'GET'
self.form.helper.layout = Layout(
Fieldset(_('Pesquisa de Parlamentar'),
row0,
form_actions(label='Pesquisar'))
)
class ParlamentarCreateForm(ParlamentarForm):
class Meta(ParlamentarForm.Meta):

8
sapl/parlamentares/urls.py

@ -18,7 +18,9 @@ from sapl.parlamentares.views import (CargoMesaCrud, ColigacaoCrud,
insere_parlamentar_composicao,
parlamentares_frente_selected,
remove_parlamentar_composicao,
lista_parlamentares)
lista_parlamentares,
parlamentares_filiados,
PesquisarParlamentarView)
from .apps import AppConfig
@ -36,6 +38,9 @@ urlpatterns = [
url(r'^parlamentar/lista$', lista_parlamentares, name='lista_parlamentares'),
url(r'^parlamentar/pesquisar-parlamentar/',
PesquisarParlamentarView.as_view(), name='pesquisar_parlamentar'),
url(r'^parlamentar/(?P<pk>\d+)/materias$',
ParlamentarMateriasView.as_view(), name='parlamentar_materias'),
@ -63,6 +68,7 @@ urlpatterns = [
url(r'^sistema/parlamentar/tipo-militar/',
include(TipoMilitarCrud.get_urls())),
url(r'^sistema/parlamentar/partido/', include(PartidoCrud.get_urls())),
url(r'^sistema/parlamentar/partido/(?P<pk>\d+)/filiados$', parlamentares_filiados, name='parlamentares_filiados'),
url(r'^sistema/mesa-diretora/sessao-legislativa/',
include(SessaoLegislativaCrud.get_urls())),

73
sapl/parlamentares/views.py

@ -18,20 +18,22 @@ from django.utils.translation import ugettext_lazy as _
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.generic import FormView
from django.views.generic.edit import UpdateView
from django_filters.views import FilterView
from image_cropping.utils import get_backend
from sapl.base.forms import SessaoLegislativaForm, PartidoForm
from sapl.base.models import Autor
from sapl.comissoes.models import Participacao
from sapl.crud.base import (RP_CHANGE, RP_DETAIL, RP_LIST, Crud, CrudAux,
CrudBaseForListAndDetailExternalAppView,
MasterDetailCrud)
MasterDetailCrud, make_pagination)
from sapl.materia.models import Autoria, Proposicao, Relatoria
from sapl.parlamentares.apps import AppConfig
from sapl.utils import parlamentares_ativos
from sapl.utils import (parlamentares_ativos, show_results_filter_set)
from .forms import (FiliacaoForm, FrenteForm, LegislaturaForm, MandatoForm,
ParlamentarCreateForm, ParlamentarForm, VotanteForm)
ParlamentarCreateForm, ParlamentarForm, VotanteForm, ParlamentarFilterSet)
from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa,
Dependente, Filiacao, Frente, Legislatura, Mandato,
NivelInstrucao, Parlamentar, Partido, SessaoLegislativa,
@ -165,6 +167,63 @@ class ProposicaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
_('Texto Eletrônico'))
class PesquisarParlamentarView(FilterView):
model = Parlamentar
filterset_class = ParlamentarFilterSet
paginate_by = 10
def get_filterset_kwargs(self, filterset_class):
super(PesquisarParlamentarView,
self).get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
qs = self.get_queryset().order_by('nome_parlamentar').distinct()
kwargs.update({
'queryset': qs,
})
return kwargs
def get_context_data(self, **kwargs):
context = super(PesquisarParlamentarView,
self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context['NO_ENTRIES_MSG'] = 'Nenhum parlamentar encontrado!'
context['title'] = _('Parlamentares')
return context
def get(self, request, *args, **kwargs):
super(PesquisarParlamentarView, self).get(request)
data = self.filterset.data
url = ''
if data:
url = "&" + str(self.request.environ['QUERY_STRING'])
if url.startswith("&page"):
ponto_comeco = url.find('nome_parlamentar=') - 1
url = url[ponto_comeco:]
context = self.get_context_data(filter=self.filterset,
object_list=self.object_list,
filter_url=url,
numero_res=len(self.object_list)
)
context['show_results'] = show_results_filter_set(
self.request.GET.copy())
return self.render_to_response(context)
class ParticipacaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
model = Participacao
parent_field = 'parlamentar'
@ -695,6 +754,14 @@ class ParlamentarMateriasView(FormView):
})
def parlamentares_filiados(request, pk):
template_name = 'parlamentares/partido_filiados.html'
parlamentares = Parlamentar.objects.select_related().all()
partido = Partido.objects.select_related().get(pk=pk)
parlamentares_filiado = [parlamentar for parlamentar in parlamentares if parlamentar.filiacao_atual == partido.sigla]
return render(request, template_name, {'partido': partido, 'parlamentares': parlamentares_filiado})
class MesaDiretoraView(FormView):
template_name = 'parlamentares/composicaomesa_form.html'
success_url = reverse_lazy('sapl.parlamentares:mesa_diretora')

83
sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py

@ -1,19 +1,18 @@
##parameters=rodape_dic, sessao='', imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao, lst_expedientes, lst_expediente_materia, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_oradores
# #parameters=rodape_dic, sessao='', imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao, lst_expedientes, lst_expediente_materia, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_oradores
"""Script para geração do PDF das sessoes plenarias
Autor: Gustavo Lepri
Atualizado por Luciano De Fázio - 22/03/2012
versão: 1.0
"""
import time
import os
import time
from django.template.defaultfilters import safe
from django.utils.html import strip_tags
from trml2pdf import parseString
from sapl.sessao.models import ResumoOrdenacao
from trml2pdf import parseString
def cabecalho(inf_basicas_dic, imagem):
"""
@ -145,7 +144,7 @@ def mesa(lst_mesa):
return tmp
def presenca(lst_presenca_sessao,lst_ausencia_sessao):
def presenca(lst_presenca_sessao, lst_ausencia_sessao):
"""
"""
@ -202,14 +201,18 @@ def expediente_materia(lst_expediente_materia):
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 += '<blockTable style="repeater" repeatRows="1" colWidths="3.5cm,11.5cm,3.5cm">>\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:
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>'+ expediente_materia['num_autores'] + ': </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;')
if len(txt_ementa) > 1000:
txt_ementa = txt_ementa[:1000] + "..."
# txt_ementa = dont_break_out(expediente_materia['txt_ementa'])
# if len(txt_ementa) > 800:
# txt_ementa = txt_ementa[:800] + "..."
tmp += '<td><para style="P4">' + txt_ementa + '</para>' + '<para style="P4">' + expediente_materia['ordem_observacao'] + '</para></td>\n'
tmp += '<td><para style="P3"><b>' + \
str(expediente_materia['nom_resultado']) + \
@ -224,6 +227,30 @@ def expediente_materia(lst_expediente_materia):
return tmp
def expediente_materia_vot_nom(lst_expediente_materia_vot_nom):
"""
"""
tmp = ''
tmp += '\t\t<para style="P1">Votações Nominais - Matérias do Expediente</para>\n\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 >Matéria</td><td>Votos</td></tr>\n'
for expediente_materia_vot_nom in lst_expediente_materia_vot_nom:
tmp += '<tr><td><para style="P3">' + str(expediente_materia_vot_nom['titulo']) + '</para></td>'
if expediente_materia_vot_nom['votos']:
tmp += '<td>'
for v in expediente_materia_vot_nom['votos']:
tmp += '<para style="P3"><b>' + str(v.parlamentar) + '</b> - ' + v.voto + '</para>'
tmp += '</td>'
else:
tmp += '<td><para style="P3"><b>Matéria não votada</b></para></td>'
tmp += '</tr>\n'
tmp += '\t\t</blockTable>\n'
return tmp
def oradores_expediente(lst_oradores_expediente):
"""
@ -271,7 +298,7 @@ def votacao(lst_votacao):
tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n'
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> ' + votacao[
'des_turno'] + '</para>\n' + '<para style="P3"><b>'+ votacao['num_autores'] +': </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;')
if len(txt_ementa) > 1000:
txt_ementa = txt_ementa[:1000] + "..."
@ -289,6 +316,30 @@ def votacao(lst_votacao):
return tmp
def votacao_vot_nom(lst_votacao_vot_nom):
"""
"""
tmp = ''
tmp += '\t\t<para style="P1">Votações Nominais - Matérias da Ordem do Dia</para>\n\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 >Matéria</td><td>Votos</td></tr>\n'
for votacao_vot_nom in lst_votacao_vot_nom:
tmp += '<tr><td><para style="P3">' + str(votacao_vot_nom['titulo']) + '</para></td>'
if votacao_vot_nom['votos']:
tmp += '<td>'
for v in votacao_vot_nom['votos']:
tmp += '<para style="P3"><b>' + str(v.parlamentar) + '</b> - ' + v.voto + '</para>'
tmp += '</td>'
else:
tmp += '<td><para style="P3"><b>Matéria não votada</b></para></td>'
tmp += '</tr>\n'
tmp += '\t\t</blockTable>\n'
return tmp
def oradores(lst_oradores):
"""
@ -323,7 +374,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_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_expediente_materia_vot_nom, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_votacao_vot_nom, lst_oradores, lst_ocorrencias):
"""
"""
arquivoPdf = str(int(time.time() * 100)) + ".pdf"
@ -349,10 +400,12 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao
'cont_mult': '',
'exp': expedientes(lst_expedientes),
'id_basica': inf_basicas(inf_basicas_dic),
'lista_p': presenca(lst_presenca_sessao,lst_ausencia_sessao),
'lista_p': presenca(lst_presenca_sessao, lst_ausencia_sessao),
'lista_p_o_d': presenca_ordem_dia(lst_presenca_ordem_dia),
'mat_exp': expediente_materia(lst_expediente_materia),
'v_n_mat_exp': expediente_materia_vot_nom(lst_expediente_materia_vot_nom),
'mat_o_d': votacao(lst_votacao),
'v_n_mat_o_d': votacao_vot_nom(lst_votacao_vot_nom),
'mesa_d': mesa(lst_mesa),
'oradores_exped': oradores_expediente(lst_oradores_expediente),
'oradores_expli': oradores(lst_oradores),
@ -371,16 +424,20 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao
tmp += dict_ord_template[ordenacao.nono]
tmp += dict_ord_template[ordenacao.decimo]
tmp += dict_ord_template[ordenacao.decimo_primeiro]
tmp += dict_ord_template[ordenacao.decimo_segundo]
tmp += dict_ord_template[ordenacao.decimo_terceiro]
else:
tmp += inf_basicas(inf_basicas_dic)
tmp += mesa(lst_mesa)
tmp += presenca(lst_presenca_sessao,lst_ausencia_sessao)
tmp += presenca(lst_presenca_sessao, lst_ausencia_sessao)
tmp += expedientes(lst_expedientes)
tmp += expediente_materia(lst_expediente_materia)
tmp += expediente_materia_vot_nom(lst_expediente_materia_vot_nom)
tmp += oradores_expediente(lst_oradores_expediente)
tmp += presenca_ordem_dia(lst_presenca_ordem_dia)
tmp += votacao(lst_votacao)
tmp += votacao_vot_nom(lst_votacao_vot_nom)
tmp += oradores(lst_oradores)
tmp += ocorrencias(lst_ocorrencias)

53
sapl/relatorios/views.py

@ -19,7 +19,8 @@ from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao,
IntegranteMesa, JustificativaAusencia,
Orador, OradorExpediente,
OrdemDia, PresencaOrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, OcorrenciaSessao)
SessaoPlenariaPresenca, OcorrenciaSessao,
RegistroVotacao, VotoParlamentar)
from sapl.settings import STATIC_ROOT
from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data
@ -633,6 +634,28 @@ def get_sessao_plenaria(sessao, casa):
dic_expediente_materia["votacao_observacao"] = ' '
lst_expediente_materia.append(dic_expediente_materia)
# Lista dos votos nominais das matérias do Expediente
lst_expediente_materia_vot_nom = []
materias_expediente_votacao_nominal = ExpedienteMateria.objects.filter(
sessao_plenaria=sessao,
tipo_votacao=2).order_by('-materia')
for mevn in materias_expediente_votacao_nominal:
votos_materia = []
titulo_materia = mevn.materia
registro = RegistroVotacao.objects.filter(expediente=mevn)
if registro:
for vp in VotoParlamentar.objects.filter(votacao=registro).order_by('parlamentar'):
votos_materia.append(vp)
dic_expediente_materia_vot_nom = {
'titulo': titulo_materia,
'votos': votos_materia
}
lst_expediente_materia_vot_nom.append(dic_expediente_materia_vot_nom)
# Lista dos oradores do Expediente
lst_oradores_expediente = []
for orador_expediente in OradorExpediente.objects.filter(
@ -722,6 +745,28 @@ def get_sessao_plenaria(sessao, casa):
dic_votacao["nom_resultado"] = "Matéria não votada"
lst_votacao.append(dic_votacao)
# Lista dos votos nominais das matérias da Ordem do Dia
lst_votacao_vot_nom = []
materias_ordem_dia_votacao_nominal = OrdemDia.objects.filter(
sessao_plenaria=sessao,
tipo_votacao=2).order_by('-materia')
for modvn in materias_ordem_dia_votacao_nominal:
votos_materia_od = []
t_materia = modvn.materia
registro_od = RegistroVotacao.objects.filter(ordem=modvn)
if registro_od:
for vp_od in VotoParlamentar.objects.filter(votacao=registro_od).order_by('parlamentar'):
votos_materia_od.append(vp_od)
dic_votacao_vot_nom = {
'titulo': t_materia,
'votos': votos_materia_od
}
lst_votacao_vot_nom.append(dic_votacao_vot_nom)
# Lista dos oradores nas Explicações Pessoais
lst_oradores = []
for orador in Orador.objects.filter(
@ -767,9 +812,11 @@ def get_sessao_plenaria(sessao, casa):
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,
lst_ocorrencias)
@ -822,9 +869,11 @@ def relatorio_sessao_plenaria(request, pk):
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,
lst_ocorrencias) = get_sessao_plenaria(sessao, casa)
@ -843,9 +892,11 @@ def relatorio_sessao_plenaria(request, pk):
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,
lst_ocorrencias)

66
sapl/sessao/views.py

@ -1419,6 +1419,29 @@ class ResumoView(DetailView):
context.update({'materia_expediente': materias_expediente})
# Votos de Votação Nominal de Matérias Expediente
materias_expediente_votacao_nominal = ExpedienteMateria.objects.filter(
sessao_plenaria_id=self.object.id,
tipo_votacao=2).order_by('-materia')
votacoes = []
for mevn in materias_expediente_votacao_nominal:
votos_materia = []
titulo_materia = mevn.materia
registro = RegistroVotacao.objects.filter(expediente=mevn)
if registro:
for vp in VotoParlamentar.objects.filter(votacao=registro).order_by('parlamentar'):
votos_materia.append(vp)
dados_votacao = {
'titulo': titulo_materia,
'votos': votos_materia
}
votacoes.append(dados_votacao)
context.update({'votos_nominais_materia_expediente': votacoes})
# =====================================================================
# Oradores Expediente
oradores = []
@ -1518,6 +1541,29 @@ class ResumoView(DetailView):
context.update({'materias_ordem': materias_ordem})
# Votos de Votação Nominal de Matérias Ordem do Dia
materias_ordem_dia_votacao_nominal = OrdemDia.objects.filter(
sessao_plenaria_id=self.object.id,
tipo_votacao=2).order_by('-materia')
votacoes_od = []
for modvn in materias_ordem_dia_votacao_nominal:
votos_materia_od = []
t_materia = modvn.materia
registro_od = RegistroVotacao.objects.filter(ordem=modvn)
if registro_od:
for vp_od in VotoParlamentar.objects.filter(votacao=registro_od).order_by('parlamentar'):
votos_materia_od.append(vp_od)
dados_votacao_od = {
'titulo': t_materia,
'votos': votos_materia_od
}
votacoes_od.append(dados_votacao_od)
context.update({'votos_nominais_materia_ordem_dia': votacoes_od})
# =====================================================================
# Oradores nas Explicações Pessoais
oradores_explicacoes = []
@ -1556,7 +1602,9 @@ class ResumoView(DetailView):
'lista_p': 'lista_presenca.html',
'lista_p_o_d': 'lista_presenca_ordem_dia.html',
'mat_exp': 'materias_expediente.html',
'v_n_mat_exp': 'votos_nominais_materias_expediente.html',
'mat_o_d': 'materias_ordem_dia.html',
'v_n_mat_o_d': 'votos_nominais_materias_ordem_dia.html',
'mesa_d': 'mesa_diretora.html',
'oradores_exped': 'oradores_expediente.html',
'oradores_expli': 'oradores_explicacoes.html',
@ -1575,7 +1623,10 @@ class ResumoView(DetailView):
'oitavo_ordenacao': dict_ord_template[ordenacao.oitavo],
'nono_ordenacao': dict_ord_template[ordenacao.nono],
'decimo_ordenacao': dict_ord_template[ordenacao.decimo],
'decimo_primeiro_ordenacao': dict_ord_template[ordenacao.decimo_primeiro]})
'decimo_primeiro_ordenacao': dict_ord_template[ordenacao.decimo_primeiro],
'decimo_segundo_ordenacao': dict_ord_template[ordenacao.decimo_segundo],
'decimo_terceiro_ordenacao': dict_ord_template[ordenacao.decimo_terceiro]})
else:
context.update(
{'primeiro_ordenacao': dict_ord_template['id_basica'],
@ -1584,11 +1635,14 @@ class ResumoView(DetailView):
'quarto_ordenacao': dict_ord_template['lista_p'],
'quinto_ordenacao': dict_ord_template['exp'],
'sexto_ordenacao': dict_ord_template['mat_exp'],
'setimo_ordenacao': dict_ord_template['oradores_exped'],
'oitavo_ordenacao': dict_ord_template['lista_p_o_d'],
'nono_ordenacao': dict_ord_template['mat_o_d'],
'decimo_ordenacao': dict_ord_template['oradores_expli'],
'decimo_primeiro_ordenacao': dict_ord_template['ocorr_sessao']})
'setimo_ordenacao': dict_ord_template['v_n_mat_exp'],
'oitavo_ordenacao': dict_ord_template['oradores_exped'],
'nono_ordenacao': dict_ord_template['lista_p_o_d'],
'decimo_ordenacao': dict_ord_template['mat_o_d'],
'decimo_primeiro_ordenacao': dict_ord_template['v_n_mat_o_d'],
'decimo_segundo_ordenacao': dict_ord_template['oradores_expli'],
'decimo_terceiro_ordenacao': dict_ord_template['ocorr_sessao']
})
return self.render_to_response(context)

1
sapl/static/sapl/css/global.e4ae5421.css

File diff suppressed because one or more lines are too long

BIN
sapl/static/sapl/css/global.e4ae5421.css.gz

Binary file not shown.

1
sapl/static/sapl/js/compilacao.68b9eb03.js

File diff suppressed because one or more lines are too long

BIN
sapl/static/sapl/js/compilacao.68b9eb03.js.gz

Binary file not shown.

7
sapl/static/sapl/js/global.eb461386.js

File diff suppressed because one or more lines are too long

BIN
sapl/static/sapl/js/global.eb461386.js.gz

Binary file not shown.

17
sapl/templates/materia/impressos/ficha_adm_pdf.html

@ -91,16 +91,25 @@ body
</table>
{% endif %}
<!-- Ementa -->
<!-- Assunto -->
<table border=0>
<td>
<div id="ementa_texto">
<strong class="text_pdf">Ementa:</strong> <span class="text_pdf">{{documento.assunto}}</span>
<div id="assunto_texto">
<strong class="text_pdf">Assunto:</strong> <span class="text_pdf">{{documento.assunto}}</span>
</div>
</td>
</table>
<!-- Interessado -->
{% if documento.interessado%}
<table border=0>
<td>
<div id="interessado_texto">
<strong class="text_pdf">Interessado:</strong> <span class="text_pdf">{{documento.interessado}}</span>
</div>
</td>
</table>
{% endif %}
</div>
</justify>

4
sapl/templates/materia/materialegislativa_filter.html

@ -1,6 +1,6 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% load crispy_forms_tags common_tags%}
{% block actions %}
@ -48,7 +48,7 @@
<td>
<strong><a href="{% url 'sapl.materia:materialegislativa_detail' m.id %}">{{m.tipo.sigla}} {{m.numero}}/{{m.ano}} - {{m.tipo}}</strong></a>
</br>
<strong>Ementa:</strong>&nbsp;{{ m.ementa|safe }}
<strong>Ementa:</strong>&nbsp;{{ m.ementa|dont_break_out }}
</br>
{% if m.data_apresentacao %}
<strong>Apresentação: </strong>{{ m.data_apresentacao }}

31
sapl/templates/norma/normajuridica_form.html

@ -7,33 +7,34 @@
<script language="Javascript">
function recuperar_materia() {
var tipo_materia = $("#id_tipo_materia").val()
var numero_materia = $("#id_numero_materia").val()
var ano_materia = $("#id_ano_materia").val()
var tipo = $('#id_tipo').val()
var ano = $('#id_ano').val()
var numero = $('#id_numero').val()
var ementa = $('#id_ementa').val()
var tipo_materia = $("#id_tipo_materia").val();
var numero_materia = $("#id_numero_materia").val();
var ano_materia = $("#id_ano_materia").val();
var tipo = $('#id_tipo').val();
var ano = $('#id_ano').val();
var numero = $('#id_numero').val();
var ementa = $('#id_ementa').val();
if (tipo_materia && numero_materia && ano_materia) {
if (ementa === undefined || ementa === "") {
$.get("/sessao/recuperar-materia",{tipo_materia: tipo_materia,
$.get("/sessao/recuperar-materia",
{tipo_materia: tipo_materia,
numero_materia: numero_materia,
ano_materia: ano_materia},
function(data, status) {
$("#id_ementa").val(data.ementa);
$("#id_indexacao").val(data.indexacao);
});
}
);
}
}
}
var fields = ["#id_tipo_materia", "#id_numero_materia", "#id_ano_materia"]
for (i = 0; i < fields.length; i++) {
$(fields[i]).change(recuperar_materia);
}
recuperar_materia();
function recuperar_norma() {
var tipo = $("#id_tipo").val()
var ano = $("#id_ano").val()
var tipo = $("#id_tipo").val();
var ano = $("#id_ano").val();
if (tipo) {
$.get("/norma/recuperar-numero-norma",{tipo: tipo,
@ -44,7 +45,7 @@
});
}
}
var fields = ["#id_tipo", "#id_ano"]
var fields = ["#id_tipo", "#id_ano"];
for (i = 0; i < fields.length; i++) {
$(fields[i]).change(recuperar_norma);
}

49
sapl/templates/parlamentares/parlamentar_filter.html

@ -0,0 +1,49 @@
{% extends "crud/list.html" %}
{% load i18n %}
{% load crispy_forms_tags staticfiles %}
{% block base_content %}
{% if not show_results %}
{% crispy filter.form %}
{% endif %}
{% if show_results %}
<div class="actions btn-group float-right" role="group">
<a href="{% url 'sapl.parlamentares:pesquisar_parlamentar' %}" class="btn btn-outline-primary">{% trans 'Fazer nova pesquisa' %}</a>
</div>
<br /><br />
{% if numero_res > 0 %}
{% if numero_res == 1 %}
<p>Foi encontrado {{ numero_res }} resultado</p>
{% else %}
<p>Foram encontrados {{ numero_res }} resultados</p>
{% endif %}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Nome do Parlamentar</th>
<th>Nome Completo</th>
<th>Ativo</th>
</tr>
</thead>
<tbody>
{% for usuario in page_obj %}
<tr>
<td>
<a href="{% url 'sapl.parlamentares:parlamentar_detail' usuario.pk %}">{{usuario.nome_parlamentar}}</a>
</td>
<td>{{ usuario.nome_completo }}</td>
<td>{% if usuario.ativo %} Sim {% else %} Não {% endif %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<font size="4"><p align="center">{{ NO_ENTRIES_MSG }}</p></font>
{% endif %}
{% endif %}
<br/>
{% include 'paginacao.html'%}
<br /><br /><br />
{% endblock base_content %}

4
sapl/templates/parlamentares/parlamentares_list.html

@ -2,6 +2,7 @@
{% load i18n %}
{% load crispy_forms_tags cropping%}
{% block actions %}
{{ block.super }}
<div class="actions btn-group float-right btn-group-lg" role="group">
{% if view.create_url %}
<a href="{% url 'sapl.parlamentares:lista_parlamentares' %}" class="btn btn-outline-primary">
@ -10,6 +11,9 @@
{% endif %}
{% block more_buttons %}{% endblock more_buttons %}
</div>
<div class="actions btn-group btn-group-sm" role="group">
<a href="{% url 'sapl.parlamentares:pesquisar_parlamentar' %}" class="btn btn-outline-primary">Pesquisar Parlamentares</a>
</div>
{% endblock actions %}
{% block extra_content %}
<fieldset class="form-group">

9
sapl/templates/parlamentares/partido_detail.html

@ -0,0 +1,9 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% load crispy_forms_tags cropping %}
{% block actions %}
{{ block.super }}
<div class="actions btn-group btn-group-sm" role="group">
<a href="{% url 'sapl.parlamentares:parlamentares_filiados' object.pk %}" class="btn btn-outline-primary">Listar Parlamentares Filiados</a>
</div>
{% endblock actions %}

42
sapl/templates/parlamentares/partido_filiados.html

@ -0,0 +1,42 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% load crispy_forms_tags cropping %}
{% block base_content %}
<h1>{{ partido.sigla }} - {{ partido.nome }}</h1>
<div class="actions btn-group btn-group-sm" role="group">
<a href="{% url 'sapl.parlamentares:partido_detail' partido.pk %}" class="btn btn-outline-primary">Informações do Partido</a>
</div>
<h2 class="legend">Parlamentares Filiados</h2>
<div class="result-count">Total de Parlamentares: <strong>{{ parlamentares|length }}</strong></div>
<div class="container-table lista-parlamentares">
<table class="table table-striped table-hover table-link-ordering">
<thead>
<tr>
<th>
Foto
</th>
<th>
Parlamentar
</th>
</tr>
</thead>
<tbody>
{% for parlamentar in parlamentares %}
<tr>
<td>
{% if parlamentar.fotografia %}
<div id="w-100">
<img class="img-fluid img-thumbnail" src="{% cropped_thumbnail parlamentar "cropping"%}">
</div>
{% endif %}
</td>
<td>
<a href="{% url 'sapl.parlamentares:parlamentar_detail' parlamentar.pk %}"> {{ parlamentar }} </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock base_content %}

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

@ -1,3 +1,5 @@
{% load common_tags %}
<fieldset>
<legend>Matérias do Expediente</legend>
<table class="table table-striped table-hover">
@ -33,7 +35,10 @@
<b>Processo:</b> {{ m.numero_processo }}
{% endif %}
</td>
<td>{{m.ementa|safe}}<br/>{{m.observacao}}</td>
<td>
{{m.ementa|dont_break_out}}<br/>
{{m.observacao|dont_break_out}}
</td>
<td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td>
</tr>
{% endfor %}

4
sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html

@ -1,3 +1,5 @@
{% load common_tags %}
<fieldset>
<legend>Matérias da Ordem do Dia</legend>
<table class="table table-striped table-hover">
@ -33,7 +35,7 @@
<b>Processo:</b> {{ m.numero_processo }}
{% endif %}
</td>
<td>{{m.ementa|safe}}</b><br/>{{m.ementa_observacao}}</td>
<td>{{m.ementa|dont_break_out}}</b><br/>{{m.observacao|dont_break_out}}</td>
<td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td>
</tr>
{% endfor %}

28
sapl/templates/sessao/blocos_resumo/votos_nominais_materias_expediente.html

@ -0,0 +1,28 @@
<fieldset>
<legend>Votações Nominais - Matérias do Expediente</legend>
</br>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Matéria</th>
<th>Votos</th>
</tr>
</thead>
<tbody>
{% for m in votos_nominais_materia_expediente %}
<tr>
<td>{{ m.titulo }}</td>
{% if m.votos %}
<td>
{% for v in m.votos %}
<li><b>{{v.parlamentar}}</b> - {{v.voto}}</li>
{% endfor %}
</td>
{% else %}
<td><b>Matéria não votada</b></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</fieldset>

28
sapl/templates/sessao/blocos_resumo/votos_nominais_materias_ordem_dia.html

@ -0,0 +1,28 @@
<fieldset>
<legend>Votações Nominais - Matérias da Ordem do Dia</legend>
</br>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Matéria</th>
<th>Votos</th>
</tr>
</thead>
<tbody>
{% for m in votos_nominais_materia_ordem_dia %}
<tr>
<td>{{ m.titulo }}</td>
{% if m.votos %}
<td>
{% for v in m.votos %}
<li><b>{{v.parlamentar}}</b> - {{v.voto}}</li>
{% endfor %}
</td>
{% else %}
<td><b>Matéria não votada</b></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</fieldset>

6
sapl/templates/sessao/resumo.html

@ -53,4 +53,10 @@
{% include 'sessao/blocos_resumo/'|add:decimo_primeiro_ordenacao %}
<br /><br /><br />
{% include 'sessao/blocos_resumo/'|add:decimo_segundo_ordenacao %}
<br /><br /><br />
{% include 'sessao/blocos_resumo/'|add:decimo_segundo_ordenacao %}
<br /><br /><br />
{% endblock detail_content %}

41
sapl/utils.py

@ -6,10 +6,6 @@ import re
from unicodedata import normalize as unicodedata_normalize
import unicodedata
from django.core.files.uploadedfile import UploadedFile
from django.forms import BaseForm
from sapl.crispy_layout_mixin import SaplFormHelper
from crispy_forms.layout import HTML, Button
from django import forms
from django.apps import apps
@ -18,11 +14,14 @@ from django.contrib import admin
from django.contrib.contenttypes.fields import (GenericForeignKey, GenericRel,
GenericRelation)
from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import UploadedFile
from django.core.mail import get_connection
from django.db import models
from django.db.models import Q
from django.forms import BaseForm
from django.forms.widgets import SplitDateTimeWidget
from django.utils import six, timezone
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
import django_filters
from easy_thumbnails import source_generators
@ -31,9 +30,9 @@ import magic
from reversion_compare.admin import CompareVersionAdmin
from unipath.path import Path
from sapl.crispy_layout_mixin import SaplFormHelper
from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
# (26/10/2018): O separador foi mudador de '/' para 'K'
# por conta dos leitores de códigos de barra, que trocavam
# a '/' por '&' ou ';'
@ -44,6 +43,24 @@ def pil_image(source, exif_orientation=False, **options):
return source_generators.pil_image(source, exif_orientation, **options)
def dont_break_out(value, max_part=50):
_safe = value.split()
def chunkstring(string):
return re.findall('.{%d}' % max_part, string)
def __map(a):
if len(a) <= max_part:
return a
return '<br>' + '<br>'.join(chunkstring(a))
_safe = map(__map, _safe)
_safe = ' '.join(_safe)
_safe = mark_safe(_safe)
return value
def clear_thumbnails_cache(queryset, field):
for r in queryset:
@ -84,7 +101,6 @@ autor_label = '''
</div>
'''
autor_modal = '''
<div id="modal_autor" title="Selecione o Autor" align="center">
<form>
@ -239,6 +255,7 @@ class RangeWidgetOverride(forms.MultiWidget):
class CustomSplitDateTimeWidget(SplitDateTimeWidget):
def render(self, name, value, attrs=None, renderer=None):
rendered_widgets = []
for i, x in enumerate(self.widgets):
@ -260,6 +277,7 @@ def register_all_models_in_admin(module_name, exclude_list=[]):
appname = appname[1] if appname[0] == 'sapl' else appname[0]
app = apps.get_app_config(appname)
for model in app.get_models():
class CustomModelAdmin(CompareVersionAdmin):
list_display = [f.name for f in model._meta.fields
if f.name != 'id' and f.name not in exclude_list]
@ -311,9 +329,11 @@ YES_NO_CHOICES = [(True, _('Sim')), (False, _('Não'))]
def listify(function):
@wraps(function)
def f(*args, **kwargs):
return list(function(*args, **kwargs))
return f
@ -351,7 +371,6 @@ LISTA_DE_UFS = [
RANGE_ANOS = [(year, year) for year in range(timezone.now().year + 1,
1889, -1)]
RANGE_MESES = [
(1, 'Janeiro'),
(2, 'Fevereiro'),
@ -431,8 +450,10 @@ def choice_force_optional(callable):
o item opcional '---------' que ChoiceFilter o adiciona, como dito
anteriormente.
"""
def _func():
return [('', '---------')] + callable()
return _func
@ -508,6 +529,7 @@ def fabrica_validador_de_tipos_de_arquivo(lista, nome):
raise ValidationError(_('Tipo de arquivo não suportado'))
except FileNotFoundError:
raise ValidationError(_('Arquivo não encontrado'))
# o nome é importante para as migrations
restringe_tipos_de_arquivo.__name__ = nome
return restringe_tipos_de_arquivo
@ -578,6 +600,7 @@ class NormaPesquisaOrderingFilter(django_filters.OrderingFilter):
class FileFieldCheckMixin(BaseForm):
def _check(self):
cleaned_data = super(FileFieldCheckMixin, self).clean()
errors = []
@ -626,7 +649,7 @@ class AnoNumeroOrderingFilter(django_filters.OrderingFilter):
return super().filter(qs, _value)
def gerar_hash_arquivo(arquivo, pk, block_size=2**20):
def gerar_hash_arquivo(arquivo, pk, block_size=2 ** 20):
md5 = hashlib.md5()
arq = open(arquivo, 'rb')
while True:
@ -727,7 +750,7 @@ def texto_upload_path(instance, filename, subpath='', pk_first=False):
if subpath is None:
subpath = '_'
path = str_path %\
path = str_path % \
{
'prefix': prefix,
'model_name': instance._meta.model_name,

2
sapl/webpack-stats.json

@ -1 +1 @@
{"status":"done","publicPath":"/static/sapl/","chunks":{"chunk-vendors":[{"name":"css/chunk-vendors.3c9fe6b4.css","publicPath":"/static/sapl/css/chunk-vendors.3c9fe6b4.css","path":"../sapl/sapl/static/sapl/css/chunk-vendors.3c9fe6b4.css"},{"name":"js/chunk-vendors.0003dc37.js","publicPath":"/static/sapl/js/chunk-vendors.0003dc37.js","path":"../sapl/sapl/static/sapl/js/chunk-vendors.0003dc37.js"},{"name":"css/chunk-vendors.3c9fe6b4.css.map","publicPath":"/static/sapl/css/chunk-vendors.3c9fe6b4.css.map","path":"../sapl/sapl/static/sapl/css/chunk-vendors.3c9fe6b4.css.map"}],"compilacao":[{"name":"css/compilacao.3372b760.css","publicPath":"/static/sapl/css/compilacao.3372b760.css","path":"../sapl/sapl/static/sapl/css/compilacao.3372b760.css"},{"name":"js/compilacao.68b9eb03.js","publicPath":"/static/sapl/js/compilacao.68b9eb03.js","path":"../sapl/sapl/static/sapl/js/compilacao.68b9eb03.js"},{"name":"css/compilacao.3372b760.css.map","publicPath":"/static/sapl/css/compilacao.3372b760.css.map","path":"../sapl/sapl/static/sapl/css/compilacao.3372b760.css.map"}],"global":[{"name":"css/global.e4ae5421.css","publicPath":"/static/sapl/css/global.e4ae5421.css","path":"../sapl/sapl/static/sapl/css/global.e4ae5421.css"},{"name":"js/global.eb461386.js","publicPath":"/static/sapl/js/global.eb461386.js","path":"../sapl/sapl/static/sapl/js/global.eb461386.js"},{"name":"css/global.e4ae5421.css.map","publicPath":"/static/sapl/css/global.e4ae5421.css.map","path":"../sapl/sapl/static/sapl/css/global.e4ae5421.css.map"}],"painel":[{"name":"css/painel.baa845ab.css","publicPath":"/static/sapl/css/painel.baa845ab.css","path":"../sapl/sapl/static/sapl/css/painel.baa845ab.css"},{"name":"js/painel.f4adb91b.js","publicPath":"/static/sapl/js/painel.f4adb91b.js","path":"../sapl/sapl/static/sapl/js/painel.f4adb91b.js"},{"name":"css/painel.baa845ab.css.map","publicPath":"/static/sapl/css/painel.baa845ab.css.map","path":"../sapl/sapl/static/sapl/css/painel.baa845ab.css.map"}]}}
{"status":"done","publicPath":"/static/sapl/","chunks":{"chunk-vendors":[{"name":"css/chunk-vendors.3c9fe6b4.css","publicPath":"/static/sapl/css/chunk-vendors.3c9fe6b4.css","path":"../sapl/sapl/static/sapl/css/chunk-vendors.3c9fe6b4.css"},{"name":"js/chunk-vendors.0003dc37.js","publicPath":"/static/sapl/js/chunk-vendors.0003dc37.js","path":"../sapl/sapl/static/sapl/js/chunk-vendors.0003dc37.js"},{"name":"css/chunk-vendors.3c9fe6b4.css.map","publicPath":"/static/sapl/css/chunk-vendors.3c9fe6b4.css.map","path":"../sapl/sapl/static/sapl/css/chunk-vendors.3c9fe6b4.css.map"}],"compilacao":[{"name":"css/compilacao.3372b760.css","publicPath":"/static/sapl/css/compilacao.3372b760.css","path":"../sapl/sapl/static/sapl/css/compilacao.3372b760.css"},{"name":"js/compilacao.c9cbd558.js","publicPath":"/static/sapl/js/compilacao.c9cbd558.js","path":"../sapl/sapl/static/sapl/js/compilacao.c9cbd558.js"},{"name":"css/compilacao.3372b760.css.map","publicPath":"/static/sapl/css/compilacao.3372b760.css.map","path":"../sapl/sapl/static/sapl/css/compilacao.3372b760.css.map"}],"global":[{"name":"css/global.f7113e2c.css","publicPath":"/static/sapl/css/global.f7113e2c.css","path":"../sapl/sapl/static/sapl/css/global.f7113e2c.css"},{"name":"js/global.2b34f8ff.js","publicPath":"/static/sapl/js/global.2b34f8ff.js","path":"../sapl/sapl/static/sapl/js/global.2b34f8ff.js"},{"name":"css/global.f7113e2c.css.map","publicPath":"/static/sapl/css/global.f7113e2c.css.map","path":"../sapl/sapl/static/sapl/css/global.f7113e2c.css.map"}],"painel":[{"name":"css/painel.baa845ab.css","publicPath":"/static/sapl/css/painel.baa845ab.css","path":"../sapl/sapl/static/sapl/css/painel.baa845ab.css"},{"name":"js/painel.f4adb91b.js","publicPath":"/static/sapl/js/painel.f4adb91b.js","path":"../sapl/sapl/static/sapl/js/painel.f4adb91b.js"},{"name":"css/painel.baa845ab.css.map","publicPath":"/static/sapl/css/painel.baa845ab.css.map","path":"../sapl/sapl/static/sapl/css/painel.baa845ab.css.map"}]}}
Loading…
Cancel
Save