diff options
author | Torsten Grote <t@grobox.de> | 2020-02-03 16:03:29 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-02-03 16:03:29 -0300 |
commit | 5441e558290e76ef30588acffed335d187b6287f (patch) | |
tree | 7147a36832ff4caaf2f40bce083fb0326bdd940c /app | |
parent | 94dd96d2481a87ce0fbad452d68afcdf0d87e067 (diff) | |
download | merchant-terminal-android-5441e558290e76ef30588acffed335d187b6287f.tar.gz merchant-terminal-android-5441e558290e76ef30588acffed335d187b6287f.tar.bz2 merchant-terminal-android-5441e558290e76ef30588acffed335d187b6287f.zip |
Fix invalid product configuration
Diffstat (limited to 'app')
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))) |