from datetime import timedelta from django.contrib.auth.decorators import login_required from django.db.models import Count from django.shortcuts import render from django.utils import timezone from analytics.models import Attribution, UTMVisit def _bar_pct(rows, key="count"): max_count = max((row[key] for row in rows), default=1) or 1 for row in rows: row["bar_pct"] = max(12, int(100 * row[key] / max_count)) return rows @login_required def report(request): since_30d = timezone.now() - timedelta(days=30) visits_last_30_days = UTMVisit.objects.filter(created_at__gte=since_30d).count() visits_by_source = _bar_pct( list( UTMVisit.objects.values("utm_source") .annotate(count=Count("id")) .order_by("-count")[:20] ) ) visits_by_combo = list( UTMVisit.objects.values("utm_source", "utm_medium", "utm_campaign") .annotate(count=Count("id")) .order_by("-count")[:50] ) top_visit = visits_by_source[0] if visits_by_source else None top_visit_campaign = ( UTMVisit.objects.exclude(utm_campaign="") .values("utm_campaign") .annotate(count=Count("id")) .order_by("-count") .first() ) leads_by_source = _bar_pct( list( Attribution.objects.values("utm_source") .annotate(count=Count("id")) .order_by("-count")[:20] ) ) leads_by_combo = list( Attribution.objects.values("utm_source", "utm_medium", "utm_campaign") .annotate(count=Count("id")) .order_by("-count")[:50] ) recent_visits = UTMVisit.objects.all()[:25] return render( request, "analytics/report.html", { "visits_last_30_days": visits_last_30_days, "total_visits": UTMVisit.objects.count(), "total_attributed": Attribution.objects.count(), "top_source": (top_visit or {}).get("utm_source") or "(direct)", "top_campaign": (top_visit_campaign or {}).get("utm_campaign") or "—", "visits_by_source": visits_by_source, "visits_by_combo": visits_by_combo, "leads_by_source": leads_by_source, "leads_by_combo": leads_by_combo, "recent_visits": recent_visits, }, )