From 392c473056192df65b2a029baf01acfb5b4a43fe Mon Sep 17 00:00:00 2001 From: dankito Date: Wed, 12 Aug 2020 16:29:41 +0200 Subject: [PATCH] Implemented that if retrieving account transactions is not supported but retrieving balances, at least balances get retrieved --- .../net/dankito/banking/fints/FinTsClient.kt | 56 ++++++++++--------- .../banking/ui/presenter/BankingPresenter.kt | 15 ++++- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt index 31076b84..2ceca0c1 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt @@ -259,13 +259,12 @@ open class FinTsClient( } - /* Second dialog: Get customer system ID - done now in getBankAndCustomerInfoForNewUser(), we try to make it without having to open an extra dialog */ - - - /* Third dialog: Get customer TAN media list - last step that can and must be done without strong customer authorization */ + /* Second dialgo: some banks require that in order to initialize a dialog with strong customer authorization TAN media is required */ getTanMediaList(bank, customer, TanMedienArtVersion.Alle, TanMediumKlasse.AlleMedien) { + /* Third dialog: Now we can initialize our first dialog with strong customer authorization. Use it to get UPD and customer's accounts */ + getAccounts(bank, customer) { getAccountsResponse -> if (getAccountsResponse.isSuccessful == false) { @@ -273,34 +272,37 @@ open class FinTsClient( return@getAccounts } - /* Fourth dialog: Try to retrieve account transactions of last 90 days without TAN */ + /* Fourth dialog: Try to retrieve account balances and transactions of last 90 days without TAN */ - // also check if retrieving account transactions of last 90 days without tan is supported (and thereby may retrieve first account transactions) - val transactionsOfLast90DaysResponses = mutableListOf() - val balances = mutableMapOf() - val countAccountSupportingRetrievingTransactions = customer.accounts.filter { it.supportsFeature(AccountFeature.RetrieveAccountTransactions) }.size - var countRetrievedAccounts = 0 + addAccountGetAccountBalancesAndTransactions(customer, bank, newUserInfoResponse, didOverwriteUserUnselectedTanProcedure, + originalAreWeThatGentleToCloseDialogs, callback) + } + } + } + } - if (countAccountSupportingRetrievingTransactions == 0) { - addAccountAfterRetrievingTransactions(bank, customer, newUserInfoResponse, didOverwriteUserUnselectedTanProcedure, - originalAreWeThatGentleToCloseDialogs, transactionsOfLast90DaysResponses, balances, callback) - } + protected open fun addAccountGetAccountBalancesAndTransactions(customer: CustomerData, bank: BankData, newUserInfoResponse: AddAccountResponse, didOverwriteUserUnselectedTanProcedure: Boolean, originalAreWeThatGentleToCloseDialogs: Boolean, callback: (AddAccountResponse) -> Unit) { + val transactionsOfLast90DaysResponses = mutableListOf() + val balances = mutableMapOf() - customer.accounts.forEach { account -> - if (account.supportsFeature(AccountFeature.RetrieveAccountTransactions)) { - tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, account, false) { response -> - transactionsOfLast90DaysResponses.add(response) - response.balance?.let { balances.put(account, it) } + val accountSupportingRetrievingTransactions = customer.accounts.filter { it.supportsFeature(AccountFeature.RetrieveBalance) || it.supportsFeature(AccountFeature.RetrieveAccountTransactions) } + val countAccountSupportingRetrievingTransactions = accountSupportingRetrievingTransactions.size + var countRetrievedAccounts = 0 - countRetrievedAccounts++ - if (countRetrievedAccounts == countAccountSupportingRetrievingTransactions) { - addAccountAfterRetrievingTransactions(bank, customer, newUserInfoResponse, didOverwriteUserUnselectedTanProcedure, originalAreWeThatGentleToCloseDialogs, - transactionsOfLast90DaysResponses, balances, callback) - } - } - } - } + if (countAccountSupportingRetrievingTransactions == 0) { + addAccountAfterRetrievingTransactions(bank, customer, newUserInfoResponse, didOverwriteUserUnselectedTanProcedure, + originalAreWeThatGentleToCloseDialogs, transactionsOfLast90DaysResponses, balances, callback) + } + accountSupportingRetrievingTransactions.forEach { account -> + tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, account, false) { response -> + transactionsOfLast90DaysResponses.add(response) + response.balance?.let { balances.put(account, it) } + + countRetrievedAccounts++ + if (countRetrievedAccounts == countAccountSupportingRetrievingTransactions) { + addAccountAfterRetrievingTransactions(bank, customer, newUserInfoResponse, didOverwriteUserUnselectedTanProcedure, originalAreWeThatGentleToCloseDialogs, + transactionsOfLast90DaysResponses, balances, callback) } } } diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt index 9bbba0ee..8fb1fecf 100644 --- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt +++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt @@ -175,6 +175,11 @@ open class BankingPresenter( ) } } + else { // TODO: find a better way to update balances if transactions couldn't be retrieved + response.balances.keys.forEach { bankAccount -> + updateBalance(bankAccount, response.balances[bankAccount]!!) + } + } findIconForBankAsync(account) } @@ -358,13 +363,19 @@ open class BankingPresenter( bankAccount.addUnbookedTransactions(response.unbookedTransactions) response.balance?.let { - bankAccount.balance = it + updateBalance(bankAccount, it) } - persistAccount(bankAccount.customer) // only needed because of balance persistAccountTransactions(bankAccount, response.bookedTransactions, response.unbookedTransactions) } + protected open fun updateBalance(bankAccount: BankAccount, balance: BigDecimal) { + bankAccount.balance = balance + + persistAccount(bankAccount.customer) + } + + open fun formatAmount(amount: BigDecimal): String { return amount.format(2) }