se agrego comando del auditor
This commit is contained in:
122
api/customs/management/commands/AUDITOR_COMMAND.md
Normal file
122
api/customs/management/commands/AUDITOR_COMMAND.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Comando de Auditoría de Pedimentos
|
||||
|
||||
## 📝 Descripción
|
||||
El comando `auditor` es una herramienta flexible para ejecutar tareas de auditoría y verificación de datos relacionados con pedimentos de una organización específica. Permite ejecutar todas las tareas o seleccionar específicamente cuáles ejecutar.
|
||||
|
||||
## 🔍 Tareas Disponibles
|
||||
|
||||
- **remesas**: Auditoría de remesas y procesamiento de COVEs
|
||||
- **partidas**: Creación y validación de partidas faltantes
|
||||
- **coves**: Auditoría de COVEs y su estado
|
||||
- **acuse-cove**: Verificación de acuses de COVEs
|
||||
- **edocs**: Auditoría de E-documents
|
||||
- **acuses**: Verificación de acuses generales
|
||||
|
||||
## 💻 Uso
|
||||
|
||||
### Ver Tareas Disponibles
|
||||
```bash
|
||||
python manage.py auditor --list
|
||||
```
|
||||
|
||||
### Ejecutar Todas las Tareas
|
||||
```bash
|
||||
python manage.py auditor <organizacion_id>
|
||||
# o explícitamente
|
||||
python manage.py auditor <organizacion_id> --tareas todas
|
||||
```
|
||||
|
||||
### Ejecutar Tareas Específicas
|
||||
```bash
|
||||
# Ejecutar solo auditoría de remesas y COVEs
|
||||
python manage.py auditor <organizacion_id> --tareas remesas coves
|
||||
|
||||
# Ejecutar partidas y acuses
|
||||
python manage.py auditor <organizacion_id> --tareas partidas acuses
|
||||
|
||||
# Ejecutar E-documents y acuses de COVEs
|
||||
python manage.py auditor <organizacion_id> --tareas edocs acuse-cove
|
||||
```
|
||||
|
||||
### Ejecución en Docker
|
||||
```bash
|
||||
docker exec -it EFC_backend_dev python manage.py auditor <organizacion_id> [opciones]
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
```bash
|
||||
# Listar tareas disponibles
|
||||
python manage.py auditor --list
|
||||
|
||||
# Auditar todo para una organización
|
||||
python manage.py auditor 9d705e97-d3f2-4b6c-8d92-9f1af2b2d4b4
|
||||
|
||||
# Auditar solo remesas y COVEs
|
||||
python manage.py auditor 9d705e97-d3f2-4b6c-8d92-9f1af2b2d4b4 --tareas remesas coves
|
||||
```
|
||||
|
||||
## 📊 Monitoreo y Resultados
|
||||
|
||||
### Indicadores de Estado
|
||||
- ✓ Tarea iniciada correctamente
|
||||
- ✗ Error en la ejecución
|
||||
|
||||
### Información Mostrada
|
||||
- ID de la organización
|
||||
- Número total de pedimentos
|
||||
- Task ID de cada tarea iniciada
|
||||
- Tiempo total de ejecución
|
||||
- Estado de cada tarea
|
||||
|
||||
## ⚠️ Consideraciones Importantes
|
||||
|
||||
### Requisitos Previos
|
||||
- Acceso al servidor/contenedor
|
||||
- Permisos de Django
|
||||
- ID válido de organización
|
||||
- Celery en ejecución
|
||||
|
||||
### Recomendaciones
|
||||
1. **Antes de Ejecutar**
|
||||
- Realizar respaldo de datos
|
||||
- Verificar disponibilidad de recursos
|
||||
- Comprobar conexión con servicios
|
||||
|
||||
2. **Durante la Ejecución**
|
||||
- Monitorear logs de Celery
|
||||
- Verificar uso de recursos
|
||||
- No interrumpir el proceso
|
||||
|
||||
3. **Después de la Ejecución**
|
||||
- Verificar logs
|
||||
- Validar resultados
|
||||
- Documentar incidencias
|
||||
|
||||
## 🔧 Solución de Problemas
|
||||
|
||||
### Errores Comunes
|
||||
1. **Organización no encontrada**
|
||||
- Verificar ID de organización
|
||||
- Confirmar existencia de pedimentos
|
||||
|
||||
2. **Tareas no inician**
|
||||
- Verificar estado de Celery
|
||||
- Comprobar permisos
|
||||
- Revisar conexiones
|
||||
|
||||
3. **Errores de ejecución**
|
||||
- Consultar logs detallados
|
||||
- Verificar disponibilidad de servicios
|
||||
- Comprobar estado de la base de datos
|
||||
|
||||
## 📝 Notas Adicionales
|
||||
- Las tareas se ejecutan de forma asíncrona
|
||||
- El tiempo mostrado corresponde solo a la inicialización
|
||||
- Las tareas continúan en segundo plano
|
||||
- Se recomienda ejecutar en horarios de bajo tráfico
|
||||
|
||||
## 🔍 Logs y Monitoreo
|
||||
Para un seguimiento detallado, revisar:
|
||||
- Logs de Celery
|
||||
- Logs de Django
|
||||
- Monitor de tareas de Celery
|
||||
97
api/customs/management/commands/auditor.py
Normal file
97
api/customs/management/commands/auditor.py
Normal file
@@ -0,0 +1,97 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from api.customs.tasks.auditoria import (
|
||||
auditar_procesamiento_remesas,
|
||||
auditar_coves,
|
||||
auditar_acuse_cove,
|
||||
auditar_edocuments,
|
||||
auditar_acuse,
|
||||
crear_partidas
|
||||
)
|
||||
from api.customs.models import Pedimento
|
||||
from datetime import datetime
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Ejecuta tareas de auditoría para una organización'
|
||||
|
||||
# Definir las tareas disponibles
|
||||
TAREAS_DISPONIBLES = {
|
||||
'remesas': (auditar_procesamiento_remesas, "Auditoría de remesas"),
|
||||
'partidas': (crear_partidas, "Creación de partidas"),
|
||||
'coves': (auditar_coves, "Auditoría de COVEs"),
|
||||
'acuse-cove': (auditar_acuse_cove, "Auditoría de acuses de COVEs"),
|
||||
'edocs': (auditar_edocuments, "Auditoría de E-documents"),
|
||||
'acuses': (auditar_acuse, "Auditoría de acuses")
|
||||
}
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'organizacion_id',
|
||||
type=str,
|
||||
help='ID de la organización a auditar'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--tareas',
|
||||
nargs='+',
|
||||
choices=['todas'] + list(self.TAREAS_DISPONIBLES.keys()),
|
||||
default=['todas'],
|
||||
help='Lista de tareas a ejecutar. Opciones: todas, ' +
|
||||
', '.join(self.TAREAS_DISPONIBLES.keys())
|
||||
)
|
||||
parser.add_argument(
|
||||
'--list',
|
||||
action='store_true',
|
||||
help='Muestra la lista de tareas disponibles'
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
organizacion_id = options['organizacion_id']
|
||||
start_time = datetime.now()
|
||||
|
||||
# Verificar si la organización tiene pedimentos
|
||||
pedimentos_count = Pedimento.objects.filter(organizacion_id=organizacion_id).count()
|
||||
if not pedimentos_count:
|
||||
self.stdout.write(
|
||||
self.style.ERROR(f'No se encontraron pedimentos para la organización {organizacion_id}')
|
||||
)
|
||||
return
|
||||
|
||||
self.stdout.write(f'Iniciando auditoría para organización {organizacion_id}')
|
||||
self.stdout.write(f'Total de pedimentos a procesar: {pedimentos_count}')
|
||||
|
||||
# Si se solicita listar las tareas
|
||||
if options['list']:
|
||||
self.stdout.write('Tareas disponibles:')
|
||||
for key, (_, desc) in self.TAREAS_DISPONIBLES.items():
|
||||
self.stdout.write(f' - {key}: {desc}')
|
||||
return
|
||||
|
||||
# Determinar qué tareas ejecutar
|
||||
tareas_seleccionadas = []
|
||||
if 'todas' in options['tareas']:
|
||||
tareas_seleccionadas = list(self.TAREAS_DISPONIBLES.values())
|
||||
else:
|
||||
for tarea in options['tareas']:
|
||||
if tarea in self.TAREAS_DISPONIBLES:
|
||||
tareas_seleccionadas.append(self.TAREAS_DISPONIBLES[tarea])
|
||||
|
||||
self.stdout.write(f'Tareas seleccionadas: {len(tareas_seleccionadas)}')
|
||||
for _, desc in tareas_seleccionadas:
|
||||
self.stdout.write(f' - {desc}')
|
||||
|
||||
# Ejecutar cada tarea
|
||||
for tarea, descripcion in tareas_seleccionadas:
|
||||
self.stdout.write(f'\nIniciando {descripcion}...')
|
||||
try:
|
||||
resultado = tarea.delay(organizacion_id)
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(f'✓ {descripcion} iniciada (Task ID: {resultado.id})')
|
||||
)
|
||||
except Exception as e:
|
||||
self.stdout.write(
|
||||
self.style.ERROR(f'✗ Error en {descripcion}: {str(e)}')
|
||||
)
|
||||
|
||||
tiempo_total = datetime.now() - start_time
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
f'\nProceso de auditoría completado en {tiempo_total}'
|
||||
))
|
||||
@@ -16,6 +16,36 @@ def extraer_coves(pedimento):
|
||||
|
||||
return xml_data
|
||||
|
||||
def modificar_estado_procesamiento(pedimento, servicio_id, nuevo_estado):
|
||||
procesamiento = ProcesamientoPedimento.objects.filter(
|
||||
pedimento=pedimento,
|
||||
servicio_id=servicio_id,
|
||||
organizacion=pedimento.organizacion
|
||||
).first()
|
||||
if procesamiento:
|
||||
procesamiento.estado_id = nuevo_estado
|
||||
procesamiento.save()
|
||||
return True
|
||||
return False
|
||||
|
||||
def auditor_descargas(pedimento, servicio, related_name, variable, mensaje):
|
||||
pedimento_id = pedimento.id
|
||||
docs = getattr(pedimento, related_name).all()
|
||||
|
||||
all_docs = all(getattr(doc, variable) for doc in docs)
|
||||
|
||||
if all_docs:
|
||||
proceso = modificar_estado_procesamiento(pedimento, servicio_id=servicio, nuevo_estado=3) # Estado "completado"
|
||||
print(f"✓ Pedimento {pedimento_id} tiene todos sus {mensaje} de edocument descargados.")
|
||||
else:
|
||||
proceso = modificar_estado_procesamiento(pedimento, servicio_id=servicio, nuevo_estado=4) # Estado "en progreso"
|
||||
print(f"✗ Pedimento {pedimento_id} NO tiene todos sus {mensaje} de edocument descargados.")
|
||||
if proceso:
|
||||
print(f"✓ Proceso de auditoría para pedimento {pedimento_id} completado.")
|
||||
else:
|
||||
print(f"✗ No se encontró proceso de auditoría para pedimento {pedimento_id}.")
|
||||
|
||||
## Auditar pedimentos
|
||||
@shared_task
|
||||
def auditar_procesamiento_remesas(organizacion_id):
|
||||
pedimentos = obtener_pedimentos(organizacion_id)
|
||||
@@ -103,53 +133,6 @@ def auditar_procesamiento_remesa_por_pedimento(pedimento_id):
|
||||
'pedimento_id': str(pedimento_id)
|
||||
}
|
||||
|
||||
|
||||
@shared_task
|
||||
def auditar_partidas(organizacion_id):
|
||||
pedimentos = Pedimento.objects.filter(organizacion_id=organizacion_id)
|
||||
for pedimento in pedimentos:
|
||||
# Validar que numero_partidas no sea None y sea mayor que 0
|
||||
if pedimento.numero_partidas is not None and pedimento.numero_partidas > 0:
|
||||
partidas_descargadas = pedimento.documents.filter(document_type=1)
|
||||
|
||||
partidas = {str(documento.archivo).split('_')[-1].split('.')[0]: documento.archivo for documento in partidas_descargadas}
|
||||
partidas_faltantes = []
|
||||
|
||||
for i in range(1, pedimento.numero_partidas + 1):
|
||||
if str(i) not in partidas.keys():
|
||||
partidas_faltantes.append(i)
|
||||
# crear servicio individual para cada partida faltante en microservicios
|
||||
|
||||
|
||||
@shared_task
|
||||
def auditar_coves(organizacion_id):
|
||||
# crear servicio individual para cada cove faltante en microservicios
|
||||
pass
|
||||
|
||||
@shared_task
|
||||
def auditar_edocuments(organizacion_id):
|
||||
# crear servicio individual para cada Edocument faltante en microservicios
|
||||
pass
|
||||
|
||||
@shared_task
|
||||
def auditar_acuse_coves(organizacion_id):
|
||||
# crear servicio individual para cada cove faltante en microservicios
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@shared_task
|
||||
def auditar_acuse_edocuments(organizacion_id):
|
||||
# crear servicio individual para cada acuse de edocument faltante en microservicios
|
||||
pedimentos = obtener_pedimentos(organizacion_id)
|
||||
|
||||
for pedimento in pedimentos:
|
||||
acuses_descargados = pedimento.documents.filter(document_type=4)
|
||||
edocs = pedimento.documentos.all()
|
||||
|
||||
|
||||
|
||||
@shared_task
|
||||
def crear_partidas(organizacion_id):
|
||||
pedimentos = obtener_pedimentos(organizacion_id)
|
||||
@@ -223,3 +206,52 @@ def crear_partidas_por_pedimento(pedimento_id):
|
||||
print(f"Pedimento {pedimento_id} ya tiene todas sus partidas ({partidas_existentes}/{pedimento.numero_partidas})")
|
||||
else:
|
||||
print(f"Error: Pedimento {pedimento_id} tiene numero_partidas inválido: {pedimento.numero_partidas}")
|
||||
|
||||
# Auditar coves
|
||||
@shared_task
|
||||
def auditar_coves(organizacion_id):
|
||||
for pedimento in obtener_pedimentos(organizacion_id):
|
||||
auditor_descargas(
|
||||
pedimento,
|
||||
servicio=8,
|
||||
related_name='coves',
|
||||
variable='acuse_descargado',
|
||||
mensaje='COVE'
|
||||
)
|
||||
|
||||
@shared_task
|
||||
def auditar_acuse_cove(organizacion_id):
|
||||
for pedimento in obtener_pedimentos(organizacion_id):
|
||||
auditor_descargas(
|
||||
pedimento,
|
||||
servicio=9,
|
||||
related_name='coves',
|
||||
variable='acuse_cove_descargado',
|
||||
mensaje='acuse de COVE'
|
||||
)
|
||||
|
||||
# Revisa si el pedimento completo todos sus acuse coves
|
||||
|
||||
# Auditar edocuments
|
||||
@shared_task
|
||||
def auditar_edocuments(organizacion_id):
|
||||
for pedimento in obtener_pedimentos(organizacion_id):
|
||||
auditor_descargas(
|
||||
pedimento,
|
||||
servicio=7,
|
||||
related_name='documentos',
|
||||
variable='edocument_descargado',
|
||||
mensaje='EDocument'
|
||||
)
|
||||
|
||||
@shared_task
|
||||
def auditar_acuse(organizacion_id):
|
||||
for pedimento in obtener_pedimentos(organizacion_id):
|
||||
auditor_descargas(
|
||||
pedimento,
|
||||
servicio=6,
|
||||
related_name='documentos',
|
||||
variable='acuse_descargado',
|
||||
mensaje='acuse'
|
||||
)
|
||||
|
||||
|
||||
@@ -260,8 +260,6 @@ class PartidaViewSet(viewsets.ModelViewSet):
|
||||
|
||||
my_tags = ['Partidas']
|
||||
|
||||
|
||||
|
||||
class ViewSetTipoOperacion(LoggingMixin, viewsets.ModelViewSet):
|
||||
"""
|
||||
ViewSet for TipoOperacion model.
|
||||
|
||||
@@ -275,3 +275,5 @@ def auditar_procesamiento_remesas_endpoint(request):
|
||||
'message': message,
|
||||
'task_id': task.id
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user