money-module/src/main/kotlin/com/cubetiqs/money/MoneyFormatter.kt

107 lines
3.7 KiB
Kotlin

package com.cubetiqs.money
import java.io.Serializable
import java.math.RoundingMode
import java.text.NumberFormat
/**
* Money Formatter (Final class)
*
* @see MoneyConfig for format properties for each of value within currency
* @see DecimalUtils for Utils formatter with number
*/
class MoneyFormatter(
private var pattern: String? = null,
private var precision: Int? = null,
private var roundingMode: RoundingMode? = null,
) : Serializable, StdMoneyFormation, MoneyFormatProvider {
fun setPattern(pattern: String?) = apply { this.pattern = pattern }
fun setPrecision(precision: Int?) = apply { this.precision = precision }
fun setRoundingMode(roundingMode: RoundingMode?) = apply { this.roundingMode = roundingMode }
fun setProvider(provider: MoneyFormatProvider?) = apply {
if (provider != null) {
this.pattern = provider.getPattern()
this.precision = provider.getPrecision()
this.roundingMode = provider.getRoundingMode()
}
}
// 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 }
constructor(value: StdMoney?) : this() {
this.value = value
}
override fun getPattern() = pattern?.trim()
override fun getPrecision() = precision ?: -1
override fun getRoundingMode() = roundingMode
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) {
autoFormat = autoFormatValueFromConfig(force = true)
return if (autoFormat.isNullOrEmpty()) {
value?.getValue().toString()
} else {
autoFormat
}
}
if (getPrecision() > -1) {
return DecimalUtils.toDecimalPrecision(value?.getValue() ?: 0, getPrecision(), getRoundingMode()) ?: ""
}
return DecimalUtils.toStringDecimal(value?.getValue() ?: 0, getPattern(), getRoundingMode())
}
override fun toMoneyString(overrideSymbol: Char?): String {
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"
}
}