actualizacion de reportes

This commit is contained in:
Dulce
2025-11-25 13:17:41 -07:00
parent 4b44c098c4
commit a765026075
6 changed files with 1013 additions and 10 deletions

View File

@@ -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'])