Browse Source

Fix #1121 votacao nominal (#1174)

* Inicia a refatoracao

* Otimizações no código

* Correcao e otimizacao do codigo de votacao nominal

* Votacao interativa refatorada

* Conserta detalhes da votacao nominal

* Conserta alguns testes e retira a tabela de VotoNominal

* Remove null=True no campo ip

* Tentativa de passar no travis
pull/1120/merge
Eduardo Calil 8 years ago
committed by Edward
parent
commit
74e48c37c2
  1. 5
      create_admin.py
  2. 1
      genkey.py
  3. 4
      sapl/api/forms.py
  4. 2
      sapl/api/serializers.py
  5. 5
      sapl/api/views.py
  6. 5
      sapl/base/search_indexes.py
  7. 7
      sapl/legacy/migracao_documentos.py
  8. 1
      sapl/legacy/migration.py
  9. 4
      sapl/materia/signals.py
  10. 2
      sapl/materia/views.py
  11. 4
      sapl/norma/signals.py
  12. 54
      sapl/painel/views.py
  13. 2
      sapl/parlamentares/models.py
  14. 15
      sapl/parlamentares/urls.py
  15. 2
      sapl/parlamentares/views.py
  16. 5
      sapl/relatorios/views.py
  17. 2
      sapl/rules/map_rules.py
  18. 4
      sapl/rules/tests/test_rules.py
  19. 6
      sapl/sessao/forms.py
  20. 21
      sapl/sessao/migrations/0004_votonominal_registro_votacao.py
  21. 39
      sapl/sessao/migrations/0005_auto_20170601_1246.py
  22. 26
      sapl/sessao/migrations/0006_auto_20170601_1257.py
  23. 26
      sapl/sessao/migrations/0007_auto_20170606_1238.py
  24. 38
      sapl/sessao/migrations/0008_auto_20170607_1220.py
  25. 60
      sapl/sessao/models.py
  26. 1
      sapl/sessao/serializers.py
  27. 17
      sapl/sessao/urls.py
  28. 604
      sapl/sessao/views.py
  29. 13
      sapl/utils.py

5
create_admin.py

@ -1,11 +1,12 @@
import sys
import os import os
import sys
import django import django
from django.contrib.auth.models import User
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sapl.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sapl.settings")
django.setup() django.setup()
from django.contrib.auth.models import User
def create_superuser(): def create_superuser():
username = "admin" username = "admin"

1
genkey.py

@ -1,5 +1,6 @@
import random import random
def generate_secret(): def generate_secret():
return ''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)]) return ''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)])

4
sapl/api/forms.py

@ -1,6 +1,6 @@
from django.db.models import Q from django.db.models import Q
from django.forms.fields import MultiValueField, CharField from django.forms.fields import CharField, MultiValueField
from django.forms.widgets import TextInput, MultiWidget from django.forms.widgets import MultiWidget, TextInput
from django_filters.filters import MethodFilter, ModelChoiceFilter from django_filters.filters import MethodFilter, ModelChoiceFilter
from rest_framework.compat import django_filters from rest_framework.compat import django_filters
from rest_framework.filters import FilterSet from rest_framework.filters import FilterSet

2
sapl/api/serializers.py

@ -2,7 +2,7 @@ from rest_framework import serializers
from sapl.base.models import Autor, CasaLegislativa from sapl.base.models import Autor, CasaLegislativa
from sapl.materia.models import MateriaLegislativa from sapl.materia.models import MateriaLegislativa
from sapl.sessao.models import SessaoPlenaria, OrdemDia from sapl.sessao.models import OrdemDia, SessaoPlenaria
class ChoiceSerializer(serializers.Serializer): class ChoiceSerializer(serializers.Serializer):

5
sapl/api/views.py

@ -5,9 +5,8 @@ from django.utils.translation import ugettext_lazy as _
from rest_framework.filters import DjangoFilterBackend from rest_framework.filters import DjangoFilterBackend
from rest_framework.generics import ListAPIView from rest_framework.generics import ListAPIView
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import (IsAuthenticated, from rest_framework.permissions import (AllowAny, IsAuthenticated,
IsAuthenticatedOrReadOnly, IsAuthenticatedOrReadOnly)
AllowAny)
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
from sapl.api.forms import AutorChoiceFilterSet, AutorSearchForFieldFilterSet from sapl.api.forms import AutorChoiceFilterSet, AutorSearchForFieldFilterSet

5
sapl/base/search_indexes.py

@ -4,13 +4,12 @@ import os.path
import textract import textract
from django.template import Context, loader from django.template import Context, loader
from haystack import indexes from haystack import indexes
from textract.exceptions import ExtensionNotSupported
from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa
from sapl.norma.models import NormaJuridica from sapl.norma.models import NormaJuridica
from textract.exceptions import ExtensionNotSupported
from sapl.settings import BASE_DIR from sapl.settings import BASE_DIR
logger = logging.getLogger(BASE_DIR.name) logger = logging.getLogger(BASE_DIR.name)
class DocumentoAcessorioIndex(indexes.SearchIndex, indexes.Indexable): class DocumentoAcessorioIndex(indexes.SearchIndex, indexes.Indexable):

7
sapl/legacy/migracao_documentos.py

