Browse Source

3263 normas compiladas com pendencia (#3285)

* alterações automáticas da IDE

* insere listagem de normas que possuem TAs não publicados

* Fix: #3263

* ajusta listagem e link para pendência

* transfere acesso para navbar e add outras 2 opcoes
pull/3287/head
Leandro Roberto Silva 4 years ago
committed by GitHub
parent
commit
fc160cb75c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 31
      sapl/crud/base.py
  2. 62
      sapl/norma/models.py
  3. 59
      sapl/norma/views.py
  4. 12
      sapl/templates/navbar.yaml
  5. 4
      sapl/templates/norma/normajuridica_filter.html
  6. 9
      sapl/templates/norma/normajuridica_list.html

31
sapl/crud/base.py

@ -9,11 +9,11 @@ from django.conf.urls import url
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.urls import reverse
from django.db import models from django.db import models
from django.db.models.fields.related import ForeignKey, ManyToManyField from django.db.models.fields.related import ForeignKey, ManyToManyField
from django.http.response import Http404 from django.http.response import Http404
from django.shortcuts import redirect from django.shortcuts import redirect
from django.urls import reverse
from django.utils.decorators import classonlymethod from django.utils.decorators import classonlymethod
from django.utils.encoding import force_text from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -29,6 +29,7 @@ from sapl.rules.map_rules import (RP_ADD, RP_CHANGE, RP_DELETE, RP_DETAIL,
RP_LIST) RP_LIST)
from sapl.utils import normalize from sapl.utils import normalize
logger = logging.getLogger(settings.BASE_DIR.name) logger = logging.getLogger(settings.BASE_DIR.name)
ACTION_LIST, ACTION_CREATE, ACTION_DETAIL, ACTION_UPDATE, ACTION_DELETE = \ ACTION_LIST, ACTION_CREATE, ACTION_DETAIL, ACTION_UPDATE, ACTION_DELETE = \
@ -79,6 +80,7 @@ def make_pagination(index, num_pages):
head = from_to(1, PAGINATION_LENGTH - len(tail) - 1) head = from_to(1, PAGINATION_LENGTH - len(tail) - 1)
return head + [None] + tail return head + [None] + tail
""" """
variáveis do crud: variáveis do crud:
help_topic help_topic
@ -416,16 +418,18 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView):
for f in fn: for f in fn:
if not f: if not f:
continue continue
f = m._meta.get_field(f) try:
if hasattr(f, 'related_model') and f.related_model: f = m._meta.get_field(f)
m = f.related_model if hasattr(f, 'related_model') and f.related_model:
if f: m = f.related_model
hook = 'hook_header_{}'.format(''.join(fn)) except:
if hasattr(self, hook): f = None
header = getattr(self, hook)() hook = 'hook_header_{}'.format(''.join(fn))
s.append(header) if hasattr(self, hook):
else: header = getattr(self, hook)()
s.append(force_text(f.verbose_name)) s.append(header)
elif f:
s.append(force_text(f.verbose_name))
s = ' / '.join(s) s = ' / '.join(s)
r.append(s) r.append(s)
@ -607,7 +611,8 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView):
# print(ordering) # print(ordering)
except Exception as e: except Exception as e:
logger.warning(_(f"ERRO: construção da tupla de ordenação. {e}")) logger.warning(
_(f"ERRO: construção da tupla de ordenação. {e}"))
# print(queryset.query) # print(queryset.query)
if not self.request.user.is_authenticated: if not self.request.user.is_authenticated:
@ -627,7 +632,7 @@ class AuditLogMixin(object):
# Classe deve implementar um get_object(), i.e., deve ser uma View # Classe deve implementar um get_object(), i.e., deve ser uma View
deleted_object = self.get_object() deleted_object = self.get_object()
try: try:
return super(AuditLogMixin, self).delete(request, args, kwargs) return super(AuditLogMixin, self).delete(request, args, kwargs)
finally: finally:
post_delete_signal.send(sender=None, post_delete_signal.send(sender=None,
instance=deleted_object, instance=deleted_object,

62
sapl/norma/models.py

@ -1,8 +1,8 @@
from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.fields import GenericRelation
from django.db import models from django.db import models
from django.template import defaultfilters from django.template import defaultfilters
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from model_utils import Choices from model_utils import Choices
import reversion import reversion
@ -10,7 +10,7 @@ from sapl.base.models import Autor
from sapl.compilacao.models import TextoArticulado from sapl.compilacao.models import TextoArticulado
from sapl.materia.models import MateriaLegislativa from sapl.materia.models import MateriaLegislativa
from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES,
restringe_tipos_de_arquivo_txt, restringe_tipos_de_arquivo_txt,
texto_upload_path, texto_upload_path,
get_settings_auth_user_model, get_settings_auth_user_model,
OverwriteStorage) OverwriteStorage)
@ -70,8 +70,66 @@ def norma_upload_path(instance, filename):
return texto_upload_path(instance, filename, subpath=instance.ano) return texto_upload_path(instance, filename, subpath=instance.ano)
class NormaJuridicaManager(models.Manager):
use_for_related_fields = True
def normas_sem_textos_articulados(self):
qs = self.get_queryset()
qs = qs.filter(texto_articulado__isnull=True)
return qs
def normas_com_textos_articulados_publicados(self):
qs = self.get_queryset()
qs = qs.filter(
texto_articulado__editable_only_by_owners=False,
texto_articulado__privacidade=0,
texto_articulado__isnull=False
)
return qs
def normas_com_textos_articulados_pendentes(self):
qs = self.get_queryset()
qs = qs.filter(
texto_articulado__editable_only_by_owners=False)
q = models.Q(
texto_articulado__privacidade=0
) | models.Q(
texto_articulado__isnull=True
)
qs = qs.exclude(q)
for n in qs:
ta = n.texto_articulado.first()
count = ta.dispositivos_set.count()
if count == 1:
count = 0
elif count == 2:
d = ta.dispositivos_set.last()
if d.auto_inserido or not d.texto or d.texto == n.ementa:
count = 0
elif count == 3:
ds = ta.dispositivos_set.all()
if ds[1].auto_inserido and \
not d[2].dispositivo_pai and\
d[2].tipo_dispositivo.dispositivo_de_articulacao:
count = 0
if not count:
ta.dispositivos_set.filter(
dispositivo_pai__isnull=False).delete()
ta.delete()
return qs
@reversion.register() @reversion.register()
class NormaJuridica(models.Model): class NormaJuridica(models.Model):
objects = NormaJuridicaManager()
ESFERA_FEDERACAO_CHOICES = Choices( ESFERA_FEDERACAO_CHOICES = Choices(
('M', 'municipal', _('Municipal')), ('M', 'municipal', _('Municipal')),
('E', 'estadual', _('Estadual')), ('E', 'estadual', _('Estadual')),

59
sapl/norma/views.py

@ -4,10 +4,14 @@ import re
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.urls import reverse from django.db.models import Q
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
from django.http.response import HttpResponseRedirect
from django.template import RequestContext, loader from django.template import RequestContext, loader
from django.urls import reverse
from django.urls.base import reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView, UpdateView from django.views.generic import TemplateView, UpdateView
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
@ -184,7 +188,7 @@ class NormaCrud(Crud):
public = [RP_LIST, RP_DETAIL] public = [RP_LIST, RP_DETAIL]
class BaseMixin(Crud.BaseMixin): class BaseMixin(Crud.BaseMixin):
list_field_names = ['tipo', 'numero', 'ano', 'ementa'] list_field_names = ['epigrafe', 'ementa']
list_url = '' list_url = ''
@ -242,14 +246,54 @@ class NormaCrud(Crud):
layout_key = 'NormaJuridicaCreate' layout_key = 'NormaJuridicaCreate'
class ListView(Crud.ListView, RedirectView): class ListView(Crud.ListView):
def get(self, request, *args, **kwargs):
if AppConfig.attr('texto_articulado_norma'):
self.status = self.request.GET.get('status', '')
return Crud.ListView.get(self, request, *args, **kwargs)
else:
url = self.get_redirect_url(*args, **kwargs)
return HttpResponseRedirect(url)
def hook_header_epigrafe(self, *args, **kwargs):
return force_text(_('Epigrafe'))
def hook_epigrafe(self, obj, ss, url):
return obj.epigrafe, reverse_lazy(
'sapl.norma:norma_ta',
kwargs={'pk': obj.id})
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
namespace = self.model._meta.app_config.name namespace = self.model._meta.app_config.name
return reverse('%s:%s' % (namespace, 'norma_pesquisa')) return reverse('%s:%s' % (namespace, 'norma_pesquisa'))
def get(self, request, *args, **kwargs): def get_queryset(self):
return RedirectView.get(self, request, *args, **kwargs) if self.status == 'pendente':
qs = NormaJuridica.objects.normas_com_textos_articulados_pendentes()
elif self.status == 'publico':
qs = NormaJuridica.objects.normas_com_textos_articulados_publicados()
else:
qs = NormaJuridica.objects.normas_sem_textos_articulados()
return qs.order_by('-texto_articulado__privacidade', '-ano', '-numero')
def get_context_data(self, **kwargs):
context = Crud.ListView.get_context_data(self, **kwargs)
if self.status == 'pendente':
context['title'] = 'Normas Jurídicas com Textos Articulados não publicados'
elif self.status == 'publico':
context['title'] = 'Normas Jurídicas com Textos Articulados publicados'
else:
context['title'] = 'Normas Jurídicas sem Textos Articulados'
return context
@classmethod
def get_url_regex(cls):
return r'^check_compilacao$'
class UpdateView(Crud.UpdateView): class UpdateView(Crud.UpdateView):
form_class = NormaJuridicaForm form_class = NormaJuridicaForm
@ -258,7 +302,8 @@ class NormaCrud(Crud):
def get_initial(self): def get_initial(self):
initial = super().get_initial() initial = super().get_initial()
norma = NormaJuridica.objects.select_related("materia").get(id=self.kwargs['pk']) norma = NormaJuridica.objects.select_related(
"materia").get(id=self.kwargs['pk'])
if norma.materia: if norma.materia:
initial['tipo_materia'] = norma.materia.tipo initial['tipo_materia'] = norma.materia.tipo
initial['ano_materia'] = norma.materia.ano initial['ano_materia'] = norma.materia.ano
@ -328,7 +373,7 @@ def recuperar_norma(request):
'id': norma.id}) 'id': norma.id})
except ObjectDoesNotExist: except ObjectDoesNotExist:
logger.warning('user=' + username + '. NormaJuridica buscada (tipo={}, ano={}, numero={}) não existe. ' logger.warning('user=' + username + '. NormaJuridica buscada (tipo={}, ano={}, numero={}) não existe. '
'Definida com ementa vazia e id 0.'.format(tipo, ano, numero)) 'Definida com ementa vazia e id 0.'.format(tipo, ano, numero))
response = JsonResponse({'ementa': '', 'id': 0}) response = JsonResponse({'ementa': '', 'id': 0})
return response return response

