membershipworks: Use django-tables2 for event reports
This commit is contained in:
parent
1f3cd94601
commit
97e9a3c9d5
@ -1,40 +1,9 @@
|
|||||||
{% extends "base.dj.html" %}
|
{% extends "base.dj.html" %}
|
||||||
|
|
||||||
{% load membershipworks_tags %}
|
{% load render_table from django_tables2 %}
|
||||||
|
|
||||||
{% block title %}Event Report Index{% endblock %}
|
{% block title %}Event Report Index{% endblock %}
|
||||||
{% block breadcrumbs %}<li class="breadcrumb-item active" aria-current="page">MW Event Reports</li>{% endblock %}
|
{% block breadcrumbs %}<li class="breadcrumb-item active" aria-current="page">MW Event Reports</li>{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="table-responsive">
|
{% render_table table %}
|
||||||
<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>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{% extends "base.dj.html" %}
|
{% extends "base.dj.html" %}
|
||||||
|
|
||||||
{% load membershipworks_tags %}
|
{% load render_table from django_tables2 %}
|
||||||
|
|
||||||
{% block title %}Event Report {{ month|date:"N Y" }}{% endblock %}
|
{% block title %}Event Report {{ month|date:"N Y" }}{% endblock %}
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
@ -13,40 +13,7 @@
|
|||||||
<li class="breadcrumb-item active" aria-current="page">{{ month|date:"F" }}</li>
|
<li class="breadcrumb-item active" aria-current="page">{{ month|date:"F" }}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="table-responsive">
|
{% render_table table %}
|
||||||
<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>
|
|
||||||
<nav aria-label="Page navigation">
|
<nav aria-label="Page navigation">
|
||||||
<ul class="pagination justify-content-center">
|
<ul class="pagination justify-content-center">
|
||||||
{% if previous_month %}
|
{% if previous_month %}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{% extends "base.dj.html" %}
|
{% extends "base.dj.html" %}
|
||||||
|
|
||||||
{% load membershipworks_tags %}
|
{% load render_table from django_tables2 %}
|
||||||
|
|
||||||
{% block title %}Event Report {{ year|date:"Y" }}{% endblock %}
|
{% block title %}Event Report {{ year|date:"Y" }}{% endblock %}
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
@ -10,38 +10,7 @@
|
|||||||
<li class="breadcrumb-item active" aria-current="page">{{ year|date:"Y" }}</li>
|
<li class="breadcrumb-item active" aria-current="page">{{ year|date:"Y" }}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="table-responsive">
|
{% render_table table %}
|
||||||
<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>
|
|
||||||
<nav aria-label="Page navigation">
|
<nav aria-label="Page navigation">
|
||||||
<ul class="pagination justify-content-center">
|
<ul class="pagination justify-content-center">
|
||||||
{% if previous_year %}
|
{% if previous_year %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
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.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
from django.db.models.functions import TruncMonth, TruncYear
|
from django.db.models.functions import TruncMonth, TruncYear
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from django.template.defaultfilters import floatformat
|
||||||
from django.views.generic.dates import (
|
from django.views.generic.dates import (
|
||||||
ArchiveIndexView,
|
ArchiveIndexView,
|
||||||
MonthArchiveView,
|
MonthArchiveView,
|
||||||
YearArchiveView,
|
YearArchiveView,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import django_tables2 as tables
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
|
from django_tables2 import A, SingleTableMixin
|
||||||
|
|
||||||
from membershipworks.membershipworks_api import MembershipWorks
|
from membershipworks.membershipworks_api import MembershipWorks
|
||||||
|
|
||||||
@ -109,12 +112,72 @@ def upcoming_events(request):
|
|||||||
return render(request, "membershipworks/upcoming_events.dj.html", context)
|
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"
|
permission_required = "membershipworks.view_eventext"
|
||||||
queryset = EventExt.objects.all()
|
queryset = EventExt.objects.all()
|
||||||
date_field = "start"
|
date_field = "start"
|
||||||
template_name = "membershipworks/event_index_report.dj.html"
|
template_name = "membershipworks/event_index_report.dj.html"
|
||||||
make_object_list = True
|
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):
|
def get_dated_queryset(self, **lookup):
|
||||||
return (
|
return (
|
||||||
@ -126,12 +189,26 @@ class EventIndexReport(PermissionRequiredMixin, ArchiveIndexView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class EventYearReport(PermissionRequiredMixin, YearArchiveView):
|
class EventYearReport(SingleTableMixin, PermissionRequiredMixin, YearArchiveView):
|
||||||
permission_required = "membershipworks.view_eventext"
|
permission_required = "membershipworks.view_eventext"
|
||||||
queryset = EventExt.objects.all()
|
queryset = EventExt.objects.all()
|
||||||
date_field = "start"
|
date_field = "start"
|
||||||
template_name = "membershipworks/event_year_report.dj.html"
|
template_name = "membershipworks/event_year_report.dj.html"
|
||||||
make_object_list = True
|
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):
|
def get_dated_queryset(self, **lookup):
|
||||||
return (
|
return (
|
||||||
@ -143,8 +220,9 @@ class EventYearReport(PermissionRequiredMixin, YearArchiveView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class EventMonthReport(PermissionRequiredMixin, MonthArchiveView):
|
class EventMonthReport(SingleTableMixin, PermissionRequiredMixin, MonthArchiveView):
|
||||||
permission_required = "membershipworks.view_eventext"
|
permission_required = "membershipworks.view_eventext"
|
||||||
queryset = EventExt.objects.select_related("category", "instructor").all()
|
queryset = EventExt.objects.select_related("category", "instructor").all()
|
||||||
date_field = "start"
|
date_field = "start"
|
||||||
template_name = "membershipworks/event_month_report.dj.html"
|
template_name = "membershipworks/event_month_report.dj.html"
|
||||||
|
table_class = EventTable
|
||||||
|
Loading…
Reference in New Issue
Block a user