diff --git a/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsView.kt b/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsView.kt index 55992da9..9a64004b 100644 --- a/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsView.kt +++ b/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsView.kt @@ -7,8 +7,8 @@ import javafx.scene.control.ContextMenu import javafx.scene.input.ContextMenuEvent import javafx.scene.input.MouseButton import javafx.scene.input.MouseEvent -import net.dankito.banking.ui.model.Account import net.dankito.banking.ui.model.AccountTransaction +import net.dankito.banking.ui.model.BankAccount import net.dankito.banking.ui.model.parameters.TransferMoneyData import net.dankito.banking.ui.model.responses.GetTransactionsResponse import net.dankito.banking.ui.presenter.MainWindowPresenter @@ -30,15 +30,13 @@ open class AccountTransactionsView(private val presenter: MainWindowPresenter) : init { - presenter.addAccountsChangedListener { handleAccountsChanged(it) } + presenter.addSelectedBankAccountsChangedListener { handleSelectedBankAccountsChanged(it) } presenter.addRetrievedAccountTransactionsResponseListener { _, response -> handleGetTransactionsResponseOffUiThread(response) } - transactionsFilter.addListener { _, _, newValue -> - transactionsToDisplay.setAll(presenter.searchAccountTransactions(newValue)) - } + transactionsFilter.addListener { _, _, newValue -> updateTransactionsToDisplay(newValue) } } @@ -110,8 +108,23 @@ open class AccountTransactionsView(private val presenter: MainWindowPresenter) : } - protected open fun handleAccountsChanged(accounts: List) { - isAccountSelected.value = accounts.isNotEmpty() // TODO: not correct, check if an account has been selected + protected open fun handleSelectedBankAccountsChanged(selectedBankAccounts: List) { + runLater { + isAccountSelected.value = selectedBankAccounts.isNotEmpty() + + updateTransactionsToDisplay() + } + } + + protected open fun updateTransactionsToDisplay() { + updateTransactionsToDisplay(transactionsFilter.value) + } + + protected open fun updateTransactionsToDisplay(filter: String) { + transactionsToDisplay.setAll(presenter.searchSelectedAccountTransactions(filter)) + + // TODO: if transactions are filtered calculate and show balance of displayed transactions? + balance.value = presenter.balanceOfSelectedBankAccounts.toString() } protected open fun handleGetTransactionsResponseOffUiThread(response: GetTransactionsResponse) { @@ -120,10 +133,7 @@ open class AccountTransactionsView(private val presenter: MainWindowPresenter) : protected open fun handleGetTransactionsResponseOnUiThread(response: GetTransactionsResponse) { if (response.isSuccessful) { - transactionsToDisplay.setAll(presenter.allTransactions) // TODO: get that one for currently displayed account and apply current filter on it - - // TODO: if transactions are filtered calculate and show balance of displayed transactions? - balance.value = presenter.balanceOfAllAccounts.toString() // TODO: get that one for currently displayed account and add currency + updateTransactionsToDisplay() } } diff --git a/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountsView.kt b/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountsView.kt index 6e6844c0..b95e143f 100644 --- a/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountsView.kt +++ b/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountsView.kt @@ -3,7 +3,11 @@ package net.dankito.banking.ui.javafx.controls import javafx.collections.FXCollections import javafx.geometry.Pos import javafx.scene.control.TreeItem +import javafx.scene.control.TreeView import javafx.scene.layout.Priority +import net.dankito.banking.ui.javafx.model.AccountsAccountTreeItem +import net.dankito.banking.ui.javafx.model.AccountsBankAccountTreeItem +import net.dankito.banking.ui.javafx.model.AccountsRootTreeItem import net.dankito.banking.ui.presenter.MainWindowPresenter import net.dankito.utils.javafx.ui.controls.addButton import net.dankito.utils.javafx.ui.extensions.fixedHeight @@ -48,7 +52,7 @@ open class AccountsView(protected val presenter: MainWindowPresenter) : View() { } add(AccountsTreeView(accounts).apply { - selectionModel.selectedItemProperty().addListener { _, _, newValue -> selectedAccountChanged(newValue) } + selectionModel.selectedItemProperty().addListener { _, _, newValue -> selectedBankAccountChanged(newValue) } vboxConstraints { vGrow = Priority.ALWAYS @@ -62,4 +66,14 @@ open class AccountsView(protected val presenter: MainWindowPresenter) : View() { presenter.showAddAccountDialog() } + protected open fun selectedBankAccountChanged(accountTreeItem: TreeItem?) { + accountTreeItem?.let { + when (accountTreeItem) { + is AccountsBankAccountTreeItem -> presenter.selectedBankAccount(accountTreeItem.bankAccount) + is AccountsAccountTreeItem -> presenter.selectedAccount(accountTreeItem.account) + else -> presenter.selectedAllBankAccounts() + } + } + } + } \ No newline at end of file diff --git a/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsAccountTreeItem.kt b/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsAccountTreeItem.kt index 415338ca..b0994999 100755 --- a/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsAccountTreeItem.kt +++ b/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsAccountTreeItem.kt @@ -3,7 +3,7 @@ package net.dankito.banking.ui.javafx.model import net.dankito.banking.ui.model.Account -open class AccountsAccountTreeItem(account: Account) : AccountsTreeItemBase(account.displayName) { +open class AccountsAccountTreeItem(val account: Account) : AccountsTreeItemBase(account.displayName) { init { isExpanded = true diff --git a/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsBankAccountTreeItem.kt b/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsBankAccountTreeItem.kt index d7ffa680..02c8ed54 100755 --- a/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsBankAccountTreeItem.kt +++ b/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/model/AccountsBankAccountTreeItem.kt @@ -3,4 +3,4 @@ package net.dankito.banking.ui.javafx.model import net.dankito.banking.ui.model.BankAccount -open class AccountsBankAccountTreeItem(bankAccount: BankAccount) : AccountsTreeItemBase(bankAccount.displayName) \ No newline at end of file +open class AccountsBankAccountTreeItem(val bankAccount: BankAccount) : AccountsTreeItemBase(bankAccount.displayName) \ No newline at end of file diff --git a/BankingUiCommon/src/main/java/net/dankito/banking/ui/presenter/MainWindowPresenter.kt b/BankingUiCommon/src/main/java/net/dankito/banking/ui/presenter/MainWindowPresenter.kt index 9e685766..a5b110fc 100644 --- a/BankingUiCommon/src/main/java/net/dankito/banking/ui/presenter/MainWindowPresenter.kt +++ b/BankingUiCommon/src/main/java/net/dankito/banking/ui/presenter/MainWindowPresenter.kt @@ -45,10 +45,15 @@ open class MainWindowPresenter( protected val clientsForAccounts = mutableMapOf() + protected var selectedBankAccountsField = mutableListOf() + + protected val accountsChangedListeners = mutableListOf<(List) -> Unit>() protected val retrievedAccountTransactionsResponseListeners = mutableListOf<(BankAccount, GetTransactionsResponse) -> Unit>() + protected val selectedBankAccountsChangedListeners = mutableListOf<(List) -> Unit>() + protected val callback: BankingClientCallback = object : BankingClientCallback { @@ -81,6 +86,8 @@ open class MainWindowPresenter( retrievedAccountTransactions(bankAccount, response) } } + + selectedAccount(account) } callback(response) @@ -203,14 +210,14 @@ open class MainWindowPresenter( } - open fun searchAccountTransactions(query: String): List { + open fun searchSelectedAccountTransactions(query: String): List { val queryLowercase = query.trim().toLowerCase() if (queryLowercase.isEmpty()) { - return allTransactions + return selectedBankAccountsAccountTransactions } - return allTransactions.filter { + return selectedBankAccountsAccountTransactions.filter { it.otherPartyName?.toLowerCase()?.contains(queryLowercase) == true || it.usage.toLowerCase().contains(queryLowercase) || it.bookingText?.toLowerCase()?.contains(queryLowercase) == true @@ -241,6 +248,34 @@ open class MainWindowPresenter( } + open val selectedBankAccounts: List + get() = ArrayList(selectedBankAccountsField) + + open val selectedBankAccountsAccountTransactions: List + get() = getAccountTransactionsForAccounts(selectedBankAccounts.map { it.account }.toSet()) + + open val balanceOfSelectedBankAccounts: BigDecimal + get() = getBalanceForAccounts(selectedBankAccounts.map { it.account }.toSet()) + + open fun selectedAllBankAccounts() { + setSelectedBankAccounts(bankAccounts) + } + + open fun selectedAccount(account: Account) { + setSelectedBankAccounts(account.bankAccounts) + } + + open fun selectedBankAccount(bankAccount: BankAccount) { + setSelectedBankAccounts(listOf(bankAccount)) + } + + protected open fun setSelectedBankAccounts(bankAccounts: List) { + this.selectedBankAccountsField = ArrayList(bankAccounts) // make a copy + + callSelectedBankAccountsChangedListeners(selectedBankAccountsField) + } + + open val accounts: List get() = clientsForAccounts.keys.toList() @@ -248,10 +283,19 @@ open class MainWindowPresenter( get() = accounts.flatMap { it.bankAccounts } open val allTransactions: List - get() = clientsForAccounts.keys.flatMap { it.transactions }.sortedByDescending { it.bookingDate } // TODO: someday add unbooked transactions + get() = getAccountTransactionsForAccounts(accounts) open val balanceOfAllAccounts: BigDecimal - get() = clientsForAccounts.keys.map { it.balance }.fold(BigDecimal.ZERO) { acc, e -> acc + e } + get() = getBalanceForAccounts(accounts) + + + protected open fun getAccountTransactionsForAccounts(accounts: Collection): List { + return accounts.flatMap { it.transactions }.sortedByDescending { it.bookingDate } // TODO: someday add unbooked transactions + } + + protected open fun getBalanceForAccounts(accounts: Collection): BigDecimal { + return accounts.map { it.balance }.fold(BigDecimal.ZERO) { acc, e -> acc + e } + } open fun addAccountsChangedListener(listener: (List) -> Unit): Boolean { @@ -270,8 +314,13 @@ open class MainWindowPresenter( } } - open fun addRetrievedAccountTransactionsResponseListener(listener: (BankAccount, GetTransactionsResponse) -> Unit) { - retrievedAccountTransactionsResponseListeners.add(listener) + + open fun addRetrievedAccountTransactionsResponseListener(listener: (BankAccount, GetTransactionsResponse) -> Unit): Boolean { + return retrievedAccountTransactionsResponseListeners.add(listener) + } + + open fun removeRetrievedAccountTransactionsResponseListener(listener: (BankAccount, GetTransactionsResponse) -> Unit): Boolean { + return retrievedAccountTransactionsResponseListeners.add(listener) } protected open fun callRetrievedAccountTransactionsResponseListener(bankAccount: BankAccount, response: GetTransactionsResponse) { @@ -280,4 +329,21 @@ open class MainWindowPresenter( } } + + open fun addSelectedBankAccountsChangedListener(listener: (List) -> Unit): Boolean { + return selectedBankAccountsChangedListeners.add(listener) + } + + open fun removeSelectedBankAccountsChangedListener(listener: (List) -> Unit): Boolean { + return selectedBankAccountsChangedListeners.add(listener) + } + + protected open fun callSelectedBankAccountsChangedListeners(selectedBankAccounts: List) { + val selectedBankAccounts = this.selectedBankAccounts + + ArrayList(selectedBankAccountsChangedListeners).forEach { + it(selectedBankAccounts) // TODO: use RxJava for this + } + } + } \ No newline at end of file