From b9e0e559e95ae706fab97ccb40431bc25b5069ee Mon Sep 17 00:00:00 2001 From: Isa Martin Date: Thu, 15 Aug 2024 13:30:23 -0700 Subject: [PATCH 1/6] - Change reward flow working correctly! --- app/src/main/graphql/fragments.graphql | 5 + .../transformers/GraphQLTransformers.kt | 2 + .../ui/fragments/RewardsFragment.kt | 5 - .../viewmodels/RewardsFragmentViewModel.kt | 17 ++- .../viewmodels/projectpage/AddOnsViewModel.kt | 27 ++-- .../projectpage/RewardsSelectionViewModel.kt | 4 +- .../usecases/GetShippingRulesUseCase.kt | 27 +++- .../RewardsFragmentViewModelTest.kt | 133 +++++++++++------- 8 files changed, 141 insertions(+), 79 deletions(-) diff --git a/app/src/main/graphql/fragments.graphql b/app/src/main/graphql/fragments.graphql index 96a5302e1f..83dc2d17be 100644 --- a/app/src/main/graphql/fragments.graphql +++ b/app/src/main/graphql/fragments.graphql @@ -310,6 +310,11 @@ fragment reward on Reward { startsAt endsAt rewardType + allowedAddons { + nodes { + id + } + } localReceiptLocation { ... location } diff --git a/app/src/main/java/com/kickstarter/services/transformers/GraphQLTransformers.kt b/app/src/main/java/com/kickstarter/services/transformers/GraphQLTransformers.kt index 8d3ad7025e..e10b4d5a2b 100644 --- a/app/src/main/java/com/kickstarter/services/transformers/GraphQLTransformers.kt +++ b/app/src/main/java/com/kickstarter/services/transformers/GraphQLTransformers.kt @@ -13,6 +13,7 @@ import com.kickstarter.features.pledgedprojectsoverview.data.PledgedProjectsOver import com.kickstarter.features.pledgedprojectsoverview.data.PledgedProjectsOverviewQueryData import com.kickstarter.features.pledgedprojectsoverview.ui.PPOCardViewType import com.kickstarter.libs.Permission +import com.kickstarter.libs.utils.extensions.isNotNull import com.kickstarter.libs.utils.extensions.negate import com.kickstarter.mock.factories.RewardFactory import com.kickstarter.models.AiDisclosure @@ -713,6 +714,7 @@ fun backingTransformer(backingGr: fragment.Backing?): Backing { val reward = backingGr?.reward()?.fragments()?.reward()?.let { reward -> return@let rewardTransformer( reward, + allowedAddons = reward.allowedAddons().isNotNull(), rewardItems = complexRewardItemsTransformer(items?.fragments()?.rewardItems()) ) } diff --git a/app/src/main/java/com/kickstarter/ui/fragments/RewardsFragment.kt b/app/src/main/java/com/kickstarter/ui/fragments/RewardsFragment.kt index 6f727d0dba..b8ce816a57 100644 --- a/app/src/main/java/com/kickstarter/ui/fragments/RewardsFragment.kt +++ b/app/src/main/java/com/kickstarter/ui/fragments/RewardsFragment.kt @@ -23,7 +23,6 @@ import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.libs.utils.extensions.reduce import com.kickstarter.libs.utils.extensions.selectPledgeFragment -import com.kickstarter.mock.factories.ShippingRuleFactory import com.kickstarter.ui.activities.compose.projectpage.RewardCarouselScreen import com.kickstarter.ui.compose.designsystem.KSTheme import com.kickstarter.ui.compose.designsystem.KickstarterApp @@ -95,10 +94,6 @@ class RewardsFragment : Fragment() { initialValue = ShippingRulesState() ).value - if (rules.selectedShippingRule != ShippingRuleFactory.emptyShippingRule()) { - viewModel.setInitialShippingRule(rules.selectedShippingRule) - } - val rewards = rules.filteredRw val listState = rememberLazyListState() diff --git a/app/src/main/java/com/kickstarter/viewmodels/RewardsFragmentViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/RewardsFragmentViewModel.kt index 26a61458de..da94e6ed5d 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/RewardsFragmentViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/RewardsFragmentViewModel.kt @@ -32,7 +32,10 @@ import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.PublishSubject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.launch import java.util.Locale class RewardsFragmentViewModel { @@ -259,7 +262,14 @@ class RewardsFragmentViewModel { Dispatchers.IO ) } - shippingRulesUseCase?.invoke() + shippingRulesUseCase?.let { useCaseState -> + useCaseState.invoke() + useCaseState.getScope().launch(useCaseState.getDispatcher()) { + shippingRulesUseCase?.shippingRulesState?.distinctUntilChanged()?.collectLatest { + selectedShippingRule = it.selectedShippingRule + } + } + } return@combineLatest Observable.empty() }.subscribe().addToDisposable(disposables) } @@ -334,11 +344,6 @@ class RewardsFragmentViewModel { override fun selectedShippingRule(shippingRule: ShippingRule) { this.shippingRulesUseCase?.filterBySelectedRule(shippingRule) - this.selectedShippingRule = shippingRule - } - - fun setInitialShippingRule(rule: ShippingRule) { - this.selectedShippingRule = rule } override fun onCleared() { diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/AddOnsViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/AddOnsViewModel.kt index 7b82169f5c..9b87bb565d 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/AddOnsViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/AddOnsViewModel.kt @@ -125,15 +125,22 @@ class AddOnsViewModel(val environment: Environment, bundle: Bundle? = null) : Vi } backing = pledgeData?.projectData()?.backing() ?: project.backing() - backing?.let { b -> - // - backed a reward no reward - if (b.reward() == null && b.amount().isNotNull()) { - currentUserReward = RewardFactory.noReward().toBuilder().pledgeAmount(b.amount()).build() - bonusAmount = b.amount() - } else { - currentUserReward = b.reward() ?: currentUserReward - bonusAmount = b.bonusAmount() - backedAddOns = b.addOns() ?: emptyList() + + if (pReason == PledgeReason.UPDATE_REWARD && backing?.reward()?.id() != currentUserReward.id()) { + // Do nothing, user is selecting a different reward/addOns ... + } else { + // User is selecting a same reward with AddOns, might just adding/deleting addOns, bonus support ... + backing?.let { b -> + // - backed a reward no reward + if (b.reward() == null && b.amount().isNotNull()) { + currentUserReward = + RewardFactory.noReward().toBuilder().pledgeAmount(b.amount()).build() + bonusAmount = b.amount() + } else { + backedAddOns = b.addOns() ?: emptyList() + currentUserReward = b.reward() ?: currentUserReward + bonusAmount = b.bonusAmount() + } } } @@ -171,7 +178,7 @@ class AddOnsViewModel(val environment: Environment, bundle: Bundle? = null) : Vi private fun getAddOns(selectedShippingRule: ShippingRule) { // - Do not execute call unless reward has addOns - if (currentUserReward.hasAddons() || backing?.addOns().isNotNull()) { + if (currentUserReward.hasAddons()) { scope.launch(dispatcher) { apolloClient .getProjectAddOns( diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/RewardsSelectionViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/RewardsSelectionViewModel.kt index 548db120bf..8b93a76a73 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/RewardsSelectionViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/RewardsSelectionViewModel.kt @@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.rx2.asFlow @@ -138,7 +139,7 @@ class RewardsSelectionViewModel(private val environment: Environment, private va private suspend fun emitShippingUIState() { // - collect useCase flow and update shippingUIState - shippingRulesUseCase?.shippingRulesState?.collectLatest { shippingUseCase -> + shippingRulesUseCase?.shippingRulesState?.distinctUntilChanged()?.collectLatest { shippingUseCase -> selectedShippingRule = shippingUseCase.selectedShippingRule mutableShippingUIState.emit(shippingUseCase) } @@ -161,7 +162,6 @@ class RewardsSelectionViewModel(private val environment: Environment, private va fun selectedShippingRule(shippingRule: ShippingRule) { viewModelScope.launch { shippingRulesUseCase?.filterBySelectedRule(shippingRule) - selectedShippingRule = shippingRule emitShippingUIState() } } diff --git a/app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt b/app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt index e2faaebd05..f5532e7881 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt @@ -136,8 +136,12 @@ class GetShippingRulesUseCase( } } + fun getScope() = this.scope + fun getDispatcher() = this.dispatcher + fun filterBySelectedRule(shippingRule: ShippingRule) { scope.launch(dispatcher) { + defaultShippingRule = shippingRule emitCurrentState(isLoading = true) delay(500) // Added delay due to the filtering happening too fast for the user to perceive the loading state filterRewardsByLocation(allAvailableRulesForProject, shippingRule, projectRewards) @@ -208,6 +212,10 @@ class GetShippingRulesUseCase( filteredRewards.add(rw) } + if (RewardUtils.isDigital(rw)) { + filteredRewards.add(rw) + } + // - If shipping is restricted, make sure the reward is able to ship to selected rule if (RewardUtils.shipsToRestrictedLocations(rw)) { if (isIsValidRule != null) { @@ -233,10 +241,23 @@ class GetShippingRulesUseCase( ): ShippingRule = if (project.isBacking()) ShippingRule.builder() .apply { + val backing = project.backing() val locationId = project.backing()?.locationId() ?: 0L - val locationName = project.backing()?.locationName() ?: "" - - this.location(Location.Builder().id(locationId).name(locationName).displayableName(locationName).build()) + this.id(locationId) + val reward = backing?.reward()?.let { + if (RewardUtils.shipsToRestrictedLocations(it)) { + val rule = backing?.reward()?.shippingRules() + ?.first { it.location()?.id() == locationId } + this.location(rule?.location()) + this.id(rule?.id()) + this.cost(rule?.cost() ?: 0.0) + } + if (RewardUtils.shipsWorldwide(it)) { + val locationName = project.backing()?.locationName() ?: "" + this.location(Location.Builder().id(locationId).name(locationName).displayableName(locationName).build()) + this.cost(it.shippingRules()?.first()?.cost() ?: 0.0) + } + } } .build() else config?.getDefaultLocationFrom(shippingRules.values.toList()) ?: ShippingRule.builder() diff --git a/app/src/test/java/com/kickstarter/viewmodels/RewardsFragmentViewModelTest.kt b/app/src/test/java/com/kickstarter/viewmodels/RewardsFragmentViewModelTest.kt index d9d7241ca9..013a24a45b 100644 --- a/app/src/test/java/com/kickstarter/viewmodels/RewardsFragmentViewModelTest.kt +++ b/app/src/test/java/com/kickstarter/viewmodels/RewardsFragmentViewModelTest.kt @@ -210,16 +210,12 @@ class RewardsFragmentViewModelTest : KSRobolectricTestCase() { this.vm.inputs.rewardClicked(reward) this.showPledgeFragment.assertNoValues() - this.showAddOnsFragment.assertValue( - Pair( - PledgeData.builder() - .pledgeFlowContext(PledgeFlowContext.CHANGE_REWARD) - .reward(reward) - .projectData(ProjectDataFactory.project(backedProject)) - .build(), - PledgeReason.UPDATE_REWARD - ) - ) + this.vm.outputs.showAddOnsFragment().subscribe { + assertEquals(it.first.reward(), reward) + assertEquals(it.first.projectData(), ProjectDataFactory.project(backedProject)) + assertEquals(it.second, PledgeReason.UPDATE_REWARD) + }.addToDisposable(disposables) + this.showAlert.assertNoValues() } @@ -270,27 +266,6 @@ class RewardsFragmentViewModelTest : KSRobolectricTestCase() { this.showPledgeFragment.assertNoValues() } - @Test - fun testShowPledgeFragment_whenManagingPledge() { - val project = ProjectFactory.backedProject() - setUpEnvironment(environment()) - - this.vm.inputs.configureWith(ProjectDataFactory.project(project)) - - val reward = RewardFactory.reward() - this.vm.inputs.rewardClicked(reward) - this.showPledgeFragment.assertValue( - Pair( - PledgeData.builder() - .pledgeFlowContext(PledgeFlowContext.CHANGE_REWARD) - .reward(reward) - .projectData(ProjectDataFactory.project(project)) - .build(), - PledgeReason.UPDATE_REWARD - ) - ) - } - @Test fun testFilterOutRewards_whenRewardNotStarted_filtersOutReward() { val rwNotLimitedStart = RewardFactory.reward() @@ -399,6 +374,70 @@ class RewardsFragmentViewModelTest : KSRobolectricTestCase() { ) // completed requests } + @Test + fun `test call vm-selectedShippingRule() with location US, pledgeData-shipping should be US `() = runTest { + + val unlimitedReward = RewardFactory.rewardWithShipping() + + val rewards = listOf( + unlimitedReward + ) + val project = ProjectFactory.project().toBuilder().rewards(rewards).build() + + val config = ConfigFactory.configForCA() + val currentConfig = MockCurrentConfigV2() + currentConfig.config(config) + + val testShippingRulesList = ShippingRulesEnvelopeFactory.shippingRules() + val apolloClient = object : MockApolloClientV2() { + override fun getShippingRules(reward: Reward): Observable { + return Observable.just(testShippingRulesList) + } + } + + val user = UserFactory.user() + val env = environment() + .toBuilder() + .currentUserV2(MockCurrentUserV2(user)) + .apolloClientV2(apolloClient) + .currentConfig2(currentConfig) + .build() + + val state = mutableListOf() + val dispatcher = UnconfinedTestDispatcher(testScheduler) + backgroundScope.launch(dispatcher) { + val useCase = GetShippingRulesUseCase(apolloClient, project, config, this, dispatcher) + setUpEnvironment(env, useCase) + + vm.inputs.configureWith(ProjectDataFactory.project(project)) + vm.countrySelectorRules().toList(state) + } + + advanceUntilIdle() // wait until all state emissions completed + + assertEquals(state.size, 3) + assertEquals(state[0], ShippingRulesState()) // Initialization + assertEquals(state[1], ShippingRulesState(loading = true)) // starts loading + assertEquals( + state[2], + ShippingRulesState( + loading = false, + selectedShippingRule = ShippingRuleFactory.canadaShippingRule(), + shippingRules = testShippingRulesList.shippingRules() + ) + ) // completed requests + + val usShippingRule = testShippingRulesList.shippingRules().first() + backgroundScope.launch(dispatcher) { + vm.inputs.configureWith(ProjectDataFactory.project(project)) + vm.inputs.selectedShippingRule(usShippingRule) + } + + vm.showAddOnsFragment().subscribe { + assertEquals(it.first.shippingRule()?.location(), usShippingRule.location()) + }.addToDisposable(disposables) + } + @Test fun `test DefaultShipping Rule is sent to PledgeFragment`() { val project = ProjectFactory.backedProject() @@ -410,17 +449,12 @@ class RewardsFragmentViewModelTest : KSRobolectricTestCase() { vm.inputs.selectedShippingRule(selectedShippingRule) vm.inputs.rewardClicked(reward) - showPledgeFragment.assertValue( - Pair( - PledgeData.builder() - .pledgeFlowContext(PledgeFlowContext.CHANGE_REWARD) - .reward(reward) - .projectData(ProjectDataFactory.project(project)) - .shippingRule(selectedShippingRule) - .build(), - PledgeReason.UPDATE_REWARD - ) - ) + vm.outputs.showPledgeFragment().subscribe { + assertEquals(it.second, PledgeFlowContext.CHANGE_REWARD) + assertEquals(it.first.reward(), reward) + assertEquals(it.first.projectData(), ProjectDataFactory.project(project)) + assertEquals(it.first.shippingRule(), selectedShippingRule) + }.addToDisposable(disposables) this.showAddOnsFragment.assertNoValues() } @@ -447,17 +481,10 @@ class RewardsFragmentViewModelTest : KSRobolectricTestCase() { this.vm.inputs.rewardClicked(reward) this.showPledgeFragment.assertNoValues() - this.showAddOnsFragment.assertValue( - Pair( - PledgeData.builder() - .pledgeFlowContext(PledgeFlowContext.CHANGE_REWARD) - .reward(reward) - .projectData(ProjectDataFactory.project(backedProject)) - .shippingRule(selectedShippingRule) - .build(), - PledgeReason.UPDATE_REWARD - ) - ) + this.vm.showAddOnsFragment().subscribe { + assertEquals(it.first.shippingRule(), selectedShippingRule) + assertEquals(it.first.reward(), reward) + }.addToDisposable(disposables) this.showAlert.assertNoValues() } } From 2b796a8fd079c4e2927e814254b2ed90be5b0969 Mon Sep 17 00:00:00 2001 From: Isa Martin Date: Thu, 15 Aug 2024 13:56:57 -0700 Subject: [PATCH 2/6] clean-up --- .../com/kickstarter/viewmodels/RewardsFragmentViewModel.kt | 2 +- .../viewmodels/projectpage/RewardsSelectionViewModel.kt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/kickstarter/viewmodels/RewardsFragmentViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/RewardsFragmentViewModel.kt index da94e6ed5d..d351752669 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/RewardsFragmentViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/RewardsFragmentViewModel.kt @@ -265,7 +265,7 @@ class RewardsFragmentViewModel { shippingRulesUseCase?.let { useCaseState -> useCaseState.invoke() useCaseState.getScope().launch(useCaseState.getDispatcher()) { - shippingRulesUseCase?.shippingRulesState?.distinctUntilChanged()?.collectLatest { + shippingRulesUseCase?.shippingRulesState?.collectLatest { selectedShippingRule = it.selectedShippingRule } } diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/RewardsSelectionViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/RewardsSelectionViewModel.kt index 8b93a76a73..11856b7735 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/RewardsSelectionViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/RewardsSelectionViewModel.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.rx2.asFlow @@ -139,7 +138,7 @@ class RewardsSelectionViewModel(private val environment: Environment, private va private suspend fun emitShippingUIState() { // - collect useCase flow and update shippingUIState - shippingRulesUseCase?.shippingRulesState?.distinctUntilChanged()?.collectLatest { shippingUseCase -> + shippingRulesUseCase?.shippingRulesState?.collectLatest { shippingUseCase -> selectedShippingRule = shippingUseCase.selectedShippingRule mutableShippingUIState.emit(shippingUseCase) } From d6d6ba40446ba4c24f63a552a91b4f99331d13d4 Mon Sep 17 00:00:00 2001 From: Isa Martin Date: Thu, 15 Aug 2024 15:34:50 -0700 Subject: [PATCH 3/6] - Adapting for noReward in crowdfund flows --- .../compose/projectpage/CheckoutScreen.kt | 4 +- .../compose/checkout/PledgeItemizedDetails.kt | 21 +++++++++ .../projectpage/CrowdfundCheckoutViewModel.kt | 47 ++++++++++++------- 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt index 1fc1fe1c25..635b7684a4 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt @@ -50,6 +50,7 @@ import com.kickstarter.R import com.kickstarter.libs.Environment import com.kickstarter.libs.KSString import com.kickstarter.libs.utils.DateTimeUtils +import com.kickstarter.libs.utils.RewardUtils import com.kickstarter.libs.utils.RewardViewUtils import com.kickstarter.libs.utils.extensions.acceptedCardType import com.kickstarter.libs.utils.extensions.hrefUrlFromTranslation @@ -457,7 +458,8 @@ fun CheckoutScreen( Spacer(modifier = Modifier.height(dimensions.paddingMediumSmall)) - if (rewardsList.isNotEmpty()) { + val isNoReward = selectedReward?.let { RewardUtils.isNoReward(it) } ?: false + if (!isNoReward) { ItemizedRewardListContainer( ksString = ksString, rewardsList = rewardsList, diff --git a/app/src/main/java/com/kickstarter/ui/views/compose/checkout/PledgeItemizedDetails.kt b/app/src/main/java/com/kickstarter/ui/views/compose/checkout/PledgeItemizedDetails.kt index f89f8c6c8c..26b733d7ec 100644 --- a/app/src/main/java/com/kickstarter/ui/views/compose/checkout/PledgeItemizedDetails.kt +++ b/app/src/main/java/com/kickstarter/ui/views/compose/checkout/PledgeItemizedDetails.kt @@ -23,6 +23,27 @@ import com.kickstarter.ui.compose.designsystem.KSTheme.colors import com.kickstarter.ui.compose.designsystem.KSTheme.dimensions import com.kickstarter.ui.compose.designsystem.KSTheme.typography + +@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun ItemizedContainerForNoRewardPreview() { + KSTheme { + Scaffold( + backgroundColor = KSTheme.colors.backgroundAccentGraySubtle + ) { padding -> + ItemizedRewardListContainer( + modifier = Modifier.padding(paddingValues = padding), + totalAmount = "US$ 1", + totalAmountCurrencyConverted = "About CA$ 1.38", + initialBonusSupport = "US$ 0", + totalBonusSupport = "US$ 1", + shippingAmount = -1.0, + ) + } + } +} + @Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt index 0d2a5d12db..e2bdd6b076 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt @@ -207,6 +207,11 @@ class CrowdfundCheckoutViewModel(val environment: Environment, bundle: Bundle? = bonusAmount = (backing.bonusAmount() ?: 0.0).toDouble() totalAmount = (backing.amount() ?: 0.0).toDouble() + // - User was backing reward no reward + if (backing.reward() == null) { + bonusAmount = 0.0 + } + checkoutData = CheckoutData.builder() .amount(totalAmount) .paymentType(CreditCardPaymentType.CREDIT_CARD) @@ -217,24 +222,34 @@ class CrowdfundCheckoutViewModel(val environment: Environment, bundle: Bundle? = private fun getPledgeInfoFrom(pData: PledgeData) { selectedRewards = pData.rewardsAndAddOnsList() - pledgeData = pData - refTag = RefTagUtils.storedCookieRefTagForProject( - project, - cookieManager, - sharedPreferences - ) + if (selectedRewards.isNotEmpty()) { + val isNoReward = RewardUtils.isNoReward(selectedRewards.first()) + pledgeData = pData + refTag = RefTagUtils.storedCookieRefTagForProject( + project, + cookieManager, + sharedPreferences + ) - shippingRule = pData.shippingRule() - shippingAmount = pData.shippingCostIfShipping() - bonusAmount = pData.bonusAmount() - totalAmount = pData.checkoutTotalAmount() + if (!isNoReward) { + shippingRule = pData.shippingRule() + shippingAmount = pData.shippingCostIfShipping() + bonusAmount = pData.bonusAmount() + totalAmount = pData.checkoutTotalAmount() + } - checkoutData = CheckoutData.builder() - .amount(pData.pledgeAmountTotal()) - .paymentType(CreditCardPaymentType.CREDIT_CARD) - .bonusAmount(bonusAmount) - .shippingAmount(pData.shippingCostIfShipping()) - .build() + if (isNoReward) { + totalAmount = selectedRewards.first().minimum() + bonusAmount = 0.0 + } + + checkoutData = CheckoutData.builder() + .amount(pData.pledgeAmountTotal()) + .paymentType(CreditCardPaymentType.CREDIT_CARD) + .bonusAmount(bonusAmount) + .shippingAmount(pData.shippingCostIfShipping()) + .build() + } } fun provideErrorAction(errorAction: (message: String?) -> Unit) { From 593915f015de12f080e372f79ce2d3e410fe3169 Mon Sep 17 00:00:00 2001 From: Isa Martin Date: Thu, 15 Aug 2024 15:54:56 -0700 Subject: [PATCH 4/6] - Reward No reward --- .../ui/activities/compose/projectpage/CheckoutScreen.kt | 3 ++- .../ui/activities/compose/projectpage/RewardCarouselScreen.kt | 2 +- .../viewmodels/projectpage/CrowdfundCheckoutViewModel.kt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt index 635b7684a4..b8bd210599 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt @@ -474,11 +474,12 @@ fun CheckoutScreen( rewardsHaveShippables = rewardsHaveShippables ) } else { + // - For noReward, totalAmount = bonusAmount as there is no reward ItemizedRewardListContainer( totalAmount = totalAmountString, totalAmountCurrencyConverted = aboutTotalString, initialBonusSupport = initialBonusSupportString, - totalBonusSupport = totalBonusSupportString, + totalBonusSupport = totalAmountString, shippingAmount = shippingAmount, ) } diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt index 5ed9509476..4199f43421 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt @@ -188,7 +188,7 @@ fun RewardCarouselScreen( ) { reward -> val ctaButtonEnabled = when { - RewardUtils.isNoReward(reward) && (project.postCampaignPledgingEnabled() ?: false && project.isInPostCampaignPledgingPhase() ?: false) -> true + RewardUtils.isNoReward(reward) -> true !reward.hasAddons() && backing?.isBacked(reward) != true -> true backing?.rewardId() != reward.id() && RewardUtils.isAvailable( project, diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt index e2bdd6b076..b7b9502b5d 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt @@ -239,7 +239,7 @@ class CrowdfundCheckoutViewModel(val environment: Environment, bundle: Bundle? = } if (isNoReward) { - totalAmount = selectedRewards.first().minimum() + totalAmount = selectedRewards.first().minimum() + bonusAmount bonusAmount = 0.0 } From c72c4ef03e0672a51ecdde62a6df838d4342f55d Mon Sep 17 00:00:00 2001 From: Isa Martin Date: Thu, 15 Aug 2024 16:48:35 -0700 Subject: [PATCH 5/6] - Reward no reward ok --- .../views/compose/checkout/PledgeItemizedDetails.kt | 1 - .../projectpage/CrowdfundCheckoutViewModel.kt | 11 ++++++++--- .../projectpage/LatePledgeCheckoutViewModel.kt | 7 ++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/kickstarter/ui/views/compose/checkout/PledgeItemizedDetails.kt b/app/src/main/java/com/kickstarter/ui/views/compose/checkout/PledgeItemizedDetails.kt index 26b733d7ec..5f6740b10a 100644 --- a/app/src/main/java/com/kickstarter/ui/views/compose/checkout/PledgeItemizedDetails.kt +++ b/app/src/main/java/com/kickstarter/ui/views/compose/checkout/PledgeItemizedDetails.kt @@ -23,7 +23,6 @@ import com.kickstarter.ui.compose.designsystem.KSTheme.colors import com.kickstarter.ui.compose.designsystem.KSTheme.dimensions import com.kickstarter.ui.compose.designsystem.KSTheme.typography - @Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt index b7b9502b5d..61838544a9 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/CrowdfundCheckoutViewModel.kt @@ -230,16 +230,16 @@ class CrowdfundCheckoutViewModel(val environment: Environment, bundle: Bundle? = cookieManager, sharedPreferences ) + shippingRule = pData.shippingRule() if (!isNoReward) { - shippingRule = pData.shippingRule() shippingAmount = pData.shippingCostIfShipping() bonusAmount = pData.bonusAmount() totalAmount = pData.checkoutTotalAmount() } if (isNoReward) { - totalAmount = selectedRewards.first().minimum() + bonusAmount + totalAmount = selectedRewards.first().pledgeAmount() + pData.bonusAmount() bonusAmount = 0.0 } @@ -372,10 +372,15 @@ class CrowdfundCheckoutViewModel(val environment: Environment, bundle: Bundle? = analytics.trackPledgeSubmitCTA(requireNotNull(checkoutData), requireNotNull(pledgeData)) } + val shouldNotSendId = pledgeData?.reward()?.let { + RewardUtils.isDigital(it) || RewardUtils.isNoReward(it) || RewardUtils.isLocalPickup(it) + } ?: true + + val locationID = pledgeData?.shippingRule()?.location()?.id()?.toString() val backingData = selectedPaymentMethod.getBackingData( proj = project, amount = pledgeData?.checkoutTotalAmount().toString(), - locationId = pledgeData?.shippingRule()?.location()?.id()?.toString(), + locationId = if (shouldNotSendId) null else locationID, rewards = RewardUtils.extendAddOns(pledgeData?.rewardsAndAddOnsList() ?: emptyList()), cookieRefTag = refTag ) diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/LatePledgeCheckoutViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/LatePledgeCheckoutViewModel.kt index 53b1f5fd8d..0409c72986 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/LatePledgeCheckoutViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/LatePledgeCheckoutViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.kickstarter.libs.Environment +import com.kickstarter.libs.utils.RewardUtils import com.kickstarter.libs.utils.extensions.checkoutTotalAmount import com.kickstarter.libs.utils.extensions.isNotNull import com.kickstarter.libs.utils.extensions.locationId @@ -417,8 +418,8 @@ class LatePledgeCheckoutViewModel(val environment: Environment) : ViewModel() { private fun createCheckout() { this.pledgeData?.let { pData -> - val locationId = pData.locationId() - val rewards = pData.rewardsAndAddOnsList() + val locationId = if (!RewardUtils.isNoReward(pData.reward())) pData.locationId() else null + val rewards = if (!RewardUtils.isNoReward(pData.reward())) pData.rewardsAndAddOnsList() else emptyList() val totalPledge = pData.checkoutTotalAmount() this.pledgeData?.projectData()?.let { projectData -> @@ -431,7 +432,7 @@ class LatePledgeCheckoutViewModel(val environment: Environment) : ViewModel() { CreateCheckoutData( project = projectData.project(), amount = totalPledge.toString(), - locationId = locationId.toString(), + locationId = locationId?.toString(), rewardsIds = rewards, refTag = projectData.refTagFromIntent() ) From 5bfd285e468c62e1163e1a1bd38490ff85539aed Mon Sep 17 00:00:00 2001 From: Isa Martin Date: Thu, 15 Aug 2024 17:12:57 -0700 Subject: [PATCH 6/6] no message (cherry picked from commit b63ae18f8b77a528a7337e2c60a35acc013fc3b9) --- .../viewmodels/usecases/GetShippingRulesUseCase.kt | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt b/app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt index f5532e7881..bf237e0ded 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCase.kt @@ -93,14 +93,6 @@ class GetShippingRulesUseCase( val avShipMap = allAvailableRulesForProject emitCurrentState(isLoading = true) - // - If project backing default shipping Rule is backed shipping rule - if (project.isBacking() && project?.backing()?.locationId().isNotNull()) { - defaultShippingRule = getDefaultShippingRule( - avShipMap, - project - ) - } - if (rewardsByShippingType.isNotEmpty()) { rewardsByShippingType.forEachIndexed { index, reward -> @@ -239,7 +231,7 @@ class GetShippingRulesUseCase( shippingRules: MutableMap, project: Project ): ShippingRule = - if (project.isBacking()) ShippingRule.builder() + if (project.isBacking() && project.backing()?.location().isNotNull()) ShippingRule.builder() .apply { val backing = project.backing() val locationId = project.backing()?.locationId() ?: 0L