taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

OrderStateFragment.kt (4794B)


      1 /*
      2  * This file is part of GNU Taler
      3  * (C) 2020 Taler Systems S.A.
      4  *
      5  * GNU Taler is free software; you can redistribute it and/or modify it under the
      6  * terms of the GNU General Public License as published by the Free Software
      7  * Foundation; either version 3, or (at your option) any later version.
      8  *
      9  * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
     10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11  * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License along with
     14  * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 
     17 package net.taler.merchantpos.order
     18 
     19 import android.os.Bundle
     20 import android.view.LayoutInflater
     21 import android.view.View
     22 import android.view.ViewGroup
     23 import androidx.fragment.app.Fragment
     24 import androidx.fragment.app.activityViewModels
     25 import androidx.recyclerview.selection.SelectionPredicates
     26 import androidx.recyclerview.selection.SelectionTracker
     27 import androidx.recyclerview.selection.StorageStrategy
     28 import androidx.recyclerview.widget.LinearLayoutManager
     29 import net.taler.merchantpos.MainViewModel
     30 import net.taler.merchantpos.databinding.FragmentOrderStateBinding
     31 import net.taler.merchantpos.order.OrderAdapter.OrderLineLookup
     32 
     33 class OrderStateFragment : Fragment() {
     34 
     35     private val viewModel: MainViewModel by activityViewModels()
     36     private val orderManager by lazy { viewModel.orderManager }
     37     private val liveOrder by lazy { orderManager.getOrder(orderManager.currentOrderId.value!!) }
     38 
     39     private lateinit var ui: FragmentOrderStateBinding
     40     private val adapter = OrderAdapter()
     41     private var tracker: SelectionTracker<String>? = null
     42 
     43     override fun onCreateView(
     44         inflater: LayoutInflater,
     45         container: ViewGroup?,
     46         savedInstanceState: Bundle?
     47     ): View? {
     48         ui = FragmentOrderStateBinding.inflate(inflater, container, false)
     49         return ui.root
     50     }
     51 
     52     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
     53         ui.orderList.apply {
     54             adapter = this@OrderStateFragment.adapter
     55             layoutManager = LinearLayoutManager(requireContext())
     56         }
     57         val detailsLookup = OrderLineLookup(ui.orderList)
     58         val tracker = SelectionTracker.Builder(
     59             "order-selection-id",
     60             ui.orderList,
     61             adapter.keyProvider,
     62             detailsLookup,
     63             StorageStrategy.createStringStorage()
     64         ).withSelectionPredicate(
     65             SelectionPredicates.createSelectSingleAnything()
     66         ).build()
     67         savedInstanceState?.let { tracker.onRestoreInstanceState(it) }
     68         adapter.tracker = tracker
     69         this.tracker = tracker
     70         if (savedInstanceState == null) {
     71             // select last selected order line when re-creating this fragment
     72             // do it before attaching the tracker observer
     73             liveOrder.selectedProductKey?.let { tracker.select(it) }
     74         }
     75         tracker.addObserver(object : SelectionTracker.SelectionObserver<String>() {
     76             override fun onItemStateChanged(key: String, selected: Boolean) {
     77                 super.onItemStateChanged(key, selected)
     78                 val item = if (selected) adapter.getItemByKey(key) else null
     79                 liveOrder.selectOrderLine(item)
     80             }
     81         })
     82         liveOrder.order.observe(viewLifecycleOwner) { order ->
     83             if (order == null) return@observe
     84             onOrderChanged(order, tracker)
     85         }
     86     }
     87 
     88     override fun onSaveInstanceState(outState: Bundle) {
     89         super.onSaveInstanceState(outState)
     90         tracker?.onSaveInstanceState(outState)
     91     }
     92 
     93     private fun onOrderChanged(order: Order, tracker: SelectionTracker<String>) {
     94         adapter.setItems(order.products) {
     95             liveOrder.lastAddedProduct?.let {
     96                 val position = adapter.findPosition(it)
     97                 if (position >= 0) {
     98                     ui.orderList.scrollToPosition(position)
     99                     ui.orderList.post { this.tracker?.select(it.id) }
    100                     return@setItems
    101                 }
    102             }
    103             val selectedKey = tracker.selection.firstOrNull()
    104             val selectedProduct = selectedKey?.let { key ->
    105                 order.products.find { it.id == key }
    106             }
    107             if (selectedProduct == null) {
    108                 val fallbackProduct = order.products.lastOrNull()
    109                 tracker.clearSelection()
    110                 if (fallbackProduct == null) {
    111                     liveOrder.selectOrderLine(null)
    112                 } else {
    113                     ui.orderList.post { this.tracker?.select(fallbackProduct.id) }
    114                 }
    115             }
    116         }
    117     }
    118 
    119 }