41 lines
1.0 KiB
Python
41 lines
1.0 KiB
Python
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)
|