diff --git a/components-sdk/src/main/java/co/xendit/components/data/model/BffChannelAvailability.kt b/components-sdk/src/main/java/co/xendit/components/data/model/BffChannelAvailability.kt index 1eda3a2..178657f 100644 --- a/components-sdk/src/main/java/co/xendit/components/data/model/BffChannelAvailability.kt +++ b/components-sdk/src/main/java/co/xendit/components/data/model/BffChannelAvailability.kt @@ -8,8 +8,11 @@ internal enum class AmountAvailabilityStatus { ABOVE_MAX } -internal fun BffChannel.amountAvailabilityStatus(amount: BigDecimal?): AmountAvailabilityStatus { - if (amount == null) return AmountAvailabilityStatus.AVAILABLE +internal fun BffChannel.amountAvailabilityStatus( + amount: BigDecimal?, + sessionType: BffSessionType? = null +): AmountAvailabilityStatus { + if (amount == null || sessionType != BffSessionType.PAY) return AmountAvailabilityStatus.AVAILABLE return when { minAmount != null && amount.compareTo(minAmount) < 0 -> AmountAvailabilityStatus.BELOW_MIN maxAmount != null && amount.compareTo(maxAmount) > 0 -> AmountAvailabilityStatus.ABOVE_MAX @@ -17,16 +20,20 @@ internal fun BffChannel.amountAvailabilityStatus(amount: BigDecimal?): AmountAva } } -internal fun BffChannel.isAvailableForAmount(amount: BigDecimal?): Boolean { - return amountAvailabilityStatus(amount) == AmountAvailabilityStatus.AVAILABLE +internal fun BffChannel.isAvailableForAmount( + amount: BigDecimal?, + sessionType: BffSessionType? = null +): Boolean { + return amountAvailabilityStatus(amount, sessionType) == AmountAvailabilityStatus.AVAILABLE } internal fun List.groupAmountAvailabilityStatus( - amount: BigDecimal? + amount: BigDecimal?, + sessionType: BffSessionType? = null ): AmountAvailabilityStatus? { if (isEmpty() || amount == null) return null - val firstStatus = first().amountAvailabilityStatus(amount) + val firstStatus = first().amountAvailabilityStatus(amount, sessionType) - return if (all { it.amountAvailabilityStatus(amount) == firstStatus }) firstStatus else null + return if (all { it.amountAvailabilityStatus(amount, sessionType) == firstStatus }) firstStatus else null } diff --git a/components-sdk/src/main/java/co/xendit/components/ui/PaymentContainerHost.kt b/components-sdk/src/main/java/co/xendit/components/ui/PaymentContainerHost.kt index 5412878..1752815 100644 --- a/components-sdk/src/main/java/co/xendit/components/ui/PaymentContainerHost.kt +++ b/components-sdk/src/main/java/co/xendit/components/ui/PaymentContainerHost.kt @@ -526,7 +526,10 @@ internal fun PaymentContainerHost( mviState.expandedUiGroup != null && mviState.selectedChannel != null val selectedChannel = mviState.selectedChannel val isSelectedChannelAvailable = - selectedChannel?.isAvailableForAmount(mviState.sessionResponse?.session?.amount) != false + selectedChannel?.isAvailableForAmount( + mviState.sessionResponse?.session?.amount, + mviState.sessionType + ) != false val currentDraft = if (selectedChannel == null) PaymentDraft() else { mviState.paymentDrafts[selectedChannel.channelCode] ?: PaymentDraft(channelCode = selectedChannel.channelCode) diff --git a/components-sdk/src/main/java/co/xendit/components/ui/components/PaymentChannelSelectionUI.kt b/components-sdk/src/main/java/co/xendit/components/ui/components/PaymentChannelSelectionUI.kt index 23c6f5f..9671fa6 100644 --- a/components-sdk/src/main/java/co/xendit/components/ui/components/PaymentChannelSelectionUI.kt +++ b/components-sdk/src/main/java/co/xendit/components/ui/components/PaymentChannelSelectionUI.kt @@ -85,11 +85,14 @@ internal fun PaymentChannelSelectionUI( val imageLoader = remember { SdkImageLoader.get(context) } val isSaveChecked = remember { mutableStateOf(false) } val sessionAmount = session?.amount + val sessionType = session?.sessionType val hasAvailableChannel = - remember(channels, sessionAmount) { channels.any { it.isAvailableForAmount(sessionAmount) } } + remember(channels, sessionAmount, sessionType) { + channels.any { it.isAvailableForAmount(sessionAmount, sessionType) } + } val selectedAvailabilityMessageResId = - remember(selectedChannel, sessionAmount) { - when (selectedChannel?.amountAvailabilityStatus(sessionAmount)) { + remember(selectedChannel, sessionAmount, sessionType) { + when (selectedChannel?.amountAvailabilityStatus(sessionAmount, sessionType)) { AmountAvailabilityStatus.BELOW_MIN -> R.string.sessionpayment_methods_channel_disabled_amount_too_small AmountAvailabilityStatus.ABOVE_MAX -> R.string.sessionpayment_methods_channel_disabled_amount_too_large else -> null @@ -166,8 +169,8 @@ internal fun PaymentChannelSelectionUI( onDismissRequest = { expanded = false } ) { channels.forEach { channel -> - val isAvailable = channel.isAvailableForAmount(sessionAmount) - val availableStatus = channel.amountAvailabilityStatus(sessionAmount) + val isAvailable = channel.isAvailableForAmount(sessionAmount, sessionType) + val availableStatus = channel.amountAvailabilityStatus(sessionAmount, sessionType) DropdownMenuItem( enabled = isAvailable, text = { diff --git a/components-sdk/src/main/java/co/xendit/components/ui/method/PaymentMethodsUI.kt b/components-sdk/src/main/java/co/xendit/components/ui/method/PaymentMethodsUI.kt index b71e4a4..fd1688c 100644 --- a/components-sdk/src/main/java/co/xendit/components/ui/method/PaymentMethodsUI.kt +++ b/components-sdk/src/main/java/co/xendit/components/ui/method/PaymentMethodsUI.kt @@ -132,10 +132,15 @@ internal fun PaymentMethodsUI( val groupChannels = groups[uiGroup].orEmpty() val pmType = groupChannels.firstOrNull()?.pmType val sessionAmount = session?.amount + val sessionType = session?.sessionType val allChannelsUnavailable = - groupChannels.isNotEmpty() && groupChannels.none { it.isAvailableForAmount(sessionAmount) } + groupChannels.isNotEmpty() && groupChannels.none { + it.isAvailableForAmount(sessionAmount, sessionType) + } val groupAvailabilityStatus = - if (allChannelsUnavailable) groupChannels.groupAmountAvailabilityStatus(sessionAmount) else null + if (allChannelsUnavailable) { + groupChannels.groupAmountAvailabilityStatus(sessionAmount, sessionType) + } else null val groupDisabledMessageResId = when { !allChannelsUnavailable -> null diff --git a/components-sdk/src/test/java/co/xendit/components/data/model/BffChannelAvailabilityTest.kt b/components-sdk/src/test/java/co/xendit/components/data/model/BffChannelAvailabilityTest.kt index 45a6029..4a542fd 100644 --- a/components-sdk/src/test/java/co/xendit/components/data/model/BffChannelAvailabilityTest.kt +++ b/components-sdk/src/test/java/co/xendit/components/data/model/BffChannelAvailabilityTest.kt @@ -24,9 +24,9 @@ class BffChannelAvailabilityTest { assertEquals( AmountAvailabilityStatus.BELOW_MIN, - channel.amountAvailabilityStatus(amount = BigDecimal("9.99")) + channel.amountAvailabilityStatus(amount = BigDecimal("9.99"), sessionType = BffSessionType.PAY) ) - assertFalse(channel.isAvailableForAmount(amount = BigDecimal("9.99"))) + assertFalse(channel.isAvailableForAmount(amount = BigDecimal("9.99"), sessionType = BffSessionType.PAY)) } @Test @@ -35,9 +35,9 @@ class BffChannelAvailabilityTest { assertEquals( AmountAvailabilityStatus.ABOVE_MAX, - channel.amountAvailabilityStatus(amount = BigDecimal("100.01")) + channel.amountAvailabilityStatus(amount = BigDecimal("100.01"), sessionType = BffSessionType.PAY) ) - assertFalse(channel.isAvailableForAmount(amount = BigDecimal("100.01"))) + assertFalse(channel.isAvailableForAmount(amount = BigDecimal("100.01"), sessionType = BffSessionType.PAY)) } @Test @@ -62,15 +62,15 @@ class BffChannelAvailabilityTest { assertEquals( AmountAvailabilityStatus.BELOW_MIN, - channel.amountAvailabilityStatus(amount = BigDecimal("9.99")) + channel.amountAvailabilityStatus(amount = BigDecimal("9.99"), sessionType = BffSessionType.PAY) ) assertEquals( AmountAvailabilityStatus.AVAILABLE, - channel.amountAvailabilityStatus(amount = BigDecimal("10.00")) + channel.amountAvailabilityStatus(amount = BigDecimal("10.00"), sessionType = BffSessionType.PAY) ) assertEquals( AmountAvailabilityStatus.AVAILABLE, - channel.amountAvailabilityStatus(amount = BigDecimal("999.99")) + channel.amountAvailabilityStatus(amount = BigDecimal("999.99"), sessionType = BffSessionType.PAY) ) } @@ -80,15 +80,47 @@ class BffChannelAvailabilityTest { assertEquals( AmountAvailabilityStatus.AVAILABLE, - channel.amountAvailabilityStatus(amount = BigDecimal("0.01")) + channel.amountAvailabilityStatus(amount = BigDecimal("0.01"), sessionType = BffSessionType.PAY) ) assertEquals( AmountAvailabilityStatus.AVAILABLE, - channel.amountAvailabilityStatus(amount = BigDecimal("100.00")) + channel.amountAvailabilityStatus(amount = BigDecimal("100.00"), sessionType = BffSessionType.PAY) ) assertEquals( AmountAvailabilityStatus.ABOVE_MAX, - channel.amountAvailabilityStatus(amount = BigDecimal("100.01")) + channel.amountAvailabilityStatus(amount = BigDecimal("100.01"), sessionType = BffSessionType.PAY) + ) + } + + @Test + fun amountAvailabilityStatus_whenSessionTypeIsSave_ignoresMinMaxLimits() { + val channel = createChannel(minAmount = "10.00", maxAmount = "100.00") + + assertEquals( + AmountAvailabilityStatus.AVAILABLE, + channel.amountAvailabilityStatus( + amount = BigDecimal("9.99"), + sessionType = BffSessionType.SAVE + ) + ) + assertEquals( + AmountAvailabilityStatus.AVAILABLE, + channel.amountAvailabilityStatus( + amount = BigDecimal("100.01"), + sessionType = BffSessionType.SAVE + ) + ) + assertTrue( + channel.isAvailableForAmount( + amount = BigDecimal("9.99"), + sessionType = BffSessionType.SAVE + ) + ) + assertTrue( + channel.isAvailableForAmount( + amount = BigDecimal("100.01"), + sessionType = BffSessionType.SAVE + ) ) } @@ -114,7 +146,7 @@ class BffChannelAvailabilityTest { assertEquals( AmountAvailabilityStatus.ABOVE_MAX, - channels.groupAmountAvailabilityStatus(amount = BigDecimal("50.00")) + channels.groupAmountAvailabilityStatus(amount = BigDecimal("50.00"), sessionType = BffSessionType.PAY) ) } @@ -127,7 +159,7 @@ class BffChannelAvailabilityTest { assertEquals( AmountAvailabilityStatus.BELOW_MIN, - channels.groupAmountAvailabilityStatus(amount = BigDecimal("50.00")) + channels.groupAmountAvailabilityStatus(amount = BigDecimal("50.00"), sessionType = BffSessionType.PAY) ) } @@ -138,7 +170,7 @@ class BffChannelAvailabilityTest { createChannel(maxAmount = "40.00") ) - assertNull(channels.groupAmountAvailabilityStatus(amount = BigDecimal("50.00"))) + assertNull(channels.groupAmountAvailabilityStatus(amount = BigDecimal("50.00"), sessionType = BffSessionType.PAY)) } @Test @@ -147,6 +179,22 @@ class BffChannelAvailabilityTest { assertNull(listOf(createChannel()).groupAmountAvailabilityStatus(amount = null)) } + @Test + fun groupAmountAvailabilityStatus_whenSessionTypeIsSave_returnsAvailable() { + val channels = listOf( + createChannel(minAmount = "60.00"), + createChannel(maxAmount = "40.00") + ) + + assertEquals( + AmountAvailabilityStatus.AVAILABLE, + channels.groupAmountAvailabilityStatus( + amount = BigDecimal("50.00"), + sessionType = BffSessionType.SAVE + ) + ) + } + private fun createChannel( minAmount: String? = null, maxAmount: String? = null