Browse Source

Refatorar exclusão de Dispositivos e religar DCC's

- DCC (Dispositivos de Contagem Continua)
pull/299/head
LeandroRoberto 9 years ago
parent
commit
206791e335
  1. 24
      compilacao/models.py
  2. 8
      compilacao/templatetags/compilacao_filters.py
  3. 236
      compilacao/views.py
  4. 50
      static/js/compilacao_edit.js
  5. 8
      static/js/compilacao_view.js
  6. 6
      static/styles/app.scss
  7. 2
      static/styles/compilacao.scss
  8. 12
      templates/compilacao/text_edit.html
  9. 23
      templates/compilacao/text_list.html

24
compilacao/models.py

@ -790,6 +790,21 @@ class Dispositivo(BaseModel, TimestampedMixin):
return (flag_direcao, flag_variacao)
def transform_in_prior(self):
numero = self.get_numero_completo()
numero.reverse()
for i in range(len(numero)):
if not numero[i]:
continue
numero[i] -= 1
numero.reverse()
break
self.set_numero_completo(numero)
def set_numero_completo(self, *numero):
numero = numero[0]
self.dispositivo0 = numero[0]
@ -1046,12 +1061,19 @@ class Dispositivo(BaseModel, TimestampedMixin):
irmao.save()
def get_proximo_nivel_zero(self):
proxima_articulacao = Dispositivo.objects.filter(
proxima_articulacao = Dispositivo.objects.order_by('ordem').filter(
ordem__gt=self.ordem,
nivel=0,
ta_id=self.ta_id).first()
return proxima_articulacao
def get_nivel_zero_anterior(self):
anterior_articulacao = Dispositivo.objects.order_by('ordem').filter(
ordem__lt=self.ordem,
nivel=0,
ta_id=self.ta_id).last()
return anterior_articulacao
def is_relative_auto_insert(self, perfil_pk=None):
if self.dispositivo_pai is not None:
# pp possiveis_pais

8
compilacao/templatetags/compilacao_filters.py

@ -2,6 +2,7 @@ from django import template
from django.core.signing import Signer
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
from compilacao.models import Dispositivo, TipoDispositivo
@ -60,12 +61,15 @@ def set_nivel_old(view, value):
@register.simple_tag
def close_div(value_max, value_min, varr):
return '</div>' * (int(value_max) - int(value_min) + 1 + varr)
return mark_safe('</div>' * (int(value_max) - int(value_min) + 1 + varr))
@register.filter
def get_sign_vigencia(value):
string = "%s,%s" % (value.inicio_vigencia, value.fim_vigencia)
string = "%s,%s,%s" % (
value.ta_publicado_id if value.ta_publicado_id else 0,
value.inicio_vigencia,
value.fim_vigencia)
signer = Signer()
return signer.sign(str(string))

236
compilacao/views.py

@ -325,6 +325,7 @@ class TextView(ListView, CompMixin):
inicio_vigencia = None
fim_vigencia = None
ta_vigencia = None
def get(self, request, *args, **kwargs):
ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id'])
@ -427,14 +428,19 @@ class TextView(ListView, CompMixin):
self.inicio_vigencia = None
self.fim_vigencia = None
self.ta_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])
self.ta_vigencia = int(string[0])
self.inicio_vigencia = parse_date(string[1])
self.fim_vigencia = parse_date(string[2])
except:
return{}
return Dispositivo.objects.filter(
ordem__gt=0,
ta_id=self.kwargs['ta_id'],
).select_related(*DISPOSITIVO_SELECT_RELATED)
return Dispositivo.objects.filter(
inicio_vigencia__lte=self.fim_vigencia,
@ -1015,17 +1021,26 @@ class ActionsEditMixin:
base_anterior = Dispositivo.objects.order_by('-ordem').filter(
ta_id=base.ta_id,
ordem__lt=base.ordem
)[:1]
).first()
data = {}
if base_anterior.exists():
if base.dispositivo_pai_id:
data = {'pk': base_anterior[0].pk,
'pai': [base.dispositivo_pai_id, ]}
if base_anterior:
data = self.get_json_for_refresh(base_anterior)
else:
data = {'pk': base_anterior[0].pk, 'pai': [-1, ]}
base_anterior = Dispositivo.objects.order_by('ordem').filter(
ta_id=base.ta_id,
ordem__lt=base.ordem
).first()
if base_anterior:
data = self.get_json_for_refresh(base_anterior)
else:
data['pk'] = ''
# TODO: a linha abaixo causa atualização da tela inteira...
# retirar a linha abaixo e identificar atualizações pontuais
data['pai'] = [-1, ]
self.remover_dispositivo(base, bloco)
data['message'] = str(self.remover_dispositivo(base, bloco))
return data
def remover_dispositivo(self, base, bloco):
@ -1034,12 +1049,12 @@ class ActionsEditMixin:
n = base.dispositivo_subsequente
if n:
print(n.id, n)
# print(n.id, n)
n.dispositivo_substituido = p
n.save()
if p:
print(p.id, p)
# print(p.id, p)
p.dispositivo_subsequente = n
if n:
p.fim_vigencia = n.ini_vigencia - timedelta(days=1)
@ -1058,38 +1073,51 @@ class ActionsEditMixin:
p.dispositivos_filhos_set.add(d)
p.save()
base.delete()
elif not bloco:
else:
if not bloco:
for d in base.dispositivos_filhos_set.all():
# inserções automáticas são excluidas junto com sua base,
# independente da escolha do usuário
d_nivel_old = d.nivel
if d.tipo_dispositivo.possiveis_pais.filter(
pai=base.tipo_dispositivo,
perfil__padrao=True,
filho_de_insercao_automatica=True).exists():
continue
# encontrar possível pai que será o primeiro parent possível
# dos parents do dispostivo
# encontrar possível pai que será o primeiro parent
# possível dos parents do dispostivo
# imediatamente anterior ao dispositivo base
anterior = Dispositivo.objects.order_by('-ordem').filter(
ta_id=base.ta_id,
ordem__lt=d.ordem
).exclude(pk=base.pk).first()
ordem__lt=base.ordem
).first()
if not anterior:
return _('Não é possível excluir este Dispositivo sem'
' excluir toda a sua estrutura!!!')
if anterior.tipo_dispositivo == d.tipo_dispositivo:
d.dispositivo_pai = anterior.dispositivo_pai
d.nivel = anterior.nivel
if not d.tipo_dispositivo.contagem_continua:
d.set_numero_completo(anterior.get_numero_completo())
d.set_numero_completo(
anterior.get_numero_completo())
if d.dispositivo_substituido != anterior:
d.transform_in_next()
d.rotulo = d.rotulo_padrao()
else:
parents = anterior.get_parents()
parents = [anterior, ] + anterior.get_parents()
for candidato in parents:
if candidato.tipo_dispositivo == d.tipo_dispositivo:
if candidato == base:
return _('Não é possível excluir este '
'Dispositivo sem '
'excluir toda a sua estrutura!!!')
if (candidato.tipo_dispositivo ==
d.tipo_dispositivo):
d.dispositivo_pai = candidato.dispositivo_pai
d.nivel = candidato.nivel
if not d.tipo_dispositivo.contagem_continua:
@ -1103,14 +1131,20 @@ class ActionsEditMixin:
pai=candidato.tipo_dispositivo,
perfil__padrao=True).exists():
d.dispositivo_pai = candidato
if ';' in d.tipo_dispositivo.rotulo_prefixo_texto:
if ';' in d.tipo_dispositivo.\
rotulo_prefixo_texto:
d.set_numero_completo([0, 0, 0, 0, 0, 0, ])
else:
d.set_numero_completo([1, 0, 0, 0, 0, 0, ])
d.nivel = candidato.nivel + 1
break
d.save()
if not parents:
d.dispositivo_pai = anterior
d.nivel = anterior.nivel + 1
d.save(clean=False)
if d.nivel != d_nivel_old:
d.organizar_niveis()
if base.nivel:
@ -1121,20 +1155,66 @@ class ActionsEditMixin:
ordem__gt=base.ordem,
tipo_dispositivo=base.tipo_dispositivo)
numero_completo_base = base.get_numero_completo()
base.delete()
# Religar numeração de dispositivos de contagem contínua
# que seram excluidos
proximo_independente_base = irmaos_posteriores.first()
proxima_articulacao = base.get_proximo_nivel_zero()
if not proximo_independente_base:
proximo_independente_base = Dispositivo.objects.\
order_by('ordem').filter(
ta_id=base.ta_id,
ordem__gt=base.ordem,
nivel__lte=base.nivel)
if proximo_independente_base:
dcc = Dispositivo.objects.order_by('ordem').filter(
ta_id=base.ta_id,
ordem__gt=base.ordem,
ordem__lt=proximo_independente_base.ordem,
tipo_dispositivo__contagem_continua=True)
religado = {}
for d in dcc:
if d.tipo_dispositivo.class_css in religado:
continue
religado[
d.tipo_dispositivo.class_css] = d.dispositivo0
if proxima_articulacao:
dcc_a_religar = Dispositivo.objects.filter(
ta_id=d.ta_id,
ordem__gt=proximo_independente_base.ordem,
tipo_dispositivo=d.tipo_dispositivo,
ordem__lt=proxima_articulacao.ordem)
else:
dcc_a_religar = Dispositivo.objects.filter(
ta_id=base.ta_id,
ordem__gt=proximo_independente_base.ordem,
tipo_dispositivo=d.tipo_dispositivo)
primeiro_a_religar = 0
for dr in dcc_a_religar:
if not primeiro_a_religar:
primeiro_a_religar = dr.dispositivo0
dr.dispositivo0 = (
dr.dispositivo0 -
primeiro_a_religar + d.dispositivo0)
dr.rotulo = dr.rotulo_padrao()
dr.save()
base.delete()
else:
proxima_articulacao = base.get_proximo_nivel_zero()
numero_completo_base = base.get_numero_completo()
if proxima_articulacao:
irmaos_posteriores = Dispositivo.objects.filter(
ta_id=base.ta_id,
ordem__gt=base.ordem,
tipo_dispositivo=base.tipo_dispositivo,
ordem__lt=proxima_articulacao.ordem
)
ordem__lt=proxima_articulacao.ordem)
else:
irmaos_posteriores = Dispositivo.objects.filter(
ta_id=base.ta_id,
@ -1143,44 +1223,71 @@ class ActionsEditMixin:
base.delete()
numero_completo_irmao = None
if (len(irmaos_posteriores) == 1 and
';' in irmaos_posteriores[0].
tipo_dispositivo.rotulo_prefixo_texto):
i = irmaos_posteriores[0]
i.set_numero_completo([0, 0, 0, 0, 0, 0, ])
i.rotulo = i.rotulo_padrao(local_insert=1)
i.save()
else:
for irmao in irmaos_posteriores:
numero_completo_irmao = irmao.get_numero_completo()
irmao.set_numero_completo(numero_completo_base)
numero_completo_base = numero_completo_irmao
irmao.transform_in_prior()
irmao.rotulo = irmao.rotulo_padrao()
irmao.save()
else:
proxima_articulacao = base.get_proximo_nivel_zero()
# Dispostivos de Contagem contínua de dentro da base
# Renumerar Dispostivos de Contagem Contínua de dentro da base
if not proxima_articulacao:
dcc = Dispositivo.objects.order_by('ordem').filter(
ta_id=base.ta_id,
ordem__gt=base.ordem,
tipo_dispositivo__contagem_continua=True)
else:
dcc = Dispositivo.objects.order_by('ordem').filter(
ta_id=base.ta_id,
ordem__gt=base.ordem,
ordem__lt=proxima_articulacao.ordem,
tipo_dispositivo__contagem_continua=True)
for d in dcc:
base_adicao = {}
nivel_zero_anterior = base.get_nivel_zero_anterior()
if nivel_zero_anterior:
nivel_zero_anterior = nivel_zero_anterior.ordem
else:
nivel_zero_anterior = 0
dcc = list(dcc)
for d in dcc: # ultimo DCC do tipo encontrado
if d.tipo_dispositivo.class_css not in base_adicao:
ultimo_dcc = Dispositivo.objects.order_by(
'ordem').filter(
ta_id=base.ta_id,
ordem__lt=d.ordem,
ordem__lt=base.ordem,
ordem__gt=nivel_zero_anterior,
tipo_dispositivo__contagem_continua=True,
tipo_dispositivo=d.tipo_dispositivo).last()
if not ultimo_dcc:
break
d.set_numero_completo(ultimo_dcc.get_numero_completo())
if d.dispositivo_substituido != ultimo_dcc:
d.transform_in_next()
base_adicao[
d.tipo_dispositivo.class_css] = ultimo_dcc.\
dispositivo0
d.rotulo = d.rotulo_padrao()
d.save(clean=False)
d.dispositivo0 += base_adicao[d.tipo_dispositivo.class_css]
base.delete()
d.rotulo = d.rotulo_padrao()
dcc.reverse()
for d in dcc:
d.save()
elif bloco:
# TODO: reorganizar dispositivos de contagem continua
base.delete()
return ''
def add_prior(self, context):
return {}
@ -1238,6 +1345,7 @@ class ActionsEditMixin:
ultimo_irmao = Dispositivo.objects.order_by(
'-ordem').filter(
ordem__lte=base.ordem,
ordem__gte=parents[-1].ordem,
tipo_dispositivo_id=tipo.pk,
ta_id=base.ta_id)[:1]
@ -1268,7 +1376,7 @@ class ActionsEditMixin:
if qtd_existente >= pp[0].quantidade_permitida:
return {'pk': base.pk,
'pai': [base.dispositivo_pai.pk, ],
'alert': str(_('Limite de inserções de '
'message': str(_('Limite de inserções de '
'dispositivos deste tipo '
'foi excedido.'))
}
@ -1280,7 +1388,6 @@ class ActionsEditMixin:
dp.ordem = ordem
dp.incrementar_irmaos(variacao, [local_add, ], force=False)
dp.clean()
dp.save()
dp_auto_insert = None
@ -1300,7 +1407,6 @@ class ActionsEditMixin:
dp.rotulo = dp.rotulo_padrao()
dp.texto = ''
dp.ordem = dp.ordem + Dispositivo.INTERVALO_ORDEM
dp.clean()
dp.save()
dp_auto_insert = dp
dp = Dispositivo.objects.get(pk=dp_pk)
@ -1377,58 +1483,38 @@ class ActionsEditMixin:
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 dp.nivel == 0:
proxima_articulacao = Dispositivo.objects.filter(
ordem__gt=dp.ordem,
nivel=0,
ta_id=dp.ta_id)[:1]
proxima_articulacao = dp.get_proximo_nivel_zero()
if not proxima_articulacao.exists():
if not proxima_articulacao:
filhos_continuos = list(Dispositivo.objects.filter(
ordem__gt=dp.ordem,
ta_id=dp.ta_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),
ordem__gt=dp.ordem,
ordem__lt=proxima_articulacao.ordem,
ta_id=dp.ta_id,
tipo_dispositivo__contagem_continua=True))
for filho in filhos_continuos:
base_reducao = {}
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
for filho in filhos_continuos:
if filho.tipo_dispositivo.class_css not in base_reducao:
base_reducao[filho.tipo_dispositivo.class_css] = \
filho.dispositivo0 - 1
filho.dispositivo0 = numtipos[
filho.dispositivo0 -= base_reducao[
filho.tipo_dispositivo.class_css]
filho.rotulo = filho.rotulo_padrao()
filho.clean()
filho.save()
except Exception as e:

50
static/js/compilacao_edit.js

@ -108,9 +108,7 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
}
else if (_action.startsWith('delete_')) {
var r = confirm("Confirma Exclusão deste dispositivo?");
if (r == true) {
x = "You pressed OK!";
} else {
if (!r) {
return
}
url = pk_refresh+'/actions?action='+_action;
@ -175,10 +173,6 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
else if (_action == 'add_next' || _action == 'add_in') {
clearEditSelected();
if (data.pk != null) {
if (data.alert != null)
alert(data.alert)
refreshScreenFocusPk(data);
}
else {
@ -189,32 +183,60 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
$("#message_block").css("display", "block");
clearEditSelected();
if (data.pk != null) {
if (data.message != null && data.message != '') {
modalMessage(data.message, 'alert-danger', function() {
//refreshScreenFocusPk(data);
});
}
else {
refreshScreenFocusPk(data);
}
}
else {
alert('Erro exclusão!');
alert('Erro exclusão de Dispositivo!');
}
}
else {
clearEditSelected();
reloadFunctionClicks();
}
}).always(function() {
$("#message_block").css("display", "none");
});
}
function modalMessage(message, alert, closeFunction) {
$('#modal-message #message').html(message);
$('#modal-message').modal('show');
if (closeFunction != null) {
$('#modal-message, #modal-message .alert button').off();
$('#modal-message .alert').removeClass('alert-success alert-info alert-warning alert-danger alert-danger');
$('#modal-message .alert').addClass(alert);
$('#modal-message').on('hidden.bs.modal', closeFunction);
$('#modal-message .alert button').on('click', function() {
$('#modal-message').modal('hide');
});
}
}
function refreshScreenFocusPk(data) {
for (var pai = 0; pai < data.pai.length; pai++)
if (data.pai[pai] != -1) {
clickUpdateDispositivo(null, data.pai[pai], data.pk, 'refresh', pai == 0, true);
}
else {
if (data.pai[0] == -1) {
$("#message_block").css("display", "block");
href = location.href.split('#')[0]
location.href = href+'#'+data.pk
location.href = href+'#'+data.pk;
location.reload(true)
}
else {
clickUpdateDispositivo(null, data.pai[0], data.pk, 'refresh', true, true);
setTimeout(function() {
for (var pai = 1; pai < data.pai.length; pai++)
clickUpdateDispositivo(null, data.pai[pai], data.pk, 'refresh', false, true);
}, 1000);
}
}
function clearEditSelected() {

8
static/js/compilacao_view.js

@ -1,11 +1,3 @@
$( window ).scroll(function() {
if (window.pageYOffset <= 180)
$( "section.vigencias" ).removeClass("fixed");
else if ( ! $( "section.vigencias" ).hasClass("fixed") )
$( "section.vigencias" ).addClass("fixed");
});
function isElementInViewport (el) {
//special bonus for those using jQuery

6
static/styles/app.scss

@ -120,3 +120,9 @@ body {
.checkbox input, .radio input {
display: initial;
}
.modal {
.alert {
margin-bottom: 0;
}
}

2
static/styles/compilacao.scss

@ -778,7 +778,7 @@ a:link:after, a:visited:after {
}
}
.articulacao {
border-top: 2 px solid #e5e5e5;
border-top: 2px solid #e5e5e5;
margin: 2em 0;
}
.bloco_alteracao {

12
templates/compilacao/text_edit.html

@ -29,6 +29,18 @@
<div id="message_block"><div id="msg">{% trans 'Aguarde... Atualizando informações!!!'%}</div></div>
<div id="modal-message" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="alert" role="alert">
<button type="button" class="close fa-times fa" aria-label="Close"></button>
<div id="message"></div>
</div>
</div>
</div>
</div>
<div class="cp cpe">
{% include 'compilacao/text_edit_bloco.html'%}
</div>

23
templates/compilacao/text_list.html

@ -49,23 +49,24 @@
</li>
{% if forloop.parentloop.last %}
</ul>
{% if view.inicio_vigencia and view.fim_vigencia %}
<span class="vigencia-active">
{% blocktrans with inicio_vigencia=view.inicio_vigencia fim_vigencia=view.fim_vigencia ta_publicado=dispositivo.ta_publicado%}
{% if view.inicio_vigencia and view.fim_vigencia %}
{% blocktrans with inicio_vigencia=view.inicio_vigencia fim_vigencia=view.fim_vigencia%}
Vigência entre <b>{{inicio_vigencia}}</b> e <b>{{fim_vigencia}}</b>.
<br>
<small>Dada pela {{ta_publicado}}</small>
</span>
{% endblocktrans%}
{% else%}
<span class="vigencia-active">
{% blocktrans with inicio_vigencia=dispositivo.inicio_vigencia ta_publicado=dispositivo.ta_publicado%}
{% blocktrans with inicio_vigencia=dispositivo.inicio_vigencia%}
Vigência a partir de <b>{{inicio_vigencia}}</b>.
{% endblocktrans%}
{% endif %}
<br>
<small>Dada pela {{ta_publicado}}</small>
{% endblocktrans %}
{% if view.ta_vigencia %}
<small>{% trans 'Dada por '%}<a href="{%url 'compilacao:ta_text' view.ta_vigencia %}">{{ta_pub_list|lookup:view.ta_vigencia}}</a></small>
{% elif view.ta_vigencia != 0 %}
<small>{% trans 'Dada por '%}<a href="{%url 'compilacao:ta_text' dispositivo.ta_publicado.pk %}">{{dispositivo.ta_publicado}}</a></small>
{% endif %}
</span>
{%endif%}
{% endif%}
{% endfor %}
{% else %}
@ -86,7 +87,7 @@
<ul class="tipo-vigencias">
<li><a class="selected" onclick="textoMultiVigente(this, false);" title="{% trans 'Texto Multivigente Sequencial'%}">{% trans 'TMS'%}</a></li>
<li><a onclick="textoMultiVigente(this, true);" title="{% trans 'Texto Multivigente Integrado com Realce de Alterações'%}">{% trans 'TMI'%}</a></li>
<li><a onclick="textoVigente(this, true);" title="{% trans 'Texto Vigente COM Links para Textos Alteradores'%}">{% trans 'TVL'%}</a></li>
<li><a onclick="textoMultiVigente(this, false); textoVigente(this, true);" title="{% trans 'Texto Vigente COM Links para Textos Alteradores'%}">{% trans 'TVL'%}</a></li>
<li><a onclick="textoVigente(this, false);" title="{% trans 'Texto Vigente'%}">{% trans 'TVT'%}</a></li>
</ul>

Loading…
Cancel
Save