4.1 KiB
Account Display Parser Architecture
Overview
Each bank's API returns account data in different formats and uses different field names for balances, product types, and status. To keep screens bank-agnostic, each bank has a dedicated parser that translates raw MibAccount model data into a standard AccountListDisplay object. Screens consume only AccountListDisplay — they never inspect bank or profileType or apply bank-specific logic.
Bank Discriminator — MibAccount.bank
All dispatchers route by account.bank, a string set explicitly by each login flow at account creation time:
bank value |
Set by |
|---|---|
"MIB" |
MibLoginFlow |
"BML" |
BmlLoginFlow |
"FAHIPAY" |
FahipayLoginFlow |
profileType is a bank-internal value (e.g. MIB's numeric profile ID, or BML's "BML_PREPAID") and is never used for bank routing. Card-type checks within BML still use profileType ("BML_PREPAID" / "BML_CREDIT").
cifType (MIB only) is the human-readable profile category name returned by the operatingProfiles API (e.g. "Individual", "Sole Propr"). It is stored on MibAccount and surfaced in the accounts list section header and settings. It is never hardcoded in the app.
Standard Output Model
// util/AccountListDisplay.kt
data class AccountListDisplay(
val name: String, // account or card display name
val number: String, // account/card number
val typeLabel: String, // human-friendly product type (e.g. "Savings", "Visa Platinum")
val balance: String, // formatted balance string (e.g. "MVR 1,234.56")
val isCard: Boolean, // true → use card layout; false → use account layout
val cardBrandIcon: Int, // drawable res for card brand logo (Visa / Mastercard / Amex)
val statusLabel: String? // null = active; non-null = shown as status label (e.g. "Inactive")
)
Dispatcher
// util/AccountListParser.kt
AccountListParser.from(account: MibAccount): AccountListDisplay?
Routes to the correct parser based on account.bank. Returns null for unknown banks — never falls back to a specific bank.
account.bank |
Parser |
|---|---|
"BML" |
BmlDashboardParser |
"FAHIPAY" |
FahipayAccountParser |
"MIB" |
MibAccountParser |
| anything else | null |
Bank Parsers
BML — util/bmlapi/BmlDashboardParser
Handles both CASA accounts and prepaid/credit cards.
- CASA balance: uses
ledgerBalance(working balance) — mapped toaccount.currentBalance - Card balance: uses
availableBalance(available limit fromcardBalance.AvailableLimit) - Card brand: resolved from product name (
VISA/MASTERCARD/AMEX) - Status: cards with
statusDesc != "Active"surfacestatusLabel; active cards returnnull
MIB — util/mibapi/MibAccountParser
- Balance:
availableBalancefrom the MIB API directly - Known product names (
SAVING ACCOUNT,CURRENT ACCOUNT) mapped to short labels cifType(e.g."Individual","Sole Propr") comes fromMibProfile.cifType, stored onMibAccount, displayed in section headers
Fahipay — util/fahipayapi/FahipayAccountParser
- Single wallet account per user;
accountTypeNameis always"Digital Wallet" - Balance:
availableBalance
Adding a New Bank
- Create
util/<bankname>api/<Bank>AccountParser.ktwith adisplayData(account: MibAccount): AccountListDisplayfunction - Set
bank = "<BANKNAME>"in the new login flow when creatingMibAccountobjects - Add a
whenbranch inAccountListParser.from()(and other dispatchers) for the new bank value - No changes needed in any screen or adapter
Usage in Screens
AccountsAdapter calls AccountListParser.from(account) once per item (skipping null results) and binds the resulting AccountListDisplay directly. The adapter has zero bank-specific logic.
The transfer screen dropdown (TransferFragment) also uses AccountListParser.from(acc)?.balance for the source account balance display.