Browse Source

Add registro de revogação unitária de dispositivos

pull/704/head
LeandroRoberto 8 years ago
parent
commit
e2cb37c858
  1. 48
      sapl/compilacao/forms.py
  2. 20
      sapl/compilacao/migrations/0055_dispositivo_dispositivo_de_revogacao.py
  3. 38
      sapl/compilacao/models.py
  4. 2
      sapl/compilacao/templatetags/compilacao_filters.py
  5. 57
      sapl/compilacao/views.py
  6. 53
      sapl/static/js/compilacao_edit.js
  7. 4
      sapl/templates/compilacao/ajax_actions_dinamic_edit.html
  8. 12
      sapl/templates/compilacao/text_list_bloco.html

48
sapl/compilacao/forms.py

@ -1280,3 +1280,51 @@ class DispositivoRegistroAlteracaoForm(Form):
super(DispositivoRegistroAlteracaoForm, self).__init__(*args, **kwargs) super(DispositivoRegistroAlteracaoForm, self).__init__(*args, **kwargs)
self.fields['dispositivo_alterado'].choices = [] self.fields['dispositivo_alterado'].choices = []
class DispositivoRegistroRevogacaoForm(Form):
dispositivo_revogado = forms.ModelChoiceField(
label=_('Dispositivo a ser revogado'),
required=False,
queryset=Dispositivo.objects.all())
dispositivo_search_form = forms.CharField(widget=forms.HiddenInput(),
required=False)
def __init__(self, *args, **kwargs):
layout = []
kwargs.pop('instance')
kwargs['initial'].pop('editor_type')
row_dispositivo = Field(
'dispositivo_revogado',
data_sapl_ta='DispositivoSearch',
data_field='dispositivo_revogado',
data_type_selection='radio',
template="compilacao/layout/dispositivo_radio.html")
layout.append(Fieldset(_('Registro de Revogação - '
'Seleção do Dispositivo a ser Revogado'),
row_dispositivo,
css_class="col-md-12"))
layout.append(Field('dispositivo_search_form'))
more = [
HTML('<a class="btn btn-inverse btn-fechar">%s</a>' %
_('Cancelar')),
]
more.append(Submit('salvar', _('Salvar'), css_class='pull-right'))
buttons = FormActions(*more, css_class='form-group')
_fields = [Div(*layout, css_class="row-fluid")] + \
[to_row([(buttons, 12)])]
self.helper = FormHelper()
self.helper.layout = Layout(*_fields)
super(DispositivoRegistroRevogacaoForm, self).__init__(*args, **kwargs)
self.fields['dispositivo_revogado'].choices = []

20
sapl/compilacao/migrations/0055_dispositivo_dispositivo_de_revogacao.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-20 11:57
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0054_auto_20160916_1424'),
]
operations = [
migrations.AddField(
model_name='dispositivo',
name='dispositivo_de_revogacao',
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Dispositivo de Revogação'),
),
]

38
sapl/compilacao/models.py

