Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POS] Simultaneous cash and card payment handling #13277

Merged
merged 15 commits into from
Jan 15, 2025
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ sealed class ChildToParentEvent {
sealed class NavigationEvent : ChildToParentEvent() {
data class ToCashPayment(val orderId: Long) : NavigationEvent()
data class ToEmailReceipt(val orderId: Long) : NavigationEvent()
data object ReturnHomeFromCashWhenCardPaymentStarted : NavigationEvent()
data object ExitPos : NavigationEvent()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent
import com.woocommerce.android.ui.woopos.root.navigation.navigateOnce

const val HOME_ROUTE = "home"
Expand All @@ -30,8 +29,17 @@ fun NavController.navigateToHomeScreenAfterSuccessfulCashPayment() {
}
}

fun NavController.navigateToHomeScreenIfHomeScreenNotOpen() {
kidinov marked this conversation as resolved.
Show resolved Hide resolved
if (currentDestination?.route != HOME_ROUTE) {
popBackStack(
HOME_ROUTE,
false
)
}
}

fun NavGraphBuilder.homeScreen(
onNavigationEvent: (WooPosNavigationEvent) -> Unit
homeViewModel: WooPosHomeViewModel,
) {
composable(
route = HOME_ROUTE,
Expand Down Expand Up @@ -70,7 +78,7 @@ fun NavGraphBuilder.homeScreen(

WooPosHomeScreen(
isPaymentCompletedViaCash = isPaymentCompletedViaCash,
onNavigationEvent = onNavigationEvent,
viewModel = homeViewModel,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
import com.woocommerce.android.ui.woopos.common.composeui.WooPosTheme
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosExitConfirmationDialog
import com.woocommerce.android.ui.woopos.common.composeui.isPreviewMode
import com.woocommerce.android.ui.woopos.common.composeui.toAdaptivePadding
import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NavigationEvent
import com.woocommerce.android.ui.woopos.home.WooPosHomeState.ProductsInfoDialog
import com.woocommerce.android.ui.woopos.home.cart.WooPosCartScreen
import com.woocommerce.android.ui.woopos.home.cart.WooPosCartScreenProductsPreview
Expand All @@ -42,18 +40,13 @@ import com.woocommerce.android.ui.woopos.home.toolbar.PreviewWooPosFloatingToolb
import com.woocommerce.android.ui.woopos.home.toolbar.WooPosFloatingToolbar
import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsScreen
import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsScreenPreview
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent.ExitPosClicked
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent.OpenCashPayment
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent.OpenEmailReceipt
import org.wordpress.android.util.ToastUtils

@Composable
fun WooPosHomeScreen(
isPaymentCompletedViaCash: Boolean,
onNavigationEvent: (WooPosNavigationEvent) -> Unit
viewModel: WooPosHomeViewModel,
) {
val viewModel: WooPosHomeViewModel = hiltViewModel()
val state = viewModel.state.collectAsState().value
val context = LocalContext.current

Expand All @@ -73,16 +66,6 @@ fun WooPosHomeScreen(
}
}

LaunchedEffect(Unit) {
viewModel.navigationEvent.collect {
when (it) {
is NavigationEvent.ToCashPayment -> onNavigationEvent(OpenCashPayment(it.orderId))
is NavigationEvent.ToEmailReceipt -> onNavigationEvent(OpenEmailReceipt(it.orderId))
NavigationEvent.ExitPos -> onNavigationEvent(ExitPosClicked)
}
}
}

WooPosHomeScreen(
state = state,
onHomeUIEvent = { viewModel.onUIEvent(it) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.woocommerce.android.ui.woopos.cardreader.WooPosCardReaderFacade
import com.woocommerce.android.ui.woopos.emailreceipt.WooPosEmailReceiptIsSendingSupported
import com.woocommerce.android.ui.woopos.emailreceipt.WooPosEmailReceiptIsSendingSupported.Companion.WC_VERSION_SUPPORTS_SENDING_RECEIPTS_BY_EMAIL
import com.woocommerce.android.ui.woopos.home.ChildToParentEvent
import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NavigationEvent
import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NavigationEvent.ToCashPayment
import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NavigationEvent.ToEmailReceipt
import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NewTransactionClicked
Expand Down Expand Up @@ -278,9 +279,13 @@ class WooPosTotalsViewModel @Inject constructor(
uiState.value = InitialState
}

is ParentToChildrenEvent.OrderSuccessfullyPaid -> showSuccessfulPaymentState(
event.paymentMethod
)
is ParentToChildrenEvent.OrderSuccessfullyPaid -> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking that it's ok that cancelation will be called also in the card reader payments cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flow works correctly, but I switched to canceling payment intent only in case the payment success comes from cash payment to avoid redundant logic – 60ef6e2

if (event.paymentMethod == PaymentMethod.CASH) {
// Cancel payment intent if order is marked completed by cash
cancelPaymentAction()
}
showSuccessfulPaymentState(event.paymentMethod)
}

is ParentToChildrenEvent.ItemClickedInProductSelector -> Unit
}
Expand All @@ -300,6 +305,9 @@ class WooPosTotalsViewModel @Inject constructor(
is CardReaderPaymentState.PaymentCapturing -> {
uiState.value = buildPaymentInProgressState()
childrenToParentEventSender.sendToParent(ChildToParentEvent.PaymentInProgress)
childrenToParentEventSender.sendToParent(
NavigationEvent.ReturnHomeFromCashWhenCardPaymentStarted
)
}

is CardReaderPaymentState.PaymentSuccessful -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.navigation
import com.woocommerce.android.ui.woopos.cashpayment.cashPaymentScreen
import com.woocommerce.android.ui.woopos.emailreceipt.emailReceiptScreen
import com.woocommerce.android.ui.woopos.home.WooPosHomeViewModel
import com.woocommerce.android.ui.woopos.home.homeScreen
import com.woocommerce.android.ui.woopos.splash.SPLASH_ROUTE
import com.woocommerce.android.ui.woopos.splash.splashScreen

const val MAIN_GRAPH_ROUTE = "main-graph"

fun NavGraphBuilder.mainGraph(
onNavigationEvent: (WooPosNavigationEvent) -> Unit
onNavigationEvent: (WooPosNavigationEvent) -> Unit,
homeViewModel: WooPosHomeViewModel,
) {
navigation(
startDestination = SPLASH_ROUTE,
route = MAIN_GRAPH_ROUTE,
) {
splashScreen(onNavigationEvent = onNavigationEvent)
homeScreen(onNavigationEvent = onNavigationEvent)
homeScreen(homeViewModel = homeViewModel)
cashPaymentScreen(onNavigationEvent = onNavigationEvent)
emailReceiptScreen(onNavigationEvent = onNavigationEvent)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ sealed class WooPosNavigationEvent {
data class OpenEmailReceipt(val orderId: Long) : WooPosNavigationEvent()
data object GoBack : WooPosNavigationEvent()
data object OpenHomeFromCashPaymentAfterSuccessfulPayment : WooPosNavigationEvent()
data object ReturnHomeFromCashPayment : WooPosNavigationEvent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.woocommerce.android.ui.woopos.cashpayment.navigateToCashPaymentScreen
import com.woocommerce.android.ui.woopos.emailreceipt.navigateToEmailReceipt
import com.woocommerce.android.ui.woopos.home.navigateToHomeScreen
import com.woocommerce.android.ui.woopos.home.navigateToHomeScreenAfterSuccessfulCashPayment
import com.woocommerce.android.ui.woopos.home.navigateToHomeScreenIfHomeScreenNotOpen

fun NavHostController.handleNavigationEvent(
event: WooPosNavigationEvent,
Expand All @@ -22,5 +23,6 @@ fun NavHostController.handleNavigationEvent(
navigateToHomeScreenAfterSuccessfulCashPayment()

is WooPosNavigationEvent.OpenEmailReceipt -> navigateToEmailReceipt(event.orderId)
WooPosNavigationEvent.ReturnHomeFromCashPayment -> navigateToHomeScreenIfHomeScreenNotOpen()
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
package com.woocommerce.android.ui.woopos.root.navigation

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NavigationEvent
import com.woocommerce.android.ui.woopos.home.WooPosHomeViewModel
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent.ExitPosClicked
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent.OpenCashPayment
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent.OpenEmailReceipt
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent.ReturnHomeFromCashPayment

@Composable
fun WooPosRootHost(
modifier: Modifier = Modifier,
rootController: NavHostController,
onNavigationEvent: (WooPosNavigationEvent) -> Unit
) {
val homeViewModel = hiltViewModel<WooPosHomeViewModel>()
LaunchedEffect(Unit) {
kidinov marked this conversation as resolved.
Show resolved Hide resolved
homeViewModel.navigationEvent.collect {
when (it) {
is NavigationEvent.ToCashPayment -> onNavigationEvent(OpenCashPayment(it.orderId))
is NavigationEvent.ToEmailReceipt -> onNavigationEvent(OpenEmailReceipt(it.orderId))
NavigationEvent.ExitPos -> onNavigationEvent(ExitPosClicked)
NavigationEvent.ReturnHomeFromCashWhenCardPaymentStarted -> onNavigationEvent(ReturnHomeFromCashPayment)
}
}
}
NavHost(
modifier = modifier,
navController = rootController,
startDestination = MAIN_GRAPH_ROUTE,
) {
mainGraph(onNavigationEvent = onNavigationEvent)
mainGraph(
onNavigationEvent = onNavigationEvent,
homeViewModel = homeViewModel,
)
}
}
Loading