Skip to content

[Woo POS] Start card reader connection flow and adapt to return result of connection to pos #11616

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

Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
415f42f
Attempt to open acitvity with card reader
kidinov May 27, 2024
a9f776b
Add redirect to card reader tutorial
samiuelson May 27, 2024
14ea468
Remove unnecessary navigate
samiuelson May 27, 2024
f06dea9
Fix start destination
samiuelson May 27, 2024
01d931f
Facade
kidinov May 29, 2024
b469387
Merge branch 'pos-card-reader-2' into 11608-woo-pos-start-cr-connecti…
kidinov May 29, 2024
932e47c
Removed unused imports
kidinov May 29, 2024
ab3485e
Start card reader activity from facade
kidinov May 29, 2024
cafa957
Intent to start activity in connection mode
kidinov May 29, 2024
750b210
Fixed transparent theme
kidinov May 29, 2024
c1bef0e
Extracted connection flow and start it via new activity
kidinov May 29, 2024
07575e1
Fixed compilation errors caused by extracting connection nav graph
kidinov May 29, 2024
c3d6853
Renamed card reader connect flow id to exclude duplicate
kidinov May 29, 2024
714d050
Reverted extraction of the connection nav graph as that causes a lot …
kidinov May 29, 2024
8ae6ca5
pass params from VM
kidinov May 29, 2024
6575e38
pass params from VM
kidinov May 29, 2024
0355768
Figuring out how if tehre is a way to send explicite result from nav …
kidinov May 29, 2024
d5f30c5
Removed attempts to handle cancelation
kidinov May 30, 2024
b058315
Fixed detekt complains
kidinov May 30, 2024
26e18db
Pop back stack instead of going up to handle cancelation/not connecte…
kidinov May 30, 2024
ed38b02
In select payment method screen
kidinov May 30, 2024
b6a99d5
Collect paymnt button and test order creation
kidinov May 30, 2024
ccdc8b4
Small refactoring of the events. Setting the correct graph
kidinov May 30, 2024
d3cee29
Hack to hide ui of select payment method fragment
kidinov May 30, 2024
62c7f6c
Fixed detekt complains
kidinov May 30, 2024
7f3fd8e
Pass result of the payment flow
kidinov May 31, 2024
fc88cbf
Return result to the root activity via suspend function
kidinov May 31, 2024
30de778
Crash if activity is null
kidinov May 31, 2024
8dfeb55
Finish activity after the flow is finished
kidinov May 31, 2024
352ef95
Merge pull request #11629 from woocommerce/11609-woo-pos-start-cr-ful…
backwardstruck May 31, 2024
81ccc3a
Merge branch 'trunk' into 11608-woo-pos-start-cr-connection-flow-and-…
kidinov Jun 3, 2024
b736ee9
Fixed naming and simplified the condition
kidinov Jun 3, 2024
60a3f10
View is not nullable
kidinov Jun 3, 2024
fe06a4e
Removed redundant super call
kidinov Jun 3, 2024
f56268a
Reader status to the up pf the class
kidinov Jun 3, 2024
e23660a
Merge remote-tracking branch 'origin/11608-woo-pos-start-cr-connectio…
kidinov Jun 3, 2024
e0dbb5b
Fixed broken back navigation from tutorial fragment
kidinov Jun 3, 2024
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
3 changes: 3 additions & 0 deletions WooCommerce/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@
<activity
android:name="com.woocommerce.android.ui.woopos.root.WooPosActivity"
android:exported="false" />
<activity
android:name="com.woocommerce.android.ui.woopos.cardreader.WooPosCardReaderActivity"
android:theme="@style/Theme.Woo.Transparent" />

<!-- Stats today app widget -->
<meta-data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ class AnalyticsTracker private constructor(
const val VALUE_ORDER_CREATION_PAYMENTS_FLOW = "creation"
const val VALUE_SCAN_TO_PAY_PAYMENT_FLOW = "scan_to_pay"
const val VALUE_TTP_TRY_PAYMENT_FLOW = "tap_to_pay_try_a_payment"
const val VALUE_WOO_POS_PAYMENTS_FLOW = "woo_pos"

const val KEY_JITM = "jitm"
const val KEY_JITM_COUNT = "count"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectE
import com.woocommerce.android.ui.payments.cardreader.connect.adapter.MultipleCardReadersFoundAdapter
import com.woocommerce.android.ui.payments.cardreader.update.CardReaderUpdateDialogFragment
import com.woocommerce.android.ui.payments.cardreader.update.CardReaderUpdateViewModel.UpdateResult
import com.woocommerce.android.ui.woopos.cardreader.WooPosCardReaderActivity
import com.woocommerce.android.util.ChromeCustomTabUtils
import com.woocommerce.android.util.LocationUtils
import com.woocommerce.android.util.UiHelpers
Expand Down Expand Up @@ -244,6 +245,12 @@ class CardReaderConnectDialogFragment : PaymentsBaseDialogFragment(R.layout.card
result = event.data as Boolean,
)
}
is CardReaderConnectEvent.PopBackStackForWooPOS -> {
parentFragmentManager.setFragmentResult(
WooPosCardReaderActivity.WOO_POS_CARD_CONNECTION_REQUEST_KEY,
Bundle(),
)
}
is CardReaderConnectEvent.ShowToast ->
ToastUtils.showToast(requireContext(), getString(event.message))
is CardReaderConnectEvent.ShowToastString ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ sealed class CardReaderConnectEvent : MultiLiveEvent.Event() {
data class OpenWPComWebView(val url: String) : CardReaderConnectEvent()

data class OpenGenericWebView(val url: String) : CardReaderConnectEvent()

data object PopBackStackForWooPOS : CardReaderConnectEvent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectE
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectEvent.OpenLocationSettings
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectEvent.OpenPermissionsSettings
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectEvent.OpenWPComWebView
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectEvent.PopBackStackForWooPOS
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectEvent.RequestBluetoothRuntimePermissions
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectEvent.RequestEnableBluetooth
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectEvent.RequestLocationPermissions
Expand All @@ -57,6 +58,7 @@ import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectV
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectViewState.MissingMerchantAddressError
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectViewState.MultipleExternalReadersFoundState
import com.woocommerce.android.ui.payments.cardreader.connect.CardReaderConnectViewState.ScanningFailedState
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderOnboardingChecker
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderType.BUILT_IN
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderType.EXTERNAL
Expand Down Expand Up @@ -281,6 +283,7 @@ class CardReaderConnectViewModel @Inject constructor(
Unit
}
}

CardReaderStatus.Connecting -> {
connectionStarted = true
viewState.value = provideConnectingState()
Expand Down Expand Up @@ -309,13 +312,16 @@ class CardReaderConnectViewModel @Inject constructor(
viewState.value = provideScanningState()
}
}

is ReadersFound -> {
tracker.trackReadersDiscovered(discoveryEvent.list.size)
onReadersFound(discoveryEvent)
}

Succeeded -> {
// noop
}

is Failed -> {
tracker.trackReaderDiscoveryFailed(discoveryEvent.msg)
WooLog.e(WooLog.T.CARD_READER, "Scanning failed: ${discoveryEvent.msg}")
Expand All @@ -330,6 +336,7 @@ class CardReaderConnectViewModel @Inject constructor(
triggerEvent(ShowToast(R.string.card_reader_detail_connected_update_failed))
exitFlow(connected = false)
}

CardReaderUpdateViewModel.UpdateResult.SUCCESS -> {
// noop
}
Expand Down Expand Up @@ -400,6 +407,7 @@ class CardReaderConnectViewModel @Inject constructor(
::onCancelClicked,
::onLearnMoreClicked
)

EXTERNAL -> ExternalReaderScanningState(
::onCancelClicked,
::onLearnMoreClicked
Expand All @@ -424,6 +432,7 @@ class CardReaderConnectViewModel @Inject constructor(
tracker.trackFetchingLocationSucceeded()
cardReaderManager.startConnectionToReader(cardReader, result.locationId)
}

is CardReaderLocationRepository.LocationIdFetchingResult.Error -> {
handleLocationFetchingError(result)
}
Expand Down Expand Up @@ -453,10 +462,12 @@ class CardReaderConnectViewModel @Inject constructor(
}
)
}

is CardReaderLocationRepository.LocationIdFetchingResult.Error.InvalidPostalCode -> {
trackLocationFailureFetching("Invalid Postal Code")
viewState.value = InvalidMerchantAddressPostCodeError(::restartFlow)
}

