From 405523881c8d2365579c5166c87521e253864a95 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 27 Feb 2024 16:09:07 +1100 Subject: [PATCH] Temperature units (#6584) * Update unit conversion - Set autoconvert_offset_to_baseunit attribute - Add aliases for common temperature units - Raise error if invalid target unit is provided * Updated unit tests - Checks for temperature conversion - Checks for invalid units --- InvenTree/InvenTree/conversion.py | 21 ++++++++++++++++++--- InvenTree/InvenTree/tests.py | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/InvenTree/InvenTree/conversion.py b/InvenTree/InvenTree/conversion.py index 8afe30939f..e154dc76f8 100644 --- a/InvenTree/InvenTree/conversion.py +++ b/InvenTree/InvenTree/conversion.py @@ -36,7 +36,12 @@ def reload_unit_registry(): _unit_registry = None - reg = pint.UnitRegistry() + reg = pint.UnitRegistry(autoconvert_offset_to_baseunit=True) + + # Aliases for temperature units + reg.define('@alias degC = celsius = Celsius') + reg.define('@alias degF = fahrenheit = Fahrenheit') + reg.define('@alias degK = kelvin = Kelvin') # Define some "standard" additional units reg.define('piece = 1') @@ -142,6 +147,18 @@ def convert_physical_value(value: str, unit: str = None, strip_units=True): Returns: The converted quantity, in the specified units """ + ureg = get_unit_registry() + + # Check that the provided unit is available in the unit registry + if unit: + try: + valid = unit in ureg + except Exception as exc: + valid = False + + if not valid: + raise ValidationError(_(f'Invalid unit provided ({unit})')) + original = str(value).strip() # Ensure that the value is a string @@ -182,8 +199,6 @@ def convert_physical_value(value: str, unit: str = None, strip_units=True): else: raise ValidationError(_('Invalid quantity supplied')) - ureg = get_unit_registry() - # Calculate the "magnitude" of the value, as a float # If the value is specified strangely (e.g. as a fraction or a dozen), this can cause issues # So, we ensure that it is converted to a floating point value diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 67ac06bde0..8a3d41b528 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -95,6 +95,31 @@ class ConversionTest(TestCase): output = InvenTree.conversion.convert_physical_value(val, strip_units=True) self.assertAlmostEqual(output, expected, 6) + def test_temperature_units(self): + """Test conversion of temperature units. + + Ref: https://github.com/inventree/InvenTree/issues/6495 + """ + tests = [ + ('3.3°F', '°C', -15.944), + ('273°K', '°F', 31.73), + ('900', '°C', 900), + ('900°F', 'degF', 900), + ('900°K', '°C', 626.85), + ('800', 'kelvin', 800), + ('-100°C', 'fahrenheit', -148), + ('-100 °C', 'Fahrenheit', -148), + ('-100 Celsius', 'fahrenheit', -148), + ('-123.45 fahrenheit', 'kelvin', 186.7888), + ('-99Fahrenheit', 'Celsius', -72.7777), + ] + + for val, unit, expected in tests: + output = InvenTree.conversion.convert_physical_value( + val, unit, strip_units=True + ) + self.assertAlmostEqual(output, expected, 3) + def test_base_units(self): """Test conversion to specified base units.""" tests = {