forked from thijooree/android
huge refactor.. might need to revert later
This commit is contained in:
@@ -9,8 +9,8 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.mib.Transaction
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.api.models.BankTransaction
|
||||
import sh.sar.basedbank.util.AccountHistoryDisplay
|
||||
import sh.sar.basedbank.databinding.ItemAccountHistoryHeaderBinding
|
||||
import sh.sar.basedbank.databinding.ItemDateHeaderBinding
|
||||
@@ -21,13 +21,13 @@ import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class AccountHistoryAdapter(
|
||||
private val account: MibAccount,
|
||||
private val account: BankAccount,
|
||||
private val display: AccountHistoryDisplay
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
private sealed class Item {
|
||||
data class DateHeader(val label: String) : Item()
|
||||
data class Trx(val transaction: Transaction) : Item()
|
||||
data class Trx(val transaction: BankTransaction) : Item()
|
||||
}
|
||||
|
||||
private val displayItems = mutableListOf<Item>()
|
||||
@@ -36,7 +36,7 @@ class AccountHistoryAdapter(
|
||||
private val iconUrlCache = mutableMapOf<String, Bitmap>()
|
||||
var onImageNeeded: ((counterpartyName: String) -> Unit)? = null
|
||||
var onIconUrlNeeded: ((url: String) -> Unit)? = null
|
||||
var onTransferClick: ((MibAccount) -> Unit)? = null
|
||||
var onTransferClick: ((BankAccount) -> Unit)? = null
|
||||
private var hideAmounts: Boolean = false
|
||||
|
||||
fun setHideAmounts(hide: Boolean) {
|
||||
@@ -84,7 +84,7 @@ class AccountHistoryAdapter(
|
||||
* Display the given (already sorted + filtered) list with date group headers.
|
||||
* Silently resets the loading footer so notifyDataSetChanged covers everything.
|
||||
*/
|
||||
fun setTransactions(transactions: List<Transaction>) {
|
||||
fun setTransactions(transactions: List<BankTransaction>) {
|
||||
_showLoadingFooter = false
|
||||
displayItems.clear()
|
||||
lastInsertedDateKey = ""
|
||||
@@ -105,7 +105,7 @@ class AccountHistoryAdapter(
|
||||
* Appends [newTransactions] (assumed to be older than all existing items) using incremental
|
||||
* notifications, so the RecyclerView doesn't reset scroll position.
|
||||
*/
|
||||
fun appendTransactions(newTransactions: List<Transaction>) {
|
||||
fun appendTransactions(newTransactions: List<BankTransaction>) {
|
||||
if (newTransactions.isEmpty()) return
|
||||
if (_showLoadingFooter) {
|
||||
val pos = itemCount - 1
|
||||
@@ -184,7 +184,7 @@ class AccountHistoryAdapter(
|
||||
|
||||
inner class TransactionVH(private val b: ItemTransactionBinding) :
|
||||
RecyclerView.ViewHolder(b.root) {
|
||||
fun bind(trx: Transaction) {
|
||||
fun bind(trx: BankTransaction) {
|
||||
val isCredit = trx.amount >= 0
|
||||
val color = sourceColor(trx.source)
|
||||
val name = trx.counterpartyName ?: trx.description
|
||||
@@ -237,7 +237,7 @@ class AccountHistoryAdapter(
|
||||
b.root.setOnClickListener { showDetail(trx) }
|
||||
}
|
||||
|
||||
private fun showDetail(trx: Transaction) {
|
||||
private fun showDetail(trx: BankTransaction) {
|
||||
val ctx = b.root.context
|
||||
val title = trx.counterpartyName?.takeIf { it.isNotBlank() } ?: trx.description
|
||||
val details = buildString {
|
||||
|
||||
@@ -22,9 +22,9 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.api.mib.MibContactsClient
|
||||
import sh.sar.basedbank.api.mib.Transaction
|
||||
import sh.sar.basedbank.api.models.BankTransaction
|
||||
import sh.sar.basedbank.api.mib.TransactionCache
|
||||
import sh.sar.basedbank.databinding.FragmentAccountHistoryBinding
|
||||
import sh.sar.basedbank.util.AccountHistoryParser
|
||||
@@ -39,10 +39,10 @@ class AccountHistoryFragment : Fragment() {
|
||||
private val viewModel: HomeViewModel by activityViewModels()
|
||||
|
||||
private lateinit var adapter: AccountHistoryAdapter
|
||||
private lateinit var account: MibAccount
|
||||
private lateinit var account: BankAccount
|
||||
private lateinit var fetcher: HistoryFetcher
|
||||
|
||||
private val allTransactions = mutableListOf<Transaction>()
|
||||
private val allTransactions = mutableListOf<BankTransaction>()
|
||||
private var searchQuery = ""
|
||||
private var firstPageDone = false
|
||||
private val pendingImageNames = mutableSetOf<String>()
|
||||
@@ -53,7 +53,7 @@ class AccountHistoryFragment : Fragment() {
|
||||
companion object {
|
||||
private const val ARG_ACCOUNT_NUMBER = "account_number"
|
||||
|
||||
fun newInstance(account: MibAccount) = AccountHistoryFragment().apply {
|
||||
fun newInstance(account: BankAccount) = AccountHistoryFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(ARG_ACCOUNT_NUMBER, account.accountNumber)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.databinding.ItemAccountBinding
|
||||
import sh.sar.basedbank.databinding.ItemCardBinding
|
||||
import sh.sar.basedbank.databinding.ItemDateHeaderBinding
|
||||
@@ -16,22 +16,22 @@ import sh.sar.basedbank.util.AccountListDisplay
|
||||
import sh.sar.basedbank.util.AccountListParser
|
||||
|
||||
class AccountsAdapter(
|
||||
accounts: List<MibAccount>,
|
||||
private val onAccountClick: (MibAccount) -> Unit = {}
|
||||
accounts: List<BankAccount>,
|
||||
private val onAccountClick: (BankAccount) -> Unit = {}
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
var onTransferClick: ((MibAccount) -> Unit)? = null
|
||||
var onTransferClick: ((BankAccount) -> Unit)? = null
|
||||
private var hideAmounts: Boolean = false
|
||||
|
||||
private sealed class Item {
|
||||
data class SectionTitle(val label: String) : Item()
|
||||
data class Account(val account: MibAccount, val display: AccountListDisplay) : Item()
|
||||
data class Card(val account: MibAccount, val display: AccountListDisplay) : Item()
|
||||
data class Account(val account: BankAccount, val display: AccountListDisplay) : Item()
|
||||
data class Card(val account: BankAccount, val display: AccountListDisplay) : Item()
|
||||
}
|
||||
|
||||
private val items: MutableList<Item> = buildItems(accounts).toMutableList()
|
||||
|
||||
fun updateAccounts(accounts: List<MibAccount>) {
|
||||
fun updateAccounts(accounts: List<BankAccount>) {
|
||||
items.clear()
|
||||
items.addAll(buildItems(accounts))
|
||||
notifyDataSetChanged()
|
||||
@@ -43,12 +43,12 @@ class AccountsAdapter(
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun buildItems(accounts: List<MibAccount>): List<Item> = buildList {
|
||||
private fun buildItems(accounts: List<BankAccount>): List<Item> = buildList {
|
||||
val displayed = accounts.mapNotNull { acc -> AccountListParser.from(acc)?.let { acc to it } }
|
||||
val nonCards = displayed.filter { !it.second.isCard }
|
||||
val cards = displayed.filter { it.second.isCard }
|
||||
|
||||
val groups = LinkedHashMap<String, MutableList<Pair<MibAccount, AccountListDisplay>>>()
|
||||
val groups = LinkedHashMap<String, MutableList<Pair<BankAccount, AccountListDisplay>>>()
|
||||
for ((acc, display) in nonCards) {
|
||||
val title = sectionTitle(acc)
|
||||
groups.getOrPut(title) { mutableListOf() }.add(acc to display)
|
||||
@@ -64,7 +64,7 @@ class AccountsAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
private fun sectionTitle(account: MibAccount): String {
|
||||
private fun sectionTitle(account: BankAccount): String {
|
||||
val bankName = when (account.bank) {
|
||||
"BML" -> "Bank of Maldives"
|
||||
"FAHIPAY" -> "Fahipay"
|
||||
@@ -112,7 +112,7 @@ class AccountsAdapter(
|
||||
|
||||
private inner class AccountViewHolder(private val binding: ItemAccountBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(account: MibAccount, display: AccountListDisplay) {
|
||||
fun bind(account: BankAccount, display: AccountListDisplay) {
|
||||
binding.tvAccountName.text = display.name
|
||||
binding.tvAccountNumber.text = display.number
|
||||
binding.tvAccountType.text = display.typeLabel
|
||||
@@ -128,7 +128,7 @@ class AccountsAdapter(
|
||||
|
||||
private inner class CardViewHolder(private val binding: ItemCardBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(account: MibAccount, display: AccountListDisplay) {
|
||||
fun bind(account: BankAccount, display: AccountListDisplay) {
|
||||
binding.ivCardBrand.setImageResource(display.cardBrandIcon)
|
||||
binding.tvCardName.text = display.name
|
||||
binding.tvCardNumber.text = display.number
|
||||
|
||||
@@ -30,8 +30,9 @@ import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.bml.BmlAccountValidation
|
||||
import sh.sar.basedbank.api.bml.BmlLoginFlow
|
||||
import sh.sar.basedbank.api.mib.MibBeneficiaryCategory
|
||||
import sh.sar.basedbank.api.bml.BmlContactsClient
|
||||
import sh.sar.basedbank.api.bml.BmlValidateClient
|
||||
import sh.sar.basedbank.api.models.BankContactCategory
|
||||
import sh.sar.basedbank.api.mib.MibContactsClient
|
||||
import sh.sar.basedbank.api.mib.MibProfile
|
||||
import sh.sar.basedbank.api.mib.MibTransferClient
|
||||
@@ -64,7 +65,7 @@ class AddContactSheetFragment : BottomSheetDialogFragment() {
|
||||
|
||||
private var selectedImageBase64: String = ""
|
||||
private var selectedCategoryId: String = "0"
|
||||
private var categories: List<MibBeneficiaryCategory> = emptyList()
|
||||
private var categories: List<BankContactCategory> = emptyList()
|
||||
|
||||
private val imagePicker = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
|
||||
uri ?: return@registerForActivityResult
|
||||
@@ -244,14 +245,12 @@ class AddContactSheetFragment : BottomSheetDialogFragment() {
|
||||
private fun lookupForBml(input: String): BmlAccountValidation? {
|
||||
val loginId = selectedDest?.bmlLoginId ?: return null
|
||||
val bmlSess = app.bmlSessions[loginId] ?: return null
|
||||
val bmlFlow = BmlLoginFlow()
|
||||
|
||||
// 1) Try BML validate
|
||||
val validated = try { bmlFlow.validateAccount(bmlSess, input) } catch (_: Exception) { null }
|
||||
val validated = try { BmlValidateClient().validateAccount(bmlSess, input) } catch (_: Exception) { null }
|
||||
if (validated != null) return validated
|
||||
|
||||
// 2) Try BML MIB verify
|
||||
val mibVerified = try { bmlFlow.verifyMibAccount(bmlSess, input) } catch (_: Exception) { null }
|
||||
val mibVerified = try { BmlValidateClient().verifyMibAccount(bmlSess, input) } catch (_: Exception) { null }
|
||||
if (mibVerified != null) return mibVerified
|
||||
|
||||
// 3) Fall back to MIB IPS lookup (for USD MIB accounts not reachable via BML)
|
||||
@@ -295,7 +294,7 @@ class AddContactSheetFragment : BottomSheetDialogFragment() {
|
||||
|
||||
// MIB lookup failed (e.g. BML USD account) — fall back to BML validate
|
||||
val bmlSess = app.anyBmlSession() ?: return null
|
||||
return try { BmlLoginFlow().validateAccount(bmlSess, input) } catch (_: Exception) { null }
|
||||
return try { BmlValidateClient().validateAccount(bmlSess, input) } catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
private fun showLookupResult(validation: BmlAccountValidation, input: String) {
|
||||
@@ -421,15 +420,14 @@ class AddContactSheetFragment : BottomSheetDialogFragment() {
|
||||
val loginId = selectedDest?.bmlLoginId ?: return false
|
||||
val bmlSess = app.bmlSessions[loginId] ?: return false
|
||||
val lookup = bmlLookup ?: return false
|
||||
val bmlFlow = BmlLoginFlow()
|
||||
val account = lookup.account
|
||||
return when {
|
||||
account.matches(Regex("^7\\d{12}$")) ->
|
||||
// BML account → IAT
|
||||
bmlFlow.saveContact(bmlSess, "IAT", account, alias)
|
||||
BmlContactsClient().saveContact(bmlSess, "IAT", account, alias)
|
||||
account.matches(Regex("^9\\d{16}$")) ->
|
||||
// MIB internal → DOT; swift is BML's internal UUID for MIB bank
|
||||
bmlFlow.saveContact(bmlSess, "DOT", account, alias,
|
||||
BmlContactsClient().saveContact(bmlSess, "DOT", account, alias,
|
||||
currency = lookup.currency, name = lookup.name, swift = MIB_SWIFT_ON_BML)
|
||||
else -> false
|
||||
}
|
||||
@@ -489,7 +487,7 @@ class AddContactSheetFragment : BottomSheetDialogFragment() {
|
||||
if (dest.isBml) {
|
||||
val loginId = dest.bmlLoginId ?: return@launch
|
||||
val bmlSess = app.bmlSessions[loginId] ?: return@launch
|
||||
val fresh = BmlLoginFlow().fetchContacts(bmlSess, loginId)
|
||||
val fresh = BmlContactsClient().fetchContacts(bmlSess, loginId)
|
||||
val existing = viewModel.contacts.value ?: emptyList()
|
||||
val merged = existing.filter { it.benefCategoryId != "BML" } + fresh
|
||||
viewModel.contacts.postValue(merged)
|
||||
|
||||
@@ -23,7 +23,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.mib.MibBeneficiaryCategory
|
||||
import sh.sar.basedbank.api.models.BankContactCategory
|
||||
import sh.sar.basedbank.api.mib.MibContactsClient
|
||||
import sh.sar.basedbank.databinding.FragmentContactsBinding
|
||||
import sh.sar.basedbank.util.ContactDisplay
|
||||
@@ -153,7 +153,7 @@ class ContactsFragment : Fragment() {
|
||||
}.also { it.attach() }
|
||||
}
|
||||
|
||||
private fun rebuildPager(cats: List<MibBeneficiaryCategory>) {
|
||||
private fun rebuildPager(cats: List<BankContactCategory>) {
|
||||
val pages = buildList {
|
||||
add(TabPage(null, getString(R.string.contacts_tab_all)))
|
||||
cats.forEach { add(TabPage(it.id, it.categoryName)) }
|
||||
|
||||
@@ -12,7 +12,7 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.bml.BmlForeignLimit
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.api.mib.MibFinanceDeal
|
||||
import sh.sar.basedbank.databinding.FragmentDashboardBinding
|
||||
import sh.sar.basedbank.databinding.ItemForeignLimitBinding
|
||||
@@ -68,7 +68,7 @@ class DashboardFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateBalances(accounts: List<MibAccount>) {
|
||||
private fun updateBalances(accounts: List<BankAccount>) {
|
||||
val hide = viewModel.hideAmounts.value ?: false
|
||||
if (hide) {
|
||||
binding.tvMvrBalance.text = "MVR ••••••"
|
||||
|
||||
@@ -36,18 +36,22 @@ import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.bml.AuthExpiredException
|
||||
import sh.sar.basedbank.api.bml.BmlAccountClient
|
||||
import sh.sar.basedbank.api.bml.BmlActivationResult
|
||||
import sh.sar.basedbank.api.bml.BmlLoginFlow
|
||||
import sh.sar.basedbank.api.bml.BmlContactsClient
|
||||
import sh.sar.basedbank.api.bml.BmlForeignLimitsClient
|
||||
import sh.sar.basedbank.api.bml.BmlProfile
|
||||
import sh.sar.basedbank.api.bml.BmlSession
|
||||
import sh.sar.basedbank.api.fahipay.FahipayAccountClient
|
||||
import sh.sar.basedbank.api.fahipay.FahipayContactsClient
|
||||
import sh.sar.basedbank.api.fahipay.FahipayLoginFlow
|
||||
import sh.sar.basedbank.api.fahipay.FahipaySession
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.api.mib.MibLoginFlow
|
||||
import sh.sar.basedbank.databinding.ActivityHomeBinding
|
||||
import sh.sar.basedbank.ui.login.LoginActivity
|
||||
import sh.sar.basedbank.api.mib.MibBeneficiary
|
||||
import sh.sar.basedbank.api.mib.MibBeneficiaryCategory
|
||||
import sh.sar.basedbank.api.models.BankContact
|
||||
import sh.sar.basedbank.api.models.BankContactCategory
|
||||
import sh.sar.basedbank.api.mib.MibContactsClient
|
||||
import sh.sar.basedbank.api.mib.MibFinancingClient
|
||||
import sh.sar.basedbank.api.mib.MibProfile
|
||||
@@ -490,7 +494,7 @@ fun applyNavLabelVisibility() {
|
||||
val loginTag = "bml_$loginId"
|
||||
val app = application as BasedBankApp
|
||||
val savedProfiles = store.loadBmlProfiles(loginId)
|
||||
val allAccounts = mutableListOf<MibAccount>()
|
||||
val allAccounts = mutableListOf<BankAccount>()
|
||||
var anyExpired = savedProfiles.isEmpty()
|
||||
|
||||
// Try each saved profile's cached session
|
||||
@@ -499,7 +503,7 @@ fun applyNavLabelVisibility() {
|
||||
if (saved != null) {
|
||||
try {
|
||||
val session = BmlSession(saved.first, saved.second)
|
||||
val accounts = BmlLoginFlow().fetchAccounts(session, loginTag, profile.name, profile.profileId)
|
||||
val accounts = BmlAccountClient().fetchAccounts(session, loginTag, profile.name, profile.profileId)
|
||||
app.bmlSessions[profile.profileId] = session
|
||||
allAccounts += accounts
|
||||
} catch (_: AuthExpiredException) { anyExpired = true
|
||||
@@ -517,7 +521,7 @@ fun applyNavLabelVisibility() {
|
||||
if (legacyToken != null) {
|
||||
try {
|
||||
val session = BmlSession(legacyToken.first, legacyToken.second)
|
||||
val accounts = BmlLoginFlow().fetchAccounts(session, loginTag)
|
||||
val accounts = BmlAccountClient().fetchAccounts(session, loginTag)
|
||||
app.bmlSessions[loginId] = session
|
||||
allAccounts += accounts
|
||||
anyExpired = false
|
||||
@@ -565,7 +569,7 @@ fun applyNavLabelVisibility() {
|
||||
}
|
||||
|
||||
if (allAccounts.isNotEmpty()) AccountCache.saveBml(this@HomeActivity, loginId, allAccounts)
|
||||
allAccounts as List<MibAccount>
|
||||
allAccounts as List<BankAccount>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,10 +585,9 @@ fun applyNavLabelVisibility() {
|
||||
if (savedSession != null) {
|
||||
try {
|
||||
val session = FahipaySession(savedSession.first, savedSession.second)
|
||||
fahipayFlow.setSessionCookie(session.sessionCookie)
|
||||
val balance = fahipayFlow.fetchBalance(session)
|
||||
val profile = fahipayFlow.fetchProfile(session)
|
||||
val accounts = listOf(fahipayFlow.buildAccount(profile, balance, loginTag))
|
||||
val balance = FahipayAccountClient().fetchBalance(session)
|
||||
val profile = FahipayAccountClient().fetchProfile(session)
|
||||
val accounts = listOf(FahipayAccountClient().buildAccount(profile, balance, loginTag))
|
||||
val app = application as BasedBankApp
|
||||
app.fahipaySessions[loginId] = session
|
||||
AccountCache.saveFahipay(this@HomeActivity, loginId, accounts)
|
||||
@@ -601,9 +604,9 @@ fun applyNavLabelVisibility() {
|
||||
val cookieValue = fahipayFlow.getSessionCookieValue() ?: ""
|
||||
val session = FahipaySession(authId, cookieValue)
|
||||
store.saveFahipaySession(loginId, authId, cookieValue)
|
||||
val profile = fahipayFlow.fetchProfile(session)
|
||||
val balance = fahipayFlow.fetchBalance(session)
|
||||
val accounts = listOf(fahipayFlow.buildAccount(profile, balance, loginTag))
|
||||
val profile = FahipayAccountClient().fetchProfile(session)
|
||||
val balance = FahipayAccountClient().fetchBalance(session)
|
||||
val accounts = listOf(FahipayAccountClient().buildAccount(profile, balance, loginTag))
|
||||
val app = application as BasedBankApp
|
||||
app.fahipaySessions[loginId] = session
|
||||
AccountCache.saveFahipay(this@HomeActivity, loginId, accounts)
|
||||
@@ -636,7 +639,7 @@ fun applyNavLabelVisibility() {
|
||||
}
|
||||
|
||||
/** Filters accounts whose profileId the user has hidden in settings. */
|
||||
private fun List<MibAccount>.filterVisibleAccounts(): List<MibAccount> {
|
||||
private fun List<BankAccount>.filterVisibleAccounts(): List<BankAccount> {
|
||||
val store = CredentialStore(this@HomeActivity)
|
||||
return filter { acc ->
|
||||
when (acc.bank) {
|
||||
@@ -669,11 +672,10 @@ fun applyNavLabelVisibility() {
|
||||
}
|
||||
|
||||
private fun refreshBmlLimits(session: BmlSession) {
|
||||
val bmlFlow = BmlLoginFlow()
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val (userName, limits) = withContext(Dispatchers.IO) {
|
||||
Pair(bmlFlow.fetchUserInfo(session)?.fullName ?: "", bmlFlow.fetchForeignLimits(session))
|
||||
Pair(BmlAccountClient().fetchUserInfo(session)?.fullName ?: "", BmlForeignLimitsClient().fetchForeignLimits(session))
|
||||
}
|
||||
val existing = viewModel.bmlLimits.value?.toMutableList() ?: mutableListOf()
|
||||
val idx = existing.indexOfFirst { it.userName == userName }
|
||||
@@ -693,7 +695,7 @@ fun applyNavLabelVisibility() {
|
||||
val allBmlContacts = withContext(Dispatchers.IO) {
|
||||
store.getBmlLoginIds().flatMap { loginId ->
|
||||
val session = app.anyBmlSessionFor(loginId) ?: return@flatMap emptyList()
|
||||
val contacts = BmlLoginFlow().fetchContacts(session, loginId)
|
||||
val contacts = BmlContactsClient().fetchContacts(session, loginId)
|
||||
if (contacts.isNotEmpty()) ContactsCache.saveBml(this@HomeActivity, loginId, contacts)
|
||||
contacts
|
||||
}
|
||||
@@ -736,13 +738,11 @@ fun applyNavLabelVisibility() {
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val groups = withContext(Dispatchers.IO) {
|
||||
val flow = FahipayLoginFlow()
|
||||
flow.setSessionCookie(session.sessionCookie)
|
||||
flow.fetchContacts(session)
|
||||
FahipayContactsClient().fetchContacts(session)
|
||||
}
|
||||
if (groups.isEmpty()) return@launch
|
||||
val contacts = groups.flatMap { it.contacts }
|
||||
val categories = groups.map { MibBeneficiaryCategory(it.categoryId, it.label, it.contacts.size) }
|
||||
val categories = groups.map { BankContactCategory(it.categoryId, it.label, it.contacts.size) }
|
||||
ContactsCache.saveFahipay(this@HomeActivity, contacts, categories)
|
||||
val mibContacts = ContactsCache.loadContacts(this@HomeActivity)
|
||||
val bmlLoginIds = sh.sar.basedbank.util.CredentialStore(this@HomeActivity).getBmlLoginIds()
|
||||
@@ -755,11 +755,11 @@ fun applyNavLabelVisibility() {
|
||||
}
|
||||
|
||||
private fun mergeContacts(
|
||||
mib: List<MibBeneficiary>,
|
||||
bml: List<MibBeneficiary>
|
||||
): List<MibBeneficiary> {
|
||||
mib: List<BankContact>,
|
||||
bml: List<BankContact>
|
||||
): List<BankContact> {
|
||||
val seen = mutableSetOf<String>()
|
||||
val result = mutableListOf<MibBeneficiary>()
|
||||
val result = mutableListOf<BankContact>()
|
||||
for (c in mib) if (seen.add(c.benefNo)) result.add(c)
|
||||
for (c in bml) if (seen.add(c.benefNo)) result.add(c)
|
||||
return result
|
||||
@@ -774,8 +774,8 @@ fun applyNavLabelVisibility() {
|
||||
val (allContacts, allCategories) = withContext(Dispatchers.IO) {
|
||||
val seenContacts = mutableSetOf<String>()
|
||||
val seenCategories = mutableSetOf<String>()
|
||||
val contacts = mutableListOf<MibBeneficiary>()
|
||||
val categories = mutableListOf<MibBeneficiaryCategory>()
|
||||
val contacts = mutableListOf<BankContact>()
|
||||
val categories = mutableListOf<BankContactCategory>()
|
||||
for (profile in profiles) {
|
||||
try {
|
||||
flow.switchProfile(session, profile)
|
||||
@@ -803,7 +803,7 @@ fun applyNavLabelVisibility() {
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshBalances(src: MibAccount) {
|
||||
fun refreshBalances(src: BankAccount) {
|
||||
val app = application as BasedBankApp
|
||||
lifecycleScope.launch {
|
||||
val current = viewModel.accounts.value ?: emptyList()
|
||||
@@ -811,12 +811,10 @@ fun applyNavLabelVisibility() {
|
||||
val fresh = withContext(Dispatchers.IO) {
|
||||
val sess = app.fahipaySessionFor(src) ?: return@withContext null
|
||||
try {
|
||||
val flow = FahipayLoginFlow()
|
||||
flow.setSessionCookie(sess.sessionCookie)
|
||||
val balance = flow.fetchBalance(sess)
|
||||
val profile = flow.fetchProfile(sess)
|
||||
val balance = FahipayAccountClient().fetchBalance(sess)
|
||||
val profile = FahipayAccountClient().fetchProfile(sess)
|
||||
val loginTag = "fahipay_${profile.profileId}"
|
||||
val accounts = listOf(flow.buildAccount(profile, balance, loginTag))
|
||||
val accounts = listOf(FahipayAccountClient().buildAccount(profile, balance, loginTag))
|
||||
val loginId = src.loginTag.removePrefix("fahipay_")
|
||||
AccountCache.saveFahipay(this@HomeActivity, loginId, accounts)
|
||||
app.fahipayAccounts = app.fahipayAccounts.filter { it.loginTag != src.loginTag } + accounts
|
||||
@@ -830,7 +828,7 @@ fun applyNavLabelVisibility() {
|
||||
val fresh = withContext(Dispatchers.IO) {
|
||||
val sess = app.bmlSessionFor(src) ?: return@withContext null
|
||||
try {
|
||||
val accounts = BmlLoginFlow().fetchAccounts(sess, src.loginTag)
|
||||
val accounts = BmlAccountClient().fetchAccounts(sess, src.loginTag)
|
||||
AccountCache.saveBml(this@HomeActivity, loginId, accounts)
|
||||
val otherBml = app.bmlAccounts.filter { it.loginTag != src.loginTag }
|
||||
app.bmlAccounts = otherBml + accounts
|
||||
|
||||
@@ -3,16 +3,16 @@ package sh.sar.basedbank.ui.home
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import sh.sar.basedbank.api.bml.BmlForeignLimit
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.mib.MibBeneficiary
|
||||
import sh.sar.basedbank.api.mib.MibBeneficiaryCategory
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.api.models.BankContact
|
||||
import sh.sar.basedbank.api.models.BankContactCategory
|
||||
import sh.sar.basedbank.api.mib.MibFinanceDeal
|
||||
|
||||
class HomeViewModel : ViewModel() {
|
||||
val accounts = MutableLiveData<List<MibAccount>>(emptyList())
|
||||
val accounts = MutableLiveData<List<BankAccount>>(emptyList())
|
||||
val financing = MutableLiveData<List<MibFinanceDeal>>(emptyList())
|
||||
val contacts = MutableLiveData<List<MibBeneficiary>>(emptyList())
|
||||
val contactCategories = MutableLiveData<List<MibBeneficiaryCategory>>(emptyList())
|
||||
val contacts = MutableLiveData<List<BankContact>>(emptyList())
|
||||
val contactCategories = MutableLiveData<List<BankContactCategory>>(emptyList())
|
||||
|
||||
data class BmlLimitsData(val userName: String, val limits: List<BmlForeignLimit>)
|
||||
val bmlLimits = MutableLiveData<List<BmlLimitsData>>(emptyList())
|
||||
|
||||
@@ -14,7 +14,8 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.api.bml.BmlLoginFlow
|
||||
import sh.sar.basedbank.api.bml.BmlAccountClient
|
||||
import sh.sar.basedbank.api.mib.MibProfileClient
|
||||
import sh.sar.basedbank.api.mib.MibLoginFlow
|
||||
import sh.sar.basedbank.databinding.FragmentOtpBinding
|
||||
import sh.sar.basedbank.databinding.ItemOtpCardBinding
|
||||
@@ -94,7 +95,7 @@ class OtpFragment : Fragment() {
|
||||
val session = app.mibSessions[loginId] ?: continue
|
||||
val flow = app.mibFlowFor(loginId)
|
||||
val profile = withContext(Dispatchers.IO) {
|
||||
try { flow.fetchPersonalProfile(session) } catch (_: Exception) { null }
|
||||
try { MibProfileClient().fetchPersonalProfile(session) } catch (_: Exception) { null }
|
||||
}
|
||||
if (profile != null) {
|
||||
store.saveMibUserProfile(loginId, CredentialStore.MibUserProfile(
|
||||
@@ -114,7 +115,7 @@ class OtpFragment : Fragment() {
|
||||
if (store.loadBmlUserProfile(loginId)?.fullName.isNullOrBlank()) {
|
||||
val session = app.bmlSessions[loginId] ?: continue
|
||||
val info = withContext(Dispatchers.IO) {
|
||||
try { BmlLoginFlow().fetchUserInfo(session) } catch (_: Exception) { null }
|
||||
try { BmlAccountClient().fetchUserInfo(session) } catch (_: Exception) { null }
|
||||
}
|
||||
if (info != null) {
|
||||
store.saveBmlUserProfile(loginId, CredentialStore.BmlUserProfile(
|
||||
|
||||
@@ -33,7 +33,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.databinding.FragmentPayMvQrBinding
|
||||
import sh.sar.basedbank.databinding.ItemAccountDropdownBinding
|
||||
import sh.sar.basedbank.util.PaymvQrParser
|
||||
@@ -46,7 +46,7 @@ class PayMvQrFragment : Fragment() {
|
||||
private val binding get() = _binding!!
|
||||
private val viewModel: HomeViewModel by activityViewModels()
|
||||
|
||||
private var selectedAccount: MibAccount? = null
|
||||
private var selectedAccount: BankAccount? = null
|
||||
private var generatedBitmap: Bitmap? = null
|
||||
private var generateJob: Job? = null
|
||||
|
||||
@@ -186,7 +186,7 @@ class PayMvQrFragment : Fragment() {
|
||||
|
||||
private fun renderQrCard(
|
||||
ctx: Context,
|
||||
account: MibAccount,
|
||||
account: BankAccount,
|
||||
qrPayload: String,
|
||||
amountStr: String?
|
||||
): Bitmap {
|
||||
@@ -378,10 +378,10 @@ class PayMvQrFragment : Fragment() {
|
||||
|
||||
private inner class QrAccountAdapter(
|
||||
private val context: Context,
|
||||
private val accounts: List<MibAccount>
|
||||
private val accounts: List<BankAccount>
|
||||
) : BaseAdapter(), Filterable {
|
||||
|
||||
fun getAccount(position: Int): MibAccount? = accounts.getOrNull(position)
|
||||
fun getAccount(position: Int): BankAccount? = accounts.getOrNull(position)
|
||||
|
||||
override fun getCount() = accounts.size
|
||||
override fun getItem(position: Int) = accounts.getOrNull(position)
|
||||
@@ -411,7 +411,7 @@ class PayMvQrFragment : Fragment() {
|
||||
FilterResults().apply { values = accounts; count = accounts.size }
|
||||
override fun publishResults(c: CharSequence?, r: FilterResults?) = notifyDataSetChanged()
|
||||
override fun convertResultToString(r: Any?) =
|
||||
(r as? MibAccount)?.let {
|
||||
(r as? BankAccount)?.let {
|
||||
val prefix = if (it.bank == "BML" && it.profileName.isNotBlank()) "${it.profileName} · " else ""
|
||||
"$prefix${it.accountBriefName}"
|
||||
} ?: ""
|
||||
|
||||
@@ -9,17 +9,17 @@ import android.view.ViewGroup
|
||||
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import sh.sar.basedbank.api.mib.Transaction
|
||||
import sh.sar.basedbank.api.models.BankTransaction
|
||||
import sh.sar.basedbank.databinding.ItemDateHeaderBinding
|
||||
import sh.sar.basedbank.databinding.ItemLoadingFooterBinding
|
||||
import sh.sar.basedbank.databinding.ItemTransactionBinding
|
||||
|
||||
/** Adapter for Transaction History — date-grouped, shows account name in secondary line. */
|
||||
/** Adapter for BankTransaction History — date-grouped, shows account name in secondary line. */
|
||||
class TransactionAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
private sealed class Item {
|
||||
data class DateHeader(val label: String) : Item()
|
||||
data class Trx(val transaction: Transaction) : Item()
|
||||
data class Trx(val transaction: BankTransaction) : Item()
|
||||
}
|
||||
|
||||
private val displayItems = mutableListOf<Item>()
|
||||
@@ -67,7 +67,7 @@ class TransactionAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
}
|
||||
|
||||
/** Replace the full sorted transaction list and rebuild date groups. */
|
||||
fun setTransactions(transactions: List<Transaction>) {
|
||||
fun setTransactions(transactions: List<BankTransaction>) {
|
||||
_showLoadingFooter = false
|
||||
displayItems.clear()
|
||||
var lastDateKey = ""
|
||||
@@ -114,7 +114,7 @@ class TransactionAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
inner class TransactionVH(private val b: ItemTransactionBinding) :
|
||||
RecyclerView.ViewHolder(b.root) {
|
||||
fun bind(trx: Transaction) {
|
||||
fun bind(trx: BankTransaction) {
|
||||
val isCredit = trx.amount >= 0
|
||||
val color = AccountHistoryAdapter.sourceColor(trx.source)
|
||||
val name = trx.counterpartyName ?: trx.description
|
||||
@@ -141,7 +141,7 @@ class TransactionAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
}
|
||||
b.tvDescription.text = trx.description
|
||||
|
||||
// Show account name in secondary line for Transaction History
|
||||
// Show account name in secondary line for BankTransaction History
|
||||
b.tvCounterparty.text = trx.accountDisplayName
|
||||
b.tvCounterparty.visibility = View.VISIBLE
|
||||
|
||||
@@ -162,7 +162,7 @@ class TransactionAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
b.root.setOnClickListener { showDetail(trx) }
|
||||
}
|
||||
|
||||
private fun showDetail(trx: Transaction) {
|
||||
private fun showDetail(trx: BankTransaction) {
|
||||
val ctx = b.root.context
|
||||
val title = trx.counterpartyName?.takeIf { it.isNotBlank() } ?: trx.description
|
||||
val details = buildString {
|
||||
|
||||
@@ -36,12 +36,13 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.bml.BmlLoginFlow
|
||||
import sh.sar.basedbank.api.bml.BmlTransferClient
|
||||
import sh.sar.basedbank.api.bml.BmlTransferResult
|
||||
import sh.sar.basedbank.api.bml.BmlValidateClient
|
||||
import sh.sar.basedbank.api.dhiraagu.DhiraaguClient
|
||||
import sh.sar.basedbank.api.fahipay.OoredooClient
|
||||
import sh.sar.basedbank.api.bml.BmlTransferResult
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.mib.MibBeneficiary
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.api.models.BankContact
|
||||
import sh.sar.basedbank.api.mib.MibContactsClient
|
||||
import sh.sar.basedbank.api.mib.MibIpsAccountInfo
|
||||
import sh.sar.basedbank.api.mib.MibLookupException
|
||||
@@ -65,11 +66,11 @@ class TransferFragment : Fragment() {
|
||||
private val binding get() = _binding!!
|
||||
private val viewModel: HomeViewModel by activityViewModels()
|
||||
|
||||
private var selectedAccount: MibAccount? = null
|
||||
private var selectedAccount: BankAccount? = null
|
||||
private val session get() = selectedAccount
|
||||
?.let { (requireActivity().application as BasedBankApp).mibSessionFor(it) }
|
||||
?: (requireActivity().application as BasedBankApp).anyMibSession()
|
||||
private fun bmlSessionFor(account: MibAccount?) =
|
||||
private fun bmlSessionFor(account: BankAccount?) =
|
||||
account?.let { (requireActivity().application as BasedBankApp).bmlSessionFor(it) }
|
||||
?: (requireActivity().application as BasedBankApp).anyBmlSession()
|
||||
|
||||
@@ -105,7 +106,7 @@ class TransferFragment : Fragment() {
|
||||
private const val ARG_AMOUNT_PREFILL = "amount_prefill"
|
||||
private const val ARG_REMARKS_PREFILL = "remarks_prefill"
|
||||
|
||||
fun newInstanceFrom(account: MibAccount) = TransferFragment().apply {
|
||||
fun newInstanceFrom(account: BankAccount) = TransferFragment().apply {
|
||||
arguments = Bundle().apply { putString(ARG_FROM_ACCOUNT, account.accountNumber) }
|
||||
}
|
||||
|
||||
@@ -239,7 +240,7 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun showFromCard(account: MibAccount) {
|
||||
private fun showFromCard(account: BankAccount) {
|
||||
val colorHex = when (account.bank) {
|
||||
"BML" -> "#0066A1"
|
||||
"FAHIPAY" -> "#15BEA7"
|
||||
@@ -284,7 +285,7 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAmountPrefix(account: MibAccount) {
|
||||
private fun updateAmountPrefix(account: BankAccount) {
|
||||
binding.tilAmount.prefixText = if (account.currencyName == "USD") "USD " else "MVR "
|
||||
}
|
||||
|
||||
@@ -369,10 +370,9 @@ class TransferFragment : Fragment() {
|
||||
val info = withContext(Dispatchers.IO) {
|
||||
if (isBmlSource && bmlSess != null) {
|
||||
val inputType = AccountInputParser.detect(accountNumber)
|
||||
val bmlFlow = BmlLoginFlow()
|
||||
val bmlResult = try {
|
||||
if (inputType == AccountInputParser.InputType.MIB_ACCOUNT) bmlFlow.verifyMibAccount(bmlSess, accountNumber)
|
||||
else bmlFlow.validateAccount(bmlSess, accountNumber)
|
||||
if (inputType == AccountInputParser.InputType.MIB_ACCOUNT) BmlValidateClient().verifyMibAccount(bmlSess, accountNumber)
|
||||
else BmlValidateClient().validateAccount(bmlSess, accountNumber)
|
||||
} catch (_: Exception) { null }
|
||||
if (bmlResult != null) {
|
||||
val bankId = when (bmlResult.trnType) {
|
||||
@@ -393,7 +393,7 @@ class TransferFragment : Fragment() {
|
||||
catch (e: MibLookupException) { errorMsg = e.message; null }
|
||||
catch (_: Exception) { errorMsg = getString(R.string.transfer_account_not_found); null }
|
||||
} else {
|
||||
val bmlResult = try { BmlLoginFlow().validateAccount(bmlSess!!, accountNumber) } catch (_: Exception) { null }
|
||||
val bmlResult = try { BmlValidateClient().validateAccount(bmlSess!!, accountNumber) } catch (_: Exception) { null }
|
||||
if (bmlResult != null) {
|
||||
val bankId = when (bmlResult.trnType) {
|
||||
"IAT" -> "MALBMVMV"
|
||||
@@ -731,7 +731,7 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun doMibTransfer(
|
||||
src: MibAccount,
|
||||
src: BankAccount,
|
||||
destAccount: String,
|
||||
destName: String,
|
||||
destDisplay: String,
|
||||
@@ -790,7 +790,7 @@ class TransferFragment : Fragment() {
|
||||
mibReferenceNo = result.trxId,
|
||||
mibTransactionDate = result.date
|
||||
)
|
||||
Triple(true, "Transaction ID: ${result.trxId}\n${result.date}", receipt)
|
||||
Triple(true, "BankTransaction ID: ${result.trxId}\n${result.date}", receipt)
|
||||
} else {
|
||||
Triple(false, result.errorMessage.ifBlank { "Transfer failed" }, null)
|
||||
}
|
||||
@@ -800,7 +800,7 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun doBmlTransfer(
|
||||
src: MibAccount,
|
||||
src: BankAccount,
|
||||
destAccount: String,
|
||||
destDisplay: String,
|
||||
amount: Double,
|
||||
@@ -809,8 +809,8 @@ class TransferFragment : Fragment() {
|
||||
isSrcCard: Boolean,
|
||||
isDestMib: Boolean,
|
||||
currency: String,
|
||||
allAccounts: List<MibAccount>,
|
||||
allContacts: List<MibBeneficiary>
|
||||
allAccounts: List<BankAccount>,
|
||||
allContacts: List<BankContact>
|
||||
): Triple<Boolean, String, TransferReceiptData?> {
|
||||
val loginId = src.loginTag.removePrefix("bml_")
|
||||
val sess = bmlSessionFor(src) ?: return Triple(false, getString(R.string.transfer_session_unavailable), null)
|
||||
@@ -845,10 +845,9 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
val toBank = bank ?: if (isDestMib) "MIB" else "BML"
|
||||
|
||||
val bmlFlow = BmlLoginFlow()
|
||||
// Step 1: initiate
|
||||
val initiated = try {
|
||||
bmlFlow.initiateTransfer(sess, debitAccount, creditAccount, amount, transferType, currency, bank)
|
||||
BmlTransferClient().initiateTransfer(sess, debitAccount, creditAccount, amount, transferType, currency, bank)
|
||||
} catch (e: Exception) { return Triple(false, e.message ?: "Initiation failed", null) }
|
||||
|
||||
if (!initiated) return Triple(false, "Failed to initiate transfer — check your session", null)
|
||||
@@ -858,7 +857,7 @@ class TransferFragment : Fragment() {
|
||||
?.let { Totp.generate(it) } ?: otp
|
||||
|
||||
return try {
|
||||
val result = bmlFlow.confirmTransfer(sess, debitAccount, creditAccount, amount, transferType, currency, confirmOtp, remarks, bank)
|
||||
val result = BmlTransferClient().confirmTransfer(sess, debitAccount, creditAccount, amount, transferType, currency, confirmOtp, remarks, bank)
|
||||
if (result.success) {
|
||||
val receipt = TransferReceiptData(
|
||||
bank = "BML",
|
||||
@@ -1000,12 +999,12 @@ class TransferFragment : Fragment() {
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun MibAccount.toDisplayString() = "$accountBriefName · $accountNumber"
|
||||
private fun BankAccount.toDisplayString() = "$accountBriefName · $accountNumber"
|
||||
|
||||
// items: String = section header, MibAccount = selectable row
|
||||
// items: String = section header, BankAccount = selectable row
|
||||
private inner class AccountDropdownAdapter(
|
||||
private val context: Context,
|
||||
accounts: List<MibAccount>
|
||||
accounts: List<BankAccount>
|
||||
) : BaseAdapter(), Filterable {
|
||||
|
||||
private val items: List<Any> = buildList {
|
||||
@@ -1018,7 +1017,7 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
fun getAccount(position: Int): MibAccount? = (items.getOrNull(position) as? MibAccount)
|
||||
fun getAccount(position: Int): BankAccount? = (items.getOrNull(position) as? BankAccount)
|
||||
?.takeUnless { (it.profileType == "BML_PREPAID" || it.profileType == "BML_CREDIT") && !it.statusDesc.equals("Active", ignoreCase = true) }
|
||||
|
||||
override fun getCount() = items.size
|
||||
@@ -1043,7 +1042,7 @@ class TransferFragment : Fragment() {
|
||||
b.tvHeader.text = item
|
||||
b.root
|
||||
} else {
|
||||
val acc = item as MibAccount
|
||||
val acc = item as BankAccount
|
||||
val b = if (convertView?.tag is ItemAccountDropdownBinding) {
|
||||
convertView.tag as ItemAccountDropdownBinding
|
||||
} else {
|
||||
|
||||
@@ -25,12 +25,12 @@ import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.bml.BmlLoginFlow
|
||||
import sh.sar.basedbank.api.fahipay.FahipayLoginFlow
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.bml.BmlHistoryClient
|
||||
import sh.sar.basedbank.api.fahipay.FahipayHistoryClient
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.api.mib.MibContactsClient
|
||||
import sh.sar.basedbank.api.mib.MibHistoryClient
|
||||
import sh.sar.basedbank.api.mib.Transaction
|
||||
import sh.sar.basedbank.api.models.BankTransaction
|
||||
import sh.sar.basedbank.api.mib.TransactionCache
|
||||
import sh.sar.basedbank.databinding.FragmentTransferHistoryBinding
|
||||
import sh.sar.basedbank.util.ContactImageCache
|
||||
@@ -48,12 +48,12 @@ class TransferHistoryFragment : Fragment() {
|
||||
private lateinit var adapter: TransactionAdapter
|
||||
|
||||
// All merged transactions sorted by date desc
|
||||
private val allTransactions = mutableListOf<Transaction>()
|
||||
private val allTransactions = mutableListOf<BankTransaction>()
|
||||
private var searchQuery = ""
|
||||
|
||||
// Per-account pagination state
|
||||
private data class AccountState(
|
||||
val account: MibAccount,
|
||||
val account: BankAccount,
|
||||
var mibNextStart: Int = 1,
|
||||
var mibTotalCount: Int = -1,
|
||||
var bmlNextPage: Int = 1,
|
||||
@@ -158,7 +158,7 @@ class TransferHistoryFragment : Fragment() {
|
||||
|
||||
lifecycleScope.launch {
|
||||
val newTransactions = withContext(Dispatchers.IO) {
|
||||
val results = mutableListOf<Transaction>()
|
||||
val results = mutableListOf<BankTransaction>()
|
||||
|
||||
// BML accounts: fetch in parallel
|
||||
val bmlStates = activeStates.filter { it.account.bank == "BML" }
|
||||
@@ -172,7 +172,7 @@ class TransferHistoryFragment : Fragment() {
|
||||
cal.add(Calendar.MONTH, -state.cardMonthOffset)
|
||||
val month = SimpleDateFormat("yyyyMM", Locale.US).format(cal.time)
|
||||
state.cardMonthOffset++
|
||||
BmlLoginFlow().fetchCardHistory(
|
||||
BmlHistoryClient().fetchCardHistory(
|
||||
session = session,
|
||||
cardId = state.account.internalId,
|
||||
accountDisplayName = state.account.accountBriefName,
|
||||
@@ -182,7 +182,7 @@ class TransferHistoryFragment : Fragment() {
|
||||
}
|
||||
else -> {
|
||||
val session = app.bmlSessionFor(state.account) ?: return@async emptyList()
|
||||
val (list, totalPages) = BmlLoginFlow().fetchAccountHistory(
|
||||
val (list, totalPages) = BmlHistoryClient().fetchAccountHistory(
|
||||
session = session,
|
||||
accountId = state.account.internalId,
|
||||
accountDisplayName = state.account.accountBriefName,
|
||||
@@ -194,7 +194,7 @@ class TransferHistoryFragment : Fragment() {
|
||||
list
|
||||
}
|
||||
}
|
||||
} catch (_: Exception) { emptyList<Transaction>() }
|
||||
} catch (_: Exception) { emptyList<BankTransaction>() }
|
||||
}
|
||||
}.awaitAll().flatten())
|
||||
|
||||
@@ -203,9 +203,7 @@ class TransferHistoryFragment : Fragment() {
|
||||
for (state in fahipayStates) {
|
||||
val session = app.fahipaySessionFor(state.account) ?: continue
|
||||
try {
|
||||
val flow = FahipayLoginFlow()
|
||||
flow.setSessionCookie(session.sessionCookie)
|
||||
val (list, total) = flow.fetchHistory(
|
||||
val (list, total) = FahipayHistoryClient().fetchHistory(
|
||||
session = session,
|
||||
accountDisplayName = state.account.accountBriefName,
|
||||
accountNumber = state.account.accountNumber,
|
||||
|
||||
@@ -18,14 +18,17 @@ import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.util.Totp
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.bml.BmlAccountClient
|
||||
import sh.sar.basedbank.api.bml.BmlActivationResult
|
||||
import sh.sar.basedbank.api.bml.BmlLoginFlow
|
||||
import sh.sar.basedbank.api.bml.BmlOtpChannel
|
||||
import sh.sar.basedbank.api.bml.BmlProfile
|
||||
import sh.sar.basedbank.api.fahipay.FahipayAccountClient
|
||||
import sh.sar.basedbank.api.fahipay.FahipayLoginFlow
|
||||
import sh.sar.basedbank.api.fahipay.FahipaySession
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.models.BankAccount
|
||||
import sh.sar.basedbank.api.mib.MibLoginFlow
|
||||
import sh.sar.basedbank.api.mib.MibProfileClient
|
||||
import sh.sar.basedbank.util.AccountCache
|
||||
import sh.sar.basedbank.util.CredentialStore
|
||||
import sh.sar.basedbank.databinding.FragmentCredentialsBinding
|
||||
@@ -56,7 +59,7 @@ class CredentialsFragment : Fragment() {
|
||||
// BML multi-profile state
|
||||
private var bmlFlow: BmlLoginFlow? = null
|
||||
private var bmlLoginId: String = ""
|
||||
private var bmlAccumulatedAccounts = mutableListOf<MibAccount>()
|
||||
private var bmlAccumulatedAccounts = mutableListOf<BankAccount>()
|
||||
private var bmlPendingBusinessProfiles = ArrayDeque<Pair<BmlProfile, List<BmlOtpChannel>>>()
|
||||
private var bmlCurrentBusinessProfile: BmlProfile? = null
|
||||
private var bmlSelectedChannel: String? = null
|
||||
@@ -202,7 +205,7 @@ class CredentialsFragment : Fragment() {
|
||||
store.saveMibCredentials(loginId, username, passwordHash, otpSeed)
|
||||
withContext(Dispatchers.IO) {
|
||||
flow.lastSession?.let { s ->
|
||||
val profile = flow.fetchPersonalProfile(s)
|
||||
val profile = MibProfileClient().fetchPersonalProfile(s)
|
||||
if (profile != null) store.saveMibUserProfile(
|
||||
loginId,
|
||||
CredentialStore.MibUserProfile(
|
||||
@@ -428,7 +431,7 @@ class CredentialsFragment : Fragment() {
|
||||
val anySession = app.anyBmlSessionFor(bmlLoginId)
|
||||
if (anySession != null) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val info = BmlLoginFlow().fetchUserInfo(anySession)
|
||||
val info = BmlAccountClient().fetchUserInfo(anySession)
|
||||
if (info != null) {
|
||||
store.saveBmlUserProfile(
|
||||
bmlLoginId,
|
||||
@@ -582,13 +585,13 @@ class CredentialsFragment : Fragment() {
|
||||
store: CredentialStore
|
||||
) {
|
||||
val (profile, balance) = withContext(Dispatchers.IO) {
|
||||
val p = flow.fetchProfile(session)
|
||||
val b = flow.fetchBalance(session)
|
||||
val p = FahipayAccountClient().fetchProfile(session)
|
||||
val b = FahipayAccountClient().fetchBalance(session)
|
||||
Pair(p, b)
|
||||
}
|
||||
val loginId = profile.profileId
|
||||
val loginTag = "fahipay_$loginId"
|
||||
val account = flow.buildAccount(profile, balance, loginTag)
|
||||
val account = FahipayAccountClient().buildAccount(profile, balance, loginTag)
|
||||
store.saveFahipayCredentials(loginId, idCard, password)
|
||||
store.saveFahipaySession(loginId, session.authId, session.sessionCookie)
|
||||
store.saveFahipayUserProfile(
|
||||
|
||||
Reference in New Issue
Block a user