Browse Source

Merge 4c7df42bd0 into 857d1f0c4a

pull/3822/merge
LeandroJataí 1 week ago
committed by GitHub
parent
commit
b217a8f329
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 28
      sapl/api/views_materia.py
  2. 45
      sapl/materia/forms.py
  3. 93
      sapl/materia/models.py
  4. 48
      sapl/materia/views.py

28
sapl/api/views_materia.py

@ -1,7 +1,10 @@
from copy import deepcopy
from django.apps.registry import apps
from django.db import transaction
from django.db.models import Q
from rest_framework.decorators import action
from rest_framework.status import HTTP_201_CREATED
from rest_framework.response import Response
from drfautoapi.drfautoapi import ApiViewSetConstrutor, \
@ -90,6 +93,31 @@ class _MateriaLegislativaViewSet:
class Meta:
ordering = ['-ano', 'tipo', 'numero']
@transaction.atomic
def create(self, request, *args, **kwargs):
data = deepcopy(request.data)
tipo = data.get('tipo', None)
numero = data.get('numero', None)
ano = data.get('ano', None)
if tipo:
numero, ano = MateriaLegislativa.get_proximo_numero(
tipo=tipo,
ano=ano,
numero_preferido=numero
)
data['numero'] = numero
data['ano'] = ano
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=HTTP_201_CREATED, headers=headers)
@action(detail=True, methods=['GET'])
def ultima_tramitacao(self, request, *args, **kwargs):

45
sapl/materia/forms.py

@ -2458,47 +2458,12 @@ class ConfirmarProposicaoForm(ProposicaoForm):
if self.instance.tipo.content_type.model_class(
) == TipoMateriaLegislativa:
numeracao = None
try:
self.logger.debug(
"Tentando obter modelo de sequência de numeração.")
numeracao = BaseAppConfig.objects.last(
).sequencia_numeracao_protocolo
except AttributeError as e:
self.logger.error("Erro ao obter modelo. " + str(e))
pass
tipo = self.instance.tipo.tipo_conteudo_related
if tipo.sequencia_numeracao:
numeracao = tipo.sequencia_numeracao
ano = timezone.now().year
if numeracao == 'A':
numero = MateriaLegislativa.objects.filter(
ano=ano, tipo=tipo).aggregate(Max('numero'))
elif numeracao == 'L':
legislatura = Legislatura.objects.filter(
data_inicio__year__lte=ano,
data_fim__year__gte=ano).first()
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
numero = MateriaLegislativa.objects.filter(
data_apresentacao__gte=data_inicio,
data_apresentacao__lte=data_fim,
tipo=tipo).aggregate(
Max('numero'))
elif numeracao == 'U':
numero = MateriaLegislativa.objects.filter(
tipo=tipo).aggregate(Max('numero'))
if numeracao is None:
numero['numero__max'] = 0
if cd['numero_materia_futuro'] and not MateriaLegislativa.objects.filter(tipo=tipo,
ano=ano,
numero=cd['numero_materia_futuro']):
max_numero = cd['numero_materia_futuro']
else:
max_numero = numero['numero__max'] + \
1 if numero['numero__max'] else 1
max_numero, ano = MateriaLegislativa.get_proximo_numero(
tipo=tipo,
ano=None,
numero_preferido=cd.get('numero_materia_futuro', None)
)
# dados básicos
materia = MateriaLegislativa()

93
sapl/materia/models.py

