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 } })