diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 38b59392d3..eeb613a920 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -2015,6 +2015,7 @@ We\'ll set up a wallet Get your Tangem Pay Card in minutes Pay Support + Select plan Payment account Session expired Invalid PIN: avoid sequences or repeats diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverter.kt index 77beec76bc..5f184ef3ce 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverter.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverter.kt @@ -68,6 +68,7 @@ internal class PaymentAccountStatusValueDMConverter @Inject constructor( ) // Transient statuses are not persisted is PaymentAccountStatusValue.Loading, + is PaymentAccountStatusValue.AwaitingPlanSelection, is PaymentAccountStatusValue.Error.ExposedDevice, is PaymentAccountStatusValue.Error.Unavailable, is PaymentAccountStatusValue.Error.NotSynced, diff --git a/data/visa/src/test/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverterTest.kt b/data/visa/src/test/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverterTest.kt index 25a40bb989..386ef7303b 100644 --- a/data/visa/src/test/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverterTest.kt +++ b/data/visa/src/test/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverterTest.kt @@ -103,6 +103,21 @@ internal class PaymentAccountStatusValueDMConverterTest { assertThat(result).isNull() } + @Test + fun `GIVEN domain AwaitingPlanSelection WHEN convert THEN returns null (transient, not persisted)`() { + // GIVEN + val domain = PaymentAccountStatusValue.AwaitingPlanSelection( + source = StatusSource.ACTUAL, + tariffPlan = null, + ) + + // WHEN + val result = converter.convert(domain) + + // THEN + assertThat(result).isNull() + } + @Test fun `GIVEN domain Error Unavailable WHEN convert THEN returns null (transient, not persisted)`() { // GIVEN diff --git a/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt b/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt index 5433fc0409..4b1037eb1b 100644 --- a/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt +++ b/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt @@ -108,6 +108,7 @@ class IsAccountsModeEnabledUseCase( -> false is PaymentAccountStatusValue.Error, is PaymentAccountStatusValue.IssuingCard, + is PaymentAccountStatusValue.AwaitingPlanSelection, is PaymentAccountStatusValue.Loaded, is PaymentAccountStatusValue.Loading, is PaymentAccountStatusValue.UnderReview, diff --git a/domain/models/src/main/kotlin/com/tangem/domain/models/account/PaymentAccountStatusValue.kt b/domain/models/src/main/kotlin/com/tangem/domain/models/account/PaymentAccountStatusValue.kt index 4c38b2adc2..6240266c9c 100644 --- a/domain/models/src/main/kotlin/com/tangem/domain/models/account/PaymentAccountStatusValue.kt +++ b/domain/models/src/main/kotlin/com/tangem/domain/models/account/PaymentAccountStatusValue.kt @@ -27,6 +27,7 @@ sealed class PaymentAccountStatusValue { get() = when (this) { is Error, is IssuingCard, + is AwaitingPlanSelection, is Empty, is NotCreated, is UnderReview, @@ -54,6 +55,7 @@ sealed class PaymentAccountStatusValue { is UnderReview -> copy(source = source) is Deactivated -> copy(source = source, error = error ?: this.error) is Loading, + is AwaitingPlanSelection, is Empty, is NotCreated, is Error, @@ -101,6 +103,19 @@ sealed class PaymentAccountStatusValue { @Serializable data class IssuingCard(override val source: StatusSource) : PaymentAccountStatusValue() + /** + * Represents a state where KYC is approved but no tariff plan has been selected yet + * + * @property source The source of the status information. + * @property tariffPlan Current tariff plan (fallback Basic) if the backend already returns one + * Transient: not persisted in the local cache. + */ + @Serializable + data class AwaitingPlanSelection( + override val source: StatusSource, + val tariffPlan: TangemPayCustomerTariffPlan?, + ) : PaymentAccountStatusValue() + /** * Represents a state where the account is deactivated. * diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/choosetoken/converter/ChooseTokenListItemConverter.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/choosetoken/converter/ChooseTokenListItemConverter.kt index 84238b8387..dc1253f1df 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/choosetoken/converter/ChooseTokenListItemConverter.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/choosetoken/converter/ChooseTokenListItemConverter.kt @@ -182,6 +182,7 @@ internal class ChooseTokenListItemConverter( val paymentCurrency: CryptoCurrencyStatus = when (val status = this.value) { is PaymentAccountStatusValue.Error, is PaymentAccountStatusValue.IssuingCard, + is PaymentAccountStatusValue.AwaitingPlanSelection, PaymentAccountStatusValue.NotCreated, is PaymentAccountStatusValue.UnderReview, PaymentAccountStatusValue.Loading, diff --git a/features/tangempay/main/api/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayMainUM.kt b/features/tangempay/main/api/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayMainUM.kt index 977ce0927e..0998520796 100644 --- a/features/tangempay/main/api/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayMainUM.kt +++ b/features/tangempay/main/api/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayMainUM.kt @@ -8,6 +8,7 @@ sealed class TangemPayMainUM { data object Empty : TangemPayMainUM() data object Loading : TangemPayMainUM() + data class SelectPlan(val onClick: () -> Unit) : TangemPayMainUM() data class UnderReview(val subtitle: TextReference, val onClick: () -> Unit) : TangemPayMainUM() data class IssuingCard(val onClick: () -> Unit) : TangemPayMainUM() data class FailedToIssue(val onClick: () -> Unit) : TangemPayMainUM() diff --git a/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContent.kt b/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContent.kt index ec5d9d03c8..bdb78bf1a1 100644 --- a/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContent.kt +++ b/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContent.kt @@ -50,6 +50,11 @@ internal fun TangemPayMainBlockContent( when (state) { is TangemPayMainUM.Empty -> Unit is TangemPayMainUM.Loading -> TangemPayMainLoading(modifier) + is TangemPayMainUM.SelectPlan -> TangemPayStateRow( + subtitle = resourceReference(R.string.tangempay_main_select_plan), + modifier = modifier, + onClick = state.onClick, + ) is TangemPayMainUM.UnderReview -> TangemPayStateRow( subtitle = state.subtitle, modifier = modifier, @@ -303,6 +308,7 @@ private class TangemPayMainBlockContentPreviewParameterProvider : CollectionPrev TangemPayMainUM.ExposedDevice, TangemPayMainUM.FailedToIssue(onClick = {}), TangemPayMainUM.UnderReview(subtitle = resourceReference(R.string.tangempay_kyc_in_progress), onClick = {}), + TangemPayMainUM.SelectPlan(onClick = {}), TangemPayMainUM.IssuingCard(onClick = {}), TangemPayMainUM.Content( subtitle = TextReference.Str("*1234"), diff --git a/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContentLegacy.kt b/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContentLegacy.kt index f72aecb6f4..3a5ba77e2e 100644 --- a/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContentLegacy.kt +++ b/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContentLegacy.kt @@ -42,6 +42,7 @@ internal fun TangemPayMainBlockItem(state: TangemPayMainUM, isBalanceHidden: Boo when (state) { is TangemPayMainUM.Empty -> Unit is TangemPayMainUM.Loading -> TangemPayMainLoadingItem(modifier) + is TangemPayMainUM.SelectPlan -> TangemPayMainSelectPlanItem(state, modifier) is TangemPayMainUM.UnderReview -> TangemPayMainUnderReviewItem(state, modifier) is TangemPayMainUM.IssuingCard -> TangemPayMainIssuingCardItem(state, modifier) is TangemPayMainUM.FailedToIssue -> TangemPayMainFailedIssueItem(state, modifier) @@ -194,6 +195,25 @@ private fun TangemPayMainTempUnavailableItem(modifier: Modifier = Modifier) { } } +@Composable +private fun TangemPayMainSelectPlanItem(state: TangemPayMainUM.SelectPlan, modifier: Modifier = Modifier) { + BlockCard( + modifier = modifier + .clip(RoundedCornerShape(size = TangemTheme.dimens.radius14)) + .background(TangemTheme.colors.background.primary), + onClick = state.onClick, + ) { + InputRowImageBase( + modifier = Modifier.padding(all = TangemTheme.dimens.spacing12), + subtitle = resourceReference(R.string.tangempay_payment_account), + caption = resourceReference(R.string.tangempay_main_select_plan), + subtitleColor = TangemTheme.colors.text.primary1, + captionColor = TangemTheme.colors.text.tertiary, + iconResWebp = R.drawable.img_visa_36, + ) + } +} + @Composable private fun TangemPayMainIssuingCardItem(state: TangemPayMainUM.IssuingCard, modifier: Modifier = Modifier) { BlockCard( @@ -344,6 +364,7 @@ private class TangemPayMainUMPreviewParameterProvider : CollectionPreviewParamet TangemPayMainUM.ExposedDevice, TangemPayMainUM.FailedToIssue(onClick = {}), TangemPayMainUM.UnderReview(subtitle = resourceReference(R.string.tangempay_kyc_in_progress), onClick = {}), + TangemPayMainUM.SelectPlan(onClick = {}), TangemPayMainUM.IssuingCard(onClick = {}), TangemPayMainUM.Content( subtitle = TextReference.Str("*1234"), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt index 83770da949..5c5652c633 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt @@ -42,6 +42,8 @@ internal interface TangemPayIntents { fun openDetails(status: AccountStatus.Payment) + fun onSelectPlanClicked(status: AccountStatus.Payment) + fun onKycProgressClicked(userWalletId: UserWalletId) fun onKycRejectedClicked(userWalletId: UserWalletId, customerId: String) @@ -114,6 +116,10 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( router.openTangemPayDetails(status = status) } + override fun onSelectPlanClicked(status: AccountStatus.Payment) { + router.openTangemPaySelectPlan(status = status) + } + override fun onKycProgressClicked(userWalletId: UserWalletId) { val cancelKycConfirmDialogMessage = DialogMessage( title = resourceReference(R.string.tangempay_kyc_confirm_cancellation_alert_title), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt index 10e80ff7c5..c97cb0afee 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt @@ -158,6 +158,10 @@ internal class DefaultWalletRouter @Inject constructor( router.push(AppRoute.TangemPayDetails(status = status)) } + override fun openTangemPaySelectPlan(status: AccountStatus.Payment) { + // TODO v_rodionov: [REDACTED_TASK_KEY] Tiers Onboarding - part 2 + } + override fun openYieldSupplyBottomSheet( cryptoCurrency: CryptoCurrency, tokenAction: TokenAction, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt index eed653fcfe..5258923d61 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt @@ -84,6 +84,8 @@ internal interface InnerWalletRouter { fun openTangemPayDetails(status: AccountStatus.Payment) + fun openTangemPaySelectPlan(status: AccountStatus.Payment) + /** Open BS abput yield supply active and all money deposited in AAVE */ fun openYieldSupplyBottomSheet( cryptoCurrency: CryptoCurrency, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletTangemPayAnalyticsEventSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletTangemPayAnalyticsEventSender.kt index bd8b2197a6..373932d2ef 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletTangemPayAnalyticsEventSender.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletTangemPayAnalyticsEventSender.kt @@ -26,6 +26,7 @@ internal class WalletTangemPayAnalyticsEventSender @Inject constructor( PaymentAccountStatusValue.Loading, PaymentAccountStatusValue.NotCreated, is PaymentAccountStatusValue.UnderReview, + is PaymentAccountStatusValue.AwaitingPlanSelection, is PaymentAccountStatusValue.Deactivated, -> return } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt index 192bb989bc..f0c06b23eb 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt @@ -236,6 +236,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( is PaymentAccountStatusValue.Error.CardIssueFailed, is PaymentAccountStatusValue.Error.ExposedDevice, is PaymentAccountStatusValue.IssuingCard, + is PaymentAccountStatusValue.AwaitingPlanSelection, is PaymentAccountStatusValue.Loaded, is PaymentAccountStatusValue.Loading, is PaymentAccountStatusValue.UnderReview, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetWalletNotificationsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetWalletNotificationsFactory.kt index 003cfb3498..e1f9cf149f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetWalletNotificationsFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetWalletNotificationsFactory.kt @@ -284,6 +284,7 @@ internal class GetWalletNotificationsFactory @Inject constructor( is PaymentAccountStatusValue.Error.CardIssueFailed, is PaymentAccountStatusValue.Error.ExposedDevice, is PaymentAccountStatusValue.IssuingCard, + is PaymentAccountStatusValue.AwaitingPlanSelection, is PaymentAccountStatusValue.Loaded, is PaymentAccountStatusValue.Loading, is PaymentAccountStatusValue.UnderReview, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TangemPayMainBlockConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TangemPayMainBlockConverter.kt index d44992bdbd..2d99c25335 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TangemPayMainBlockConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TangemPayMainBlockConverter.kt @@ -35,6 +35,9 @@ internal class TangemPayMainBlockConverter( is PaymentAccountStatusValue.IssuingCard -> TangemPayMainUM.IssuingCard( onClick = { tangemPayClickIntents.onIssuingCardClicked() }, ) + is PaymentAccountStatusValue.AwaitingPlanSelection -> TangemPayMainUM.SelectPlan( + onClick = { tangemPayClickIntents.onSelectPlanClicked(value) }, + ) is PaymentAccountStatusValue.UnderReview -> TangemPayMainUM.UnderReview( subtitle = when (statusValue.kycStatus) { KycStatus.REJECTED -> TextReference.Res(R.string.tangempay_kyc_has_failed)