Browse Source

Merge pull request #814 from interlegis/810-relacionamento-norma

Fix #810 relacionamento norma
pull/822/head
Eduardo Edson Batista Cordeiro Alves 8 years ago
committed by GitHub
parent
commit
9da4b33a18
  1. 49
      sapl/norma/forms.py
  2. 41
      sapl/norma/migrations/0023_auto_20161123_1359.py
  3. 25
      sapl/norma/migrations/0024_auto_20161123_1430.py
  4. 29
      sapl/norma/migrations/0025_normarelacionada.py
  5. 21
      sapl/norma/migrations/0026_auto_20161123_1450.py
  6. 26
      sapl/norma/migrations/0027_auto_20161123_1538.py
  7. 58
      sapl/norma/models.py
  8. 11
      sapl/norma/urls.py
  9. 54
      sapl/norma/views.py
  10. 15
      sapl/templates/norma/layouts.yaml
  11. 27
      sapl/templates/norma/normarelacionada_form.html
  12. 2
      sapl/templates/norma/subnav.yaml
  13. 3
      sapl/templates/sistema.html

49
sapl/norma/forms.py

@ -14,7 +14,8 @@ from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa
from sapl.settings import MAX_DOC_UPLOAD_SIZE from sapl.settings import MAX_DOC_UPLOAD_SIZE
from sapl.utils import RANGE_ANOS, RangeWidgetOverride from sapl.utils import RANGE_ANOS, RangeWidgetOverride
from .models import AssuntoNorma, NormaJuridica from .models import (AssuntoNorma, NormaJuridica, NormaRelacionada,
TipoNormaJuridica)
def get_esferas(): def get_esferas():
@ -146,3 +147,49 @@ class NormaJuridicaForm(ModelForm):
norma.materia = self.cleaned_data['materia'] norma.materia = self.cleaned_data['materia']
norma = super(NormaJuridicaForm, self).save(commit=True) norma = super(NormaJuridicaForm, self).save(commit=True)
return norma return norma
class NormaRelacionadaForm(ModelForm):
tipo = forms.ModelChoiceField(
label='Tipo',
required=True,
queryset=TipoNormaJuridica.objects.all(),
empty_label='----------',
)
numero = forms.CharField(label='Número', required=True)
ano = forms.CharField(label='Ano', required=True)
ementa = forms.CharField(
required=False,
widget=forms.Textarea(attrs={'disabled': 'disabled'}))
class Meta:
model = NormaRelacionada
fields = ['tipo', 'numero', 'ano', 'ementa', 'tipo_vinculo']
def __init__(self, *args, **kwargs):
super(NormaRelacionadaForm, self).__init__(*args, **kwargs)
def clean(self):
if self.errors:
return self.errors
cleaned_data = self.cleaned_data
try:
norma_relacionada = NormaJuridica.objects.get(
numero=cleaned_data['numero'],
ano=cleaned_data['ano'],
tipo=cleaned_data['tipo'])
except ObjectDoesNotExist:
msg = _('A norma a ser relacionada não existe.')
raise ValidationError(msg)
else:
cleaned_data['norma_relacionada'] = norma_relacionada
return cleaned_data
def save(self, commit=False):
relacionada = super(NormaRelacionadaForm, self).save(commit)
relacionada.norma_relacionada = self.cleaned_data['norma_relacionada']
relacionada.save()
return relacionada

41
sapl/norma/migrations/0023_auto_20161123_1359.py

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-11-23 13:59
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('norma', '0022_auto_20161110_0910'),
]
operations = [
migrations.AlterModelOptions(
name='vinculonormajuridica',
options={'verbose_name': 'Tipo de Vínculo entre Normas Jurídicas', 'verbose_name_plural': 'Tipos de Vínculos entre Normas Jurídicas'},
),
migrations.RemoveField(
model_name='vinculonormajuridica',
name='norma_referente',
),
migrations.RemoveField(
model_name='vinculonormajuridica',
name='norma_referida',
),
migrations.RemoveField(
model_name='vinculonormajuridica',
name='tipo_vinculo',
),
migrations.AddField(
model_name='vinculonormajuridica',
name='descricao',
field=models.CharField(blank=True, max_length=20, verbose_name='Descrição'),
),
migrations.AddField(
model_name='vinculonormajuridica',
name='sigla',
field=models.CharField(blank=True, max_length=1, verbose_name='Nome'),
),
]

