mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 10:28:48 +02:00
Convert USD and EUR to CRC in analytics endpoints
All checks were successful
Deploy to VPS / deploy (push) Successful in 13s
All checks were successful
Deploy to VPS / deploy (push) Successful in 13s
All three analytics endpoints (by-category, monthly-trend, daily-spending) now convert foreign currency amounts to CRC using current exchange rates. EUR/CRC rate derived from ExchangeRate-API (USD-based cross rate). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,10 @@ _cache: dict[str, tuple[ExchangeRate, datetime]] = {}
|
||||
_last_known: ExchangeRate | None = None # survives cache expiry — always holds the last successful rate
|
||||
CACHE_TTL = timedelta(hours=1)
|
||||
|
||||
# EUR/CRC mid-market rate cache
|
||||
_eur_crc_cache: dict[str, tuple[float, datetime]] = {}
|
||||
_last_known_eur_crc: float | None = None
|
||||
|
||||
|
||||
def _fetch_bccr_rate(indicator: int, date_str: str) -> float | None:
|
||||
"""Fetch a single indicator from BCCR API."""
|
||||
@@ -167,6 +171,45 @@ def get_current_rate(session: Session) -> ExchangeRate | None:
|
||||
return None
|
||||
|
||||
|
||||
def _fetch_eur_crc_mid() -> float | None:
|
||||
"""Derive EUR/CRC mid-market rate from ExchangeRate-API (USD-based).
|
||||
|
||||
EUR/CRC = CRC_per_USD / EUR_per_USD
|
||||
"""
|
||||
try:
|
||||
resp = httpx.get(EXCHANGERATE_API_URL, timeout=10)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
if data.get("result") == "success":
|
||||
crc = data["rates"].get("CRC")
|
||||
eur = data["rates"].get("EUR")
|
||||
if crc and eur:
|
||||
return float(crc) / float(eur)
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def get_eur_crc_rate() -> float | None:
|
||||
"""Get current EUR→CRC mid-market rate (cached 1 hour)."""
|
||||
global _last_known_eur_crc
|
||||
|
||||
cached = _eur_crc_cache.get("current")
|
||||
if cached and datetime.utcnow() - cached[1] < CACHE_TTL:
|
||||
return cached[0]
|
||||
|
||||
rate = _fetch_eur_crc_mid()
|
||||
if rate is not None:
|
||||
_eur_crc_cache["current"] = (rate, datetime.utcnow())
|
||||
_last_known_eur_crc = rate
|
||||
return rate
|
||||
|
||||
if _last_known_eur_crc:
|
||||
return _last_known_eur_crc
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_rate_history(session: Session, days: int = 30) -> list[ExchangeRate]:
|
||||
"""Get historical exchange rates."""
|
||||
cutoff = datetime.utcnow() - timedelta(days=days)
|
||||
|
||||
Reference in New Issue
Block a user