@@ -13,6 +13,15 @@ const val THOUSAND = 1_000
13
13
const val MILLION = 1_000_000
14
14
const val BILLION = 1_000_000_000
15
15
16
+ /* *
17
+ * A use case class responsible for formatting currency and cryptocurrency values based on user preferences.
18
+ * It supports regular currency formatting with or without decimal places, as well as shortened formats
19
+ * (e.g., "1k", "1m"). For cryptocurrency, it formats up to 9 decimal places and removes unnecessary trailing zeros.
20
+ *
21
+ * @property features Provides feature toggles to customize app behavior.
22
+ * @property devicePreferences Manages user-specific preferences for locale and other device settings.
23
+ * @property context Application context, used for feature check and resource access.
24
+ */
16
25
class FormatMoneyUseCase @Inject constructor(
17
26
private val features : Features ,
18
27
private val devicePreferences : DevicePreferences ,
@@ -23,25 +32,69 @@ class FormatMoneyUseCase @Inject constructor(
23
32
private val withoutDecimalFormatter = DecimalFormat (" ###,###" , DecimalFormatSymbols (locale))
24
33
private val withDecimalFormatter = DecimalFormat (" ###,###.00" , DecimalFormatSymbols (locale))
25
34
private val shortenAmountFormatter = DecimalFormat (" ###,###.##" , DecimalFormatSymbols (locale))
35
+ private val cryptoFormatter =
36
+ DecimalFormat (" ###,###,##0.${" 0" .repeat(9 )} " , DecimalFormatSymbols (locale))
26
37
27
- suspend fun format (value : Double , shortenAmount : Boolean ): String {
28
- if (abs(value) >= THOUSAND && shortenAmount) {
29
- val result = if (abs(value) >= BILLION ) {
38
+ /* *
39
+ * Formats a currency or cryptocurrency amount based on the input parameters.
40
+ *
41
+ * @param value The numeric value to format.
42
+ * @param shortenAmount Flag to indicate if the amount should be shortened (e.g., "1k" for 1,000).
43
+ * @param isCrypto Flag to indicate if the value is a cryptocurrency, enabling up to 9 decimal places.
44
+ * @return The formatted string representation of the value.
45
+ */
46
+ suspend fun format (value : Double , shortenAmount : Boolean , isCrypto : Boolean = false): String {
47
+ val result = if (isCrypto) {
48
+ formatCrypto(value)
49
+ } else if (abs(value) >= THOUSAND && shortenAmount) {
50
+ if (abs(value) >= BILLION ) {
30
51
" ${shortenAmountFormatter.format(value / BILLION )} b"
31
52
} else if (abs(value) >= MILLION ) {
32
53
" ${shortenAmountFormatter.format(value / MILLION )} m"
33
54
} else {
34
55
" ${shortenAmountFormatter.format(value / THOUSAND )} k"
35
56
}
36
- return result
37
57
} else {
38
58
val showDecimalPoint = features.showDecimalNumber.isEnabled(context)
39
59
40
60
val formatter = when (showDecimalPoint) {
41
61
true -> withDecimalFormatter
42
62
false -> withoutDecimalFormatter
43
63
}
44
- return formatter.format(value)
64
+ formatter.format(value)
45
65
}
66
+
67
+ return result
68
+ }
69
+
70
+ /* *
71
+ * Formats a cryptocurrency value with up to 9 decimal places, removing unnecessary trailing zeros.
72
+ *
73
+ * @param value The cryptocurrency value to format.
74
+ * @return The formatted cryptocurrency value as a string.
75
+ */
76
+ private fun formatCrypto (value : Double ): String {
77
+ val result = cryptoFormatter.format(value)
78
+ return when {
79
+ result.lastOrNull() == localDecimalSeparator().firstOrNull() -> {
80
+ val newResult = result.dropLast(1 )
81
+ newResult.ifEmpty { " 0" }
82
+ }
83
+
84
+ result.isEmpty() -> {
85
+ " 0"
86
+ }
87
+
88
+ else -> result
89
+ }
90
+ }
91
+
92
+ /* *
93
+ * Retrieves the local decimal separator based on the user's locale.
94
+ *
95
+ * @return The decimal separator as a string.
96
+ */
97
+ private fun localDecimalSeparator (): String {
98
+ return DecimalFormatSymbols (locale).decimalSeparator.toString()
46
99
}
47
- }
100
+ }
0 commit comments