Add a club legal address, used for invoices/referee forms ahead of the home ground
New Club.legal_address/legal_zip_code/legal_city, editable from the identity page (management:club_settings). Official document headers (the dues invoice, the referee payment form) previously borrowed the club's home Location for this -- conflating "where we play" with "our registered address", which aren't always the same place. New club.services.invoicing.resolve_document_address(club) picks the club's own legal address when set, falling back to the home Location exactly as before when it isn't, so nothing breaks for a club that hasn't set one yet. Location.is_home now means only what it always should have: telling a home game from an away one. Renamed the shared "home_location" template/context variable to "document_address" on both PDFs to match -- it was never accurate once a legal address could win instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -8,6 +8,7 @@ membership.fee_status -- never a flag duplicated here that could drift out of st
|
||||
"""
|
||||
|
||||
from datetime import timedelta
|
||||
from types import SimpleNamespace
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
@@ -158,11 +159,30 @@ def render_pdf(html: str) -> bytes:
|
||||
return HTML(string=html).write_pdf()
|
||||
|
||||
|
||||
def resolve_document_address(club):
|
||||
"""The address to print on an official document header (a dues invoice,
|
||||
the referee payment form) -- the club's own ``legal_address`` when set,
|
||||
else its home ground (``events.models.Location``, ``is_home=True``), so
|
||||
a club that hasn't set a legal address yet still gets *something* rather
|
||||
than a blank header.
|
||||
|
||||
``Location.is_home`` itself is purely about telling a home game from an
|
||||
away one -- this is the one place its address doubles as a stand-in for
|
||||
an actual registered/mailing address, and only when the club hasn't set
|
||||
one of its own. Returns an object exposing ``.address``/``.zip_code``/
|
||||
``.city`` either way (a plain namespace for the legal-address branch, the
|
||||
real ``Location`` for the fallback), or ``None`` when neither is set.
|
||||
"""
|
||||
if club.legal_address:
|
||||
return SimpleNamespace(address=club.legal_address, zip_code=club.legal_zip_code, city=club.legal_city)
|
||||
return Location.objects.filter(club=club, is_home=True).first()
|
||||
|
||||
|
||||
def invoice_pdf(invoice: DuesInvoice) -> bytes:
|
||||
# Same header convention as management/event_referee_form_pdf.html: the club's
|
||||
# legal name (official_name falls back to the everyday name when unset) and its
|
||||
# home location -- never an event-specific location, since a dues invoice isn't
|
||||
# tied to any one event.
|
||||
home_location = Location.objects.filter(club=invoice.club, is_home=True).first()
|
||||
html = render_to_string("club/dues_invoice_pdf.html", {"club": invoice.club, "invoice": invoice, "membership": invoice.membership, "member": invoice.membership.member, "home_location": home_location})
|
||||
# document address -- never an event-specific location, since a dues invoice
|
||||
# isn't tied to any one event.
|
||||
document_address = resolve_document_address(invoice.club)
|
||||
html = render_to_string("club/dues_invoice_pdf.html", {"club": invoice.club, "invoice": invoice, "membership": invoice.membership, "member": invoice.membership.member, "document_address": document_address})
|
||||
return render_pdf(html)
|
||||
|
||||
Reference in New Issue
Block a user