diff --git a/compilacao/forms.py b/compilacao/forms.py
index eed197ca4..cb854f9af 100644
--- a/compilacao/forms.py
+++ b/compilacao/forms.py
@@ -1,20 +1,24 @@
-from crispy_forms.bootstrap import FieldWithButtons, FormActions, StrictButton
+from crispy_forms.bootstrap import FieldWithButtons, FormActions, StrictButton,\
+ InlineRadios, Alert
from crispy_forms.helper import FormHelper
from crispy_forms.layout import (HTML, Button, Column, Div, Field, Fieldset,
Layout, Row)
from django import forms
from django.core.exceptions import NON_FIELD_ERRORS
from django.forms.models import ModelForm
+from django.template import defaultfilters
from django.utils.translation import ugettext_lazy as _
from compilacao.models import (NOTAS_PUBLICIDADE_CHOICES,
PARTICIPACAO_SOCIAL_CHOICES, Dispositivo, Nota,
Publicacao, TextoArticulado, TipoNota,
TipoPublicacao, TipoTextoArticulado, TipoVide,
- VeiculoPublicacao, Vide)
+ VeiculoPublicacao, Vide, TipoDispositivo)
from crispy_layout_mixin import SaplFormLayout, to_column, to_row
+from sapl import utils
from sapl.utils import YES_NO_CHOICES
+
error_messages = {
'required': _('Este campo é obrigatório'),
'invalid': _('URL inválida.')
@@ -257,6 +261,10 @@ class NotaForm(ModelForm):
super(NotaForm, self).__init__(*args, **kwargs)
+class DispositivoSearchFragmentForm(ModelForm):
+ pass
+
+
class VideForm(ModelForm):
dispositivo_base = forms.ModelChoiceField(
queryset=Dispositivo.objects.all(),
@@ -343,7 +351,7 @@ class VideForm(ModelForm):
'números ou algo'
' que estejam '
'no rótulo ou no texto.')),
- StrictButton("Buscar", css_class='btn-busca')), 12))),
+ StrictButton(_('Buscar'), css_class='btn-busca')), 12))),
Row(to_column(
(Div(css_class='container-busca'), 12)))
)
@@ -482,82 +490,156 @@ class DispositivoIntegerField(forms.IntegerField):
class DispositivoEdicaoBasicaForm(ModelForm):
- texto = forms.CharField(
- widget=forms.Textarea,
- required=False)
+ class Meta:
+ model = Dispositivo
+ fields = []
+
+ def __init__(self, *args, **kwargs):
+
+ layout = []
+
+ inst = kwargs['instance'] if 'instance' in kwargs else None
+
+ if inst and inst.tipo_dispositivo.formato_variacao0 in [
+ TipoDispositivo.FNC8, TipoDispositivo.FNCN]:
+ if 'rotulo' in DispositivoEdicaoBasicaForm.Meta.fields:
+ DispositivoEdicaoBasicaForm.Meta.fields.remove('rotulo')
+ for i in range(6):
+ DispositivoEdicaoBasicaForm.Meta.fields.remove(
+ 'dispositivo%s' % i)
+ else:
+ if 'rotulo' not in DispositivoEdicaoBasicaForm.Meta.fields:
+ DispositivoEdicaoBasicaForm.Meta.fields.append('rotulo')
+ for i in range(6):
+ DispositivoEdicaoBasicaForm.Meta.fields.append(
+ 'dispositivo%s' % i)
+ # adiciona campos de rótulo no formulário
+ self.dispositivo0 = forms.IntegerField(
+ min_value=0,
+ label=Dispositivo._meta.get_field('dispositivo0').verbose_name,
+ widget=forms.NumberInput(
+ attrs={'title': _('Valor 0(zero) é permitido apenas para '
+ 'Dispositivos com tipos variáveis.'),
+ 'onchange': 'atualizaRotulo()'}))
+ self.dispositivo1 = DispositivoIntegerField(
+ label=('1ª %s' % _('Variação')),
+ field_name='dispositivo1')
+ self.dispositivo2 = DispositivoIntegerField(
+ label=('2ª'),
+ field_name='dispositivo2')
+ self.dispositivo3 = DispositivoIntegerField(
+ label=('3ª'),
+ field_name='dispositivo3')
+ self.dispositivo4 = DispositivoIntegerField(
+ label=('4ª'),
+ field_name='dispositivo4')
+ self.dispositivo5 = DispositivoIntegerField(
+ label=('5ª'),
+ field_name='dispositivo5')
+
+ self.rotulo = forms.CharField(
+ required=False, label=_('Rótulo Resultante'))
+
+ rotulo_fieldset = to_row([
+ ('dispositivo0', 3),
+ ('dispositivo1', 2),
+ ('dispositivo2', 1),
+ ('dispositivo3', 1),
+ ('dispositivo4', 1),
+ ('dispositivo5', 1),
+ ('rotulo', 3)])
+
+ layout.append(Fieldset(_('Construção do Rótulo'), rotulo_fieldset,
+ css_class="col-md-12"))
+
+ if inst and inst.tipo_dispositivo.dispositivo_de_articulacao:
+ if 'texto' in DispositivoEdicaoBasicaForm.Meta.fields:
+ DispositivoEdicaoBasicaForm.Meta.fields.remove('texto')
+ else:
+ if 'texto' not in DispositivoEdicaoBasicaForm.Meta.fields:
+ DispositivoEdicaoBasicaForm.Meta.fields.append('texto')
+
+ self.texto = forms.CharField(required=False,
+ label='',
+ widget=forms.Textarea())
+ row_texto = to_row([('texto', 12)])
+ layout.append(
+ Fieldset(Dispositivo._meta.get_field('texto').verbose_name,
+ row_texto,
+ css_class="col-md-12"))
+
+ fields = DispositivoEdicaoBasicaForm.Meta.fields
+ if fields:
+ self.base_fields.clear()
+ for f in fields:
+ self.base_fields.update({f: getattr(self, f)})
- dispositivo1 = DispositivoIntegerField(
- label=('1ª %s' % _('Variação')),
- field_name='dispositivo1')
- dispositivo2 = DispositivoIntegerField(
- label=('2ª'),
- field_name='dispositivo2')
- dispositivo3 = DispositivoIntegerField(
- label=('3ª'),
- field_name='dispositivo3')
- dispositivo4 = DispositivoIntegerField(
- label=('4ª'),
- field_name='dispositivo4')
- dispositivo5 = DispositivoIntegerField(
- label=('5ª'),
- field_name='dispositivo5')
-
- rotulo = forms.CharField(label=_('Rótulo Resultante'))
+ self.helper = FormHelper()
+ self.helper.layout = SaplFormLayout(
+ *layout,
+ label_cancel=_('Retornar para o Editor Sequencial'))
+
+ super(DispositivoEdicaoBasicaForm, self).__init__(*args, **kwargs)
+
+
+class DispositivoEdicaoVigenciaForm(ModelForm):
+
+ inconstitucionalidade = forms.ChoiceField(
+ label=Dispositivo._meta.get_field(
+ 'inconstitucionalidade').verbose_name,
+ choices=utils.YES_NO_CHOICES,
+ widget=forms.RadioSelect())
class Meta:
model = Dispositivo
- fields = (
- 'dispositivo0',
- 'dispositivo1',
- 'dispositivo2',
- 'dispositivo3',
- 'dispositivo4',
- 'dispositivo5',
- 'rotulo',
- 'texto')
-
- widgets = {
- 'dispositivo0': forms.NumberInput(
- attrs={'title': _('Valor 0(zero) é permitido apenas '
- 'para Dispositivos com tipos variáveis.'),
- 'onchange': 'atualizaRotulo()'})}
+ fields = ['inicio_vigencia',
+ 'fim_vigencia',
+ 'inicio_eficacia',
+ 'fim_eficacia',
+ 'publicacao',
+ 'inconstitucionalidade'
+ ]
def __init__(self, *args, **kwargs):
layout = []
- rotulo_fieldset = to_row([
- ('dispositivo0', 3),
- ('dispositivo1', 2),
- ('dispositivo2', 1),
- ('dispositivo3', 1),
- ('dispositivo4', 1),
- ('dispositivo5', 1),
- ('rotulo', 3)
- ])
+ row_publicacao = to_row([
+ ('publicacao', 6),
+ (InlineRadios('inconstitucionalidade'), 3), ])
+ row_publicacao.fields.append(
+ Alert(
+ css_class='alert-info col-md-3',
+ content='%s%s' % (
+ _('Dica!'), _('Inclua uma Nota de Dispositivo informando '
+ 'sobre a Inconstitucionalidade.'))))
layout.append(
- Fieldset(
- _('Montagem do Rótulo'),
- rotulo_fieldset,
- css_class="col-md-12"))
-
- # Campo Texto
- row_texto = to_row([('texto', 12)])
- css_class_texto = "col-md-12"
- if 'instance' in kwargs and\
- kwargs['instance'].tipo_dispositivo.dispositivo_de_articulacao:
- css_class_texto = "col-md-12 hidden"
+ Fieldset(_('Registro de Publicação e Validade'),
+ row_publicacao,
+ css_class="col-md-12"))
+
+ row_datas = to_row([
+ ('inicio_vigencia', 3),
+ ('fim_vigencia', 3),
+ ('inicio_eficacia', 3),
+ ('fim_eficacia', 3), ])
layout.append(
- Fieldset(
- Dispositivo._meta.get_field('texto').verbose_name,
- row_texto,
- css_class=css_class_texto))
+ Fieldset(_('Datas de Controle de Vigência'),
+ row_datas,
+ css_class="col-md-12"))
self.helper = FormHelper()
- if layout:
- self.helper.layout = SaplFormLayout(*layout)
- else:
- self.helper.layout = SaplFormLayout()
-
- super(DispositivoEdicaoBasicaForm, self).__init__(*args, **kwargs)
+ self.helper.layout = SaplFormLayout(
+ *layout,
+ label_cancel=_('Retornar para o Editor Sequencial'))
+
+ super(DispositivoEdicaoVigenciaForm, self).__init__(*args, **kwargs)
+
+ pubs = Publicacao.objects.order_by(
+ '-data', '-hora').filter(ta=self.instance.ta)
+ self.fields['publicacao'].choices = [("", "---------")] + [(
+ p.pk, _('%s realizada em %s') % (
+ p.tipo_publicacao,
+ defaultfilters.date(
+ p.data, "d \d\e F \d\e Y"))) for p in pubs]
diff --git a/compilacao/models.py b/compilacao/models.py
index 026b4496e..f9bfb61ff 100644
--- a/compilacao/models.py
+++ b/compilacao/models.py
@@ -556,7 +556,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
texto = models.TextField(
blank=True,
default='',
- verbose_name=_('Texto na Norma Original'))
+ verbose_name=_('Texto Original'))
texto_atualizador = models.TextField(
blank=True,
default='',
@@ -575,7 +575,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
inconstitucionalidade = models.BooleanField(
default=False,
choices=utils.YES_NO_CHOICES,
- verbose_name=_('Declaração de Inconstitucionalidade'))
+ verbose_name=_('Declarado Inconstitucional'))
# Relevant attribute only in altering norms
visibilidade = models.BooleanField(
default=False,
diff --git a/compilacao/urls.py b/compilacao/urls.py
index d70445d2a..0d48376b1 100644
--- a/compilacao/urls.py
+++ b/compilacao/urls.py
@@ -33,9 +33,13 @@ urlpatterns_compilacao = [
url(r'^(?P[0-9]+)/text/(?P[0-9]+)/refresh',
views.DispositivoSimpleEditView.as_view(), name='dispositivo_refresh'),
- url(r'^(?P[0-9]+)/text/(?P[0-9]+)/edit',
+ url(r'^(?P[0-9]+)/text/(?P[0-9]+)/edit$',
views.DispositivoEdicaoBasicaView.as_view(), name='dispositivo_edit'),
+ url(r'^(?P[0-9]+)/text/(?P[0-9]+)/edit/vigencia',
+ views.DispositivoEdicaoVigenciaView.as_view(),
+ name='dispositivo_edit_vigencia'),
+
url(r'^(?P[0-9]+)/text/(?P[0-9]+)/actions',
diff --git a/compilacao/views.py b/compilacao/views.py
index f631d48bc..62bdd32f4 100644
--- a/compilacao/views.py
+++ b/compilacao/views.py
@@ -1,6 +1,6 @@
-import sys
from collections import OrderedDict
from datetime import datetime, timedelta
+import sys
from braces.views import FormMessagesMixin
from django import forms
@@ -21,7 +21,8 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.views.generic.list import ListView
from compilacao.forms import (DispositivoEdicaoBasicaForm, NotaForm,
- PublicacaoForm, TaForm, TipoTaForm, VideForm)
+ PublicacaoForm, TaForm, TipoTaForm, VideForm,
+ DispositivoEdicaoVigenciaForm)
from compilacao.models import (Dispositivo, Nota,
PerfilEstruturalTextoArticulado, Publicacao,
TextoArticulado, TipoDispositivo, TipoNota,
@@ -29,6 +30,7 @@ from compilacao.models import (Dispositivo, Nota,
VeiculoPublicacao, Vide)
from crud.base import Crud, CrudListView, make_pagination
+
DISPOSITIVO_SELECT_RELATED = (
'tipo_dispositivo',
'ta_publicado',
@@ -1772,12 +1774,6 @@ class VideDeleteView(VideMixin, TemplateView):
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 = ''
@@ -2003,8 +1999,8 @@ class DispositivoEdicaoBasicaView(UpdateView):
'compilacao:dispositivo_edit',
kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']})
- def get_context_data(self, **kwargs):
- return UpdateView.get_context_data(self, **kwargs)
+ def get_url_this_view(self):
+ return 'compilacao:dispositivo_edit'
def run_actions(self, request):
if 'action' in request.GET and\
@@ -2018,10 +2014,32 @@ class DispositivoEdicaoBasicaView(UpdateView):
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}, 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, ''
@@ -2032,3 +2050,27 @@ class DispositivoEdicaoBasicaView(UpdateView):
return render_json_response
return UpdateView.get(self, request, *args, **kwargs)
+
+
+class DispositivoEdicaoVigenciaView(DispositivoEdicaoBasicaView):
+ model = Dispositivo
+ form_class = DispositivoEdicaoVigenciaForm
+
+ 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']})
+
+ def run_actions(self, request):
+ if 'action' in request.GET and\
+ request.GET['action'] == 'atualiza_rotulo':
+ try:
+ pass
+ except:
+ return True, JsonResponse({'message': str(
+ _('Ocorreu erro na atualização do rótulo'))}, safe=False)
+ return True, JsonResponse({}, safe=False)
+ return False, ''
diff --git a/crispy_layout_mixin.py b/crispy_layout_mixin.py
index 46dadf7a7..c812b4315 100644
--- a/crispy_layout_mixin.py
+++ b/crispy_layout_mixin.py
@@ -1,11 +1,11 @@
from math import ceil
from os.path import dirname, join
-import rtyaml
from crispy_forms.bootstrap import FormActions
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit
from django.utils.translation import ugettext as _
+import rtyaml
def heads_and_tails(list_of_lists):
@@ -39,10 +39,10 @@ def form_actions(more=[], save_label=_('Salvar')):
class SaplFormLayout(Layout):
- def __init__(self, *fields):
+ def __init__(self, *fields, label_cancel=_('Cancelar')):
buttons = form_actions(more=[
HTML('%s' % _('Cancelar'))])
+ ' class="btn btn-inverse">%s' % label_cancel)])
_fields = list(to_fieldsets(fields)) + [to_row([(buttons, 12)])]
super(SaplFormLayout, self).__init__(*_fields)
diff --git a/templates/compilacao/dispositivo_form.html b/templates/compilacao/dispositivo_form.html
index cb17c9cfa..1c5350be9 100644
--- a/templates/compilacao/dispositivo_form.html
+++ b/templates/compilacao/dispositivo_form.html
@@ -7,6 +7,16 @@
{% block head_content %}{{block.super}}
{% endblock %}
+{% block sections_nav %}
+
+{% endblock sections_nav %}
{% block title %}
{{object.ta}}
{% trans 'Edição de Dispositivo' %}
@@ -52,6 +62,12 @@
$.get(url, formData).done(function(data) {
if (data.rotulo != undefined) {
$('[name="rotulo"]').val(data.rotulo);
+ $('[name="dispositivo0"]').val(data.dispositivo0);
+ $('[name="dispositivo1"]').val(data.dispositivo1);
+ $('[name="dispositivo2"]').val(data.dispositivo2);
+ $('[name="dispositivo3"]').val(data.dispositivo3);
+ $('[name="dispositivo4"]').val(data.dispositivo4);
+ $('[name="dispositivo5"]').val(data.dispositivo5);
return;
}
});
diff --git a/templates/compilacao/dispositivo_form_parents.html b/templates/compilacao/dispositivo_form_parents.html
index 7006d2581..09d1c2cf1 100644
--- a/templates/compilacao/dispositivo_form_parents.html
+++ b/templates/compilacao/dispositivo_form_parents.html
@@ -2,13 +2,13 @@
{% load compilacao_filters %}
{% if not node.dispositivos_filhos_set.exists %}
-
+
{{node|nomenclatura}}
{% else %}