membershipworks: Use django-tables2 for event reports
This commit is contained in:
parent
1f3cd94601
commit
97e9a3c9d5
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user