@ -132,7 +132,7 @@ class TextoArticulado(TimestampedMixin):
'numero': self.numero, 'numero': self.numero,
'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")} 'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")}
def ordenar_dispositivos(self): def reagrupar_ordem_de_dispositivos(self):
dpts = Dispositivo.objects.filter(ta=self) dpts = Dispositivo.objects.filter(ta=self)
@ -150,6 +150,37 @@ class TextoArticulado(TimestampedMixin):
count += Dispositivo.INTERVALO_ORDEM count += Dispositivo.INTERVALO_ORDEM
Dispositivo.objects.filter(pk=d).update(ordem=count) Dispositivo.objects.filter(pk=d).update(ordem=count)
def reordenar_dispositivos(self):
dpts = Dispositivo.objects.filter(ta=self)
if not dpts.exists():
return
ordem_max = dpts.last().ordem
dpts.update(ordem=F('ordem') + ordem_max)
raizes = Dispositivo.objects.filter(
ta=self,
dispositivo_pai__isnull=True).values_list(
'pk', flat=True).order_by('ordem')
count = []
count.append(Dispositivo.INTERVALO_ORDEM)
def update(dpk):
Dispositivo.objects.filter(pk=dpk).update(ordem=count[0])
count[0] = count[0] + Dispositivo.INTERVALO_ORDEM
filhos = Dispositivo.objects.filter(
dispositivo_pai_id=dpk).values_list(
'pk', flat=True).order_by('ordem')
for dpk in filhos:
update(dpk)
for dpk in raizes:
update(dpk)
class TipoNota(models.Model): class TipoNota(models.Model):
sigla = models.CharField( sigla = models.CharField(
@ -587,6 +618,11 @@ class Dispositivo(BaseModel, TimestampedMixin):
choices=YES_NO_CHOICES, choices=YES_NO_CHOICES,
verbose_name=_('Visibilidade no Texto Articulado Publicado')) verbose_name=_('Visibilidade no Texto Articulado Publicado'))
dispositivo_de_revogacao = models.BooleanField(
default=False,
choices=YES_NO_CHOICES,
verbose_name=_('Dispositivo de Revogação'))
tipo_dispositivo = models.ForeignKey( tipo_dispositivo = models.ForeignKey(
TipoDispositivo, TipoDispositivo,
related_name='dispositivos_do_tipo_set', related_name='dispositivos_do_tipo_set',

2
sapl/compilacao/templatetags/compilacao_filters.py

@ -86,7 +86,7 @@ def nota_automatica(dispositivo, ta_pub_list):
ta_publicado = ta_pub_list[dispositivo.ta_publicado_id] if\ ta_publicado = ta_pub_list[dispositivo.ta_publicado_id] if\
ta_pub_list else dispositivo.ta_publicado ta_pub_list else dispositivo.ta_publicado
if dispositivo.texto == Dispositivo.TEXTO_PADRAO_DISPOSITIVO_REVOGADO: if dispositivo.dispositivo_de_revogacao:
return _('Revogado pelo %s - %s.') % ( return _('Revogado pelo %s - %s.') % (
d, ta_publicado) d, ta_publicado)
elif not dispositivo.dispositivo_substituido_id: elif not dispositivo.dispositivo_substituido_id:

57
sapl/compilacao/views.py

@ -1,6 +1,6 @@
import sys
from collections import OrderedDict from collections import OrderedDict
from datetime import datetime, timedelta from datetime import datetime, timedelta
import sys
from braces.views import FormMessagesMixin from braces.views import FormMessagesMixin
from django import forms from django import forms
@ -30,7 +30,8 @@ from sapl.compilacao.forms import (DispositivoDefinidorVigenciaForm,
DispositivoRegistroAlteracaoForm, DispositivoRegistroAlteracaoForm,
DispositivoSearchModalForm, NotaForm, DispositivoSearchModalForm, NotaForm,
PublicacaoForm, TaForm, PublicacaoForm, TaForm,
TextNotificacoesForm, TipoTaForm, VideForm) TextNotificacoesForm, TipoTaForm, VideForm,
DispositivoRegistroRevogacaoForm)
from sapl.compilacao.models import (Dispositivo, Nota, from sapl.compilacao.models import (Dispositivo, Nota,
PerfilEstruturalTextoArticulado, PerfilEstruturalTextoArticulado,
Publicacao, TextoArticulado, Publicacao, TextoArticulado,
@ -41,6 +42,7 @@ from sapl.compilacao.utils import (DISPOSITIVO_SELECT_RELATED,
DISPOSITIVO_SELECT_RELATED_EDIT) DISPOSITIVO_SELECT_RELATED_EDIT)
from sapl.crud.base import Crud, CrudListView, make_pagination from sapl.crud.base import Crud, CrudListView, make_pagination
TipoNotaCrud = Crud.build(TipoNota, 'tipo_nota') TipoNotaCrud = Crud.build(TipoNota, 'tipo_nota')
TipoVideCrud = Crud.build(TipoVide, 'tipo_vide') TipoVideCrud = Crud.build(TipoVide, 'tipo_vide')
TipoPublicacaoCrud = Crud.build(TipoPublicacao, 'tipo_publicacao') TipoPublicacaoCrud = Crud.build(TipoPublicacao, 'tipo_publicacao')
@ -983,8 +985,7 @@ class TextEditView(TemplateView):
ta_publicado = lista_ta_publicado[dispositivo.ta_publicado_id] if\ ta_publicado = lista_ta_publicado[dispositivo.ta_publicado_id] if\
lista_ta_publicado else dispositivo.ta_publicado lista_ta_publicado else dispositivo.ta_publicado
if dispositivo.texto == \ if dispositivo.dispositivo_de_revogacao:
Dispositivo.TEXTO_PADRAO_DISPOSITIVO_REVOGADO:
return _('Revogado pelo %s - %s.') % ( return _('Revogado pelo %s - %s.') % (
d, ta_publicado) d, ta_publicado)
elif not dispositivo.dispositivo_substituido_id: elif not dispositivo.dispositivo_substituido_id:
@ -1170,7 +1171,7 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin):
else: else:
self.set_message(data, 'success', _( self.set_message(data, 'success', _(
'Exclusão efetuada com sucesso!'), modal=True) 'Exclusão efetuada com sucesso!'), modal=True)
ta_base.ordenar_dispositivos() ta_base.reagrupar_ordem_de_dispositivos()
except Exception as e: except Exception as e:
data['pk'] = self.kwargs['dispositivo_id'] data['pk'] = self.kwargs['dispositivo_id']
self.set_message(data, 'danger', str(e), modal=True) self.set_message(data, 'danger', str(e), modal=True)
@ -2066,7 +2067,17 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
return perfis[0].pk return perfis[0].pk
return None return None
def registra_alteracao(self, bloco_alteracao, dispositivo_a_alterar): def registra_revogacao(self, bloco_alteracao, dispositivo_a_revogar):
return self.registra_alteracao(
bloco_alteracao,
dispositivo_a_revogar,
revogacao=True
)
def registra_alteracao(self,
bloco_alteracao,
dispositivo_a_alterar,
revogacao=False):
""" """
Caracteristicas: Caracteristicas:
1 - Se é um dispositivo simples e sem subsequente 1 - Se é um dispositivo simples e sem subsequente
@ -2096,10 +2107,10 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
for d in history: for d in history:
"""FIXME: A comparação "<" deverá ser mudada para """FIXME: A comparação "<" deverá ser mudada para
"<=" caso um seja necessário permitir duas alterações "<=" caso seja necessário permitir duas alterações
com mesmo inicio_vigencia no mesmo dispositivo. Neste Caso, com mesmo inicio_vigencia no mesmo dispositivo. Neste Caso,
a sequencia correta ficará a cargo dos reposicionamentos entre a sequencia correta ficará a cargo dos reposicionamentos e
dispositivos de mesmo nível, (a ser implementado) entre dispositivos de mesmo nível,
""" """
if d.inicio_vigencia < bloco_alteracao.inicio_vigencia: if d.inicio_vigencia < bloco_alteracao.inicio_vigencia:
dispositivo_a_alterar = d dispositivo_a_alterar = d
@ -2118,8 +2129,12 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
dispositivo_a_alterar, dispositivo_a_alterar.tipo_dispositivo) dispositivo_a_alterar, dispositivo_a_alterar.tipo_dispositivo)
ndp.rotulo = dispositivo_a_alterar.rotulo ndp.rotulo = dispositivo_a_alterar.rotulo
ndp.texto = dispositivo_a_alterar.texto
ndp.publicacao = bloco_alteracao.publicacao ndp.publicacao = bloco_alteracao.publicacao
if not revogacao:
ndp.texto = dispositivo_a_alterar.texto
else:
ndp.texto = Dispositivo.TEXTO_PADRAO_DISPOSITIVO_REVOGADO
ndp.dispositivo_de_revogacao = True
ndp.dispositivo_vigencia = bloco_alteracao.dispositivo_vigencia ndp.dispositivo_vigencia = bloco_alteracao.dispositivo_vigencia
if ndp.dispositivo_vigencia: if ndp.dispositivo_vigencia:
@ -2167,9 +2182,16 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
d.dispositivo_pai = ndp d.dispositivo_pai = ndp
d.save() d.save()
self.set_message( ndp.ta.reordenar_dispositivos()
data, 'success',
_('Dispositivo de Alteração adicionado com sucesso.')) if not revogacao:
self.set_message(
data, 'success',
_('Dispositivo de Alteração adicionado com sucesso.'))
else:
self.set_message(
data, 'success',
_('Dispositivo de Revogação adicionado com sucesso.'))
except Exception as e: except Exception as e:
print(e) print(e)
@ -2221,6 +2243,8 @@ class DispositivoDinamicEditView(
self.form_class = DispositivoEdicaoBasicaForm self.form_class = DispositivoEdicaoBasicaForm
elif self.action.endswith('_alteracao'): elif self.action.endswith('_alteracao'):
self.form_class = DispositivoRegistroAlteracaoForm self.form_class = DispositivoRegistroAlteracaoForm
elif self.action.endswith('_revogacao'):
self.form_class = DispositivoRegistroRevogacaoForm
context = self.get_context_data() context = self.get_context_data()
return self.render_to_response(context) return self.render_to_response(context)
elif self.action.startswith('get_actions'): elif self.action.startswith('get_actions'):
@ -2267,6 +2291,13 @@ class DispositivoDinamicEditView(
data = self.registra_alteracao(d, dispositivo_a_alterar) data = self.registra_alteracao(d, dispositivo_a_alterar)
if formtype == 'get_form_revogacao':
dispositivo_a_revogar = Dispositivo.objects.get(
pk=request.POST['dispositivo_revogado'])
data = self.registra_revogacao(d, dispositivo_a_revogar)
elif formtype == 'get_form_base': elif formtype == 'get_form_base':
texto = request.POST['texto'].strip() texto = request.POST['texto'].strip()
texto_atualizador = request.POST['texto_atualizador'].strip() texto_atualizador = request.POST['texto_atualizador'].strip()

53
sapl/static/js/compilacao_edit.js

@ -138,6 +138,28 @@ function DispositivoEdit() {
}); });
} }
instance.get_form_revogacao = function () {
var _this = $(this);
_this.off('get_form_revogacao');
$('.dpt-actions, .dpt-actions-bottom').html('');
var dpt_form = _this.children().filter('.dpt-form').children().first();
var url_search = dpt_form[0]['id_dispositivo_search_form'].value;
DispostivoSearch({
'url_form': url_search,
'text_button': 'Selecionar'
});
instance.scrollTo(_this);
dpt_form.submit(instance.onSubmitFormRegistraRevogacao);
var btn_fechar = _this.find('.btn-fechar');
btn_fechar.on('click', function() {
instance.clearEditSelected();
instance.triggerBtnDptEdit(_this.attr('pk'));
});
}
instance.loadActionsEdit = function(dpt) { instance.loadActionsEdit = function(dpt) {
var pk = dpt.attr('pk'); var pk = dpt.attr('pk');
var url = pk+'/refresh?action=get_actions'; var url = pk+'/refresh?action=get_actions';
@ -258,8 +280,39 @@ function DispositivoEdit() {
}); });
if (event != null) if (event != null)
event.preventDefault(); event.preventDefault();
}
instance.onSubmitFormRegistraRevogacao = function(event) {
var _this = this;
var form_data = {
'csrfmiddlewaretoken' : this['csrfmiddlewaretoken'].value,
'dispositivo_revogado' : this['dispositivo_revogado'].value,
'formtype': 'get_form_revogacao',
};
var url = $(this).closest('.dpt').attr( "pk" )+'/refresh';
instance.waitShow();
$.post(url, form_data)
.done(function(data) {
instance.clearEditSelected();
if (data.pk != null) {
instance.refreshScreenFocusPk(data);
instance.message(data);
}
else {
alert('Erro na resposta!');
}
}).always(function() {
instance.waitHide();
});
if (event != null)
event.preventDefault();
} }
instance.onSubmitEditFormBase = function(event) { instance.onSubmitEditFormBase = function(event) {
var _this = this; var _this = this;

4
sapl/templates/compilacao/ajax_actions_dinamic_edit.html

@ -53,7 +53,7 @@
{% endif %} {% endif %}
</div> </div>
<div class="btn-group " role="group"> <div class="btn-group " role="group">
{% if object.dispositivo_subsequente == None %} {% if not object.dispositivo_subsequente %}
{% for perfil in perfil_estrutural_list%} {% for perfil in perfil_estrutural_list%}
<button type="button" class="btn-action btn-perfis btn btn-xs {%if request.session.perfil_estrutural == perfil.pk%}btn-primary{%else%}btn-default{%endif%}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" pk="{{object.pk}}" perfil_pk="{{perfil.pk}}" action="json_get_perfis" title="{{perfil.nome}}"> <button type="button" class="btn-action btn-perfis btn btn-xs {%if request.session.perfil_estrutural == perfil.pk%}btn-primary{%else%}btn-default{%endif%}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" pk="{{object.pk}}" perfil_pk="{{perfil.pk}}" action="json_get_perfis" title="{{perfil.nome}}">
{{perfil.sigla}} {{perfil.sigla}}
@ -61,7 +61,7 @@
{% endfor %} {% endfor %}
{%endif%} {%endif%}
</div> </div>
{% if not object.ta_publicado%} {% if not object.ta_publicado and not object.dispositivo_subsequente %}
<div class="btn-group " role="group"> <div class="btn-group " role="group">
<button type="button" class="btn-action btn btn-xs radius-right {% if object.pk == object.dispositivo_vigencia_id %}btn-primary{%else%}btn-default{%endif%}" pk="{{object.pk}}" action="json_set_dvt" title="{% if object.pk == object.dispositivo_vigencia_id %}{% trans 'Dispositivo de Vigência Atual'%}{%else%}{% trans 'Tornar este o Dispositivo de Vigência de todo o Texto Articulado.'%}{%endif%}"> <button type="button" class="btn-action btn btn-xs radius-right {% if object.pk == object.dispositivo_vigencia_id %}btn-primary{%else%}btn-default{%endif%}" pk="{{object.pk}}" action="json_set_dvt" title="{% if object.pk == object.dispositivo_vigencia_id %}{% trans 'Dispositivo de Vigência Atual'%}{%else%}{% trans 'Tornar este o Dispositivo de Vigência de todo o Texto Articulado.'%}{%endif%}">
DVt DVt

12
sapl/templates/compilacao/text_list_bloco.html

@ -19,7 +19,9 @@
{% spaceless %} {% spaceless %}
<div class="{{ dpt.tipo_dispositivo.class_css }}"> <div class="{{ dpt.tipo_dispositivo.class_css }}">
<div class="dptt {% dispositivo_desativado dpt view.inicio_vigencia view.fim_vigencia %}" id="dptt{{dpt.pk}}" > <div class="dptt {% dispositivo_desativado dpt view.inicio_vigencia view.fim_vigencia %}" id="dptt{{dpt.pk}}" >
{% if not dpt.tipo_dispositivo.dispositivo_de_articulacao %}
{% if not dpt.tipo_dispositivo.dispositivo_de_articulacao or dpt.tipo_dispositivo.dispositivo_de_articulacao and dpt.dispositivo_subsequente %}
{% if dpt.auto_inserido %} {% if dpt.auto_inserido %}
{{ dpt.dispositivo_pai.tipo_dispositivo.rotulo_prefixo_html|safe }} {{ dpt.dispositivo_pai.tipo_dispositivo.rotulo_prefixo_html|safe }}
<a class="dpt-link" name="{{dpt.pk}}">{{ dpt.dispositivo_pai.rotulo }}</a> <a class="dpt-link" name="{{dpt.pk}}">{{ dpt.dispositivo_pai.rotulo }}</a>
@ -30,12 +32,16 @@
{{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }} {{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }}
{% endif %} {% endif %}
{% endif %} {% endif %}
<span class="dtxt" id="d{% if not dpt.dispositivo_subsequente_id and dpt.dispositivo_substituido_id %}a{% endif %}{{dpt.pk}}" pks="{{dpt.dispositivo_substituido_id|default:''}}" pk="{{dpt.pk}}">{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{%if dpt.texto %}{{ dpt.texto|safe }}{%else%}{%if not dpt.tipo_dispositivo.dispositivo_de_articulacao %}&nbsp;{% endif %}{% endif %}</span> <span class="dtxt" id="d{% if not dpt.dispositivo_subsequente_id and dpt.dispositivo_substituido_id %}a{% endif %}{{dpt.pk}}" pks="{{dpt.dispositivo_substituido_id|default:''}}" pk="{{dpt.pk}}">{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{%if dpt.texto %}{{ dpt.texto|safe }}{%else%}{%if not dpt.tipo_dispositivo.dispositivo_de_articulacao %}&nbsp;{% endif %}{% endif %}</span>
{% if dpt.ta_publicado_id and not dpt.tipo_dispositivo.dispositivo_de_articulacao %} {% if dpt.ta_publicado_id %}
<a class="nota-alteracao" href="{%url 'sapl.compilacao:ta_text' dpt.ta_publicado.pk %}#{{dpt.dispositivo_atualizador_id}}"> <a class="nota-alteracao" href="{%url 'sapl.compilacao:ta_text' dpt.ta_publicado.pk %}#{{dpt.dispositivo_atualizador_id}}">
{{ dpt.tipo_dispositivo.nota_automatica_prefixo_html|safe }} {{ dpt.tipo_dispositivo.nota_automatica_prefixo_html|safe }}
{% nota_automatica dpt ta_pub_list %} {% nota_automatica dpt ta_pub_list %}
{{ dpt.tipo_dispositivo.nota_automatica_sufixo_html|safe }} {{ dpt.tipo_dispositivo.nota_automatica_sufixo_html|safe }}
{% if dpt.tipo_dispositivo.dispositivo_de_articulacao and dpt.dispositivo_substituido %}
&nbsp;
{% endif %}
</a> </a>
{% endif %} {% endif %}
{% if user.is_authenticated and not dpt.tipo_dispositivo.dispositivo_de_articulacao%} {% if user.is_authenticated and not dpt.tipo_dispositivo.dispositivo_de_articulacao%}
@ -52,7 +58,7 @@
{% endif %} {% endif %}
</div> </div>
{% if not dpt.tipo_dispositivo.dispositivo_de_articulacao%} {% if not dpt.tipo_dispositivo.dispositivo_de_articulacao %}
<div class="dn" id="dn{{dpt.pk}}" pk="{{dpt.pk}}">{# Dispostivo Nota e Vides #} <div class="dn" id="dn{{dpt.pk}}" pk="{{dpt.pk}}">{# Dispostivo Nota e Vides #}
<ul class="dnl">{# Dispostivo Nota Lista#} <ul class="dnl">{# Dispostivo Nota Lista#}

Loading…
Cancel
Save