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=( '{{ value }} ' ' ' ' ' ), 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( '{}