summaryrefslogtreecommitdiff
path: root/merchant-terminal/src/main/java/net/taler/merchantpos/history
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-08-04 09:46:38 -0300
committerTorsten Grote <t@grobox.de>2020-08-04 09:46:38 -0300
commit35f7ed512ed7445362d6caee1bf60441f4ce979e (patch)
tree08fb02c802ff36065dd85fb9dcb95a0adabc03c3 /merchant-terminal/src/main/java/net/taler/merchantpos/history
parentd3a035c59c508b7b0ef3c06a1b0f1f3c0a077bb8 (diff)
downloadtaler-android-35f7ed512ed7445362d6caee1bf60441f4ce979e.tar.gz
taler-android-35f7ed512ed7445362d6caee1bf60441f4ce979e.tar.bz2
taler-android-35f7ed512ed7445362d6caee1bf60441f4ce979e.zip
[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
Diffstat (limited to 'merchant-terminal/src/main/java/net/taler/merchantpos/history')
-rw-r--r--merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt (renamed from merchant-terminal/src/main/java/net/taler/merchantpos/history/MerchantHistoryFragment.kt)6
-rw-r--r--merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt109
-rw-r--r--merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt134
-rw-r--r--merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundUriFragment.kt69
4 files changed, 3 insertions, 315 deletions
diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/history/MerchantHistoryFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt
index 596b8b0..8cc435a 100644
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/history/MerchantHistoryFragment.kt
+++ b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt
@@ -35,8 +35,8 @@ import net.taler.common.navigate
import net.taler.merchantlib.OrderHistoryEntry
import net.taler.merchantpos.MainViewModel
import net.taler.merchantpos.R
-import net.taler.merchantpos.history.MerchantHistoryFragmentDirections.Companion.actionGlobalMerchantSettings
-import net.taler.merchantpos.history.MerchantHistoryFragmentDirections.Companion.actionNavHistoryToRefundFragment
+import net.taler.merchantpos.history.HistoryFragmentDirections.Companion.actionGlobalMerchantSettings
+import net.taler.merchantpos.history.HistoryFragmentDirections.Companion.actionNavHistoryToRefundFragment
internal interface RefundClickListener {
fun onRefundClicked(item: OrderHistoryEntry)
@@ -45,7 +45,7 @@ internal interface RefundClickListener {
/**
* Fragment to display the merchant's payment history, received from the backend.
*/
-class MerchantHistoryFragment : Fragment(), RefundClickListener {
+class HistoryFragment : Fragment(), RefundClickListener {
companion object {
const val TAG = "taler-merchant"
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
deleted file mode 100644
index 17d78f6..0000000
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt
+++ /dev/null
@@ -1,109 +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 <http://www.gnu.org/licenses/>
- */
-
-package net.taler.merchantpos.history
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.annotation.StringRes
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
-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
-import net.taler.merchantlib.OrderHistoryEntry
-import net.taler.merchantpos.MainViewModel
-import net.taler.merchantpos.R
-import net.taler.merchantpos.history.RefundFragmentDirections.Companion.actionRefundFragmentToRefundUriFragment
-import net.taler.merchantpos.history.RefundResult.AlreadyRefunded
-import net.taler.merchantpos.history.RefundResult.Error
-import net.taler.merchantpos.history.RefundResult.PastDeadline
-import net.taler.merchantpos.history.RefundResult.Success
-
-class RefundFragment : Fragment() {
-
- private val model: MainViewModel by activityViewModels()
- private val refundManager by lazy { model.refundManager }
-
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_refund, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- val item = refundManager.toBeRefunded ?: throw IllegalStateException()
- amountInputView.setText(item.amount.amountStr)
- currencyView.text = item.amount.currency
- abortButton.setOnClickListener { findNavController().navigateUp() }
- refundButton.setOnClickListener { onRefundButtonClicked(item) }
-
- refundManager.refundResult.observe(viewLifecycleOwner, Observer { result ->
- onRefundResultChanged(result)
- })
- }
-
- private fun onRefundButtonClicked(item: OrderHistoryEntry) {
- 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.amount.amountStr)
- return
- }
- if (inputAmount.isZero()) {
- amountView.error = getString(R.string.refund_error_zero)
- return
- }
- amountView.error = null
- refundButton.fadeOut()
- progressBar.fadeIn()
- refundManager.refund(item, inputAmount, reasonInputView.text.toString())
- }
-
- private fun onRefundResultChanged(result: RefundResult?): Any = when (result) {
- Error -> onError(R.string.refund_error_backend)
- PastDeadline -> onError(R.string.refund_error_deadline)
- AlreadyRefunded -> onError(R.string.refund_error_already_refunded)
- is Success -> {
- progressBar.fadeOut()
- refundButton.fadeIn()
- navigate(actionRefundFragmentToRefundUriFragment())
- }
- null -> { // no-op
- }
- }
-
- private fun onError(@StringRes res: Int) {
- Snackbar.make(requireView(), res, LENGTH_LONG).show()
- progressBar.fadeOut()
- refundButton.fadeIn()
- }
-
-}
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
deleted file mode 100644
index 7f9b4c5..0000000
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt
+++ /dev/null
@@ -1,134 +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 <http://www.gnu.org/licenses/>
- */
-
-package net.taler.merchantpos.history
-
-import android.util.Log
-import androidx.annotation.UiThread
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import com.android.volley.Request.Method.POST
-import com.android.volley.RequestQueue
-import com.android.volley.Response.Listener
-import com.android.volley.VolleyError
-import net.taler.common.Amount
-import net.taler.merchantlib.OrderHistoryEntry
-import net.taler.merchantpos.LogErrorListener
-import net.taler.merchantpos.config.ConfigManager
-import net.taler.merchantpos.config.MerchantRequest
-import org.json.JSONObject
-
-sealed class RefundResult {
- object Error : RefundResult()
- object PastDeadline : RefundResult()
- object AlreadyRefunded : RefundResult()
- class Success(
- val refundUri: String,
- val item: OrderHistoryEntry,
- val amount: Amount,
- val reason: String
- ) : RefundResult()
-}
-
-class RefundManager(
- private val configManager: ConfigManager,
- private val queue: RequestQueue
-) {
-
- companion object {
- val TAG = RefundManager::class.java.simpleName
- }
-
- var toBeRefunded: OrderHistoryEntry? = null
- private set
-
- private val mRefundResult = MutableLiveData<RefundResult>()
- internal val refundResult: LiveData<RefundResult> = mRefundResult
-
- @UiThread
- internal fun startRefund(item: OrderHistoryEntry) {
- toBeRefunded = item
- mRefundResult.value = null
- }
-
- @UiThread
- internal fun abortRefund() {
- toBeRefunded = null
- mRefundResult.value = null
- }
-
- @UiThread
- internal fun refund(item: OrderHistoryEntry, amount: Amount, reason: String) {
- val merchantConfig = configManager.merchantConfig!!
- val refundRequest = mapOf(
- "order_id" to item.orderId,
- "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) },
- LogErrorListener { onRefundError(it) }
- )
- queue.add(req)
- }
-
- @UiThread
- private fun onRefundResponse(
- json: JSONObject,
- item: OrderHistoryEntry,
- amount: Amount,
- reason: String
- ) {
- if (!json.has("contract_terms")) {
- Log.e(TAG, "Contract terms missing: $json")
- onRefundError()
- return
- }
-
- val contractTerms = json.getJSONObject("contract_terms")
- val refundDeadline = if (contractTerms.has("refund_deadline")) {
- contractTerms.getJSONObject("refund_deadline").getLong("t_ms")
- } else null
- val autoRefund = contractTerms.has("auto_refund")
- val refundUri = json.getString("taler_refund_uri")
-
- Log.e("TEST", "refundDeadline: $refundDeadline")
- if (refundDeadline != null) Log.e(
- "TEST",
- "refundDeadline passed: ${System.currentTimeMillis() > refundDeadline}"
- )
- Log.e("TEST", "autoRefund: $autoRefund")
- Log.e("TEST", "refundUri: $refundUri")
-
- mRefundResult.value = RefundResult.Success(refundUri, item, amount, reason)
- }
-
- @UiThread
- private fun onRefundError(error: VolleyError? = null) {
- val data = error?.networkResponse?.data
- if (data != null) {
- val json = JSONObject(String(data))
- if (json.has("code") && json.getInt("code") == 2602) {
- mRefundResult.value = RefundResult.AlreadyRefunded
- return
- }
- }
- mRefundResult.value = RefundResult.Error
- }
-
-}
diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundUriFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundUriFragment.kt
deleted file mode 100644
index 1ea0959..0000000
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundUriFragment.kt
+++ /dev/null
@@ -1,69 +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 <http://www.gnu.org/licenses/>
- */
-
-package net.taler.merchantpos.history
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.navigation.fragment.findNavController
-import kotlinx.android.synthetic.main.fragment_refund_uri.*
-import net.taler.common.NfcManager.Companion.hasNfc
-import net.taler.common.QrCodeManager.makeQrCode
-import net.taler.merchantpos.MainViewModel
-import net.taler.merchantpos.R
-
-class RefundUriFragment : Fragment() {
-
- private val model: MainViewModel by activityViewModels()
- private val refundManager by lazy { model.refundManager }
-
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_refund_uri, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- val result = refundManager.refundResult.value
- if (result !is RefundResult.Success) throw IllegalStateException()
-
- refundQrcodeView.setImageBitmap(makeQrCode(result.refundUri))
-
- val introRes =
- if (hasNfc(requireContext())) R.string.refund_intro_nfc else R.string.refund_intro
- refundIntroView.setText(introRes)
-
- refundAmountView.text = result.amount.toString()
-
- refundRefView.text =
- getString(R.string.refund_order_ref, result.item.orderId, result.reason)
-
- cancelRefundButton.setOnClickListener { findNavController().navigateUp() }
- completeButton.setOnClickListener { findNavController().navigateUp() }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- refundManager.abortRefund()
- }
-
-}