summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-02-03 16:03:29 -0300
committerTorsten Grote <t@grobox.de>2020-02-03 16:03:29 -0300
commit5441e558290e76ef30588acffed335d187b6287f (patch)
tree7147a36832ff4caaf2f40bce083fb0326bdd940c /app
parent94dd96d2481a87ce0fbad452d68afcdf0d87e067 (diff)
downloadmerchant-terminal-android-5441e558290e76ef30588acffed335d187b6287f.tar.gz
merchant-terminal-android-5441e558290e76ef30588acffed335d187b6287f.tar.bz2
merchant-terminal-android-5441e558290e76ef30588acffed335d187b6287f.zip
Fix invalid product configuration
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/net/taler/merchantpos/config/ConfigManager.kt11
-rw-r--r--app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt9
-rw-r--r--app/src/main/java/net/taler/merchantpos/order/Definitions.kt2
-rw-r--r--app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt2
-rw-r--r--app/src/main/java/net/taler/merchantpos/order/OrderManager.kt21
-rw-r--r--app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt8
6 files changed, 35 insertions, 18 deletions
diff --git a/app/src/main/java/net/taler/merchantpos/config/ConfigManager.kt b/app/src/main/java/net/taler/merchantpos/config/ConfigManager.kt
index 9009466..6c230d1 100644
--- a/app/src/main/java/net/taler/merchantpos/config/ConfigManager.kt
+++ b/app/src/main/java/net/taler/merchantpos/config/ConfigManager.kt
@@ -33,7 +33,7 @@ interface ConfigurationReceiver {
/**
* Returns true if the configuration was valid, false otherwise.
*/
- suspend fun onConfigurationReceived(json: JSONObject): Boolean
+ suspend fun onConfigurationReceived(json: JSONObject, currency: String): Boolean
}
class ConfigManager(
@@ -97,11 +97,10 @@ class ConfigManager(
mConfigUpdateResult.value = ConfigUpdateResult(null)
return
}
- this.merchantConfig = merchantConfig
val params = mapOf("instance" to merchantConfig.instance)
val req = MerchantRequest(GET, merchantConfig, "config", params, null,
- Listener { onMerchantConfigReceived(config, json, it) },
+ Listener { onMerchantConfigReceived(config, json, merchantConfig, it) },
ErrorListener { onNetworkError(it) }
)
queue.add(req)
@@ -110,20 +109,22 @@ class ConfigManager(
private fun onMerchantConfigReceived(
newConfig: Config?,
configJson: JSONObject,
+ merchantConfig: MerchantConfig,
json: JSONObject
) = scope.launch(Dispatchers.Main) {
val currency = json.getString("currency")
var configValid = true
configurationReceivers.forEach {
- configValid = configValid or it.onConfigurationReceived(configJson)
+ val result = it.onConfigurationReceived(configJson, currency)
+ configValid = result && configValid
}
if (configValid) {
newConfig?.let {
config = it
saveConfig(it)
}
- merchantConfig = merchantConfig!!.copy(currency = currency)
+ this@ConfigManager.merchantConfig = merchantConfig.copy(currency = currency)
mConfigUpdateResult.value = ConfigUpdateResult(currency)
} else {
mConfigUpdateResult.value = ConfigUpdateResult(null)
diff --git a/app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt b/app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt
index abe7d10..abee7e3 100644
--- a/app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt
@@ -3,7 +3,9 @@ package net.taler.merchantpos.config
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
-import android.view.View.*
+import android.view.View.GONE
+import android.view.View.INVISIBLE
+import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@@ -64,7 +66,10 @@ class MerchantConfigFragment : Fragment() {
override fun onStart() {
super.onStart()
// focus password if this is the only empty field
- if (!configUrlView.editText!!.text.isBlank() && !usernameView.editText!!.text.isBlank()) {
+ if (passwordView.editText!!.text.isBlank()
+ && !configUrlView.editText!!.text.isBlank()
+ && !usernameView.editText!!.text.isBlank()
+ ) {
passwordView.requestFocus()
}
}
diff --git a/app/src/main/java/net/taler/merchantpos/order/Definitions.kt b/app/src/main/java/net/taler/merchantpos/order/Definitions.kt
index d45e175..569993c 100644
--- a/app/src/main/java/net/taler/merchantpos/order/Definitions.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/Definitions.kt
@@ -1,5 +1,6 @@
package net.taler.merchantpos.order
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
import net.taler.merchantpos.Amount
@@ -10,6 +11,7 @@ data class Category(
var selected: Boolean = false
}
+@JsonIgnoreProperties("priceAsDouble")
data class Product(
@JsonProperty("product_id")
val id: String,
diff --git a/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt b/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
index d42b149..8856bda 100644
--- a/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
@@ -60,7 +60,7 @@ class OrderFragment : Fragment() {
override fun onStart() {
super.onStart()
- if (viewModel.configManager.needsConfig()) {
+ if (viewModel.configManager.needsConfig() || viewModel.configManager.merchantConfig?.currency == null) {
findNavController().navigate(R.id.action_global_merchantSettings)
}
}
diff --git a/app/src/main/java/net/taler/merchantpos/order/OrderManager.kt b/app/src/main/java/net/taler/merchantpos/order/OrderManager.kt
index 5d781a1..42a2060 100644
--- a/app/src/main/java/net/taler/merchantpos/order/OrderManager.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/OrderManager.kt
@@ -7,8 +7,11 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations.map
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
+import net.taler.merchantpos.Amount.Companion.fromString
import net.taler.merchantpos.config.ConfigurationReceiver
-import net.taler.merchantpos.order.RestartState.*
+import net.taler.merchantpos.order.RestartState.DISABLED
+import net.taler.merchantpos.order.RestartState.ENABLED
+import net.taler.merchantpos.order.RestartState.UNDO
import org.json.JSONObject
enum class RestartState { ENABLED, DISABLED, UNDO }
@@ -35,7 +38,8 @@ class OrderManager(private val mapper: ObjectMapper) : ConfigurationReceiver {
private val mRestartState = MutableLiveData<RestartState>().apply { value = DISABLED }
internal val restartState: LiveData<RestartState> = mRestartState
- override suspend fun onConfigurationReceived(json: JSONObject): Boolean {
+ @Suppress("BlockingMethodInNonBlockingContext") // run on Dispatchers.Main
+ override suspend fun onConfigurationReceived(json: JSONObject, currency: String): Boolean {
// parse categories
val categoriesStr = json.getJSONArray("categories").toString()
val categoriesType = object : TypeReference<List<Category>>() {}
@@ -46,7 +50,6 @@ class OrderManager(private val mapper: ObjectMapper) : ConfigurationReceiver {
}
// pre-select the first category
categories[0].selected = true
- mCategories.postValue(categories)
// parse products (live data gets updated in setCurrentCategory())
val productsStr = json.getJSONArray("products").toString()
@@ -56,11 +59,15 @@ class OrderManager(private val mapper: ObjectMapper) : ConfigurationReceiver {
// group products by categories
productsByCategory.clear()
products.forEach { product ->
+ val productCurrency = fromString(product.price).currency
+ if (productCurrency != currency) {
+ Log.e(TAG, "Product $product has currency $productCurrency, $currency expected")
+ return false
+ }
product.categories.forEach { categoryId ->
val category = categories.find { it.id == categoryId }
if (category == null) {
Log.e(TAG, "Product $product has unknown category $categoryId")
- onConfigurationError()
return false
}
if (productsByCategory.containsKey(category)) {
@@ -71,6 +78,7 @@ class OrderManager(private val mapper: ObjectMapper) : ConfigurationReceiver {
}
}
return if (productsByCategory.size > 0) {
+ mCategories.postValue(categories)
mProducts.postValue(productsByCategory[categories[0]])
true
} else {
@@ -78,11 +86,6 @@ class OrderManager(private val mapper: ObjectMapper) : ConfigurationReceiver {
}
}
- private fun onConfigurationError() {
- Log.e("TEST", "ERROR")
- // TODO
- }
-
internal fun setCurrentCategory(category: Category) {
val newCategories = categories.value?.apply {
forEach { if (it.selected) it.selected = false }
diff --git a/app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt b/app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt
index a3645cc..99780b0 100644
--- a/app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt
+++ b/app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt
@@ -19,11 +19,13 @@ import net.taler.merchantpos.order.Order
import net.taler.merchantpos.order.getTotalAsString
import org.json.JSONArray
import org.json.JSONObject
+import java.net.URLEncoder
import java.util.concurrent.TimeUnit.MINUTES
import java.util.concurrent.TimeUnit.SECONDS
private val TIMEOUT = MINUTES.toMillis(2)
private val CHECK_INTERVAL = SECONDS.toMillis(1)
+private const val FULFILLMENT_PREFIX = "taler://fulfillment-success/"
class PaymentManager(
private val configManager: ConfigManager,
@@ -59,12 +61,15 @@ class PaymentManager(
mPayment.value = Payment(order, summary, currency)
+ val fulfillmentId = "${System.currentTimeMillis()}-${order.hashCode()}"
+ val fulfillmentUrl =
+ "${FULFILLMENT_PREFIX}${URLEncoder.encode(summary, "UTF-8")}#$fulfillmentId"
val body = JSONObject().apply {
put("order", JSONObject().apply {
put("amount", amount)
put("summary", summary)
// fulfillment_url needs to be unique per order
- put("fulfillment_url", "https://example.com/${order.hashCode()}")
+ put("fulfillment_url", fulfillmentUrl)
put("instance", "default")
put("products", order.getProductsJson())
})
@@ -81,6 +86,7 @@ class PaymentManager(
val json = JSONArray()
forEach { product, quantity ->
val node = mapper.valueToTree<ObjectNode>(product).apply {
+ remove("categories")
put("quantity", quantity)
}
json.put(JSONObject(mapper.writeValueAsString(node)))