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. 85
      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. 43
      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 python-magic==0.4.15
unipath==1.1 unipath==1.1
WeasyPrint==44 WeasyPrint==44
Pillow==5.1.0
gunicorn==19.9.0 gunicorn==19.9.0
textract==1.5.0 textract==1.5.0

55
sapl/base/forms.py

@ -64,19 +64,46 @@ def get_roles():
class UsuarioCreateForm(ModelForm): class UsuarioCreateForm(ModelForm):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
username = forms.CharField(required=True, label="Nome de usuário", username = forms.CharField(
max_length=30) required=True,
firstname = forms.CharField(required=True, label="Nome", max_length=30) label="Nome de usuário",
lastname = forms.CharField(required=True, label="Sobrenome", max_length=30) max_length=30
password1 = forms.CharField(required=True, widget=forms.PasswordInput, )
label='Senha', max_length=128) firstname = forms.CharField(
password2 = forms.CharField(required=True, widget=forms.PasswordInput, required=True,
label='Confirmar senha', max_length=128) label="Nome",
user_active = forms.ChoiceField(required=False, choices=YES_NO_CHOICES, max_length=30
label="Usuário ativo?", initial='True') )
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( roles = forms.MultipleChoiceField(
required=True, widget=forms.CheckboxSelectMultiple(), choices=get_roles) required=True,
widget=forms.CheckboxSelectMultiple(),
choices=get_roles
)
class Meta: class Meta:
model = get_user_model() model = get_user_model()
@ -84,7 +111,7 @@ class UsuarioCreateForm(ModelForm):
'password1', 'password2', 'user_active', 'roles'] 'password1', 'password2', 'user_active', 'roles']
def clean(self): def clean(self):
super(UsuarioCreateForm, self).clean() super().clean()
if not self.is_valid(): if not self.is_valid():
return self.cleaned_data return self.cleaned_data
@ -99,7 +126,7 @@ class UsuarioCreateForm(ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(UsuarioCreateForm, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
row0 = to_row([('username', 12)]) 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 import template
from django.template.defaultfilters import stringfilter from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe 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.parlamentares.models import Filiacao
from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO
register = template.Library() register = template.Library()
@ -286,3 +288,12 @@ def render_chunk_vendors(extension=None):
return mark_safe('\n'.join(tags)) return mark_safe('\n'.join(tags))
except: except:
return '' 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() model = get_user_model()
form_class = UsuarioCreateForm form_class = UsuarioCreateForm
success_message = 'Usuário criado com sucesso!' success_message = 'Usuário criado com sucesso!'
fail_message = 'Usuário não criado!'
permission_required = ('base.add_appconfig',) permission_required = ('base.add_appconfig',)
def get_success_url(self): def get_success_url(self):
return reverse('sapl.base:usuario') return reverse('sapl.base:usuario')
def form_valid(self, form): def form_valid(self, form):
data = form.cleaned_data data = form.cleaned_data
new_user = get_user_model().objects.create( 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.first_name = data['firstname']
new_user.last_name = data['lastname'] new_user.last_name = data['lastname']
new_user.set_password(data['password1']) new_user.set_password(data['password1'])
@ -1354,6 +1356,10 @@ class CreateUsuarioView(PermissionRequiredMixin, CreateView):
messages.success(self.request, self.success_message) messages.success(self.request, self.success_message)
return HttpResponseRedirect(self.get_success_url()) 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): class DeleteUsuarioView(PermissionRequiredMixin, DeleteView):
model = get_user_model() model = get_user_model()

1
sapl/crispy_layout_mixin.py

@ -166,6 +166,7 @@ def get_field_display(obj, fieldname):
value) value)
elif 'TextField' in str_type_from_field: elif 'TextField' in str_type_from_field:
display = value.replace('\n', '<br/>') display = value.replace('\n', '<br/>')
display = '<div class="dont-break-out">{}</div>'.format(display)
else: else:
display = str(value) display = str(value)
return verbose_name, display 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.base.models import Autor, TipoAutor
from sapl.crispy_layout_mixin import form_actions, to_row from sapl.crispy_layout_mixin import form_actions, to_row
from sapl.rules import SAPL_GROUP_VOTANTE from sapl.rules import SAPL_GROUP_VOTANTE
import django_filters
from .models import (ComposicaoColigacao, Filiacao, Frente, Legislatura, from .models import (ComposicaoColigacao, Filiacao, Frente, Legislatura,
Mandato, Parlamentar, Votante) Mandato, Parlamentar, Votante)
@ -210,6 +211,29 @@ class ParlamentarForm(FileFieldCheckMixin, ModelForm):
attrs={'id': 'texto-rico'})} 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 ParlamentarCreateForm(ParlamentarForm):
class Meta(ParlamentarForm.Meta): class Meta(ParlamentarForm.Meta):

