Files
fuj-management/docs/scripts.md
Jan Novak 3bfea4e0a4 feat: initial dashboard implementation and robust attendance parsing
- Added a Makefile to easily run project scripts (fees, match, web, image)
- Modified attendance.py to dynamically handle a variable number of header rows from the Google Sheet
- Updated both attendance calculations and calculate_fees terminal output to show actual attendance counts (e.g., '750 CZK (3)')
- Created a Flask web dashboard (app.py and templates/fees.html) to view member fees in an attractive, condensed, terminal-like UI
- Bound the Flask server to port 5000 and added a routing alias from '/' to '/fees'
- Configured Python virtual environment (.venv) creation directly into the Makefile to resolve global pip install errors on macOS

Co-authored-by: Antigravity <antigravity@deepmind.com>
2026-02-27 13:20:42 +01:00

3.0 KiB

Scripts

All scripts live in scripts/ and use Python 3.10+ with stdlib only (no pip dependencies).

calculate_fees.py

Calculates monthly fees for each Adult member based on Tuesday practice attendance.

cd scripts && python3 calculate_fees.py

Outputs a table of Adult members with their monthly fee (0 / 200 / 750 CZK) and totals per month. Data is fetched live from the Google Sheet.

match_payments.py

Matches incoming bank payments against expected fees to produce a reconciliation report.

cd scripts && python3 match_payments.py [--from YYYY-MM-DD] [--to YYYY-MM-DD]
Option Default Description
--from 2025-12-01 Start of date range for bank transactions
--to today End of date range

Bank data access is controlled by the FIO_API_TOKEN environment variable:

  • Set — uses the Fio REST API (JSON, structured data, all fields)
  • Not set — scrapes the public transparent account HTML page
# With API token:
FIO_API_TOKEN=xxx python3 match_payments.py --from 2026-01-01 --to 2026-02-11

# Without (public page):
python3 match_payments.py --from 2026-01-01 --to 2026-02-11

Report sections:

  1. Summary table — per member, per month: OK / UNPAID {amount} / {paid}/{expected} + balance
  2. Credits — advance payments for months without attendance data yet
  3. Unmatched transactions — payments the script couldn't assign to any member
  4. Matched transaction details — full breakdown of which payment was assigned where, with [REVIEW] tags on low-confidence matches

Known limitations:

  • Lump-sum payments covering multiple months are split evenly rather than by actual per-month fee
  • Messages with no member name and a sender not in the member list cannot be matched
  • Common surnames (Novák) are excluded from last-name-only matching to avoid false positives

Shared modules

attendance.py

Shared attendance and fee logic, imported by both scripts above.

Key functions:

Function Description
fetch_csv() Fetches the Google Sheet as parsed CSV rows
parse_dates(header_row) Extracts (column_index, date) pairs from the header
group_by_month(dates) Groups column indices by YYYY-MM
calculate_fee(count) Applies fee rules: 0→0, 1→200, 2+→750 CZK
get_members(rows) Parses member rows into (name, tier, row) tuples
get_members_with_fees() Full pipeline: fetch → parse → compute fees. Returns (members, sorted_months)

czech_utils.py

Czech language text utilities.

Function Description
normalize(text) Strip diacritics and lowercase (Štrúdlstrudl)
parse_month_references(text) Extract YYYY-MM strings from Czech free text. Handles month names in all declensions (leden, ledna, lednu), numeric formats (01/26, 11+12/2025), dot notation (12.2025), and ranges (listopad-leden)
CZECH_MONTHS Dict mapping normalized Czech month names (all declensions) to month numbers