huge refactor.. might need to revert later
Auto Tag on Version Change / check-version (push) Successful in 4s

This commit is contained in:
2026-05-20 22:43:29 +05:00
parent e894f81887
commit 6d48c27391
49 changed files with 1224 additions and 1072 deletions
@@ -3,7 +3,7 @@ package sh.sar.basedbank.util
import android.content.Context
import org.json.JSONArray
import org.json.JSONObject
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
object AccountCache {
@@ -12,7 +12,7 @@ object AccountCache {
private fun bmlKey(loginId: String) = "bml_accounts_$loginId"
private fun fahipayKey(loginId: String) = "fahipay_accounts_$loginId"
fun save(context: Context, accounts: List<MibAccount>) {
fun save(context: Context, accounts: List<BankAccount>) {
val arr = JSONArray()
for (acc in accounts) {
arr.put(JSONObject().apply {
@@ -38,7 +38,7 @@ object AccountCache {
.edit().putString(KEY_MIB, CacheEncryption.encrypt(arr.toString())).apply()
}
fun saveBml(context: Context, loginId: String, accounts: List<MibAccount>) {
fun saveBml(context: Context, loginId: String, accounts: List<BankAccount>) {
val arr = JSONArray()
for (acc in accounts) {
arr.put(JSONObject().apply {
@@ -61,14 +61,14 @@ object AccountCache {
.edit().putString(bmlKey(loginId), CacheEncryption.encrypt(arr.toString())).apply()
}
fun loadBml(context: Context, loginId: String): List<MibAccount> {
fun loadBml(context: Context, loginId: String): List<BankAccount> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString(bmlKey(loginId), null) ?: return emptyList()
return try {
val arr = JSONArray(CacheEncryption.decrypt(raw))
(0 until arr.length()).map { i ->
val o = arr.getJSONObject(i)
MibAccount(
BankAccount(
bank = "BML",
profileName = o.optString("profileName"),
profileType = o.optString("profileType"),
@@ -89,10 +89,10 @@ object AccountCache {
} catch (_: Exception) { emptyList() }
}
fun loadBml(context: Context, loginIds: List<String>): List<MibAccount> =
fun loadBml(context: Context, loginIds: List<String>): List<BankAccount> =
loginIds.flatMap { loadBml(context, it) }
fun saveFahipay(context: Context, loginId: String, accounts: List<MibAccount>) {
fun saveFahipay(context: Context, loginId: String, accounts: List<BankAccount>) {
val arr = JSONArray()
for (acc in accounts) {
arr.put(JSONObject().apply {
@@ -115,14 +115,14 @@ object AccountCache {
.edit().putString(fahipayKey(loginId), CacheEncryption.encrypt(arr.toString())).apply()
}
fun loadFahipay(context: Context, loginId: String): List<MibAccount> {
fun loadFahipay(context: Context, loginId: String): List<BankAccount> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString(fahipayKey(loginId), null) ?: return emptyList()
return try {
val arr = JSONArray(CacheEncryption.decrypt(raw))
(0 until arr.length()).map { i ->
val o = arr.getJSONObject(i)
MibAccount(
BankAccount(
bank = "FAHIPAY",
profileName = o.optString("profileName"),
profileType = o.optString("profileType"),
@@ -143,14 +143,14 @@ object AccountCache {
} catch (_: Exception) { emptyList() }
}
fun loadFahipay(context: Context, loginIds: List<String>): List<MibAccount> =
fun loadFahipay(context: Context, loginIds: List<String>): List<BankAccount> =
loginIds.flatMap { loadFahipay(context, it) }
fun clear(context: Context) {
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit().clear().apply()
}
fun load(context: Context): List<MibAccount> {
fun load(context: Context): List<BankAccount> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString(KEY_MIB, null) ?: return emptyList()
return try {
@@ -158,7 +158,7 @@ object AccountCache {
val arr = JSONArray(json)
(0 until arr.length()).map { i ->
val o = arr.getJSONObject(i)
MibAccount(
BankAccount(
bank = o.optString("bank", "MIB"),
profileName = o.optString("profileName"),
profileType = o.optString("profileType"),
@@ -1,13 +1,13 @@
package sh.sar.basedbank.util
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.util.bmlapi.BmlHistoryParser
import sh.sar.basedbank.util.fahipayapi.FahipayHistoryParser
import sh.sar.basedbank.util.mibapi.MibHistoryParser
object AccountHistoryParser {
fun from(account: MibAccount): AccountHistoryDisplay? = when (account.bank) {
fun from(account: BankAccount): AccountHistoryDisplay? = when (account.bank) {
"BML" -> BmlHistoryParser.displayData(account)
"FAHIPAY" -> FahipayHistoryParser.displayData(account)
"MIB" -> MibHistoryParser.displayData(account)
@@ -1,13 +1,13 @@
package sh.sar.basedbank.util
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.util.bmlapi.BmlDashboardParser
import sh.sar.basedbank.util.fahipayapi.FahipayAccountParser
import sh.sar.basedbank.util.mibapi.MibAccountParser
object AccountListParser {
fun from(account: MibAccount): AccountListDisplay? = when (account.bank) {
fun from(account: BankAccount): AccountListDisplay? = when (account.bank) {
"BML" -> BmlDashboardParser.displayData(account)
"FAHIPAY" -> FahipayAccountParser.displayData(account)
"MIB" -> MibAccountParser.displayData(account)
@@ -1,18 +1,18 @@
package sh.sar.basedbank.util
import sh.sar.basedbank.api.mib.MibBeneficiary
import sh.sar.basedbank.api.models.BankContact
import sh.sar.basedbank.util.bmlapi.BmlContactParser
import sh.sar.basedbank.util.fahipayapi.FahipayContactParser
import sh.sar.basedbank.util.mibapi.MibContactParser
object ContactListParser {
fun from(contact: MibBeneficiary): ContactDisplay? = when {
fun from(contact: BankContact): ContactDisplay? = when {
contact.benefCategoryId == "BML" -> BmlContactParser.displayData(contact)
contact.benefType == "FAHIPAY" -> FahipayContactParser.displayData(contact)
contact.benefType in setOf("I", "L", "S") -> MibContactParser.displayData(contact)
else -> null
}
fun fromList(contacts: List<MibBeneficiary>): List<ContactDisplay> = contacts.mapNotNull { from(it) }
fun fromList(contacts: List<BankContact>): List<ContactDisplay> = contacts.mapNotNull { from(it) }
}
@@ -1,7 +1,7 @@
package sh.sar.basedbank.util
import sh.sar.basedbank.BasedBankApp
import sh.sar.basedbank.api.bml.BmlLoginFlow
import sh.sar.basedbank.api.bml.BmlContactsClient
import sh.sar.basedbank.api.mib.MibContactsClient
/**
@@ -21,7 +21,7 @@ object ContactManager {
private fun deleteBml(contact: ContactDisplay, app: BasedBankApp): Boolean {
val sess = app.bmlSessions[contact.profileId] ?: app.anyBmlSession() ?: return false
val contactId = contact.id.removePrefix("bml_")
return try { BmlLoginFlow().deleteContact(sess, contactId) } catch (_: Exception) { false }
return try { BmlContactsClient().deleteContact(sess, contactId) } catch (_: Exception) { false }
}
private fun deleteMib(contact: ContactDisplay, app: BasedBankApp): Boolean {
@@ -3,8 +3,8 @@ package sh.sar.basedbank.util
import android.content.Context
import org.json.JSONArray
import org.json.JSONObject
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
object ContactsCache {
@@ -14,8 +14,8 @@ object ContactsCache {
fun save(
context: Context,
contacts: List<MibBeneficiary>,
categories: List<MibBeneficiaryCategory>
contacts: List<BankContact>,
categories: List<BankContactCategory>
) {
val prefs = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit()
@@ -55,7 +55,7 @@ object ContactsCache {
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit().clear().apply()
}
fun loadContacts(context: Context): List<MibBeneficiary> {
fun loadContacts(context: Context): List<BankContact> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString(KEY_CONTACTS, null) ?: return emptyList()
return try {
@@ -63,7 +63,7 @@ object ContactsCache {
val arr = JSONArray(json)
(0 until arr.length()).map { i ->
val o = arr.getJSONObject(i)
MibBeneficiary(
BankContact(
benefNo = o.optString("benefNo"),
benefName = o.optString("benefName"),
benefNickName = o.optString("benefNickName"),
@@ -86,7 +86,7 @@ object ContactsCache {
private fun bmlKey(loginId: String) = "bml_contacts_$loginId"
fun saveBml(context: Context, loginId: String, contacts: List<MibBeneficiary>) {
fun saveBml(context: Context, loginId: String, contacts: List<BankContact>) {
val arr = JSONArray()
for (c in contacts) {
arr.put(JSONObject().apply {
@@ -108,14 +108,14 @@ object ContactsCache {
.edit().putString(bmlKey(loginId), CacheEncryption.encrypt(arr.toString())).apply()
}
fun loadBml(context: Context, loginId: String): List<MibBeneficiary> {
fun loadBml(context: Context, loginId: String): List<BankContact> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString(bmlKey(loginId), null) ?: return emptyList()
return try {
val arr = JSONArray(CacheEncryption.decrypt(raw))
(0 until arr.length()).map { i ->
val o = arr.getJSONObject(i)
MibBeneficiary(
BankContact(
benefNo = o.optString("benefNo"),
benefName = o.optString("benefName"),
benefNickName = o.optString("benefNickName"),
@@ -134,10 +134,10 @@ object ContactsCache {
} catch (_: Exception) { emptyList() }
}
fun loadBml(context: Context, loginIds: List<String>): List<MibBeneficiary> =
fun loadBml(context: Context, loginIds: List<String>): List<BankContact> =
loginIds.flatMap { loadBml(context, it) }
fun saveFahipay(context: Context, contacts: List<MibBeneficiary>, categories: List<MibBeneficiaryCategory>) {
fun saveFahipay(context: Context, contacts: List<BankContact>, categories: List<BankContactCategory>) {
val prefs = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit()
val arr = JSONArray()
for (c in contacts) arr.put(JSONObject().apply {
@@ -159,14 +159,14 @@ object ContactsCache {
prefs.apply()
}
fun loadFahipay(context: Context): List<MibBeneficiary> {
fun loadFahipay(context: Context): List<BankContact> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString("fahipay_contacts", null) ?: return emptyList()
return try {
val arr = JSONArray(CacheEncryption.decrypt(raw))
(0 until arr.length()).map { i ->
val o = arr.getJSONObject(i)
MibBeneficiary(
BankContact(
benefNo = o.optString("benefNo"),
benefName = "",
benefNickName = o.optString("benefNickName"),
@@ -185,19 +185,19 @@ object ContactsCache {
} catch (_: Exception) { emptyList() }
}
fun loadFahipayCategories(context: Context): List<MibBeneficiaryCategory> {
fun loadFahipayCategories(context: Context): List<BankContactCategory> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString("fahipay_categories", null) ?: return emptyList()
return try {
val arr = JSONArray(CacheEncryption.decrypt(raw))
(0 until arr.length()).map { i ->
val o = arr.getJSONObject(i)
MibBeneficiaryCategory(o.optString("id"), o.optString("categoryName"), o.optInt("numBenef"))
BankContactCategory(o.optString("id"), o.optString("categoryName"), o.optInt("numBenef"))
}
} catch (_: Exception) { emptyList() }
}
fun loadCategories(context: Context): List<MibBeneficiaryCategory> {
fun loadCategories(context: Context): List<BankContactCategory> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString(KEY_CATEGORIES, null) ?: return emptyList()
return try {
@@ -205,7 +205,7 @@ object ContactsCache {
val arr = JSONArray(json)
(0 until arr.length()).map { i ->
val o = arr.getJSONObject(i)
MibBeneficiaryCategory(
BankContactCategory(
id = o.optString("id"),
categoryName = o.optString("categoryName"),
numBenef = o.optInt("numBenef", 0)
@@ -4,11 +4,11 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import sh.sar.basedbank.BasedBankApp
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.MibHistoryClient
import sh.sar.basedbank.api.mib.Transaction
import sh.sar.basedbank.api.models.BankTransaction
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
@@ -18,7 +18,7 @@ import java.util.Locale
* The fragment holds one instance per account and calls [hasMore] / [fetchNextPage]
* without knowing which bank it is talking to.
*/
class HistoryFetcher(private val account: MibAccount) {
class HistoryFetcher(private val account: BankAccount) {
private val isMib get() = account.bank == "MIB"
private val isBmlCard get() = account.profileType == "BML_PREPAID" || account.profileType == "BML_CREDIT"
@@ -46,18 +46,16 @@ class HistoryFetcher(private val account: MibAccount) {
else -> bmlTotalPages < 0 || bmlNextPage <= bmlTotalPages
}
suspend fun fetchNextPage(app: BasedBankApp, pageSize: Int = 10): List<Transaction> = when {
suspend fun fetchNextPage(app: BasedBankApp, pageSize: Int = 10): List<BankTransaction> = when {
isFahipay -> withContext(Dispatchers.IO) { fetchFahipay(app) }
isMib -> app.mibMutex.withLock { withContext(Dispatchers.IO) { fetchMib(app, pageSize) } }
isBmlCard -> withContext(Dispatchers.IO) { fetchBmlCard(app) }
else -> withContext(Dispatchers.IO) { fetchBmlCasa(app) }
}
private fun fetchFahipay(app: BasedBankApp): List<Transaction> {
private fun fetchFahipay(app: BasedBankApp): List<BankTransaction> {
val session = app.fahipaySessionFor(account) ?: return emptyList()
val flow = FahipayLoginFlow()
flow.setSessionCookie(session.sessionCookie)
val (list, total) = flow.fetchHistory(
val (list, total) = FahipayHistoryClient().fetchHistory(
session = session,
accountDisplayName = account.accountBriefName,
accountNumber = account.accountNumber,
@@ -68,7 +66,7 @@ class HistoryFetcher(private val account: MibAccount) {
return list
}
private fun fetchMib(app: BasedBankApp, pageSize: Int): List<Transaction> {
private fun fetchMib(app: BasedBankApp, pageSize: Int): List<BankTransaction> {
val loginId = account.loginTag.removePrefix("mib_")
val session = app.mibSessions[loginId] ?: return emptyList()
val profiles = app.mibProfilesMap[loginId] ?: emptyList()
@@ -86,13 +84,13 @@ class HistoryFetcher(private val account: MibAccount) {
return list
}
private fun fetchBmlCard(app: BasedBankApp): List<Transaction> {
private fun fetchBmlCard(app: BasedBankApp): List<BankTransaction> {
val session = app.bmlSessionFor(account) ?: return emptyList()
val cal = Calendar.getInstance()
cal.add(Calendar.MONTH, -cardMonthOffset)
val month = SimpleDateFormat("yyyyMM", Locale.US).format(cal.time)
cardMonthOffset++
return BmlLoginFlow().fetchCardHistory(
return BmlHistoryClient().fetchCardHistory(
session = session,
cardId = account.internalId,
accountDisplayName = account.accountBriefName,
@@ -101,9 +99,9 @@ class HistoryFetcher(private val account: MibAccount) {
)
}
private fun fetchBmlCasa(app: BasedBankApp): List<Transaction> {
private fun fetchBmlCasa(app: BasedBankApp): List<BankTransaction> {
val session = app.bmlSessionFor(account) ?: return emptyList()
val (list, totalPages) = BmlLoginFlow().fetchAccountHistory(
val (list, totalPages) = BmlHistoryClient().fetchAccountHistory(
session = session,
accountId = account.internalId,
accountDisplayName = account.accountBriefName,
@@ -1,12 +1,12 @@
package sh.sar.basedbank.util.bmlapi
import sh.sar.basedbank.api.mib.MibBeneficiary
import sh.sar.basedbank.api.models.BankContact
import sh.sar.basedbank.util.ContactDisplay
import sh.sar.basedbank.util.TransferNetwork
object BmlContactParser {
fun displayData(contact: MibBeneficiary) = ContactDisplay(
fun displayData(contact: BankContact) = ContactDisplay(
id = contact.benefNo,
name = contact.benefNickName,
realName = contact.benefName,
@@ -1,7 +1,7 @@
package sh.sar.basedbank.util.bmlapi
import sh.sar.basedbank.R
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.util.AccountListDisplay
object BmlDashboardParser {
@@ -10,7 +10,7 @@ object BmlDashboardParser {
* Returns all display fields for an account/card row in the accounts list.
* Handles both BML CASA accounts and BML prepaid/credit cards.
*/
fun displayData(account: MibAccount): AccountListDisplay {
fun displayData(account: BankAccount): AccountListDisplay {
val isCard = account.profileType == "BML_PREPAID" || account.profileType == "BML_CREDIT"
return if (isCard) {
val isActive = account.statusDesc.equals("Active", ignoreCase = true)
@@ -51,7 +51,7 @@ object BmlDashboardParser {
}
/** Balance shown in the accounts list — ledger (working) balance for BML CASA. */
fun listBalance(account: MibAccount): String =
fun listBalance(account: BankAccount): String =
"${account.currencyName} ${account.currentBalance}"
fun cardBrandIcon(productName: String): Int = when {
@@ -1,11 +1,11 @@
package sh.sar.basedbank.util.bmlapi
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.util.AccountHistoryDisplay
object BmlHistoryParser {
fun displayData(account: MibAccount): AccountHistoryDisplay {
fun displayData(account: BankAccount): AccountHistoryDisplay {
val blocked = account.blockedAmount.toDoubleOrNull() ?: 0.0
return AccountHistoryDisplay(
name = account.accountBriefName,
@@ -1,11 +1,11 @@
package sh.sar.basedbank.util.fahipayapi
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.util.AccountListDisplay
object FahipayAccountParser {
fun displayData(account: MibAccount) = AccountListDisplay(
fun displayData(account: BankAccount) = AccountListDisplay(
name = account.accountBriefName,
number = account.accountNumber,
typeLabel = account.accountTypeName,
@@ -1,12 +1,12 @@
package sh.sar.basedbank.util.fahipayapi
import sh.sar.basedbank.api.mib.MibBeneficiary
import sh.sar.basedbank.api.models.BankContact
import sh.sar.basedbank.util.ContactDisplay
import sh.sar.basedbank.util.TransferNetwork
object FahipayContactParser {
fun displayData(contact: MibBeneficiary) = ContactDisplay(
fun displayData(contact: BankContact) = ContactDisplay(
id = contact.benefNo,
name = contact.benefNickName,
realName = contact.benefName,
@@ -1,11 +1,11 @@
package sh.sar.basedbank.util.fahipayapi
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.util.AccountHistoryDisplay
object FahipayHistoryParser {
fun displayData(account: MibAccount) = AccountHistoryDisplay(
fun displayData(account: BankAccount) = AccountHistoryDisplay(
name = account.accountBriefName,
number = account.accountNumber,
bankPill = "FP",
@@ -1,11 +1,11 @@
package sh.sar.basedbank.util.mibapi
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.util.AccountListDisplay
object MibAccountParser {
fun displayData(account: MibAccount) = AccountListDisplay(
fun displayData(account: BankAccount) = AccountListDisplay(
name = account.accountBriefName,
number = account.accountNumber,
typeLabel = productLabel(account.accountTypeName),
@@ -1,12 +1,12 @@
package sh.sar.basedbank.util.mibapi
import sh.sar.basedbank.api.mib.MibBeneficiary
import sh.sar.basedbank.api.models.BankContact
import sh.sar.basedbank.util.ContactDisplay
import sh.sar.basedbank.util.TransferNetwork
object MibContactParser {
fun displayData(contact: MibBeneficiary): ContactDisplay {
fun displayData(contact: BankContact): ContactDisplay {
val network = when (contact.benefType) {
"I" -> TransferNetwork.MIB
"S" -> TransferNetwork.SWIFT
@@ -1,11 +1,11 @@
package sh.sar.basedbank.util.mibapi
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.util.AccountHistoryDisplay
object MibHistoryParser {
fun displayData(account: MibAccount) = AccountHistoryDisplay(
fun displayData(account: BankAccount) = AccountHistoryDisplay(
name = account.accountBriefName,
number = account.accountNumber,
bankPill = null, // MIB has no bank pill