Browse Source

Integração com TextoArticulado

- Integração de NormaJuridica com TextoArticulado
    - Integração de Materia Legislativa com TextoArticulado
pull/98/head
LeandroRoberto 9 years ago
parent
commit
9b20e8ea3e
  1. 16
      compilacao/forms.py
  2. 30
      compilacao/migrations/0035_auto_20151226_1349.py
  3. 19
      compilacao/migrations/0036_auto_20151226_1411.py
  4. 19
      compilacao/migrations/0037_auto_20151226_1414.py
  5. 19
      compilacao/migrations/0038_tipotextoarticulado_model.py
  6. 19
      compilacao/migrations/0039_auto_20151226_1433.py
  7. 26
      compilacao/models.py
  8. 54
      compilacao/urls.py
  9. 327
      compilacao/views.py
  10. 214
      compilacao/views2.py
  11. 8
      materia/urls.py
  12. 89
      materia/views.py
  13. 9
      norma/urls.py
  14. 39
      norma/views.py
  15. 4
      sapl/settings.py
  16. 26
      static/js/compilacao_notas.js
  17. 12
      static/js/compilacao_view.js
  18. 40
      templates/compilacao/text_edit.html
  19. 2
      templates/compilacao/text_edit_bloco.html
  20. 0
      templates/compilacao/text_edit_blocoalteracao.html
  21. 21
      templates/compilacao/text_list.html
  22. 45
      templates/compilacao/textoarticulado_detail.html
  23. 1
      templates/materia/materialegislativa_detail.html
  24. 14
      templates/norma/normajuridica_detail.html

16
compilacao/forms.py

