gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant-terminal-android] branch master updated: Initial support


From: gnunet
Subject: [taler-merchant-terminal-android] branch master updated: Initial support for multiple concurrent orders
Date: Wed, 26 Feb 2020 19:10:31 +0100

This is an automated email from the git hooks/post-receive script.

torsten-grote pushed a commit to branch master
in repository merchant-terminal-android.

The following commit(s) were added to refs/heads/master by this push:
     new ffb3649  Initial support for multiple concurrent orders
ffb3649 is described below

commit ffb36499d1d1cedacc20c2b8a59efe7134ed7f34
Author: Torsten Grote <address@hidden>
AuthorDate: Tue Feb 25 18:11:16 2020 -0300

    Initial support for multiple concurrent orders
---
 app/build.gradle                                   |   5 +-
 .../net/taler/merchantpos/order/Definitions.kt     |   3 +-
 .../java/net/taler/merchantpos/order/LiveOrder.kt  |  93 ++++++++++++++
 .../net/taler/merchantpos/order/OrderFragment.kt   |  36 ++++--
 .../net/taler/merchantpos/order/OrderManager.kt    | 143 ++++++++++++---------
 .../taler/merchantpos/order/OrderStateFragment.kt  |  22 ++--
 .../taler/merchantpos/order/ProductsFragment.kt    |   2 +-
 .../merchantpos/payment/PaymentSuccessFragment.kt  |   1 +
 .../merchantpos/payment/ProcessPaymentFragment.kt  |   7 +-
 app/src/main/res/color/button_bottom.xml           |   5 +
 app/src/main/res/layout/fragment_order.xml         |  25 ++--
 app/src/main/res/navigation/nav_graph.xml          |   8 +-
 app/src/main/res/values/strings.xml                |   6 +-
 build.gradle                                       |   2 +
 14 files changed, 253 insertions(+), 105 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index 2a9d620..c48d7c9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,12 +1,12 @@
 apply plugin: 'com.android.application'
-
 apply plugin: 'kotlin-android'
 apply plugin: 'kotlin-kapt'
 apply plugin: 'kotlin-android-extensions'
