From 35f7ed512ed7445362d6caee1bf60441f4ce979e Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 4 Aug 2020 09:46:38 -0300 Subject: [pos] Implement new refund API (untested since there is no wallet support) Also do a bit of code cleanup and minor refactorings This also removes the volley HTTP library which is not needed anymore --- .../net/taler/merchantpos/config/ConfigFragment.kt | 164 +++++++++++++++++++++ .../merchantpos/config/MerchantConfigFragment.kt | 164 --------------------- .../taler/merchantpos/config/MerchantRequest.kt | 59 -------- 3 files changed, 164 insertions(+), 223 deletions(-) create mode 100644 merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt delete mode 100644 merchant-terminal/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt delete mode 100644 merchant-terminal/src/main/java/net/taler/merchantpos/config/MerchantRequest.kt (limited to 'merchant-terminal/src/main/java/net/taler/merchantpos/config') diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt new file mode 100644 index 0000000..daddbff --- /dev/null +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt @@ -0,0 +1,164 @@ +/* + * 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.merchantpos.config + +import android.net.Uri +import android.os.Bundle +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +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 +import androidx.lifecycle.Observer +import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG +import com.google.android.material.snackbar.Snackbar +import kotlinx.android.synthetic.main.fragment_merchant_config.* +import net.taler.common.navigate +import net.taler.merchantpos.MainViewModel +import net.taler.merchantpos.R +import net.taler.merchantpos.config.ConfigFragmentDirections.Companion.actionSettingsToOrder +import net.taler.merchantpos.topSnackbar + +/** + * Fragment that displays merchant settings. + */ +class ConfigFragment : Fragment() { + + private val model: MainViewModel by activityViewModels() + private val configManager by lazy { model.configManager } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_merchant_config, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + configUrlView.editText!!.setOnFocusChangeListener { _, hasFocus -> + if (!hasFocus) checkForUrlCredentials() + } + okButton.setOnClickListener { + checkForUrlCredentials() + val inputUrl = configUrlView.editText!!.text + val url = if (inputUrl.startsWith("http")) { + inputUrl.toString() + } else { + "https://$inputUrl".also { configUrlView.editText!!.setText(it) } + } + progressBar.visibility = VISIBLE + okButton.visibility = INVISIBLE + val config = Config( + configUrl = url, + username = usernameView.editText!!.text.toString(), + password = passwordView.editText!!.text.toString() + ) + configManager.fetchConfig(config, true, savePasswordCheckBox.isChecked) + configManager.configUpdateResult.observe(viewLifecycleOwner, Observer { result -> + if (onConfigUpdate(result)) { + configManager.configUpdateResult.removeObservers(viewLifecycleOwner) + } + }) + } + forgetPasswordButton.setOnClickListener { + configManager.forgetPassword() + passwordView.editText!!.text = null + forgetPasswordButton.visibility = GONE + } + configDocsView.movementMethod = LinkMovementMethod.getInstance() + updateView(savedInstanceState == null) + } + + override fun onStart() { + super.onStart() + // focus password if this is the only empty field + if (passwordView.editText!!.text.isBlank() + && !configUrlView.editText!!.text.isBlank() + && !usernameView.editText!!.text.isBlank() + ) { + passwordView.requestFocus() + } + } + + private fun updateView(isInitialization: Boolean = false) { + val config = configManager.config + configUrlView.editText!!.setText( + if (isInitialization && config.configUrl.isBlank()) CONFIG_URL_DEMO + else config.configUrl + ) + usernameView.editText!!.setText( + if (isInitialization && config.username.isBlank()) CONFIG_USERNAME_DEMO + else config.username + ) + passwordView.editText!!.setText( + if (isInitialization && config.password.isBlank()) CONFIG_PASSWORD_DEMO + else config.password + ) + forgetPasswordButton.visibility = if (config.hasPassword()) VISIBLE else GONE + } + + private fun checkForUrlCredentials() { + val text = configUrlView.editText!!.text.toString() + Uri.parse(text)?.userInfo?.let { userInfo -> + if (userInfo.contains(':')) { + val (user, pass) = userInfo.split(':') + val strippedUrl = text.replace("${userInfo}@", "") + configUrlView.editText!!.setText(strippedUrl) + usernameView.editText!!.setText(user) + passwordView.editText!!.setText(pass) + } + } + } + + /** + * Processes updated config and returns true, if observer can be removed. + */ + private fun onConfigUpdate(result: ConfigUpdateResult?) = when (result) { + null -> false + is ConfigUpdateResult.Error -> { + onError(result.msg) + true + } + is ConfigUpdateResult.Success -> { + onConfigReceived(result.currency) + true + } + } + + private fun onConfigReceived(currency: String) { + onResultReceived() + updateView() + topSnackbar(requireView(), getString(R.string.config_changed, currency), LENGTH_LONG) + navigate(actionSettingsToOrder()) + } + + private fun onError(msg: String) { + onResultReceived() + Snackbar.make(requireView(), msg, LENGTH_LONG).show() + } + + private fun onResultReceived() { + progressBar.visibility = INVISIBLE + okButton.visibility = VISIBLE + } + +} diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt deleted file mode 100644 index 77a87fb..0000000 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt +++ /dev/null @@ -1,164 +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.merchantpos.config - -import android.net.Uri -import android.os.Bundle -import android.text.method.LinkMovementMethod -import android.view.LayoutInflater -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 -import androidx.lifecycle.Observer -import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG -import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_merchant_config.* -import net.taler.common.navigate -import net.taler.merchantpos.MainViewModel -import net.taler.merchantpos.R -import net.taler.merchantpos.config.MerchantConfigFragmentDirections.Companion.actionSettingsToOrder -import net.taler.merchantpos.topSnackbar - -/** - * Fragment that displays merchant settings. - */ -class MerchantConfigFragment : Fragment() { - - private val model: MainViewModel by activityViewModels() - private val configManager by lazy { model.configManager } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - return inflater.inflate(R.layout.fragment_merchant_config, container, false) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - configUrlView.editText!!.setOnFocusChangeListener { _, hasFocus -> - if (!hasFocus) checkForUrlCredentials() - } - okButton.setOnClickListener { - checkForUrlCredentials() - val inputUrl = configUrlView.editText!!.text - val url = if (inputUrl.startsWith("http")) { - inputUrl.toString() - } else { - "https://$inputUrl".also { configUrlView.editText!!.setText(it) } - } - progressBar.visibility = VISIBLE - okButton.visibility = INVISIBLE - val config = Config( - configUrl = url, - username = usernameView.editText!!.text.toString(), - password = passwordView.editText!!.text.toString() - ) - configManager.fetchConfig(config, true, savePasswordCheckBox.isChecked) - configManager.configUpdateResult.observe(viewLifecycleOwner, Observer { result -> - if (onConfigUpdate(result)) { - configManager.configUpdateResult.removeObservers(viewLifecycleOwner) - } - }) - } - forgetPasswordButton.setOnClickListener { - configManager.forgetPassword() - passwordView.editText!!.text = null - forgetPasswordButton.visibility = GONE - } - configDocsView.movementMethod = LinkMovementMethod.getInstance() - updateView(savedInstanceState == null) - } - - override fun onStart() { - super.onStart() - // focus password if this is the only empty field - if (passwordView.editText!!.text.isBlank() - && !configUrlView.editText!!.text.isBlank() - && !usernameView.editText!!.text.isBlank() - ) { - passwordView.requestFocus() - } - } - - private fun updateView(isInitialization: Boolean = false) { - val config = configManager.config - configUrlView.editText!!.setText( - if (isInitialization && config.configUrl.isBlank()) CONFIG_URL_DEMO - else config.configUrl - ) - usernameView.editText!!.setText( - if (isInitialization && config.username.isBlank()) CONFIG_USERNAME_DEMO - else config.username - ) - passwordView.editText!!.setText( - if (isInitialization && config.password.isBlank()) CONFIG_PASSWORD_DEMO - else config.password - ) - forgetPasswordButton.visibility = if (config.hasPassword()) VISIBLE else GONE - } - - private fun checkForUrlCredentials() { - val text = configUrlView.editText!!.text.toString() - Uri.parse(text)?.userInfo?.let { userInfo -> - if (userInfo.contains(':')) { - val (user, pass) = userInfo.split(':') - val strippedUrl = text.replace("${userInfo}@", "") - configUrlView.editText!!.setText(strippedUrl) - usernameView.editText!!.setText(user) - passwordView.editText!!.setText(pass) - } - } - } - - /** - * Processes updated config and returns true, if observer can be removed. - */ - private fun onConfigUpdate(result: ConfigUpdateResult?) = when (result) { - null -> false - is ConfigUpdateResult.Error -> { - onError(result.msg) - true - } - is ConfigUpdateResult.Success -> { - onConfigReceived(result.currency) - true - } - } - - private fun onConfigReceived(currency: String) { - onResultReceived() - updateView() - topSnackbar(requireView(), getString(R.string.config_changed, currency), LENGTH_LONG) - navigate(actionSettingsToOrder()) - } - - private fun onError(msg: String) { - onResultReceived() - Snackbar.make(requireView(), msg, LENGTH_LONG).show() - } - - private fun onResultReceived() { - progressBar.visibility = INVISIBLE - okButton.visibility = VISIBLE - } - -} diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/MerchantRequest.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/MerchantRequest.kt deleted file mode 100644 index 5d41196..0000000 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/config/MerchantRequest.kt +++ /dev/null @@ -1,59 +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.merchantpos.config - -import android.net.Uri -import android.util.ArrayMap -import com.android.volley.Response -import com.android.volley.toolbox.JsonObjectRequest -import net.taler.merchantlib.MerchantConfig -import net.taler.merchantpos.LogErrorListener -import org.json.JSONObject - -class MerchantRequest( - method: Int, - private val merchantConfig: MerchantConfig, - endpoint: String, - params: Map?, - jsonRequest: JSONObject?, - listener: Response.Listener, - errorListener: LogErrorListener -) : - JsonObjectRequest( - method, - merchantConfig.legacyUrl(endpoint, params), - jsonRequest, - listener, - errorListener - ) { - - override fun getHeaders(): MutableMap { - val headerMap = ArrayMap() - headerMap["Authorization"] = "ApiKey " + merchantConfig.apiKey - return headerMap - } - -} - -private fun MerchantConfig.legacyUrl(endpoint: String, params: Map?): String { - val uriBuilder = Uri.parse(baseUrl).buildUpon() - uriBuilder.appendPath(endpoint) - params?.forEach { - uriBuilder.appendQueryParameter(it.key, it.value) - } - return uriBuilder.toString() -} -- cgit v1.2.3