actualizacion de reportes
This commit is contained in:
@@ -3,10 +3,15 @@ from django.core.files.base import ContentFile
|
||||
from django.utils import timezone
|
||||
from api.reports.models import ReportDocument
|
||||
from api.customs.models import Pedimento, Cove, EDocument, Partida
|
||||
from django.db.models import Q
|
||||
from django.db.models import Q, Exists, OuterRef
|
||||
# from django.db.models import Q,
|
||||
from api.record.models import Document
|
||||
import csv
|
||||
import os
|
||||
from django.conf import settings
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
@shared_task
|
||||
def generate_report_document(report_id):
|
||||
@@ -15,7 +20,6 @@ def generate_report_document(report_id):
|
||||
report.status = 'processing'
|
||||
report.save(update_fields=['status'])
|
||||
filters = report.filters or {}
|
||||
# Construir Q para filtros complejos
|
||||
pedimentos_filters = Q()
|
||||
if filters.get('organizacion_id'):
|
||||
pedimentos_filters &= Q(organizacion_id=filters['organizacion_id'])
|
||||
@@ -83,3 +87,179 @@ def generate_report_document(report_id):
|
||||
report.error_message = str(e)
|
||||
report.finished_at = timezone.now()
|
||||
report.save(update_fields=['status', 'error_message', 'finished_at'])
|
||||
|
||||
@shared_task
|
||||
def generate_report_control_pedimento(report_id):
|
||||
try:
|
||||
logger.info(f"🔴🔴🔴 INICIANDO TAREA para control de pedimento {report_id}")
|
||||
report = ReportDocument.objects.get(id=report_id)
|
||||
report.status = 'processing'
|
||||
report.save(update_fields=['status'])
|
||||
filters = report.filters or {}
|
||||
logger.info(f"🔴🔴🔴 FILTROS: {filters}")
|
||||
|
||||
# Construir filtros
|
||||
pedimentos_filters = {}
|
||||
if filters.get('organizacion_id'):
|
||||
pedimentos_filters['organizacion_id'] = filters['organizacion_id']
|
||||
if filters.get('fecha_pago__gte'):
|
||||
pedimentos_filters['fecha_pago__gte'] = filters['fecha_pago__gte']
|
||||
if filters.get('fecha_pago__lte'):
|
||||
pedimentos_filters['fecha_pago__lte'] = filters['fecha_pago__lte']
|
||||
if filters.get('pedimento_app'):
|
||||
pedimentos_filters['pedimento_app'] = filters['pedimento_app']
|
||||
|
||||
# pedimentos por organizacion
|
||||
pedimentos_qs = Pedimento.objects.filter(**pedimentos_filters)
|
||||
pedimentos_total = pedimentos_qs.count()
|
||||
logger.info(f'🔴🔴🔴 PEDIMENTOS ENCONTRADOS: {pedimentos_total}')
|
||||
|
||||
pedimento_ids = list(pedimentos_qs.values_list('id', flat=True))
|
||||
|
||||
# inicializar totales
|
||||
pedimentos_completos = 0
|
||||
total_documentos = 0
|
||||
documentos_sin_descargar = 0
|
||||
|
||||
# Para cada pedimento, verificar si está completo
|
||||
for pedimento in pedimentos_qs:
|
||||
# Contar documentos de este pedimento
|
||||
docs_pedimento = 0
|
||||
docs_pendientes_pedimento = 0
|
||||
|
||||
# COVES
|
||||
coves_count = Cove.objects.filter(pedimento_id=pedimento.id).count()
|
||||
coves_pendientes = Cove.objects.filter(pedimento_id=pedimento.id, cove_descargado=False).count()
|
||||
docs_pedimento += coves_count
|
||||
docs_pendientes_pedimento += coves_pendientes
|
||||
|
||||
# PARTIDAS
|
||||
partidas_count = Partida.objects.filter(pedimento_id=pedimento.id).count()
|
||||
partidas_pendientes = Partida.objects.filter(pedimento_id=pedimento.id, descargado=False).count()
|
||||
docs_pedimento += partidas_count
|
||||
docs_pendientes_pedimento += partidas_pendientes
|
||||
|
||||
# EDOCUMENTS
|
||||
edocs_count = EDocument.objects.filter(pedimento_id=pedimento.id).count()
|
||||
edocs_pendientes = EDocument.objects.filter(pedimento_id=pedimento.id, edocument_descargado=False).count()
|
||||
docs_pedimento += edocs_count
|
||||
docs_pendientes_pedimento += edocs_pendientes
|
||||
|
||||
# Acumular totales
|
||||
total_documentos += docs_pedimento
|
||||
documentos_sin_descargar += docs_pendientes_pedimento
|
||||
|
||||
# Si no tiene documentos pendientes, está completo
|
||||
if docs_pendientes_pedimento == 0 and docs_pedimento > 0:
|
||||
pedimentos_completos += 1
|
||||
|
||||
# 3. PORCENTAJE
|
||||
porcentaje_faltantes = (documentos_sin_descargar / total_documentos * 100) if total_documentos > 0 else 0
|
||||
|
||||
# 4. GENERAR CSV CON DETALLES
|
||||
filename = f"report_{report.id}_{timezone.now().strftime('%Y%m%d%H%M%S')}.csv"
|
||||
file_path = os.path.join(settings.MEDIA_ROOT, 'reports', filename)
|
||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||||
|
||||
todas_las_filas = []
|
||||
|
||||
# Recopilar datos detallados - UNA FILA POR CADA DOCUMENTO
|
||||
for pedimento in pedimentos_qs:
|
||||
# DATOS BASE DEL PEDIMENTO (se repiten en cada fila)
|
||||
datos_base_pedimento = [
|
||||
pedimento.aduana or '',
|
||||
pedimento.patente or '',
|
||||
pedimento.regimen or '',
|
||||
pedimento.pedimento or '', # No. Pedimento (7 dígitos)
|
||||
pedimento.pedimento_app or '', # No. Pedimento App completo
|
||||
pedimento.clave_pedimento or '',
|
||||
pedimento.tipo_operacion.tipo if pedimento.tipo_operacion else '',
|
||||
str(pedimento.contribuyente_id) if pedimento.contribuyente_id else ''
|
||||
]
|
||||
|
||||
# COVES - Una fila por cada COVE
|
||||
coves = Cove.objects.filter(pedimento_id=pedimento.id)
|
||||
for cove in coves:
|
||||
estado = 'VERDADERO' if cove.cove_descargado else 'FALSO'
|
||||
fila = datos_base_pedimento + [
|
||||
# str(cove.id), # Identificador de documento
|
||||
cove.numero_cove,
|
||||
'COVE', # Tipo de documento
|
||||
estado
|
||||
]
|
||||
todas_las_filas.append(fila)
|
||||
|
||||
# PARTIDAS - Una fila por cada Partida
|
||||
partidas = Partida.objects.filter(pedimento_id=pedimento.id)
|
||||
for partida in partidas:
|
||||
estado = 'VERDADERO' if partida.descargado else 'FALSO'
|
||||
fila = datos_base_pedimento + [
|
||||
# str(partida.id),
|
||||
partida.numero_partida,
|
||||
'PARTIDA', # Tipo de documento
|
||||
estado
|
||||
]
|
||||
todas_las_filas.append(fila)
|
||||
|
||||
# EDOCUMENTS - Una fila por cada EDocument
|
||||
edocuments = EDocument.objects.filter(pedimento_id=pedimento.id)
|
||||
for edoc in edocuments:
|
||||
estado = 'VERDADERO' if edoc.edocument_descargado else 'FALSO'
|
||||
fila = datos_base_pedimento + [
|
||||
# str(edoc.id),
|
||||
edoc.numero_edocument,
|
||||
'EDOCUMENT', # Tipo de documento
|
||||
estado
|
||||
]
|
||||
todas_las_filas.append(fila)
|
||||
|
||||
# 5. ESCRIBIR ARCHIVO CSV
|
||||
with open(file_path, 'w', newline='', encoding='utf-8') as f:
|
||||
writer = csv.writer(f)
|
||||
|
||||
# SECCIÓN DE TOTALES
|
||||
writer.writerow(['RESUMEN DEL REPORTE - CONTROL DE PEDIMENTOS'])
|
||||
writer.writerow([])
|
||||
writer.writerow(['TOTAL DE EXPEDIENTES:', pedimentos_total])
|
||||
writer.writerow(['TOTAL DE EXPEDIENTES COMPLETOS:', pedimentos_completos])
|
||||
writer.writerow(['TOTAL DE DOCUMENTOS:', total_documentos])
|
||||
writer.writerow(['DOCUMENTOS SIN DESCARGAR:', documentos_sin_descargar])
|
||||
writer.writerow(['PORCENTAJE DE DOCUMENTOS FALTANTES (%):', f"{porcentaje_faltantes:.2f}%"])
|
||||
writer.writerow([])
|
||||
writer.writerow([])
|
||||
|
||||
# ENCABEZADOS DE DATOS (según requerimiento)
|
||||
headers = [
|
||||
'ADUANA', 'PATENTE', 'REGIMEN', 'NO. PEDIMENTO', 'PEDIMENTO_APP',
|
||||
'CLAVE_PEDIMENTO', 'TIPO_OPERACION', 'CONTRIBUYENTE_ID',
|
||||
'IDENTIFICADOR_DOCUMENTO', 'TIPO_DOCUMENTO', 'ESTADO'
|
||||
]
|
||||
writer.writerow(headers)
|
||||
|
||||
# DATOS DETALLADOS
|
||||
for fila in todas_las_filas:
|
||||
writer.writerow(fila)
|
||||
|
||||
# 6. LOGS Y GUARDAR
|
||||
logger.info(f"📊 REPORTE FINAL:")
|
||||
logger.info(f" - Expedientes: {pedimentos_total}")
|
||||
logger.info(f" - Expedientes completos: {pedimentos_completos}")
|
||||
logger.info(f" - Total documentos: {total_documentos}")
|
||||
logger.info(f" - Documentos sin descargar: {documentos_sin_descargar}")
|
||||
logger.info(f" - Porcentaje faltantes: {porcentaje_faltantes:.2f}%")
|
||||
|
||||
with open(file_path, 'rb') as f:
|
||||
report.file.save(filename, ContentFile(f.read()), save=True)
|
||||
|
||||
report.status = 'ready'
|
||||
report.finished_at = timezone.now()
|
||||
report.save(update_fields=['status', 'file', 'finished_at'])
|
||||
|
||||
logger.info(f"✅ REPORTE GENERADO EXITOSAMENTE: {filename}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ ERROR en generate_report_control_pedimento: {str(e)}", exc_info=True)
|
||||
report.status = 'error'
|
||||
report.error_message = str(e)
|
||||
report.finished_at = timezone.now()
|
||||
report.save(update_fields=['status', 'error_message', 'finished_at'])
|
||||
Reference in New Issue
Block a user