from decimal import Decimal, InvalidOperation from typing import Union from money.currency import Currency from xexe.constants import DEFAULT_MAX_DECIMALS DEFAULT_MONEY_PRECISION = DEFAULT_MAX_DECIMALS class MoneyAmount: def __init__(self, amount, currency): self.amount = self._parse_amount(amount) self.currency = self._parse_currency(currency) def _parse_amount(self, amount: Union[int, Decimal, str]): if isinstance(amount, (int, Decimal)): return Decimal(amount).quantize(DEFAULT_MONEY_PRECISION) elif isinstance(amount, str): try: return Decimal(amount).quantize(DEFAULT_MONEY_PRECISION) except InvalidOperation: raise ValueError(f"Invalid amount: {amount}") else: raise TypeError(f"Amount must be int, Decimal, or str, not {type(amount)}") def _parse_currency(self, currency): if isinstance(currency, Currency): return currency if isinstance(currency, str): return Currency[currency] raise TypeError( f"Currency must be a Currency object or str, not {type(currency)}" ) def __eq__(self, other): if isinstance(other, MoneyAmount): return self.amount == other.amount and self.currency == other.currency return False