mirror of
https://github.com/inventree/InvenTree.git
synced 2025-11-13 19:36:46 +00:00
* Improvements for format_number func
- Prevent accidental rendering in scientific notation
* Add multiplier argument to format_number
(cherry picked from commit c1bbef1a4d)
Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
committed by
GitHub
parent
485e4ae178
commit
babe952bcf
@@ -453,6 +453,7 @@ def render_html_text(text: str, **kwargs):
|
|||||||
def format_number(
|
def format_number(
|
||||||
number: Union[int, float, Decimal],
|
number: Union[int, float, Decimal],
|
||||||
decimal_places: Optional[int] = None,
|
decimal_places: Optional[int] = None,
|
||||||
|
multiplier: Optional[Union[int, float, Decimal]] = None,
|
||||||
integer: bool = False,
|
integer: bool = False,
|
||||||
leading: int = 0,
|
leading: int = 0,
|
||||||
separator: Optional[str] = None,
|
separator: Optional[str] = None,
|
||||||
@@ -462,16 +463,20 @@ def format_number(
|
|||||||
Arguments:
|
Arguments:
|
||||||
number: The number to be formatted
|
number: The number to be formatted
|
||||||
decimal_places: Number of decimal places to render
|
decimal_places: Number of decimal places to render
|
||||||
|
multiplier: Optional multiplier to apply to the number before formatting
|
||||||
integer: Boolean, whether to render the number as an integer
|
integer: Boolean, whether to render the number as an integer
|
||||||
leading: Number of leading zeros (default = 0)
|
leading: Number of leading zeros (default = 0)
|
||||||
separator: Character to use as a thousands separator (default = None)
|
separator: Character to use as a thousands separator (default = None)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
number = Decimal(str(number))
|
number = Decimal(str(number).strip())
|
||||||
except Exception:
|
except Exception:
|
||||||
# If the number cannot be converted to a Decimal, just return the original value
|
# If the number cannot be converted to a Decimal, just return the original value
|
||||||
return str(number)
|
return str(number)
|
||||||
|
|
||||||
|
if multiplier is not None:
|
||||||
|
number *= Decimal(str(multiplier).strip())
|
||||||
|
|
||||||
if integer:
|
if integer:
|
||||||
# Convert to integer
|
# Convert to integer
|
||||||
number = Decimal(int(number))
|
number = Decimal(int(number))
|
||||||
@@ -487,7 +492,13 @@ def format_number(
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# Re-encode, and normalize again
|
# Re-encode, and normalize again
|
||||||
value = Decimal(number).normalize()
|
# Ensure that the output never uses scientific notation
|
||||||
|
value = Decimal(number)
|
||||||
|
value = (
|
||||||
|
value.quantize(Decimal(1))
|
||||||
|
if value == value.to_integral()
|
||||||
|
else value.normalize()
|
||||||
|
)
|
||||||
|
|
||||||
if separator:
|
if separator:
|
||||||
value = f'{value:,}'
|
value = f'{value:,}'
|
||||||
|
|||||||
@@ -210,6 +210,14 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase):
|
|||||||
"""Simple tests for number formatting tags."""
|
"""Simple tests for number formatting tags."""
|
||||||
fn = report_tags.format_number
|
fn = report_tags.format_number
|
||||||
|
|
||||||
|
self.assertEqual(fn(None), 'None')
|
||||||
|
|
||||||
|
for i in [1, '1', '1.0000', ' 1 ']:
|
||||||
|
self.assertEqual(fn(i), '1')
|
||||||
|
|
||||||
|
for x in ['10.000000', ' 10 ', 10.000000, 10]:
|
||||||
|
self.assertEqual(fn(x), '10')
|
||||||
|
|
||||||
self.assertEqual(fn(1234), '1234')
|
self.assertEqual(fn(1234), '1234')
|
||||||
self.assertEqual(fn(1234.5678, decimal_places=2), '1234.57')
|
self.assertEqual(fn(1234.5678, decimal_places=2), '1234.57')
|
||||||
self.assertEqual(fn(1234.5678, decimal_places=3), '1234.568')
|
self.assertEqual(fn(1234.5678, decimal_places=3), '1234.568')
|
||||||
@@ -218,6 +226,9 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase):
|
|||||||
fn(9988776655.4321, integer=True, separator=' '), '9 988 776 655'
|
fn(9988776655.4321, integer=True, separator=' '), '9 988 776 655'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Test with multiplier
|
||||||
|
self.assertEqual(fn(1000, multiplier=1.5), '1500')
|
||||||
|
|
||||||
# Failure cases
|
# Failure cases
|
||||||
self.assertEqual(fn('abc'), 'abc')
|
self.assertEqual(fn('abc'), 'abc')
|
||||||
self.assertEqual(fn(1234.456, decimal_places='a'), '1234.456')
|
self.assertEqual(fn(1234.456, decimal_places='a'), '1234.456')
|
||||||
|
|||||||
Reference in New Issue
Block a user