Skip to content

Commit

Permalink
Merge pull request #555 from wearebasti/bugfix-decimal-display-521
Browse files Browse the repository at this point in the history
Fix: provide option to set decimal_places_display explicitly #521
  • Loading branch information
benjaoming committed Dec 29, 2020
2 parents abd4a69 + 58dc300 commit 63088db
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 5 deletions.
19 changes: 16 additions & 3 deletions djmoney/money.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from moneyed import Currency, Money as DefaultMoney
from moneyed.localization import _FORMATTER, format_money

from .settings import DECIMAL_PLACES
from .settings import DECIMAL_PLACES, DECIMAL_PLACES_DISPLAY


__all__ = ["Money", "Currency"]
Expand All @@ -22,10 +22,23 @@ class Money(DefaultMoney):

use_l10n = None

def __init__(self, *args, **kwargs):
def __init__(self, *args, decimal_places_display=None, **kwargs):
self.decimal_places = kwargs.pop("decimal_places", DECIMAL_PLACES)
self._decimal_places_display = decimal_places_display
super().__init__(*args, **kwargs)

@property
def decimal_places_display(self):
if self._decimal_places_display is None:
return DECIMAL_PLACES_DISPLAY.get(self.currency.code, self.decimal_places)

return self._decimal_places_display

@decimal_places_display.setter
def decimal_places_display(self, value):
""" Set number of digits being displayed - `None` resets to `DECIMAL_PLACES_DISPLAY` setting """
self._decimal_places_display = value

def _fix_decimal_places(self, *args):
""" Make sure to user 'biggest' number of decimal places of all given money instances """
candidates = (getattr(candidate, "decimal_places", 0) for candidate in args)
Expand Down Expand Up @@ -74,7 +87,7 @@ def is_localized(self):
return self.use_l10n

def __str__(self):
kwargs = {"money": self, "decimal_places": self.decimal_places}
kwargs = {"money": self, "decimal_places": self.decimal_places_display}
if self.is_localized:
locale = get_current_locale()
if locale:
Expand Down
3 changes: 3 additions & 0 deletions djmoney/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

CURRENCY_CHOICES.sort(key=operator.itemgetter(1, 0))
DECIMAL_PLACES = getattr(settings, "CURRENCY_DECIMAL_PLACES", 2)
DECIMAL_PLACES_DISPLAY = getattr(
settings, "CURRENCY_DECIMAL_PLACES_DISPLAY", {currency[0]: DECIMAL_PLACES for currency in CURRENCY_CHOICES}
)

OPEN_EXCHANGE_RATES_URL = getattr(settings, "OPEN_EXCHANGE_RATES_URL", "https://openexchangerates.org/api/latest.json")
OPEN_EXCHANGE_RATES_APP_ID = getattr(settings, "OPEN_EXCHANGE_RATES_APP_ID", None)
Expand Down
7 changes: 7 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Changelog
`Unreleased`_ - TBD
-------------------

**Added**

- Improved localization: New setting ``CURRENCY_DECIMAL_PLACES_DISPLAY`` configures decimal places to display for each configured currency `#521`_ (`wearebasti`_)


`1.2.2`_ - 2020-12-29
---------------------

Expand Down Expand Up @@ -780,8 +785,10 @@ wrapping with ``money_manager``.
.. _#418: https://github.com/django-money/django-money/issues/418
.. _#411: https://github.com/django-money/django-money/issues/411
.. _#519: https://github.com/django-money/django-money/issues/519
.. _#521: https://github.com/django-money/django-money/issues/521
.. _#522: https://github.com/django-money/django-money/issues/522


.. _77cc33: https://github.com/77cc33
.. _AlexRiina: https://github.com/AlexRiina
.. _carvincarl: https://github.com/carvincarl
Expand Down
28 changes: 26 additions & 2 deletions tests/test_money.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,23 @@ def test_round():


def test_configurable_decimal_number():
# Override default configuration per instance
assert str(Money("10.543", "USD", decimal_places=3)) == "$10.543"
# Override default configuration per instance, keeps human readable output to default
mny = Money("10.543", "USD", decimal_places=3)
assert str(mny) == "$10.54"
assert mny.decimal_places == 3


def test_localize_decimal_places_default():
# use default decimal display places from settings
assert str(Money("10.543125", "USD")) == "$10.54"


def test_localize_decimal_places_overwrite():
assert str(Money("10.543125", "USD", decimal_places_display=4)) == "$10.5431"


def test_localize_decimal_places_both():
assert str(Money("10.543125", "USD", decimal_places=5, decimal_places_display=1)) == "$10.5"


def test_add_decimal_places():
Expand Down Expand Up @@ -90,3 +105,12 @@ def test_fix_decimal_places_none():
def test_fix_decimal_places_multiple():
one = Money(1, "USD", decimal_places=7)
assert one._fix_decimal_places(None, Money(3, "USD", decimal_places=8)) == 8


def test_decimal_places_display_overwrite():
number = Money("1.23456789", "USD")
assert str(number) == "$1.23"
number.decimal_places_display = 5
assert str(number) == "$1.23457"
number.decimal_places_display = None
assert str(number) == "$1.23"

0 comments on commit 63088db

Please sign in to comment.