Further work on decimal rounding

- Prevent numbers from being represented in scientific notation
This commit is contained in:
Oliver Walters 2020-04-12 00:56:15 +10:00
parent 04cee99791
commit 3c46e12839
4 changed files with 31 additions and 10 deletions

View File

@ -11,6 +11,8 @@ from django.core import validators
from django import forms from django import forms
from decimal import Decimal from decimal import Decimal
from InvenTree.helpers import normalize
class InvenTreeURLFormField(FormURLField): class InvenTreeURLFormField(FormURLField):
""" Custom URL form field with custom scheme validators """ """ Custom URL form field with custom scheme validators """
@ -53,7 +55,7 @@ class RoundingDecimalFormField(forms.DecimalField):
""" """
if type(value) == Decimal: if type(value) == Decimal:
return value.normalize() return normalize(value)
else: else:
return value return value

View File

@ -8,6 +8,8 @@ import json
import os.path import os.path
from PIL import Image from PIL import Image
from decimal import Decimal
from wsgiref.util import FileWrapper from wsgiref.util import FileWrapper
from django.http import StreamingHttpResponse from django.http import StreamingHttpResponse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@ -104,6 +106,20 @@ def isNull(text):
return str(text).strip().lower() in ['top', 'null', 'none', 'empty', 'false', '-1', ''] return str(text).strip().lower() in ['top', 'null', 'none', 'empty', 'false', '-1', '']
def normalize(d):
"""
Normalize a decimal number, and remove exponential formatting.
"""
if type(d) is not Decimal:
d = Decimal(d)
d = d.normalize()
# Ref: https://docs.python.org/3/library/decimal.html
return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
def decimal2string(d): def decimal2string(d):
""" """
Format a Decimal number as a string, Format a Decimal number as a string,
@ -117,6 +133,9 @@ def decimal2string(d):
A string representation of the input number A string representation of the input number
""" """
if type(d) is Decimal:
d = normalize(d)
try: try:
# Ensure that the provided string can actually be converted to a float # Ensure that the provided string can actually be converted to a float
float(d) float(d)

View File

@ -96,8 +96,8 @@ class CompanySimpleTest(TestCase):
def test_part_pricing(self): def test_part_pricing(self):
m2x4 = Part.objects.get(name='M2x4 LPHS') m2x4 = Part.objects.get(name='M2x4 LPHS')
self.assertEqual(m2x4.get_price_info(10), "70.00000 - 75.00000") self.assertEqual(m2x4.get_price_info(10), "70 - 75")
self.assertEqual(m2x4.get_price_info(100), "125.00000 - 350.00000") self.assertEqual(m2x4.get_price_info(100), "125 - 350")
pmin, pmax = m2x4.get_price_range(5) pmin, pmax = m2x4.get_price_range(5)
self.assertEqual(pmin, 35) self.assertEqual(pmin, 35)

View File

@ -37,7 +37,7 @@ from InvenTree import helpers
from InvenTree import validators from InvenTree import validators
from InvenTree.models import InvenTreeTree, InvenTreeAttachment from InvenTree.models import InvenTreeTree, InvenTreeAttachment
from InvenTree.fields import InvenTreeURLField from InvenTree.fields import InvenTreeURLField
from InvenTree.helpers import decimal2string from InvenTree.helpers import decimal2string, normalize
from InvenTree.status_codes import BuildStatus, StockStatus, OrderStatus from InvenTree.status_codes import BuildStatus, StockStatus, OrderStatus
@ -781,8 +781,8 @@ class Part(models.Model):
if min_price == max_price: if min_price == max_price:
return min_price return min_price
min_price = min_price.normalize() min_price = normalize(min_price)
max_price = max_price.normalize() max_price = normalize(max_price)
return "{a} - {b}".format(a=min_price, b=max_price) return "{a} - {b}".format(a=min_price, b=max_price)
@ -807,8 +807,8 @@ class Part(models.Model):
if min_price is None or max_price is None: if min_price is None or max_price is None:
return None return None
min_price = min_price.normalize() min_price = normalize(min_price)
max_price = max_price.normalize() max_price = normalize(max_price)
return (min_price, max_price) return (min_price, max_price)
@ -843,8 +843,8 @@ class Part(models.Model):
if min_price is None or max_price is None: if min_price is None or max_price is None:
return None return None
min_price = min_price.normalize() min_price = normalize(min_price)
max_price = max_price.normalize() max_price = normalize(max_price)
return (min_price, max_price) return (min_price, max_price)