+apply plugin: "androidx.navigation.safeargs.kotlin"
 
 android {
     compileSdkVersion 29
-    buildToolsVersion "29.0.2"
+    buildToolsVersion "29.0.3"
     defaultConfig {
         applicationId "net.taler.merchantpos"
         minSdkVersion 26
@@ -42,7 +42,6 @@ dependencies {
     implementation "androidx.recyclerview:recyclerview-selection:1.1.0-rc01"
 
     // Navigation
-    def nav_version = "2.2.1"
     implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
     implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
 
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 872f2f5..3aeeed4 100644
--- a/app/src/main/java/net/taler/merchantpos/order/Definitions.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/Definitions.kt
@@ -63,8 +63,9 @@ data class ContractProduct(
     )
 }
 
-data class Order(val availableCategories: Map<Int, Category>) {
+data class Order(val id: Int, val availableCategories: Map<Int, Category>) {
     val products = ArrayList<ConfigProduct>()
+    val title: String = id.toString()
     val summary: String
         get() {
             val categories = HashMap<Category, Int>()
diff --git a/app/src/main/java/net/taler/merchantpos/order/LiveOrder.kt 
b/app/src/main/java/net/taler/merchantpos/order/LiveOrder.kt
new file mode 100644
index 0000000..206b046
--- /dev/null
+++ b/app/src/main/java/net/taler/merchantpos/order/LiveOrder.kt
@@ -0,0 +1,93 @@
+package net.taler.merchantpos.order
+
+import androidx.annotation.UiThread
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.Transformations
+import net.taler.merchantpos.CombinedLiveData
+import net.taler.merchantpos.order.RestartState.DISABLED
+import net.taler.merchantpos.order.RestartState.ENABLED
+import net.taler.merchantpos.order.RestartState.UNDO
+
+internal enum class RestartState { ENABLED, DISABLED, UNDO }
+
+internal interface LiveOrder {
+    val order: LiveData<Order>
+    val orderTotal: LiveData<Double>
+    val restartState: LiveData<RestartState>
+    val modifyOrderAllowed: LiveData<Boolean>
+    val lastAddedProduct: ConfigProduct?
+    val selectedProductKey: String?
+    fun restartOrUndo()
+    fun selectOrderLine(product: ConfigProduct?)
+    fun increaseSelectedOrderLine()
+    fun decreaseSelectedOrderLine()
+}
+
+internal class MutableLiveOrder(
+    val id: Int,
+    private val productsByCategory: HashMap<Category, ArrayList<ConfigProduct>>
+) : LiveOrder {
+    private val availableCategories: Map<Int, Category>
+        get() = productsByCategory.keys.map { it.id to it }.toMap()
+    override val order: MutableLiveData<Order> = MutableLiveData(Order(id, 
availableCategories))
+    override val orderTotal: LiveData<Double> = Transformations.map(order) { 
it.total }
+    override val restartState = MutableLiveData<RestartState>(DISABLED)
+    private val selectedOrderLine = MutableLiveData<ConfigProduct>()
+    override val selectedProductKey: String?
+        get() = selectedOrderLine.value?.id
+    override val modifyOrderAllowed =
+        CombinedLiveData(restartState, selectedOrderLine) { restartState, 
selectedOrderLine ->
+            restartState != DISABLED && selectedOrderLine != null
+        }
+    override var lastAddedProduct: ConfigProduct? = null
+    private var undoOrder: Order? = null
+
+    @UiThread
+    internal fun addProduct(product: ConfigProduct) {
+        lastAddedProduct = product
+        order.value = order.value!! + product
+        restartState.value = ENABLED
+    }
+
+    @UiThread
+    internal fun removeProduct(product: ConfigProduct) {
+        val modifiedOrder = order.value!! - product
+        order.value = modifiedOrder
+        restartState.value = if (modifiedOrder.products.isEmpty()) DISABLED 
else ENABLED
+    }
+
+    @UiThread
+    internal fun isEmpty() = order.value!!.products.isEmpty()
+
+    @UiThread
+    override fun restartOrUndo() {
+        if (restartState.value == UNDO) {
+            order.value = undoOrder
+            restartState.value = ENABLED
+            undoOrder = null
+        } else {
+            undoOrder = order.value
+            order.value = Order(id, availableCategories)
+            restartState.value = UNDO
+        }
+    }
+
+    @UiThread
+    override fun selectOrderLine(product: ConfigProduct?) {
+        selectedOrderLine.value = product
+    }
+
+    @UiThread
+    override fun increaseSelectedOrderLine() {
+        val orderLine = selectedOrderLine.value ?: throw 
IllegalStateException()
+        addProduct(orderLine)
+    }
+
+    @UiThread
+    override fun decreaseSelectedOrderLine() {
+        val orderLine = selectedOrderLine.value ?: throw 
IllegalStateException()
+        removeProduct(orderLine)
+    }
+
+}
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 90d882f..8ababad 100644
--- a/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
@@ -8,10 +8,12 @@ import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.Observer
 import androidx.navigation.fragment.findNavController
+import androidx.navigation.fragment.navArgs
 import androidx.transition.TransitionManager.beginDelayedTransition
 import kotlinx.android.synthetic.main.fragment_order.*
 import net.taler.merchantpos.MainViewModel
 import net.taler.merchantpos.R
+import 
net.taler.merchantpos.order.OrderFragmentDirections.Companion.actionGlobalOrder
 import net.taler.merchantpos.order.RestartState.ENABLED
 import net.taler.merchantpos.order.RestartState.UNDO
 
@@ -20,6 +22,8 @@ class OrderFragment : Fragment() {
     private val viewModel: MainViewModel by activityViewModels()
     private val orderManager by lazy { viewModel.orderManager }
     private val paymentManager by lazy { viewModel.paymentManager }
+    private val args: OrderFragmentArgs by navArgs()
+    private val liveOrder by lazy { orderManager.getOrder(args.orderId) }
 
     override fun onCreateView(
         inflater: LayoutInflater,
@@ -30,8 +34,8 @@ class OrderFragment : Fragment() {
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        restartButton.setOnClickListener { orderManager.restartOrUndo() }
-        orderManager.restartState.observe(viewLifecycleOwner, Observer { state 
->
+        restartButton.setOnClickListener { liveOrder.restartOrUndo() }
+        liveOrder.restartState.observe(viewLifecycleOwner, Observer { state ->
             beginDelayedTransition(view as ViewGroup)
             if (state == UNDO) {
                 restartButton.setText(R.string.order_undo)
@@ -42,28 +46,36 @@ class OrderFragment : Fragment() {
                 restartButton.isEnabled = state == ENABLED
                 completeButton.isEnabled = state == ENABLED
             }
+            nextButton.isEnabled = state == ENABLED
         })
-        minusButton.setOnClickListener { 
orderManager.decreaseSelectedOrderLine() }
-        plusButton.setOnClickListener { 
orderManager.increaseSelectedOrderLine() }
-        orderManager.modifyOrderAllowed.observe(viewLifecycleOwner, Observer { 
allowed ->
+        minusButton.setOnClickListener { liveOrder.decreaseSelectedOrderLine() 
}
+        plusButton.setOnClickListener { liveOrder.increaseSelectedOrderLine() }
+        liveOrder.modifyOrderAllowed.observe(viewLifecycleOwner, Observer { 
allowed ->
             minusButton.isEnabled = allowed
             plusButton.isEnabled = allowed
         })
+        orderManager.hasPreviousOrder.observe(viewLifecycleOwner, Observer { 
hasPreviousOrder ->
+            prevButton.isEnabled = hasPreviousOrder
+        })
     }
 
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         super.onActivityCreated(savedInstanceState)
-        reconfigureButton.setOnClickListener {
-            findNavController().navigate(R.id.action_order_to_merchantSettings)
-        }
-        historyButton.setOnClickListener {
-            findNavController().navigate(R.id.action_order_to_merchantHistory)
-        }
+        liveOrder.order.observe(viewLifecycleOwner, Observer { order ->
+            activity?.title = getString(R.string.order_label_title, 
order.title)
+        })
+        prevButton.setOnClickListener { orderManager.previousOrder() }
+        nextButton.setOnClickListener { orderManager.nextOrder() }
         completeButton.setOnClickListener {
-            val order = orderManager.order.value ?: return@setOnClickListener
+            val order = liveOrder.order.value ?: return@setOnClickListener
             paymentManager.createPayment(order)
             findNavController().navigate(R.id.action_order_to_processPayment)
         }
+        orderManager.currentOrderId.observe(viewLifecycleOwner, Observer { 
orderId ->
+            if (args.orderId != orderId) {
+                findNavController().navigate(actionGlobalOrder(orderId))
+            }
+        })
     }
 
     override fun onStart() {
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 60f1e4a..53c824b 100644
--- a/app/src/main/java/net/taler/merchantpos/order/OrderManager.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/OrderManager.kt
@@ -4,32 +4,28 @@ import android.util.Log
 import androidx.annotation.UiThread
 import androidx.lifecycle.LiveData
 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.CombinedLiveData
 import net.taler.merchantpos.config.ConfigurationReceiver
-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 }
-
 class OrderManager(private val mapper: ObjectMapper) : ConfigurationReceiver {
 
     companion object {
         val TAG = OrderManager::class.java.simpleName
     }
 
+    private var orderCounter: Int = 0
+    private val mCurrentOrderId = MutableLiveData<Int>()
+    internal val currentOrderId: LiveData<Int> = mCurrentOrderId
+
     private val productsByCategory = HashMap<Category, 
ArrayList<ConfigProduct>>()
 
-    private val mOrder = MutableLiveData<Order>()
-    private val newOrder  // an empty order containing only available 
categories
-        get() = Order(productsByCategory.keys.map { it.id to it }.toMap())
-    internal val order: LiveData<Order> = mOrder
-    internal val orderTotal: LiveData<Double> = map(mOrder) { it.total }
+    private val orders = LinkedHashMap<Int, MutableLiveOrder>()
+
+    private val mHasPreviousOrder = MutableLiveData<Boolean>(false)
+    internal val hasPreviousOrder: LiveData<Boolean> = mHasPreviousOrder
 
     private val mProducts = MutableLiveData<List<ConfigProduct>>()
     internal val products: LiveData<List<ConfigProduct>> = mProducts
@@ -37,20 +33,6 @@ class OrderManager(private val mapper: ObjectMapper) : 
ConfigurationReceiver {
     private val mCategories = MutableLiveData<List<Category>>()
     internal val categories: LiveData<List<Category>> = mCategories
 
-    private var undoOrder: Order? = null
-    private val mRestartState = MutableLiveData<RestartState>().apply { value 
= DISABLED }
-    internal val restartState: LiveData<RestartState> = mRestartState
-
-    private val mSelectedOrderLine = MutableLiveData<ConfigProduct>()
-
-    internal var lastAddedProduct: ConfigProduct? = null
-        private set
-
-    internal val modifyOrderAllowed =
-        CombinedLiveData(restartState, mSelectedOrderLine) { restartState, 
selectedOrderLine ->
-            restartState != DISABLED && selectedOrderLine != null
-        }
-
     @Suppress("BlockingMethodInNonBlockingContext") // run on Dispatchers.Main
     override suspend fun onConfigurationReceived(json: JSONObject, currency: 
String): Boolean {
         // parse categories
@@ -99,65 +81,102 @@ class OrderManager(private val mapper: ObjectMapper) : 
ConfigurationReceiver {
         return if (productsByCategory.size > 0) {
             mCategories.postValue(categories)
             mProducts.postValue(productsByCategory[categories[0]])
+            // Initialize first empty order, note this won't work when 
updating config mid-flight
+            val id = orderCounter++
+            orders[id] = MutableLiveOrder(id, productsByCategory)
+            mCurrentOrderId.postValue(id)
             true
         } else {
             false
         }
     }
 
-    internal fun setCurrentCategory(category: Category) {
-        val newCategories = categories.value?.apply {
-            forEach { if (it.selected) it.selected = false }
-            category.selected = true
-        }
-        mCategories.postValue(newCategories)
-        mProducts.postValue(productsByCategory[category])
+    @UiThread
+    internal fun getOrder(orderId: Int): LiveOrder {
+        return orders[orderId] ?: throw IllegalArgumentException()
     }
 
     @UiThread
-    internal fun addProduct(product: ConfigProduct) {
-        lastAddedProduct = product
-        val order = mOrder.value ?: newOrder
-        mOrder.value = order + product
-        mRestartState.value = ENABLED
+    internal fun nextOrder() {
+        val currentId = currentOrderId.value!!
+        var foundCurrentOrder = false
+        var nextId: Int? = null
+        for (orderId in orders.keys) {
+            if (foundCurrentOrder) {
+                nextId = orderId
+                break
+            }
+            if (orderId == currentId) foundCurrentOrder = true
+        }
+        if (nextId == null) {
+            nextId = orderCounter++
+            orders[nextId] = MutableLiveOrder(nextId, productsByCategory)
+        }
+        val currentOrder = order(currentId)
+        val stillHasPrevious = if (currentOrder.isEmpty()) {
+            val wasFirst = orders.keys.first() == currentId
+            orders.remove(currentId)
+            !wasFirst  // we still have a previous order if the removed one 
wasn't the first
+        } else {
+            currentOrder.lastAddedProduct = null  // not needed anymore and 
would select it
+            true  // we did not remove anything, so our next order still has a 
previous
+        }
+        mCurrentOrderId.value = nextId
+        mHasPreviousOrder.value = stillHasPrevious
     }
 
     @UiThread
-    internal fun removeProduct(product: ConfigProduct) {
-        val order = mOrder.value ?: throw IllegalStateException()
-        val modifiedOrder = order - product
-        mOrder.value = modifiedOrder
-        mRestartState.value = if (modifiedOrder.products.isEmpty()) DISABLED 
else ENABLED
+    internal fun previousOrder() {
+        val currentId = currentOrderId.value!!
+        var previousId: Int? = null
+        var foundCurrentOrder = false
+        for (orderId in orders.keys) {
+            if (orderId == currentId) {
+                foundCurrentOrder = true
+                break
+            }
+            previousId = orderId
+        }
+        if (previousId == null || !foundCurrentOrder) {
+            throw AssertionError("Could not find previous order for 
$currentId")
+        }
+        val currentOrder = order(currentId)
+        // remove current order if empty, or lastAddedProduct as it is not 
needed anymore
+        // and would get selected when navigating back instead of last 
selection
+        if (currentOrder.isEmpty()) orders.remove(currentId)
+        else currentOrder.lastAddedProduct = null
+        mCurrentOrderId.value = previousId
+        mHasPreviousOrder.value = previousId != orders.keys.first()
     }
 
-    @UiThread
-    internal fun restartOrUndo() {
-        if (restartState.value == UNDO) {
-            mOrder.value = undoOrder
-            mRestartState.value = ENABLED
-            undoOrder = null
-        } else {
-            undoOrder = mOrder.value
-            mOrder.value = newOrder
-            mRestartState.value = UNDO
+    internal fun setCurrentCategory(category: Category) {
+        val newCategories = categories.value?.apply {
+            forEach { if (it.selected) it.selected = false }
+            category.selected = true
         }
+        mCategories.postValue(newCategories)
+        mProducts.postValue(productsByCategory[category])
     }
 
     @UiThread
-    fun selectOrderLine(product: ConfigProduct?) {
-        mSelectedOrderLine.value = product
+    internal fun addProduct(orderId: Int, product: ConfigProduct) {
+        order(orderId).addProduct(product)
     }
 
     @UiThread
-    fun increaseSelectedOrderLine() {
-        val orderLine = mSelectedOrderLine.value ?: throw 
IllegalStateException()
-        addProduct(orderLine)
+    internal fun onOrderPaid(orderId: Int) {
+        if (currentOrderId.value == orderId) {
+            if (hasPreviousOrder.value!!) previousOrder()
+            else {
+                nextOrder()
+                mHasPreviousOrder.value = false
+            }
+        }
+        orders.remove(orderId)
     }
 
-    @UiThread
-    fun decreaseSelectedOrderLine() {
-        val orderLine = mSelectedOrderLine.value ?: throw 
IllegalStateException()
-        removeProduct(orderLine)
+    private fun order(orderId: Int): MutableLiveOrder {
+        return orders[orderId] ?: throw IllegalStateException()
     }
 
 }
diff --git 
a/app/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt 
b/app/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt
index f016795..090208b 100644
--- a/app/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt
@@ -32,6 +32,7 @@ class OrderStateFragment : Fragment() {
 
     private val viewModel: MainViewModel by activityViewModels()
     private val orderManager by lazy { viewModel.orderManager }
+    private val liveOrder by lazy { 
orderManager.getOrder(orderManager.currentOrderId.value!!) }
     private val adapter = OrderAdapter()
     private var tracker: SelectionTracker<String>? = null
 
@@ -60,19 +61,23 @@ class OrderStateFragment : Fragment() {
         ).build()
         savedInstanceState?.let { tracker.onRestoreInstanceState(it) }
         adapter.tracker = tracker
+        this.tracker = tracker
+        if (savedInstanceState == null) {
+            // select last selected order line when re-creating this fragment
+            // do it before attaching the tracker observer
+            liveOrder.selectedProductKey?.let { tracker.select(it) }
+        }
         tracker.addObserver(object : 
SelectionTracker.SelectionObserver<String>() {
             override fun onItemStateChanged(key: String, selected: Boolean) {
                 super.onItemStateChanged(key, selected)
                 val item = if (selected) adapter.getItemByKey(key) else null
-                orderManager.selectOrderLine(item)
+                liveOrder.selectOrderLine(item)
             }
         })
-        this.tracker = tracker
-
-        orderManager.order.observe(viewLifecycleOwner, Observer { order ->
+        liveOrder.order.observe(viewLifecycleOwner, Observer { order ->
             onOrderChanged(order, tracker)
         })
-        orderManager.orderTotal.observe(viewLifecycleOwner, Observer { 
orderTotal ->
+        liveOrder.orderTotal.observe(viewLifecycleOwner, Observer { orderTotal 
->
             if (orderTotal == 0.0) {
                 totalView.fadeOut()
                 totalView.text = null
@@ -91,11 +96,12 @@ class OrderStateFragment : Fragment() {
 
     private fun onOrderChanged(order: Order, tracker: 
SelectionTracker<String>) {
         adapter.setItems(order.products) {
-            orderManager.lastAddedProduct?.let {
+            liveOrder.lastAddedProduct?.let {
                 val position = adapter.findPosition(it)
                 if (position >= 0) {
-                    orderList.scrollToPosition(position)
-                    orderList.post { this.tracker?.select(it.id) }
+                    // orderList can be null m(
+                    orderList?.scrollToPosition(position)
+                    orderList?.post { this.tracker?.select(it.id) }
                 }
             }
             // workaround for bug: SelectionObserver doesn't update when 
removing selected item
diff --git a/app/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt 
b/app/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt
index d680fff..54bd763 100644
--- a/app/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt
@@ -52,7 +52,7 @@ class ProductsFragment : Fragment(), ProductSelectionListener 
{
     }
 
     override fun onProductSelected(product: ConfigProduct) {
-        orderManager.addProduct(product)
+        orderManager.addProduct(orderManager.currentOrderId.value!!, product)
     }
 
 }
diff --git 
a/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt 
b/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
index 1e9953f..d9ab028 100644
--- a/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
@@ -24,4 +24,5 @@ class PaymentSuccessFragment : Fragment() {
             findNavController().navigateUp()
         }
     }
+
 }
diff --git 
a/app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt 
b/app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
index 6965e56..8eb7e97 100644
--- a/app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
@@ -17,6 +17,7 @@ import net.taler.merchantpos.QrCodeManager.makeQrCode
 import net.taler.merchantpos.R
 import net.taler.merchantpos.fadeIn
 import net.taler.merchantpos.fadeOut
+import 
net.taler.merchantpos.payment.ProcessPaymentFragmentDirections.Companion.actionProcessPaymentToPaymentSuccess
 import net.taler.merchantpos.topSnackbar
 
 class ProcessPaymentFragment : Fragment() {
@@ -50,8 +51,10 @@ class ProcessPaymentFragment : Fragment() {
             return
         }
         if (payment.paid) {
-            
findNavController().navigate(R.id.action_processPayment_to_paymentSuccess)
-            model.orderManager.restartOrUndo()
+            model.orderManager.onOrderPaid(payment.order.id)
+            actionProcessPaymentToPaymentSuccess().let {
+                findNavController().navigate(it)
+            }
             return
         }
         payIntroView.fadeIn()
diff --git a/app/src/main/res/color/button_bottom.xml 
b/app/src/main/res/color/button_bottom.xml
new file mode 100644
index 0000000..83363e9
--- /dev/null
+++ b/app/src/main/res/color/button_bottom.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android";>
+    <item android:color="@color/bottomButtons" android:state_enabled="true" />
+    <item android:alpha="0.12" android:color="?attr/colorOnSurface" />
+</selector>
diff --git a/app/src/main/res/layout/fragment_order.xml 
b/app/src/main/res/layout/fragment_order.xml
index 3fd4902..19fb629 100644
--- a/app/src/main/res/layout/fragment_order.xml
+++ b/app/src/main/res/layout/fragment_order.xml
@@ -60,7 +60,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="8dp"
-            android:backgroundTint="@color/bottomButtons"
+            android:backgroundTint="@color/button_bottom"
             android:text="@string/order_restart"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toStartOf="parent" />
@@ -80,7 +80,7 @@
             android:id="@+id/minusButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginStart="16dp"
+            android:layout_marginStart="32dp"
             android:minWidth="48dp"
             android:text="-1"
             app:layout_constraintBottom_toBottomOf="parent"
@@ -88,35 +88,36 @@
             tools:ignore="HardcodedText" />
 
     <Button
-            android:id="@+id/reconfigureButton"
+            android:id="@+id/prevButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginStart="16dp"
-            android:backgroundTint="@color/bottomButtons"
-            android:text="@string/button_reconfigure"
+            android:layout_marginStart="32dp"
+            android:backgroundTint="@color/button_bottom"
+            android:text="@string/button_previous"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toEndOf="@+id/plusButton" />
 
     <Button
-            android:id="@+id/historyButton"
+            android:id="@+id/nextButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
-            android:backgroundTint="@color/bottomButtons"
-            android:text="@string/button_history"
+            android:backgroundTint="@color/button_bottom"
+            android:text="@string/button_next"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toEndOf="@+id/reconfigureButton" />
+            app:layout_constraintStart_toEndOf="@+id/prevButton" />
 
     <Button
             android:id="@+id/completeButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginStart="32dp"
             android:layout_marginEnd="8dp"
-            android:backgroundTint="@color/bottomButtons"
+            android:backgroundTint="@color/button_bottom"
             android:text="@string/button_complete"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintHorizontal_bias="1.0"
-            app:layout_constraintStart_toEndOf="@+id/historyButton" />
+            app:layout_constraintStart_toEndOf="@+id/nextButton" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/navigation/nav_graph.xml 
b/app/src/main/res/navigation/nav_graph.xml
index 35c2bf2..4a37ae3 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -3,14 +3,18 @@
         xmlns:app="http://schemas.android.com/apk/res-auto";
         xmlns:tools="http://schemas.android.com/tools";
         android:id="@+id/nav_graph"
-        app:startDestination="@id/order"
+        app:startDestination="@id/configFetcher"
         tools:ignore="UnusedNavigation">
 
     <fragment
             android:id="@+id/order"
             android:name="net.taler.merchantpos.order.OrderFragment"
-            android:label="@string/order_label"
+            android:label=""
             tools:layout="@layout/fragment_order">
+        <argument
+                android:name="orderId"
+                android:defaultValue="0"
+                app:argType="integer" />
         <action
                 android:id="@+id/action_order_to_processPayment"
                 app:destination="@id/processPayment" />
diff --git a/app/src/main/res/values/strings.xml 
b/app/src/main/res/values/strings.xml
index d313f03..fe85bce 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -3,11 +3,11 @@
     <string name="app_name_short">Merchant Terminal</string>
     <string name="project_name">GNU Taler</string>
 
-    <string name="menu_order">Order</string>
+    <string name="menu_order">Orders</string>
     <string name="menu_history">History</string>
     <string name="menu_settings">Settings</string>
 
-    <string name="order_label">Order</string>
+    <string name="order_label_title">Order #%s</string>
     <!-- The first placeholder is the amount and the second the currency -->
     <string name="order_total">Total: %1$.2f %2$s</string>
     <string name="order_restart">Restart</string>
@@ -46,5 +46,7 @@
     <string name="history_ref_no">Ref. No:</string>
 
     <string name="error_network">Network Error</string>
+    <string name="button_previous">Prev</string>
+    <string name="button_next">Next</string>
 
 </resources>
diff --git a/build.gradle b/build.gradle
index 82723c0..e252cd1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,6 @@
 buildscript {
     ext.kotlin_version = '1.3.61'
+    ext.nav_version = "2.2.1"
     repositories {
         google()
         jcenter()
@@ -8,6 +9,7 @@ buildscript {
     dependencies {
         classpath 'com.android.tools.build:gradle:3.6.0'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+        classpath 
"androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
     }
 }
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]