Billing Development Notes
Models
EventInvoice: FK to events.EventAttendees, stores invoice/reference numbers, invoice/due dates, amount, and currency.
EventBillingConfiguration: one-to-one with events.Event, specifying due date, integration type (BillingIntegrations enum), base price(s), and optional price_selector pointing at a registration field name.
Flow (billing/handlers.py)
events.views.EventDetailView.form_valid() calls billing.handlers.handle_event_billing() when the event_billing experimental feature is enabled.
handle_event_billing fetches the billing configuration for the event (parent fallback) and resolves the integration provider.
- For invoice integration:
- Generates a random invoice number (
generate_invoice_number) and a checksum-protected reference number.
- Computes the amount via
get_selection_price()—either a fixed float or matched to a registration answer by name.
- Creates the
EventInvoice row (with retry recursion on failure).
- Sends an invoice email using
billing/util.send_event_invoice().
- If the price resolves to
0, it sends a free-event confirmation email instead.
Utility Functions
generate_reference_number() implements the 7-3-1 checksum common in Finnish reference numbers.
get_selection_price() reads EventRegistrationForm.choice_list to map answers to prices; mismatches raise ValueError.
- Email templates live in
templates/billing/. Context merges BILLING_CONTEXT and CONTENT_VARIABLES from settings.
Admin
EventBillingConfigurationAdmin adds a custom URL (/ref_numbers/) to export invoice data as CSV. ref_export renders a button on each row, the changelist links to the configured event plus that event’s generated invoices, and an All invoices tool link exposes the full invoice audit list without making invoices a separate sidebar entry.
EventInvoiceAdmin shows the related event as a link, supports event/currency filters, and uses attendee/event select_related for the list.
Extending
- Support additional integrations (e.g., Stripe) by adding new members to
BillingIntegrations and branching in handle_event_billing.
- Persist audit logs (sent emails, retries) to help finance teams troubleshoot.
- Add constraints to prevent deleting an
EventAttendees row that already has invoices unless cascading deletes are expected.