101 lines
3.1 KiB
Kotlin
101 lines
3.1 KiB
Kotlin
package com.iiyh.emoneyinfo.data
|
|
|
|
import androidx.annotation.StringRes
|
|
import com.iiyh.emoneyinfo.R
|
|
import java.text.NumberFormat
|
|
import java.text.SimpleDateFormat
|
|
import java.util.Date
|
|
import java.util.Locale
|
|
import kotlin.math.abs
|
|
|
|
enum class CardType(@param:StringRes val labelRes: Int) {
|
|
UNKNOWN(R.string.card_unknown),
|
|
MANDIRI(R.string.card_mandiri),
|
|
FLAZZ(R.string.card_flazz),
|
|
BRIZZI(R.string.card_brizzi),
|
|
TAPCASH(R.string.card_tapcash),
|
|
JACKCARD(R.string.card_jackcard),
|
|
MEGACASH(R.string.card_megacash),
|
|
KMT(R.string.card_kmt)
|
|
}
|
|
|
|
data class TransactionItem(
|
|
val title: String,
|
|
val date: Date,
|
|
val amount: Long,
|
|
val isCredit: Boolean,
|
|
val locationName: String = ""
|
|
) {
|
|
fun formattedAmount(): String {
|
|
val formatter = NumberFormat.getCurrencyInstance(Locale.forLanguageTag("id-ID")).apply {
|
|
maximumFractionDigits = 0
|
|
currency = java.util.Currency.getInstance("IDR")
|
|
}
|
|
val raw = formatter.format(abs(amount)).replace("IDR", "Rp")
|
|
return if (isCredit) "+$raw" else "-$raw"
|
|
}
|
|
|
|
fun formattedDate(): String = SimpleDateFormat("dd MMM yyyy · HH:mm", Locale.forLanguageTag("id-ID")).format(date)
|
|
|
|
fun subtitle(): String = buildString {
|
|
append(formattedDate())
|
|
if (locationName.isNotBlank()) {
|
|
append(" · ")
|
|
append(locationName)
|
|
}
|
|
}
|
|
|
|
fun historyKey(): String = buildString {
|
|
append(date.time / 1000)
|
|
append('|')
|
|
append(amount)
|
|
append('|')
|
|
append(if (isCredit) 1 else 0)
|
|
append('|')
|
|
append(locationName.trim())
|
|
append('|')
|
|
append(title)
|
|
}
|
|
}
|
|
|
|
data class EmoneyUiState(
|
|
val cardType: CardType = CardType.UNKNOWN,
|
|
val balance: Long = 0,
|
|
val cardNumber: String = "",
|
|
val transactions: List<TransactionItem> = emptyList(),
|
|
val scanMessage: String = "",
|
|
val isNfcSupported: Boolean = true
|
|
) {
|
|
fun formattedBalance(): String {
|
|
val formatter = NumberFormat.getCurrencyInstance(Locale.forLanguageTag("id-ID")).apply {
|
|
maximumFractionDigits = 0
|
|
currency = java.util.Currency.getInstance("IDR")
|
|
}
|
|
return formatter.format(balance).replace("IDR", "Rp")
|
|
}
|
|
|
|
fun hasCardData(): Boolean = cardType != CardType.UNKNOWN || cardNumber.isNotBlank() || balance > 0 || transactions.isNotEmpty()
|
|
|
|
fun clearingHistory(scanMessage: String): EmoneyUiState = copy(
|
|
transactions = emptyList(),
|
|
scanMessage = scanMessage
|
|
)
|
|
|
|
fun deduplicatingHistory(): EmoneyUiState {
|
|
val deduplicated = transactions.distinctBy { it.historyKey() }
|
|
return if (deduplicated.size == transactions.size) this else copy(transactions = deduplicated)
|
|
}
|
|
}
|
|
|
|
fun String.formatCardNumber(): String {
|
|
val digits = filter { it.isDigit() }
|
|
if (digits.isEmpty()) return this
|
|
return digits.chunked(4).joinToString(" ")
|
|
}
|
|
|
|
fun String.maskFirst12(): String {
|
|
val digits = filter { it.isDigit() }
|
|
if (digits.length != 16) return formatCardNumber()
|
|
return "**** **** **** ${digits.takeLast(4)}"
|
|
}
|