Updated on 2026-08-14
This commit is contained in:
commit
a136c0bfdf
2 changed files with 36 additions and 2 deletions
|
|
@ -11,6 +11,8 @@ import java.util.Locale
|
|||
|
||||
private const val TEXT_CHUNK_THOUSAND = 3
|
||||
private const val POINT_SEPARATOR = '.'
|
||||
private const val COMMA_SEPARATOR = ','
|
||||
const val DECIMAL_SEPARATOR_LIMIT = 1
|
||||
|
||||
@Composable
|
||||
fun rememberDecimalFormat(): DecimalFormat {
|
||||
|
|
@ -152,6 +154,37 @@ fun BigDecimal.parseBigDecimal(decimals: Int, roundingMode: RoundingMode = Round
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Universal amount string parser to [BigDecimal]
|
||||
* Able to parse values with only ONE separator, assuming separator is COMMA.
|
||||
* Otherwise returns null.
|
||||
*/
|
||||
fun String.parseBigDecimalOrNull() = runCatching {
|
||||
// Filtering value containing more than one either grouping or decimal separator.
|
||||
// We assume there will be only decimal separator, otherwise parsing will fail.
|
||||
if (count { !it.isDigit() } > DECIMAL_SEPARATOR_LIMIT) return null
|
||||
|
||||
// An attempt to parse value with POINT decimal separator
|
||||
val parsed = this.toBigDecimalOrNull()
|
||||
|
||||
if (parsed == null) {
|
||||
// If parsing with POINT separator fails trying to parse with COMMA separator
|
||||
val decimalFormatSymbol = DecimalFormatSymbols().apply {
|
||||
decimalSeparator = COMMA_SEPARATOR
|
||||
}
|
||||
val decimalFormat = DecimalFormat().apply {
|
||||
decimalFormatSymbols = decimalFormatSymbol
|
||||
isParseBigDecimal = true
|
||||
}
|
||||
|
||||
// Return either number or null if fails
|
||||
decimalFormat.parse(this) as? BigDecimal
|
||||
} else {
|
||||
// If parsing with POINT separator succeeds return number
|
||||
parsed
|
||||
}
|
||||
}.getOrNull()
|
||||
|
||||
private fun Int.getWithIntegerDecimals(before: String, separator: Char, after: String): String = if (this == 0) {
|
||||
before
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.data.qrscanning.repository
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.core.ui.utils.parseBigDecimalOrNull
|
||||
import com.tangem.domain.qrscanning.models.QrResult
|
||||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.qrscanning.repository.QrScanningEventsRepository
|
||||
|
|
@ -44,7 +45,7 @@ internal class DefaultQrScanningEventsRepository : QrScanningEventsRepository {
|
|||
when (it.key) {
|
||||
Parameter.Amount -> {
|
||||
// According to BIP-0021, the value is specified in decimals. No conversion needed
|
||||
result.amount = it.value.toBigDecimalOrNull()
|
||||
result.amount = it.value.parseBigDecimalOrNull()
|
||||
}
|
||||
Parameter.Message,
|
||||
Parameter.Memo,
|
||||
|
|
@ -70,7 +71,7 @@ internal class DefaultQrScanningEventsRepository : QrScanningEventsRepository {
|
|||
-> {
|
||||
// Extra convert parses scientific notation to decimal
|
||||
// This is necessary to be able comparing BigDecimal values
|
||||
result.amount = it.value.toBigDecimalOrNull()
|
||||
result.amount = it.value.parseBigDecimalOrNull()
|
||||
?.toPlainString()?.toBigDecimalOrNull()
|
||||
?.divide(BigDecimal.TEN.pow(cryptoCurrency.decimals))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue