Skip to content

Commit

Permalink
♻️ Добавил поддержку различной meta-информации по валютам расчётов и …
Browse files Browse the repository at this point in the history
…покрыл тестами текущее поведение класса Currency
  • Loading branch information
esemi committed May 8, 2021
1 parent 54d84c0 commit eeea022
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 26 deletions.
50 changes: 25 additions & 25 deletions investments/currency.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
from enum import Enum
from enum import Enum, unique
from typing import Tuple


@unique
class Currency(Enum):
USD = 1
RUB = 2
EUR = 3
"""
Список поддерживаемых валют следует смотреть на официальном сайте IB.
@see https://www.interactivebrokers.com/en/index.php?f=1323
"""

USD = (('$', 'USD'), '840', 'R01235')
RUB = (('₽', 'RUB', 'RUR'), '643', '')
EUR = (('€', 'EUR'), '978', 'R01239')

def __init__(self, aliases: Tuple[str], iso_code: str, cbr_code: str):
self.iso_code = iso_code
self.cbr_code = cbr_code
self.aliases = aliases

@staticmethod
def parse(strval: str):
if strval in {'$', 'USD'}:
return Currency.USD
if strval in {'₽', 'RUB'}:
return Currency.RUB
if strval in {'€', 'EUR'}:
return Currency.EUR
raise ValueError(strval)
try:
return [item for _, item in Currency.__members__.items() if strval in item.aliases][0]
except IndexError:
raise ValueError(strval)

def __str__(self):
if self == Currency.USD:
return '$'
elif self == Currency.RUB:
return '₽'
elif self == Currency.EUR:
return '€'
return self.__repr__(self)
return str(self.aliases[0])

@property
def iso_numeric_code(self) -> str:
"""
Код валюты в соответствии с общероссийским классификатором валют (ОК (МК (ИСО 4217) 003-97) 014-2000).
Expand All @@ -35,10 +41,4 @@ def iso_numeric_code(self) -> str:
ValueError: if currency is unsupported
"""
if self == Currency.USD:
return '840'
elif self == Currency.RUB:
return '643'
elif self == Currency.EUR:
return '978'
raise ValueError(self)
return self.iso_code
2 changes: 1 addition & 1 deletion investments/ibdds/ibdds.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def show_report(cash: List[Cash]):
withdrawals_amount = dds_specific_round(sum(withdrawals) if withdrawals else Money(0, currency))

report = [
[f'{currency.name} {currency.iso_numeric_code()}', 'Сумма в тысячах единиц'],
[f'{currency.name} {currency.iso_numeric_code}', 'Сумма в тысячах единиц'],
['Остаток денежных средств на счете на начало отчетного периода', begin_amount],
['Зачислено денежных средств за отчетный период', deposits_amount],
['Списано денежных средств за отчетный период', abs(withdrawals_amount)],
Expand Down
35 changes: 35 additions & 0 deletions tests/currency_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import pytest

from investments.currency import Currency


@pytest.mark.parametrize('search_value,res', [
('$', Currency.USD),
('EUR', Currency.EUR),
('RUR', Currency.RUB),
('RUB', Currency.RUB),
('₽', Currency.RUB),
])
def test_parse(search_value: str, res: Currency):
assert Currency.parse(search_value) is res


def test_parse_failure():
with pytest.raises(ValueError):
assert Currency.parse('invalid')


@pytest.mark.parametrize('currency,expected_repr', [
(Currency.USD, '$'),
(Currency.RUB, '₽'),
])
def test_repr(currency: Currency, expected_repr: str):
assert str(currency) == expected_repr


@pytest.mark.parametrize('currency,expected', [
(Currency.USD, '840'),
(Currency.RUB, '643'),
])
def test_iso_numeric_code(currency: Currency, expected: str):
assert currency.iso_numeric_code == expected

0 comments on commit eeea022

Please sign in to comment.