Browse Source

Fix #2987 - Número Inicial de Protocolo (#3019)

* Retirar campo de numeração manual - Protocolo Doc

* Retirar campo de numeração manual - Protocolo Mat

* Fix #2987

* Update sapl/protocoloadm/views.py

Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com>

* Adiciona correções

* Fix migrations

* Atualiza cód. commit 658f261

Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com>
pull/3165/head
João Rodrigues 4 years ago
committed by GitHub
parent
commit
0cf7cf7254
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      sapl/base/forms.py
  2. 20
      sapl/base/migrations/0040_appconfig_inicio_numeracao_protocolo.py
  3. 5
      sapl/base/models.py
  4. 59
      sapl/base/views.py
  5. 26
      sapl/protocoloadm/forms.py
  6. 4
      sapl/protocoloadm/tests/test_protocoloadm.py
  7. 121
      sapl/protocoloadm/views.py
  8. 2
      sapl/templates/base/layouts.yaml

1
sapl/base/forms.py

@ -1553,6 +1553,7 @@ class ConfiguracoesAppForm(ModelForm):
model = AppConfig
fields = ['documentos_administrativos',
'sequencia_numeracao_protocolo',
'inicio_numeracao_protocolo',
'sequencia_numeracao_proposicao',
'esfera_federacao',
# 'painel_aberto', # TODO: a ser implementado na versão 3.2

20
sapl/base/migrations/0040_appconfig_inicio_numeracao_protocolo.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-05-26 17:58
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0039_auto_20191202_1114'),
]
operations = [
migrations.AddField(
model_name='appconfig',
name='inicio_numeracao_protocolo',
field=models.PositiveIntegerField(default=1, verbose_name='Início da numeração de protocolo'),
),
]

5
sapl/base/models.py

@ -108,6 +108,11 @@ class AppConfig(models.Model):
verbose_name=_('Sequência de numeração de protocolos'),
choices=SEQUENCIA_NUMERACAO_PROTOCOLO, default='A')
inicio_numeracao_protocolo = models.PositiveIntegerField(
verbose_name=_('Início da numeração de protocolo'),
default=1
)
esfera_federacao = models.CharField(
max_length=1,
blank=True,

59
sapl/base/views.py

@ -56,9 +56,9 @@ from sapl.protocoloadm.models import (Anexado, DocumentoAdministrativo, Protocol
TipoDocumentoAdministrativo)
from sapl.sessao.models import (Bancada, PresencaOrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, TipoSessaoPlenaria)
from sapl.utils import (gerar_hash_arquivo, intervalos_tem_intersecao,
mail_service_configured, parlamentares_ativos,
SEPARADOR_HASH_PROPOSICAO, show_results_filter_set, num_materias_por_tipo)
from sapl.utils import (from_date_to_datetime_utc, gerar_hash_arquivo, intervalos_tem_intersecao,
mail_service_configured, parlamentares_ativos, SEPARADOR_HASH_PROPOSICAO,
show_results_filter_set, num_materias_por_tipo)
from .forms import (AlterarSenhaForm, CasaLegislativaForm,
ConfiguracoesAppForm, RelatorioAtasFilterSet,
@ -2103,6 +2103,59 @@ class AppConfigCrud(CrudAux):
kwargs={'pk': app_config.pk}))
class UpdateView(CrudAux.UpdateView):
form_class = ConfiguracoesAppForm
def form_valid(self, form):
numeracao = AppConfig.objects.last().sequencia_numeracao_protocolo
numeracao_antiga = AppConfig.objects.last().inicio_numeracao_protocolo
self.object = form.save()
numeracao_nova = self.object.inicio_numeracao_protocolo
if numeracao_nova != numeracao_antiga:
if numeracao == 'A':
numero_max = Protocolo.objects.filter(
ano=timezone.now().year
).aggregate(Max('numero'))['numero__max']
elif numeracao == 'L':
legislatura = Legislatura.objects.filter(
data_inicio__year__lte=timezone.now().year,
data_fim__year__gte=timezone.now().year
).first()
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
data_inicio_utc = from_date_to_datetime_utc(data_inicio)
data_fim_utc = from_date_to_datetime_utc(data_fim)
numero_max = Protocolo.objects.filter(
Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) |
Q(
timestamp__isnull=False, timestamp__gte=data_inicio_utc,
timestamp__lte=data_fim_utc
) | Q(
timestamp_data_hora_manual__isnull=False,
timestamp_data_hora_manual__gte=data_inicio_utc,
timestamp_data_hora_manual__lte=data_fim_utc,
)
).aggregate(Max('numero'))['numero__max']
elif numeracao == 'U':
numero_max = Protocolo.objects.all().aggregate(
Max('numero')
)['numero__max']
ultimo_numero_cadastrado = int(numero_max) if numero_max else 0
if numeracao_nova <= ultimo_numero_cadastrado and numeracao != 'U':
msg = "O novo início da numeração de protocolo entrará em vigor na " \
"próxima sequência, pois já existe protocolo cadastrado com " \
"número superior ou igual ao número inicial definido."
messages.warning(self.request, msg)
return super().form_valid(form)
class ListView(CrudAux.ListView):
def get(self, request, *args, **kwargs):

26
sapl/protocoloadm/forms.py

@ -343,7 +343,7 @@ class AnularProtocoloAdmForm(ModelForm):
*args, **kwargs)
class ProtocoloDocumentForm(ModelForm):
class ProtocoloDocumentoForm(ModelForm):
tipo_protocolo = forms.ChoiceField(required=True,
label=_('Tipo de Protocolo'),
@ -367,9 +367,6 @@ class ProtocoloDocumentForm(ModelForm):
observacao = forms.CharField(required=False,
widget=forms.Textarea, label=_('Observação'))
numero = forms.IntegerField(
required=False, label=_('Número de Protocolo (opcional)'))
data_hora_manual = forms.ChoiceField(
label=_('Informar data e hora manualmente?'),
widget=forms.RadioSelect(),
@ -384,7 +381,6 @@ class ProtocoloDocumentForm(ModelForm):
'assunto',
'interessado',
'observacao',
'numero',
'data',
'hora',
]
@ -426,8 +422,6 @@ class ProtocoloDocumentForm(ModelForm):
[('interessado', 12)])
row6 = to_row(
[('observacao', 12)])
row7 = to_row(
[('numero', 12)])
fieldset = Fieldset(_('Protocolo com data e hora informados manualmente'),
row3,
@ -447,14 +441,11 @@ class ProtocoloDocumentForm(ModelForm):
row4,
row5,
HTML("&nbsp;"),
Fieldset(_('Número do Protocolo (Apenas se quiser que a numeração comece '
'a partir do número a ser informado)'),
row7,
HTML("&nbsp;"),
Fieldset(HTML("&nbsp;"),
form_actions(label=_('Protocolar Documento'))
)
)
super(ProtocoloDocumentForm, self).__init__(
super(ProtocoloDocumentoForm, self).__init__(
*args, **kwargs)
if not config.protocolo_manual:
@ -503,9 +494,6 @@ class ProtocoloMateriaForm(ModelForm):
assunto_ementa = forms.CharField(required=True,
widget=forms.Textarea, label=_('Ementa'))
numero = forms.IntegerField(
required=False, label=_('Número de Protocolo (opcional)'))
data_hora_manual = forms.ChoiceField(
label=_('Informar data e hora manualmente?'),
widget=forms.RadioSelect(),
@ -523,7 +511,6 @@ class ProtocoloMateriaForm(ModelForm):
'numero_materia',
'ano_materia',
'vincular_materia',
'numero',
'data',
'hora',
]
@ -616,8 +603,6 @@ class ProtocoloMateriaForm(ModelForm):
[('assunto_ementa', 12)])
row5 = to_row(
[('observacao', 12)])
row6 = to_row(
[('numero', 12)])
fieldset = Fieldset(_('Protocolo com data e hora informados manualmente'),
row3,
@ -637,10 +622,7 @@ class ProtocoloMateriaForm(ModelForm):
row4,
row5,
HTML("&nbsp;"),
Fieldset(_('Número do Protocolo (Apenas se quiser que a numeração comece'
' a partir do número a ser informado)'),
row6,
HTML("&nbsp;"),
Fieldset(HTML("&nbsp;"),
form_actions(label=_('Protocolar Matéria')))
)

4
sapl/protocoloadm/tests/test_protocoloadm.py

@ -13,7 +13,7 @@ from sapl.comissoes.models import Comissao, TipoComissao
from sapl.materia.models import UnidadeTramitacao
from sapl.protocoloadm.forms import (AnularProtocoloAdmForm,
DocumentoAdministrativoForm,
MateriaLegislativa, ProtocoloDocumentForm,
MateriaLegislativa, ProtocoloDocumentoForm,
ProtocoloMateriaForm, TramitacaoAdmForm,
TramitacaoAdmEditForm,
compara_tramitacoes_doc,
@ -415,7 +415,7 @@ def test_protocolo_documento_form_invalido():
config = baker.make(AppConfig)
form = ProtocoloDocumentForm(
form = ProtocoloDocumentoForm(
data={},
initial={
'user_data_hora_manual': '',

121
sapl/protocoloadm/views.py

@ -44,23 +44,19 @@ from sapl.utils import (create_barcode, get_base_url, get_client_ip,
from django.shortcuts import render
from .forms import (AcompanhamentoDocumentoForm, AnularProtocoloAdmForm,
DocumentoAcessorioAdministrativoForm,
DocumentoAdministrativoFilterSet,
DocumentoAdministrativoForm, FichaPesquisaAdmForm, FichaSelecionaAdmForm, ProtocoloDocumentForm,
ProtocoloFilterSet, ProtocoloMateriaForm,
TramitacaoAdmEditForm, TramitacaoAdmForm,
from .forms import (AcompanhamentoDocumentoForm, AnexadoEmLoteFilterSet, AnexadoForm,
AnularProtocoloAdmForm, compara_tramitacoes_doc,
DesvincularDocumentoForm, DesvincularMateriaForm,
filtra_tramitacao_adm_destino_and_status,
filtra_tramitacao_adm_destino, filtra_tramitacao_adm_status,
AnexadoForm, AnexadoEmLoteFilterSet,
PrimeiraTramitacaoEmLoteAdmFilterSet,
TramitacaoEmLoteAdmForm,
TramitacaoEmLoteAdmFilterSet,
compara_tramitacoes_doc)
from .models import (AcompanhamentoDocumento, DocumentoAcessorioAdministrativo,
DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoFilterSet,
DocumentoAdministrativoForm, FichaPesquisaAdmForm, FichaSelecionaAdmForm,
filtra_tramitacao_adm_destino, filtra_tramitacao_adm_destino_and_status,
filtra_tramitacao_adm_status, PrimeiraTramitacaoEmLoteAdmFilterSet,
ProtocoloDocumentoForm, ProtocoloFilterSet, ProtocoloMateriaForm,
TramitacaoAdmEditForm, TramitacaoAdmForm, TramitacaoEmLoteAdmForm,
TramitacaoEmLoteAdmFilterSet)
from .models import (Anexado, AcompanhamentoDocumento, DocumentoAcessorioAdministrativo,
DocumentoAdministrativo, StatusTramitacaoAdministrativo,
TipoDocumentoAdministrativo, TramitacaoAdministrativo, Anexado)
TipoDocumentoAdministrativo, TramitacaoAdministrativo)
TipoDocumentoAdministrativoCrud = CrudAux.build(
@ -582,7 +578,7 @@ class ProtocoloDocumentoView(PermissionRequiredMixin,
logger = logging.getLogger(__name__)
template_name = "protocoloadm/protocolar_documento.html"
form_class = ProtocoloDocumentForm
form_class = ProtocoloDocumentoForm
form_valid_message = _('Protocolo cadastrado com sucesso!')
permission_required = ('protocoloadm.add_protocolo', )
@ -617,12 +613,14 @@ class ProtocoloDocumentoView(PermissionRequiredMixin,
return self.render_to_response(self.get_context_data())
if numeracao == 'A':
numero = Protocolo.objects.filter(
ano=timezone.now().year).aggregate(Max('numero'))
numero_max = Protocolo.objects.filter(ano=timezone.now().year).aggregate(
Max('numero')
)['numero__max']
elif numeracao == 'L':
legislatura = Legislatura.objects.filter(
data_inicio__year__lte=timezone.now().year,
data_fim__year__gte=timezone.now().year).first()
data_fim__year__gte=timezone.now().year
).first()
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
@ -630,32 +628,28 @@ class ProtocoloDocumentoView(PermissionRequiredMixin,
data_inicio_utc = from_date_to_datetime_utc(data_inicio)
data_fim_utc = from_date_to_datetime_utc(data_fim)
numero = Protocolo.objects.filter(
Q(data__isnull=False,
data__gte=data_inicio,
data__lte=data_fim) |
Q(timestamp__isnull=False,
timestamp__gte=data_inicio_utc,
timestamp__lte=data_fim_utc) |
Q(timestamp_data_hora_manual__isnull=False,
numero_max = Protocolo.objects.filter(
Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) | Q(
timestamp__isnull=False, timestamp__gte=data_inicio_utc,
timestamp__lte=data_fim_utc
) | Q(
timestamp_data_hora_manual__isnull=False,
timestamp_data_hora_manual__gte=data_inicio_utc,
timestamp_data_hora_manual__lte=data_fim_utc,)).\
aggregate(Max('numero'))
timestamp_data_hora_manual__lte=data_fim_utc,
)
).aggregate(Max('numero'))['numero__max']
elif numeracao == 'U':
numero = Protocolo.objects.all().aggregate(Max('numero'))
numero_max = Protocolo.objects.all().aggregate(Max('numero'))['numero__max']
protocolo.tipo_processo = '0' # TODO validar o significado
protocolo.anulado = False
if not protocolo.numero:
inicio_numeracao = AppConfig.objects.first().inicio_numeracao_protocolo
numero = int(numero_max) if numero_max else 0
protocolo.numero = (
numero['numero__max'] + 1) if numero['numero__max'] else 1
elif protocolo.numero < (numero['numero__max'] + 1) if numero['numero__max'] else 0:
msg = _('Número de protocolo deve ser maior que {}'.format(
numero['numero__max']))
self.logger.error(
"user=" + username + ". Número de protocolo deve ser maior que {}.".format(numero['numero__max']))
messages.add_message(self.request, messages.ERROR, msg)
return self.render_to_response(self.get_context_data())
(numero + 1 ) if numero and numero >= inicio_numeracao else inicio_numeracao
)
protocolo.ano = timezone.now().year
protocolo.assunto_ementa = self.request.POST['assunto']
@ -829,47 +823,40 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView):
return self.render_to_response(self.get_context_data())
if numeracao == 'A':
numero = Protocolo.objects.filter(
ano=timezone.now().year).aggregate(Max('numero'))
numero_max = Protocolo.objects.filter(ano=timezone.now().year).aggregate(
Max('numero')
)['numero__max']
elif numeracao == 'L':
legislatura = Legislatura.objects.filter(
data_inicio__year__lte=timezone.now().year,
data_fim__year__gte=timezone.now().year).first()
data_fim__year__gte=timezone.now().year
).first()
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
data_inicio_utc = from_date_to_datetime_utc(data_inicio)
data_fim_utc = from_date_to_datetime_utc(data_fim)
numero = Protocolo.objects.filter(
Q(data__isnull=False,
data__gte=data_inicio,
data__lte=data_fim) |
Q(timestamp__isnull=False,
timestamp__gte=data_inicio_utc,
timestamp__lte=data_fim_utc) |
Q(timestamp_data_hora_manual__isnull=False,
numero_max = Protocolo.objects.filter(
Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) | Q(
timestamp__isnull=False, timestamp__gte=data_inicio_utc,
timestamp__lte=data_fim_utc
) | Q(
timestamp_data_hora_manual__isnull=False,
timestamp_data_hora_manual__gte=data_inicio_utc,
timestamp_data_hora_manual__lte=data_fim_utc,)).\
aggregate(Max('numero'))
timestamp_data_hora_manual__lte=data_fim_utc,
)
).aggregate(Max('numero'))['numero__max']
elif numeracao == 'U':
numero = Protocolo.objects.all().aggregate(Max('numero'))
if numeracao is None:
numero['numero__max'] = 0
numero_max = Protocolo.objects.all().aggregate(Max('numero'))['numero__max']
if not protocolo.numero:
inicio_numeracao = AppConfig.objects.first().inicio_numeracao_protocolo
numero = int(numero_max) if numero_max else 0
protocolo.numero = (
numero['numero__max'] + 1) if numero['numero__max'] else 1
if numero['numero__max']:
if protocolo.numero < (numero['numero__max'] + 1):
self.logger.error("user=" + username + ". Número de protocolo ({}) é menor que {}"
.format(protocolo.numero, numero['numero__max']))
msg = _('Número de protocolo deve ser maior que {}'.format(
numero['numero__max']))
messages.add_message(self.request, messages.ERROR, msg)
return self.render_to_response(self.get_context_data())
(numero + 1 ) if numero and numero >= inicio_numeracao else inicio_numeracao
)
protocolo.ano = timezone.now().year
protocolo.tipo_protocolo = 0

2
sapl/templates/base/layouts.yaml

@ -18,7 +18,7 @@ AppConfig:
- esfera_federacao
{% trans 'Proposições e Protocolo' %}:
- sequencia_numeracao_proposicao sequencia_numeracao_protocolo
- sequencia_numeracao_proposicao sequencia_numeracao_protocolo inicio_numeracao_protocolo
- protocolo_manual receber_recibo_proposicao
- proposicao_incorporacao_obrigatoria escolher_numero_materia_proposicao

Loading…
Cancel
Save