commit 97f8c41c87f07dcbf418f81060cc8e8842938201
parent 72d0f8816eb4eba03ea7e8474642b6c503ca5cc1
Author: Iván Ávalos <avalos@disroot.org>
Date: Thu, 26 Sep 2024 15:19:29 +0200
[cashier] allow withdrawing under debit threshold
Diffstat:
6 files changed, 69 insertions(+), 8 deletions(-)
diff --git a/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt b/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt
@@ -38,9 +38,13 @@ import net.taler.common.fadeIn
import net.taler.common.fadeOut
sealed class BalanceResult {
- class Error(val msg: String) : BalanceResult()
- object Offline : BalanceResult()
- class Success(val amount: SignedAmount) : BalanceResult()
+ data class Error(val msg: String) : BalanceResult()
+ data object Offline : BalanceResult()
+ data class Success(
+ val amount: SignedAmount,
+ val debitThreshold: Amount,
+ val minCashout: Amount? = null,
+ ) : BalanceResult()
}
class BalanceFragment : Fragment() {
@@ -137,14 +141,23 @@ class BalanceFragment : Fragment() {
when (result) {
is BalanceResult.Success -> {
ui.balanceView.text = result.amount.toString()
+ if (!result.debitThreshold.isZero()) {
+ ui.debitView.text = getString(
+ R.string.balance_debit_threshold,
+ result.debitThreshold.toString(),
+ )
+ ui.debitView.fadeIn()
+ }
uiList.forEach { it.fadeIn() }
}
is BalanceResult.Error -> {
ui.balanceView.text = getString(R.string.balance_error, result.msg)
+ ui.debitView.fadeOut()
uiList.forEach { it.fadeOut() }
}
BalanceResult.Offline -> {
ui.balanceView.text = getString(R.string.balance_offline)
+ ui.debitView.fadeOut()
uiList.forEach { it.fadeOut() }
}
}.exhaustive
@@ -164,8 +177,12 @@ class BalanceFragment : Fragment() {
}
private fun onAmountConfirmed(amount: Amount) {
+ val balance = viewModel.balance.value as? BalanceResult.Success
+ val minCashout = balance?.minCashout
if (amount.isZero()) {
ui.amountView.error = getString(R.string.withdraw_error_zero)
+ } else if (minCashout != null && amount < minCashout) {
+ ui.amountView.error = getString(R.string.withdraw_error_under_min_cashout, minCashout.toString())
} else when (withdrawManager.hasSufficientBalance(amount)) {
true -> {
ui.amountView.error = null
diff --git a/cashier/src/main/java/net/taler/cashier/MainViewModel.kt b/cashier/src/main/java/net/taler/cashier/MainViewModel.kt
@@ -71,14 +71,22 @@ class MainViewModel(private val app: Application) : AndroidViewModel(app) {
try {
val balanceObj = response.json.getJSONObject("balance")
val balanceAmount = balanceObj.getString("amount")
+ val debitThreshold = response.json.getString("debit_threshold")
+ val minCashout = if (response.json.has("min_cashout")) {
+ response.json.getString("min_cashout")
+ } else null
val positive = when (val creditDebitIndicator =
balanceObj.getString("credit_debit_indicator")) {
"credit" -> true
"debit" -> false
else -> throw AmountParserException("Unexpected credit_debit_indicator: $creditDebitIndicator")
}
- BalanceResult.Success(SignedAmount(positive,
- Amount.fromJSONString(balanceAmount)))
+ BalanceResult.Success(
+ amount = SignedAmount(positive, Amount.fromJSONString(balanceAmount)),
+ debitThreshold = Amount.fromJSONString(debitThreshold),
+ minCashout = minCashout?.let { Amount.fromJSONString(it) }
+
+ )
} catch (e: Exception) {
Log.e(TAG, "Error parsing balance", e)
BalanceResult.Error("Invalid amount:\n${response.json.toString(2)}")
diff --git a/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt b/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt
@@ -80,7 +80,9 @@ class WithdrawManager(
val balanceResult = viewModel.balance.value
if (balanceResult !is BalanceResult.Success) return false
return try {
- balanceResult.amount.positive && amount <= balanceResult.amount.amount
+ (balanceResult.amount.positive && amount <= (balanceResult.debitThreshold + balanceResult.amount.amount)) ||
+ (!balanceResult.amount.positive && amount <= (balanceResult.debitThreshold - balanceResult.amount.amount))
+
} catch (e: IllegalStateException) {
Log.e(TAG, "Error comparing amounts", e)
null
diff --git a/cashier/src/main/res/layout-w550dp/fragment_balance.xml b/cashier/src/main/res/layout-w550dp/fragment_balance.xml
@@ -79,6 +79,22 @@
app:layout_constraintTop_toBottomOf="@+id/balanceLabel"
tools:text="100 KUDOS" />
+ <TextView
+ android:id="@+id/debitView"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:paddingStart="@dimen/default_margin"
+ android:paddingTop="8dp"
+ android:paddingEnd="@dimen/default_margin"
+ android:paddingBottom="@dimen/default_margin"
+ app:layout_constraintEnd_toStartOf="@id/guideline"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/balanceView"
+ android:visibility="gone"
+ tools:visibility="visible"
+ tools:text="@string/balance_debit_threshold" />
+
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
diff --git a/cashier/src/main/res/layout/fragment_balance.xml b/cashier/src/main/res/layout/fragment_balance.xml
@@ -45,7 +45,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/background"
- app:layout_constraintBottom_toBottomOf="@+id/balanceView"
+ app:layout_constraintBottom_toBottomOf="@+id/debitView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/lastTransactionView" />
@@ -76,6 +76,22 @@
app:layout_constraintTop_toBottomOf="@+id/balanceLabel"
tools:text="100 KUDOS" />
+ <TextView
+ android:id="@+id/debitView"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:paddingStart="@dimen/default_margin"
+ android:paddingTop="8dp"
+ android:paddingEnd="@dimen/default_margin"
+ android:paddingBottom="@dimen/default_margin"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/balanceView"
+ android:visibility="gone"
+ tools:visibility="visible"
+ tools:text="@string/balance_debit_threshold" />
+
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
diff --git a/cashier/src/main/res/values/strings.xml b/cashier/src/main/res/values/strings.xml
@@ -14,7 +14,8 @@
<string name="balance_current_label">Current balance</string>
<string name="balance_error">ERROR: %s</string>
- <string name="balance_offline">Offline. Please connect to the Internet.</string>
+ <string name="balance_offline">Offline. Please connect to the Internet.</string>\
+ <string name="balance_debit_threshold">Maximum debt: %1$s</string>
<string name="ok">OK</string>
@@ -26,6 +27,7 @@
<string name="withdraw_into">How much e-cash should be withdrawn?</string>
<string name="withdraw_error_zero">Enter positive amount!</string>
<string name="withdraw_error_insufficient_balance">Insufficient balance</string>
+ <string name="withdraw_error_under_min_cashout">Amount below minimum cash-out of %1$s</string>
<string name="withdraw_error_currency_mismatch">Error: Bank reported a different currency</string>
<string name="withdraw_error_fetch">Error communicating with bank: %s</string>
<string name="withdraw_error_timeout">No wallet tried to withdraw. Please try again.</string>