Skip to content

Commit 94ef104

Browse files
raymondjavaxxnickyr
authored andcommitted
Allow constructing money from sub-units. (#5)
* Allow constructing money from sub-units. * Remove unnecessary rounding. * Update README to document sub units conversion. * Disable `too-many-public-methods` check in tests.
1 parent 732210b commit 94ef104

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

README.rst

+10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ A Money object can be created with an amount (specified as a string) and a curre
3030
>>> m
3131
GBP 9.95
3232
33+
Money objects can also be created from and converted to sub units.
34+
35+
.. code:: python
36+
37+
>>> m = Money.from_sub_units(499, Currency.USD)
38+
>>> m
39+
USD 4.99
40+
>>> m.sub_units
41+
499
42+
3343
Money is immutable and supports most mathematical and logical operators.
3444

3545
.. code:: python

money/money.py

+12
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ def currency(self) -> Currency:
2929

3030
return self._currency
3131

32+
@classmethod
33+
def from_sub_units(cls, sub_units: int, currency: Currency=Currency.USD):
34+
"""Creates a Money instance from sub-units."""
35+
sub_units_per_unit = CurrencyHelper.sub_unit_for_currency(currency)
36+
return cls(Decimal(sub_units) / Decimal(sub_units_per_unit), currency)
37+
38+
@property
39+
def sub_units(self) -> int:
40+
"""Converts the amount to sub-units"""
41+
sub_units_per_unit = CurrencyHelper.sub_unit_for_currency(self.currency)
42+
return int(self.amount * sub_units_per_unit)
43+
3244
def __hash__(self) -> str:
3345
return hash((self._amount, self._currency))
3446

money/tests/test_money.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from money.exceptions import InvalidAmountError, CurrencyMismatchError, InvalidOperandError
88

99
# pylint: disable=unneeded-not,expression-not-assigned,no-self-use,missing-docstring
10-
# pylint: disable=misplaced-comparison-constant,singleton-comparison
10+
# pylint: disable=misplaced-comparison-constant,singleton-comparison,too-many-public-methods
1111

1212
class TestMoney:
1313
"""Money tests"""
@@ -36,6 +36,17 @@ def test_construction(self):
3636
# nonfractional currency
3737
Money('10.2', Currency.KRW)
3838

39+
def test_from_sub_units(self):
40+
money = Money.from_sub_units(101, Currency.USD)
41+
assert money == Money('1.01', Currency.USD)
42+
43+
money = Money.from_sub_units(5, Currency.JPY)
44+
assert money == Money('5', Currency.JPY)
45+
46+
def test_sub_units(self):
47+
money = Money('1.01', Currency.USD)
48+
assert money.sub_units == 101
49+
3950
def test_hash(self):
4051
assert hash(Money('1.2')) == hash(Money('1.2', Currency.USD))
4152
assert hash(Money('1.5')) != hash(Money('9.3'))

0 commit comments

Comments
 (0)