membershipworks: Add Missing Paperwork report

This commit is contained in:
Adam Goldsmith 2024-02-16 11:37:30 -05:00
parent f9fdd7d549
commit d59318e2a5
4 changed files with 82 additions and 17 deletions

View File

@ -25,6 +25,11 @@ class MembershipworksDashboardFragment(dashboard.LinksCardDashboardFragment):
reverse("membershipworks:event-attendees"), reverse("membershipworks:event-attendees"),
permission="membershipworks.view_event", permission="membershipworks.view_event",
), ),
Link(
"Missing Paperwork",
reverse("membershipworks:missing-paperwork-report"),
permission="membershipworks.view_member",
),
] ]
@property @property

View File

@ -0,0 +1,12 @@
{% extends "base.dj.html" %}
{% load render_table from django_tables2 %}
{% block title %}Missing Paperwork Report{% endblock %}
{% block admin_link %}
{% url 'admin:membershipworks_member_changelist' %}
{% endblock %}
{% block content %}
{% include "cmsmanage/components/download_table.dj.html" %}
{% render_table table %}
{% endblock %}

View File

@ -1,51 +1,48 @@
from django.urls import path from django.urls import path
from .views import ( from . import views
EventAttendeeListView,
EventIndexReport,
EventInvoiceView,
EventMonthReport,
EventYearReport,
MemberAutocomplete,
upcoming_events,
)
app_name = "membershipworks" app_name = "membershipworks"
urlpatterns = [ urlpatterns = [
path( path(
"member-autocomplete/", "member-autocomplete/",
MemberAutocomplete.as_view(), views.MemberAutocomplete.as_view(),
name="member-autocomplete", name="member-autocomplete",
), ),
path( path(
"upcoming-events/", "upcoming-events/",
upcoming_events, views.upcoming_events,
name="upcoming-events", name="upcoming-events",
), ),
path( path(
"event-report/", "event-report/",
EventIndexReport.as_view(), views.EventIndexReport.as_view(),
name="event-index-report", name="event-index-report",
), ),
path( path(
"event-report/<int:year>/", "event-report/<int:year>/",
EventYearReport.as_view(), views.EventYearReport.as_view(),
name="event-year-report", name="event-year-report",
), ),
path( path(
"event-report/<int:year>/<int:month>/", "event-report/<int:year>/<int:month>/",
EventMonthReport.as_view(month_format="%m"), views.EventMonthReport.as_view(month_format="%m"),
name="event-month-report", name="event-month-report",
), ),
path( path(
"event-invoice/<eid>", "event-invoice/<eid>",
EventInvoiceView.as_view(), views.EventInvoiceView.as_view(),
name="event-invoice", name="event-invoice",
), ),
path( path(
"event-attendees", "event-attendees",
EventAttendeeListView.as_view(), views.EventAttendeeListView.as_view(),
name="event-attendees", name="event-attendees",
), ),
path(
"missing-paperwork",
views.MissingPaperworkReport.as_view(),
name="missing-paperwork-report",
),
] ]

View File

@ -4,7 +4,7 @@ from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import permission_required 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 import Subquery from django.db.models import OuterRef, Q, Subquery
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.template.defaultfilters import floatformat
@ -19,6 +19,7 @@ import django_filters
import django_tables2 as tables import django_tables2 as tables
from dal import autocomplete from dal import autocomplete
from django_filters.views import BaseFilterView from django_filters.views import BaseFilterView
from django_mysql.models import GroupConcat
from django_tables2 import A, SingleTableMixin from django_tables2 import A, SingleTableMixin
from django_tables2.export.views import ExportMixin from django_tables2.export.views import ExportMixin
@ -365,3 +366,53 @@ class EventAttendeeListView(
def get_table_data(self): def get_table_data(self):
return super().get_table_data().values("name", "email").distinct() return super().get_table_data().values("name", "email").distinct()
class MissingPaperworkTable(tables.Table):
policy_agreement = tables.BooleanColumn()
authorize_charge = tables.BooleanColumn()
class Meta:
model = Member
fields = [
"first_name",
"last_name",
"membership",
"billing_method",
"join_date",
"membership_agreement_signed_and_on_file_date",
"waiver_form_signed_and_on_file_date",
"policy_agreement",
"authorize_charge",
]
class MissingPaperworkReport(
ExportMixin,
SingleTableMixin,
PermissionRequiredMixin,
ListView,
):
model = Member
permission_required = "membershipworks.view_member"
template_name = "membershipworks/missing_paperwork_report.dj.html"
table_class = MissingPaperworkTable
export_formats = ("csv", "xlsx", "ods")
def get_queryset(self):
qs = super().get_queryset()
return (
qs.with_is_active()
.filter(
Q(membership_agreement_signed_and_on_file_date__isnull=True)
| Q(waiver_form_signed_and_on_file_date__isnull=True),
is_active=True,
)
.annotate(
membership=Subquery(
qs.filter(
pk=OuterRef("pk"), flags__type__in=("level", "addon")
).values(m=GroupConcat("flags__name"))
),
)
)