taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

TransactionRefundComposable.kt (5459B)


      1 /*
      2  * This file is part of GNU Taler
      3  * (C) 2023 Taler Systems S.A.
      4  *
      5  * GNU Taler is free software; you can redistribute it and/or modify it under the
      6  * terms of the GNU General Public License as published by the Free Software
      7  * Foundation; either version 3, or (at your option) any later version.
      8  *
      9  * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
     10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11  * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License along with
     14  * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 
     17 package net.taler.wallet.refund
     18 
     19 import androidx.compose.foundation.layout.Column
     20 import androidx.compose.foundation.layout.fillMaxWidth
     21 import androidx.compose.foundation.layout.padding
     22 import androidx.compose.foundation.rememberScrollState
     23 import androidx.compose.foundation.verticalScroll
     24 import androidx.compose.material3.MaterialTheme
     25 import androidx.compose.material3.Text
     26 import androidx.compose.runtime.Composable
     27 import androidx.compose.ui.Alignment.Companion.CenterHorizontally
     28 import androidx.compose.ui.Modifier
     29 import androidx.compose.ui.platform.LocalContext
     30 import androidx.compose.ui.res.stringResource
     31 import androidx.compose.ui.tooling.preview.Preview
     32 import androidx.compose.ui.unit.dp
     33 import net.taler.common.Amount
     34 import net.taler.common.CurrencySpecification
     35 import net.taler.common.Timestamp
     36 import net.taler.lib.android.toAbsoluteTime
     37 import net.taler.wallet.BottomInsetsSpacer
     38 import net.taler.wallet.R
     39 import net.taler.wallet.backend.TalerErrorCode
     40 import net.taler.wallet.backend.TalerErrorInfo
     41 import net.taler.wallet.balances.ScopeInfo
     42 import net.taler.wallet.compose.TalerSurface
     43 import net.taler.wallet.transactions.AmountType
     44 import net.taler.wallet.transactions.ErrorTransactionButton
     45 import net.taler.wallet.transactions.TransactionAction
     46 import net.taler.wallet.transactions.TransactionAction.Abort
     47 import net.taler.wallet.transactions.TransactionAction.Retry
     48 import net.taler.wallet.transactions.TransactionAction.Suspend
     49 import net.taler.wallet.transactions.TransactionAmountComposable
     50 import net.taler.wallet.transactions.TransactionInfoComposable
     51 import net.taler.wallet.transactions.TransactionMajorState.Pending
     52 import net.taler.wallet.transactions.TransactionRefund
     53 import net.taler.wallet.transactions.TransactionState
     54 import net.taler.wallet.transactions.TransactionStateComposable
     55 import net.taler.wallet.transactions.TransitionsComposable
     56 
     57 @Composable
     58 fun TransactionRefundComposable(
     59     t: TransactionRefund,
     60     devMode: Boolean,
     61     spec: CurrencySpecification?,
     62     onTransition: (t: TransactionAction) -> Unit,
     63     modifier: Modifier = Modifier,
     64 ) {
     65     val scrollState = rememberScrollState()
     66     Column(
     67         modifier = modifier
     68             .fillMaxWidth()
     69             .verticalScroll(scrollState),
     70         horizontalAlignment = CenterHorizontally,
     71     ) {
     72         TransactionStateComposable(state = t.txState)
     73 
     74         Text(
     75             modifier = Modifier.padding(16.dp),
     76             text = t.timestamp.ms.toAbsoluteTime(LocalContext.current).toString(),
     77             style = MaterialTheme.typography.bodyLarge,
     78         )
     79 
     80         TransactionAmountComposable(
     81             label = stringResource(id = R.string.transaction_refund),
     82             amount = t.amountEffective.withSpec(spec),
     83             amountType = AmountType.Positive,
     84         )
     85 
     86         TransactionAmountComposable(
     87             label = stringResource(id = R.string.transaction_order_total),
     88             amount = t.amountRaw.withSpec(spec),
     89             amountType = AmountType.Neutral,
     90         )
     91 
     92         if (t.amountRaw > t.amountEffective) {
     93             val fee = t.amountRaw - t.amountEffective
     94             TransactionAmountComposable(
     95                 label = stringResource(id = R.string.amount_fee),
     96                 amount = fee.withSpec(spec),
     97                 amountType = AmountType.Negative,
     98             )
     99         }
    100 
    101         TransactionInfoComposable(
    102             label = stringResource(id = R.string.transaction_order),
    103             info = t.paymentInfo?.summary ?: "",
    104         )
    105 
    106         TransitionsComposable(t, devMode, onTransition)
    107 
    108         if (devMode && t.error != null) {
    109             ErrorTransactionButton(error = t.error)
    110         }
    111 
    112         BottomInsetsSpacer()
    113     }
    114 }
    115 
    116 @Preview
    117 @Composable
    118 fun TransactionRefundComposablePreview() {
    119     val t = TransactionRefund(
    120         transactionId = "transactionId",
    121         timestamp = Timestamp.fromMillis(System.currentTimeMillis() - 360 * 60 * 1000),
    122         txState = TransactionState(Pending),
    123         txActions = listOf(Retry, Suspend, Abort),
    124         paymentInfo = RefundPaymentInfo(
    125             merchant = MerchantInfo(name = "Taler"),
    126             summary = "Some Product that was bought and can have quite a long label",
    127         ),
    128         refundedTransactionId = "transactionId",
    129         amountRaw = Amount.fromString("TESTKUDOS", "42.23"),
    130         amountEffective = Amount.fromString("TESTKUDOS", "42.1337"),
    131         error = TalerErrorInfo(code = TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED),
    132         scopes = listOf(ScopeInfo.Exchange(
    133             currency = "TESTKUDOS",
    134             url = "exchange.test.taler.net",
    135         ))
    136     )
    137     TalerSurface {
    138         TransactionRefundComposable(t = t, devMode = true, spec = null, onTransition = {})
    139     }
    140 }