Files
backend/api/customs/tasks/internal_services.py

275 lines
12 KiB
Python

import logging
from celery import shared_task, group
from api.customs.models import ProcesamientoPedimento, Pedimento, Cove, EDocument
from core.utils import xml_controller
from core.redis_events import publish_task_event
from api.customs.tasks.auditoria import _crear_notificacion_auditoria
from api.customs.tasks.microservice import (
procesar_cove_individual,
procesar_acuse_individual,
procesar_acuse_cove_individual,
procesar_edoc_individual,
procesar_partida_individual,
procesar_remesa_individual,
)
@shared_task
def crear_procesamiento_remesa(pedimento_id):
import logging
logger = logging.getLogger('api.customs.async_operations')
pedimento = Pedimento.objects.get(id=pedimento_id)
logger.info(f"[TAREA] crear_procesamiento_remesa para pedimento {pedimento_id}")
if pedimento.remesas:
existe = ProcesamientoPedimento.objects.filter(
pedimento=pedimento,
servicio_id=5,
organizacion=pedimento.organizacion,
estado_id__in=[1, 2, 3, 4]
).exists()
if not existe:
logger.info(f"[TAREA] ProcesamientoPedimento remesa creado para pedimento {pedimento_id}")
ProcesamientoPedimento.objects.create(
pedimento=pedimento,
estado_id=1,
servicio_id=5,
organizacion=pedimento.organizacion
)
procesar_remesa_individual.apply_async(args=[str(pedimento.id), str(pedimento.organizacion.id)])
@shared_task
def crear_procesamiento_partida(pedimento_id):
import logging
logger = logging.getLogger('api.customs.async_operations')
pedimento = Pedimento.objects.get(id=pedimento_id)
logger.info(f"[TAREA] crear_procesamiento_partida para pedimento {pedimento_id}")
existe = ProcesamientoPedimento.objects.filter(
pedimento=pedimento,
servicio_id=4,
organizacion=pedimento.organizacion,
estado_id__in=[1, 2, 3, 4]
).exists()
if not existe:
logger.info(f"[TAREA] ProcesamientoPedimento partida creado para pedimento {pedimento_id}")
ProcesamientoPedimento.objects.create(
pedimento=pedimento,
estado_id=1,
servicio_id=4,
organizacion=pedimento.organizacion
)
procesar_partida_individual.apply_async(args=[str(pedimento.id), str(pedimento.organizacion.id)])
@shared_task
def crear_procesamiento_cove(pedimento_id):
import logging
logger = logging.getLogger('api.customs.async_operations')
pedimento = Pedimento.objects.get(id=pedimento_id)
logger.info(f"[TAREA] crear_procesamiento_cove para pedimento {pedimento_id}")
if pedimento.coves.exists():
existe = ProcesamientoPedimento.objects.filter(
pedimento=pedimento,
servicio_id=8,
organizacion=pedimento.organizacion,
estado_id__in=[1, 2, 3, 4]
).exists()
if not existe:
logger.info(f"[TAREA] ProcesamientoPedimento cove creado para pedimento {pedimento_id}")
ProcesamientoPedimento.objects.create(
pedimento=pedimento,
estado_id=1,
servicio_id=8,
organizacion=pedimento.organizacion
)
procesar_cove_individual.apply_async(args=[str(pedimento.id), str(pedimento.organizacion.id)])
@shared_task
def crear_procesamiento_acuse(pedimento_id):
import logging
logger = logging.getLogger('api.customs.async_operations')
pedimento = Pedimento.objects.get(id=pedimento_id)
logger.info(f"[TAREA] crear_procesamiento_acuse para pedimento {pedimento_id}")
if pedimento.documentos.exists():
existe = ProcesamientoPedimento.objects.filter(
pedimento=pedimento,
servicio_id=6,
organizacion=pedimento.organizacion,
estado_id__in=[1, 2, 3, 4]
).exists()
if not existe:
logger.info(f"[TAREA] ProcesamientoPedimento acuse creado para pedimento {pedimento_id}")
ProcesamientoPedimento.objects.create(
pedimento=pedimento,
estado_id=1,
servicio_id=6,
organizacion=pedimento.organizacion
)
procesar_acuse_individual.apply_async(args=[str(pedimento.id), str(pedimento.organizacion.id)])
@shared_task
def crear_procesamiento_acuse_cove(pedimento_id):
import logging
logger = logging.getLogger('api.customs.async_operations')
pedimento = Pedimento.objects.get(id=pedimento_id)
logger.info(f"[TAREA] crear_procesamiento_acuse_cove para pedimento {pedimento_id}")
if pedimento.coves.exists():
existe = ProcesamientoPedimento.objects.filter(
pedimento=pedimento,
servicio_id=9,
organizacion=pedimento.organizacion,
estado_id__in=[1, 2, 3, 4]
).exists()
if not existe:
logger.info(f"[TAREA] ProcesamientoPedimento acuse_cove creado para pedimento {pedimento_id}")
ProcesamientoPedimento.objects.create(
pedimento=pedimento,
estado_id=1,
servicio_id=9,
organizacion=pedimento.organizacion
)
procesar_acuse_cove_individual.apply_async(args=[str(pedimento.id), str(pedimento.organizacion.id)])
@shared_task
def crear_procesamiento_edocument(pedimento_id):
import logging
logger = logging.getLogger('api.customs.async_operations')
pedimento = Pedimento.objects.get(id=pedimento_id)
logger.info(f"[TAREA] crear_procesamiento_edocument para pedimento {pedimento_id}")
if pedimento.documentos.exists():
existe = ProcesamientoPedimento.objects.filter(
pedimento=pedimento,
servicio_id=7,
organizacion=pedimento.organizacion,
estado_id__in=[1, 2, 3, 4]
).exists()
if not existe:
logger.info(f"[TAREA] ProcesamientoPedimento edocument creado para pedimento {pedimento_id}")
ProcesamientoPedimento.objects.create(
pedimento=pedimento,
estado_id=1,
servicio_id=7,
organizacion=pedimento.organizacion
)
procesar_edoc_individual.apply_async(args=[str(pedimento.id), str(pedimento.organizacion.id)])
@shared_task
def crear_procesamiento_pedimento_completo(organizacion_id):
import logging
logger = logging.getLogger('api.customs.async_operations')
pedimentos = Pedimento.objects.filter(organizacion_id=organizacion_id)
for pedimento in pedimentos:
logger.info(f"[TAREA] crear_procesamiento_pedimento_completo para pedimento {pedimento.id}")
existe = ProcesamientoPedimento.objects.filter(
pedimento=pedimento,
servicio_id=3, # ID del servicio de Pedimento Completo
organizacion=pedimento.organizacion,
estado_id__in=[1, 2, 3, 4]
).exists()
if not existe:
logger.info(f"[TAREA] ProcesamientoPedimento pedimento_completo creado para pedimento {pedimento.id}")
ProcesamientoPedimento.objects.create(
pedimento=pedimento,
estado_id=1, # Estado "pendiente"
servicio_id=3,
organizacion=pedimento.organizacion
)
@shared_task
def crear_servicios(organizacion_id):
pedimentos = Pedimento.objects.filter(organizacion=organizacion_id)
for pedimento in pedimentos:
crear_procesamiento_remesa.apply_async(args=[str(pedimento.id)])
crear_procesamiento_partida.apply_async(args=[str(pedimento.id)])
crear_procesamiento_cove.apply_async(args=[str(pedimento.id)])
crear_procesamiento_acuse.apply_async(args=[str(pedimento.id)])
crear_procesamiento_acuse_cove.apply_async(args=[str(pedimento.id)])
crear_procesamiento_edocument.apply_async(args=[str(pedimento.id)])
@shared_task(bind=True)
def auditar_pedimentos(self, organizacion_id, user_id=None):
_logger = logging.getLogger('api.customs.async_operations')
task_id = self.request.id
pedimentos = Pedimento.objects.filter(organizacion_id=organizacion_id)
total_pedimentos = pedimentos.count()
publish_task_event(task_id, "processing", f"Auditando pedimentos: {total_pedimentos} pedimentos", progress=0)
procesados = 0
sin_xml = 0
errores = []
for idx, pedimento in enumerate(pedimentos):
pc = pedimento.documents.filter(document_type__id=2).first()
if pc:
try:
with open(f'./media/{pc.archivo}', 'r') as f:
xml_content = f.read()
xml_data = xml_controller.extract_data(xml_content)
pedimento.numero_operacion = xml_data.get('numero_operacion')
pedimento.curp_apoderado = xml_data.get('curp_apoderado')
pedimento.agente_aduanal = xml_data.get('agente_aduanal')
pedimento.numero_partidas = xml_data.get('numero_partidas')
pedimento.remesas = xml_data.get('remesas')
pedimento.tipo_operacion__id = xml_data.get('tipo_operacion')
pedimento.fecha_pago = xml_data.get('fecha_pago')
pedimento.pedimento_app = xml_data.get('fecha_pago')[2:4] + "-" + pedimento.aduana[:2] + "-" + pedimento.patente + "-" + pedimento.pedimentodd
for edoc in xml_data.get('identificadores_ed', []):
EDocument.objects.get_or_create(
pedimento=pedimento,
organizacion=pedimento.organizacion,
clave=edoc.get('clave'),
descripcion=edoc.get('descripcion'),
numero_edocument=edoc.get('complemento1')
)
from django.db import IntegrityError
try:
for cove in xml_data.get('coves', []):
try:
Cove.objects.get_or_create(
pedimento=pedimento,
organizacion=pedimento.organizacion,
numero_cove=cove
)
except IntegrityError:
# Si ya existe por unique, recupera el objeto existente
Cove.objects.get(numero_cove=cove)
except:
pass
procesados += 1
except Exception as e:
errores.append({'pedimento_id': str(pedimento.id), 'error': str(e)})
_logger.error(f"Error auditando pedimento {pedimento.id}: {e}")
else:
sin_xml += 1
if total_pedimentos > 0 and (idx + 1) % 10 == 0:
pct = int(((idx + 1) / total_pedimentos) * 100)
publish_task_event(task_id, "processing", f"Auditando pedimentos: {idx + 1}/{total_pedimentos}", progress=pct)
resultado = {
'organizacion_id': str(organizacion_id),
'auditoria': 'pedimentos',
'total_pedimentos': total_pedimentos,
'procesados': procesados,
'sin_xml': sin_xml,
'con_errores': len(errores),
'detalle_errores': errores,
}
publish_task_event(task_id, "completed", "Auditoría de pedimentos completada", resultado=resultado, progress=100)
if user_id:
_crear_notificacion_auditoria(user_id, task_id, "Pedimentos", resultado)
return resultado
@shared_task
def crear_todos_los_servicios():
from organization.models import Organizacion
organizaciones = Organizacion.objects.all()
for org in organizaciones:
crear_procesamiento_pedimento_completo.apply_async(args=[str(org.id)])
crear_servicios.apply_async(args=[str(org.id)])