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 TEXT_CHUNK_THOUSAND = 3
|
||||||
private const val POINT_SEPARATOR = '.'
|
private const val POINT_SEPARATOR = '.'
|
||||||
|
private const val COMMA_SEPARATOR = ','
|
||||||
|
const val DECIMAL_SEPARATOR_LIMIT = 1
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun rememberDecimalFormat(): DecimalFormat {
|
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) {
|
private fun Int.getWithIntegerDecimals(before: String, separator: Char, after: String): String = if (this == 0) {
|
||||||
before
|
before
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.data.qrscanning.repository
|
package com.tangem.data.qrscanning.repository
|
||||||
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
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.QrResult
|
||||||
import com.tangem.domain.qrscanning.models.SourceType
|
import com.tangem.domain.qrscanning.models.SourceType
|
||||||
import com.tangem.domain.qrscanning.repository.QrScanningEventsRepository
|
import com.tangem.domain.qrscanning.repository.QrScanningEventsRepository
|
||||||
|
|
@ -44,7 +45,7 @@ internal class DefaultQrScanningEventsRepository : QrScanningEventsRepository {
|
||||||
when (it.key) {
|
when (it.key) {
|
||||||
Parameter.Amount -> {
|
Parameter.Amount -> {
|
||||||
// According to BIP-0021, the value is specified in decimals. No conversion needed
|
// 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.Message,
|
||||||
Parameter.Memo,
|
Parameter.Memo,
|
||||||
|
|
@ -70,7 +71,7 @@ internal class DefaultQrScanningEventsRepository : QrScanningEventsRepository {
|
||||||
-> {
|
-> {
|
||||||
// Extra convert parses scientific notation to decimal
|
// Extra convert parses scientific notation to decimal
|
||||||
// This is necessary to be able comparing BigDecimal values
|
// This is necessary to be able comparing BigDecimal values
|
||||||
result.amount = it.value.toBigDecimalOrNull()
|
result.amount = it.value.parseBigDecimalOrNull()
|
||||||
?.toPlainString()?.toBigDecimalOrNull()
|
?.toPlainString()?.toBigDecimalOrNull()
|
||||||
?.divide(BigDecimal.TEN.pow(cryptoCurrency.decimals))
|
?.divide(BigDecimal.TEN.pow(cryptoCurrency.decimals))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue