visual overhaul + accounting corrections
This commit is contained in:
17 files changed
+1268
-389
No files matched your search
+278
-170
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Admin · boker.club{% endblock %}
|
||||
{% block title %}Admin · myboker.org{% endblock %}
|
||||
{% block page_class %}page--admin{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
<h1 class="hero__title">Ledger controls</h1>
|
||||
<p class="hero__sub">Append events to the audit trail. All history is permanent.</p>
|
||||
<p class="hero__sub">Append events to the audit trail. Player ledger history stays permanent.</p>
|
||||
</div>
|
||||
|
||||
<!-- Banker cash/book position. Cash tiles are real money only; rollovers only
|
||||
@@ -22,7 +22,7 @@
|
||||
<div class="stat__val" style="color:var(--num)">{{ admin_totals.cash_in_cents | money }}</div>
|
||||
</div>
|
||||
<div class="stat stat--rail" style="--rail:var(--pos);">
|
||||
<span class="kicker">Cash out</span>
|
||||
<span class="kicker">Cash paid out</span>
|
||||
<div class="stat__val" style="color:var(--pos)">{{ admin_totals.cash_out_cents | money }}</div>
|
||||
</div>
|
||||
<div class="stat stat--rail" style="--rail:var(--neg);">
|
||||
@@ -38,125 +38,255 @@
|
||||
<div class="stat__val {% if admin_totals.net_book_position_cents == 0 %}num-muted{% elif admin_totals.net_book_position_cents > 0 %}num-pos{% else %}num-neg{% endif %}">
|
||||
{{ admin_totals.net_book_position_cents | money }}
|
||||
</div>
|
||||
<div class="stat__sub">cash in - cash out + receivables - payables</div>
|
||||
<div class="stat__sub">cash in - cash paid out + receivables - payables</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Two-column workspace -->
|
||||
<!-- Admin workspace -->
|
||||
<div class="admin-workspace">
|
||||
|
||||
<!-- LEFT: append form + recent sessions -->
|
||||
<div class="col-main">
|
||||
|
||||
<form class="panel append" method="post" action="{{ url_for('admin_dashboard') }}">
|
||||
<div class="panel__head">
|
||||
<h2 class="panel__title">Append ledger event</h2>
|
||||
<span class="panel__tag">fast entry</span>
|
||||
</div>
|
||||
<div class="append__body">
|
||||
<div class="append__grid">
|
||||
<label class="field">
|
||||
<span class="field__label">Session</span>
|
||||
<select class="control" name="session_id" required>
|
||||
<option value="">Select session</option>
|
||||
{% for s in open_sessions %}
|
||||
<option value="{{ s.session_id }}" {{ 'selected' if append_form.session_id == s.session_id else '' }}>
|
||||
{{ session_label(s) }}{{ ' (live)' if s.status == 'open' else '' }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span class="field__label">Player</span>
|
||||
<input class="control" list="player_names_list" type="text" name="player_name" placeholder="Player name" value="{{ append_form.player_name }}" required>
|
||||
<datalist id="player_names_list">
|
||||
{% for name in player_names %}<option value="{{ name }}"></option>{% endfor %}
|
||||
</datalist>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span class="field__label">Event type</span>
|
||||
<select class="control" name="event_type" required id="eventTypeSelect">
|
||||
{% for value, label, color in event_types %}
|
||||
<option value="{{ value }}" data-color="{{ color }}" data-label="{{ label }}" {{ 'selected' if append_form.event_type == value else '' }}>{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span class="field__label">Amount</span>
|
||||
<span class="control control--money">
|
||||
<span class="control__prefix">$</span>
|
||||
<input name="amount" inputmode="decimal" placeholder="0" autofocus>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<label class="field append__note">
|
||||
<span class="field__label">Note <span class="field__opt">(optional)</span></span>
|
||||
<input class="control" name="note" placeholder="e.g. fronted buy-in, settle next week">
|
||||
<form class="panel append" method="post" action="{{ url_for('admin_dashboard') }}">
|
||||
<div class="panel__head">
|
||||
<h2 class="panel__title">Append ledger event</h2>
|
||||
<span class="panel__tag">fast entry</span>
|
||||
</div>
|
||||
<div class="append__body">
|
||||
<div class="append__grid">
|
||||
<label class="field">
|
||||
<span class="field__label">Session</span>
|
||||
<select class="control" name="session_id" required>
|
||||
<option value="">Select session</option>
|
||||
{% for s in open_sessions %}
|
||||
<option value="{{ s.session_id }}" {{ 'selected' if append_form.session_id == s.session_id else '' }}>
|
||||
{{ session_label(s) }}{{ ' (live)' if s.status == 'open' else '' }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<div class="append__footer">
|
||||
<button type="submit" class="btn btn--primary">Append event</button>
|
||||
<span class="append__preview">Will record as
|
||||
<span class="evtag-pill" id="eventTypePreview" style="color:{{ event_type_colors[append_form.event_type] }}">{{ event_type_labels[append_form.event_type] | upper }}</span>
|
||||
<label class="field">
|
||||
<span class="field__label">Player</span>
|
||||
<input class="control" list="player_names_list" type="text" name="player_name" placeholder="Player name" value="{{ append_form.player_name }}" required>
|
||||
<datalist id="player_names_list">
|
||||
{% for name in player_names %}<option value="{{ name }}"></option>{% endfor %}
|
||||
</datalist>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span class="field__label">Event type</span>
|
||||
<select class="control" name="event_type" required id="eventTypeSelect">
|
||||
{% for value, label, color in event_types %}
|
||||
<option value="{{ value }}" data-color="{{ color }}" data-label="{{ label }}" {{ 'selected' if append_form.event_type == value else '' }}>{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span class="field__label">Amount</span>
|
||||
<span class="control control--money">
|
||||
<span class="control__prefix">$</span>
|
||||
<input name="amount" inputmode="decimal" placeholder="0" autofocus>
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div><!-- /.col-main -->
|
||||
|
||||
<!-- RIGHT: session controls + CSV + raw events feed -->
|
||||
<div class="col-side">
|
||||
|
||||
<div class="panel panel--pad">
|
||||
<h2 class="panel__title panel__title--mb">Session controls</h2>
|
||||
|
||||
{% if live_session %}
|
||||
<div class="livecard">
|
||||
<div class="livecard__head">
|
||||
<span class="dot dot--live"></span>
|
||||
<span class="livecard__name">{{ session_label(live_session) }}</span>
|
||||
<span class="livecard__no">{{ live_session_no }}</span>
|
||||
<label class="field append__note">
|
||||
<span class="field__label">Note <span class="field__opt">(optional)</span></span>
|
||||
<textarea class="control append__textarea" name="note" placeholder="e.g. fronted buy-in, settle next week"></textarea>
|
||||
</label>
|
||||
<div class="append__footer">
|
||||
<button type="submit" class="btn btn--primary">Append event</button>
|
||||
<span class="append__preview">Will record as
|
||||
<span class="evtag-pill" id="eventTypePreview" style="color:{{ event_type_colors[append_form.event_type] }}">{{ event_type_labels[append_form.event_type] | upper }}</span>
|
||||
</span>
|
||||
</div>
|
||||
{% if pending_carry_items %}
|
||||
<div class="carry-recs">
|
||||
<div class="micro">Recommended carry-ins</div>
|
||||
{% for item in pending_carry_items %}
|
||||
<div class="carry-rec">
|
||||
<span>{{ item.player_name }}</span>
|
||||
<strong>{{ item.amount_cents | money }}</strong>
|
||||
{% if live_session and item.player_name in live_session_player_names %}
|
||||
<form method="post" action="{{ url_for('admin_apply_payout_carry_in') }}">
|
||||
<input type="hidden" name="session_id" value="{{ live_session.session_id }}">
|
||||
<input type="hidden" name="player_name" value="{{ item.player_name }}">
|
||||
<button class="table-action-button" type="submit">Apply</button>
|
||||
</form>
|
||||
{% elif live_session %}
|
||||
<em>Add buy-in first</em>
|
||||
{% else %}
|
||||
<em>Open session</em>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="livecard__metrics">
|
||||
<div><div class="micro">In play</div><div class="mono16">{{ live_session.total_invested_cents | money }}</div></div>
|
||||
<div><div class="micro">Seated</div><div class="mono16">{{ live_session.entries|length }}</div></div>
|
||||
<div><div class="micro">Open</div><div class="mono16 mono16--warn">{{ live_unresolved_count }}</div></div>
|
||||
</div>
|
||||
<form method="post" action="{{ url_for('admin_session_state') }}">
|
||||
<input type="hidden" name="session_id" value="{{ live_session.session_id }}">
|
||||
<button class="btn-close" type="submit" name="state" value="closed">Close & settle session</button>
|
||||
</form>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form method="post" action="{{ url_for('admin_open_session') }}">
|
||||
<input type="hidden" name="session_date" value="{{ admin_today }}">
|
||||
<button class="btn-newsession {{ 'btn-newsession--primary' if not live_session else '' }}" type="submit">+ Open new session</button>
|
||||
</form>
|
||||
<div class="panel panel--pad session-control-panel">
|
||||
<h2 class="panel__title panel__title--mb">Session controls</h2>
|
||||
<div class="session-summary-strip">
|
||||
<div>
|
||||
<span class="micro">Today</span>
|
||||
<strong>{{ admin_today }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span class="micro">Empty</span>
|
||||
<strong>{{ empty_session_count }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel--pad">
|
||||
<h2 class="panel__title" style="margin:0 0 4px">Import / export</h2>
|
||||
<p class="csv__desc">Back up or migrate the raw event ledger.</p>
|
||||
<form method="post" action="{{ url_for('admin_import_csv') }}" enctype="multipart/form-data" class="import-form">
|
||||
<div class="csv__btns">
|
||||
<a class="csv-btn-ghost" href="{{ url_for('admin_export_csv') }}">↓ Export CSV</a>
|
||||
<label class="csv-btn-ghost" for="csvTopImport">↑ Import CSV</label>
|
||||
</div>
|
||||
<input id="csvTopImport" type="file" accept=".csv,text/csv" name="csv_file" hidden onchange="this.form.submit()">
|
||||
<label class="csv__drop" id="csvDrop" for="csvTopImport">Drop ledger.csv to import</label>
|
||||
{% if live_session %}
|
||||
<div class="livecard">
|
||||
<div class="livecard__head">
|
||||
<span class="dot dot--live"></span>
|
||||
<span class="livecard__name">{{ session_label(live_session) }}</span>
|
||||
<span class="livecard__no">{{ live_session_no }}</span>
|
||||
</div>
|
||||
<div class="livecard__metrics">
|
||||
<div><div class="micro">Invested</div><div class="mono16">{{ live_session.total_invested_cents | money }}</div></div>
|
||||
<div><div class="micro">Seated</div><div class="mono16">{{ live_session.entries|length }}</div></div>
|
||||
<div><div class="micro">Open</div><div class="mono16 mono16--warn">{{ live_unresolved_count }}</div></div>
|
||||
</div>
|
||||
<form method="post" action="{{ url_for('admin_session_state') }}"
|
||||
{% if live_unresolved_count > 0 %}data-close-warning="true"{% endif %}>
|
||||
<input type="hidden" name="session_id" value="{{ live_session.session_id }}">
|
||||
<button class="btn-close" type="submit" name="state" value="closed">Close session</button>
|
||||
</form>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="livecard livecard--empty">
|
||||
<div class="livecard__head">
|
||||
<span class="dot dot--idle"></span>
|
||||
<span class="livecard__name">No open session</span>
|
||||
<span class="livecard__no">idle</span>
|
||||
</div>
|
||||
<div class="livecard__metrics">
|
||||
<div><div class="micro">Invested</div><div class="mono16">{{ 0 | money }}</div></div>
|
||||
<div><div class="micro">Seated</div><div class="mono16">0</div></div>
|
||||
<div><div class="micro">Open</div><div class="mono16">0</div></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div><!-- /.col-side -->
|
||||
<form method="post" action="{{ url_for('admin_open_session') }}">
|
||||
<input type="hidden" name="session_date" value="{{ admin_today }}">
|
||||
<button class="btn-newsession {{ 'btn-newsession--primary' if not live_session else '' }}" type="submit">+ Open new session</button>
|
||||
</form>
|
||||
|
||||
<form method="post" action="{{ url_for('admin_prune_empty_sessions') }}" class="prune-session-form">
|
||||
<button class="secondary-button" type="submit" {% if empty_session_count == 0 %}disabled{% endif %}>
|
||||
Prune empty sessions{% if empty_session_count > 0 %} ({{ empty_session_count }}){% endif %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="panel panel--pad import-export-panel">
|
||||
<h2 class="panel__title" style="margin:0 0 4px">Import / export</h2>
|
||||
<p class="csv__desc">Back up or migrate the raw event ledger.</p>
|
||||
<form method="post" action="{{ url_for('admin_import_csv') }}" enctype="multipart/form-data" class="import-form">
|
||||
<div class="csv__btns">
|
||||
<a class="csv-btn-ghost" href="{{ url_for('admin_export_csv') }}">↓ Export CSV</a>
|
||||
<label class="csv-btn-ghost" for="csvTopImport">↑ Import CSV</label>
|
||||
</div>
|
||||
<input id="csvTopImport" type="file" accept=".csv,text/csv" name="csv_file" hidden onchange="this.form.submit()">
|
||||
<label class="csv__drop" id="csvDrop" for="csvTopImport">Drop ledger.csv to import</label>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div><!-- /.admin-workspace -->
|
||||
|
||||
<!-- Debt resolution -->
|
||||
<div class="panel debt-panel">
|
||||
<div class="panel__head">
|
||||
<div>
|
||||
<span class="kicker" style="margin:0;">Front receivables</span>
|
||||
<h2 class="panel__title">Debt resolution</h2>
|
||||
</div>
|
||||
<div class="debt-summary">
|
||||
<span class="badge badge--owes">Open {{ admin_totals.players_owe_house_cents | money }}</span>
|
||||
<span class="badge badge--paid">Cash repaid {{ admin_totals.collected_cents | money }}</span>
|
||||
<span class="badge badge--written_off">Written off {{ admin_totals.written_off_cents | money }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% if debt_entries %}
|
||||
<div class="debt-layout">
|
||||
<div class="debt-list">
|
||||
{% for item in debt_entries %}
|
||||
{% set s = item.session %}{% set e = item.entry %}
|
||||
<div class="debt-list-item">
|
||||
<div>
|
||||
<strong>{{ e.player_name }}</strong>
|
||||
<span>{{ session_label(s) }}</span>
|
||||
</div>
|
||||
<b>{{ e.player_owes_cents | money }}</b>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="debt-action-grid">
|
||||
<form class="form-card debt-form" method="post" action="{{ url_for('admin_collect_front') }}">
|
||||
<h3>Collect debt</h3>
|
||||
<label>
|
||||
<span>Outstanding debt</span>
|
||||
<select name="debt_key" required>
|
||||
<option value="">Select debt</option>
|
||||
{% for item in debt_entries %}
|
||||
{% set s = item.session %}{% set e = item.entry %}
|
||||
<option value="{{ s.session_id }}||{{ e.player_name }}">
|
||||
{{ e.player_name }} · {{ session_label(s) }} · owes {{ e.player_owes_cents | money }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Amount collected</span>
|
||||
<input type="number" step="0.01" name="amount" placeholder="0.00" required>
|
||||
</label>
|
||||
<label>
|
||||
<span>Note</span>
|
||||
<textarea name="note" rows="2" placeholder="E-transfer received, cash, etc."></textarea>
|
||||
</label>
|
||||
<button class="primary-button" type="submit">Mark collected</button>
|
||||
</form>
|
||||
|
||||
<form class="form-card debt-form" method="post" action="{{ url_for('admin_write_off_front') }}">
|
||||
<h3>Write off debt</h3>
|
||||
<label>
|
||||
<span>Outstanding debt</span>
|
||||
<select name="debt_key" required>
|
||||
<option value="">Select debt</option>
|
||||
{% for item in debt_entries %}
|
||||
{% set s = item.session %}{% set e = item.entry %}
|
||||
<option value="{{ s.session_id }}||{{ e.player_name }}">
|
||||
{{ e.player_name }} · {{ session_label(s) }} · owes {{ e.player_owes_cents | money }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Amount to write off</span>
|
||||
<input type="number" step="0.01" name="amount" placeholder="0.00" required>
|
||||
</label>
|
||||
<label>
|
||||
<span>Note</span>
|
||||
<textarea name="note" rows="2" placeholder="Won't be collected."></textarea>
|
||||
</label>
|
||||
<button class="secondary-button" type="submit">Write off debt</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="debt-empty">
|
||||
<div class="debt-empty__mark">$0</div>
|
||||
<p>No open player debts right now.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="admin-bottom-grid">
|
||||
<div class="panel">
|
||||
<div class="panel__head">
|
||||
<div>
|
||||
<span class="kicker" style="margin:0;">Recent sessions</span>
|
||||
<span class="kicker" style="margin:0;">All sessions</span>
|
||||
<h2 class="panel__title">Current totals</h2>
|
||||
</div>
|
||||
</div>
|
||||
@@ -167,8 +297,8 @@
|
||||
<th>Session</th>
|
||||
<th>Players</th>
|
||||
<th>Cash in</th>
|
||||
<th>Cash out</th>
|
||||
<th>House owes</th>
|
||||
<th>Cash paid out</th>
|
||||
<th>House owes players</th>
|
||||
<th>Players owe house</th>
|
||||
<th>Book position</th>
|
||||
<th>Status</th>
|
||||
@@ -180,8 +310,8 @@
|
||||
<tr>
|
||||
<td><a href="{{ url_for('session_detail', session_id=s.session_id) }}">{{ session_label(s) }}</a></td>
|
||||
<td style="font-family:var(--font-mono);color:var(--num)">{{ s.entries|length }}</td>
|
||||
<td style="font-family:var(--font-mono);color:var(--num)">{{ s.total_cash_in_cents | money }}</td>
|
||||
<td style="font-family:var(--font-mono);color:var(--pos)">{{ s.total_paid_out_cents | money }}</td>
|
||||
<td style="font-family:var(--font-mono);color:var(--num)">{{ s.total_banker_cash_in_cents | money }}</td>
|
||||
<td style="font-family:var(--font-mono);color:var(--pos)">{{ s.total_banker_cash_out_cents | money }}</td>
|
||||
<td class="{{ 'negative' if s.total_current_due_to_player_cents > 0 else '' }}" style="font-family:var(--font-mono)">{{ s.total_current_due_to_player_cents | money }}</td>
|
||||
<td class="{{ 'negative' if s.total_current_due_to_house_cents > 0 else '' }}" style="font-family:var(--font-mono)">{{ s.total_current_due_to_house_cents | money }}</td>
|
||||
<td class="{% if s.total_net_book_position_cents > 0 %}positive{% elif s.total_net_book_position_cents < 0 %}negative{% endif %}" style="font-family:var(--font-mono)">{{ s.total_net_book_position_cents | money }}</td>
|
||||
@@ -231,6 +361,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-backdrop" id="closeSessionModal" hidden>
|
||||
<div class="modal-card" role="dialog" aria-modal="true" aria-labelledby="closeSessionModalTitle">
|
||||
<div class="modal-card__head">
|
||||
<span class="kicker" style="margin:0;">Open settlement</span>
|
||||
<h2 class="panel__title" id="closeSessionModalTitle">Close session?</h2>
|
||||
</div>
|
||||
<p class="modal-card__text">This session has unpaid or uncarried cashouts, or unresolved debts. Closing stops table entry, but the open settlement items will remain tracked.</p>
|
||||
<div class="modal-card__actions">
|
||||
<button class="secondary-button" type="button" id="cancelCloseSession">Keep open</button>
|
||||
<button class="btn btn--primary" type="button" id="confirmCloseSession">Close session</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const eventTypeSelect = document.getElementById('eventTypeSelect');
|
||||
const eventTypePreview = document.getElementById('eventTypePreview');
|
||||
@@ -255,74 +399,38 @@ csvDrop?.addEventListener('drop', (event) => {
|
||||
csvInput.files = event.dataTransfer.files;
|
||||
csvInput.form?.submit();
|
||||
});
|
||||
|
||||
const closeSessionModal = document.getElementById('closeSessionModal');
|
||||
const cancelCloseSession = document.getElementById('cancelCloseSession');
|
||||
const confirmCloseSession = document.getElementById('confirmCloseSession');
|
||||
let pendingCloseForm = null;
|
||||
|
||||
document.querySelectorAll('form[data-close-warning="true"]').forEach((form) => {
|
||||
form.addEventListener('submit', (event) => {
|
||||
if (form.dataset.confirmed === 'true') return;
|
||||
event.preventDefault();
|
||||
pendingCloseForm = form;
|
||||
closeSessionModal.hidden = false;
|
||||
confirmCloseSession?.focus();
|
||||
});
|
||||
});
|
||||
|
||||
cancelCloseSession?.addEventListener('click', () => {
|
||||
closeSessionModal.hidden = true;
|
||||
pendingCloseForm = null;
|
||||
});
|
||||
|
||||
closeSessionModal?.addEventListener('click', (event) => {
|
||||
if (event.target !== closeSessionModal) return;
|
||||
closeSessionModal.hidden = true;
|
||||
pendingCloseForm = null;
|
||||
});
|
||||
|
||||
confirmCloseSession?.addEventListener('click', () => {
|
||||
if (!pendingCloseForm) return;
|
||||
pendingCloseForm.dataset.confirmed = 'true';
|
||||
pendingCloseForm.submit();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Front debt resolution -->
|
||||
{% if debt_entries %}
|
||||
<div class="panel debt-panel" style="margin-top:20px;">
|
||||
<div class="panel__head">
|
||||
<div>
|
||||
<span class="kicker" style="margin:0;">Front receivables</span>
|
||||
<h2 class="panel__title">Debt resolution</h2>
|
||||
</div>
|
||||
<div class="debt-summary">
|
||||
<span class="badge badge--owes">Open {{ admin_totals.players_owe_house_cents | money }}</span>
|
||||
<span class="badge badge--paid">Repaid {{ admin_totals.collected_cents | money }}</span>
|
||||
<span class="badge badge--written_off">Written off {{ admin_totals.written_off_cents | money }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="debt-action-grid" style="padding:20px;">
|
||||
<form class="form-card" style="padding:0;background:transparent;" method="post" action="{{ url_for('admin_collect_front') }}">
|
||||
<h3>Collect debt</h3>
|
||||
<label>
|
||||
<span>Outstanding debt</span>
|
||||
<select name="debt_key" required>
|
||||
<option value="">Select debt</option>
|
||||
{% for item in debt_entries %}
|
||||
{% set s = item.session %}{% set e = item.entry %}
|
||||
<option value="{{ s.session_id }}||{{ e.player_name }}">
|
||||
{{ e.player_name }} · {{ session_label(s) }} · owes {{ e.player_owes_cents | money }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Amount collected</span>
|
||||
<input type="number" step="0.01" name="amount" placeholder="0.00" required>
|
||||
</label>
|
||||
<label>
|
||||
<span>Note</span>
|
||||
<textarea name="note" rows="2" placeholder="E-transfer received, cash, etc."></textarea>
|
||||
</label>
|
||||
<button class="primary-button" type="submit">Mark collected</button>
|
||||
</form>
|
||||
|
||||
<form class="form-card" style="padding:0;background:transparent;" method="post" action="{{ url_for('admin_write_off_front') }}">
|
||||
<h3>Write off debt</h3>
|
||||
<label>
|
||||
<span>Outstanding debt</span>
|
||||
<select name="debt_key" required>
|
||||
<option value="">Select debt</option>
|
||||
{% for item in debt_entries %}
|
||||
{% set s = item.session %}{% set e = item.entry %}
|
||||
<option value="{{ s.session_id }}||{{ e.player_name }}">
|
||||
{{ e.player_name }} · {{ session_label(s) }} · owes {{ e.player_owes_cents | money }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Amount to write off</span>
|
||||
<input type="number" step="0.01" name="amount" placeholder="0.00" required>
|
||||
</label>
|
||||
<label>
|
||||
<span>Note</span>
|
||||
<textarea name="note" rows="2" placeholder="Won't be collected."></textarea>
|
||||
</label>
|
||||
<button class="secondary-button" type="submit">Write off front</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
Reference in new issue
Block a user