Browse Source

Merge branch '3.1.x'

pull/1828/merge
Edward Ribeiro 7 years ago
parent
commit
a877df5ac5
  1. 2
      Dockerfile
  2. 36
      create_admin.py
  3. 2
      docker-compose.yml
  4. 1
      sapl/audiencia/views.py
  5. 20
      sapl/base/migrations/0020_auto_20180821_1421.py
  6. 6
      sapl/base/models.py
  7. 41
      sapl/comissoes/forms.py
  8. 5
      sapl/compilacao/models.py
  9. 3
      sapl/compilacao/views.py
  10. 5
      sapl/materia/forms.py
  11. 27
      sapl/materia/models.py
  12. 4
      sapl/materia/urls.py
  13. 49
      sapl/materia/views.py
  14. 10
      sapl/norma/models.py
  15. 13
      sapl/norma/views.py
  16. 2
      sapl/protocoloadm/models.py
  17. 3
      sapl/protocoloadm/urls.py
  18. 19
      sapl/protocoloadm/views.py
  19. 9
      sapl/relatorios/views.py
  20. 5
      sapl/sessao/views.py
  21. 13
      sapl/static/styles/app.scss
  22. 23
      sapl/templates/base.html
  23. 4
      sapl/templates/compilacao/textoarticulado_detail.html
  24. 3
      sapl/templates/compilacao/textoarticulado_menu_config.html
  25. 27
      sapl/templates/materia/proposicao_confirm_return.html
  26. 2
      sapl/templates/materia/proposicao_detail.html
  27. 4
      sapl/templates/norma/normajuridica_detail.html
  28. 1
      sapl/templates/norma/normajuridica_form.html
  29. 31
      sapl/templates/protocoloadm/protocolar_materia.html
  30. 2
      sapl/templates/protocoloadm/protocolo_filter.html
  31. 2
      sapl/templates/protocoloadm/protocolo_mostrar.html
  32. 2
      setup.py

2
Dockerfile

@ -4,6 +4,8 @@ ENV BUILD_PACKAGES postgresql-dev graphviz-dev graphviz build-base git pkgconfig
python3-dev libxml2-dev jpeg-dev libressl-dev libffi-dev libxslt-dev nodejs py3-lxml \
py3-magic postgresql-client poppler-utils antiword vim
RUN apk update && apk upgrade
RUN apk --update add fontconfig ttf-dejavu && fc-cache -fv
RUN apk add --no-cache python3 nginx tzdata && \

36
create_admin.py

@ -7,24 +7,43 @@ import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sapl.settings")
def get_enviroment_admin_password(username):
password = os.environ.get('ADMIN_PASSWORD')
if not password:
print(
"[SUPERUSER] Environment variable $ADMIN_PASSWORD"
" for user %s was not set. Leaving..." % username)
sys.exit('MISSING_ADMIN_PASSWORD')
def create_user_interlegis():
from django.contrib.auth.models import User
password = get_enviroment_admin_password('interlegis')
print("[SUPERUSER INTERLEGIS] Creating interlegis superuser...")
user, created = User.objects.get_or_create(username='interlegis')
if not created:
print("[SUPERUSER INTERLEGIS] User interlegis already exists."
" Updating password.")
user.is_superuser = True
user.is_staff = True
user.set_password(password)
user.save()
print("[SUPERUSER INTERLEGIS] Done.")
def create_superuser():
from django.contrib.auth.models import User
username = "admin"
password = os.environ[
'ADMIN_PASSWORD'] if 'ADMIN_PASSWORD' in os.environ else None
email = os.environ['ADMIN_EMAIL'] if 'ADMIN_EMAIL' in os.environ else ''
email = os.environ.get('ADMIN_EMAIL', '')
if User.objects.filter(username=username).exists():
print("[SUPERUSER] User %s already exists."
" Exiting without change." % username)
sys.exit('ADMIN_USER_EXISTS')
else:
if not password:
print(
"[SUPERUSER] Environment variable $ADMIN_PASSWORD"
" for user %s was not set. Leaving..." % username)
sys.exit('MISSING_ADMIN_PASSWORD')
password = get_enviroment_admin_password(username)
print("[SUPERUSER] Creating superuser...")
@ -39,4 +58,5 @@ def create_superuser():
if __name__ == '__main__':
django.setup()
create_user_interlegis() # must come before create_superuser
create_superuser()

2
docker-compose.yml

