Add a dues-invoicing feature: send, track and remind on membership fees

New DuesInvoice model (one per membership, resendable) plus
club.services.invoicing: resolves the best email to invoice (the
member's own, else a parent/guardian's), snapshots the outstanding
balance and a due date on send, and mails a branded HTML invoice
(same club-colour email shell as the parent-claim email) with a
WeasyPrint PDF attached when the native libs are available.

Dues & billing gains a bulk "Send invoice" action (checkbox selection
+ a shared due-in-days prompt), a per-row invoice status column, a
staff-facing invoice detail/PDF page, and a push-button "Send
reminders" action for every sent, unpaid invoice past its own due
date.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
2026-08-20 21:23:06 +02:00
parent 44ddf7b6eb
commit 94d6cbd4e9
19 changed files with 1334 additions and 8 deletions

View File

@@ -1,7 +1,7 @@
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from .models import Club, ClubMembership, ClubRole, FeePayment, MemberRequirementStatus, OnboardingRequirement, Season, Sponsor
from .models import Club, ClubMembership, ClubRole, DuesInvoice, FeePayment, MemberRequirementStatus, OnboardingRequirement, Season, Sponsor
@admin.register(Club)
@@ -57,6 +57,15 @@ class FeePaymentAdmin(admin.ModelAdmin):
search_fields = ["membership__club__name", "membership__member__last_name", "reference"]
@admin.register(DuesInvoice)
class DuesInvoiceAdmin(admin.ModelAdmin):
list_display = ["number", "membership", "amount", "due_date", "sent_at", "reminder_count"]
list_filter = ["club"]
search_fields = ["number", "membership__member__last_name", "membership__member__first_name"]
raw_id_fields = ["membership"]
readonly_fields = ["number"]
@admin.register(ClubRole)
class ClubRoleAdmin(admin.ModelAdmin):
list_display = ["club__name", "member__last_name", "member__first_name", "role"]