@ -3,20 +3,19 @@ import os
import re import re
import magic import magic
from django.db.models.signals import post_delete, post_save from django.db.models.signals import post_delete, post_save
from sapl.base.models import CasaLegislativa from sapl.base.models import CasaLegislativa
from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa, from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa,
Proposicao) Proposicao)
from sapl.norma.models import NormaJuridica from sapl.norma.models import NormaJuridica
from sapl.parlamentares.models import Parlamentar from sapl.parlamentares.models import Parlamentar
from sapl.protocoloadm.models import DocumentoAdministrativo from sapl.protocoloadm.models import (DocumentoAcessorioAdministrativo,
from sapl.protocoloadm.models import DocumentoAcessorioAdministrativo DocumentoAdministrativo)
from sapl.sessao.models import SessaoPlenaria from sapl.sessao.models import SessaoPlenaria
from sapl.settings import MEDIA_ROOT from sapl.settings import MEDIA_ROOT
from sapl.utils import delete_texto, save_texto from sapl.utils import delete_texto, save_texto
# MIGRAÇÃO DE DOCUMENTOS ################################################### # MIGRAÇÃO DE DOCUMENTOS ###################################################
EXTENSOES = { EXTENSOES = {
'application/msword': '.doc', 'application/msword': '.doc',

1
sapl/legacy/migration.py

@ -599,6 +599,7 @@ def adjust_ordemdia_antes_salvar(new, old):
if not old.tip_votacao: if not old.tip_votacao:
new.tipo_votacao = 1 new.tipo_votacao = 1
if old.num_ordem is None: if old.num_ordem is None:
new.numero_ordem = 999999999 new.numero_ordem = 999999999

4
sapl/materia/signals.py

@ -1,8 +1,8 @@
from django.db.models.signals import post_delete, post_save from django.db.models.signals import post_delete, post_save
from sapl.utils import save_texto, delete_texto
from .models import DocumentoAcessorio, MateriaLegislativa from sapl.utils import delete_texto, save_texto
from .models import DocumentoAcessorio, MateriaLegislativa
post_save.connect(save_texto, sender=MateriaLegislativa) post_save.connect(save_texto, sender=MateriaLegislativa)
post_save.connect(save_texto, sender=DocumentoAcessorio) post_save.connect(save_texto, sender=DocumentoAcessorio)

2
sapl/materia/views.py

@ -7,7 +7,7 @@ from crispy_forms.layout import HTML
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.core.mail import send_mail from django.core.mail import send_mail
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse

4
sapl/norma/signals.py

@ -1,8 +1,8 @@
from django.db.models.signals import post_delete, post_save from django.db.models.signals import post_delete, post_save
from sapl.utils import save_texto, delete_texto
from .models import NormaJuridica from sapl.utils import delete_texto, save_texto
from .models import NormaJuridica
post_save.connect(save_texto, sender=NormaJuridica) post_save.connect(save_texto, sender=NormaJuridica)
post_delete.connect(delete_texto, sender=NormaJuridica) post_delete.connect(delete_texto, sender=NormaJuridica)

54
sapl/painel/views.py

@ -14,8 +14,7 @@ from sapl.painel.models import Painel
from sapl.parlamentares.models import Filiacao, Votante from sapl.parlamentares.models import Filiacao, Votante
from sapl.sessao.models import (ExpedienteMateria, OrdemDia, PresencaOrdemDia, from sapl.sessao.models import (ExpedienteMateria, OrdemDia, PresencaOrdemDia,
RegistroVotacao, SessaoPlenaria, RegistroVotacao, SessaoPlenaria,
SessaoPlenariaPresenca, VotoNominal, SessaoPlenariaPresenca, VotoParlamentar)
VotoParlamentar)
from sapl.utils import get_client_ip from sapl.utils import get_client_ip
from .models import Cronometro from .models import Cronometro
@ -38,7 +37,11 @@ def votante_view(request, pk):
context = {'head_title': str(_('Votação Individual')), 'sessao_id': pk} context = {'head_title': str(_('Votação Individual')), 'sessao_id': pk}
# Pega sessão # Pega sessão
try:
sessao = SessaoPlenaria.objects.get(pk=pk) sessao = SessaoPlenaria.objects.get(pk=pk)
except ObjectDoesNotExist:
raise Http404()
context.update({'sessao': sessao, context.update({'sessao': sessao,
'data': sessao.data_inicio, 'data': sessao.data_inicio,
'hora': sessao.hora_inicio}) 'hora': sessao.hora_inicio})
@ -98,11 +101,17 @@ def votante_view(request, pk):
'Nenhuma matéria com votação nominal aberta.'}) 'Nenhuma matéria com votação nominal aberta.'})
# Recupera o voto do parlamentar logado # Recupera o voto do parlamentar logado
voto = []
if ordem_dia:
voto = VotoParlamentar.objects.filter(
ordem=ordem_dia)
elif expediente:
voto = VotoParlamentar.objects.filter(
expediente=expediente)
if voto:
try: try:
voto = VotoNominal.objects.get( voto = voto.get(parlamentar=parlamentar)
sessao=sessao,
parlamentar=parlamentar,
materia=materia)
except ObjectDoesNotExist: except ObjectDoesNotExist:
context.update({'voto_parlamentar': 'Voto não computado.'}) context.update({'voto_parlamentar': 'Voto não computado.'})
else: else:
@ -110,23 +119,42 @@ def votante_view(request, pk):
# Salva o voto # Salva o voto
if request.method == 'POST': if request.method == 'POST':
if ordem_dia:
try: try:
voto = VotoNominal.objects.get( voto = VotoParlamentar.objects.get(
sessao=sessao,
parlamentar=parlamentar, parlamentar=parlamentar,
materia=materia) ordem=ordem_dia)
except ObjectDoesNotExist: except ObjectDoesNotExist:
voto = VotoNominal.objects.create( voto = VotoParlamentar.objects.create(
sessao=sessao,
parlamentar=parlamentar, parlamentar=parlamentar,
materia=materia,
voto=request.POST['voto'], voto=request.POST['voto'],
user=request.user,
ip=get_client_ip(request), ip=get_client_ip(request),
user=request.user) ordem=ordem_dia)
else: else:
voto.voto = request.POST['voto'] voto.voto = request.POST['voto']
voto.ip = get_client_ip(request) voto.ip = get_client_ip(request)
voto.user = request.user
voto.save() voto.save()
elif expediente:
try:
voto = VotoParlamentar.objects.get(
parlamentar=parlamentar,
expediente=expediente)
except ObjectDoesNotExist:
voto = VotoParlamentar.objects.create(
parlamentar=parlamentar,
voto=request.POST['voto'],
user=request.user,
ip=get_client_ip(request),
expediente=expediente)
else:
voto.voto = request.POST['voto']
voto.ip = get_client_ip(request)
voto.user = request.user
voto.save()
return HttpResponseRedirect( return HttpResponseRedirect(
reverse('sapl.painel:voto_individual', kwargs={'pk': pk})) reverse('sapl.painel:voto_individual', kwargs={'pk': pk}))

2
sapl/parlamentares/models.py

@ -1,9 +1,9 @@
from datetime import datetime from datetime import datetime
import reversion
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from model_utils import Choices from model_utils import Choices
import reversion
from sapl.base.models import Autor from sapl.base.models import Autor
from sapl.utils import (INDICADOR_AFASTAMENTO, UF, YES_NO_CHOICES, from sapl.utils import (INDICADOR_AFASTAMENTO, UF, YES_NO_CHOICES,

15
sapl/parlamentares/urls.py

@ -1,22 +1,21 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from sapl.parlamentares.views import (altera_field_mesa, from sapl.parlamentares.views import (CargoMesaCrud, ColigacaoCrud,
altera_field_mesa_public_view,
CargoMesaCrud, ColigacaoCrud,
ComposicaoColigacaoCrud, DependenteCrud, ComposicaoColigacaoCrud, DependenteCrud,
FiliacaoCrud, FrenteCrud, FrenteList, FiliacaoCrud, FrenteCrud, FrenteList,
LegislaturaCrud, LegislaturaCrud, MandatoCrud,
insere_parlamentar_composicao,
MandatoCrud,
MesaDiretoraView, NivelInstrucaoCrud, MesaDiretoraView, NivelInstrucaoCrud,
ParlamentarCrud, ParlamentarCrud,
ParticipacaoParlamentarCrud, PartidoCrud, ParticipacaoParlamentarCrud, PartidoCrud,
ProposicaoParlamentarCrud, ProposicaoParlamentarCrud,
RelatoriaParlamentarCrud, RelatoriaParlamentarCrud,
remove_parlamentar_composicao,
SessaoLegislativaCrud, SessaoLegislativaCrud,
TipoAfastamentoCrud, TipoDependenteCrud, TipoAfastamentoCrud, TipoDependenteCrud,
TipoMilitarCrud, VotanteView) TipoMilitarCrud, VotanteView,
altera_field_mesa,
altera_field_mesa_public_view,
insere_parlamentar_composicao,
remove_parlamentar_composicao)
from .apps import AppConfig from .apps import AppConfig

2
sapl/parlamentares/views.py

@ -1,5 +1,5 @@
from django.contrib import messages from django.contrib import messages
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
from django.db.models import F, Q from django.db.models import F, Q
from django.http import JsonResponse from django.http import JsonResponse

5
sapl/relatorios/views.py

@ -1,7 +1,6 @@
from datetime import datetime
import re
import html import html
import re
from datetime import datetime
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse

2
sapl/rules/map_rules.py

@ -152,8 +152,6 @@ rules_group_sessao = {
(sessao.PresencaOrdemDia, __base__), (sessao.PresencaOrdemDia, __base__),
(sessao.RegistroVotacao, __base__), (sessao.RegistroVotacao, __base__),
(sessao.VotoParlamentar, __base__), (sessao.VotoParlamentar, __base__),
(sessao.VotoNominal, __base__),
] ]
} }

