fix: include juniors in payment-inference roster
Some checks failed
Deploy to K8s / deploy (push) Successful in 10s
Build and Push / build (push) Successful in 6s
Build and Push / build-go (push) Failing after 12m23s

infer_payments was building member_names from get_members_with_fees()
(adults sheet only). Junior-only members were invisible to the matcher,
so a payment message containing an exact junior name would produce a
fuzzy review match against a different adult sharing the same first name.

Fix: union the adult and junior rosters (deduped via canonical_member_key)
so all members are candidates. The existing exact-name short-circuit in
match_members then handles precedence correctly.

Two regression tests added for the Jáchym Kubík / Jáchym Hrušák case.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 16:38:21 +02:00
parent 3e597242eb
commit c5a8a4e7b1
4 changed files with 168 additions and 5 deletions

View File

@@ -11,8 +11,8 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from googleapiclient.discovery import build
from sync_fio_to_sheets import get_sheets_service, DEFAULT_SPREADSHEET_ID
from match_payments import infer_transaction_details
from attendance import get_members_with_fees
from match_payments import infer_transaction_details, canonical_member_key
from attendance import get_members_with_fees, get_junior_members_with_fees
def parse_czk_amount(val) -> float:
"""Parse Czech currency string or handle raw numeric value."""
@@ -96,10 +96,19 @@ def infer_payments(spreadsheet_id: str, credentials_path: str, dry_run: bool = F
print(f"Current header: {header}")
return
# 2. Fetch members for matching
# 2. Fetch members for matching — union adults + juniors so junior-only
# members (e.g. kids not on the adult sheet) are visible to the matcher.
print("Fetching member list for matching...")
members_data, _ = get_members_with_fees()
member_names = [m[0] for m in members_data]
adult_members, _ = get_members_with_fees()
junior_members, _ = get_junior_members_with_fees()
seen: set[str] = set()
member_names: list[str] = []
for m in adult_members + junior_members:
key = canonical_member_key(m[0])
if key not in seen:
seen.add(key)
member_names.append(m[0])
# 3. Process rows
print("Inferring details for empty rows...")