added support for BML loans
Auto Tag on Version Change / check-version (push) Successful in 3s

This commit is contained in:
2026-05-21 22:58:58 +05:00
parent 50150b826f
commit e82218e897
12 changed files with 644 additions and 46 deletions
@@ -3,12 +3,14 @@ package sh.sar.basedbank.util
import android.content.Context
import org.json.JSONArray
import org.json.JSONObject
import sh.sar.basedbank.api.bml.BmlLoanDetail
import sh.sar.basedbank.api.mib.MibFinanceDeal
object FinancingCache {
private const val PREFS = "financing_cache"
private const val KEY_MIB = "mib_financing"
private const val KEY_BML_LOANS = "bml_loans"
fun save(context: Context, deals: List<MibFinanceDeal>) {
val arr = JSONArray()
@@ -34,6 +36,52 @@ object FinancingCache {
.edit().putString(KEY_MIB, CacheEncryption.encrypt(arr.toString())).apply()
}
fun saveBmlLoans(context: Context, loans: Map<String, BmlLoanDetail>) {
val arr = JSONArray()
for ((internalId, d) in loans) {
arr.put(JSONObject().apply {
put("internalId", internalId)
put("loanAmount", d.loanAmount)
put("outstandingAmt", d.outstandingAmt)
put("repayAmount", d.repayAmount)
put("intRate", d.intRate)
put("loanStatus", d.loanStatus)
put("startDate", d.startDate)
put("endDate", d.endDate)
put("noOfRepayOverdue", d.noOfRepayOverdue)
put("overdueAmount", d.overdueAmount)
})
}
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.edit().putString(KEY_BML_LOANS, CacheEncryption.encrypt(arr.toString())).apply()
}
fun loadBmlLoans(context: Context): Map<String, BmlLoanDetail> {
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.getString(KEY_BML_LOANS, null) ?: return emptyMap()
return try {
val json = CacheEncryption.decrypt(raw)
val arr = JSONArray(json)
buildMap {
for (i in 0 until arr.length()) {
val o = arr.getJSONObject(i)
val id = o.optString("internalId")
if (id.isNotBlank()) put(id, BmlLoanDetail(
loanAmount = o.optDouble("loanAmount", 0.0),
outstandingAmt = o.optDouble("outstandingAmt", 0.0),
repayAmount = o.optDouble("repayAmount", 0.0),
intRate = o.optDouble("intRate", 0.0),
loanStatus = o.optString("loanStatus"),
startDate = o.optString("startDate"),
endDate = o.optString("endDate"),
noOfRepayOverdue = o.optInt("noOfRepayOverdue", 0),
overdueAmount = o.optDouble("overdueAmount", 0.0)
))
}
}
} catch (_: Exception) { emptyMap() }
}
fun clear(context: Context) {
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit().clear().apply()
}
@@ -22,6 +22,7 @@ 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"
private val isBmlLoan get() = account.profileType == "BML_LOAN"
private val isFahipay get() = account.bank == "FAHIPAY"
// MIB pagination
@@ -40,6 +41,7 @@ class HistoryFetcher(private val account: BankAccount) {
private var fahipayTotal = -1
fun hasMore(): Boolean = when {
isBmlLoan -> false
isFahipay -> fahipayTotal < 0 || fahipayNextStart < fahipayTotal
isMib -> mibTotalCount < 0 || mibNextStart <= mibTotalCount
isBmlCard -> cardMonthOffset < 3
@@ -47,6 +49,7 @@ class HistoryFetcher(private val account: BankAccount) {
}
suspend fun fetchNextPage(app: BasedBankApp, pageSize: Int = 10): List<BankTransaction> = when {
isBmlLoan -> emptyList()
isFahipay -> withContext(Dispatchers.IO) { fetchFahipay(app) }
isMib -> app.mibMutex.withLock { withContext(Dispatchers.IO) { fetchMib(app, pageSize) } }
isBmlCard -> withContext(Dispatchers.IO) { fetchBmlCard(app) }
@@ -10,7 +10,8 @@ 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: BankAccount): AccountListDisplay {
fun displayData(account: BankAccount): AccountListDisplay? {
if (account.profileType == "BML_LOAN") return null // Loans shown on financing page only
val isCard = account.profileType == "BML_PREPAID" || account.profileType == "BML_CREDIT"
return if (isCard) {
val isActive = account.statusDesc.equals("Active", ignoreCase = true)