@ -11,7 +11,7 @@ sapldb:
ports:
- "5432:5432"
sapl:
image: interlegis/sapl:3.1.107
image: interlegis/sapl:3.1.110
restart: always
environment:
ADMIN_PASSWORD: interlegis

1
sapl/audiencia/views.py

@ -34,6 +34,7 @@ class AudienciaCrud(Crud):
def get_initial(self):
initial = super(UpdateView, self).get_initial()
if self.object.materia:
initial['tipo_materia'] = self.object.materia.tipo.id
initial['numero_materia'] = self.object.materia.numero
initial['ano_materia'] = self.object.materia.ano

20
sapl/base/migrations/0020_auto_20180821_1421.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-08-21 17:21
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0019_auto_20180815_1025'),
]
operations = [
migrations.AlterField(
model_name='appconfig',
name='documentos_administrativos',
field=models.CharField(choices=[('O', 'Ostensiva'), ('R', 'Restritiva')], default='O', max_length=1, verbose_name='Visibilidade dos Documentos Administrativos'),
),
]

6
sapl/base/models.py

@ -9,8 +9,8 @@ from django.utils.translation import ugettext_lazy as _
from sapl.utils import (LISTA_DE_UFS, YES_NO_CHOICES,
get_settings_auth_user_model, models_with_gr_for_model)
TIPO_DOCUMENTO_ADMINISTRATIVO = (('O', _('Ostensivo')),
('R', _('Restritivo')))
TIPO_DOCUMENTO_ADMINISTRATIVO = (('O', _('Ostensiva')),
('R', _('Restritiva')))
SEQUENCIA_NUMERACAO = (('A', _('Sequencial por ano')),
('L', _('Sequencial por legislatura')),
@ -70,7 +70,7 @@ class AppConfig(models.Model):
documentos_administrativos = models.CharField(
max_length=1,
verbose_name=_('Ostensivo/Restritivo'),
verbose_name=_('Visibilidade dos Documentos Administrativos'),
choices=TIPO_DOCUMENTO_ADMINISTRATIVO, default='O')
sequencia_numeracao = models.CharField(

41
sapl/comissoes/forms.py

@ -45,6 +45,7 @@ class ComposicaoForm(forms.ModelForm):
return cleaned_data
class PeriodoForm(forms.ModelForm):
class Meta:
@ -63,9 +64,20 @@ class PeriodoForm(forms.ModelForm):
if data_fim and data_fim < data_inicio:
raise ValidationError('A Data Final não pode ser menor que '
'a Data Inicial')
legislatura = Legislatura.objects.filter(data_inicio__lte=data_inicio,
data_fim__gte=data_fim)
if not legislatura:
raise ValidationError('O período informado '
'deve estar contido em uma única '
'legislatura existente')
return cleaned_data
class ParticipacaoCreateForm(forms.ModelForm):
parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput())
@ -245,11 +257,36 @@ class ComissaoForm(forms.ModelForm):
if len(self.cleaned_data['nome']) > 100:
msg = _('Nome da Comissão deve ter no máximo 50 caracteres.')
raise ValidationError(msg)
if self.cleaned_data['data_extincao']:
if (self.cleaned_data['data_extincao'] <
if (self.cleaned_data['data_extincao'] and
self.cleaned_data['data_extincao'] <
self.cleaned_data['data_criacao']):
msg = _('Data de extinção não pode ser menor que a de criação')
raise ValidationError(msg)
if (self.cleaned_data['data_final_prevista_temp'] and
self.cleaned_data['data_final_prevista_temp'] <
self.cleaned_data['data_criacao']):
msg = _('Data Prevista para Término não pode ser menor que a de criação')
raise ValidationError(msg)
if (self.cleaned_data['data_prorrogada_temp'] and
self.cleaned_data['data_prorrogada_temp'] <
self.cleaned_data['data_criacao']):
msg = _('Data Novo Prazo não pode ser menor que a de criação')
raise ValidationError(msg)
if (self.cleaned_data['data_instalacao_temp'] and
self.cleaned_data['data_instalacao_temp'] <
self.cleaned_data['data_criacao']):
msg = _('Data de Instalação não pode ser menor que a de criação')
raise ValidationError(msg)
if (self.cleaned_data['data_final_prevista_temp'] and self.cleaned_data['data_instalacao_temp'] and
self.cleaned_data['data_final_prevista_temp'] <
self.cleaned_data['data_instalacao_temp']):
msg = _('Data Prevista para Término não pode ser menor que a de Instalação')
raise ValidationError(msg)
if (self.cleaned_data['data_prorrogada_temp'] and self.cleaned_data['data_instalacao_temp'] and
self.cleaned_data['data_prorrogada_temp'] <
self.cleaned_data['data_instalacao_temp']):
msg = _('Data Novo Prazo não pode ser menor que a de Instalação')
raise ValidationError(msg)
return self.cleaned_data
@transaction.atomic

5
sapl/compilacao/models.py

@ -237,7 +237,10 @@ class TextoArticulado(TimestampedMixin):
def __str__(self):
if self.content_object:
return str(self.content_object)
assert hasattr(self.content_object, 'epigrafe'), _(
'Modelos integrados aos Textos Articulados devem possuir a '
'property "epigrafe"')
return str(self.content_object.epigrafe)
else:
return _('%(tipo)s%(numero)s de %(data)s') % {
'tipo': self.tipo_ta,

3
sapl/compilacao/views.py

@ -137,6 +137,7 @@ class IntegracaoTaView(TemplateView):
'observacao': 'observacao',
'numero': 'numero',
'ano': 'ano',
'tipo': 'tipo',
}
Caso o model de integração não possua um dos campos,
@ -562,7 +563,7 @@ class TaDetailView(CompMixin, DetailView):
'Metadados para o Texto Articulado de %s\n'
'<small>%s</small>') % (
self.get_object().content_object._meta.verbose_name_plural,
self.get_object().content_object)
self.get_object().content_object.epigrafe)
else:
return self.get_object()