12
sapl/templates/navbar.yaml

@ -75,6 +75,16 @@
url: 'sapl.norma:normajuridica_create' url: 'sapl.norma:normajuridica_create'
check_permission: norma.add_normajuridica check_permission: norma.add_normajuridica
- title: {% trans 'Textos Articulados Publicados' %}
url: {% url 'sapl.norma:normajuridica_list'%}?status=publico
check_permission: compilacao.change_dispositivo_edicao_dinamica
- title: {% trans 'Textos Articulados Pendentes' %}
url: {% url 'sapl.norma:normajuridica_list' %}?status=pendente
check_permission: compilacao.change_dispositivo_edicao_dinamica
- title: {% trans 'Textos Articulados não cadastrados' %}
url: {% url 'sapl.norma:normajuridica_list' %}?status=sem_texto
check_permission: compilacao.change_dispositivo_edicao_dinamica
- title: {% trans 'Sistema' %} - title: {% trans 'Sistema' %}
check_permission: base.menu_sistemas check_permission: base.menu_sistemas
children: children:
@ -86,7 +96,7 @@
check_permission: user.is_superuser check_permission: user.is_superuser
- title: {% trans 'Inconsistências de Dados' %} - title: {% trans 'Inconsistências de Dados' %}
url: {% url 'sapl.base:lista_inconsistencias' %} url: {% url 'sapl.base:lista_inconsistencias' %}
check_permission: user.is_superuser check_permission: user.is_superuser
{% comment %} {% comment %}
<li class="nav__sub-item"><a class="nav__sub-link" href="#">Provedor LexML</a></li> <li class="nav__sub-item"><a class="nav__sub-link" href="#">Provedor LexML</a></li>

