Files
backend/api/reports/views_stats.py

121 lines
4.2 KiB
Python

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from django.db.models import Count, Sum
from django.db.models.functions import TruncDay, TruncWeek, TruncMonth
from django.db.models import Q
from api.customs.models import Pedimento, Cove, EDocument
from api.record.models import Document
from datetime import datetime, timedelta
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def documentos_por_fecha(request):
"""
Endpoint para obtener datos agregados de documentos por fecha
Parámetros:
- start_date: fecha inicial (YYYY-MM-DD)
- end_date: fecha final (YYYY-MM-DD)
- periodo: 'dia', 'semana', 'mes' (default: dia)
- organizacion_id: ID de la organización
- tipo_documento: ID del tipo de documento
"""
# Obtener parámetros
start_date = request.query_params.get('start_date')
end_date = request.query_params.get('end_date')
periodo = request.query_params.get('periodo', 'dia') # dia, semana, mes
org_id = request.query_params.get('organizacion_id')
tipo_doc = request.query_params.get('tipo_documento')
# Si no hay fechas, usar último mes
if not start_date:
start_date = (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')
if not end_date:
end_date = datetime.now().strftime('%Y-%m-%d')
# Construir filtros base para cada modelo
doc_filters = {}
cove_filters = {}
edoc_filters = {}
if org_id:
doc_filters['organizacion_id'] = org_id
cove_filters['organizacion_id'] = org_id
edoc_filters['organizacion_id'] = org_id
if start_date:
doc_filters['created_at__gte'] = start_date
cove_filters['created_at__gte'] = start_date
edoc_filters['created_at__gte'] = start_date
if end_date:
doc_filters['created_at__lte'] = end_date
cove_filters['created_at__lte'] = end_date
edoc_filters['created_at__lte'] = end_date
if tipo_doc:
doc_filters['document_type__id'] = tipo_doc # Solo para Document
# Obtener datos agregados según el periodo
if periodo == 'dia':
trunc_func = TruncDay
elif periodo == 'semana':
trunc_func = TruncWeek
elif periodo == 'mes':
trunc_func = TruncMonth
else:
trunc_func = TruncDay
# Obtener estadísticas de documentos
documentos = Document.objects.filter(**doc_filters).annotate(
fecha=trunc_func('created_at')
).values('fecha').annotate(
total=Count('id'),
size_total=Sum('size')
).order_by('fecha')
# Obtener estadísticas de coves
coves = Cove.objects.filter(**cove_filters).annotate(
fecha=trunc_func('created_at')
).values('fecha').annotate(
total=Count('id'),
descargados=Count('id', filter=Q(cove_descargado=True)),
acuses=Count('id', filter=Q(acuse_cove_descargado=True))
).order_by('fecha')
# Obtener estadísticas de edocs
edocs = EDocument.objects.filter(**edoc_filters).annotate(
fecha=trunc_func('created_at')
).values('fecha').annotate(
total=Count('id'),
descargados=Count('id', filter=Q(edocument_descargado=True)),
acuses=Count('id', filter=Q(acuse_descargado=True))
).order_by('fecha')
# Calcular totales
totales = {
'documentos': {
'total': sum(d['total'] for d in documentos),
'size_total': sum(d['size_total'] for d in documentos)
},
'coves': {
'total': sum(c['total'] for c in coves),
'descargados': sum(c['descargados'] for c in coves),
'acuses': sum(c['acuses'] for c in coves)
},
'edocs': {
'total': sum(e['total'] for e in edocs),
'descargados': sum(e['descargados'] for e in edocs),
'acuses': sum(e['acuses'] for e in edocs)
}
}
return Response({
'documentos': list(documentos),
'coves': list(coves),
'edocs': list(edocs),
'totales': totales,
'periodo': periodo,
'filtros': {
'start_date': start_date,
'end_date': end_date,
'organizacion_id': org_id,
'tipo_documento': tipo_doc
}
})