25
sapl/norma/migrations/0024_auto_20161123_1430.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-11-23 14:30
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('norma', '0023_auto_20161123_1359'),
]
operations = [
migrations.AlterField(
model_name='vinculonormajuridica',
name='descricao',
field=models.CharField(blank=True, max_length=50, verbose_name='Descrição'),
),
migrations.AlterField(
model_name='vinculonormajuridica',
name='sigla',
field=models.CharField(blank=True, max_length=1, verbose_name='Sigla'),
),
]

29
sapl/norma/migrations/0025_normarelacionada.py

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-11-23 14:44
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('norma', '0024_auto_20161123_1430'),
]
operations = [
migrations.CreateModel(
name='NormaRelacionada',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('norma_principal', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='norma_principal', to='norma.NormaJuridica')),
('norma_relacionada', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='norma_relacionada', to='norma.NormaJuridica')),
('tipo_vinculo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='norma.VinculoNormaJuridica')),
],
options={
'verbose_name': 'Norma Relacionada',
'verbose_name_plural': 'Normas Relacionadas',
},
),
]

21
sapl/norma/migrations/0026_auto_20161123_1450.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-11-23 14:50
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('norma', '0025_normarelacionada'),
]
operations = [
migrations.AlterField(
model_name='normarelacionada',
name='tipo_vinculo',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='norma.VinculoNormaJuridica', verbose_name='Tipo de Vínculo'),
),
]

26
sapl/norma/migrations/0027_auto_20161123_1538.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-11-23 15:38
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('norma', '0026_auto_20161123_1450'),
]
operations = [
migrations.AlterField(
model_name='normarelacionada',
name='norma_principal',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='norma_principal', to='norma.NormaJuridica', verbose_name='Norma Principal'),
),
migrations.AlterField(
model_name='normarelacionada',
name='norma_relacionada',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='norma_relacionada', to='norma.NormaJuridica', verbose_name='Norma Relacionada'),
),
]

58
sapl/norma/models.py

@ -171,37 +171,37 @@ class LegislacaoCitada(models.Model):
class VinculoNormaJuridica(models.Model): class VinculoNormaJuridica(models.Model):
TIPO_VINCULO_CHOICES = ( sigla = models.CharField(
('A', _('Altera a norma')), max_length=1, blank=True, verbose_name=_('Sigla'))
('R', _('Revoga integralmente a norma')), descricao = models.CharField(
('P', _('Revoga parcialmente a norma')), max_length=50, blank=True, verbose_name=_('Descrição'))
('T', _('Revoga integralmente por consolidação')),
('C', _('Norma correlata')), class Meta:
('S', _('Ressalva a norma')), verbose_name = _('Tipo de Vínculo entre Normas Jurídicas')
('E', _('Reedita a norma')), verbose_name_plural = _('Tipos de Vínculos entre Normas Jurídicas')
('I', _('Reedita a norma com alteração')),
('G', _('Regulamenta a norma')), def __str__(self):
('K', _('Suspende parcialmente a norma')), return self.descricao
('L', _('Suspende integralmente a norma')),
('N', _('Julgada integralmente inconstitucional')),
('O', _('Julgada parcialmente inconstitucional')),
)
# TODO M2M ??? class NormaRelacionada(models.Model):
norma_referente = models.ForeignKey( norma_principal = models.ForeignKey(
NormaJuridica, related_name='norma_referente_set') NormaJuridica,
norma_referida = models.ForeignKey( related_name='norma_principal',
NormaJuridica, related_name='norma_referida_set') verbose_name=_('Norma Principal'))
tipo_vinculo = models.CharField( norma_relacionada = models.ForeignKey(
max_length=1, blank=True, choices=TIPO_VINCULO_CHOICES) NormaJuridica,
related_name='norma_relacionada',
verbose_name=_('Norma Relacionada'))
tipo_vinculo = models.ForeignKey(
VinculoNormaJuridica, verbose_name=_('Tipo de Vínculo'))
class Meta: class Meta:
verbose_name = _('Vínculo entre Normas Jurídicas') verbose_name = _('Norma Relacionada')
verbose_name_plural = _('Vínculos entre Normas Jurídicas') verbose_name_plural = _('Normas Relacionadas')
def __str__(self): def __str__(self):
return _('Referente: %(referente)s \n' return _('Principal: %(norma_principal)s'
'Referida: %(referida)s \nVínculo: %(vinculo)s') % { ' - Relacionada: %(norma_relacionada)s') % {
'referente': self.norma_referente, 'norma_principal': self.norma_principal,
'referida': self.norma_referida, 'norma_relacionada': self.norma_relacionada}
'vinculo': self.tipo_vinculo}

