Browse Source

Conclui integração de compilacao com sapl

- Adiciona configuração de ativação da compilação de Textos Articulados a
base de configurações do sapl... model sapl.base.models.AppConfig
- Adiciona rotina de carga inicial das configurações mediante
parametrização que segue Lei Federal Brasileira - Lei Complementar 95 -
já com um perfil opcional para variação númerica de Dispositivos.
pull/704/head
LeandroRoberto 8 years ago
parent
commit
32af19a63d
  1. 21
      sapl/compilacao/migrations/0056_auto_20161006_1251.py
  2. 4
      sapl/compilacao/models.py
  3. 228
      sapl/compilacao/views.py
  4. 44
      sapl/materia/views.py
  5. 22
      sapl/norma/views.py
  6. 1
      sapl/static/js/compilacao_edit.js

21
sapl/compilacao/migrations/0056_auto_20161006_1251.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-10-06 15:51
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0055_dispositivo_dispositivo_de_revogacao'),
]
operations = [
migrations.AlterField(
model_name='tipotextoarticulado',
name='content_type',
field=models.OneToOneField(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='Modelo Integrado'),
),
]

4
sapl/compilacao/models.py

@ -71,9 +71,9 @@ class BaseModel(models.Model):
class TipoTextoArticulado(models.Model): class TipoTextoArticulado(models.Model):
sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) sigla = models.CharField(max_length=3, verbose_name=_('Sigla'))
descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição'))
content_type = models.ForeignKey( content_type = models.OneToOneField(
ContentType, ContentType,
blank=True, null=True, default=None, null=True, default=None,
verbose_name=_('Modelo Integrado')) verbose_name=_('Modelo Integrado'))
participacao_social = models.NullBooleanField( participacao_social = models.NullBooleanField(
default=False, default=False,

228
sapl/compilacao/views.py

@ -5,6 +5,7 @@ import sys
from braces.views import FormMessagesMixin from braces.views import FormMessagesMixin
from django import forms from django import forms
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -12,6 +13,7 @@ from django.core.signing import Signer
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
from django.db import transaction, connection from django.db import transaction, connection
from django.db.models import Q from django.db.models import Q
from django.db.utils import IntegrityError
from django.http.response import (HttpResponse, HttpResponseRedirect, from django.http.response import (HttpResponse, HttpResponseRedirect,
JsonResponse) JsonResponse)
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
@ -56,15 +58,46 @@ TipoDispositivoCrud = Crud.build(
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def get_integrations_view_names():
result = []
modules = sys.modules
for key, value in modules.items():
if key.endswith('.views'):
for v in value.__dict__.values():
if hasattr(v, '__bases__'):
for base in v.__bases__:
if base == IntegracaoTaView:
result.append(v)
return result
def choice_models_in_extenal_views():
integrations_view_names = get_integrations_view_names()
result = [(None, '-------------'), ]
for item in integrations_view_names:
if hasattr(item, 'model') and hasattr(item, 'model_type_foreignkey'):
ct = ContentType.objects.filter(
model=item.model.__name__.lower(),
app_label=item.model._meta.app_label)
if ct.exists():
result.append((
ct[0].pk,
item.model._meta.verbose_name_plural))
return result
class IntegracaoTaView(TemplateView): class IntegracaoTaView(TemplateView):
def ta_ativado(self, kwargs): def get_redirect_deactivated(self):
pass messages.error(
self.request,
_('O modulo de Textos Articulados está desativado.'))
return redirect('/')
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try: try:
if not TipoDispositivo.objects.exists(): if settings.DEBUG or not TipoDispositivo.objects.exists():
self.import_pattern() self.import_pattern()
except Exception as e: except Exception as e:
logger.error( logger.error(
@ -72,6 +105,7 @@ class IntegracaoTaView(TemplateView):
_('Ocorreu erro na importação do arquivo base dos Tipos de' _('Ocorreu erro na importação do arquivo base dos Tipos de'
'Dispositivos, entre outras informações iniciais.'), 'Dispositivos, entre outras informações iniciais.'),
str(e))) str(e)))
return self.get_redirect_deactivated()
item = get_object_or_404(self.model, pk=kwargs['pk']) item = get_object_or_404(self.model, pk=kwargs['pk'])
related_object_type = ContentType.objects.get_for_model(item) related_object_type = ContentType.objects.get_for_model(item)
@ -83,76 +117,74 @@ class IntegracaoTaView(TemplateView):
tipo_ta = TipoTextoArticulado.objects.filter( tipo_ta = TipoTextoArticulado.objects.filter(
content_type=related_object_type) content_type=related_object_type)
if self.ta_ativado(kwargs): if not ta.exists():
ta = TextoArticulado()
tipo_ta = TipoTextoArticulado.objects.filter(
content_type=related_object_type)[:1]
if tipo_ta.exists():
ta.tipo_ta = tipo_ta[0]
ta.content_object = item
else:
ta = ta[0]
if not ta.exists(): if hasattr(item, 'ementa') and item.ementa:
ta = TextoArticulado() ta.ementa = item.ementa
tipo_ta = TipoTextoArticulado.objects.filter( else:
content_type=related_object_type)[:1] ta.ementa = _('Integração com %s sem ementa.') % item
if tipo_ta.exists():
ta.tipo_ta = tipo_ta[0]
ta.content_object = item
else:
ta = ta[0]
if hasattr(item, 'ementa') and item.ementa: if hasattr(item, 'observacao') and item.observacao:
ta.ementa = item.ementa ta.observacao = item.observacao
else: else:
ta.ementa = _('Integração com %s sem ementa.') % item ta.observacao = _('Integração com %s sem observacao.') % item
if hasattr(item, 'observacao') and item.observacao: if hasattr(item, 'numero') and item.numero:
ta.observacao = item.observacao ta.numero = item.numero
else: else:
ta.observacao = _('Integração com %s sem observacao.') % item ta.numero = int('%s%s%s' % (
int(datetime.now().year),
int(datetime.now().month),
int(datetime.now().day)))
if hasattr(item, 'numero') and item.numero: if hasattr(item, 'ano') and item.ano:
ta.numero = item.numero ta.ano = item.ano
else: else:
ta.numero = int('%s%s%s' % ( ta.ano = datetime.now().year
int(datetime.now().year),
int(datetime.now().month),
int(datetime.now().day)))
if hasattr(item, 'ano') and item.ano: if hasattr(item, 'data_apresentacao'):
ta.ano = item.ano ta.data = item.data_apresentacao
else: elif hasattr(item, 'data'):
ta.ano = datetime.now().year ta.data = item.data
else:
ta.data = datetime.now()
if hasattr(item, 'data_apresentacao'): ta.save()
ta.data = item.data_apresentacao
elif hasattr(item, 'data'):
ta.data = item.data
else:
ta.data = datetime.now()
ta.save() return redirect(to=reverse_lazy('sapl.compilacao:ta_text',
kwargs={'ta_id': ta.pk}))
return redirect(to=reverse_lazy('sapl.compilacao:ta_text', """msg = messages.error if not request.user.is_anonymous(
kwargs={'ta_id': ta.pk})) ) else messages.info
else:
msg = messages.error if not request.user.is_anonymous(
) else messages.info
msg(request, msg(request,
_('A funcionalidade de Textos Articulados está desativada.')) _('A funcionalidade de Textos Articulados está desativada.'))
if not request.user.is_anonymous(): if not request.user.is_anonymous():
msg( msg(
request, request,
_('Para ativá-la, os Tipos de Textos devem ser criados.')) _('Para ativá-la, os Tipos de Textos devem ser criados.'))
msg(request, msg(request,
_('Sua tela foi redirecionada para a tela de ' _('Sua tela foi redirecionada para a tela de '
'cadastro de Textos Articulados.')) 'cadastro de Textos Articulados.'))
return redirect(to=reverse_lazy('sapl.compilacao:tipo_ta_list', return redirect(to=reverse_lazy('sapl.compilacao:tipo_ta_list',
kwargs={})) kwargs={}))
else: else:
return redirect(to=reverse_lazy( return redirect(to=reverse_lazy(
'%s:%s_detail' % ( '%s:%s_detail' % (
item._meta.app_config.name, item._meta.model_name), item._meta.app_config.name, item._meta.model_name),
kwargs={'pk': item.pk})) kwargs={'pk': item.pk}))"""
def import_pattern(self): def import_pattern(self):
@ -166,48 +198,52 @@ class IntegracaoTaView(TemplateView):
with connection.cursor() as cursor: with connection.cursor() as cursor:
for line in lines: for line in lines:
cursor.execute(line) try:
cursor.execute(line)
print(lines) except IntegrityError as e:
if not settings.DEBUG:
logger.error(
string_concat(
_('Ocorreu erro na importação: '),
line,
str(e)))
integrations_view_names = get_integrations_view_names()
def cria_sigla(verbose_name):
verbose_name = verbose_name.upper().split()
if len(verbose_name) == 1:
verbose_name = verbose_name[0]
sigla = ''
for letra in verbose_name:
if letra in 'BCDFGHJKLMNPQRSTVWXYZ':
sigla += letra
else:
sigla = ''.join([palavra[0] for palavra in verbose_name])
return sigla[:3]
# INSERT INTO compilacao_tipotextoarticulado (id, sigla, descricao, participacao_social, content_type_id) VALUES (2, 'ML', 'Matéria Legislativa', true, 119); for view in integrations_view_names:
# INSERT INTO compilacao_tipotextoarticulado (id, sigla, descricao, participacao_social, content_type_id) VALUES (5, 'PRP', 'Proposição', true, 136); try:
# INSERT INTO compilacao_tipotextoarticulado (id, sigla, descricao, tipo = TipoTextoArticulado()
# participacao_social, content_type_id) VALUES (1, 'NJ', 'Norma Juridica', tipo.sigla = cria_sigla(
# false, 142); view.model._meta.verbose_name
if view.model._meta.verbose_name
else view.model._meta.model_name)
tipo.descricao = view.model._meta.verbose_name
tipo.content_type = ContentType.objects.get_by_natural_key(
view.model._meta.app_label, view.model._meta.model_name)
tipo.save()
except IntegrityError as e:
if not settings.DEBUG:
logger.error(
string_concat(
_('Ocorreu erro na criação tipo de ta: '),
str(e)))
class Meta: class Meta:
abstract = True abstract = True
def get_integrations_view_names():
result = []
modules = sys.modules
for key, value in modules.items():
if key.endswith('.views'):
for v in value.__dict__.values():
if hasattr(v, '__bases__'):
for base in v.__bases__:
if base == IntegracaoTaView:
result.append(v)
return result
def choice_models_in_extenal_views():
integrations_view_names = get_integrations_view_names()
result = [(None, '-------------'), ]
for item in integrations_view_names:
if hasattr(item, 'model') and hasattr(item, 'model_type_foreignkey'):
ct = ContentType.objects.filter(
model=item.model.__name__.lower(),
app_label=item.model._meta.app_label)
if ct.exists():
result.append((
ct[0].pk,
item.model._meta.verbose_name_plural))
return result
class CompMixin: class CompMixin:
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

44
sapl/materia/views.py

@ -24,7 +24,7 @@ from django.views.generic import CreateView, ListView, TemplateView, UpdateView
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
from django_filters.views import FilterView from django_filters.views import FilterView
from sapl.base.models import CasaLegislativa from sapl.base.models import CasaLegislativa, AppConfig
from sapl.compilacao.views import IntegracaoTaView from sapl.compilacao.views import IntegracaoTaView
from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
from sapl.crud.base import (ACTION_CREATE, ACTION_DELETE, ACTION_DETAIL, from sapl.crud.base import (ACTION_CREATE, ACTION_DELETE, ACTION_DETAIL,
@ -72,6 +72,38 @@ TipoAutorCrud = CrudAux.build(
TipoAutor, 'regime_tramitacao') TipoAutor, 'regime_tramitacao')
class MateriaTaView(IntegracaoTaView):
model = MateriaLegislativa
model_type_foreignkey = TipoMateriaLegislativa
"""
Para manter a app compilacao isolada das outras aplicações,
este get foi implementado para tratar uma prerrogativa externa
de usuário.
"""
def get(self, request, *args, **kwargs):
if AppConfig.attr('texto_articulado_materia'):
return IntegracaoTaView.get(self, request, *args, **kwargs)
else:
return self.get_redirect_deactivated()
class ProposicaoTaView(IntegracaoTaView):
model = Proposicao
model_type_foreignkey = TipoProposicao
def get(self, request, *args, **kwargs):
"""
Para manter a app compilacao isolada das outras aplicações,
este get foi implementado para tratar uma prerrogativa externa
de usuário.
"""
if AppConfig.attr('texto_articulado_proposicao'):
return IntegracaoTaView.get(self, request, *args, **kwargs)
else:
return self.get_redirect_deactivated()
def recuperar_materia(request): def recuperar_materia(request):
tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo']) tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo'])
materia = MateriaLegislativa.objects.filter(tipo=tipo).last() materia = MateriaLegislativa.objects.filter(tipo=tipo).last()
@ -970,16 +1002,6 @@ class MateriaLegislativaPesquisaView(FilterView):
return context return context
class MateriaTaView(IntegracaoTaView):
model = MateriaLegislativa
model_type_foreignkey = TipoMateriaLegislativa
class ProposicaoTaView(IntegracaoTaView):
model = Proposicao
model_type_foreignkey = TipoProposicao
class AcompanhamentoMateriaView(PermissionRequiredMixin, CreateView): class AcompanhamentoMateriaView(PermissionRequiredMixin, CreateView):
template_name = "materia/acompanhamento_materia.html" template_name = "materia/acompanhamento_materia.html"
permission_required = permissoes_materia() permission_required = permissoes_materia()

22
sapl/norma/views.py

@ -5,6 +5,7 @@ from django.shortcuts import redirect
from django.views.generic import FormView, ListView from django.views.generic import FormView, ListView
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
from sapl.base.models import AppConfig
from sapl.compilacao.views import IntegracaoTaView from sapl.compilacao.views import IntegracaoTaView
from sapl.crud.base import RP_DETAIL, RP_LIST, Crud, CrudAux, make_pagination from sapl.crud.base import RP_DETAIL, RP_LIST, Crud, CrudAux, make_pagination
from sapl.norma.forms import NormaJuridicaForm from sapl.norma.forms import NormaJuridicaForm
@ -23,6 +24,22 @@ TipoNormaCrud = CrudAux.build(
list_field_names=['equivalente_lexml', 'sigla', 'descricao']) list_field_names=['equivalente_lexml', 'sigla', 'descricao'])
class NormaTaView(IntegracaoTaView):
model = NormaJuridica
model_type_foreignkey = TipoNormaJuridica
def get(self, request, *args, **kwargs):
"""
Para manter a app compilacao isolada das outras aplicações,
este get foi implementado para tratar uma prerrogativa externa
de usuário.
"""
if AppConfig.attr('texto_articulado_norma'):
return IntegracaoTaView.get(self, request, *args, **kwargs)
else:
return self.get_redirect_deactivated()
class NormaCrud(Crud): class NormaCrud(Crud):
model = NormaJuridica model = NormaJuridica
help_path = 'norma_juridica' help_path = 'norma_juridica'
@ -179,8 +196,3 @@ class PesquisaNormaListView(ListView):
context['page_range'] = make_pagination( context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
return context return context
class NormaTaView(IntegracaoTaView):
model = NormaJuridica
model_type_foreignkey = TipoNormaJuridica

1
sapl/static/js/compilacao_edit.js

@ -548,6 +548,7 @@ function DispositivoEdit() {
instance.init = function() { instance.init = function() {
$('.dpt-actions-fixed').first().css('opacity','1');
editortype = ReadCookie("editortype"); editortype = ReadCookie("editortype");
if (editortype == null || editortype == '') { if (editortype == null || editortype == '') {
editortype = "textarea" editortype = "textarea"

Loading…
Cancel
Save