fix/forzar-carga-acuses

This commit is contained in:
2026-05-25 14:52:06 -06:00
parent e378f2d949
commit 94846fec8a
6 changed files with 581 additions and 186 deletions

View File

@@ -2505,6 +2505,7 @@ class ViewSetEDocument(LoggingMixin, viewsets.ModelViewSet, OrganizacionFiltrada
'partial_update': 'edocuments.edit',
'destroy': 'edocuments.delete',
'bulk_delete_edocs_vu': 'edocuments.delete',
'reset_acuse': 'edocuments.edit',
}
codename = perms.get(self.action, 'edocuments.view')
return [IsAuthenticated(), require_permission(codename)()]
@@ -2531,6 +2532,88 @@ class ViewSetEDocument(LoggingMixin, viewsets.ModelViewSet, OrganizacionFiltrada
def perform_destroy(self, instance):
instance.delete()
@action(detail=True, methods=['post'], url_path='reset-acuse')
def reset_acuse(self, request, pk=None):
"""
Detecta inconsistencia cuando acuse_descargado=True pero no existe el documento
de acuse (tipo 4). Crea un registro de error tipo 26 para Errores VU y
restablece acuse_descargado=False para permitir reintentar.
"""
from api.record.models import Document, DocumentType
import logging
logger = logging.getLogger('api.customs.views')
edoc = self.get_object()
if not edoc.acuse_descargado:
return Response(
{"error": "El acuse no está marcado como descargado"},
status=status.HTTP_400_BAD_REQUEST
)
# Verificar si el acuse PDF (tipo 4 = Pedimento Acuse) existe realmente
acuse_disponible = Document.objects.filter(
pedimento=edoc.pedimento,
archivo__icontains=edoc.numero_edocument,
document_type_id=4
).exists()
if acuse_disponible:
return Response(
{"status": "El acuse está disponible correctamente", "acuse_disponible": True},
status=status.HTTP_200_OK
)
# Inconsistencia confirmada: crear documento de error tipo 26 para Errores VU
doc_type_error = DocumentType.objects.filter(id=26).first()
if doc_type_error:
error_content = (
f"Inconsistencia detectada: el acuse del EDocument {edoc.numero_edocument} "
f"fue marcado como descargado pero el documento no se encuentra disponible. "
f"El estado fue restablecido para permitir reprocesamiento."
).encode('utf-8')
try:
with tempfile.NamedTemporaryFile(
mode='wb', suffix='.txt', delete=False
) as f:
f.write(error_content)
tmp_path = f.name
pedimento_app = getattr(edoc.pedimento, 'pedimento_app', str(edoc.pedimento.pedimento))
file_name = f"error_acuse_{edoc.numero_edocument}.txt"
saved_path = storage_service.save_document_from_path(
file_path=tmp_path,
file_name=file_name,
organizacion_id=edoc.organizacion_id,
pedimento_app=pedimento_app
)
if saved_path:
Document.objects.create(
organizacion=edoc.organizacion,
pedimento=edoc.pedimento,
archivo=saved_path,
document_type=doc_type_error,
extension='TXT',
size=len(error_content),
fuente=None,
)
except Exception as e:
logger.error(
f"Error creando documento de error para acuse {edoc.numero_edocument}: {e}"
)
finally:
if os.path.exists(tmp_path):
os.unlink(tmp_path)
edoc.acuse_descargado = False
edoc.save()
serializer = self.get_serializer(edoc)
return Response(serializer.data, status=status.HTTP_200_OK)
class ViewSetCove(viewsets.ModelViewSet, OrganizacionFiltradaMixin):
"""
ViewSet for Cove model.