8
sapl/parlamentares/urls.py

@ -18,7 +18,9 @@ from sapl.parlamentares.views import (CargoMesaCrud, ColigacaoCrud,
insere_parlamentar_composicao, insere_parlamentar_composicao,
parlamentares_frente_selected, parlamentares_frente_selected,
remove_parlamentar_composicao, remove_parlamentar_composicao,
lista_parlamentares) lista_parlamentares,
parlamentares_filiados,
PesquisarParlamentarView)
from .apps import AppConfig from .apps import AppConfig
@ -36,6 +38,9 @@ urlpatterns = [
url(r'^parlamentar/lista$', lista_parlamentares, name='lista_parlamentares'), 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$', url(r'^parlamentar/(?P<pk>\d+)/materias$',
ParlamentarMateriasView.as_view(), name='parlamentar_materias'), ParlamentarMateriasView.as_view(), name='parlamentar_materias'),
@ -63,6 +68,7 @@ urlpatterns = [
url(r'^sistema/parlamentar/tipo-militar/', url(r'^sistema/parlamentar/tipo-militar/',
include(TipoMilitarCrud.get_urls())), include(TipoMilitarCrud.get_urls())),
url(r'^sistema/parlamentar/partido/', include(PartidoCrud.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/', url(r'^sistema/mesa-diretora/sessao-legislativa/',
include(SessaoLegislativaCrud.get_urls())), 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.decorators.clickjacking import xframe_options_exempt
from django.views.generic import FormView from django.views.generic import FormView
from django.views.generic.edit import UpdateView from django.views.generic.edit import UpdateView
from django_filters.views import FilterView
from image_cropping.utils import get_backend from image_cropping.utils import get_backend
from sapl.base.forms import SessaoLegislativaForm, PartidoForm from sapl.base.forms import SessaoLegislativaForm, PartidoForm
from sapl.base.models import Autor from sapl.base.models import Autor
from sapl.comissoes.models import Participacao from sapl.comissoes.models import Participacao
from sapl.crud.base import (RP_CHANGE, RP_DETAIL, RP_LIST, Crud, CrudAux, from sapl.crud.base import (RP_CHANGE, RP_DETAIL, RP_LIST, Crud, CrudAux,
CrudBaseForListAndDetailExternalAppView, CrudBaseForListAndDetailExternalAppView,
MasterDetailCrud) MasterDetailCrud, make_pagination)
from sapl.materia.models import Autoria, Proposicao, Relatoria from sapl.materia.models import Autoria, Proposicao, Relatoria
from sapl.parlamentares.apps import AppConfig 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, from .forms import (FiliacaoForm, FrenteForm, LegislaturaForm, MandatoForm,
ParlamentarCreateForm, ParlamentarForm, VotanteForm) ParlamentarCreateForm, ParlamentarForm, VotanteForm, ParlamentarFilterSet)
from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa,
Dependente, Filiacao, Frente, Legislatura, Mandato, Dependente, Filiacao, Frente, Legislatura, Mandato,
NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, NivelInstrucao, Parlamentar, Partido, SessaoLegislativa,
@ -165,6 +167,63 @@ class ProposicaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
_('Texto Eletrônico')) _('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): class ParticipacaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
model = Participacao model = Participacao
parent_field = 'parlamentar' 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): class MesaDiretoraView(FormView):
template_name = 'parlamentares/composicaomesa_form.html' template_name = 'parlamentares/composicaomesa_form.html'
success_url = reverse_lazy('sapl.parlamentares:mesa_diretora') success_url = reverse_lazy('sapl.parlamentares:mesa_diretora')

