from __future__ import annotations from dataclasses import replace from decimal import Decimal from broker_sync.fx import FxCache, convert_to_gbp from broker_sync.models import Activity, ActivityType _QTY_PRICE_TYPES = {ActivityType.BUY, ActivityType.SELL} def normalise_to_gbp(activity: Activity, *, cache: FxCache) -> Activity: """Return a copy of `activity` with amount_gbp/fx_rate_gbp/fx_rate_source set. Two cases: - BUY/SELL: amount_gbp = quantity * unit_price * rate. - Everything else (DIVIDEND/DEPOSIT/FEE/...): amount_gbp = amount * rate. Source is always the cache's source tag (ECB_LIVE or HMRC_MONTHLY). """ on_date = activity.date.date() if activity.activity_type in _QTY_PRICE_TYPES: assert activity.quantity is not None and activity.unit_price is not None native_total: Decimal = activity.quantity * activity.unit_price else: assert activity.amount is not None native_total = activity.amount amount_gbp, rate, source = convert_to_gbp(native_total, activity.currency, on_date, cache=cache) return replace( activity, amount_gbp=amount_gbp, fx_rate_gbp=rate, fx_rate_source=source, )