Browse Source

Merge branch '3.1.x' into 2700-resumo-sessao-pdf-duplicado

pull/2704/head
Vinícius Cantuária 7 years ago
committed by GitHub
parent
commit
4f8705c721
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      sapl/base/migrations/0033_auto_20190415_1050.py
  2. 3
      sapl/base/models.py
  3. 20
      sapl/materia/forms.py
  4. 20
      sapl/materia/migrations/0045_auto_20190415_1050.py
  5. 22
      sapl/materia/views.py
  6. 4
      sapl/protocoloadm/forms.py
  7. 22
      sapl/protocoloadm/views.py
  8. 33
      sapl/sessao/migrations/0037_auto_20190415_1324.py
  9. 13
      sapl/sessao/models.py
  10. 24
      sapl/sessao/views.py
  11. 4
      sapl/templates/base/layouts.yaml
  12. 84
      scripts/remove_multiplos_autores.py
  13. 13
      scripts/remove_protocolos_inexistentes_materias.py

20
sapl/base/migrations/0033_auto_20190415_1050.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-04-15 13:50
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0032_merge_20190219_0941'),
]
operations = [
migrations.AlterField(
model_name='appconfig',
name='sequencia_numeracao',
field=models.CharField(choices=[('A', 'Sequencial por ano para cada autor'), ('B', 'Sequencial por ano indepententemente do autor'), ('L', 'Sequencial por legislatura'), ('U', 'Sequencial único')], default='A', max_length=1, verbose_name='Sequência de numeração'),
),
]

3
sapl/base/models.py

@ -18,7 +18,8 @@ TIPO_DOCUMENTO_ADMINISTRATIVO = ((DOC_ADM_OSTENSIVO, _('Ostensiva')),
RELATORIO_ATOS_ACESSADOS = (('S', _('Sim')), RELATORIO_ATOS_ACESSADOS = (('S', _('Sim')),
('N', _('Não'))) ('N', _('Não')))
SEQUENCIA_NUMERACAO = (('A', _('Sequencial por ano')), SEQUENCIA_NUMERACAO = (('A', _('Sequencial por ano para cada autor')),
('B', _('Sequencial por ano indepententemente do autor')),
('L', _('Sequencial por legislatura')), ('L', _('Sequencial por legislatura')),
('U', _('Sequencial único'))) ('U', _('Sequencial único')))

20
sapl/materia/forms.py

@ -790,6 +790,13 @@ class AnexadaForm(ModelForm):
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
data_anexacao = cleaned_data['data_anexacao']
data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao
if data_anexacao > data_desanexacao:
self.logger.error("Data de anexação posterior à data de desanexação.")
raise ValidationError(_("Data de anexação posterior à data de desanexação."))
try: try:
self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={})." self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={})."
.format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo']))
@ -1659,12 +1666,17 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
return super().save(commit) return super().save(commit)
inst.ano = timezone.now().year inst.ano = timezone.now().year
numero__max = Proposicao.objects.filter( sequencia_numeracao = AppConfig.attr('sequencia_numeracao')
autor=inst.autor, if sequencia_numeracao == 'A':
ano=timezone.now().year).aggregate(Max('numero_proposicao')) numero__max = Proposicao.objects.filter(
autor=inst.autor,
ano=timezone.now().year).aggregate(Max('numero_proposicao'))
elif sequencia_numeracao == 'B':
numero__max = Proposicao.objects.filter(
ano=timezone.now().year).aggregate(Max('numero_proposicao'))
numero__max = numero__max['numero_proposicao__max'] numero__max = numero__max['numero_proposicao__max']
inst.numero_proposicao = ( inst.numero_proposicao = (
numero__max + 1) if numero__max else 1 numero__max + 1) if numero__max else 1
self.gerar_hash(inst, receber_recibo) self.gerar_hash(inst, receber_recibo)

20
sapl/materia/migrations/0045_auto_20190415_1050.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-04-15 13:50
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('materia', '0044_auto_20190327_1409'),
]
operations = [
migrations.AlterField(
model_name='tipomaterialegislativa',
name='sequencia_numeracao',
field=models.CharField(blank=True, choices=[('A', 'Sequencial por ano para cada autor'), ('B', 'Sequencial por ano indepententemente do autor'), ('L', 'Sequencial por legislatura'), ('U', 'Sequencial único')], max_length=1, verbose_name='Sequência de numeração'),
),
]

22
sapl/materia/views.py

