# 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. ```bash 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. ```bash 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 ```bash # 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údl` → `strudl`) | | `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 |