is CardReaderLocationRepository.LocationIdFetchingResult.Error.Other -> {
trackLocationFailureFetching(result.error)
onReaderConnectionFailed()
Expand Down Expand Up @@ -510,7 +521,13 @@ class CardReaderConnectViewModel @Inject constructor(

private fun exitFlow(connected: Boolean) {
if (!connected) {
triggerEvent(ExitWithResult(false))
when (arguments.cardReaderFlowParam) {
is CardReaderFlowParam.CardReadersHub,
is CardReaderFlowParam.PaymentOrRefund.Payment,
is CardReaderFlowParam.PaymentOrRefund.Refund -> triggerEvent(ExitWithResult(false))

CardReaderFlowParam.WooPosConnection -> triggerEvent(PopBackStackForWooPOS)
}
} else {
triggerEvent(ShowCardReaderTutorial(arguments.cardReaderFlowParam, arguments.cardReaderType))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ sealed class CardReaderFlowParam : Parcelable {
}
}

@Parcelize
data object WooPosConnection : CardReaderFlowParam()

sealed class PaymentOrRefund : CardReaderFlowParam() {
abstract val orderId: Long

Expand All @@ -426,6 +429,7 @@ sealed class CardReaderFlowParam : Parcelable {
ORDER,
ORDER_CREATION,
TRY_TAP_TO_PAY,
WOO_POS,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,9 @@ class CardReaderOnboardingViewModel @Inject constructor(
CardReaderOnboardingEvent.ContinueToConnection(params, requireNotNull(arguments.cardReaderType))
)
}
is CardReaderFlowParam.WooPosConnection -> {
error("Unsupported flow param: $params")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class CardReaderStatusCheckerViewModel
handleOnboardingStatus(param)
}
}
is CardReaderFlowParam.WooPosConnection -> handleOnboardingStatus(param)
}
}

Expand All @@ -87,6 +88,7 @@ class CardReaderStatusCheckerViewModel
triggerEvent(StatusCheckerEvent.NavigateToWelcome(param, arguments.cardReaderType))
}
}

