From db8b71418b766258a7a4bda91e496b1b03cb28cd Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 20 Mar 2020 15:43:23 -0300 Subject: Let all apps use the same Amount class The wallet now also uses taler-kotlin-common --- wallet/.gitlab-ci.yml | 2 +- wallet/build.gradle | 9 +- wallet/src/main/java/net/taler/wallet/Amount.kt | 141 --------------------- .../main/java/net/taler/wallet/BalanceFragment.kt | 9 +- .../src/main/java/net/taler/wallet/MainActivity.kt | 1 - wallet/src/main/java/net/taler/wallet/Utils.kt | 40 ------ .../main/java/net/taler/wallet/WalletViewModel.kt | 5 +- .../java/net/taler/wallet/history/HistoryEvent.kt | 41 +++--- .../net/taler/wallet/history/ReserveTransaction.kt | 1 + .../taler/wallet/history/WalletHistoryAdapter.kt | 28 ++-- .../java/net/taler/wallet/payment/ContractTerms.kt | 56 -------- .../net/taler/wallet/payment/PaymentManager.kt | 5 +- .../wallet/payment/PaymentSuccessfulFragment.kt | 2 +- .../net/taler/wallet/payment/ProductAdapter.kt | 3 +- .../taler/wallet/payment/PromptPaymentFragment.kt | 14 +- .../wallet/withdraw/PromptWithdrawFragment.kt | 8 +- .../wallet/withdraw/ReviewExchangeTosFragment.kt | 4 +- .../net/taler/wallet/withdraw/WithdrawManager.kt | 4 +- wallet/src/main/res/values/strings.xml | 2 +- .../test/java/net/taler/wallet/ExampleUnitTest.kt | 33 ----- 20 files changed, 57 insertions(+), 351 deletions(-) delete mode 100644 wallet/src/main/java/net/taler/wallet/Amount.kt delete mode 100644 wallet/src/main/java/net/taler/wallet/Utils.kt delete mode 100644 wallet/src/main/java/net/taler/wallet/payment/ContractTerms.kt delete mode 100644 wallet/src/test/java/net/taler/wallet/ExampleUnitTest.kt (limited to 'wallet') diff --git a/wallet/.gitlab-ci.yml b/wallet/.gitlab-ci.yml index a07cb28..acd4a49 100644 --- a/wallet/.gitlab-ci.yml +++ b/wallet/.gitlab-ci.yml @@ -1,7 +1,7 @@ .binary_deps: only: changes: - - "wallet" + - wallet/**/* before_script: - wget "https://git.taler.net/wallet-android.git/plain/akono.aar?h=binary-deps" -O akono/akono.aar - mkdir -p app/src/main/assets diff --git a/wallet/build.gradle b/wallet/build.gradle index c31e392..3b8e13d 100644 --- a/wallet/build.gradle +++ b/wallet/build.gradle @@ -23,7 +23,7 @@ android { buildToolsVersion "29.0.3" defaultConfig { applicationId "net.taler.wallet" - minSdkVersion 21 + minSdkVersion 24 targetSdkVersion 29 versionCode 6 versionName "0.6.0pre8" @@ -48,10 +48,8 @@ android { dependencies { implementation project(":akono") + implementation project(":taler-kotlin-common") - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.core:core-ktx:1.2.0' implementation 'com.google.android.material:material:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' @@ -61,12 +59,9 @@ dependencies { // ViewModel and LiveData def lifecycle_version = "2.2.0" - implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" - implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" // QR codes - implementation 'com.google.zxing:core:3.4.0' implementation 'com.journeyapps:zxing-android-embedded:3.2.0@aar' // Nicer ProgressBar diff --git a/wallet/src/main/java/net/taler/wallet/Amount.kt b/wallet/src/main/java/net/taler/wallet/Amount.kt deleted file mode 100644 index a19e9bc..0000000 --- a/wallet/src/main/java/net/taler/wallet/Amount.kt +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This file is part of GNU Taler - * (C) 2020 Taler Systems S.A. - * - * GNU Taler is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 3, or (at your option) any later version. - * - * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * GNU Taler; see the file COPYING. If not, see - */ - -@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") - -package net.taler.wallet - -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.deser.std.StdDeserializer -import org.json.JSONObject -import kotlin.math.round - -private const val FRACTIONAL_BASE = 1e8 - -@JsonDeserialize(using = AmountDeserializer::class) -data class Amount(val currency: String, val amount: String) { - fun isZero(): Boolean { - return amount.toDouble() == 0.0 - } - - companion object { - fun fromJson(jsonAmount: JSONObject): Amount { - val amountCurrency = jsonAmount.getString("currency") - val amountValue = jsonAmount.getString("value") - val amountFraction = jsonAmount.getString("fraction") - val amountIntValue = Integer.parseInt(amountValue) - val amountIntFraction = Integer.parseInt(amountFraction) - return Amount( - amountCurrency, - (amountIntValue + amountIntFraction / FRACTIONAL_BASE).toString() - ) - } - - fun fromString(strAmount: String): Amount { - val components = strAmount.split(":") - return Amount(components[0], components[1]) - } - } - - override fun toString(): String { - return String.format("%.2f $currency", amount.toDouble()) - } -} - -class AmountDeserializer : StdDeserializer(Amount::class.java) { - override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Amount { - val node = p.codec.readValue(p, String::class.java) - return Amount.fromString(node) - } -} - -class ParsedAmount( - /** - * name of the currency using either a three-character ISO 4217 currency code, - * or a regional currency identifier starting with a "*" followed by at most 10 characters. - * ISO 4217 exponents in the name are not supported, - * although the "fraction" is corresponds to an ISO 4217 exponent of 6. - */ - val currency: String, - - /** - * unsigned 32 bit value in the currency, - * note that "1" here would correspond to 1 EUR or 1 USD, depending on currency, not 1 cent. - */ - val value: UInt, - - /** - * unsigned 32 bit fractional value to be added to value - * representing an additional currency fraction, - * in units of one millionth (1e-6) of the base currency value. - * For example, a fraction of 500,000 would correspond to 50 cents. - */ - val fraction: Double -) { - companion object { - fun parseAmount(str: String): ParsedAmount { - val split = str.split(":") - check(split.size == 2) - val currency = split[0] - val valueSplit = split[1].split(".") - val value = valueSplit[0].toUInt() - val fraction: Double = if (valueSplit.size > 1) { - round("0.${valueSplit[1]}".toDouble() * FRACTIONAL_BASE) - } else 0.0 - return ParsedAmount(currency, value, fraction) - } - } - - operator fun minus(other: ParsedAmount): ParsedAmount { - check(currency == other.currency) { "Can only subtract from same currency" } - var resultValue = value - var resultFraction = fraction - if (resultFraction < other.fraction) { - if (resultValue < 1u) { - return ParsedAmount(currency, 0u, 0.0) - } - resultValue-- - resultFraction += FRACTIONAL_BASE - } - check(resultFraction >= other.fraction) - resultFraction -= other.fraction - if (resultValue < other.value) { - return ParsedAmount(currency, 0u, 0.0) - } - resultValue -= other.value - return ParsedAmount(currency, resultValue, resultFraction) - } - - fun isZero(): Boolean { - return value == 0u && fraction == 0.0 - } - - @Suppress("unused") - fun toJSONString(): String { - return "$currency:${getValueString()}" - } - - override fun toString(): String { - return "${getValueString()} $currency" - } - - private fun getValueString(): String { - return "$value${(fraction / FRACTIONAL_BASE).toString().substring(1)}" - } - -} diff --git a/wallet/src/main/java/net/taler/wallet/BalanceFragment.kt b/wallet/src/main/java/net/taler/wallet/BalanceFragment.kt index 84a1b3c..e4ec681 100644 --- a/wallet/src/main/java/net/taler/wallet/BalanceFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/BalanceFragment.kt @@ -177,7 +177,7 @@ class BalanceAdapter : Adapter() { fun bind(item: BalanceItem) { currencyView.text = item.available.currency - amountView.text = item.available.amount + amountView.text = item.available.amountStr val amountIncoming = item.pendingIncoming if (amountIncoming.isZero()) { @@ -186,11 +186,8 @@ class BalanceAdapter : Adapter() { } else { balanceInboundAmount.visibility = VISIBLE balanceInboundLabel.visibility = VISIBLE - balanceInboundAmount.text = v.context.getString( - R.string.balances_inbound_amount, - amountIncoming.amount, - amountIncoming.currency - ) + balanceInboundAmount.text = + v.context.getString(R.string.balances_inbound_amount, amountIncoming) } } } diff --git a/wallet/src/main/java/net/taler/wallet/MainActivity.kt b/wallet/src/main/java/net/taler/wallet/MainActivity.kt index c2f20f7..df7bdc6 100644 --- a/wallet/src/main/java/net/taler/wallet/MainActivity.kt +++ b/wallet/src/main/java/net/taler/wallet/MainActivity.kt @@ -59,7 +59,6 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener, private lateinit var nav: NavController - @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) diff --git a/wallet/src/main/java/net/taler/wallet/Utils.kt b/wallet/src/main/java/net/taler/wallet/Utils.kt deleted file mode 100644 index fb0b3ae..0000000 --- a/wallet/src/main/java/net/taler/wallet/Utils.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of GNU Taler - * (C) 2020 Taler Systems S.A. - * - * GNU Taler is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 3, or (at your option) any later version. - * - * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * GNU Taler; see the file COPYING. If not, see - */ - -package net.taler.wallet - -import android.view.View -import android.view.View.INVISIBLE -import android.view.View.VISIBLE - -fun View.fadeIn(endAction: () -> Unit = {}) { - if (visibility == VISIBLE) return - alpha = 0f - visibility = VISIBLE - animate().alpha(1f).withEndAction { - if (context != null) endAction.invoke() - }.start() -} - -fun View.fadeOut(endAction: () -> Unit = {}) { - if (visibility == INVISIBLE) return - animate().alpha(0f).withEndAction { - if (context == null) return@withEndAction - visibility = INVISIBLE - alpha = 1f - endAction.invoke() - }.start() -} diff --git a/wallet/src/main/java/net/taler/wallet/WalletViewModel.kt b/wallet/src/main/java/net/taler/wallet/WalletViewModel.kt index 14a800f..9599123 100644 --- a/wallet/src/main/java/net/taler/wallet/WalletViewModel.kt +++ b/wallet/src/main/java/net/taler/wallet/WalletViewModel.kt @@ -26,6 +26,7 @@ import androidx.lifecycle.distinctUntilChanged import com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule +import net.taler.common.Amount import net.taler.wallet.backend.WalletBackendApi import net.taler.wallet.history.HistoryManager import net.taler.wallet.payment.PaymentManager @@ -90,10 +91,10 @@ class WalletViewModel(val app: Application) : AndroidViewModel(app) { for (currency in currencyList) { val jsonAmount = byCurrency.getJSONObject(currency) .getJSONObject("available") - val amount = Amount.fromJson(jsonAmount) + val amount = Amount.fromJsonObject(jsonAmount) val jsonAmountIncoming = byCurrency.getJSONObject(currency) .getJSONObject("pendingIncoming") - val amountIncoming = Amount.fromJson(jsonAmountIncoming) + val amountIncoming = Amount.fromJsonObject(jsonAmountIncoming) balanceList.add(BalanceItem(amount, amountIncoming)) } mBalances.postValue(balanceList) diff --git a/wallet/src/main/java/net/taler/wallet/history/HistoryEvent.kt b/wallet/src/main/java/net/taler/wallet/history/HistoryEvent.kt index 9e5c99d..b78c062 100644 --- a/wallet/src/main/java/net/taler/wallet/history/HistoryEvent.kt +++ b/wallet/src/main/java/net/taler/wallet/history/HistoryEvent.kt @@ -29,7 +29,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo import com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY import com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME import com.fasterxml.jackson.annotation.JsonTypeName -import net.taler.wallet.ParsedAmount.Companion.parseAmount +import net.taler.common.Amount +import net.taler.common.Timestamp import net.taler.wallet.R import org.json.JSONObject @@ -70,13 +71,6 @@ enum class RefreshReason { BACKUP_RESTORED } - -@JsonInclude(NON_EMPTY) -class Timestamp( - @JsonProperty("t_ms") - val ms: Long -) - @JsonInclude(NON_EMPTY) class ReserveShortInfo( /** @@ -181,12 +175,12 @@ class ReserveBalanceUpdatedEvent( /** * Amount currently left in the reserve. */ - val amountReserveBalance: String, + val amountReserveBalance: Amount, /** * Amount we expected to be in the reserve at that time, * considering ongoing withdrawals from that reserve. */ - val amountExpected: String + val amountExpected: Amount ) : HistoryEvent(timestamp) { override val title = R.string.history_event_reserve_balance_updated } @@ -208,11 +202,11 @@ class HistoryWithdrawnEvent( * Amount that has been subtracted from the reserve's balance * for this withdrawal. */ - val amountWithdrawnRaw: String, + val amountWithdrawnRaw: Amount, /** * Amount that actually was added to the wallet's balance. */ - val amountWithdrawnEffective: String + val amountWithdrawnEffective: Amount ) : HistoryEvent(timestamp) { override val layout = R.layout.history_receive override val title = R.string.history_event_withdrawn @@ -263,7 +257,7 @@ class HistoryPaymentSentEvent( /** * Amount that was paid, including deposit and wire fees. */ - val amountPaidWithFees: String, + val amountPaidWithFees: Amount, /** * Session ID that the payment was (re-)submitted under. */ @@ -285,7 +279,7 @@ class HistoryPaymentAbortedEvent( /** * Amount that was lost due to refund and refreshing fees. */ - val amountLost: String + val amountLost: Amount ) : HistoryEvent(timestamp) { override val layout = R.layout.history_payment override val title = R.string.history_event_payment_aborted @@ -300,11 +294,11 @@ class HistoryRefreshedEvent( * Amount that is now available again because it has * been refreshed. */ - val amountRefreshedEffective: String, + val amountRefreshedEffective: Amount, /** * Amount that we spent for refreshing. */ - val amountRefreshedRaw: String, + val amountRefreshedRaw: Amount, /** * Why was the refreshing done? */ @@ -321,8 +315,7 @@ class HistoryRefreshedEvent( override val layout = R.layout.history_payment override val icon = R.drawable.history_refresh override val title = R.string.history_event_refreshed - override val showToUser = - !(parseAmount(amountRefreshedRaw) - parseAmount(amountRefreshedEffective)).isZero() + override val showToUser = !(amountRefreshedRaw - amountRefreshedEffective).isZero() } @JsonTypeName("order-redirected") @@ -352,7 +345,7 @@ class HistoryTipAcceptedEvent( /** * Raw amount of the tip, without extra fees that apply. */ - val tipRaw: String + val tipRaw: Amount ) : HistoryEvent(timestamp) { override val icon = R.drawable.history_tip_accepted override val title = R.string.history_event_tip_accepted @@ -370,7 +363,7 @@ class HistoryTipDeclinedEvent( /** * Raw amount of the tip, without extra fees that apply. */ - val tipAmount: String + val tipAmount: Amount ) : HistoryEvent(timestamp) { override val icon = R.drawable.history_tip_declined override val title = R.string.history_event_tip_declined @@ -391,15 +384,15 @@ class HistoryRefundedEvent( * Part of the refund that couldn't be applied because * the refund permissions were expired. */ - val amountRefundedInvalid: String, + val amountRefundedInvalid: Amount, /** * Amount that has been refunded by the merchant. */ - val amountRefundedRaw: String, + val amountRefundedRaw: Amount, /** * Amount will be added to the wallet's balance after fees and refreshing. */ - val amountRefundedEffective: String + val amountRefundedEffective: Amount ) : HistoryEvent(timestamp) { override val icon = R.drawable.history_refund override val title = R.string.history_event_refund @@ -444,7 +437,7 @@ data class OrderShortInfo( /** * Amount that must be paid for the contract. */ - val amount: String, + val amount: Amount, /** * Summary of the proposal, given by the merchant. */ diff --git a/wallet/src/main/java/net/taler/wallet/history/ReserveTransaction.kt b/wallet/src/main/java/net/taler/wallet/history/ReserveTransaction.kt index 45c539c..6c8fdaa 100644 --- a/wallet/src/main/java/net/taler/wallet/history/ReserveTransaction.kt +++ b/wallet/src/main/java/net/taler/wallet/history/ReserveTransaction.kt @@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo import com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY import com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME import com.fasterxml.jackson.annotation.JsonTypeName +import net.taler.common.Timestamp @JsonTypeInfo( diff --git a/wallet/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt b/wallet/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt index 71bdebc..5424b62 100644 --- a/wallet/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt +++ b/wallet/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt @@ -38,9 +38,8 @@ import androidx.annotation.CallSuper import androidx.core.net.toUri import androidx.recyclerview.widget.RecyclerView.Adapter import androidx.recyclerview.widget.RecyclerView.ViewHolder +import net.taler.common.Amount import net.taler.wallet.BuildConfig -import net.taler.wallet.ParsedAmount -import net.taler.wallet.ParsedAmount.Companion.parseAmount import net.taler.wallet.R @@ -119,7 +118,7 @@ internal class WalletHistoryAdapter( info.text = when (event) { is ExchangeAddedEvent -> event.exchangeBaseUrl is ExchangeUpdatedEvent -> event.exchangeBaseUrl - is ReserveBalanceUpdatedEvent -> parseAmount(event.amountReserveBalance).toString() + is ReserveBalanceUpdatedEvent -> event.amountReserveBalance.toString() is HistoryPaymentSentEvent -> event.orderShortInfo.summary is HistoryOrderAcceptedEvent -> event.orderShortInfo.summary is HistoryOrderRefusedEvent -> event.orderShortInfo.summary @@ -151,36 +150,30 @@ internal class WalletHistoryAdapter( title.text = getHostname(event.exchangeBaseUrl) summary.setText(event.title) - val parsedEffective = parseAmount(event.amountWithdrawnEffective) - val parsedRaw = parseAmount(event.amountWithdrawnRaw) - showAmounts(parsedEffective, parsedRaw) + showAmounts(event.amountWithdrawnEffective, event.amountWithdrawnRaw) } private fun bind(event: HistoryRefundedEvent) { title.text = event.orderShortInfo.summary summary.setText(event.title) - val parsedEffective = parseAmount(event.amountRefundedEffective) - val parsedRaw = parseAmount(event.amountRefundedRaw) - showAmounts(parsedEffective, parsedRaw) + showAmounts(event.amountRefundedEffective, event.amountRefundedRaw) } private fun bind(event: HistoryTipAcceptedEvent) { title.setText(event.title) summary.text = null - val amount = parseAmount(event.tipRaw) - showAmounts(amount, amount) + showAmounts(event.tipRaw, event.tipRaw) } private fun bind(event: HistoryTipDeclinedEvent) { title.setText(event.title) summary.text = null - val amount = parseAmount(event.tipAmount) - showAmounts(amount, amount) + showAmounts(event.tipAmount, event.tipAmount) amountWithdrawn.paintFlags = amountWithdrawn.paintFlags or STRIKE_THRU_TEXT_FLAG } - private fun showAmounts(effective: ParsedAmount, raw: ParsedAmount) { + private fun showAmounts(effective: Amount, raw: Amount) { @SuppressLint("SetTextI18n") amountWithdrawn.text = "+$raw" val calculatedFee = raw - effective @@ -220,19 +213,18 @@ internal class WalletHistoryAdapter( private fun bind(event: HistoryPaymentSentEvent) { title.text = event.orderShortInfo.summary @SuppressLint("SetTextI18n") - amountPaidWithFees.text = "-${parseAmount(event.amountPaidWithFees)}" + amountPaidWithFees.text = "-${event.amountPaidWithFees}" } private fun bind(event: HistoryPaymentAbortedEvent) { title.text = event.orderShortInfo.summary @SuppressLint("SetTextI18n") - amountPaidWithFees.text = "-${parseAmount(event.amountLost)}" + amountPaidWithFees.text = "-${event.amountLost}" } private fun bind(event: HistoryRefreshedEvent) { title.text = "" - val fee = - parseAmount(event.amountRefreshedRaw) - parseAmount(event.amountRefreshedEffective) + val fee = event.amountRefreshedRaw - event.amountRefreshedEffective @SuppressLint("SetTextI18n") if (fee.isZero()) amountPaidWithFees.text = null else amountPaidWithFees.text = "-$fee" diff --git a/wallet/src/main/java/net/taler/wallet/payment/ContractTerms.kt b/wallet/src/main/java/net/taler/wallet/payment/ContractTerms.kt deleted file mode 100644 index da91dea..0000000 --- a/wallet/src/main/java/net/taler/wallet/payment/ContractTerms.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of GNU Taler - * (C) 2020 Taler Systems S.A. - * - * GNU Taler is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 3, or (at your option) any later version. - * - * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * GNU Taler; see the file COPYING. If not, see - */ - -package net.taler.wallet.payment - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import com.fasterxml.jackson.annotation.JsonProperty -import net.taler.wallet.Amount - - -@JsonIgnoreProperties(ignoreUnknown = true) -data class ContractTerms( - val summary: String, - val products: List, - val amount: Amount -) - -interface Product { - val id: String? - val description: String - val price: Amount - val location: String? - val image: String? -} - -@JsonIgnoreProperties("totalPrice") -data class ContractProduct( - @JsonProperty("product_id") - override val id: String?, - override val description: String, - override val price: Amount, - @JsonProperty("delivery_location") - override val location: String?, - override val image: String?, - val quantity: Int -) : Product { - - val totalPrice: Amount by lazy { - val amount = price.amount.toDouble() * quantity - Amount(price.currency, amount.toString()) - } - -} diff --git a/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt b/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt index ee0edaf..8aaebbc 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt @@ -22,7 +22,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue -import net.taler.wallet.Amount +import net.taler.common.Amount +import net.taler.common.ContractTerms import net.taler.wallet.TAG import net.taler.wallet.backend.WalletBackendApi import org.json.JSONObject @@ -79,7 +80,7 @@ class PaymentManager( "payment-possible" -> PayStatus.Prepared( contractTerms = getContractTerms(json), proposalId = json.getString("proposalId"), - totalFees = Amount.fromJson(json.getJSONObject("totalFees")) + totalFees = Amount.fromJsonObject(json.getJSONObject("totalFees")) ) "paid" -> PayStatus.AlreadyPaid(getContractTerms(json)) "insufficient-balance" -> PayStatus.InsufficientBalance(getContractTerms(json)) diff --git a/wallet/src/main/java/net/taler/wallet/payment/PaymentSuccessfulFragment.kt b/wallet/src/main/java/net/taler/wallet/payment/PaymentSuccessfulFragment.kt index 2084c45..2a868b0 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PaymentSuccessfulFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PaymentSuccessfulFragment.kt @@ -23,8 +23,8 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import kotlinx.android.synthetic.main.fragment_payment_successful.* +import net.taler.common.fadeIn import net.taler.wallet.R -import net.taler.wallet.fadeIn /** * Fragment that shows the success message for a payment. diff --git a/wallet/src/main/java/net/taler/wallet/payment/ProductAdapter.kt b/wallet/src/main/java/net/taler/wallet/payment/ProductAdapter.kt index 4b1b062..24bbd27 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/ProductAdapter.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/ProductAdapter.kt @@ -28,6 +28,7 @@ import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.ViewHolder +import net.taler.common.ContractProduct import net.taler.wallet.R import net.taler.wallet.payment.ProductAdapter.ProductViewHolder @@ -76,7 +77,7 @@ internal class ProductAdapter(private val listener: ProductImageClickListener) : } else { image.visibility = VISIBLE // product.image was validated before, so non-null below - val match = REGEX_PRODUCT_IMAGE.matchEntire(product.image)!! + val match = REGEX_PRODUCT_IMAGE.matchEntire(product.image!!)!! val decodedString = Base64.decode(match.groups[2]!!.value, Base64.DEFAULT) val bitmap = decodeByteArray(decodedString, 0, decodedString.size) image.setImageBitmap(bitmap) diff --git a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt index 44dcf26..2eea59e 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt @@ -16,7 +16,6 @@ package net.taler.wallet.payment -import android.annotation.SuppressLint import android.graphics.Bitmap import android.os.Bundle import android.view.LayoutInflater @@ -33,11 +32,12 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionManager.beginDelayedTransition import kotlinx.android.synthetic.main.payment_bottom_bar.* import kotlinx.android.synthetic.main.payment_details.* -import net.taler.wallet.Amount +import net.taler.common.Amount +import net.taler.common.ContractTerms +import net.taler.common.fadeIn +import net.taler.common.fadeOut import net.taler.wallet.R import net.taler.wallet.WalletViewModel -import net.taler.wallet.fadeIn -import net.taler.wallet.fadeOut /** * Show a payment and ask the user to accept/decline. @@ -144,11 +144,9 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener { adapter.setItems(contractTerms.products) if (contractTerms.products.size == 1) paymentManager.toggleDetailsShown() val amount = contractTerms.amount - @SuppressLint("SetTextI18n") - totalView.text = "${amount.amount} ${amount.currency}" + totalView.text = amount.toString() if (totalFees != null && !totalFees.isZero()) { - val fee = "${totalFees.amount} ${totalFees.currency}" - feeView.text = getString(R.string.payment_fee, fee) + feeView.text = getString(R.string.payment_fee, totalFees) feeView.fadeIn() } else { feeView.visibility = GONE diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt index 454816b..8fb4cb8 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt @@ -16,7 +16,6 @@ package net.taler.wallet.withdraw -import android.annotation.SuppressLint import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -26,10 +25,10 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController import kotlinx.android.synthetic.main.fragment_prompt_withdraw.* +import net.taler.common.fadeIn +import net.taler.common.fadeOut import net.taler.wallet.R import net.taler.wallet.WalletViewModel -import net.taler.wallet.fadeIn -import net.taler.wallet.fadeOut import net.taler.wallet.withdraw.WithdrawStatus.Loading import net.taler.wallet.withdraw.WithdrawStatus.TermsOfServiceReviewRequired import net.taler.wallet.withdraw.WithdrawStatus.Withdrawing @@ -73,8 +72,7 @@ class PromptWithdrawFragment : Fragment() { progressBar.fadeOut() introView.fadeIn() - @SuppressLint("SetTextI18n") - withdrawAmountView.text = "${status.amount.amount} ${status.amount.currency}" + withdrawAmountView.text = status.amount.toString() withdrawAmountView.fadeIn() feeView.fadeIn() diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt index cd01a33..eac9e13 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt @@ -26,10 +26,10 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController import kotlinx.android.synthetic.main.fragment_review_exchange_tos.* +import net.taler.common.fadeIn +import net.taler.common.fadeOut import net.taler.wallet.R import net.taler.wallet.WalletViewModel -import net.taler.wallet.fadeIn -import net.taler.wallet.fadeOut class ReviewExchangeTosFragment : Fragment() { diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt index e3af757..d686465 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt @@ -18,7 +18,7 @@ package net.taler.wallet.withdraw import android.util.Log import androidx.lifecycle.MutableLiveData -import net.taler.wallet.Amount +import net.taler.common.Amount import net.taler.wallet.TAG import net.taler.wallet.backend.WalletBackendApi import org.json.JSONObject @@ -124,7 +124,7 @@ class WithdrawManager(private val walletBackendApi: WalletBackendApi) { } val wi = result.getJSONObject("bankWithdrawDetails") val suggestedExchange = wi.getString("suggestedExchange") - val amount = Amount.fromJson(wi.getJSONObject("amount")) + val amount = Amount.fromJsonObject(wi.getJSONObject("amount")) val ei = result.getJSONObject("exchangeWithdrawDetails") val termsOfServiceAccepted = ei.getBoolean("termsOfServiceAccepted") diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml index 8981e04..04a507b 100644 --- a/wallet/src/main/res/values/strings.xml +++ b/wallet/src/main/res/values/strings.xml @@ -40,7 +40,7 @@ my aid Balances - +%1s %2s + +%s inbound There is no digital cash in your wallet.\n\nYou can get test money from the demo bank:\n\nhttps://bank.demo.taler.net diff --git a/wallet/src/test/java/net/taler/wallet/ExampleUnitTest.kt b/wallet/src/test/java/net/taler/wallet/ExampleUnitTest.kt deleted file mode 100644 index de74f68..0000000 --- a/wallet/src/test/java/net/taler/wallet/ExampleUnitTest.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of GNU Taler - * (C) 2020 Taler Systems S.A. - * - * GNU Taler is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 3, or (at your option) any later version. - * - * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * GNU Taler; see the file COPYING. If not, see - */ - -package net.taler.wallet - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} -- cgit v1.2.3