diff --git a/src/main/kotlin/com/cubetiqs/money/MoneyConfig.kt b/src/main/kotlin/com/cubetiqs/money/MoneyConfig.kt index a9918cd..8b68f19 100644 --- a/src/main/kotlin/com/cubetiqs/money/MoneyConfig.kt +++ b/src/main/kotlin/com/cubetiqs/money/MoneyConfig.kt @@ -65,7 +65,7 @@ object MoneyConfig { MoneyConfig.config.put(currency, value) } } else { - throw MoneyCurrencyStateException("money config format is not valid!") + throw MoneyCurrencyStateException("money config format $temp is not valid!") } } } @@ -107,8 +107,8 @@ object MoneyConfig { @Throws(MoneyCurrencyStateException::class) fun getRate(currency: StdMoney.Currency): Double { - return getConfig()[currency.getCurrency().toUpperCase()] - ?: throw MoneyCurrencyStateException("money currency $currency is not valid!") + return getConfig()[currency.getCurrency().toUpperCase().trim()] + ?: throw MoneyCurrencyStateException("money currency ${currency.getCurrency()} is not valid!") } class MoneyConfigProperties( diff --git a/src/main/kotlin/com/cubetiqs/money/MoneyHistory.kt b/src/main/kotlin/com/cubetiqs/money/MoneyHistory.kt deleted file mode 100644 index 5af4193..0000000 --- a/src/main/kotlin/com/cubetiqs/money/MoneyHistory.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.cubetiqs.money - -import java.io.Serializable - -/** - * @author sombochea - * @email sombochea@cubetiqs.com> - * @date 08/02/21 - * @since 1.0 - */ -data class MoneyHistory( - val valueOn: String? = null, - val valueOf: String? = null, - val currency: String? = null -) : Serializable \ No newline at end of file diff --git a/src/main/kotlin/com/cubetiqs/money/MoneyObject.kt b/src/main/kotlin/com/cubetiqs/money/MoneyObject.kt index 099a36d..5bff641 100644 --- a/src/main/kotlin/com/cubetiqs/money/MoneyObject.kt +++ b/src/main/kotlin/com/cubetiqs/money/MoneyObject.kt @@ -1,47 +1,143 @@ package com.cubetiqs.money -import java.io.Serializable +import java.util.* -sealed class MoneyObject : Serializable, StdMoney { - private var value: Double = 0.0 - private var currency: StdMoney.Currency = MoneyCurrency.USD - private val moneyStates: MutableMap = mutableMapOf() - - constructor(value: Double, currency: MoneyCurrency) { - this.value = value - this.currency = currency - isComputed = false - } - - /** - * Check if computed, set it to true. Because we no need to add the same value again after once - * computed. - */ - @Transient - var isComputed = false - private set - - @Transient - var isInit = false - private set - - /** Calculate the value. Must be call after complete add money. */ - fun compute(): MoneyObject = apply { - - } - - companion object { - @JvmStatic - private fun defaultCurrency(): StdMoney.Currency { - return MoneyExchangeUtils.getBaseCurrency() +/** + * Money Object Generator (Quick building the money) + * + * @since 1.0 + * @author sombochea + */ +class MoneyObject( + val value: Double, + val currency: String, + var operator: MoneyOperator? = null, + var with: MoneyObject? = null, +) : StdMoney { + fun appendWith(with: MoneyObject?) { + if (this.with == null) { + this.with = with + } else { + this.with!!.appendWith(with) } } + override fun getMoneyCurrency(): StdMoney.Currency { + return StdMoney.initCurrency(currency) + } + override fun getMoneyValue(): Double { return value } - override fun getMoneyCurrency(): StdMoney.Currency { - return currency + private fun generate(): StdMoney { + if (this.with != null) { + val withGenerated = this.with!!.generate() + return when (operator) { + MoneyOperator.PLUS -> this plusWith withGenerated + MoneyOperator.MINUS -> this minusWith withGenerated + MoneyOperator.DIVIDE -> this divideWith withGenerated + MoneyOperator.MULTIPLY -> this multiplyWith withGenerated + // if operator is null or empty with default Plus operator + else -> this plusWith withGenerated + } + } + + return StdMoney.initMoney(value, currency = StdMoney.initCurrency(currency)) + } + + fun compute(): StdMoney { + return generate() + } + + override fun toString(): String { + return "MoneyObject(value=$value, currency='$currency', operator=$operator, with=$with)" + } + + enum class MoneyOperator { + // (+) + PLUS, + + // (-) + MINUS, + + // (/) + DIVIDE, + + // (*) + MULTIPLY; + + companion object { + fun operator(value: Char?): MoneyOperator { + return try { + when (value!!) { + '+' -> PLUS + '-' -> MINUS + '/' -> DIVIDE + '*' -> MULTIPLY + else -> throw IllegalArgumentException("operator not found with value: $value!") + } + } catch (ex: Exception) { + throw IllegalArgumentException("operator not found!") + } + } + } + } + + class MoneyGeneratorBuilder { + private var currency: String? = null + private val withs: MutableCollection = LinkedList() + + fun withCurrency(currency: String) = apply { + this.currency = currency + } + + fun with(`object`: MoneyObject) = apply { + this.withs.add(`object`) + } + + fun with(value: Double, currency: String, operator: MoneyOperator = MoneyOperator.PLUS) = apply { + this.with( + MoneyObject( + value, currency, operator + ) + ) + } + + fun with(value: Double, currency: String, operator: Char) = apply { + this.with( + MoneyObject( + value, currency, MoneyOperator.operator(operator) + ) + ) + } + + fun build(): MoneyObject { + val first: MoneyObject + if (this.currency.isNullOrEmpty() && withs.isNotEmpty()) { + first = withs.first() + withs.remove(first) + } else { + first = MoneyObject( + value = 0.0, + operator = MoneyOperator.PLUS, + currency = this.currency ?: MoneyCurrency.USD.getCurrency() + ) + } + + withs.forEach { with -> + first.appendWith(with) + } + + return first + } + + override fun toString(): String { + return "MoneyGeneratorBuilder(currency=$currency, withs=$withs)" + } + } + + companion object { + fun builder() = MoneyGeneratorBuilder() } } \ No newline at end of file diff --git a/src/main/kotlin/com/cubetiqs/money/MoneyState.kt b/src/main/kotlin/com/cubetiqs/money/MoneyState.kt deleted file mode 100644 index 463728e..0000000 --- a/src/main/kotlin/com/cubetiqs/money/MoneyState.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.cubetiqs.money - -import java.io.Serializable - -/** - * @author sombochea - * @email sombochea@cubetiqs.com - * @date 08/02/21 - * @since 1.0 - */ -data class MoneyState( - var value: String? = null, - var currency: String? = null, - var history: MoneyHistory? = null -) : Serializable \ No newline at end of file diff --git a/src/test/kotlin/MoneyTests.kt b/src/test/kotlin/MoneyTests.kt index 15ebec6..97aec99 100644 --- a/src/test/kotlin/MoneyTests.kt +++ b/src/test/kotlin/MoneyTests.kt @@ -3,18 +3,31 @@ import org.junit.Assert import org.junit.Test class MoneyTests { - @Test - fun exchange_2usd_to_khr_test() { + private fun initMoneyConfig() { applyMoneyConfig { setProperties(buildMoneyConfigProperties { setDeliEqual(':') setDeliSplit(',') }) - // parse("USD:1,KHR:4000") - // appendRate("usd", 1.0) - // appendRate("khr", 4000.0) + fromJson(MyBatchRates.getJsonRates()) } + } + + @Test + 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()) @@ -37,8 +50,56 @@ class MoneyTests { object MyBatchRates { fun getJsonRates(): String { return """ - {"USD": 1.0,"KHR": 4000.0} + {"USD": 1.0,"KHR": 4000.0, "eur": 0.5} """.trimIndent() } } + + @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.getMoneyValue(), 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() + + println(result) + + Assert.assertEquals(expected, result.getMoneyValue(), 0.0) + } } \ No newline at end of file