From 32af19a63d42e7efff91d3223c27b01bc1845277 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Thu, 6 Oct 2016 13:25:32 -0300 Subject: [PATCH] =?UTF-8?q?Conclui=20integra=C3=A7=C3=A3o=20de=20compilaca?= =?UTF-8?q?o=20com=20sapl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- .../migrations/0056_auto_20161006_1251.py | 21 ++ sapl/compilacao/models.py | 4 +- sapl/compilacao/views.py | 228 ++++++++++-------- sapl/materia/views.py | 44 +++- sapl/norma/views.py | 22 +- sapl/static/js/compilacao_edit.js | 1 + 6 files changed, 206 insertions(+), 114 deletions(-) create mode 100644 sapl/compilacao/migrations/0056_auto_20161006_1251.py diff --git a/sapl/compilacao/migrations/0056_auto_20161006_1251.py b/sapl/compilacao/migrations/0056_auto_20161006_1251.py new file mode 100644 index 000000000..d92358d04 --- /dev/null +++ b/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'), + ), + ] diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index e2425bfcf..72bfc47e1 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -71,9 +71,9 @@ class BaseModel(models.Model): class TipoTextoArticulado(models.Model): sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) - content_type = models.ForeignKey( + content_type = models.OneToOneField( ContentType, - blank=True, null=True, default=None, + null=True, default=None, verbose_name=_('Modelo Integrado')) participacao_social = models.NullBooleanField( default=False, diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index c56cadeb4..6a1e907d9 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -5,6 +5,7 @@ import sys from braces.views import FormMessagesMixin from django import forms +from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required 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.db import transaction, connection from django.db.models import Q +from django.db.utils import IntegrityError from django.http.response import (HttpResponse, HttpResponseRedirect, JsonResponse) from django.shortcuts import get_object_or_404, redirect @@ -56,15 +58,46 @@ TipoDispositivoCrud = Crud.build( 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): - def ta_ativado(self, kwargs): - pass + def get_redirect_deactivated(self): + messages.error( + self.request, + _('O modulo de Textos Articulados está desativado.')) + return redirect('/') def get(self, request, *args, **kwargs): try: - if not TipoDispositivo.objects.exists(): + if settings.DEBUG or not TipoDispositivo.objects.exists(): self.import_pattern() except Exception as e: logger.error( @@ -72,6 +105,7 @@ class IntegracaoTaView(TemplateView): _('Ocorreu erro na importação do arquivo base dos Tipos de' 'Dispositivos, entre outras informações iniciais.'), str(e))) + return self.get_redirect_deactivated() item = get_object_or_404(self.model, pk=kwargs['pk']) related_object_type = ContentType.objects.get_for_model(item) @@ -83,76 +117,74 @@ class IntegracaoTaView(TemplateView): tipo_ta = TipoTextoArticulado.objects.filter( 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(): - 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 hasattr(item, 'ementa') and item.ementa: + ta.ementa = item.ementa + else: + ta.ementa = _('Integração com %s sem ementa.') % item - if hasattr(item, 'ementa') and item.ementa: - ta.ementa = item.ementa - else: - ta.ementa = _('Integração com %s sem ementa.') % item + if hasattr(item, 'observacao') and item.observacao: + ta.observacao = item.observacao + else: + ta.observacao = _('Integração com %s sem observacao.') % item - if hasattr(item, 'observacao') and item.observacao: - ta.observacao = item.observacao - else: - ta.observacao = _('Integração com %s sem observacao.') % item + if hasattr(item, 'numero') and item.numero: + ta.numero = item.numero + else: + 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: - ta.numero = item.numero - else: - ta.numero = int('%s%s%s' % ( - int(datetime.now().year), - int(datetime.now().month), - int(datetime.now().day))) + if hasattr(item, 'ano') and item.ano: + ta.ano = item.ano + else: + ta.ano = datetime.now().year - if hasattr(item, 'ano') and item.ano: - ta.ano = item.ano - else: - ta.ano = datetime.now().year + if hasattr(item, 'data_apresentacao'): + ta.data = item.data_apresentacao + elif hasattr(item, 'data'): + ta.data = item.data + else: + ta.data = datetime.now() - if hasattr(item, 'data_apresentacao'): - ta.data = item.data_apresentacao - elif hasattr(item, 'data'): - ta.data = item.data - else: - ta.data = datetime.now() + ta.save() - 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', - kwargs={'ta_id': ta.pk})) - else: - msg = messages.error if not request.user.is_anonymous( - ) else messages.info + """msg = messages.error if not request.user.is_anonymous( + ) else messages.info - msg(request, - _('A funcionalidade de Textos Articulados está desativada.')) + msg(request, + _('A funcionalidade de Textos Articulados está desativada.')) - if not request.user.is_anonymous(): - msg( - request, - _('Para ativá-la, os Tipos de Textos devem ser criados.')) + if not request.user.is_anonymous(): + msg( + request, + _('Para ativá-la, os Tipos de Textos devem ser criados.')) - msg(request, - _('Sua tela foi redirecionada para a tela de ' - 'cadastro de Textos Articulados.')) + msg(request, + _('Sua tela foi redirecionada para a tela de ' + 'cadastro de Textos Articulados.')) - return redirect(to=reverse_lazy('sapl.compilacao:tipo_ta_list', - kwargs={})) - else: + return redirect(to=reverse_lazy('sapl.compilacao:tipo_ta_list', + kwargs={})) + else: - return redirect(to=reverse_lazy( - '%s:%s_detail' % ( - item._meta.app_config.name, item._meta.model_name), - kwargs={'pk': item.pk})) + return redirect(to=reverse_lazy( + '%s:%s_detail' % ( + item._meta.app_config.name, item._meta.model_name), + kwargs={'pk': item.pk}))""" def import_pattern(self): @@ -166,48 +198,52 @@ class IntegracaoTaView(TemplateView): with connection.cursor() as cursor: for line in lines: - cursor.execute(line) - - print(lines) + try: + cursor.execute(line) + 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); - # INSERT INTO compilacao_tipotextoarticulado (id, sigla, descricao, participacao_social, content_type_id) VALUES (5, 'PRP', 'Proposição', true, 136); - # INSERT INTO compilacao_tipotextoarticulado (id, sigla, descricao, - # participacao_social, content_type_id) VALUES (1, 'NJ', 'Norma Juridica', - # false, 142); + for view in integrations_view_names: + try: + tipo = TipoTextoArticulado() + tipo.sigla = cria_sigla( + 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: 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: def get_context_data(self, **kwargs): diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 4efbc599b..a1638acfe 100644 --- a/sapl/materia/views.py +++ b/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_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.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.crud.base import (ACTION_CREATE, ACTION_DELETE, ACTION_DETAIL, @@ -72,6 +72,38 @@ TipoAutorCrud = CrudAux.build( 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): tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo']) materia = MateriaLegislativa.objects.filter(tipo=tipo).last() @@ -970,16 +1002,6 @@ class MateriaLegislativaPesquisaView(FilterView): return context -class MateriaTaView(IntegracaoTaView): - model = MateriaLegislativa - model_type_foreignkey = TipoMateriaLegislativa - - -class ProposicaoTaView(IntegracaoTaView): - model = Proposicao - model_type_foreignkey = TipoProposicao - - class AcompanhamentoMateriaView(PermissionRequiredMixin, CreateView): template_name = "materia/acompanhamento_materia.html" permission_required = permissoes_materia() diff --git a/sapl/norma/views.py b/sapl/norma/views.py index a93bb012d..19aba74e3 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -5,6 +5,7 @@ from django.shortcuts import redirect from django.views.generic import FormView, ListView from django.views.generic.base import RedirectView +from sapl.base.models import AppConfig from sapl.compilacao.views import IntegracaoTaView from sapl.crud.base import RP_DETAIL, RP_LIST, Crud, CrudAux, make_pagination from sapl.norma.forms import NormaJuridicaForm @@ -23,6 +24,22 @@ TipoNormaCrud = CrudAux.build( 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): model = NormaJuridica help_path = 'norma_juridica' @@ -179,8 +196,3 @@ class PesquisaNormaListView(ListView): context['page_range'] = make_pagination( page_obj.number, paginator.num_pages) return context - - -class NormaTaView(IntegracaoTaView): - model = NormaJuridica - model_type_foreignkey = TipoNormaJuridica diff --git a/sapl/static/js/compilacao_edit.js b/sapl/static/js/compilacao_edit.js index 89d69f200..722d4755a 100644 --- a/sapl/static/js/compilacao_edit.js +++ b/sapl/static/js/compilacao_edit.js @@ -548,6 +548,7 @@ function DispositivoEdit() { instance.init = function() { + $('.dpt-actions-fixed').first().css('opacity','1'); editortype = ReadCookie("editortype"); if (editortype == null || editortype == '') { editortype = "textarea"