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.utils import RANGE_ANOS, RangeWidgetOverride
from .models import AssuntoNorma, NormaJuridica
from .models import (AssuntoNorma, NormaJuridica, NormaRelacionada,
TipoNormaJuridica)
def get_esferas():
@ -146,3 +147,49 @@ class NormaJuridicaForm(ModelForm):
norma.materia = self.cleaned_data['materia']
norma = super(NormaJuridicaForm, self).save(commit=True)
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):
TIPO_VINCULO_CHOICES = (
('A', _('Altera a norma')),
('R', _('Revoga integralmente a norma')),
('P', _('Revoga parcialmente a norma')),
('T', _('Revoga integralmente por consolidação')),
('C', _('Norma correlata')),
('S', _('Ressalva a norma')),
('E', _('Reedita a norma')),
('I', _('Reedita a norma com alteração')),
('G', _('Regulamenta a norma')),
('K', _('Suspende parcialmente a norma')),
('L', _('Suspende integralmente a norma')),
('N', _('Julgada integralmente inconstitucional')),
('O', _('Julgada parcialmente inconstitucional')),
)
sigla = models.CharField(
max_length=1, blank=True, verbose_name=_('Sigla'))
descricao = models.CharField(
max_length=50, blank=True, verbose_name=_('Descrição'))
class Meta:
verbose_name = _('Tipo de Vínculo entre Normas Jurídicas')
verbose_name_plural = _('Tipos de Vínculos entre Normas Jurídicas')
def __str__(self):
return self.descricao
# TODO M2M ???
norma_referente = models.ForeignKey(
NormaJuridica, related_name='norma_referente_set')
norma_referida = models.ForeignKey(
NormaJuridica, related_name='norma_referida_set')
tipo_vinculo = models.CharField(
max_length=1, blank=True, choices=TIPO_VINCULO_CHOICES)
class NormaRelacionada(models.Model):
norma_principal = models.ForeignKey(
NormaJuridica,
related_name='norma_principal',
verbose_name=_('Norma Principal'))
norma_relacionada = models.ForeignKey(
NormaJuridica,
related_name='norma_relacionada',
verbose_name=_('Norma Relacionada'))
tipo_vinculo = models.ForeignKey(
VinculoNormaJuridica, verbose_name=_('Tipo de Vínculo'))
class Meta:
verbose_name = _('Vínculo entre Normas Jurídicas')
verbose_name_plural = _('Vínculos entre Normas Jurídicas')
verbose_name = _('Norma Relacionada')
verbose_name_plural = _('Normas Relacionadas')
def __str__(self):
return _('Referente: %(referente)s \n'
'Referida: %(referida)s \nVínculo: %(vinculo)s') % {
'referente': self.norma_referente,
'referida': self.norma_referida,
'vinculo': self.tipo_vinculo}
return _('Principal: %(norma_principal)s'
' - Relacionada: %(norma_relacionada)s') % {
'norma_principal': self.norma_principal,
'norma_relacionada': self.norma_relacionada}

11
sapl/norma/urls.py

@ -1,7 +1,8 @@
from django.conf.urls import include, url
from sapl.norma.views import (AssuntoNormaCrud, NormaCrud, NormaPesquisaView,
TipoNormaCrud, NormaTaView)
NormaRelacionadaCrud, NormaTaView, TipoNormaCrud,
VinculoNormaJuridicaCrud, recuperar_norma)
from .apps import AppConfig
@ -9,14 +10,20 @@ app_name = AppConfig.name
urlpatterns = [
url(r'^norma/', include(NormaCrud.get_urls())),
url(r'^norma/', include(NormaCrud.get_urls() +
NormaRelacionadaCrud.get_urls())),
# Integração com Compilação
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/assunto/', include(AssuntoNormaCrud.get_urls())),
url(r'^sistema/norma/vinculo/', include(
VinculoNormaJuridicaCrud.get_urls())),
url(r'^norma/pesquisar$',
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 django.core.urlresolvers import reverse
from django.http import JsonResponse
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
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,
MasterDetailCrud, make_pagination)
from .forms import NormaFilterSet, NormaJuridicaForm
from .models import AssuntoNorma, NormaJuridica, TipoNormaJuridica
from .forms import NormaFilterSet, NormaJuridicaForm, NormaRelacionadaForm
from .models import (AssuntoNorma, NormaJuridica, NormaRelacionada,
TipoNormaJuridica, VinculoNormaJuridica)
# LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '')
AssuntoNormaCrud = CrudAux.build(AssuntoNorma, 'assunto_norma_juridica',
@ -23,6 +25,37 @@ AssuntoNormaCrud = CrudAux.build(AssuntoNorma, 'assunto_norma_juridica',
TipoNormaCrud = CrudAux.build(
TipoNormaJuridica, 'tipo_norma_juridica',
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):
@ -129,3 +162,20 @@ class NormaCrud(Crud):
self.initial['ano_materia'] = norma.materia.ano
self.initial['numero_materia'] = norma.materia.numero
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
- capitulo secao subsecao artigo
- 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' %}
url: normajuridica_detail
- title: {% trans 'Normas Relacionadas' %}
url: normarelacionada_list
# Opção adicionada para chamar o TextoArticulado da norma.
# 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>
<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: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>
<hr />

Loading…
Cancel
Save