From 96ee98d414d5efc60538fd80d751889aaf250308 Mon Sep 17 00:00:00 2001 From: joaohortsenado <100957576+joaohortsenado@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:58:47 -0300 Subject: [PATCH] =?UTF-8?q?Corrige=20ordem=20dos=20expedientes=20no=20PDF?= =?UTF-8?q?=20do=20Resumo=20da=20Sess=C3=A3o=20(#3844)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O PDF do Resumo da Sessão ordenava os expedientes alfabeticamente pelo nome do tipo, ignorando o campo `ordenacao` de TipoExpediente. Numa Casa que cadastre vários tipos, isso embaralha o documento: "Grande Expediente" sai antes de "Leitura e Aprovação da Ata" e o encerramento pode ser impresso logo após a abertura. A tela do Resumo e o Extrato passam por sapl.sessao.views.get_expedientes, que já ordena por `tipo__ordenacao`; apenas o relatório em PDF, que usa get_sessao_plenaria, ficou para trás. O order_by('tipo__nome') havia sido introduzido em 25be37eb justamente para acompanhar o Resumo, mas quando 2eb0b796 (#2920) criou o campo `ordenacao` somente get_expedientes foi atualizado, e os dois caminhos divergiram em silêncio. Alinha get_sessao_plenaria à mesma ordenação e adiciona testes que travam a equivalência entre o PDF e o Resumo exibido em tela. OSTicket #125461 --- sapl/relatorios/tests.py | 53 ++++++++++++++++++++++++++++++++++++++-- sapl/relatorios/views.py | 4 ++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/sapl/relatorios/tests.py b/sapl/relatorios/tests.py index a79ca8be5..fe46e86c4 100644 --- a/sapl/relatorios/tests.py +++ b/sapl/relatorios/tests.py @@ -1,3 +1,52 @@ -# from django.test import TestCase +import pytest +from model_bakery import baker -# Create your tests here. +from sapl.base.models import CasaLegislativa +from sapl.relatorios.views import get_sessao_plenaria +from sapl.sessao.models import ExpedienteSessao, SessaoPlenaria, TipoExpediente +from sapl.sessao.views import get_expedientes + + +def cria_sessao_com_expedientes(): + """Cria uma sessão cujos expedientes têm `ordenacao` inversa à ordem + alfabética dos nomes -- o caso que expõe o OSTicket #125461.""" + sessao = baker.make(SessaoPlenaria) + tipo_leitura = baker.make( + TipoExpediente, nome='Leitura e Aprovação da Ata', ordenacao=1) + tipo_grande = baker.make( + TipoExpediente, nome='Grande Expediente', ordenacao=2) + + for tipo in (tipo_grande, tipo_leitura): + baker.make(ExpedienteSessao, sessao_plenaria=sessao, tipo=tipo, + conteudo='
Conteúdo de {}.
'.format(tipo.nome)) + + return sessao + + +@pytest.mark.django_db(transaction=False) +def test_relatorio_sessao_respeita_ordenacao_do_tipo_expediente(): + """O PDF da Sessão Plenária deve seguir o campo `ordenacao` de + TipoExpediente, e não a ordem alfabética do nome.""" + sessao = cria_sessao_com_expedientes() + casa = baker.make(CasaLegislativa) + user = baker.make('auth.User') + + lst_expedientes = get_sessao_plenaria(sessao, casa, user)[6] + nomes = [e['nom_expediente'] for e in lst_expedientes] + + assert nomes == ['Leitura e Aprovação da Ata', 'Grande Expediente'] + + +@pytest.mark.django_db(transaction=False) +def test_relatorio_sessao_tem_mesma_ordem_de_expedientes_do_resumo(): + """O PDF e o Resumo exibido em tela não podem divergir: foi essa + divergência que originou o OSTicket #125461.""" + sessao = cria_sessao_com_expedientes() + casa = baker.make(CasaLegislativa) + user = baker.make('auth.User') + + do_pdf = [e['nom_expediente'] + for e in get_sessao_plenaria(sessao, casa, user)[6]] + da_tela = [e['tipo'].nome for e in get_expedientes(sessao)['expedientes']] + + assert do_pdf == da_tela diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 60ba1635e..8b89342fd 100755 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -609,8 +609,10 @@ def get_sessao_plenaria(sessao, casa, user): # Exibe os Expedientes lst_expedientes = [] + # A ordenação deve ser a mesma de sapl.sessao.views.get_expedientes, para + # que o PDF confira com o Resumo exibido em tela. OSTicket #125461 expedientes = ExpedienteSessao.objects.filter( - sessao_plenaria=sessao).order_by('tipo__nome') + sessao_plenaria=sessao).order_by('tipo__ordenacao', 'tipo__nome') for e in expedientes: conteudo = e.conteudo if not is_empty(conteudo):