From fdb4585dca880ab2d0b91bd48ed72f1119ca9a63 Mon Sep 17 00:00:00 2001 From: mariiapanasetskaia Date: Fri, 13 Dec 2024 10:49:27 +0100 Subject: [PATCH 1/9] api impl for banner and UpsellAddonOffer --- .../graphql/TravelAddonBannerQuery.graphql | 10 +++ .../data/GetTravelAddonBannerInfoUseCase.kt | 52 ++++++++++-- .../graphql/UpsellAddonOfferMutation.graphql | 33 ++++++++ .../data/GetTravelAddonOfferUseCase.kt | 80 ++++++++++++++++++- .../insurance/InsuranceDestination.kt | 4 +- .../ui/history/TravelCertificateHistory.kt | 2 + 6 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 app/data/data-addons/src/main/graphql/TravelAddonBannerQuery.graphql create mode 100644 app/feature/feature-addon-purchase/src/main/graphql/UpsellAddonOfferMutation.graphql diff --git a/app/data/data-addons/src/main/graphql/TravelAddonBannerQuery.graphql b/app/data/data-addons/src/main/graphql/TravelAddonBannerQuery.graphql new file mode 100644 index 0000000000..e4e2d703b6 --- /dev/null +++ b/app/data/data-addons/src/main/graphql/TravelAddonBannerQuery.graphql @@ -0,0 +1,10 @@ +query TravelAddonBanner($flow: UpsellTravelAddonFlow!) { + currentMember { + upsellTravelAddonBanner (flow: $flow) { + badges + contractIds + descriptionDisplayName + titleDisplayName + } + } +} diff --git a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCase.kt b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCase.kt index ce3c9e1852..465033402e 100644 --- a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCase.kt +++ b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCase.kt @@ -2,9 +2,10 @@ package com.hedvig.android.data.addons.data import arrow.core.Either import arrow.core.NonEmptyList -import arrow.core.nonEmptyListOf import arrow.core.raise.either +import arrow.core.toNonEmptyListOrNull import com.apollographql.apollo.ApolloClient +import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.featureflags.FeatureManager import com.hedvig.android.featureflags.flags.Feature @@ -12,6 +13,8 @@ import com.hedvig.android.logger.LogPriority import com.hedvig.android.logger.logcat import kotlin.String import kotlinx.coroutines.flow.first +import octopus.TravelAddonBannerQuery +import octopus.type.UpsellTravelAddonFlow interface GetTravelAddonBannerInfoUseCase { suspend fun invoke(source: TravelAddonBannerSource): Either @@ -30,13 +33,45 @@ internal class GetTravelAddonBannerInfoUseCaseImpl( } null } else { - // TODO: actual impl here!!!! - // TODO: and null if eligibleInsurancesIds is empty - TravelAddonBannerInfo( - title = "Travel Plus", - description = "Extended travel insurance with extra coverage for your travels", - labels = listOf("Popular"), - eligibleInsurancesIds = nonEmptyListOf("id1"), +// TravelAddonBannerInfo( +// title = "Travel Plus", +// description = "Extended travel insurance with extra coverage for your travels", +// labels = listOf("Popular"), +// eligibleInsurancesIds = nonEmptyListOf("id1"), +// ) //todo: remove mock + val mappedSource = when (source) { + TravelAddonBannerSource.TRAVEL_CERTIFICATES -> UpsellTravelAddonFlow.APP_UPSELL_UPGRADE + TravelAddonBannerSource.INSURANCES_TAB -> UpsellTravelAddonFlow.APP_ONLY_UPSALE + } + apolloClient.query(TravelAddonBannerQuery(mappedSource)).safeExecute().fold( + ifLeft = { error -> + logcat(LogPriority.ERROR) { "Error from travelAddonBannerQuery from source: $mappedSource: $error" } + raise(ErrorMessage()) + }, + ifRight = { result -> + val bannerData = result.currentMember.upsellTravelAddonBanner + if (bannerData == null) { + logcat(LogPriority.DEBUG) { "Got null response from TravelAddonBannerQuery" } + null + } else { + val nonEmptyContracts = bannerData.contractIds.toNonEmptyListOrNull() + if (nonEmptyContracts.isNullOrEmpty()) { + logcat(LogPriority.ERROR) { + "Got non null response from TravelAddonBannerQuery from source: " + + "$mappedSource, but contractIds are empty" + } + null + } else { + TravelAddonBannerInfo( + title = bannerData.titleDisplayName, + description = bannerData.descriptionDisplayName, + labels = bannerData.badges, + eligibleInsurancesIds = nonEmptyContracts, + bannerSource = mappedSource, + ) + } + } + }, ) } } @@ -48,6 +83,7 @@ data class TravelAddonBannerInfo( val description: String, val labels: List, val eligibleInsurancesIds: NonEmptyList, + val bannerSource: UpsellTravelAddonFlow, ) enum class TravelAddonBannerSource { diff --git a/app/feature/feature-addon-purchase/src/main/graphql/UpsellAddonOfferMutation.graphql b/app/feature/feature-addon-purchase/src/main/graphql/UpsellAddonOfferMutation.graphql new file mode 100644 index 0000000000..0df6686ac7 --- /dev/null +++ b/app/feature/feature-addon-purchase/src/main/graphql/UpsellAddonOfferMutation.graphql @@ -0,0 +1,33 @@ +mutation UpsellAddonOffer($contractId: ID!) { + upsellTravelAddonOffer(contractId: $contractId) { + offer { + activationDate + currentAddon { + displayItems { + displayValue + displayTitle + } + premium { + ...MoneyFragment + } + } + descriptionDisplayName + quotes { + addonId + displayItems { + displayTitle + displayValue + } + displayName + premium { + ...MoneyFragment + } + quoteId + } + titleDisplayName + } + userError { + message + } + } +} diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt index 8e149a2a76..548a245867 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt @@ -1,16 +1,25 @@ package com.hedvig.android.feature.addon.purchase.data import arrow.core.Either +import arrow.core.NonEmptyList import arrow.core.nonEmptyListOf import arrow.core.raise.either +import arrow.core.toNonEmptyListOrNull import com.apollographql.apollo.ApolloClient +import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.core.uidata.UiCurrencyCode import com.hedvig.android.core.uidata.UiMoney import com.hedvig.android.data.productvariant.InsuranceVariantDocument import com.hedvig.android.feature.addon.purchase.data.Addon.TravelAddonOffer import com.hedvig.android.featureflags.FeatureManager +import com.hedvig.android.featureflags.flags.Feature +import com.hedvig.android.logger.LogPriority +import com.hedvig.android.logger.logcat +import kotlin.String +import kotlinx.coroutines.flow.first import kotlinx.datetime.LocalDate +import octopus.UpsellAddonOfferMutation internal interface GetTravelAddonOfferUseCase { suspend fun invoke(id: String): Either @@ -21,13 +30,80 @@ internal class GetTravelAddonOfferUseCaseImpl( private val featureManager: FeatureManager, ) : GetTravelAddonOfferUseCase { override suspend fun invoke(id: String): Either { - // todo: REMOVE MOCK! return either { - mockWithUpgrade + val isAddonFlagOn = featureManager.isFeatureEnabled(Feature.TRAVEL_ADDON).first() + if (!isAddonFlagOn) { + logcat(LogPriority.ERROR) { "Tried to start UpsellAddonOfferMutation but addon feature flag is off" } + raise(ErrorMessage()) + } else { + apolloClient.mutation(UpsellAddonOfferMutation(id)).safeExecute().fold( + ifLeft = { error -> + logcat(LogPriority.ERROR) { "Tried to start UpsellAddonOfferMutation but got error: $error" } + //not passing error message to the member here, as we want to redirect member to chat if there is a message + raise(ErrorMessage()) + }, + ifRight = { result -> + if (result.upsellTravelAddonOffer.userError != null) { + raise(ErrorMessage(result.upsellTravelAddonOffer.userError.message)) + //the only case where we want to redirect to chat + } + val data = result.upsellTravelAddonOffer.offer + if (data == null) { + logcat(LogPriority.ERROR) { "Tried to do UpsellAddonOfferMutation but got null offer" } + raise(ErrorMessage()) + } + val nonEmptyQuotes = data.quotes.toNonEmptyListOrNull() + if (nonEmptyQuotes.isNullOrEmpty()) { + logcat(LogPriority.ERROR) { "Tried to do UpsellAddonOfferMutation but got empty quotes" } + raise(ErrorMessage()) + } + + TravelAddonOffer( + addonOptions = nonEmptyQuotes.toTravelAddonQuotes(), + title = data.titleDisplayName, + description = data.descriptionDisplayName, + activationDate = data.activationDate, + currentTravelAddon = data.currentAddon.toCurrentAddon(), + ) + }, + ) + } + } } } +private fun NonEmptyList.toTravelAddonQuotes() + : NonEmptyList { + return this.map { + TravelAddonQuote( + quoteId = it.quoteId, + addonId = it.addonId, + displayName = it.displayName, + price = UiMoney.fromMoneyFragment(it.premium), + addonVariant = AddonVariant( + documents = listOf(), //todo: Addons - populate! + termsVersion = "", //todo: Addons - populate! + displayDetails = it.displayItems.map { item -> + item.displayTitle to item.displayValue + }, + ), + ) + } +} + +private fun UpsellAddonOfferMutation.Data.UpsellTravelAddonOffer.Offer.CurrentAddon?.toCurrentAddon(): CurrentTravelAddon? { + return this?.let { + CurrentTravelAddon( + price = UiMoney.fromMoneyFragment(premium), + displayDetails = displayItems.map { + it.displayTitle to it.displayValue + }, + ) + } +} + +//todo: remove mocks when not needed private val mockWithoutUpgrade = TravelAddonOffer( addonOptions = nonEmptyListOf( TravelAddonQuote( diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/InsuranceDestination.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/InsuranceDestination.kt index 72b97e0e2e..0a795b0e22 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/InsuranceDestination.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/InsuranceDestination.kt @@ -83,6 +83,7 @@ import com.hedvig.android.pullrefresh.pullRefresh import com.hedvig.android.pullrefresh.rememberPullRefreshState import hedvig.resources.R import kotlinx.datetime.LocalDate +import octopus.type.UpsellTravelAddonFlow @Composable internal fun InsuranceDestination( @@ -471,7 +472,7 @@ private class InsuranceUiStateProvider : CollectionPreviewParameterProvider Date: Fri, 13 Dec 2024 10:50:36 +0100 Subject: [PATCH 2/9] add todos --- .../feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt index 548a245867..6edc797b27 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt @@ -82,8 +82,8 @@ private fun NonEmptyList item.displayTitle to item.displayValue }, From 0dfae9b1ba0a9f6757f364ddea6d1061201bcd55 Mon Sep 17 00:00:00 2001 From: mariiapanasetskaia Date: Fri, 13 Dec 2024 11:02:00 +0100 Subject: [PATCH 3/9] SubmitAddonPurchaseUseCaseImpl impl --- .../UpsellTravelAddonActivateMutation.graphql | 7 +++++++ .../purchase/data/SubmitAddonPurchaseUseCase.kt | 16 +++++++++++----- .../addon/purchase/di/AddonPurchaseModule.kt | 3 +-- 3 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 app/feature/feature-addon-purchase/src/main/graphql/UpsellTravelAddonActivateMutation.graphql diff --git a/app/feature/feature-addon-purchase/src/main/graphql/UpsellTravelAddonActivateMutation.graphql b/app/feature/feature-addon-purchase/src/main/graphql/UpsellTravelAddonActivateMutation.graphql new file mode 100644 index 0000000000..cd970d1d67 --- /dev/null +++ b/app/feature/feature-addon-purchase/src/main/graphql/UpsellTravelAddonActivateMutation.graphql @@ -0,0 +1,7 @@ +mutation UpsellTravelAddonActivate($addonId: ID!, $quoteId: ID!) { + upsellTravelAddonActivate(addonId: $addonId, quoteId: $quoteId) { + userError { + message + } + } +} diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt index edfe93b9f6..2d5b5be96b 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt @@ -3,22 +3,28 @@ package com.hedvig.android.feature.addon.purchase.data import arrow.core.Either import arrow.core.raise.either import com.apollographql.apollo.ApolloClient +import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.featureflags.FeatureManager import kotlinx.datetime.LocalDate +import octopus.UpsellTravelAddonActivateMutation.Data.UpsellTravelAddonActivate internal interface SubmitAddonPurchaseUseCase { - suspend fun invoke(quoteId: String, addonId: String): Either + suspend fun invoke(quoteId: String, addonId: String): Either } internal class SubmitAddonPurchaseUseCaseImpl( private val apolloClient: ApolloClient, - private val featureManager: FeatureManager, ) : SubmitAddonPurchaseUseCase { - override suspend fun invoke(quoteId: String, addonId: String): Either { - // TODO: REMOVE MOCK! + override suspend fun invoke(quoteId: String, addonId: String): Either { return either { - LocalDate(2025, 1, 1) + apolloClient.mutation(UpsellTravelAddonActivate(addonId = addonId, quoteId = quoteId)).safeExecute().fold( + ifLeft = { error -> + raise(ErrorMessage(error.message)) + }, + ifRight = { + return Unit + } } } } diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/di/AddonPurchaseModule.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/di/AddonPurchaseModule.kt index 77517de224..cf768a2272 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/di/AddonPurchaseModule.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/di/AddonPurchaseModule.kt @@ -53,8 +53,7 @@ val addonPurchaseModule = module { single { SubmitAddonPurchaseUseCaseImpl( - apolloClient = get(), - featureManager = get(), + apolloClient = get() ) } } From 6b8505a96228ff22c6423f6f6f4327eb4c925577 Mon Sep 17 00:00:00 2001 From: mariiapanasetskaia Date: Fri, 13 Dec 2024 11:14:04 +0100 Subject: [PATCH 4/9] SubmitAddonPurchaseUseCaseImpl impl --- .../purchase/data/SubmitAddonPurchaseUseCase.kt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt index 2d5b5be96b..a153292ad5 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt @@ -6,7 +6,10 @@ import com.apollographql.apollo.ApolloClient import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.featureflags.FeatureManager +import com.hedvig.android.logger.LogPriority +import com.hedvig.android.logger.logcat import kotlinx.datetime.LocalDate +import octopus.UpsellTravelAddonActivateMutation import octopus.UpsellTravelAddonActivateMutation.Data.UpsellTravelAddonActivate internal interface SubmitAddonPurchaseUseCase { @@ -18,13 +21,16 @@ internal class SubmitAddonPurchaseUseCaseImpl( ) : SubmitAddonPurchaseUseCase { override suspend fun invoke(quoteId: String, addonId: String): Either { return either { - apolloClient.mutation(UpsellTravelAddonActivate(addonId = addonId, quoteId = quoteId)).safeExecute().fold( + apolloClient.mutation(UpsellTravelAddonActivateMutation(addonId = addonId, quoteId = quoteId)).safeExecute().fold( ifLeft = { error -> - raise(ErrorMessage(error.message)) + logcat(LogPriority.ERROR) { "Tried to do UpsellTravelAddonActivateMutation but got error: $error" } + raise(ErrorMessage()) }, - ifRight = { - return Unit - } + ifRight = { result -> + if (result.upsellTravelAddonActivate.userError!=null) { + raise(ErrorMessage(result.upsellTravelAddonActivate.userError.message)) + } + }) } } } From ac700304ea48fccbf37a293ad8914a7b3341238c Mon Sep 17 00:00:00 2001 From: mariiapanasetskaia Date: Fri, 13 Dec 2024 11:18:12 +0100 Subject: [PATCH 5/9] remove mock not needed --- .../data/GetTravelAddonBannerInfoUseCase.kt | 6 ----- .../data/GetInsuranceForTravelAddonUseCase.kt | 22 ++++++------------- .../data/GetTravelAddonOfferUseCase.kt | 14 +++++------- .../data/SubmitAddonPurchaseUseCase.kt | 8 +++---- .../addon/purchase/di/AddonPurchaseModule.kt | 2 +- .../insurance/InsuranceDestination.kt | 2 +- .../ui/history/TravelCertificateHistory.kt | 2 +- 7 files changed, 19 insertions(+), 37 deletions(-) diff --git a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCase.kt b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCase.kt index 465033402e..10d4441f67 100644 --- a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCase.kt +++ b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCase.kt @@ -33,12 +33,6 @@ internal class GetTravelAddonBannerInfoUseCaseImpl( } null } else { -// TravelAddonBannerInfo( -// title = "Travel Plus", -// description = "Extended travel insurance with extra coverage for your travels", -// labels = listOf("Popular"), -// eligibleInsurancesIds = nonEmptyListOf("id1"), -// ) //todo: remove mock val mappedSource = when (source) { TravelAddonBannerSource.TRAVEL_CERTIFICATES -> UpsellTravelAddonFlow.APP_UPSELL_UPGRADE TravelAddonBannerSource.INSURANCES_TAB -> UpsellTravelAddonFlow.APP_ONLY_UPSALE diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt index 0480c5d77a..b49c2163d5 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt @@ -2,6 +2,7 @@ package com.hedvig.android.feature.addon.purchase.data import arrow.core.Either import arrow.core.raise.either +import arrow.core.raise.ensure import com.apollographql.apollo.ApolloClient import com.apollographql.apollo.cache.normalized.FetchPolicy import com.apollographql.apollo.cache.normalized.fetchPolicy @@ -41,21 +42,12 @@ internal class GetInsuranceForTravelAddonUseCaseImpl( } raise(ErrorMessage()) } else { - // TODO: remove mock! -// val result = memberResponse.bind().currentMember.toInsurancesForAddon(ids) -// ensure(result.isNotEmpty()) { -// { "Tried to get list of insurances for addon purchase but the list is empty!" } -// ErrorMessage() -// } -// result - listOf( - InsuranceForAddon( - id = "id", - displayName = "Rent Bas", - "Tulegatan 1", - ContractGroup.RENTAL, - ), - ) // TODO: remove mock!! + val result = memberResponse.bind().currentMember.toInsurancesForAddon(ids) + ensure(result.isNotEmpty()) { + { "Tried to get list of insurances for addon purchase but the list is empty!" } + ErrorMessage() + } + result } } } diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt index 6edc797b27..d177ff6c40 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt @@ -39,13 +39,13 @@ internal class GetTravelAddonOfferUseCaseImpl( apolloClient.mutation(UpsellAddonOfferMutation(id)).safeExecute().fold( ifLeft = { error -> logcat(LogPriority.ERROR) { "Tried to start UpsellAddonOfferMutation but got error: $error" } - //not passing error message to the member here, as we want to redirect member to chat if there is a message + // not passing error message to the member here, as we want to redirect member to chat if there is a message raise(ErrorMessage()) }, ifRight = { result -> if (result.upsellTravelAddonOffer.userError != null) { raise(ErrorMessage(result.upsellTravelAddonOffer.userError.message)) - //the only case where we want to redirect to chat + // the only case where we want to redirect to chat } val data = result.upsellTravelAddonOffer.offer if (data == null) { @@ -68,13 +68,11 @@ internal class GetTravelAddonOfferUseCaseImpl( }, ) } - } } } -private fun NonEmptyList.toTravelAddonQuotes() - : NonEmptyList { +private fun NonEmptyList.toTravelAddonQuotes(): NonEmptyList { return this.map { TravelAddonQuote( quoteId = it.quoteId, @@ -82,8 +80,8 @@ private fun NonEmptyList item.displayTitle to item.displayValue }, @@ -103,7 +101,7 @@ private fun UpsellAddonOfferMutation.Data.UpsellTravelAddonOffer.Offer.CurrentAd } } -//todo: remove mocks when not needed +// todo: remove mocks when not needed private val mockWithoutUpgrade = TravelAddonOffer( addonOptions = nonEmptyListOf( TravelAddonQuote( diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt index a153292ad5..b909e1b182 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/SubmitAddonPurchaseUseCase.kt @@ -5,12 +5,9 @@ import arrow.core.raise.either import com.apollographql.apollo.ApolloClient import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage -import com.hedvig.android.featureflags.FeatureManager import com.hedvig.android.logger.LogPriority import com.hedvig.android.logger.logcat -import kotlinx.datetime.LocalDate import octopus.UpsellTravelAddonActivateMutation -import octopus.UpsellTravelAddonActivateMutation.Data.UpsellTravelAddonActivate internal interface SubmitAddonPurchaseUseCase { suspend fun invoke(quoteId: String, addonId: String): Either @@ -27,10 +24,11 @@ internal class SubmitAddonPurchaseUseCaseImpl( raise(ErrorMessage()) }, ifRight = { result -> - if (result.upsellTravelAddonActivate.userError!=null) { + if (result.upsellTravelAddonActivate.userError != null) { raise(ErrorMessage(result.upsellTravelAddonActivate.userError.message)) } - }) + }, + ) } } } diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/di/AddonPurchaseModule.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/di/AddonPurchaseModule.kt index cf768a2272..410f7f3bd1 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/di/AddonPurchaseModule.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/di/AddonPurchaseModule.kt @@ -53,7 +53,7 @@ val addonPurchaseModule = module { single { SubmitAddonPurchaseUseCaseImpl( - apolloClient = get() + apolloClient = get(), ) } } diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/InsuranceDestination.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/InsuranceDestination.kt index 0a795b0e22..d147899728 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/InsuranceDestination.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/InsuranceDestination.kt @@ -472,7 +472,7 @@ private class InsuranceUiStateProvider : CollectionPreviewParameterProvider Date: Fri, 13 Dec 2024 11:22:50 +0100 Subject: [PATCH 6/9] change activation date --- .../addon/purchase/ui/summary/AddonSummaryViewModel.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/ui/summary/AddonSummaryViewModel.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/ui/summary/AddonSummaryViewModel.kt index 7e88df1e24..4106c8a051 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/ui/summary/AddonSummaryViewModel.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/ui/summary/AddonSummaryViewModel.kt @@ -55,9 +55,12 @@ internal class AddonSummaryPresenter( ).fold( ifLeft = { currentState = initialState.copy(navigateToFailure = true) + // todo: not really passing UserError message here. Should we? Or should we maybe redirect to chat in + // the case of final failure? }, ifRight = { date -> - currentState = initialState.copy(activationDateForSuccessfullyPurchasedAddon = date) + currentState = + initialState.copy(activationDateForSuccessfullyPurchasedAddon = summaryParameters.activationDate) }, ) } From dac3e56ba024590301cb7fcd7e4039bc68904ac7 Mon Sep 17 00:00:00 2001 From: mariiapanasetskaia Date: Fri, 13 Dec 2024 11:53:52 +0100 Subject: [PATCH 7/9] fix test --- .../insurances/insurance/presentation/InsurancePresenterTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt b/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt index 2dae10c3e4..df06f700f1 100644 --- a/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt +++ b/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt @@ -33,6 +33,7 @@ import kotlinx.coroutines.test.runTest import kotlinx.datetime.LocalDate import octopus.CrossSellsQuery import octopus.type.CrossSellType +import octopus.type.UpsellTravelAddonFlow import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -543,5 +544,6 @@ internal class InsurancePresenterTest { "desc", listOf(), nonEmptyListOf("id"), + bannerSource = UpsellTravelAddonFlow.APP_ONLY_UPSALE ) } From cafdc2d55b2d4a019d1c01108eb235701ec28c6d Mon Sep 17 00:00:00 2001 From: panasetskaya <90948269+panasetskaya@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:35:46 +0100 Subject: [PATCH 8/9] logcat Co-authored-by: stylianosgakis --- .../addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt index b49c2163d5..2108332c95 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetInsuranceForTravelAddonUseCase.kt @@ -44,7 +44,7 @@ internal class GetInsuranceForTravelAddonUseCaseImpl( } else { val result = memberResponse.bind().currentMember.toInsurancesForAddon(ids) ensure(result.isNotEmpty()) { - { "Tried to get list of insurances for addon purchase but the list is empty!" } + logcat { "Tried to get list of insurances for addon purchase but the list is empty!" } ErrorMessage() } result From cc01727125fa6ce5174991b28d3e4df9e05f1be3 Mon Sep 17 00:00:00 2001 From: mariiapanasetskaia Date: Fri, 13 Dec 2024 14:37:19 +0100 Subject: [PATCH 9/9] indent --- .../data/GetTravelAddonOfferUseCase.kt | 61 +++++++++---------- .../presentation/InsurancePresenterTest.kt | 2 +- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt index d177ff6c40..b35548cdf5 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/data/GetTravelAddonOfferUseCase.kt @@ -35,39 +35,38 @@ internal class GetTravelAddonOfferUseCaseImpl( if (!isAddonFlagOn) { logcat(LogPriority.ERROR) { "Tried to start UpsellAddonOfferMutation but addon feature flag is off" } raise(ErrorMessage()) - } else { - apolloClient.mutation(UpsellAddonOfferMutation(id)).safeExecute().fold( - ifLeft = { error -> - logcat(LogPriority.ERROR) { "Tried to start UpsellAddonOfferMutation but got error: $error" } - // not passing error message to the member here, as we want to redirect member to chat if there is a message + } + apolloClient.mutation(UpsellAddonOfferMutation(id)).safeExecute().fold( + ifLeft = { error -> + logcat(LogPriority.ERROR) { "Tried to start UpsellAddonOfferMutation but got error: $error" } + // not passing error message to the member here, as we want to redirect member to chat if there is a message + raise(ErrorMessage()) + }, + ifRight = { result -> + if (result.upsellTravelAddonOffer.userError != null) { + raise(ErrorMessage(result.upsellTravelAddonOffer.userError.message)) + // the only case where we want to redirect to chat + } + val data = result.upsellTravelAddonOffer.offer + if (data == null) { + logcat(LogPriority.ERROR) { "Tried to do UpsellAddonOfferMutation but got null offer" } + raise(ErrorMessage()) + } + val nonEmptyQuotes = data.quotes.toNonEmptyListOrNull() + if (nonEmptyQuotes.isNullOrEmpty()) { + logcat(LogPriority.ERROR) { "Tried to do UpsellAddonOfferMutation but got empty quotes" } raise(ErrorMessage()) - }, - ifRight = { result -> - if (result.upsellTravelAddonOffer.userError != null) { - raise(ErrorMessage(result.upsellTravelAddonOffer.userError.message)) - // the only case where we want to redirect to chat - } - val data = result.upsellTravelAddonOffer.offer - if (data == null) { - logcat(LogPriority.ERROR) { "Tried to do UpsellAddonOfferMutation but got null offer" } - raise(ErrorMessage()) - } - val nonEmptyQuotes = data.quotes.toNonEmptyListOrNull() - if (nonEmptyQuotes.isNullOrEmpty()) { - logcat(LogPriority.ERROR) { "Tried to do UpsellAddonOfferMutation but got empty quotes" } - raise(ErrorMessage()) - } + } - TravelAddonOffer( - addonOptions = nonEmptyQuotes.toTravelAddonQuotes(), - title = data.titleDisplayName, - description = data.descriptionDisplayName, - activationDate = data.activationDate, - currentTravelAddon = data.currentAddon.toCurrentAddon(), - ) - }, - ) - } + TravelAddonOffer( + addonOptions = nonEmptyQuotes.toTravelAddonQuotes(), + title = data.titleDisplayName, + description = data.descriptionDisplayName, + activationDate = data.activationDate, + currentTravelAddon = data.currentAddon.toCurrentAddon(), + ) + }, + ) } } } diff --git a/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt b/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt index df06f700f1..adea1a0f62 100644 --- a/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt +++ b/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt @@ -544,6 +544,6 @@ internal class InsurancePresenterTest { "desc", listOf(), nonEmptyListOf("id"), - bannerSource = UpsellTravelAddonFlow.APP_ONLY_UPSALE + bannerSource = UpsellTravelAddonFlow.APP_ONLY_UPSALE, ) }