from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework import status from drf_yasg.utils import swagger_auto_schema 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 ) 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 @swagger_auto_schema( method='post', operation_description="Crea partidas para 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') }, required=['organizacion_id'] ), responses={ 200: openapi.Response('Tarea iniciada correctamente'), 400: openapi.Response('Error en los parámetros'), 403: openapi.Response('No tiene permisos suficientes') } ) @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 ) # 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 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) @swagger_auto_schema( method='post', operation_description="Crea partidas para un pedimento específico", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID del pedimento') }, required=['pedimento_id'] ), responses={ 200: openapi.Response('Tarea iniciada correctamente'), 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 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 ) # 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 ) except Pedimento.DoesNotExist: 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}" return Response({ 'message': message, 'task_id': task.id }, status=status.HTTP_200_OK) @swagger_auto_schema( method='post', operation_description="Audita 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') }, required=['organizacion_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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_pedimentos_endpoint(request): """ Inicia una tarea de auditoría para todos los pedimentos de una organización. Verifica todos los documentos y datos asociados a los pedimentos. """ 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_pedimentos.delay(organizacion_id) message = f"Auditoría iniciada para la organización {organizacion_id}" return Response({ 'message': message, 'task_id': task.id }, status=status.HTTP_200_OK) @swagger_auto_schema( method='post', operation_description="Audita el procesamiento de remesa para un pedimento específico", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID del pedimento a auditar') }, required=['pedimento_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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 & (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 ) # 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 ) except Pedimento.DoesNotExist: 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}" return Response({ 'message': message, 'task_id': task.id, 'pedimento': { 'id': str(pedimento.id), 'pedimento': pedimento.pedimento, 'tiene_remesas': pedimento.remesas } }, status=status.HTTP_200_OK) @swagger_auto_schema( method='post', operation_description="Audita los COVEs 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') }, required=['organizacion_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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_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) @swagger_auto_schema( method='post', operation_description="Audita los acuses de COVE 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') }, required=['organizacion_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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_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) @swagger_auto_schema( method='post', operation_description="Audita los EDocuments 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') }, required=['organizacion_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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_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) @swagger_auto_schema( method='post', operation_description="Audita los acuses 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') }, required=['organizacion_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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_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) @swagger_auto_schema( method='post', operation_description="Audita el COVE de un pedimento específico", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID del pedimento') }, required=['pedimento_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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_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) 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) @swagger_auto_schema( method='post', operation_description="Audita el acuse de COVE de un pedimento específico", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID del pedimento') }, required=['pedimento_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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_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) 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) @swagger_auto_schema( method='post', operation_description="Audita el EDocument de un pedimento específico", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID del pedimento') }, required=['pedimento_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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_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) 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) @swagger_auto_schema( method='post', operation_description="Audita el acuse de un pedimento específico", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'pedimento_id': openapi.Schema(type=openapi.TYPE_STRING, description='ID del pedimento') }, required=['pedimento_id'] ), responses={ 200: openapi.Response('Tarea de auditoría iniciada correctamente'), 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) 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) ### Procesamiento de pedimentos ### @swagger_auto_schema( method='post', operation_description="Procesamiento de todos los pedimentos de todas las organizaciones", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={} ), responses={ 200: openapi.Response('Tarea de procesamiento iniciada correctamente'), 403: openapi.Response('No tiene permisos suficientes'), 404: openapi.Response('No se encontraron organizaciones') } ) @api_view(['POST']) @permission_classes([IsAuthenticated & (IsSuperUser | IsSameOrganizationDeveloper)]) def auditor_procesar_pedimentos_organizacion(request): """ Inicia una tarea de procesamiento para todos los pedimentos de todas las organizaciones. Solo usuarios administradores pueden ejecutar esta función. """ # Validar permisos (solo superusuarios pueden procesar todas las organizaciones) user = request.user if not user.is_superuser: return Response( {'error': 'Solo los superusuarios pueden procesar todas las organizaciones'}, status=status.HTTP_403_FORBIDDEN ) organizaciones = Organizacion.objects.all() if not organizaciones.exists(): return Response( {'error': 'No se encontraron organizaciones'}, status=status.HTTP_404_NOT_FOUND ) # Lista para recopilar todos los task_ids y detalles tasks_iniciadas = [] for organizacion in organizaciones: organizacion_id = str(organizacion.id) print(f"Procesando organización: {organizacion_id} - {organizacion.nombre}") # Ejecutar la tarea de procesamiento task = procesar_pedimentos_completos.delay(organizacion_id) # Agregar información de la tarea a la lista tasks_iniciadas.append({ 'organizacion_id': organizacion_id, 'organizacion_nombre': organizacion.nombre, 'task_id': task.id }) # Crear mensaje general y lista de task_ids total_organizaciones = len(tasks_iniciadas) task_ids = [task['task_id'] for task in tasks_iniciadas] message = f"Procesamiento de pedimentos iniciado para {total_organizaciones} organización(es)" return Response({ 'message': message, 'total_organizaciones': total_organizaciones, 'task_ids': task_ids, 'tasks_detalle': tasks_iniciadas }, status=status.HTTP_200_OK) ### Fin Procesamiento de pedimentos ###