else -> triggerEvent(
StatusCheckerEvent.NavigateToOnboarding(
CardReaderOnboardingParams.Failed(param, state),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.woocommerce.android.extensions.navigateSafely
import com.woocommerce.android.ui.payments.PaymentsBaseDialogFragment
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderType.BUILT_IN
import com.woocommerce.android.ui.woopos.cardreader.WooPosCardReaderActivity
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

Expand Down Expand Up @@ -58,7 +59,13 @@ class CardReaderTutorialDialogFragment : PaymentsBaseDialogFragment(R.layout.car

private fun navigateNext() {
when (val param = args.cardReaderFlowParam) {
is CardReaderFlowParam.CardReadersHub -> findNavController().popBackStack()
is CardReaderFlowParam.CardReadersHub,
is CardReaderFlowParam.WooPosConnection -> {
parentFragmentManager.setFragmentResult(
WooPosCardReaderActivity.WOO_POS_CARD_CONNECTION_REQUEST_KEY,
Bundle(),
)
}
is CardReaderFlowParam.PaymentOrRefund -> {
val action = CardReaderTutorialDialogFragmentDirections
.actionCardReaderTutorialDialogFragmentToCardReaderPaymentDialogFragment(param, args.cardReaderType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ class PaymentsHubViewModel @Inject constructor(
is PaymentOrRefund -> {
// no-op
}
is CardReaderFlowParam.WooPosConnection -> error("Unsupported card reader flow param $params")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ data class NavigateToOrderDetails(
val orderId: Long
) : MultiLiveEvent.Event()

object ReturnResultToWooPos : MultiLiveEvent.Event()

data class NavigateToTapToPaySummary(
val order: Order
) : MultiLiveEvent.Event()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import com.woocommerce.android.ui.payments.methodselection.SelectPaymentMethodVi
import com.woocommerce.android.ui.payments.methodselection.SelectPaymentMethodViewState.Success
import com.woocommerce.android.ui.payments.scantopay.ScanToPayDialogFragment
import com.woocommerce.android.ui.payments.taptopay.summary.TapToPaySummaryFragment
import com.woocommerce.android.ui.woopos.cardreader.WooPosCardReaderActivity
import com.woocommerce.android.ui.woopos.cardreader.WooPosCardReaderPaymentResult
import com.woocommerce.android.util.ChromeCustomTabUtils
import com.woocommerce.android.util.UiHelpers
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.ShowDialog
Expand All @@ -59,10 +61,14 @@ class SelectPaymentMethodFragment : BaseFragment(R.layout.fragment_select_paymen
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
): View? {
_binding = FragmentSelectPaymentMethodBinding.inflate(inflater, container, false)
setupToolbar()
return binding.root
return if (viewModel.displayUi) {
setupToolbar()
binding.root
} else {
View(requireContext())
}
}

private fun setupToolbar() {
Expand Down Expand Up @@ -274,6 +280,18 @@ class SelectPaymentMethodFragment : BaseFragment(R.layout.fragment_select_paymen
)
)
}

is ReturnResultToWooPos -> {
parentFragmentManager.setFragmentResult(
WooPosCardReaderActivity.WOO_POS_CARD_PAYMENT_REQUEST_KEY,
Bundle().apply {
putParcelable(
WooPosCardReaderActivity.WOO_POS_CARD_PAYMENT_RESULT_KEY,
WooPosCardReaderPaymentResult.Success,
)
}
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowP
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam.PaymentOrRefund.Payment.PaymentType.ORDER_CREATION
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam.PaymentOrRefund.Payment.PaymentType.SIMPLE
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam.PaymentOrRefund.Payment.PaymentType.TRY_TAP_TO_PAY
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam.PaymentOrRefund.Payment.PaymentType.WOO_POS
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam.PaymentOrRefund.Refund
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam.WooPosConnection
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderType.BUILT_IN
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderType.EXTERNAL
import com.woocommerce.android.ui.payments.cardreader.payment.CardReaderPaymentCollectibilityChecker
Expand Down Expand Up @@ -86,6 +88,9 @@ class SelectPaymentMethodViewModel @Inject constructor(
private val cardReaderPaymentFlowParam
get() = navArgs.cardReaderFlowParam as Payment

val displayUi: Boolean
get() = isWooPOSPaymentFlow()

init {
checkStatus()
}
Expand All @@ -97,7 +102,6 @@ class SelectPaymentMethodViewModel @Inject constructor(
when (param) {
is Payment -> {
launch {
// stay on screen
cardReaderTrackingInfoKeeper.setCountry(
wooCommerceStore.getStoreCountryCode(selectedSite.get())
)
Expand All @@ -109,14 +113,19 @@ class SelectPaymentMethodViewModel @Inject constructor(
cardReaderTrackingInfoKeeper.setCurrency(order.currency)
}

showPaymentState()
when (param.paymentType) {
SIMPLE, ORDER, ORDER_CREATION, TRY_TAP_TO_PAY -> showPaymentState()
WOO_POS -> onBtReaderClicked()
}
}
Unit
}

is Refund -> triggerEvent(NavigateToCardReaderRefundFlow(param, EXTERNAL))
}
}

is WooPosConnection -> error("Unsupported card reader flow param: $param")
}
}

Expand Down Expand Up @@ -244,6 +253,7 @@ class SelectPaymentMethodViewModel @Inject constructor(
val messageIdForPaymentType = when (cardReaderPaymentFlowParam.paymentType) {
SIMPLE, TRY_TAP_TO_PAY -> R.string.simple_payments_cash_dlg_message
ORDER, ORDER_CREATION -> R.string.existing_order_cash_dlg_message
WOO_POS -> error("Unsupported card reader flow param: $cardReaderPaymentFlowParam")
}
triggerEvent(
MultiLiveEvent.Event.ShowDialog(
Expand Down Expand Up @@ -443,6 +453,7 @@ class SelectPaymentMethodViewModel @Inject constructor(
SIMPLE -> NavigateBackToHub(CardReadersHub())
TRY_TAP_TO_PAY -> NavigateToTapToPaySummary(order.first())
ORDER, ORDER_CREATION -> NavigateBackToOrderList(order.first())
WOO_POS -> ReturnResultToWooPos
}
)
}
Expand All @@ -452,7 +463,8 @@ class SelectPaymentMethodViewModel @Inject constructor(
SIMPLE -> AnalyticsTracker.VALUE_SIMPLE_PAYMENTS_FLOW
ORDER -> AnalyticsTracker.VALUE_ORDER_PAYMENTS_FLOW
TRY_TAP_TO_PAY -> AnalyticsTracker.VALUE_TTP_TRY_PAYMENT_FLOW
Payment.PaymentType.ORDER_CREATION -> AnalyticsTracker.VALUE_ORDER_CREATION_PAYMENTS_FLOW
ORDER_CREATION -> AnalyticsTracker.VALUE_ORDER_CREATION_PAYMENTS_FLOW
WOO_POS -> AnalyticsTracker.VALUE_WOO_POS_PAYMENTS_FLOW
}

private fun onLearnMoreIppClicked() {
Expand All @@ -471,6 +483,12 @@ class SelectPaymentMethodViewModel @Inject constructor(
return currencyFormatter.formatCurrency(total, currencyCode)
}

private fun isWooPOSPaymentFlow() = if (navArgs.cardReaderFlowParam is Payment) {
(navArgs.cardReaderFlowParam as Payment).paymentType != WOO_POS
} else {
true
}

companion object {
private const val DELAY_MS = 1L
const val UTM_CAMPAIGN = "feature_announcement_card"
Expand Down
Loading
Loading