11
sapl/norma/urls.py

@ -1,7 +1,8 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from sapl.norma.views import (AssuntoNormaCrud, NormaCrud, NormaPesquisaView, from sapl.norma.views import (AssuntoNormaCrud, NormaCrud, NormaPesquisaView,
TipoNormaCrud, NormaTaView) NormaRelacionadaCrud, NormaTaView, TipoNormaCrud,
VinculoNormaJuridicaCrud, recuperar_norma)
from .apps import AppConfig from .apps import AppConfig
@ -9,14 +10,20 @@ app_name = AppConfig.name
urlpatterns = [ urlpatterns = [
url(r'^norma/', include(NormaCrud.get_urls())), url(r'^norma/', include(NormaCrud.get_urls() +
NormaRelacionadaCrud.get_urls())),
# Integração com Compilação # Integração com Compilação
url(r'^norma/(?P<pk>[0-9]+)/ta$', NormaTaView.as_view(), name='norma_ta'), url(r'^norma/(?P<pk>[0-9]+)/ta$', NormaTaView.as_view(), name='norma_ta'),
url(r'^sistema/norma/tipo/', include(TipoNormaCrud.get_urls())), url(r'^sistema/norma/tipo/', include(TipoNormaCrud.get_urls())),
url(r'^sistema/norma/assunto/', include(AssuntoNormaCrud.get_urls())), url(r'^sistema/norma/assunto/', include(AssuntoNormaCrud.get_urls())),
url(r'^sistema/norma/vinculo/', include(
VinculoNormaJuridicaCrud.get_urls())),
url(r'^norma/pesquisar$', url(r'^norma/pesquisar$',
NormaPesquisaView.as_view(), name='norma_pesquisa'), NormaPesquisaView.as_view(), name='norma_pesquisa'),
url(r'^norma/recuperar-norma/', recuperar_norma),
] ]

54
sapl/norma/views.py

