From f89b0cf01d74e76b83eeac57ed319710f3a4b605 Mon Sep 17 00:00:00 2001 From: Sambo Chea Date: Tue, 9 Feb 2021 15:36:10 +0700 Subject: [PATCH] Fixed auto formatter and auto currency with default from system and custom formatter override and check and extract function --- .../kotlin/com/cubetiqs/money/MoneyConfig.kt | 50 +++++++++++++---- .../com/cubetiqs/money/MoneyFormatter.kt | 56 ++++++++++++++----- .../kotlin/com/cubetiqs/money/MoneyView.kt | 9 ++- 3 files changed, 88 insertions(+), 27 deletions(-) diff --git a/src/main/kotlin/com/cubetiqs/money/MoneyConfig.kt b/src/main/kotlin/com/cubetiqs/money/MoneyConfig.kt index b8525ae..debc051 100644 --- a/src/main/kotlin/com/cubetiqs/money/MoneyConfig.kt +++ b/src/main/kotlin/com/cubetiqs/money/MoneyConfig.kt @@ -1,5 +1,6 @@ package com.cubetiqs.money +import java.lang.Exception import java.util.* import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap @@ -12,10 +13,11 @@ import java.util.concurrent.ConcurrentMap * @since 1.0 */ 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 LOCALES_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. @@ -23,7 +25,7 @@ object MoneyConfig { * Key is the currency * Value is the rate */ - private val configRates: ConcurrentMap = ConcurrentHashMap(CONFIG_INITIAL_SIZE) + private val configRates: ConcurrentMap = ConcurrentHashMap(CONFIG_RATE_INITIAL_SIZE) // use to format the money for each value, if have private val configFormatter: ConcurrentMap = @@ -35,13 +37,27 @@ object MoneyConfig { // use to custom currencies and allow to detect auto, when use auto detect for currencies translate private val configCurrencies: ConcurrentMap = ConcurrentHashMap(CURRENCIES_INITIAL_SIZE) - // use to auto format, when this true - // and formatter for money value, with current locale or custom set locale - private var autoLocaleFormatter: Boolean = false + // allow to use config of any states + private val configs: ConcurrentMap = ConcurrentHashMap(CONFIG_INITIAL_SIZE) - // use to auto format, when this true - // and formatter for money value, with current currency or custom set currency - private var autoCurrencyFormatter: Boolean = false + // allow to set the value into custom config + fun setConfig(key: String, value: Any?) = apply { + if (configs.containsKey(key)) { + configs.replace(key, value) + } else { + this.configs[key] = value + } + } + + // allow to get the value from custom config + fun 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 private var configPrefix: String = "" @@ -58,6 +74,7 @@ object MoneyConfig { "configFormatter" to configFormatter, "configLocales" to configLocales, "configCurrencies" to configCurrencies, + "configs" to configs, ) } @@ -92,15 +109,24 @@ object MoneyConfig { } fun setAutoLocaleFormatter(enabled: Boolean) = apply { - this.autoLocaleFormatter = enabled + setConfig(getConfigKey("autoLocaleFormatter"), enabled) } fun setAutoCurrencyFormatter(enabled: Boolean) = apply { - this.autoCurrencyFormatter = enabled + setConfig(getConfigKey("autoCurrencyFormatter"), enabled) } - fun isAutoLocaleFormatterEnabled() = this.autoLocaleFormatter - fun isAutoCurrencyFormatterEnabled() = this.autoCurrencyFormatter + // use to auto format, when this true + // 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 // example: myOwned_usd diff --git a/src/main/kotlin/com/cubetiqs/money/MoneyFormatter.kt b/src/main/kotlin/com/cubetiqs/money/MoneyFormatter.kt index 7ca58b3..259e876 100644 --- a/src/main/kotlin/com/cubetiqs/money/MoneyFormatter.kt +++ b/src/main/kotlin/com/cubetiqs/money/MoneyFormatter.kt @@ -3,7 +3,6 @@ package com.cubetiqs.money import java.io.Serializable import java.math.RoundingMode import java.text.NumberFormat -import javax.swing.text.NumberFormatter /** * 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 private var value: StdMoney? = null fun setValue(value: StdMoney?) = apply { this.value = value } @@ -42,22 +47,24 @@ class MoneyFormatter( override fun format(): String { value?.getValue() ?: return "" - if (MoneyConfig.isAutoLocaleFormatterEnabled()) { - val systemCurrency = if (MoneyConfig.isAutoCurrencyFormatterEnabled()) { - MoneyConfig.getCurrency() - } else { - value?.getCurrency()?.findCurrency() - } - - if (systemCurrency != null) { - val numberFormatter = NumberFormat.getNumberInstance(MoneyConfig.getLocale()) - numberFormatter.currency = systemCurrency - return numberFormatter.format(value?.getValue()) - } + var autoFormat = if (disableAutoFormat) { + null + } else { + autoFormatValueFromConfig(force = false) } + if (!autoFormat.isNullOrEmpty()) { + return autoFormat + } + + // if don't have the pattern, precision and rounding, will able to use system auto format enabled 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) { @@ -71,6 +78,27 @@ class MoneyFormatter( 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 { const val DEFAULT_FORMATTER = "defaultFormatter" const val DEFAULT_LOCALE = "defaultLocale" diff --git a/src/main/kotlin/com/cubetiqs/money/MoneyView.kt b/src/main/kotlin/com/cubetiqs/money/MoneyView.kt index e2fcdfc..3176e0a 100644 --- a/src/main/kotlin/com/cubetiqs/money/MoneyView.kt +++ b/src/main/kotlin/com/cubetiqs/money/MoneyView.kt @@ -6,7 +6,13 @@ open class MoneyView( ) : MoneyMixin { 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.value = money.getValue() this.currency = this._currency?.getCurrency() @@ -28,6 +34,7 @@ open class MoneyView( return MoneyConfig .getFormatter(getCurrency()) .setValue(this.asStdMoney()) + .setDisableAutoFormat(true) .format() } } \ No newline at end of file