From 7fad0a46abf7a842f4429e45bc5f7430543e2ec2 Mon Sep 17 00:00:00 2001 From: rangelbruno Date: Mon, 9 Feb 2026 12:18:31 -0300 Subject: [PATCH] =?UTF-8?q?Fix(OnlyOffice):=20Corrige=20Salvar=20e=20Volta?= =?UTF-8?q?r=20em=20documentos=20j=C3=A1=20existentes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Usa Django cache para rastrear o ciclo forcesave → callback → check_doc, evitando que o polling retorne true antes do callback salvar o arquivo. Aplica a correção em Matéria, Documento Acessório e Proposição. --- sapl/materia/onlyoffice_materia_views.py | 25 ++++++++++++++++++++++++ sapl/materia/onlyoffice_views.py | 13 ++++++++++++ 2 files changed, 38 insertions(+) diff --git a/sapl/materia/onlyoffice_materia_views.py b/sapl/materia/onlyoffice_materia_views.py index ebe8e4be7..a25b677f5 100644 --- a/sapl/materia/onlyoffice_materia_views.py +++ b/sapl/materia/onlyoffice_materia_views.py @@ -8,6 +8,7 @@ import logging import time from django.conf import settings from django.contrib.auth.decorators import login_required +from django.core.cache import cache from django.http import JsonResponse, HttpResponse from django.shortcuts import get_object_or_404, render, redirect from django.urls import reverse @@ -241,6 +242,8 @@ def materia_onlyoffice_callback(request, pk): save=True ) logger.info(f"Documento salvo com sucesso: {filename}") + cache.set(f'materia_saved_{pk}', True, timeout=120) + cache.delete(f'materia_forcesave_{pk}') return JsonResponse({"error": 0}) except Exception as e: logger.error(f"Erro ao salvar arquivo: {e}") @@ -262,7 +265,16 @@ def materia_check_doc(request, pk): """ Verifica se a matéria já possui documento salvo. Usado pelo frontend para polling após forcesave do OnlyOffice. + Usa cache para rastrear o ciclo forcesave → callback → check. """ + if cache.get(f'materia_saved_{pk}'): + cache.delete(f'materia_saved_{pk}') + cache.delete(f'materia_forcesave_{pk}') + return JsonResponse({"has_document": True}) + + if cache.get(f'materia_forcesave_{pk}'): + return JsonResponse({"has_document": False}) + materia = get_object_or_404(MateriaLegislativa, pk=pk) has_document = bool(materia.texto_original) return JsonResponse({"has_document": has_document}) @@ -300,6 +312,7 @@ def materia_forcesave(request, pk): resp = http_requests.post(command_url, json=payload, timeout=10) result = resp.json() logger.info(f"Forcesave response para matéria {pk}: {result}") + cache.set(f'materia_forcesave_{pk}', True, timeout=120) return JsonResponse(result) except Exception as e: logger.error(f"Erro ao chamar forcesave para matéria {pk}: {e}") @@ -552,6 +565,8 @@ def docacessorio_onlyoffice_callback(request, pk): save=True ) logger.info(f"Documento salvo com sucesso: {filename}") + cache.set(f'docacessorio_saved_{pk}', True, timeout=120) + cache.delete(f'docacessorio_forcesave_{pk}') return JsonResponse({"error": 0}) except Exception as e: logger.error(f"Erro ao salvar arquivo: {e}") @@ -573,7 +588,16 @@ def docacessorio_check_doc(request, pk): """ Verifica se o documento acessório já possui arquivo salvo. Usado pelo frontend para polling após forcesave do OnlyOffice. + Usa cache para rastrear o ciclo forcesave → callback → check. """ + if cache.get(f'docacessorio_saved_{pk}'): + cache.delete(f'docacessorio_saved_{pk}') + cache.delete(f'docacessorio_forcesave_{pk}') + return JsonResponse({"has_document": True}) + + if cache.get(f'docacessorio_forcesave_{pk}'): + return JsonResponse({"has_document": False}) + documento = get_object_or_404(DocumentoAcessorio, pk=pk) has_document = bool(documento.arquivo) return JsonResponse({"has_document": has_document}) @@ -611,6 +635,7 @@ def docacessorio_forcesave(request, pk): resp = http_requests.post(command_url, json=payload, timeout=10) result = resp.json() logger.info(f"Forcesave response para documento acessório {pk}: {result}") + cache.set(f'docacessorio_forcesave_{pk}', True, timeout=120) return JsonResponse(result) except Exception as e: logger.error(f"Erro ao chamar forcesave para documento acessório {pk}: {e}") diff --git a/sapl/materia/onlyoffice_views.py b/sapl/materia/onlyoffice_views.py index c3c8f9e60..1697de0c1 100644 --- a/sapl/materia/onlyoffice_views.py +++ b/sapl/materia/onlyoffice_views.py @@ -8,6 +8,7 @@ import os import time from django.conf import settings from django.contrib.auth.decorators import login_required +from django.core.cache import cache from django.http import JsonResponse, HttpResponse from django.shortcuts import get_object_or_404 from django.urls import reverse @@ -266,6 +267,8 @@ def onlyoffice_callback(request, pk): proposicao.save() logger.info(f"Documento salvo com sucesso: {filename}") + cache.set(f'proposicao_saved_{pk}', True, timeout=120) + cache.delete(f'proposicao_forcesave_{pk}') return JsonResponse({"error": 0}) except Exception as e: logger.error(f"Erro ao salvar arquivo: {e}") @@ -288,7 +291,16 @@ def proposicao_check_doc(request, pk): """ Verifica se a proposição já possui documento salvo. Usado pelo frontend para polling após forcesave do OnlyOffice. + Usa cache para rastrear o ciclo forcesave → callback → check. """ + if cache.get(f'proposicao_saved_{pk}'): + cache.delete(f'proposicao_saved_{pk}') + cache.delete(f'proposicao_forcesave_{pk}') + return JsonResponse({"has_document": True}) + + if cache.get(f'proposicao_forcesave_{pk}'): + return JsonResponse({"has_document": False}) + proposicao = get_object_or_404(Proposicao, pk=pk) has_document = bool(proposicao.texto_original) return JsonResponse({"has_document": has_document}) @@ -329,6 +341,7 @@ def proposicao_forcesave(request, pk): resp = http_requests.post(command_url, json=payload, timeout=10) result = resp.json() logger.info(f"Forcesave response para proposição {pk}: {result}") + cache.set(f'proposicao_forcesave_{pk}', True, timeout=120) return JsonResponse(result) except Exception as e: logger.error(f"Erro ao chamar forcesave para proposição {pk}: {e}")