Split tables out of view
modules into tables
This commit is contained in:
parent
0ce441336f
commit
029b4dff28
63
doorcontrol/tables.py
Normal file
63
doorcontrol/tables.py
Normal file
@ -0,0 +1,63 @@
|
||||
import calendar
|
||||
|
||||
import django_tables2 as tables
|
||||
|
||||
from .models import HIDEvent
|
||||
|
||||
|
||||
class UnitTimeTable(tables.Table):
|
||||
members = tables.columns.Column()
|
||||
members_delta = tables.columns.TemplateColumn(
|
||||
"{{ value|floatformat:2}}%", verbose_name="Δ Members"
|
||||
)
|
||||
access_count = tables.columns.Column()
|
||||
access_count_delta = tables.columns.TemplateColumn(
|
||||
"{{ value|floatformat:2}}%", verbose_name="Δ Access Count"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
fields = ("members", "members_delta", "access_count", "access_count_delta")
|
||||
|
||||
|
||||
class DeniedAccessTable(tables.Table):
|
||||
name = tables.TemplateColumn(
|
||||
"{{ record.forename|default:'' }} {{ record.surname|default:'' }}"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = HIDEvent
|
||||
|
||||
fields = (
|
||||
"timestamp",
|
||||
"door",
|
||||
"event_type",
|
||||
"name",
|
||||
"raw_card_number",
|
||||
"decoded_card_number",
|
||||
)
|
||||
|
||||
|
||||
class MostActiveMembersTable(tables.Table):
|
||||
name = tables.Column()
|
||||
access_count = tables.Column()
|
||||
|
||||
|
||||
class DetailByDayTable(tables.Table):
|
||||
timestamp__date = tables.DateColumn(verbose_name="Date")
|
||||
name = tables.Column()
|
||||
access_count = tables.Column()
|
||||
|
||||
|
||||
class BusiestDayOfWeekTable(tables.Table):
|
||||
timestamp__week_day = tables.Column("Week Day")
|
||||
events = tables.Column()
|
||||
members = tables.Column()
|
||||
|
||||
def render_timestamp__week_day(self, value):
|
||||
return calendar.day_name[(value - 2) % 7]
|
||||
|
||||
|
||||
class BusiestTimeOfDayTable(tables.Table):
|
||||
timestamp__hour = tables.TemplateColumn("{{ value }}:00", verbose_name="Hour")
|
||||
events = tables.Column()
|
||||
members = tables.Column()
|
@ -1,4 +1,3 @@
|
||||
import calendar
|
||||
import datetime
|
||||
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
@ -19,6 +18,14 @@ from django_tables2 import SingleTableMixin
|
||||
from django_tables2.export.views import ExportMixin
|
||||
|
||||
from .models import Door, HIDEvent
|
||||
from .tables import (
|
||||
BusiestDayOfWeekTable,
|
||||
BusiestTimeOfDayTable,
|
||||
DeniedAccessTable,
|
||||
DetailByDayTable,
|
||||
MostActiveMembersTable,
|
||||
UnitTimeTable,
|
||||
)
|
||||
|
||||
REPORTS = []
|
||||
|
||||
@ -96,20 +103,6 @@ class BaseAccessReport(
|
||||
return context
|
||||
|
||||
|
||||
class UnitTimeTable(tables.Table):
|
||||
members = tables.columns.Column()
|
||||
members_delta = tables.columns.TemplateColumn(
|
||||
"{{ value|floatformat:2}}%", verbose_name="Δ Members"
|
||||
)
|
||||
access_count = tables.columns.Column()
|
||||
access_count_delta = tables.columns.TemplateColumn(
|
||||
"{{ value|floatformat:2}}%", verbose_name="Δ Access Count"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
fields = ("members", "members_delta", "access_count", "access_count_delta")
|
||||
|
||||
|
||||
@register_report
|
||||
class AccessPerUnitTime(BaseAccessReport):
|
||||
table_class = UnitTimeTable
|
||||
@ -209,24 +202,6 @@ class AccessPerUnitTime(BaseAccessReport):
|
||||
)
|
||||
|
||||
|
||||
class DeniedAccessTable(tables.Table):
|
||||
name = tables.TemplateColumn(
|
||||
"{{ record.forename|default:'' }} {{ record.surname|default:'' }}"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = HIDEvent
|
||||
|
||||
fields = (
|
||||
"timestamp",
|
||||
"door",
|
||||
"event_type",
|
||||
"name",
|
||||
"raw_card_number",
|
||||
"decoded_card_number",
|
||||
)
|
||||
|
||||
|
||||
@register_report
|
||||
class DeniedAccess(BaseAccessReport):
|
||||
_report_name = "Denied Access"
|
||||
@ -244,11 +219,6 @@ class DeniedAccess(BaseAccessReport):
|
||||
)
|
||||
|
||||
|
||||
class MostActiveMembersTable(tables.Table):
|
||||
name = tables.Column()
|
||||
access_count = tables.Column()
|
||||
|
||||
|
||||
@register_report
|
||||
class MostActiveMembers(BaseAccessReport):
|
||||
_report_name = "Most Active Members"
|
||||
@ -271,12 +241,6 @@ class MostActiveMembers(BaseAccessReport):
|
||||
)
|
||||
|
||||
|
||||
class DetailByDayTable(tables.Table):
|
||||
timestamp__date = tables.DateColumn(verbose_name="Date")
|
||||
name = tables.Column()
|
||||
access_count = tables.Column()
|
||||
|
||||
|
||||
@register_report
|
||||
class DetailByDay(BaseAccessReport):
|
||||
_report_name = "Detail by Day"
|
||||
@ -299,15 +263,6 @@ class DetailByDay(BaseAccessReport):
|
||||
)
|
||||
|
||||
|
||||
class BusiestDayOfWeekTable(tables.Table):
|
||||
timestamp__week_day = tables.Column("Week Day")
|
||||
events = tables.Column()
|
||||
members = tables.Column()
|
||||
|
||||
def render_timestamp__week_day(self, value):
|
||||
return calendar.day_name[(value - 2) % 7]
|
||||
|
||||
|
||||
@register_report
|
||||
class BusiestDayOfWeek(BaseAccessReport):
|
||||
_report_name = "Busiest Day of the Week"
|
||||
@ -326,12 +281,6 @@ class BusiestDayOfWeek(BaseAccessReport):
|
||||
)
|
||||
|
||||
|
||||
class BusiestTimeOfDayTable(tables.Table):
|
||||
timestamp__hour = tables.TemplateColumn("{{ value }}:00", verbose_name="Hour")
|
||||
events = tables.Column()
|
||||
members = tables.Column()
|
||||
|
||||
|
||||
@register_report
|
||||
class BusiestTimeOfDay(BaseAccessReport):
|
||||
_report_name = "Busiest Time of Day"
|
||||
|
168
membershipworks/tables.py
Normal file
168
membershipworks/tables.py
Normal file
@ -0,0 +1,168 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from django.template.defaultfilters import floatformat
|
||||
from django.utils.html import format_html
|
||||
from django.utils.safestring import SafeString
|
||||
|
||||
import django_tables2 as tables
|
||||
|
||||
from .models import EventAttendee, EventExt, Member
|
||||
|
||||
|
||||
class DurationColumn(tables.Column):
|
||||
def render(self, value: timedelta):
|
||||
if value is None:
|
||||
return None
|
||||
return floatformat(value.total_seconds() / 60 / 60, -2)
|
||||
|
||||
def value(self, value: timedelta):
|
||||
if value is None:
|
||||
return None
|
||||
return value.total_seconds() / 60 / 60
|
||||
|
||||
|
||||
class EventTable(tables.Table):
|
||||
title = tables.TemplateColumn(
|
||||
template_code=(
|
||||
'<a title="MembershipWorks" href="https://membershipworks.com/admin/#!event/admin/{{ record.url }}">{{ value }}</a> '
|
||||
'<a title="Admin" href="{% url "admin:membershipworks_eventext_change" record.pk %}"><i class="bi bi-pencil-square"></i></a> '
|
||||
'<a title="Details" href="{% url "membershipworks:event-detail" record.pk %}"><i class="bi bi-receipt"></i></a> '
|
||||
),
|
||||
accessor="unescaped_title",
|
||||
)
|
||||
occurred = tables.BooleanColumn(visible=False)
|
||||
start = tables.DateColumn("N d, Y")
|
||||
duration = DurationColumn()
|
||||
person_hours = DurationColumn()
|
||||
meetings = tables.Column()
|
||||
gross_revenue = tables.Column()
|
||||
total_due_to_instructor = tables.Column()
|
||||
net_revenue = tables.Column()
|
||||
invoice__date_submitted = tables.DateColumn(verbose_name="Invoice Submitted")
|
||||
invoice__date_paid = tables.DateColumn(verbose_name="Invoice Paid")
|
||||
|
||||
class Meta:
|
||||
model = EventExt
|
||||
fields = (
|
||||
"title",
|
||||
"occurred",
|
||||
"start",
|
||||
"instructor",
|
||||
"category",
|
||||
"count",
|
||||
"cap",
|
||||
"meetings",
|
||||
"duration",
|
||||
"person_hours",
|
||||
"gross_revenue",
|
||||
"total_due_to_instructor",
|
||||
"net_revenue",
|
||||
)
|
||||
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")
|
||||
meetings__sum = tables.Column("Meetings")
|
||||
duration__sum = DurationColumn("Class Hours")
|
||||
person_hours__sum = DurationColumn("Person Hours")
|
||||
gross_revenue__sum = tables.Column("Gross Revenue")
|
||||
total_due_to_instructor__sum = tables.Column("Total Due to Instructor")
|
||||
net_revenue__sum = tables.Column("Net Revenue")
|
||||
|
||||
|
||||
class UserEventTable(EventTable):
|
||||
title = tables.Column(linkify=True, accessor="unescaped_title")
|
||||
instructor = None
|
||||
person_hours = None
|
||||
gross_revenue = None
|
||||
net_revenue = None
|
||||
|
||||
|
||||
class InvoiceMoneyColumn(tables.columns.Column):
|
||||
def render(self, value):
|
||||
return f"${super().render(value):.2f}"
|
||||
|
||||
|
||||
class InvoiceMoneyFooterColumn(InvoiceMoneyColumn):
|
||||
def render_footer(self, bound_column, table):
|
||||
value = getattr(table.event, bound_column.accessor)
|
||||
if value is not None:
|
||||
return f"${value:.2f}"
|
||||
else:
|
||||
return bound_column.default
|
||||
|
||||
|
||||
class InvoiceTable(tables.Table):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.event = kwargs.pop("event")
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def _math_header(name: str, formula: str) -> SafeString:
|
||||
return format_html(
|
||||
'{} <div class="text-nowrap font-monospace fw-light">[{}]</div>',
|
||||
name,
|
||||
formula,
|
||||
)
|
||||
|
||||
label = tables.Column("Ticket Type", footer="Subtotals")
|
||||
list_price = InvoiceMoneyColumn("Ticket Price")
|
||||
actual_price = InvoiceMoneyColumn(_math_header("Actual Price", "P"))
|
||||
quantity = tables.Column(
|
||||
_math_header("Quantity", "Q"),
|
||||
footer=lambda table: table.event.quantity,
|
||||
)
|
||||
amount = InvoiceMoneyFooterColumn(_math_header("Amount", "A=P*Q"))
|
||||
materials = InvoiceMoneyFooterColumn(
|
||||
_math_header("CMS Collected Materials Fee", "M=m*Q")
|
||||
)
|
||||
amount_without_materials = InvoiceMoneyFooterColumn(
|
||||
_math_header("Event Revenue Base", "B=A-M")
|
||||
)
|
||||
instructor_revenue = InvoiceMoneyFooterColumn(
|
||||
_math_header("Instructor Percentage Revenue", "R=B*I")
|
||||
)
|
||||
instructor_amount = InvoiceMoneyFooterColumn(
|
||||
_math_header("Amount Due to Instructor", "R+M")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
attrs = {
|
||||
"class": "table table-sm mx-auto w-auto",
|
||||
"tbody": {"class": "table-group-divider"},
|
||||
"tfoot": {"class": "table-group-divider"},
|
||||
}
|
||||
orderable = False
|
||||
|
||||
|
||||
class EventAttendeeTable(tables.Table):
|
||||
class Meta:
|
||||
model = EventAttendee
|
||||
fields = ("name", "email")
|
||||
|
||||
|
||||
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",
|
||||
]
|
@ -1,5 +1,5 @@
|
||||
import uuid
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from django.conf import settings
|
||||
@ -15,12 +15,9 @@ from django.db.models import OuterRef, Q, Subquery
|
||||
from django.db.models.functions import TruncMonth, TruncYear
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.template.defaultfilters import floatformat
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils import timezone
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import format_html
|
||||
from django.utils.safestring import SafeString
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.views.generic.dates import (
|
||||
ArchiveIndexView,
|
||||
@ -46,6 +43,14 @@ from membershipworks.membershipworks_api import MembershipWorks
|
||||
from .forms import EventInvoiceForm
|
||||
from .invoice_email import make_invoice_emails
|
||||
from .models import EventAttendee, EventExt, EventInvoice, Member
|
||||
from .tables import (
|
||||
EventAttendeeTable,
|
||||
EventSummaryTable,
|
||||
EventTable,
|
||||
InvoiceTable,
|
||||
MissingPaperworkTable,
|
||||
UserEventTable,
|
||||
)
|
||||
|
||||
|
||||
class MemberAutocomplete(autocomplete.Select2QuerySetView):
|
||||
@ -138,75 +143,6 @@ def upcoming_events(request):
|
||||
return render(request, "membershipworks/upcoming_events.dj.html", context)
|
||||
|
||||
|
||||
class DurationColumn(tables.Column):
|
||||
def render(self, value: timedelta):
|
||||
if value is None:
|
||||
return None
|
||||
return floatformat(value.total_seconds() / 60 / 60, -2)
|
||||
|
||||
def value(self, value: timedelta):
|
||||
if value is None:
|
||||
return None
|
||||
return value.total_seconds() / 60 / 60
|
||||
|
||||
|
||||
class EventTable(tables.Table):
|
||||
title = tables.TemplateColumn(
|
||||
template_code=(
|
||||
'<a title="MembershipWorks" href="https://membershipworks.com/admin/#!event/admin/{{ record.url }}">{{ value }}</a> '
|
||||
'<a title="Admin" href="{% url "admin:membershipworks_eventext_change" record.pk %}"><i class="bi bi-pencil-square"></i></a> '
|
||||
'<a title="Details" href="{% url "membershipworks:event-detail" record.pk %}"><i class="bi bi-receipt"></i></a> '
|
||||
),
|
||||
accessor="unescaped_title",
|
||||
)
|
||||
occurred = tables.BooleanColumn(visible=False)
|
||||
start = tables.DateColumn("N d, Y")
|
||||
duration = DurationColumn()
|
||||
person_hours = DurationColumn()
|
||||
meetings = tables.Column()
|
||||
gross_revenue = tables.Column()
|
||||
total_due_to_instructor = tables.Column()
|
||||
net_revenue = tables.Column()
|
||||
invoice__date_submitted = tables.DateColumn(verbose_name="Invoice Submitted")
|
||||
invoice__date_paid = tables.DateColumn(verbose_name="Invoice Paid")
|
||||
|
||||
class Meta:
|
||||
model = EventExt
|
||||
fields = (
|
||||
"title",
|
||||
"occurred",
|
||||
"start",
|
||||
"instructor",
|
||||
"category",
|
||||
"count",
|
||||
"cap",
|
||||
"meetings",
|
||||
"duration",
|
||||
"person_hours",
|
||||
"gross_revenue",
|
||||
"total_due_to_instructor",
|
||||
"net_revenue",
|
||||
)
|
||||
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")
|
||||
meetings__sum = tables.Column("Meetings")
|
||||
duration__sum = DurationColumn("Class Hours")
|
||||
person_hours__sum = DurationColumn("Person Hours")
|
||||
gross_revenue__sum = tables.Column("Gross Revenue")
|
||||
total_due_to_instructor__sum = tables.Column("Total Due to Instructor")
|
||||
net_revenue__sum = tables.Column("Net Revenue")
|
||||
|
||||
|
||||
class EventIndexReport(
|
||||
ExportMixin, SingleTableMixin, PermissionRequiredMixin, ArchiveIndexView
|
||||
):
|
||||
@ -303,14 +239,6 @@ class EventMonthReport(
|
||||
return f"mw_events_{self.get_year()}-{self.get_month():02}.{export_format}"
|
||||
|
||||
|
||||
class UserEventTable(EventTable):
|
||||
title = tables.Column(linkify=True, accessor="unescaped_title")
|
||||
instructor = None
|
||||
person_hours = None
|
||||
gross_revenue = None
|
||||
net_revenue = None
|
||||
|
||||
|
||||
class UserEventView(SingleTableMixin, ListView):
|
||||
model = EventExt
|
||||
table_class = UserEventTable
|
||||
@ -339,63 +267,6 @@ class UserEventView(SingleTableMixin, ListView):
|
||||
return f"my_events_{self.member.uid if self.member is not None else 'no-uid'}.{export_format}"
|
||||
|
||||
|
||||
class InvoiceMoneyColumn(tables.columns.Column):
|
||||
def render(self, value):
|
||||
return f"${super().render(value):.2f}"
|
||||
|
||||
|
||||
class InvoiceMoneyFooterColumn(InvoiceMoneyColumn):
|
||||
def render_footer(self, bound_column, table):
|
||||
value = getattr(table.event, bound_column.accessor)
|
||||
if value is not None:
|
||||
return f"${value:.2f}"
|
||||
else:
|
||||
return bound_column.default
|
||||
|
||||
|
||||
class InvoiceTable(tables.Table):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.event = kwargs.pop("event")
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def _math_header(name: str, formula: str) -> SafeString:
|
||||
return format_html(
|
||||
'{} <div class="text-nowrap font-monospace fw-light">[{}]</div>',
|
||||
name,
|
||||
formula,
|
||||
)
|
||||
|
||||
label = tables.Column("Ticket Type", footer="Subtotals")
|
||||
list_price = InvoiceMoneyColumn("Ticket Price")
|
||||
actual_price = InvoiceMoneyColumn(_math_header("Actual Price", "P"))
|
||||
quantity = tables.Column(
|
||||
_math_header("Quantity", "Q"),
|
||||
footer=lambda table: table.event.quantity,
|
||||
)
|
||||
amount = InvoiceMoneyFooterColumn(_math_header("Amount", "A=P*Q"))
|
||||
materials = InvoiceMoneyFooterColumn(
|
||||
_math_header("CMS Collected Materials Fee", "M=m*Q")
|
||||
)
|
||||
amount_without_materials = InvoiceMoneyFooterColumn(
|
||||
_math_header("Event Revenue Base", "B=A-M")
|
||||
)
|
||||
instructor_revenue = InvoiceMoneyFooterColumn(
|
||||
_math_header("Instructor Percentage Revenue", "R=B*I")
|
||||
)
|
||||
instructor_amount = InvoiceMoneyFooterColumn(
|
||||
_math_header("Amount Due to Instructor", "R+M")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
attrs = {
|
||||
"class": "table table-sm mx-auto w-auto",
|
||||
"tbody": {"class": "table-group-divider"},
|
||||
"tfoot": {"class": "table-group-divider"},
|
||||
}
|
||||
orderable = False
|
||||
|
||||
|
||||
class EventDetailView(
|
||||
SingleTableMixin, FormMixin, AccessMixin, DetailView, ProcessFormView
|
||||
):
|
||||
@ -527,12 +398,6 @@ class EventInvoicePDFView(AccessMixin, BaseDetailView):
|
||||
return self.handle_no_permission()
|
||||
|
||||
|
||||
class EventAttendeeTable(tables.Table):
|
||||
class Meta:
|
||||
model = EventAttendee
|
||||
fields = ("name", "email")
|
||||
|
||||
|
||||
class EventAttendeeFilters(django_filters.FilterSet):
|
||||
new_since = django_filters.DateFilter(
|
||||
field_name="event__start", method="filter_new_since"
|
||||
@ -560,25 +425,6 @@ class EventAttendeeListView(
|
||||
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,
|
||||
|
92
paperwork/tables.py
Normal file
92
paperwork/tables.py
Normal file
@ -0,0 +1,92 @@
|
||||
import django_tables2 as tables
|
||||
|
||||
from .models import (
|
||||
InstructorOrVendor,
|
||||
Waiver,
|
||||
)
|
||||
|
||||
|
||||
class WarnEmptyColumn(tables.Column):
|
||||
attrs = {
|
||||
"td": {
|
||||
"class": lambda value, bound_column: (
|
||||
"table-danger" if value == bound_column.default else ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WaiverReportTable(tables.Table):
|
||||
emergency_contact_name = WarnEmptyColumn()
|
||||
emergency_contact_number = WarnEmptyColumn()
|
||||
|
||||
class Meta:
|
||||
model = Waiver
|
||||
fields = [
|
||||
"name",
|
||||
"date",
|
||||
"emergency_contact_name",
|
||||
"emergency_contact_number",
|
||||
"waiver_version",
|
||||
"guardian_name",
|
||||
"guardian_relation",
|
||||
"guardian_date",
|
||||
]
|
||||
|
||||
|
||||
class InstructorOrVendorTable(tables.Table):
|
||||
instructor_agreement_date = WarnEmptyColumn(
|
||||
"Instructor Agreement Date(s)", default="Missing"
|
||||
)
|
||||
w9_date = WarnEmptyColumn(default="Missing")
|
||||
|
||||
class Meta:
|
||||
model = InstructorOrVendor
|
||||
fields = [
|
||||
"name",
|
||||
"instructor_agreement_date",
|
||||
"w9_date",
|
||||
"phone",
|
||||
"email_address",
|
||||
]
|
||||
|
||||
|
||||
class ShopAccessErrorColumn(tables.Column):
|
||||
def td_class(value):
|
||||
if value.startswith("Has access but"):
|
||||
return "table-danger"
|
||||
elif value.startswith("Has cert but"):
|
||||
return "table-warning"
|
||||
else:
|
||||
return ""
|
||||
|
||||
attrs = {"td": {"class": td_class}}
|
||||
|
||||
|
||||
class AccessVerificationTable(tables.Table):
|
||||
account_name = tables.Column()
|
||||
access_card = tables.Column()
|
||||
billing_method = tables.Column()
|
||||
join_date = tables.DateColumn()
|
||||
renewal_date = tables.DateColumn()
|
||||
access_front_door = tables.BooleanColumn(verbose_name="Front Door")
|
||||
access_studio_space = tables.BooleanColumn(verbose_name="Studio Space")
|
||||
wood_shop_error = ShopAccessErrorColumn()
|
||||
metal_shop_error = ShopAccessErrorColumn()
|
||||
extended_hours_error = ShopAccessErrorColumn()
|
||||
extended_hours_shops_error = ShopAccessErrorColumn()
|
||||
storage_closet_error = ShopAccessErrorColumn()
|
||||
|
||||
|
||||
class CertifiersTable(tables.Table):
|
||||
certified_by = tables.Column()
|
||||
certification_version__definition__name = tables.Column("Certification")
|
||||
certification_version__definition__department__name = tables.Column("Department")
|
||||
number_issued_on_this_tool = tables.Column()
|
||||
last_issued_certification_date = tables.Column()
|
||||
|
||||
|
||||
class CertificationCountTable(tables.Table):
|
||||
certification_version__definition__name = tables.Column("Certification")
|
||||
certification_version__definition__department__name = tables.Column("Department")
|
||||
total_issued = tables.Column()
|
@ -19,7 +19,6 @@ from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFou
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.views.generic import ListView
|
||||
|
||||
import django_tables2 as tables
|
||||
import requests
|
||||
import weasyprint
|
||||
from django_mysql.models import GroupConcat
|
||||
@ -35,6 +34,13 @@ from .models import (
|
||||
InstructorOrVendor,
|
||||
Waiver,
|
||||
)
|
||||
from .tables import (
|
||||
AccessVerificationTable,
|
||||
CertificationCountTable,
|
||||
CertifiersTable,
|
||||
InstructorOrVendorTable,
|
||||
WaiverReportTable,
|
||||
)
|
||||
|
||||
WIKI_URL = settings.WIKI_URL
|
||||
|
||||
@ -120,34 +126,6 @@ def certification_pdf(request, cert_name):
|
||||
)
|
||||
|
||||
|
||||
class WarnEmptyColumn(tables.Column):
|
||||
attrs = {
|
||||
"td": {
|
||||
"class": lambda value, bound_column: "table-danger"
|
||||
if value == bound_column.default
|
||||
else ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WaiverReportTable(tables.Table):
|
||||
emergency_contact_name = WarnEmptyColumn()
|
||||
emergency_contact_number = WarnEmptyColumn()
|
||||
|
||||
class Meta:
|
||||
model = Waiver
|
||||
fields = [
|
||||
"name",
|
||||
"date",
|
||||
"emergency_contact_name",
|
||||
"emergency_contact_number",
|
||||
"waiver_version",
|
||||
"guardian_name",
|
||||
"guardian_relation",
|
||||
"guardian_date",
|
||||
]
|
||||
|
||||
|
||||
class WaiverReport(ExportMixin, SingleTableMixin, PermissionRequiredMixin, ListView):
|
||||
permission_required = "paperwork.view_waiver"
|
||||
template_name = "paperwork/waiver_report.dj.html"
|
||||
@ -156,23 +134,6 @@ class WaiverReport(ExportMixin, SingleTableMixin, PermissionRequiredMixin, ListV
|
||||
table_pagination = False
|
||||
|
||||
|
||||
class InstructorOrVendorTable(tables.Table):
|
||||
instructor_agreement_date = WarnEmptyColumn(
|
||||
"Instructor Agreement Date(s)", default="Missing"
|
||||
)
|
||||
w9_date = WarnEmptyColumn(default="Missing")
|
||||
|
||||
class Meta:
|
||||
model = InstructorOrVendor
|
||||
fields = [
|
||||
"name",
|
||||
"instructor_agreement_date",
|
||||
"w9_date",
|
||||
"phone",
|
||||
"email_address",
|
||||
]
|
||||
|
||||
|
||||
class InstructorOrVendorReport(
|
||||
ExportMixin,
|
||||
SingleTableMixin,
|
||||
@ -203,33 +164,6 @@ class InstructorOrVendorReport(
|
||||
)
|
||||
|
||||
|
||||
class ShopAccessErrorColumn(tables.Column):
|
||||
def td_class(value):
|
||||
if value.startswith("Has access but"):
|
||||
return "table-danger"
|
||||
elif value.startswith("Has cert but"):
|
||||
return "table-warning"
|
||||
else:
|
||||
return ""
|
||||
|
||||
attrs = {"td": {"class": td_class}}
|
||||
|
||||
|
||||
class AccessVerificationTable(tables.Table):
|
||||
account_name = tables.Column()
|
||||
access_card = tables.Column()
|
||||
billing_method = tables.Column()
|
||||
join_date = tables.DateColumn()
|
||||
renewal_date = tables.DateColumn()
|
||||
access_front_door = tables.BooleanColumn(verbose_name="Front Door")
|
||||
access_studio_space = tables.BooleanColumn(verbose_name="Studio Space")
|
||||
wood_shop_error = ShopAccessErrorColumn()
|
||||
metal_shop_error = ShopAccessErrorColumn()
|
||||
extended_hours_error = ShopAccessErrorColumn()
|
||||
extended_hours_shops_error = ShopAccessErrorColumn()
|
||||
storage_closet_error = ShopAccessErrorColumn()
|
||||
|
||||
|
||||
class AccessVerificationReport(
|
||||
ExportMixin,
|
||||
SingleTableMixin,
|
||||
@ -317,14 +251,6 @@ class AccessVerificationReport(
|
||||
return qs
|
||||
|
||||
|
||||
class CertifiersTable(tables.Table):
|
||||
certified_by = tables.Column()
|
||||
certification_version__definition__name = tables.Column("Certification")
|
||||
certification_version__definition__department__name = tables.Column("Department")
|
||||
number_issued_on_this_tool = tables.Column()
|
||||
last_issued_certification_date = tables.Column()
|
||||
|
||||
|
||||
class CertifiersReport(
|
||||
ExportMixin,
|
||||
SingleTableMixin,
|
||||
@ -356,12 +282,6 @@ class CertifiersReport(
|
||||
)
|
||||
|
||||
|
||||
class CertificationCountTable(tables.Table):
|
||||
certification_version__definition__name = tables.Column("Certification")
|
||||
certification_version__definition__department__name = tables.Column("Department")
|
||||
total_issued = tables.Column()
|
||||
|
||||
|
||||
class CertificationCountReport(
|
||||
ExportMixin,
|
||||
SingleTableMixin,
|
||||
|
Loading…
Reference in New Issue
Block a user