diff --git a/core/ui/src/main/java/com/tangem/core/ui/format/bigdecimal/BigDecimalFiatFormat.kt b/core/ui/src/main/java/com/tangem/core/ui/format/bigdecimal/BigDecimalFiatFormat.kt index 2c29aedd8b..7629ed6986 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/format/bigdecimal/BigDecimalFiatFormat.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/format/bigdecimal/BigDecimalFiatFormat.kt @@ -98,13 +98,22 @@ fun BigDecimalFiatFormatStyled.defaultAmount(spanStyleReference: SpanStyleRefere } val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.decimalSeparator - val formattedAmount = formatter.format(formattingAmount) - .replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol) + val currencySymbol = formatterCurrency.getSymbol(locale) + val rawFormatted = formatter.format(formattingAmount) - val separatorIndex = decimalSeparator?.let { formattedAmount.indexOf(it) } ?: formattedAmount.length + val separatorIndex = decimalSeparator?.let { rawFormatted.indexOf(it).takeIf { i -> i >= 0 } } + ?: rawFormatted.length - val wholePart = formattedAmount.take(separatorIndex) - val fractionalPart = formattedAmount.drop(separatorIndex) + val formattedAmount = rawFormatted.replace(currencySymbol, fiatCurrencySymbol) + val offset = fiatCurrencySymbol.length - currencySymbol.length + val adjustedIndex = if (rawFormatted.indexOf(currencySymbol) in 0 until separatorIndex) { + separatorIndex + offset + } else { + separatorIndex + } + + val wholePart = formattedAmount.take(adjustedIndex) + val fractionalPart = formattedAmount.drop(adjustedIndex) combinedReference( if (formattingAmount.isLessThanThreshold()) stringReference(CAN_BE_LOWER_SIGN) else TextReference.EMPTY, @@ -192,13 +201,22 @@ private fun BigDecimalFiatFormatStyled.price(spanStyleReference: SpanStyleRefere } val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.decimalSeparator - val formattedAmount = formatter.format(priceAmount) - .replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol) + val currencySymbol = formatterCurrency.getSymbol(locale) + val rawFormatted = formatter.format(priceAmount) - val separatorIndex = decimalSeparator?.let { formattedAmount.indexOf(it) } ?: formattedAmount.length + val separatorIndex = decimalSeparator?.let { rawFormatted.indexOf(it).takeIf { i -> i >= 0 } } + ?: rawFormatted.length - val wholePart = formattedAmount.take(separatorIndex) - val fractionalPart = formattedAmount.drop(separatorIndex) + val formattedAmount = rawFormatted.replace(currencySymbol, fiatCurrencySymbol) + val offset = fiatCurrencySymbol.length - currencySymbol.length + val adjustedIndex = if (rawFormatted.indexOf(currencySymbol) in 0 until separatorIndex) { + separatorIndex + offset + } else { + separatorIndex + } + + val wholePart = formattedAmount.take(adjustedIndex) + val fractionalPart = formattedAmount.drop(adjustedIndex) combinedReference( stringReference(wholePart), diff --git a/core/ui/src/test/kotlin/com/tangem/core/ui/format/bigdecimal/BigDecimalFiatFormatTest.kt b/core/ui/src/test/kotlin/com/tangem/core/ui/format/bigdecimal/BigDecimalFiatFormatTest.kt index d5c2cb310e..fcc2eca898 100644 --- a/core/ui/src/test/kotlin/com/tangem/core/ui/format/bigdecimal/BigDecimalFiatFormatTest.kt +++ b/core/ui/src/test/kotlin/com/tangem/core/ui/format/bigdecimal/BigDecimalFiatFormatTest.kt @@ -294,4 +294,52 @@ internal class BigDecimalFiatFormatTest { Truth.assertThat(formatted) .isEqualTo("0.00000000000000000000123".addUsdSymbolLeft()) } + + @Test + fun `price zero is formatted with default precision and does not crash`() { + val testValue = BigDecimal.ZERO + + val formatted = testValue.format { + fiat( + fiatCurrencyCode = usdCurrencyCode, + fiatCurrencySymbol = usdSymbol, + locale = testLocale, + ).price() + } + + Truth.assertThat(formatted) + .isEqualTo("0.00".addUsdSymbolLeft()) + } + + @Test + fun `price negative integer keeps sign and does not crash`() { + val testValue = BigDecimal("-500") + + val formatted = testValue.format { + fiat( + fiatCurrencyCode = usdCurrencyCode, + fiatCurrencySymbol = usdSymbol, + locale = testLocale, + ).price() + } + + Truth.assertThat(formatted) + .isEqualTo("-" + "500.00".addUsdSymbolLeft()) + } + + @Test + fun `price negative fractional keeps sign and does not crash`() { + val testValue = BigDecimal("-0.5") + + val formatted = testValue.format { + fiat( + fiatCurrencyCode = usdCurrencyCode, + fiatCurrencySymbol = usdSymbol, + locale = testLocale, + ).price() + } + + Truth.assertThat(formatted) + .isEqualTo("-" + "0.50".addUsdSymbolLeft()) + } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/converter/MarketsTokenItemConverter.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/converter/MarketsTokenItemConverter.kt index dda2c04ee8..2d25b64eb9 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/converter/MarketsTokenItemConverter.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/converter/MarketsTokenItemConverter.kt @@ -91,7 +91,6 @@ internal class MarketsTokenItemConverter( private fun TokenMarket.getCurrentPrice(prev: TokenMarket? = null): MarketsListItemUM.Price { val prevPrice = prev?.tokenQuotesShort?.currentPrice - val priceText = tokenQuotesShort.currentPrice.format { fiat( fiatCurrencyCode = appCurrency.code,