Fixed auto formatter and auto currency with default from system and custom formatter override and check and extract function

This commit is contained in:
Sambo Chea 2021-02-09 15:36:10 +07:00
parent 8509c578ca
commit f89b0cf01d
3 changed files with 88 additions and 27 deletions

View File

@ -1,5 +1,6 @@
package com.cubetiqs.money package com.cubetiqs.money
import java.lang.Exception
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap import java.util.concurrent.ConcurrentMap
@ -12,10 +13,11 @@ import java.util.concurrent.ConcurrentMap
* @since 1.0 * @since 1.0
*/ */
object MoneyConfig { object MoneyConfig {
private const val CONFIG_INITIAL_SIZE = 10 private const val CONFIG_RATE_INITIAL_SIZE = 10
private const val CONFIG_FORMATTER_INITIAL_SIZE = 10 private const val CONFIG_FORMATTER_INITIAL_SIZE = 10
private const val LOCALES_INITIAL_SIZE = 5 private const val LOCALES_INITIAL_SIZE = 5
private const val CURRENCIES_INITIAL_SIZE = 5 private const val CURRENCIES_INITIAL_SIZE = 5
private const val CONFIG_INITIAL_SIZE = 50
/** /**
* All money currencies and its rate are stored in memory state for exchange or compute the value. * All money currencies and its rate are stored in memory state for exchange or compute the value.
@ -23,7 +25,7 @@ object MoneyConfig {
* Key is the currency * Key is the currency
* Value is the rate * Value is the rate
*/ */
private val configRates: ConcurrentMap<String, Double> = ConcurrentHashMap(CONFIG_INITIAL_SIZE) private val configRates: ConcurrentMap<String, Double> = ConcurrentHashMap(CONFIG_RATE_INITIAL_SIZE)
// use to format the money for each value, if have // use to format the money for each value, if have
private val configFormatter: ConcurrentMap<String, MoneyFormatProvider> = private val configFormatter: ConcurrentMap<String, MoneyFormatProvider> =
@ -35,13 +37,27 @@ object MoneyConfig {
// use to custom currencies and allow to detect auto, when use auto detect for currencies translate // use to custom currencies and allow to detect auto, when use auto detect for currencies translate
private val configCurrencies: ConcurrentMap<String, Currency> = ConcurrentHashMap(CURRENCIES_INITIAL_SIZE) private val configCurrencies: ConcurrentMap<String, Currency> = ConcurrentHashMap(CURRENCIES_INITIAL_SIZE)
// use to auto format, when this true // allow to use config of any states
// and formatter for money value, with current locale or custom set locale private val configs: ConcurrentMap<String, Any?> = ConcurrentHashMap(CONFIG_INITIAL_SIZE)
private var autoLocaleFormatter: Boolean = false
// use to auto format, when this true // allow to set the value into custom config
// and formatter for money value, with current currency or custom set currency fun setConfig(key: String, value: Any?) = apply {
private var autoCurrencyFormatter: Boolean = false if (configs.containsKey(key)) {
configs.replace(key, value)
} else {
this.configs[key] = value
}
}
// allow to get the value from custom config
fun <T> getConfigOrDefault(key: String, defaultValue: T? = null): T? {
return (try {
@Suppress("UNCHECKED_CAST")
configs[key] as? T
} catch (ex: Exception) {
null
}) ?: defaultValue
}
// use to identified for config dataset with prefix mode // use to identified for config dataset with prefix mode
private var configPrefix: String = "" private var configPrefix: String = ""
@ -58,6 +74,7 @@ object MoneyConfig {
"configFormatter" to configFormatter, "configFormatter" to configFormatter,
"configLocales" to configLocales, "configLocales" to configLocales,
"configCurrencies" to configCurrencies, "configCurrencies" to configCurrencies,
"configs" to configs,
) )
} }
@ -92,15 +109,24 @@ object MoneyConfig {
} }
fun setAutoLocaleFormatter(enabled: Boolean) = apply { fun setAutoLocaleFormatter(enabled: Boolean) = apply {
this.autoLocaleFormatter = enabled setConfig(getConfigKey("autoLocaleFormatter"), enabled)
} }
fun setAutoCurrencyFormatter(enabled: Boolean) = apply { fun setAutoCurrencyFormatter(enabled: Boolean) = apply {
this.autoCurrencyFormatter = enabled setConfig(getConfigKey("autoCurrencyFormatter"), enabled)
} }
fun isAutoLocaleFormatterEnabled() = this.autoLocaleFormatter // use to auto format, when this true
fun isAutoCurrencyFormatterEnabled() = this.autoCurrencyFormatter // and formatter for money value, with current locale or custom set locale
fun isAutoLocaleFormatterEnabled(): Boolean {
return getConfigOrDefault(getConfigKey("autoLocaleFormatter"), false) ?: false
}
// use to auto format, when this true
// and formatter for money value, with current currency or custom set currency
fun isAutoCurrencyFormatterEnabled(): Boolean {
return getConfigOrDefault(getConfigKey("autoCurrencyFormatter"), false) ?: false
}
// get custom config key within currency generally // get custom config key within currency generally
// example: myOwned_usd // example: myOwned_usd

