swap Money for MoneyAmount, fix a couple of things along the way
This commit is contained in:
parent
ab2ac1ec6a
commit
0947b34ebf
6 changed files with 26 additions and 27 deletions
|
|
@ -108,11 +108,10 @@ def test_get_rates_dry_run_always_returns_42_as_rates():
|
||||||
# Check that all rows have the expected rate of 42, 1/42 or 1 and the correct dates
|
# Check that all rows have the expected rate of 42, 1/42 or 1 and the correct dates
|
||||||
for row in rows:
|
for row in rows:
|
||||||
assert row["rate"] in (
|
assert row["rate"] in (
|
||||||
"42",
|
"42.00000000",
|
||||||
"0.024",
|
"0.02380952",
|
||||||
"0.02",
|
"0.00000000",
|
||||||
"0",
|
"1.00000000",
|
||||||
"1",
|
|
||||||
), f"Expected rate to be 42, 1/42 or 1, but got {row['rate']}"
|
), f"Expected rate to be 42, 1/42 or 1, but got {row['rate']}"
|
||||||
assert row["rate_date"] in [
|
assert row["rate_date"] in [
|
||||||
(some_random_date + datetime.timedelta(days=i)).strftime("%Y-%m-%d")
|
(some_random_date + datetime.timedelta(days=i)).strftime("%Y-%m-%d")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from decimal import Decimal
|
||||||
import pytest
|
import pytest
|
||||||
from money.currency import Currency
|
from money.currency import Currency
|
||||||
|
|
||||||
from xexe.money_amount import DEFAULT_MAX_DECIMALS, MoneyAmount
|
from xexe.money_amount import DEFAULT_MONEY_PRECISION, MoneyAmount
|
||||||
|
|
||||||
|
|
||||||
def test_money_amount_simple_creation_works():
|
def test_money_amount_simple_creation_works():
|
||||||
|
|
@ -23,13 +23,13 @@ def test_money_amount_takes_integer_amounts():
|
||||||
def test_money_amount_takes_decimal_amounts():
|
def test_money_amount_takes_decimal_amounts():
|
||||||
an_amount = MoneyAmount(amount=Decimal(10.5), currency=Currency.USD)
|
an_amount = MoneyAmount(amount=Decimal(10.5), currency=Currency.USD)
|
||||||
|
|
||||||
assert an_amount.amount == Decimal(10.5).quantize(DEFAULT_MAX_DECIMALS)
|
assert an_amount.amount == Decimal(10.5).quantize(DEFAULT_MONEY_PRECISION)
|
||||||
|
|
||||||
|
|
||||||
def test_money_amount_takes_proper_strings_amounts():
|
def test_money_amount_takes_proper_strings_amounts():
|
||||||
an_amount = MoneyAmount(amount="10.55", currency=Currency.USD)
|
an_amount = MoneyAmount(amount="10.55", currency=Currency.USD)
|
||||||
|
|
||||||
assert an_amount.amount == Decimal(10.55).quantize(DEFAULT_MAX_DECIMALS)
|
assert an_amount.amount == Decimal(10.55).quantize(DEFAULT_MONEY_PRECISION)
|
||||||
|
|
||||||
|
|
||||||
def test_money_amount_fails_with_ugly_strings():
|
def test_money_amount_fails_with_ugly_strings():
|
||||||
|
|
@ -46,4 +46,4 @@ def test_money_amount_takes_string_for_currency():
|
||||||
def test_money_amount_works_with_8_decimal_positions():
|
def test_money_amount_works_with_8_decimal_positions():
|
||||||
an_amount = MoneyAmount(amount="1.12345678", currency="USD")
|
an_amount = MoneyAmount(amount="1.12345678", currency="USD")
|
||||||
|
|
||||||
assert an_amount.amount == Decimal(1.12345678).quantize(DEFAULT_MAX_DECIMALS)
|
assert an_amount.amount == Decimal(1.12345678).quantize(DEFAULT_MONEY_PRECISION)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import pathlib
|
import pathlib
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
from money.currency import Currency
|
from money.currency import Currency
|
||||||
|
|
||||||
|
|
@ -8,8 +7,6 @@ from xexe.rate_fetching import MockRateFetcher, XERateFetcher
|
||||||
|
|
||||||
DEFAULT_CURRENCIES = {Currency("EUR"), Currency("GBP"), Currency("USD")}
|
DEFAULT_CURRENCIES = {Currency("EUR"), Currency("GBP"), Currency("USD")}
|
||||||
|
|
||||||
DEFAULT_MAX_DECIMALS = Decimal("0.00000001")
|
|
||||||
|
|
||||||
RATES_SOURCES = {"mock": MockRateFetcher, "xe": XERateFetcher}
|
RATES_SOURCES = {"mock": MockRateFetcher, "xe": XERateFetcher}
|
||||||
|
|
||||||
DWH_SCHEMA = "sync_xedotcom_currency_rates"
|
DWH_SCHEMA = "sync_xedotcom_currency_rates"
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@ from decimal import Decimal
|
||||||
from numbers import Number
|
from numbers import Number
|
||||||
from typing import Iterable, Set, Union
|
from typing import Iterable, Set, Union
|
||||||
|
|
||||||
from money.currency import Currency, CurrencyHelper
|
from money.currency import Currency
|
||||||
from money.money import Money
|
|
||||||
|
from xexe.money_amount import DEFAULT_MONEY_PRECISION_POSITIONS, MoneyAmount
|
||||||
|
|
||||||
|
|
||||||
class ExchangeRate:
|
class ExchangeRate:
|
||||||
|
|
@ -13,13 +14,13 @@ class ExchangeRate:
|
||||||
self,
|
self,
|
||||||
from_currency: Currency,
|
from_currency: Currency,
|
||||||
to_currency: Currency,
|
to_currency: Currency,
|
||||||
rate: Union[Money, Number, str],
|
rate: Union[MoneyAmount, Number, str],
|
||||||
rate_date: datetime.date,
|
rate_date: datetime.date,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.from_currency = from_currency
|
self.from_currency = from_currency
|
||||||
self.to_currency = to_currency
|
self.to_currency = to_currency
|
||||||
if not isinstance(rate, Money):
|
if not isinstance(rate, MoneyAmount):
|
||||||
rate = Money(rate, to_currency)
|
rate = MoneyAmount(amount=rate, currency=to_currency)
|
||||||
self.rate = rate
|
self.rate = rate
|
||||||
self.rate_date = rate_date
|
self.rate_date = rate_date
|
||||||
|
|
||||||
|
|
@ -100,7 +101,7 @@ def add_equal_rates(rates: ExchangeRates, overwrite: bool = False) -> ExchangeRa
|
||||||
new_rate = ExchangeRate(
|
new_rate = ExchangeRate(
|
||||||
from_currency=currency,
|
from_currency=currency,
|
||||||
to_currency=currency,
|
to_currency=currency,
|
||||||
rate=Money(1, currency),
|
rate=MoneyAmount(1, currency),
|
||||||
rate_date=date,
|
rate_date=date,
|
||||||
)
|
)
|
||||||
if new_rate in rates and not overwrite:
|
if new_rate in rates and not overwrite:
|
||||||
|
|
@ -122,7 +123,7 @@ def add_inverse_rates(rates: ExchangeRates) -> ExchangeRates:
|
||||||
from_currency=rate.to_currency,
|
from_currency=rate.to_currency,
|
||||||
to_currency=rate.from_currency,
|
to_currency=rate.from_currency,
|
||||||
rate_date=rate.rate_date,
|
rate_date=rate.rate_date,
|
||||||
rate=f"{1 / rate.amount:.{CurrencyHelper.decimal_precision_for_currency(rate.from_currency)}f}",
|
rate=f"{1 / rate.amount:.{DEFAULT_MONEY_PRECISION_POSITIONS}f}",
|
||||||
)
|
)
|
||||||
rates.add_rate(inverse_rate)
|
rates.add_rate(inverse_rate)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,12 @@ from typing import Union
|
||||||
|
|
||||||
from money.currency import Currency
|
from money.currency import Currency
|
||||||
|
|
||||||
from xexe.constants import DEFAULT_MAX_DECIMALS
|
DEFAULT_MONEY_PRECISION_POSITIONS = 8
|
||||||
|
DEFAULT_MONEY_PRECISION = Decimal(
|
||||||
DEFAULT_MONEY_PRECISION = DEFAULT_MAX_DECIMALS
|
"0." + ("0" * (DEFAULT_MONEY_PRECISION_POSITIONS - 1)) + "1"
|
||||||
|
)
|
||||||
|
# If we have X decimal positions, we want 7 zeros and 1 one
|
||||||
|
# i.e. 0. 000 000 01
|
||||||
|
|
||||||
|
|
||||||
class MoneyAmount:
|
class MoneyAmount:
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
from money.currency import Currency, CurrencyHelper
|
from money.currency import Currency
|
||||||
from money.money import Money
|
|
||||||
from xecd_rates_client import XecdClient
|
from xecd_rates_client import XecdClient
|
||||||
|
|
||||||
from xexe.exchange_rates import ExchangeRate
|
from xexe.exchange_rates import ExchangeRate
|
||||||
|
from xexe.money_amount import DEFAULT_MONEY_PRECISION_POSITIONS, MoneyAmount
|
||||||
|
|
||||||
|
|
||||||
class RateFetcher(ABC):
|
class RateFetcher(ABC):
|
||||||
|
|
@ -35,7 +34,7 @@ class MockRateFetcher(RateFetcher):
|
||||||
return ExchangeRate(
|
return ExchangeRate(
|
||||||
from_currency=from_currency,
|
from_currency=from_currency,
|
||||||
to_currency=to_currency,
|
to_currency=to_currency,
|
||||||
rate=Money(42, to_currency),
|
rate=MoneyAmount(42, to_currency),
|
||||||
rate_date=rate_date,
|
rate_date=rate_date,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -71,7 +70,7 @@ class XERateFetcher(RateFetcher):
|
||||||
"Z", "+00:00"
|
"Z", "+00:00"
|
||||||
) # Funny replace is necessary because of API response format
|
) # Funny replace is necessary because of API response format
|
||||||
).date()
|
).date()
|
||||||
rate = f"""{response["to"][0]["mid"]:.{CurrencyHelper.decimal_precision_for_currency(to_currency)}f}"""
|
rate = f"""{response["to"][0]["mid"]:.{DEFAULT_MONEY_PRECISION_POSITIONS}f}"""
|
||||||
|
|
||||||
return ExchangeRate(
|
return ExchangeRate(
|
||||||
from_currency=from_currency,
|
from_currency=from_currency,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue