diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt index b91e0723..c49eb345 100644 --- a/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt +++ b/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt @@ -56,6 +56,15 @@ class Response private constructor( val isFailure: Boolean get() = value is Failure + /** + * The HTTP status the backend answered with, or null when the request never + * got an answer at all (a network error) or succeeded. Callers that have to + * tell one kind of failure from another need this: the message cannot. + */ + val statusCode: Int? + get() = ((value as? Failure)?.exception as? ResponseException) + ?.response?.status?.value + suspend fun handle(onFailure: ((String) -> Unit)? = null, onSuccess: ((T) -> Unit)? = null) { if (value is Failure) onFailure?.let { it(getFailureString(value)) } else onSuccess?.let { diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryManager.kt index 1b8e27a2..41ac8c44 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryManager.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryManager.kt @@ -233,11 +233,22 @@ class HistoryManager( mIsLoading.value = true mIsLoadingMore.value = false val merchantConfig = configManager.merchantConfig!! - api.deleteOrder(merchantConfig, orderId).handle( - { _ -> + val result = api.deleteOrder(merchantConfig, orderId) + // Same as on the payment screen: only a 409 is a claim that force can + // override, so only a 409 may raise the force-delete prompt. + val needsForce = result.statusCode == 409 + result.handle( + { errorMsg -> assertUiThread() mIsLoading.value = false - mForceDeleteOrderId.value = orderId + if (needsForce) + { + mForceDeleteOrderId.value = orderId + } + else + { + onError(R.string.error_delete_order, errorMsg) + } } ) { assertUiThread() diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt index 91672e4f..9934d9c5 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt @@ -402,10 +402,23 @@ class PaymentManager( val orderId = mPayment.value?.orderId ?: return scope.launch { val result = api.deleteOrder(merchantConfig, orderId) + // Only a 409 is the backend refusing because the order is claimed or + // already paid. Every other failure -- no network, a 5xx, an expired + // token -- is a failure of the request itself, which force cannot fix + // and which must not be reported to the cashier as a wallet's claim. + val needsForce = result.statusCode == 409 result.handle( onFailure = { errorStr -> Log.w(TAG, "Delete order $orderId failed: $errorStr") - mDeleteNeedsForce.postValue(true) + if (needsForce) + { + mDeleteNeedsForce.postValue(true) + } + else + { + mPayment.postValue(mPayment.value?.copy(error = errorStr)) + mDeleteNeedsForce.postValue(null) + } }, onSuccess = { Log.d(TAG, "Delete order $orderId succeeded")