@ -3,6 +3,7 @@ from datetime import datetime
from django.contrib.auth.models import Group
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models.functions import Concat
from django.template import defaultfilters
@ -382,6 +383,98 @@ class MateriaLegislativa(models.Model):
using=using,
update_fields=update_fields)
@staticmethod
def get_proximo_numero(tipo, ano=None, numero_preferido=None):
"""
Retorna o próximo número disponível para uma MateriaLegislativa
baseado no tipo e nas configurações de numeração.
Args:
tipo: TipoMateriaLegislativa - o tipo da matéria
ano: int - o ano da matéria (default: ano atual)
numero_preferido: int - número preferido/desejado (opcional)
Returns:
tuple[int, int]: Uma tupla contendo (numero, ano) da matéria.
"""
from django.db.models import Max
from sapl.parlamentares.models import Legislatura
import sapl.base.models
if ano is None:
ano = timezone.now().year
# Obtém a configuração de numeração
numeracao = None
try:
numeracao = sapl.base.models.AppConfig.objects.last(
).sequencia_numeracao_protocolo
except AttributeError:
pass
if not isinstance(tipo, TipoMateriaLegislativa):
if tipo is None:
raise ValidationError(_("O tipo é obrigatório."))
try:
tipo_id = int(tipo)
except (ValueError, TypeError):
raise ValidationError(_("Tipo inválido: '%s'") % tipo)
try:
tipo = TipoMateriaLegislativa.objects.get(pk=tipo_id)
except TipoMateriaLegislativa.DoesNotExist:
raise TipoMateriaLegislativa.DoesNotExist(
_("TipoMateriaLegislativa with pk '%s' does not exist.") % tipo_id
)
# O tipo pode sobrescrever a configuração global
if tipo.sequencia_numeracao:
numeracao = tipo.sequencia_numeracao
# Calcula o próximo número baseado no tipo de numeração
if numeracao == 'A': # Por ano
numero = MateriaLegislativa.objects.filter(
ano=ano, tipo=tipo).aggregate(Max('numero'))
elif numeracao == 'L': # Por legislatura
legislatura = Legislatura.objects.filter(
data_inicio__year__lte=ano,
data_fim__year__gte=ano).first()
if legislatura:
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
numero = MateriaLegislativa.objects.filter(
data_apresentacao__gte=data_inicio,
data_apresentacao__lte=data_fim,
tipo=tipo).aggregate(Max('numero'))
else:
numero = {'numero__max': 0}
elif numeracao == 'U': # Único/Universal
numero = MateriaLegislativa.objects.filter(
tipo=tipo).aggregate(Max('numero'))
else:
numero = {'numero__max': 0}
# Converte o número preferido para inteiro, se possível
numero_preferido_int = None
if numero_preferido:
try:
numero_preferido_int = int(numero_preferido)
except (TypeError, ValueError):
numero_preferido_int = None
# Verifica se o número preferido está disponível
if numero_preferido_int is not None and not MateriaLegislativa.objects.filter(
tipo=tipo,
ano=ano,
numero=numero_preferido_int).exists():
return numero_preferido_int, ano
# Retorna o próximo número sequencial
max_numero = numero['numero__max']
return ((max_numero + 1) if max_numero else 1), ano
class Autoria(models.Model):
autor = models.ForeignKey(Autor,

48
sapl/materia/views.py

@ -340,53 +340,15 @@ class ProposicaoTaView(IntegracaoTaView):
@permission_required('materia.detail_materialegislativa')
def recuperar_materia(request):
logger = logging.getLogger(__name__)
username = request.user.username
tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo'])
ano = request.GET.get('ano', '')
if not (tipo and ano):
return JsonResponse({'numero': '', 'ano': ''})
numeracao = None
try:
logger.debug("user=" + username +
". Tentando obter numeração da matéria.")
numeracao = sapl.base.models.AppConfig.objects.last(
).sequencia_numeracao_protocolo
except AttributeError as e:
logger.error("user=" + username + ". " + str(e) +
" Numeracao da matéria definida como None.")
pass
ano = request.GET.get('ano', None)
if tipo.sequencia_numeracao:
numeracao = tipo.sequencia_numeracao
if numeracao == 'A':
numero = MateriaLegislativa.objects.filter(
ano=ano, tipo=tipo).aggregate(Max('numero'))
elif numeracao == 'L':
legislatura = Legislatura.objects.filter(
data_inicio__year__lte=ano,
data_fim__year__gte=ano).first()
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
numero = MateriaLegislativa.objects.filter(
data_apresentacao__gte=data_inicio,
data_apresentacao__lte=data_fim,
tipo=tipo).aggregate(
Max('numero'))
elif numeracao == 'U':
numero = MateriaLegislativa.objects.filter(
tipo=tipo).aggregate(Max('numero'))
if numeracao is None:
numero['numero__max'] = 0
max_numero = numero['numero__max'] + 1 if numero['numero__max'] else 1
max_numero, ano = MateriaLegislativa.get_proximo_numero(
tipo=tipo,
ano=int(ano) if ano else None
)
response = JsonResponse({'numero': max_numero, 'ano': ano})
return response

Loading…
Cancel
Save