From d39b65a8289625ef27e1e4b8db76d9c44ec7d5fa Mon Sep 17 00:00:00 2001 From: joaohortsenado <100957576+joaohortsenado@users.noreply.github.com> Date: Tue, 6 Dec 2022 10:34:26 -0300 Subject: [PATCH] feat: nova funcionalidade para leitura em bloco de materias do expediente (#3618) * feat: nova funcionalidade para leitura em bloco de materias do expediente * fix: Ajustes na Leitura em bloco, inclusao da funcionalidade para Ordem do dia Co-authored-by: joao --- sapl/sessao/urls.py | 7 + sapl/sessao/views.py | 264 ++++++++++++------ .../sessao/leitura/leitura_bloco.html | 114 ++++++++ sapl/templates/sessao/subnav.yaml | 6 + 4 files changed, 305 insertions(+), 86 deletions(-) create mode 100644 sapl/templates/sessao/leitura/leitura_bloco.html diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index 8464c2d78..05e19a844 100644 --- a/sapl/sessao/urls.py +++ b/sapl/sessao/urls.py @@ -31,6 +31,7 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente, sessao_legislativa_legislatura_ajax, VotacaoEmBlocoOrdemDia, VotacaoEmBlocoExpediente, VotacaoEmBlocoSimbolicaView, VotacaoEmBlocoNominalView, + LeituraEmBlocoExpediente, LeituraEmBlocoOrdemDia, recuperar_nome_tipo_sessao, ExpedienteLeituraView, OrdemDiaLeituraView, @@ -158,6 +159,12 @@ urlpatterns = [ url(r'^sessao/(?P\d+)/votacao_bloco_expediente$', VotacaoEmBlocoExpediente.as_view(), name='votacao_bloco_expediente'), + url(r'^sessao/(?P\d+)/leitura_bloco_expediente$', + LeituraEmBlocoExpediente.as_view(), + name='leitura_bloco_expediente'), + url(r'^sessao/(?P\d+)/leitura_bloco_ordem_dia$', + LeituraEmBlocoOrdemDia.as_view(), + name='leitura_bloco_ordem_dia'), url(r'^sessao/(?P\d+)/resumo$', ResumoView.as_view(), name='resumo'), url(r'^sessao/(?P\d+)/resumo_ata$', diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 97ec4be36..4ad940c96 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -38,10 +38,10 @@ from sapl.materia.models import (Autoria, TipoMateriaLegislativa, from sapl.materia.views import MateriaLegislativaPesquisaView from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato, Parlamentar, SessaoLegislativa) -from sapl.protocoloadm.models import TipoDocumentoAdministrativo,\ +from sapl.protocoloadm.models import TipoDocumentoAdministrativo, \ DocumentoAdministrativo from sapl.sessao.apps import AppConfig -from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm, OrdemExpedienteLeituraForm,\ +from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm, OrdemExpedienteLeituraForm, \ CorrespondenciaForm, CorrespondenciaEmLoteFilterSet from sapl.sessao.models import Correspondencia from sapl.settings import TIME_ZONE @@ -62,7 +62,6 @@ from .models import (Bancada, CargoBancada, CargoMesa, RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia, ORDENACAO_RESUMO, RegistroLeitura) - TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria') TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa') CargoBancadaCrud = CrudAux.build(CargoBancada, '') @@ -167,7 +166,8 @@ def verifica_sessao_iniciada(request, spk, is_leitura=False): username = request.user.username aux_text = 'leitura' if is_leitura else 'votação' logger.info('user=' + username + '. Não é possível abrir matérias para {}. ' - 'Esta SessaoPlenaria (id={}) não foi iniciada ou está finalizada.'.format(aux_text, spk)) + 'Esta SessaoPlenaria (id={}) não foi iniciada ou está finalizada.'.format( + aux_text, spk)) msg = _('Não é possível abrir matérias para {}. ' 'Esta Sessão Plenária não foi iniciada ou está finalizada.' ' Vá em "Abertura"->"Dados Básicos" e altere os valores dos campos necessários.'.format(aux_text)) @@ -199,7 +199,7 @@ def abrir_votacao(request, pk, spk): materia_votacao = model.objects.get(id=pk) is_leitura = materia_votacao.tipo_votacao == 4 if (verifica_presenca(request, presenca_model, spk, is_leitura) and - verifica_votacoes_abertas(request) and + verifica_votacoes_abertas(request) and verifica_sessao_iniciada(request, spk, is_leitura)): materia_votacao.votacao_aberta = True sessao = SessaoPlenaria.objects.get(id=spk) @@ -235,22 +235,22 @@ def customize_link_materia(context, pk, has_permission, is_expediente): num_protocolo = materia.numero_protocolo if materia.numero_protocolo else "-" sessao_plenaria = SessaoPlenaria.objects.get(id=pk) data_sessao = sessao_plenaria.data_fim if sessao_plenaria.data_fim else sessao_plenaria.data_inicio - tramitacao = Tramitacao.objects\ - .select_related('materia', 'status', 'materia__tipo')\ - .filter(materia=materia, turno__isnull=False, data_tramitacao__lte=data_sessao)\ - .exclude(turno__exact='')\ - .order_by('-data_tramitacao', '-id')\ - .first() + tramitacao = Tramitacao.objects \ + .select_related('materia', 'status', 'materia__tipo') \ + .filter(materia=materia, turno__isnull=False, data_tramitacao__lte=data_sessao) \ + .exclude(turno__exact='') \ + .order_by('-data_tramitacao', '-id') \ + .first() turno = '-' if tramitacao: for t in Tramitacao.TURNO_CHOICES: if t[0] == tramitacao.turno: turno = t[1] break - materia_em_tramitacao = MateriaEmTramitacao.objects\ - .select_related("materia", "tramitacao")\ - .filter(materia=materia)\ - .first() + materia_em_tramitacao = MateriaEmTramitacao.objects \ + .select_related("materia", "tramitacao") \ + .filter(materia=materia) \ + .first() # idUnica para cada materia idAutor = "autor" + str(i) idAutores = "autores" + str(i) @@ -274,8 +274,8 @@ def customize_link_materia(context, pk, has_permission, is_expediente): exist_leitura = obj.registroleitura_set.filter( materia=obj.materia).exists() - if (obj.tipo_votacao != 4 and not exist_resultado and not exist_retirada) or\ - (obj.tipo_votacao == 4 and not exist_leitura): + if (obj.tipo_votacao != LEITURA and not exist_resultado and not exist_retirada) or \ + (obj.tipo_votacao == LEITURA and not exist_leitura): if obj.votacao_aberta: url = '' if is_expediente: @@ -472,11 +472,11 @@ def customize_link_materia(context, pk, has_permission, is_expediente): 'mid': obj.materia_id}) resultado = ( - '%s

%s
' % ( - url, - context.get('page', 1), - resultado_descricao, - resultado_observacao)) + '%s

%s
' % ( + url, + context.get('page', 1), + resultado_descricao, + resultado_observacao)) else: if obj.tipo_votacao == NOMINAL: @@ -487,7 +487,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente): 'pk': obj.sessao_plenaria_id, 'oid': obj.pk, 'mid': obj.materia_id}) + \ - '?&materia=expediente' + '?&materia=expediente' else: url = reverse( 'sapl.sessao:votacao_nominal_transparencia', @@ -495,7 +495,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente): 'pk': obj.sessao_plenaria_id, 'oid': obj.pk, 'mid': obj.materia_id}) + \ - '?&materia=ordem' + '?&materia=ordem' resultado = ('%s
%s
' % (url, @@ -510,7 +510,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente): 'pk': obj.sessao_plenaria_id, 'oid': obj.pk, 'mid': obj.materia_id}) + \ - '?&materia=expediente' + '?&materia=expediente' else: url = reverse( 'sapl.sessao:votacao_simbolica_transparencia', @@ -518,7 +518,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente): 'pk': obj.sessao_plenaria_id, 'oid': obj.pk, 'mid': obj.materia_id}) + \ - '?&materia=ordem' + '?&materia=ordem' resultado = ('%s
%s
' % (url, @@ -673,8 +673,8 @@ class TransferenciaMateriasSessaoAbstract(PermissionRequiredMixin, ListView): exp = ExpedienteMateria.objects.filter(sessao_plenaria=sessao) numero_ordem = exp.last().numero_ordem if exp.exists() else 0 for num_ordem, expediente in enumerate( - ExpedienteMateria.objects.filter(id__in=marcadas), - numero_ordem + 1 + ExpedienteMateria.objects.filter(id__in=marcadas), + numero_ordem + 1 ): lista_expediente.append( ExpedienteMateria( @@ -694,7 +694,7 @@ class TransferenciaMateriasSessaoAbstract(PermissionRequiredMixin, ListView): o = OrdemDia.objects.filter(sessao_plenaria=sessao) numero_ordem = o.last().numero_ordem if o.exists() else 0 for num_ordem, ordemdia in enumerate( - OrdemDia.objects.filter(id__in=marcadas), numero_ordem + 1 + OrdemDia.objects.filter(id__in=marcadas), numero_ordem + 1 ): lista_ordemdia.append( OrdemDia( @@ -780,9 +780,9 @@ class MateriaOrdemDiaCrud(MasterDetailCrud): pk=self.kwargs['pk']).data_inicio.strftime('%d/%m/%Y') max_numero_ordem = OrdemDia.objects.filter( sessao_plenaria=self.kwargs['pk']).aggregate( - Max('numero_ordem'))['numero_ordem__max'] + Max('numero_ordem'))['numero_ordem__max'] self.initial['numero_ordem'] = ( - max_numero_ordem if max_numero_ordem else 0) + 1 + max_numero_ordem if max_numero_ordem else 0) + 1 return self.initial def get_success_url(self): @@ -923,9 +923,9 @@ class ExpedienteMateriaCrud(MasterDetailCrud): pk=self.kwargs['pk']).data_inicio.strftime('%d/%m/%Y') max_numero_ordem = ExpedienteMateria.objects.filter( sessao_plenaria=self.kwargs['pk']).aggregate( - Max('numero_ordem'))['numero_ordem__max'] + Max('numero_ordem'))['numero_ordem__max'] initial['numero_ordem'] = ( - max_numero_ordem if max_numero_ordem else 0) + 1 + max_numero_ordem if max_numero_ordem else 0) + 1 return initial def get_success_url(self): @@ -1312,7 +1312,7 @@ class SessaoCrud(Crud): username = self.request.user.username self.logger.error('user=' + username + '. Cadastre alguma legislatura antes de adicionar ' - 'uma sessão plenária!') + 'uma sessão plenária!') messages.add_message(self.request, messages.ERROR, msg) return {} @@ -1405,7 +1405,7 @@ class PresencaView(FormMixin, PresencaMixin, DetailView): # Id dos parlamentares presentes marcados = request.POST.getlist('presenca_ativos') \ - + request.POST.getlist('presenca_inativos') + + request.POST.getlist('presenca_inativos') # Deletar os que foram desmarcados deletar = set(presentes_banco) - set(marcados) @@ -1461,7 +1461,7 @@ class PainelView(PermissionRequiredForAppCrudMixin, TemplateView): username = self.request.user.username self.logger.error('user=' + username + '. Você precisa primeiro configurar os cronômetros' - ' nas Configurações da Aplicação') + ' nas Configurações da Aplicação') msg = _( 'Você precisa primeiro configurar os cronômetros \ nas Configurações da Aplicação') @@ -1520,7 +1520,7 @@ class PresencaOrdemDiaView(FormMixin, PresencaMixin, DetailView): # Id dos parlamentares presentes marcados = request.POST.getlist('presenca_ativos') \ - + request.POST.getlist('presenca_inativos') + + request.POST.getlist('presenca_inativos') # Deletar os que foram desmarcados deletar = set(presentes_banco) - set(marcados) @@ -1782,7 +1782,7 @@ def insere_parlamentar_composicao(request): username = request.user.username if request.user.has_perm( '%s.add_%s' % ( - AppConfig.label, IntegranteMesa._meta.model_name)): + AppConfig.label, IntegranteMesa._meta.model_name)): composicao = IntegranteMesa() @@ -1815,8 +1815,9 @@ def insere_parlamentar_composicao(request): cargo_id=composicao.cargo.id).exists() if parlamentar_ja_inserido: - logger.debug("user=" + username + ". Parlamentar (id={}) já inserido na sessao_plenaria(id={}) e cargo(ìd={})." - .format(request.POST['parlamentar'], composicao.sessao_plenaria.id, composicao.cargo.id)) + logger.debug( + "user=" + username + ". Parlamentar (id={}) já inserido na sessao_plenaria(id={}) e cargo(ìd={})." + .format(request.POST['parlamentar'], composicao.sessao_plenaria.id, composicao.cargo.id)) return JsonResponse({'msg': ('Parlamentar já inserido!', 0)}) composicao.save() @@ -1843,8 +1844,8 @@ def remove_parlamentar_composicao(request): logger = logging.getLogger(__name__) username = request.user.username if request.POST and request.user.has_perm( - '%s.delete_%s' % ( - AppConfig.label, IntegranteMesa._meta.model_name)): + '%s.delete_%s' % ( + AppConfig.label, IntegranteMesa._meta.model_name)): if 'composicao_mesa' in request.POST: try: @@ -1968,7 +1969,6 @@ def get_mesa_diretora(sessao_plenaria): def get_presenca_sessao(sessao_plenaria): - parlamentares_sessao = [p.parlamentar for p in SessaoPlenariaPresenca.objects.filter( sessao_plenaria_id=sessao_plenaria.id ).order_by('parlamentar__nome_parlamentar').distinct()] @@ -2029,7 +2029,8 @@ def get_materias_expediente(sessao_plenaria): for m in ExpedienteMateria.objects.select_related("materia").filter(sessao_plenaria_id=sessao_plenaria.id): tramitacao = '' data_sessao = sessao_plenaria.data_fim if sessao_plenaria.data_fim else sessao_plenaria.data_inicio - for aux_tramitacao in Tramitacao.objects.filter(materia=m.materia, data_tramitacao__lte=data_sessao).order_by('-data_tramitacao', '-id'): + for aux_tramitacao in Tramitacao.objects.filter(materia=m.materia, data_tramitacao__lte=data_sessao).order_by( + '-data_tramitacao', '-id'): if aux_tramitacao.turno: tramitacao = aux_tramitacao break @@ -2175,7 +2176,8 @@ def get_materias_ordem_do_dia(sessao_plenaria): for o in OrdemDia.objects.filter(sessao_plenaria_id=sessao_plenaria.id): tramitacao = '' data_sessao = sessao_plenaria.data_fim if sessao_plenaria.data_fim else sessao_plenaria.data_inicio - for aux_tramitacao in Tramitacao.objects.filter(materia=o.materia, data_tramitacao__lte=data_sessao).order_by('-data_tramitacao', '-id'): + for aux_tramitacao in Tramitacao.objects.filter(materia=o.materia, data_tramitacao__lte=data_sessao).order_by( + '-data_tramitacao', '-id'): if aux_tramitacao.turno: tramitacao = aux_tramitacao break @@ -2316,8 +2318,8 @@ class ResumoView(DetailView): # Votos de Votação Nominal de Matérias Expediente votacoes = [] - for mevn in ExpedienteMateria.objects.filter(sessao_plenaria_id=self.object.id, tipo_votacao=2)\ - .order_by('-materia'): + for mevn in ExpedienteMateria.objects.filter(sessao_plenaria_id=self.object.id, tipo_votacao=2) \ + .order_by('-materia'): votos_materia = [] titulo_materia = mevn.materia registro = RegistroVotacao.objects.filter(expediente=mevn) @@ -2437,7 +2439,7 @@ class ResumoView(DetailView): }) except KeyError as e: self.logger.error("KeyError: " + str(e) + ". Erro ao tentar utilizar " - "configuração de ordenação. Utilizando ordenação padrão.") + "configuração de ordenação. Utilizando ordenação padrão.") context.update({ 'primeiro_ordenacao': 'identificacao_basica.html', 'segundo_ordenacao': 'conteudo_multimidia.html', @@ -2510,7 +2512,6 @@ class ExpedienteView(FormMixin, DetailView): list_conteudo = request.POST.getlist('conteudo') for tipo, conteudo in zip(list_tipo, list_conteudo): - ExpedienteSessao.objects.filter( sessao_plenaria_id=self.object.id, tipo_id=tipo).delete() @@ -2523,8 +2524,9 @@ class ExpedienteView(FormMixin, DetailView): msg = _('Registro salvo com sucesso') messages.add_message(self.request, messages.SUCCESS, msg) - self.logger.info('user=' + username + '. ExpedienteSessao(sessao_plenaria_id={} e tipo_id={}) salvo com sucesso.' - .format(self.object.id, tipo)) + self.logger.info( + 'user=' + username + '. ExpedienteSessao(sessao_plenaria_id={} e tipo_id={}) salvo com sucesso.' + .format(self.object.id, tipo)) return self.form_valid(form) else: @@ -2609,7 +2611,8 @@ class OcorrenciaSessaoView(FormMixin, DetailView): username = self.request.user.username self.logger.info( - 'user=' + username + '. OcorrenciaSessao de sessao_plenaria_id={} atualizada com sucesso.'.format(self.object.id)) + 'user=' + username + '. OcorrenciaSessao de sessao_plenaria_id={} atualizada com sucesso.'.format( + self.object.id)) @method_decorator(permission_required('sessao.add_ocorrenciasessao')) def post(self, request, *args, **kwargs): @@ -2677,7 +2680,8 @@ class ConsideracoesFinaisView(FormMixin, DetailView): username = self.request.user.username self.logger.info( - 'user=' + username + '. consideracoesFinais de sessao_plenaria_id={} atualizada com sucesso.'.format(self.object.id)) + 'user=' + username + '. consideracoesFinais de sessao_plenaria_id={} atualizada com sucesso.'.format( + self.object.id)) @method_decorator(permission_required('sessao.add_consideracoesfinais')) def post(self, request, *args, **kwargs): @@ -2701,7 +2705,6 @@ class ConsideracoesFinaisView(FormMixin, DetailView): class VotacaoEditView(SessaoPermissionMixin): - ''' Votação Simbólica e Secreta ''' @@ -2716,7 +2719,7 @@ class VotacaoEditView(SessaoPermissionMixin): materia_id = kwargs['mid'] ordem_id = kwargs['oid'] - if(int(request.POST['anular_votacao']) == 1): + if (int(request.POST['anular_votacao']) == 1): RegistroVotacao.objects.filter(ordem_id=ordem_id).delete() ordem = OrdemDia.objects.get(id=ordem_id) @@ -2752,7 +2755,7 @@ class VotacaoEditView(SessaoPermissionMixin): ' ', ' ', strip_tags(votacao.observacao)), 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': - votacao.tipo_resultado_votacao_id} + votacao.tipo_resultado_votacao_id} context.update({'votacao_titulo': titulo, 'votacao': votacao_existente, 'tipos': self.get_tipos_votacao()}) @@ -2774,7 +2777,6 @@ class VotacaoEditView(SessaoPermissionMixin): class VotacaoView(SessaoPermissionMixin): - """ Votação Simbólica e Secreta """ @@ -2895,7 +2897,8 @@ class VotacaoView(SessaoPermissionMixin): except Exception as e: username = request.user.username self.logger.error('user=' + username + '. Problemas ao salvar RegistroVotacao da materia de id={} ' - 'e da ordem de id={}. '.format(materia_id, ordem_id) + str(e)) + 'e da ordem de id={}. '.format(materia_id, ordem_id) + str( + e)) return self.form_invalid(form) else: ordem = OrdemDia.objects.get(id=ordem_id) @@ -3108,7 +3111,7 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): # Caso todas as opções sejam 'Não votou', fecha a votação if nao_votou == len(request.POST.getlist('voto_parlamentar')): self.logger.error('user=' + username + '. Não é possível finalizar a votação sem ' - 'nenhum voto') + 'nenhum voto') form.add_error(None, 'Não é possível finalizar a votação sem ' 'nenhum voto') return self.form_invalid(form) @@ -3266,7 +3269,8 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): if not ordem or not votacao: self.logger.error( - 'user=' + username + '. Objeto OrdemDia com id={} ou RegistroVotacao de OrdemDia não existe.'.format(ordem_id)) + 'user=' + username + '. Objeto OrdemDia com id={} ou RegistroVotacao de OrdemDia não existe.'.format( + ordem_id)) raise Http404() materia = ordem.materia @@ -3354,7 +3358,7 @@ class VotacaoNominalEditAbstract(SessaoPermissionMixin): 'user=' + username + '. Objeto ExpedienteMateria com id={} não existe.'.format(expediente_id)) raise Http404() - if(int(request.POST['anular_votacao']) == 1): + if (int(request.POST['anular_votacao']) == 1): fechar_votacao_materia(materia_votacao) return self.form_valid(form) @@ -3430,7 +3434,7 @@ class VotacaoNominalTransparenciaDetailView(TemplateView): ' ', ' ', strip_tags(votacao.observacao)), 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': - votacao.tipo_resultado_votacao_id} + votacao.tipo_resultado_votacao_id} context.update({'resultado_votacao': votacao_existente, 'tipos': self.get_tipos_votacao()}) @@ -3470,7 +3474,7 @@ class VotacaoNominalExpedienteDetailView(DetailView): ' ', ' ', strip_tags(votacao.observacao)), 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': - votacao.tipo_resultado_votacao_id} + votacao.tipo_resultado_votacao_id} context.update({'votacao': votacao_existente, 'tipos': self.get_tipos_votacao()}) @@ -3518,7 +3522,7 @@ class VotacaoSimbolicaTransparenciaDetailView(TemplateView): ' ', ' ', strip_tags(votacao.observacao)), 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': - votacao.tipo_resultado_votacao_id} + votacao.tipo_resultado_votacao_id} context.update({'resultado_votacao': votacao_existente, 'tipos': self.get_tipos_votacao()}) @@ -3530,7 +3534,6 @@ class VotacaoSimbolicaTransparenciaDetailView(TemplateView): class VotacaoExpedienteView(SessaoPermissionMixin): - """ Votação Simbólica e Secreta """ @@ -3683,7 +3686,6 @@ class VotacaoExpedienteView(SessaoPermissionMixin): class VotacaoExpedienteEditView(SessaoPermissionMixin): - """ Votação Simbólica e Secreta """ @@ -3735,7 +3737,7 @@ class VotacaoExpedienteEditView(SessaoPermissionMixin): ' ', ' ', strip_tags(votacao.observacao)), 'resultado': votacao.tipo_resultado_votacao.nome, 'tipo_resultado': - votacao.tipo_resultado_votacao_id} + votacao.tipo_resultado_votacao_id} context.update({'votacao_titulo': titulo, 'votacao': votacao_existente}) @@ -3887,8 +3889,8 @@ class PautaSessaoDetailView(DetailView): # ===================================================================== # Expedientes expedientes = [] - for e in ExpedienteSessao.objects.select_related("tipo").filter(sessao_plenaria_id=self.object.id)\ - .order_by('tipo__ordenacao'): + for e in ExpedienteSessao.objects.select_related("tipo").filter(sessao_plenaria_id=self.object.id) \ + .order_by('tipo__ordenacao'): conteudo = e.conteudo from sapl.relatorios.views import is_empty if not is_empty(conteudo): @@ -4070,7 +4072,8 @@ def verifica_materia_sessao_plenaria_ajax(request): materia=id_materia_selecionada ).exists() - return JsonResponse({'is_materia_presente': is_materia_presente, 'is_materia_presente_any_sessao': is_materia_presente_any_sessao}) + return JsonResponse( + {'is_materia_presente': is_materia_presente, 'is_materia_presente_any_sessao': is_materia_presente_any_sessao}) class AdicionarVariasMateriasExpediente(PermissionRequiredForAppCrudMixin, @@ -4217,7 +4220,7 @@ class AdicionarVariasMateriasOrdemDia(AdicionarVariasMateriasExpediente): MateriaLegislativa.objects.get(id=m)) messages.add_message(request, messages.ERROR, msg) self.logger.error('user=' + username + '. Formulário Inválido. Você esqueceu de selecionar ' - 'o tipo de votação de MateriaLegislativa com id={}'.format(m)) + 'o tipo de votação de MateriaLegislativa com id={}'.format(m)) return self.get(request, self.kwargs) @@ -4316,7 +4319,6 @@ class JustificativaAusenciaCrud(MasterDetailCrud): @property def layout_display(self): - layout = super().layout_display if self.object.ausencia == 2: @@ -4335,7 +4337,6 @@ class JustificativaAusenciaCrud(MasterDetailCrud): layout_key = None def get_context_data_old(self, **kwargs): - context = super().get_context_data(**kwargs) presencas = SessaoPlenariaPresenca.objects.filter( @@ -4371,7 +4372,6 @@ class JustificativaAusenciaCrud(MasterDetailCrud): kwargs={'pk': self.kwargs['pk']}) class UpdateView(MasterDetailCrud.UpdateView): - form_class = JustificativaAusenciaForm layout_key = None @@ -4384,6 +4384,97 @@ class JustificativaAusenciaCrud(MasterDetailCrud): pass +class LeituraEmBloco(PermissionRequiredForAppCrudMixin, ListView): + template_name = 'sessao/leitura/leitura_bloco.html' + app_label = AppConfig.label + expediente = True + paginate_by = 100 + + def get_queryset(self): + return ExpedienteMateria.objects.filter(sessao_plenaria_id=self.kwargs['pk'], + retiradapauta=None, tipo_votacao=LEITURA, registroleitura__materia=None) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['pk'] = self.kwargs['pk'] + context['root_pk'] = self.kwargs['pk'] + if not verifica_sessao_iniciada(self.request, self.kwargs['pk']): + context['sessao_iniciada'] = False + return context + context['sessao_iniciada'] = True + context['turno_choices'] = Tramitacao.TURNO_CHOICES + context['title'] = SessaoPlenaria.objects.get(id=self.kwargs['pk']) + if self.expediente: + context['expediente'] = True + else: + context['expediente'] = False + return context + + def post(self, request, *args, **kwargs): + if 'marcadas_4' in request.POST: + models = None + selectedlist = request.POST.getlist('marcadas_4') + if request.POST['origem'] == 'ordem': + models = OrdemDia.objects.filter(id__in=selectedlist) + elif request.POST['origem'] == 'expediente': + models = ExpedienteMateria.objects.filter(id__in=selectedlist) + + if not models: + messages.add_message(self.request, messages.ERROR, + _('Impossível localizar as matérias selecionadas')) + return self.get(request, self.kwargs) + + materias = [m.materia for m in models] + RegistroLeitura.objects.filter(materia__in=materias).delete() + leituras = [] + for m in models: + obj = None + if isinstance(m, ExpedienteMateria): + obj = RegistroLeitura(expediente=m, materia=m.materia, + observacao=request.POST['observacao'], + user=self.request.user, + ip=get_client_ip(self.request)) + elif isinstance(m, OrdemDia): + obj = RegistroLeitura(ordem=m, materia=m.materia, + observacao=request.POST['observacao'], + user=self.request.user, + ip=get_client_ip(self.request)) + leituras.append(obj) + + RegistroLeitura.objects.bulk_create(leituras) + else: + messages.add_message(self.request, messages.ERROR, _('Nenhuma matéria selecionada para leitura em Bloco')) + return self.get(request, self.kwargs) + + return HttpResponseRedirect(self.get_success_url()) + + def get_success_url(self): + if self.request.POST['origem'] == 'ordem': + return reverse('sapl.sessao:ordemdia_list', + kwargs={'pk': self.kwargs['pk']}) + else: + return reverse('sapl.sessao:expedientemateria_list', + kwargs={'pk': self.kwargs['pk']}) + + +class LeituraEmBlocoExpediente(LeituraEmBloco): + expediente = True + paginate_by = 100 + + def get_queryset(self): + return ExpedienteMateria.objects.filter(sessao_plenaria_id=self.kwargs['pk'], + retiradapauta=None, tipo_votacao=LEITURA, registroleitura__materia=None) + + +class LeituraEmBlocoOrdemDia(LeituraEmBloco): + expediente = False + paginate_by = 100 + + def get_queryset(self): + return OrdemDia.objects.filter(sessao_plenaria_id=self.kwargs['pk'], + retiradapauta=None, tipo_votacao=LEITURA, registroleitura__materia=None) + + class VotacaoEmBlocoExpediente(PermissionRequiredForAppCrudMixin, ListView): template_name = 'sessao/votacao/votacao_bloco.html' app_label = AppConfig.label @@ -4423,7 +4514,6 @@ class VotacaoEmBlocoOrdemDia(VotacaoEmBlocoExpediente): class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateView): - """ Votação Simbólica """ @@ -4519,8 +4609,8 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie except Exception as e: username = request.user.username self.logger.error('user=' + username + '. Problemas ao salvar ' - 'RegistroVotacao da materia de id={} ' - 'e da ordem de id={}. ' + 'RegistroVotacao da materia de id={} ' + 'e da ordem de id={}. ' .format(ordem.materia.id, ordem.id) + str(e)) return self.form_invalid(form, context) else: @@ -4551,8 +4641,10 @@ class VotacaoEmBlocoSimbolicaView(PermissionRequiredForAppCrudMixin, TemplateVie votacao.save() except Exception as e: username = request.user.username - self.logger.error('user=' + username + '. Problemas ao salvar RegistroVotacao da materia de id={} ' - 'e da ordem de id={}. '.format(expediente.materia.id, expediente.id) + str(e)) + self.logger.error( + 'user=' + username + '. Problemas ao salvar RegistroVotacao da materia de id={} ' + 'e da ordem de id={}. '.format(expediente.materia.id, + expediente.id) + str(e)) return self.form_invalid(form, context) else: expediente.resultado = resultado.nome @@ -4716,7 +4808,7 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView) if form.is_valid(): if form.cleaned_data['resultado_votacao'] == None: form.add_error(None, 'Não é possível finalizar a votação sem ' - 'nenhum resultado da votação.') + 'nenhum resultado da votação.') return self.form_invalid(form, context) qtde_votos = (int(request.POST['votos_sim']) + @@ -4727,9 +4819,9 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView) # Caso todas as opções sejam 'Não votou', fecha a votação if int(request.POST['nao_votou']) == qtde_votos: self.logger.error('user=' + username + '. Não é possível finalizar a votação sem ' - 'nenhum voto.') + 'nenhum voto.') form.add_error(None, 'Não é possível finalizar a votação sem ' - 'nenhum voto.') + 'nenhum voto.') return self.form_invalid(form, context) if request.POST['origem'] == 'ordem': @@ -5155,9 +5247,9 @@ class CorrespondenciaCrud(MasterDetailCrud): initial = super().get_initial() max_numero_ordem = Correspondencia.objects.filter( sessao_plenaria=self.kwargs['pk']).aggregate( - Max('numero_ordem'))['numero_ordem__max'] + Max('numero_ordem'))['numero_ordem__max'] initial['numero_ordem'] = ( - max_numero_ordem if max_numero_ordem else 0) + 1 + max_numero_ordem if max_numero_ordem else 0) + 1 return initial @@ -5258,8 +5350,8 @@ class CorrespondenciaEmLoteView(PermissionRequiredMixin, FilterView): sessao_plenaria = SessaoPlenaria.objects.get( pk=self.kwargs['pk']) not_list = [self.kwargs['pk']] + \ - [m for m in sessao_plenaria.correspondencias.values_list( - 'id', flat=True)] + [m for m in sessao_plenaria.correspondencias.values_list( + 'id', flat=True)] context['object_list'] = context['object_list'].exclude( pk__in=not_list) diff --git a/sapl/templates/sessao/leitura/leitura_bloco.html b/sapl/templates/sessao/leitura/leitura_bloco.html new file mode 100644 index 000000000..ac6a45cb4 --- /dev/null +++ b/sapl/templates/sessao/leitura/leitura_bloco.html @@ -0,0 +1,114 @@ +{% extends "crud/detail.html" %} +{% load i18n crispy_forms_tags %} + +{% block base_content %} + + {% if sessao_iniciada %} +
+ {% csrf_token %} +

+ + + + + + + + + +

{% trans "Mensagem de Leitura" %}

+
+
+ Observações + +
+
+
+ +
+ +

{% if expediente %} Selecione o(s) expediente(s) desejado(s). {% else %} Selecione a(s) ordem(s) do dia desejada(s). {% endif %}

+ + + + + + + + +
+ +
+ + {% for o in object_list %} + + + + {% endfor %} +

{% if expediente %} {% trans "Expediente" %} {% else %} {% trans "Ordem do Dia" %} {% endif %}

+ {% include 'paginacao.html' %} + + + + + + + + {% if expediente %} + Voltar + + {% else %} + Voltar + + {% endif %} + +
+ {% endif %} + +{% endblock base_content %} + +{% block extra_js %} + +{% endblock extra_js%} diff --git a/sapl/templates/sessao/subnav.yaml b/sapl/templates/sessao/subnav.yaml index e349f4b02..c1a825b64 100644 --- a/sapl/templates/sessao/subnav.yaml +++ b/sapl/templates/sessao/subnav.yaml @@ -32,6 +32,9 @@ - title: {% trans 'Votação em Bloco' %} url: votacao_bloco_expediente check_permission: sessao.add_sessaoplenaria + - title: {% trans 'Leitura em Bloco' %} + url: leitura_bloco_expediente + check_permission: sessao.add_sessaoplenaria - title: {% trans 'Copiar Matérias para Sessão Posterior' %} url: transf_mat_exp check_permission: sessao.add_sessaoplenaria @@ -48,6 +51,9 @@ - title: {% trans 'Votação em Bloco' %} url: votacao_bloco_ordemdia check_permission: sessao.add_sessaoplenaria + - title: {% trans 'Leitura em Bloco' %} + url: leitura_bloco_ordem_dia + check_permission: sessao.add_sessaoplenaria - title: {% trans 'Copiar Matérias para Sessão Posterior' %} url: transf_mat_ordemdia check_permission: sessao.add_sessaoplenaria