@ -218,11 +218,13 @@ class VideForm(ModelForm):
queryset=Dispositivo.objects.all(),
widget=forms.HiddenInput())
tipo_norma = forms.ModelChoiceField(
queryset=TipoNormaJuridica.objects.all(),
tipo_ta = forms.ModelChoiceField(
queryset=TipoTextoArticulado.objects.all(),
required=False)
num_norma = forms.IntegerField(label=_('Núm. da Norma'), required=False)
ano_norma = forms.IntegerField(label=_('Ano da Norma'), required=False)
num_ta = forms.IntegerField(
label=_('Núm Texto Articulado'), required=False)
ano_ta = forms.IntegerField(
label=_('Ano Texto Articulado'), required=False)
texto = forms.CharField(
label='',
@ -280,9 +282,9 @@ class VideForm(ModelForm):
), 4)),
to_column((
Div(
Div(to_column(('tipo_norma', 6))),
Div(to_column(('num_norma', 3)),
to_column(('ano_norma', 3))),
Div(to_column(('tipo_ta', 6))),
Div(to_column(('num_ta', 3)),
to_column(('ano_ta', 3))),
Div(to_column(
(Field(
'busca_dispositivo',

30
compilacao/migrations/0035_auto_20151226_1349.py

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import builtins
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('compilacao', '0034_auto_20151226_1321'),
]
operations = [
migrations.AddField(
model_name='textoarticulado',
name='content_type',
field=models.ForeignKey(
to='contenttypes.ContentType', default=142),
preserve_default=False,
),
migrations.AddField(
model_name='textoarticulado',
name='object_id',
field=models.PositiveIntegerField(default=1),
preserve_default=False,
),
]

19
compilacao/migrations/0036_auto_20151226_1411.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0035_auto_20151226_1349'),
]
operations = [
migrations.AlterField(
model_name='textoarticulado',
name='content_type',
field=models.ForeignKey(default=None, null=True, to='contenttypes.ContentType', blank=True),
),
]

19
compilacao/migrations/0037_auto_20151226_1414.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0036_auto_20151226_1411'),
]
operations = [
migrations.AlterField(
model_name='textoarticulado',
name='object_id',
field=models.PositiveIntegerField(blank=True, default=None, null=True),
),
]

19
compilacao/migrations/0038_tipotextoarticulado_model.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0037_auto_20151226_1414'),
]
operations = [
migrations.AddField(
model_name='tipotextoarticulado',
name='model',
field=models.CharField(max_length=50, blank=True, default='', null=True, verbose_name='Modelagem Django'),
),
]

19
compilacao/migrations/0039_auto_20151226_1433.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0038_tipotextoarticulado_model'),
]
operations = [
migrations.AlterField(
model_name='tipotextoarticulado',
name='model',
field=models.CharField(verbose_name='Modelagem Django', default='', blank=True, null=True, max_length=50, unique=True),
),
]

26
compilacao/models.py

@ -1,6 +1,8 @@
from datetime import datetime
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import F, Q
from django.db.models.aggregates import Max
@ -61,6 +63,12 @@ class BaseModel(models.Model):
class TipoTextoArticulado(models.Model):
sigla = models.CharField(max_length=3, verbose_name=_('Sigla'))
descricao = models.CharField(max_length=50, verbose_name=_('Descrição'))
model = models.CharField(
default='',
blank=True, null=True,
max_length=50,
unique=True,
verbose_name=_('Modelagem Django'))
participacao_social = models.NullBooleanField(
default=False,
blank=True, null=True,
@ -98,16 +106,26 @@ class TextoArticulado(TimestampedMixin):
choices=PARTICIPACAO_SOCIAL_CHOICES,
verbose_name=_('Participação Social'))
content_type = models.ForeignKey(
ContentType,
blank=True, null=True, default=None)
object_id = models.PositiveIntegerField(
blank=True, null=True, default=None)
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
verbose_name = _('Texto Articulado')
verbose_name_plural = _('Textos Articulados')
ordering = ['-data', '-numero']
def __str__(self):
return _('Texto Articulado nº %(numero)s de %(data)s') % {
'tipo': self.tipo_ta,
'numero': self.numero,
'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")}
if self.content_object:
return str(self.content_object)
else:
return _('Texto Articulado nº %(numero)s de %(data)s') % {
'tipo': self.tipo_ta,
'numero': self.numero,
'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")}
class TipoNota(models.Model):

54
compilacao/urls.py

@ -13,55 +13,59 @@ urlpatterns_compilacao = [
url(r'^(?P<ta_id>[0-9]+)/text$',
views.TextoView.as_view(), name='ta_text'),
views.TextView.as_view(), name='ta_text'),
url(r'^(?P<ta_id>[0-9]+)/text/vigencia/(?P<sign>.+)/$',
views.TextoView.as_view(), name='ta_vigencia'),
]
views.TextView.as_view(), name='ta_vigencia'),
urlpatterns = [
url(r'^ta/', include(urlpatterns_compilacao)),
]
url(r'^(?P<ta_id>[0-9]+)/text/edit',
views.TextEditView.as_view(), name='ta_text_edit'),
"""
url(r'^(?P<ta_id>[0-9]+)/compilacao/(?P<dispositivo_id>[0-9]+)/$',
url(r'^(?P<ta_id>[0-9]+)/text/(?P<dispositivo_id>[0-9]+)/$',
views.DispositivoView.as_view(), name='dispositivo'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/edit',
views.CompilacaoEditView.as_view(), name='comp_edit'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/(?P<dispositivo_id>[0-9]+)/refresh',
views.DispositivoEditView.as_view(), name='dispositivo_edit'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/(?P<dispositivo_id>[0-9]+)/actions',
views.ActionsEditView.as_view(), name='dispositivo_actions'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/'
url(r'^(?P<ta_id>[0-9]+)/text/'
'(?P<dispositivo_id>[0-9]+)/nota/create$',
views.NotasCreateView.as_view(), name='nota_create'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/'
url(r'^(?P<ta_id>[0-9]+)/text/'
'(?P<dispositivo_id>[0-9]+)/nota/(?P<pk>[0-9]+)/edit$',
views.NotasEditView.as_view(), name='nota_edit'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/'
url(r'^(?P<ta_id>[0-9]+)/text/'
'(?P<dispositivo_id>[0-9]+)/nota/(?P<pk>[0-9]+)/delete$',
views.NotasDeleteView.as_view(), name='nota_delete'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/'
url(r'^(?P<ta_id>[0-9]+)/text/'
'(?P<dispositivo_id>[0-9]+)/vide/create$',
views.VideCreateView.as_view(), name='vide_create'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/'
url(r'^(?P<ta_id>[0-9]+)/text/'
'(?P<dispositivo_id>[0-9]+)/vide/(?P<pk>[0-9]+)/edit$',
views.VideEditView.as_view(), name='vide_edit'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/'
url(r'^(?P<ta_id>[0-9]+)/text/'
'(?P<dispositivo_id>[0-9]+)/vide/(?P<pk>[0-9]+)/delete$',
views.VideDeleteView.as_view(), name='vide_delete'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/search$',
url(r'^(?P<ta_id>[0-9]+)/text/search$',
views.DispositivoSearchFragmentFormView.as_view(),
name='search_dispositivo'),
]
urlpatterns = [
url(r'^ta/', include(urlpatterns_compilacao)),
]
"""
url(r'^(?P<ta_id>[0-9]+)/compilacao/(?P<dispositivo_id>[0-9]+)/refresh',
views.DispositivoEditView.as_view(), name='dispositivo_edit'),
url(r'^(?P<ta_id>[0-9]+)/compilacao/(?P<dispositivo_id>[0-9]+)/actions',
views.ActionsEditView.as_view(), name='dispositivo_actions'),
"""

327
compilacao/views.py

@ -104,7 +104,7 @@ class TaDeleteView(DeleteView):
return reverse_lazy('ta_list')
class TextoView(ListView):
class TextView(ListView):
template_name = 'compilacao/text_list.html'
flag_alteradora = -1
@ -118,7 +118,10 @@ class TextoView(ListView):
fim_vigencia = None
def get_context_data(self, **kwargs):
context = super(TextoView, self).get_context_data(**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'])).\
@ -185,16 +188,7 @@ class TextoView(ListView):
r = Dispositivo.objects.filter(
ordem__gt=0,
ta_id=self.kwargs['ta_id'],
).select_related(
'tipo_dispositivo',
'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')
).select_related(*DISPOSITIVO_SELECT_RELATED)
return r
@ -264,7 +258,7 @@ class TextoView(ListView):
return self.flag_alteradora > 0
class DispositivoView(TextoView):
class DispositivoView(TextView):
# template_name = 'compilacao/index.html'
template_name = 'compilacao/text_list_bloco.html'
@ -298,3 +292,310 @@ class DispositivoView(TextoView):
ta_id=self.kwargs['ta_id']
).select_related(*DISPOSITIVO_SELECT_RELATED)
return itens
class TextEditView(TextView):
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):
self.object_list = self.get_queryset()
context = self.get_context_data(
object_list=self.object_list)
return self.render_to_response(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.timestamp = datetime.now()
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.timestamp = datetime.now()
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.timestamp = datetime.now()
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 DispositivoSuccessUrlMixin(object):
def get_success_url(self):
return reverse(
'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 = forms.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):
try:
ta_id = kwargs.pop('ta_id')
dispositivo_id = kwargs.pop('dispositivo_id')
form = forms.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("post")
class NotasEditView(NotaMixin, UpdateView):
model = Nota
template_name = 'compilacao/ajax_form.html'
form_class = forms.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)
class VideCreateView(VideMixin, CreateView):
template_name = 'compilacao/ajax_form.html'
form_class = forms.VideForm
def post(self, request, *args, **kwargs):
try:
ta_id = kwargs.pop('ta_id')
dispositivo_id = kwargs.pop('dispositivo_id')
form = forms.VideForm(request.POST, request.FILES, **kwargs)
kwargs['ta_id'] = ta_id
kwargs['dispositivo_id'] = dispositivo_id
if form.is_valid():
vd = form.save(commit=False)
vd.save()
self.kwargs['pk'] = vd.pk
return self.form_valid(form)
else:
return self.form_invalid(form)
except Exception as e:
print(e)
return HttpResponse("post")
class VideEditView(VideMixin, UpdateView):
model = Vide
template_name = 'compilacao/ajax_form.html'
form_class = forms.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 DispositivoSearchFragmentFormView(ListView):
template_name = 'compilacao/dispositivo_search_fragment_form.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(
DispositivoSearchFragmentFormView,
self).dispatch(*args, **kwargs)
def get_queryset(self):
try:
busca = ''
if 'busca' in self.request.GET:
busca = self.request.GET['busca']
q = Q(nivel__gt=0)
busca = busca.split(' ')
n = 10
for item in busca:
if not item:
continue
if q:
q = q & (Q(dispositivo_pai__rotulo__icontains=item) |
Q(rotulo__icontains=item) |
Q(texto__icontains=item) |
Q(texto_atualizador__icontains=item))
n = 50
else:
q = (Q(dispositivo_pai__rotulo__icontains=item) |
Q(rotulo__icontains=item) |
Q(texto__icontains=item) |
Q(texto_atualizador__icontains=item))
n = 50
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)
n = 50
if 'num_ta' in self.request.GET:
num_ta = self.request.GET['num_ta']
if num_ta:
q = q & Q(ta__numero=num_ta)
n = 50
if 'ano_ta' in self.request.GET:
ano_ta = self.request.GET['ano_ta']
if ano_ta:
q = q & Q(ta__ano=ano_ta)
n = 50
if 'initial_ref' in self.request.GET:
initial_ref = self.request.GET['initial_ref']
if initial_ref:
q = q & Q(pk=initial_ref)
n = 50
return Dispositivo.objects.filter(q)[:n]
except Exception as e:
print(e)

214
compilacao/views2.py

@ -1135,217 +1135,3 @@ class ActionsEditView(ActionsEditMixin, TemplateView):
context['perfil_pk'] = self.request.session['perfil_estrutural']
return self.render_to_json_response(context, **response_kwargs)
class DispositivoSuccessUrlMixin(object):
def get_success_url(self):
return reverse(
'dispositivo', kwargs={
'ta_id': self.kwargs[
'ta_id'],
'dispositivo_id': self.kwargs[
'dispositivo_id']})
class NotaMixin(DispositivoSuccessUrlMixin):
def get_modelo_nota(self, request):
# TODO: permitir edição apenas das notas do usuário conectado
# TODO: tratar revalidação no método post
# TODO: não mostrar botão de edição na interface
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 = forms.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):
try:
ta_id = kwargs.pop('ta_id')
dispositivo_id = kwargs.pop('dispositivo_id')
form = forms.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("post")
class NotasEditView(NotaMixin, UpdateView):
model = Nota
template_name = 'compilacao/ajax_form.html'
form_class = forms.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)
class VideCreateView(VideMixin, CreateView):
template_name = 'compilacao/ajax_form.html'
form_class = forms.VideForm
def post(self, request, *args, **kwargs):
try:
ta_id = kwargs.pop('ta_id')
dispositivo_id = kwargs.pop('dispositivo_id')
form = forms.VideForm(request.POST, request.FILES, **kwargs)
kwargs['ta_id'] = ta_id
kwargs['dispositivo_id'] = dispositivo_id
if form.is_valid():
vd = form.save(commit=False)
vd.save()
self.kwargs['pk'] = vd.pk
return self.form_valid(form)
else:
return self.form_invalid(form)
except Exception as e:
print(e)
return HttpResponse("post")
class VideEditView(VideMixin, UpdateView):
model = Vide
template_name = 'compilacao/ajax_form.html'
form_class = forms.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 DispositivoSearchFragmentFormView(ListView):
template_name = 'compilacao/dispositivo_search_fragment_form.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(
DispositivoSearchFragmentFormView,
self).dispatch(*args, **kwargs)
def get_queryset(self):
try:
busca = ''
if 'busca' in self.request.GET:
busca = self.request.GET['busca']
q = Q(nivel__gt=0)
busca = busca.split(' ')
n = 10
for item in busca:
if not item:
continue
if q:
q = q & (Q(dispositivo_pai__rotulo__icontains=item) |
Q(rotulo__icontains=item) |
Q(texto__icontains=item) |
Q(texto_atualizador__icontains=item))
n = 50
else:
q = (Q(dispositivo_pai__rotulo__icontains=item) |
Q(rotulo__icontains=item) |
Q(texto__icontains=item) |
Q(texto_atualizador__icontains=item))
n = 50
if 'tipo_ta' in self.request.GET:
tipo_ta = self.request.GET['tipo_ta']
if tipo_ta:
q = q & Q(ta__tipo_id=tipo_ta)
n = 50
if 'num_ta' in self.request.GET:
num_ta = self.request.GET['num_ta']
if num_ta:
q = q & Q(ta__numero=num_ta)
n = 50
if 'ano_ta' in self.request.GET:
ano_ta = self.request.GET['ano_ta']
if ano_ta:
q = q & Q(ta__ano=ano_ta)
n = 50
if 'initial_ref' in self.request.GET:
initial_ref = self.request.GET['initial_ref']
if initial_ref:
q = q & Q(pk=initial_ref)
n = 50
return Dispositivo.objects.filter(q)[:n]
except Exception as e:
print(e)

8
materia/urls.py

@ -15,7 +15,8 @@ from materia.views import (AutoriaEditView, AutoriaView,
regime_tramitacao_crud, status_tramitacao_crud,
tipo_autor_crud, tipo_documento_crud,
tipo_fim_relatoria_crud, tipo_materia_crud,
tipo_proposicao_crud, unidade_tramitacao_crud)
tipo_proposicao_crud, unidade_tramitacao_crud,
MateriaTaView)
materia_legislativa_patterns = materia_legislativa_crud.urlpatterns
@ -26,6 +27,11 @@ urlpatterns = [
materia_legislativa_crud.namespace,
materia_legislativa_crud.namespace)),
url(r'^materia/(?P<pk>[0-9]+)/ta$',
MateriaTaView.as_view(), name='materia_ta'),
url(r'^sistema/proposicoes/tipo/', include(tipo_proposicao_crud.urls)),
url(r'^sistema/proposicoes/autor/', include(autor_crud.urls)),
url(r'^sistema/materia/tipo/', include(tipo_materia_crud.urls)),

89
materia/views.py

@ -4,10 +4,11 @@ from re import sub
from crispy_forms.helper import FormHelper
from crispy_forms.layout import ButtonHolder, Column, Fieldset, Layout, Submit
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse, reverse_lazy
from django.forms import ModelForm
from django.shortcuts import redirect
from django.shortcuts import redirect, get_object_or_404
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
@ -15,11 +16,12 @@ from django.views.generic import ListView
from django.views.generic.edit import FormMixin
from vanilla import GenericView
import sapl
from comissoes.models import Comissao, Composicao
from compilacao.models import TextoArticulado, TipoTextoArticulado
from norma.models import LegislacaoCitada, NormaJuridica, TipoNormaJuridica
from parlamentares.models import Parlamentar
from sapl.crud import build_crud
import sapl
from .models import (Anexada, Autor, Autoria, DespachoInicial,
DocumentoAcessorio, MateriaLegislativa, Numeracao, Orgao,
@ -28,6 +30,7 @@ from .models import (Anexada, Autor, Autoria, DespachoInicial,
TipoFimRelatoria, TipoMateriaLegislativa, TipoProposicao,
Tramitacao, UnidadeTramitacao)
origem_crud = build_crud(
Origem, 'origem', [
@ -508,10 +511,10 @@ class MateriaAnexadaView(FormMixin, GenericView):
error = 'A matéria a ser anexada não pode ser do mesmo \
tipo da matéria principal.'
return self.render_to_response(
{'error': error,
'form': form,
'materialegislativa': mat_principal,
'anexadas': anexadas})
{'error': error,
'form': form,
'materialegislativa': mat_principal,
'anexadas': anexadas})
anexada = Anexada()
anexada.materia_principal = mat_principal
@ -527,17 +530,17 @@ class MateriaAnexadaView(FormMixin, GenericView):
error = 'A matéria a ser anexada não existe no cadastro \
de matérias legislativas.'
return self.render_to_response(
{'error': error,
'form': form,
'materialegislativa': mat_principal,
'anexadas': anexadas})
{'error': error,
'form': form,
'materialegislativa': mat_principal,
'anexadas': anexadas})
return self.form_valid(form)
else:
return self.render_to_response(
{'form': form,
'materialegislativa': mat_principal,
'anexadas': anexadas})
{'form': form,
'materialegislativa': mat_principal,
'anexadas': anexadas})
def get_success_url(self):
pk = self.kwargs['pk']
@ -615,14 +618,14 @@ class MateriaAnexadaEditView(FormMixin, GenericView):
error = 'A matéria a ser anexada não existe no cadastro \
de matérias legislativas.'
return self.render_to_response(
{'error': error,
'form': form,
'materialegislativa': mat_principal})
{'error': error,
'form': form,
'materialegislativa': mat_principal})
else:
return self.render_to_response(
{'form': form,
'materialegislativa': mat_principal})
{'form': form,
'materialegislativa': mat_principal})
def get_success_url(self):
pk = self.kwargs['pk']
@ -1519,7 +1522,7 @@ class TramitacaoEditView(FormMixin, GenericView):
if form.is_valid():
if 'excluir' in request.POST:
if tramitacao == Tramitacao.objects.filter(
materia=materia).last():
materia=materia).last():
tramitacao.delete()
return self.form_valid(form)
else:
@ -1765,7 +1768,7 @@ class ProposicaoForm(ModelForm):
ButtonHolder(
Submit('sumbmit', 'Salvar',
css_class='button primary')
), css_class='columns large-2'))
), css_class='columns large-2'))
self.helper = FormHelper()
self.helper.layout = Layout(
@ -1836,7 +1839,7 @@ class ProposicaoListView(ListView):
page_obj = context['page_obj']
context['page_range'] = sapl.crud.make_pagination(
page_obj.number, paginator.num_pages)
page_obj.number, paginator.num_pages)
return context
@ -1907,7 +1910,7 @@ class MateriaLegislativaPesquisaForm(forms.Form):
label='Tramitando',
choices=em_tramitacao(),
widget=forms.Select(
attrs={'class': 'selector'}))
attrs={'class': 'selector'}))
# TODO: Verificar se esses campos estão corretos
# assunto? # -> usado 'ementa' em 'assunto'
@ -1979,13 +1982,13 @@ class MateriaLegislativaPesquisaView(FormMixin, GenericView):
if request.POST['data_apresentacao']:
kwargs['data_apresentacao'] = datetime.strptime(
request.POST['data_apresentacao'],
'%d/%m/%Y').strftime('%Y-%m-%d')
request.POST['data_apresentacao'],
'%d/%m/%Y').strftime('%Y-%m-%d')
if request.POST['data_publicacao']:
kwargs['data_publicacao'] = datetime.strptime(
request.POST['data_publicacao'],
'%d/%m/%Y').strftime('%Y-%m-%d')
request.POST['data_publicacao'],
'%d/%m/%Y').strftime('%Y-%m-%d')
if request.POST['tramitacao']:
kwargs['em_tramitacao'] = request.POST['tramitacao']
@ -2018,3 +2021,35 @@ class PesquisaMateriaListView(FormMixin, ListView):
context['page_range'] = sapl.crud.make_pagination(
page_obj.number, paginator.num_pages)
return context
class MateriaTaView(GenericView):
def get(self, *args, **kwargs):
materia = get_object_or_404(MateriaLegislativa, pk=kwargs['pk'])
related_object_type = ContentType.objects.get_for_model(materia)
ta = TextoArticulado.objects.filter(
object_id=materia.pk,
content_type=related_object_type)
if not ta.exists():
tipo_ta = TipoTextoArticulado.objects.filter(
model=materia.__class__.__name__.lower())[:1]
ta = TextoArticulado()
if tipo_ta.exists():
ta.tipo_ta = tipo_ta[0]
ta.ementa = materia.ementa
ta.numero = materia.numero
ta.ano = materia.ano
ta.data = materia.data_apresentacao
ta.content_object = materia
ta.save()
else:
ta = ta[0]
return redirect(to=reverse_lazy('ta_text', kwargs={'ta_id': ta.pk}))

9
norma/urls.py

@ -1,8 +1,10 @@
from django.conf.urls import include, url
from compilacao.urls import urlpatterns as __url__compilacao
from compilacao.urls import urlpatterns as __url__compilacao,\
urlpatterns_compilacao
from norma.views import (NormaIncluirView, assunto_norma_crud,
norma_temporario_crud, tipo_norma_crud)
norma_temporario_crud, tipo_norma_crud,
NormaTaView)
norma_url_patterns = norma_temporario_crud.urlpatterns
@ -13,6 +15,9 @@ urlpatterns = [
norma_temporario_crud.namespace,
norma_temporario_crud.namespace)),
url(r'^norma/(?P<pk>[0-9]+)/ta$',
NormaTaView.as_view(), name='norma_ta'),
url(r'^sistema/norma/tipo/', include(tipo_norma_crud.urls)),
url(r'^sistema/norma/assunto/', include(assunto_norma_crud.urls)),

39
norma/views.py

@ -4,14 +4,19 @@ from re import sub
from crispy_forms.helper import FormHelper
from crispy_forms.layout import ButtonHolder, Fieldset, Layout, Submit
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse_lazy
from django.forms import ModelForm
from django.shortcuts import get_object_or_404, redirect
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import RedirectView
from django.views.generic.edit import FormMixin
from vanilla import GenericView
from compilacao.models import TextoArticulado, TipoTextoArticulado
from materia.models import MateriaLegislativa, TipoMateriaLegislativa
from sapl.crud import build_crud
import sapl
@ -60,7 +65,7 @@ norma_temporario_crud = build_crud(
NormaJuridica, 'normajuridica', [
[_('Identificação Básica'),
[('tipo_ta', 3), ('tipo', 3), ('numero', 2), ('ano', 2), ('data', 2)],
[('tipo', 5), ('numero', 2), ('ano', 2), ('data', 3)],
[('ementa', 12)]],
])
@ -219,3 +224,35 @@ class NormaIncluirView(FormMixin, GenericView):
return self.form_valid(form)
else:
return self.form_invalid(form)
class NormaTaView(GenericView):
def get(self, *args, **kwargs):
norma = get_object_or_404(NormaJuridica, pk=kwargs['pk'])
related_object_type = ContentType.objects.get_for_model(norma)
ta = TextoArticulado.objects.filter(
object_id=norma.pk,
content_type=related_object_type)
if not ta.exists():
tipo_ta = TipoTextoArticulado.objects.filter(
model=norma.__class__.__name__.lower())[:1]
ta = TextoArticulado()
if tipo_ta.exists():
ta.tipo_ta = tipo_ta[0]
ta.ementa = norma.ementa
ta.numero = norma.numero
ta.ano = norma.ano
ta.data = norma.data
ta.content_object = norma
ta.save()
else:
ta = ta[0]
return redirect(to=reverse_lazy('ta_text', kwargs={'ta_id': ta.pk}))

4
sapl/settings.py

@ -59,8 +59,8 @@ INSTALLED_APPS = (
'crispy_forms_foundation',
'sass_processor',
)
# if DEBUG:
# INSTALLED_APPS += ('debug_toolbar',)
if DEBUG:
INSTALLED_APPS += ('debug_toolbar',)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',

26
static/js/compilacao_notas.js

@ -21,7 +21,7 @@ function onEventsDneExec(pk) {
$('#dne'+pk+" select[name='tipo']").change(function(event) {
var url = '';
url = 'compilacao/'+pk+'/nota/create?action=modelo_nota&id_tipo='+this.value;
url = 'text/'+pk+'/nota/create?action=modelo_nota&id_tipo='+this.value;
$.get(url).done(function( data ) {
$('#dne'+pk+" textarea[name='texto']").val(data);
});
@ -40,9 +40,9 @@ function onEventsDneExec(pk) {
onChangeParamNorma();
}
var onChangeParamNorma = function(event) {
var tipo_norma = $("select[name='tipo_norma']").val();
var num_norma = $("input[name='num_norma']").val();
var ano_norma = $("input[name='ano_norma']").val();
var tipo_ta = $("select[name='tipo_ta']").val();
var num_ta = $("input[name='num_ta']").val();
var ano_ta = $("input[name='ano_ta']").val();
var busca_dispositivo = $("input[name='busca_dispositivo']").val();
var dispositivo_ref = $("#id_dispositivo_ref").val();
$('#id_dispositivo_ref').remove();
@ -51,18 +51,18 @@ var onChangeParamNorma = function(event) {
dispositivo_ref = ''
var url = '';
var pk = $("select[name='tipo_norma']").closest('.dne').attr('pk')
var pk = $("select[name='tipo_ta']").closest('.dne').attr('pk')
var formData = {
'tipo_norma' : tipo_norma,
'num_norma' : num_norma,
'ano_norma' : ano_norma,
'tipo_ta' : tipo_ta,
'num_ta' : num_ta,
'ano_ta' : ano_ta,
'busca' : busca_dispositivo,
'tipo_form' : 'radio',
'initial_ref' : dispositivo_ref
};
url = 'compilacao/search';
url = 'text/search';
$('.container-busca').html('');
insertWaitAjax('.container-busca')
$.get(url, formData).done(function( data ) {
@ -85,7 +85,7 @@ var onSubmitEditForm = function(event) {
}
id_edit = $('#id_pk').val();
url = 'compilacao/'+id_dispositivo+'/'+model+'/'
url = 'text/'+id_dispositivo+'/'+model+'/'
if (id_edit == null || id_edit == '')
url += 'create';
else
@ -119,7 +119,7 @@ var onDelete = function(event) {
var id_dispositivo = $(event).closest('.dn').attr('pk');
var id_delete = $(event).attr('pk');
var url = 'compilacao/'+id_dispositivo+'/'+model+'/'+id_delete+'/delete';
var url = 'text/'+id_dispositivo+'/'+model+'/'+id_delete+'/delete';
$.get( url, function(data) {
$('#dne'+id_dispositivo+' .dne-form').closest('.dpt').html(data)
@ -140,12 +140,12 @@ function getForm(_this) {
if (_this.className.indexOf('create') >= 0 ) {
id_dispositivo = $(_this).attr('pk');
url = 'compilacao/'+id_dispositivo+'/'+model+'/create';
url = 'text/'+id_dispositivo+'/'+model+'/create';
}
else if (_this.className.indexOf('edit') >= 0 ) {
var id_edit = $(_this).attr('pk');
id_dispositivo = $(_this).closest('.dn').attr('pk');
url = 'compilacao/'+id_dispositivo+'/'+model+'/'+id_edit+'/edit'
url = 'text/'+id_dispositivo+'/'+model+'/'+id_edit+'/edit'
}
$('#dne'+id_dispositivo).addClass('dne-nota');

12
static/js/compilacao_view.js

@ -1,7 +1,7 @@
$( window ).scroll(function() {
if (window.pageYOffset <= 180)
$( "section.vigencias" ).removeClass("fixed");
else if (!$( "section.vigencias" ).hasClass("fixed"))
else if ( ! $( "section.vigencias" ).hasClass("fixed") )
$( "section.vigencias" ).addClass("fixed");
});
@ -41,7 +41,7 @@ function textoMultiVigente(item, diff) {
for (var i = 0; i < ldpts.length; i++) {
if ($(ldpts[i]).hasClass('displaynone'))
continue;
if (isElementInViewport( ldpts[i])) {
if (isElementInViewport( ldpts[i])) {
elv = ldpts[i];
break;
}
@ -123,20 +123,20 @@ function textoVigente(item, link) {
for (var i = 0; i < ldpts.length; i++) {
if ($(ldpts[i]).hasClass('displaynone'))
continue;
if (isElementInViewport( ldpts[i])) {
if (isElementInViewport( ldpts[i])) {
elv = ldpts[i];
break;
}
}
$(".cp .tipo-vigencias a").removeClass("selected")
$(item).addClass("selected")
$(".dptt.desativado").addClass("displaynone");
$(".link_alterador").removeClass("displaynone");
if (!link)
$(".link_alterador").addClass("displaynone");
if (elv) {
$('html, body').animate({
scrollTop: $(elv).parent().offset().top - 60

40
templates/compilacao/edit.html → templates/compilacao/text_edit.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "compilacao/textoarticulado_detail.html" %}
{% load i18n %}
{% load compilacao_filters %}
{% load staticfiles %}
@ -17,43 +17,19 @@
<h1><b>Edição:</b> {{ view.get_ta }} - <i>{% trans 'Texto Multivigente' %}</i></h1>
{% endblock %}
{% block base_content %}
{% block sections_nav %}
{% endblock %}
{% block base_content %}{{block.super}}
{% block actions %}{% endblock %}
{% block detail_content %}{% endblock %}
<div id="message_block"><div id="msg">{% trans 'Aguarde... Atualizando informações!!!'%}</div></div>
<div class="cpe">
{% include 'compilacao/edit_bloco.html'%}
{% include 'compilacao/text_edit_bloco.html'%}
</div>
{% if False %}
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% if message %}
<div data-alert="" class="alert-box success radius">
{{message}}
<a href="#" class="close">×</a>
</div>
{% endif %}
<fieldset>
<legend>{% trans 'Parser ODF' %}</legend>
{{ form.as_p }}
<input type="submit" name="import_submit" value="{% trans 'Importar' %}" class="button primary" />
</fieldset>
</form>
{% for parser in parser_list %}
<div class="test_import">
{{ parser|safe}}
</div>
{% endfor %}
{% endif%}
{% endblock base_content %}

2
templates/compilacao/edit_bloco.html → templates/compilacao/text_edit_bloco.html

@ -116,7 +116,7 @@
{% endif %}
{% endspaceless %}
{% if view.is_ta_alterador and dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%}
{%with node=dpt template_name='compilacao/edit_bloco_alteracao.html' %}
{%with node=dpt template_name='compilacao/text_edit_blocoalteracao.html' %}
{%include template_name%}
{%endwith%}
{% endif%}

0
templates/compilacao/edit_bloco_alteracao.html → templates/compilacao/text_edit_blocoalteracao.html

21
templates/compilacao/text_list.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "compilacao/textoarticulado_detail.html" %}
{% load i18n %}
{% load compilacao_filters %}
{% load staticfiles %}
@ -21,15 +21,24 @@
<h1>{{ view.get_ta }}</h1>
{% endblock %}
{% block base_content %}
{% block sections_nav %}{{block.super}}
<dd><a href="{% url 'ta_text_edit' object.pk %}" class="button secondary">{% trans 'Edição do Texto' %}</a></dd>
{% endblock %}
{% block base_content %}{{block.super}}
{% block actions %}{% endblock %}
{% block detail_content %}{% endblock %}
<div class="cp">
<div style="float: right; clear:right;">
<a id="btn_font_menos" title="Diminuir tamanho da letra">a</a>
<a id="btn_font_mais" title="Aumentar tamanho da Letra">A</a>
</div>
{% if object_list %}
<div style="float: right; clear:right;">
<a id="btn_font_menos" title="Diminuir tamanho da letra">a</a>
<a id="btn_font_mais" title="Aumentar tamanho da Letra">A</a>
</div>
{% endif %}
{% for key, values in view.get_vigencias.items %}
{% if forloop.first %}

45
templates/compilacao/textoarticulado_detail.html

@ -1,4 +1,7 @@
{% extends "base.html" %} {% load i18n %} {% load compilacao_filters %} {% block base_content %} {# FIXME is this the best markup to use? #}
{% extends "base.html" %} {% load i18n %} {% load compilacao_filters %}
{% block base_content %} {# FIXME is this the best markup to use? #}
<div class="clearfix">
{% block actions %}
<dl class="sub-nav right">
@ -8,20 +11,16 @@
{% endblock actions %}
{% block sections_nav %}
<dl class="sub-nav left">
<dd><a href="{% url 'ta_detail' object.pk %}" class="button secondary">{% trans 'Início' %}</a></dd>
<dd><a href="{% url 'ta_text' object.pk %}" class="button secondary">{% trans 'Texto' %}</a></dd>
</dl>
{% endblock %}
<dl class="sub-nav left">
{% block sections_nav %}
<dd><a href="{% url 'ta_detail' object.pk %}" class="button secondary">{% trans 'Início' %}</a></dd>
<dd><a href="{% url 'ta_text' object.pk %}" class="button secondary">{% trans 'Texto' %}</a></dd>
{% endblock %}
</dl>
</div>
{% block detail_content %} {# TODO replace fieldset for something semantically correct, but with similar visual grouping style #}
@ -30,14 +29,23 @@
<div class="row">
<div class="columns large-4">
<div class="columns large-3">
<div id="div_id_tipo" class="holder">
<label>{% verbose_name object 'tipo_ta' %}</label>
<p>{{ object.tipo_ta}}</p>
</div>
</div>
<div class="columns large-3">
{% if object.content_object %}
<div class="columns large-3">
<div id="div_id_tipo" class="holder">
<label>{% verbose_name object.content_object 'tipo' %}</label>
<p>{{ object.content_object.tipo}}</p>
</div>
</div>
{%endif%}
<div class="columns large-2">
<div id="div_id_numero" class="holder">
<label>{% verbose_name object 'numero' %}</label>
<p>{{ object.numero}}</p>
@ -51,7 +59,7 @@
</div>
</div>
<div class="columns large-3">
<div class="columns large-2">
<div id="div_id_data" class="holder">
<label>{% verbose_name object 'data' %}</label>
<p>{{ object.data}}</p>
@ -69,8 +77,5 @@
</div>
</fieldset>
</fieldset>
{% endblock detail_content %} {% endblock base_content %}

1
templates/materia/materialegislativa_detail.html

@ -12,5 +12,6 @@
<dd><a href="{% url 'numeracao' materialegislativa.id %}" class="button secondary">{% trans 'Numeração' %}</a></dd>
<dd><a href="{% url 'tramitacao_materia' materialegislativa.id %}" class="button secondary">{% trans 'Tramitação' %}</a></dd>
<dd><a href="{% url 'relatoria' materialegislativa.id %}" class="button secondary">{% trans 'Relatoria' %}</a></dd>
<dd><a href="{% url 'materia_ta' materialegislativa.id %}" class="button secondary">{% trans 'Texto' %}</a></dd>
</dl>
{% endblock sections_nav %}

14
templates/norma/normajuridica_detail.html

@ -1,7 +1,15 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% block actions %} {% endblock %}
{% block actions %}
<dl class="sub-nav right">
<dd><a href="{% url 'ta_edit' object.pk %}" class="button">{% trans 'Editar' %}</a></dd>
<dd><a href="{% url 'ta_delete' object.pk %}" class="button alert">{% trans 'Excluir' %}</a></dd>
</dl>
{% endblock actions %}
{% block sections_nav %}
<dl class="sub-nav left">
</dl>
<dl class="sub-nav left">
<dd><a href="{% url 'normajuridica:detail' object.pk %}" class="button secondary">{% trans 'Início' %}</a></dd>
<dd><a href="{% url 'norma_ta' object.pk %}" class="button secondary">{% trans 'Texto' %}</a></dd>
</dl>
{% endblock sections_nav %}

Loading…
Cancel
Save