aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-03-30 14:17:09 -0300
committerTorsten Grote <t@grobox.de>2020-03-30 14:17:09 -0300
commitdb0cf385fe707091f219cc61fb4e12b5b1fe64d0 (patch)
treec50aca48f996e0dec20315cde0ae4d278bdf0640
parent1dbc22f1faba07331953d761097d5ad91ffff5ce (diff)
downloadtaler-android-db0cf385fe707091f219cc61fb4e12b5b1fe64d0.tar.gz
taler-android-db0cf385fe707091f219cc61fb4e12b5b1fe64d0.tar.bz2
taler-android-db0cf385fe707091f219cc61fb4e12b5b1fe64d0.zip
Fix amount serialization in PoS app
-rw-r--r--merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt15
-rw-r--r--merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt14
-rw-r--r--merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt5
-rw-r--r--merchant-terminal/src/main/res/values/strings.xml1
-rw-r--r--taler-kotlin-common/src/main/java/net/taler/common/Amount.kt33
5 files changed, 47 insertions, 21 deletions
diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt
index 609eadd..7652ca4 100644
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt
+++ b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt
@@ -28,6 +28,8 @@ import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.fragment_refund.*
+import net.taler.common.Amount
+import net.taler.common.AmountParserException
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.common.navigate
@@ -52,7 +54,7 @@ class RefundFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val item = refundManager.toBeRefunded ?: throw IllegalStateException()
- amountInputView.setText(item.amount.toString())
+ amountInputView.setText(item.amount.amountStr)
currencyView.text = item.amount.currency
abortButton.setOnClickListener { findNavController().navigateUp() }
refundButton.setOnClickListener { onRefundButtonClicked(item) }
@@ -63,12 +65,17 @@ class RefundFragment : Fragment() {
}
private fun onRefundButtonClicked(item: HistoryItem) {
- val inputAmount = amountInputView.text.toString().toDouble()
- if (inputAmount > item.amountStr.toDouble()) { // TODO real Amount comparision
+ val inputAmount = try {
+ Amount.fromString(item.amount.currency, amountInputView.text.toString())
+ } catch (e: AmountParserException) {
+ amountView.error = getString(R.string.refund_error_invalid_amount)
+ return
+ }
+ if (inputAmount > item.amount) {
amountView.error = getString(R.string.refund_error_max_amount, item.amountStr)
return
}
- if (inputAmount <= 0.0) {
+ if (inputAmount.isZero()) {
amountView.error = getString(R.string.refund_error_zero)
return
}
diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt
index 270b3b8..910116e 100644
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt
+++ b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt
@@ -24,6 +24,7 @@ import com.android.volley.Request.Method.POST
import com.android.volley.RequestQueue
import com.android.volley.Response.ErrorListener
import com.android.volley.Response.Listener
+import net.taler.common.Amount
import net.taler.merchantpos.config.ConfigManager
import net.taler.merchantpos.config.MerchantRequest
import org.json.JSONObject
@@ -34,7 +35,7 @@ sealed class RefundResult {
class Success(
val refundUri: String,
val item: HistoryItem,
- val amount: Double,
+ val amount: Amount,
val reason: String
) : RefundResult()
}
@@ -44,6 +45,10 @@ class RefundManager(
private val queue: RequestQueue
) {
+ companion object {
+ val TAG = RefundManager::class.java.simpleName
+ }
+
var toBeRefunded: HistoryItem? = null
private set
@@ -57,14 +62,15 @@ class RefundManager(
}
@UiThread
- internal fun refund(item: HistoryItem, amount: Double, reason: String) {
+ internal fun refund(item: HistoryItem, amount: Amount, reason: String) {
val merchantConfig = configManager.merchantConfig!!
val refundRequest = mapOf(
"order_id" to item.orderId,
- "refund" to "${item.amount.currency}:$amount",
+ "refund" to amount.toJSONString(),
"reason" to reason
)
val body = JSONObject(refundRequest)
+ Log.d(TAG, body.toString(4))
val req = MerchantRequest(POST, merchantConfig, "refund", null, body,
Listener { onRefundResponse(it, item, amount, reason) },
ErrorListener { onRefundError() }
@@ -76,7 +82,7 @@ class RefundManager(
private fun onRefundResponse(
json: JSONObject,
item: HistoryItem,
- amount: Double,
+ amount: Amount,
reason: String
) {
if (!json.has("contract_terms")) {
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 f83370e..054d7cd 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
@@ -71,9 +71,9 @@ class PaymentManager(
val merchantConfig = configManager.merchantConfig!!
val currency = merchantConfig.currency!!
- val amount = order.total.toJSONString()
val summary = order.summary
val summaryI18n = order.summaryI18n
+// val refundDeadline = Timestamp(System.currentTimeMillis() + HOURS.toMillis(2))
mPayment.value = Payment(order, summary, currency)
@@ -82,12 +82,13 @@ class PaymentManager(
"${FULFILLMENT_PREFIX}${URLEncoder.encode(summary, "UTF-8")}#$fulfillmentId"
val body = JSONObject().apply {
put("order", JSONObject().apply {
- put("amount", amount)
+ put("amount", order.total.toJSONString())
put("summary", summary)
if (summaryI18n != null) put("summary_i18n", order.summaryI18n)
// fulfillment_url needs to be unique per order
put("fulfillment_url", fulfillmentUrl)
put("instance", "default")
+// put("refund_deadline", JSONObject(mapper.writeValueAsString(refundDeadline)))
put("products", order.getProductsJson())
})
}
diff --git a/merchant-terminal/src/main/res/values/strings.xml b/merchant-terminal/src/main/res/values/strings.xml
index 863ae6f..756ef38 100644
--- a/merchant-terminal/src/main/res/values/strings.xml
+++ b/merchant-terminal/src/main/res/values/strings.xml
@@ -53,6 +53,7 @@
<string name="refund_abort">Abort</string>
<string name="refund_confirm">Give Refund</string>
<string name="refund_error_max_amount">Greater than order amount of %s</string>
+ <string name="refund_error_invalid_amount">Invalid amount</string>
<string name="refund_error_zero">Needs to be positive amount</string>
<string name="refund_error_backend">Error processing refund</string>
<string name="refund_error_deadline">Refund deadline has passed</string>
diff --git a/taler-kotlin-common/src/main/java/net/taler/common/Amount.kt b/taler-kotlin-common/src/main/java/net/taler/common/Amount.kt
index 49b699f..bd12a40 100644
--- a/taler-kotlin-common/src/main/java/net/taler/common/Amount.kt
+++ b/taler-kotlin-common/src/main/java/net/taler/common/Amount.kt
@@ -17,30 +17,24 @@
package net.taler.common
import android.annotation.SuppressLint
+import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonMappingException
+import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
+import com.fasterxml.jackson.databind.ser.std.StdSerializer
import org.json.JSONObject
import java.lang.Math.floorDiv
import kotlin.math.pow
import kotlin.math.roundToInt
-class AmountDeserializer : StdDeserializer<Amount>(Amount::class.java) {
- override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Amount {
- val node = p.codec.readValue(p, String::class.java)
- try {
- return Amount.fromJSONString(node)
- } catch (e: AmountParserException) {
- throw JsonMappingException(p, "Error parsing Amount", e)
- }
- }
-}
-
class AmountParserException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause)
class AmountOverflowException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause)
+@JsonSerialize(using = AmountSerializer::class)
@JsonDeserialize(using = AmountDeserializer::class)
data class Amount(
/**
@@ -215,3 +209,20 @@ data class Amount(
}
}
+
+class AmountSerializer : StdSerializer<Amount>(Amount::class.java) {
+ override fun serialize(value: Amount, gen: JsonGenerator, provider: SerializerProvider) {
+ gen.writeString(value.toJSONString())
+ }
+}
+
+class AmountDeserializer : StdDeserializer<Amount>(Amount::class.java) {
+ override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Amount {
+ val node = p.codec.readValue(p, String::class.java)
+ try {
+ return Amount.fromJSONString(node)
+ } catch (e: AmountParserException) {
+ throw JsonMappingException(p, "Error parsing Amount", e)
+ }
+ }
+}