mirror of
https://github.com/corda/corda.git
synced 2025-01-02 19:26:47 +00:00
Amount: add ruble and Yen, fix toString.
This commit is contained in:
parent
7cac55ca4a
commit
23fcbd284c
@ -27,7 +27,9 @@ fun commodity(code: String) = Commodity.getInstance(code)!!
|
|||||||
@JvmField val GBP = currency("GBP")
|
@JvmField val GBP = currency("GBP")
|
||||||
@JvmField val EUR = currency("EUR")
|
@JvmField val EUR = currency("EUR")
|
||||||
@JvmField val CHF = currency("CHF")
|
@JvmField val CHF = currency("CHF")
|
||||||
@JvmField val FCOJ = commodity("FCOJ")
|
@JvmField val JPY = currency("JPY")
|
||||||
|
@JvmField val RUB = currency("RUB")
|
||||||
|
@JvmField val FCOJ = commodity("FCOJ") // Frozen concentrated orange juice, yum!
|
||||||
|
|
||||||
fun DOLLARS(amount: Int): Amount<Currency> = Amount(amount.toLong() * 100, USD)
|
fun DOLLARS(amount: Int): Amount<Currency> = Amount(amount.toLong() * 100, USD)
|
||||||
fun DOLLARS(amount: Double): Amount<Currency> = Amount((amount * 100).toLong(), USD)
|
fun DOLLARS(amount: Double): Amount<Currency> = Amount((amount * 100).toLong(), USD)
|
||||||
|
@ -39,7 +39,7 @@ import java.util.*
|
|||||||
data class Amount<T>(val quantity: Long, val token: T) : Comparable<Amount<T>> {
|
data class Amount<T>(val quantity: Long, val token: T) : Comparable<Amount<T>> {
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* Build an amount from a decimal representation. For example, with an input of "12.34" GBP,
|
* Build a currency amount from a decimal representation. For example, with an input of "12.34" GBP,
|
||||||
* returns an amount with a quantity of "1234".
|
* returns an amount with a quantity of "1234".
|
||||||
*
|
*
|
||||||
* @see Amount<Currency>.toDecimal
|
* @see Amount<Currency>.toDecimal
|
||||||
@ -52,7 +52,9 @@ data class Amount<T>(val quantity: Long, val token: T) : Comparable<Amount<T>> {
|
|||||||
private val currencySymbols: Map<String, Currency> = mapOf(
|
private val currencySymbols: Map<String, Currency> = mapOf(
|
||||||
"$" to USD,
|
"$" to USD,
|
||||||
"£" to GBP,
|
"£" to GBP,
|
||||||
"€" to EUR
|
"€" to EUR,
|
||||||
|
"¥" to JPY,
|
||||||
|
"₽" to RUB
|
||||||
)
|
)
|
||||||
private val currencyCodes: Map<String, Currency> by lazy { Currency.getAvailableCurrencies().map { it.currencyCode to it }.toMap() }
|
private val currencyCodes: Map<String, Currency> by lazy { Currency.getAvailableCurrencies().map { it.currencyCode to it }.toMap() }
|
||||||
|
|
||||||
@ -68,10 +70,16 @@ data class Amount<T>(val quantity: Long, val token: T) : Comparable<Amount<T>> {
|
|||||||
* - €5000
|
* - €5000
|
||||||
*
|
*
|
||||||
* Note this method does NOT respect internationalisation rules: it ignores commas and uses . as the
|
* Note this method does NOT respect internationalisation rules: it ignores commas and uses . as the
|
||||||
* decimal point separator, always. It also ignores the users locale: $ is special cased to be USD,
|
* decimal point separator, always. It also ignores the users locale:
|
||||||
* £ is special cased to GBP and € is special cased to Euro. Thus an input of $12 expecting some other
|
*
|
||||||
* countries dollar will not work. Do your own parsing if you need correct handling of currency amounts
|
* - $ is always USD,
|
||||||
* with locale-sensitive handling.
|
* - £ is always GBP
|
||||||
|
* - € is always the Euro
|
||||||
|
* - ¥ is always Japanese Yen.
|
||||||
|
* - ₽ is always the Russian ruble.
|
||||||
|
*
|
||||||
|
* Thus an input of $12 expecting some other countries dollar will not work. Do your own parsing if
|
||||||
|
* you need correct handling of currency amounts with locale-sensitive handling.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if the input string was not understood.
|
* @throws IllegalArgumentException if the input string was not understood.
|
||||||
*/
|
*/
|
||||||
@ -117,17 +125,17 @@ data class Amount<T>(val quantity: Long, val token: T) : Comparable<Amount<T>> {
|
|||||||
constructor(quantity: BigInteger, token: T) : this(quantity.toLong(), token)
|
constructor(quantity: BigInteger, token: T) : this(quantity.toLong(), token)
|
||||||
|
|
||||||
operator fun plus(other: Amount<T>): Amount<T> {
|
operator fun plus(other: Amount<T>): Amount<T> {
|
||||||
checkCurrency(other)
|
checkToken(other)
|
||||||
return Amount(Math.addExact(quantity, other.quantity), token)
|
return Amount(Math.addExact(quantity, other.quantity), token)
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun minus(other: Amount<T>): Amount<T> {
|
operator fun minus(other: Amount<T>): Amount<T> {
|
||||||
checkCurrency(other)
|
checkToken(other)
|
||||||
return Amount(Math.subtractExact(quantity, other.quantity), token)
|
return Amount(Math.subtractExact(quantity, other.quantity), token)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkCurrency(other: Amount<T>) {
|
private fun checkToken(other: Amount<T>) {
|
||||||
require(other.token == token) { "Currency mismatch: ${other.token} vs $token" }
|
require(other.token == token) { "Token mismatch: ${other.token} vs $token" }
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun div(other: Long): Amount<T> = Amount(quantity / other, token)
|
operator fun div(other: Long): Amount<T> = Amount(quantity / other, token)
|
||||||
@ -135,10 +143,16 @@ data class Amount<T>(val quantity: Long, val token: T) : Comparable<Amount<T>> {
|
|||||||
operator fun div(other: Int): Amount<T> = Amount(quantity / other, token)
|
operator fun div(other: Int): Amount<T> = Amount(quantity / other, token)
|
||||||
operator fun times(other: Int): Amount<T> = Amount(Math.multiplyExact(quantity, other.toLong()), token)
|
operator fun times(other: Int): Amount<T> = Amount(Math.multiplyExact(quantity, other.toLong()), token)
|
||||||
|
|
||||||
override fun toString(): String = (BigDecimal(quantity).divide(BigDecimal(100))).setScale(2).toPlainString() + " " + token
|
override fun toString(): String {
|
||||||
|
val bd = if (token is Currency)
|
||||||
|
BigDecimal(quantity).movePointLeft(token.defaultFractionDigits)
|
||||||
|
else
|
||||||
|
BigDecimal(quantity)
|
||||||
|
return bd.toPlainString() + " " + token
|
||||||
|
}
|
||||||
|
|
||||||
override fun compareTo(other: Amount<T>): Int {
|
override fun compareTo(other: Amount<T>): Int {
|
||||||
checkCurrency(other)
|
checkToken(other)
|
||||||
return quantity.compareTo(other.quantity)
|
return quantity.compareTo(other.quantity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,14 @@ class AmountTests {
|
|||||||
assertEquals(Amount(1234L, GBP), Amount.parseCurrency("£12.34"))
|
assertEquals(Amount(1234L, GBP), Amount.parseCurrency("£12.34"))
|
||||||
assertEquals(Amount(1200L, GBP), Amount.parseCurrency("£12"))
|
assertEquals(Amount(1200L, GBP), Amount.parseCurrency("£12"))
|
||||||
assertEquals(Amount(1000L, USD), Amount.parseCurrency("$10"))
|
assertEquals(Amount(1000L, USD), Amount.parseCurrency("$10"))
|
||||||
|
assertEquals(Amount(5000L, JPY), Amount.parseCurrency("¥5000"))
|
||||||
|
assertEquals(Amount(500000L, RUB), Amount.parseCurrency("₽5000"))
|
||||||
assertEquals(Amount(1500000000L, CHF), Amount.parseCurrency("15,000,000 CHF"))
|
assertEquals(Amount(1500000000L, CHF), Amount.parseCurrency("15,000,000 CHF"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun rendering() {
|
||||||
|
assertEquals("5000 JPY", Amount.parseCurrency("¥5000").toString())
|
||||||
|
assertEquals("50.12 USD", Amount.parseCurrency("$50.12").toString())
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user