Skip to content

Commit

Permalink
fix: IAP error dialog improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
farhan-arshad-dev committed Jul 9, 2024
1 parent 1fc7be2 commit fe90121
Show file tree
Hide file tree
Showing 4 changed files with 330 additions and 251 deletions.
95 changes: 95 additions & 0 deletions core/src/main/java/org/openedx/core/exception/iap/IAPException.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.openedx.core.exception.iap

import android.text.TextUtils
import com.android.billingclient.api.BillingClient
import org.json.JSONObject
import org.openedx.core.presentation.iap.IAPErrorDialogType
import org.openedx.core.presentation.iap.IAPRequestType
import retrofit2.Response
import java.util.Locale
Expand Down Expand Up @@ -44,6 +46,99 @@ class IAPException(
return body.toString()
}

fun getIAPErrorDialogType(): IAPErrorDialogType {
return when (requestType) {
IAPRequestType.PRICE_CODE -> {
IAPErrorDialogType.PRICE_ERROR_DIALOG
}

IAPRequestType.NO_SKU_CODE -> {
IAPErrorDialogType.NO_SKU_ERROR_DIALOG
}

IAPRequestType.ADD_TO_BASKET_CODE -> {
when (httpErrorCode) {
400 -> {
IAPErrorDialogType.ADD_TO_BASKET_BAD_REQUEST_ERROR_DIALOG
}

403 -> {
IAPErrorDialogType.ADD_TO_BASKET_FORBIDDEN_ERROR_DIALOG
}

406 -> {
IAPErrorDialogType.ADD_TO_BASKET_NOT_ACCEPTABLE_ERROR_DIALOG
}

else -> {
IAPErrorDialogType.ADD_TO_BASKET_GENERAL_ERROR_DIALOG
}
}
}

IAPRequestType.CHECKOUT_CODE -> {
when (httpErrorCode) {
400 -> {
IAPErrorDialogType.CHECKOUT_BAD_REQUEST_ERROR_DIALOG
}

403 -> {
IAPErrorDialogType.CHECKOUT_FORBIDDEN_ERROR_DIALOG
}

406 -> {
IAPErrorDialogType.CHECKOUT_NOT_ACCEPTABLE_ERROR_DIALOG
}

else -> {
IAPErrorDialogType.CHECKOUT_GENERAL_ERROR_DIALOG
}

}
}

IAPRequestType.EXECUTE_ORDER_CODE -> {
when (httpErrorCode) {
400 -> {
IAPErrorDialogType.EXECUTE_BAD_REQUEST_ERROR_DIALOG
}

403 -> {
IAPErrorDialogType.EXECUTE_FORBIDDEN_ERROR_DIALOG
}

406 -> {
IAPErrorDialogType.EXECUTE_NOT_ACCEPTABLE_ERROR_DIALOG
}

409 -> {
IAPErrorDialogType.EXECUTE_CONFLICT_ERROR_DIALOG
}

else -> {
IAPErrorDialogType.EXECUTE_GENERAL_ERROR_DIALOG
}
}
}

IAPRequestType.CONSUME_CODE -> {
IAPErrorDialogType.CONSUME_ERROR_DIALOG
}

IAPRequestType.PAYMENT_SDK_CODE -> {
if (httpErrorCode == BillingClient.BillingResponseCode.BILLING_UNAVAILABLE) {
IAPErrorDialogType.PAYMENT_SDK_ERROR_DIALOG
} else {
IAPErrorDialogType.GENERAL_DIALOG_ERROR
}
}

else -> {
IAPErrorDialogType.GENERAL_DIALOG_ERROR
}
}
}

