Add referee assignment/eligibility system, team bulk-add, member Groups, and referee management dashboard with PDF export

Builds the referee workflow end to end: club-defined RefereeLevel/RefereeProfile
eligibility tied to teams, EventReferee assignment (member or external, with
fee/km payment tracking), an admin dashboard with KPI tiles, date-grouped game
tiles and range filters, and a downloadable payment form PDF modeled on the
club's existing paper document (using Club.legal_name when set). Also lands
team roster bulk-add, member mass-upload with family linking, and the
members.Group model, developed alongside this work.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-09 21:39:19 +02:00
parent 86e28c317f
commit 309bd4d83e
54 changed files with 4574 additions and 88 deletions

View File

@@ -18,17 +18,22 @@ def find_member_by_email(email):
return Member.objects.filter(user__email__iexact=email).first()
def get_or_create_login_member(email, first_name="", last_name=""):
"""Find or create the Member behind ``email``, creating a User (no usable
password -- they set one via the reset-link flow) the first time we see them.
Mirrors controlpanel.services.admins.grant_club_admin.
"""
def get_or_create_login_user(email):
"""Find or create the User behind ``email`` -- no usable password, they set
one via the reset-link flow the first time we see them. Mirrors
controlpanel.services.admins.grant_club_admin."""
email = email.lower()
user, user_created = User.objects.get_or_create(email=email, defaults={"is_active": True})
if user_created:
user.set_unusable_password()
user.save(update_fields=["password"])
return user, user_created
def get_or_create_login_member(email, first_name="", last_name=""):
"""Find or create the Member behind ``email``, creating a User the first time
we see them."""
user, _ = get_or_create_login_user(email)
member, _ = Member.objects.get_or_create(user=user, defaults={"first_name": first_name, "last_name": last_name})
return member