membershipworks: Use django-tables2 for event reports

This commit is contained in:
Adam Goldsmith 2024-01-22 12:33:34 -05:00
parent 1f3cd94601
commit 97e9a3c9d5
4 changed files with 88 additions and 105 deletions

View File

@ -1,40 +1,9 @@
{% extends "base.dj.html" %}
{% load membershipworks_tags %}
{% load render_table from django_tables2 %}
{% block title %}Event Report Index{% endblock %}
{% block breadcrumbs %}<li class="breadcrumb-item active" aria-current="page">MW Event Reports</li>{% endblock %}
{% block content %}
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="column">Month</th>
<th scope="column">Events</th>
<th scope="column">Canceled Events</th>
<th scope="column">Tickets</th>
<th scope="column">Unique Instructors</th>
<th scope="column">Meetings</th>
<th scope="column">Total Hours</th>
<th scope="column">Total Person Hours</th>
</tr>
</thead>
<tbody>
{% for year in object_list %}
<tr>
<td>
<a href="{% url 'membershipworks:event-year-report' year.year|date:"Y" %}">{{ year.year|date:"Y" }}</a>
</td>
<td>{{ year.event_count }}</td>
<td>{{ year.canceled_event_count }}</td>
<td>{{ year.count__sum }}</td>
<td>{{ year.instructor__count }}</td>
<td>{{ year.meeting_times__count__sum }}</td>
<td>{{ year.duration__sum|duration_as_hours|floatformat:-2 }}</td>
<td>{{ year.person_hours__sum|duration_as_hours|floatformat:-2 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% render_table table %}
{% endblock %}

View File

@ -1,6 +1,6 @@
{% extends "base.dj.html" %}
{% load membershipworks_tags %}
{% load render_table from django_tables2 %}
{% block title %}Event Report {{ month|date:"N Y" }}{% endblock %}
{% block breadcrumbs %}
@ -13,40 +13,7 @@
<li class="breadcrumb-item active" aria-current="page">{{ month|date:"F" }}</li>
{% endblock %}
{% block content %}
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="column">Title</th>
<th scope="column">Date</th>
<th scope="column">Instructor</th>
<th scope="column">Category</th>
<th scope="column">Ticket Count</th>
<th scope="column">Ticket Cap</th>
<th scope="column">Meetings</th>
<th scope="column">Total Duration</th>
<th scope="column">Person Hours</th>
</tr>
</thead>
<tbody>
{% for event in object_list %}
<tr {% if not event.occurred %}class="text-decoration-line-through table-danger"{% endif %}>
<td>
<a href="https://membershipworks.com/admin/#!event/admin/{{ event.url }}">{{ event.title }}</a>
</td>
<td>{{ event.start|date }}</td>
<td>{{ event.instructor }}</td>
<td>{{ event.category }}</td>
<td>{{ event.count }}</td>
<td>{{ event.cap }}</td>
<td>{{ event.meeting_times__count }}</td>
<td>{{ event.duration|duration_as_hours|floatformat:-2 }}</td>
<td>{{ event.person_hours|duration_as_hours|floatformat:-2 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% render_table table %}
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if previous_month %}

View File

@ -1,6 +1,6 @@
{% extends "base.dj.html" %}
{% load membershipworks_tags %}
{% load render_table from django_tables2 %}
{% block title %}Event Report {{ year|date:"Y" }}{% endblock %}
{% block breadcrumbs %}
@ -10,38 +10,7 @@
<li class="breadcrumb-item active" aria-current="page">{{ year|date:"Y" }}</li>
{% endblock %}
{% block content %}
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="column">Month</th>
<th scope="column">Events</th>
<th scope="column">Canceled Events</th>
<th scope="column">Tickets</th>
<th scope="column">Unique Instructors</th>
<th scope="column">Meetings</th>
<th scope="column">Total Hours</th>
<th scope="column">Total Person Hours</th>
</tr>
</thead>
<tbody>
{% for month in object_list %}
<tr>
<td>
<a href="{% url 'membershipworks:event-month-report' month.month|date:"Y" month.month|date:"m" %}">{{ month.month|date:"F Y" }}</a>
</td>
<td>{{ month.event_count }}</td>
<td>{{ month.canceled_event_count }}</td>
<td>{{ month.count__sum }}</td>
<td>{{ month.instructor__count }}</td>
<td>{{ month.meeting_times__count__sum }}</td>
<td>{{ month.duration__sum|duration_as_hours|floatformat:-2 }}</td>
<td>{{ month.person_hours__sum|duration_as_hours|floatformat:-2 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% render_table table %}
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if previous_year %}

View File

@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timedelta
from django.conf import settings
from django.contrib import messages
@ -6,13 +6,16 @@ from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.db.models.functions import TruncMonth, TruncYear
from django.shortcuts import render
from django.template.defaultfilters import floatformat
from django.views.generic.dates import (
ArchiveIndexView,
MonthArchiveView,
YearArchiveView,
)
import django_tables2 as tables
from dal import autocomplete
from django_tables2 import A, SingleTableMixin
from membershipworks.membershipworks_api import MembershipWorks
@ -109,12 +112,72 @@ def upcoming_events(request):
return render(request, "membershipworks/upcoming_events.dj.html", context)
class EventIndexReport(PermissionRequiredMixin, ArchiveIndexView):
class DurationColumn(tables.Column):
def render(self, value: timedelta):
if value is None:
return None
return floatformat(value.total_seconds() / 60 / 60, -2)
class EventTable(tables.Table):
title = tables.Column(
linkify=lambda record: f"https://membershipworks.com/admin/#!event/admin/{record.url}"
)
start = tables.DateColumn("N d, Y")
duration = DurationColumn()
person_hours = DurationColumn()
meeting_times__count = tables.Column("Meetings")
class Meta:
model = EventExt
fields = (
"title",
"start",
"instructor",
"category",
"count",
"cap",
"meeting_times__count",
"duration",
"person_hours",
)
row_attrs = {
"class": lambda record: (
"" if record.occurred else "text-decoration-line-through table-danger"
)
}
class EventSummaryTable(tables.Table):
event_count = tables.Column("Events")
canceled_event_count = tables.Column("Canceled Events")
count__sum = tables.Column("Tickets")
instructor__count = tables.Column("Unique Instructors")
meeting_times__count__sum = tables.Column("Meetings")
duration__sum = DurationColumn("Class Hours")
person_hours__sum = DurationColumn("Person Hours")
class EventIndexReport(SingleTableMixin, PermissionRequiredMixin, ArchiveIndexView):
permission_required = "membershipworks.view_eventext"
queryset = EventExt.objects.all()
date_field = "start"
template_name = "membershipworks/event_index_report.dj.html"
make_object_list = True
table_class = EventSummaryTable
def get_table_kwargs(self):
year_column = tables.DateColumn(
"Y",
linkify=(
"membershipworks:event-year-report",
[A("year__year")],
),
)
return {
"sequence": ("year", "..."),
"extra_columns": (("year", year_column),),
}
def get_dated_queryset(self, **lookup):
return (
@ -126,12 +189,26 @@ class EventIndexReport(PermissionRequiredMixin, ArchiveIndexView):
)
class EventYearReport(PermissionRequiredMixin, YearArchiveView):
class EventYearReport(SingleTableMixin, PermissionRequiredMixin, YearArchiveView):
permission_required = "membershipworks.view_eventext"
queryset = EventExt.objects.all()
date_field = "start"
template_name = "membershipworks/event_year_report.dj.html"
make_object_list = True
table_class = EventSummaryTable
def get_table_kwargs(self):
month_column = tables.DateColumn(
"F Y",
linkify=(
"membershipworks:event-month-report",
[A("month__year"), A("month__month")],
),
)
return {
"sequence": ("month", "..."),
"extra_columns": (("month", month_column),),
}
def get_dated_queryset(self, **lookup):
return (
@ -143,8 +220,9 @@ class EventYearReport(PermissionRequiredMixin, YearArchiveView):
)
class EventMonthReport(PermissionRequiredMixin, MonthArchiveView):
class EventMonthReport(SingleTableMixin, PermissionRequiredMixin, MonthArchiveView):
permission_required = "membershipworks.view_eventext"
queryset = EventExt.objects.select_related("category", "instructor").all()
date_field = "start"
template_name = "membershipworks/event_month_report.dj.html"
table_class = EventTable