View File

@ -3,7 +3,6 @@ package com.cubetiqs.money
import java.io.Serializable import java.io.Serializable
import java.math.RoundingMode import java.math.RoundingMode
import java.text.NumberFormat import java.text.NumberFormat
import javax.swing.text.NumberFormatter
/** /**
* Money Formatter (Final class) * Money Formatter (Final class)
@ -27,6 +26,12 @@ class MoneyFormatter(
} }
} }
// allow to force the auto format from money config
private var disableAutoFormat: Boolean = true
fun setDisableAutoFormat(disabled: Boolean) = apply {
this.disableAutoFormat = disabled
}
// when want to format the value for each of them, need to parse the money value here // when want to format the value for each of them, need to parse the money value here
private var value: StdMoney? = null private var value: StdMoney? = null
fun setValue(value: StdMoney?) = apply { this.value = value } fun setValue(value: StdMoney?) = apply { this.value = value }
@ -42,22 +47,24 @@ class MoneyFormatter(
override fun format(): String { override fun format(): String {
value?.getValue() ?: return "" value?.getValue() ?: return ""
if (MoneyConfig.isAutoLocaleFormatterEnabled()) { var autoFormat = if (disableAutoFormat) {
val systemCurrency = if (MoneyConfig.isAutoCurrencyFormatterEnabled()) { null
MoneyConfig.getCurrency()
} else { } else {
value?.getCurrency()?.findCurrency() autoFormatValueFromConfig(force = false)
} }
if (systemCurrency != null) { if (!autoFormat.isNullOrEmpty()) {
val numberFormatter = NumberFormat.getNumberInstance(MoneyConfig.getLocale()) return autoFormat
numberFormatter.currency = systemCurrency
return numberFormatter.format(value?.getValue())
}
} }
// if don't have the pattern, precision and rounding, will able to use system auto format enabled
if (getPattern() == null && getPrecision() < 0 && getRoundingMode() == null) { if (getPattern() == null && getPrecision() < 0 && getRoundingMode() == null) {
return value?.getValue().toString() autoFormat = autoFormatValueFromConfig(force = true)
return if (autoFormat.isNullOrEmpty()) {
value?.getValue().toString()
} else {
autoFormat
}
} }
if (getPrecision() > -1) { if (getPrecision() > -1) {
@ -71,6 +78,27 @@ class MoneyFormatter(
return value?.asMoneyString(overrideSymbol) ?: "" return value?.asMoneyString(overrideSymbol) ?: ""
} }
private fun autoFormatValueFromConfig(force: Boolean): String? {
if (force || MoneyConfig.isAutoLocaleFormatterEnabled()) {
val systemCurrency = if (MoneyConfig.isAutoCurrencyFormatterEnabled()) {
MoneyConfig.getCurrency()
} else {
value?.getCurrency()?.findCurrency()
}
if (systemCurrency != null) {
val numberFormatter = NumberFormat.getNumberInstance(MoneyConfig.getLocale())
if (getRoundingMode() != null) {
numberFormatter.roundingMode = getRoundingMode()
}
numberFormatter.currency = systemCurrency
return numberFormatter.format(value?.getValue())
}
}
return null
}
companion object { companion object {
const val DEFAULT_FORMATTER = "defaultFormatter" const val DEFAULT_FORMATTER = "defaultFormatter"
const val DEFAULT_LOCALE = "defaultLocale" const val DEFAULT_LOCALE = "defaultLocale"

View File

@ -6,7 +6,13 @@ open class MoneyView(
) : MoneyMixin { ) : MoneyMixin {
private var _currency: StdMoney.Currency? = null private var _currency: StdMoney.Currency? = null
constructor(money: StdMoney) : this() { constructor(value: StdMoney) : this() {
val money = if (MoneyConfig.isAutoCurrencyFormatterEnabled()) {
value exchangeTo MoneyConfig.getCurrency().currencyCode
} else {
value
}
this._currency = money.getCurrency() this._currency = money.getCurrency()
this.value = money.getValue() this.value = money.getValue()
this.currency = this._currency?.getCurrency() this.currency = this._currency?.getCurrency()
@ -28,6 +34,7 @@ open class MoneyView(
return MoneyConfig return MoneyConfig
.getFormatter(getCurrency()) .getFormatter(getCurrency())
.setValue(this.asStdMoney()) .setValue(this.asStdMoney())
.setDisableAutoFormat(true)
.format() .format()
} }
} }