paid status

This commit is contained in:
SowinskiBraeden committed 2026-03-21 00:45:02 -07:00
1 parent faa90f385a
commit 6a655002d4
5 files changed
+96 -5

No files matched your search

+48
View File
@@ -832,6 +832,54 @@ td a:hover {
min-height: 260px;
}
.status-none {
color: #94a3b8;
background: rgba(148, 163, 184, 0.1);
border: 1px solid rgba(148, 163, 184, 0.2);
}
.status-unpaid {
color: #f59e0b;
background: rgba(245, 158, 11, 0.12);
border: 1px solid rgba(245, 158, 11, 0.24);
}
.status-partial {
color: #fb923c;
background: rgba(251, 146, 60, 0.12);
border: 1px solid rgba(251, 146, 60, 0.24);
}
.status-paid {
color: #22c55e;
background: rgba(34, 197, 94, 0.12);
border: 1px solid rgba(34, 197, 94, 0.24);
}
.pill-paid {
color: #22c55e;
background: rgba(34, 197, 94, 0.12);
border: 1px solid rgba(34, 197, 94, 0.22);
}
.pill-cashout {
color: #f59e0b;
background: rgba(245, 158, 11, 0.12);
border: 1px solid rgba(245, 158, 11, 0.22);
}
.pill-buyin {
color: #60a5fa;
background: rgba(96, 165, 250, 0.12);
border: 1px solid rgba(96, 165, 250, 0.22);
}
.pill-note {
color: #cbd5e1;
background: rgba(203, 213, 225, 0.08);
border: 1px solid rgba(203, 213, 225, 0.14);
}
@media (max-width: 980px) {
.site-shell {
width: min(100% - 24px, 100%);
+21
View File
@@ -30,12 +30,31 @@ class SessionEntry:
player_name: str
buy_in_cents: int = 0
cash_out_cents: int = 0
paid_cents: int = 0
notes: list[str] = field(default_factory=list)
@property
def net_cents(self) -> int:
return self.cash_out_cents - self.buy_in_cents
@property
def payout_due_cents(self) -> int:
return max(self.cash_out_cents, 0)
@property
def payout_remaining_cents(self) -> int:
return max(self.payout_due_cents - self.paid_cents, 0)
@property
def payout_status(self) -> str:
if self.payout_due_cents <= 0:
return "none"
if self.paid_cents <= 0:
return "unpaid"
if self.payout_remaining_cents <= 0:
return "paid"
return "partial"
@dataclass
class SessionSummary:
@@ -171,6 +190,8 @@ def build_session_summaries(events: list[EventRow]) -> list[SessionSummary]:
entry.buy_in_cents += event["amount_cents"]
elif event_type == "cashout":
entry.cash_out_cents += event["amount_cents"]
elif event_type == "paid":
entry.paid_cents += event["amount_cents"]
if event["note"]:
entry.notes.append(event["note"])
+8 -1
View File
@@ -30,7 +30,14 @@ class EventRow(TypedDict):
actor: str
VALID_EVENT_TYPES = {"buyin", "cashout", "note", "session_open", "session_close"}
VALID_EVENT_TYPES = {
"buyin",
"cashout",
"paid",
"note",
"session_open",
"session_close",
}
def ensure_data_file(csv_path: Path) -> None:
+3 -2
View File
@@ -34,6 +34,7 @@
<select name="event_type" required>
<option value="buyin">Buy-in</option>
<option value="cashout">Cash-out</option>
<option value="paid">Paid out</option>
<option value="note">Note only</option>
</select>
</label>
@@ -45,7 +46,7 @@
<label>
<span>Note</span>
<textarea name="note" rows="4" placeholder="Rebuy, correction, settled chips later, etc."></textarea>
<textarea name="note" rows="4" placeholder="Rebuy, correction, partial payout, e-transfer sent, cash paid, etc."></textarea>
</label>
<button class="primary-button" type="submit">Add event</button>
@@ -135,7 +136,7 @@
<article class="event-card">
<div class="event-card-top">
<strong>{{ event.player_name }}</strong>
<span class="pill">{{ event.event_type }}</span>
<span class="pill pill-{{ event.event_type }}">{{ event.event_type }}</span>
</div>
<p class="event-amount">{{ event.amount_cents | money }}</p>
<p class="muted-text small">{{ event.session_date | pretty_date }}</p>
+16 -2
View File
@@ -35,6 +35,9 @@
<th>Player</th>
<th>Buy-in</th>
<th>Cash-out</th>
<th>Paid</th>
<th>Remaining</th>
<th>Status</th>
<th>Net</th>
<th>Notes</th>
</tr>
@@ -45,7 +48,18 @@
<td><a href="{{ url_for('player_detail', player_name=entry.player_name) }}">{{ entry.player_name }}</a></td>
<td>{{ entry.buy_in_cents | money }}</td>
<td>{{ entry.cash_out_cents | money }}</td>
<td class="{{ 'positive' if entry.net_cents > 0 else 'negative' if entry.net_cents < 0 else '' }}">{{ entry.net_cents | money }}</td>
<td>{{ entry.paid_cents | money }}</td>
<td class="{{ 'positive' if entry.payout_remaining_cents == 0 else 'negative' if entry.payout_remaining_cents > 0 else '' }}">
{{ entry.payout_remaining_cents | money }}
</td>
<td>
<span class="status-badge status-{{ entry.payout_status }}">
{{ entry.payout_status }}
</span>
</td>
<td class="{{ 'positive' if entry.net_cents > 0 else 'negative' if entry.net_cents < 0 else '' }}">
{{ entry.net_cents | money }}
</td>
<td>
{% if entry.notes %}
<ul class="note-list">
@@ -76,7 +90,7 @@
<article class="event-card">
<div class="event-card-top">
<strong>{{ event.player_name }}</strong>
<span class="pill">{{ event.event_type }}</span>
<span class="pill pill-{{ event.event_type }}">{{ event.event_type }}</span>
</div>
<p class="event-amount">{{ event.amount_cents | money }}</p>
{% if event.note %}