diff --git a/sapl/base/forms.py b/sapl/base/forms.py
index 2ccde243a..99d6842ad 100644
--- a/sapl/base/forms.py
+++ b/sapl/base/forms.py
@@ -1583,7 +1583,8 @@ class ConfiguracoesAppForm(ModelForm):
'tramitacao_documento',
'google_recaptcha_site_key',
'google_recaptcha_secret_key',
- 'sapl_as_sapn']
+ 'sapl_as_sapn',
+ 'identificacao_de_documentos']
def __init__(self, *args, **kwargs):
super(ConfiguracoesAppForm, self).__init__(*args, **kwargs)
diff --git a/sapl/base/migrations/0051_auto_20220814_2138.py b/sapl/base/migrations/0051_auto_20220814_2138.py
new file mode 100644
index 000000000..39f98c00f
--- /dev/null
+++ b/sapl/base/migrations/0051_auto_20220814_2138.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.2.28 on 2022-08-15 00:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('base', '0050_metadata'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='appconfig',
+ name='identificacao_de_documentos',
+ field=models.CharField(default='{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}', help_text='\n Como mostrar a identificação dos documentos administrativos?\n Você pode usar um conjunto de combinações que pretender.\n Ao fazer sua edição, será mostrado logo abaixo o último documento cadastrado, como exemplo de resultado de sua edição.\n Em caso de erro, nenhum documento será mostrado e aparecerá apenas o formato padrão mínimo, que é este: "{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}".\n Muito importante, use as chaves "{}", sem elas, você estará inserindo um texto qualquer e não o valor de um campo.\n Você pode combinar as seguintes campos: {sigla} {nome} {numero} {ano} {complemento} {assunto}\n Ainda pode ser usado {/}, {-}, {.} se você quiser que uma barra, traço, ou ponto\n seja adicionado apenas se o próximo campo que será usado tenha algum conteúdo\n (não use dois destes destes condicionais em sequência, somente o último será considerado).\n ', max_length=254, verbose_name='Formato da identificação dos documentos'),
+ ),
+ migrations.AlterField(
+ model_name='appconfig',
+ name='protocolo_manual',
+ field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Permitir informe manual de data e hora de protocolo?'),
+ ),
+ ]
diff --git a/sapl/base/models.py b/sapl/base/models.py
index c27db2748..88f315aba 100644
--- a/sapl/base/models.py
+++ b/sapl/base/models.py
@@ -1,6 +1,7 @@
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields.jsonb import JSONField
+from django.core.cache import cache
from django.core.serializers.json import DjangoJSONEncoder
from django.db import models
from django.db.models.deletion import CASCADE
@@ -93,63 +94,124 @@ class AppConfig(models.Model):
('N', _('Nunca Protocolar ao incorporar uma proposição')),
)
- documentos_administrativos = models.CharField(
- max_length=1,
- verbose_name=_('Visibilidade dos Documentos Administrativos'),
- choices=TIPO_DOCUMENTO_ADMINISTRATIVO, default='O')
+ # MANTENHA A SEQUÊNCIA EQUIVALENTE COM /sapl/templates/base/layout.yaml
+ # AppConfig:
- estatisticas_acesso_normas = models.CharField(
+ # CONFIGURAÇÕES GERAIS
+ # Linha 1 ------------
+ esfera_federacao = models.CharField(
max_length=1,
- verbose_name=_('Estatísticas de acesso a normas'),
- choices=RELATORIO_ATOS_ACESSADOS, default='N')
+ blank=True,
+ default="",
+ verbose_name=_('Esfera Federação'),
+ choices=ESFERA_FEDERACAO_CHOICES)
+ sapl_as_sapn = models.BooleanField(
+ verbose_name=_(
+ 'Utilizar SAPL como SAPN?'),
+ choices=YES_NO_CHOICES, default=False)
- sequencia_numeracao_proposicao = models.CharField(
- max_length=1,
- verbose_name=_('Sequência de numeração de proposições'),
- choices=SEQUENCIA_NUMERACAO_PROPOSICAO, default='A')
+ # MÓDULO PARLAMENTARES
+ # MÓDULO MESA DIRETORA
+
+ # MÓDULO COMISSÕES
+
+ # MÓDULO BANCADAS PARLAMENTARES
+
+ # MÓDULO DOCUMENTOS ADMINISTRATIVOS
+ # Linha 1 -------------------------
+ documentos_administrativos = models.CharField(
+ max_length=1,
+ verbose_name=_('Visibilidade dos Documentos Administrativos'),
+ choices=TIPO_DOCUMENTO_ADMINISTRATIVO, default='O')
+ tramitacao_documento = models.BooleanField(
+ verbose_name=_(
+ 'Tramitar documentos anexados junto com os documentos principais?'),
+ choices=YES_NO_CHOICES, default=True)
+ # Linha 2 -------------------------
+ protocolo_manual = models.BooleanField(
+ verbose_name=_('Permitir informe manual de data e hora de protocolo?'),
+ choices=YES_NO_CHOICES, default=False)
sequencia_numeracao_protocolo = models.CharField(
max_length=1,
verbose_name=_('Sequência de numeração de protocolos'),
choices=SEQUENCIA_NUMERACAO_PROTOCOLO, default='A')
-
inicio_numeracao_protocolo = models.PositiveIntegerField(
verbose_name=_('Início da numeração de protocolo'),
default=1
)
+ # Linha 3 -------------------------
+ identificacao_de_documentos = models.CharField(
+ max_length=254,
+ verbose_name=_('Formato da identificação dos documentos'),
+ default='{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}',
+ help_text="""
+ Como mostrar a identificação dos documentos administrativos?
+ Você pode usar um conjunto de combinações que pretender.
+ Ao fazer sua edição, será mostrado logo abaixo o último documento cadastrado, como exemplo de resultado de sua edição.
+ Em caso de erro, nenhum documento será mostrado e aparecerá apenas o formato padrão mínimo, que é este: "{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}".
+ Muito importante, use as chaves "{}", sem elas, você estará inserindo um texto qualquer e não o valor de um campo.
+ Você pode combinar as seguintes campos: {sigla} {nome} {numero} {ano} {complemento} {assunto}
+ Ainda pode ser usado {/}, {-}, {.} se você quiser que uma barra, traço, ou ponto
+ seja adicionado apenas se o próximo campo que será usado tenha algum conteúdo
+ (não use dois destes destes condicionais em sequência, somente o último será considerado).
+ """
+ )
- esfera_federacao = models.CharField(
+ # MÓDULO PROPOSIÇÕES
+ # Linha 1 ----------
+ sequencia_numeracao_proposicao = models.CharField(
max_length=1,
- blank=True,
- default="",
- verbose_name=_('Esfera Federação'),
- choices=ESFERA_FEDERACAO_CHOICES)
+ verbose_name=_('Sequência de numeração de proposições'),
+ choices=SEQUENCIA_NUMERACAO_PROPOSICAO, default='A')
+ receber_recibo_proposicao = models.BooleanField(
+ verbose_name=_('Protocolar proposição somente com recibo?'),
+ choices=YES_NO_CHOICES, default=True)
+ proposicao_incorporacao_obrigatoria = models.CharField(
+ verbose_name=_('Regra de incorporação de proposições e protocolo'),
+ max_length=1, choices=POLITICA_PROTOCOLO_CHOICES, default='O')
+ escolher_numero_materia_proposicao = models.BooleanField(
+ verbose_name=_(
+ 'Indicar número da matéria a ser gerada na proposição?'),
+ choices=YES_NO_CHOICES, default=False)
- # TODO: a ser implementado na versão 3.2
- # painel_aberto = models.BooleanField(
- # verbose_name=_('Painel aberto para usuário anônimo'),
- # choices=YES_NO_CHOICES, default=False)
+ # MÓDULO MATÉRIA LEGISLATIVA
+ # Linha 1 ------------------
+ tramitacao_origem_fixa = models.BooleanField(
+ verbose_name=_(
+ 'Fixar origem de novas tramitações como sendo a tramitação de destino da última tramitação?'),
+ choices=YES_NO_CHOICES,
+ default=True,
+ help_text=_('Ao utilizar a opção NÂO, você compreende que os controles '
+ 'de origem e destino das tramitações são anulados, '
+ 'podendo seu operador registrar quaisquer origem e '
+ 'destino para as tramitações. Se você colocar Não, '
+ 'fizer tramitações aleatórias e voltar para SIM, '
+ 'o destino da tramitação mais recente será utilizado '
+ 'para a origem de uma nova inserção!'))
+ tramitacao_materia = models.BooleanField(
+ verbose_name=_(
+ 'Tramitar matérias anexadas junto com as matérias principais?'),
+ choices=YES_NO_CHOICES, default=True)
+ # MÓDULO NORMAS JURÍDICAS
+ # MÓDULO TEXTOS ARTICULADOS
+ # Linha 1 -----------------
texto_articulado_proposicao = models.BooleanField(
verbose_name=_('Usar Textos Articulados para Proposições'),
choices=YES_NO_CHOICES, default=False)
-
texto_articulado_materia = models.BooleanField(
verbose_name=_('Usar Textos Articulados para Matérias'),
choices=YES_NO_CHOICES, default=False)
-
texto_articulado_norma = models.BooleanField(
verbose_name=_('Usar Textos Articulados para Normas'),
choices=YES_NO_CHOICES, default=True)
- proposicao_incorporacao_obrigatoria = models.CharField(
- verbose_name=_('Regra de incorporação de proposições e protocolo'),
- max_length=1, choices=POLITICA_PROTOCOLO_CHOICES, default='O')
-
+ # MÓDULO SESSÃO PLENÁRIA
assinatura_ata = models.CharField(
verbose_name=_('Quem deve assinar a ata'),
max_length=1, choices=ASSINATURA_ATA_CHOICES, default='T')
-
+ # MÓDULO PAINEL
cronometro_discurso = models.DurationField(
verbose_name=_('Cronômetro do Discurso'),
blank=True,
@@ -174,41 +236,20 @@ class AppConfig(models.Model):
default=False,
verbose_name=_('Mostrar brasão da Casa no painel?'))
- receber_recibo_proposicao = models.BooleanField(
- verbose_name=_('Protocolar proposição somente com recibo?'),
- choices=YES_NO_CHOICES, default=True)
-
- protocolo_manual = models.BooleanField(
- verbose_name=_('Informar data e hora de protocolo?'),
- choices=YES_NO_CHOICES, default=False)
-
- escolher_numero_materia_proposicao = models.BooleanField(
- verbose_name=_(
- 'Indicar número da matéria a ser gerada na proposição?'),
- choices=YES_NO_CHOICES, default=False)
+ # MÓDULO ESTATÍSTICAS DE ACESSO
+ estatisticas_acesso_normas = models.CharField(
+ max_length=1,
+ verbose_name=_('Estatísticas de acesso a normas'),
+ choices=RELATORIO_ATOS_ACESSADOS, default='N')
- tramitacao_origem_fixa = models.BooleanField(
- verbose_name=_(
- 'Fixar origem de novas tramitações como sendo a tramitação de destino da última tramitação?'),
- choices=YES_NO_CHOICES,
- default=True,
- help_text=_('Ao utilizar a opção NÂO, você compreende que os controles '
- 'de origem e destino das tramitações são anulados, '
- 'podendo seu operador registrar quaisquer origem e '
- 'destino para as tramitações. Se você colocar Não, '
- 'fizer tramitações aleatórias e voltar para SIM, '
- 'o destino da tramitação mais recente será utilizado '
- 'para a origem de uma nova inserção!'))
+ # MÓDULO SEGURANÇA
- tramitacao_materia = models.BooleanField(
- verbose_name=_(
- 'Tramitar matérias anexadas junto com as matérias principais?'),
- choices=YES_NO_CHOICES, default=True)
+ # MÓDULO LEXML
- tramitacao_documento = models.BooleanField(
- verbose_name=_(
- 'Tramitar documentos anexados junto com os documentos principais?'),
- choices=YES_NO_CHOICES, default=True)
+ # TODO: a ser implementado na versão 3.2
+ # painel_aberto = models.BooleanField(
+ # verbose_name=_('Painel aberto para usuário anônimo'),
+ # choices=YES_NO_CHOICES, default=False)
google_recaptcha_site_key = models.CharField(
verbose_name=_('Chave pública gerada pelo Google Recaptcha'),
@@ -217,11 +258,6 @@ class AppConfig(models.Model):
verbose_name=_('Chave privada gerada pelo Google Recaptcha'),
max_length=256, default='')
- sapl_as_sapn = models.BooleanField(
- verbose_name=_(
- 'Utilizar SAPL como SAPN?'),
- choices=YES_NO_CHOICES, default=False)
-
class Meta:
verbose_name = _('Configurações da Aplicação')
verbose_name_plural = _('Configurações da Aplicação')
@@ -231,15 +267,32 @@ class AppConfig(models.Model):
)
ordering = ('-id',)
+ def save(self, force_insert=False, force_update=False, using=None,
+ update_fields=None):
+ fields = self._meta.get_fields()
+ for f in fields:
+ if f.name != 'id' and not cache.get(f'sapl_{f.name}') is None:
+ cache.set(f'sapl_{f.name}', getattr(self, f.name), 600)
+
+ return models.Model.save(self, force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields)
+
@classmethod
def attr(cls, attr):
+ value = cache.get(f'sapl_{attr}')
+ if not value is None:
+ return value
+ print(f'entrou aqui para {attr}')
+
config = AppConfig.objects.first()
if not config:
config = AppConfig()
config.save()
- return getattr(config, attr)
+ value = getattr(config, attr)
+ cache.set(f'sapl_{attr}', value, 600)
+
+ return value
def __str__(self):
return _('Configurações da Aplicação - %(id)s') % {
diff --git a/sapl/base/views.py b/sapl/base/views.py
index f1385e3a2..05a6c8f49 100644
--- a/sapl/base/views.py
+++ b/sapl/base/views.py
@@ -4,7 +4,9 @@ import datetime
import itertools
import logging
import os
+import re
+from django.apps.registry import apps
from django.contrib import messages
from django.contrib.auth import get_user_model, views
from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -32,8 +34,8 @@ from django.views.generic.base import RedirectView, TemplateView
from django_filters.views import FilterView
from haystack.query import SearchQuerySet
from haystack.views import SearchView
-
from ratelimit.decorators import ratelimit
+
from sapl import settings
from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica
from sapl.base.forms import (AutorForm, TipoAutorForm, AutorFilterSet, RecuperarSenhaForm,
@@ -1893,6 +1895,7 @@ class UserCrud(Crud):
list_field_names = [
'usuario', 'groups', 'is_active'
]
+
def openapi_url(self):
return ''
@@ -1927,7 +1930,6 @@ class UserCrud(Crud):
class DetailView(Crud.DetailView):
layout_key = 'UserDetail'
-
def hook_usuario(self, obj):
return 'Usuário', '{}
{}'.format(
obj.get_full_name() or '...',
@@ -2100,10 +2102,45 @@ class AppConfigCrud(CrudAux):
kwargs={'pk': app_config.pk}))
class UpdateView(CrudAux.UpdateView):
-
- template_name = 'base/AppConfig.html'
form_class = ConfiguracoesAppForm
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['title'] = self.model._meta.verbose_name
+ return context
+
+ def get(self, request, *args, **kwargs):
+ if 'jsidd' in request.GET:
+ return self.json_simular_identificacao_de_documentos(request, *args, **kwargs)
+
+ return super().get(request, *args, **kwargs)
+
+ def json_simular_identificacao_de_documentos(self, request, *args, **kwargs):
+
+ DocumentoAdministrativo = apps.get_model(
+ 'protocoloadm',
+ 'DocumentoAdministrativo'
+ )
+
+ d = DocumentoAdministrativo.objects.order_by('-id').first()
+
+ jsidd = request.GET.get('jsidd', '')
+ values = {
+ '{sigla}': d.tipo.sigla if d else 'OF',
+ '{nome}': d.tipo.descricao if d else 'Ofício',
+ '{numero}': f'{d.numero:0>3}' if d else '001',
+ '{ano}': f'{d.ano}' if d else str(timezone.now().year),
+ '{complemento}': d.complemento if d else 'GAB',
+ '{assunto}': d.assunto if d else 'Simulação de Identificação de Documentos'
+ }
+
+ result = DocumentoAdministrativo.mask_to_str(values, jsidd)
+
+ return JsonResponse({
+ 'jsidd': result[0],
+ 'error': list(result[1])
+ })
+
def form_valid(self, form):
numeracao = AppConfig.objects.last().sequencia_numeracao_protocolo
numeracao_antiga = AppConfig.objects.last().inicio_numeracao_protocolo
diff --git a/sapl/norma/models.py b/sapl/norma/models.py
index a24c7ac86..2fbd96ccf 100644
--- a/sapl/norma/models.py
+++ b/sapl/norma/models.py
@@ -151,7 +151,9 @@ class NormaJuridica(models.Model):
verbose_name=_('Tipo da Norma Jurídica'))
materia = models.ForeignKey(
MateriaLegislativa, blank=True, null=True,
- on_delete=models.PROTECT, verbose_name=_('Matéria'))
+ on_delete=models.PROTECT,
+ verbose_name=_('Matéria'),
+ related_name='normajuridica_set')
orgao = models.ForeignKey(
Orgao, blank=True, null=True,
on_delete=models.PROTECT, verbose_name=_('Órgão'))
diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py
index 744d30e5e..58223f21c 100644
--- a/sapl/protocoloadm/forms.py
+++ b/sapl/protocoloadm/forms.py
@@ -1139,9 +1139,10 @@ class DocumentoAdministrativoForm(FileFieldCheckMixin, ModelForm):
tipo = TipoDocumentoAdministrativo.objects.get(
id=tipo_documento)
raise ValidationError(
- _('{}/{} ({}) já existente!'.format(numero_documento,
- ano_documento,
- tipo)))
+ _('{}/{} ({}) já existente! '
+ 'Você diferenciar preenchendo o campo complemento'.format(numero_documento,
+ ano_documento,
+ tipo)))
# campos opcionais, mas que se informados devem ser válidos
if numero_protocolo and ano_protocolo:
diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py
index 82f899465..883ca4274 100644
--- a/sapl/protocoloadm/models.py
+++ b/sapl/protocoloadm/models.py
@@ -1,10 +1,13 @@
+import re
+
from django.db import models
from django.utils import timezone
+from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from model_utils import Choices
import reversion
-from sapl.base.models import Autor
+from sapl.base.models import Autor, AppConfig as SaplAppConfig
from sapl.materia.models import TipoMateriaLegislativa, UnidadeTramitacao,\
MateriaLegislativa
from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, texto_upload_path,
@@ -250,19 +253,67 @@ class DocumentoAdministrativo(models.Model):
verbose_name_plural = _('Documentos Administrativos')
ordering = ('id',)
- def __str__(self):
- return _('%(tipo)s - %(assunto)s') % {
- 'tipo': self.tipo, 'assunto': self.assunto
+ @classmethod
+ def mask_to_str(cls, values, mask):
+ erro = set()
+ pattern = '({[^{}]+}|{[ /.-]*})'
+ campos_escolhidos = re.findall(pattern, mask)
+ campos_permitidos = {
+ '{.}', '{/}', '{-}',
+ '{sigla}',
+ '{nome}',
+ '{numero}',
+ '{ano}',
+ '{complemento}',
+ '{assunto}',
+ }
+ condicionais = {
+ '{.}': '.',
+ '{/}': '/',
+ '{-}': '-',
}
- @property
- def epigrafe(self):
- return _('%(tipo)s - %(numero)s/%(ano)s') % {
- 'tipo': self.tipo,
- 'numero': self.numero,
- 'ano': self.ano
+ erro = set(campos_escolhidos) - campos_permitidos
+
+ if erro:
+ mask = '{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}'
+ campos_escolhidos = re.findall(pattern, mask)
+
+ for i, k in enumerate(campos_escolhidos):
+ if k in values.keys():
+ if i > 0 and campos_escolhidos[i - 1] in condicionais:
+ mask = mask.replace(
+ campos_escolhidos[i - 1],
+ condicionais[campos_escolhidos[i - 1]]if values[k] else '', 1)
+ mask = mask.replace(k, values[k], 1)
+ elif k in condicionais:
+ if i > 0 and campos_escolhidos[i - 1] in condicionais:
+ mask = mask.replace(
+ campos_escolhidos[i - 1],
+ '', 1)
+ if i + 1 == len(campos_escolhidos):
+ mask = mask.replace(k, '', 1)
+
+ return mask, erro
+
+ @cached_property
+ def _identificacao_de_documento(self):
+ mask = SaplAppConfig.attr('identificacao_de_documentos')
+
+ values = {
+ '{sigla}': self.tipo.sigla,
+ '{nome}': self.tipo.descricao,
+ '{numero}': f'{self.numero:0>3}',
+ '{ano}': f'{self.ano}',
+ '{complemento}': self.complemento,
+ '{assunto}': self.assunto
}
+ return DocumentoAdministrativo.mask_to_str(values, mask)[0]
+
+ def __str__(self):
+ return self._identificacao_de_documento
+
def delete(self, using=None, keep_parents=False):
texto_integral = self.texto_integral
result = super().delete(using=using, keep_parents=keep_parents)
@@ -487,11 +538,6 @@ class VinculoDocAdminMateria(models.Model):
def __str__(self):
return f'Vinculo: {self.documento} - {self.materia}'
- return _('Vinculo %(documento)s // %(materia)s') % {
- 'documento': self.documento.epigrafe,
- 'materia': self.materia
- }
-
@reversion.register()
class AcompanhamentoDocumento(models.Model):
diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py
index 869c6d240..2b1346f7b 100755
--- a/sapl/protocoloadm/views.py
+++ b/sapl/protocoloadm/views.py
@@ -1783,7 +1783,7 @@ class VinculoDocAdminMateriaCrud(MasterDetailCrud):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- context['title'] = self.object.documento.epigrafe
+ context['title'] = self.object.documento
return context
def get_initial(self):
diff --git a/sapl/templates/base/AppConfig.html b/sapl/templates/base/AppConfig.html
deleted file mode 100644
index 6865a8500..000000000
--- a/sapl/templates/base/AppConfig.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% extends "base.html" %}
-{% load i18n crispy_forms_tags menus%}
-
-{% block base_content %}
-{% crispy form %}
-{% endblock base_content %}
diff --git a/sapl/templates/base/appconfig_form.html b/sapl/templates/base/appconfig_form.html
new file mode 100644
index 000000000..2f152f06e
--- /dev/null
+++ b/sapl/templates/base/appconfig_form.html
@@ -0,0 +1,38 @@
+{% extends "base.html" %}
+{% load i18n crispy_forms_tags menus%}
+
+{% block base_content %}
+{% crispy form %}
+{% endblock base_content %}
+
+{% block extra_js %}
+
+{% endblock %}
diff --git a/sapl/templates/base/layouts.yaml b/sapl/templates/base/layouts.yaml
index 69c06a1c4..e9029810d 100644
--- a/sapl/templates/base/layouts.yaml
+++ b/sapl/templates/base/layouts.yaml
@@ -20,40 +20,29 @@ UserDetail:
AppConfig:
{% trans 'Configurações Gerais' %}:
- - esfera_federacao documentos_administrativos sapl_as_sapn
+ - esfera_federacao sapl_as_sapn
#{% trans 'Módulo Parlamentares' %}:
-
#{% trans 'Módulo Mesa Diretora' %}:
-
#{% trans 'Módulo Comissões' %}:
-
#{% trans 'Módulo Bancadas Parlamentares' %}:
- # {% trans 'Módulo Normas Jurídicas' %}:
+ {% trans 'Módulo Administrativo' %}:
+ - documentos_administrativos tramitacao_documento
+ - protocolo_manual sequencia_numeracao_protocolo inicio_numeracao_protocolo
+ - identificacao_de_documentos
{% trans 'Módulo Proposições' %}:
- - sequencia_numeracao_proposicao sequencia_numeracao_protocolo inicio_numeracao_protocolo
- - protocolo_manual receber_recibo_proposicao
- - proposicao_incorporacao_obrigatoria escolher_numero_materia_proposicao
+ - sequencia_numeracao_proposicao receber_recibo_proposicao proposicao_incorporacao_obrigatoria escolher_numero_materia_proposicao
{% trans 'Módulo Matéria Legislativa' %}:
- - tramitacao_origem_fixa tramitacao_materia tramitacao_documento
+ - tramitacao_origem_fixa:7 tramitacao_materia
+ # {% trans 'Módulo Normas Jurídicas' %}:
{% trans 'Módulo Textos Articulados' %}:
- texto_articulado_proposicao texto_articulado_materia texto_articulado_norma
- #{% trans 'Módulo Sessão Plenária' %}:
-
- #{% trans 'Módulo LexML' %}:
-
- #{% trans 'Módulo Administrativo' %}:
-
-
- {% trans 'Estatísticas de acesso' %}:
- - estatisticas_acesso_normas
-
- {% trans 'Assinaturas' %}:
+ {% trans 'Módulo Sessão Plenária' %}:
- assinatura_ata
{% trans 'Módulo Painel' %}:
@@ -61,9 +50,14 @@ AppConfig:
- cronometro_ordem cronometro_consideracoes
- mostrar_brasao_painel
+ {% trans 'Estatísticas de acesso' %}:
+ - estatisticas_acesso_normas
+
{% trans 'Segurança' %}:
- google_recaptcha_site_key google_recaptcha_secret_key
+ #{% trans 'Módulo LexML' %}:
+
TipoAutor:
{% trans 'Tipo Autor' %}:
- descricao
diff --git a/sapl/templates/materia/layouts.yaml b/sapl/templates/materia/layouts.yaml
index 142dcdf91..6ab3dbf2e 100644
--- a/sapl/templates/materia/layouts.yaml
+++ b/sapl/templates/materia/layouts.yaml
@@ -29,6 +29,7 @@ MateriaLegislativa:
- data_apresentacao numero_protocolo tipo_apresentacao
- tipo_autor autor
- texto_original
+
{% trans 'Outras Informações' %}:
- apelido dias_prazo polemica
- objeto regime_tramitacao em_tramitacao
diff --git a/sapl/templates/materia/materialegislativa_detail.html b/sapl/templates/materia/materialegislativa_detail.html
index 3b736318f..032ccb3c2 100644
--- a/sapl/templates/materia/materialegislativa_detail.html
+++ b/sapl/templates/materia/materialegislativa_detail.html
@@ -19,33 +19,43 @@
{% block detail_content %}
{{ block.super }}
{% if object.numero_protocolo %}
- Protocolo: {{ object.numero_protocolo }}/{{ object.ano }},
- Data Protocolo:
+ Protocolo: {{ object.numero_protocolo }}/{{ object.ano }},
+ Data Protocolo:
{{ object.data_entrada_protocolo|localtime|date:"d/m/Y"|default_if_none:"Não informado" }} -
Horário: {{ object.data_entrada_protocolo|localtime|date:"G:i:s" }}
{% endif %}
{% if object.registrovotacao_set.exists %}
- Data Votação:
- {% for rv in object.registrovotacao_set.all %}
- {% if rv.ordem %}
-
- {{ rv.ordem.sessao_plenaria.data_inicio }}
-
- {% elif rv.expediente %}
-
- {{ rv.expediente.sessao_plenaria.data_inicio }}
-
- {% endif %}
-
- {% endfor %}
+ Data Votação:
+ {% for rv in object.registrovotacao_set.all %}
+ {% if rv.ordem %}
+
+ {{ rv.ordem.sessao_plenaria.data_inicio }}
+
+ {% elif rv.expediente %}
+
+ {{ rv.expediente.sessao_plenaria.data_inicio }}
+
+ {% endif %}
+
+ {% endfor %}
{% endif %}
+
{% if object.normajuridica_set.last %}
-
Norma Jurídica Relacionada
- +Norma Jurídica Relacionada
+ +Documentos Administrativos Públicos Vinculados a Matéria