T2026-05-030
This commit is contained in:
@@ -8,27 +8,24 @@ from drf_yasg import openapi
|
||||
from core.permissions import IsSuperUser, IsSameOrganizationDeveloper
|
||||
from .tasks.auditoria import (
|
||||
crear_partidas,
|
||||
crear_partidas_por_pedimento,
|
||||
auditar_procesamiento_remesa_por_pedimento,
|
||||
auditar_coves,
|
||||
auditar_acuse_cove,
|
||||
auditar_edocuments,
|
||||
auditar_acuse,
|
||||
auditar_cove_por_pedimento,
|
||||
auditar_acuse_cove_por_pedimento,
|
||||
auditar_edocument_por_pedimento,
|
||||
auditar_acuse_por_pedimento
|
||||
auditar_remesas,
|
||||
)
|
||||
from .tasks.internal_services import auditar_pedimentos
|
||||
from .tasks.microservice_v2 import procesar_pedimentos_completos
|
||||
from api.customs.models import Pedimento
|
||||
from api.organization.models import Organizacion
|
||||
from api.record.models import Document
|
||||
from .tasks.auditoria import auditar_pedimento_por_id
|
||||
from .tasks.auditoria_xml import extraer_info_pedimento_xml
|
||||
import tempfile
|
||||
import os
|
||||
from api.utils.storage_service import storage_service
|
||||
import logging
|
||||
import uuid
|
||||
logger = logging.getLogger('api.customs.views_auditor')
|
||||
|
||||
def get_document_content(documento):
|
||||
"""
|
||||
@@ -72,7 +69,7 @@ def get_document_path(documento):
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Crea partidas para todos los pedimentos de una organización",
|
||||
operation_description="Crea partidas faltantes para todos los pedimentos de una organización e informa cuáles están descargadas",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
@@ -81,7 +78,7 @@ def get_document_path(documento):
|
||||
required=['organizacion_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea iniciada correctamente'),
|
||||
202: openapi.Response('Tarea iniciada — usar task_id para consultar resultado'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes')
|
||||
}
|
||||
@@ -89,37 +86,27 @@ def get_document_path(documento):
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated & (IsSuperUser | IsSameOrganizationDeveloper)])
|
||||
def crear_partidas_organizacion(request):
|
||||
"""
|
||||
Crea partidas para todos los pedimentos de una organización específica.
|
||||
"""
|
||||
organizacion_id = request.data.get('organizacion_id')
|
||||
|
||||
if not organizacion_id:
|
||||
return Response(
|
||||
{'error': 'Debe proporcionar organizacion_id'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
return Response({'error': 'Debe proporcionar organizacion_id'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Validar permisos
|
||||
user = request.user
|
||||
if not user.is_superuser and str(user.organizacion.id) != organizacion_id:
|
||||
return Response(
|
||||
{'error': 'No tiene permisos para esta organización'},
|
||||
status=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
return Response({'error': 'No tiene permisos para esta organización'}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# Ejecutar la tarea
|
||||
task = crear_partidas.delay(organizacion_id)
|
||||
message = f"Creación de partidas iniciada para la organización {organizacion_id}"
|
||||
|
||||
return Response({
|
||||
'message': message,
|
||||
'task_id': task.id
|
||||
}, status=status.HTTP_200_OK)
|
||||
'organizacion_id': organizacion_id,
|
||||
'auditoria': 'partidas',
|
||||
'task_id': task.id,
|
||||
'mensaje': f'Creación de partidas iniciada. Consulta el resultado en GET /api/tasks/status/{task.id}/',
|
||||
}, status=status.HTTP_202_ACCEPTED)
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Crea partidas para un pedimento específico",
|
||||
operation_description="Crea partidas faltantes para un pedimento e informa cuáles están descargadas",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
@@ -128,48 +115,74 @@ def crear_partidas_organizacion(request):
|
||||
required=['pedimento_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea iniciada correctamente'),
|
||||
200: openapi.Response('Resultado de creación y estado de descarga de partidas'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
404: openapi.Response('Pedimento no encontrado')
|
||||
}
|
||||
)
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated ])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def crear_partidas_pedimento(request):
|
||||
"""
|
||||
Crea partidas para un pedimento específico.
|
||||
"""
|
||||
pedimento_id = request.data.get('pedimento_id')
|
||||
|
||||
if not pedimento_id:
|
||||
return Response(
|
||||
{'error': 'Debe proporcionar pedimento_id'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
return Response({'error': 'Debe proporcionar pedimento_id'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Validar permisos y existencia del pedimento
|
||||
try:
|
||||
pedimento = Pedimento.objects.get(id=pedimento_id)
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response(
|
||||
{'error': 'No tiene permisos para este pedimento'},
|
||||
status=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
pedimento = Pedimento.objects.prefetch_related('partidas').select_related('organizacion').get(id=pedimento_id)
|
||||
except Pedimento.DoesNotExist:
|
||||
return Response(
|
||||
{'error': 'Pedimento no encontrado'},
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# Ejecutar la tarea
|
||||
task = crear_partidas_por_pedimento.delay(pedimento_id)
|
||||
message = f"Creación de partidas iniciada para el pedimento {pedimento_id}"
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
if not pedimento.numero_partidas or pedimento.numero_partidas <= 0:
|
||||
return Response({
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'pedimento': pedimento.pedimento,
|
||||
'estado': 'sin_datos',
|
||||
'mensaje': f'El pedimento no tiene número de partidas definido (numero_partidas={pedimento.numero_partidas})',
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
# Crear partidas faltantes (get_or_create por número)
|
||||
from api.customs.models import Partida
|
||||
partidas_creadas = 0
|
||||
for i in range(1, pedimento.numero_partidas + 1):
|
||||
_, created = Partida.objects.get_or_create(
|
||||
pedimento=pedimento,
|
||||
numero_partida=i,
|
||||
defaults={'organizacion_id': pedimento.organizacion_id}
|
||||
)
|
||||
if created:
|
||||
partidas_creadas += 1
|
||||
|
||||
# Evaluar estado de descarga sobre el conjunto completo
|
||||
partidas = list(pedimento.partidas.order_by('numero_partida'))
|
||||
total = len(partidas)
|
||||
descargadas = [p.numero_partida for p in partidas if p.descargado]
|
||||
no_descargadas = [p.numero_partida for p in partidas if not p.descargado]
|
||||
|
||||
if not no_descargadas:
|
||||
estado = 'completado'
|
||||
mensaje = f'Todas las partidas están descargadas ({total}/{total})'
|
||||
else:
|
||||
estado = 'en_proceso'
|
||||
mensaje = f'{len(no_descargadas)} de {total} partidas pendientes de descarga'
|
||||
|
||||
return Response({
|
||||
'message': message,
|
||||
'task_id': task.id
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'pedimento': pedimento.pedimento,
|
||||
'estado': estado,
|
||||
'mensaje': mensaje,
|
||||
'resumen': {
|
||||
'total_partidas': total,
|
||||
'partidas_creadas_ahora': partidas_creadas,
|
||||
'descargadas': len(descargadas),
|
||||
'no_descargadas': len(no_descargadas),
|
||||
},
|
||||
'no_descargadas': no_descargadas,
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
@swagger_auto_schema(
|
||||
@@ -223,7 +236,7 @@ def auditar_pedimentos_endpoint(request):
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita el procesamiento de remesa para un pedimento específico",
|
||||
operation_description="Audita el estado de procesamiento de remesa de un pedimento específico",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
@@ -232,7 +245,7 @@ def auditar_pedimentos_endpoint(request):
|
||||
required=['pedimento_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
200: openapi.Response('Estado de procesamiento de remesa del pedimento'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
404: openapi.Response('Pedimento no encontrado')
|
||||
@@ -241,247 +254,179 @@ def auditar_pedimentos_endpoint(request):
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated & (IsSuperUser | IsSameOrganizationDeveloper)])
|
||||
def auditar_procesamiento_remesa_pedimento_endpoint(request):
|
||||
"""
|
||||
Inicia una tarea de auditoría de remesa para un pedimento específico.
|
||||
Verifica el estado del procesamiento de remesa y la creación de COVEs.
|
||||
"""
|
||||
pedimento_id = request.data.get('pedimento_id')
|
||||
|
||||
if not pedimento_id:
|
||||
return Response(
|
||||
{'error': 'Debe proporcionar pedimento_id'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
return Response({'error': 'Debe proporcionar pedimento_id'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Validar permisos y existencia del pedimento
|
||||
try:
|
||||
pedimento = Pedimento.objects.get(id=pedimento_id)
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response(
|
||||
{'error': 'No tiene permisos para este pedimento'},
|
||||
status=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
pedimento = Pedimento.objects.select_related('organizacion').prefetch_related('coves').get(id=pedimento_id)
|
||||
except Pedimento.DoesNotExist:
|
||||
return Response(
|
||||
{'error': 'Pedimento no encontrado'},
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# Ejecutar la tarea de auditoría
|
||||
task = auditar_procesamiento_remesa_por_pedimento.delay(pedimento_id)
|
||||
message = f"Auditoría de remesa iniciada para el pedimento {pedimento_id}"
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
if not pedimento.remesas:
|
||||
return Response({
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'pedimento': pedimento.pedimento,
|
||||
'tiene_remesas': False,
|
||||
'estado': 'completado',
|
||||
'mensaje': 'El pedimento no tiene remesas para procesar',
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
tiene_documento_remesa = pedimento.documents.filter(document_type=3).exists()
|
||||
coves = list(pedimento.coves.all())
|
||||
total_coves = len(coves)
|
||||
|
||||
if not tiene_documento_remesa:
|
||||
estado = 'en_proceso'
|
||||
mensaje = 'Documento XML de remesa aún no descargado'
|
||||
elif total_coves == 0:
|
||||
estado = 'en_proceso'
|
||||
mensaje = 'Documento de remesa disponible pero no se han creado COVEs'
|
||||
else:
|
||||
estado = 'completado'
|
||||
mensaje = f'Remesa procesada — {total_coves} COVE(s) registrados'
|
||||
|
||||
return Response({
|
||||
'message': message,
|
||||
'task_id': task.id,
|
||||
'pedimento': {
|
||||
'id': str(pedimento.id),
|
||||
'pedimento': pedimento.pedimento,
|
||||
'tiene_remesas': pedimento.remesas
|
||||
}
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'pedimento': pedimento.pedimento,
|
||||
'tiene_remesas': True,
|
||||
'estado': estado,
|
||||
'mensaje': mensaje,
|
||||
'resumen': {
|
||||
'tiene_documento_remesa': tiene_documento_remesa,
|
||||
'total_coves_registrados': total_coves,
|
||||
},
|
||||
'coves': [c.numero_cove for c in coves],
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
def _lanzar_auditoria_organizacion(request, task_fn, label):
|
||||
"""Helper compartido para los 4 endpoints de auditoría masiva por organización."""
|
||||
organizacion_id = request.data.get('organizacion_id')
|
||||
if not organizacion_id:
|
||||
return Response({'error': 'Debe proporcionar organizacion_id'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
user = request.user
|
||||
if not user.is_superuser and str(user.organizacion.id) != organizacion_id:
|
||||
return Response({'error': 'No tiene permisos para esta organización'}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
task = task_fn.delay(organizacion_id)
|
||||
return Response({
|
||||
'organizacion_id': organizacion_id,
|
||||
'auditoria': label,
|
||||
'task_id': task.id,
|
||||
'mensaje': f'Auditoría de {label} iniciada. Consulta el resultado en GET /api/tasks/status/{task.id}/',
|
||||
}, status=status.HTTP_202_ACCEPTED)
|
||||
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita los COVEs de una organización",
|
||||
operation_description="Audita el estado de descarga de COVEs de todos los pedimentos de una organización",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID de la organización')
|
||||
},
|
||||
properties={'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING)},
|
||||
required=['organizacion_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
202: openapi.Response('Tarea iniciada — usar task_id para consultar resultado'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes')
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
}
|
||||
)
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated & (IsSuperUser | IsSameOrganizationDeveloper)])
|
||||
def auditar_coves_endpoint(request):
|
||||
"""
|
||||
Inicia una tarea de auditoría para los COVEs de una organización.
|
||||
Verifica la existencia y validez de los COVEs generados.
|
||||
"""
|
||||
organizacion_id = request.data.get('organizacion_id')
|
||||
|
||||
if not organizacion_id:
|
||||
return Response(
|
||||
{'error': 'Debe proporcionar organizacion_id'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# Validar permisos
|
||||
user = request.user
|
||||
if not user.is_superuser and str(user.organizacion.id) != organizacion_id:
|
||||
return Response(
|
||||
{'error': 'No tiene permisos para esta organización'},
|
||||
status=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
|
||||
# Ejecutar la tarea de auditoría
|
||||
task = auditar_coves.delay(organizacion_id)
|
||||
message = f"Auditoría de COVEs iniciada para la organización {organizacion_id}"
|
||||
|
||||
return Response({
|
||||
'message': message,
|
||||
'task_id': task.id
|
||||
}, status=status.HTTP_200_OK)
|
||||
return _lanzar_auditoria_organizacion(request, auditar_coves, 'COVEs')
|
||||
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita los acuses de COVE de una organización",
|
||||
operation_description="Audita el estado de descarga de acuses de COVE de todos los pedimentos de una organización",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID de la organización')
|
||||
},
|
||||
properties={'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING)},
|
||||
required=['organizacion_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
202: openapi.Response('Tarea iniciada — usar task_id para consultar resultado'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes')
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
}
|
||||
)
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated & (IsSuperUser | IsSameOrganizationDeveloper)])
|
||||
def auditar_acuse_cove_endpoint(request):
|
||||
"""
|
||||
Inicia una tarea de auditoría para los acuses de COVE de una organización.
|
||||
Verifica la recepción y validez de los acuses de COVE.
|
||||
"""
|
||||
organizacion_id = request.data.get('organizacion_id')
|
||||
|
||||
if not organizacion_id:
|
||||
return Response(
|
||||
{'error': 'Debe proporcionar organizacion_id'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# Validar permisos
|
||||
user = request.user
|
||||
if not user.is_superuser and str(user.organizacion.id) != organizacion_id:
|
||||
return Response(
|
||||
{'error': 'No tiene permisos para esta organización'},
|
||||
status=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
|
||||
# Ejecutar la tarea de auditoría
|
||||
task = auditar_acuse_cove.delay(organizacion_id)
|
||||
message = f"Auditoría de acuses de COVE iniciada para la organización {organizacion_id}"
|
||||
|
||||
return Response({
|
||||
'message': message,
|
||||
'task_id': task.id
|
||||
}, status=status.HTTP_200_OK)
|
||||
return _lanzar_auditoria_organizacion(request, auditar_acuse_cove, 'acuses de COVE')
|
||||
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita los EDocuments de una organización",
|
||||
operation_description="Audita el estado de descarga de EDocuments de todos los pedimentos de una organización",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID de la organización')
|
||||
},
|
||||
properties={'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING)},
|
||||
required=['organizacion_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
202: openapi.Response('Tarea iniciada — usar task_id para consultar resultado'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes')
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
}
|
||||
)
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated & (IsSuperUser | IsSameOrganizationDeveloper)])
|
||||
def auditar_edocuments_endpoint(request):
|
||||
"""
|
||||
Inicia una tarea de auditoría para los EDocuments de una organización.
|
||||
Verifica la existencia y validez de los EDocuments generados.
|
||||
"""
|
||||
organizacion_id = request.data.get('organizacion_id')
|
||||
|
||||
if not organizacion_id:
|
||||
return Response(
|
||||
{'error': 'Debe proporcionar organizacion_id'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# Validar permisos
|
||||
user = request.user
|
||||
if not user.is_superuser and str(user.organizacion.id) != organizacion_id:
|
||||
return Response(
|
||||
{'error': 'No tiene permisos para esta organización'},
|
||||
status=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
|
||||
# Ejecutar la tarea de auditoría
|
||||
task = auditar_edocuments.delay(organizacion_id)
|
||||
message = f"Auditoría de EDocuments iniciada para la organización {organizacion_id}"
|
||||
|
||||
return Response({
|
||||
'message': message,
|
||||
'task_id': task.id
|
||||
}, status=status.HTTP_200_OK)
|
||||
return _lanzar_auditoria_organizacion(request, auditar_edocuments, 'EDocuments')
|
||||
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita los acuses de una organización",
|
||||
operation_description="Audita el estado de descarga de acuses de EDocument de todos los pedimentos de una organización",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID de la organización')
|
||||
},
|
||||
properties={'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING)},
|
||||
required=['organizacion_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
202: openapi.Response('Tarea iniciada — usar task_id para consultar resultado'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes')
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
}
|
||||
)
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated & (IsSuperUser | IsSameOrganizationDeveloper)])
|
||||
def auditar_acuse_endpoint(request):
|
||||
"""
|
||||
Inicia una tarea de auditoría para los acuses de una organización.
|
||||
Verifica la recepción y validez de los acuses.
|
||||
"""
|
||||
organizacion_id = request.data.get('organizacion_id')
|
||||
|
||||
if not organizacion_id:
|
||||
return Response(
|
||||
{'error': 'Debe proporcionar organizacion_id'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# Validar permisos
|
||||
user = request.user
|
||||
if not user.is_superuser and str(user.organizacion.id) != organizacion_id:
|
||||
return Response(
|
||||
{'error': 'No tiene permisos para esta organización'},
|
||||
status=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
|
||||
# Ejecutar la tarea de auditoría
|
||||
task = auditar_acuse.delay(organizacion_id)
|
||||
message = f"Auditoría de acuses iniciada para la organización {organizacion_id}"
|
||||
|
||||
return Response({
|
||||
'message': message,
|
||||
'task_id': task.id
|
||||
}, status=status.HTTP_200_OK)
|
||||
return _lanzar_auditoria_organizacion(request, auditar_acuse, 'acuses de EDocument')
|
||||
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita el COVE de un pedimento específico",
|
||||
operation_description="Audita el estado de descarga de remesas de todos los pedimentos de una organización",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={'organizacion_id': openapi.Schema(type=openapi.TYPE_STRING)},
|
||||
required=['organizacion_id']
|
||||
),
|
||||
responses={
|
||||
202: openapi.Response('Tarea iniciada — usar task_id para consultar resultado'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
}
|
||||
)
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated & (IsSuperUser | IsSameOrganizationDeveloper)])
|
||||
def auditar_remesas_endpoint(request):
|
||||
return _lanzar_auditoria_organizacion(request, auditar_remesas, 'remesas')
|
||||
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita el estado de descarga de COVEs de un pedimento específico",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
@@ -490,7 +435,7 @@ def auditar_acuse_endpoint(request):
|
||||
required=['pedimento_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
200: openapi.Response('Estado de descarga de COVEs del pedimento'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
404: openapi.Response('Pedimento no encontrado')
|
||||
@@ -502,19 +447,48 @@ def auditar_cove_pedimento_endpoint(request):
|
||||
pedimento_id = request.data.get('pedimento_id')
|
||||
if not pedimento_id:
|
||||
return Response({'error': 'Debe proporcionar pedimento_id'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
try:
|
||||
pedimento = Pedimento.objects.get(id=pedimento_id)
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
pedimento = Pedimento.objects.select_related('organizacion').prefetch_related('coves').get(id=pedimento_id)
|
||||
except Pedimento.DoesNotExist:
|
||||
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
|
||||
task = auditar_cove_por_pedimento.delay(pedimento_id)
|
||||
return Response({'message': f'Auditoría de COVE iniciada para el pedimento {pedimento_id}', 'task_id': task.id}, status=status.HTTP_200_OK)
|
||||
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
coves = list(pedimento.coves.all())
|
||||
total = len(coves)
|
||||
descargados = sum(1 for c in coves if c.cove_descargado)
|
||||
pendientes = [c.numero_cove for c in coves if not c.cove_descargado]
|
||||
|
||||
if total == 0:
|
||||
nuevo_estado = 3
|
||||
mensaje = 'El pedimento no tiene COVEs registrados'
|
||||
elif descargados == total:
|
||||
nuevo_estado = 3
|
||||
mensaje = 'Todos los COVEs están descargados'
|
||||
else:
|
||||
nuevo_estado = 4
|
||||
mensaje = f'{total - descargados} de {total} COVEs pendientes de descarga'
|
||||
|
||||
from api.customs.tasks.auditoria import modificar_estado_procesamiento
|
||||
modificar_estado_procesamiento(pedimento, servicio_id=8, nuevo_estado=nuevo_estado)
|
||||
|
||||
return Response({
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'estado': 'completado' if nuevo_estado == 3 else 'en_proceso',
|
||||
'mensaje': mensaje,
|
||||
'resumen': {
|
||||
'total_coves': total,
|
||||
'coves_descargados': descargados,
|
||||
},
|
||||
'pendientes': pendientes,
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita el acuse de COVE de un pedimento específico",
|
||||
operation_description="Audita el estado de descarga de acuses de COVE de un pedimento específico",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
@@ -523,7 +497,7 @@ def auditar_cove_pedimento_endpoint(request):
|
||||
required=['pedimento_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
200: openapi.Response('Estado de descarga de acuses de COVE del pedimento'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
404: openapi.Response('Pedimento no encontrado')
|
||||
@@ -535,19 +509,48 @@ def auditar_acuse_cove_pedimento_endpoint(request):
|
||||
pedimento_id = request.data.get('pedimento_id')
|
||||
if not pedimento_id:
|
||||
return Response({'error': 'Debe proporcionar pedimento_id'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
try:
|
||||
pedimento = Pedimento.objects.get(id=pedimento_id)
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
pedimento = Pedimento.objects.select_related('organizacion').prefetch_related('coves').get(id=pedimento_id)
|
||||
except Pedimento.DoesNotExist:
|
||||
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
|
||||
task = auditar_acuse_cove_por_pedimento.delay(pedimento_id)
|
||||
return Response({'message': f'Auditoría de acuse de COVE iniciada para el pedimento {pedimento_id}', 'task_id': task.id}, status=status.HTTP_200_OK)
|
||||
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
coves = list(pedimento.coves.all())
|
||||
total = len(coves)
|
||||
descargados = sum(1 for c in coves if c.acuse_cove_descargado)
|
||||
pendientes = [c.numero_cove for c in coves if not c.acuse_cove_descargado]
|
||||
|
||||
if total == 0:
|
||||
nuevo_estado = 3
|
||||
mensaje = 'El pedimento no tiene COVEs registrados, no hay acuses que auditar'
|
||||
elif descargados == total:
|
||||
nuevo_estado = 3
|
||||
mensaje = 'Todos los acuses de COVE están descargados'
|
||||
else:
|
||||
nuevo_estado = 4
|
||||
mensaje = f'{total - descargados} de {total} acuses de COVE pendientes de descarga'
|
||||
|
||||
from api.customs.tasks.auditoria import modificar_estado_procesamiento
|
||||
modificar_estado_procesamiento(pedimento, servicio_id=9, nuevo_estado=nuevo_estado)
|
||||
|
||||
return Response({
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'estado': 'completado' if nuevo_estado == 3 else 'en_proceso',
|
||||
'mensaje': mensaje,
|
||||
'resumen': {
|
||||
'total_coves': total,
|
||||
'acuses_descargados': descargados,
|
||||
},
|
||||
'pendientes': pendientes,
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita el EDocument de un pedimento específico",
|
||||
operation_description="Audita el estado de descarga de EDocuments de un pedimento específico",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
@@ -556,7 +559,7 @@ def auditar_acuse_cove_pedimento_endpoint(request):
|
||||
required=['pedimento_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
200: openapi.Response('Estado de descarga de EDocuments del pedimento'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
404: openapi.Response('Pedimento no encontrado')
|
||||
@@ -568,19 +571,48 @@ def auditar_edocument_pedimento_endpoint(request):
|
||||
pedimento_id = request.data.get('pedimento_id')
|
||||
if not pedimento_id:
|
||||
return Response({'error': 'Debe proporcionar pedimento_id'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
try:
|
||||
pedimento = Pedimento.objects.get(id=pedimento_id)
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
pedimento = Pedimento.objects.select_related('organizacion').prefetch_related('documentos').get(id=pedimento_id)
|
||||
except Pedimento.DoesNotExist:
|
||||
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
|
||||
task = auditar_edocument_por_pedimento.delay(pedimento_id)
|
||||
return Response({'message': f'Auditoría de EDocument iniciada para el pedimento {pedimento_id}', 'task_id': task.id}, status=status.HTTP_200_OK)
|
||||
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
edocuments = list(pedimento.documentos.all())
|
||||
total = len(edocuments)
|
||||
descargados = sum(1 for d in edocuments if d.edocument_descargado)
|
||||
pendientes = [d.numero_edocument for d in edocuments if not d.edocument_descargado]
|
||||
|
||||
if total == 0:
|
||||
nuevo_estado = 3
|
||||
mensaje = 'El pedimento no tiene EDocuments registrados'
|
||||
elif descargados == total:
|
||||
nuevo_estado = 3
|
||||
mensaje = 'Todos los EDocuments están descargados'
|
||||
else:
|
||||
nuevo_estado = 4
|
||||
mensaje = f'{total - descargados} de {total} EDocuments pendientes de descarga'
|
||||
|
||||
from api.customs.tasks.auditoria import modificar_estado_procesamiento
|
||||
modificar_estado_procesamiento(pedimento, servicio_id=7, nuevo_estado=nuevo_estado)
|
||||
|
||||
return Response({
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'estado': 'completado' if nuevo_estado == 3 else 'en_proceso',
|
||||
'mensaje': mensaje,
|
||||
'resumen': {
|
||||
'total_edocuments': total,
|
||||
'edocuments_descargados': descargados,
|
||||
},
|
||||
'pendientes': pendientes,
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
@swagger_auto_schema(
|
||||
method='post',
|
||||
operation_description="Audita el acuse de un pedimento específico",
|
||||
operation_description="Audita el estado de descarga de acuses de EDocument de un pedimento específico",
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
@@ -589,28 +621,56 @@ def auditar_edocument_pedimento_endpoint(request):
|
||||
required=['pedimento_id']
|
||||
),
|
||||
responses={
|
||||
200: openapi.Response('Tarea de auditoría iniciada correctamente'),
|
||||
200: openapi.Response('Estado de descarga de acuses de EDocument del pedimento'),
|
||||
400: openapi.Response('Error en los parámetros'),
|
||||
403: openapi.Response('No tiene permisos suficientes'),
|
||||
404: openapi.Response('Pedimento no encontrado')
|
||||
}
|
||||
)
|
||||
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def auditar_acuse_pedimento_endpoint(request):
|
||||
pedimento_id = request.data.get('pedimento_id')
|
||||
if not pedimento_id:
|
||||
return Response({'error': 'Debe proporcionar pedimento_id'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
try:
|
||||
pedimento = Pedimento.objects.get(id=pedimento_id)
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
pedimento = Pedimento.objects.select_related('organizacion').prefetch_related('documentos').get(id=pedimento_id)
|
||||
except Pedimento.DoesNotExist:
|
||||
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
|
||||
task = auditar_acuse_por_pedimento.delay(pedimento_id)
|
||||
return Response({'message': f'Auditoría de acuse iniciada para el pedimento {pedimento_id}', 'task_id': task.id}, status=status.HTTP_200_OK)
|
||||
|
||||
user = request.user
|
||||
if not user.is_superuser and str(pedimento.organizacion.id) != str(user.organizacion.id):
|
||||
return Response({'error': 'No tiene permisos para este pedimento'}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
edocuments = list(pedimento.documentos.all())
|
||||
total = len(edocuments)
|
||||
descargados = sum(1 for d in edocuments if d.acuse_descargado)
|
||||
pendientes = [d.numero_edocument for d in edocuments if not d.acuse_descargado]
|
||||
|
||||
if total == 0:
|
||||
nuevo_estado = 3
|
||||
mensaje = 'El pedimento no tiene EDocuments registrados, no hay acuses que auditar'
|
||||
elif descargados == total:
|
||||
nuevo_estado = 3
|
||||
mensaje = 'Todos los acuses de EDocument están descargados'
|
||||
else:
|
||||
nuevo_estado = 4
|
||||
mensaje = f'{total - descargados} de {total} acuses de EDocument pendientes de descarga'
|
||||
|
||||
from api.customs.tasks.auditoria import modificar_estado_procesamiento
|
||||
modificar_estado_procesamiento(pedimento, servicio_id=6, nuevo_estado=nuevo_estado)
|
||||
|
||||
return Response({
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'estado': 'completado' if nuevo_estado == 3 else 'en_proceso',
|
||||
'mensaje': mensaje,
|
||||
'resumen': {
|
||||
'total_edocuments': total,
|
||||
'acuses_descargados': descargados,
|
||||
},
|
||||
'pendientes': pendientes,
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
### Procesamiento de pedimentos ###
|
||||
@swagger_auto_schema(
|
||||
@@ -1663,6 +1723,10 @@ def auditar_pedimento_endpoint(request):
|
||||
informacion_extraida = []
|
||||
|
||||
for documento in documentos_xml:
|
||||
|
||||
print(f"documento >>>> {documento}")
|
||||
logger.info(f"documento >>>> {documento}")
|
||||
|
||||
try:
|
||||
xml_info = {
|
||||
'documento_id': str(documento.id),
|
||||
@@ -1695,9 +1759,6 @@ def auditar_pedimento_endpoint(request):
|
||||
'error': f'Error procesando archivo: {str(e)}'
|
||||
})
|
||||
|
||||
# Ejecutar la tarea de auditoría completa
|
||||
task = auditar_pedimento_por_id.delay(pedimento_id)
|
||||
|
||||
response_data = {
|
||||
'pedimento_id': str(pedimento_id),
|
||||
'pedimento': pedimento.pedimento,
|
||||
@@ -1706,7 +1767,6 @@ def auditar_pedimento_endpoint(request):
|
||||
'xmls_analizados': xmls_analizados,
|
||||
'informacion_extraida': informacion_extraida,
|
||||
'auditoria_completa': True,
|
||||
'task_id': task.id,
|
||||
'mensaje': f'Auditoría completada para el pedimento {pedimento.pedimento}'
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user