Browse Source

Feat(Matéria): Adiciona cabeçalho com identificação no documento

Adiciona automaticamente o cabeçalho com tipo, número e ano
no início do documento da matéria legislativa após o recebimento
da proposição. Ex: "INDICAÇÃO 10 / 2026"
pull/3858/head
rangelbruno 7 months ago
parent
commit
48ce9c0eab
  1. 6
      sapl/materia/forms.py
  2. 85
      sapl/utils_template.py

6
sapl/materia/forms.py

@ -43,6 +43,7 @@ from sapl.utils import (autor_label, autor_modal, timing,
SEPARADOR_HASH_PROPOSICAO, SEPARADOR_HASH_PROPOSICAO,
validar_arquivo, YES_NO_CHOICES, validar_arquivo, YES_NO_CHOICES,
GoogleRecapthaMixin, get_client_ip) GoogleRecapthaMixin, get_client_ip)
from sapl.utils_template import adicionar_cabecalho_materia
from .models import (AcompanhamentoMateria, Anexada, Autoria, from .models import (AcompanhamentoMateria, Anexada, Autoria,
DespachoInicial, DocumentoAcessorio, Numeracao, DespachoInicial, DocumentoAcessorio, Numeracao,
@ -2650,6 +2651,11 @@ class ConfirmarProposicaoForm(ProposicaoForm):
materia.save() materia.save()
conteudo_gerado = materia conteudo_gerado = materia
# Adiciona cabeçalho com identificação da matéria no documento
# Ex: "INDICAÇÃO 10 / 2026"
if proposicao.texto_original:
adicionar_cabecalho_materia(materia)
if proposicao.texto_articulado.exists(): if proposicao.texto_articulado.exists():
ta = proposicao.texto_articulado.first() ta = proposicao.texto_articulado.first()
ta_materia = ta.clone_for(materia) ta_materia = ta.clone_for(materia)

85
sapl/utils_template.py

@ -3,8 +3,11 @@ Utilitários para aplicar templates de documentos aos novos documentos
criados via OnlyOffice. criados via OnlyOffice.
""" """
import logging import logging
import os
from io import BytesIO from io import BytesIO
from django.core.files.base import ContentFile
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -223,3 +226,85 @@ def aplicar_template_existente(documento_path, tipo_conteudo, tipo_especifico=No
except Exception as e: except Exception as e:
logger.error(f"Erro ao aplicar template a documento existente: {e}") logger.error(f"Erro ao aplicar template a documento existente: {e}")
return None return None
def adicionar_cabecalho_materia(materia):
"""
Adiciona cabeçalho com identificação da matéria no início do documento.
Adiciona um parágrafo no início do documento com o formato:
"TIPO NÚMERO / ANO" (ex: "INDICAÇÃO 10 / 2026")
Args:
materia: objeto MateriaLegislativa com texto_original preenchido
Returns:
True se o cabeçalho foi adicionado com sucesso, False caso contrário
"""
if not materia.texto_original:
logger.warning(f"Matéria {materia.pk} não possui texto_original")
return False
# Verifica se é um arquivo .docx
arquivo_path = materia.texto_original.path
extensao = os.path.splitext(arquivo_path)[1].lower()
if extensao not in ['.docx', '.doc']:
logger.info(f"Arquivo {arquivo_path} não é .docx, pulando adição de cabeçalho")
return False
try:
from docx import Document
from docx.shared import Pt, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
# Carrega o documento
doc = Document(arquivo_path)
# Monta o texto do cabeçalho: "TIPO NÚMERO / ANO"
tipo_nome = str(materia.tipo).upper()
cabecalho_texto = f"{tipo_nome} {materia.numero} / {materia.ano}"
# Insere o cabeçalho no início do documento
# Precisamos inserir antes do primeiro parágrafo
if doc.paragraphs:
primeiro_paragrafo = doc.paragraphs[0]
# Cria novo parágrafo antes do primeiro
novo_paragrafo = primeiro_paragrafo.insert_paragraph_before(cabecalho_texto)
# Formata o cabeçalho
novo_paragrafo.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in novo_paragrafo.runs:
run.bold = True
run.font.size = Pt(14)
# Adiciona linha em branco após o cabeçalho
primeiro_paragrafo.insert_paragraph_before('')
else:
# Documento vazio, adiciona o cabeçalho como primeiro parágrafo
paragrafo = doc.add_paragraph(cabecalho_texto)
paragrafo.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in paragrafo.runs:
run.bold = True
run.font.size = Pt(14)
doc.add_paragraph('')
# Salva o documento modificado
file_stream = BytesIO()
doc.save(file_stream)
file_stream.seek(0)
# Atualiza o arquivo da matéria
nome_arquivo = os.path.basename(arquivo_path)
materia.texto_original.save(nome_arquivo, ContentFile(file_stream.read()), save=True)
logger.info(f"Cabeçalho adicionado à matéria {materia.pk}: {cabecalho_texto}")
return True
except ImportError:
logger.error("python-docx não está instalado")
return False
except Exception as e:
logger.error(f"Erro ao adicionar cabeçalho à matéria {materia.pk}: {e}")
return False

Loading…
Cancel
Save