from __future__ import annotations from datetime import date from decimal import Decimal from difflib import SequenceMatcher from .fingerprints import normalize_counterparty def _date_distance(a: date, b: date) -> int: return abs((a - b).days) def score_event_match( *, amount_a: Decimal, amount_b: Decimal, currency_a: str, currency_b: str, date_a: date, date_b: date, party_a: str | None, party_b: str | None, ) -> float: if currency_a.upper() != currency_b.upper(): return 0.0 amount_score = ( 1.0 if amount_a == amount_b else max(0.0, 1.0 - (abs(amount_a - amount_b) / max(abs(amount_a), Decimal("1")))) ) days = _date_distance(date_a, date_b) date_score = 1.0 if days == 0 else max(0.0, 1.0 - (days / 14)) party_score = SequenceMatcher( None, normalize_counterparty(party_a), normalize_counterparty(party_b), ).ratio() return round((amount_score * 0.45) + (date_score * 0.30) + (party_score * 0.25), 4)