Compare commits
13 Commits
003e1a59db
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
9b328c93c7
|
|||
|
6deb73600d
|
|||
|
|
aaf3c6aea8 | ||
| c4e7f514cb | |||
| f6914f5282 | |||
| 88abd05184 | |||
|
|
78578cf1cc | ||
|
|
c5395b89ef | ||
| 0a330a0bc1 | |||
| f89b0cf01d | |||
| 8509c578ca | |||
| 1a447f1954 | |||
| 0676972a83 |
139
README.md
Normal file
139
README.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Money Object Module
|
||||
- Allow to do better with money module
|
||||
- Exchangeable for different currencies with custom override
|
||||
- Add money config able to custom by set of config
|
||||
- So on.
|
||||
|
||||
### Example (Tests)
|
||||
```kotlin
|
||||
import com.cubetiqs.money.*
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
|
||||
class MoneyTests {
|
||||
private fun initMoneyConfig() {
|
||||
applyMoneyConfig {
|
||||
setProperties(buildMoneyConfigProperties {
|
||||
setDeliEqual(':')
|
||||
setDeliSplit(',')
|
||||
})
|
||||
|
||||
fromJsonRates(MyBatchRates.getJsonRates())
|
||||
}
|
||||
}
|
||||
|
||||
object MyBatchRates {
|
||||
fun getJsonRates(): String {
|
||||
return """
|
||||
{"USD": 1.0,"KHR": 4000.0, "eur": 0.5}
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun exchange_2usd_to_khr_test() {
|
||||
initMoneyConfig()
|
||||
|
||||
// Is valid for money config?
|
||||
Assert.assertTrue(MoneyConfig.isConfigRatesValid())
|
||||
|
||||
// arithmetic operators calculation
|
||||
val moneyUsd =
|
||||
(2 withCurrency "usd") divideWith (2 withCurrency "usd") plusOf 1 minusOf 1 plusOf 1 multiplyOf 2 divideOf 2 divideWith (8000 withCurrency "khr") plusOf 1
|
||||
val moneyKhr = moneyUsd exchangeTo "khr"
|
||||
|
||||
// Is correct exchange?
|
||||
Assert.assertEquals(8000.0, moneyKhr.getValue(), 0.0)
|
||||
|
||||
// complex operators and exchanging
|
||||
val sum =
|
||||
((moneyUsd + moneyKhr) * Money.TEN) exchangeTo MoneyCurrency.KHR minusWith (Money.ONE exchangeTo MoneyCurrency.KHR)
|
||||
|
||||
Assert.assertEquals(156000.0, sum.getValue(), 0.0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun moneyGenerator() {
|
||||
initMoneyConfig()
|
||||
|
||||
val moneyGen = MoneyObject(
|
||||
value = 1.0,
|
||||
currency = "usd",
|
||||
operator = MoneyObject.MoneyOperator.PLUS,
|
||||
with = MoneyObject(
|
||||
value = 8000.0,
|
||||
currency = "khr",
|
||||
operator = MoneyObject.MoneyOperator.MINUS,
|
||||
with = MoneyObject(
|
||||
value = 1000.0,
|
||||
currency = "khr",
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val result = moneyGen.compute()
|
||||
Assert.assertEquals(2.75, result.getValue(), 0.0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun moneyGeneratorBuilder() {
|
||||
initMoneyConfig()
|
||||
|
||||
val expected = 72000.0
|
||||
|
||||
val builder = MoneyObject.builder()
|
||||
.with(10.0, "usd", '+')
|
||||
.with(1.5, "eur", '+')
|
||||
.with(8000.0, "khr")
|
||||
.with(10000.0, "khr")
|
||||
.with(2000.0, "khr")
|
||||
.with(.5, "eur", '-')
|
||||
.with(1.0, "usd")
|
||||
.withCurrency("khr")
|
||||
.build()
|
||||
|
||||
val result = builder.compute()
|
||||
Assert.assertEquals(expected, result.getValue(), 0.0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun moneyGeneratorBuilderWithStringValues() {
|
||||
initMoneyConfig()
|
||||
|
||||
val values = "usd:1:+,khr:4000:-,usd:1:+,eur:1:+" // result = 3
|
||||
val expected1 = 3.0
|
||||
val expected2 = 3.5
|
||||
|
||||
val builder = MoneyObject.builder()
|
||||
.withCurrency("usd")
|
||||
.with(1.0, "usd", '-')
|
||||
.with(4000.0, "khr")
|
||||
.with(1.0, "usd")
|
||||
.with(1.0, "usd")
|
||||
.with(1.0, "usd")
|
||||
.with(1.0, "usd")
|
||||
.with(1.0, "eur", '-') // 2 usd
|
||||
.with(1.0, "usd")
|
||||
.with(2.0, "usd", '/')
|
||||
.with(2.0, "usd")
|
||||
.build() // 3.5
|
||||
|
||||
val result1 = MoneyObject.builder()
|
||||
.parseFromString(values)
|
||||
.withCurrency("usd")
|
||||
.build()
|
||||
.compute()
|
||||
val result2 = builder.compute()
|
||||
|
||||
Assert.assertEquals(expected1, result1.getValue(), 0.0)
|
||||
Assert.assertEquals(expected2, result2.getValue(), 0.0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun moneyFormatterTest() {
|
||||
val systemCurrency = Currency.getInstance("USD").symbol
|
||||
println(systemCurrency)
|
||||
}
|
||||
}
|
||||
```
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,5 +1,10 @@
|
||||
package com.cubetiqs.money
|
||||
|
||||
import java.lang.Exception
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.ConcurrentMap
|
||||
|
||||
/**
|
||||
* Default money config in static object.
|
||||
* Sample parse format: USD=1,KHR=4000,EUR=0.99
|
||||
@@ -8,27 +13,74 @@ package com.cubetiqs.money
|
||||
* @since 1.0
|
||||
*/
|
||||
object MoneyConfig {
|
||||
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.
|
||||
*
|
||||
* Key is the currency
|
||||
* Value is the rate
|
||||
*/
|
||||
private val config: MutableMap<String, Double> = mutableMapOf()
|
||||
private val configRates: ConcurrentMap<String, Double> = ConcurrentHashMap(CONFIG_RATE_INITIAL_SIZE)
|
||||
|
||||
// use to format the money for each value, if have
|
||||
private val configFormatter: MutableMap<String, MoneyFormatProvider> = mutableMapOf()
|
||||
private val configFormatter: ConcurrentMap<String, MoneyFormatProvider> =
|
||||
ConcurrentHashMap(CONFIG_FORMATTER_INITIAL_SIZE)
|
||||
|
||||
// use to custom locales and allow to detect auto formatter, if enable auto locale format
|
||||
private val configLocales: ConcurrentMap<String, Locale> = ConcurrentHashMap(LOCALES_INITIAL_SIZE)
|
||||
|
||||
// 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)
|
||||
|
||||
// allow to use config of any states
|
||||
private val configs: ConcurrentMap<String, Any?> = ConcurrentHashMap(CONFIG_INITIAL_SIZE)
|
||||
|
||||
// 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 = ""
|
||||
private fun isConfigPrefixValid() = configPrefix.isNotEmpty() && configPrefix.isNotBlank()
|
||||
|
||||
// use to fallback, if the currency not found
|
||||
// if the fallback greater than ZERO, then called it
|
||||
// else throws
|
||||
private var fallbackRate: Double = 0.0
|
||||
|
||||
// validate the config, if have it's valid
|
||||
fun isValid(): Boolean {
|
||||
return config.isNotEmpty()
|
||||
fun getConfigs(): Map<String, Any?> {
|
||||
return mapOf(
|
||||
"configRates" to configRates,
|
||||
"configFormatter" to configFormatter,
|
||||
"configLocales" to configLocales,
|
||||
"configCurrencies" to configCurrencies,
|
||||
"configs" to configs,
|
||||
)
|
||||
}
|
||||
|
||||
// validate the config rates, if have it's valid
|
||||
fun isConfigRatesValid(): Boolean {
|
||||
return configRates.isNotEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +108,26 @@ object MoneyConfig {
|
||||
this.fallbackRate = fallbackRate
|
||||
}
|
||||
|
||||
fun setAutoLocaleFormatter(enabled: Boolean) = apply {
|
||||
setConfig(getConfigKey("autoLocaleFormatter"), enabled)
|
||||
}
|
||||
|
||||
fun setAutoCurrencyFormatter(enabled: Boolean) = apply {
|
||||
setConfig(getConfigKey("autoCurrencyFormatter"), enabled)
|
||||
}
|
||||
|
||||
// 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
|
||||
private fun getConfigKey(key: String): String {
|
||||
@@ -75,12 +147,12 @@ object MoneyConfig {
|
||||
fun parse(config: String, clearAllStates: Boolean = true) {
|
||||
// remove all states, if needed
|
||||
if (clearAllStates) {
|
||||
if (configPrefix.isEmpty() || config.isBlank()) {
|
||||
MoneyConfig.config.clear()
|
||||
if (!isConfigPrefixValid()) {
|
||||
configRates.clear()
|
||||
} else {
|
||||
val keys = MoneyConfig.config.filter { it.key.startsWith(prefix = configPrefix) }.keys
|
||||
val keys = configRates.filter { it.key.startsWith(prefix = configPrefix) }.keys
|
||||
keys.forEach { key ->
|
||||
MoneyConfig.config.remove(key)
|
||||
configRates.remove(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,16 +165,16 @@ object MoneyConfig {
|
||||
.split(getProperties().deliEqual)
|
||||
if (temp.size == 2) {
|
||||
val currency = temp[0]
|
||||
.toUpperCase()
|
||||
.uppercase()
|
||||
.trim()
|
||||
val key = getConfigKey(currency)
|
||||
val value = temp[1].toDouble()
|
||||
|
||||
// set the value into dataset
|
||||
if (MoneyConfig.config.containsKey(key)) {
|
||||
MoneyConfig.config.replace(key, value)
|
||||
if (configRates.containsKey(key)) {
|
||||
configRates.replace(key, value)
|
||||
} else {
|
||||
MoneyConfig.config.put(key, value)
|
||||
configRates.put(key, value)
|
||||
}
|
||||
} else {
|
||||
throw MoneyCurrencyStateException("money config format $temp is not valid!")
|
||||
@@ -113,12 +185,12 @@ object MoneyConfig {
|
||||
// append the rate into dataset
|
||||
// for config key are completed change inside
|
||||
fun appendRate(currency: String, rate: Double) = apply {
|
||||
val currencyKey = currency.toUpperCase().trim()
|
||||
val currencyKey = currency.uppercase().trim()
|
||||
val key = getConfigKey(currencyKey)
|
||||
if (config.containsKey(key)) {
|
||||
config.replace(key, rate)
|
||||
if (configRates.containsKey(key)) {
|
||||
configRates.replace(key, rate)
|
||||
} else {
|
||||
config[key] = rate
|
||||
configRates[key] = rate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,14 +220,81 @@ object MoneyConfig {
|
||||
}
|
||||
|
||||
// all currencies with its rate
|
||||
fun getConfig() = config
|
||||
fun getConfigRates() = configRates
|
||||
|
||||
@Throws(MoneyCurrencyStateException::class)
|
||||
fun getRate(currency: StdMoney.Currency): Double {
|
||||
return getConfig()[getConfigKey(currency.getCurrency().toUpperCase().trim())]
|
||||
return getConfigRates()[getConfigKey(currency.getCurrency().uppercase().trim())]
|
||||
?: if (fallbackRate > 0) fallbackRate else throw MoneyCurrencyStateException("money currency ${currency.getCurrency()} is not valid!")
|
||||
}
|
||||
|
||||
// apply custom locale below
|
||||
fun applyDefaultLocale(locale: Locale = Locale.getDefault()) = apply {
|
||||
configLocales[MoneyFormatter.DEFAULT_LOCALE] = locale
|
||||
}
|
||||
|
||||
// get default locale from system or user defined
|
||||
private fun getDefaultLocale(): Locale {
|
||||
return configLocales[MoneyFormatter.DEFAULT_LOCALE] ?: Locale.getDefault()
|
||||
}
|
||||
|
||||
// add custom locale
|
||||
fun applyLocale(locale: Locale) = apply {
|
||||
if (isConfigPrefixValid()) {
|
||||
if (configLocales.containsKey(configPrefix)) {
|
||||
configLocales.replace(configPrefix, locale)
|
||||
} else {
|
||||
configLocales[configPrefix] = locale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get locale by config prefix or default if not found
|
||||
fun getLocale(): Locale {
|
||||
if (isConfigPrefixValid() && configLocales.containsKey(configPrefix)) {
|
||||
return configLocales[configPrefix] ?: getDefaultLocale()
|
||||
}
|
||||
|
||||
return getDefaultLocale()
|
||||
}
|
||||
|
||||
// get default currency from system or user defined
|
||||
private fun getDefaultCurrency(): Currency {
|
||||
return configCurrencies[MoneyFormatter.DEFAULT_CURRENCY] ?: Currency.getInstance(getDefaultLocale())
|
||||
}
|
||||
|
||||
// apply the default currency for system at runtime
|
||||
fun applyDefaultCurrency(currency: StdMoney.Currency) = apply {
|
||||
configCurrencies[MoneyFormatter.DEFAULT_CURRENCY] = currency.findCurrency()
|
||||
}
|
||||
|
||||
// apply the currency into the config for system currency at runtime
|
||||
fun applyCurrency(currency: StdMoney.Currency) = apply {
|
||||
if (isConfigPrefixValid()) {
|
||||
val systemCurrency = currency.findCurrency()
|
||||
if (systemCurrency != null) {
|
||||
if (configCurrencies.containsKey(configPrefix)) {
|
||||
configCurrencies.replace(configPrefix, systemCurrency)
|
||||
} else {
|
||||
configCurrencies[configPrefix] = systemCurrency
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get currency by config prefix or default if not found
|
||||
fun getCurrency(): Currency {
|
||||
if (isConfigPrefixValid() && configCurrencies.containsKey(configPrefix)) {
|
||||
return configCurrencies[configPrefix] ?: getDefaultCurrency()
|
||||
}
|
||||
|
||||
return getDefaultCurrency()
|
||||
}
|
||||
|
||||
fun getCurrencySymbol(): String {
|
||||
return getCurrency().getSymbol(getDefaultLocale())
|
||||
}
|
||||
|
||||
// apply default formatter for all not exists
|
||||
fun applyDefaultFormatter(
|
||||
provider: MoneyFormatProvider? = null
|
||||
@@ -167,7 +306,7 @@ object MoneyConfig {
|
||||
|
||||
// add money formatter by currency of each money value
|
||||
fun addFormatter(currency: String, formatter: MoneyFormatProvider) = apply {
|
||||
val key = getConfigKey(currency.toUpperCase().trim())
|
||||
val key = getConfigKey(currency.uppercase().trim())
|
||||
if (configFormatter.containsKey(key)) {
|
||||
configFormatter.replace(key, formatter)
|
||||
} else {
|
||||
@@ -179,7 +318,7 @@ object MoneyConfig {
|
||||
fun getFormatter(currency: String? = null): MoneyFormatter {
|
||||
// apply default formatter
|
||||
val formatter = (if (!currency.isNullOrEmpty()) {
|
||||
val key = getConfigKey(currency.toUpperCase().trim())
|
||||
val key = getConfigKey(currency.uppercase().trim())
|
||||
configFormatter[key]
|
||||
} else {
|
||||
null
|
||||
|
||||
@@ -14,7 +14,7 @@ open class MoneyCurrency(
|
||||
private var configs: Map<String, Any?>? = null,
|
||||
) : Serializable, StdMoney.Currency {
|
||||
override fun getCurrency(): String {
|
||||
return name.toUpperCase().trim()
|
||||
return name.uppercase().trim()
|
||||
}
|
||||
|
||||
fun getSymbol(): String? {
|
||||
|
||||
@@ -14,4 +14,23 @@ object MoneyExchangeUtils {
|
||||
fun getBaseCurrency(): StdMoney.Currency {
|
||||
return StdMoney.USD
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the Base Exchange Price / Converter to any Rates.
|
||||
* Multiple differentiate exchange relation computation.
|
||||
* Example: A -> B -> C meant You can with all variables, but must find the based MEANT of its.
|
||||
*
|
||||
* Sample Explanation: Matrix Multiply
|
||||
* 1 USD -> 0.90 EUR
|
||||
* 1 USD -> 4000 KHR
|
||||
* If I want to exchange from EUR to KHR, I need.
|
||||
* 1 EUR -> 1 * (1 / 0.90) / (1 / 4000)
|
||||
*
|
||||
* @author sombochea
|
||||
* @since 1.0
|
||||
*/
|
||||
fun computeFromBaseRate(amountFrom: Double = 1.0, baseRate: Double = 1.0, rateFrom: Double, rateTo: Double): Double {
|
||||
// amount * ((baseRate / rateFrom) / (baseRate / rateTo))
|
||||
return amountFrom.times((baseRate.div(rateFrom)).div(baseRate.div(rateTo)))
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.cubetiqs.money
|
||||
|
||||
import java.util.*
|
||||
|
||||
infix fun StdMoney.exchangeTo(currency: StdMoney.Currency): StdMoney {
|
||||
return MoneyExchangeUtils.exchange(this, currency)
|
||||
}
|
||||
|
||||
infix fun StdMoney.exchangeTo(currency: String): StdMoney = this exchangeTo object : StdMoney.Currency {
|
||||
override fun getCurrency(): String {
|
||||
return currency.toUpperCase().trim()
|
||||
return currency.uppercase().trim()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +69,7 @@ infix fun Number.withCurrency(currency: StdMoney.Currency): StdMoney = object :
|
||||
|
||||
infix fun Number.withCurrency(currency: String): StdMoney = this withCurrency object : StdMoney.Currency {
|
||||
override fun getCurrency(): String {
|
||||
return currency.toUpperCase().trim()
|
||||
return currency.uppercase().trim()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,4 +128,9 @@ fun MoneyView.asStdMoney(): StdMoney {
|
||||
return this@asStdMoney.getValue()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// detect currency symbol, if needed
|
||||
fun StdMoney.Currency.findCurrency(): Currency? {
|
||||
return Currency.getInstance(this.getCurrency())
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.cubetiqs.money
|
||||
|
||||
import java.io.Serializable
|
||||
import java.math.RoundingMode
|
||||
import java.text.NumberFormat
|
||||
|
||||
/**
|
||||
* Money Formatter (Final class)
|
||||
@@ -25,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 }
|
||||
@@ -40,8 +47,24 @@ class MoneyFormatter(
|
||||
override fun format(): String {
|
||||
value?.getValue() ?: return ""
|
||||
|
||||
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) {
|
||||
@@ -55,7 +78,30 @@ 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"
|
||||
const val DEFAULT_CURRENCY = "defaultCurrency"
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ open class MoneyObject(
|
||||
if (temp.length == 1) {
|
||||
operator(temp[0])
|
||||
} else {
|
||||
valueOf(temp.toUpperCase().trim())
|
||||
valueOf(temp.uppercase().trim())
|
||||
}
|
||||
}
|
||||
is Char -> {
|
||||
|
||||
@@ -4,23 +4,37 @@ open class MoneyView(
|
||||
private var value: Number? = null,
|
||||
private var currency: String? = null,
|
||||
) : MoneyMixin {
|
||||
constructor(money: StdMoney) : this() {
|
||||
private var _currency: StdMoney.Currency? = null
|
||||
|
||||
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 = money.getCurrency().getCurrency()
|
||||
this.currency = this._currency?.getCurrency()
|
||||
}
|
||||
|
||||
fun getValue(): Double {
|
||||
return value?.toDouble() ?: 0.0
|
||||
return (value?.toDouble() ?: 0.0)
|
||||
}
|
||||
|
||||
fun getCurrency(): String? {
|
||||
return currency
|
||||
}
|
||||
|
||||
fun getSymbol(): String? {
|
||||
return this._currency?.findCurrency()?.symbol
|
||||
}
|
||||
|
||||
fun getFormat(): String {
|
||||
return MoneyConfig
|
||||
.getFormatter(getCurrency())
|
||||
.setValue(this.asStdMoney())
|
||||
.setDisableAutoFormat(true)
|
||||
.format()
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ interface StdMoney : MoneyMixin {
|
||||
fun initCurrency(currency: String?): Currency {
|
||||
return object : Currency {
|
||||
override fun getCurrency(): String {
|
||||
return currency?.toUpperCase()?.trim() ?: "USD"
|
||||
return currency?.uppercase()?.trim() ?: "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import com.cubetiqs.money.*
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
|
||||
class MoneyTests {
|
||||
private fun initMoneyConfig() {
|
||||
@@ -26,19 +27,8 @@ class MoneyTests {
|
||||
fun exchange_2usd_to_khr_test() {
|
||||
initMoneyConfig()
|
||||
|
||||
// applyMoneyConfig {
|
||||
// setProperties(buildMoneyConfigProperties {
|
||||
// setDeliEqual(':')
|
||||
// setDeliSplit(',')
|
||||
// })
|
||||
// // parse("USD:1,KHR:4000")
|
||||
// // appendRate("usd", 1.0)
|
||||
// // appendRate("khr", 4000.0)
|
||||
// fromJson(MyBatchRates.getJsonRates())
|
||||
// }
|
||||
|
||||
// Is valid for money config?
|
||||
Assert.assertTrue(MoneyConfig.isValid())
|
||||
Assert.assertTrue(MoneyConfig.isConfigRatesValid())
|
||||
|
||||
// arithmetic operators calculation
|
||||
val moneyUsd =
|
||||
@@ -138,6 +128,7 @@ class MoneyTests {
|
||||
|
||||
@Test
|
||||
fun moneyFormatterTest() {
|
||||
|
||||
val systemCurrency = Currency.getInstance("USD").symbol
|
||||
println(systemCurrency)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user