fix layout + collect/writeoff debts
This commit is contained in:
8 files changed
+263
-35
No files matched your search
@@ -12,7 +12,7 @@ The idea is pretty simple: public pages for stats and session history, plus a sm
|
||||
- admin login for recording events
|
||||
- open / closed session tracking
|
||||
- payout tracking with `paid` events
|
||||
- front debt write-offs with `front_writeoff` events
|
||||
- front debt collections and write-offs with `front_collected` / `front_writeoff` events
|
||||
- session and player charts
|
||||
- CSV import / export from the admin page
|
||||
- append-only `entries.csv` ledger instead of overwriting old rows
|
||||
@@ -38,6 +38,7 @@ Current event types:
|
||||
|
||||
- `buyin`
|
||||
- `front`
|
||||
- `front_collected`
|
||||
- `front_writeoff`
|
||||
- `cashout`
|
||||
- `paid`
|
||||
@@ -52,6 +53,7 @@ A few examples:
|
||||
- another `buyin` for a rebuy
|
||||
- another `cashout` if chip counts are corrected later
|
||||
- a `paid` event when someone is actually settled up
|
||||
- a `front_collected` event when a front is repaid outside poker
|
||||
- a `front_writeoff` event when a front will not be collected
|
||||
- a `note` event for bookkeeping context
|
||||
- `session_open` / `session_close` to mark whether a game night is still live
|
||||
|
||||
@@ -438,6 +438,74 @@ def admin_write_off_front() -> str:
|
||||
return redirect(url_for("admin_dashboard"))
|
||||
|
||||
|
||||
@app.post("/admin/collect-front")
|
||||
def admin_collect_front() -> str:
|
||||
if not is_admin():
|
||||
flash("Admin login required.", "error")
|
||||
return redirect(url_for("admin_login"))
|
||||
|
||||
debt_key = request.form.get("debt_key", "").strip()
|
||||
note = request.form.get("note", "").strip()
|
||||
amount_raw = request.form.get("amount", "0").strip()
|
||||
|
||||
try:
|
||||
amount_cents = int(round(float(amount_raw) * 100))
|
||||
except ValueError:
|
||||
flash("Amount must be a number.", "error")
|
||||
return redirect(url_for("admin_dashboard"))
|
||||
|
||||
if amount_cents <= 0:
|
||||
flash("Collected amount must be greater than zero.", "error")
|
||||
return redirect(url_for("admin_dashboard"))
|
||||
|
||||
try:
|
||||
session_id, player_name = debt_key.split("||", 1)
|
||||
except ValueError:
|
||||
flash("Select a valid player debt.", "error")
|
||||
return redirect(url_for("admin_dashboard"))
|
||||
|
||||
events = load_events(DATA_PATH)
|
||||
sessions = build_session_summaries(events)
|
||||
target = next(
|
||||
(session for session in sessions if session.session_id == session_id),
|
||||
None,
|
||||
)
|
||||
|
||||
if target is None:
|
||||
flash("Session not found.", "error")
|
||||
return redirect(url_for("admin_dashboard"))
|
||||
|
||||
entry = next(
|
||||
(entry for entry in target.entries if entry.player_name == player_name),
|
||||
None,
|
||||
)
|
||||
|
||||
if entry is None or entry.player_owes_cents <= 0:
|
||||
flash("That player does not have an outstanding front debt.", "error")
|
||||
return redirect(url_for("admin_dashboard"))
|
||||
|
||||
if amount_cents > entry.player_owes_cents:
|
||||
flash(
|
||||
f"Collection cannot exceed {cents_to_dollars(entry.player_owes_cents)}.",
|
||||
"error",
|
||||
)
|
||||
return redirect(url_for("admin_dashboard"))
|
||||
|
||||
append_event(
|
||||
DATA_PATH,
|
||||
session_id=target.session_id,
|
||||
session_date=target.session_date,
|
||||
player_name=entry.player_name,
|
||||
event_type="front_collected",
|
||||
amount_cents=amount_cents,
|
||||
note=note or "Front debt collected.",
|
||||
actor=app.config["ADMIN_USERNAME"],
|
||||
)
|
||||
|
||||
flash("Front debt collected.", "success")
|
||||
return redirect(url_for("admin_dashboard"))
|
||||
|
||||
|
||||
@app.post("/admin/open-session")
|
||||
def admin_open_session() -> str:
|
||||
if not is_admin():
|
||||
@@ -537,6 +605,9 @@ def admin_dashboard():
|
||||
"players_owe_cents": sum(
|
||||
session.total_player_owes_cents for session in sessions
|
||||
),
|
||||
"collected_cents": sum(
|
||||
session.total_front_collected_cents for session in sessions
|
||||
),
|
||||
"written_off_cents": sum(
|
||||
session.total_front_writeoff_cents for session in sessions
|
||||
),
|
||||
|
||||
+87
-4
@@ -294,6 +294,14 @@ h2 {
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
h3 {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin: 0;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.muted-text {
|
||||
margin: 0;
|
||||
color: var(--text-muted);
|
||||
@@ -383,6 +391,10 @@ h2 {
|
||||
min-height: 112px;
|
||||
}
|
||||
|
||||
.compact-form textarea {
|
||||
min-height: 92px;
|
||||
}
|
||||
|
||||
.form-card input:focus,
|
||||
.form-card select:focus,
|
||||
.form-card textarea:focus {
|
||||
@@ -394,6 +406,14 @@ h2 {
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.admin-layout {
|
||||
grid-template-columns: minmax(420px, 1.15fr) minmax(360px, 0.85fr);
|
||||
}
|
||||
|
||||
.admin-layout > .grid {
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
@@ -763,11 +783,14 @@ td a:hover {
|
||||
}
|
||||
|
||||
.leaderboard-layout,
|
||||
.session-layout,
|
||||
.admin-layout {
|
||||
.session-layout {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.admin-layout {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.results-panel-full {
|
||||
display: block;
|
||||
}
|
||||
@@ -958,6 +981,12 @@ td a:hover {
|
||||
border: 1px solid rgba(251, 146, 60, 0.22);
|
||||
}
|
||||
|
||||
.pill-front_collected {
|
||||
color: #22c55e;
|
||||
background: rgba(34, 197, 94, 0.12);
|
||||
border: 1px solid rgba(34, 197, 94, 0.22);
|
||||
}
|
||||
|
||||
.pill-front_writeoff {
|
||||
color: #f87171;
|
||||
background: rgba(248, 113, 113, 0.12);
|
||||
@@ -995,6 +1024,12 @@ td a:hover {
|
||||
border: 1px solid rgba(248, 113, 113, 0.24);
|
||||
}
|
||||
|
||||
.status-collected {
|
||||
color: #22c55e;
|
||||
background: rgba(34, 197, 94, 0.12);
|
||||
border: 1px solid rgba(34, 197, 94, 0.24);
|
||||
}
|
||||
|
||||
.inline-action-form {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -1038,6 +1073,39 @@ td a:hover {
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
}
|
||||
|
||||
.debt-panel {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.debt-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.debt-summary span {
|
||||
display: inline-flex;
|
||||
min-height: 34px;
|
||||
align-items: center;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 999px;
|
||||
padding: 0 12px;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.86rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.debt-action-grid {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.import-form input[type="file"] {
|
||||
width: 100%;
|
||||
margin-top: 0.5rem;
|
||||
@@ -1088,20 +1156,34 @@ td a:hover {
|
||||
.admin-cash-grid {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
grid-template-columns: repeat(6, minmax(150px, 1fr));
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (max-width: 1180px) {
|
||||
.admin-cash-grid {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1180px) {
|
||||
.profile-summary-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.admin-cash-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.debt-action-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.debt-summary {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
@@ -1135,6 +1217,7 @@ td a:hover {
|
||||
|
||||
.two-col,
|
||||
.three-col,
|
||||
.four-col,
|
||||
.leaderboard-layout,
|
||||
.session-layout,
|
||||
.admin-layout {
|
||||
|
||||
@@ -31,6 +31,7 @@ class SessionEntry:
|
||||
player_name: str
|
||||
buy_in_cents: int = 0
|
||||
front_cents: int = 0
|
||||
front_collected_cents: int = 0
|
||||
front_writeoff_cents: int = 0
|
||||
cash_out_cents: int = 0
|
||||
paid_cents: int = 0
|
||||
@@ -68,7 +69,7 @@ class SessionEntry:
|
||||
|
||||
@property
|
||||
def player_owes_cents(self) -> int:
|
||||
return max(self.raw_player_owes_cents - self.front_writeoff_applied_cents, 0)
|
||||
return max(self.raw_player_owes_cents - self.front_resolved_cents, 0)
|
||||
|
||||
@property
|
||||
def raw_player_owes_cents(self) -> int:
|
||||
@@ -84,7 +85,18 @@ class SessionEntry:
|
||||
|
||||
@property
|
||||
def front_writeoff_applied_cents(self) -> int:
|
||||
return min(self.front_writeoff_cents, self.raw_player_owes_cents)
|
||||
return min(
|
||||
self.front_writeoff_cents,
|
||||
max(self.raw_player_owes_cents - self.front_collected_applied_cents, 0),
|
||||
)
|
||||
|
||||
@property
|
||||
def front_collected_applied_cents(self) -> int:
|
||||
return min(self.front_collected_cents, self.raw_player_owes_cents)
|
||||
|
||||
@property
|
||||
def front_resolved_cents(self) -> int:
|
||||
return self.front_collected_applied_cents + self.front_writeoff_applied_cents
|
||||
|
||||
@property
|
||||
def payout_status(self) -> str:
|
||||
@@ -92,6 +104,8 @@ class SessionEntry:
|
||||
return "owes"
|
||||
if self.front_writeoff_applied_cents > 0:
|
||||
return "written_off"
|
||||
if self.front_collected_applied_cents > 0:
|
||||
return "collected"
|
||||
if self.gross_payout_cents <= 0:
|
||||
return "none"
|
||||
if self.current_due_cents <= 0:
|
||||
@@ -169,6 +183,10 @@ class SessionSummary:
|
||||
def total_front_writeoff_cents(self) -> int:
|
||||
return sum(entry.front_writeoff_applied_cents for entry in self.entries)
|
||||
|
||||
@property
|
||||
def total_front_collected_cents(self) -> int:
|
||||
return sum(entry.front_collected_applied_cents for entry in self.entries)
|
||||
|
||||
@property
|
||||
def total_cash_in_cents(self) -> int:
|
||||
return sum(entry.buy_in_cents for entry in self.entries)
|
||||
@@ -196,6 +214,7 @@ class PlayerStats:
|
||||
biggest_loss_cents: int
|
||||
total_buy_in_cents: int
|
||||
total_front_cents: int
|
||||
total_front_collected_cents: int
|
||||
total_front_writeoff_cents: int
|
||||
current_player_owes_cents: int
|
||||
total_rollover_in_cents: int
|
||||
@@ -347,6 +366,8 @@ def build_session_summaries(events: list[EventRow]) -> list[SessionSummary]:
|
||||
entry.buy_in_cents += event["amount_cents"]
|
||||
elif event_type == "front":
|
||||
entry.front_cents += event["amount_cents"]
|
||||
elif event_type == "front_collected":
|
||||
entry.front_collected_cents += event["amount_cents"]
|
||||
elif event_type == "front_writeoff":
|
||||
entry.front_writeoff_cents += event["amount_cents"]
|
||||
elif event_type == "rollover_in":
|
||||
@@ -481,6 +502,9 @@ def build_leaderboard(sessions: list[SessionSummary]) -> list[PlayerStats]:
|
||||
|
||||
total_buy_in = sum(entry.buy_in_cents for entry in entries)
|
||||
total_front = sum(entry.front_cents for entry in entries)
|
||||
total_front_collected = sum(
|
||||
entry.front_collected_applied_cents for entry in entries
|
||||
)
|
||||
total_front_writeoff = sum(
|
||||
entry.front_writeoff_applied_cents for entry in entries
|
||||
)
|
||||
@@ -507,6 +531,7 @@ def build_leaderboard(sessions: list[SessionSummary]) -> list[PlayerStats]:
|
||||
biggest_loss_cents=biggest_loss,
|
||||
total_buy_in_cents=total_buy_in,
|
||||
total_front_cents=total_front,
|
||||
total_front_collected_cents=total_front_collected,
|
||||
total_front_writeoff_cents=total_front_writeoff,
|
||||
current_player_owes_cents=current_player_owes,
|
||||
total_rollover_in_cents=total_rollover_in,
|
||||
|
||||
@@ -35,6 +35,7 @@ class EventRow(TypedDict):
|
||||
VALID_EVENT_TYPES = {
|
||||
"buyin",
|
||||
"front",
|
||||
"front_collected",
|
||||
"front_writeoff",
|
||||
"cashout",
|
||||
"paid",
|
||||
|
||||
@@ -113,9 +113,58 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<form class="panel form-card" method="post" action="{{ url_for('admin_write_off_front') }}">
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="panel debt-panel">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<p class="eyebrow">Front debt</p>
|
||||
<h2>Write off debt</h2>
|
||||
<h2>Debt resolution</h2>
|
||||
</div>
|
||||
<div class="debt-summary">
|
||||
<span>Open {{ admin_totals.players_owe_cents | money }}</span>
|
||||
<span>Collected {{ admin_totals.collected_cents | money }}</span>
|
||||
<span>Written off {{ admin_totals.written_off_cents | money }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if debt_entries %}
|
||||
<div class="debt-action-grid">
|
||||
<form class="form-card compact-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 session = item.session %}
|
||||
{% set entry = item.entry %}
|
||||
<option value="{{ session.session_id }}||{{ entry.player_name }}">
|
||||
{{ entry.player_name }} · {{ session_label(session) }} · owes {{ entry.player_owes_cents | money }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span>Amount collected</span>
|
||||
<input type="number" step="0.01" name="amount" placeholder="5.00" required>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span>Note</span>
|
||||
<textarea name="note" rows="3" placeholder="E-transfer received, cash collected, etc."></textarea>
|
||||
</label>
|
||||
|
||||
<div class="button-row">
|
||||
<button class="primary-button" type="submit">Mark collected</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form class="form-card compact-form" method="post" action="{{ url_for('admin_write_off_front') }}">
|
||||
<h3>Write off debt</h3>
|
||||
|
||||
<label>
|
||||
<span>Outstanding debt</span>
|
||||
@@ -145,7 +194,10 @@
|
||||
<button class="secondary-button" type="submit">Write off front</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="muted-text">No outstanding front debt.</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
<section class="grid admin-cash-grid">
|
||||
@@ -205,6 +257,7 @@
|
||||
<th>Paid out</th>
|
||||
<th>Still owed</th>
|
||||
<th>Players owe</th>
|
||||
<th>Collected</th>
|
||||
<th>Written off</th>
|
||||
<th>Open balance</th>
|
||||
<th>Status</th>
|
||||
@@ -228,6 +281,9 @@
|
||||
<td class="{{ 'negative' if session.total_player_owes_cents > 0 else '' }}">
|
||||
{{ session.total_player_owes_cents | money }}
|
||||
</td>
|
||||
<td class="{{ 'positive' if session.total_front_collected_cents > 0 else '' }}">
|
||||
{{ session.total_front_collected_cents | money }}
|
||||
</td>
|
||||
<td class="{{ 'negative' if session.total_front_writeoff_cents > 0 else '' }}">
|
||||
{{ session.total_front_writeoff_cents | money }}
|
||||
</td>
|
||||
@@ -252,7 +308,7 @@
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="10">No sessions yet.</td>
|
||||
<td colspan="11">No sessions yet.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@@ -9,33 +9,13 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="grid three-col">
|
||||
<section class="grid three-col profile-summary-grid">
|
||||
<article class="panel stat-card"><span>Total Net</span><strong class="{{ 'positive' if player.total_net_cents > 0 else 'negative' if player.total_net_cents < 0 else 'neutral' }}">{{ player.total_net_cents | money }}</strong></article>
|
||||
<article class="panel stat-card"><span>Win %</span><strong>{{ "%.1f"|format(player.win_pct) }}%</strong></article>
|
||||
<article class="panel stat-card"><span>ROI</span><strong>{{ "%.1f"|format(player.roi_pct) }}%</strong></article>
|
||||
<article class="panel stat-card"><span>Total invested</span><strong>{{ player.total_invested_cents | money }}</strong></article>
|
||||
<article class="panel stat-card"><span>Paid Buy-in</span><strong>{{ player.total_buy_in_cents | money }}</strong></article>
|
||||
<article class="panel stat-card"><span>Fronted</span><strong>{{ player.total_front_cents | money }}</strong></article>
|
||||
<article class="panel stat-card"><span>Current debt</span><strong class="{{ 'negative' if player.current_player_owes_cents > 0 else '' }}">{{ player.current_player_owes_cents | money }}</strong></article>
|
||||
<article class="panel stat-card"><span>Written off</span><strong class="{{ 'negative' if player.total_front_writeoff_cents > 0 else '' }}">{{ player.total_front_writeoff_cents | money }}</strong></article>
|
||||
<!--<article class="panel stat-card"><span>Rolled in</span><strong>{{ player.total_rollover_in_cents | money }}</strong></article>-->
|
||||
<article class="panel stat-card"><span>Cash-outs</span><strong>{{ player.total_cash_out_cents | money }}</strong></article>
|
||||
<article class="panel stat-card"><span>Current debt</span><strong class="{{ 'negative' if player.current_player_owes_cents > 0 else '' }}">{{ player.current_player_owes_cents | money }}</strong></article>
|
||||
<article class="panel stat-card"><span>Win %</span><strong>{{ "%.1f"|format(player.win_pct) }}%</strong></article>
|
||||
<article class="panel stat-card"><span>Sessions</span><strong>{{ player.sessions_played }}</strong></article>
|
||||
<article class="panel stat-card">
|
||||
<span>Current Streak</span>
|
||||
<strong>
|
||||
{% if player.current_win_streak > 0 %}
|
||||
W{{ player.current_win_streak }}
|
||||
{% elif player.current_loss_streak > 0 %}
|
||||
L{{ player.current_loss_streak }}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</strong>
|
||||
</article>
|
||||
|
||||
<!--<article class="panel stat-card"><span>Longest win streak</span><strong>{{ player.longest_win_streak }}</strong></article>
|
||||
<article class="panel stat-card"><span>Longest loss streak</span><strong>{{ player.longest_loss_streak }}</strong></article>-->
|
||||
</section>
|
||||
|
||||
<section class="grid one-col">
|
||||
@@ -87,12 +67,18 @@
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>Total Net</th><td>{{ player.total_net_cents | money }}</td></tr>
|
||||
<tr><th>Win %</th><td>{{ "%.1f"|format(player.win_pct) }}%</td></tr>
|
||||
<tr><th>ROI</th><td>{{ "%.1f"|format(player.roi_pct) }}%</td></tr>
|
||||
<tr><th>Sessions</th><td>{{ player.sessions_played }}</td></tr>
|
||||
<tr><th>Paid Buy-ins</th><td>{{ player.total_buy_in_cents | money }}</td></tr>
|
||||
<tr><th>Fronted</th><td>{{ player.total_front_cents | money }}</td></tr>
|
||||
<tr><th>Debt Collected</th><td>{{ player.total_front_collected_cents | money }}</td></tr>
|
||||
<tr><th>Current Debt</th><td>{{ player.current_player_owes_cents | money }}</td></tr>
|
||||
<tr><th>Written Off</th><td>{{ player.total_front_writeoff_cents | money }}</td></tr>
|
||||
<tr><th>Rolled In</th><td>{{ player.total_rollover_in_cents | money }}</td></tr>
|
||||
<tr><th>Total Invested</th><td>{{ player.total_invested_cents | money }}</td></tr>
|
||||
<tr><th>Cash-outs</th><td>{{ player.total_cash_out_cents | money }}</td></tr>
|
||||
<tr><th>Rolled Out</th><td>{{ player.total_rollover_out_cents | money }}</td></tr>
|
||||
<tr><th>Winning Sessions</th><td>{{ player.winning_sessions }}</td></tr>
|
||||
<tr><th>Losing Sessions</th><td>{{ player.losing_sessions }}</td></tr>
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
<th class="detail-col">Gross due</th>
|
||||
<th class="detail-col">Paid</th>
|
||||
<th class="detail-col">Rolled out</th>
|
||||
<th class="detail-col">Collected</th>
|
||||
<th class="detail-col">Written off</th>
|
||||
<th>Still owed</th>
|
||||
<th>Status</th>
|
||||
@@ -128,13 +129,16 @@
|
||||
|
||||
<td class="detail-col">{{ entry.paid_cents | money }}</td>
|
||||
<td class="detail-col">{{ entry.rollover_out_cents | money }}</td>
|
||||
<td class="detail-col">{{ entry.front_collected_applied_cents | money }}</td>
|
||||
<td class="detail-col">{{ entry.front_writeoff_applied_cents | money }}</td>
|
||||
|
||||
<td class="{% if entry.player_owes_cents > 0 %}negative{% elif entry.front_writeoff_applied_cents > 0 %}negative{% elif entry.current_due_cents > 0 %}negative{% else %}positive{% endif %}">
|
||||
<td class="{% if entry.player_owes_cents > 0 %}negative{% elif entry.front_writeoff_applied_cents > 0 %}negative{% elif entry.front_collected_applied_cents > 0 %}positive{% elif entry.current_due_cents > 0 %}negative{% else %}positive{% endif %}">
|
||||
{% if entry.player_owes_cents > 0 %}
|
||||
Owes {{ entry.player_owes_cents | money }}
|
||||
{% elif entry.front_writeoff_applied_cents > 0 %}
|
||||
Written off {{ entry.front_writeoff_applied_cents | money }}
|
||||
{% elif entry.front_collected_applied_cents > 0 %}
|
||||
Collected {{ entry.front_collected_applied_cents | money }}
|
||||
{% else %}
|
||||
{{ entry.current_due_cents | money }}
|
||||
{% endif %}
|
||||
|
||||
Reference in new issue
Block a user