diff --git a/shared/ui/core/src/main/java/com/ivy/ui/FormatMoneyUseCase.kt b/shared/ui/core/src/main/java/com/ivy/ui/FormatMoneyUseCase.kt index bc0114e044..d1aed35b19 100644 --- a/shared/ui/core/src/main/java/com/ivy/ui/FormatMoneyUseCase.kt +++ b/shared/ui/core/src/main/java/com/ivy/ui/FormatMoneyUseCase.kt @@ -7,6 +7,11 @@ import dagger.hilt.android.qualifiers.ApplicationContext import java.text.DecimalFormat import java.text.DecimalFormatSymbols import javax.inject.Inject +import kotlin.math.abs + +const val THOUSAND = 1_000 +const val MILLION = 1_000_000 +const val BILLION = 1_000_000_000 class FormatMoneyUseCase @Inject constructor( private val features: Features, @@ -17,13 +22,26 @@ class FormatMoneyUseCase @Inject constructor( private val locale = devicePreferences.locale() private val withoutDecimalFormatter = DecimalFormat("###,###", DecimalFormatSymbols(locale)) private val withDecimalFormatter = DecimalFormat("###,###.00", DecimalFormatSymbols(locale)) + private val shortenAmountFormatter = DecimalFormat("###,###.##", DecimalFormatSymbols(locale)) - suspend fun format(value: Double): String { - val showDecimalPoint = features.showDecimalNumber.isEnabled(context) + suspend fun format(value: Double, shortenAmount: Boolean): String { + if (abs(value) >= THOUSAND && shortenAmount) { + val result = if (abs(value) >= BILLION) { + "${shortenAmountFormatter.format(value / BILLION)}b" + } else if (abs(value) >= MILLION) { + "${shortenAmountFormatter.format(value / MILLION)}m" + } else { + "${shortenAmountFormatter.format(value / THOUSAND)}k" + } + return result + } else { + val showDecimalPoint = features.showDecimalNumber.isEnabled(context) - return when (showDecimalPoint) { - true -> withDecimalFormatter.format(value) - false -> withoutDecimalFormatter.format(value) + val formatter = when (showDecimalPoint) { + true -> withDecimalFormatter + false -> withoutDecimalFormatter + } + return formatter.format(value) } } } \ No newline at end of file diff --git a/shared/ui/core/src/test/java/com/ivy/ui/FormatMoneyUseCaseTest.kt b/shared/ui/core/src/test/java/com/ivy/ui/FormatMoneyUseCaseTest.kt index 4a98251c3f..a477fcbda6 100644 --- a/shared/ui/core/src/test/java/com/ivy/ui/FormatMoneyUseCaseTest.kt +++ b/shared/ui/core/src/test/java/com/ivy/ui/FormatMoneyUseCaseTest.kt @@ -23,33 +23,80 @@ class FormatMoneyUseCaseTest { enum class MoneyFormatterTestCase( val amount: Double, val showDecimal: Boolean, + val shortenAmount: Boolean, val locale: Locale, val expectedOutput: String ) { ENG_SHOW_DECIMAL( - amount = 1000.12, + amount = 1_000.12, showDecimal = true, + shortenAmount = false, locale = Locale.ENGLISH, expectedOutput = "1,000.12" ), ENG_HIDE_DECIMAL( - amount = 1000.12, + amount = 1_000.12, showDecimal = false, + shortenAmount = false, locale = Locale.ENGLISH, expectedOutput = "1,000" ), GERMAN_SHOW_DECIMAL( - amount = 1000.12, + amount = 1_000.12, showDecimal = true, + shortenAmount = false, locale = Locale.GERMAN, expectedOutput = "1.000,12" ), GERMAN_HIDE_DECIMAL( - amount = 1000.12, + amount = 1_000.12, showDecimal = false, + shortenAmount = false, locale = Locale.GERMAN, expectedOutput = "1.000" ), + ENGLISH_1K_SHORT_AMT( + amount = 13_000.10, + showDecimal = true, + shortenAmount = true, + locale = Locale.ENGLISH, + expectedOutput = "13k" + ), + ENGLISH_MILLION_SHORT_AMT( + amount = 1_233_500.10, + showDecimal = true, + shortenAmount = true, + locale = Locale.ENGLISH, + expectedOutput = "1.23m" + ), + ENGLISH_BILLION_SHORT_AMT( + amount = 1_233_000_000.10, + showDecimal = true, + shortenAmount = true, + locale = Locale.ENGLISH, + expectedOutput = "1.23b" + ), + GERMAN_1K_SHORT_AMT( + amount = 13_000.10, + showDecimal = true, + shortenAmount = true, + locale = Locale.GERMAN, + expectedOutput = "13k" + ), + GERMAN_MILLION_SHORT_AMT( + amount = 1_233_500.10, + showDecimal = true, + shortenAmount = true, + locale = Locale.GERMAN, + expectedOutput = "1,23m" + ), + GERMAN_BILLION_SHORT_AMT( + amount = 1_233_000_000.10, + showDecimal = true, + shortenAmount = true, + locale = Locale.GERMAN, + expectedOutput = "1,23b" + ), } private lateinit var formatMoneyUseCase: FormatMoneyUseCase @@ -65,7 +112,10 @@ class FormatMoneyUseCaseTest { formatMoneyUseCase = FormatMoneyUseCase(features, devicePreferences, context) // when - val result = formatMoneyUseCase.format(value = testCase.amount) + val result = formatMoneyUseCase.format( + value = testCase.amount, + shortenAmount = testCase.shortenAmount + ) // then result shouldBe testCase.expectedOutput