From b62bd90f86f6fc4ba9e1971df4818a65c9eedada Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Tue, 20 Jun 2023 11:35:26 -0600 Subject: [wallet] Handle "fail" DD37 action and prevent non-deletable transactions from being deleted. --- .../wallet/transactions/TransactionDetailFragment.kt | 7 ++++++- .../taler/wallet/transactions/TransactionManager.kt | 20 +++++++++++++++++--- .../wallet/transactions/TransitionsComposable.kt | 14 +++++++------- wallet/src/main/res/drawable/ic_fail.xml | 5 +++++ wallet/src/main/res/values/strings.xml | 1 + 5 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 wallet/src/main/res/drawable/ic_fail.xml diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt index 1a709b0..b0f5e1b 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt @@ -83,7 +83,7 @@ abstract class TransactionDetailFragment : Fragment() { protected fun onTransitionButton(t: Transaction, tt: TransactionAction) { when (tt) { - Delete, Abort -> { + Delete, Abort, Fail -> { MaterialAlertDialogBuilder(requireContext(), R.style.MaterialAlertDialog_Material3) .setTitle(dialogTitle(tt)!!) .setMessage(dialogMessage(tt)!!) @@ -94,6 +94,7 @@ abstract class TransactionDetailFragment : Fragment() { when (tt) { Delete -> deleteTransaction(t) Abort -> abortTransaction(t) + Fail -> failTransaction(t) else -> {} } dialog.dismiss() @@ -122,6 +123,10 @@ abstract class TransactionDetailFragment : Fragment() { transactionManager.abortTransaction(t.transactionId) } + private fun failTransaction(t: Transaction) { + transactionManager.failTransaction(t.transactionId) + } + private fun suspendTransaction(t: Transaction) { transactionManager.suspendTransaction(t.transactionId) } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt index dfe25ad..725f2c5 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt @@ -26,6 +26,7 @@ import kotlinx.coroutines.launch import net.taler.wallet.TAG import net.taler.wallet.backend.TalerErrorInfo import net.taler.wallet.backend.WalletBackendApi +import net.taler.wallet.transactions.TransactionAction.Delete import net.taler.wallet.transactions.TransactionMajorState.Pending import java.util.LinkedList @@ -158,6 +159,16 @@ class TransactionManager( } } + fun failTransaction(transactionId: String) = scope.launch { + api.request("failTransaction") { + put("transactionId", transactionId) + }.onError { + Log.e(TAG, "Error failTransaction $it") + }.onSuccess { + loadTransactions() + } + } + fun suspendTransaction(transactionId: String) = scope.launch { api.request("suspendTransaction") { put("transactionId", transactionId) @@ -179,9 +190,12 @@ class TransactionManager( } fun deleteTransactions(transactionIds: List) { - // TODO: do NOT delete non-deletable transactions - transactionIds.forEach { id -> - deleteTransaction(id) + allTransactions[selectedCurrency]?.filter { transaction -> + transaction.transactionId in transactionIds + }?.forEach { toBeDeletedTx -> + if (Delete in toBeDeletedTx.txActions) { + deleteTransaction(toBeDeletedTx.transactionId) + } } } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt index e66de47..3fb43fe 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt @@ -37,7 +37,7 @@ import net.taler.wallet.transactions.TransactionAction.* @OptIn(ExperimentalLayoutApi::class) @Composable fun TransitionsComposable(t: Transaction, onTransition: (t: TransactionAction) -> Unit) { - FlowRow { + FlowRow { t.txActions.forEach { TransitionComposable(it, onTransition) } @@ -47,16 +47,16 @@ fun TransitionsComposable(t: Transaction, onTransition: (t: TransactionAction) - @Composable fun TransitionComposable(t: TransactionAction, onClick: (t: TransactionAction) -> Unit) { // TODO: handle more transitions! - if (t !in arrayOf(Delete, Retry, Abort, Resume, Suspend)) return + if (t !in arrayOf(Delete, Retry, Abort, Fail, Resume, Suspend)) return Button( modifier = Modifier.padding(16.dp), colors = ButtonDefaults.buttonColors(containerColor = when(t) { Delete -> MaterialTheme.colorScheme.error Retry -> MaterialTheme.colorScheme.primary Abort -> MaterialTheme.colorScheme.error + Fail -> MaterialTheme.colorScheme.error Resume -> MaterialTheme.colorScheme.primary Suspend -> MaterialTheme.colorScheme.primary - else -> error("Unsupported") }), onClick = { onClick(t) }, ) { @@ -66,18 +66,18 @@ fun TransitionComposable(t: TransactionAction, onClick: (t: TransactionAction) - Delete -> painterResource(id = R.drawable.ic_delete) Retry -> painterResource(id = R.drawable.ic_retry) Abort -> painterResource(id = R.drawable.ic_cancel) + Fail -> painterResource(id = R.drawable.ic_fail) Resume -> painterResource(id = R.drawable.ic_resume) Suspend -> painterResource(id = R.drawable.ic_suspend) - else -> error("Unsupported") }, contentDescription = null, tint = when (t) { Delete -> MaterialTheme.colorScheme.onError Retry -> MaterialTheme.colorScheme.onPrimary Abort -> MaterialTheme.colorScheme.onError + Fail -> MaterialTheme.colorScheme.onError Resume -> MaterialTheme.colorScheme.onPrimary Suspend -> MaterialTheme.colorScheme.onPrimary - else -> error("Unsupported") }, ) Text( @@ -86,17 +86,17 @@ fun TransitionComposable(t: TransactionAction, onClick: (t: TransactionAction) - Delete -> stringResource(R.string.transactions_delete) Retry -> stringResource(R.string.transactions_retry) Abort -> stringResource(R.string.transactions_abort) + Fail -> stringResource(id = R.string.transactions_fail) Resume -> stringResource(R.string.transactions_resume) Suspend -> stringResource(R.string.transactions_suspend) - else -> error("Unsupported") }, color = when (t) { Delete -> MaterialTheme.colorScheme.onError Retry -> MaterialTheme.colorScheme.onPrimary Abort -> MaterialTheme.colorScheme.onError + Fail -> MaterialTheme.colorScheme.onError Resume -> MaterialTheme.colorScheme.onPrimary Suspend -> MaterialTheme.colorScheme.onPrimary - else -> error("Unsupported") }, ) } diff --git a/wallet/src/main/res/drawable/ic_fail.xml b/wallet/src/main/res/drawable/ic_fail.xml new file mode 100644 index 0000000..a25c5ed --- /dev/null +++ b/wallet/src/main/res/drawable/ic_fail.xml @@ -0,0 +1,5 @@ + + + diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml index 716d537..4facfc8 100644 --- a/wallet/src/main/res/values/strings.xml +++ b/wallet/src/main/res/values/strings.xml @@ -87,6 +87,7 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card Delete Retry Abort + Fail Suspend Resume Select All -- cgit v1.2.3