Showing balance of displayed (filtered / all) transactions at top

This commit is contained in:
dankito 2024-08-29 17:49:17 +02:00
parent 3488afc9eb
commit 4911152846
3 changed files with 101 additions and 36 deletions

View File

@ -16,15 +16,17 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import net.codinux.banking.client.model.Amount import net.codinux.banking.client.model.Amount
import net.codinux.banking.ui.extensions.toBigDecimal
import net.codinux.banking.ui.forms.RoundedCornersCard
import net.codinux.banking.ui.config.Colors import net.codinux.banking.ui.config.Colors
import net.codinux.banking.ui.config.DI import net.codinux.banking.ui.config.DI
import net.codinux.banking.ui.forms.RoundedCornersCard
import net.codinux.banking.ui.service.CalculatorService
import net.codinux.banking.ui.state.UiState import net.codinux.banking.ui.state.UiState
import org.jetbrains.compose.ui.tooling.preview.Preview import org.jetbrains.compose.ui.tooling.preview.Preview
private val filterService = DI.accountTransactionsFilterService private val filterService = DI.accountTransactionsFilterService
private val calculator = CalculatorService()
private val formatUtil = DI.formatUtil private val formatUtil = DI.formatUtil
@Composable @Composable
@ -46,9 +48,17 @@ fun TransactionsList(uiState: UiState) {
derivedStateOf { transactionsToDisplay.groupBy { LocalDate(it.valueDate.year, it.valueDate.monthNumber, 1) } } derivedStateOf { transactionsToDisplay.groupBy { LocalDate(it.valueDate.year, it.valueDate.monthNumber, 1) } }
} }
LazyColumn(
modifier = Modifier.padding(horizontal = 8.dp).widthIn(max = 800.dp) Column(Modifier.fillMaxHeight().padding(horizontal = 8.dp)) {
) { Row(Modifier.fillMaxWidth().height(32.dp).background(Colors.Zinc200), verticalAlignment = Alignment.CenterVertically) {
Text("${transactionsToDisplay.size} Umsätze")
Spacer(Modifier.weight(1f))
val balance = calculator.calculateBalanceOfDisplayedTransactions(transactionsToDisplay, userAccounts, transactionsFilter)
Text(formatUtil.formatAmount(balance, "EUR"), color = formatUtil.getColorForAmount(balance))
}
LazyColumn(Modifier.fillMaxHeight()) {
items(groupedByMonth.keys.sortedDescending()) { month -> items(groupedByMonth.keys.sortedDescending()) { month ->
Column(Modifier.fillMaxWidth()) { Column(Modifier.fillMaxWidth()) {
Text( Text(
@ -77,16 +87,14 @@ fun TransactionsList(uiState: UiState) {
Column(Modifier.fillMaxWidth().padding(top = 10.dp), horizontalAlignment = Alignment.End) { Column(Modifier.fillMaxWidth().padding(top = 10.dp), horizontalAlignment = Alignment.End) {
Text( Text(
// TODO: find a better solution text = formatUtil.formatAmount(calculator.sumIncome(monthTransactions), calculator.getTransactionsCurrency(monthTransactions)),
text = formatUtil.formatAmount(Amount(monthTransactions.map { it.amount.toBigDecimal() }.filter { it > 0 }.sum().toString()), "EUR"),
color = formatUtil.getColorForAmount(Amount.Zero) color = formatUtil.getColorForAmount(Amount.Zero)
) )
} }
Column(Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 16.dp), horizontalAlignment = Alignment.End) { Column(Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 16.dp), horizontalAlignment = Alignment.End) {
Text( Text(
// TODO: find a better solution text = formatUtil.formatAmount(calculator.sumExpenses(monthTransactions), calculator.getTransactionsCurrency(monthTransactions)),
text = formatUtil.formatAmount(Amount(monthTransactions.map { it.amount.toBigDecimal() }.filter { it < 0 }.sum().toString()), "EUR"),
color = formatUtil.getColorForAmount(Amount("-1")) color = formatUtil.getColorForAmount(Amount("-1"))
) )
} }
@ -94,6 +102,7 @@ fun TransactionsList(uiState: UiState) {
} }
} }
} }
}
@Preview @Preview
@Composable @Composable

View File

@ -6,6 +6,10 @@ import net.codinux.banking.dataaccess.entities.UserAccountEntity
class AccountTransactionsFilter { class AccountTransactionsFilter {
val noFiltersApplied: Boolean
get() = showAllAccounts && noSearchTermApplied
var selectedAccounts = mutableStateOf<List<BankAccountFilter>>(emptyList()) var selectedAccounts = mutableStateOf<List<BankAccountFilter>>(emptyList())
private set private set
@ -27,6 +31,9 @@ class AccountTransactionsFilter {
var searchTerm by mutableStateOf("") var searchTerm by mutableStateOf("")
private set private set
val noSearchTermApplied: Boolean
get() = searchTerm.isBlank()
fun updateSearchTerm(searchTerm: String) { fun updateSearchTerm(searchTerm: String) {
this.searchTerm = searchTerm this.searchTerm = searchTerm
} }

View File

@ -0,0 +1,49 @@
package net.codinux.banking.ui.service
import net.codinux.banking.client.model.Amount
import net.codinux.banking.dataaccess.entities.UserAccountEntity
import net.codinux.banking.ui.extensions.toBigDecimal
import net.codinux.banking.ui.model.AccountTransactionViewModel
import net.codinux.banking.ui.model.AccountTransactionsFilter
class CalculatorService {
fun sumTransactions(transactions: Collection<AccountTransactionViewModel>): Amount =
// TODO: find a better solution
Amount(transactions.sumOf { it.amount.toBigDecimal() }.toString())
fun sumAmounts(amounts: Collection<Amount>): Amount =
// TODO: find a better solution
Amount(amounts.sumOf { it.toBigDecimal() }.toString())
fun sumIncome(transactions: Collection<AccountTransactionViewModel>): Amount =
// TODO: find a better solution
Amount(transactions.map { it.amount.toBigDecimal() }.filter { it > 0 }.sum().toString())
fun sumExpenses(transactions: Collection<AccountTransactionViewModel>): Amount =
// TODO: find a better solution
Amount(transactions.map { it.amount.toBigDecimal() }.filter { it < 0 }.sum().toString())
fun calculateBalanceOfDisplayedTransactions(transactions: Collection<AccountTransactionViewModel>, userAccounts: Collection<UserAccountEntity>, filter: AccountTransactionsFilter): Amount {
if (filter.noFiltersApplied) {
return sumAmounts(userAccounts.flatMap { it.accounts.map { it.balance } })
}
val selectedAccount = filter.selectedAccount
return if (selectedAccount != null) {
if (selectedAccount.bankAccount != null) {
selectedAccount.bankAccount.balance
} else {
sumAmounts(selectedAccount.userAccount.accounts.map { it.balance })
}
} else {
sumTransactions(transactions)
}
}
fun getTransactionsCurrency(transactions: Collection<AccountTransactionViewModel>): String =
// TODO: really get transactions' currency
"EUR"
}