91 lines
3.4 KiB
Kotlin
91 lines
3.4 KiB
Kotlin
@file:Suppress("ktlint:filename")
|
|
|
|
package cash.z.ecc.android.sdk.demoapp.ext.ui
|
|
|
|
import cash.z.ecc.android.sdk.demoapp.model.CurrencyConversion
|
|
import cash.z.ecc.android.sdk.demoapp.model.FiatCurrencyConversionRateState
|
|
import cash.z.ecc.android.sdk.demoapp.model.Locale
|
|
import cash.z.ecc.android.sdk.demoapp.model.MonetarySeparators
|
|
import cash.z.ecc.android.sdk.demoapp.model.toJavaLocale
|
|
import cash.z.ecc.android.sdk.ext.Conversions
|
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
|
import kotlinx.datetime.Clock
|
|
import java.math.BigDecimal
|
|
import java.math.MathContext
|
|
import java.math.RoundingMode
|
|
import java.text.DecimalFormat
|
|
import java.text.NumberFormat
|
|
import java.util.Currency
|
|
import kotlin.time.Duration
|
|
|
|
fun Zatoshi.toFiatCurrencyState(
|
|
currencyConversion: CurrencyConversion?,
|
|
locale: Locale,
|
|
monetarySeparators: MonetarySeparators,
|
|
clock: Clock = Clock.System
|
|
): FiatCurrencyConversionRateState {
|
|
if (currencyConversion == null) {
|
|
return FiatCurrencyConversionRateState.Unavailable
|
|
}
|
|
|
|
val fiatCurrencyConversionRate = toFiatString(currencyConversion, locale, monetarySeparators)
|
|
|
|
val currentSystemTime = clock.now()
|
|
|
|
val age = currentSystemTime - currencyConversion.timestamp
|
|
|
|
return if (age < Duration.ZERO && age.absoluteValue > FiatCurrencyConversionRateState.FUTURE_CUTOFF_AGE_INCLUSIVE) {
|
|
// Special case if the device's clock is set to the future.
|
|
// TODO [#535]: Consider using NTP requests to get the correct time instead of relying on the device's clock.
|
|
FiatCurrencyConversionRateState.Unavailable
|
|
} else if (age <= FiatCurrencyConversionRateState.CURRENT_CUTOFF_AGE_INCLUSIVE) {
|
|
FiatCurrencyConversionRateState.Current(fiatCurrencyConversionRate)
|
|
} else if (age <= FiatCurrencyConversionRateState.STALE_CUTOFF_AGE_INCLUSIVE) {
|
|
FiatCurrencyConversionRateState.Stale(fiatCurrencyConversionRate)
|
|
} else {
|
|
FiatCurrencyConversionRateState.Unavailable
|
|
}
|
|
}
|
|
|
|
fun Zatoshi.toFiatString(
|
|
currencyConversion: CurrencyConversion,
|
|
locale: Locale,
|
|
monetarySeparators: MonetarySeparators
|
|
) =
|
|
convertZatoshiToZecDecimal()
|
|
.convertZecDecimalToFiatDecimal(BigDecimal(currencyConversion.priceOfZec))
|
|
.convertFiatDecimalToFiatString(
|
|
Currency.getInstance(currencyConversion.fiatCurrency.code),
|
|
locale.toJavaLocale(),
|
|
monetarySeparators
|
|
)
|
|
|
|
private fun Zatoshi.convertZatoshiToZecDecimal(): BigDecimal {
|
|
return BigDecimal(value, MathContext.DECIMAL128).divide(
|
|
Conversions.ONE_ZEC_IN_ZATOSHI,
|
|
MathContext.DECIMAL128
|
|
).setScale(Conversions.ZEC_FORMATTER.maximumFractionDigits, RoundingMode.HALF_EVEN)
|
|
}
|
|
|
|
private fun BigDecimal.convertZecDecimalToFiatDecimal(zecPrice: BigDecimal): BigDecimal {
|
|
return multiply(zecPrice, MathContext.DECIMAL128)
|
|
}
|
|
|
|
private fun BigDecimal.convertFiatDecimalToFiatString(
|
|
fiatCurrency: Currency,
|
|
locale: java.util.Locale,
|
|
monetarySeparators: MonetarySeparators
|
|
): String {
|
|
return NumberFormat.getCurrencyInstance(locale).apply {
|
|
currency = fiatCurrency
|
|
roundingMode = RoundingMode.HALF_EVEN
|
|
if (this is DecimalFormat) {
|
|
decimalFormatSymbols.apply {
|
|
decimalSeparator = monetarySeparators.decimal
|
|
monetaryDecimalSeparator = monetarySeparators.decimal
|
|
groupingSeparator = monetarySeparators.grouping
|
|
}
|
|
}
|
|
}.format(this)
|
|
}
|