4
sapl/rules/tests/test_rules.py

@ -6,8 +6,8 @@ from django.contrib.contenttypes.models import ContentType
from django.utils import six from django.utils import six
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from sapl.base.models import (CasaLegislativa, ProblemaMigracao, Argumento, from sapl.base.models import (Argumento, CasaLegislativa, Constraint,
Constraint) ProblemaMigracao)
from sapl.compilacao.models import (PerfilEstruturalTextoArticulado, from sapl.compilacao.models import (PerfilEstruturalTextoArticulado,
TipoDispositivo, TipoDispositivo,
TipoDispositivoRelationship) TipoDispositivoRelationship)

6
sapl/sessao/forms.py

@ -35,6 +35,7 @@ def recupera_anos():
def ANO_CHOICES(): def ANO_CHOICES():
return [('', '---------')] + recupera_anos() return [('', '---------')] + recupera_anos()
MES_CHOICES = [('', '---------')] + RANGE_MESES MES_CHOICES = [('', '---------')] + RANGE_MESES
DIA_CHOICES = [('', '---------')] + RANGE_DIAS_MES DIA_CHOICES = [('', '---------')] + RANGE_DIAS_MES
@ -151,14 +152,12 @@ class OrdemDiaForm(ExpedienteMateriaForm):
def clean_data_ordem(self): def clean_data_ordem(self):
return self.instance.sessao_plenaria.data_inicio return self.instance.sessao_plenaria.data_inicio
def clean_numero_ordem(self): def clean_numero_ordem(self):
sessao = self.instance.sessao_plenaria sessao = self.instance.sessao_plenaria
numero_ordem_exists = OrdemDia.objects.filter( numero_ordem_exists = OrdemDia.objects.filter(
sessao_plenaria=sessao, sessao_plenaria=sessao,
numero_ordem=self.cleaned_data[ numero_ordem=self.cleaned_data['numero_ordem']).exists()
'numero_ordem']).exists()
if numero_ordem_exists: if numero_ordem_exists:
msg = _('Esse número de ordem já existe.') msg = _('Esse número de ordem já existe.')
@ -166,7 +165,6 @@ class OrdemDiaForm(ExpedienteMateriaForm):
return self.cleaned_data['numero_ordem'] return self.cleaned_data['numero_ordem']
def clean(self): def clean(self):
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
sessao = self.instance.sessao_plenaria sessao = self.instance.sessao_plenaria

21
sapl/sessao/migrations/0004_votonominal_registro_votacao.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2017-06-01 11:06
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('sessao', '0003_resumoordenacao'),
]
operations = [
migrations.AddField(
model_name='votonominal',
name='registro_votacao',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.RegistroVotacao'),
),
]

39
sapl/sessao/migrations/0005_auto_20170601_1246.py

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2017-06-01 12:46
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
from datetime import datetime
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('sessao', '0004_votonominal_registro_votacao'),
]
operations = [
migrations.RemoveField(
model_name='votonominal',
name='registro_votacao',
),
migrations.AddField(
model_name='votoparlamentar',
name='data_hora',
field=models.DateTimeField(auto_now_add=True, blank=True, null=True, verbose_name='Data/Hora'),
preserve_default=False,
),
migrations.AddField(
model_name='votoparlamentar',
name='ip',
field=models.CharField(blank=True, max_length=30, null=True, verbose_name='IP'),
),
migrations.AddField(
model_name='votoparlamentar',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
),
]

26
sapl/sessao/migrations/0006_auto_20170601_1257.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2017-06-01 12:57
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('sessao', '0005_auto_20170601_1246'),
]
operations = [
migrations.AddField(
model_name='votonominal',
name='votacao',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.RegistroVotacao'),
),
migrations.AlterField(
model_name='votoparlamentar',
name='votacao',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.RegistroVotacao'),
),
]

26
sapl/sessao/migrations/0007_auto_20170606_1238.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2017-06-06 12:38
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('sessao', '0006_auto_20170601_1257'),
]
operations = [
migrations.AddField(
model_name='votoparlamentar',
name='expediente',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.ExpedienteMateria'),
),
migrations.AddField(
model_name='votoparlamentar',
name='ordem',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sessao.OrdemDia'),
),
]

38
sapl/sessao/migrations/0008_auto_20170607_1220.py

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2017-06-07 12:20
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('sessao', '0007_auto_20170606_1238'),
]
operations = [
migrations.RemoveField(
model_name='votonominal',
name='materia',
),
migrations.RemoveField(
model_name='votonominal',
name='parlamentar',
),
migrations.RemoveField(
model_name='votonominal',
name='sessao',
),
migrations.RemoveField(
model_name='votonominal',
name='user',
),
migrations.RemoveField(
model_name='votonominal',
name='votacao',
),
migrations.DeleteModel(
name='VotoNominal',
),
]

60
sapl/sessao/models.py

@ -86,7 +86,8 @@ def get_sessao_media_path(instance, subpath, filename):
def pauta_upload_path(instance, filename): def pauta_upload_path(instance, filename):
return texto_upload_path(instance, filename, subpath='pauta', pk_first=True) return texto_upload_path(
instance, filename, subpath='pauta', pk_first=True)
# return get_sessao_media_path(instance, 'pauta', filename) # return get_sessao_media_path(instance, 'pauta', filename)
@ -96,7 +97,8 @@ def ata_upload_path(instance, filename):
def anexo_upload_path(instance, filename): def anexo_upload_path(instance, filename):
return texto_upload_path(instance, filename, subpath='anexo', pk_first=True) return texto_upload_path(
instance, filename, subpath='anexo', pk_first=True)
# return get_sessao_media_path(instance, 'anexo', filename) # return get_sessao_media_path(instance, 'anexo', filename)
@ -412,11 +414,39 @@ class RegistroVotacao(models.Model):
@reversion.register() @reversion.register()
class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar
votacao = models.ForeignKey(RegistroVotacao, on_delete=models.PROTECT) '''
As colunas ordem e expediente são redundantes, levando em consideração
que RegistroVotacao possui ordem/expediente. Entretanto, para
viabilizar a votação interativa, uma vez que ela é feita antes de haver
um RegistroVotacao, é preciso identificar o voto por ordem/expediente.
'''
votacao = models.ForeignKey(RegistroVotacao,
blank=True,
null=True)
parlamentar = models.ForeignKey(Parlamentar, on_delete=models.PROTECT) parlamentar = models.ForeignKey(Parlamentar, on_delete=models.PROTECT)
# XXX change to restricted choices
voto = models.CharField(max_length=10) voto = models.CharField(max_length=10)
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)
ordem = models.ForeignKey(OrdemDia,
blank=True,
null=True)
expediente = models.ForeignKey(ExpedienteMateria,
blank=True,
null=True)
class Meta: class Meta:
verbose_name = _('Registro de Votação de Parlamentar') verbose_name = _('Registro de Votação de Parlamentar')
verbose_name_plural = _('Registros de Votações de Parlamentares') verbose_name_plural = _('Registros de Votações de Parlamentares')
@ -426,28 +456,6 @@ class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar
'votacao': self.votacao, 'parlamentar': self.parlamentar} 'votacao': self.votacao, 'parlamentar': self.parlamentar}
@reversion.register()
class VotoNominal(models.Model):
parlamentar = models.ForeignKey(Parlamentar, on_delete=models.PROTECT)
voto = models.CharField(verbose_name=_('Voto'), max_length=10)
sessao = models.ForeignKey(SessaoPlenaria, on_delete=models.PROTECT)
materia = models.ForeignKey(MateriaLegislativa, on_delete=models.PROTECT)
user = models.ForeignKey(get_settings_auth_user_model(),
on_delete=models.PROTECT)
ip = models.CharField(verbose_name=_('IP'), max_length=30)
data_hora = models.DateTimeField(
verbose_name=_('Data/Hora'), auto_now_add=True)
class Meta:
verbose_name = _('Registro do Voto do Parlamentar')
verbose_name_plural = _('Registros dos Votos dos Parlamentares')
def __str__(self):
return '%s - %s' % (self.parlamentar.nome_parlamentar, self.voto)
@reversion.register() @reversion.register()
class SessaoPlenariaPresenca(models.Model): class SessaoPlenariaPresenca(models.Model):
sessao_plenaria = models.ForeignKey(SessaoPlenaria, sessao_plenaria = models.ForeignKey(SessaoPlenaria,

1
sapl/sessao/serializers.py

@ -2,6 +2,7 @@ from rest_framework import serializers
from .models import SessaoPlenaria from .models import SessaoPlenaria
class SessaoPlenariaSerializer(serializers.Serializer): class SessaoPlenariaSerializer(serializers.Serializer):
class Meta: class Meta:
model = SessaoPlenaria model = SessaoPlenaria

17
sapl/sessao/urls.py

@ -1,8 +1,8 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from sapl.sessao.views import (AdicionarVariasMateriasExpediente, from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
AdicionarVariasMateriasOrdemDia, AdicionarVariasMateriasOrdemDia, BancadaCrud,
BancadaCrud, BlocoCrud, CargoBancadaCrud, BlocoCrud, CargoBancadaCrud,
ExpedienteMateriaCrud, ExpedienteView, ExpedienteMateriaCrud, ExpedienteView,
MateriaOrdemDiaCrud, MesaView, OradorCrud, MateriaOrdemDiaCrud, MesaView, OradorCrud,
OradorExpedienteCrud, PainelView, OradorExpedienteCrud, PainelView,
@ -11,18 +11,17 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
PesquisarPautaSessaoView, PesquisarPautaSessaoView,
PesquisarSessaoPlenariaView, PesquisarSessaoPlenariaView,
PresencaOrdemDiaView, PresencaView, PresencaOrdemDiaView, PresencaView,
ResumoOrdenacaoView, ResumoView, ResumoOrdenacaoView, ResumoView, SessaoCrud,
SessaoCrud, TipoExpedienteCrud, TipoExpedienteCrud, TipoResultadoVotacaoCrud,
TipoResultadoVotacaoCrud, TipoSessaoCrud, TipoSessaoCrud, VotacaoEditView,
VotacaoEditView, VotacaoExpedienteEditView, VotacaoExpedienteEditView,
VotacaoExpedienteView, VotacaoNominalEditView, VotacaoExpedienteView, VotacaoNominalEditView,
VotacaoNominalExpedienteEditView,
VotacaoNominalExpedienteDetailView, VotacaoNominalExpedienteDetailView,
VotacaoNominalExpedienteEditView,
VotacaoNominalExpedienteView, VotacaoNominalExpedienteView,
VotacaoNominalView, VotacaoView, VotacaoNominalView, VotacaoView,
abrir_votacao_expediente_view, abrir_votacao_expediente_view,
abrir_votacao_ordem_view, abrir_votacao_ordem_view, atualizar_mesa,
atualizar_mesa,
insere_parlamentar_composicao, insere_parlamentar_composicao,
mudar_ordem_materia_sessao, recuperar_materia, mudar_ordem_materia_sessao, recuperar_materia,
recuperar_numero_sessao, recuperar_numero_sessao,

604
sapl/sessao/views.py

@ -8,7 +8,7 @@ from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.forms.utils import ErrorList from django.forms.utils import ErrorList
from django.http import JsonResponse from django.http import JsonResponse
from django.http.response import HttpResponseRedirect from django.http.response import Http404, HttpResponseRedirect
from django.utils.datastructures import MultiValueDictKeyError from django.utils.datastructures import MultiValueDictKeyError
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.html import strip_tags from django.utils.html import strip_tags
@ -37,15 +37,14 @@ from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm
from .forms import (AdicionarVariasMateriasFilterSet, ExpedienteForm, from .forms import (AdicionarVariasMateriasFilterSet, ExpedienteForm,
ListMateriaForm, MesaForm, OradorExpedienteForm, ListMateriaForm, MesaForm, OradorExpedienteForm,
OradorForm, PautaSessaoFilterSet, PresencaForm, OradorForm, PautaSessaoFilterSet, PresencaForm,
ResumoOrdenacaoForm, ResumoOrdenacaoForm, SessaoPlenariaFilterSet,
SessaoPlenariaFilterSet, VotacaoEditForm, VotacaoForm, VotacaoEditForm, VotacaoForm, VotacaoNominalForm)
VotacaoNominalForm)
from .models import (Bancada, Bloco, CargoBancada, CargoMesa, from .models import (Bancada, Bloco, CargoBancada, CargoMesa,
ExpedienteMateria, ExpedienteSessao, IntegranteMesa, ExpedienteMateria, ExpedienteSessao, IntegranteMesa,
MateriaLegislativa, Orador, OradorExpediente, OrdemDia, MateriaLegislativa, Orador, OradorExpediente, OrdemDia,
PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao, PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao,
SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente, SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente,
TipoResultadoVotacao, TipoSessaoPlenaria, VotoNominal, TipoResultadoVotacao, TipoSessaoPlenaria,
VotoParlamentar) VotoParlamentar)
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria') TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
@ -190,20 +189,20 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
url = reverse('sapl.sessao:votacaosimbolica', url = reverse('sapl.sessao:votacaosimbolica',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 2: elif obj.tipo_votacao == 2:
url = reverse('sapl.sessao:votacaonominal', url = reverse('sapl.sessao:votacaonominal',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 3: elif obj.tipo_votacao == 3:
url = reverse('sapl.sessao:votacaosecreta', url = reverse('sapl.sessao:votacaosecreta',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
if self.request.user.has_module_perms(AppConfig.label): if self.request.user.has_module_perms(AppConfig.label):
btn_registrar = ''' btn_registrar = '''
<a href="%s" <a href="%s"
@ -238,20 +237,20 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
url = reverse('sapl.sessao:votacaosimbolicaedit', url = reverse('sapl.sessao:votacaosimbolicaedit',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 2: elif obj.tipo_votacao == 2:
url = reverse('sapl.sessao:votacaonominaledit', url = reverse('sapl.sessao:votacaonominaledit',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 3: elif obj.tipo_votacao == 3:
url = reverse('sapl.sessao:votacaosecretaedit', url = reverse('sapl.sessao:votacaosecretaedit',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
obj.resultado = ('<a href="%s">%s</a><br/>%s' % obj.resultado = ('<a href="%s">%s</a><br/>%s' %
(url, (url,
resultado_descricao, resultado_descricao,
@ -310,20 +309,20 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
url = reverse('sapl.sessao:votacaosimbolicaexp', url = reverse('sapl.sessao:votacaosimbolicaexp',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 2: elif obj.tipo_votacao == 2:
url = reverse('sapl.sessao:votacaonominalexp', url = reverse('sapl.sessao:votacaonominalexp',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 3: elif obj.tipo_votacao == 3:
url = reverse('sapl.sessao:votacaosecretaexp', url = reverse('sapl.sessao:votacaosecretaexp',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
if self.request.user.has_module_perms(AppConfig.label): if self.request.user.has_module_perms(AppConfig.label):
btn_registrar = ''' btn_registrar = '''
@ -355,31 +354,32 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
'sapl.sessao:votacaosimbolicaexpedit', 'sapl.sessao:votacaosimbolicaexpedit',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 2: elif obj.tipo_votacao == 2:
url = reverse('sapl.sessao:votacaonominalexpedit', url = reverse('sapl.sessao:votacaonominalexpedit',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
elif obj.tipo_votacao == 3: elif obj.tipo_votacao == 3:
url = reverse('sapl.sessao:votacaosecretaexpedit', url = reverse('sapl.sessao:votacaosecretaexpedit',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
obj.resultado = ('<a href="%s">%s</a><br/>%s' % obj.resultado = ('<a href="%s">%s</a><br/>%s' %
(url, (url,
resultado_descricao, resultado_descricao,
resultado_observacao)) resultado_observacao))
else: else:
if obj.tipo_votacao == 2: if obj.tipo_votacao == 2:
url = reverse('sapl.sessao:votacaonominalexpdetail', url = reverse(
'sapl.sessao:votacaonominalexpdetail',
kwargs={ kwargs={
'pk': obj.sessao_plenaria_id, 'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id, 'oid': obj.pk,
'mid': obj.pk}) 'mid': obj.materia_id})
obj.resultado = ('<a href="%s">%s</a><br/>%s' % obj.resultado = ('<a href="%s">%s</a><br/>%s' %
(url, (url,
resultado_descricao, resultado_descricao,
@ -761,8 +761,8 @@ class ListMateriaOrdemDiaView(FormMixin, DetailView):
autor = [str(a.autor) for a in autoria] autor = [str(a.autor) for a in autoria]
mat = {'pk': pk, mat = {'pk': pk,
'oid': o.materia_id, 'oid': o.id,
'ordem_id': o.id, 'ordem_id': o.materia_id,
'ementa': ementa, 'ementa': ementa,
'titulo': titulo, 'titulo': titulo,
'numero': numero, 'numero': numero,
@ -821,8 +821,8 @@ class ListMateriaOrdemDiaView(FormMixin, DetailView):
autor = [str(a.autor) for a in autoria] autor = [str(a.autor) for a in autoria]
mat = {'pk': pk, mat = {'pk': pk,
'oid': o.materia_id, 'oid': o.id,
'ordem_id': o.id, 'ordem_id': o.materia_id,
'ementa': ementa, 'ementa': ementa,
'titulo': titulo, 'titulo': titulo,
'numero': numero, 'numero': numero,
@ -1388,8 +1388,8 @@ class VotacaoEditView(SessaoPermissionMixin):
self.object = self.get_object() self.object = self.get_object()
form = VotacaoEditForm(request.POST) form = VotacaoEditForm(request.POST)
materia_id = kwargs['oid'] materia_id = kwargs['mid']
ordem_id = kwargs['mid'] ordem_id = kwargs['oid']
if(int(request.POST['anular_votacao']) == 1): if(int(request.POST['anular_votacao']) == 1):
RegistroVotacao.objects.filter( RegistroVotacao.objects.filter(
@ -1417,8 +1417,8 @@ class VotacaoEditView(SessaoPermissionMixin):
else: else:
titulo = _("Não definida") titulo = _("Não definida")
materia_id = kwargs['oid'] materia_id = kwargs['mid']
ordem_id = kwargs['mid'] ordem_id = kwargs['oid']
ordem = OrdemDia.objects.get(id=ordem_id) ordem = OrdemDia.objects.get(id=ordem_id)
@ -1471,7 +1471,7 @@ class VotacaoView(SessaoPermissionMixin):
else: else:
titulo = _("Não definida") titulo = _("Não definida")
ordem_id = kwargs['mid'] ordem_id = kwargs['oid']
ordem = OrdemDia.objects.get(id=ordem_id) ordem = OrdemDia.objects.get(id=ordem_id)
qtde_presentes = PresencaOrdemDia.objects.filter( qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.object.id).count() sessao_plenaria_id=self.object.id).count()
@ -1497,7 +1497,7 @@ class VotacaoView(SessaoPermissionMixin):
else: else:
titulo = _("Não definida") titulo = _("Não definida")
ordem_id = kwargs['mid'] ordem_id = kwargs['oid']
ordem = OrdemDia.objects.get(id=ordem_id) ordem = OrdemDia.objects.get(id=ordem_id)
qtde_presentes = PresencaOrdemDia.objects.filter( qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.object.id).count() sessao_plenaria_id=self.object.id).count()
@ -1515,8 +1515,8 @@ class VotacaoView(SessaoPermissionMixin):
return self.form_valid(form) return self.form_valid(form)
if form.is_valid(): if form.is_valid():
materia_id = kwargs['oid'] materia_id = kwargs['mid']
ordem_id = kwargs['mid'] ordem_id = kwargs['oid']
qtde_presentes = PresencaOrdemDia.objects.filter( qtde_presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=self.object.id).count() sessao_plenaria_id=self.object.id).count()
@ -1568,294 +1568,113 @@ class VotacaoView(SessaoPermissionMixin):
kwargs={'pk': pk}) kwargs={'pk': pk})
class VotacaoNominalView(SessaoPermissionMixin): def fechar_votacao_materia(materia):
template_name = 'sessao/votacao/nominal.html' if type(materia) == OrdemDia:
registro_votacao = RegistroVotacao.objects.filter(ordem=materia)
def get(self, request, *args, **kwargs): voto_parlamentar = VotoParlamentar.objects.filter(ordem=materia)
ordem_id = kwargs['mid']
ordem = OrdemDia.objects.get(id=ordem_id)
total = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=ordem.sessao_plenaria_id).count()
materia = {'materia': ordem.materia, elif type(materia) == ExpedienteMateria:
'ementa': sub( registro_votacao = RegistroVotacao.objects.filter(
'&nbsp;', ' ', strip_tags(ordem.observacao))} expediente=materia)
context = {'materia': materia, 'object': self.get_object(), voto_parlamentar = VotoParlamentar.objects.filter(expediente=materia)
'parlamentares': self.get_parlamentares(ordem.materia),
'tipos': self.get_tipos_votacao(),
'total': total}
return self.render_to_response(context) for v in voto_parlamentar:
v.delete()
def post(self, request, *args, **kwargs):
self.object = self.get_object()
ordem_id = kwargs['mid']
ordem = OrdemDia.objects.get(id=ordem_id)
form = VotacaoNominalForm(request.POST)
if 'cancelar-votacao' in request.POST:
sessao = self.object
materia = ordem.materia
presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=expediente.sessao_plenaria_id)
for p in presentes:
try:
voto = VotoNominal.objects.get(
parlamentar=p.parlamentar,
sessao=self.object.pk,
materia=materia)
except ObjectDoesNotExist:
pass
else:
voto.delete()
ordem.votacao_aberta = False for r in registro_votacao:
ordem.save() r.delete()
return self.form_valid(form)
if form.is_valid(): if materia.resultado:
materia_id = kwargs['oid'] materia.resultado = ''
ordem_id = kwargs['mid'] materia.votacao_aberta = False
materia.save()
votos_sim = 0
votos_nao = 0
abstencoes = 0
nao_votou = 0
for votos in request.POST.getlist('voto_parlamentar'): class VotacaoNominalAbstract(SessaoPermissionMixin):
v = votos.split(':') template_name = 'sessao/votacao/nominal.html'
voto = v[0] ordem = None
parlamentar_id = v[1] expediente = None
if(voto == 'Sim'): def get(self, request, *args, **kwargs):
votos_sim += 1 if self.ordem:
elif(voto == 'o'): ordem_id = kwargs['oid']
votos_nao += 1 if RegistroVotacao.objects.filter(ordem_id=ordem_id).exists():
elif(voto == 'Abstenção'): msg = _('Esta matéria já foi votada!')
abstencoes += 1 messages.add_message(request, messages.ERROR, msg)
elif(voto == 'Não Votou'): return HttpResponseRedirect(reverse(
nao_votou += 1 'sapl.sessao:ordemdia_list', kwargs={'pk': kwargs['pk']}))
try: try:
votacao = RegistroVotacao.objects.get( ordem = OrdemDia.objects.get(id=ordem_id)
materia_id=materia_id,
ordem_id=ordem_id)
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass raise Http404()
else:
votacao.delete()
votacao = RegistroVotacao() presentes = PresencaOrdemDia.objects.filter(
votacao.numero_votos_sim = votos_sim sessao_plenaria_id=ordem.sessao_plenaria_id)
votacao.numero_votos_nao = votos_nao total = presentes.count()
votacao.numero_abstencoes = abstencoes
votacao.observacao = request.POST['observacao']
votacao.materia_id = materia_id
votacao.ordem_id = ordem_id
votacao.tipo_resultado_votacao_id = int(
request.POST['resultado_votacao'])
votacao.save()
for votos in request.POST.getlist('voto_parlamentar'):
v = votos.split(':')
voto = v[0]
parlamentar_id = v[1]
voto_parlamentar = VotoParlamentar()
voto_parlamentar.voto = voto
voto_parlamentar.parlamentar_id = parlamentar_id
voto_parlamentar.votacao_id = votacao.id
voto_parlamentar.save()
ordem = OrdemDia.objects.get(
sessao_plenaria_id=self.object.id,
materia_id=materia_id)
resultado = TipoResultadoVotacao.objects.get(
id=request.POST['resultado_votacao'])
ordem.resultado = resultado.nome
ordem.votacao_aberta = False
ordem.save()
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_parlamentares(self, materia): materia_votacao = ordem
self.object = self.get_object()
presencas = PresencaOrdemDia.objects.filter( elif self.expediente:
sessao_plenaria_id=self.object.id expediente_id = kwargs['oid']
) if (RegistroVotacao.objects.filter(
presentes = [p.parlamentar for p in presencas] expediente_id=expediente_id).exists()):
msg = _('Esta matéria já foi votada!')
messages.add_message(request, messages.ERROR, msg)
return HttpResponseRedirect(reverse(
'sapl.sessao:expedientemateria_list',
kwargs={'pk': kwargs['pk']}))
for parlamentar in Parlamentar.objects.filter(ativo=True):
if parlamentar in presentes:
try: try:
voto = VotoNominal.objects.get( expediente = ExpedienteMateria.objects.get(id=expediente_id)
parlamentar=parlamentar,
sessao=self.object.pk,
materia=materia)
except ObjectDoesNotExist: except ObjectDoesNotExist:
yield [parlamentar, None] raise Http404()
else:
yield [parlamentar, voto.voto]
def get_tipos_votacao(self):
for tipo in TipoResultadoVotacao.objects.all():
yield tipo
def get_success_url(self):
pk = self.kwargs['pk']
return reverse('sapl.sessao:ordemdia_list',
kwargs={'pk': pk})
presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=expediente.sessao_plenaria_id)
total = presentes.count()
class VotacaoNominalEditView(SessaoPermissionMixin): materia_votacao = expediente
template_name = 'sessao/votacao/nominal_edit.html'
def get(self, request, *args, **kwargs):
context = {}
materia_id = kwargs['oid']
ordem_id = kwargs['mid']
votacao = RegistroVotacao.objects.get(
materia_id=materia_id,
ordem_id=ordem_id)
ordem = OrdemDia.objects.get(id=ordem_id)
votos = VotoParlamentar.objects.filter(votacao_id=votacao.id)
list_votos = []
for v in votos:
parlamentar = Parlamentar.objects.get(id=v.parlamentar_id)
list_votos.append({'parlamentar': parlamentar, 'voto': v.voto})
context.update({'votos': list_votos}) materia = {'materia': materia_votacao.materia,
materia = {'materia': ordem.materia,
'ementa': sub( 'ementa': sub(
'&nbsp;', ' ', strip_tags(ordem.observacao))} '&nbsp;', ' ', strip_tags(
context.update({'materia': materia}) materia_votacao.observacao))}
context = {'materia': materia, 'object': self.get_object(),
votacao_existente = {'observacao': sub( 'parlamentares': self.get_parlamentares(presentes),
'&nbsp;', ' ', strip_tags(votacao.observacao)), 'tipos': self.get_tipos_votacao(),
'resultado': votacao.tipo_resultado_votacao.nome, 'total': total}
'tipo_resultado':
votacao.tipo_resultado_votacao_id}
context.update({'votacao': votacao_existente,
'tipos': self.get_tipos_votacao()})
return self.render_to_response(context) return self.render_to_response(context)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
form = VotacaoEditForm(request.POST)
materia_id = kwargs['oid'] if self.ordem:
ordem_id = kwargs['mid'] ordem_id = kwargs['oid']
sessao = self.object
ordem = ExpedienteMateria.objects.get(id=ordem_id)
presentes = PresencaOrdemDia.objects.filter(
sessao_plenaria_id=ordem.sessao_plenaria_id)
for p in presentes:
try: try:
voto = VotoNominal.objects.get( ordem = OrdemDia.objects.get(id=ordem_id)
parlamentar=p.parlamentar,
sessao=self.object.pk,
materia=materia_id)
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass raise Http404()
else:
voto.delete()
if(int(request.POST['anular_votacao']) == 1): materia_votacao = ordem
registro = RegistroVotacao.objects.get(
materia_id=materia_id,
ordem_id=ordem_id)
ordem = OrdemDia.objects.get(
sessao_plenaria_id=self.object.id,
materia_id=materia_id)
ordem.resultado = ''
ordem.votacao_aberta = False
ordem.save()
elif self.expediente:
expediente_id = kwargs['oid']
try: try:
votacao = VotoParlamentar.objects.filter(
votacao_id=registro.id)
for v in votacao:
v.delete()
except:
pass
return self.form_valid(form)
def get_tipos_votacao(self):
for tipo in TipoResultadoVotacao.objects.all():
yield tipo
def get_success_url(self):
pk = self.kwargs['pk']
return reverse('sapl.sessao:ordemdia_list',
kwargs={'pk': pk})
class VotacaoNominalExpedienteView(SessaoPermissionMixin):
template_name = 'sessao/votacao/nominal.html'
def get(self, request, *args, **kwargs):
expediente_id = kwargs['mid']
expediente = ExpedienteMateria.objects.get(id=expediente_id) expediente = ExpedienteMateria.objects.get(id=expediente_id)
total = SessaoPlenariaPresenca.objects.filter( except ObjectDoesNotExist:
sessao_plenaria_id=expediente.sessao_plenaria_id).count() raise Http404()
materia = {'materia': expediente.materia,
'ementa': sub(
'&nbsp;', ' ', strip_tags(expediente.observacao))}
context = {'materia': materia, 'object': self.get_object(),
'parlamentares': self.get_parlamentares(expediente.materia),
'tipos': self.get_tipos_votacao(),
'total': total}
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
expediente_id = kwargs['mid'] materia_votacao = expediente
expediente = ExpedienteMateria.objects.get(id=expediente_id)
form = VotacaoNominalForm(request.POST) form = VotacaoNominalForm(request.POST)
if 'cancelar-votacao' in request.POST: if 'cancelar-votacao' in request.POST:
sessao = self.object fechar_votacao_materia(materia_votacao)
expediente_id = kwargs['mid']
expediente = ExpedienteMateria.objects.get(id=expediente_id)
materia = expediente.materia
presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=expediente.sessao_plenaria_id)
for p in presentes:
try:
voto = VotoNominal.objects.get(
parlamentar=p.parlamentar,
sessao=self.object.pk,
materia=materia)
except ObjectDoesNotExist:
pass
else:
voto.delete()
expediente.votacao_aberta = False
expediente.save()
return self.form_valid(form) return self.form_valid(form)
if form.is_valid(): if form.is_valid():
materia_id = kwargs['oid']
expediente_id = kwargs['mid']
votos_sim = 0 votos_sim = 0
votos_nao = 0 votos_nao = 0
abstencoes = 0 abstencoes = 0
@ -1875,62 +1694,86 @@ class VotacaoNominalExpedienteView(SessaoPermissionMixin):
elif(voto == 'Não Votou'): elif(voto == 'Não Votou'):
nao_votou += 1 nao_votou += 1
try: # Caso todas as opções sejam 'Não votou', fecha a votação
if nao_votou == len(request.POST.getlist('voto_parlamentar')):
fechar_votacao_materia(materia_votacao)
return self.form_valid(form)
if self.ordem:
votacao = RegistroVotacao.objects.filter(
ordem_id=ordem_id)
elif self.expediente:
votacao = RegistroVotacao.objects.filter(
expediente_id=expediente_id)
# Remove todas as votação desta matéria, caso existam
for v in votacao:
v.delete()
votacao = RegistroVotacao() votacao = RegistroVotacao()
votacao.numero_votos_sim = votos_sim votacao.numero_votos_sim = votos_sim
votacao.numero_votos_nao = votos_nao votacao.numero_votos_nao = votos_nao
votacao.numero_abstencoes = abstencoes votacao.numero_abstencoes = abstencoes
votacao.observacao = request.POST['observacao'] votacao.observacao = request.POST['observacao']
votacao.materia_id = materia_id
votacao.expediente = expediente if self.ordem:
votacao.materia_id = ordem.materia.id
votacao.ordem_id = ordem_id
elif self.expediente:
votacao.materia_id = expediente.materia.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.save() votacao.save()
except:
return self.form_invalid(form)
else:
votacao = RegistroVotacao.objects.get(
materia_id=materia_id,
expediente_id=expediente)
for votos in request.POST.getlist('voto_parlamentar'): for votos in request.POST.getlist('voto_parlamentar'):
v = votos.split(':') v = votos.split(':')
voto = v[0] voto = v[0]
parlamentar_id = v[1] parlamentar_id = v[1]
voto_parlamentar = VotoParlamentar() if self.ordem:
voto_parlamentar = VotoParlamentar.objects.get_or_create(
parlamentar_id=parlamentar_id,
ordem=ordem)[0]
elif self.expediente:
voto_parlamentar = VotoParlamentar.objects.get_or_create(
parlamentar_id=parlamentar_id,
expediente=expediente)[0]
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.save() voto_parlamentar.save()
expediente = ExpedienteMateria.objects.get(
sessao_plenaria_id=self.object.id,
materia_id=materia_id)
resultado = TipoResultadoVotacao.objects.get( resultado = TipoResultadoVotacao.objects.get(
id=request.POST['resultado_votacao']) id=request.POST['resultado_votacao'])
expediente.resultado = resultado.nome
expediente.votacao_aberta = False materia_votacao.resultado = resultado.nome
expediente.save() materia_votacao.votacao_aberta = False
materia_votacao.save()
return self.form_valid(form) return self.form_valid(form)
else: else:
return self.form_invalid(form) return self.form_invalid(form)
def get_parlamentares(self, materia): def get_parlamentares(self, presencas):
self.object = self.get_object() self.object = self.get_object()
presencas = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id
)
presentes = [p.parlamentar for p in presencas] presentes = [p.parlamentar for p in presencas]
if self.ordem:
voto_parlamentar = VotoParlamentar.objects.filter(
ordem=self.kwargs['oid'])
elif self.expediente:
voto_parlamentar = VotoParlamentar.objects.filter(
expediente=self.kwargs['oid'])
for parlamentar in Parlamentar.objects.filter(ativo=True): for parlamentar in Parlamentar.objects.filter(ativo=True):
if parlamentar in presentes: if parlamentar in presentes:
try: try:
voto = VotoNominal.objects.get( voto = voto_parlamentar.get(
parlamentar=parlamentar, parlamentar=parlamentar)
sessao=self.object.pk,
materia=materia)
except ObjectDoesNotExist: except ObjectDoesNotExist:
yield [parlamentar, None] yield [parlamentar, None]
else: else:
@ -1942,22 +1785,47 @@ class VotacaoNominalExpedienteView(SessaoPermissionMixin):
def get_success_url(self): def get_success_url(self):
pk = self.kwargs['pk'] pk = self.kwargs['pk']
if self.ordem:
return reverse('sapl.sessao:ordemdia_list',
kwargs={'pk': pk})
elif self.expediente:
return reverse('sapl.sessao:expedientemateria_list', return reverse('sapl.sessao:expedientemateria_list',
kwargs={'pk': pk}) kwargs={'pk': pk})
class VotacaoNominalExpedienteEditView(SessaoPermissionMixin): class VotacaoNominalEditAbstract(SessaoPermissionMixin):
template_name = 'sessao/votacao/nominal_edit.html' template_name = 'sessao/votacao/nominal_edit.html'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
context = {} context = {}
materia_id = kwargs['oid']
expediente_id = kwargs['mid']
if self.ordem:
ordem_id = kwargs['oid']
try:
ordem = OrdemDia.objects.get(id=ordem_id)
votacao = RegistroVotacao.objects.get( votacao = RegistroVotacao.objects.get(
materia_id=materia_id, ordem_id=ordem_id)
expediente_id=expediente_id) except ObjectDoesNotExist:
raise Http404()
materia = ordem.materia
observacao = ordem.observacao
elif self.expediente:
expediente_id = kwargs['oid']
try:
expediente = ExpedienteMateria.objects.get(id=expediente_id) expediente = ExpedienteMateria.objects.get(id=expediente_id)
votacao = RegistroVotacao.objects.get(
expediente_id=expediente_id)
except ObjectDoesNotExist:
raise Http404()
materia = expediente.materia
observacao = expediente.observacao
votos = VotoParlamentar.objects.filter(votacao_id=votacao.id) votos = VotoParlamentar.objects.filter(votacao_id=votacao.id)
list_votos = [] list_votos = []
@ -1967,9 +1835,9 @@ class VotacaoNominalExpedienteEditView(SessaoPermissionMixin):
context.update({'votos': list_votos}) context.update({'votos': list_votos})
materia = {'materia': expediente.materia, materia = {'materia': materia,
'ementa': sub( 'ementa': sub(
'&nbsp;', ' ', strip_tags(expediente.observacao))} '&nbsp;', ' ', strip_tags(observacao))}
context.update({'materia': materia}) context.update({'materia': materia})
votacao_existente = {'observacao': sub( votacao_existente = {'observacao': sub(
@ -1986,45 +1854,25 @@ class VotacaoNominalExpedienteEditView(SessaoPermissionMixin):
self.object = self.get_object() self.object = self.get_object()
form = VotacaoEditForm(request.POST) form = VotacaoEditForm(request.POST)
materia_id = kwargs['oid'] if self.ordem:
expediente_id = kwargs['mid'] ordem_id = kwargs['oid']
sessao = self.object
expediente = ExpedienteMateria.objects.get(id=expediente_id)
presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=expediente.sessao_plenaria_id)
for p in presentes:
try: try:
voto = VotoNominal.objects.get( materia_votacao = OrdemDia.objects.get(id=ordem_id)
parlamentar=p.parlamentar,
sessao=self.object.pk,
materia=materia_id)
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass raise Http404()
else:
voto.delete()
if(int(request.POST['anular_votacao']) == 1): elif self.expediente:
registro = RegistroVotacao.objects.get( expediente_id = kwargs['oid']
materia_id=materia_id,
expediente_id=expediente_id)
expediente = ExpedienteMateria.objects.get(
sessao_plenaria_id=self.object.id,
materia_id=materia_id)
expediente.resultado = ''
expediente.votacao_aberta = False
expediente.save()
try: try:
votacao = VotoParlamentar.objects.filter( materia_votacao = ExpedienteMateria.objects.get(
votacao_id=registro.id) id=expediente_id)
for v in votacao: except ObjectDoesNotExist:
v.delete() raise Http404()
except:
pass
registro.delete() if(int(request.POST['anular_votacao']) == 1):
fechar_votacao_materia(materia_votacao)
return self.form_valid(form) return self.form_valid(form)
@ -2034,16 +1882,42 @@ class VotacaoNominalExpedienteEditView(SessaoPermissionMixin):
def get_success_url(self): def get_success_url(self):
pk = self.kwargs['pk'] pk = self.kwargs['pk']
if self.ordem:
return reverse('sapl.sessao:ordemdia_list',
kwargs={'pk': pk})
elif self.expediente:
return reverse('sapl.sessao:expedientemateria_list', return reverse('sapl.sessao:expedientemateria_list',
kwargs={'pk': pk}) kwargs={'pk': pk})
class VotacaoNominalView(VotacaoNominalAbstract):
ordem = True
expediente = False
class VotacaoNominalExpedienteView(VotacaoNominalAbstract):
expediente = True
ordem = False
class VotacaoNominalEditView(VotacaoNominalEditAbstract):
ordem = True
expediente = False
class VotacaoNominalExpedienteEditView(VotacaoNominalEditAbstract):
expediente = True
ordem = False
class VotacaoNominalExpedienteDetailView(DetailView): class VotacaoNominalExpedienteDetailView(DetailView):
template_name = 'sessao/votacao/nominal_detail.html' template_name = 'sessao/votacao/nominal_detail.html'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
context = {} context = {}
materia_id = kwargs['oid'] materia_id = kwargs['mid']
expediente_id = kwargs['mid'] expediente_id = kwargs['oid']
votacao = RegistroVotacao.objects.get( votacao = RegistroVotacao.objects.get(
materia_id=materia_id, materia_id=materia_id,
@ -2105,7 +1979,7 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
else: else:
titulo = _("Não definida") titulo = _("Não definida")
expediente_id = kwargs['mid'] expediente_id = kwargs['oid']
expediente = ExpedienteMateria.objects.get(id=expediente_id) expediente = ExpedienteMateria.objects.get(id=expediente_id)
qtde_presentes = SessaoPlenariaPresenca.objects.filter( qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id).count() sessao_plenaria_id=self.object.id).count()
@ -2132,7 +2006,7 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
else: else:
titulo = _("Não definida") titulo = _("Não definida")
expediente_id = kwargs['mid'] expediente_id = kwargs['oid']
expediente = ExpedienteMateria.objects.get(id=expediente_id) expediente = ExpedienteMateria.objects.get(id=expediente_id)
qtde_presentes = SessaoPlenariaPresenca.objects.filter( qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id).count() sessao_plenaria_id=self.object.id).count()
@ -2151,8 +2025,8 @@ class VotacaoExpedienteView(SessaoPermissionMixin):
return self.form_valid(form) return self.form_valid(form)
if form.is_valid(): if form.is_valid():
materia_id = kwargs['oid'] materia_id = kwargs['mid']
expediente_id = kwargs['mid'] expediente_id = kwargs['oid']
qtde_presentes = SessaoPlenariaPresenca.objects.filter( qtde_presentes = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=self.object.id).count() sessao_plenaria_id=self.object.id).count()
@ -2235,8 +2109,8 @@ class VotacaoExpedienteEditView(SessaoPermissionMixin):
else: else:
titulo = _("Não definida") titulo = _("Não definida")
materia_id = kwargs['oid'] materia_id = kwargs['mid']
expediente_id = kwargs['mid'] expediente_id = kwargs['oid']
expediente = ExpedienteMateria.objects.get(id=expediente_id) expediente = ExpedienteMateria.objects.get(id=expediente_id)
@ -2267,8 +2141,8 @@ class VotacaoExpedienteEditView(SessaoPermissionMixin):
self.object = self.get_object() self.object = self.get_object()
form = VotacaoEditForm(request.POST) form = VotacaoEditForm(request.POST)
materia_id = kwargs['oid'] materia_id = kwargs['mid']
expediente_id = kwargs['mid'] expediente_id = kwargs['oid']
if(int(request.POST['anular_votacao']) == 1): if(int(request.POST['anular_votacao']) == 1):
try: try:

13
sapl/utils.py

@ -1,13 +1,15 @@
import hashlib
import logging
import os
import re
from datetime import date from datetime import date
from functools import wraps from functools import wraps
from subprocess import PIPE, call from subprocess import PIPE, call
from threading import Thread from threading import Thread
from unicodedata import normalize as unicodedata_normalize from unicodedata import normalize as unicodedata_normalize
import hashlib
import logging
import os
import re
import django_filters
import magic
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Button from crispy_forms.layout import HTML, Button
from django import forms from django import forms
@ -20,13 +22,10 @@ from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from floppyforms import ClearableFileInput from floppyforms import ClearableFileInput
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
import django_filters
import magic
from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
from sapl.settings import BASE_DIR, PROJECT_DIR from sapl.settings import BASE_DIR, PROJECT_DIR
sapl_logger = logging.getLogger(BASE_DIR.name) sapl_logger = logging.getLogger(BASE_DIR.name)

Loading…
Cancel
Save