@ -2112,19 +2112,31 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
marcadas = request.POST.getlist('materia_id') marcadas = request.POST.getlist('materia_id')
if len(marcadas) == 0:
msg = _('Nenhuma máteria foi selecionada.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
data_anexacao = datetime.strptime( data_anexacao = datetime.strptime(
request.POST['data_anexacao'], "%d/%m/%Y").date() request.POST['data_anexacao'], "%d/%m/%Y").date()
if request.POST['data_desanexacao'] == '': if request.POST['data_desanexacao'] == '':
data_desanexacao = None data_desanexacao = None
v_data_desanexacao = data_anexacao
else: else:
data_desanexacao = datetime.strptime( data_desanexacao = datetime.strptime(
request.POST['data_desanexacao'], "%d/%m/%Y").date() request.POST['data_desanexacao'], "%d/%m/%Y").date()
v_data_desanexacao = data_desanexacao
if len(marcadas) == 0:
msg = _('Nenhuma máteria foi selecionada.')
messages.add_message(request, messages.ERROR, msg)
if data_anexacao > v_data_desanexacao:
msg = _('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
if data_anexacao > v_data_desanexacao:
msg = _('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
principal = MateriaLegislativa.objects.get(pk=kwargs['pk']) principal = MateriaLegislativa.objects.get(pk=kwargs['pk'])
for materia in MateriaLegislativa.objects.filter(id__in=marcadas): for materia in MateriaLegislativa.objects.filter(id__in=marcadas):

4
sapl/protocoloadm/forms.py

@ -811,8 +811,8 @@ class AnexadoForm(ModelForm):
data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao
if data_anexacao > data_desanexacao: if data_anexacao > data_desanexacao:
self.logger.error("A data de anexação não pode ser posterior a data de desanexação.") self.logger.error("Data de anexação posterior à data de desanexação.")
raise ValidationError(_("A data de anexação não pode ser posterior a data de desanexação.")) raise ValidationError(_("Data de anexação posterior à data de desanexação."))
try: try:
self.logger.info( self.logger.info(
"Tentando obter objeto DocumentoAdministrativo (numero={}, ano={}, tipo={})." "Tentando obter objeto DocumentoAdministrativo (numero={}, ano={}, tipo={})."

22
sapl/protocoloadm/views.py

@ -1047,21 +1047,33 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
marcados = request.POST.getlist('documento_id') marcados = request.POST.getlist('documento_id')
if len(marcados) == 0:
msg =_('Nenhum documento foi selecionado')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
data_anexacao = datetime.strptime( data_anexacao = datetime.strptime(
request.POST['data_anexacao'], "%d/%m/%Y" request.POST['data_anexacao'], "%d/%m/%Y"
).date() ).date()
if request.POST['data_desanexacao'] == '': if request.POST['data_desanexacao'] == '':
data_desanexacao = None data_desanexacao = None
v_data_desanexacao = data_anexacao
else: else:
data_desanexacao = datetime.strptime( data_desanexacao = datetime.strptime(
request.POST['data_desanexacao'], "%d/%m/%Y" request.POST['data_desanexacao'], "%d/%m/%Y"
).date() ).date()
v_data_desanexacao = data_desanexacao
if len(marcados) == 0:
msg =_('Nenhum documento foi selecionado')
messages.add_message(request, messages.ERROR, msg)
if data_anexacao > v_data_desanexacao:
msg=_('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
if data_anexacao > v_data_desanexacao:
msg =_('Data de anexação posterior à data de desanexação.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, messages.ERROR, msg)
principal = DocumentoAdministrativo.objects.get(pk = kwargs['pk']) principal = DocumentoAdministrativo.objects.get(pk = kwargs['pk'])
for documento in DocumentoAdministrativo.objects.filter(id__in = marcados): for documento in DocumentoAdministrativo.objects.filter(id__in = marcados):

33
sapl/sessao/migrations/0037_auto_20190415_1324.py

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-04-15 16:24
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('sessao', '0036_auto_20190412_1106'),
]
operations = [
migrations.AddField(
model_name='registrovotacao',
name='data_hora',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Data/Hora'),
),
migrations.AddField(
model_name='registrovotacao',
name='ip',
field=models.CharField(blank=True, default='', max_length=30, verbose_name='IP'),
),
migrations.AddField(
model_name='registrovotacao',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
),
]

13
sapl/sessao/models.py

@ -456,6 +456,19 @@ class RegistroVotacao(models.Model):
verbose_name=_('Abstenções')) verbose_name=_('Abstenções'))
observacao = models.TextField( observacao = models.TextField(
blank=True, verbose_name=_('Observações')) blank=True, verbose_name=_('Observações'))
user = models.ForeignKey(get_settings_auth_user_model(),
on_delete=models.PROTECT,
null=True,
blank=True)
ip = models.CharField(verbose_name=_('IP'),
max_length=30,
blank=True,
default='')
data_hora = models.DateTimeField(
verbose_name=_('Data/Hora'),
auto_now_add=True,
blank=True,
null=True)
class Meta: class Meta:
verbose_name = _('Votação') verbose_name = _('Votação')

24
sapl/sessao/views.py

@ -35,7 +35,7 @@ from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato,
Parlamentar, SessaoLegislativa) Parlamentar, SessaoLegislativa)
from sapl.sessao.apps import AppConfig from sapl.sessao.apps import AppConfig
from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm
from sapl.utils import show_results_filter_set, remover_acentos from sapl.utils import show_results_filter_set, remover_acentos, get_client_ip
from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, BlocoForm, from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, BlocoForm,
ExpedienteForm, JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm, ExpedienteForm, JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm,
@ -2115,6 +2115,8 @@ class VotacaoView(SessaoPermissionMixin):
votacao.ordem_id = ordem_id votacao.ordem_id = ordem_id
votacao.tipo_resultado_votacao_id = int( votacao.tipo_resultado_votacao_id = int(
request.POST['resultado_votacao']) request.POST['resultado_votacao'])
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save() votacao.save()
except Exception as e: except Exception as e:
username = request.user.username username = request.user.username
@ -2335,6 +2337,8 @@ class VotacaoNominalAbstract(SessaoPermissionMixin):
votacao.numero_votos_nao = votos_nao votacao.numero_votos_nao = votos_nao
votacao.numero_abstencoes = abstencoes votacao.numero_abstencoes = abstencoes
votacao.observacao = request.POST.get('observacao', None) votacao.observacao = request.POST.get('observacao', None)
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.materia_id = materia_votacao.materia.id votacao.materia_id = materia_votacao.materia.id
if self.ordem: if self.ordem:
@ -2362,6 +2366,8 @@ class VotacaoNominalAbstract(SessaoPermissionMixin):
voto_parlamentar.voto = voto voto_parlamentar.voto = voto
voto_parlamentar.parlamentar_id = parlamentar_id voto_parlamentar.parlamentar_id = parlamentar_id
voto_parlamentar.votacao_id = votacao.id voto_parlamentar.votacao_id = votacao.id
voto_parlamentar.user = request.user
voto_parlamentar.ip = get_client_ip(request)
voto_parlamentar.save() voto_parlamentar.save()
resultado = form.cleaned_data['resultado_votacao'] resultado = form.cleaned_data['resultado_votacao']
@ -2799,10 +2805,10 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
if (int(request.POST['voto_presidente']) == 0): if (int(request.POST['voto_presidente']) == 0):
qtde_presentes -= 1 qtde_presentes -= 1
if (qtde_votos > qtde_presentes or qtde_votos < qtde_presentes): if qtde_votos != qtde_presentes:
form._errors["total_votos"] = ErrorList([u""]) form._errors["total_votos"] = ErrorList([u""])
return self.render_to_response(context) return self.render_to_response(context)
elif (qtde_presentes == qtde_votos): else:
try: try:
votacao = RegistroVotacao() votacao = RegistroVotacao()
votacao.numero_votos_sim = int(request.POST['votos_sim']) votacao.numero_votos_sim = int(request.POST['votos_sim'])
@ -2813,6 +2819,8 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
votacao.expediente_id = expediente_id votacao.expediente_id = expediente_id
votacao.tipo_resultado_votacao_id = int( votacao.tipo_resultado_votacao_id = int(
request.POST['resultado_votacao']) request.POST['resultado_votacao'])
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save() votacao.save()
except Exception as e: except Exception as e:
username = request.user.username username = request.user.username
@ -3592,6 +3600,8 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie
resultado = TipoResultadoVotacao.objects.get( resultado = TipoResultadoVotacao.objects.get(
id=request.POST['resultado_votacao']) id=request.POST['resultado_votacao'])
votacao.tipo_resultado_votacao = resultado votacao.tipo_resultado_votacao = resultado
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save() votacao.save()
except Exception as e: except Exception as e:
username = request.user.username username = request.user.username
@ -3623,6 +3633,8 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie
resultado = TipoResultadoVotacao.objects.get( resultado = TipoResultadoVotacao.objects.get(
id=request.POST['resultado_votacao']) id=request.POST['resultado_votacao'])
votacao.tipo_resultado_votacao = resultado votacao.tipo_resultado_votacao = resultado
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save() votacao.save()
except Exception as e: except Exception as e:
username = request.user.username username = request.user.username
@ -3814,6 +3826,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView)
voto_parlamentar.voto = voto voto_parlamentar.voto = voto
voto_parlamentar.parlamentar_id = parlamentar_id voto_parlamentar.parlamentar_id = parlamentar_id
voto_parlamentar.votacao_id = votacao.id voto_parlamentar.votacao_id = votacao.id
voto_parlamentar.user = request.user
voto_parlamentar.ip = get_client_ip(request)
voto_parlamentar.save() voto_parlamentar.save()
ordem.resultado = form.cleaned_data['resultado_votacao'].nome ordem.resultado = form.cleaned_data['resultado_votacao'].nome
@ -3841,6 +3855,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView)
votacao.materia = expediente.materia votacao.materia = expediente.materia
votacao.expediente = expediente votacao.expediente = expediente
votacao.tipo_resultado_votacao = form.cleaned_data['resultado_votacao'] votacao.tipo_resultado_votacao = form.cleaned_data['resultado_votacao']
votacao.user = request.user
votacao.ip = get_client_ip(request)
votacao.save() votacao.save()
# Salva os votos de cada parlamentar # Salva os votos de cada parlamentar
@ -3856,6 +3872,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView)
voto_parlamentar.voto = voto voto_parlamentar.voto = voto
voto_parlamentar.parlamentar_id = parlamentar_id voto_parlamentar.parlamentar_id = parlamentar_id
voto_parlamentar.votacao_id = votacao.id voto_parlamentar.votacao_id = votacao.id
voto_parlamentar.user = request.user
voto_parlamentar.ip = get_client_ip(request)
voto_parlamentar.save() voto_parlamentar.save()
expediente.resultado = form.cleaned_data['resultado_votacao'].nome expediente.resultado = form.cleaned_data['resultado_votacao'].nome

