379 lines
13 KiB
Python
379 lines
13 KiB
Python
from django.db.models import Count, Q
|
|
from django.utils import timezone
|
|
from datetime import timedelta
|
|
from reportlab.lib.pagesizes import letter
|
|
from reportlab.lib.units import mm
|
|
from reportlab.graphics.shapes import Drawing, Rect
|
|
from reportlab.lib import colors
|
|
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
|
from reportlab.graphics.charts.piecharts import Pie
|
|
from reportlab.platypus import (
|
|
SimpleDocTemplate,
|
|
Table,
|
|
TableStyle,
|
|
Paragraph,
|
|
Spacer,
|
|
PageBreak,
|
|
Image,
|
|
)
|
|
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 accounts.models import IAmPrincipalType
|
|
from manage_events.models import Event, EventInteractionType, EventShare, EventView
|
|
import os
|
|
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
def generate_filename(email, date):
|
|
# Extract the username from the email address
|
|
username = email.split("@")[0]
|
|
# Get the full month name from the date
|
|
month_name = date.strftime("%B")
|
|
# Create the filename
|
|
filename = f"{username}_{month_name}_report.pdf"
|
|
return filename
|
|
|
|
|
|
def event_managers():
|
|
principal_type = IAmPrincipalType.objects.filter(name="event_manager").first()
|
|
return User.objects.filter(principal_type=principal_type, is_active=True)
|
|
|
|
|
|
def get_previous_month_date_range():
|
|
today = timezone.now()
|
|
first_day_of_current_month = today.replace(day=1)
|
|
last_day_of_previous_month = first_day_of_current_month - timedelta(days=1)
|
|
first_day_of_previous_month = last_day_of_previous_month.replace(day=1)
|
|
return first_day_of_previous_month, last_day_of_previous_month
|
|
|
|
|
|
def generate_event_report(user_id, start_date, end_date):
|
|
# start_date, end_date = get_previous_month_date_range()
|
|
user = User.objects.get(id=user_id)
|
|
|
|
# events = Event.objects.filter(
|
|
# created_by=user, start_date__gte=start_date, start_date__lte=end_date
|
|
# ).annotate(
|
|
# favorites_count=Count("favorites"),
|
|
# 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"),
|
|
# )
|
|
# # print("events: ", events)
|
|
|
|
# report_data = []
|
|
# for event in events:
|
|
# views = EventView.objects.filter(event=event)
|
|
# locations = defaultdict(int)
|
|
# for view in views:
|
|
# locations[view.location] += 1
|
|
|
|
# shares = (
|
|
# EventShare.objects.filter(event=event)
|
|
# .values("principal")
|
|
# .annotate(share_count=Count("principal"))
|
|
# )
|
|
# shares_data = {
|
|
# User.objects.get(id=share["principal"]).get_full_name(): share[
|
|
# "share_count"
|
|
# ]
|
|
# for share in shares
|
|
# }
|
|
|
|
# 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),
|
|
# "social_media_shares": event.social_media_shares_count,
|
|
# "shares_data": shares_data,
|
|
# }
|
|
# )
|
|
# # print("report_data: ", report_data)
|
|
# return report_data
|
|
events = Event.objects.filter(
|
|
created_by=user, start_date__gte=start_date, start_date__lte=end_date
|
|
)
|
|
|
|
report_data = []
|
|
for event in events:
|
|
# Collecting individual counts for each event
|
|
favorites_count = event.favorites.count()
|
|
interested_count = event.interaction_event.filter(
|
|
status=EventInteractionType.INTERESTED
|
|
).count()
|
|
going_count = event.interaction_event.filter(
|
|
status=EventInteractionType.GOING
|
|
).count()
|
|
reviews_count = event.reviews.filter(active=True, deleted=False).count()
|
|
views_count = event.views.count()
|
|
|
|
# Collecting views and locations
|
|
views = EventView.objects.filter(event=event)
|
|
locations = defaultdict(int)
|
|
for view in views:
|
|
locations[view.location] += 1
|
|
|
|
# Collecting shares data
|
|
shares = (
|
|
EventShare.objects.filter(event=event)
|
|
.values("principal")
|
|
.annotate(share_count=Count("principal"))
|
|
)
|
|
shares_data = {
|
|
User.objects.get(id=share["principal"]).get_full_name(): share[
|
|
"share_count"
|
|
]
|
|
for share in shares
|
|
}
|
|
|
|
# Appending event data to report
|
|
report_data.append(
|
|
{
|
|
"event_name": event.title,
|
|
"event_type": event.category.title,
|
|
"event_date": str(event.start_date),
|
|
"favorites_count": favorites_count,
|
|
"interested_count": interested_count,
|
|
"going_count": going_count,
|
|
"reviews_count": reviews_count,
|
|
"views_count": views_count,
|
|
"locations": dict(locations),
|
|
"social_media_shares": event.social_media_shares_count,
|
|
"shares_data": shares_data,
|
|
}
|
|
)
|
|
|
|
return report_data
|
|
|
|
|
|
def generate_event_report_pdf_three(user, report_data, start_date):
|
|
# start_date, _ = get_previous_month_date_range()
|
|
filename = generate_filename(user.email, start_date)
|
|
|
|
buffer = BytesIO()
|
|
# pdf = canvas.Canvas(buffer, pagesize=letter)
|
|
pdf = SimpleDocTemplate(buffer, pagesize=letter)
|
|
width, height = letter
|
|
elements = []
|
|
|
|
styles = getSampleStyleSheet()
|
|
|
|
custom_style = ParagraphStyle(
|
|
name="Custom",
|
|
parent=styles["Normal"],
|
|
fontName="Helvetica",
|
|
fontSize=14,
|
|
leading=18,
|
|
spaceAfter=12,
|
|
)
|
|
|
|
def add_page_number(canvas, doc):
|
|
page_num_text = f"Page {doc.page}"
|
|
canvas.drawRightString(200 * mm, 10 * mm, page_num_text)
|
|
|
|
# Header Section
|
|
title = Paragraph("Good Times Ltd. Monthly Report", styles["Title"])
|
|
report_for_month = Paragraph(
|
|
f"Report for the month of - {start_date.strftime('%B %Y')}", styles["Title"]
|
|
)
|
|
organiser_name = Paragraph(
|
|
f"Name of the Organiser - {user.get_full_name()}", styles["Title"]
|
|
)
|
|
contact_email = Paragraph(f"Contact Email - {user.email}", styles["Title"])
|
|
|
|
elements.extend(
|
|
[
|
|
title,
|
|
Spacer(1, 12),
|
|
report_for_month,
|
|
Spacer(1, 12),
|
|
organiser_name,
|
|
Spacer(1, 12),
|
|
contact_email,
|
|
Spacer(1, 72), # Add space before the logo
|
|
]
|
|
)
|
|
|
|
# Insert company logo
|
|
logo_path = settings.LOGO_PATH
|
|
print("logo_path: ", logo_path)
|
|
logo_path = os.path.join(str(logo_path), "images/icon.png") # Path to the logo
|
|
logo = Image(logo_path)
|
|
logo.drawWidth = 200 # Adjust the width as needed
|
|
logo.drawHeight = 300 # Adjust the height as needed
|
|
logo.hAlign = "CENTER" # Center the logo
|
|
|
|
elements.append(logo)
|
|
elements.append(Spacer(1, 12)) # Add space after the logo
|
|
|
|
# Page break after header and logo
|
|
elements.append(PageBreak())
|
|
|
|
# Summary Section
|
|
summary_text = (
|
|
f"Number of Events added in {start_date.strftime('%B %Y')} - {len(report_data)}"
|
|
)
|
|
elements.append(Paragraph(summary_text, styles["Title"]))
|
|
elements.append(Spacer(1, 24))
|
|
|
|
data = [["Sr No.", "Name of the Event", "Event Type", "Date"]]
|
|
for idx, event in enumerate(report_data, start=1):
|
|
data.append(
|
|
[
|
|
idx,
|
|
event["event_name"],
|
|
event["event_type"],
|
|
event["event_date"],
|
|
]
|
|
)
|
|
|
|
table = Table(data, colWidths=[50, 250, 150, 100])
|
|
style = TableStyle(
|
|
[
|
|
("BACKGROUND", (0, 0), (-1, 0), colors.grey),
|
|
("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),
|
|
("ALIGN", (0, 0), (-1, -1), "CENTER"),
|
|
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
|
|
("BOTTOMPADDING", (0, 0), (-1, 0), 12),
|
|
("BACKGROUND", (0, 1), (-1, -1), colors.beige),
|
|
("GRID", (0, 0), (-1, -1), 1, colors.black),
|
|
]
|
|
)
|
|
table.setStyle(style)
|
|
|
|
elements.append(table)
|
|
elements.append(PageBreak())
|
|
|
|
# Traffic Details Section
|
|
traffic_header = "Traffic Details for profile - Event Organisers London Ltd."
|
|
elements.append(Paragraph(traffic_header, styles["Title"]))
|
|
elements.append(Spacer(1, 12))
|
|
|
|
views_count = sum(event["views_count"] for event in report_data)
|
|
favorites_count = sum(event["favorites_count"] for event in report_data)
|
|
social_media_shares = sum(event["social_media_shares"] for event in report_data)
|
|
|
|
elements.append(Paragraph(f"Number of Event Views - {views_count}", custom_style))
|
|
elements.append(Spacer(1, 12))
|
|
elements.append(
|
|
Paragraph(f"Number of Event Favorites - {favorites_count}", custom_style)
|
|
)
|
|
elements.append(Spacer(1, 12))
|
|
elements.append(
|
|
Paragraph(f"Social Media Shares - {social_media_shares}", custom_style)
|
|
)
|
|
# elements.append(PageBreak())
|
|
elements.append(Spacer(1, 60))
|
|
|
|
# Top 5 Locations and Top 5 Viewed Events
|
|
all_locations = defaultdict(int)
|
|
for event in report_data:
|
|
for location, count in event["locations"].items():
|
|
all_locations[location] += count
|
|
# top 5 events by location
|
|
top_locations = sorted(all_locations.items(), key=lambda x: x[1], reverse=True)[:5]
|
|
|
|
# top 5 events overall by views
|
|
top_events_by_views = sorted(
|
|
report_data, key=lambda x: x["views_count"], reverse=True
|
|
)[:5]
|
|
|
|
data = [
|
|
["Top 5 Locations Viewed From", "Top 5 Viewed Events"],
|
|
]
|
|
|
|
for i in range(5):
|
|
location = top_locations[i][0] if i < len(top_locations) else ""
|
|
event = (
|
|
top_events_by_views[i]["event_name"] if i < len(top_events_by_views) else ""
|
|
)
|
|
data.append([location, event])
|
|
|
|
table = Table(data, colWidths=[200, 200])
|
|
style = TableStyle(
|
|
[
|
|
("BACKGROUND", (0, 0), (-1, 0), colors.grey),
|
|
("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),
|
|
("ALIGN", (0, 0), (-1, -1), "CENTER"),
|
|
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
|
|
("BOTTOMPADDING", (0, 0), (-1, 0), 12),
|
|
("BACKGROUND", (0, 1), (-1, -1), colors.beige),
|
|
("GRID", (0, 0), (-1, -1), 1, colors.black),
|
|
]
|
|
)
|
|
table.setStyle(style)
|
|
|
|
elements.append(table)
|
|
elements.append(PageBreak())
|
|
|
|
# Detailed Review of Each Event
|
|
for event in report_data:
|
|
elements.append(
|
|
Paragraph(f"Event Name - {event['event_name']}", styles["Heading1"])
|
|
)
|
|
elements.append(Spacer(1, 12))
|
|
elements.append(Paragraph(f"Event Type - {event['event_type']}", custom_style))
|
|
elements.append(Paragraph(f"Event Date - {event['event_date']}", custom_style))
|
|
|
|
views = f"Number of Views - {event['views_count']}"
|
|
favorites = f"Favorites Count - {event['favorites_count']}"
|
|
interested = f"Interested in Going - {event['interested_count']}"
|
|
going = f"Going - {event['going_count']}"
|
|
reviews = f"Reviews - {event['reviews_count']}"
|
|
shares = f"Social Media Shares - {event['social_media_shares']}"
|
|
|
|
elements.append(Paragraph(views, custom_style))
|
|
elements.append(Paragraph(shares, custom_style))
|
|
elements.append(Paragraph(favorites, custom_style))
|
|
elements.append(Paragraph(interested, custom_style))
|
|
elements.append(Paragraph(going, custom_style))
|
|
elements.append(Paragraph(reviews, custom_style))
|
|
elements.append(Spacer(1, 48))
|
|
|
|
pie_data = [
|
|
event["views_count"],
|
|
event["social_media_shares"],
|
|
event["favorites_count"],
|
|
event["interested_count"],
|
|
event["going_count"],
|
|
]
|
|
pie_labels = ["Views", "Shares", "Favorites", "Interested", "Going"]
|
|
|
|
drawing = Drawing(300, 200)
|
|
pie = Pie()
|
|
pie.data = pie_data
|
|
pie.labels = pie_labels
|
|
pie.width = 150
|
|
pie.height = 150
|
|
pie.x = 75
|
|
pie.y = 25
|
|
drawing.add(pie)
|
|
elements.append(drawing)
|
|
elements.append(PageBreak())
|
|
pdf.build(elements, onFirstPage=add_page_number, onLaterPages=add_page_number)
|
|
buffer.seek(0)
|
|
pdf_data = buffer.read()
|
|
buffer.close()
|
|
return pdf_data, filename
|