feature/implementacion de hub en EFC

This commit is contained in:
2026-06-08 07:19:01 -06:00
parent a9931d2838
commit e1716d65a7
20 changed files with 3749 additions and 649 deletions

View File

@@ -13,6 +13,22 @@ from .tasks.auditoria import (
auditar_edocuments,
auditar_acuse,
auditar_remesas,
auditar_integridad_partidas,
auditar_integridad_partidas_por_pedimento,
auditar_integridad_edocuments,
auditar_integridad_edocuments_por_pedimento,
auditar_integridad_coves,
auditar_integridad_coves_por_pedimento,
auditar_integridad_remesa,
auditar_integridad_remesa_por_pedimento,
corregir_integridad_partidas,
corregir_integridad_edocuments,
corregir_integridad_coves,
corregir_integridad_remesa,
_corregir_integridad_partidas_pedimento,
_corregir_integridad_edocuments_pedimento,
_corregir_integridad_coves_pedimento,
_corregir_integridad_remesa_pedimento,
)
from .tasks.internal_services import auditar_pedimentos
from .tasks.microservice_v2 import procesar_pedimentos_completos, procesar_pedimento_completo_individual
@@ -2316,4 +2332,380 @@ def auto_corregir_pedamento_endpoint(request):
'mensaje': 'Corrección individual encolada.',
},
status=status.HTTP_202_ACCEPTED,
)
)
# ──────────────────────────────────────────────────────────────────────────────
# Endpoints de auditorías de integridad
# ──────────────────────────────────────────────────────────────────────────────
@swagger_auto_schema(
method='post',
operation_description="Audita integridad de partidas: compara numero_partidas del XML vs partidas registradas en DB (solo lectura, no crea registros)",
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, require_permission('auditoria.process')])
def auditar_integridad_partidas_endpoint(request):
return _lanzar_auditoria_organizacion(request, auditar_integridad_partidas, 'integridad de partidas')
@swagger_auto_schema(
method='post',
operation_description="Audita integridad de partidas para un pedimento específico",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING)},
required=['pedimento_id']
),
responses={
200: openapi.Response('Resultado de integridad de partidas 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, require_permission('auditoria.view')])
def auditar_integridad_partidas_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.select_related('organizacion').get(id=pedimento_id)
except Pedimento.DoesNotExist:
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
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)
resultado = auditar_integridad_partidas_por_pedimento(pedimento_id)
return Response(resultado, status=status.HTTP_200_OK)
@swagger_auto_schema(
method='post',
operation_description="Audita integridad de edocuments: compara lista del XML del pedimento completo vs EDocuments registrados en DB",
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, require_permission('auditoria.process')])
def auditar_integridad_edocuments_endpoint(request):
return _lanzar_auditoria_organizacion(request, auditar_integridad_edocuments, 'integridad de edocuments')
@swagger_auto_schema(
method='post',
operation_description="Audita integridad de edocuments para un pedimento específico",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING)},
required=['pedimento_id']
),
responses={
200: openapi.Response('Resultado de integridad 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'),
}
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.view')])
def auditar_integridad_edocuments_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.select_related('organizacion').get(id=pedimento_id)
except Pedimento.DoesNotExist:
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
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)
resultado = auditar_integridad_edocuments_por_pedimento(pedimento_id)
return Response(resultado, status=status.HTTP_200_OK)
@swagger_auto_schema(
method='post',
operation_description="Audita integridad de COVEs del PC XML contra los registrados en DB (nivel 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'), 400: 'Error en parámetros', 403: 'Sin permisos'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def auditar_integridad_coves_endpoint(request):
return _lanzar_auditoria_organizacion(request, auditar_integridad_coves, 'integridad de COVEs')
@swagger_auto_schema(
method='post',
operation_description="Audita integridad de COVEs del PC XML para un pedimento específico",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING)},
required=['pedimento_id']
),
responses={200: 'Resultado', 400: 'Error en parámetros', 403: 'Sin permisos', 404: 'No encontrado'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.view')])
def auditar_integridad_coves_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.select_related('organizacion').get(id=pedimento_id)
except Pedimento.DoesNotExist:
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
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)
resultado = auditar_integridad_coves_por_pedimento(pedimento_id)
return Response(resultado, status=status.HTTP_200_OK)
@swagger_auto_schema(
method='post',
operation_description="Audita integridad de COVEs del XML de remesa contra los registrados en DB (nivel 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'), 400: 'Error en parámetros', 403: 'Sin permisos'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def auditar_integridad_remesa_endpoint(request):
return _lanzar_auditoria_organizacion(request, auditar_integridad_remesa, 'integridad de remesas')
@swagger_auto_schema(
method='post',
operation_description="Audita integridad de COVEs del XML de remesa para un pedimento específico",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING)},
required=['pedimento_id']
),
responses={200: 'Resultado', 400: 'Error en parámetros', 403: 'Sin permisos', 404: 'No encontrado'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.view')])
def auditar_integridad_remesa_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.select_related('organizacion').get(id=pedimento_id)
except Pedimento.DoesNotExist:
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
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)
resultado = auditar_integridad_remesa_por_pedimento(pedimento_id)
return Response(resultado, status=status.HTTP_200_OK)
# ──────────────────────────────────────────────────────────────────────────────
# Endpoints de CORRECCIÓN de integridad
# ──────────────────────────────────────────────────────────────────────────────
@swagger_auto_schema(
method='post',
operation_description="Crea Partidas faltantes en toda la organización y dispara procesamiento VUCEM",
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'), 400: 'Error en parámetros', 403: 'Sin permisos'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def corregir_integridad_partidas_endpoint(request):
return _lanzar_auditoria_organizacion(request, corregir_integridad_partidas, 'corrección de partidas')
@swagger_auto_schema(
method='post',
operation_description="Crea Partidas faltantes para un pedimento específico y dispara procesamiento VUCEM",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING)},
required=['pedimento_id']
),
responses={200: 'Resultado', 400: 'Error en parámetros', 403: 'Sin permisos', 404: 'No encontrado'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def corregir_integridad_partidas_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.select_related('organizacion').get(id=pedimento_id)
except Pedimento.DoesNotExist:
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
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)
resultado = _corregir_integridad_partidas_pedimento(pedimento)
return Response(resultado, status=status.HTTP_200_OK)
@swagger_auto_schema(
method='post',
operation_description="Crea EDocuments faltantes en toda la organización desde el XML del pedimento completo y dispara procesamiento VUCEM",
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'), 400: 'Error en parámetros', 403: 'Sin permisos'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def corregir_integridad_edocuments_endpoint(request):
return _lanzar_auditoria_organizacion(request, corregir_integridad_edocuments, 'corrección de edocuments')
@swagger_auto_schema(
method='post',
operation_description="Crea EDocuments faltantes para un pedimento específico y dispara procesamiento VUCEM",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING)},
required=['pedimento_id']
),
responses={200: 'Resultado', 400: 'Error en parámetros', 403: 'Sin permisos', 404: 'No encontrado'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def corregir_integridad_edocuments_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.select_related('organizacion').get(id=pedimento_id)
except Pedimento.DoesNotExist:
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
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)
resultado = _corregir_integridad_edocuments_pedimento(pedimento)
return Response(resultado, status=status.HTTP_200_OK)
@swagger_auto_schema(
method='post',
operation_description="Crea COVEs faltantes del PC XML en toda la organización y dispara procesamiento VUCEM",
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'), 400: 'Error en parámetros', 403: 'Sin permisos'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def corregir_integridad_coves_endpoint(request):
return _lanzar_auditoria_organizacion(request, corregir_integridad_coves, 'corrección de COVEs')
@swagger_auto_schema(
method='post',
operation_description="Crea COVEs faltantes del PC XML para un pedimento específico y dispara procesamiento VUCEM",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING)},
required=['pedimento_id']
),
responses={200: 'Resultado', 400: 'Error en parámetros', 403: 'Sin permisos', 404: 'No encontrado'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def corregir_integridad_coves_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.select_related('organizacion').get(id=pedimento_id)
except Pedimento.DoesNotExist:
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
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)
resultado = _corregir_integridad_coves_pedimento(pedimento)
return Response(resultado, status=status.HTTP_200_OK)
@swagger_auto_schema(
method='post',
operation_description="Crea COVEs faltantes del XML de remesa en toda la organización y dispara procesamiento VUCEM",
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'), 400: 'Error en parámetros', 403: 'Sin permisos'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def corregir_integridad_remesa_endpoint(request):
return _lanzar_auditoria_organizacion(request, corregir_integridad_remesa, 'corrección de remesas')
@swagger_auto_schema(
method='post',
operation_description="Crea COVEs faltantes del XML de remesa para un pedimento específico y dispara procesamiento VUCEM",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING)},
required=['pedimento_id']
),
responses={200: 'Resultado', 400: 'Error en parámetros', 403: 'Sin permisos', 404: 'No encontrado'},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated, require_permission('auditoria.process')])
def corregir_integridad_remesa_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.select_related('organizacion').get(id=pedimento_id)
except Pedimento.DoesNotExist:
return Response({'error': 'Pedimento no encontrado'}, status=status.HTTP_404_NOT_FOUND)
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)
resultado = _corregir_integridad_remesa_pedimento(pedimento)
return Response(resultado, status=status.HTTP_200_OK)