Browse Source

Exclusão de dispositivos e blocos de dispositivos

pull/299/head
LeandroRoberto 9 years ago
parent
commit
6b183274cc
  1. 26
      compilacao/migrations/0044_auto_20160301_1816.py
  2. 27
      compilacao/models.py
  3. 174
      compilacao/views.py
  4. 2
      static/js/compilacao_edit.js
  5. 104
      static/styles/compilacao.scss
  6. 3
      templates/compilacao/text_edit.html
  7. 31
      templates/compilacao/text_edit_bloco.html
  8. 3
      templates/compilacao/text_edit_blocoalteracao.html

26
compilacao/migrations/0044_auto_20160301_1816.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-03-01 21:16
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0043_auto_20160110_1733'),
]
operations = [
migrations.AlterField(
model_name='dispositivo',
name='dispositivo_subsequente',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='compilacao.Dispositivo', verbose_name='Dispositivo Subsequente'),
),
migrations.AlterField(
model_name='dispositivo',
name='dispositivo_substituido',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='compilacao.Dispositivo', verbose_name='Dispositivo Substituido'),
),
]

27
compilacao/models.py

@ -59,6 +59,17 @@ class BaseModel(models.Model):
self.__class__, tuple(unique_fields))
raise ValidationError(msg)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None, clean=True):
if clean:
self.clean()
return models.Model.save(
self,
force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields)
class TipoTextoArticulado(models.Model):
sigla = models.CharField(max_length=3, verbose_name=_('Sigla'))
@ -581,11 +592,13 @@ class Dispositivo(BaseModel, TimestampedMixin):
'self',
blank=True, null=True, default=None,
related_name='+',
on_delete=models.SET_NULL,
verbose_name=_('Dispositivo Subsequente'))
dispositivo_substituido = models.ForeignKey(
'self',
blank=True, null=True, default=None,
related_name='+',
on_delete=models.SET_NULL,
verbose_name=_('Dispositivo Substituido'))
dispositivo_pai = models.ForeignKey(
'self',
@ -925,7 +938,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
def get_parents_asc(self):
return self.get_parents(ordem='asc')
def incrementar_irmaos(self, variacao=0, tipoadd=[]):
def incrementar_irmaos(self, variacao=0, tipoadd=[], force=True):
if not self.tipo_dispositivo.contagem_continua:
irmaos = list(Dispositivo.objects.filter(
@ -956,6 +969,10 @@ class Dispositivo(BaseModel, TimestampedMixin):
dp_profundidade = self.get_profundidade()
if (not force and not variacao and len(irmaos) > 0 and
irmaos[0].get_numero_completo() > self.get_numero_completo()):
return
irmaos_a_salvar = []
ultimo_irmao = None
for irmao in irmaos:
@ -1032,12 +1049,8 @@ class Dispositivo(BaseModel, TimestampedMixin):
proxima_articulacao = Dispositivo.objects.filter(
ordem__gt=self.ordem,
nivel=0,
ta_id=self.ta_id)[:1]
if not proxima_articulacao.exists():
return None
return proxima_articulacao[0]
ta_id=self.ta_id).first()
return proxima_articulacao
def is_relative_auto_insert(self, perfil_pk=None):
if self.dispositivo_pai is not None:

174
compilacao/views.py

@ -1007,26 +1007,180 @@ class ActionsEditMixin:
return JsonResponse(action(context), safe=False)
def delete_item_dispositivo(self, context):
return self.delete_bloco_dispositivo(context)
return self.delete_bloco_dispositivo(context, bloco=False)
def delete_bloco_dispositivo(self, context):
def delete_bloco_dispositivo(self, context, bloco=True):
base = Dispositivo.objects.get(pk=context['dispositivo_id'])
base_anterior = Dispositivo.objects.order_by('-ordem').filter(
ta_id=base.ta_id,
ordem__lt=base.ordem
)[:1]
base.delete()
data = {}
if base_anterior.exists():
if base_anterior[0].dispositivo_pai_id:
data = {'pk': base_anterior[0].pk, 'pai': [
base_anterior[0].dispositivo_pai_id, ]}
if base.dispositivo_pai_id:
data = {'pk': base_anterior[0].pk,
'pai': [base.dispositivo_pai_id, ]}
else:
data = {'pk': base_anterior[0].pk, 'pai': [-1, ]}
return data
else:
return {}
self.remover_dispositivo(base, bloco)
return data
def remover_dispositivo(self, base, bloco):
if base.dispositivo_subsequente or base.dispositivo_substituido:
p = base.dispositivo_substituido
n = base.dispositivo_subsequente
if n:
print(n.id, n)
n.dispositivo_substituido = p
n.save()
if p:
print(p.id, p)
p.dispositivo_subsequente = n
if n:
p.fim_vigencia = n.ini_vigencia - timedelta(days=1)
p.fim_eficacia = n.ini_eficacia - timedelta(days=1)
else:
p.fim_vigencia = None
p.fim_eficacia = None
for d in base.dispositivos_filhos_set.all():
if d.tipo_dispositivo.possiveis_pais.filter(
pai=base.tipo_dispositivo,
perfil__padrao=True,
filho_de_insercao_automatica=True).exists():
self.remover_dispositivo(d, bloco)
elif not bloco:
p.dispositivos_filhos_set.add(d)
p.save()
base.delete()
elif 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
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
# 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()
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())
if d.dispositivo_substituido != anterior:
d.transform_in_next()
d.rotulo = d.rotulo_padrao()
else:
parents = anterior.get_parents()
for candidato in parents:
if candidato.tipo_dispositivo == d.tipo_dispositivo:
d.dispositivo_pai = candidato.dispositivo_pai
d.nivel = candidato.nivel
if not d.tipo_dispositivo.contagem_continua:
d.set_numero_completo(
candidato.get_numero_completo())
if d.dispositivo_substituido != candidato:
d.transform_in_next()
d.rotulo = d.rotulo_padrao()
break
elif d.tipo_dispositivo.possiveis_pais.filter(
pai=candidato.tipo_dispositivo,
perfil__padrao=True).exists():
d.dispositivo_pai = candidato
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()
d.organizar_niveis()
if base.nivel:
if not base.tipo_dispositivo.contagem_continua:
pai_base = base.dispositivo_pai
irmaos_posteriores = pai_base.dispositivos_filhos_set.\
filter(
ordem__gt=base.ordem,
tipo_dispositivo=base.tipo_dispositivo)
numero_completo_base = base.get_numero_completo()
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
)
else:
irmaos_posteriores = Dispositivo.objects.filter(
ta_id=base.ta_id,
ordem__gt=base.ordem,
tipo_dispositivo=base.tipo_dispositivo)
base.delete()
numero_completo_irmao = None
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.rotulo = irmao.rotulo_padrao()
irmao.save()
else:
proxima_articulacao = base.get_proximo_nivel_zero()
# Dispostivos de Contagem contínua de dentro da base
dcc = Dispositivo.objects.order_by('ordem').filter(
ta_id=base.ta_id,
ordem__gt=base.ordem,
tipo_dispositivo__contagem_continua=True)
for d in dcc:
ultimo_dcc = Dispositivo.objects.order_by(
'ordem').filter(
ta_id=base.ta_id,
ordem__lt=d.ordem,
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()
d.rotulo = d.rotulo_padrao()
d.save(clean=False)
base.delete()
elif bloco:
# TODO: reorganizar dispositivos de contagem continua
base.delete()
def add_prior(self, context):
return {}
@ -1124,7 +1278,7 @@ class ActionsEditMixin:
dp.rotulo = dp.rotulo_padrao()
dp.ordem = ordem
dp.incrementar_irmaos(variacao, [local_add, ])
dp.incrementar_irmaos(variacao, [local_add, ], force=False)
dp.clean()
dp.save()

2
static/js/compilacao_edit.js

@ -250,7 +250,7 @@ $(document).ready(function() {
$("#message_block").css("display", "none");
href = location.href.split('#')
if (href.length == 2) {
if (href.length == 2 && href[1] != '') {
clickUpdateDispositivo(null, href[1], href[1], 'refresh', true);
}

104
static/styles/compilacao.scss

@ -143,12 +143,15 @@ a:link:after, a:visited:after {
.cp {
.desativado, .desativado * {
text-decoration: line-through;
color: #999 !important;
.desativado {
table, table td {
border: 1px dotted #ccc;
.dtxt, .dtxt * {
text-decoration: line-through;
color: #999 !important;
table, table td {
border: 1px dotted #ccc;
}
}
}
@ -261,7 +264,6 @@ a:link:after, a:visited:after {
}
.bloco_alteracao {
padding-left: 10%;
font-style: italic;
@ -399,6 +401,8 @@ a:link:after, a:visited:after {
transform-origin: right;
transition: all 0.3s ease;
border-top: 1px solid $color_buttons;
ul.btns-action {
list-style: none;
padding: 0;
@ -436,6 +440,7 @@ a:link:after, a:visited:after {
text-align: left;
font-size: 1.6rem;
.container-busca {
ul{
list-style: none;
@ -708,7 +713,16 @@ a:link:after, a:visited:after {
margin-bottom: 15em;
margin-left: 0.8em;
.desativado, .desativado * {
text-decoration: line-through;
color: #999 !important;
table, table td {
border: 1px dotted #ccc;
}
}
a {
text-decoration: none;
@ -723,54 +737,36 @@ a:link:after, a:visited:after {
font-weight: bold;
color: #BFD1F6;
}
.artigo {
float: none;
}
.caput {
margin-top: 0;
}
& > .actions_left {
color: #fff;
left: 0em;
position: absolute;
left: -2.6em;
opacity: 0;
transition: all 0.4s ease-in-out;
z-index: 1;
a {
&.btn-edit {
@include background-top-down(#3498DB, #2980C9);
@include border-radius(7px);
color: #ffffff !important;
font-weight: bold;
padding: 2px 7px 2px 7px;
padding: 5px 7px 3px;
display: inline-block;
line-height: 1;
&:hover {
@include background-top-down(#3cb0fd, #3498DB);
}
}
}
}
&:hover > .actions_left {
opacity: 0.5;
background-color: transparent !important;
&::before {
content: "";
border: inset 0.375rem;
border-color: transparent transparent transparent #3cb0fd;
position: absolute;
display: block;
height: 0;
width: 0;
top: 0.4rem;
right: -0.73rem;
}
&:hover {
opacity: 1;
&::before {
border-color: transparent transparent transparent #3cf0ff;
}
}
opacity: 1;
}
.bloco {
display: block;
clear: both;
@ -781,27 +777,36 @@ a:link:after, a:visited:after {
cursor: pointer;
}
}
.articulacao{
margin-left: -0.8em;
.articulacao {
border-top: 2 px solid #e5e5e5;
margin: 2em 0;
}
.bloco_alteracao {
border: 1px solid #ddd;
margin: -1px 0 0;
padding: 1em;
}
.articulacao1 {
margin-top: 2em;
&::before {
content: "Articulação";
background-color: #eee;
border-bottom: 1px solid #aaa;
border-bottom: 1px dotted #E88C8C;
padding: 0.333em;
padding-left: 1em;
display:block;
}
}
.bloco_alteracao {
@extend .articulacao;
margin: 0;
padding-top: 3em;
padding-left: 0em;
background: #ddd;
.bloco_alteracao1 {
@extend .articulacao1;
margin: -1px 0 0;
padding: 1em;
border: 1px dotted #E88C8C;
overflow: hidden;
&::before {
content: "Bloco de Alteração";
margin: -1em -1em 0;
display: block;
}
}
@ -837,16 +842,19 @@ a:link:after, a:visited:after {
a:hover {
background: transparent;
}
}
& > .bloco {
padding: 1em 0;
opacity: 1;
margin: 0 !important;
margin: 1em !important;
}
.bloco_alteracao {
padding-top: 2em;
}
& > .dpt {
padding: 0;
&:last-child {

3
templates/compilacao/text_edit.html

@ -14,7 +14,6 @@
<h1><b>Edição:</b> {{ view.title }} - <i>{% trans 'Texto Multivigente' %}</i></h1>
{% endblock %}
<div id="message_block"><div id="msg">{% trans 'Aguarde... Atualizando informações!!!'%}</div></div>
{% block actions %}
<div class="clearfix">
<div class="actions btn-toolbar pull-right" role="toolbar">
@ -28,6 +27,8 @@
{% block base_content %}{{block.super}}
<div id="message_block"><div id="msg">{% trans 'Aguarde... Atualizando informações!!!'%}</div></div>
<div class="cp cpe">
{% include 'compilacao/text_edit_bloco.html'%}
</div>

31
templates/compilacao/text_edit_bloco.html

@ -46,13 +46,16 @@
<ul class="actions_inserts {% if not dpt.tipo_dispositivo.dispositivo_de_articulacao %}menu_flutuante{%endif%}">
{% if dpt.dispositivo_subsequente == None %}
{% for inserts in view|select_provaveis_inserts:request %}
<li class="{{inserts.action}}"><a class="btn-inserts" action="" pk="{{dpt.pk}}">{{inserts.icone|safe}}<span>{{inserts.tipo_insert}}</span></a>
<ul id="afe{{dpt.id}}" >
{% for item in inserts.itens %}
<li><a class="btn-inserts btn-action" action="{{inserts|lookup:'action'}}" pk="{{item.dispositivo_base}}" variacao="{{item.variacao}}" tipo_pk="{{item.tipo_pk}}">{{item.provavel}}</a></li>
{% endfor %}
</ul>
</li>
{% if inserts.itens %}
<li class="{{inserts.action}}"><a class="btn-inserts" action="" pk="{{dpt.pk}}">{{inserts.icone|safe}}<span>{{inserts.tipo_insert}}</span></a>
<ul id="afe{{dpt.id}}" >
{% for item in inserts.itens %}
<li><a class="btn-inserts btn-action" action="{{inserts|lookup:'action'}}" pk="{{item.dispositivo_base}}" variacao="{{item.variacao}}" tipo_pk="{{item.tipo_pk}}">{{item.provavel}}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
{%endif%}
@ -60,8 +63,8 @@
<li class="menu_excluir"><a {% if not dpt.dispositivos_filhos_set.exists %}class="btn-excluir btn-action" action="delete_item_dispositivo" pk={{dpt.pk}}{%else%}class="btn-excluir"{%endif%}>&nbsp;<span>Excluir</span></a>
{% if dpt.dispositivos_filhos_set.exists %}
<ul>
<li><a href="#" class="btn-excluir btn-action" action="delete_item_dispositivo_todo" pk={{dpt.pk}}>TODO: Excluir apenas este dispositivo</a></li>
<li><a href="#" class="btn-excluir btn-action" action="delete_bloco_dispositivo" pk={{dpt.pk}}>Excluir toda a estrutura deste dispositivo</a></li>
<li><a href="#" class="btn-excluir btn-action" action="delete_item_dispositivo" pk={{dpt.pk}}>{% trans 'Excluir apenas este dispositivo'%}</a></li>
<li><a href="#" class="btn-excluir btn-action" action="delete_bloco_dispositivo" pk={{dpt.pk}}>{% trans 'Excluir este dispositivo e toda sua estrutura'%}</a></li>
</ul>
{% endif %}
</li>
@ -79,7 +82,7 @@
</div>
<ul class="label_status" >
<li>Ordem: {{dpt.ordem}}, Nivel: {{dpt.nivel}}, Número: {{dpt.get_numero_completo}}</li>
<li>p: {{dpt.dispositivo_substituido_id}}, n: {{dpt.dispositivo_subsequente_id}}, Ordem: {{dpt.ordem}}, Nivel: {{dpt.nivel}}, Número: {{dpt.get_numero_completo}}</li>
<li><a>.</a></li>
</ul>
@ -95,23 +98,23 @@
{% endif%}
{% if view.pk_view == 0 and view.pk_edit == 0 or view.pk_edit != view.pk_view %}
{% if not dpt.rotulo and not dpt.texto %}
{% if not dpt.rotulo and not dpt.texto and dpt.tipo_dispositivo.dispositivo_de_articulacao%}
<div class="btns-action actions_left">
<a class="btn-edit" pk="{{dpt.pk}}" title="Edição do dispositivo: {{ dpt.tipo_dispositivo.nome }} {{ dpt.rotulo }}">E</a>
<a class="btn-edit" pk="{{dpt.pk}}">{% trans 'Editar'%} {{ dpt.tipo_dispositivo.nome }} {{ dpt.rotulo }}</a>
</div>
{% endif %}
<div class="bloco {% dispositivo_desativado dpt view.inicio_vigencia view.fim_vigencia %} {{ dpt.tipo_dispositivo.class_css }}">
{% spaceless %}
<div class="de" id="id{{dpt.id}}" pk="{{dpt.pk}}" ordem="{{dpt.ordem}}" name="{{dpt.pk}}" title="{{dpt.pk}}">{{ dpt.tipo_dispositivo.rotulo_prefixo_html|safe }}{{ dpt.rotulo }}{{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{% if dpt.texto == '' and not dpt.tipo_dispositivo.dispositivo_de_articulacao %}<span class="semtexto">({{dpt.tipo_dispositivo}} sem texto)</span>{%else%}{{ dpt.texto|safe }}{%endif%}</div>
{% if dpt.ta_publicado_id != None and not dpt.tipo_dispositivo.dispositivo_de_articulacao %}
<a class="link_alterador" href="compilacao:ta_text_edit' dpt.ta_publicado.pk %}#{{dpt.dispositivo_atualizador_id}}">
<a class="link_alterador" href="{% url 'compilacao:ta_text_edit' dpt.ta_publicado.pk %}#{{dpt.dispositivo_atualizador_id}}">
{{ dpt.tipo_dispositivo.nota_automatica_prefixo_html|safe }}
{% nota_automatica dpt ta_pub_list %}
{{ dpt.tipo_dispositivo.nota_automatica_sufixo_html|safe }}
</a>
{% endif %}
{% endspaceless %}
{% if view.is_ta_alterador and dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%}
{% if dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%}
{%with node=dpt template_name='compilacao/text_edit_blocoalteracao.html' %}
{%include template_name%}
{%endwith%}

3
templates/compilacao/text_edit_blocoalteracao.html

@ -1,10 +1,11 @@
{% load compilacao_filters %}
{% load common_tags %}
aaaaa
{% for ch in dpt.pk|get_bloco_atualizador %}
{% spaceless %}
<div class="dpt" id="d{{ch.id}}">
<div class="{{ ch.tipo_dispositivo.class_css }}" id="id{{ch.id}}" nivel="{{ch.nivel}}">
{{ ch.tipo_dispositivo.rotulo_prefixo_html|safe }}<a name="{{ch.pk}}" href="compilacao:ta_text_edit' ch.ta.pk %}#{{ch.pk}}">{{ ch.rotulo }}</a>{{ ch.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ ch.tipo_dispositivo.texto_prefixo_html|safe }}{{ ch.texto|safe }}
{{ ch.tipo_dispositivo.rotulo_prefixo_html|safe }}<a name="{{ch.pk}}" href="{% url 'compilacao:ta_text_edit' ch.ta.pk %}#{{ch.pk}}">{{ ch.rotulo }}</a>{{ ch.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ ch.tipo_dispositivo.texto_prefixo_html|safe }}{{ ch.texto|safe }}
</div>
</div>
{% endspaceless %}

Loading…
Cancel
Save