@ -1,6 +1,7 @@
from datetime import datetime from datetime import datetime
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import JsonResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import FormView, ListView from django.views.generic import FormView, ListView
@ -12,8 +13,9 @@ from sapl.compilacao.views import IntegracaoTaView
from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux,
MasterDetailCrud, make_pagination) MasterDetailCrud, make_pagination)
from .forms import NormaFilterSet, NormaJuridicaForm from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm
from .models import AssuntoNorma, NormaJuridica, TipoNormaJuridica from .models import (AssuntoNorma, NormaJuridica, NormaRelacionada,
TipoNormaJuridica, VinculoNormaJuridica)
# LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '') # LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '')
AssuntoNormaCrud = CrudAux.build(AssuntoNorma, 'assunto_norma_juridica', AssuntoNormaCrud = CrudAux.build(AssuntoNorma, 'assunto_norma_juridica',
@ -23,6 +25,37 @@ AssuntoNormaCrud = CrudAux.build(AssuntoNorma, 'assunto_norma_juridica',
TipoNormaCrud = CrudAux.build( TipoNormaCrud = CrudAux.build(
TipoNormaJuridica, 'tipo_norma_juridica', TipoNormaJuridica, 'tipo_norma_juridica',
list_field_names=['sigla', 'descricao', 'equivalente_lexml']) list_field_names=['sigla', 'descricao', 'equivalente_lexml'])
VinculoNormaJuridicaCrud = CrudAux.build(
VinculoNormaJuridica, '', list_field_names=['sigla', 'descricao'])
class NormaRelacionadaCrud(MasterDetailCrud):
model = NormaRelacionada
parent_field = 'norma_principal'
help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['norma_relacionada']
class CreateView(MasterDetailCrud.CreateView):
form_class = NormaRelacionadaForm
class UpdateView(MasterDetailCrud.UpdateView):
form_class = NormaRelacionadaForm
def get_initial(self):
self.initial['tipo'] = self.object.norma_relacionada.tipo.id
self.initial['numero'] = self.object.norma_relacionada.numero
self.initial['ano'] = self.object.norma_relacionada.ano
self.initial['ementa'] = self.object.norma_relacionada.ementa
return self.initial
class DetailView(MasterDetailCrud.DetailView):
@property
def layout_key(self):
return 'NormaRelacionadaDetail'
class NormaPesquisaView(FilterView): class NormaPesquisaView(FilterView):
@ -129,3 +162,20 @@ class NormaCrud(Crud):
self.initial['ano_materia'] = norma.materia.ano self.initial['ano_materia'] = norma.materia.ano
self.initial['numero_materia'] = norma.materia.numero self.initial['numero_materia'] = norma.materia.numero
return self.initial.copy() return self.initial.copy()
def recuperar_norma(request):
tipo = TipoNormaJuridica.objects.get(pk=request.GET['tipo'])
numero = request.GET['numero']
ano = request.GET['ano']
try:
norma = NormaJuridica.objects.get(tipo=tipo,
ano=ano,
numero=numero)
response = JsonResponse({'ementa': norma.ementa,
'id': norma.id})
except ObjectDoesNotExist:
response = JsonResponse({'ementa': '', 'id': 0})
return response

15
sapl/templates/norma/layouts.yaml

@ -49,3 +49,18 @@ LegislacaoCitadaDetail:
- disposicoes parte livro titulo - disposicoes parte livro titulo
- capitulo secao subsecao artigo - capitulo secao subsecao artigo
- paragrafo inciso alinea item - paragrafo inciso alinea item
VinculoNormaJuridica:
{% trans 'Tipo de Vínculo entre Normas Jurídicas' %}:
- sigla:2 descricao
NormaRelacionada:
{% trans 'Norma Relacionada' %}:
- tipo numero ano
- tipo_vinculo
- ementa
NormaRelacionadaDetail:
{% trans 'Norma Relacionada' %}:
- norma_relacionada
- tipo_vinculo

27
sapl/templates/norma/normarelacionada_form.html

@ -0,0 +1,27 @@
{% extends "crud/form.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% load common_tags %}
{% block extra_js %}
<script language="Javascript">
function recuperar_norma() {
var tipo = $("#id_tipo").val()
var numero = $("#id_numero").val()
var ano = $("#id_ano").val()
if (tipo && numero && ano) {
$.get("/norma/recuperar-norma",{tipo: tipo,
numero: numero,
ano: ano},
function(data, status) {
$("#id_ementa").val(data.ementa);
});
}
}
var fields = ["#id_tipo", "#id_numero", "#id_ano"]
for (i = 0; i < fields.length; i++) {
$(fields[i]).change(recuperar_norma);
}
</script>
{% endblock %}

2
sapl/templates/norma/subnav.yaml

@ -2,6 +2,8 @@
- title: {% trans 'Início' %} - title: {% trans 'Início' %}
url: normajuridica_detail url: normajuridica_detail
- title: {% trans 'Normas Relacionadas' %}
url: normarelacionada_list
# Opção adicionada para chamar o TextoArticulado da norma. # Opção adicionada para chamar o TextoArticulado da norma.
# para integração foram necessárias apenas criar a url norma_ta em urls.py # para integração foram necessárias apenas criar a url norma_ta em urls.py

3
sapl/templates/sistema.html

@ -70,7 +70,8 @@
<h2>Módulo Normas Jurídicas</h2> <h2>Módulo Normas Jurídicas</h2>
<div class="row"> <div class="row">
<div class="col-md-6"><a href="{% url 'sapl.norma:tiponormajuridica_list' %}" class="btn btn-link">Tipo de Norma Jurídica</a></div> <div class="col-md-6"><a href="{% url 'sapl.norma:tiponormajuridica_list' %}" class="btn btn-link">Tipo de Norma Jurídica</a></div>
<div class="col-md-6"><a href="{% url 'sapl.norma:assuntonorma_list' %}" class="btn btn-link">Assunto de Norma Jurídica</a></div> <div class="col-md-6"><a href="{% url 'sapl.norma:assuntonorma_list' %}" class="btn btn-link">Assunto de Norma Jurídica</a></div>
<div class="col-md-6"><a href="{% url 'sapl.norma:vinculonormajuridica_list' %}" class="btn btn-link">Tipo de Vínculo</a></div>
</div> </div>
<hr /> <hr />

Loading…
Cancel
Save