Files
RosterChief/club/templates/club/dues_invoice_pdf.html
Bernard Siebens c7887637ff 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
2026-08-21 17:50:08 +02:00

101 lines
4.8 KiB
HTML

{% load i18n %}
{% comment %}
Rendered by WeasyPrint, not a browser -- same convention as billing/templates/billing/invoice.html
and management/templates/management/membership_list_pdf.html: a standalone document with its
own print stylesheet, no app.css. Branded off the club's own colours (falling back to the same
shades club.templatetags.club_email's HTML emails use) rather than a fixed accent, since this
is the club's invoice to its own member, not RosterChief's to the club.
{% endcomment %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ invoice.number }}</title>
<style>
@page {
size: A4;
margin: 20mm;
@bottom-center {
content: "{{ club.name }} — {% trans "invoice" %} {{ invoice.number }} — " counter(page) " / " counter(pages);
font-size: 8pt;
color: #666;
}
}
body { font-family: sans-serif; font-size: 10pt; color: #111; }
h1 { font-size: 20pt; margin: 0 0 2mm; }
.muted { color: #666; }
.header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12mm; }
.accent { color: {{ club.primary_color|default:"#4f46e5" }}; }
.parties { display: flex; justify-content: space-between; margin-bottom: 10mm; }
.parties h2 { font-size: 9pt; text-transform: uppercase; letter-spacing: 0.5pt; color: #666; margin: 0 0 2mm; }
table { width: 100%; border-collapse: collapse; margin-bottom: 6mm; }
th { text-align: left; font-size: 9pt; text-transform: uppercase; letter-spacing: 0.5pt; color: #666; border-bottom: 1px solid #ccc; padding: 2mm 0; }
td { padding: 2mm 0; border-bottom: 1px solid #eee; }
.right { text-align: right; }
.total td { font-weight: bold; border-bottom: 2px solid #111; border-top: 1px solid #111; }
.balance { font-size: 12pt; font-weight: bold; }
.paid { color: #15803d; }
.owed { color: #b91c1c; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>{{ club.official_name }}</h1>
{% if document_address %}
<div class="muted">{{ document_address.address }}</div>
<div class="muted">{{ document_address.zip_code }} {{ document_address.city }}</div>
{% endif %}
{% if club.contact_email %}<div class="muted">{{ club.contact_email }}</div>{% endif %}
</div>
<div class="right">
<h1 class="accent">{% trans "Invoice" %}</h1>
<div><strong>{{ invoice.number }}</strong></div>
{% if invoice.sent_at %}<div class="muted">{% blocktrans with date=invoice.sent_at|date:"j F Y" %}Issued {{ date }}{% endblocktrans %}</div>{% endif %}
</div>
</div>
<div class="parties">
<div>
<h2>{% trans "Billed to" %}</h2>
<div><strong>{{ member }}</strong></div>
{% if invoice.sent_to_email %}<div class="muted">{{ invoice.sent_to_email }}{% if invoice.sent_to_guardian %} ({% trans "parent/guardian" %}){% endif %}</div>{% endif %}
</div>
<div class="right">
<h2>{% trans "Season" %}</h2>
<div>{{ membership.season }}</div>
<div class="muted">{% blocktrans with date=invoice.due_date|date:"j F Y" %}Due {{ date }}{% endblocktrans %}</div>
</div>
</div>
<table>
<thead>
<tr>
<th>{% trans "Description" %}</th>
<th class="right">{% trans "Amount" %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<strong>{% trans "Membership fee" %}</strong>
<div class="muted">{{ club.name }} — {{ membership.season }}</div>
</td>
<td class="right">€{{ invoice.amount }}</td>
</tr>
<tr class="total">
<td>{% trans "Balance due" %}</td>
<td class="right balance {% if invoice.is_paid %}paid{% else %}owed{% endif %}">€{{ invoice.amount }}</td>
</tr>
</tbody>
</table>
{% if invoice.is_paid %}
<p class="paid"><strong>{% trans "Paid in full." %}</strong> {% trans "Thank you." %}</p>
{% else %}
<p class="muted">{% blocktrans with date=invoice.due_date|date:"j F Y" %}Payable by {{ date }}.{% endblocktrans %}</p>
{% endif %}
</body>
</html>