4
sapl/templates/norma/normajuridica_filter.html

@ -1,6 +1,6 @@
{% extends "crud/detail.html" %} {% extends "crud/detail.html" %}
{% load i18n %} {% load i18n %}
{% load crispy_forms_tags %} {% load crispy_forms_tags common_tags %}
{% block actions %} {% block actions %}
<div class="actions btn-group float-right" role="group"> <div class="actions btn-group float-right" role="group">
@ -9,8 +9,6 @@
Pesquisa Textual Pesquisa Textual
</a> </a>
{% endif %} {% endif %}
{% if perms.norma.add_normajuridica %} {% if perms.norma.add_normajuridica %}
<a href="{% url 'sapl.norma:normajuridica_create' %}" class="btn btn-outline-primary"> <a href="{% url 'sapl.norma:normajuridica_create' %}" class="btn btn-outline-primary">
{% blocktrans with verbose_name=view.verbose_name %} Adicionar Norma Jurídica {% endblocktrans %} {% blocktrans with verbose_name=view.verbose_name %} Adicionar Norma Jurídica {% endblocktrans %}

9
sapl/templates/norma/normajuridica_list.html

@ -0,0 +1,9 @@
{% extends "crud/list.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block extra_actions %}
<div class="actions btn-group float-left" role="group">
<a href="{% url 'sapl.norma:norma_pesquisa' %}" class="btn btn-outline-primary">{% trans 'Fazer Nova Pesquisa' %}</a>
</div>
{% endblock %}
Loading…
Cancel
Save