forked from shihaam/thijooree
Merge pull request 'fix/accounts-list-balance-consistency' (#5) from ahusan/fksar:fix/accounts-list-balance-consistency into main
Reviewed-on: shihaam/thijooree#5
This commit is contained in:
@@ -27,6 +27,10 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix = ".debug"
|
||||||
|
versionNameSuffix = "-debug"
|
||||||
|
}
|
||||||
release {
|
release {
|
||||||
signingConfig = signingConfigs.getByName("release")
|
signingConfig = signingConfigs.getByName("release")
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = false
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.json.JSONObject
|
|||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
import kotlin.math.abs
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
class SessionExpiredException : Exception("MIB session expired")
|
class SessionExpiredException : Exception("MIB session expired")
|
||||||
@@ -168,7 +169,7 @@ class MibLoginFlow(private val credentialStore: CredentialStore) {
|
|||||||
accountTypeName = a.optString("accountTypeName"),
|
accountTypeName = a.optString("accountTypeName"),
|
||||||
availableBalance = a.optString("availableBalance"),
|
availableBalance = a.optString("availableBalance"),
|
||||||
currentBalance = a.optString("currentBalance"),
|
currentBalance = a.optString("currentBalance"),
|
||||||
blockedAmount = a.optString("blockedAmount"),
|
blockedAmount = absBlockedAmount(a.optString("blockedAmount")),
|
||||||
mvrBalance = a.optString("mvrBalance"),
|
mvrBalance = a.optString("mvrBalance"),
|
||||||
statusDesc = a.optString("statusDesc"),
|
statusDesc = a.optString("statusDesc"),
|
||||||
profileImageHash = profile.customerImage,
|
profileImageHash = profile.customerImage,
|
||||||
@@ -188,6 +189,13 @@ class MibLoginFlow(private val credentialStore: CredentialStore) {
|
|||||||
|
|
||||||
// ─── Helpers ─────────────────────────────────────────────────────────────
|
// ─── Helpers ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** MIB returns blockedAmount as a signed decimal where negative = funds held.
|
||||||
|
* Normalize to a positive magnitude so downstream code can treat it uniformly. */
|
||||||
|
private fun absBlockedAmount(raw: String): String {
|
||||||
|
val v = raw.toDoubleOrNull() ?: return raw
|
||||||
|
return "%.2f".format(abs(v))
|
||||||
|
}
|
||||||
|
|
||||||
private fun initialKeyExchange(
|
private fun initialKeyExchange(
|
||||||
appId: String, encKey: String, sfunc: String, key2: String? = null
|
appId: String, encKey: String, sfunc: String, key2: String? = null
|
||||||
): Pair<MibSession, String> {
|
): Pair<MibSession, String> {
|
||||||
@@ -325,7 +333,7 @@ class MibLoginFlow(private val credentialStore: CredentialStore) {
|
|||||||
accountTypeName = a.optString("accountTypeName"),
|
accountTypeName = a.optString("accountTypeName"),
|
||||||
availableBalance = a.optString("availableBalance"),
|
availableBalance = a.optString("availableBalance"),
|
||||||
currentBalance = a.optString("currentBalance"),
|
currentBalance = a.optString("currentBalance"),
|
||||||
blockedAmount = a.optString("blockedAmount"),
|
blockedAmount = absBlockedAmount(a.optString("blockedAmount")),
|
||||||
mvrBalance = a.optString("mvrBalance"),
|
mvrBalance = a.optString("mvrBalance"),
|
||||||
statusDesc = a.optString("statusDesc"),
|
statusDesc = a.optString("statusDesc"),
|
||||||
profileImageHash = profile.customerImage,
|
profileImageHash = profile.customerImage,
|
||||||
|
|||||||
@@ -125,6 +125,14 @@ class AccountsAdapter(
|
|||||||
binding.tvAccountNumber.text = display.number
|
binding.tvAccountNumber.text = display.number
|
||||||
binding.tvAccountType.text = display.typeLabel
|
binding.tvAccountType.text = display.typeLabel
|
||||||
binding.tvBalance.text = if (hideAmounts) maskAmount(display.balance) else display.balance
|
binding.tvBalance.text = if (hideAmounts) maskAmount(display.balance) else display.balance
|
||||||
|
val blocked = display.blockedBalance
|
||||||
|
if (blocked != null) {
|
||||||
|
val shown = if (hideAmounts) maskAmount(blocked) else blocked
|
||||||
|
binding.tvBlocked.text = binding.root.context.getString(R.string.account_blocked_label, shown)
|
||||||
|
binding.tvBlocked.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvBlocked.visibility = View.GONE
|
||||||
|
}
|
||||||
binding.btnTransfer.setOnClickListener { onTransferClick?.invoke(account) }
|
binding.btnTransfer.setOnClickListener { onTransferClick?.invoke(account) }
|
||||||
binding.root.setOnClickListener { onAccountClick(account) }
|
binding.root.setOnClickListener { onAccountClick(account) }
|
||||||
binding.root.setOnLongClickListener {
|
binding.root.setOnLongClickListener {
|
||||||
|
|||||||
@@ -57,14 +57,24 @@ class DashboardFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
viewModel.accounts.observe(viewLifecycleOwner) { updateBalances(it) }
|
viewModel.accounts.observe(viewLifecycleOwner) {
|
||||||
viewModel.financing.observe(viewLifecycleOwner) { updatePendingFinances() }
|
updateBalances(it)
|
||||||
viewModel.bmlLoanDetails.observe(viewLifecycleOwner) { updatePendingFinances() }
|
updateAttentionRow()
|
||||||
|
}
|
||||||
|
viewModel.financing.observe(viewLifecycleOwner) {
|
||||||
|
updatePendingFinances()
|
||||||
|
updateAttentionRow()
|
||||||
|
}
|
||||||
|
viewModel.bmlLoanDetails.observe(viewLifecycleOwner) {
|
||||||
|
updatePendingFinances()
|
||||||
|
updateAttentionRow()
|
||||||
|
}
|
||||||
viewModel.bmlLimits.observe(viewLifecycleOwner) { updateForeignLimits(it) }
|
viewModel.bmlLimits.observe(viewLifecycleOwner) { updateForeignLimits(it) }
|
||||||
viewModel.hideAmounts.observe(viewLifecycleOwner) {
|
viewModel.hideAmounts.observe(viewLifecycleOwner) {
|
||||||
updateBalances(viewModel.accounts.value ?: emptyList())
|
updateBalances(viewModel.accounts.value ?: emptyList())
|
||||||
updatePendingFinances()
|
updatePendingFinances()
|
||||||
updateForeignLimits(viewModel.bmlLimits.value ?: emptyList())
|
updateForeignLimits(viewModel.bmlLimits.value ?: emptyList())
|
||||||
|
updateAttentionRow()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.swipeRefresh.setOnRefreshListener {
|
binding.swipeRefresh.setOnRefreshListener {
|
||||||
@@ -76,6 +86,10 @@ class DashboardFragment : Fragment() {
|
|||||||
(activity as? HomeActivity)?.navigateTo(R.id.nav_finances)
|
(activity as? HomeActivity)?.navigateTo(R.id.nav_finances)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.cardOverdue.setOnClickListener {
|
||||||
|
(activity as? HomeActivity)?.navigateTo(R.id.nav_finances)
|
||||||
|
}
|
||||||
|
|
||||||
val cardAdapter = DashboardCardAdapter()
|
val cardAdapter = DashboardCardAdapter()
|
||||||
binding.rvCards.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
|
binding.rvCards.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
|
||||||
binding.rvCards.adapter = cardAdapter
|
binding.rvCards.adapter = cardAdapter
|
||||||
@@ -244,6 +258,56 @@ class DashboardFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateAttentionRow() {
|
||||||
|
val hide = viewModel.hideAmounts.value ?: false
|
||||||
|
val accounts = viewModel.accounts.value ?: emptyList()
|
||||||
|
|
||||||
|
// Blocked: sum across CASA-style accounts (exclude cards and loans) per currency.
|
||||||
|
val blockedByCurrency = accounts
|
||||||
|
.filter { it.profileType != "BML_CREDIT" && it.profileType != "BML_PREPAID" && it.profileType != "BML_DEBIT" && it.profileType != "BML_LOAN" }
|
||||||
|
.mapNotNull { acc ->
|
||||||
|
val v = acc.blockedAmount.replace(",", "").toDoubleOrNull() ?: 0.0
|
||||||
|
if (v > 0.0) acc.currencyName.uppercase() to v else null
|
||||||
|
}
|
||||||
|
.groupBy({ it.first }, { it.second })
|
||||||
|
.mapValues { (_, vs) -> vs.sum() }
|
||||||
|
|
||||||
|
val blockedTotal = blockedByCurrency.values.sum()
|
||||||
|
if (blockedTotal > 0.0) {
|
||||||
|
// Primary line: prefer MVR if present, otherwise the first currency.
|
||||||
|
val primaryCcy = if ("MVR" in blockedByCurrency) "MVR" else blockedByCurrency.keys.first()
|
||||||
|
val primaryAmt = blockedByCurrency.getValue(primaryCcy)
|
||||||
|
binding.tvBlockedTotal.text = if (hide) "$primaryCcy ••••••" else "$primaryCcy %,.2f".format(primaryAmt)
|
||||||
|
|
||||||
|
val secondary = blockedByCurrency.filterKeys { it != primaryCcy }
|
||||||
|
if (secondary.isNotEmpty()) {
|
||||||
|
binding.tvBlockedSecondary.text = secondary.entries.joinToString(" · ") { (ccy, amt) ->
|
||||||
|
if (hide) "$ccy ••••••" else "$ccy %,.2f".format(amt)
|
||||||
|
}
|
||||||
|
binding.tvBlockedSecondary.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvBlockedSecondary.visibility = View.GONE
|
||||||
|
}
|
||||||
|
binding.cardBlocked.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.cardBlocked.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overdue: MIB finance deals + BML loan details (assumed MVR — matches existing Pending Finances).
|
||||||
|
val mibOverdue = (viewModel.financing.value ?: emptyList()).sumOf { it.overdueAmount }
|
||||||
|
val bmlOverdue = (viewModel.bmlLoanDetails.value ?: emptyMap()).values.sumOf { it.overdueAmount }
|
||||||
|
val overdueTotal = mibOverdue + bmlOverdue
|
||||||
|
if (overdueTotal > 0.0) {
|
||||||
|
binding.tvOverdueTotal.text = if (hide) "MVR ••••••" else "MVR %,.2f".format(overdueTotal)
|
||||||
|
binding.cardOverdue.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.cardOverdue.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.rowAttention.visibility =
|
||||||
|
if (blockedTotal > 0.0 || overdueTotal > 0.0) View.VISIBLE else View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
private fun updatePendingFinances() {
|
private fun updatePendingFinances() {
|
||||||
val hide = viewModel.hideAmounts.value ?: false
|
val hide = viewModel.hideAmounts.value ?: false
|
||||||
val mibTotal = (viewModel.financing.value ?: emptyList()).sumOf { it.outstandingAmount }
|
val mibTotal = (viewModel.financing.value ?: emptyList()).sumOf { it.outstandingAmount }
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ data class AccountListDisplay(
|
|||||||
val number: String,
|
val number: String,
|
||||||
val typeLabel: String,
|
val typeLabel: String,
|
||||||
val balance: String,
|
val balance: String,
|
||||||
|
val blockedBalance: String? = null, // null when zero or not applicable
|
||||||
val isCard: Boolean = false,
|
val isCard: Boolean = false,
|
||||||
val cardBrandIcon: Int = 0, // drawable res, only meaningful if isCard
|
val cardBrandIcon: Int = 0, // drawable res, only meaningful if isCard
|
||||||
val statusLabel: String? = null // null = active; shown as status pill if set
|
val statusLabel: String? = null // null = active; shown as status pill if set
|
||||||
|
|||||||
@@ -26,11 +26,13 @@ object BmlDashboardParser {
|
|||||||
statusLabel = if (isActive) null else account.statusDesc
|
statusLabel = if (isActive) null else account.statusDesc
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
val blocked = account.blockedAmount.toDoubleOrNull() ?: 0.0
|
||||||
AccountListDisplay(
|
AccountListDisplay(
|
||||||
name = account.accountBriefName,
|
name = account.accountBriefName,
|
||||||
number = account.accountNumber,
|
number = account.accountNumber,
|
||||||
typeLabel = productLabel(account.accountTypeName),
|
typeLabel = productLabel(account.accountTypeName),
|
||||||
balance = listBalance(account)
|
balance = listBalance(account),
|
||||||
|
blockedBalance = if (blocked > 0.0) "${account.currencyName} ${account.blockedAmount}" else null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,9 +54,9 @@ object BmlDashboardParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Balance shown in the accounts list — ledger (working) balance for BML CASA. */
|
/** Balance shown in the accounts list — available balance, consistent with transfer/contact picker. */
|
||||||
fun listBalance(account: BankAccount): String =
|
fun listBalance(account: BankAccount): String =
|
||||||
"${account.currencyName} ${account.currentBalance}"
|
"${account.currencyName} ${account.availableBalance}"
|
||||||
|
|
||||||
fun cardBrandIcon(productName: String): Int = when {
|
fun cardBrandIcon(productName: String): Int = when {
|
||||||
productName.contains("AMEX", ignoreCase = true) ||
|
productName.contains("AMEX", ignoreCase = true) ||
|
||||||
|
|||||||
@@ -5,12 +5,16 @@ import sh.sar.basedbank.util.AccountListDisplay
|
|||||||
|
|
||||||
object MibAccountParser {
|
object MibAccountParser {
|
||||||
|
|
||||||
fun displayData(account: BankAccount) = AccountListDisplay(
|
fun displayData(account: BankAccount): AccountListDisplay {
|
||||||
name = account.accountBriefName,
|
val blocked = account.blockedAmount.toDoubleOrNull() ?: 0.0
|
||||||
number = account.accountNumber,
|
return AccountListDisplay(
|
||||||
typeLabel = productLabel(account.accountTypeName),
|
name = account.accountBriefName,
|
||||||
balance = "${account.currencyName} ${account.availableBalance}"
|
number = account.accountNumber,
|
||||||
)
|
typeLabel = productLabel(account.accountTypeName),
|
||||||
|
balance = "${account.currencyName} ${account.availableBalance}",
|
||||||
|
blockedBalance = if (blocked > 0.0) "${account.currencyName} ${account.blockedAmount}" else null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a display-ready product label for a MIB (Faisanet) account type name.
|
* Returns a display-ready product label for a MIB (Faisanet) account type name.
|
||||||
|
|||||||
@@ -5,13 +5,16 @@ import sh.sar.basedbank.util.AccountHistoryDisplay
|
|||||||
|
|
||||||
object MibHistoryParser {
|
object MibHistoryParser {
|
||||||
|
|
||||||
fun displayData(account: BankAccount) = AccountHistoryDisplay(
|
fun displayData(account: BankAccount): AccountHistoryDisplay {
|
||||||
name = account.accountBriefName,
|
val blocked = account.blockedAmount.toDoubleOrNull() ?: 0.0
|
||||||
number = account.accountNumber,
|
return AccountHistoryDisplay(
|
||||||
bankPill = null, // MIB has no bank pill
|
name = account.accountBriefName,
|
||||||
typeLabel = MibAccountParser.productLabel(account.accountTypeName),
|
number = account.accountNumber,
|
||||||
availableBalance = "${account.currencyName} ${account.availableBalance}",
|
bankPill = null, // MIB has no bank pill
|
||||||
workingBalance = "${account.currencyName} ${account.currentBalance}",
|
typeLabel = MibAccountParser.productLabel(account.accountTypeName),
|
||||||
blockedBalance = null
|
availableBalance = "${account.currencyName} ${account.availableBalance}",
|
||||||
)
|
workingBalance = "${account.currencyName} ${account.currentBalance}",
|
||||||
|
blockedBalance = if (blocked > 0.0) "${account.currencyName} ${account.blockedAmount}" else null
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,103 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Attention row: Blocked + Overdue (hidden when nothing applies) -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/rowAttention"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardBlocked"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
app:cardElevation="1dp"
|
||||||
|
app:cardCornerRadius="12dp"
|
||||||
|
app:cardBackgroundColor="?attr/colorErrorContainer"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dashboard_blocked"
|
||||||
|
android:textAppearance="?attr/textAppearanceLabelSmall"
|
||||||
|
android:textColor="?attr/colorOnErrorContainer" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvBlockedTotal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="MVR —"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:textColor="?attr/colorOnErrorContainer" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvBlockedSecondary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:textAppearance="?attr/textAppearanceLabelSmall"
|
||||||
|
android:textColor="?attr/colorOnErrorContainer"
|
||||||
|
android:alpha="0.75"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardOverdue"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
app:cardElevation="1dp"
|
||||||
|
app:cardCornerRadius="12dp"
|
||||||
|
app:cardBackgroundColor="?attr/colorErrorContainer"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dashboard_overdue"
|
||||||
|
android:textAppearance="?attr/textAppearanceLabelSmall"
|
||||||
|
android:textColor="?attr/colorOnErrorContainer" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvOverdueTotal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="MVR —"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:textColor="?attr/colorOnErrorContainer" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- Pending Finances card -->
|
<!-- Pending Finances card -->
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/cardPendingFinances"
|
android:id="@+id/cardPendingFinances"
|
||||||
|
|||||||
@@ -72,6 +72,15 @@
|
|||||||
android:textAppearance="?attr/textAppearanceTitleSmall"
|
android:textAppearance="?attr/textAppearanceTitleSmall"
|
||||||
android:textColor="?attr/colorOnSurface" />
|
android:textColor="?attr/colorOnSurface" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvBlocked"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:textAppearance="?attr/textAppearanceLabelSmall"
|
||||||
|
android:textColor="?attr/colorError"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btnTransfer"
|
android:id="@+id/btnTransfer"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
|
|||||||
@@ -208,6 +208,9 @@
|
|||||||
<string name="accounts">Accounts</string>
|
<string name="accounts">Accounts</string>
|
||||||
<string name="cards">Cards</string>
|
<string name="cards">Cards</string>
|
||||||
<string name="available_balance">Available Balance</string>
|
<string name="available_balance">Available Balance</string>
|
||||||
|
<string name="account_blocked_label">%1$s blocked</string>
|
||||||
|
<string name="dashboard_blocked">Blocked Funds</string>
|
||||||
|
<string name="dashboard_overdue">Overdue Financing</string>
|
||||||
|
|
||||||
<!-- Transfer -->
|
<!-- Transfer -->
|
||||||
<string name="transfer_tab_quick">Quick Transfer</string>
|
<string name="transfer_tab_quick">Quick Transfer</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user