diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/request/OrderRequest.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/request/OrderRequest.kt index 58213aa421..a780a06f11 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/request/OrderRequest.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/request/OrderRequest.kt @@ -11,7 +11,9 @@ data class OrderRequest( @JsonClass(generateAdapter = true) data class Data( @Json(name = "customer_wallet_address") val customerWalletAddress: String, - @Json(name = "specification_name") val specificationName: String = "SP_000004", - @Json(name = "type") val type: String = "CARD_ISSUE_VIRTUAL_RAIN_KYC", + @Json(name = "specification_name") val specificationName: String?, + @Json(name = "type") val type: String, + @Json(name = "target_tariff_plan_id") val targetTariffPlanId: String? = null, + @Json(name = "tariff_plan_transition_type") val tariffPlanTransitionType: String? = null, ) } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CustomerMeResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CustomerMeResponse.kt index db7e0ecff9..9b90eb277d 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CustomerMeResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CustomerMeResponse.kt @@ -40,6 +40,16 @@ data class CustomerMeResponse( @Json(name = "name") val name: String?, @Json(name = "description_items") val descriptionItems: List?, @Json(name = "images") val images: List? = null, + @Json(name = "fees") val fees: List? = null, + ) + + @JsonClass(generateAdapter = true) + data class Fee( + @Json(name = "type") val type: String?, + @Json(name = "amount") val amount: BigDecimal?, + @Json(name = "currency") val currency: String?, + @Json(name = "description") val description: String?, + @Json(name = "period") val period: String?, ) @JsonClass(generateAdapter = true) diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/OrderResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/OrderResponse.kt index e8ce00ce4f..e758050797 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/OrderResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/OrderResponse.kt @@ -27,6 +27,7 @@ data class OrderResponse( @Json(name = "emboss_name") val embossName: String?, @Json(name = "product_instance_id") val productInstanceId: String?, @Json(name = "payment_account_id") val paymentAccountId: String?, + @Json(name = "target_tariff_plan_id") val targetTariffPlanId: String?, @Json(name = "transaction_hash") val transactionHash: String?, ) diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/converter/TangemPayTariffPlanConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/converter/TangemPayTariffPlanConverter.kt index abd2b2b864..53be058106 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/converter/TangemPayTariffPlanConverter.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/converter/TangemPayTariffPlanConverter.kt @@ -14,6 +14,18 @@ internal object TangemPayTariffPlanConverter { name = name, descriptionItems = value.descriptionItems.orEmpty().mapNotNull(::convertDescriptionItem), images = value.images.orEmpty().mapNotNull(::convertImage), + fees = value.fees.orEmpty().mapNotNull(::convertFee), + ) + } + + private fun convertFee(fee: CustomerMeResponse.Fee): TangemPayTariffPlan.Fee? { + val amount = fee.amount ?: return null + return TangemPayTariffPlan.Fee( + type = TangemPayTariffPlan.Fee.Type.fromString(fee.type), + amount = amount, + currency = fee.currency.orEmpty(), + description = fee.description.orEmpty(), + period = fee.period?.let(TangemPayTariffPlan.Fee.Period::fromString), ) } diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt index 17c046245e..f3b88d0807 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt @@ -139,6 +139,17 @@ internal interface TangemPayDataModule { return GetTangemPayTariffPlanTransitionsUseCase(repository) } + @Provides + fun provideGetTangemPayTariffPlanStateUseCase( + customerOrderRepository: CustomerOrderRepository, + getTangemPayTariffPlanTransitionsUseCase: GetTangemPayTariffPlanTransitionsUseCase, + ): GetTangemPayTariffPlanStateUseCase { + return GetTangemPayTariffPlanStateUseCase( + customerOrderRepository = customerOrderRepository, + getTariffPlanTransitions = getTangemPayTariffPlanTransitionsUseCase, + ) + } + @Provides @Singleton fun providePaymentAccountStatusesStore( diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcher.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcher.kt index e77a8ea836..35cca5b3c2 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcher.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcher.kt @@ -17,6 +17,7 @@ import com.tangem.domain.pay.model.CustomerInfo.ProductInstance.SpecificationDat import com.tangem.domain.pay.model.OrderData import com.tangem.domain.pay.model.OrderStatus import com.tangem.domain.pay.model.TangemPayEntryPoint +import com.tangem.domain.pay.usecase.GetTangemPayTariffPlanStateUseCase import com.tangem.domain.pay.repository.* import com.tangem.domain.quotes.single.SingleQuoteStatusProducer import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier @@ -63,6 +64,7 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor( private val cardDetailsRepository: TangemPayCardDetailsRepository, private val issueCardRepository: TangemPayIssueCardRepository, private val virtualAccountFeatureToggles: VirtualAccountFeatureToggles, + private val getTangemPayTariffPlanStateUseCase: GetTangemPayTariffPlanStateUseCase, ) : PaymentAccountStatusFetcher { private val logger = TangemLogger.withTag(TAG) @@ -395,7 +397,12 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor( ), error = null, virtualAccount = virtualAccount, - tariffPlan = tariffPlan, + tariffPlan = tariffPlan?.let { tariff -> + getTangemPayTariffPlanStateUseCase( + userWalletId = userWalletId, + tariff = tariff, + ) + }, ) } diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultCustomerOrderRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultCustomerOrderRepository.kt index e0f31f3e9d..2ae89ee37b 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultCustomerOrderRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultCustomerOrderRepository.kt @@ -5,6 +5,7 @@ import com.tangem.data.pay.util.OrderConverter import com.tangem.data.pay.util.OrderStatusConverter import com.tangem.datasource.api.pay.TangemPayApi import com.tangem.datasource.api.pay.models.request.OrderRequest +import com.tangem.domain.models.account.TangemPayTariffPlanTransition import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.model.Order import com.tangem.domain.pay.model.OrderData @@ -53,8 +54,10 @@ internal class DefaultCustomerOrderRepository @Inject constructor( override suspend fun createOrder( userWalletId: UserWalletId, type: OrderType, - specificationName: String, + specificationName: String?, idempotencyKey: String, + targetTariffPlanId: String?, + transitionType: TangemPayTariffPlanTransition.Type?, ): Either { val walletAddress = requestHelper.getCustomerWalletAddress(userWalletId) return requestHelper.performRequest(userWalletId) { authHeader -> @@ -65,6 +68,8 @@ internal class DefaultCustomerOrderRepository @Inject constructor( customerWalletAddress = walletAddress, specificationName = specificationName, type = type.wireValue, + targetTariffPlanId = targetTariffPlanId, + tariffPlanTransitionType = transitionType?.name, ), idempotencyKey = idempotencyKey, ), diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt index 1bc2bfa461..049f062c03 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt @@ -29,6 +29,7 @@ import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.datasource.TangemPayAuthDataSource import com.tangem.domain.pay.model.CustomerInfo +import com.tangem.domain.pay.model.OrderType import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.tangempay.TangemPayAnalyticsEvents import com.tangem.domain.visa.error.VisaApiError @@ -161,7 +162,11 @@ internal class DefaultOnboardingRepository @Inject constructor( val walletAddress = requestHelper.getCustomerWalletAddress(userWalletId) requestHelper.performRequest(userWalletId) { authHeader -> - val data = OrderRequest.Data(customerWalletAddress = walletAddress) + val data = OrderRequest.Data( + customerWalletAddress = walletAddress, + specificationName = "SP_000004", + type = OrderType.CARD_ISSUE_VIRTUAL_RAIN_KYC.wireValue, + ) tangemPayApi.createOrder( authHeader = authHeader, body = OrderRequest(data = data, idempotencyKey = UUID.randomUUID().toString()), diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/util/OrderConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/util/OrderConverter.kt index f70bef92f5..3b22216961 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/util/OrderConverter.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/util/OrderConverter.kt @@ -2,6 +2,7 @@ package com.tangem.data.pay.util import com.tangem.datasource.api.pay.models.response.OrderResponse import com.tangem.domain.pay.model.Order +import com.tangem.domain.pay.model.OrderStep import com.tangem.domain.pay.model.OrderType /** Maps a wire `OrderResponse.Result` into the domain [Order] model. */ @@ -15,11 +16,12 @@ internal object OrderConverter { customerId = value.customerId, type = type, status = status, - step = value.step, + step = OrderStep.fromString(value.step), stepChangeCode = value.stepChangeCode, productInstanceId = value.data.productInstanceId, paymentAccountId = value.data.paymentAccountId, cardId = null, // Card id not in v1 response shape; resolved via productInstanceId. + toTariffPlanId = value.data.targetTariffPlanId, withdrawTxHash = value.data.transactionHash?.ifEmpty { null }, createdAt = value.createdAt, updatedAt = value.updatedAt, diff --git a/data/visa/src/test/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcherTest.kt b/data/visa/src/test/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcherTest.kt index e916df8fbc..033bd391f5 100644 --- a/data/visa/src/test/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcherTest.kt +++ b/data/visa/src/test/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcherTest.kt @@ -19,6 +19,7 @@ import com.tangem.domain.pay.TangemPayEligibilityManager import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher import com.tangem.domain.pay.model.CustomerInfo import com.tangem.domain.pay.repository.* +import com.tangem.domain.pay.usecase.GetTangemPayTariffPlanStateUseCase import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier import com.tangem.domain.visa.error.VisaApiError import com.tangem.features.virtualaccount.VirtualAccountFeatureToggles @@ -48,6 +49,7 @@ internal class DefaultPaymentAccountStatusFetcherTest { private val cardDetailsRepository: TangemPayCardDetailsRepository = mockk() private val issueCardRepository: TangemPayIssueCardRepository = mockk() private val virtualAccountFeatureToggles: VirtualAccountFeatureToggles = mockk() + private val getTangemPayTariffPlanStateUseCase: GetTangemPayTariffPlanStateUseCase = mockk() private val fetcher = DefaultPaymentAccountStatusFetcher( paymentAccountStatusesStore = paymentAccountStatusesStore, @@ -63,6 +65,7 @@ internal class DefaultPaymentAccountStatusFetcherTest { cardDetailsRepository = cardDetailsRepository, issueCardRepository = issueCardRepository, virtualAccountFeatureToggles = virtualAccountFeatureToggles, + getTangemPayTariffPlanStateUseCase = getTangemPayTariffPlanStateUseCase, ) private val userWalletId = UserWalletId("011") 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 aebdca0714..4c38b2adc2 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 @@ -166,7 +166,7 @@ sealed class PaymentAccountStatusValue { val fiatRate: SerializedBigDecimal?, val error: Error?, val virtualAccount: VirtualAccountOnramp?, - val tariffPlan: TangemPayCustomerTariffPlan?, + val tariffPlan: TangemPayTariffPlanState?, ) : PaymentAccountStatusValue() { val cryptoCurrencyStatus: CryptoCurrencyStatus = CryptoCurrencyStatus( currency = cryptoCurrency, diff --git a/domain/models/src/main/kotlin/com/tangem/domain/models/account/TangemPayTariffPlan.kt b/domain/models/src/main/kotlin/com/tangem/domain/models/account/TangemPayTariffPlan.kt index 5ee1d9997a..094d113ea0 100644 --- a/domain/models/src/main/kotlin/com/tangem/domain/models/account/TangemPayTariffPlan.kt +++ b/domain/models/src/main/kotlin/com/tangem/domain/models/account/TangemPayTariffPlan.kt @@ -1,5 +1,6 @@ package com.tangem.domain.models.account +import com.tangem.domain.models.serialization.SerializedBigDecimal import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import java.util.Locale @@ -11,7 +12,55 @@ data class TangemPayTariffPlan( @SerialName("name") val name: String, @SerialName("description_items") val descriptionItems: List, @SerialName("images") val images: List = emptyList(), + @SerialName("fees") val fees: List = emptyList(), ) { + @Serializable + data class Fee( + @SerialName("type") val type: Type, + @SerialName("amount") val amount: SerializedBigDecimal, + @SerialName("currency") val currency: String, + @SerialName("description") val description: String, + @SerialName("period") val period: Period?, + ) { + @Serializable + enum class Type { + @SerialName("FREE") + FREE, + + @SerialName("RECURRING") + RECURRING, + + @SerialName("UNKNOWN") + UNKNOWN, + ; + + companion object { + fun fromString(value: String?) = when (value?.uppercase(Locale.US)) { + "FREE" -> FREE + "RECURRING" -> RECURRING + else -> UNKNOWN + } + } + } + + @Serializable + enum class Period { + @SerialName("MONTH") + MONTH, + + @SerialName("UNKNOWN") + UNKNOWN, + ; + + companion object { + fun fromString(value: String?) = when (value?.uppercase(Locale.US)) { + "MONTH" -> MONTH + else -> UNKNOWN + } + } + } + } + @Serializable data class DescriptionItem( @SerialName("section") val section: Section, diff --git a/domain/models/src/main/kotlin/com/tangem/domain/models/account/TangemPayTariffPlanState.kt b/domain/models/src/main/kotlin/com/tangem/domain/models/account/TangemPayTariffPlanState.kt new file mode 100644 index 0000000000..657ca64400 --- /dev/null +++ b/domain/models/src/main/kotlin/com/tangem/domain/models/account/TangemPayTariffPlanState.kt @@ -0,0 +1,29 @@ +package com.tangem.domain.models.account + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class TangemPayTariffPlanState( + @SerialName("tariff") val tariff: TangemPayCustomerTariffPlan, + @SerialName("order") val order: Order?, +) { + @Serializable + data class Order( + @SerialName("orderId") val orderId: String, + @SerialName("step") val step: OrderStep, + ) + + @Serializable + sealed interface OrderStep { + + @Serializable + data object Unknown : OrderStep + + @Serializable + data class AwaitingDeposit( + @SerialName("fromPlan") val fromPlan: TangemPayTariffPlan, + @SerialName("toPlan") val toPlan: TangemPayTariffPlan, + ) : OrderStep + } +} \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/Order.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/Order.kt index 4ad4c662f9..fc447ae13e 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/Order.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/Order.kt @@ -14,6 +14,7 @@ package com.tangem.domain.pay.model * @property productInstanceId set for card-scoped orders. * @property paymentAccountId set for card-scoped and payment-account-level orders. * @property cardId set for card-scoped orders that are filtered by card. + * @property toTariffPlanId target tariff plan id for [OrderType.TARIFF_PLAN_TRANSITION] orders. * @property withdrawTxHash present for completed [OrderType.WITHDRAW] orders. * @property updatedAt ISO-8601 timestamp used to pick the most recent matching order. */ @@ -22,11 +23,12 @@ data class Order( val customerId: String?, val type: OrderType, val status: OrderStatus, - val step: String?, + val step: OrderStep, val stepChangeCode: Int?, val productInstanceId: String?, val paymentAccountId: String?, val cardId: String?, + val toTariffPlanId: String?, val withdrawTxHash: String?, val createdAt: String?, val updatedAt: String?, diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/OrderStep.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/OrderStep.kt new file mode 100644 index 0000000000..03dcabee92 --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/OrderStep.kt @@ -0,0 +1,16 @@ +package com.tangem.domain.pay.model + +import java.util.Locale + +enum class OrderStep { + AWAITING_DEPOSIT, + UNKNOWN, + ; + + companion object { + fun fromString(value: String?) = when (value?.uppercase(Locale.US)) { + "AWAITING_DEPOSIT" -> AWAITING_DEPOSIT + else -> UNKNOWN + } + } +} \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/OrderType.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/OrderType.kt index 432d0ea5e0..81db6482fb 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/OrderType.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/OrderType.kt @@ -18,6 +18,7 @@ enum class OrderType(val wireValue: String) { CARD_FREEZE("CARD_FREEZE"), CARD_UNFREEZE("CARD_UNFREEZE"), WITHDRAW("WITHDRAW"), + TARIFF_PLAN_TRANSITION("TARIFF_PLAN_TRANSITION"), UNKNOWN(""), ; diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/CustomerOrderRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/CustomerOrderRepository.kt index db6412e923..4f172d5b4d 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/CustomerOrderRepository.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/CustomerOrderRepository.kt @@ -1,6 +1,7 @@ package com.tangem.domain.pay.repository import arrow.core.Either +import com.tangem.domain.models.account.TangemPayTariffPlanTransition import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.model.Order import com.tangem.domain.pay.model.OrderData @@ -34,7 +35,9 @@ interface CustomerOrderRepository { suspend fun createOrder( userWalletId: UserWalletId, type: OrderType, - specificationName: String, + specificationName: String?, idempotencyKey: String, + targetTariffPlanId: String? = null, + transitionType: TangemPayTariffPlanTransition.Type? = null, ): Either } \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/GetTangemPayTariffPlanStateUseCase.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/GetTangemPayTariffPlanStateUseCase.kt new file mode 100644 index 0000000000..4785577e09 --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/GetTangemPayTariffPlanStateUseCase.kt @@ -0,0 +1,63 @@ +package com.tangem.domain.pay.usecase + +import com.tangem.domain.models.account.TangemPayCustomerTariffPlan +import com.tangem.domain.models.account.TangemPayTariffPlanState +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.pay.model.Order +import com.tangem.domain.pay.model.OrderStatus +import com.tangem.domain.pay.model.OrderStep +import com.tangem.domain.pay.model.OrderType +import com.tangem.domain.pay.repository.CustomerOrderRepository +import com.tangem.domain.pay.util.OrderResolver + +class GetTangemPayTariffPlanStateUseCase( + private val customerOrderRepository: CustomerOrderRepository, + private val getTariffPlanTransitions: GetTangemPayTariffPlanTransitionsUseCase, +) { + suspend operator fun invoke( + userWalletId: UserWalletId, + tariff: TangemPayCustomerTariffPlan, + ): TangemPayTariffPlanState { + val order = findTariffPlanOrder(userWalletId) + return TangemPayTariffPlanState( + tariff = tariff, + order = order?.let { activeOrder -> + TangemPayTariffPlanState.Order( + orderId = activeOrder.id, + step = resolveStep( + userWalletId = userWalletId, + tariff = tariff, + order = activeOrder, + ), + ) + }, + ) + } + + private suspend fun findTariffPlanOrder(userWalletId: UserWalletId): Order? { + return customerOrderRepository.findOrders( + userWalletId = userWalletId, + types = setOf(OrderType.TARIFF_PLAN_TRANSITION), + statuses = OrderStatus.activeStatuses, + ).getOrNull()?.let { orders -> + OrderResolver.selectActive(orders = orders, type = OrderType.TARIFF_PLAN_TRANSITION) + } + } + + private suspend fun resolveStep( + userWalletId: UserWalletId, + tariff: TangemPayCustomerTariffPlan, + order: Order, + ): TangemPayTariffPlanState.OrderStep { + if (order.step != OrderStep.AWAITING_DEPOSIT) return TangemPayTariffPlanState.OrderStep.Unknown + + val transition = getTariffPlanTransitions(userWalletId).getOrNull() + ?.firstOrNull { it.plan.id == order.toTariffPlanId } + ?: return TangemPayTariffPlanState.OrderStep.Unknown + + return TangemPayTariffPlanState.OrderStep.AwaitingDeposit( + fromPlan = tariff.plan, + toPlan = transition.plan, + ) + } +} \ No newline at end of file diff --git a/domain/visa/src/test/kotlin/com/tangem/domain/pay/model/OrderConflictRulesTest.kt b/domain/visa/src/test/kotlin/com/tangem/domain/pay/model/OrderConflictRulesTest.kt index 1ed00d3f7b..2be25d47c6 100644 --- a/domain/visa/src/test/kotlin/com/tangem/domain/pay/model/OrderConflictRulesTest.kt +++ b/domain/visa/src/test/kotlin/com/tangem/domain/pay/model/OrderConflictRulesTest.kt @@ -142,12 +142,13 @@ internal class OrderConflictRulesTest { customerId = "customer", type = type, status = status, - step = null, + step = OrderStep.UNKNOWN, stepChangeCode = null, productInstanceId = productInstanceId, paymentAccountId = null, // Mirrors production: the v1 order response has no card id; conflicts match by productInstanceId. cardId = null, + toTariffPlanId = null, withdrawTxHash = null, createdAt = null, updatedAt = null, diff --git a/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/CheckOrderConflictUseCaseTest.kt b/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/CheckOrderConflictUseCaseTest.kt index d36c36616e..448d6b9fef 100644 --- a/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/CheckOrderConflictUseCaseTest.kt +++ b/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/CheckOrderConflictUseCaseTest.kt @@ -56,11 +56,12 @@ internal class CheckOrderConflictUseCaseTest { customerId = "customer", type = type, status = status, - step = null, + step = OrderStep.UNKNOWN, stepChangeCode = null, productInstanceId = null, paymentAccountId = null, cardId = null, + toTariffPlanId = null, withdrawTxHash = null, createdAt = null, updatedAt = null, diff --git a/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/IssueAdditionalCardUseCaseTest.kt b/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/IssueAdditionalCardUseCaseTest.kt index e64a03b9d1..3540d0cbfc 100644 --- a/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/IssueAdditionalCardUseCaseTest.kt +++ b/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/IssueAdditionalCardUseCaseTest.kt @@ -7,6 +7,7 @@ import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.model.Offer import com.tangem.domain.pay.model.Order import com.tangem.domain.pay.model.OrderStatus +import com.tangem.domain.pay.model.OrderStep import com.tangem.domain.pay.model.OrderType import com.tangem.domain.pay.repository.CustomerOffersRepository import com.tangem.domain.pay.repository.CustomerOrderRepository @@ -51,7 +52,9 @@ internal class IssueAdditionalCardUseCaseTest { assertThat(result.leftOrNull()).isEqualTo(VisaApiError.Unspecified) coVerify(exactly = 0) { orderRepository.findOrders(any(), any(), any()) } - coVerify(exactly = 0) { orderRepository.createOrder(any(), any(), any(), any()) } + coVerify(exactly = 0) { + orderRepository.createOrder(any(), any(), any(), any(), any(), any()) + } } @Test @@ -77,7 +80,9 @@ internal class IssueAdditionalCardUseCaseTest { val result = useCase(userWalletId) assertThat(result.isRight()).isTrue() - coVerify(exactly = 0) { orderRepository.createOrder(any(), any(), any(), any()) } + coVerify(exactly = 0) { + orderRepository.createOrder(any(), any(), any(), any(), any(), any()) + } coVerify(exactly = 1) { issueCardRepository.storeIssueOrderId(userWalletId, existing.id) } } @@ -148,11 +153,12 @@ internal class IssueAdditionalCardUseCaseTest { customerId = "customer", type = type, status = status, - step = null, + step = OrderStep.UNKNOWN, stepChangeCode = null, productInstanceId = null, paymentAccountId = null, cardId = null, + toTariffPlanId = null, withdrawTxHash = null, createdAt = null, updatedAt = null, diff --git a/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/RestoreActiveIssueOrdersUseCaseTest.kt b/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/RestoreActiveIssueOrdersUseCaseTest.kt index b18d650fb7..aa5ff70436 100644 --- a/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/RestoreActiveIssueOrdersUseCaseTest.kt +++ b/domain/visa/src/test/kotlin/com/tangem/domain/pay/usecase/RestoreActiveIssueOrdersUseCaseTest.kt @@ -6,6 +6,7 @@ import com.google.common.truth.Truth.assertThat import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.model.Order import com.tangem.domain.pay.model.OrderStatus +import com.tangem.domain.pay.model.OrderStep import com.tangem.domain.pay.model.OrderType import com.tangem.domain.pay.model.TangemPayOrderInfo import com.tangem.domain.pay.repository.CustomerOrderRepository @@ -113,11 +114,12 @@ internal class RestoreActiveIssueOrdersUseCaseTest { customerId = "customer", type = type, status = status, - step = null, + step = OrderStep.UNKNOWN, stepChangeCode = null, productInstanceId = null, paymentAccountId = null, cardId = null, + toTariffPlanId = null, withdrawTxHash = null, createdAt = null, updatedAt = null, diff --git a/domain/visa/src/test/kotlin/com/tangem/domain/pay/util/OrderResolverTest.kt b/domain/visa/src/test/kotlin/com/tangem/domain/pay/util/OrderResolverTest.kt index 0681644652..7070fb63a7 100644 --- a/domain/visa/src/test/kotlin/com/tangem/domain/pay/util/OrderResolverTest.kt +++ b/domain/visa/src/test/kotlin/com/tangem/domain/pay/util/OrderResolverTest.kt @@ -3,6 +3,7 @@ package com.tangem.domain.pay.util import com.google.common.truth.Truth.assertThat import com.tangem.domain.pay.model.Order import com.tangem.domain.pay.model.OrderStatus +import com.tangem.domain.pay.model.OrderStep import com.tangem.domain.pay.model.OrderType import org.junit.jupiter.api.Test @@ -112,11 +113,12 @@ internal class OrderResolverTest { customerId = null, type = type, status = status, - step = null, + step = OrderStep.UNKNOWN, stepChangeCode = null, productInstanceId = productInstanceId, paymentAccountId = null, cardId = cardId, + toTariffPlanId = null, withdrawTxHash = null, createdAt = null, updatedAt = updatedAt, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt index 143aa1524c..90a6987d78 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt @@ -75,7 +75,7 @@ internal class TangemPayDetailsStateFactory( onBackClick = onBack, onOpenMenu = onOpenMenu, items = getTopBarMenuItems(), - itemsV2 = getTopBarMenuItemsV2(tariffPlan = status.tariffPlan), + itemsV2 = getTopBarMenuItemsV2(tariffPlan = status.tariffPlan?.tariff), ), pullToRefreshConfig = PullToRefreshConfig( isRefreshing = false,