companion object {
private const val DEFAULT_HTTP_ERROR_CODE = -1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.android.billingclient.api.BillingClient
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import org.openedx.core.R
Expand All @@ -46,15 +45,10 @@ import org.openedx.core.presentation.iap.IAPLoaderType
import org.openedx.core.presentation.iap.IAPRequestType
import org.openedx.core.presentation.iap.IAPUIState
import org.openedx.core.presentation.iap.IAPViewModel
import org.openedx.core.ui.CourseAlreadyPurchasedErrorDialog
import org.openedx.core.ui.CourseAlreadyPurchasedExecuteErrorDialog
import org.openedx.core.ui.GeneralUpgradeErrorDialog
import org.openedx.core.ui.HandleUIMessage
import org.openedx.core.ui.NoSkuErrorDialog
import org.openedx.core.ui.IAPErrorDialog
import org.openedx.core.ui.OpenEdXButton
import org.openedx.core.ui.PriceLoadErrorDialog
import org.openedx.core.ui.UnlockingAccessView
import org.openedx.core.ui.UpgradeErrorDialog
import org.openedx.core.ui.ValuePropUpgradeFeatures
import org.openedx.core.ui.theme.OpenEdXTheme
import org.openedx.core.ui.theme.appColors
Expand Down Expand Up @@ -152,206 +146,66 @@ class IAPDialogFragment : DialogFragment() {

is IAPUIState.Error -> {
val iapException = (iapState as IAPUIState.Error).iapException
when {
(iapException.requestType == IAPRequestType.PRICE_CODE) -> {
PriceLoadErrorDialog(onConfirm = {
IAPErrorDialog(iapException = iapException, onIAPAction = { iapAction ->
when (iapAction) {
IAPAction.ACTION_RELOAD_PRICE -> {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_RELOAD_PRICE.action
)
iapViewModel.loadPrice()
}, onDismiss = {
}

IAPAction.ACTION_CLOSE -> {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_CLOSE.action
)
onDismiss()
})
}
}

(iapException.requestType == IAPRequestType.NO_SKU_CODE) -> {
NoSkuErrorDialog(onConfirm = {
IAPAction.ACTION_OK -> {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_OK.action
)
onDismiss()
})
}

(iapException.requestType == IAPRequestType.ADD_TO_BASKET_CODE ||
iapException.requestType == IAPRequestType.CHECKOUT_CODE) &&
(iapException.httpErrorCode == 406) -> {
CourseAlreadyPurchasedErrorDialog(
onRefresh = {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_REFRESH.action
)
iapViewModel.refreshCourse()
},
onDismiss = {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_CLOSE.action
)
onDismiss()
})
}
}

(iapException.requestType == IAPRequestType.EXECUTE_ORDER_CODE) -> {
if (iapException.httpErrorCode == 409) {
UpgradeErrorDialog(
title = stringResource(id = R.string.iap_error_title),
description = stringResource(id = R.string.iap_course_already_paid_for_message),
confirmText = stringResource(id = R.string.core_cancel),
onConfirm = {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_CLOSE.action
)
dismiss()
},
dismissText = stringResource(id = R.string.iap_get_help),
onDismiss = {
iapViewModel.showFeedbackScreen(
requireActivity(),
iapException.requestType.request,
iapException.getFormattedErrorMessage()
)
onDismiss()
}
IAPAction.ACTION_REFRESH -> {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_REFRESH.action
)
} else {
val confirmText = when (iapException.httpErrorCode) {
406 -> {
stringResource(id = R.string.iap_label_refresh_now)
}

else -> {
stringResource(id = R.string.iap_refresh_to_retry)
}
}

val description = when (iapException.httpErrorCode) {
400, 403 -> {
stringResource(id = R.string.iap_course_not_fullfilled)
}

406 -> {
stringResource(id = R.string.iap_course_already_paid_for_message)
}
iapViewModel.refreshCourse()
}

else -> {
stringResource(id = R.string.iap_general_upgrade_error_message)
}
}
CourseAlreadyPurchasedExecuteErrorDialog(
confirmText = confirmText,
description = description,
onRefresh = {
if (iapException.httpErrorCode == 406) {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_REFRESH.action
)
iapViewModel.refreshCourse()
} else {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_RETRY.action
)
iapViewModel.retryExecuteOrder()
}
},
onGetHelp = {
iapViewModel.showFeedbackScreen(
requireActivity(),
iapException.requestType.request,
iapException.getFormattedErrorMessage()
)
onDismiss()
},
onDismiss = {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_CLOSE.action
)
onDismiss()
}
IAPAction.ACTION_GET_HELP -> {
iapViewModel.showFeedbackScreen(
requireActivity(),
iapException.requestType.request,
iapException.getFormattedErrorMessage()
)
onDismiss()
}
}

iapException.requestType == IAPRequestType.CONSUME_CODE -> {
CourseAlreadyPurchasedExecuteErrorDialog(
onRefresh = {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_RETRY.action
)
IAPAction.ACTION_RETRY -> {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_RETRY.action
)
if (iapException.requestType == IAPRequestType.CONSUME_CODE) {
iapViewModel.retryToConsumeOrder()
},
onGetHelp = {
iapViewModel.showFeedbackScreen(
requireActivity(),
iapException.requestType.request,
iapException.getFormattedErrorMessage()
)
onDismiss()
},
onDismiss = {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_CLOSE.action
)
onDismiss()
}
)
}

else -> {
val description: String = when {
(iapException.httpErrorCode == 403) -> {
stringResource(id = R.string.iap_unauthenticated_account_message)
}

(iapException.httpErrorCode == 400) -> {
if (iapException.requestType == IAPRequestType.CHECKOUT_CODE) {
stringResource(id = R.string.iap_payment_could_not_be_processed)
} else {
stringResource(id = R.string.iap_course_not_available_message)
}
}

(iapException.requestType == IAPRequestType.PAYMENT_SDK_CODE &&
iapException.httpErrorCode == BillingClient.BillingResponseCode.BILLING_UNAVAILABLE) -> {
stringResource(id = R.string.iap_payment_could_not_be_processed)
} else if (iapException.requestType == IAPRequestType.EXECUTE_ORDER_CODE) {
iapViewModel.retryExecuteOrder()
}
}

else -> {
""
}
else -> {
// ignore
}
GeneralUpgradeErrorDialog(
description = description,
onConfirm = {
iapViewModel.logIAPErrorActionEvent(
iapException.requestType.request,
IAPAction.ACTION_CLOSE.action
)
onDismiss()
},
onDismiss = {
iapViewModel.showFeedbackScreen(
requireActivity(),
iapException.requestType.request,
iapException.getFormattedErrorMessage()
)
onDismiss()
})
}
}
})
}

is IAPUIState.Clear -> {
Expand Down
Loading

0 comments on commit fe90121

Please sign in to comment.