From 1c3f3505b05b61e1479dabd70ac24f94913c4ca0 Mon Sep 17 00:00:00 2001 From: dankito Date: Wed, 30 Sep 2020 04:33:34 +0200 Subject: [PATCH] Implemented remembering with which accounts wrong credentials have been entered and ignoring these in automatic updates --- .../dankito/banking/persistence/model/Bank.kt | 2 + .../persistence/model/BankDataEntity.kt | 1 + .../net/dankito/banking/ui/model/BankData.kt | 2 + .../net/dankito/banking/ui/model/IBankData.kt | 2 + .../banking/ui/presenter/BankingPresenter.kt | 59 +++++++++++++++++-- .../BankingiOSApp.xcdatamodel/contents | 3 +- .../BankingiOSApp/persistence/Mapper.swift | 4 +- .../ui/dialogs/BankSettingsDialog.swift | 7 +-- 8 files changed, 68 insertions(+), 12 deletions(-) diff --git a/persistence/database/RoomBankingPersistence/src/main/java/net/dankito/banking/persistence/model/Bank.kt b/persistence/database/RoomBankingPersistence/src/main/java/net/dankito/banking/persistence/model/Bank.kt index 5d73ed43..246e3386 100644 --- a/persistence/database/RoomBankingPersistence/src/main/java/net/dankito/banking/persistence/model/Bank.kt +++ b/persistence/database/RoomBankingPersistence/src/main/java/net/dankito/banking/persistence/model/Bank.kt @@ -39,6 +39,8 @@ open class Bank( override var technicalId: String = id.toString(), + override var wrongCredentialsEntered: Boolean = false, + override var savePassword: Boolean = true, override var userSetDisplayName: String? = null, diff --git a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/BankDataEntity.kt b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/BankDataEntity.kt index 59306f17..b28a6938 100644 --- a/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/BankDataEntity.kt +++ b/persistence/json/BankingPersistenceJson/src/main/kotlin/net/dankito/banking/persistence/model/BankDataEntity.kt @@ -24,6 +24,7 @@ open class BankDataEntity( override var selectedTanMethod: TanMethod? = null, override var tanMedia: List = listOf(), override var technicalId: String = UUID.randomUUID().toString(), + override var wrongCredentialsEntered: Boolean = false, override var savePassword: Boolean = true, override var userSetDisplayName: String? = null, override var displayIndex: Int = 0 diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankData.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankData.kt index 4ee7cafe..43f75907 100644 --- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankData.kt +++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankData.kt @@ -37,6 +37,8 @@ open class BankData( override var tanMedia: List = listOf() + override var wrongCredentialsEntered: Boolean = false + override var savePassword: Boolean = true diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IBankData.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IBankData.kt index f40297cf..b842331b 100644 --- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IBankData.kt +++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/IBankData.kt @@ -31,6 +31,8 @@ interface IBankData, TAccountTransac var selectedTanMethod: TanMethod? var tanMedia: List + var wrongCredentialsEntered: Boolean + var savePassword: Boolean var userSetDisplayName: String? 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 9994d2e0..b2d3544a 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 @@ -349,13 +349,13 @@ open class BankingPresenter( } open fun updateAllAccountsTransactionsAsync(callback: ((GetTransactionsResponse) -> Unit)? = null) { - val accountsToUpdate = allAccounts.filter { it.hideAccount == false && it.updateAccountAutomatically } + val accountsToUpdate = allAccounts.filter { considerAccountInAutomaticUpdates(it) } updateAccountsTransactionsAsync(accountsToUpdate, true, callback) } open fun updateSelectedAccountsTransactionsAsync(callback: ((GetTransactionsResponse) -> Unit)? = null) { - var accountsToUpdate = selectedAccounts.filter { it.updateAccountAutomatically } + var accountsToUpdate = selectedAccounts.filter { considerAccountInAutomaticUpdates(it) } if (accountsToUpdate.isEmpty() && (selectedAccountType == SelectedAccountType.SingleAccount || (selectedAccountType == SelectedAccountType.SingleBank && selectedAccounts.size == 1))) { accountsToUpdate = selectedAccounts @@ -364,6 +364,12 @@ open class BankingPresenter( updateAccountsTransactionsAsync(accountsToUpdate, false, callback) } + protected open fun considerAccountInAutomaticUpdates(account: TypedBankAccount): Boolean { + return account.updateAccountAutomatically + && account.hideAccount == false + && account.bank.wrongCredentialsEntered == false + } + protected open fun updateAccountsTransactionsAsync(accounts: List, abortIfTanIsRequired: Boolean = false, callback: ((GetTransactionsResponse) -> Unit)? = null) { accounts.forEach { account -> @@ -394,6 +400,15 @@ open class BankingPresenter( updateAccountTransactionsAndBalances(retrievedData) } + + response.retrievedData.map { it.account.bank }.toSet().forEach { bank -> + handleSuccessfulResponse(bank, response) + } + } + else { + response.retrievedData.map { it.account.bank }.toSet().forEach { bank -> + handleUnsuccessfulResponse(bank, response) + } } callRetrievedAccountTransactionsResponseListener(response) @@ -489,12 +504,29 @@ open class BankingPresenter( callBanksChangedListeners() } - open fun bankUpdated(bank: TypedBankData) { + open fun bankUpdated(bank: TypedBankData, enteredUsername: String, enteredPassword: String, selectedTanMethod: TanMethod?) { + val didCredentialsChange = bank.userName != enteredUsername || bank.password != enteredPassword + val didSelectedTanMethodChange = bank.selectedTanMethod != selectedTanMethod + + if (didCredentialsChange) { + bank.userName = enteredUsername + bank.password = enteredPassword + + if (bank.wrongCredentialsEntered) { + bank.wrongCredentialsEntered = false // so that on next call its accounts are considered and so it gets checked if credentials are now correct + } + } + if (didSelectedTanMethodChange) { + bank.selectedTanMethod = selectedTanMethod + } + persistBankAsync(bank) callBanksChangedListeners() - getBankingClientForBank(bank)?.dataChanged(bank) + if (didCredentialsChange || didSelectedTanMethodChange) { + getBankingClientForBank(bank)?.dataChanged(bank) + } } open fun accountUpdated(account: TypedBankAccount) { @@ -541,6 +573,10 @@ open class BankingPresenter( client.transferMoneyAsync(data) { response -> if (response.successful) { updateAccountTransactionsAsync(account, true) + handleSuccessfulResponse(account.bank, response) + } + else { + handleUnsuccessfulResponse(account.bank, response) } callback(response) @@ -579,6 +615,21 @@ open class BankingPresenter( } + protected open fun handleSuccessfulResponse(bank: IBankData<*, *>, response: BankingClientResponse) { + if (response.wrongCredentialsEntered == false && bank.wrongCredentialsEntered) { + bank.wrongCredentialsEntered = false + persistBankAsync(bank) + } + } + + protected open fun handleUnsuccessfulResponse(bank: IBankData<*, *>, response: BankingClientResponse) { + if (response.wrongCredentialsEntered && bank.wrongCredentialsEntered == false) { + bank.wrongCredentialsEntered = true + persistBankAsync(bank) + } + } + + open fun findUniqueBankForIbanAsync(iban: String, callback: (BankInfo?) -> Unit) { asyncRunner.runAsync { callback(findUniqueBankForIban(iban)) diff --git a/ui/BankingiOSApp/BankingiOSApp/BankingiOSApp.xcdatamodeld/BankingiOSApp.xcdatamodel/contents b/ui/BankingiOSApp/BankingiOSApp/BankingiOSApp.xcdatamodeld/BankingiOSApp.xcdatamodel/contents index d9b987ce..8478b41f 100644 --- a/ui/BankingiOSApp/BankingiOSApp/BankingiOSApp.xcdatamodeld/BankingiOSApp.xcdatamodel/contents +++ b/ui/BankingiOSApp/BankingiOSApp/BankingiOSApp.xcdatamodeld/BankingiOSApp.xcdatamodel/contents @@ -84,6 +84,7 @@ + @@ -109,7 +110,7 @@ - + diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift index 256235a0..5b82b64e 100644 --- a/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift +++ b/ui/BankingiOSApp/BankingiOSApp/persistence/Mapper.swift @@ -8,6 +8,7 @@ class Mapper { func map(_ bank: PersistedBankData) -> IBankData { let mapped = BankData(bankCode: map(bank.bankCode), userName: map(bank.userName), password: map(bank.password), finTsServerAddress: map(bank.finTsServerAddress), bankName: map(bank.bankName), bic: map(bank.bic), customerName: map(bank.customerName), userId: map(bank.userId), iconUrl: bank.iconUrl, accounts: []) + mapped.wrongCredentialsEntered = bank.wrongCredentialsEntered mapped.savePassword = bank.savePassword mapped.userSetDisplayName = bank.userSetDisplayName mapped.displayIndex = bank.displayIndex @@ -20,7 +21,7 @@ class Mapper { mapped.tanMedia = map(bank.tanMedia?.array as? [PersistedTanMedium]) mapped.technicalId = bank.objectIDAsString - + return mapped } @@ -37,6 +38,7 @@ class Mapper { mapped.userId = bank.userId mapped.iconUrl = bank.iconUrl + mapped.wrongCredentialsEntered = bank.wrongCredentialsEntered mapped.savePassword = bank.savePassword mapped.userSetDisplayName = bank.userSetDisplayName mapped.displayIndex = bank.displayIndex diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankSettingsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankSettingsDialog.swift index 1fe6f3cb..91eb6c18 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankSettingsDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/dialogs/BankSettingsDialog.swift @@ -130,12 +130,7 @@ struct BankSettingsDialog: View { if hasUnsavedData { bank.userSetDisplayName = displayName - bank.userName = userName - bank.password = password - - bank.selectedTanMethod = selectedTanMethod - - presenter.bankUpdated(bank: bank) + presenter.bankUpdated(bank: bank, enteredUsername: userName, enteredPassword: password, selectedTanMethod: selectedTanMethod) } closeDialog()