85
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 """Script para geração do PDF das sessoes plenarias
Autor: Gustavo Lepri Autor: Gustavo Lepri
Atualizado por Luciano De Fázio - 22/03/2012 Atualizado por Luciano De Fázio - 22/03/2012
versão: 1.0 versão: 1.0
""" """
import time
import os import os
import time
from django.template.defaultfilters import safe from django.template.defaultfilters import safe
from django.utils.html import strip_tags from django.utils.html import strip_tags
from trml2pdf import parseString
from sapl.sessao.models import ResumoOrdenacao from sapl.sessao.models import ResumoOrdenacao
from trml2pdf import parseString
def cabecalho(inf_basicas_dic, imagem): def cabecalho(inf_basicas_dic, imagem):
""" """
@ -124,7 +123,7 @@ def inf_basicas(inf_basicas_dic):
dat_inicio_sessao + ' <b>- </b> ' + hr_inicio_sessao + '</para>\n' dat_inicio_sessao + ' <b>- </b> ' + hr_inicio_sessao + '</para>\n'
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'
return tmp return tmp
@ -145,7 +144,7 @@ def mesa(lst_mesa):
return tmp 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<para style="P2">\n'
tmp += '\t\t\t<font color="white"> <br/></font>\n' tmp += '\t\t\t<font color="white"> <br/></font>\n'
tmp += '\t\t</para>\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' 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>' + 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;') 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="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']) + \
@ -224,6 +227,30 @@ def expediente_materia(lst_expediente_materia):
return tmp 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): 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' 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> ' + 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;') txt_ementa = votacao['txt_ementa'].replace('&', '&amp;')
if len(txt_ementa) > 1000: if len(txt_ementa) > 1000:
txt_ementa = txt_ementa[:1000] + "..." txt_ementa = txt_ementa[:1000] + "..."
@ -289,6 +316,30 @@ def votacao(lst_votacao):
return tmp 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): def oradores(lst_oradores):
""" """
@ -323,7 +374,7 @@ def ocorrencias(lst_ocorrencias):
return tmp 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" 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': '', '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,lst_ausencia_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),
'v_n_mat_exp': expediente_materia_vot_nom(lst_expediente_materia_vot_nom),
'mat_o_d': votacao(lst_votacao), 'mat_o_d': votacao(lst_votacao),
'v_n_mat_o_d': votacao_vot_nom(lst_votacao_vot_nom),
'mesa_d': mesa(lst_mesa), 'mesa_d': mesa(lst_mesa),
'oradores_exped': oradores_expediente(lst_oradores_expediente), 'oradores_exped': oradores_expediente(lst_oradores_expediente),
'oradores_expli': oradores(lst_oradores), '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.nono]
tmp += dict_ord_template[ordenacao.decimo] tmp += dict_ord_template[ordenacao.decimo]
tmp += dict_ord_template[ordenacao.decimo_primeiro] tmp += dict_ord_template[ordenacao.decimo_primeiro]
tmp += dict_ord_template[ordenacao.decimo_segundo]
tmp += dict_ord_template[ordenacao.decimo_terceiro]
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,lst_ausencia_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 += expediente_materia_vot_nom(lst_expediente_materia_vot_nom)
tmp += oradores_expediente(lst_oradores_expediente) tmp += oradores_expediente(lst_oradores_expediente)
tmp += presenca_ordem_dia(lst_presenca_ordem_dia) tmp += presenca_ordem_dia(lst_presenca_ordem_dia)
tmp += votacao(lst_votacao) tmp += votacao(lst_votacao)
tmp += votacao_vot_nom(lst_votacao_vot_nom)
tmp += oradores(lst_oradores) tmp += oradores(lst_oradores)
tmp += ocorrencias(lst_ocorrencias) tmp += ocorrencias(lst_ocorrencias)

53
sapl/relatorios/views.py

@ -19,7 +19,8 @@ from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao,
IntegranteMesa, JustificativaAusencia, IntegranteMesa, JustificativaAusencia,
Orador, OradorExpediente, Orador, OradorExpediente,
OrdemDia, PresencaOrdemDia, SessaoPlenaria, OrdemDia, PresencaOrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, OcorrenciaSessao) SessaoPlenariaPresenca, OcorrenciaSessao,
RegistroVotacao, VotoParlamentar)
from sapl.settings import STATIC_ROOT from sapl.settings import STATIC_ROOT
from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data 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"] = ' ' dic_expediente_materia["votacao_observacao"] = ' '
lst_expediente_materia.append(dic_expediente_materia) 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 # Lista dos oradores do Expediente
lst_oradores_expediente = [] lst_oradores_expediente = []
for orador_expediente in OradorExpediente.objects.filter( 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" dic_votacao["nom_resultado"] = "Matéria não votada"
lst_votacao.append(dic_votacao) 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 # Lista dos oradores nas Explicações Pessoais
lst_oradores = [] lst_oradores = []
for orador in Orador.objects.filter( for orador in Orador.objects.filter(
@ -767,9 +812,11 @@ def get_sessao_plenaria(sessao, casa):
lst_ausencia_sessao, lst_ausencia_sessao,
lst_expedientes, lst_expedientes,
lst_expediente_materia, lst_expediente_materia,
lst_expediente_materia_vot_nom,
lst_oradores_expediente, lst_oradores_expediente,
lst_presenca_ordem_dia, lst_presenca_ordem_dia,
lst_votacao, lst_votacao,
lst_votacao_vot_nom,
lst_oradores, lst_oradores,
lst_ocorrencias) lst_ocorrencias)
@ -822,9 +869,11 @@ def relatorio_sessao_plenaria(request, pk):
lst_ausencia_sessao, lst_ausencia_sessao,
lst_expedientes, lst_expedientes,
lst_expediente_materia, lst_expediente_materia,
lst_expediente_materia_vot_nom,
lst_oradores_expediente, lst_oradores_expediente,
lst_presenca_ordem_dia, lst_presenca_ordem_dia,
lst_votacao, lst_votacao,
lst_votacao_vot_nom,
lst_oradores, lst_oradores,
lst_ocorrencias) = get_sessao_plenaria(sessao, casa) lst_ocorrencias) = get_sessao_plenaria(sessao, casa)
@ -843,9 +892,11 @@ def relatorio_sessao_plenaria(request, pk):
lst_ausencia_sessao, lst_ausencia_sessao,
lst_expedientes, lst_expedientes,
lst_expediente_materia, lst_expediente_materia,
lst_expediente_materia_vot_nom,
lst_oradores_expediente, lst_oradores_expediente,
lst_presenca_ordem_dia, lst_presenca_ordem_dia,
lst_votacao, lst_votacao,
lst_votacao_vot_nom,
lst_oradores, lst_oradores,
lst_ocorrencias) lst_ocorrencias)

66
sapl/sessao/views.py

@ -1419,6 +1419,29 @@ class ResumoView(DetailView):
context.update({'materia_expediente': materias_expediente}) 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 Expediente
oradores = [] oradores = []
@ -1518,6 +1541,29 @@ class ResumoView(DetailView):
context.update({'materias_ordem': materias_ordem}) 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 nas Explicações Pessoais
oradores_explicacoes = [] oradores_explicacoes = []
@ -1556,7 +1602,9 @@ class ResumoView(DetailView):
'lista_p': 'lista_presenca.html', 'lista_p': 'lista_presenca.html',
'lista_p_o_d': 'lista_presenca_ordem_dia.html', 'lista_p_o_d': 'lista_presenca_ordem_dia.html',
'mat_exp': 'materias_expediente.html', 'mat_exp': 'materias_expediente.html',
'v_n_mat_exp': 'votos_nominais_materias_expediente.html',
'mat_o_d': 'materias_ordem_dia.html', 'mat_o_d': 'materias_ordem_dia.html',
'v_n_mat_o_d': 'votos_nominais_materias_ordem_dia.html',
'mesa_d': 'mesa_diretora.html', 'mesa_d': 'mesa_diretora.html',
'oradores_exped': 'oradores_expediente.html', 'oradores_exped': 'oradores_expediente.html',
'oradores_expli': 'oradores_explicacoes.html', 'oradores_expli': 'oradores_explicacoes.html',
@ -1575,7 +1623,10 @@ class ResumoView(DetailView):
'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]}) '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: else:
context.update( context.update(
{'primeiro_ordenacao': dict_ord_template['id_basica'], {'primeiro_ordenacao': dict_ord_template['id_basica'],
@ -1584,11 +1635,14 @@ class ResumoView(DetailView):
'quarto_ordenacao': dict_ord_template['lista_p'], 'quarto_ordenacao': dict_ord_template['lista_p'],
'quinto_ordenacao': dict_ord_template['exp'], 'quinto_ordenacao': dict_ord_template['exp'],
'sexto_ordenacao': dict_ord_template['mat_exp'], 'sexto_ordenacao': dict_ord_template['mat_exp'],
'setimo_ordenacao': dict_ord_template['oradores_exped'], 'setimo_ordenacao': dict_ord_template['v_n_mat_exp'],
'oitavo_ordenacao': dict_ord_template['lista_p_o_d'], 'oitavo_ordenacao': dict_ord_template['oradores_exped'],
'nono_ordenacao': dict_ord_template['mat_o_d'], 'nono_ordenacao': dict_ord_template['lista_p_o_d'],
'decimo_ordenacao': dict_ord_template['oradores_expli'], 'decimo_ordenacao': dict_ord_template['mat_o_d'],
'decimo_primeiro_ordenacao': dict_ord_template['ocorr_sessao']}) '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) 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> </table>
{% endif %} {% endif %}
<!-- Ementa --> <!-- Assunto -->
<table border=0> <table border=0>
<td> <td>
<div id="ementa_texto"> <div id="assunto_texto">
<strong class="text_pdf">Ementa:</strong> <span class="text_pdf">{{documento.assunto}}</span> <strong class="text_pdf">Assunto:</strong> <span class="text_pdf">{{documento.assunto}}</span>
</div> </div>
</td> </td>
</table> </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> </div>
</justify> </justify>

4
sapl/templates/materia/materialegislativa_filter.html

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

43
sapl/templates/norma/normajuridica_form.html

@ -7,33 +7,34 @@
<script language="Javascript"> <script language="Javascript">
function recuperar_materia() { function recuperar_materia() {
var tipo_materia = $("#id_tipo_materia").val() var tipo_materia = $("#id_tipo_materia").val();
var numero_materia = $("#id_numero_materia").val() var numero_materia = $("#id_numero_materia").val();
var ano_materia = $("#id_ano_materia").val() var ano_materia = $("#id_ano_materia").val();
var tipo = $('#id_tipo').val() var tipo = $('#id_tipo').val();
var ano = $('#id_ano').val() var ano = $('#id_ano').val();
var numero = $('#id_numero').val() var numero = $('#id_numero').val();
var ementa = $('#id_ementa').val() var ementa = $('#id_ementa').val();
if (tipo_materia && numero_materia && ano_materia) { if (tipo_materia && numero_materia && ano_materia) {
if (ementa === undefined || ementa === "") { $.get("/sessao/recuperar-materia",
$.get("/sessao/recuperar-materia",{tipo_materia: tipo_materia, {tipo_materia: tipo_materia,
numero_materia: numero_materia, numero_materia: numero_materia,
ano_materia: ano_materia}, ano_materia: ano_materia},
function(data, status) { function(data, status) {
$("#id_ementa").val(data.ementa); $("#id_ementa").val(data.ementa);
$("#id_indexacao").val(data.indexacao); $("#id_indexacao").val(data.indexacao);
});
} }
);
} }
} }
var fields = ["#id_tipo_materia", "#id_numero_materia", "#id_ano_materia"] var fields = ["#id_tipo_materia", "#id_numero_materia", "#id_ano_materia"]
for (i = 0; i < fields.length; i++) { for (i = 0; i < fields.length; i++) {
$(fields[i]).change(recuperar_materia); $(fields[i]).change(recuperar_materia);
} }
recuperar_materia();
function recuperar_norma() { function recuperar_norma() {
var tipo = $("#id_tipo").val() var tipo = $("#id_tipo").val();
var ano = $("#id_ano").val() var ano = $("#id_ano").val();
if (tipo) { if (tipo) {
$.get("/norma/recuperar-numero-norma",{tipo: 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++) { for (i = 0; i < fields.length; i++) {
$(fields[i]).change(recuperar_norma); $(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 i18n %}
{% load crispy_forms_tags cropping%} {% load crispy_forms_tags cropping%}
{% block actions %} {% block actions %}
{{ block.super }}
<div class="actions btn-group float-right btn-group-lg" role="group"> <div class="actions btn-group float-right btn-group-lg" role="group">
{% if view.create_url %} {% if view.create_url %}
<a href="{% url 'sapl.parlamentares:lista_parlamentares' %}" class="btn btn-outline-primary"> <a href="{% url 'sapl.parlamentares:lista_parlamentares' %}" class="btn btn-outline-primary">
@ -10,6 +11,9 @@
{% endif %} {% endif %}
{% block more_buttons %}{% endblock more_buttons %} {% block more_buttons %}{% endblock more_buttons %}
</div> </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 %} {% endblock actions %}
{% block extra_content %} {% block extra_content %}
<fieldset class="form-group"> <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> <fieldset>
<legend>Matérias do Expediente</legend> <legend>Matérias do Expediente</legend>
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
@ -33,7 +35,10 @@
<b>Processo:</b> {{ m.numero_processo }} <b>Processo:</b> {{ m.numero_processo }}
{% endif %} {% endif %}
</td> </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> <td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td>
</tr> </tr>
{% endfor %} {% endfor %}

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

@ -1,3 +1,5 @@
{% load common_tags %}
<fieldset> <fieldset>
<legend>Matérias da Ordem do Dia</legend> <legend>Matérias da Ordem do Dia</legend>
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
@ -33,7 +35,7 @@
<b>Processo:</b> {{ m.numero_processo }} <b>Processo:</b> {{ m.numero_processo }}
{% endif %} {% endif %}
</td> </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> <td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td>
</tr> </tr>
{% endfor %} {% 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 %} {% include 'sessao/blocos_resumo/'|add:decimo_primeiro_ordenacao %}
<br /><br /><br /> <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 %} {% endblock detail_content %}

41
sapl/utils.py

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