mirror of https://github.com/interlegis/sapl.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
955 lines
33 KiB
955 lines
33 KiB
|
|
|
|
from collections import OrderedDict
|
|
from datetime import timedelta, datetime
|
|
from os.path import sys
|
|
|
|
from django import forms
|
|
from django.core.signing import Signer
|
|
from django.db.models import Q
|
|
from django.db.models.aggregates import Max
|
|
from django.http.response import JsonResponse
|
|
from django.utils.dateparse import parse_date
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from django.views.generic.base import TemplateView
|
|
from django.views.generic.edit import FormMixin
|
|
from django.views.generic.list import ListView
|
|
|
|
from compilacao.models import (Dispositivo, TipoNota, TipoVide, TipoPublicacao,
|
|
VeiculoPublicacao, TipoDispositivo)
|
|
from norma.models import NormaJuridica
|
|
from sapl.crud import build_crud
|
|
|
|
|
|
DISPOSITIVO_SELECT_RELATED = (
|
|
'tipo_dispositivo',
|
|
'norma_publicada',
|
|
'norma',
|
|
'dispositivo_atualizador',
|
|
'dispositivo_atualizador__dispositivo_pai',
|
|
'dispositivo_atualizador__dispositivo_pai__norma',
|
|
'dispositivo_atualizador__dispositivo_pai__norma__tipo',
|
|
'dispositivo_pai',
|
|
'dispositivo_pai__tipo_dispositivo')
|
|
|
|
tipo_nota_crud = build_crud(
|
|
TipoNota, 'tipo_nota', [
|
|
|
|
[_('Tipo da Nota'),
|
|
[('sigla', 2), ('nome', 10)],
|
|
[('modelo', 12)]],
|
|
])
|
|
|
|
tipo_vide_crud = build_crud(
|
|
TipoVide, 'tipo_vide', [
|
|
|
|
[_('Tipo de Vide'),
|
|
[('sigla', 2), ('nome', 10)]],
|
|
])
|
|
|
|
tipo_publicacao_crud = build_crud(
|
|
TipoPublicacao, 'tipo_publicacao', [
|
|
|
|
[_('Tipo de Publicação'),
|
|
[('sigla', 2), ('nome', 10)]],
|
|
])
|
|
|
|
|
|
veiculo_publicacao_crud = build_crud(
|
|
VeiculoPublicacao, 'veiculo_publicacao', [
|
|
|
|
[_('Veículo de Publicação'),
|
|
[('sigla', 2), ('nome', 10)]],
|
|
])
|
|
|
|
tipo_dispositivo_crud = build_crud(
|
|
TipoDispositivo, 'tipo_dispositivo', [
|
|
|
|
[_('Dados Básicos'),
|
|
[('nome', 8), ('class_css', 4)]],
|
|
|
|
[_('Configurações para Edição do Rótulo'),
|
|
[('rotulo_prefixo_texto', 3),
|
|
('rotulo_sufixo_texto', 3),
|
|
('rotulo_ordinal', 3),
|
|
('contagem_continua', 3)],
|
|
|
|
],
|
|
|
|
[_('Configurações para Renderização de Rótulo e Texto'),
|
|
|
|
|
|
|
|
[('rotulo_prefixo_html', 6),
|
|
('rotulo_sufixo_html', 6), ],
|
|
|
|
[('texto_prefixo_html', 4),
|
|
('dispositivo_de_articulacao', 4),
|
|
('texto_sufixo_html', 4)],
|
|
],
|
|
|
|
[_('Configurações para Nota Automática'),
|
|
[('nota_automatica_prefixo_html', 6),
|
|
('nota_automatica_sufixo_html', 6),
|
|
],
|
|
],
|
|
|
|
[_('Configurações para Variações Numéricas'),
|
|
|
|
[('formato_variacao0', 12)],
|
|
[('rotulo_separador_variacao01', 5), ('formato_variacao1', 7), ],
|
|
[('rotulo_separador_variacao12', 5), ('formato_variacao2', 7), ],
|
|
[('rotulo_separador_variacao23', 5), ('formato_variacao3', 7), ],
|
|
[('rotulo_separador_variacao34', 5), ('formato_variacao4', 7), ],
|
|
[('rotulo_separador_variacao45', 5), ('formato_variacao5', 7), ],
|
|
|
|
],
|
|
|
|
])
|
|
|
|
|
|
class CompilacaoView(ListView):
|
|
template_name = 'compilacao/index.html'
|
|
|
|
flag_alteradora = -1
|
|
|
|
flag_nivel_ini = 0
|
|
flag_nivel_old = -1
|
|
|
|
itens_de_vigencia = {}
|
|
|
|
inicio_vigencia = None
|
|
fim_vigencia = None
|
|
|
|
def get_queryset(self):
|
|
self.flag_alteradora = -1
|
|
self.flag_nivel_ini = 0
|
|
self.flag_nivel_old = -1
|
|
|
|
self.inicio_vigencia = None
|
|
self.fim_vigencia = None
|
|
if 'sign' in self.kwargs:
|
|
signer = Signer()
|
|
try:
|
|
string = signer.unsign(self.kwargs['sign']).split(',')
|
|
self.inicio_vigencia = parse_date(string[0])
|
|
self.fim_vigencia = parse_date(string[1])
|
|
except:
|
|
return{}
|
|
|
|
return Dispositivo.objects.filter(
|
|
inicio_vigencia__lte=self.fim_vigencia,
|
|
ordem__gt=0,
|
|
norma_id=self.kwargs['norma_id'],
|
|
).select_related(*DISPOSITIVO_SELECT_RELATED)
|
|
else:
|
|
return Dispositivo.objects.filter(
|
|
ordem__gt=0,
|
|
norma_id=self.kwargs['norma_id']
|
|
).select_related(*DISPOSITIVO_SELECT_RELATED)
|
|
|
|
def get_vigencias(self):
|
|
itens = Dispositivo.objects.filter(
|
|
norma_id=self.kwargs['norma_id'],
|
|
).order_by(
|
|
'inicio_vigencia'
|
|
).distinct(
|
|
'inicio_vigencia'
|
|
).select_related(
|
|
'norma_publicada',
|
|
'norma',
|
|
'norma_publicada__tipo',
|
|
'norma__tipo',)
|
|
|
|
ajuste_datas_vigencia = []
|
|
|
|
for item in itens:
|
|
ajuste_datas_vigencia.append(item)
|
|
|
|
lenLista = len(ajuste_datas_vigencia)
|
|
for i in range(lenLista):
|
|
if i + 1 < lenLista:
|
|
ajuste_datas_vigencia[
|
|
i].fim_vigencia = ajuste_datas_vigencia[
|
|
i + 1].inicio_vigencia - timedelta(days=1)
|
|
else:
|
|
ajuste_datas_vigencia[i].fim_vigencia = None
|
|
|
|
self.itens_de_vigencia = {}
|
|
|
|
idx = -1
|
|
length = len(ajuste_datas_vigencia)
|
|
for item in ajuste_datas_vigencia:
|
|
idx += 1
|
|
if idx == 0:
|
|
self.itens_de_vigencia[0] = [item, ]
|
|
continue
|
|
|
|
if idx + 1 < length:
|
|
ano = item.norma_publicada.ano
|
|
if ano in self.itens_de_vigencia:
|
|
self.itens_de_vigencia[ano].append(item)
|
|
else:
|
|
self.itens_de_vigencia[ano] = [item, ]
|
|
else:
|
|
self.itens_de_vigencia[9999] = [item, ]
|
|
|
|
if len(self.itens_de_vigencia.keys()) <= 1:
|
|
return {}
|
|
|
|
self.itens_de_vigencia = OrderedDict(
|
|
sorted(self.itens_de_vigencia.items(), key=lambda t: t[0]))
|
|
|
|
return self.itens_de_vigencia
|
|
|
|
def get_norma(self):
|
|
return NormaJuridica.objects.select_related('tipo').get(
|
|
pk=self.kwargs['norma_id'])
|
|
|
|
def is_norma_alteradora(self):
|
|
if self.flag_alteradora == -1:
|
|
self.flag_alteradora = Dispositivo.objects.select_related(
|
|
'dispositivos_alterados_pela_norma_set'
|
|
).filter(norma_id=self.kwargs['norma_id']).count()
|
|
return self.flag_alteradora > 0
|
|
|
|
|
|
class DispositivoView(CompilacaoView):
|
|
# template_name = 'compilacao/index.html'
|
|
template_name = 'compilacao/index_bloco.html'
|
|
|
|
def get_queryset(self):
|
|
self.flag_alteradora = -1
|
|
self.flag_nivel_ini = 0
|
|
self.flag_nivel_old = -1
|
|
|
|
try:
|
|
bloco = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id'])
|
|
except Dispositivo.DoesNotExist:
|
|
return []
|
|
|
|
self.flag_nivel_old = bloco.nivel - 1
|
|
self.flag_nivel_ini = bloco.nivel
|
|
|
|
proximo_bloco = Dispositivo.objects.filter(
|
|
ordem__gt=bloco.ordem,
|
|
nivel__lte=bloco.nivel,
|
|
norma_id=self.kwargs['norma_id'])[:1]
|
|
|
|
if proximo_bloco.count() == 0:
|
|
itens = Dispositivo.objects.filter(
|
|
ordem__gte=bloco.ordem,
|
|
norma_id=self.kwargs['norma_id']
|
|
).select_related(*DISPOSITIVO_SELECT_RELATED)
|
|
else:
|
|
itens = Dispositivo.objects.filter(
|
|
ordem__gte=bloco.ordem,
|
|
ordem__lt=proximo_bloco[0].ordem,
|
|
norma_id=self.kwargs['norma_id']
|
|
).select_related(*DISPOSITIVO_SELECT_RELATED)
|
|
return itens
|
|
|
|
|
|
class CompilacaoEditView(CompilacaoView):
|
|
template_name = 'compilacao/edit.html'
|
|
|
|
flag_alteradora = -1
|
|
|
|
flag_nivel_ini = 0
|
|
flag_nivel_old = -1
|
|
|
|
pk_add = 0
|
|
pk_view = 0
|
|
|
|
def get_queryset(self):
|
|
self.pk_add = 0
|
|
self.pk_view = 0
|
|
|
|
self.flag_alteradora = -1
|
|
self.flag_nivel_ini = 0
|
|
self.flag_nivel_old = -1
|
|
|
|
result = Dispositivo.objects.filter(
|
|
norma_id=self.kwargs['norma_id']
|
|
).select_related(*DISPOSITIVO_SELECT_RELATED)
|
|
|
|
if not result.exists():
|
|
|
|
norma = NormaJuridica.objects.get(pk=self.kwargs['norma_id'])
|
|
|
|
td = TipoDispositivo.objects.filter(class_css='articulacao')[0]
|
|
a = Dispositivo()
|
|
a.nivel = 0
|
|
a.ordem = Dispositivo.INTERVALO_ORDEM
|
|
a.ordem_bloco_atualizador = 0
|
|
a.set_numero_completo([1, 0, 0, 0, 0, 0, ])
|
|
a.norma = norma
|
|
a.tipo_dispositivo = td
|
|
a.inicio_vigencia = norma.data_publicacao
|
|
a.inicio_eficacia = norma.data_publicacao
|
|
a.timestamp = datetime.now()
|
|
a.save()
|
|
|
|
td = TipoDispositivo.objects.filter(class_css='ementa')[0]
|
|
e = Dispositivo()
|
|
e.nivel = 1
|
|
e.ordem = a.ordem + Dispositivo.INTERVALO_ORDEM
|
|
e.ordem_bloco_atualizador = 0
|
|
e.set_numero_completo([1, 0, 0, 0, 0, 0, ])
|
|
e.norma = norma
|
|
e.tipo_dispositivo = td
|
|
e.inicio_vigencia = norma.data_publicacao
|
|
e.inicio_eficacia = norma.data_publicacao
|
|
e.timestamp = datetime.now()
|
|
e.texto = norma.ementa
|
|
e.save()
|
|
|
|
a.pk = None
|
|
a.nivel = 0
|
|
a.ordem = e.ordem + Dispositivo.INTERVALO_ORDEM
|
|
a.ordem_bloco_atualizador = 0
|
|
a.set_numero_completo([2, 0, 0, 0, 0, 0, ])
|
|
a.timestamp = datetime.now()
|
|
a.save()
|
|
|
|
result = Dispositivo.objects.filter(
|
|
norma_id=self.kwargs['norma_id']
|
|
).select_related(*DISPOSITIVO_SELECT_RELATED)
|
|
|
|
return result
|
|
|
|
|
|
class DispositivoSimpleEditForm(forms.Form):
|
|
texto = forms.CharField(required=False, widget=forms.Textarea)
|
|
|
|
|
|
class DispositivoEditView(CompilacaoEditView, FormMixin):
|
|
template_name = 'compilacao/edit_bloco.html'
|
|
form_class = DispositivoSimpleEditForm
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
|
|
d = Dispositivo.objects.get(
|
|
pk=self.kwargs['dispositivo_id'])
|
|
|
|
texto = request.POST['texto']
|
|
d.texto = texto
|
|
d.save()
|
|
|
|
return self.get(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
self.flag_alteradora = -1
|
|
self.flag_nivel_ini = 0
|
|
self.flag_nivel_old = -1
|
|
|
|
try:
|
|
self.pk_add = int(self.request.GET['pkadd'])
|
|
except:
|
|
self.pk_add = 0
|
|
self.pk_view = int(self.kwargs['dispositivo_id'])
|
|
|
|
try:
|
|
if self.pk_add == self.pk_view:
|
|
bloco = Dispositivo.objects.get(
|
|
pk=self.kwargs['dispositivo_id'])
|
|
else:
|
|
bloco = Dispositivo.objects.get(
|
|
pk=self.kwargs['dispositivo_id'])
|
|
except Dispositivo.DoesNotExist:
|
|
return []
|
|
|
|
self.flag_nivel_old = bloco.nivel - 1
|
|
self.flag_nivel_ini = bloco.nivel
|
|
|
|
if self.pk_add == self.pk_view:
|
|
return [bloco, ]
|
|
|
|
proximo_bloco = Dispositivo.objects.filter(
|
|
ordem__gt=bloco.ordem,
|
|
nivel__lte=bloco.nivel,
|
|
norma_id=self.kwargs['norma_id'])[:1]
|
|
|
|
if proximo_bloco.count() == 0:
|
|
itens = Dispositivo.objects.filter(
|
|
ordem__gte=bloco.ordem,
|
|
norma_id=self.kwargs['norma_id']
|
|
).select_related(*DISPOSITIVO_SELECT_RELATED)
|
|
else:
|
|
itens = Dispositivo.objects.filter(
|
|
ordem__gte=bloco.ordem,
|
|
ordem__lt=proximo_bloco[0].ordem,
|
|
norma_id=self.kwargs['norma_id']
|
|
).select_related(*DISPOSITIVO_SELECT_RELATED)
|
|
return itens
|
|
|
|
def select_provaveis_inserts(self):
|
|
|
|
# Não salvar d_base
|
|
if self.pk_add == 0:
|
|
d_base = Dispositivo.objects.get(pk=self.pk_view)
|
|
else:
|
|
d_base = Dispositivo.objects.get(pk=self.pk_add)
|
|
|
|
result = [{'tipo_insert': 'Inserir Depois',
|
|
'icone': '↷ ',
|
|
'action': 'add_next',
|
|
'itens': []},
|
|
{'tipo_insert': 'Inserir Dentro',
|
|
'icone': '⇲ ',
|
|
'action': 'add_in',
|
|
'itens': []},
|
|
{'tipo_insert': 'Inserir Antes',
|
|
'icone': '↶ ',
|
|
'action': 'add_prior',
|
|
'itens': []}
|
|
]
|
|
|
|
disps = Dispositivo.objects.order_by(
|
|
'-ordem').filter(
|
|
ordem__lte=d_base.ordem,
|
|
norma_id=d_base.norma_id)
|
|
|
|
nivel = sys.maxsize
|
|
for d in disps:
|
|
|
|
if d.nivel >= nivel:
|
|
continue
|
|
|
|
if d.tipo_dispositivo.class_css == 'caput':
|
|
continue
|
|
|
|
nivel = d.nivel
|
|
|
|
r = []
|
|
|
|
if d == d_base:
|
|
result[2]['itens'].append({
|
|
'class_css': d.tipo_dispositivo.class_css,
|
|
'tipo_pk': d.pk,
|
|
'variacao': 0,
|
|
'provavel': '%s (%s)' % (
|
|
d.rotulo_padrao(True, d, False),
|
|
d.tipo_dispositivo.nome,),
|
|
'dispositivo_base': d_base.pk})
|
|
|
|
flag_direcao = 1
|
|
flag_variacao = 0
|
|
while True:
|
|
# rt resultado da transformacao
|
|
rt = d.transform_in_next(flag_direcao)
|
|
if not rt[0]:
|
|
break
|
|
flag_variacao += rt[1]
|
|
r.append({'class_css': d.tipo_dispositivo.class_css,
|
|
'tipo_pk': d.tipo_dispositivo.pk,
|
|
'variacao': flag_variacao,
|
|
'provavel': '%s (%s)' % (
|
|
d.rotulo_padrao(
|
|
True, d_base, True),
|
|
d.tipo_dispositivo.nome,),
|
|
'dispositivo_base': d_base.pk})
|
|
|
|
flag_direcao = -1
|
|
|
|
r.reverse()
|
|
|
|
if len(r) > 0 and d.tipo_dispositivo.class_css == 'articulacao':
|
|
r = [r[0], ]
|
|
|
|
if d.tipo_dispositivo == d_base.tipo_dispositivo:
|
|
result[0]['itens'] += r
|
|
else:
|
|
result[0]['itens'] += r
|
|
result[2]['itens'] += r
|
|
|
|
if nivel == 0:
|
|
break
|
|
|
|
# tipo do dispositivo base
|
|
tipb = d_base.tipo_dispositivo
|
|
|
|
for mudarnivel in [1, 0]:
|
|
if mudarnivel:
|
|
# Outros Tipos de Dispositivos PARA DENTRO
|
|
otds = TipoDispositivo.objects.order_by(
|
|
'-contagem_continua', 'id').filter(
|
|
Q(id__gt=100) & Q(id__gt=d_base.tipo_dispositivo_id))
|
|
else:
|
|
# Outros Tipos de Dispositivos PARA FORA
|
|
classes_ja_inseridas = []
|
|
for c in result[0]['itens']:
|
|
if c['class_css'] not in classes_ja_inseridas:
|
|
classes_ja_inseridas.append(c['class_css'])
|
|
otds = TipoDispositivo.objects.order_by(
|
|
'-contagem_continua', 'id').filter(
|
|
id__gt=100,
|
|
id__lt=d_base.tipo_dispositivo_id).exclude(
|
|
class_css__in=classes_ja_inseridas)
|
|
|
|
for td in otds:
|
|
|
|
if td.class_css == 'caput':
|
|
continue
|
|
|
|
d_base.tipo_dispositivo = td
|
|
|
|
if td.contagem_continua:
|
|
disps = Dispositivo.objects.filter(
|
|
tipo_dispositivo_id=td.pk,
|
|
ordem__lte=d_base.ordem,
|
|
norma_id=d_base.norma_id).aggregate(
|
|
Max('dispositivo0'),
|
|
Max('dispositivo1'),
|
|
Max('dispositivo2'),
|
|
Max('dispositivo3'),
|
|
Max('dispositivo4'),
|
|
Max('dispositivo5'))
|
|
|
|
else:
|
|
disps = Dispositivo.objects.filter(
|
|
tipo_dispositivo_id=td.pk,
|
|
dispositivo_pai_id=d_base.pk).aggregate(
|
|
Max('dispositivo0'),
|
|
Max('dispositivo1'),
|
|
Max('dispositivo2'),
|
|
Max('dispositivo3'),
|
|
Max('dispositivo4'),
|
|
Max('dispositivo5'))
|
|
|
|
if disps['dispositivo0__max'] is not None:
|
|
d_base.set_numero_completo([
|
|
disps['dispositivo0__max'],
|
|
disps['dispositivo1__max'],
|
|
disps['dispositivo2__max'],
|
|
disps['dispositivo3__max'],
|
|
disps['dispositivo4__max'],
|
|
disps['dispositivo5__max'],
|
|
])
|
|
|
|
d_base.transform_in_next()
|
|
else:
|
|
if ';' in td.rotulo_prefixo_texto:
|
|
d_base.set_numero_completo([0, 0, 0, 0, 0, 0, ])
|
|
else:
|
|
d_base.set_numero_completo([1, 0, 0, 0, 0, 0, ])
|
|
|
|
r = [{'class_css': td.class_css,
|
|
'tipo_pk': td.pk,
|
|
'variacao': 0,
|
|
'provavel': '%s (%s)' % (
|
|
d_base.rotulo_padrao(True, None, True),
|
|
td.nome,),
|
|
'dispositivo_base': d_base.pk}]
|
|
|
|
if mudarnivel == 1:
|
|
if (tipb.class_css == 'caput' and
|
|
td.class_css == 'paragrafo'):
|
|
result[0]['itens'].insert(0, r[0])
|
|
else:
|
|
result[1]['itens'] += r
|
|
else:
|
|
if td.pk < tipb.pk:
|
|
result[2]['itens'] += r
|
|
result[0]['itens'] += r
|
|
|
|
if tipb.class_css == 'caput':
|
|
result.pop()
|
|
# result.remove(result[0])
|
|
|
|
# retira inserir após e inserir antes
|
|
if tipb.class_css == 'articulacao':
|
|
r = result[0]
|
|
result.remove(result[0])
|
|
result.insert(1, r)
|
|
|
|
return result
|
|
|
|
|
|
class ActionsEditMixin(object):
|
|
|
|
def render_to_json_response(self, context, **response_kwargs):
|
|
|
|
if context['action'] == 'add_next':
|
|
return JsonResponse(self.add_next(context), safe=False)
|
|
elif context['action'] == 'add_in':
|
|
return JsonResponse(self.add_in(context), safe=False)
|
|
elif context['action'] == 'add_prior':
|
|
return JsonResponse(self.add_prior(context), safe=False)
|
|
else:
|
|
return JsonResponse({}, safe=False)
|
|
|
|
def add_prior(self, context):
|
|
pass
|
|
|
|
def add_in(self, context):
|
|
# pai = Dispositivo.objects.get(pk=context['dispositivo_id'])
|
|
# dp = Dispositivo.objects.get(pk=context['dispositivo_id'])
|
|
|
|
# Tipo Filho
|
|
# tf = TipoDispositivo.objects.get(pk=context['tipo_pk'])
|
|
|
|
return {}
|
|
|
|
def add_next(self, context):
|
|
try:
|
|
base = Dispositivo.objects.get(pk=context['dispositivo_id'])
|
|
dp = Dispositivo.objects.get(pk=context['dispositivo_id'])
|
|
|
|
tipo = TipoDispositivo.objects.get(pk=context['tipo_pk'])
|
|
variacao = int(context['variacao'])
|
|
|
|
while dp.dispositivo_pai is not None and \
|
|
dp.tipo_dispositivo_id != tipo.pk:
|
|
dp = dp.dispositivo_pai
|
|
|
|
# Inserção interna a uma articulação de um tipo já existente
|
|
# ou de uma nova articulacao
|
|
if dp.dispositivo_pai is not None or \
|
|
tipo.class_css == 'articulacao':
|
|
|
|
dpbase = dp
|
|
dp = Dispositivo.init_with_base(dpbase, tipo)
|
|
dp.transform_in_next(variacao)
|
|
dp.rotulo = dp.rotulo_padrao()
|
|
|
|
if dp.tipo_dispositivo.class_css == 'artigo':
|
|
ordem = base.criar_espaco_apos(espaco_a_criar=2)
|
|
else:
|
|
ordem = base.criar_espaco_apos(espaco_a_criar=1)
|
|
|
|
dp.ordem = ordem
|
|
|
|
# Incrementar irmãos
|
|
|
|
if not tipo.contagem_continua:
|
|
irmaos = list(Dispositivo.objects.filter(
|
|
Q(ordem__gt=dp.ordem) | Q(dispositivo0=0),
|
|
dispositivo_pai_id=dp.dispositivo_pai_id,
|
|
tipo_dispositivo_id=tipo.pk))
|
|
|
|
elif tipo.class_css == 'articulacao':
|
|
irmaos = list(Dispositivo.objects.filter(
|
|
ordem__gt=dp.ordem,
|
|
norma_id=dp.norma_id,
|
|
tipo_dispositivo_id=tipo.pk))
|
|
|
|
else: # contagem continua restrita a articulacao
|
|
proxima_articulacao = Dispositivo.objects.filter(
|
|
ordem__gt=dp.ordem,
|
|
nivel=0,
|
|
norma_id=dp.norma_id)[:1]
|
|
|
|
if not proxima_articulacao.exists():
|
|
irmaos = list(Dispositivo.objects.filter(
|
|
ordem__gt=dp.ordem,
|
|
norma_id=dp.norma_id,
|
|
tipo_dispositivo_id=tipo.pk))
|
|
else:
|
|
irmaos = list(Dispositivo.objects.filter(
|
|
Q(ordem__gt=dp.ordem) &
|
|
Q(ordem__lt=proxima_articulacao[0].ordem),
|
|
norma_id=dp.norma_id,
|
|
tipo_dispositivo_id=tipo.pk))
|
|
|
|
dp_profundidade = dp.get_profundidade()
|
|
|
|
irmaos_a_salvar = []
|
|
ultimo_irmao = None
|
|
for irmao in irmaos:
|
|
|
|
if irmao.ordem <= dp.ordem:
|
|
irmaos_a_salvar.append(irmao)
|
|
continue
|
|
|
|
irmao_profundidade = irmao.get_profundidade()
|
|
if irmao_profundidade < dp_profundidade:
|
|
break
|
|
|
|
if irmao.get_numero_completo() < dp.get_numero_completo():
|
|
if irmao_profundidade > dp_profundidade:
|
|
if ultimo_irmao is None:
|
|
irmao.transform_in_next(
|
|
dp_profundidade - irmao_profundidade)
|
|
irmao.transform_in_next(
|
|
irmao_profundidade - dp_profundidade)
|
|
else:
|
|
irmao.set_numero_completo(
|
|
ultimo_irmao.get_numero_completo())
|
|
|
|
irmao.transform_in_next(
|
|
irmao_profundidade -
|
|
ultimo_irmao.get_profundidade())
|
|
|
|
ultimo_irmao = irmao
|
|
else:
|
|
irmao.transform_in_next()
|
|
irmao.rotulo = irmao.rotulo_padrao()
|
|
irmaos_a_salvar.append(irmao)
|
|
else:
|
|
irmao_numero = irmao.get_numero_completo()
|
|
irmao_numero[dp_profundidade] += 1
|
|
irmao.set_numero_completo(irmao_numero)
|
|
irmao.rotulo = irmao.rotulo_padrao()
|
|
irmaos_a_salvar.append(irmao)
|
|
|
|
irmaos_a_salvar.reverse()
|
|
for irmao in irmaos_a_salvar:
|
|
if irmao.dispositivo0 == 0 and \
|
|
irmao.ordem <= dp.ordem and variacao == 0:
|
|
irmao.dispositivo0 = 1
|
|
irmao.rotulo = irmao.rotulo_padrao()
|
|
dp.dispositivo0 = 2
|
|
dp.rotulo = dp.rotulo_padrao()
|
|
irmao.clean()
|
|
irmao.save()
|
|
|
|
dp.clean()
|
|
dp.save()
|
|
|
|
# Inserção automática do caput para artigos
|
|
if dp.tipo_dispositivo.class_css == 'artigo':
|
|
tipocaput = TipoDispositivo.objects.filter(
|
|
class_css='caput')
|
|
dp.dispositivo_pai_id = dp.pk
|
|
dp.pk = None
|
|
dp.nivel += 1
|
|
dp.tipo_dispositivo = tipocaput[0]
|
|
dp.set_numero_completo([1, 0, 0, 0, 0, 0, ])
|
|
dp.rotulo = dp.rotulo_padrao()
|
|
dp.texto = ''
|
|
|
|
dp.ordem = ordem + Dispositivo.INTERVALO_ORDEM
|
|
dp.clean()
|
|
dp.save()
|
|
dp = Dispositivo.objects.get(pk=dp.dispositivo_pai_id)
|
|
|
|
# Inserção de dispositivo sem precedente de mesmo tipo
|
|
else:
|
|
dp = Dispositivo.objects.get(pk=context['dispositivo_id'])
|
|
|
|
# Encontrar primeiro irmão que contem um pai compativel
|
|
while True:
|
|
if dp.dispositivo_pai is not None and \
|
|
dp.dispositivo_pai.tipo_dispositivo_id > tipo.pk:
|
|
dp = dp.dispositivo_pai
|
|
else:
|
|
break
|
|
|
|
dpaux = dp
|
|
dp = Dispositivo.init_with_base(dpaux, tipo)
|
|
|
|
if tipo.contagem_continua:
|
|
ultimo_irmao = Dispositivo.objects.order_by(
|
|
'-ordem').filter(
|
|
ordem__lte=dp.ordem,
|
|
tipo_dispositivo_id=tipo.pk,
|
|
norma_id=dp.norma_id)[:1]
|
|
|
|
if not ultimo_irmao.exists():
|
|
dp.set_numero_completo([1, 0, 0, 0, 0, 0, ])
|
|
else:
|
|
ultimo_irmao = ultimo_irmao[0]
|
|
dp.set_numero_completo(
|
|
ultimo_irmao.get_numero_completo())
|
|
dp.transform_in_next()
|
|
else:
|
|
if ';' in tipo.rotulo_prefixo_texto:
|
|
dp.set_numero_completo([0, 0, 0, 0, 0, 0, ])
|
|
else:
|
|
dp.set_numero_completo([1, 0, 0, 0, 0, 0, ])
|
|
dp.rotulo = dp.rotulo_padrao()
|
|
dp.texto = ''
|
|
dp.ordem = base.criar_espaco_apos(espaco_a_criar=1)
|
|
|
|
# Incrementar irmãos
|
|
irmaos = Dispositivo.objects.order_by('-ordem').filter(
|
|
dispositivo_pai_id=dp.dispositivo_pai_id,
|
|
ordem__gt=dp.ordem,
|
|
tipo_dispositivo_id=tipo.pk)
|
|
|
|
''' inserção sem precedente é feita sem variação
|
|
portanto, não é necessário usar transform_next() para
|
|
incrementar, e sim, apenas somar no atributo dispositivo0
|
|
dada a possibilidade de existir irmãos com viariação'''
|
|
for irmao in irmaos:
|
|
irmao.dispositivo0 += 1
|
|
irmao.rotulo = irmao.rotulo_padrao()
|
|
irmao.clean()
|
|
irmao.save()
|
|
|
|
dp.clean()
|
|
dp.save()
|
|
|
|
''' Reenquadrar todos os dispositivos que possuem pai
|
|
antes da inserção atual e que são inferiores a dp,
|
|
redirecionando para o novo pai'''
|
|
|
|
possiveis_filhos = Dispositivo.objects.filter(
|
|
ordem__gt=dp.ordem,
|
|
norma_id=dp.norma_id)
|
|
|
|
nivel = sys.maxsize
|
|
flag_niveis = False
|
|
for filho in possiveis_filhos:
|
|
|
|
if filho.nivel > nivel:
|
|
continue
|
|
|
|
if filho.tipo_dispositivo_id <= dp.tipo_dispositivo_id:
|
|
break
|
|
|
|
if filho.dispositivo_pai.ordem >= dp.ordem:
|
|
continue
|
|
|
|
nivel = filho.nivel
|
|
|
|
filho.dispositivo_pai = dp
|
|
filho.clean()
|
|
filho.save()
|
|
flag_niveis = True
|
|
|
|
if flag_niveis:
|
|
dp.organizar_niveis()
|
|
|
|
numtipos = {}
|
|
|
|
''' Renumerar filhos imediatos que
|
|
não possuam contagem continua'''
|
|
|
|
if flag_niveis:
|
|
filhos = Dispositivo.objects.filter(
|
|
dispositivo_pai_id=dp.pk)
|
|
|
|
for filho in filhos:
|
|
|
|
if filho.tipo_dispositivo.contagem_continua:
|
|
continue
|
|
|
|
if filho.tipo_dispositivo.class_css in numtipos:
|
|
if filho.dispositivo_substituido is None:
|
|
numtipos[filho.tipo_dispositivo.class_css] += 1
|
|
else:
|
|
t = filho.tipo_dispositivo
|
|
prefixo = t.rotulo_prefixo_texto.split(';')
|
|
if len(prefixo) > 1:
|
|
count_irmaos_m_tipo = Dispositivo.objects.filter(
|
|
~Q(pk=filho.pk),
|
|
tipo_dispositivo=t,
|
|
dispositivo_pai=filho.dispositivo_pai)[:1]
|
|
|
|
if count_irmaos_m_tipo.exists():
|
|
numtipos[filho.tipo_dispositivo.class_css] = 1
|
|
else:
|
|
numtipos[filho.tipo_dispositivo.class_css] = 0
|
|
else:
|
|
numtipos[filho.tipo_dispositivo.class_css] = 1
|
|
|
|
filho.dispositivo0 = numtipos[
|
|
filho.tipo_dispositivo.class_css]
|
|
|
|
filho.rotulo = filho.rotulo_padrao()
|
|
filho.clean()
|
|
filho.save()
|
|
|
|
''' Renumerar dispositivos de
|
|
contagem continua, caso a inserção seja uma articulação'''
|
|
|
|
numtipos = {}
|
|
if tipo.class_css == 'articulacao':
|
|
|
|
proxima_articulacao = Dispositivo.objects.filter(
|
|
ordem__gt=dp.ordem,
|
|
nivel=0,
|
|
norma_id=dp.norma_id)[:1]
|
|
|
|
if not proxima_articulacao.exists():
|
|
filhos_continuos = list(Dispositivo.objects.filter(
|
|
ordem__gt=dp.ordem,
|
|
norma_id=dp.norma_id,
|
|
tipo_dispositivo__contagem_continua=True))
|
|
else:
|
|
filhos_continuos = list(Dispositivo.objects.filter(
|
|
Q(ordem__gt=dp.ordem) &
|
|
Q(ordem__lt=proxima_articulacao[0].ordem),
|
|
norma_id=dp.norma_id,
|
|
tipo_dispositivo__contagem_continua=True))
|
|
|
|
for filho in filhos_continuos:
|
|
|
|
if filho.tipo_dispositivo.class_css in numtipos:
|
|
if filho.dispositivo_substituido is None:
|
|
numtipos[filho.tipo_dispositivo.class_css] += 1
|
|
else:
|
|
t = filho.tipo_dispositivo
|
|
prefixo = t.rotulo_prefixo_texto.split(';')
|
|
if len(prefixo) > 1:
|
|
count_irmaos_m_tipo = Dispositivo.objects.filter(
|
|
~Q(pk=filho.pk),
|
|
tipo_dispositivo=t,
|
|
dispositivo_pai=filho.dispositivo_pai)[:1]
|
|
|
|
if count_irmaos_m_tipo.exists():
|
|
numtipos[filho.tipo_dispositivo.class_css] = 1
|
|
else:
|
|
numtipos[filho.tipo_dispositivo.class_css] = 0
|
|
else:
|
|
numtipos[filho.tipo_dispositivo.class_css] = 1
|
|
|
|
filho.dispositivo0 = numtipos[
|
|
filho.tipo_dispositivo.class_css]
|
|
|
|
filho.rotulo = filho.rotulo_padrao()
|
|
filho.clean()
|
|
filho.save()
|
|
|
|
except Exception as e:
|
|
print(e)
|
|
|
|
# data = serializers.serialize('json', dp)
|
|
if tipo.contagem_continua:
|
|
# pais a atualizar
|
|
|
|
pais = []
|
|
|
|
if dp.dispositivo_pai is None:
|
|
data = {'pk': dp.pk, 'pai': [-1, ]}
|
|
else:
|
|
pkfilho = dp.pk
|
|
dp = dp.dispositivo_pai
|
|
|
|
if proxima_articulacao is not None and \
|
|
proxima_articulacao.exists():
|
|
parents = Dispositivo.objects.filter(
|
|
norma_id=dp.norma_id,
|
|
ordem__gte=dp.ordem,
|
|
ordem__lt=proxima_articulacao[0].ordem,
|
|
nivel__lte=dp.nivel)
|
|
else:
|
|
parents = Dispositivo.objects.filter(
|
|
norma_id=dp.norma_id,
|
|
ordem__gte=dp.ordem,
|
|
nivel__lte=dp.nivel)
|
|
|
|
nivel = sys.maxsize
|
|
for p in parents:
|
|
|
|
if p.nivel > nivel:
|
|
continue
|
|
|
|
pais.append(p.pk)
|
|
nivel = p.nivel
|
|
data = {'pk': pkfilho, 'pai': pais}
|
|
else:
|
|
data = {'pk': dp.pk, 'pai': [dp.dispositivo_pai.pk, ]}
|
|
|
|
return data
|
|
|
|
|
|
class ActionsEditView(ActionsEditMixin, TemplateView):
|
|
|
|
def render_to_response(self, context, **response_kwargs):
|
|
context['action'] = self.request.GET['action']
|
|
context['tipo_pk'] = self.request.GET['tipo_pk']
|
|
context['variacao'] = self.request.GET['variacao']
|
|
return self.render_to_json_response(context, **response_kwargs)
|
|
|