Browse Source

Parametriza tramitação de matérias (#3575)

* insere field tramitacao_origem_fixa

* ajusta default para True do field tramitacao_origem_fixa

* adiciona tramitacao_origem_fixa ao form de Configurações da aplicação

* refatora form e view materia para tramitacao_origem_fixa

* altera help text de tramitacao_origem_fixa
pull/3576/head
LeandroJataí 3 years ago
committed by GitHub
parent
commit
8a0cdc877b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      sapl/base/forms.py
  2. 19
      sapl/base/migrations/0048_appconfig_tramitacao_origem_fixa.py
  3. 13
      sapl/base/models.py
  4. 34
      sapl/materia/forms.py
  5. 20
      sapl/materia/views.py
  6. 2
      sapl/templates/base/layouts.yaml

19
sapl/base/forms.py

@ -17,8 +17,8 @@ from django.forms import Form, ModelForm
from django.utils import timezone from django.utils import timezone
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from haystack.forms import ModelSearchForm
import django_filters import django_filters
from haystack.forms import ModelSearchForm
from sapl.audiencia.models import AudienciaPublica from sapl.audiencia.models import AudienciaPublica
from sapl.base.models import Autor, TipoAutor, OperadorAutor from sapl.base.models import Autor, TipoAutor, OperadorAutor
@ -882,9 +882,9 @@ class RelatorioNormasMesFilterSet(django_filters.FilterSet):
initial=ultimo_ano_com_norma) initial=ultimo_ano_com_norma)
tipo = django_filters.ChoiceFilter(required=False, tipo = django_filters.ChoiceFilter(required=False,
label='Tipo Norma', label='Tipo Norma',
choices=choice_tipos_normas, choices=choice_tipos_normas,
initial=0) initial=0)
class Meta: class Meta:
model = NormaJuridica model = NormaJuridica
@ -977,9 +977,9 @@ class RelatorioNormasVigenciaFilterSet(django_filters.FilterSet):
initial=ultimo_ano_com_norma) initial=ultimo_ano_com_norma)
tipo = django_filters.ChoiceFilter(required=False, tipo = django_filters.ChoiceFilter(required=False,
label='Tipo Norma', label='Tipo Norma',
choices=choice_tipos_normas, choices=choice_tipos_normas,
initial=0) initial=0)
vigencia = forms.ChoiceField( vigencia = forms.ChoiceField(
label=_('Vigência'), label=_('Vigência'),
@ -1163,8 +1163,8 @@ class RelatorioHistoricoTramitacaoFilterSet(django_filters.FilterSet):
class RelatorioDataFimPrazoTramitacaoFilterSet(django_filters.FilterSet): class RelatorioDataFimPrazoTramitacaoFilterSet(django_filters.FilterSet):
ano = django_filters.ChoiceFilter(required=False, ano = django_filters.ChoiceFilter(required=False,
label='Ano da Matéria', label='Ano da Matéria',
choices=choice_anos_com_materias) choices=choice_anos_com_materias)
@property @property
def qs(self): def qs(self):
@ -1578,6 +1578,7 @@ class ConfiguracoesAppForm(ModelForm):
'assinatura_ata', 'assinatura_ata',
'estatisticas_acesso_normas', 'estatisticas_acesso_normas',
'escolher_numero_materia_proposicao', 'escolher_numero_materia_proposicao',
'tramitacao_origem_fixa',
'tramitacao_materia', 'tramitacao_materia',
'tramitacao_documento', 'tramitacao_documento',
'google_recaptcha_site_key', 'google_recaptcha_site_key',

19
sapl/base/migrations/0048_appconfig_tramitacao_origem_fixa.py

@ -0,0 +1,19 @@
# Generated by Django 2.2.28 on 2022-06-27 11:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0047_auto_20210315_1522'),
]
operations = [
migrations.AddField(
model_name='appconfig',
name='tramitacao_origem_fixa',
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=True,
verbose_name='Fixar Origem das tramitações como sendo a tramitação de destino da última tramitação?'),
),
]

13
sapl/base/models.py

@ -185,6 +185,19 @@ class AppConfig(models.Model):
'Indicar número da matéria a ser gerada na proposição?'), 'Indicar número da matéria a ser gerada na proposição?'),
choices=YES_NO_CHOICES, default=False) choices=YES_NO_CHOICES, default=False)
tramitacao_origem_fixa = models.BooleanField(
verbose_name=_(
'Fixar origem de novas tramitações como sendo a tramitação de destino da última tramitação?'),
choices=YES_NO_CHOICES,
default=True,
help_text=_('Ao utilizar a opção NÂO, você compreende que os controles '
'de origem e destino das tramitações são anulados, '
'podendo seu operador registrar quaisquer origem e '
'destino para as tramitações. Se você colocar Não, '
'fizer tramitações aleatórias e voltar para SIM, '
'o destino da tramitação mais recente será utilizado '
'para a origem de uma nova inserção!'))
tramitacao_materia = models.BooleanField( tramitacao_materia = models.BooleanField(
verbose_name=_( verbose_name=_(
'Tramitar matérias anexadas junto com as matérias principais?'), 'Tramitar matérias anexadas junto com as matérias principais?'),

34
sapl/materia/forms.py

@ -18,7 +18,7 @@ from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import django_filters import django_filters
from sapl.base.models import AppConfig, Autor, TipoAutor from sapl.base.models import AppConfig as BaseAppConfig, Autor, TipoAutor
from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.comissoes.models import Comissao, Composicao, Participacao
from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC, from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC,
STATUS_TA_PRIVATE) STATUS_TA_PRIVATE)
@ -43,7 +43,6 @@ from sapl.utils import (autor_label, autor_modal, timing,
SEPARADOR_HASH_PROPOSICAO, SEPARADOR_HASH_PROPOSICAO,
validar_arquivo, YES_NO_CHOICES, validar_arquivo, YES_NO_CHOICES,
GoogleRecapthaMixin) GoogleRecapthaMixin)
import sapl
from .models import (AcompanhamentoMateria, Anexada, Autoria, from .models import (AcompanhamentoMateria, Anexada, Autoria,
DespachoInicial, DocumentoAcessorio, Numeracao, DespachoInicial, DocumentoAcessorio, Numeracao,
@ -509,7 +508,7 @@ class TramitacaoForm(ModelForm):
if not self.instance.data_tramitacao: if not self.instance.data_tramitacao:
if ultima_tramitacao: if ultima_tramitacao and BaseAppConfig.attr('tramitacao_origem_fixa'):
destino = ultima_tramitacao.unidade_tramitacao_destino destino = ultima_tramitacao.unidade_tramitacao_destino
if (destino != self.cleaned_data['unidade_tramitacao_local']): if (destino != self.cleaned_data['unidade_tramitacao_local']):
self.logger.error("A origem da nova tramitação ({}) não é igual ao " self.logger.error("A origem da nova tramitação ({}) não é igual ao "
@ -562,7 +561,7 @@ class TramitacaoForm(ModelForm):
materia.em_tramitacao = False if tramitacao.status.indicador == "F" else True materia.em_tramitacao = False if tramitacao.status.indicador == "F" else True
materia.save() materia.save()
tramitar_anexadas = sapl.base.models.AppConfig.attr( tramitar_anexadas = BaseAppConfig.attr(
'tramitacao_materia') 'tramitacao_materia')
if tramitar_anexadas: if tramitar_anexadas:
lista_tramitacao = [] lista_tramitacao = []
@ -664,7 +663,7 @@ class TramitacaoUpdateForm(TramitacaoForm):
# ela não pode ter seu destino alterado. # ela não pode ter seu destino alterado.
if ultima_tramitacao != obj: if ultima_tramitacao != obj:
if cd['unidade_tramitacao_destino'] != \ if cd['unidade_tramitacao_destino'] != \
obj.unidade_tramitacao_destino: obj.unidade_tramitacao_destino and BaseAppConfig.attr('tramitacao_origem_fixa'):
self.logger.error("Você não pode mudar a Unidade de Destino desta " self.logger.error("Você não pode mudar a Unidade de Destino desta "
"tramitação para {}, pois irá conflitar com a Unidade " "tramitação para {}, pois irá conflitar com a Unidade "
"Local da tramitação seguinte ({})." "Local da tramitação seguinte ({})."
@ -701,7 +700,7 @@ class TramitacaoUpdateForm(TramitacaoForm):
materia.em_tramitacao = False if nova_tram_principal.status.indicador == "F" else True materia.em_tramitacao = False if nova_tram_principal.status.indicador == "F" else True
materia.save() materia.save()
tramitar_anexadas = sapl.base.models.AppConfig.attr( tramitar_anexadas = BaseAppConfig.attr(
'tramitacao_materia') 'tramitacao_materia')
if tramitar_anexadas: if tramitar_anexadas:
anexadas_list = lista_anexados(materia) anexadas_list = lista_anexados(materia)
@ -1783,7 +1782,7 @@ class TramitacaoEmLoteForm(ModelForm):
ip = self.initial['ip'] if 'ip' in self.initial else '' ip = self.initial['ip'] if 'ip' in self.initial else ''
ultima_edicao = self.initial['ultima_edicao'] if 'ultima_edicao' in self.initial else '' ultima_edicao = self.initial['ultima_edicao'] if 'ultima_edicao' in self.initial else ''
tramitar_anexadas = AppConfig.attr('tramitacao_materia') tramitar_anexadas = BaseAppConfig.attr('tramitacao_materia')
for mat_id in materias: for mat_id in materias:
mat = MateriaLegislativa.objects.get(id=mat_id) mat = MateriaLegislativa.objects.get(id=mat_id)
tramitacao = Tramitacao.objects.create( tramitacao = Tramitacao.objects.create(
@ -1902,10 +1901,10 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
} }
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.texto_articulado_proposicao = AppConfig.attr( self.texto_articulado_proposicao = BaseAppConfig.attr(
'texto_articulado_proposicao') 'texto_articulado_proposicao')
self.receber_recibo = AppConfig.attr( self.receber_recibo = BaseAppConfig.attr(
'receber_recibo_proposicao') 'receber_recibo_proposicao')
if not self.texto_articulado_proposicao: if not self.texto_articulado_proposicao:
@ -1927,7 +1926,7 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
] ]
if AppConfig.objects.last().escolher_numero_materia_proposicao: if BaseAppConfig.objects.last().escolher_numero_materia_proposicao:
fields.append(to_column(('numero_materia_futuro', 12)),) fields.append(to_column(('numero_materia_futuro', 12)),)
else: else:
if 'numero_materia_futuro' in self._meta.fields: if 'numero_materia_futuro' in self._meta.fields:
@ -2043,7 +2042,7 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
def save(self, commit=True): def save(self, commit=True):
cd = self.cleaned_data cd = self.cleaned_data
inst = self.instance inst = self.instance
receber_recibo = AppConfig.objects.last().receber_recibo_proposicao receber_recibo = BaseAppConfig.objects.last().receber_recibo_proposicao
if inst.pk: if inst.pk:
if 'tipo_texto' in cd: if 'tipo_texto' in cd:
@ -2063,7 +2062,8 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
return super().save(commit) return super().save(commit)
inst.ano = timezone.now().year inst.ano = timezone.now().year
sequencia_numeracao = AppConfig.attr('sequencia_numeracao_proposicao') sequencia_numeracao = BaseAppConfig.attr(
'sequencia_numeracao_proposicao')
if sequencia_numeracao == 'A': if sequencia_numeracao == 'A':
numero__max = Proposicao.objects.filter( numero__max = Proposicao.objects.filter(
autor=inst.autor, autor=inst.autor,
@ -2220,7 +2220,7 @@ class ConfirmarProposicaoForm(ProposicaoForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.proposicao_incorporacao_obrigatoria = \ self.proposicao_incorporacao_obrigatoria = \
AppConfig.attr('proposicao_incorporacao_obrigatoria') BaseAppConfig.attr('proposicao_incorporacao_obrigatoria')
if self.proposicao_incorporacao_obrigatoria != 'C': if self.proposicao_incorporacao_obrigatoria != 'C':
if 'gerar_protocolo' in self._meta.fields: if 'gerar_protocolo' in self._meta.fields:
@ -2272,7 +2272,7 @@ class ConfirmarProposicaoForm(ProposicaoForm):
) )
] ]
if not AppConfig.objects.last().escolher_numero_materia_proposicao or \ if not BaseAppConfig.objects.last().escolher_numero_materia_proposicao or \
not self.instance.numero_materia_futuro: not self.instance.numero_materia_futuro:
if 'numero_materia_futuro' in self._meta.fields: if 'numero_materia_futuro' in self._meta.fields:
del fields[0][0][3] del fields[0][0][3]
@ -2352,7 +2352,7 @@ class ConfirmarProposicaoForm(ProposicaoForm):
if not self.is_valid(): if not self.is_valid():
return self.cleaned_data return self.cleaned_data
numeracao = AppConfig.attr('sequencia_numeracao_proposicao') numeracao = BaseAppConfig.attr('sequencia_numeracao_proposicao')
if not numeracao: if not numeracao:
self.logger.error("A sequência de numeração (por ano ou geral)" self.logger.error("A sequência de numeração (por ano ou geral)"
@ -2435,7 +2435,7 @@ class ConfirmarProposicaoForm(ProposicaoForm):
try: try:
self.logger.debug( self.logger.debug(
"Tentando obter modelo de sequência de numeração.") "Tentando obter modelo de sequência de numeração.")
numeracao = AppConfig.objects.last( numeracao = BaseAppConfig.objects.last(
).sequencia_numeracao_protocolo ).sequencia_numeracao_protocolo
except AttributeError as e: except AttributeError as e:
self.logger.error("Erro ao obter modelo. " + str(e)) self.logger.error("Erro ao obter modelo. " + str(e))
@ -2587,7 +2587,7 @@ class ConfirmarProposicaoForm(ProposicaoForm):
GenericForeignKey GenericForeignKey
""" """
numeracao = AppConfig.attr('sequencia_numeracao_protocolo') numeracao = BaseAppConfig.attr('sequencia_numeracao_protocolo')
if numeracao == 'A': if numeracao == 'A':
nm = Protocolo.objects.filter( nm = Protocolo.objects.filter(
ano=timezone.now().year).aggregate(Max('numero')) ano=timezone.now().year).aggregate(Max('numero'))

20
sapl/materia/views.py

@ -1,11 +1,11 @@
from datetime import datetime from datetime import datetime
from io import BytesIO from io import BytesIO
from random import choice
from string import ascii_letters, digits
import logging import logging
import os import os
from random import choice
import shutil import shutil
from string import ascii_letters, digits
import time import time
import zipfile import zipfile
@ -31,6 +31,7 @@ from django.views.generic.edit import FormView
from django_filters.views import FilterView from django_filters.views import FilterView
import weasyprint import weasyprint
import sapl
from sapl.base.email_utils import do_envia_email_confirmacao from sapl.base.email_utils import do_envia_email_confirmacao
from sapl.base.models import Autor, CasaLegislativa, AppConfig as BaseAppConfig from sapl.base.models import Autor, CasaLegislativa, AppConfig as BaseAppConfig
from sapl.comissoes.models import Participacao from sapl.comissoes.models import Participacao
@ -53,7 +54,6 @@ from sapl.utils import (autor_label, autor_modal, gerar_hash_arquivo, get_base_u
mail_service_configured, montar_row_autor, SEPARADOR_HASH_PROPOSICAO, mail_service_configured, montar_row_autor, SEPARADOR_HASH_PROPOSICAO,
show_results_filter_set, get_tempfile_dir, show_results_filter_set, get_tempfile_dir,
google_recaptcha_configured) google_recaptcha_configured)
import sapl
from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
AnexadaEmLoteFilterSet, AdicionarVariasAutoriasFilterSet, AnexadaEmLoteFilterSet, AdicionarVariasAutoriasFilterSet,
@ -437,7 +437,8 @@ class PesquisarStatusTramitacaoView(FilterView):
url = '' url = ''
if 'descricao' in self.request.META['QUERY_STRING'] or\ if 'descricao' in self.request.META['QUERY_STRING'] or\
'page' in self.request.META['QUERY_STRING']: resultados = self.object_list 'page' in self.request.META['QUERY_STRING']:
resultados = self.object_list
else: else:
resultados = [] resultados = []
@ -1395,10 +1396,11 @@ class TramitacaoCrud(MasterDetailCrud):
# necessária? # necessária?
if ultima_tramitacao: if ultima_tramitacao:
if ultima_tramitacao.unidade_tramitacao_destino: if ultima_tramitacao.unidade_tramitacao_destino:
context['form'].fields[ if BaseAppConfig.attr('tramitacao_origem_fixa'):
'unidade_tramitacao_local'].choices = [ context['form'].fields[
(ultima_tramitacao.unidade_tramitacao_destino.pk, 'unidade_tramitacao_local'].choices = [
ultima_tramitacao.unidade_tramitacao_destino)] (ultima_tramitacao.unidade_tramitacao_destino.pk,
ultima_tramitacao.unidade_tramitacao_destino)]
else: else:
self.logger.error('user=' + username + '. Unidade de tramitação destino ' self.logger.error('user=' + username + '. Unidade de tramitação destino '
'da última tramitação não pode ser vazia!') 'da última tramitação não pode ser vazia!')
@ -1411,7 +1413,7 @@ class TramitacaoCrud(MasterDetailCrud):
# Se não for a primeira tramitação daquela matéria, o campo # Se não for a primeira tramitação daquela matéria, o campo
# não pode ser modificado # não pode ser modificado
if not primeira_tramitacao: if not primeira_tramitacao and BaseAppConfig.attr('tramitacao_origem_fixa'):
context['form'].fields[ context['form'].fields[
'unidade_tramitacao_local'].widget.attrs['readonly'] = True 'unidade_tramitacao_local'].widget.attrs['readonly'] = True

2
sapl/templates/base/layouts.yaml

@ -38,7 +38,7 @@ AppConfig:
- proposicao_incorporacao_obrigatoria escolher_numero_materia_proposicao - proposicao_incorporacao_obrigatoria escolher_numero_materia_proposicao
{% trans 'Módulo Matéria Legislativa' %}: {% trans 'Módulo Matéria Legislativa' %}:
- tramitacao_materia tramitacao_documento - tramitacao_origem_fixa tramitacao_materia tramitacao_documento
{% trans 'Módulo Textos Articulados' %}: {% trans 'Módulo Textos Articulados' %}:
- texto_articulado_proposicao texto_articulado_materia texto_articulado_norma - texto_articulado_proposicao texto_articulado_materia texto_articulado_norma

Loading…
Cancel
Save