Compare commits
6 Commits
3f02799284
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| e82fb280ab | |||
| 4dc6ae521c | |||
| 377809383d | |||
| a8841a537d | |||
| 32441f7de6 | |||
| 7204246dc9 |
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.4.0"
|
kotlin("jvm") version "1.4.0"
|
||||||
|
`java-library`
|
||||||
|
id("de.marcphilipp.nexus-publish") version "0.4.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.cubetiqs.libra"
|
group = "com.cubetiqs.libra"
|
||||||
@@ -13,3 +15,22 @@ dependencies {
|
|||||||
implementation(kotlin("stdlib"))
|
implementation(kotlin("stdlib"))
|
||||||
testImplementation("org.junit.vintage:junit-vintage-engine:5.6.2")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.6.2")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("mavenJava") {
|
||||||
|
from(components["java"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nexusPublishing {
|
||||||
|
repositories {
|
||||||
|
create("mavenJava") {
|
||||||
|
nexusUrl.set(uri("https://nexus.osa.cubetiqs.com/repository/local-maven-dev/"))
|
||||||
|
snapshotRepositoryUrl.set(uri("https://nexus.osa.cubetiqs.com/repository/local-maven-dev/"))
|
||||||
|
username.set("cubetiq")
|
||||||
|
password.set("cube17tiq")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package com.cubetiqs.libra.moneyutils
|
|||||||
|
|
||||||
open class Money(
|
open class Money(
|
||||||
var value: Double,
|
var value: Double,
|
||||||
private var currency: String = "USD"
|
@SpecialString(trim = true, upperCase = true) private var currency: String = "USD"
|
||||||
) : StdMoney {
|
) : StdMoney {
|
||||||
|
|
||||||
//////////////////// - PROPERTIES - ////////////////////
|
//////////////////// - PROPERTIES - ////////////////////
|
||||||
@@ -12,7 +12,7 @@ open class Money(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getMoneyCurrency(): String {
|
override fun getMoneyCurrency(): String {
|
||||||
return this.currency.toUpperCase()
|
return this.currency
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////// - GENERIC - ////////////////////
|
//////////////////// - GENERIC - ////////////////////
|
||||||
@@ -24,5 +24,27 @@ open class Money(
|
|||||||
companion object {
|
companion object {
|
||||||
val ZERO: StdMoney
|
val ZERO: StdMoney
|
||||||
get() = Money(value = 0.0)
|
get() = Money(value = 0.0)
|
||||||
|
val ONE: StdMoney
|
||||||
|
get() = Money(value = 1.0)
|
||||||
|
val TEN: StdMoney
|
||||||
|
get() = Money(value = 10.0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new money object with custom value
|
||||||
|
*
|
||||||
|
* @param value Double
|
||||||
|
* @param currency String
|
||||||
|
*/
|
||||||
|
fun create(value: Double, currency: String = MoneyCurrency.USD.name): StdMoney {
|
||||||
|
return Money(value = value, currency = currency)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new money object with custom value
|
||||||
|
*
|
||||||
|
* @param value Double
|
||||||
|
* @param currency MoneyCurrency
|
||||||
|
*/
|
||||||
|
fun create(value: Double, currency: MoneyCurrency = MoneyCurrency.USD): StdMoney = create(value, currency.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.libra.moneyutils
|
||||||
|
|
||||||
|
fun StdMoney.addMoney(value: Double, currency: String): StdMoney {
|
||||||
|
return this + Money.create(value, currency)
|
||||||
|
}
|
||||||
@@ -15,8 +15,11 @@ object MoneyConfig {
|
|||||||
* Value is the rate
|
* Value is the rate
|
||||||
*/
|
*/
|
||||||
private val config: MutableMap<String, Double> = mutableMapOf()
|
private val config: MutableMap<String, Double> = mutableMapOf()
|
||||||
private var valid: Boolean = false
|
|
||||||
fun isValid() = valid
|
// validate the config, if have it's valid
|
||||||
|
fun isValid(): Boolean {
|
||||||
|
return this.config.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Money properties for money config format
|
* Money properties for money config format
|
||||||
@@ -58,9 +61,6 @@ object MoneyConfig {
|
|||||||
throw MoneyCurrencyStateException("money config format is not valid!")
|
throw MoneyCurrencyStateException("money config format is not valid!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate the config is load or not
|
|
||||||
this.valid = this.config.isNotEmpty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// all currencies with its rate
|
// all currencies with its rate
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.cubetiqs.libra.moneyutils
|
||||||
|
|
||||||
|
enum class MoneyCurrency {
|
||||||
|
USD,
|
||||||
|
KHR,
|
||||||
|
EUR
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.libra.moneyutils
|
||||||
|
|
||||||
|
interface MoneyExchangeAdapter {
|
||||||
|
fun getRate(currency: String): Double
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.cubetiqs.libra.moneyutils
|
||||||
|
|
||||||
|
fun StdMoney.exchangeTo(currency: String): StdMoney {
|
||||||
|
return MoneyExchangeUtils.exchange(this, currency)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun StdMoney.isMatchedCurrency(currency: String) = this.getMoneyCurrency().equals(currency, ignoreCase = true)
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
package com.cubetiqs.libra.moneyutils
|
package com.cubetiqs.libra.moneyutils
|
||||||
|
|
||||||
operator fun Money.unaryMinus() = (-getMoneyValue())
|
operator fun StdMoney.unaryMinus() = (-getMoneyValue())
|
||||||
operator fun Money.unaryPlus() = (+getMoneyValue())
|
operator fun StdMoney.unaryPlus() = (+getMoneyValue())
|
||||||
operator fun Money.inc() = Money(value++)
|
operator fun Money.inc() = Money(value++)
|
||||||
operator fun Money.dec() = Money(value--)
|
operator fun Money.dec() = Money(value--)
|
||||||
operator fun Money.plus(other: Money) = Money(value + other.value)
|
operator fun StdMoney.plus(other: StdMoney) = Money(getMoneyValue() + other.getMoneyValue())
|
||||||
operator fun Money.times(other: Money) = Money(value * other.value)
|
operator fun StdMoney.times(other: StdMoney) = Money(getMoneyValue() * other.getMoneyValue())
|
||||||
operator fun Money.div(other: Money) = Money(value / other.value)
|
operator fun StdMoney.div(other: StdMoney) = Money(getMoneyValue() / other.getMoneyValue())
|
||||||
operator fun Money.timesAssign(other: Money) {
|
operator fun Money.timesAssign(other: StdMoney) {
|
||||||
this.value = this.value * other.value
|
this.value = this.getMoneyValue() * other.getMoneyValue()
|
||||||
}
|
}
|
||||||
operator fun Money.not() = this.value != this.value
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.libra.moneyutils
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FIELD)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class SpecialString(val value: String = "", val upperCase: Boolean = true, val trim: Boolean = true)
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.cubetiqs.libra.moneyutils
|
||||||
|
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class SpecialStringProcessor: ISerializer {
|
||||||
|
override fun <T> serialize(data: T?): T? {
|
||||||
|
if (data == null) return null
|
||||||
|
val clazz = data.javaClass
|
||||||
|
clazz.declaredFields.forEach {
|
||||||
|
it.isAccessible = true
|
||||||
|
if (it.isAnnotationPresent(SpecialString::class.java) && it.genericType == String::class.java) {
|
||||||
|
val annotationValues = it.getAnnotation(SpecialString::class.java)
|
||||||
|
var value = it.get(data).toString()
|
||||||
|
if (annotationValues.trim) {
|
||||||
|
value = value.trim()
|
||||||
|
}
|
||||||
|
if (annotationValues.upperCase) {
|
||||||
|
value = value.toUpperCase()
|
||||||
|
}
|
||||||
|
it.set(data, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSerializeKey(field: Field): String {
|
||||||
|
val annotationValue = field.getAnnotation(SpecialString::class.java).value
|
||||||
|
return if (annotationValue.isEmpty()) {
|
||||||
|
field.name
|
||||||
|
} else annotationValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISerializer {
|
||||||
|
fun <T> serialize(data: T?): T?
|
||||||
|
}
|
||||||
@@ -20,5 +20,6 @@ interface StdMoney {
|
|||||||
*
|
*
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
|
@SpecialString
|
||||||
fun getMoneyCurrency(): String
|
fun getMoneyCurrency(): String
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,26 @@
|
|||||||
import com.cubetiqs.libra.moneyutils.Money
|
import com.cubetiqs.libra.moneyutils.Money
|
||||||
import com.cubetiqs.libra.moneyutils.MoneyConfig
|
import com.cubetiqs.libra.moneyutils.MoneyConfig
|
||||||
|
import com.cubetiqs.libra.moneyutils.MoneyCurrency
|
||||||
import com.cubetiqs.libra.moneyutils.MoneyExchangeUtils
|
import com.cubetiqs.libra.moneyutils.MoneyExchangeUtils
|
||||||
import com.cubetiqs.libra.moneyutils.plus
|
import com.cubetiqs.libra.moneyutils.SpecialStringProcessor
|
||||||
import com.cubetiqs.libra.moneyutils.times
|
|
||||||
import com.cubetiqs.libra.moneyutils.timesAssign
|
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class MoneyTests {
|
class MoneyTests {
|
||||||
@Test
|
@Test
|
||||||
fun test() {
|
fun money_operator_test() {
|
||||||
val money = Money(10.0)
|
// val money = Money(10.0)
|
||||||
val money2 = Money(20.0)
|
// val money2 = Money(20.0)
|
||||||
money *= money
|
// money *= money
|
||||||
println((money + money2) * money2)
|
// println((money + money2) * money2)
|
||||||
Assert.assertEquals(10, 10)
|
// Assert.assertEquals(100.0, money.value, 0.0)
|
||||||
|
|
||||||
|
val test = SpecialStringProcessor().serialize(Money(1.0, " usd "))
|
||||||
|
println(test)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun exchange_2usd_to_khr_test() {
|
||||||
val properties = MoneyConfig
|
val properties = MoneyConfig
|
||||||
.MoneyConfigProperties
|
.MoneyConfigProperties
|
||||||
.MoneyConfigPropertiesBuilder()
|
.MoneyConfigPropertiesBuilder()
|
||||||
@@ -27,11 +32,27 @@ class MoneyTests {
|
|||||||
.setProperties(properties)
|
.setProperties(properties)
|
||||||
.parse("USD:1,KHR:4000")
|
.parse("USD:1,KHR:4000")
|
||||||
|
|
||||||
|
Assert.assertTrue(MoneyConfig.isValid())
|
||||||
|
|
||||||
println(MoneyConfig.getConfig())
|
println(MoneyConfig.getConfig())
|
||||||
|
|
||||||
val moneyUsd = Money(10.0)
|
val moneyUsd = Money(2.0)
|
||||||
val moneyKhr = MoneyExchangeUtils.exchange(moneyUsd, "KHR")
|
val moneyKhr = MoneyExchangeUtils.exchange(moneyUsd, "KHR")
|
||||||
|
|
||||||
Assert.assertEquals(40000.0, moneyKhr.getMoneyValue(), 0.0)
|
Assert.assertEquals(8000.0, moneyKhr.getMoneyValue(), 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun money_exchange_config_builder_test() {
|
||||||
|
MoneyConfig.propertiesBuilder
|
||||||
|
.setDeliEqual('=')
|
||||||
|
.setDeliSplit(';')
|
||||||
|
|
||||||
|
MoneyConfig.parse("USD:1,KHR=4000,EUR=0.99")
|
||||||
|
|
||||||
|
val moneyUsd = Money.ONE
|
||||||
|
val moneyKhr = Money.create(20000.0, MoneyCurrency.KHR)
|
||||||
|
|
||||||
|
val result = moneyUsd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
37
src/test/kotlin/ObjectTests.kt
Normal file
37
src/test/kotlin/ObjectTests.kt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class ObjectTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun builder_object_test() {
|
||||||
|
val person = Person
|
||||||
|
.builder()
|
||||||
|
.name("Sambo Chea")
|
||||||
|
.id(10)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
println(person)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Person(val id: Long? = null, val name: String? = null) {
|
||||||
|
companion object {
|
||||||
|
fun builder(): PersonBuilder {
|
||||||
|
return PersonBuilder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PersonBuilder {
|
||||||
|
private var id: Long? = null
|
||||||
|
private var name: String? = null
|
||||||
|
|
||||||
|
fun id(id: Long?) = apply { this.id = id }
|
||||||
|
fun name(name: String?) = apply { this.name = name }
|
||||||
|
|
||||||
|
fun build(): Person {
|
||||||
|
return Person(id, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user