diff --git a/brel/brel_fact.py b/brel/brel_fact.py index 8f64727d..2bf76733 100644 --- a/brel/brel_fact.py +++ b/brel/brel_fact.py @@ -126,11 +126,18 @@ def __bool__(self) -> bool: f"Fact {self.__id} does not have a bool value. It has value {self.__value}, which does not resolve to a bool." ) - def get_value(self) -> str: + def get_value(self) -> Any: """ :returns Any: The value of the fact. The type of the value depends on the type of the fact. """ - return self.__value + if self.get_concept().get_value().is_integer(): + return int(self) + elif self.get_concept().get_value().is_numeric(): + return float(self) + elif self.get_concept().get_value().is_boolean(): + return bool(self) + else: + return self.__value def get_precision(self) -> float | None: """ diff --git a/brel/reportelements/concept.py b/brel/reportelements/concept.py index 96ef229c..0943747b 100644 --- a/brel/reportelements/concept.py +++ b/brel/reportelements/concept.py @@ -23,6 +23,122 @@ from brel.resource import BrelLabel from brel.services.translation.translation_service import TranslationService +textual_types = [ + "domainItemType", + "escapedItemType", + "xmlNodesItemType", + "xmlItemType", + "textBlockItemType", + "guidanceItemType", + "noLangTokenItemType", + "noLangStringItemType", + "prefixedContentItemType", + "prefixedContentType", + "SQNameItemType", + "SQNameType", + "gYearListItemType", + "dateTimeItemType", + "fractionItemType", + "stringItemType", + "booleanItemType", + "hexBinaryItemType", + "base64BinaryItemType", + "anyURIItemType", + "QNameItemType", + "durationItemType", + "dateTimeItemType", + "timeItemType", + "dateItemType", + "gYearMonthItemType", + "gYearItemType", + "gMonthDayItemType", + "gDayItemType", + "gMonthItemType", + "normalizedStringItemType", + "tokenItemType", + "languageItemType", + "NameItemType", + "NCNameItemType", + "financialInstrumentGlobalIdentifierItemType", +] + +numeric_types = [ + "percentItemType", + "perShareItemType", + "areaItemType", + "volumeItemType", + "massItemType", + "weightItemType", + "energyItemType", + "powerItemType", + "lengthItemType", + "memoryItemType", + "noDecimalsMonetaryItemType", + "nonNegativeMonetaryItemType", + "nonNegativeNoDecimalsMonetaryItemType", + "insolationItemType", + "temperatureItemType", + "pressureItemType", + "frequencyItemType", + "irradianceItemType", + "speedItemType", + "planeAngleItemType", + "voltageItemType", + "electricCurrentItemType", + "forceItemType", + "electricChargeItemType", + "flowItemType", + "massFlowItemType", + "monetaryPerLengthItemType", + "monetaryPerAreaItemType", + "monetaryPerVolumeItemType", + "monetaryPerDurationItemType", + "monetaryPerEnergyItemType", + "monetaryPerMassItemType", + "ghgEmissionsItemType", + "energyPerMonetaryItemType", + "ghgEmissionsPerMonetaryItemType", + "volumePerMonetaryItemType", + "decimalItemType", + "floatItemType", + "doubleItemType", + "integerItemType", + "nonPositiveIntegerItemType", + "negativeIntegerItemType", + "longItemType", + "intItemType", + "shortItemType", + "byteItemType", + "nonNegativeIntegerItemType", + "unsignedLongItemType", + "unsignedIntItemType", + "unsignedShortItemType", + "unsignedByteItemType", + "positiveIntegerItemType", + "monetaryItemType", + "sharesItemType", + "pureItemType", + "perUnitItemType", +] + +integer_types = [ + "noDecimalsMonetaryItemType", + "nonNegativeNoDecimalsMonetaryItemType", + "integerItemType", + "nonPositiveIntegerItemType", + "negativeIntegerItemType", + "longItemType", + "intItemType", + "shortItemType", + "byteItemType", + "nonNegativeIntegerItemType", + "unsignedLongItemType", + "unsignedIntItemType", + "unsignedShortItemType", + "unsignedByteItemType", + "positiveIntegerItemType", +] + class Concept(IReportElement): """ @@ -107,6 +223,34 @@ def get_data_type(self) -> str: """ return self.__data_type + def is_textual(self) -> bool: + """ + Check if the concept is of a textual type. + :returns bool: True 'IFF' the concept is of a textual type, False otherwise + """ + return self.__data_type.split(":")[-1] in textual_types + + def is_numeric(self) -> bool: + """ + Check if the concept is of a numeric type. + :returns bool: True 'IFF' the concept is of a numeric type, False otherwise + """ + return self.__data_type.split(":")[-1] in numeric_types + + def is_integer(self) -> bool: + """ + Check if the concept is of an integer type. + :returns bool: True 'IFF' the concept is of an integer type, False otherwise + """ + return self.__data_type.split(":")[-1] in integer_types + + def is_boolean(self) -> bool: + """ + Check if the concept is of a boolean type. + :returns bool: True 'IFF' the concept is of a boolean type, False otherwise + """ + return self.__data_type.split(":")[-1] == "booleanItemType" + def get_balance_type(self) -> str | None: """ Get the balance type of the concept. diff --git a/tests/core_tests/test_fact.py b/tests/core_tests/test_fact.py index 22d8f70e..a195427b 100644 --- a/tests/core_tests/test_fact.py +++ b/tests/core_tests/test_fact.py @@ -65,7 +65,7 @@ def test_qname_getters(): assert isinstance(int(fact), int), "Expected int as fact value is int" assert int(fact) > 1000000, "Expected apples gross profit to be > 1M" - assert isinstance(float(fact), float), "Expected float as fact value is float" + assert isinstance(fact.get_value(), float), "Expected float as fact value is float" assert float(fact) > 1000000, "Expected apples gross profit to be > 1M" try: # check if parsing a false fact as bool works bool(fact)