mirror of
https://github.com/pretix/pretix.git
synced 2026-10-01 19:14:43 +00:00
Fix precision issue
This commit is contained in:
@@ -49,6 +49,13 @@ def money_filter(value: Optional[Decimal | float | int | str], arg='', hide_curr
|
||||
raise ValueError("No currency passed.")
|
||||
arg = arg.upper()
|
||||
|
||||
if value.normalize().as_tuple().exponent < -9:
|
||||
# Heuristic: It's unlikely we'll ever see values of less than 0.000000001 in any currency. Therefore, if we
|
||||
# do see them, we very likely deal with a floating point error. This happens mostly in dev mode when computations
|
||||
# are made in SQLite, which uses REAL precision, but it can also happen when we naively pass a float from Python
|
||||
# land to this filter (even though it should not happen).
|
||||
value = value.quantize(Decimal('1e-9'), ROUND_HALF_UP).normalize()
|
||||
|
||||
currency_places = settings.CURRENCY_PLACES.get(arg, 2)
|
||||
required_places = -value.normalize().as_tuple().exponent
|
||||
render_places = max(currency_places, required_places)
|
||||
@@ -108,6 +115,12 @@ def tax_rate_format(number: Optional[Decimal | float | int | str]):
|
||||
number = Decimal('0.00')
|
||||
if not isinstance(number, Decimal):
|
||||
raise TypeError("Invalid data type passed to tax rate format filter: %r" % type(number))
|
||||
if number.normalize().as_tuple().exponent < -9:
|
||||
# Heuristic: It's unlikely we'll ever see values of less than 0.000000001 in any currency. Therefore, if we
|
||||
# do see them, we very likely deal with a floating point error. This happens mostly in dev mode when computations
|
||||
# are made in SQLite, which uses REAL precision, but it can also happen when we naively pass a float from Python
|
||||
# land to this filter (even though it should not happen).
|
||||
number = number.quantize(Decimal('1e-9'), ROUND_HALF_UP).normalize()
|
||||
return mark_safe(
|
||||
formats.number_format(
|
||||
number,
|
||||
|
||||
@@ -60,7 +60,9 @@ def test_urlreplace_replace_parameter():
|
||||
"locale,amount,currency,expected",
|
||||
[
|
||||
("en", None, "USD", "$0.00"),
|
||||
("en", "", "USD", ""),
|
||||
("en", 1000000, "USD", "$1,000,000.00"),
|
||||
("en", 2.23, "USD", "$2.23"),
|
||||
("en", Decimal("1000.00"), "USD", "$1,000.00"),
|
||||
("de", Decimal("1.23"), "EUR", "1,23" + NBSP + "€"),
|
||||
("de", Decimal("1000.00"), "EUR", "1.000,00" + NBSP + "€"),
|
||||
@@ -74,6 +76,7 @@ def test_urlreplace_replace_parameter():
|
||||
|
||||
# deal with precision that is higher than the currency
|
||||
("de", Decimal("1.234"), "EUR", "1,234" + NBSP + "€"),
|
||||
("de", 1.234, "EUR", "1,234" + NBSP + "€"),
|
||||
("de", Decimal("1.2340"), "EUR", "1,234" + NBSP + "€"),
|
||||
("de", Decimal("1.2300"), "EUR", "1,23" + NBSP + "€"),
|
||||
("de", Decimal("1023.1"), "JPY", "1.023,10" + NBSP + "¥"),
|
||||
@@ -118,6 +121,11 @@ def test_money_filter_hidecurrency(locale, amount, currency, expected):
|
||||
("en", Decimal("2.50"), "2.5"),
|
||||
("en", Decimal("4.3e7"), "43000000"),
|
||||
("en", Decimal("2.2340"), "2.234"),
|
||||
("en", "2.23", "2.23"),
|
||||
("en", 2.23, "2.23"),
|
||||
("en", 2, "2"),
|
||||
("en", "", ""),
|
||||
("en", None, "0"),
|
||||
]
|
||||
)
|
||||
def test_tax_rate_format(locale, rate, expected):
|
||||
|
||||
Reference in New Issue
Block a user