save trsnaction type to history for reload, raastas and bill pay to autoselct card
Auto Tag on Version Change / check-version (push) Successful in 3s

This commit is contained in:
2026-10-03 01:32:39 +05:00
parent bb76f4e591
commit 5abd981096
3 changed files with 50 additions and 14 deletions
@@ -52,6 +52,7 @@ import sh.sar.basedbank.databinding.ItemPickerSectionHeaderBinding
import sh.sar.basedbank.databinding.ItemTransferTypeBinding
import sh.sar.basedbank.ui.home.transfer.BmlTransferHandler
import sh.sar.basedbank.ui.home.transfer.BmlVerifiedCards
import sh.sar.basedbank.ui.home.transfer.CardPayoutService
import sh.sar.basedbank.ui.home.transfer.CardPayoutTransferHandler
import sh.sar.basedbank.ui.home.transfer.CarrierLookup
import sh.sar.basedbank.ui.home.transfer.FahipayService
@@ -407,7 +408,7 @@ class TransferFragment : Fragment() {
return@setFragmentResultListener
}
val label = bundle.getString(ContactPickerSheetFragment.KEY_LABEL) ?: ""
if (applyFahipayContact(accountNumber, bundle.getString(ContactPickerSheetFragment.KEY_CATEGORY), label)) {
if (applyServiceContact(accountNumber, bundle.getString(ContactPickerSheetFragment.KEY_CATEGORY), label)) {
return@setFragmentResultListener
}
val subtitle = bundle.getString(ContactPickerSheetFragment.KEY_SUBTITLE) ?: accountNumber
@@ -453,7 +454,7 @@ class TransferFragment : Fragment() {
// Pre-select contact if navigated from contacts page or QR scan
arguments?.getString(ARG_ACCOUNT)?.let { account ->
val name = arguments?.getString(ARG_NAME) ?: account
if (applyFahipayContact(account, arguments?.getString(ARG_CONTACT_CATEGORY), name)) return@let
if (applyServiceContact(account, arguments?.getString(ARG_CONTACT_CATEGORY), name)) return@let
prefillToDirectly(
accountNumber = account,
displayName = name,
@@ -1141,15 +1142,27 @@ class TransferFragment : Fragment() {
}
/**
* A saved Fahipay favourite: its list ([categoryId]) already says which service pays it, so
* that service is applied as the only transfer type, with no carrier lookup. That switches
* the source to the Fahipay wallet and brings in the service's amount rules, the same as a
* searched number. Returns false, doing nothing, when [categoryId] isn't a Fahipay list.
* A saved Fahipay favourite, or a recent paid with a Fahipay or card service: its category
* ([categoryId]) already says which service pays it, so that service is applied as the only
* transfer type, with no carrier lookup. That switches the source to the Fahipay wallet or
* the default card and brings in the service's amount rules, the same as a searched number.
* Returns false, doing nothing, when [categoryId] isn't one of those.
*/
private fun applyFahipayContact(number: String, categoryId: String?, name: String): Boolean {
val service = FahipayService.fromContactCategory(categoryId) ?: return false
private fun applyServiceContact(number: String, categoryId: String?, name: String): Boolean {
val ownerName = name.takeIf { it.isNotBlank() && it != number }
val type = FahipayService.fromContactCategory(categoryId)?.let { TransferType.Fahipay(it, ownerName) }
?: CardPayoutService.fromContactCategory(categoryId)?.let { service ->
// The cards that could pay it then may not be payable now
val cards = cardPayoutHandler().payableCards()
if (cards.isEmpty()) {
Toast.makeText(requireContext(), R.string.bml_card_pay_no_verified, Toast.LENGTH_LONG).show()
return true
}
TransferType.Card(service, ownerName, cards)
}
?: return false
clearRecipient()
offerTransferTypes(number, listOf(TransferType.Fahipay(service, name.takeIf { it.isNotBlank() && it != number })))
offerTransferTypes(number, listOf(type))
return true
}
@@ -33,22 +33,37 @@ enum class CardPayoutService(
override val maxAmount: Int?,
override val decimalsAllowed: Boolean,
override val gstPercent: Int?,
/**
* Tags the recents paid with this service (`RecentPick.contactCategory`), so picking one
* again pays the same way. Not a real contact list: card payouts have no favourites.
*/
val contactCategory: String,
override val gstAdded: Boolean = false,
) : PayoutService {
DHIRAAGU_RELOAD("Dhiraagu Reload", "Dhiraagu · Reload", R.drawable.dhiraagu_logo,
minAmount = 20, maxAmount = 1000, decimalsAllowed = false, gstPercent = 8) {
minAmount = 20, maxAmount = 1000, decimalsAllowed = false, gstPercent = 8,
contactCategory = "CARD_DHIRAAGU_RELOAD") {
// Dhiraagu rounds the GST to 2 places and credits the rest
override fun creditedAfterGst(amount: BigDecimal): BigDecimal =
amount - DhiraaguPaymentClient.gstOf(amount.setScale(0, RoundingMode.DOWN).toInt())
},
// Easy Pay sets no limits of its own: any amount with up to 2 decimals, no GST
DHIRAAGU_BILL("Dhiraagu Bill Pay", "Dhiraagu · Bill Pay", R.drawable.dhiraagu_logo,
minAmount = 1, maxAmount = null, decimalsAllowed = true, gstPercent = null),
minAmount = 1, maxAmount = null, decimalsAllowed = true, gstPercent = null,
contactCategory = "CARD_DHIRAAGU_BILL"),
// Ooredoo credits the whole amount and charges the card 8% GST on top
OOREDOO_RAASTAS("Raastas", "Ooredoo · Raastas", R.drawable.ooredoo_logo,
minAmount = 20, maxAmount = null, decimalsAllowed = false, gstPercent = 8, gstAdded = true),
minAmount = 20, maxAmount = null, decimalsAllowed = false, gstPercent = 8,
contactCategory = "CARD_RAASTAS", gstAdded = true),
OOREDOO_BILL("Ooredoo Bill Pay", "Ooredoo · Bill Pay", R.drawable.ooredoo_logo,
minAmount = 10, maxAmount = null, decimalsAllowed = true, gstPercent = null);
minAmount = 10, maxAmount = null, decimalsAllowed = true, gstPercent = null,
contactCategory = "CARD_OOREDOO_BILL");
companion object {
/** The service a recent was paid with, from its [contactCategory], or null when it isn't one. */
fun fromContactCategory(categoryId: String?): CardPayoutService? =
entries.firstOrNull { it.contactCategory == categoryId }
}
}
/**
@@ -136,7 +151,8 @@ class CardPayoutTransferHandler(
displayName = displayName,
subtitle = "${type.label} · $number",
colorHex = "#E4002B",
imageHash = null
imageHash = null,
contactCategory = type.service.contactCategory
)
fragment.focusAmount()
}
+7
View File
@@ -189,6 +189,13 @@ paid ("You pay MVR 21.60 with 8% GST"). The order check in step 2 below compares
**Reference.** None. The field is cleared and disabled, as for the Fahipay services.
**Recents.** As with Fahipay services, the recent is saved with the service's category
(`CardPayoutService.contactCategory`: `CARD_DHIRAAGU_RELOAD`, `CARD_DHIRAAGU_BILL`,
`CARD_RAASTAS`, `CARD_OOREDOO_BILL`). Picking it again applies that service with no lookup, so
the default card (or another payable card) is selected rather than the default account
(`TransferFragment.applyServiceContact`). With no payable card left, it toasts and stops. A number
keeps one recent, so paying it another way replaces the category.
**Sending.** The only part that differs from paying a card-only BML merchant link is where the
BML transaction comes from: