Untitled
unknown
kotlin
3 years ago
27 kB
11
Indexable
package `in`.swipe.app.app.ui.customers
import `in`.swipe.app.R
import `in`.swipe.app.app.Constants
import `in`.swipe.app.app.SwipeApplication
import `in`.swipe.app.app.Utils
import `in`.swipe.app.app.Utils.hideKeyboard
import `in`.swipe.app.app.navigateTo
import `in`.swipe.app.app.ui.customers.addcustomermanually.AddCustomerManuallyActivity
import `in`.swipe.app.app.ui.document.FabExtendingOnScrollListener
import `in`.swipe.app.app.ui.home.SharedViewModel
import `in`.swipe.app.app.ui.parties.AddPartiesListener
import `in`.swipe.app.app.ui.parties.PartiesViewModel
import `in`.swipe.app.app.ui.parties.SearchQueryListener
import `in`.swipe.app.app.ui.parties.bottomsheet.SortPartiesBottomSheetFragment
import `in`.swipe.app.app.ui.parties.bottomsheet.UserDetailsBottomSheetFragment
import `in`.swipe.app.app.ui.utils.WrapContentLinearLayoutManager
import `in`.swipe.app.data.model.models.CustomerData
import `in`.swipe.app.data.model.models.Vendor
import `in`.swipe.app.data.prefs.PreferenceHelper
import `in`.swipe.app.databinding.FragmentCustomersBinding
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.*
import android.widget.AbsListView
import android.widget.LinearLayout
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
import com.mancj.materialsearchbar.MaterialSearchBar
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import kotlin.math.max
class CustomersFragment : Fragment(), SearchQueryListener, AddPartiesListener,
MenuItem.OnMenuItemClickListener, MaterialSearchBar.OnSearchActionListener,
Toolbar.OnMenuItemClickListener, SortPartiesBottomSheetFragment.OnItemClickListener,
CustomerAdapter.OnItemClickListener {
private lateinit var binding: FragmentCustomersBinding
private lateinit var parentActivity: AppCompatActivity
private lateinit var navHostFragment: NavHostFragment
private lateinit var navController: NavController
private var isCustomerAccess = PreferenceHelper.getCustomersAccess()
private var customerAdapter: CustomerAdapter? = null
private lateinit var linearLayoutManager: WrapContentLinearLayoutManager
private var newInvoiceLayout = false
private var isSelectCustomer = false
private val viewModel by sharedViewModel<CustomersViewModel>()
private lateinit var sortBottomSheet: SortPartiesBottomSheetFragment
private lateinit var userDetailsBottomSheet: UserDetailsBottomSheetFragment
private var radioButtonValue = "Default"
private var sortNetBalanceBy = ""
private lateinit var resultLauncher: ActivityResultLauncher<Intent>
private var selectedCustomerId = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
if (it.containsKey("newInvoiceLayout")) {
newInvoiceLayout = it.getBoolean("newInvoiceLayout")
}
if (it.containsKey(Constants.BUNDLE_IS_SELECT_CUSTOMER)) {
isSelectCustomer = it.getBoolean(Constants.BUNDLE_IS_SELECT_CUSTOMER)
}
}
resultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
data?.let {
if (isVisible) {
selectedCustomerId = it.getIntExtra(Constants.NEW_CUSTOMER_ID, -1)
}
}
}
}
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentCustomersBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
parentActivity = activity as AppCompatActivity
logFragment("onViewCreated called")
setupNavigationComponent()
setListeners()
observeData()
if (isCustomerAccess == 1) {
viewModel.getAllCustomers(sortNetBalanceBy)
startShimmer()
}
if (isCustomerAccess == 1) {
binding.noAccess.visibility = View.GONE
binding.recyclerview.visibility = View.VISIBLE
} else {
binding.noAccess.visibility = View.VISIBLE
customerAdapter?.resetDiffer()
binding.recyclerview.visibility = View.GONE
}
if (isSelectCustomer) {
binding.includeTool.visibility = View.VISIBLE
binding.btnCreateCustomer.visibility = View.GONE
binding.searchBarCustomer.visibility = View.GONE
binding.sortCustomer.visibility = View.GONE
searchCustomers()
} else {
binding.includeTool.visibility = View.GONE
binding.btnCreateCustomer.visibility = View.VISIBLE
binding.sortCustomer.visibility = View.VISIBLE
binding.searchBarCustomer.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s.isNullOrEmpty().not() || s.isNullOrBlank().not()) {
viewModel.searchCustomer(s.toString())
} else {
if (PreferenceHelper.getCustomersAccess() == 1) {
viewModel.getAllCustomers(sortNetBalanceBy)
binding.recyclerview.visibility = View.VISIBLE
} else {
binding.noDataMessage.visibility = View.GONE
binding.noAccess.visibility = View.VISIBLE
customerAdapter?.resetDiffer()
binding.recyclerview.visibility = View.GONE
}
}
}
override fun afterTextChanged(s: Editable?) {
}
})
}
binding.btnCreateCustomer.setOnClickListener {
logFragment("btnCreateCustomer clicked")
val addCustomerManuallyIntent =
Intent(parentActivity, AddCustomerManuallyActivity::class.java)
resultLauncher.launch(addCustomerManuallyIntent)
requireActivity().overridePendingTransition(
R.anim.activity_slide_in_right_trans,
R.anim.activity_slide_out_left_trans
)
}
binding.addCust.setOnClickListener {
logFragment("addCust clicked")
val addCustomerManuallyIntent =
Intent(parentActivity, AddCustomerManuallyActivity::class.java)
resultLauncher.launch(addCustomerManuallyIntent)
requireActivity().overridePendingTransition(
R.anim.activity_slide_in_right_trans,
R.anim.activity_slide_out_left_trans
)
}
binding.btnAddCustomer.setOnClickListener {
logFragment("btnCreateCustomer clicked")
binding.btnCreateCustomer.visibility = View.VISIBLE
binding.addCustomerLayout.visibility = View.GONE
val addCustomerManuallyIntent =
Intent(parentActivity, AddCustomerManuallyActivity::class.java)
resultLauncher.launch(addCustomerManuallyIntent)
requireActivity().overridePendingTransition(
R.anim.activity_slide_in_right_trans,
R.anim.activity_slide_out_left_trans
)
}
setupToolBar()
binding.customerFragmentToolbar.setOnMenuItemClickListener(this@CustomersFragment)
binding.sortCustomer.setOnClickListener {
sortBottomSheet = SortPartiesBottomSheetFragment(this, radioButtonValue)
val fm = childFragmentManager
sortBottomSheet.show(fm, tag)
}
}
private fun setupToolBar() {
//parentActivity.setSupportActionBar(binding.customerFragmentToolbar)
binding.customerFragmentToolbar.title = "Customers"
binding.customerFragmentToolbar.navigationIcon =
ContextCompat.getDrawable(requireActivity(), R.drawable.ic_back_black)
binding.customerFragmentToolbar.setNavigationOnClickListener {
activity?.onBackPressed()
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
menu.clear()
inflater.inflate(R.menu.parties_toolbar_menu, menu)
val searchItem = menu.findItem(R.id.menuItemSearch)
searchItem.setOnMenuItemClickListener(this)
super.onCreateOptionsMenu(menu, inflater)
}
private fun searchCustomers() {
binding.searchBarCust.addTextChangeListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s.isNullOrEmpty().not() || s.isNullOrBlank().not())
viewModel.searchCustomer(s.toString())
else
viewModel.getAllCustomers(sortNetBalanceBy)
}
override fun afterTextChanged(s: Editable?) {
}
})
binding.searchBarCust.setOnSearchActionListener(this@CustomersFragment)
}
override fun onResume() {
super.onResume()
if (isAdded && isSelectCustomer) {
if (isCustomerAccess == 1) {
viewModel.getAllCustomers(sortNetBalanceBy)
startShimmer()
}
}
}
private fun setupNavigationComponent() {
logFragment("setupNavigationComponent clicked")
navHostFragment =
parentActivity.supportFragmentManager.findFragmentById(R.id.navHostFragmentContainer) as NavHostFragment
navController = navHostFragment.navController
}
private fun setListeners() {
val dividerItemDecoration =
DividerItemDecoration(parentActivity, LinearLayout.VERTICAL)
linearLayoutManager = WrapContentLinearLayoutManager(parentActivity)
customerAdapter = CustomerAdapter(
parentActivity,
navController,
newInvoiceLayout,
this
)
binding.recyclerview.layoutManager = linearLayoutManager
binding.recyclerview.addItemDecoration(dividerItemDecoration)
binding.recyclerview.setHasFixedSize(true)
binding.recyclerview.adapter = customerAdapter
binding.swipeRefreshLayout.setOnRefreshListener {
logFragment("swipeRefreshLayout.setOnRefreshListener clicked")
if(PreferenceHelper.getCustomersAccess() == 1) {
if (viewModel.searchingState.value == PartiesViewModel.IDLE) {
viewModel.getAllCustomers(sortNetBalanceBy)
startShimmer()
} else {
stopShimmer()
binding.swipeRefreshLayout.isRefreshing = false
}
binding.recyclerview.visibility = View.VISIBLE
} else {
binding.swipeRefreshLayout.isRefreshing = false
binding.noDataMessage.visibility = View.GONE
binding.noAccess.visibility = View.VISIBLE
binding.recyclerview.visibility = View.GONE
customerAdapter?.resetDiffer()
}
}
binding.recyclerview.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
viewModel.isScrolling.value = true
}
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val currentItems = linearLayoutManager.childCount
val totalItems = linearLayoutManager.itemCount
val scrollOutItems = linearLayoutManager.findFirstVisibleItemPosition()
if (viewModel.isScrolling.value == true && dy >= 0 && (currentItems + scrollOutItems == totalItems && viewModel.searchingState.value == PartiesViewModel.IDLE)) {
if (viewModel.getCanLoadNewData().value == true) {
logFragment("viewModel.getMoreData() called")
viewModel.isScrolling.value = false
viewModel.currentPage.value = viewModel.currentPage.value?.plus(1)
viewModel.getMoreData(sortNetBalanceBy)
}
}
}
})
binding.recyclerview.addOnScrollListener(FabExtendingOnScrollListener(binding.btnCreateCustomer))
}
private fun observeData() {
viewModel.getDataFetched().observe(viewLifecycleOwner) {
it?.let {
when (it) {
true -> {
if (binding.recyclerview.adapter == null) {
logFragment("setting up customers adapter")
stopShimmer()
val dividerItemDecoration =
DividerItemDecoration(parentActivity, LinearLayout.VERTICAL)
linearLayoutManager = WrapContentLinearLayoutManager(parentActivity)
customerAdapter = CustomerAdapter(
parentActivity,
navController,
newInvoiceLayout,
this
)
binding.recyclerview.layoutManager = linearLayoutManager
binding.recyclerview.addItemDecoration(dividerItemDecoration)
binding.recyclerview.adapter = customerAdapter
}
if (viewModel.searchingState.value != PartiesViewModel.IDLE) {
viewModel.searchingState.value = PartiesViewModel.IDLE
}
binding.swipeRefreshLayout.isRefreshing = false
}
false -> {
stopShimmer()
logFragment("error fetching customers")
binding.swipeRefreshLayout.isRefreshing = false
Toast.makeText(
parentActivity,
R.string.error_fetching_customers,
Toast.LENGTH_LONG
).show()
}
}
}
}
viewModel.searchingState.observe(viewLifecycleOwner) {
it?.let {
when (it) {
PartiesViewModel.IDLE -> {
binding.progressBar.visibility = View.GONE
}
PartiesViewModel.IS_SEARCHING -> {
binding.progressBar.visibility = View.VISIBLE
}
PartiesViewModel.SEARCHING_COMPLETED -> {
customerAdapter?.updateCustomersData(viewModel.newCustomers.value!!)
binding.progressBar.visibility = View.GONE
}
PartiesViewModel.SEARCHING_GOT_ERROR -> {
Toast.makeText(activity, R.string.error_getting_search, Toast.LENGTH_LONG)
.show()
binding.progressBar.visibility = View.GONE
}
}
}
}
viewModel.newCustomers.observe(viewLifecycleOwner) {
it?.let {
logFragment("newCustomers observer called", it.toString())
stopShimmer()
if (selectedCustomerId != -1 && isSelectCustomer) {
if (it.size > 0) {
ViewModelProvider(context as AppCompatActivity)[SharedViewModel::class.java].selectedCustomer.value =
Pair(it.findLast { it.customer_id == selectedCustomerId },true)
selectedCustomerId = -1
requireActivity().onBackPressed()
} else {
Toast.makeText(
requireActivity(),
"Something went wrong!!",
Toast.LENGTH_SHORT
).show()
}
}
if (viewModel.searchingState.value != null && viewModel.searchingState.value != PartiesViewModel.SEARCHING_COMPLETED) {
if (it.size == 0 && viewModel.currentPage.value == 0) {
customerAdapter?.updateCustomersData(it)
binding.noDataMessage.visibility = View.VISIBLE
binding.noAccess.visibility = View.GONE
if (viewModel.searchingState.value == -1) {
binding.btnCreateCustomer.visibility = View.GONE
binding.noDataMessage.visibility = View.GONE
binding.addCustomerLayout.visibility = View.VISIBLE
binding.addCustomerText.visibility = View.GONE
binding.btnAddCustomer.visibility = View.VISIBLE
} else {
binding.btnCreateCustomer.visibility = View.VISIBLE
binding.addCustomerLayout.visibility = View.GONE
}
if (isSelectCustomer) {
binding.addCust.visibility = View.VISIBLE
if (viewModel.searchingState.value != PartiesViewModel.IS_SEARCHING) {
if (isVisible) {
binding.searchBarCust.visibility = View.INVISIBLE
activity?.currentFocus?.hideKeyboard()
}
}
}
} else {
binding.noAccess.visibility = View.GONE
binding.recyclerview.visibility = View.VISIBLE
binding.swipeRefreshLayout.visibility = View.VISIBLE
binding.customersList.visibility = View.VISIBLE
if (isSelectCustomer) {
binding.addCust.visibility = View.VISIBLE
binding.searchBarCust.visibility = View.VISIBLE
binding.searchBarCust.setHint("Search Customers")
binding.searchBarCust.openSearch()
if (isVisible) {
Utils.showKeyboard(binding.searchBarCust.searchEditText)
}
}
binding.addCustomerLayout.visibility = View.GONE
binding.noDataMessage.visibility = View.GONE
if (!isSelectCustomer)
binding.btnCreateCustomer.visibility = View.VISIBLE
}
if (viewModel.currentPage.value == 0) {
customerAdapter?.updateCustomersData(it)
} else {
customerAdapter?.updateData(it)
}
}
}
}
viewModel.getIsLoadingNewData().observe(viewLifecycleOwner) {
it?.let {
logFragment("getIsLoadingNewData observer called")
if (it) {
} else {
stopShimmer()
}
}
}
viewModel.getCanLoadNewData().observe(viewLifecycleOwner) {
it?.let {
logFragment("getCanLoadNewData observer called")
if (!it) {
Toast.makeText(parentActivity, R.string.no_more_data, Toast.LENGTH_LONG).show()
customerAdapter?.lastPage = true
customerAdapter?.notifyItemChanged(
customerAdapter?.differ?.currentList?.lastIndex ?: 0
)
}
}
}
viewModel.dataFetched.observe(viewLifecycleOwner) {
if (!it) {
binding.noAccess.visibility = View.VISIBLE
customerAdapter?.resetDiffer()
binding.addCustomerLayout.visibility = View.GONE
binding.recyclerview.visibility = View.GONE
}
}
}
private fun startShimmer() {
binding.shimmerLayout.startShimmer()
binding.shimmerLayout.visibility = View.VISIBLE
binding.swipeRefreshLayout.visibility = View.GONE
binding.recyclerview.visibility = View.GONE
}
private fun stopShimmer() {
binding.shimmerLayout.stopShimmer()
binding.shimmerLayout.visibility = View.GONE
binding.swipeRefreshLayout.visibility = View.VISIBLE
binding.recyclerview.visibility = View.VISIBLE
}
override fun onSearchQuerySubmit(query: String) {
if (isVisible) {
if (query.isNullOrEmpty().not()) {
viewModel.searchCustomer(query)
}
}
}
override fun onSearchBarClosed() {
if (isAdded) {
viewModel.getAllCustomers(sortNetBalanceBy)
logFragment("onSearchBarClosed called")
}
}
override fun onDestroy() {
if (customerAdapter != null)
customerAdapter!!.resetDiffer()
super.onDestroy()
}
override fun add() {
logFragment("action_navBarMenuParties_to_addNewCustFragment called")
navController.currentDestination?.getAction(R.id.action_navBarMenuParties_to_addNewCustFragment)
?.let {
navController.navigateTo(
R.id.action_navBarMenuParties_to_addNewCustFragment
)
} ?: run {
navController.navigateTo(R.id.action_createInvoiceParties_to_addNewCustFragment)
}
}
fun logFragment(methodName: String, methodParameter: String = "None") {
val bundle = Bundle()
bundle.putString(Constants.FRAGMENT_NAME, "customers_fragment")
bundle.putString(Constants.FRAGMENT_METHOD, methodName)
bundle.putString(Constants.FRAGMENT_METHOD_PARAMETER, methodParameter)
if (activity != null)
(activity?.applicationContext as SwipeApplication).logFragment(bundle)
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
val cx = binding.searchBarCust.measuredWidth / 2
val cy = binding.searchBarCust.measuredHeight / 2
if (isVisible){
val finalRadius = max(binding.searchBarCust.width, binding.searchBarCust.height) / 2
val anim = ViewAnimationUtils.createCircularReveal(
binding.searchBarCust, cx, cy, 0F,
finalRadius.toFloat()
)
binding.searchBarCust.visibility = View.VISIBLE
binding.searchBarCust.performClick()
anim.start()
}
return true
}
override fun onSearchStateChanged(enabled: Boolean) {
if (!enabled) {
activity?.onBackPressed()
// val cx = binding.searchBarCust.measuredWidth / 2
// val cy = binding.searchBarCust.measuredHeight / 2
//
// val finalRadius =
// max(binding.searchBarCust.width, binding.searchBarCust.height) / 2
//
// val anim = ViewAnimationUtils.createCircularReveal(
// binding.searchBarCust, cx, cy,
// finalRadius.toFloat(), 0F
// )
// binding.searchBarCust.visibility = View.VISIBLE
// anim.addListener(object : Animator.AnimatorListener {
// override fun onAnimationStart(animation: Animator?) {
// }
//
// override fun onAnimationEnd(animation: Animator?) {
// binding.searchBarCust.visibility = View.INVISIBLE
// }
//
// override fun onAnimationCancel(animation: Animator?) {
// }
//
// override fun onAnimationRepeat(animation: Animator?) {
// }
// })
// anim.start()
}
}
fun getAllCustomers() {
// if (isVisible) {
// viewModel.getAllCustomers()
// }
}
override fun onSearchConfirmed(text: CharSequence?) {
}
override fun onButtonClicked(buttonCode: Int) {
}
override fun onRadioItemSelected(selectedRadioValue: String) {
radioButtonValue = selectedRadioValue
sortNetBalanceBy = when (selectedRadioValue) {
"Net Balance - Low to High" -> "asc"
"Net Balance - High to Low" -> "desc"
else -> ""
}
viewModel.getAllCustomers(sortNetBalanceBy)
}
override fun onMoreDetailsClick(customer: CustomerData) {
userDetailsBottomSheet = UserDetailsBottomSheetFragment("customer",customer)
val fm = childFragmentManager
userDetailsBottomSheet.show(fm,tag)
}
}Editor is loading...