4
sapl/templates/base/layouts.yaml

@ -18,8 +18,8 @@ AppConfig:
- esfera_federacao - esfera_federacao
{% trans 'Proposições e Protocolo' %}: {% trans 'Proposições e Protocolo' %}:
- sequencia_numeracao proposicao_incorporacao_obrigatoria receber_recibo_proposicao - sequencia_numeracao protocolo_manual receber_recibo_proposicao
- escolher_numero_materia_proposicao protocolo_manual - proposicao_incorporacao_obrigatoria escolher_numero_materia_proposicao
{% trans 'Textos Articulados' %}: {% trans 'Textos Articulados' %}:
- texto_articulado_proposicao texto_articulado_materia texto_articulado_norma - texto_articulado_proposicao texto_articulado_materia texto_articulado_norma

84
scripts/remove_multiplos_autores.py

@ -0,0 +1,84 @@
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Count
from sapl.base.models import Autor
from sapl.parlamentares.models import Parlamentar
def pega_autores():
return [[autor for autor in Autor.objects.filter(nome=nome)]
for nome in Autor.objects.values_list('nome', flat=True).annotate(qntd=Count('nome')).filter(qntd__gt=1)]
def pega_parlamentares_autores():
parlamentares = [[parlamentar for parlamentar in Parlamentar.objects.filter(nome_parlamentar=nome_parlamentar)]
for nome_parlamentar in Parlamentar.objects.values_list('nome_parlamentar', flat=True)
.annotate(qntd=Count('nome_parlamentar')).filter(qntd__gt=1)]
parlamentares_autores = []
for parlamentar in parlamentares:
parlamentar_autor = []
for clone in parlamentar[1:]:
try:
autor_principal = Autor.objects.get(parlamentar_set=parlamentar[0])
except ObjectDoesNotExist:
try:
autor_clonado = Autor.objects.get(parlamentar_set=clone)
except ObjectDoesNotExist:
pass
else:
autor_clonado.object_id = parlamentar[0].id
autor_clonado.save()
parlamentares_autores.append(autor_clonado)
else:
if len(parlamentar_autor) == 0:
parlamentar_autor.append(autor_principal)
try:
autor_clonado = Autor.objects.get(parlamentar_set=clone)
except ObjectDoesNotExist:
pass
else:
parlamentar_autor.append(autor_clonado)
parlamentares_autores.extend(parlamentar_autor)
return parlamentares_autores
def transfere_valeres(autores):
for autor in autores:
for clone in autor[1:]:
for autoria in clone.autoria_set.all():
autoria.autor_id = autor[0]
autoria.save()
for proposicao in clone.proposicao_set.all():
proposicao.autor_id = autor[0]
proposicao.save()
for autorianorma in clone.autorianorma_set.all():
autorianorma.autor_id = autor[0]
autorianorma.save()
for documentoadministrativo in clone.documentoadministrativo_set.all():
documentoadministrativo.autor_id = autor[0]
documentoadministrativo.save()
for protocolo in clone.protocolo_set.all():
protocolo.autor_id = autor[0]
protocolo.save()
clone.delete()
def main():
autores = pega_autores()
parlamentares_autores = pega_parlamentares_autores()
autores.append(parlamentares_autores)
transfere_valeres(autores)
if __name__ == '__main__':
main()

13
scripts/remove_protocolos_inexistentes_materias.py

@ -0,0 +1,13 @@
from sapl.materia.models import MateriaLegislativa
from sapl.protocoloadm.models import Protocolo
def main():
for materia in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False):
if not Protocolo.objects.filter(ano=materia.ano, numero=materia.numero_protocolo).exists():
materia.numero_protocolo = None
materia.save()
if __name__ == '__main__':
main()
Loading…
Cancel
Save