Skip to content

Commit fc830b0

Browse files
committed
fix: add fraction digit overrides for currencies that report decimals but don't use them in practice
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 9c3b5b3 commit fc830b0

4 files changed

Lines changed: 19 additions & 9 deletions

File tree

services/opencode/src/main/kotlin/com/getcode/opencode/internal/extensions/Currency.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fun Currency.Companion.fromCode(code: CurrencyCode, resources: ResourceHelper):
1414
name = currencyJava.displayName,
1515
resId = resId,
1616
symbol = code.singleCharacterCurrencySymbol.orEmpty(),
17-
fractionUnits = currencyJava.defaultFractionDigits,
17+
fractionUnits = code.fractionDigits,
1818
)
1919
}
2020

services/opencode/src/main/kotlin/com/getcode/opencode/internal/extensions/CurrencyCode.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ import com.getcode.utils.trace
55
import java.util.Currency
66
import java.util.Locale
77

8+
val CurrencyCode.fractionDigits: Int
9+
get() = when (this) {
10+
CurrencyCode.AFN -> 0 // No pul coins/notes in circulation since 2002; all transactions in whole afghanis due to low subunit value.
11+
CurrencyCode.COP -> 0 // Centavos obsolete since the 1980s; all pricing and payments in whole pesos.
12+
CurrencyCode.IDR -> 0 // Sen coins/banknotes obsolete since 1987 due to hyperinflation; all transactions rounded to whole rupiah.
13+
CurrencyCode.IRR -> 0 // Dinar never circulated; prices often quoted in "tomans" (1,000 rials) with inflation making subunits irrelevant.
14+
CurrencyCode.MGA -> 0 // Non-decimal 5:1 ratio; iraimbilanja coins obsolete since 1960s, no practical use despite ISO decimal assumption.
15+
CurrencyCode.MRU -> 0 // Non-decimal 5:1 ratio; khoum coins rare and unused in transactions since 1970s, despite a 2017 commemorative issue.
16+
CurrencyCode.TZS -> 0 // Senti coins withdrawn in the 1980s; no circulation since, with whole shillings used exclusively.
17+
CurrencyCode.UYU -> 0 // Centésimo coins withdrawn in 1998; prices rounded to nearest peso in retail and payments.
18+
else -> Currency.getInstance(name).defaultFractionDigits
19+
}
20+
821
internal fun CurrencyCode.getClosestLocale(): Locale {
922
val currency = Currency.getInstance(name.uppercase())
1023

services/opencode/src/main/kotlin/com/getcode/opencode/model/financial/Fiat.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.getcode.opencode.model.financial
33
import android.os.Parcelable
44
import com.flipcash.libs.currency.math.Estimator
55
import com.flipcash.libs.currency.math.divideWithHighPrecision
6+
import com.getcode.opencode.internal.extensions.fractionDigits
67
import com.getcode.opencode.utils.roundTo
78
import com.getcode.solana.keys.Mint
89
import kotlinx.parcelize.Parcelize
@@ -79,7 +80,7 @@ data class Fiat(
7980
}
8081

8182
val formatter = DecimalFormat.getInstance(Locale.US).apply {
82-
val decimalDigits = Currency.getInstance(currencyCode.name).defaultFractionDigits
83+
val decimalDigits = currencyCode.fractionDigits
8384
val preferredDigits = when (rule) {
8485
is FormattingRule.Length -> rule.decimalPlaces
8586
FormattingRule.None -> decimalDigits
@@ -233,4 +234,5 @@ fun Number.toFiat(currencyCode: CurrencyCode = CurrencyCode.USD): Fiat = when (t
233234
else -> throw IllegalArgumentException("Unsupported number type")
234235
}
235236

236-
fun min(a: Fiat, b: Fiat): Fiat = if (a < b) a else b
237+
fun min(a: Fiat, b: Fiat): Fiat = if (a < b) a else b
238+
fun max(a: Fiat, b: Fiat): Fiat = if (a > b) a else b

services/opencode/src/main/kotlin/com/getcode/opencode/model/financial/LocalFiat.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.getcode.utils.trace
1111
import kotlinx.serialization.Serializable
1212
import java.math.BigDecimal
1313
import javax.annotation.concurrent.Immutable
14+
import kotlin.math.max
1415

1516
typealias Usd = Fiat
1617

@@ -98,8 +99,6 @@ data class LocalFiat(
9899

99100
// determine the "full units" of the token being exchanged
100101
val units = quarks.units()
101-
// determine the exchange rate (native amount / units of token) (USD based)
102-
val usdFx = BigDecimal(cappedValue.decimalValue).divideWithHighPrecision(units)
103102

104103
val underlyingTokenAmount = Fiat(quarks.toLong(), CurrencyCode.USD)
105104
val sellEstimate = Fiat.tokenBalance(quarks.toLong(), token).convertingTo(rate)
@@ -119,7 +118,6 @@ data class LocalFiat(
119118
valueLocked = valueLocked,
120119
quarks = quarks,
121120
units = units,
122-
usdFx = usdFx,
123121
fx = fx,
124122
sellEstimate = sellEstimate
125123
)
@@ -145,7 +143,6 @@ data class LocalFiat(
145143
valueLocked: Long,
146144
quarks: BigDecimal,
147145
units: BigDecimal,
148-
usdFx: BigDecimal,
149146
fx: Double,
150147
sellEstimate: Fiat,
151148
) {
@@ -160,7 +157,6 @@ data class LocalFiat(
160157
println("locked value (of ${token.symbol}): $valueLocked")
161158
println("calculated quarks: $quarks")
162159
println("units: $units")
163-
println("usdFx: ${usdFx.toDouble()}")
164160
println("fx: $fx")
165161
println("sell estimate: ${sellEstimate.formatted(rule = FormattingRule.Length(token.decimals))}")
166162
println("##################################################")
@@ -180,7 +176,6 @@ data class LocalFiat(
180176
"locked value of ${token.symbol}" to valueLocked
181177
"calculated quarks" to quarks
182178
"units" to units
183-
"usdFx" to usdFx.toDouble()
184179
"fx" to fx
185180
"sell estimate" to sellEstimate.formatted(rule = FormattingRule.Length(token.decimals))
186181
}

0 commit comments

Comments
 (0)