diff --git a/app/src/main/java/sh/sar/basedbank/api/bml/BmlLoginFlow.kt b/app/src/main/java/sh/sar/basedbank/api/bml/BmlLoginFlow.kt index f377be7..6c5fe00 100644 --- a/app/src/main/java/sh/sar/basedbank/api/bml/BmlLoginFlow.kt +++ b/app/src/main/java/sh/sar/basedbank/api/bml/BmlLoginFlow.kt @@ -185,25 +185,66 @@ class BmlLoginFlow { val root = JSONObject(json) if (!root.optBoolean("success")) return emptyList() val dashboard = root.optJSONObject("payload")?.optJSONArray("dashboard") ?: return emptyList() - return (0 until dashboard.length()).map { i -> + + val casaAccounts = mutableListOf() + val seenPrepaid = mutableSetOf() + val prepaidCards = mutableListOf() + + for (i in 0 until dashboard.length()) { val item = dashboard.getJSONObject(i) val currency = item.optString("currency", "MVR") - val available = item.optDouble("availableBalance", 0.0) - MibAccount( - profileName = "Bank of Maldives", - profileType = "BML", - accountNumber = item.optString("account"), - accountBriefName = item.optString("alias"), - currencyName = currency, - accountTypeName = item.optString("product"), - availableBalance = "%.2f".format(available), - currentBalance = "%.2f".format(item.optDouble("ledgerBalance", 0.0)), - blockedAmount = "%.2f".format(item.optDouble("lockedAmount", 0.0)), - mvrBalance = if (currency == "MVR") "%.2f".format(available) else "0.00", - statusDesc = item.optString("account_status", "Active"), - profileImageHash = null - ) + val accountType = item.optString("account_type", "CASA") + val product = item.optString("product") + val accountNumber = item.optString("account") + val status = item.optString("account_status", "Active") + + if (accountType == "CASA") { + val available = item.optDouble("availableBalance", 0.0) + casaAccounts.add(MibAccount( + profileName = "Bank of Maldives", + profileType = "BML", + accountNumber = accountNumber, + accountBriefName = item.optString("alias"), + currencyName = currency, + accountTypeName = product, + availableBalance = "%.2f".format(available), + currentBalance = "%.2f".format(item.optDouble("ledgerBalance", 0.0)), + blockedAmount = "%.2f".format(item.optDouble("lockedAmount", 0.0)), + mvrBalance = if (currency == "MVR") "%.2f".format(available) else "0.00", + statusDesc = status, + profileImageHash = null + )) + } else if (accountType == "Card") { + val isPrepaid = item.optBoolean("prepaid_card", false) + if (isPrepaid) { + // Deduplicate by account number, prefer Active + if (!seenPrepaid.contains(accountNumber) || status == "Active") { + seenPrepaid.add(accountNumber) + prepaidCards.removeAll { it.accountNumber == accountNumber } + val cardBalance = item.optJSONObject("cardBalance") + val available = cardBalance?.optDouble("AvailableLimit", 0.0) ?: 0.0 + prepaidCards.add(MibAccount( + profileName = "Cards", + profileType = "BML_PREPAID", + accountNumber = accountNumber, + accountBriefName = product, + currencyName = currency, + accountTypeName = product, + availableBalance = "%.2f".format(available), + currentBalance = "%.2f".format(cardBalance?.optDouble("CurrentBalance", 0.0) ?: 0.0), + blockedAmount = "0.00", + mvrBalance = if (currency == "MVR") "%.2f".format(available) else "0.00", + statusDesc = status, + profileImageHash = null + )) + } + } else { + // Linked debit cards have no independent balance or account link — skip + } + } } + + return casaAccounts + prepaidCards } private fun parseContacts(json: String): List { diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/AccountsAdapter.kt b/app/src/main/java/sh/sar/basedbank/ui/home/AccountsAdapter.kt index 2fee318..7562eac 100644 --- a/app/src/main/java/sh/sar/basedbank/ui/home/AccountsAdapter.kt +++ b/app/src/main/java/sh/sar/basedbank/ui/home/AccountsAdapter.kt @@ -1,10 +1,14 @@ package sh.sar.basedbank.ui.home +import android.graphics.Color +import android.graphics.drawable.GradientDrawable import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import sh.sar.basedbank.api.mib.MibAccount import sh.sar.basedbank.databinding.ItemAccountBinding +import sh.sar.basedbank.databinding.ItemCardBinding import sh.sar.basedbank.databinding.ItemProfileHeaderBinding class AccountsAdapter(accounts: List) : @@ -13,6 +17,7 @@ class AccountsAdapter(accounts: List) : private sealed class Item { data class Header(val profileName: String, val profileType: String) : Item() data class Account(val account: MibAccount) : Item() + data class Card(val account: MibAccount) : Item() } private val items: MutableList = buildItems(accounts).toMutableList() @@ -30,28 +35,34 @@ class AccountsAdapter(accounts: List) : add(Item.Header(account.profileName, account.profileType)) lastProfile = account.profileName } - add(Item.Account(account)) + if (account.profileType == "BML_PREPAID") { + add(Item.Card(account)) + } else { + add(Item.Account(account)) + } } } override fun getItemViewType(position: Int) = when (items[position]) { - is Item.Header -> TYPE_HEADER + is Item.Header -> TYPE_HEADER is Item.Account -> TYPE_ACCOUNT + is Item.Card -> TYPE_CARD } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val inflater = LayoutInflater.from(parent.context) - return if (viewType == TYPE_HEADER) { - HeaderViewHolder(ItemProfileHeaderBinding.inflate(inflater, parent, false)) - } else { - AccountViewHolder(ItemAccountBinding.inflate(inflater, parent, false)) + return when (viewType) { + TYPE_HEADER -> HeaderViewHolder(ItemProfileHeaderBinding.inflate(inflater, parent, false)) + TYPE_CARD -> CardViewHolder(ItemCardBinding.inflate(inflater, parent, false)) + else -> AccountViewHolder(ItemAccountBinding.inflate(inflater, parent, false)) } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (val item = items[position]) { - is Item.Header -> (holder as HeaderViewHolder).bind(item) + is Item.Header -> (holder as HeaderViewHolder).bind(item) is Item.Account -> (holder as AccountViewHolder).bind(item.account) + is Item.Card -> (holder as CardViewHolder).bind(item.account) } } @@ -62,9 +73,10 @@ class AccountsAdapter(accounts: List) : fun bind(item: Item.Header) { binding.tvProfileName.text = item.profileName binding.tvProfileType.text = when (item.profileType) { - "BML" -> "Bank of Maldives" - "0" -> "Personal" - else -> "Business" + "BML" -> "Bank of Maldives" + "BML_PREPAID" -> "BML" + "0" -> "Personal" + else -> "Business" } } } @@ -80,8 +92,45 @@ class AccountsAdapter(accounts: List) : } } + private inner class CardViewHolder(private val binding: ItemCardBinding) : + RecyclerView.ViewHolder(binding.root) { + fun bind(account: MibAccount) { + val brand = cardBrand(account.accountTypeName) + binding.tvCardBrand.text = brand.label + setBrandBackground(brand.color) + binding.tvCardName.text = account.accountBriefName + binding.tvCardNumber.text = account.accountNumber + + val isPrepaid = account.profileType == "BML_PREPAID" + binding.layoutCardBalance.visibility = if (isPrepaid) View.VISIBLE else View.GONE + if (isPrepaid) { + binding.tvCardBalance.text = "${account.currencyName} ${account.availableBalance}" + } + } + + private fun setBrandBackground(colorHex: String) { + val drawable = GradientDrawable().apply { + shape = GradientDrawable.RECTANGLE + cornerRadius = 100f + setColor(Color.parseColor(colorHex)) + } + binding.tvCardBrand.background = drawable + } + } + companion object { - private const val TYPE_HEADER = 0 + private const val TYPE_HEADER = 0 private const val TYPE_ACCOUNT = 1 + private const val TYPE_CARD = 2 + + private data class Brand(val label: String, val color: String) + + private fun cardBrand(productName: String): Brand = when { + productName.contains("AMEX", ignoreCase = true) || + productName.contains("AMERICAN EXPRESS", ignoreCase = true) -> Brand("AMEX", "#016FD0") + productName.contains("VISA", ignoreCase = true) -> Brand("VISA", "#1A1F71") + productName.contains("MASTERCARD", ignoreCase = true) -> Brand("MC", "#FF5F00") + else -> Brand("CARD", "#555555") + } } } diff --git a/app/src/main/res/layout/item_card.xml b/app/src/main/res/layout/item_card.xml new file mode 100644 index 0000000..6e5cd09 --- /dev/null +++ b/app/src/main/res/layout/item_card.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +