diff --git a/manage_events/report.py b/manage_events/report.py index f435fe5..94d237c 100644 --- a/manage_events/report.py +++ b/manage_events/report.py @@ -8,10 +8,11 @@ from reportlab.graphics.shapes import Drawing from reportlab.graphics.charts.piecharts import Pie from io import BytesIO from django.conf import settings +from collections import defaultdict from reportlab.graphics import renderPDF from django.contrib.auth import get_user_model from goodtimes.services import EmailService -from manage_events.models import Event, EventInteractionType +from manage_events.models import Event, EventInteractionType, EventView User = get_user_model() @@ -36,44 +37,35 @@ def get_previous_month_date_range(): def generate_event_report(user_id): - # Calculate the start and end dates for the previous month start_date, end_date = get_previous_month_date_range() - - # Get the user (manager) user = User.objects.get(id=user_id) - # Filter events created by the user in the previous month - events = Event.objects.filter( - created_by=user, created_on__gte=start_date, created_on__lte=end_date - ).annotate( - favorites_count=Count( - "favorites", filter=Q(favorites__active=True, favorites__deleted=False) - ), - interested_count=Count( - "interaction_event", - filter=Q(interaction_event__status=EventInteractionType.INTERESTED), - ), - going_count=Count( - "interaction_event", - filter=Q(interaction_event__status=EventInteractionType.GOING), - ), - reviews_count=Count( - "reviews", filter=Q(reviews__active=True, reviews__deleted=False) - ), + events = Event.objects.filter(created_by=user, created_on__gte=start_date, created_on__lte=end_date).annotate( + favorites_count=Count("favorites", filter=Q(favorites__active=True, favorites__deleted=False)), + interested_count=Count("interaction_event", filter=Q(interaction_event__status=EventInteractionType.INTERESTED)), + going_count=Count("interaction_event", filter=Q(interaction_event__status=EventInteractionType.GOING)), + reviews_count=Count("reviews", filter=Q(reviews__active=True, reviews__deleted=False)), + views_count=Count("views", filter=Q(views__active=True, views__deleted=False)), ) - # Generate the report report_data = [] for event in events: - report_data.append( - { - "event_name": event.title, - "favorites_count": event.favorites_count, - "interested_count": event.interested_count, - "going_count": event.going_count, - "reviews_count": event.reviews_count, - } - ) + views = EventView.objects.filter(event=event) + locations = defaultdict(int) + for view in views: + locations[view.location] += 1 + + report_data.append({ + "event_name": event.title, + "event_type": event.category.title, + "event_date": str(event.start_date), + "favorites_count": event.favorites_count, + "interested_count": event.interested_count, + "going_count": event.going_count, + "reviews_count": event.reviews_count, + "views_count": event.views_count, + "locations": dict(locations), + }) return report_data @@ -211,3 +203,124 @@ def generate_event_report_pdf_two(user, report_data): buffer.close() return pdf_data, filename + + +def generate_event_report_pdf_three(user, report_data): + start_date, _ = get_previous_month_date_range() + filename = generate_filename(user.email, start_date) + + buffer = BytesIO() + pdf = canvas.Canvas(buffer, pagesize=letter) + width, height = letter + + # Header Section + title = "Good Times Ltd. Monthly Report" + report_for_month = f"Report for the month of - {start_date.strftime('%B %Y')}" + organiser_name = f"Name of the Organiser - {user.get_full_name()}" + contact_name = f"Contact Name - {user.get_full_name()}" + + pdf.setFont("Helvetica-Bold", 20) + title_width = pdf.stringWidth(title, "Helvetica-Bold", 20) + pdf.drawString((width - title_width) / 2, 750, title) + + pdf.setFont("Helvetica", 16) + report_for_month_width = pdf.stringWidth(report_for_month, "Helvetica", 16) + pdf.drawString((width - report_for_month_width) / 2, 720, report_for_month) + + organiser_name_width = pdf.stringWidth(organiser_name, "Helvetica", 16) + pdf.drawString((width - organiser_name_width) / 2, 690, organiser_name) + + contact_name_width = pdf.stringWidth(contact_name, "Helvetica", 16) + pdf.drawString((width - contact_name_width) / 2, 660, contact_name) + pdf.showPage() + # Summary Section + pdf.setFont("Helvetica-Bold", 12) + pdf.drawString( + 100, + 640, + f"Number of Events added in {start_date.strftime('%B %Y')} - {len(report_data)}", + ) + + y_pos = 620 + pdf.setFont("Helvetica-Bold", 10) + pdf.drawString(50, y_pos, "Event Name") + pdf.drawString(200, y_pos, "Event Type") + pdf.drawString(350, y_pos, "Date") + y_pos -= 20 + + pdf.setFont("Helvetica", 10) + for event in report_data: + pdf.drawString(50, y_pos, event["event_name"]) + pdf.drawString(200, y_pos, event["event_type"]) + pdf.drawString(350, y_pos, event["event_date"]) + y_pos -= 20 + + # Start a new page for Traffic Details Section + pdf.showPage() + + pdf.setFont("Helvetica-Bold", 12) + pdf.drawString( + 50, height - 50, "Traffic Details for profile - Event Organisers London Ltd." + ) + + # Detailed Review of Each Event + for event in report_data: + pdf.showPage() + pdf.setFont("Helvetica-Bold", 12) + pdf.drawString(50, height - 50, f"Event Name - {event['event_name']}") + pdf.setFont("Helvetica", 10) + pdf.drawString(50, height - 70, f"Event Type - {event['event_type']}") + pdf.drawString(50, height - 90, f"Event Date - {event['event_date']}") + + y_pos = height - 120 + pdf.drawString(50, y_pos, f"Number of Views - {event['views_count']}") + pdf.drawString(200, y_pos, f"Favorites Count - {event['favorites_count']}") + pdf.drawString(350, y_pos, f"Interested in Going - {event['interested_count']}") + pdf.drawString(500, y_pos, f"Going - {event['going_count']}") + pdf.drawString(650, y_pos, f"Reviews - {event['reviews_count']}") + y_pos -= 40 + + pdf.setFont("Helvetica-Bold", 10) + pdf.drawString(50, y_pos, "View Details:") + y_pos -= 20 + pdf.setFont("Helvetica", 10) + pdf.drawString(100, y_pos, "User Email") + pdf.drawString(300, y_pos, "Location") + pdf.drawString(500, y_pos, "View Date") + y_pos -= 20 + for view in event["locations"]: + pdf.drawString(100, y_pos, view["user__email"]) + pdf.drawString(300, y_pos, view["location"]) + pdf.drawString(500, y_pos, view["view_date"].strftime("%d %B %Y %H:%M")) + y_pos -= 20 + + # Draw pie chart on a new page if there's not enough space + if y_pos < 150: + pdf.showPage() + y_pos = height - 150 + + pie_data = [ + event["views_count"], + event["favorites_count"], + event["interested_count"], + event["going_count"], + ] + pie_labels = ["Views", "Favorites", "Interested", "Going"] + + drawing = Drawing(200, 100) + pie = Pie() + pie.x = 50 + pie.y = y_pos - 100 + pie.data = pie_data + pie.labels = pie_labels + pie.width = 100 + pie.height = 100 + drawing.add(pie) + renderPDF.draw(drawing, pdf, 50, y_pos - 100) + y_pos -= 150 # Adjust for pie chart height + + pdf.save() + buffer.seek(0) + pdf_data = buffer.read() + buffer.close() + return pdf_data, filename diff --git a/manage_events/views.py b/manage_events/views.py index 05c53e5..89c3336 100644 --- a/manage_events/views.py +++ b/manage_events/views.py @@ -481,7 +481,7 @@ class VenueDeleteView(LoginRequiredMixin, generic.View): User = get_user_model() -from .report import generate_event_report, generate_event_report_pdf +from .report import generate_event_report, generate_event_report_pdf_three from django.http import HttpResponse @@ -495,7 +495,7 @@ class GenerateEventReportView(generic.View): user = get_object_or_404(User, id=user_id) # Generate the PDF - pdf_data, filename = generate_event_report_pdf(user, report_data) + pdf_data, filename = generate_event_report_pdf_three(user, report_data) # Create the HttpResponse object with the PDF data response = HttpResponse(pdf_data, content_type="application/pdf")