From 25610bd22560dfaaee1a346254c25d89d3453f69 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Sat, 25 Jun 2016 23:00:08 -0300 Subject: [PATCH 01/18] =?UTF-8?q?Restrutura=20branch=20com=20mudan=C3=A7as?= =?UTF-8?q?=20de=20arq=20no=20master?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/compilacao/forms.py | 105 +- sapl/compilacao/models.py | 6 + .../templatetags/compilacao_filters.py | 48 +- sapl/compilacao/urls.py | 8 +- sapl/compilacao/utils.py | 12 + sapl/compilacao/views.py | 1386 ++++++++++------- .../compilacao/dispositivo_form.html | 23 +- .../compilacao/dispositivo_form_parents.html | 17 +- .../compilacao/dispositivo_form_search.html | 4 +- .../compilacao/layout/dispositivo_radio.html | 14 +- sapl/templates/compilacao/text_edit.html | 15 +- .../templates/compilacao/text_edit_bloco.html | 215 ++- .../compilacao/text_edit_blocoalteracao.html | 6 +- .../templates/compilacao/text_list_bloco.html | 4 +- .../compilacao/text_notificacoes.html | 13 +- .../compilacao/textoarticulado_detail.html | 1 - .../textoarticulado_menu_config.html | 2 - 17 files changed, 1181 insertions(+), 698 deletions(-) diff --git a/sapl/compilacao/forms.py b/sapl/compilacao/forms.py index 29892b150..7933177d9 100644 --- a/sapl/compilacao/forms.py +++ b/sapl/compilacao/forms.py @@ -484,6 +484,9 @@ class DispositivoEdicaoBasicaForm(ModelForm): inst = kwargs['instance'] if 'instance' in kwargs else None + editor_type = kwargs['initial']['editor_type']\ + if'editor_type' in kwargs['initial'] else '' + if inst and inst.tipo_dispositivo.formato_variacao0 in [ TipoDispositivo.FNC8, TipoDispositivo.FNCN]: if 'rotulo' in DispositivoEdicaoBasicaForm.Meta.fields: @@ -491,6 +494,12 @@ class DispositivoEdicaoBasicaForm(ModelForm): for i in range(6): DispositivoEdicaoBasicaForm.Meta.fields.remove( 'dispositivo%s' % i) + elif editor_type == 'get_form_base': + if 'rotulo' in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.remove('rotulo') + for i in range(6): + DispositivoEdicaoBasicaForm.Meta.fields.remove( + 'dispositivo%s' % i) else: if 'rotulo' not in DispositivoEdicaoBasicaForm.Meta.fields: DispositivoEdicaoBasicaForm.Meta.fields.append('rotulo') @@ -552,6 +561,46 @@ class DispositivoEdicaoBasicaForm(ModelForm): row_texto, css_class="col-md-12")) + if editor_type == 'get_form_base' and inst.dispositivo_atualizador_id: + if inst and inst.tipo_dispositivo.dispositivo_de_articulacao: + if 'texto_atualizador' in\ + DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.remove( + 'texto_atualizador') + DispositivoEdicaoBasicaForm.Meta.fields.remove( + 'visibilidade') + else: + if 'texto_atualizador' not in\ + DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.append( + 'texto_atualizador') + DispositivoEdicaoBasicaForm.Meta.fields.append( + 'visibilidade') + + self.texto_atualizador = forms.CharField( + required=False, + label='', + widget=forms.Textarea()) + self.visibilidade = forms.ChoiceField( + label=Dispositivo._meta.get_field( + 'visibilidade').verbose_name, + choices=utils.YES_NO_CHOICES, + widget=forms.RadioSelect()) + + layout.append( + Fieldset(Dispositivo._meta.get_field( + 'texto_atualizador').verbose_name, + to_row([(InlineRadios('visibilidade'), 12)]), + to_row([('texto_atualizador', 12)]), + css_class="col-md-12")) + else: + if 'texto_atualizador' in\ + DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.remove( + 'texto_atualizador') + DispositivoEdicaoBasicaForm.Meta.fields.remove( + 'visibilidade') + fields = DispositivoEdicaoBasicaForm.Meta.fields if fields: self.base_fields.clear() @@ -559,12 +608,58 @@ class DispositivoEdicaoBasicaForm(ModelForm): self.base_fields.update({f: getattr(self, f)}) self.helper = FormHelper() - self.helper.layout = SaplFormLayout( - *layout, - label_cancel=_('Ir para o Editor Sequencial')) + + if not editor_type: + label_cancel = _('Ir para o Editor Sequencial') + self.helper.layout = SaplFormLayout( + *layout, label_cancel=label_cancel) + + elif editor_type == "get_form_base": + getattr(self, "actions_" + editor_type)(layout, inst) super(DispositivoEdicaoBasicaForm, self).__init__(*args, **kwargs) + def actions_get_form_base(self, layout, inst): + label_cancel = _('Fechar') + + more = [ + HTML('%s' % + label_cancel), + ] + + btns_excluir = [] + + if not inst.is_relative_auto_insert(): + btns_excluir = [ + HTML('%s' % (_('Excluir apenas este dispositivo.'), + _('Excluir Dispositivo')))] + + if inst.dispositivos_filhos_set.exists(): + btns_excluir.append( + HTML( + '%s' % (_('Excluir este dispositivo ' + 'e toda sua estrutura.'), + _('Excluir Bloco de Dispositivo.')))) + + if btns_excluir: + css_class = 'btn-group pull-right btns-excluir' + more.append(Div(*btns_excluir, css_class=css_class)) + + if not inst.tipo_dispositivo.dispositivo_de_articulacao: + more.append(Submit('salvar', _('Salvar'), css_class='pull-right')) + + buttons = FormActions(*more, css_class='form-group') + + _fields = [to_row([(buttons, 12)])] + \ + [Div(*layout, css_class="row-fluid")] + self.helper.layout = Layout(*_fields) + class DispositivoSearchModalForm(Form): @@ -624,7 +719,7 @@ class DispositivoSearchModalForm(Form): placeholder=_('Digite palavras, letras, ' 'números ou algo' ' que estejam no texto.')), - StrictButton(_('Buscar'), css_class='btn-busca')), 7)) + StrictButton(_('Buscar'), css_class='btn-busca btn-primary')), 7)) ) ) @@ -1082,7 +1177,7 @@ class TextNotificacoesForm(Form): type_notificacoes = forms.ChoiceField( label=_('Níveis de Notificações'), - choices=[('default', _('Mostrar Dispositivos sem Notificações!')), + choices=[('default', _('Dispositivos sem Notificações!')), ('success', _('Informações!')), ('info', _('Boas Práticas!')), ('warning', _('Alertas!')), diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index fbc282610..4d413d1d0 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -1112,6 +1112,12 @@ class Dispositivo(BaseModel, TimestampedMixin): ta_id=self.ta_id).last() return anterior_articulacao + def get_niveis_zero(self): + niveis_zero = Dispositivo.objects.order_by('ordem').filter( + nivel=0, + ta_id=self.ta_id) + return niveis_zero + def is_relative_auto_insert(self, perfil_pk=None): if self.dispositivo_pai is not None: # pp possiveis_pais diff --git a/sapl/compilacao/templatetags/compilacao_filters.py b/sapl/compilacao/templatetags/compilacao_filters.py index 3fd024a77..b81d16e16 100644 --- a/sapl/compilacao/templatetags/compilacao_filters.py +++ b/sapl/compilacao/templatetags/compilacao_filters.py @@ -10,6 +10,52 @@ from sapl.compilacao.models import Dispositivo register = template.Library() +class DispositivoTreeNode(template.Node): + + def __init__(self, template_nodes, dispositivo_list_var): + self.template_nodes = template_nodes + self.dispositivo_list_var = dispositivo_list_var + + def _render_node(self, context, node): + bits_alts = [] + bits_filhos = [] + context.push() + for child in node['alts']: + bits_alts.append(self._render_node(context, child)) + for child in node['filhos']: + bits_filhos.append(self._render_node(context, child)) + context['node'] = node + context['alts'] = mark_safe(''.join(bits_alts)) + context['filhos'] = mark_safe(''.join(bits_filhos)) + rendered = self.template_nodes.render(context) + context.pop() + return rendered + + def render(self, context): + dispositivo_list_var = self.dispositivo_list_var.resolve(context) + bits = [self._render_node(context, node) + for node in dispositivo_list_var] + return ''.join(bits) + + +@register.tag +def dispositivotree(parser, token): + + bits = token.contents.split() + if len(bits) != 2: + raise template.TemplateSyntaxError( + _('%s tag requires a queryset') % bits[0]) + + dispositivo_list_var = template.Variable(bits[1]) + + template_nodes = parser.parse(('enddispositivotree',)) + parser.delete_first_token() + + return DispositivoTreeNode(template_nodes, dispositivo_list_var) + +# -------------------------------------------------------------- + + @register.filter def get_bloco_atualizador(pk_atualizador): return Dispositivo.objects.order_by('ordem_bloco_atualizador').filter( @@ -34,7 +80,7 @@ def dispositivo_desativado(dispositivo, inicio_vigencia, fim_vigencia): @register.simple_tag def nota_automatica(dispositivo, ta_pub_list): - if dispositivo.ta_publicado is not None: + if dispositivo.ta_publicado: d = dispositivo.dispositivo_atualizador.dispositivo_pai ta_publicado = ta_pub_list[dispositivo.ta_publicado_id] if\ diff --git a/sapl/compilacao/urls.py b/sapl/compilacao/urls.py index f5466e747..1c6cc2e70 100644 --- a/sapl/compilacao/urls.py +++ b/sapl/compilacao/urls.py @@ -34,7 +34,8 @@ urlpatterns_compilacao = [ views.DispositivoView.as_view(), name='dispositivo'), url(r'^(?P[0-9]+)/text/(?P[0-9]+)/refresh', - views.DispositivoSimpleEditView.as_view(), name='dispositivo_refresh'), + views.DispositivoDinamicEditView.as_view(), + name='dispositivo_refresh'), url(r'^(?P[0-9]+)/text/(?P[0-9]+)/edit$', views.DispositivoEdicaoBasicaView.as_view(), name='dispositivo_edit'), @@ -51,8 +52,6 @@ urlpatterns_compilacao = [ views.DispositivoDefinidorVigenciaView.as_view(), name='dispositivo_edit_definidor_vigencia'), - url(r'^(?P[0-9]+)/text/(?P[0-9]+)/actions', - views.ActionsEditView.as_view(), name='dispositivo_actions'), url(r'^(?P[0-9]+)/text/' '(?P[0-9]+)/nota/create$', @@ -126,3 +125,6 @@ urlpatterns = [ include(VeiculoPublicacaoCrud.get_urls())), ] + +"""url(r'^(?P[0-9]+)/text/(?P[0-9]+)/actions', + views.ActionsEditView.as_view(), name='dispositivo_actions'),""" \ No newline at end of file diff --git a/sapl/compilacao/utils.py b/sapl/compilacao/utils.py index 38c55239a..83f44e8f3 100644 --- a/sapl/compilacao/utils.py +++ b/sapl/compilacao/utils.py @@ -12,6 +12,18 @@ DISPOSITIVO_SELECT_RELATED = ( 'ta_publicado', 'ta',) +DISPOSITIVO_SELECT_RELATED_EDIT = ( + 'ta_publicado', + 'ta', + 'dispositivo_atualizador', + 'dispositivo_atualizador__dispositivo_pai', + 'dispositivo_atualizador__dispositivo_pai__ta', + 'dispositivo_atualizador__dispositivo_pai__ta__tipo_ta', + 'dispositivo_pai', + 'dispositivo_pai__tipo_dispositivo', + 'ta_publicado', + 'ta',) + def int_to_roman(int_value): # if isinstance(int_value, type(1)): diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index ff88d627d..804cc4fbf 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -1,6 +1,6 @@ -import sys from collections import OrderedDict from datetime import datetime, timedelta +import sys from braces.views import FormMessagesMixin from django import forms @@ -27,21 +27,23 @@ from sapl.compilacao.forms import (DispositivoDefinidorVigenciaForm, DispositivoEdicaoBasicaForm, DispositivoEdicaoVigenciaForm, DispositivoSearchModalForm, NotaForm, - PublicacaoForm, TaForm, - TextNotificacoesForm, TipoTaForm, VideForm) + PublicacaoForm, TaForm, TextNotificacoesForm, + TipoTaForm, VideForm) from sapl.compilacao.models import (Dispositivo, Nota, - PerfilEstruturalTextoArticulado, - Publicacao, TextoArticulado, - TipoDispositivo, TipoNota, TipoPublicacao, - TipoTextoArticulado, TipoVide, + PerfilEstruturalTextoArticulado, Publicacao, + TextoArticulado, TipoDispositivo, TipoNota, + TipoPublicacao, TipoTextoArticulado, TipoVide, VeiculoPublicacao, Vide) -from sapl.compilacao.utils import DISPOSITIVO_SELECT_RELATED +from sapl.compilacao.utils import DISPOSITIVO_SELECT_RELATED,\ + DISPOSITIVO_SELECT_RELATED_EDIT from sapl.crud.base import Crud, CrudListView, make_pagination + TipoNotaCrud = Crud.build(TipoNota, 'tipo_nota') TipoVideCrud = Crud.build(TipoVide, 'tipo_vide') TipoPublicacaoCrud = Crud.build(TipoPublicacao, 'tipo_publicacao') VeiculoPublicacaoCrud = Crud.build(VeiculoPublicacao, 'veiculo_publicacao') +#^class(.)+\((.)*^(CompMix)(.)* class IntegracaoTaView(TemplateView): @@ -133,15 +135,21 @@ def choice_models_in_extenal_views(): class CompMixin: - @property - def title(self): - try: - return self.get_object() - except: - return self.object + def get_context_data(self, **kwargs): + context = super(CompMixin, self).get_context_data(**kwargs) + + if hasattr(self, 'model') and not hasattr(self, 'object'): + context.update( + {'title': self.model._meta.verbose_name_plural + if isinstance(self, ListView) + else self.model._meta.verbose_name}) + + if isinstance(self, ListView): + context['NO_ENTRIES_MSG'] = CrudListView.no_entries_msg + return context -class TipoTaListView(ListView): +class TipoTaListView(CompMixin, ListView): model = TipoTextoArticulado paginate_by = 10 verbose_name = model._meta.verbose_name @@ -155,7 +163,7 @@ class TipoTaListView(ListView): return reverse_lazy('sapl.compilacao:tipo_ta_create') -class TipoTaCreateView(FormMessagesMixin, CreateView): +class TipoTaCreateView(CompMixin, FormMessagesMixin, CreateView): model = TipoTextoArticulado form_class = TipoTaForm template_name = "crud/form.html" @@ -220,7 +228,7 @@ class TipoTaDeleteView(CompMixin, DeleteView): return reverse_lazy('sapl.compilacao:tipo_ta_list') -class TaListView(ListView): +class TaListView(CompMixin, ListView): model = TextoArticulado paginate_by = 10 verbose_name = model._meta.verbose_name @@ -242,7 +250,7 @@ class TaListView(ListView): return context -class TaDetailView(DetailView): +class TaDetailView(CompMixin, DetailView): model = TextoArticulado @property @@ -257,7 +265,7 @@ class TaDetailView(DetailView): return self.get_object() -class TaCreateView(FormMessagesMixin, CreateView): +class TaCreateView(CompMixin, FormMessagesMixin, CreateView): model = TextoArticulado form_class = TaForm template_name = "crud/form.html" @@ -309,7 +317,7 @@ class TaDeleteView(CompMixin, DeleteView): return reverse_lazy('sapl.compilacao:ta_list') -class DispositivoSuccessUrlMixin: +class DispositivoSuccessUrlMixin(CompMixin): def get_success_url(self): return reverse_lazy( @@ -469,7 +477,7 @@ class VideDeleteView(VideMixin, TemplateView): return HttpResponseRedirect(self.get_success_url()) -class PublicacaoListView(ListView): +class PublicacaoListView(CompMixin, ListView): model = Publicacao verbose_name = model._meta.verbose_name @@ -500,7 +508,7 @@ class PublicacaoListView(ListView): return context -class PublicacaoCreateView(FormMessagesMixin, CreateView): +class PublicacaoCreateView(CompMixin, FormMessagesMixin, CreateView): model = Publicacao form_class = PublicacaoForm template_name = "crud/form.html" @@ -568,7 +576,7 @@ class PublicacaoDeleteView(CompMixin, DeleteView): kwargs={'ta_id': self.kwargs['ta_id']}) -class TextView(ListView, CompMixin): +class TextView(CompMixin, ListView): template_name = 'compilacao/text_list.html' flag_alteradora = -1 @@ -810,53 +818,189 @@ class DispositivoView(TextView): return itens -class TextEditView(ListView, CompMixin): +class TextEditView(TemplateView): template_name = 'compilacao/text_edit.html' - flag_alteradora = -1 + def get_context_data(self, **kwargs): + dispositivo_id = int(self.kwargs['dispositivo_id']) \ + if 'dispositivo_id' in self.kwargs else 0 - flag_nivel_ini = 0 - flag_nivel_old = -1 + if dispositivo_id: + self.object = Dispositivo.objects.get(pk=dispositivo_id) - pk_edit = 0 - pk_view = 0 + context = super(TextEditView, self).get_context_data(**kwargs) - def get(self, request, *args, **kwargs): + if not dispositivo_id: + ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id']) + self.object = ta - return ListView.get(self, request, *args, **kwargs) + context['object'] = self.object + context['dispositivos_list'] = self.dispositivos_list() - def get_context_data(self, **kwargs): - context = super(TextEditView, self).get_context_data(**kwargs) + if 'action' in self.request.GET: + context['action'] = self.request.GET['action'] - ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id']) - self.object = ta + return context - context['object'] = self.object + def dispositivos_list(self): + self.runBase() - tas_pub = [d.ta_publicado for d in self.object_list if d.ta_publicado] + tds = {td.pk: td for td in TipoDispositivo.objects.all()} + + dispositivo_id = int(self.kwargs['dispositivo_id']) \ + if 'dispositivo_id' in self.kwargs else 0 + ta_id = int(self.kwargs['ta_id']) \ + if 'ta_id' in self.kwargs else 0 + + q = Q(ta_id=ta_id) + + dispositivos_de_alteracao = [] + dispositivos = [] + if dispositivo_id: + bloco = Dispositivo.objects.get(pk=dispositivo_id) + + if (tds[bloco.tipo_dispositivo_id].dispositivo_de_alteracao and + not tds[bloco.tipo_dispositivo_id + ].dispositivo_de_articulacao) or ( + bloco.ta_id != ta_id and bloco.ta_publicado_id == ta_id): + dispositivos = [bloco, ] + else: + proximo_bloco = Dispositivo.objects.filter( + ordem__gt=bloco.ordem, + nivel__lte=bloco.nivel, + ta_id=ta_id)[:1] + + if not proximo_bloco.exists(): + q = q & Q(ordem__gte=bloco.ordem) + else: + q = q & Q(ordem__gte=bloco.ordem) & \ + Q(ordem__lt=proximo_bloco[0].ordem) + + dispositivos_de_alteracao = Dispositivo.objects.filter( + ta_id=ta_id, + tipo_dispositivo__dispositivo_de_alteracao=True, + tipo_dispositivo__dispositivo_de_articulacao=False + ).select_related(*DISPOSITIVO_SELECT_RELATED_EDIT) + + if not dispositivos: + dispositivos = Dispositivo.objects.filter( + q).select_related(*DISPOSITIVO_SELECT_RELATED_EDIT) + + dispositivos_alterados = Dispositivo.objects.filter( + ta_publicado_id=ta_id) + + dispositivos_alteradores = Dispositivo.objects.filter( + dispositivos_alterados_set__ta_id=ta_id) + + dpts = list(dispositivos) + \ + list(dispositivos_de_alteracao) + \ + list(dispositivos_alterados) + \ + list(dispositivos_alteradores) + + tas_pub = [d.ta_publicado for d in dispositivos if d.ta_publicado] tas_pub = set(tas_pub) - ta_pub_list = {} + lista_ta_publicado = {} for ta in tas_pub: - ta_pub_list[ta.pk] = str(ta) - context['ta_pub_list'] = ta_pub_list - - return context + lista_ta_publicado[ta.pk] = str(ta) + + dpts = {d.pk: { + 'dpt': d, + 'filhos': [], + 'alts': [], + 'pai': None, + 'st': None, # dispositivo substituido + 'sq': None, # dispositivo subsequente + 'da': None, # dispositivo atualizador + 'td': tds[d.tipo_dispositivo_id], # tipo do dispositivo + 'na': self.nota_alteracao(d, lista_ta_publicado)\ + if d.ta_id == ta_id else None + } for d in dpts} + + apagar = [] + for d in dispositivos: + try: + if d.dispositivo_substituido_id: + dpts[d.pk]['st'] = dpts[d.dispositivo_substituido_id] + except: + pass + try: + if d.dispositivo_subsequente_id: + dpts[d.pk]['sq'] = dpts[d.dispositivo_subsequente_id] + except: + pass + try: + if d.dispositivo_atualizador_id: + dpts[d.pk]['da'] = dpts[d.dispositivo_atualizador_id] + except: + pass + try: + if d.dispositivo_pai_id: + """ Pode não ser possível vincular a estrutura do pai + devido a busca de bloco não envolver o pai do bloco, + por isso os try's except's""" + dpts[d.pk]['pai'] = dpts[d.dispositivo_pai_id] + + if tds[d.tipo_dispositivo_id].\ + dispositivo_de_alteracao and not\ + tds[d.tipo_dispositivo_id].\ + dispositivo_de_articulacao: + apagar.append(d.pk) + else: + dpts[d.dispositivo_pai_id]['filhos'].append(dpts[d.pk]) + apagar.append(d.pk) + except: + pass + try: + if tds[d.tipo_dispositivo_id].dispositivo_de_alteracao and\ + tds[d.tipo_dispositivo_id].dispositivo_de_articulacao: + + alts = Dispositivo.objects.values_list( + 'pk', flat=True).order_by( + 'ordem_bloco_atualizador').filter( + Q(dispositivo_pai_id=d.pk) | + Q(dispositivo_atualizador_id=d.pk)) + + for dAlt in alts: + dpts[d.pk]['alts'].append(dpts[dAlt]) + dpts[dAlt]['da'] = dpts[d.pk] + except: + pass - def get_queryset(self): - self.pk_edit = 0 - self.pk_view = 0 + for pk in apagar: + del dpts[pk] + + r = [] + for dd in dispositivos: + if dd.pk in dpts: + r.append(dpts[dd.pk]) + return r + + def nota_alteracao(self, dispositivo, lista_ta_publicado): + if dispositivo.ta_publicado_id: + d = dispositivo.dispositivo_atualizador.dispositivo_pai + + ta_publicado = lista_ta_publicado[dispositivo.ta_publicado_id] if\ + lista_ta_publicado else dispositivo.ta_publicado + + if dispositivo.texto == \ + Dispositivo.TEXTO_PADRAO_DISPOSITIVO_REVOGADO: + return _('Revogado pelo %s - %s.') % ( + d, ta_publicado) + elif not dispositivo.dispositivo_substituido_id: + return _('Inclusão feita pelo %s - %s.') % ( + d, ta_publicado) + else: + return _('Alteração feita pelo %s - %s.') % ( + d, ta_publicado) - self.flag_alteradora = -1 - self.flag_nivel_ini = 0 - self.flag_nivel_old = -1 + return '' - result = Dispositivo.objects.filter( - ta_id=self.kwargs['ta_id'] - ).select_related(*DISPOSITIVO_SELECT_RELATED) + def runBase(self): + result = Dispositivo.objects.filter(ta_id=self.kwargs['ta_id']) if not result.exists(): - ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id']) + ta = self.object td = TipoDispositivo.objects.filter(class_css='articulacao')[0] a = Dispositivo() @@ -891,459 +1035,143 @@ class TextEditView(ListView, CompMixin): a.set_numero_completo([2, 0, 0, 0, 0, 0, ]) a.save() - result = Dispositivo.objects.filter( - ta_id=self.kwargs['ta_id'] - ).select_related(*DISPOSITIVO_SELECT_RELATED) - return result +class ActionsCommonsMixin: - def set_perfil_in_session(self, request=None, perfil_id=0): - if not request: - return None + def set_message(self, data, type, message): + data['message'] = { + 'type': "success", + 'value': str(_('Dispositivo alterado com sucesso.'))} + return - if perfil_id: - perfil = PerfilEstruturalTextoArticulado.objects.get( - pk=perfil_id) - request.session['perfil_estrutural'] = perfil.pk - else: - perfis = PerfilEstruturalTextoArticulado.objects.filter( - padrao=True)[:1] + def get_json_for_refresh(self, dp, dpauto=None): - if not perfis.exists(): - request.session.pop('perfil_estrutural') + if dp.tipo_dispositivo.contagem_continua: + pais = [] + if dp.dispositivo_pai is None: + data = {'pk': dp.pk, 'pai': [-1, ]} else: - request.session['perfil_estrutural'] = perfis[0].pk + pkfilho = dp.pk + dp = dp.dispositivo_pai + proxima_articulacao = dp.get_proximo_nivel_zero() -class DispositivoSimpleEditView(TextEditView): - template_name = 'compilacao/text_edit_bloco.html' + if proxima_articulacao is not None: + parents = Dispositivo.objects.filter( + ta_id=dp.ta_id, + ordem__gte=dp.ordem, + ordem__lt=proxima_articulacao.ordem, + nivel__lte=dp.nivel) + else: + parents = Dispositivo.objects.filter( + ta_id=dp.ta_id, + ordem__gte=dp.ordem, + nivel__lte=dp.nivel) - def post(self, request, *args, **kwargs): + nivel = sys.maxsize + for p in parents: + if p.nivel > nivel: + continue + pais.append(p.pk) + nivel = p.nivel + data = { + 'pk': pkfilho if not dpauto else dpauto.pk, 'pai': pais} + else: + data = {'pk': dp.pk if not dpauto else dpauto.pk, 'pai': [ + dp.dispositivo_pai.pk, ]} - d = Dispositivo.objects.get( - pk=self.kwargs['dispositivo_id']) + return data - texto = request.POST['texto'] - if d.texto != '': - d.texto = texto - d.save() - return self.get(request, *args, **kwargs) - d.texto = texto.strip() - d.save() +class ActionDragAndMoveDispositivoAlteradoMixin(ActionsCommonsMixin): - if texto != '': - dnext = Dispositivo.objects.filter( - ta_id=d.ta_id, - ordem__gt=d.ordem, - texto='', - tipo_dispositivo__dispositivo_de_articulacao=False)[:1] + def json_drag_move_dpt_alterado(self, context): - if not dnext.exists(): - dnext = [] - dnext.append(d) - pais = [d.dispositivo_pai_id, ] - else: + bloco = Dispositivo.objects.get(pk=self.request.GET['bloco_pk']) + dpt = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) - if dnext[0].nivel > d.nivel: - pais = [d.pk, ] - else: - if dnext[0].dispositivo_pai_id == d.dispositivo_pai_id: - pais = [dnext[0].dispositivo_pai_id, ] - else: - pais = [ - dnext[0].dispositivo_pai_id, - d.dispositivo_pai_id] - data = {'pk': dnext[0].pk, 'pai': pais} + if dpt.tipo_dispositivo.dispositivo_de_alteracao: + dpt.dispositivo_pai = bloco else: - data = {'pk': d.pk, 'pai': [d.pk, ]} + dpt.dispositivo_atualizador = bloco - return JsonResponse(data, safe=False) + filhos = Dispositivo.objects.order_by( + 'ordem_bloco_atualizador').filter( + Q(dispositivo_pai_id=bloco.pk) | + Q(dispositivo_atualizador_id=bloco.pk)) - def get_queryset_perfil_estrutural(self): - perfis = PerfilEstruturalTextoArticulado.objects.all() - return perfis + if not filhos.exists(): + dpt.ordem_bloco_atualizador = Dispositivo.INTERVALO_ORDEM + else: + index = int(self.request.GET['index']) + fpks = filhos.values_list( + 'pk', flat=True).order_by('ordem_bloco_atualizador') - def get(self, request, *args, **kwargs): + index_dpt = 0 + try: + index_dpt = list(fpks).index(dpt.pk) + except: + pass - try: - if 'perfil_pk' in request.GET: - self.set_perfil_in_session( - request, request.GET['perfil_pk']) - elif 'perfil_estrutural' not in request.session: - self.set_perfil_in_session(request=request) + filho_index = filhos[ + index if index_dpt >= index + else index + 1] if ( + index if index_dpt >= index + else index + 1) < filhos.count() else filhos.last() + if filhos.last() == filho_index: + dpt.ordem_bloco_atualizador = \ + filho_index.ordem_bloco_atualizador + 1 + else: + dpt.ordem_bloco_atualizador = \ + filho_index.ordem_bloco_atualizador - 1 - self.object_list = self.get_queryset() + dpt.save() + bloco.ordenar_bloco_alteracao() - self.perfil_estrutural_list = self.get_queryset_perfil_estrutural() + data = {} - context = self.get_context_data( - object_list=self.object_list, - perfil_estrutural_list=self.perfil_estrutural_list - ) - except Exception as e: - print(e) - return self.render_to_response(context) +class ActionDeleteDispositivoMixin(ActionsCommonsMixin): - def get_queryset(self): - self.flag_alteradora = -1 - self.flag_nivel_ini = 0 - self.flag_nivel_old = -1 + def json_delete_item_dispositivo(self, context): + return self.json_delete_bloco_dispositivo(context, bloco=False) - try: - self.pk_edit = int(self.request.GET['edit']) - except: - self.pk_edit = 0 - self.pk_view = int(self.kwargs['dispositivo_id']) + def json_delete_bloco_dispositivo(self, context, bloco=True): + base = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) - try: - if self.pk_edit == self.pk_view: - bloco = Dispositivo.objects.get( - pk=self.kwargs['dispositivo_id']) + base_anterior = Dispositivo.objects.order_by('-ordem').filter( + ta_id=base.ta_id, + ordem__lt=base.ordem + ).first() + + data = {} + if base_anterior: + data = self.get_json_for_refresh(base_anterior) + else: + 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: - bloco = Dispositivo.objects.get( - pk=self.kwargs['dispositivo_id']) - except Dispositivo.DoesNotExist: - return [] + data['pk'] = '' - self.flag_nivel_old = bloco.nivel - 1 - self.flag_nivel_ini = bloco.nivel + ta_base = base.ta - if self.pk_edit == self.pk_view: - return [bloco, ] + # TODO: a linha abaixo causa atualização da tela inteira... + # retirar a linha abaixo e identificar atualizações pontuais + data['pai'] = [-1, ] - proximo_bloco = Dispositivo.objects.filter( - ordem__gt=bloco.ordem, - nivel__lte=bloco.nivel, - ta_id=self.kwargs['ta_id'])[:1] - - if proximo_bloco.count() == 0: - itens = Dispositivo.objects.filter( - ordem__gte=bloco.ordem, - ta_id=self.kwargs['ta_id'] - ).select_related(*DISPOSITIVO_SELECT_RELATED) - else: - itens = Dispositivo.objects.filter( - ordem__gte=bloco.ordem, - ordem__lt=proximo_bloco[0].ordem, - ta_id=self.kwargs['ta_id'] - ).select_related(*DISPOSITIVO_SELECT_RELATED) - return itens - - def select_provaveis_inserts(self, request=None): - try: - if request and 'perfil_estrutural' not in request.session: - self.set_perfil_in_session(request) - - perfil_pk = request.session['perfil_estrutural'] - - # Não salvar d_base - if self.pk_edit == 0: - base = Dispositivo.objects.get(pk=self.pk_view) - else: - base = Dispositivo.objects.get(pk=self.pk_edit) - - prox_possivel = Dispositivo.objects.filter( - ordem__gt=base.ordem, - nivel__lte=base.nivel, - ta_id=base.ta_id)[:1] - - if prox_possivel.exists(): - prox_possivel = prox_possivel[0] - else: - prox_possivel = None - - 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': []} - ] - - # Possíveis inserções sequenciais já existentes - parents = base.get_parents() - parents.insert(0, base) - nivel = sys.maxsize - for dp in parents: - - if dp.nivel >= nivel: - continue - - if dp.is_relative_auto_insert(perfil_pk): - continue - - if prox_possivel and \ - dp.tipo_dispositivo != base.tipo_dispositivo and\ - dp.nivel < prox_possivel.nivel and\ - not prox_possivel.tipo_dispositivo.permitido_inserir_in( - dp.tipo_dispositivo, - perfil_pk=perfil_pk): - - if dp.tipo_dispositivo != prox_possivel.tipo_dispositivo: - continue - - nivel = dp.nivel - - # um do mesmo para inserção antes - if dp == base: - result[2]['itens'].append({ - 'class_css': dp.tipo_dispositivo.class_css, - 'tipo_pk': dp.tipo_dispositivo.pk, - 'variacao': 0, - 'provavel': '%s (%s)' % ( - dp.rotulo_padrao(local_insert=1), - dp.tipo_dispositivo.nome,), - 'dispositivo_base': base.pk}) - - if dp.dispositivo_pai: - flag_pv = dp.tipo_dispositivo.permitido_variacao( - dp.dispositivo_pai.tipo_dispositivo, - perfil_pk=perfil_pk) - else: - flag_pv = False - - r = [] - flag_direcao = 1 - flag_variacao = 0 - while True: - if dp.dispositivo0 == 0: - local_insert = 1 - else: - local_insert = 0 - - rt = dp.transform_in_next(flag_direcao) - if not rt[0]: - break - flag_variacao += rt[1] - r.append({'class_css': dp.tipo_dispositivo.class_css, - 'tipo_pk': dp.tipo_dispositivo.pk, - 'variacao': flag_variacao, - 'provavel': '%s (%s)' % ( - dp.rotulo_padrao(local_insert), - dp.tipo_dispositivo.nome,), - 'dispositivo_base': base.pk}) - - flag_direcao = -1 - - r.reverse() - - if not flag_pv: - r = [r[0], ] - - if len(r) > 0 and dp.tipo_dispositivo.formato_variacao0 == \ - TipoDispositivo.FNCN: - r = [r[0], ] - - if dp.tipo_dispositivo == 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 = base.tipo_dispositivo - - for paradentro in [1, 0]: - if paradentro: - # Outros Tipos de Dispositivos PARA DENTRO - otds = TipoDispositivo.objects.order_by( - '-contagem_continua', 'id').all() - 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']) - for c in result[1]['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').all().exclude( - class_css__in=classes_ja_inseridas) - - for td in otds: - - if paradentro and not td.permitido_inserir_in( - tipb, - include_relative_autos=False, - perfil_pk=perfil_pk): - continue - - base.tipo_dispositivo = td - - if not paradentro: - - flag_insercao = False - for possivelpai in parents: - if td.permitido_inserir_in( - possivelpai.tipo_dispositivo, - include_relative_autos=False, - perfil_pk=perfil_pk): - flag_insercao = True - break - - if not flag_insercao: - continue - - if possivelpai.is_relative_auto_insert(perfil_pk): - continue - - if prox_possivel: - if prox_possivel.nivel == base.nivel: - if prox_possivel.tipo_dispositivo != td and\ - not prox_possivel.tipo_dispositivo.\ - permitido_inserir_in( - td, perfil_pk=perfil_pk): - continue - else: - if possivelpai.tipo_dispositivo != \ - prox_possivel.tipo_dispositivo and\ - not prox_possivel.tipo_dispositivo.\ - permitido_inserir_in( - possivelpai.tipo_dispositivo, - perfil_pk=perfil_pk) and \ - possivelpai.nivel < \ - prox_possivel.nivel: - continue - base.dispositivo_pai = possivelpai - Dispositivo.set_numero_for_add_in( - possivelpai, base, td) - else: - Dispositivo.set_numero_for_add_in(base, base, td) - - r = [{'class_css': td.class_css, - 'tipo_pk': td.pk, - 'variacao': 0, - 'provavel': '%s (%s)' % ( - base.rotulo_padrao(1, paradentro), - td.nome,), - 'dispositivo_base': base.pk}] - - if paradentro == 1: - """if (tipb.class_css == 'caput' and - td.class_css == 'paragrafo'): - result[0]['itens'].insert(0, r[0]) - else:""" - result[1]['itens'] += r - else: - result[2]['itens'] += r - result[0]['itens'] += r - - # if len(result[0]['itens']) < len(result[1]['itens']): - # r = result[0] - # result.remove(result[0]) - # result.insert(1, r) - - # remover temporariamente a opção inserir antes - # confirmar necessidade - if len(result) > 2: - result.pop() - - # if tipb.dispositivo_de_articulacao and\ - # tipb.dispositivo_de_alteracao: - # result.pop() - - except Exception as e: - print(e) - - return result - - -class ActionsEditMixin: - - def render_to_json_response(self, context, **response_kwargs): - - action = getattr(self, context['action']) - return JsonResponse(action(context), safe=False) - - def set_dvt(self, context): - # Dispositivo de Vigência do Texto Original e de Dpts Alterados - dvt = Dispositivo.objects.get(pk=context['dispositivo_id']) - - if dvt.is_relative_auto_insert(): - dvt = dvt.dispositivo_pai - - try: - Dispositivo.objects.filter( - (Q(ta=dvt.ta) & Q(ta_publicado__isnull=True)) | - Q(ta_publicado=dvt.ta) - ).update( - dispositivo_vigencia=dvt, - inicio_vigencia=dvt.inicio_vigencia, - inicio_eficacia=dvt.inicio_eficacia) - - dps = Dispositivo.objects.filter(dispositivo_vigencia_id=dvt.pk, - ta_publicado_id=dvt.ta_id) - with transaction.atomic(): - for d in dps: - if d.dispositivo_substituido: - ds = d.dispositivo_substituido - ds.fim_vigencia = d.inicio_vigencia - timedelta(days=1) - ds.fim_eficacia = d.inicio_eficacia - timedelta(days=1) - d.save() - - if d.dispositivo_subsequente: - ds = d.dispositivo_subsequente - d.fim_vigencia = ds.inicio_vigencia - timedelta(days=1) - d.fim_eficacia = ds.inicio_eficacia - timedelta(days=1) - d.save() - - return {'message': str(_('Dispositivo de Vigência atualizado ' - 'com sucesso!!!'))} - except: - return {'message': str(_('Ocorreu um erro na atualização do ' - 'Dispositivo de Vigência'))} - - def delete_item_dispositivo(self, context): - return self.delete_bloco_dispositivo(context, bloco=False) - - 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 - ).first() - - data = {} - if base_anterior: - data = self.get_json_for_refresh(base_anterior) - else: - 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'] = '' - - ta_base = base.ta - - # TODO: a linha abaixo causa atualização da tela inteira... - # retirar a linha abaixo e identificar atualizações pontuais - data['pai'] = [-1, ] - - try: - with transaction.atomic(): - data['message'] = str(self.remover_dispositivo(base, bloco)) - ta_base.ordenar_dispositivos() - except Exception as e: - print(e) - data['pk'] = context['dispositivo_id'] - data['message'] = str(_('Ocorreu um erro ao ' - 'excluir esse Dispositivo')) + try: + with transaction.atomic(): + message = str(self.remover_dispositivo(base, bloco)) + if message: + self.set_message(data, 'success', message) + ta_base.ordenar_dispositivos() + except Exception as e: + data['pk'] = self.kwargs['dispositivo_id'] + self.set_message(data, 'danger', str(e)) return data @@ -1407,8 +1235,9 @@ class ActionsEditMixin: dispositivo_pai=base).first() if not anterior: - return _('Não é possível excluir este Dispositivo sem' - ' excluir toda a sua estrutura!!!') + raise Exception( + _('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 @@ -1425,9 +1254,10 @@ class ActionsEditMixin: for candidato in parents: if candidato == base: - return _('Não é possível excluir este ' - 'Dispositivo sem ' - 'excluir toda a sua estrutura!!!') + raise Exception( + _('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 @@ -1458,6 +1288,12 @@ class ActionsEditMixin: d.nivel = candidato.nivel + 1 d.rotulo = d.rotulo_padrao() break + else: + + raise Exception( + _('Não é possível excluir este ' + 'Dispositivo sem ' + 'excluir toda a sua estrutura!!!')) if not parents: d.dispositivo_pai = anterior @@ -1607,16 +1443,285 @@ class ActionsEditMixin: primeiro_a_religar = dr.dispositivo0 base.delete() - dr.dispositivo0 = ( - dr.dispositivo0 - - primeiro_a_religar + d.dispositivo0) - dr.rotulo = dr.rotulo_padrao() + dr.dispositivo0 = ( + dr.dispositivo0 - + primeiro_a_religar + d.dispositivo0) + dr.rotulo = dr.rotulo_padrao() + + dr.save(clean=base != dr) + if base.pk: + base.delete() + + return '' + + +class ActionDispositivoCreateMixin(ActionsCommonsMixin): + + def select_provaveis_inserts(self, request=None): + try: + if request and 'perfil_estrutural' not in request.session: + self.set_perfil_in_session(request) + + perfil_pk = request.session['perfil_estrutural'] + + # Não salvar d_base + if self.pk_edit == 0: + base = Dispositivo.objects.get(pk=self.pk_view) + else: + base = Dispositivo.objects.get(pk=self.pk_edit) + + prox_possivel = Dispositivo.objects.filter( + ordem__gt=base.ordem, + nivel__lte=base.nivel, + ta_id=base.ta_id)[:1] + + if prox_possivel.exists(): + prox_possivel = prox_possivel[0] + else: + prox_possivel = None + + 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': []} + ] + + # Possíveis inserções sequenciais já existentes + parents = base.get_parents() + parents.insert(0, base) + nivel = sys.maxsize + for dp in parents: + + if dp.nivel >= nivel: + continue + + if dp.is_relative_auto_insert(perfil_pk): + continue + + if prox_possivel and \ + dp.tipo_dispositivo != base.tipo_dispositivo and\ + dp.nivel < prox_possivel.nivel and\ + not prox_possivel.tipo_dispositivo.permitido_inserir_in( + dp.tipo_dispositivo, + perfil_pk=perfil_pk): + + if dp.tipo_dispositivo != prox_possivel.tipo_dispositivo: + continue + + nivel = dp.nivel + + # um do mesmo para inserção antes + if dp == base: + result[2]['itens'].append({ + 'class_css': dp.tipo_dispositivo.class_css, + 'tipo_pk': dp.tipo_dispositivo.pk, + 'variacao': 0, + 'provavel': '%s (%s)' % ( + dp.rotulo_padrao(local_insert=1), + dp.tipo_dispositivo.nome,), + 'dispositivo_base': base.pk}) + + if dp.dispositivo_pai: + flag_pv = dp.tipo_dispositivo.permitido_variacao( + dp.dispositivo_pai.tipo_dispositivo, + perfil_pk=perfil_pk) + else: + flag_pv = False + + r = [] + flag_direcao = 1 + flag_variacao = 0 + while True: + if dp.dispositivo0 == 0: + local_insert = 1 + else: + local_insert = 0 + + rt = dp.transform_in_next(flag_direcao) + if not rt[0]: + break + flag_variacao += rt[1] + r.append({'class_css': dp.tipo_dispositivo.class_css, + 'tipo_pk': dp.tipo_dispositivo.pk, + 'variacao': flag_variacao, + 'provavel': '%s (%s)' % ( + dp.rotulo_padrao(local_insert), + dp.tipo_dispositivo.nome,), + 'dispositivo_base': base.pk}) + + flag_direcao = -1 + + r.reverse() + + if not flag_pv: + r = [r[0], ] + + if len(r) > 0 and dp.tipo_dispositivo.formato_variacao0 == \ + TipoDispositivo.FNCN: + r = [r[0], ] + + if dp.tipo_dispositivo == 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 = base.tipo_dispositivo + + for paradentro in [1, 0]: + if paradentro: + # Outros Tipos de Dispositivos PARA DENTRO + otds = TipoDispositivo.objects.order_by( + '-contagem_continua', 'id').all() + 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']) + for c in result[1]['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').all().exclude( + class_css__in=classes_ja_inseridas) + + for td in otds: + + if paradentro and not td.permitido_inserir_in( + tipb, + include_relative_autos=False, + perfil_pk=perfil_pk): + continue + + base.tipo_dispositivo = td + + if not paradentro: + + flag_insercao = False + for possivelpai in parents: + if td.permitido_inserir_in( + possivelpai.tipo_dispositivo, + include_relative_autos=False, + perfil_pk=perfil_pk): + flag_insercao = True + break + + if not flag_insercao: + continue + + if possivelpai.is_relative_auto_insert(perfil_pk): + continue + + if prox_possivel: + if prox_possivel.nivel == base.nivel: + if prox_possivel.tipo_dispositivo != td and\ + not prox_possivel.tipo_dispositivo.\ + permitido_inserir_in( + td, perfil_pk=perfil_pk): + continue + else: + if possivelpai.tipo_dispositivo != \ + prox_possivel.tipo_dispositivo and\ + not prox_possivel.tipo_dispositivo.\ + permitido_inserir_in( + possivelpai.tipo_dispositivo, + perfil_pk=perfil_pk) and \ + possivelpai.nivel < \ + prox_possivel.nivel: + continue + base.dispositivo_pai = possivelpai + Dispositivo.set_numero_for_add_in( + possivelpai, base, td) + else: + Dispositivo.set_numero_for_add_in(base, base, td) + + r = [{'class_css': td.class_css, + 'tipo_pk': td.pk, + 'variacao': 0, + 'provavel': '%s (%s)' % ( + base.rotulo_padrao(1, paradentro), + td.nome,), + 'dispositivo_base': base.pk}] + + if paradentro == 1: + """if (tipb.class_css == 'caput' and + td.class_css == 'paragrafo'): + result[0]['itens'].insert(0, r[0]) + else:""" + result[1]['itens'] += r + else: + result[2]['itens'] += r + result[0]['itens'] += r + + # if len(result[0]['itens']) < len(result[1]['itens']): + # r = result[0] + # result.remove(result[0]) + # result.insert(1, r) + + # remover temporariamente a opção inserir antes + # confirmar necessidade + if len(result) > 2: + result.pop() + + # if tipb.dispositivo_de_articulacao and\ + # tipb.dispositivo_de_alteracao: + # result.pop() + + except Exception as e: + print(e) + + return result + + def set_dvt(self, context): + # Dispositivo de Vigência do Texto Original e de Dpts Alterados + dvt = Dispositivo.objects.get(pk=context['dispositivo_id']) + + if dvt.is_relative_auto_insert(): + dvt = dvt.dispositivo_pai + + try: + Dispositivo.objects.filter( + (Q(ta=dvt.ta) & Q(ta_publicado__isnull=True)) | + Q(ta_publicado=dvt.ta) + ).update( + dispositivo_vigencia=dvt, + inicio_vigencia=dvt.inicio_vigencia, + inicio_eficacia=dvt.inicio_eficacia) + + dps = Dispositivo.objects.filter(dispositivo_vigencia_id=dvt.pk, + ta_publicado_id=dvt.ta_id) + with transaction.atomic(): + for d in dps: + if d.dispositivo_substituido: + ds = d.dispositivo_substituido + ds.fim_vigencia = d.inicio_vigencia - timedelta(days=1) + ds.fim_eficacia = d.inicio_eficacia - timedelta(days=1) + d.save() - dr.save(clean=base != dr) - if base.pk: - base.delete() + if d.dispositivo_subsequente: + ds = d.dispositivo_subsequente + d.fim_vigencia = ds.inicio_vigencia - timedelta(days=1) + d.fim_eficacia = ds.inicio_eficacia - timedelta(days=1) + d.save() - return '' + return {'message': str(_('Dispositivo de Vigência atualizado ' + 'com sucesso!!!'))} + except: + return {'message': str(_('Ocorreu um erro na atualização do ' + 'Dispositivo de Vigência'))} def add_prior(self, context): return {} @@ -1877,6 +1982,240 @@ class ActionsEditMixin: return data + +class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, + ActionDeleteDispositivoMixin, + ActionDispositivoCreateMixin): + + def render_to_json_response(self, context, **response_kwargs): + + action = getattr(self, context['action']) + data = action(context) + + if 'message' in context and 'message' not in data: + data['message'] = context['message'] + + return JsonResponse(data, safe=False) + + def get_queryset_perfil_estrutural(self): + perfis = PerfilEstruturalTextoArticulado.objects.all() + return perfis + + def json_get_perfis(self, context): + + try: + if 'perfil_pk' in self.request.GET: + self.set_perfil_in_session( + self.request, self.request.GET['perfil_pk']) + elif 'perfil_estrutural' not in self.request.session: + self.set_perfil_in_session(request=self.request) + + self.object_list = self.get_queryset() + + self.perfil_estrutural_list = self.get_queryset_perfil_estrutural() + + context = self.get_context_data( + object_list=self.object_list, + perfil_estrutural_list=self.perfil_estrutural_list + ) + except Exception as e: + print(e) + + return self.render_to_response(context) + + def set_perfil_in_session(self, request=None, perfil_id=0): + if not request: + return None + + if perfil_id: + perfil = PerfilEstruturalTextoArticulado.objects.get( + pk=perfil_id) + request.session['perfil_estrutural'] = perfil.pk + return perfil.pk + else: + perfis = PerfilEstruturalTextoArticulado.objects.filter( + padrao=True)[:1] + + if not perfis.exists(): + request.session.pop('perfil_estrutural') + else: + request.session['perfil_estrutural'] = perfis[0].pk + return perfis[0].pk + return None + + +class DispositivoDinamicEditView( + CompMixin, ActionsEditMixin, TextEditView, UpdateView): + template_name = 'compilacao/text_edit_bloco.html' + model = Dispositivo + form_class = DispositivoEdicaoBasicaForm + + def get_initial(self): + initial = UpdateView.get_initial(self) + + #perfil_pk = self.set_perfil_in_session(self.request) + + if 'action' in self.request.GET: + initial.update({'editor_type': self.request.GET['action']}) + return initial + + def get(self, request, *args, **kwargs): + if 'action' not in request.GET: + self.template_name = 'compilacao/text_edit_bloco.html' + return TextEditView.get(self, request, *args, **kwargs) + + self.template_name = 'compilacao/ajax_form.html' + action = request.GET['action'] + + if action.startswith('get_form_'): + self.form_class = DispositivoEdicaoBasicaForm + context = self.get_context_data() + return self.render_to_response(context) + elif action.startswith('json_'): + context = self.get_context_data() + return self.render_to_json_response(context) + + return JsonResponse({}, safe=False) + + def post(self, request, *args, **kwargs): + + d = Dispositivo.objects.get( + pk=self.kwargs['dispositivo_id']) + + texto = request.POST['texto'] + texto_atualizador = request.POST['texto_atualizador'] + visibilidade = request.POST['visibilidade'] + + # if d.texto != '': + # d.texto = texto + # d.save() + # return self.get(request, *args, **kwargs) + d_texto = d.texto + d.texto = texto.strip() + d.texto_atualizador = texto_atualizador.strip() + d.visibilidade = not visibilidade or visibilidade == 'True' + d.save() + + if texto != '' and d.ta_id == int(self.kwargs['ta_id']): + dnext = Dispositivo.objects.filter( + ta_id=d.ta_id, + ordem__gt=d.ordem, + texto='', + tipo_dispositivo__dispositivo_de_articulacao=False)[:1] + + if not dnext.exists(): + dnext = [] + dnext.append(d) + pais = [d.dispositivo_pai_id, ] + else: + + if dnext[0].nivel > d.nivel: + pais = [d.pk, ] + else: + if dnext[0].dispositivo_pai_id == d.dispositivo_pai_id: + pais = [dnext[0].dispositivo_pai_id, ] + else: + pais = [ + dnext[0].dispositivo_pai_id, + d.dispositivo_pai_id] + + data = {'pk': dnext[0].pk + if not d_texto else 0, 'pai': pais} + elif d.ta_id != int(self.kwargs['ta_id']): + data = {'pk': 0, + 'pai': [d.dispositivo_atualizador_id, ]} + else: + data = {'pk': d.pk + if not d_texto or not d.texto else 0, 'pai': [d.pk, ]} + + self.set_message(data, 'success', str( + _('Dispositivo alterado com sucesso.'))) + + return JsonResponse(data, safe=False) + + +class DispositivoSimpleEditView__Old: + template_name = 'compilacao/text_edit_bloco.html' + + def get_queryset_perfil_estrutural(self): + perfis = PerfilEstruturalTextoArticulado.objects.all() + return perfis + + def get(self, request, *args, **kwargs): + + try: + if 'perfil_pk' in request.GET: + self.set_perfil_in_session( + request, request.GET['perfil_pk']) + elif 'perfil_estrutural' not in request.session: + self.set_perfil_in_session(request=request) + + self.object_list = self.get_queryset() + + self.perfil_estrutural_list = self.get_queryset_perfil_estrutural() + + context = self.get_context_data( + object_list=self.object_list, + perfil_estrutural_list=self.perfil_estrutural_list + ) + except Exception as e: + print(e) + + return self.render_to_response(context) + + def get_queryset(self): + self.flag_alteradora = -1 + self.flag_nivel_ini = 0 + self.flag_nivel_old = -1 + + try: + self.pk_edit = int(self.request.GET['edit']) + except: + self.pk_edit = 0 + self.pk_view = int(self.kwargs['dispositivo_id']) + + try: + if self.pk_edit == 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_edit == self.pk_view: + return [bloco, ] + + proximo_bloco = Dispositivo.objects.filter( + ordem__gt=bloco.ordem, + nivel__lte=bloco.nivel, + ta_id=self.kwargs['ta_id'])[:1] + + if proximo_bloco.count() == 0: + itens = Dispositivo.objects.filter( + ordem__gte=bloco.ordem, + ta_id=self.kwargs['ta_id'] + ).select_related(*DISPOSITIVO_SELECT_RELATED) + else: + itens = Dispositivo.objects.filter( + ordem__gte=bloco.ordem, + ordem__lt=proximo_bloco[0].ordem, + ta_id=self.kwargs['ta_id'] + ).select_related(*DISPOSITIVO_SELECT_RELATED) + return itens + + +class ActionsEditMixin_old: + + def render_to_json_response(self, context, **response_kwargs): + + action = getattr(self, context['action']) + return JsonResponse(action(context), safe=False) + def get_json_for_refresh(self, dp, dpauto=None): if dp.tipo_dispositivo.contagem_continua: @@ -1915,51 +2254,8 @@ class ActionsEditMixin: return data - def move_dpt_alterado(self, context): - - bloco = Dispositivo.objects.get(pk=context['bloco_pk']) - dpt = Dispositivo.objects.get(pk=context['dispositivo_id']) - - if dpt.tipo_dispositivo.dispositivo_de_alteracao: - dpt.dispositivo_pai = bloco - else: - dpt.dispositivo_atualizador = bloco - - filhos = Dispositivo.objects.order_by( - 'ordem_bloco_atualizador').filter( - Q(dispositivo_pai_id=bloco.pk) | - Q(dispositivo_atualizador_id=bloco.pk)) - - if not filhos.exists(): - dpt.ordem_bloco_atualizador = Dispositivo.INTERVALO_ORDEM - else: - index = int(context['index']) - fpks = filhos.values_list( - 'pk', flat=True).order_by('ordem_bloco_atualizador') - - index_dpt = 0 - try: - index_dpt = list(fpks).index(dpt.pk) - except: - pass - - filho_index = filhos[ - index if index_dpt >= index - else index + 1] if ( - index if index_dpt >= index - else index + 1) < filhos.count() else filhos.last() - if filhos.last() == filho_index: - dpt.ordem_bloco_atualizador = \ - filho_index.ordem_bloco_atualizador + 1 - else: - dpt.ordem_bloco_atualizador = \ - filho_index.ordem_bloco_atualizador - 1 - - dpt.save() - bloco.ordenar_bloco_alteracao() - -class ActionsEditView(ActionsEditMixin, TemplateView): +class ActionsEditView_Old(ActionsEditMixin, TemplateView): def render_to_response(self, context, **response_kwargs): context['action'] = self.request.GET['action'] @@ -1977,7 +2273,7 @@ class ActionsEditView(ActionsEditMixin, TemplateView): del self.request.session['herancas'] del self.request.session['herancas_fila'] - if context['action'] == 'move_dpt_alterado': + if context['action'] == 'drag_move_dpt_alterado': context['index'] = self.request.GET['index'] context['bloco_pk'] = self.request.GET['bloco_pk'] @@ -2177,7 +2473,7 @@ class DispositivoSearchModalView(FormView): form_class = DispositivoSearchModalForm -class DispositivoEdicaoBasicaView(FormMessagesMixin, UpdateView): +class DispositivoEdicaoBasicaView(CompMixin, FormMessagesMixin, UpdateView): model = Dispositivo template_name = 'compilacao/dispositivo_form_edicao_basica.html' form_class = DispositivoEdicaoBasicaForm @@ -2249,7 +2545,7 @@ class DispositivoEdicaoBasicaView(FormMessagesMixin, UpdateView): return UpdateView.get(self, request, *args, **kwargs) -class DispositivoEdicaoVigenciaView(FormMessagesMixin, UpdateView): +class DispositivoEdicaoVigenciaView(CompMixin, FormMessagesMixin, UpdateView): model = Dispositivo template_name = 'compilacao/dispositivo_form_vigencia.html' form_class = DispositivoEdicaoVigenciaForm @@ -2272,7 +2568,7 @@ class DispositivoEdicaoVigenciaView(FormMessagesMixin, UpdateView): kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']}) -class DispositivoDefinidorVigenciaView(FormMessagesMixin, FormView): +class DispositivoDefinidorVigenciaView(CompMixin, FormMessagesMixin, FormView): model = Dispositivo template_name = 'compilacao/dispositivo_form_definidor_vigencia.html' form_class = DispositivoDefinidorVigenciaForm @@ -2329,7 +2625,7 @@ class DispositivoDefinidorVigenciaView(FormMessagesMixin, FormView): return self.form_invalid(form) -class DispositivoEdicaoAlteracaoView(FormMessagesMixin, UpdateView): +class DispositivoEdicaoAlteracaoView(CompMixin, FormMessagesMixin, UpdateView): model = Dispositivo template_name = 'compilacao/dispositivo_form_alteracao.html' form_class = DispositivoEdicaoAlteracaoForm @@ -2359,13 +2655,13 @@ class DispositivoEdicaoAlteracaoView(FormMessagesMixin, UpdateView): try: with transaction.atomic(): return self.form_valid(form) - except: + except Exception as e: return self.form_invalid(form) else: return self.form_invalid(form) -class TextNotificacoesView(ListView, CompMixin, FormView): +class TextNotificacoesView(CompMixin, ListView, FormView): template_name = 'compilacao/text_notificacoes.html' form_class = TextNotificacoesForm @@ -2567,6 +2863,18 @@ class TextNotificacoesView(ListView, CompMixin, FormView): _('Dispositivo está substituindo um Dispositivo de outro ' 'Texto Articulado.')) + padd(r, type_notificacao, 'compilacao:dispositivo_edit_alteracao', + r.dispositivo_substituido and + r.dispositivo_substituido.dispositivo_subsequente != r, + _('Dispositivo está substituindo um Dispositivo que não ' + 'possui este como seu Dispositivo Subsequente.')) + + padd(r, type_notificacao, 'compilacao:dispositivo_edit_alteracao', + r.dispositivo_subsequente and + r.dispositivo_subsequente.dispositivo_substituido != r, + _('Dispositivo foi substituído por outro que não ' + 'possui este como seu Dispositivo Substituído.')) + rr = [] for r in result: p = [] diff --git a/sapl/templates/compilacao/dispositivo_form.html b/sapl/templates/compilacao/dispositivo_form.html index 3bff729b3..caa60db4b 100644 --- a/sapl/templates/compilacao/dispositivo_form.html +++ b/sapl/templates/compilacao/dispositivo_form.html @@ -23,16 +23,37 @@ {% endblock%} {% block base_content %}
+
+ + {% trans "Articulações" %} + + + +
{%for parent in object.get_parents_asc %} {%with node=parent active=False template_name='compilacao/dispositivo_form_parents.html' %} {%include template_name%} {%endwith%} {%endfor %} - {%with node=object active=True template_name='compilacao/dispositivo_form_parents.html' %} {%include template_name%} {%endwith%}
+
+ {%if object.ta_publicado_id %} + + {{ object.tipo_dispositivo.nota_automatica_prefixo_html|safe }} + {% nota_automatica object None %} + {{ object.tipo_dispositivo.nota_automatica_sufixo_html|safe }} + {%endif%}

{% crispy form %} {% endblock %} diff --git a/sapl/templates/compilacao/dispositivo_form_parents.html b/sapl/templates/compilacao/dispositivo_form_parents.html index c2f5f3e34..167671a4b 100644 --- a/sapl/templates/compilacao/dispositivo_form_parents.html +++ b/sapl/templates/compilacao/dispositivo_form_parents.html @@ -4,28 +4,25 @@ {{node|nomenclatura}} -{% else %} +{% else %} - {% endif %} diff --git a/sapl/templates/compilacao/dispositivo_form_search.html b/sapl/templates/compilacao/dispositivo_form_search.html index 4a7732446..9bcb1cba2 100644 --- a/sapl/templates/compilacao/dispositivo_form_search.html +++ b/sapl/templates/compilacao/dispositivo_form_search.html @@ -5,14 +5,14 @@ diff --git a/sapl/templates/compilacao/layout/dispositivo_radio.html b/sapl/templates/compilacao/layout/dispositivo_radio.html index e95e3a451..1e0a8d430 100644 --- a/sapl/templates/compilacao/layout/dispositivo_radio.html +++ b/sapl/templates/compilacao/layout/dispositivo_radio.html @@ -18,7 +18,7 @@
{% if dpt.nivel > 1 %} - {% trans "Herança:" %} {% heranca request dpt 1 0 %} + {% trans "Herança:" %} {% heranca request dpt 0 0 %} {% endif %}
@@ -29,6 +29,18 @@ 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 %} {% endif %}{% endif %} + {% if dpt.ta_publicado_id and not dpt.tipo_dispositivo.dispositivo_de_articulacao %} + + {{ dpt.tipo_dispositivo.nota_automatica_prefixo_html|safe }} + {% nota_automatica dpt ta_pub_list %} + {{ dpt.tipo_dispositivo.nota_automatica_sufixo_html|safe }} + + {% else %} + + + {% endif %}
diff --git a/sapl/templates/compilacao/text_edit.html b/sapl/templates/compilacao/text_edit.html index f1793c6e0..a92cfae96 100644 --- a/sapl/templates/compilacao/text_edit.html +++ b/sapl/templates/compilacao/text_edit.html @@ -11,7 +11,7 @@ {% endblock %} {% block title%} -

Edição: {{ view.title }} - {% trans 'Texto Multivigente' %}

+

{{object }}. {% trans 'Texto Multivigente em Edição' %}

{% endblock %} {% block actions %} @@ -19,20 +19,23 @@ {% endblock actions %} {% block base_content %}{{block.super}} -
{% trans 'Aguarde... Atualizando informações!!!'%}
+
{% trans 'Aguarde... Atualizando informações!!!'%}
+ +
+
+