Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
push:
branches:
- develop
- eng/metro-nav3-pr2-nav2-to-nav3
- feat/xsell-addon-rec
workflow_dispatch:

concurrency:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ fragment ClaimFragment on Claim {
displayTitle
displayValue
}
contractId
}
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,22 @@ type AgreementDisplayItem {
displaySubtitle: String
displayValue: String!
}
input AnswersInput {
relationship: String
isPregnant: Boolean
hasKids: Boolean
hasCat: Boolean
hasDog: Boolean
yourAge: String
partnerAge: String
isStudent: Boolean
housingType: String
houseAge: String
isRental: Boolean
hasCar: Boolean
carAge: String
wantsAllRisk: Boolean
}
enum AppPlatform {
IOS
ANDROID
Expand Down Expand Up @@ -872,6 +888,7 @@ type Claim {
isUploadingFilesEnabled: Boolean!
infoText: String
displayItems: [ClaimDisplayItem!]!
contractId: String
"""
Terms & conditions for the claim found using claims contractId and dateOfOccurrence, otherwise null.
"""
Expand Down Expand Up @@ -1003,7 +1020,7 @@ type ClaimIntentStep {
"""
A union of all the different kinds of "step content".
"""
union ClaimIntentStepContent = ClaimIntentStepContentForm|ClaimIntentStepContentSelect|ClaimIntentStepContentTask|ClaimIntentStepContentAudioRecording|ClaimIntentStepContentFileUpload|ClaimIntentStepContentSummary|ClaimIntentStepContentDeflection|ClaimIntentStepContentDeflectionMessage
union ClaimIntentStepContent = ClaimIntentStepContentForm|ClaimIntentStepContentSelect|ClaimIntentStepContentTask|ClaimIntentStepContentAudioRecording|ClaimIntentStepContentFileUpload|ClaimIntentStepContentSummary|ClaimIntentStepContentDeflection|ClaimIntentStepContentDeflectionMessage|ClaimIntentStepContentInformation
"""
An audio recording step is one where the user is meant to record some audio.
Submitted using `Mutation.claimIntentSubmitAudio`.
Expand Down Expand Up @@ -1181,6 +1198,22 @@ This typically will be backed by a String - but other formats could appear.
"""
scalar ClaimIntentStepContentFormFieldValue
"""
A read and acknowledge notice if the member needs to be shown some urgent information (if water is still leaking -> turn off the pipe). Not terminal
Submitted using `Mutation.claimIntentSubmitInformation`.
"""
type ClaimIntentStepContentInformation {
notice: String!
"""
So we can show a white/red border if info/critical respectively.
"""
severity: ClaimIntentStepContentInformationSeverity!
buttonTitle: String!
}
enum ClaimIntentStepContentInformationSeverity {
INFO
CRITICAL
}
"""
A select step is one that contains a choice to select one of several alternatives.
It can be seen as a special-case form with nicer rendering.
Submitted using `Mutation.claimIntentSubmitSelect`.
Expand Down Expand Up @@ -1268,6 +1301,9 @@ input ClaimIntentSubmitFormInput {
stepId: ID!
fields: [ClaimIntentFormSubmitInputField!]!
}
input ClaimIntentSubmitInformationInput {
stepId: ID!
}
input ClaimIntentSubmitSelectInput {
stepId: ID!
selectedId: ID!
Expand Down Expand Up @@ -1662,6 +1698,10 @@ input CrossSellInput {
A/B test experiments for attribution tracking
"""
experiments: [CrossSellExperimentInput!]!
"""
The contract that was changed in the flow. When set, enables addon recommendations for that contract.
"""
contractId: ID
}
enum CrossSellSource {
HOME
Expand All @@ -1677,6 +1717,10 @@ type CrossSellV2 {
"""
recommendedCrossSell: RecommendedCrossSell
"""
Addon recommendation for the contract in input.contractId (null when not applicable)
"""
recommendedAddon: RecommendedAddonCrossSell
"""
Other available cross-sells (behavior varies by userFlow)
"""
otherCrossSells: [CrossSell!]!
Expand Down Expand Up @@ -2433,6 +2477,28 @@ type InsuranceEvidenceOutput {
insuranceEvidenceInformation: InsuranceEvidenceInformation
userError: UserError
}
input InsuranceGuideInput {
"""
Email of the user.
"""
email: String
"""
Id of the insurance guide shopSession.
"""
shopSessionId: UUID!
"""
Insurance recommendation form answers.
"""
answers: AnswersInput!
"""
Insurance recommendations.
"""
recommendations: [RecommendationInput!]!
}
type InsuranceGuideOutput {
success: Boolean!
userError: UserError
}
input InsurelyInitiateIframeDataCollectionInput {
collectionId: String!
partner: String
Expand Down Expand Up @@ -3449,6 +3515,10 @@ type MoveIntentMutationOutput {
Fail case
"""
userError: UserError
"""
Id of the new contract if it was created after finalizing the move
"""
newContractId: ID
}
type MoveIntentQuoteCost {
quoteId: ID!
Expand Down Expand Up @@ -3655,6 +3725,10 @@ type Mutation {
"""
claimIntentSubmitTask(input: ClaimIntentSubmitTaskInput!): ClaimIntentMutationOutput!
"""
Acknowledge a step containing a `ClaimIntentStepContentInformation`, continuing the flow.
"""
claimIntentSubmitInformation(input: ClaimIntentSubmitInformationInput!): ClaimIntentMutationOutput!
"""
Submit a step containing a `ClaimIntentStepContentSummary`.
"""
claimIntentSubmitSummary(input: ClaimIntentSubmitSummaryInput!): ClaimIntentMutationOutput!
Expand Down Expand Up @@ -3729,6 +3803,10 @@ type Mutation {
"""
productOffersCancellationRequestedUpdate(productOfferIds: [UUID!]!, requested: Boolean!): ProductOffersMutationOutput!
"""
Called to save insurance recommendation form and save recommendation email.
"""
insuranceGuide(input: InsuranceGuideInput!): InsuranceGuideOutput!
"""
Create a `PriceIntent`.
The `input.productName` has to be the name of a product among the ones listed at `Query.availableProducts`. The
choice of product also affects which data will be needed for the intent to be confirmed and to produce offers.
Expand Down Expand Up @@ -4305,6 +4383,10 @@ type ProductOffer {
"""
priceIntentId: UUID
"""
Link to the price calculator for this offer (resumes the shop session).
"""
priceCalculatorLink: String
"""
UI-safe masked form data used to generate the offer. PII fields (street, zipCode, city) are masked when address came from registration address lookup.
"""
priceIntentData: PricingFormData!
Expand Down Expand Up @@ -4706,6 +4788,28 @@ type RecommendationExternalInsurance {
"""
dataCollectionId: String!
}
input RecommendationInput {
productId: String!
name: String!
tier: String
productPageUrl: String!
priceCalculatorUrl: String!
}
"""
A recommendation to add an addon to an existing contract. The button opens the addon flow via an app deep link.
"""
type RecommendedAddonCrossSell {
id: ID!
title: String!
description: String!
buttonTitle: String!
"""
App deep link to the addon flow for this contract
"""
deepLink: String!
pillowImageSmall: StoryblokImageAsset!
pillowImageLarge: StoryblokImageAsset!
}
type RecommendedCrossSell {
crossSell: CrossSell!
bannerText: String!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ interface ChangeTierRepository {

suspend fun addQuotesToStorage(quotes: List<TierDeductibleQuote>)

suspend fun submitChangeTierQuote(quoteId: String): Either<ErrorMessage, Unit>
suspend fun submitChangeTierQuote(quoteId: String, insuranceId: String,): Either<ErrorMessage, Unit>

suspend fun getCurrentQuoteId(): String
}
Expand Down Expand Up @@ -74,7 +74,7 @@ internal class ChangeTierRepositoryImpl(
changeTierQuoteStorage.insertAll(quotes)
}

override suspend fun submitChangeTierQuote(quoteId: String): Either<ErrorMessage, Unit> {
override suspend fun submitChangeTierQuote(quoteId: String, insuranceId: String,): Either<ErrorMessage, Unit> {
return either {
apolloClient
.mutation(ChangeTierDeductibleCommitIntentMutation(quoteId))
Expand All @@ -84,7 +84,8 @@ internal class ChangeTierRepositoryImpl(
logcat(ERROR) { "Tried to submit change tier quoteId: $quoteId but got error: $left" }
}
.bind()
crossSellAfterFlowRepository.completedCrossSellTriggeringSelfServiceSuccessfully(CrossSellInfoType.ChangeTier)
crossSellAfterFlowRepository.completedCrossSellTriggeringSelfServiceSuccessfully(
CrossSellInfoType.ChangeTier(insuranceId),)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class ChangeTierRepositoryImplTest {
val testApolloClientRule = TestApolloClientRule(TestNetworkTransportType.MAP)

private val testId = "testId"
private val testInsuranceId = "testInsuranceId"

private val apolloClientWithBadResponseToSubmit: ApolloClient
get() = testApolloClientRule.apolloClient.apply {
Expand Down Expand Up @@ -74,7 +75,7 @@ class ChangeTierRepositoryImplTest {
crossSellAfterFlowRepository = CrossSellAfterFlowRepositoryImpl(),
changeTierQuoteStorage = storage,
)
val result = repository.submitChangeTierQuote(testId)
val result = repository.submitChangeTierQuote(testId, testInsuranceId)
assertThat(result)
.isLeft()
}
Expand All @@ -98,10 +99,10 @@ class ChangeTierRepositoryImplTest {
}
},
)
val result = repository.submitChangeTierQuote(testId)
val result = repository.submitChangeTierQuote(testId, testInsuranceId)
assertThat(result).isRight().isEqualTo(Unit)
assertThat(crossSellAfterFlowRepository.shouldShowCrossSellSheetWithInfo().first())
.isEqualTo(CrossSellInfoType.ChangeTier)
.isEqualTo(CrossSellInfoType.ChangeTier(testInsuranceId))
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ internal class CrossSellAfterClaimClosedRepositoryImpl(
status = claim.status?.name,
type = claim.claimType,
typeOfContract = claim.productVariant?.typeOfContract,

),
contractId = claim.contractId
),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ interface CrossSellAfterFlowRepository {

sealed class CrossSellInfoType() {
abstract val source: String

abstract val contractId: String?
protected abstract val extraInfo: Map<String, Any?>?
val attributes: Map<String, Any?>
get() = buildMap {
Expand All @@ -31,6 +33,7 @@ sealed class CrossSellInfoType() {

data class ClosedClaim(
val info: ClaimInfo,
override val contractId: String?
) : CrossSellInfoType() {
override val source: String = "closedClaim"
override val extraInfo: Map<String, Any?> = with(info) {
Expand All @@ -52,22 +55,28 @@ sealed class CrossSellInfoType() {
)
}

data object ChangeTier : CrossSellInfoType() {
data class ChangeTier(
override val contractId: String?
) : CrossSellInfoType() {
override val source: String = "changeTier"
override val extraInfo: Map<String, Any?>? = null
}

data object Addon : CrossSellInfoType() {
override val source: String = "addon"
override val extraInfo: Map<String, Any?>? = null
override val contractId: String? = null
}

data object EditCoInsured : CrossSellInfoType() {
override val source: String = "editCoInsured"
override val extraInfo: Map<String, Any?>? = null
override val contractId: String? = null
}

data object MovingFlow : CrossSellInfoType() {
data class MovingFlow(
override val contractId: String?
) : CrossSellInfoType() {
override val source: String = "movingFlow"
override val extraInfo: Map<String, Any?>? = null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private class SummaryPresenter(
if (submitIteration > 0) {
val previousState = currentState
currentState = MakingChanges
tierRepository.submitChangeTierQuote(params.quoteIdToSubmit).fold(
tierRepository.submitChangeTierQuote(params.quoteIdToSubmit, params.insuranceId).fold(
ifLeft = {
currentState = previousState
backstack.add(SubmitFailureKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal class FakeChangeTierRepository() : ChangeTierRepository {
override suspend fun addQuotesToStorage(quotes: List<TierDeductibleQuote>) {
}

override suspend fun submitChangeTierQuote(quoteId: String): Either<ErrorMessage, Unit> {
override suspend fun submitChangeTierQuote(quoteId: String, insuranceId: String): Either<ErrorMessage, Unit> {
return either {}
}

Expand Down
2 changes: 2 additions & 0 deletions app/feature/feature-cross-sell-sheet/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ hedvig {

dependencies {
implementation(libs.apollo.runtime)
implementation(libs.apollo.normalizedCache)
implementation(libs.arrow.core)
implementation(libs.arrow.fx)
implementation(projects.apolloCore)
Expand All @@ -23,4 +24,5 @@ dependencies {
implementation(projects.dataCrossSellAfterFlow)
implementation(projects.designSystemHedvig)
implementation(projects.moleculePublic)

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
query BottomSheetCrossSells($input: CrossSellInput!) {
currentMember {
crossSellV2(input: $input) {
recommendedAddon {
id
title
description
buttonTitle
deepLink
pillowImageLarge {
src
}
pillowImageSmall {
src
}
}
recommendedCrossSell {
crossSell {
...CrossSellFragment
Expand Down
Loading
Loading