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
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<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
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
private val configCurrencies: ConcurrentMap<String, Currency> = 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<String, Any?> = 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 <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
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

View File

@ -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"

View File

@ -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()
}
}