5
sapl/materia/forms.py

@ -123,13 +123,14 @@ class MateriaSimplificadaForm(ModelForm):
model = MateriaLegislativa
fields = ['tipo', 'numero', 'ano', 'data_apresentacao',
'numero_protocolo', 'regime_tramitacao',
'em_tramitacao', 'ementa', 'texto_original']
'em_tramitacao', 'ementa', 'tipo_apresentacao',
'texto_original']
def __init__(self, *args, **kwargs):
row1 = to_row([('tipo', 6), ('numero', 3), ('ano', 3)])
row2 = to_row([('data_apresentacao', 6), ('numero_protocolo', 6)])
row3 = to_row([('regime_tramitacao', 6), ('em_tramitacao', 6)])
row3 = to_row([('regime_tramitacao', 6), ('em_tramitacao', 3), ('tipo_apresentacao', 3)])
row4 = to_row([('ementa', 12)])
row5 = to_row([('texto_original', 12)])

27
sapl/materia/models.py

@ -1,14 +1,15 @@
import reversion
from django.contrib.auth.models import Group
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db.models.functions import Concat
from django.template import defaultfilters
from django.utils import formats, timezone
from django.utils.translation import ugettext_lazy as _
from model_utils import Choices
import reversion
from sapl.base.models import SEQUENCIA_NUMERACAO, Autor
from sapl.comissoes.models import Comissao
@ -19,6 +20,7 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, SaplGenericForeignKey,
SaplGenericRelation, restringe_tipos_de_arquivo_txt,
texto_upload_path)
EM_TRAMITACAO = [(1, 'Sim'),
(0, 'Não')]
@ -242,6 +244,16 @@ class MateriaLegislativa(models.Model):
return _('%(tipo)s%(numero)s de %(ano)s') % {
'tipo': self.tipo, 'numero': self.numero, 'ano': self.ano}
@property
def epigrafe(self):
return _('%(tipo)s%(numero)s de %(data)s') % {
'tipo': self.tipo,
'numero': self.numero,
'data': defaultfilters.date(
self.data_apresentacao,
"d \d\e F \d\e Y"
)}
def data_entrada_protocolo(self):
'''
hack: recuperar a data de entrada do protocolo sem gerar
@ -425,7 +437,8 @@ class DocumentoAcessorio(models.Model):
verbose_name=_('Tipo'))
nome = models.CharField(max_length=50, verbose_name=_('Nome'))
data = models.DateField(blank=True, null=True, default=None, verbose_name=_('Data'))
data = models.DateField(blank=True, null=True,
default=None, verbose_name=_('Data'))
autor = models.CharField(
max_length=50, blank=True, verbose_name=_('Autor'))
ementa = models.TextField(blank=True, verbose_name=_('Ementa'))
@ -756,6 +769,16 @@ class Proposicao(models.Model):
self.id,
descricao)
@property
def epigrafe(self):
return _('%(tipo)s%(numero)s de %(data)s') % {
'tipo': self.tipo,
'numero': self.numero,
'data': defaultfilters.date(
self.data_envio if self.data_envio else timezone.now(),
"d \d\e F \d\e Y"
)}
def delete(self, using=None, keep_parents=False):
if self.texto_original:
self.texto_original.delete()

4
sapl/materia/urls.py

@ -24,7 +24,7 @@ from sapl.materia.views import (AcompanhamentoConfirmarView,
TipoProposicaoCrud, TramitacaoCrud,
TramitacaoEmLoteView, UnidadeTramitacaoCrud,
proposicao_texto, recuperar_materia,
ExcluirTramitacaoEmLoteView)
ExcluirTramitacaoEmLoteView, RetornarProposicao)
from sapl.norma.views import NormaPesquisaSimplesView
from .apps import AppConfig
@ -120,6 +120,8 @@ urlpatterns_proposicao = [
url(r'^proposicao/texto/(?P<pk>\d+)$', proposicao_texto,
name='proposicao_texto'),
url(r'^proposicao/(?P<pk>\d+)/retornar', RetornarProposicao.as_view(),
name='retornar-proposicao'),
]
urlpatterns_sistema = [

49
sapl/materia/views.py

@ -2,7 +2,6 @@ from datetime import datetime
from random import choice
from string import ascii_letters, digits
import weasyprint
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML
from django.contrib import messages
@ -17,10 +16,11 @@ from django.shortcuts import get_object_or_404, redirect
from django.template import RequestContext, loader
from django.utils import formats, timezone
from django.utils.translation import ugettext_lazy as _
from django.views.generic import FormView, ListView, TemplateView, CreateView, UpdateView
from django.views.generic import ListView, TemplateView, CreateView, UpdateView
from django.views.generic.base import RedirectView
from django.views.generic.edit import FormView
from django_filters.views import FilterView
import weasyprint
import sapl
from sapl.base.models import Autor, CasaLegislativa
@ -67,6 +67,7 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria,
TipoProposicao, Tramitacao, UnidadeTramitacao)
from .signals import tramitacao_signal
AssuntoMateriaCrud = CrudAux.build(AssuntoMateria, 'assunto_materia')
OrigemCrud = CrudAux.build(Origem, '')
@ -96,9 +97,10 @@ def proposicao_texto(request, pk):
if proposicao.texto_original:
if (not proposicao.data_recebimento and
proposicao.autor.user_id != request.user.id):
messages.error(request, _('Você não tem permissão para acessar o texto original.'))
messages.error(request, _(
'Você não tem permissão para acessar o texto original.'))
return redirect(reverse('sapl.materia:proposicao_detail',
kwargs={'pk':pk}))
kwargs={'pk': pk}))
arquivo = proposicao.texto_original
@ -221,6 +223,7 @@ class MateriaTaView(IntegracaoTaView):
'observacao': None,
'numero': 'numero',
'ano': 'ano',
'tipo': 'tipo',
}
map_funcs = {
'publicacao_func': False,
@ -251,6 +254,7 @@ class ProposicaoTaView(IntegracaoTaView):
'observacao': None,
'numero': 'numero_proposicao',
'ano': 'ano',
'tipo': 'tipo',
}
map_funcs = {
'publicacao_func': False
@ -509,6 +513,31 @@ class ReceberProposicao(PermissionRequiredForAppCrudMixin, FormView):
return context
class RetornarProposicao(UpdateView):
app_label = sapl.protocoloadm.apps.AppConfig.label
template_name = "materia/proposicao_confirm_return.html"
model = Proposicao
fields = ['data_envio', 'descricao' ]
permission_required = ('materia.detail_proposicao_enviada', )
def dispatch(self, request, *args, **kwargs):
try:
p = Proposicao.objects.get(id=kwargs['pk'])
except:
raise Http404()
if p.autor.user != request.user:
messages.error(
request,
'Usuário sem acesso a esta opção.' %
request.user)
return redirect('/')
return super(RetornarProposicao, self).dispatch(
request, *args, **kwargs)
class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView):
app_label = sapl.protocoloadm.apps.AppConfig.label
template_name = "materia/confirmar_proposicao.html"
@ -994,7 +1023,8 @@ class RelatoriaCrud(MasterDetailCrud):
except ObjectDoesNotExist:
pass
else:
composicao = comissao.composicao_set.last()
composicao = comissao.composicao_set.order_by(
'-periodo__data_inicio').first()
participacao = Participacao.objects.filter(
composicao=composicao)
@ -2035,9 +2065,12 @@ class ExcluirTramitacaoEmLoteView(PermissionRequiredMixin, FormView):
def form_valid(self, form):
tramitacao_set = Tramitacao.objects.filter(data_tramitacao=form.cleaned_data['data_tramitacao'],
unidade_tramitacao_local=form.cleaned_data['unidade_tramitacao_local'],
unidade_tramitacao_destino=form.cleaned_data['unidade_tramitacao_destino'],
tramitacao_set = Tramitacao.objects.filter(
data_tramitacao=form.cleaned_data['data_tramitacao'],
unidade_tramitacao_local=form.cleaned_data[
'unidade_tramitacao_local'],
unidade_tramitacao_destino=form.cleaned_data[
'unidade_tramitacao_destino'],
status=form.cleaned_data['status'])
for tramitacao in tramitacao_set:
materia = tramitacao.materia

10
sapl/norma/models.py

@ -1,9 +1,9 @@
import reversion
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django.template import defaultfilters
from django.utils.translation import ugettext_lazy as _
from model_utils import Choices
import reversion
from sapl.compilacao.models import TextoArticulado
from sapl.materia.models import MateriaLegislativa
@ -146,12 +146,18 @@ class NormaJuridica(models.Model):
norma=self.id)
return anexos
def __str__(self):
return _('%(numero)s de %(data)s') % {
'numero': self.numero,
'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")}
@property
def epigrafe(self):
return _('%(tipo)s%(numero)s de %(data)s') % {
'tipo': self.tipo,
'numero': self.numero,
'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")}
def delete(self, using=None, keep_parents=False):
if self.texto_integral:
self.texto_integral.delete()

13
sapl/norma/views.py

@ -1,6 +1,6 @@
import re
import weasyprint
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
@ -12,6 +12,7 @@ from django.views.generic import TemplateView, UpdateView
from django.views.generic.base import RedirectView
from django.views.generic.edit import FormView
from django_filters.views import FilterView
import weasyprint
from sapl.base.models import AppConfig
from sapl.compilacao.views import IntegracaoTaView
@ -24,6 +25,7 @@ from .forms import (AnexoNormaJuridicaForm, NormaFilterSet, NormaJuridicaForm,
from .models import (AnexoNormaJuridica, AssuntoNorma, NormaJuridica, NormaRelacionada,
TipoNormaJuridica, TipoVinculoNormaJuridica)
# LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '')
AssuntoNormaCrud = CrudAux.build(AssuntoNorma, 'assunto_norma_juridica',
list_field_names=['assunto', 'descricao'])
@ -72,7 +74,10 @@ class NormaPesquisaView(FilterView):
def get_queryset(self):
qs = super().get_queryset()
qs = qs.extra({'norma_i': "CAST(regexp_replace(numero,'[^0-9]','', 'g') AS INTEGER)", 'norma_letra': "regexp_replace(numero,'[^a-zA-Z]','', 'g')"}).order_by('-data', '-norma_i', '-norma_letra')
qs = qs.extra({
'nm_i': "CAST(regexp_replace(numero,'[^0-9]','', 'g') AS INTEGER)",
'norma_letra': "regexp_replace(numero,'[^a-zA-Z]','', 'g')"
}).order_by('-data', '-nm_i', '-norma_letra')
return qs
@ -98,6 +103,7 @@ class NormaPesquisaView(FilterView):
return context
class AnexoNormaJuridicaCrud(MasterDetailCrud):
model = AnexoNormaJuridica
parent_field = 'norma'
@ -105,7 +111,7 @@ class AnexoNormaJuridicaCrud(MasterDetailCrud):
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['id','anexo_arquivo']
list_field_names = ['id', 'anexo_arquivo']
class CreateView(MasterDetailCrud.CreateView):
form_class = AnexoNormaJuridicaForm
@ -141,6 +147,7 @@ class NormaTaView(IntegracaoTaView):
'observacao': 'observacao',
'numero': 'numero',
'ano': 'ano',
'tipo': 'tipo',
}
map_funcs = {

2
sapl/protocoloadm/models.py

@ -55,6 +55,8 @@ class Protocolo(models.Model):
null=False,
choices=RANGE_ANOS,
verbose_name=_('Ano do Protocolo'))
# TODO: Remover esses dois campos após migração,
# TODO: pois timestamp supre a necessidade
data = models.DateField()
hora = models.TimeField()
# TODO transformar campo timestamp em auto_now_add

3
sapl/protocoloadm/urls.py

@ -12,6 +12,7 @@ from sapl.protocoloadm.views import (AnularProtocoloAdmView,
ProtocoloMostrarView,
ProtocoloPesquisaView,
StatusTramitacaoAdministrativoCrud,
recuperar_materia_protocolo,
TipoDocumentoAdministrativoCrud,
TramitacaoAdmCrud,
atualizar_numero_documento,
@ -77,6 +78,8 @@ urlpatterns_protocolo = [
url(r'^protocoloadm/atualizar_numero_documento$',
atualizar_numero_documento, name='atualizar_numero_documento'),
url(r'^protocoloadm/recuperar-materia',
recuperar_materia_protocolo, name='recuperar_materia_protocolo'),
]

19
sapl/protocoloadm/views.py

@ -1,6 +1,7 @@
from braces.views import FormValidMessageMixin
from django.contrib import messages
from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
@ -45,6 +46,24 @@ TipoDocumentoAdministrativoCrud = CrudAux.build(
# FIXME precisa de uma chave diferente para o layout
# ProtocoloMateriaCrud = Crud.build(Protocolo, '')
@permission_required('protocoloadm.add_protocolo')
def recuperar_materia_protocolo(request):
tipo = request.GET.get('tipo')
ano = request.GET.get('ano')
numero = request.GET.get('numero')
try:
materia = MateriaLegislativa.objects.get(
tipo=tipo, ano=ano,numero=numero)
autoria = materia.autoria_set.first()
content = {'ementa': materia.ementa.strip(),
'ano':materia.ano, 'numero':materia.numero}
if autoria:
content.update({'autor': autoria.autor.pk,
'tipo_autor':autoria.autor.tipo.pk})
response = JsonResponse(content)
except Exception as e:
response = JsonResponse({'error':e})
return response
def doc_texto_integral(request, pk):
can_see = True

9
sapl/relatorios/views.py

@ -826,9 +826,10 @@ def get_protocolos(prots):
dic['titulo'] = str(protocolo.numero) + '/' + str(protocolo.ano)
dic['data'] = protocolo.data.strftime(
"%d/%m/%Y") + ' - <b>Horário:</b>' + protocolo.hora.strftime(
"%H:%m")
ts = timezone.localtime(protocolo.timestamp)
dic['data'] = ts.strftime("%d/%m/%Y") + ' - <b>Horário:</b>' + \
ts.strftime("%H:%m")
dic['txt_assunto'] = protocolo.assunto_ementa
@ -941,7 +942,7 @@ def get_etiqueta_protocolos(prots):
tz_hora = timezone.localtime(p.timestamp)
dic['data'] = '<b>Data: </b>' + p.data.strftime(
dic['data'] = '<b>Data: </b>' + tz_hora.strftime(
"%d/%m/%Y") + ' - <b>Horário: </b>' + tz_hora.strftime("%H:%M")
dic['txt_assunto'] = p.assunto_ementa
dic['txt_interessado'] = p.interessado

5
sapl/sessao/views.py

@ -460,9 +460,10 @@ def recuperar_materia(request):
ano=ano,
numero=numero)
response = JsonResponse({'ementa': materia.ementa,
'id': materia.id})
'id': materia.id,
'indexacao': materia.indexacao})
except ObjectDoesNotExist:
response = JsonResponse({'ementa': '', 'id': 0})
response = JsonResponse({'ementa': '', 'id': 0, 'indexacao':''})
return response

13
sapl/static/styles/app.scss

@ -558,6 +558,19 @@ p {
}
}
.btn-cancel-iframe {
position: relative;
text-align: right;
opacity: 0.5;
&:hover {
opacity: 1;
}
a {
padding: 10px;
display: inline-block;
}
}
@media (max-width: 1199px) {
.masthead {

23
sapl/templates/base.html

@ -29,6 +29,7 @@
<body>
<div class="page fadein">
{% if not request|has_iframe %}
{% block navigation %}
<nav class="navbar navbar-inverse navbar-static-top">
@ -108,6 +109,9 @@
</header>
{% endblock main_header %}
{% else %}
<div class="btn-cancel-iframe">
<a href="?iframe=0" target="_blank"><i class="fa fa-2x fa-arrows-alt"></i></a>
</div>
<header class="masthead">
<div class="container">
<div class="hidden-print">
@ -245,6 +249,25 @@
{% block extra_js %}{% endblock %}
<script type="text/javascript" >
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
$(document).ready(function(){
let iframe_set_backend = {{ request|has_iframe|lower }}
if (iframe_set_backend && !inIframe() ) {
let href = location.href
location.href = href + '?iframe=0'
}
});
</script>
{% endblock foot_js %}
</body>
</html>

4
sapl/templates/compilacao/textoarticulado_detail.html

@ -8,9 +8,9 @@
{%if object %}
<li>
{% if request.GET.back_type == 'history' and object.content_object %}
<a href="javascript:window.history.back()" title="{% trans 'Voltar para '%}{{object.content_object}}">{% trans 'Voltar para '%}{{object.content_object}}</a>
<a href="javascript:window.history.back()" title="{% trans 'Voltar para '%}{{object}}">{% trans 'Voltar para '%}{{object}}</a>
{% elif object.content_object%}
<a href="{% url object|urldetail_content_type:object.content_object object.content_object.pk %}" title="{% trans 'Voltar para '%}{{object.content_object}}">{% trans 'Voltar para '%}{{object.content_object}}</a>
<a href="{% url object|urldetail_content_type:object.content_object object.content_object.pk %}" title="{% trans 'Voltar para '%}{{object}}">{% trans 'Voltar para '%}{{object}}</a>
{%else%}
<a href="{% url 'sapl.compilacao:ta_detail' object.pk %}">{% trans 'Início' %}</a>
{%endif%}

3
sapl/templates/compilacao/textoarticulado_menu_config.html

@ -13,8 +13,5 @@
{% if perms.compilacao.list_tiponota %}<li><a href="{% url 'sapl.compilacao:tiponota_list' %}">{%model_verbose_name_plural 'sapl.compilacao.models.TipoNota'%}</a></li>{% endif %}
{% if perms.compilacao.list_tipovide %}<li><a href="{% url 'sapl.compilacao:tipovide_list' %}">{%model_verbose_name_plural 'sapl.compilacao.models.TipoVide'%}</a></li>{% endif %}
{% if user.is_superuser %}
<li><a href="/admin/compilacao/tipodispositivorelationship/">Relacionamento entre Dispositivos</a></li>
{% endif %}
</ul>
{% endif %}

27
sapl/templates/materia/proposicao_confirm_return.html

@ -0,0 +1,27 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% block sections_nav %}{% endblock sections_nav %}
{% block title %}
<h1 class="page-header">
{{ object|safe|linebreaksbr }}
</h1>
{% endblock %}
{% block base_content %}
<form action="" method="post">{% csrf_token %}
<br>
<div class="panel panel-danger">
<div class="panel-heading text-center">
{% blocktrans %}
ATENÇÃO: Retornar a proposição cancela o envio da mesma para protocolo e invalida o recibo já emitido.<br />
Será necessário novo envio e impressão de novo recibo para recebimento pela Casa Legislativa.<br />
Confirma retorno da proposição para o Parlamentar/Gabinete?
{% endblocktrans %}<br>
</div>
<div class="panel-body text-center">
<a href="{% url 'sapl.materia:proposicao_detail' object.pk %}" class="btn btn-inverse">{% trans 'Cancelar' %}</a>
<a href="{% url 'sapl.materia:proposicao_detail' object.pk %}?action=return" class="btn btn-default btn-excluir">{% trans 'Confirmar' %}</a>
</div>
</div>
</form>
{% endblock %}

2
sapl/templates/materia/proposicao_detail.html

@ -21,7 +21,7 @@
<div class="actions btn-group" role="group">
<a class="btn btn-default" onclick="window.open('{% url 'sapl.materia:recibo-proposicao' object.pk %}','Recibo','width=1100, height=600, scrollbars=yes')">{% trans "Recibo de Envio" %}</a>
{% if not object.data_recebimento %}
<a href="{{ view.detail_url }}?action=return" class="btn btn-default btn-excluir">{% trans 'Retornar Proposição Enviada' %}</a>
<a href="{% url 'sapl.materia:retornar-proposicao' object.pk %}" class="btn btn-default btn-excluir">{% trans 'Retornar Proposição Enviada' %}</a>
{% endif %}
</div>
{% endblock %}

4
sapl/templates/norma/normajuridica_detail.html

@ -42,7 +42,7 @@
<div class="form-control-static">
<b>{{ p.tipo_vinculo.descricao_ativa }}</b>&nbsp;
<a href="{% url 'sapl.norma:normajuridica_detail' p.norma_relacionada.pk %}">
{{ p.norma_relacionada }}
{{ p.norma_relacionada.epigrafe }}
</a>
</div>
{% endfor %}
@ -53,7 +53,7 @@
<div class="form-control-static">
<b>{{ r.tipo_vinculo.descricao_passiva }}</b>&nbsp;
<a href="{% url 'sapl.norma:normajuridica_detail' r.norma_principal.pk %}">
{{ r.norma_principal }}
{{ r.norma_principal.epigrafe }}
</a>
</div>
{% endfor %}

1
sapl/templates/norma/normajuridica_form.html

@ -17,6 +17,7 @@
ano_materia: ano_materia},
function(data, status) {
$("#id_ementa").val(data.ementa);
$("#id_indexacao").val(data.indexacao);
});
}
}

31
sapl/templates/protocoloadm/protocolar_materia.html

@ -26,6 +26,36 @@
}
$(document).ready(function() {
function busca_ementa() {
var vincular_materia = $("#id_vincular_materia_1").prop("checked");
var ano_materia = $("#id_ano_materia").val();
var numero_materia = $("#id_numero_materia").val();
var tipo_materia = $("#id_tipo_materia").val();
var json_data = {
ano : ano_materia,
numero : numero_materia,
tipo : tipo_materia
}
if (vincular_materia === true && ano_materia !== undefined &&
numero_materia !== undefined && numero_materia !== "") {
$.getJSON("/protocoloadm/recuperar-materia", json_data, function(data){
if (data) {
if (data['error'] === undefined){
$('#id_assunto_ementa').val(data['ementa']);
if (data['autor'] !== undefined) {
$('#id_autor').val(data['autor']);
$('#id_tipo_autor').val(data['tipo_autor']);
}
}
}
})
}
};
$("#id_ano_materia").blur(busca_ementa);
$("#id_numero_materia").blur(busca_ementa);
$("#id_tipo_materia").change(busca_ementa);
$("#id_tipo_autor").change(function() {
var tipo_selecionado = $("#id_tipo_autor").val();
var autor_selecionado = $("#id_autor").val();
@ -51,6 +81,7 @@
});
}
});
});
</script>
{% endblock %}

2
sapl/templates/protocoloadm/protocolo_filter.html

@ -44,7 +44,7 @@
{% if p.anulado %}<strong><font color="red">&nbsp;&nbsp;** NULO **</font></strong>{% endif %}
</br>
<strong>Assunto:</strong> {{ p.assunto_ementa|default_if_none:"Não informado"}}</br>
<strong>Data Protocolo:</strong> {{ p.data|date:"d/m/Y"|default_if_none:"Não informado" }} - Horário: {{ p.timestamp|localtime|date:"G:i:s" }}</br>
<strong>Data Protocolo:</strong> {{ p.timestamp|localtime|date:"d/m/Y"|default_if_none:"Não informado" }} - Horário: {{ p.timestamp|localtime|date:"G:i:s" }}</br>
{% if p.tipo_processo == 0 %}
<strong>Interessado:</strong> {{ p.interessado|default_if_none:"Não informado" }}</br>

2
sapl/templates/protocoloadm/protocolo_mostrar.html

@ -9,7 +9,7 @@
<a href="{% url 'sapl.relatorios:relatorio_etiqueta_protocolo' protocolo.numero protocolo.ano %}"><img src="{% static 'img/etiqueta.png' %}" alt="Etiqueta Individual"></a></br>
<strong>Assunto: </strong> {{ protocolo.assunto_ementa|default:"Não informado" }}</br>
<strong>Data Protocolo: </strong> {{ protocolo.data|date:"d/m/Y" }} - Horário: {{ protocolo.timestamp|localtime|date:"H:i" }}</br>
<strong>Data Protocolo: </strong> {{ protocolo.timestamp|localtime|date:"d/m/Y" }} - Horário: {{ protocolo.timestamp|localtime|date:"G:i:s" }}</br>
{% if protocolo.tipo_processo == 0 %}
<strong>Interessado:</strong> {{ protocolo.interessado|default_if_none:"Não informado" }}</br>

2
setup.py

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

Loading…
Cancel
Save