2018-12-03 19:34:13 +00:00
|
|
|
package cy.agorise.bitsybitshareswallet.viewmodels
|
|
|
|
|
|
|
|
import android.app.Application
|
2019-04-26 21:05:58 +00:00
|
|
|
import androidx.lifecycle.*
|
2018-12-03 19:34:13 +00:00
|
|
|
import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail
|
2019-04-26 21:05:58 +00:00
|
|
|
import cy.agorise.bitsybitshareswallet.models.FilterOptions
|
2018-12-03 19:34:13 +00:00
|
|
|
import cy.agorise.bitsybitshareswallet.repositories.TransferDetailRepository
|
2019-12-25 23:15:19 +00:00
|
|
|
import cy.agorise.bitsybitshareswallet.utils.Helper
|
2019-04-26 21:05:58 +00:00
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
import kotlinx.coroutines.withContext
|
|
|
|
import java.util.*
|
2018-12-03 19:34:13 +00:00
|
|
|
|
2019-04-26 19:41:34 +00:00
|
|
|
class TransactionsViewModel(application: Application) : AndroidViewModel(application) {
|
2019-11-06 21:53:39 +00:00
|
|
|
companion object {
|
2019-12-25 23:15:19 +00:00
|
|
|
const val TAG = "TransactionsViewModel"
|
2019-11-06 21:53:39 +00:00
|
|
|
}
|
2018-12-03 19:34:13 +00:00
|
|
|
private var mRepository = TransferDetailRepository(application)
|
|
|
|
|
2019-04-26 21:05:58 +00:00
|
|
|
/**
|
|
|
|
* [FilterOptions] used to filter the list of [TransferDetail] taken from the database
|
|
|
|
*/
|
|
|
|
private var mFilterOptions = FilterOptions()
|
|
|
|
|
|
|
|
private lateinit var transactions : LiveData<List<TransferDetail>>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This [MediatorLiveData] is used to combine two sources of information into one, keeping the
|
|
|
|
* client of this [ViewModel] receiving only one stream of data (a list of filtered [TransferDetail])
|
|
|
|
*/
|
|
|
|
private val filteredTransactions = MediatorLiveData<List<TransferDetail>>()
|
|
|
|
|
|
|
|
init {
|
|
|
|
// Initialize the start and end dates for the FilterOptions
|
|
|
|
val calendar = Calendar.getInstance()
|
|
|
|
mFilterOptions.endDate = calendar.timeInMillis
|
|
|
|
calendar.add(Calendar.MONTH, -2)
|
|
|
|
mFilterOptions.startDate = calendar.timeInMillis
|
|
|
|
}
|
|
|
|
|
|
|
|
internal fun getFilteredTransactions(userId: String): LiveData<List<TransferDetail>> {
|
2020-01-06 16:08:46 +00:00
|
|
|
val currencyCode = Helper.getCoingeckoSupportedCurrency(Locale.getDefault())
|
2019-12-25 23:15:19 +00:00
|
|
|
transactions = mRepository.getAll(userId, currencyCode)
|
|
|
|
|
|
|
|
filteredTransactions.addSource(transactions) { transactions ->
|
|
|
|
viewModelScope.launch {
|
|
|
|
filteredTransactions.value = filter(transactions, mFilterOptions)
|
|
|
|
}
|
|
|
|
}
|
2019-04-26 21:05:58 +00:00
|
|
|
|
|
|
|
return filteredTransactions
|
|
|
|
}
|
|
|
|
|
|
|
|
internal fun getFilterOptions(): FilterOptions {
|
|
|
|
return mFilterOptions
|
|
|
|
}
|
|
|
|
|
|
|
|
internal fun applyFilterOptions(filterOptions: FilterOptions) = transactions.value?.let { transactions ->
|
|
|
|
viewModelScope.launch {
|
|
|
|
filteredTransactions.value = filter(transactions, filterOptions)
|
|
|
|
}
|
|
|
|
}.also { mFilterOptions = filterOptions }
|
|
|
|
|
|
|
|
internal fun setFilterQuery(query: String) = transactions.value?.let { transactions ->
|
|
|
|
mFilterOptions.query = query
|
|
|
|
viewModelScope.launch {
|
|
|
|
filteredTransactions.value = filter(transactions, mFilterOptions)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal fun getFilteredTransactionsOnce() = filteredTransactions.value
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filters the given list of [TransferDetail] given the [FilterOptions] and returns a filtered list
|
|
|
|
* of [TransferDetail], doing all the work in a background thread using kotlin coroutines
|
|
|
|
*/
|
|
|
|
private suspend fun filter(transactions: List<TransferDetail>, filterOptions: FilterOptions) : List<TransferDetail> {
|
|
|
|
return withContext(Dispatchers.Default) {
|
|
|
|
|
|
|
|
// Create a list to store the filtered transactions
|
|
|
|
val filteredTransactions = ArrayList<TransferDetail>()
|
|
|
|
|
|
|
|
// Make sure the filter dates use the same format as the transactions' dates
|
|
|
|
val startDate = filterOptions.startDate / 1000
|
|
|
|
val endDate = filterOptions.endDate / 1000
|
|
|
|
|
|
|
|
for (transaction in transactions) {
|
|
|
|
// Filter by transfer direction
|
|
|
|
if (transaction.direction) { // Transfer sent
|
|
|
|
if (filterOptions.transactionsDirection == 1)
|
|
|
|
// Looking for received transfers only
|
|
|
|
continue
|
|
|
|
} else { // Transfer received
|
|
|
|
if (filterOptions.transactionsDirection == 2)
|
|
|
|
// Looking for sent transactions only
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Filter by date range
|
|
|
|
if (!filterOptions.dateRangeAll && (transaction.date < startDate ||
|
|
|
|
transaction.date > endDate))
|
|
|
|
continue
|
|
|
|
|
|
|
|
// Filter by asset
|
|
|
|
if (!filterOptions.assetAll && transaction.assetSymbol != filterOptions.asset)
|
|
|
|
continue
|
|
|
|
|
|
|
|
// Filter by equivalent value
|
|
|
|
if (!filterOptions.equivalentValueAll && ((transaction.fiatAmount ?: -1 ) < filterOptions.fromEquivalentValue
|
|
|
|
|| (transaction.fiatAmount ?: -1) > filterOptions.toEquivalentValue))
|
|
|
|
continue
|
|
|
|
|
|
|
|
// Filter transactions sent to agorise
|
|
|
|
if (filterOptions.agoriseFees && transaction.to.equals("agorise"))
|
|
|
|
continue
|
|
|
|
|
|
|
|
// Filter by search query
|
2019-05-06 18:28:28 +00:00
|
|
|
val text = "${transaction.from ?: ""} ${transaction.to ?: ""} ${transaction.memo}"
|
2019-04-26 21:05:58 +00:00
|
|
|
if (text.contains(filterOptions.query, ignoreCase = true)) {
|
|
|
|
filteredTransactions.add(transaction)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
filteredTransactions
|
|
|
|
}
|
2018-12-03 19:34:13 +00:00
|
|
|
}
|
|
|
|
}
|