Sistema de Apoio ao Processo Legislativo
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

2293 lines
81 KiB

import sys
from collections import OrderedDict
from datetime import datetime, timedelta
from braces.views import FormMessagesMixin
from django import forms
from django.contrib.auth.decorators import login_required
from django.contrib.contenttypes.models import ContentType
from django.core.signing import Signer
from django.core.urlresolvers import reverse_lazy
from django.db import transaction
from django.db.models import Q
from django.http.response import (HttpResponse, HttpResponseRedirect,
JsonResponse)
from django.shortcuts import get_object_or_404, redirect
from django.utils.dateparse import parse_date
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView
from django.views.generic.detail import DetailView
from django.views.generic.edit import (CreateView, DeleteView, FormView,
UpdateView)
from django.views.generic.list import ListView
from compilacao.forms import (DispositivoDefinidorVigenciaForm,
DispositivoEdicaoAlteracaoForm,
DispositivoEdicaoBasicaForm,
DispositivoEdicaoVigenciaForm,
DispositivoSearchModalForm, NotaForm,
PublicacaoForm, TaForm, TipoTaForm, VideForm)
from compilacao.models import (Dispositivo, Nota,
PerfilEstruturalTextoArticulado, Publicacao,
TextoArticulado, TipoDispositivo, TipoNota,
TipoPublicacao, TipoTextoArticulado, TipoVide,
VeiculoPublicacao, Vide)
from compilacao.utils import DISPOSITIVO_SELECT_RELATED
from 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 IntegracaoTaView(TemplateView):
def get(self, *args, **kwargs):
item = get_object_or_404(self.model, pk=kwargs['pk'])
related_object_type = ContentType.objects.get_for_model(item)
ta = TextoArticulado.objects.filter(
object_id=item.pk,
content_type=related_object_type)
if not ta.exists():
ta = TextoArticulado()
tipo_ta = TipoTextoArticulado.objects.filter(
content_type=related_object_type)[:1]
if tipo_ta.exists():
ta.tipo_ta = tipo_ta[0]
ta.content_object = item
else:
ta = ta[0]
if hasattr(item, 'ementa') and item.ementa:
ta.ementa = item.ementa
else:
ta.ementa = _('Integração com %s sem ementa.') % item
if hasattr(item, 'observacao') and item.observacao:
ta.observacao = item.observacao
else:
ta.observacao = _('Integração com %s sem observacao.') % item
if hasattr(item, 'numero') and item.numero:
ta.numero = item.numero
else:
ta.numero = int('%s%s%s' % (
int(datetime.now().year),
int(datetime.now().month),
int(datetime.now().day)))
if hasattr(item, 'ano') and item.ano:
ta.ano = item.ano
else:
ta.ano = datetime.now().year
if hasattr(item, 'data_apresentacao'):
ta.data = item.data_apresentacao
elif hasattr(item, 'data'):
ta.data = item.data
else:
ta.data = datetime.now()
ta.save()
return redirect(to=reverse_lazy('compilacao:ta_text',
kwargs={'ta_id': ta.pk}))
class Meta:
abstract = True
def get_integrations_view_names():
result = []
modules = sys.modules
for key, value in modules.items():
if key.endswith('.views'):
for v in value.__dict__.values():
if hasattr(v, '__bases__'):
for base in v.__bases__:
if base == IntegracaoTaView:
result.append(v)
return result
def choice_models_in_extenal_views():
integrations_view_names = get_integrations_view_names()
result = [(None, '-------------'), ]
for item in integrations_view_names:
if hasattr(item, 'model') and hasattr(item, 'model_type_foreignkey'):
ct = ContentType.objects.filter(
model=item.model.__name__.lower(),
app_label=item.model._meta.app_label)
if ct.exists():
result.append((
ct[0].pk,
item.model._meta.verbose_name_plural))
return result
class CompMixin:
@property
def title(self):
try:
return self.get_object()
except:
return self.object
class TipoTaListView(ListView):
model = TipoTextoArticulado
paginate_by = 10
verbose_name = model._meta.verbose_name
@property
def title(self):
return self.model._meta.verbose_name_plural
@property
def create_url(self):
return reverse_lazy('compilacao:tipo_ta_create')
class TipoTaCreateView(FormMessagesMixin, CreateView):
model = TipoTextoArticulado
form_class = TipoTaForm
template_name = "crud/form.html"
form_valid_message = _('Registro criado com sucesso!')
form_invalid_message = _('O registro não foi criado.')
def get(self, request, *args, **kwargs):
self.object = None
form = self.get_form()
form.fields['content_type'] = forms.ChoiceField(
choices=choice_models_in_extenal_views(),
label=_('Modelo Integrado'), required=False)
return self.render_to_response(self.get_context_data(form=form))
def get_success_url(self):
return reverse_lazy('compilacao:tipo_ta_detail',
kwargs={'pk': self.object.id})
@property
def cancel_url(self):
return reverse_lazy('compilacao:tipo_ta_list')
class TipoTaDetailView(CompMixin, DetailView):
model = TipoTextoArticulado
class TipoTaUpdateView(CompMixin, UpdateView):
model = TipoTextoArticulado
form_class = TipoTaForm
template_name = "crud/form.html"
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
form.fields['content_type'] = forms.ChoiceField(
choices=choice_models_in_extenal_views(),
label=_('Modelo Integrado'), required=False)
return self.render_to_response(self.get_context_data(form=form))
def get_success_url(self):
return reverse_lazy('compilacao:tipo_ta_detail',
kwargs={'pk': self.kwargs['pk']})
@property
def cancel_url(self):
return reverse_lazy('compilacao:tipo_ta_detail',
kwargs={'pk': self.kwargs['pk']})
class TipoTaDeleteView(CompMixin, DeleteView):
model = TipoTextoArticulado
template_name = "crud/confirm_delete.html"
@property
def detail_url(self):
return reverse_lazy('compilacao:tipo_ta_detail',
kwargs={'pk': self.kwargs['pk']})
def get_success_url(self):
return reverse_lazy('compilacao:tipo_ta_list')
class TaListView(ListView):
model = TextoArticulado
paginate_by = 10
verbose_name = model._meta.verbose_name
@property
def title(self):
return self.model._meta.verbose_name_plural
@property
def create_url(self):
return reverse_lazy('compilacao:ta_create')
def get_context_data(self, **kwargs):
context = super(TaListView, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
return context
class TaDetailView(DetailView):
model = TextoArticulado
@property
def title(self):
if self.get_object().content_object:
return _(
'Metadados para o Texto Articulado de %s\n'
'<small>%s</small>') % (
self.get_object().content_object._meta.verbose_name_plural,
self.get_object().content_object)
else:
return self.get_object()
class TaCreateView(FormMessagesMixin, CreateView):
model = TextoArticulado
form_class = TaForm
template_name = "crud/form.html"
form_valid_message = _('Registro criado com sucesso!')
form_invalid_message = _('O registro não foi criado.')
def get_success_url(self):
return reverse_lazy('compilacao:ta_detail',
kwargs={'pk': self.object.id})
@property
def cancel_url(self):
return reverse_lazy('compilacao:ta_list')
class TaUpdateView(CompMixin, UpdateView):
model = TextoArticulado
form_class = TaForm
template_name = "crud/form.html"
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
# if self.object and self.object.content_object:
# form.fields['tipo_ta'].required = False
# form.fields['tipo_ta'].widget.attrs['disabled'] = 'disabled'
return self.render_to_response(self.get_context_data(form=form))
def get_success_url(self):
return reverse_lazy('compilacao:ta_detail',
kwargs={'pk': self.kwargs['pk']})
@property
def cancel_url(self):
return reverse_lazy('compilacao:ta_detail',
kwargs={'pk': self.kwargs['pk']})
class TaDeleteView(CompMixin, DeleteView):
model = TextoArticulado
template_name = "crud/confirm_delete.html"
@property
def detail_url(self):
return reverse_lazy('compilacao:ta_detail',
kwargs={'pk': self.kwargs['pk']})
def get_success_url(self):
return reverse_lazy('compilacao:ta_list')
class DispositivoSuccessUrlMixin:
def get_success_url(self):
return reverse_lazy(
'compilacao:dispositivo', kwargs={
'ta_id': self.kwargs[
'ta_id'],
'dispositivo_id': self.kwargs[
'dispositivo_id']})
class NotaMixin(DispositivoSuccessUrlMixin):
def get_modelo_nota(self, request):
if 'action' in request.GET and request.GET['action'] == 'modelo_nota':
tn = TipoNota.objects.get(pk=request.GET['id_tipo'])
return True, tn.modelo
return False, ''
def get_initial(self):
dispositivo = get_object_or_404(
Dispositivo, pk=self.kwargs.get('dispositivo_id'))
initial = {'dispositivo': dispositivo}
if 'pk' in self.kwargs:
initial['pk'] = self.kwargs.get('pk')
return initial
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(NotaMixin, self).dispatch(*args, **kwargs)
class NotasCreateView(NotaMixin, CreateView):
template_name = 'compilacao/ajax_form.html'
form_class = NotaForm
def get(self, request, *args, **kwargs):
flag_action, modelo_nota = self.get_modelo_nota(request)
if flag_action:
return HttpResponse(modelo_nota)
return super(NotasCreateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = None
try:
ta_id = kwargs.pop('ta_id')
dispositivo_id = kwargs.pop('dispositivo_id')
form = NotaForm(request.POST, request.FILES, **kwargs)
kwargs['ta_id'] = ta_id
kwargs['dispositivo_id'] = dispositivo_id
if form.is_valid():
nt = form.save(commit=False)
nt.owner_id = request.user.pk
nt.save()
self.kwargs['pk'] = nt.pk
return self.form_valid(form)
else:
return self.form_invalid(form)
except Exception as e:
print(e)
return HttpResponse("error post")
class NotasEditView(NotaMixin, UpdateView):
model = Nota
template_name = 'compilacao/ajax_form.html'
form_class = NotaForm
def get(self, request, *args, **kwargs):
flag_action, modelo_nota = self.get_modelo_nota(request)
if flag_action:
return HttpResponse(modelo_nota)
return super(NotasEditView, self).get(request, *args, **kwargs)
class NotasDeleteView(NotaMixin, TemplateView):
def get(self, request, *args, **kwargs):
nt = Nota.objects.get(pk=self.kwargs['pk'])
nt.delete()
return HttpResponseRedirect(self.get_success_url())
class VideMixin(DispositivoSuccessUrlMixin):
def get_initial(self):
dispositivo_base = get_object_or_404(
Dispositivo, pk=self.kwargs.get('dispositivo_id'))
initial = {'dispositivo_base': dispositivo_base, }
if 'pk' in self.kwargs:
initial['pk'] = self.kwargs.get('pk')
return initial
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(VideMixin, self).dispatch(*args, **kwargs)
def choice_model_type_foreignkey_in_extenal_views(id_tipo_ta=None):
yield None, '-------------'
if not id_tipo_ta:
return
tipo_ta = TipoTextoArticulado.objects.get(pk=id_tipo_ta)
integrations_view_names = get_integrations_view_names()
for item in integrations_view_names:
if hasattr(item, 'model_type_foreignkey'):
if (tipo_ta.content_type.model == item.model.__name__.lower() and
tipo_ta.content_type.app_label ==
item.model._meta.app_label):
for i in item.model_type_foreignkey.objects.all():
yield i.pk, i
class VideCreateView(VideMixin, CreateView):
model = Vide
template_name = 'compilacao/ajax_form.html'
form_class = VideForm
def get(self, request, *args, **kwargs):
self.object = None
form = self.get_form()
return self.render_to_response(self.get_context_data(form=form))
"""
def get_form_kwargs(self):
kwargs = super(VideCreateView, self).get_form_kwargs()
if 'choice_model_type_foreignkey_in_extenal_views' not in kwargs:
kwargs.update({
'choice_model_type_foreignkey_in_extenal_views':
choice_model_type_foreignkey_in_extenal_views
})
return kwargs"""
class VideEditView(VideMixin, UpdateView):
model = Vide
template_name = 'compilacao/ajax_form.html'
form_class = VideForm
class VideDeleteView(VideMixin, TemplateView):
def get(self, request, *args, **kwargs):
vd = Vide.objects.get(pk=self.kwargs['pk'])
vd.delete()
return HttpResponseRedirect(self.get_success_url())
class PublicacaoListView(ListView):
model = Publicacao
verbose_name = model._meta.verbose_name
@property
def title(self):
return _('%s de %s' % (
self.model._meta.verbose_name_plural,
self.ta))
@property
def ta(self):
ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id'])
return ta
@property
def create_url(self):
return reverse_lazy(
'compilacao:ta_pub_create',
kwargs={'ta_id': self.kwargs['ta_id']})
def get_queryset(self):
pubs = Publicacao.objects.filter(ta_id=self.kwargs['ta_id'])
return pubs
def get_context_data(self, **kwargs):
context = super(PublicacaoListView, self).get_context_data(**kwargs)
context['NO_ENTRIES_MSG'] = CrudListView.no_entries_msg
return context
class PublicacaoCreateView(FormMessagesMixin, CreateView):
model = Publicacao
form_class = PublicacaoForm
template_name = "crud/form.html"
form_valid_message = _('Registro criado com sucesso!')
form_invalid_message = _('O registro não foi criado.')
def get_success_url(self):
return reverse_lazy(
'compilacao:ta_pub_detail',
kwargs={
'pk': self.object.id,
'ta_id': self.kwargs['ta_id']})
@property
def cancel_url(self):
return reverse_lazy(
'compilacao:ta_pub_list',
kwargs={'ta_id': self.kwargs['ta_id']})
def get_initial(self):
return {'ta': self.kwargs['ta_id']}
class PublicacaoDetailView(CompMixin, DetailView):
model = Publicacao
class PublicacaoUpdateView(CompMixin, UpdateView):
model = Publicacao
form_class = PublicacaoForm
template_name = "crud/form.html"
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
# if self.object and self.object.content_object:
# form.fields['tipo_ta'].required = False
# form.fields['tipo_ta'].widget.attrs['disabled'] = 'disabled'
return self.render_to_response(self.get_context_data(form=form))
def get_success_url(self):
return reverse_lazy('compilacao:ta_pub_detail',
kwargs={
'pk': self.object.id,
'ta_id': self.kwargs['ta_id']})
@property
def cancel_url(self):
return self.get_success_url()
class PublicacaoDeleteView(CompMixin, DeleteView):
model = Publicacao
template_name = "crud/confirm_delete.html"
@property
def detail_url(self):
return reverse_lazy('compilacao:ta_pub_detail',
kwargs={
'pk': self.object.id,
'ta_id': self.kwargs['ta_id']})
def get_success_url(self):
return reverse_lazy('compilacao:ta_pub_list',
kwargs={'ta_id': self.kwargs['ta_id']})
class TextView(ListView, CompMixin):
template_name = 'compilacao/text_list.html'
flag_alteradora = -1
flag_nivel_ini = 0
flag_nivel_old = -1
itens_de_vigencia = {}
inicio_vigencia = None
fim_vigencia = None
ta_vigencia = None
def get(self, request, *args, **kwargs):
ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id'])
self.object = ta
if ta.content_object:
item = ta.content_object
self.object = item
if hasattr(item, 'ementa') and item.ementa:
ta.ementa = item.ementa
else:
ta.ementa = _('Integração com %s sem ementa.') % item
if hasattr(item, 'observacao') and item.observacao:
ta.observacao = item.observacao
else:
ta.observacao = _('Integração com %s sem observacao.') % item
if hasattr(item, 'numero') and item.numero:
ta.numero = item.numero
else:
ta.numero = int('%s%s%s' % (
int(datetime.now().year),
int(datetime.now().month),
int(datetime.now().day)))
if hasattr(item, 'ano') and item.ano:
ta.ano = item.ano
else:
ta.ano = datetime.now().year
if hasattr(item, 'data_apresentacao'):
ta.data = item.data_apresentacao
elif hasattr(item, 'data'):
ta.data = item.data
else:
ta.data = datetime.now()
ta.save()
return super(TextView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(TextView, self).get_context_data(**kwargs)
context['object'] = TextoArticulado.objects.get(
pk=self.kwargs['ta_id'])
cita = Vide.objects.filter(
Q(dispositivo_base__ta_id=self.kwargs['ta_id'])).\
select_related(
'dispositivo_ref',
'dispositivo_ref__ta',
'dispositivo_ref__dispositivo_pai',
'dispositivo_ref__dispositivo_pai__ta', 'tipo')
context['cita'] = {}
for c in cita:
if c.dispositivo_base_id not in context['cita']:
context['cita'][c.dispositivo_base_id] = []
context['cita'][c.dispositivo_base_id].append(c)
citado = Vide.objects.filter(
Q(dispositivo_ref__ta_id=self.kwargs['ta_id'])).\
select_related(
'dispositivo_base',
'dispositivo_base__ta',
'dispositivo_base__dispositivo_pai',
'dispositivo_base__dispositivo_pai__ta', 'tipo')
context['citado'] = {}
for c in citado:
if c.dispositivo_ref_id not in context['citado']:
context['citado'][c.dispositivo_ref_id] = []
context['citado'][c.dispositivo_ref_id].append(c)
notas = Nota.objects.filter(
dispositivo__ta_id=self.kwargs['ta_id']).select_related(
'owner', 'tipo')
context['notas'] = {}
for n in notas:
if n.dispositivo_id not in context['notas']:
context['notas'][n.dispositivo_id] = []
context['notas'][n.dispositivo_id].append(n)
tas_pub = [d.ta_publicado for d in self.object_list if d.ta_publicado]
tas_pub = set(tas_pub)
ta_pub_list = {}
for ta in tas_pub:
ta_pub_list[ta.pk] = str(ta)
context['ta_pub_list'] = ta_pub_list
# context['vigencias'] = self.get_vigencias()
return context
def get_queryset(self):
self.flag_alteradora = -1
self.flag_nivel_ini = 0
self.flag_nivel_old = -1
self.inicio_vigencia = None
self.fim_vigencia = None
self.ta_vigencia = None
if 'sign' in self.kwargs:
signer = Signer()
try:
string = signer.unsign(self.kwargs['sign']).split(',')
self.ta_vigencia = int(string[0])
self.inicio_vigencia = parse_date(string[1])
self.fim_vigencia = parse_date(string[2])
except:
return Dispositivo.objects.filter(
ordem__gt=0,
ta_id=self.kwargs['ta_id'],
).select_related(*DISPOSITIVO_SELECT_RELATED)
return Dispositivo.objects.filter(
inicio_vigencia__lte=self.fim_vigencia,
ordem__gt=0,
ta_id=self.kwargs['ta_id'],
).select_related(*DISPOSITIVO_SELECT_RELATED)
else:
r = Dispositivo.objects.filter(
ordem__gt=0,
ta_id=self.kwargs['ta_id'],
).select_related(*DISPOSITIVO_SELECT_RELATED)
return r
def get_vigencias(self):
itens = Dispositivo.objects.filter(
ta_id=self.kwargs['ta_id'],
).order_by(
'inicio_vigencia'
).distinct(
'inicio_vigencia'
).select_related(
'ta_publicado',
'ta',
'ta_publicado__tipo_ta',
'ta__tipo_ta',)
ajuste_datas_vigencia = []
for item in itens:
ajuste_datas_vigencia.append(item)
lenLista = len(ajuste_datas_vigencia)
for i in range(lenLista):
if i + 1 < lenLista:
ajuste_datas_vigencia[
i].fim_vigencia = ajuste_datas_vigencia[
i + 1].inicio_vigencia - timedelta(days=1)
else:
ajuste_datas_vigencia[i].fim_vigencia = None
self.itens_de_vigencia = {}
idx = -1
length = len(ajuste_datas_vigencia)
for item in ajuste_datas_vigencia:
idx += 1
if idx == 0:
self.itens_de_vigencia[0] = [item, ]
continue
if idx + 1 < length:
ano = item.ta_publicado.ano if item.ta_publicado else\
item.ta.ano
if ano in self.itens_de_vigencia:
self.itens_de_vigencia[ano].append(item)
else:
self.itens_de_vigencia[ano] = [item, ]
else:
self.itens_de_vigencia[9999] = [item, ]
if len(self.itens_de_vigencia.keys()) <= 1:
return {}
self.itens_de_vigencia = OrderedDict(
sorted(self.itens_de_vigencia.items(), key=lambda t: t[0]))
return self.itens_de_vigencia
def is_ta_alterador(self):
if self.flag_alteradora == -1:
self.flag_alteradora = Dispositivo.objects.select_related(
'dispositivos_alterados_pelo_texto_articulado_set'
).filter(ta_id=self.kwargs['ta_id']).count()
return self.flag_alteradora > 0
class DispositivoView(TextView):
# template_name = 'compilacao/index.html'
template_name = 'compilacao/text_list_bloco.html'
def get_queryset(self):
self.flag_alteradora = -1
self.flag_nivel_ini = 0
self.flag_nivel_old = -1
try:
bloco = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id'])
except Dispositivo.DoesNotExist:
return []
self.flag_nivel_old = bloco.nivel - 1
self.flag_nivel_ini = bloco.nivel
proximo_bloco = Dispositivo.objects.filter(
ordem__gt=bloco.ordem,
nivel__lte=bloco.nivel,
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 TextEditView(ListView, CompMixin):
template_name = 'compilacao/text_edit.html'
flag_alteradora = -1
flag_nivel_ini = 0
flag_nivel_old = -1
pk_edit = 0
pk_view = 0
def get(self, request, *args, **kwargs):
return ListView.get(self, request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(TextEditView, self).get_context_data(**kwargs)
ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id'])
self.object = ta
context['object'] = self.object
tas_pub = [d.ta_publicado for d in self.object_list if d.ta_publicado]
tas_pub = set(tas_pub)
ta_pub_list = {}
for ta in tas_pub:
ta_pub_list[ta.pk] = str(ta)
context['ta_pub_list'] = ta_pub_list
return context
def get_queryset(self):
self.pk_edit = 0
self.pk_view = 0
self.flag_alteradora = -1
self.flag_nivel_ini = 0
self.flag_nivel_old = -1
result = Dispositivo.objects.filter(
ta_id=self.kwargs['ta_id']
).select_related(*DISPOSITIVO_SELECT_RELATED)
if not result.exists():
ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id'])
td = TipoDispositivo.objects.filter(class_css='articulacao')[0]
a = Dispositivo()
a.nivel = 0
a.ordem = Dispositivo.INTERVALO_ORDEM
a.ordem_bloco_atualizador = 0
a.set_numero_completo([1, 0, 0, 0, 0, 0, ])
a.ta = ta
a.tipo_dispositivo = td
a.inicio_vigencia = ta.data
a.inicio_eficacia = ta.data
a.save()
td = TipoDispositivo.objects.filter(class_css='ementa')[0]
e = Dispositivo()
e.nivel = 1
e.ordem = a.ordem + Dispositivo.INTERVALO_ORDEM
e.ordem_bloco_atualizador = 0
e.set_numero_completo([1, 0, 0, 0, 0, 0, ])
e.ta = ta
e.tipo_dispositivo = td
e.inicio_vigencia = ta.data
e.inicio_eficacia = ta.data
e.texto = ta.ementa
e.dispositivo_pai = a
e.save()
a.pk = None
a.nivel = 0
a.ordem = e.ordem + Dispositivo.INTERVALO_ORDEM
a.ordem_bloco_atualizador = 0
a.set_numero_completo([2, 0, 0, 0, 0, 0, ])
a.save()
result = Dispositivo.objects.filter(
ta_id=self.kwargs['ta_id']
).select_related(*DISPOSITIVO_SELECT_RELATED)
return result
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
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
class DispositivoSimpleEditView(TextEditView):
template_name = 'compilacao/text_edit_bloco.html'
def post(self, request, *args, **kwargs):
d = Dispositivo.objects.get(
pk=self.kwargs['dispositivo_id'])
texto = request.POST['texto']
if d.texto != '':
d.texto = texto
d.save()
return self.get(request, *args, **kwargs)
d.texto = texto.strip()
d.save()
if texto != '':
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, 'pai': pais}
else:
data = {'pk': d.pk, 'pai': [d.pk, ]}
return JsonResponse(data, safe=False)
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
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': '&#8631;&nbsp;',
'action': 'add_next',
'itens': []},
{'tipo_insert': _('Inserir Dentro'),
'icone': '&#8690;&nbsp;',
'action': 'add_in',
'itens': []},
{'tipo_insert': _('Inserir Antes'),
'icone': '&#8630;&nbsp;',
'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 falta de necessidade
if len(result) > 2:
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.organizar_ordem_de_dispositivos()
except Exception as e:
print(e)
data['pk'] = context['dispositivo_id']
data['message'] = str(_('Ocorreu um erro ao '
'excluir esse Dispositivo'))
return data
def remover_dispositivo(self, base, bloco):
base_ordem = base.ordem
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.is_relative_auto_insert():
self.remover_dispositivo(d, bloco)
elif not bloco:
p.dispositivos_filhos_set.add(d)
p.save()
base.delete()
else:
proxima_articulacao = base.get_proximo_nivel_zero()
if not bloco:
# tranferir filhos para primeiro pai possível acima da base
# de exclusão
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
""" TODO: Criar possibilidade de transferência de filhos
de dispositivos automáticos
ex: na exclusão de artigos, na versão atual,
os caputs serão excluidos automáticamente mesmo que a
exclusão não seja em bloco. O que fazer com os incisos?
transferir para o caput imediatamente acima visto se
tratar de uma exclusão de item?"""
d_nivel_old = d.nivel
if d.is_relative_auto_insert():
d.delete()
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).exclude(
dispositivo_pai=base).first()
if not anterior:
return _('Não é possível excluir este Dispositivo sem'
' excluir toda a sua estrutura!!!')
if anterior.tipo_dispositivo == d.tipo_dispositivo:
d.dispositivo_pai = anterior.dispositivo_pai
d.nivel = anterior.nivel
if not d.tipo_dispositivo.contagem_continua:
d.set_numero_completo(
anterior.get_numero_completo())
if d.dispositivo_substituido != anterior:
d.transform_in_next()
d.rotulo = d.rotulo_padrao()
else:
parents = [anterior, ] + anterior.get_parents()
for candidato in parents:
if candidato == base:
return _('Não é possível excluir este '
'Dispositivo sem '
'excluir toda a sua estrutura!!!')
if (candidato.tipo_dispositivo ==
d.tipo_dispositivo):
d.dispositivo_pai = candidato.dispositivo_pai
d.nivel = candidato.nivel
if not d.tipo_dispositivo.contagem_continua:
d.set_numero_completo(
candidato.get_numero_completo())
if d.dispositivo_substituido != candidato:
d.transform_in_next()
d.rotulo = d.rotulo_padrao()
break
elif (candidato.tipo_dispositivo ==
d.dispositivo_pai.tipo_dispositivo):
d.dispositivo_pai = candidato
d.nivel = candidato.nivel + 1
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
d.rotulo = d.rotulo_padrao()
break
if not parents:
d.dispositivo_pai = anterior
d.nivel = anterior.nivel + 1
d.save(clean=False)
if d.nivel != d_nivel_old:
d.organizar_niveis()
pai_base = base.dispositivo_pai
if pai_base:
# Localizar irmaos posteriores do mesmo tipo de base
# se não DCC
if not base.tipo_dispositivo.contagem_continua:
irmaos_posteriores = pai_base.dispositivos_filhos_set.\
filter(
ordem__gt=base_ordem,
tipo_dispositivo=base.tipo_dispositivo)
# se DCC
else:
irmaos_posteriores = Dispositivo.objects.order_by(
'ordem').filter(
ta_id=base.ta_id,
ordem__gt=base_ordem,
tipo_dispositivo_id=base.tipo_dispositivo_id)
if proxima_articulacao:
irmaos_posteriores = irmaos_posteriores.exclude(
ordem__gte=proxima_articulacao.ordem)
# excluir e renumerar irmaos
profundidade_base = base.get_profundidade()
base.delete()
for irmao in irmaos_posteriores:
irmao.transform_in_prior(
profundidade=profundidade_base)
irmao.rotulo = irmao.rotulo_padrao()
irmao.save()
irmaos = pai_base.dispositivos_filhos_set.\
filter(tipo_dispositivo=base.tipo_dispositivo)
if (irmaos.count() == 1 and
';' in irmaos[0].
tipo_dispositivo.rotulo_prefixo_texto):
i = irmaos[0]
i.set_numero_completo([0, 0, 0, 0, 0, 0, ])
i.rotulo = i.rotulo_padrao(local_insert=1)
i.save()
else:
# Renumerar Dispostivos de Contagem Contínua
# de dentro da base se pai
dcc = Dispositivo.objects.order_by('ordem').filter(
ta_id=base.ta_id,
ordem__gt=base.ordem,
tipo_dispositivo__contagem_continua=True)
if proxima_articulacao:
dcc = dcc.exclude(
ordem__gte=proxima_articulacao.ordem)
base_adicao = {}
nivel_zero_anterior = base.get_nivel_zero_anterior()
if nivel_zero_anterior:
nivel_zero_anterior = nivel_zero_anterior.ordem
else:
nivel_zero_anterior = 0
dcc = list(dcc)
for d in dcc: # ultimo DCC do tipo encontrado
if d.tipo_dispositivo.class_css not in base_adicao:
ultimo_dcc = Dispositivo.objects.order_by(
'ordem').filter(
ta_id=base.ta_id,
ordem__lt=base.ordem,
ordem__gt=nivel_zero_anterior,
tipo_dispositivo__contagem_continua=True,
tipo_dispositivo=d.tipo_dispositivo).last()
if not ultimo_dcc:
break
base_adicao[
d.tipo_dispositivo.class_css] = ultimo_dcc.\
dispositivo0
d.dispositivo0 += base_adicao[
d.tipo_dispositivo.class_css]
d.rotulo = d.rotulo_padrao()
dcc.reverse()
for d in dcc:
d.save()
base.delete()
# em Bloco
else:
# Religar numeração de dispositivos de contagem contínua
# que serão excluidos
# pbi - proxima base independente
pbi = Dispositivo.objects.\
order_by('ordem').filter(
ta_id=base.ta_id,
ordem__gt=base_ordem,
nivel__lte=base.nivel).first()
if not pbi:
base.delete()
else:
dcc_a_excluir = Dispositivo.objects.order_by(
'ordem').filter(
ta_id=base.ta_id,
ordem__gte=base_ordem,
ordem__lt=pbi.ordem,
tipo_dispositivo__contagem_continua=True)
if proxima_articulacao:
dcc_a_excluir = dcc_a_excluir.exclude(
ordem__gte=proxima_articulacao.ordem)
religado = {}
for d in dcc_a_excluir:
if d.tipo_dispositivo.class_css in religado:
continue
religado[
d.tipo_dispositivo.class_css] = d.dispositivo0
dcc_a_religar = Dispositivo.objects.filter(
ta_id=d.ta_id,
ordem__gte=pbi.ordem,
tipo_dispositivo=d.tipo_dispositivo)
if proxima_articulacao:
dcc_a_religar = dcc_a_religar.exclude(
ordem__gte=proxima_articulacao.ordem)
primeiro_a_religar = 0
for dr in dcc_a_religar:
if not primeiro_a_religar:
primeiro_a_religar = dr.dispositivo0
base.delete()
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 ''
def add_prior(self, context):
return {}
def add_in(self, context):
return self.add_next(context, local_add='add_in')
def add_next(self, context, local_add='add_next'):
try:
dp_auto_insert = None
base = Dispositivo.objects.get(pk=context['dispositivo_id'])
tipo = TipoDispositivo.objects.get(pk=context['tipo_pk'])
pub_last = Publicacao.objects.order_by(
'data', 'hora').filter(ta=base.ta).last()
variacao = int(context['variacao'])
parents = [base, ] + base.get_parents()
if 'perfil_pk' not in context:
perfil_padrao = PerfilEstruturalTextoArticulado.objects.filter(
padrao=True).first()
if perfil_padrao:
context['perfil_pk'] = perfil_padrao.pk
else:
raise Exception('Não existe perfil padrão!')
tipos_dp_auto_insert = tipo.filhos_permitidos.filter(
filho_de_insercao_automatica=True,
perfil_id=context['perfil_pk'])
count_auto_insert = 0
for tipoauto in tipos_dp_auto_insert:
qtdp = tipoauto.quantidade_permitida
if qtdp >= 0:
qtdp -= Dispositivo.objects.filter(
ta_id=base.ta_id,
tipo_dispositivo_id=tipoauto.filho_permitido.pk
).count()
if qtdp > 0:
count_auto_insert += 1
else:
count_auto_insert += 1
dp_irmao = None
dp_pai = None
for dp in parents:
if dp.tipo_dispositivo == tipo:
dp_irmao = dp
break
if tipo.permitido_inserir_in(
dp.tipo_dispositivo,
perfil_pk=context['perfil_pk']):
dp_pai = dp
break
dp_pai = dp
if dp_irmao is not None:
dp = Dispositivo.new_instance_based_on(dp_irmao, tipo)
dp.transform_in_next(variacao)
else:
# Inserção sem precedente
dp = Dispositivo.new_instance_based_on(dp_pai, tipo)
dp.dispositivo_pai = dp_pai
dp.nivel += 1
if tipo.contagem_continua:
ultimo_irmao = Dispositivo.objects.order_by(
'-ordem').filter(
ordem__lte=base.ordem,
ordem__gte=parents[-1].ordem,
tipo_dispositivo_id=tipo.pk,
ta_id=base.ta_id)[:1]
if not ultimo_irmao.exists():
dp.set_numero_completo([1, 0, 0, 0, 0, 0, ])
else:
ultimo_irmao = ultimo_irmao[0]
dp.set_numero_completo(
ultimo_irmao.get_numero_completo())
dp.transform_in_next()
else:
if ';' in tipo.rotulo_prefixo_texto:
dp.set_numero_completo([0, 0, 0, 0, 0, 0, ])
else:
dp.set_numero_completo([1, 0, 0, 0, 0, 0, ])
# verificar se existe restrição de quantidade de itens
if dp.dispositivo_pai:
pp = dp.tipo_dispositivo.possiveis_pais.filter(
pai_id=dp.dispositivo_pai.tipo_dispositivo_id,
perfil_id=context['perfil_pk'])
if pp.exists() and pp[0].quantidade_permitida >= 0:
qtd_existente = Dispositivo.objects.filter(
ta_id=dp.ta_id,
tipo_dispositivo_id=dp.tipo_dispositivo_id).count()
if qtd_existente >= pp[0].quantidade_permitida:
return {'pk': base.pk,
'pai': [base.dispositivo_pai.pk, ],
'message': str(_('Limite de inserções de '
'dispositivos deste tipo '
'foi excedido.'))
}
ordem = base.criar_espaco(
espaco_a_criar=1 + count_auto_insert, local=local_add)
dp.rotulo = dp.rotulo_padrao()
dp.ordem = ordem
dp.incrementar_irmaos(variacao, [local_add, ], force=False)
dp.publicacao = pub_last
dp.save()
# Inserção automática
if count_auto_insert:
dp_pk = dp.pk
dp.nivel += 1
for tipoauto in tipos_dp_auto_insert:
dp.dispositivo_pai_id = dp_pk
dp.pk = None
dp.tipo_dispositivo = tipoauto.filho_permitido
if ';' in dp.tipo_dispositivo.rotulo_prefixo_texto:
dp.set_numero_completo([0, 0, 0, 0, 0, 0, ])
else:
dp.set_numero_completo([1, 0, 0, 0, 0, 0, ])
dp.rotulo = dp.rotulo_padrao()
dp.texto = ''
dp.ordem = dp.ordem + Dispositivo.INTERVALO_ORDEM
dp.publicacao = pub_last
dp.save()
dp_auto_insert = dp
dp = Dispositivo.objects.get(pk=dp_pk)
''' Reenquadrar todos os dispositivos que possuem pai
antes da inserção atual e que são inferiores a dp,
redirecionando para o novo pai'''
nivel = sys.maxsize
flag_niveis = False
if not dp.tipo_dispositivo.dispositivo_de_alteracao:
possiveis_filhos = Dispositivo.objects.filter(
ordem__gt=dp.ordem,
ta_id=dp.ta_id)
for filho in possiveis_filhos:
if filho.nivel > nivel:
continue
if not filho.dispositivo_pai or\
filho.dispositivo_pai.ordem >= dp.ordem:
continue
nivel = filho.nivel
if not filho.tipo_dispositivo.permitido_inserir_in(
dp.tipo_dispositivo,
perfil_pk=context['perfil_pk']):
continue
filho.dispositivo_pai = dp
filho.save()
flag_niveis = True
if flag_niveis:
dp.organizar_niveis()
numtipos = {}
''' Renumerar filhos imediatos que
não possuam contagem continua'''
if flag_niveis:
filhos = Dispositivo.objects.filter(
dispositivo_pai_id=dp.pk)
for filho in filhos:
if filho.tipo_dispositivo.contagem_continua:
continue
if filho.tipo_dispositivo.class_css in numtipos:
if filho.dispositivo_substituido is None:
numtipos[filho.tipo_dispositivo.class_css] += 1
else:
t = filho.tipo_dispositivo
prefixo = t.rotulo_prefixo_texto.split(';')
if len(prefixo) > 1:
count_irmaos_m_tipo = Dispositivo.objects.filter(
~Q(pk=filho.pk),
tipo_dispositivo=t,
dispositivo_pai=filho.dispositivo_pai)[:1]
if count_irmaos_m_tipo.exists():
numtipos[filho.tipo_dispositivo.class_css] = 1
else:
numtipos[filho.tipo_dispositivo.class_css] = 0
else:
numtipos[filho.tipo_dispositivo.class_css] = 1
filho.dispositivo0 = numtipos[
filho.tipo_dispositivo.class_css]
filho.rotulo = filho.rotulo_padrao()
filho.save()
''' Renumerar dispositivos de
contagem continua, caso a inserção seja uma articulação'''
if dp.nivel == 0:
proxima_articulacao = dp.get_proximo_nivel_zero()
if not proxima_articulacao:
filhos_continuos = list(Dispositivo.objects.filter(
ordem__gt=dp.ordem,
ta_id=dp.ta_id,
tipo_dispositivo__contagem_continua=True))
else:
filhos_continuos = list(Dispositivo.objects.filter(
ordem__gt=dp.ordem,
ordem__lt=proxima_articulacao.ordem,
ta_id=dp.ta_id,
tipo_dispositivo__contagem_continua=True))
base_reducao = {}
for filho in filhos_continuos:
if filho.tipo_dispositivo.class_css not in base_reducao:
base_reducao[filho.tipo_dispositivo.class_css] = \
filho.dispositivo0 - 1
filho.dispositivo0 -= base_reducao[
filho.tipo_dispositivo.class_css]
filho.rotulo = filho.rotulo_padrao()
filho.save()
except Exception as e:
print(e)
if dp_auto_insert is None:
data = self.get_json_for_refresh(dp)
else:
data = self.get_json_for_refresh(dp=dp, dpauto=dp_auto_insert)
return data
def get_json_for_refresh(self, dp, dpauto=None):
if dp.tipo_dispositivo.contagem_continua:
pais = []
if dp.dispositivo_pai is None:
data = {'pk': dp.pk, 'pai': [-1, ]}
else:
pkfilho = dp.pk
dp = dp.dispositivo_pai
proxima_articulacao = dp.get_proximo_nivel_zero()
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)
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, ]}
return data
class ActionsEditView(ActionsEditMixin, TemplateView):
def render_to_response(self, context, **response_kwargs):
context['action'] = self.request.GET['action']
if 'tipo_pk' in self.request.GET:
context['tipo_pk'] = self.request.GET['tipo_pk']
if 'variacao' in self.request.GET:
context['variacao'] = self.request.GET['variacao']
if 'perfil_estrutural' in self.request.session:
context['perfil_pk'] = self.request.session['perfil_estrutural']
if 'herancas' in self.request.session:
del self.request.session['herancas']
del self.request.session['herancas_fila']
return self.render_to_json_response(context, **response_kwargs)
class DispositivoSearchFragmentFormView(ListView):
template_name = 'compilacao/dispositivo_form_search_fragment.html'
def get(self, request, *args, **kwargs):
if 'action' in request.GET and request.GET['action'] == 'get_tipos':
result = choice_model_type_foreignkey_in_extenal_views(
id_tipo_ta=request.GET['tipo_ta'])
itens = []
for i in result:
item = {}
item[i[0] if i[0] else ''] = str(i[1])
itens.append(item)
return JsonResponse(itens, safe=False)
return ListView.get(self, request, *args, **kwargs)
def get_queryset(self):
try:
n = 10
if 'max_results' in self.request.GET:
n = int(self.request.GET['max_results'])
q = Q()
if 'initial_ref' in self.request.GET:
initial_ref = self.request.GET['initial_ref']
if initial_ref:
q = q & Q(pk=initial_ref)
result = Dispositivo.objects.filter(q).select_related(
'ta').exclude(
tipo_dispositivo__dispositivo_de_alteracao=True)
return result[:n]
str_texto = ''
texto = ''
rotulo = ''
num_ta = ''
ano_ta = ''
if 'texto' in self.request.GET:
str_texto = self.request.GET['texto']
texto = str_texto.split(' ')
if 'rotulo' in self.request.GET:
rotulo = self.request.GET['rotulo']
if rotulo:
q = q & Q(rotulo__icontains=rotulo)
for item in texto:
if not item:
continue
if q:
q = q & (Q(texto__icontains=item) |
Q(texto_atualizador__icontains=item))
else:
q = (Q(texto__icontains=item) |
Q(texto_atualizador__icontains=item))
if 'tipo_ta' in self.request.GET:
tipo_ta = self.request.GET['tipo_ta']
if tipo_ta:
q = q & Q(ta__tipo_ta_id=tipo_ta)
if 'num_ta' in self.request.GET:
num_ta = self.request.GET['num_ta']
if num_ta:
q = q & Q(ta__numero=num_ta)
if 'ano_ta' in self.request.GET:
ano_ta = self.request.GET['ano_ta']
if ano_ta:
q = q & Q(ta__ano=ano_ta)
if not q.children and not n:
n = 10
q = q & Q(nivel__gt=0)
result = Dispositivo.objects.order_by(
'-ta__data',
'-ta__ano',
'-ta__numero',
'ta',
'ordem').filter(q).select_related('ta')
if 'data_type_selection' in self.request.GET and\
self.request.GET['data_type_selection'] == 'checkbox':
result = result.exclude(
tipo_dispositivo__dispositivo_de_alteracao=True)
else:
if 'data_function' in self.request.GET and\
self.request.GET['data_function'] == 'alterador':
result = result.exclude(
tipo_dispositivo__dispositivo_de_alteracao=False,
)
result = result.exclude(
tipo_dispositivo__dispositivo_de_articulacao=False,
)
print(str(result.query))
def resultados(r):
if n:
return r[:n]
else:
return r
"""if num_ta and ano_ta and not rotulo and not str_texto and\
'data_type_selection' in self.request.GET and\
self.request.GET['data_type_selection'] == 'checkbox':
return r
else:
return r[:n]"""
if 'tipo_model' not in self.request.GET:
return resultados(result)
tipo_model = self.request.GET['tipo_model']
if not tipo_model:
return resultados(result)
integrations_view_names = get_integrations_view_names()
tipo_ta = TipoTextoArticulado.objects.get(pk=tipo_ta)
model_class = None
for item in integrations_view_names:
if hasattr(item, 'model_type_foreignkey') and\
hasattr(item, 'model'):
if (tipo_ta.content_type.model ==
item.model.__name__.lower() and
tipo_ta.content_type.app_label ==
item.model._meta.app_label):
model_class = item.model
model_type_class = item.model_type_foreignkey
tipo_model = item.model_type_foreignkey.objects.get(
pk=tipo_model)
break
if not model_class:
return resultados(result)
column_field = ''
for field in model_class._meta.fields:
if field.related_model == model_type_class:
column_field = field.column
break
if not column_field:
return resultados(result)
r = []
for d in result:
if not d.ta.content_object or\
not hasattr(d.ta.content_object, column_field):
continue
if tipo_model.pk == getattr(d.ta.content_object, column_field):
r.append(d)
if (len(r) == n and (not num_ta or
not ano_ta or rotulo or str_texto)):
break
return r
except Exception as e:
print(e)
class DispositivoSearchModalView(FormView):
template_name = 'compilacao/dispositivo_form_search.html'
form_class = DispositivoSearchModalForm
class DispositivoEdicaoBasicaView(FormMessagesMixin, UpdateView):
model = Dispositivo
template_name = 'compilacao/dispositivo_form_edicao_basica.html'
form_class = DispositivoEdicaoBasicaForm
form_valid_message = _('Alterações no Dispositivo realizadas com sucesso!')
form_invalid_message = _('Houve erro em registrar '
'as alterações no Dispositivo')
@property
def cancel_url(self):
return reverse_lazy(
'compilacao:ta_text_edit',
kwargs={'ta_id': self.kwargs['ta_id']}) + '#' + str(self.object.pk)
def get_success_url(self):
return reverse_lazy(
'compilacao:dispositivo_edit',
kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']})
def get_url_this_view(self):
return 'compilacao:dispositivo_edit'
def run_actions(self, request):
if 'action' in request.GET and\
request.GET['action'] == 'atualiza_rotulo':
try:
d = Dispositivo.objects.get(pk=self.kwargs['pk'])
d.dispositivo0 = int(request.GET['dispositivo0'])
d.dispositivo1 = int(request.GET['dispositivo1'])
d.dispositivo2 = int(request.GET['dispositivo2'])
d.dispositivo3 = int(request.GET['dispositivo3'])
d.dispositivo4 = int(request.GET['dispositivo4'])
d.dispositivo5 = int(request.GET['dispositivo5'])
d.rotulo = d.rotulo_padrao()
numero = d.get_numero_completo()[1:]
zerar = False
for i in range(len(numero)):
if not numero[i]:
zerar = True
if zerar:
numero[i] = 0
if zerar:
d.set_numero_completo([d.dispositivo0, ] + numero)
d.rotulo = d.rotulo_padrao()
except:
return True, JsonResponse({'message': str(
_('Ocorreu erro na atualização do rótulo'))}, safe=False)
return True, JsonResponse({
'rotulo': d.rotulo,
'dispositivo0': d.dispositivo0,
'dispositivo1': d.dispositivo1,
'dispositivo2': d.dispositivo2,
'dispositivo3': d.dispositivo3,
'dispositivo4': d.dispositivo4,
'dispositivo5': d.dispositivo5}, safe=False)
return False, ''
def get(self, request, *args, **kwargs):
flag_action, render_json_response = self.run_actions(request)
if flag_action:
return render_json_response
return UpdateView.get(self, request, *args, **kwargs)
class DispositivoEdicaoVigenciaView(FormMessagesMixin, UpdateView):
model = Dispositivo
template_name = 'compilacao/dispositivo_form_vigencia.html'
form_class = DispositivoEdicaoVigenciaForm
form_valid_message = _('Alterações no Dispositivo realizadas com sucesso!')
form_invalid_message = _('Houve erro em registrar '
'as alterações no Dispositivo')
@property
def cancel_url(self):
return reverse_lazy(
'compilacao:ta_text_edit',
kwargs={'ta_id': self.kwargs['ta_id']}) + '#' + str(self.object.pk)
def get_url_this_view(self):
return 'compilacao:dispositivo_edit_vigencia'
def get_success_url(self):
return reverse_lazy(
'compilacao:dispositivo_edit_vigencia',
kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']})
class DispositivoDefinidorVigenciaView(FormMessagesMixin, FormView):
model = Dispositivo
template_name = 'compilacao/dispositivo_form_definidor_vigencia.html'
form_class = DispositivoDefinidorVigenciaForm
form_valid_message = _('Alterações no Dispositivo realizadas com sucesso!')
form_invalid_message = _('Houve erro em registrar '
'as alterações no Dispositivo')
def get_form_kwargs(self):
kwargs = FormView.get_form_kwargs(self)
kwargs.update({
'pk': self.kwargs['pk'],
})
return kwargs
@property
def cancel_url(self):
return reverse_lazy(
'compilacao:ta_text_edit',
kwargs={'ta_id': self.kwargs['ta_id']}) + '#' + str(self.object.pk)
def get_url_this_view(self):
return 'compilacao:dispositivo_edit_definidor_vigencia'
def get_success_url(self):
return reverse_lazy(
'compilacao:dispositivo_edit_definidor_vigencia',
kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']})
def get(self, request, *args, **kwargs):
self.object = get_object_or_404(Dispositivo, pk=kwargs['pk'])
return FormView.get(self, request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = FormView.get_context_data(self, **kwargs)
context.update({'object': self.object})
return context
def post(self, request, *args, **kwargs):
self.object = get_object_or_404(Dispositivo, pk=kwargs['pk'])
form = self.get_form()
if form.is_valid():
dvs = form.cleaned_data['dispositivo_vigencia']
try:
with transaction.atomic():
self.object.dispositivos_vigencias_set.clear()
for item in dvs:
d = Dispositivo.objects.get(pk=item)
self.object.dispositivos_vigencias_set.add(d)
return self.form_valid(form)
except:
return self.form_invalid(form)
else:
return self.form_invalid(form)
class DispositivoEdicaoAlteracaoView(FormMessagesMixin, UpdateView):
model = Dispositivo
template_name = 'compilacao/dispositivo_form_alteracao.html'
form_class = DispositivoEdicaoAlteracaoForm
form_valid_message = _('Alterações no Dispositivo realizadas com sucesso!')
form_invalid_message = _('Houve erro em registrar '
'as alterações no Dispositivo')
@property
def cancel_url(self):
return reverse_lazy(
'compilacao:ta_text_edit',
kwargs={'ta_id': self.kwargs['ta_id']}) + '#' + str(self.object.pk)
def get_url_this_view(self):
return 'compilacao:dispositivo_edit_alteracao'
def get_success_url(self):
return reverse_lazy(
'compilacao:dispositivo_edit_alteracao',
kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']})
def post(self, request, *args, **kwargs):
self.object = get_object_or_404(Dispositivo, pk=kwargs['pk'])
form = self.get_form()
if form.is_valid():
try:
with transaction.atomic():
return self.form_valid(form)
except:
return self.form_invalid(form)
else:
return self.form_invalid(form)