feat: add member details popup with attendance and fee exceptions
This commit is contained in:
31
app.py
31
app.py
@@ -9,7 +9,7 @@ scripts_dir = Path(__file__).parent / "scripts"
|
||||
sys.path.append(str(scripts_dir))
|
||||
|
||||
from attendance import get_members_with_fees, SHEET_ID as ATTENDANCE_SHEET_ID
|
||||
from match_payments import reconcile, fetch_sheet_data, DEFAULT_SPREADSHEET_ID as PAYMENTS_SHEET_ID
|
||||
from match_payments import reconcile, fetch_sheet_data, fetch_exceptions, normalize, DEFAULT_SPREADSHEET_ID as PAYMENTS_SHEET_ID
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@@ -37,14 +37,29 @@ def fees():
|
||||
|
||||
monthly_totals = {m: 0 for m in sorted_months}
|
||||
|
||||
# Get exceptions for formatting
|
||||
credentials_path = ".secret/fuj-management-bot-credentials.json"
|
||||
exceptions = fetch_exceptions(PAYMENTS_SHEET_ID, credentials_path)
|
||||
|
||||
formatted_results = []
|
||||
for name, month_fees in results:
|
||||
row = {"name": name, "months": []}
|
||||
norm_name = normalize(name)
|
||||
for m in sorted_months:
|
||||
fee, count = month_fees.get(m, (0, 0))
|
||||
monthly_totals[m] += fee
|
||||
cell = f"{fee} CZK ({count})" if count > 0 else "-"
|
||||
row["months"].append(cell)
|
||||
|
||||
# Check for exception
|
||||
norm_period = normalize(m)
|
||||
override = exceptions.get((norm_name, norm_period))
|
||||
|
||||
if override is not None and override != fee:
|
||||
cell = f"{override} ({fee}) CZK ({count})" if count > 0 else f"{override} ({fee}) CZK"
|
||||
is_overridden = True
|
||||
else:
|
||||
cell = f"{fee} CZK ({count})" if count > 0 else "-"
|
||||
is_overridden = False
|
||||
row["months"].append({"cell": cell, "overridden": is_overridden})
|
||||
formatted_results.append(row)
|
||||
|
||||
return render_template(
|
||||
@@ -69,7 +84,8 @@ def reconcile_view():
|
||||
return "No data."
|
||||
|
||||
transactions = fetch_sheet_data(PAYMENTS_SHEET_ID, credentials_path)
|
||||
result = reconcile(members, sorted_months, transactions)
|
||||
exceptions = fetch_exceptions(PAYMENTS_SHEET_ID, credentials_path)
|
||||
result = reconcile(members, sorted_months, transactions, exceptions)
|
||||
|
||||
# Format month labels
|
||||
month_labels = {
|
||||
@@ -84,8 +100,9 @@ def reconcile_view():
|
||||
data = result["members"][name]
|
||||
row = {"name": name, "months": [], "balance": data["total_balance"]}
|
||||
for m in sorted_months:
|
||||
mdata = data["months"].get(m, {"expected": 0, "paid": 0})
|
||||
mdata = data["months"].get(m, {"expected": 0, "original_expected": 0, "paid": 0})
|
||||
expected = mdata["expected"]
|
||||
original = mdata["original_expected"]
|
||||
paid = int(mdata["paid"])
|
||||
|
||||
cell_status = ""
|
||||
@@ -106,14 +123,16 @@ def reconcile_view():
|
||||
# Format credits and debts
|
||||
credits = sorted([{"name": n, "amount": a["total_balance"]} for n, a in result["members"].items() if a["total_balance"] > 0], key=lambda x: x["name"])
|
||||
debts = sorted([{"name": n, "amount": abs(a["total_balance"])} for n, a in result["members"].items() if a["total_balance"] < 0], key=lambda x: x["name"])
|
||||
|
||||
# Format unmatched
|
||||
unmatched = result["unmatched"]
|
||||
import json
|
||||
|
||||
return render_template(
|
||||
"reconcile.html",
|
||||
months=[month_labels[m] for m in sorted_months],
|
||||
raw_months=sorted_months,
|
||||
results=formatted_results,
|
||||
member_data=json.dumps(result["members"]),
|
||||
credits=credits,
|
||||
debts=debts,
|
||||
unmatched=unmatched,
|
||||
|
||||
Reference in New Issue
Block a user