Implemented remembering with which accounts wrong credentials have been entered and ignoring these in automatic updates

This commit is contained in:
dankito 2020-09-30 04:33:34 +02:00
parent 38bb0c90ff
commit 1c3f3505b0
8 changed files with 68 additions and 12 deletions

View File

@ -39,6 +39,8 @@ open class Bank(
override var technicalId: String = id.toString(), override var technicalId: String = id.toString(),
override var wrongCredentialsEntered: Boolean = false,
override var savePassword: Boolean = true, override var savePassword: Boolean = true,
override var userSetDisplayName: String? = null, override var userSetDisplayName: String? = null,

View File

@ -24,6 +24,7 @@ open class BankDataEntity(
override var selectedTanMethod: TanMethod? = null, override var selectedTanMethod: TanMethod? = null,
override var tanMedia: List<TanMedium> = listOf(), override var tanMedia: List<TanMedium> = listOf(),
override var technicalId: String = UUID.randomUUID().toString(), override var technicalId: String = UUID.randomUUID().toString(),
override var wrongCredentialsEntered: Boolean = false,
override var savePassword: Boolean = true, override var savePassword: Boolean = true,
override var userSetDisplayName: String? = null, override var userSetDisplayName: String? = null,
override var displayIndex: Int = 0 override var displayIndex: Int = 0

View File

@ -37,6 +37,8 @@ open class BankData(
override var tanMedia: List<TanMedium> = listOf() override var tanMedia: List<TanMedium> = listOf()
override var wrongCredentialsEntered: Boolean = false
override var savePassword: Boolean = true override var savePassword: Boolean = true

View File

@ -31,6 +31,8 @@ interface IBankData<TAccount: IBankAccount<TAccountTransaction>, TAccountTransac
var selectedTanMethod: TanMethod? var selectedTanMethod: TanMethod?
var tanMedia: List<TanMedium> var tanMedia: List<TanMedium>
var wrongCredentialsEntered: Boolean
var savePassword: Boolean var savePassword: Boolean
var userSetDisplayName: String? var userSetDisplayName: String?

View File

@ -349,13 +349,13 @@ open class BankingPresenter(
} }
open fun updateAllAccountsTransactionsAsync(callback: ((GetTransactionsResponse) -> Unit)? = null) { 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) updateAccountsTransactionsAsync(accountsToUpdate, true, callback)
} }
open fun updateSelectedAccountsTransactionsAsync(callback: ((GetTransactionsResponse) -> Unit)? = null) { 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 if (accountsToUpdate.isEmpty() && (selectedAccountType == SelectedAccountType.SingleAccount
|| (selectedAccountType == SelectedAccountType.SingleBank && selectedAccounts.size == 1))) { || (selectedAccountType == SelectedAccountType.SingleBank && selectedAccounts.size == 1))) {
accountsToUpdate = selectedAccounts accountsToUpdate = selectedAccounts
@ -364,6 +364,12 @@ open class BankingPresenter(
updateAccountsTransactionsAsync(accountsToUpdate, false, callback) 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<TypedBankAccount>, abortIfTanIsRequired: Boolean = false, callback: ((GetTransactionsResponse) -> Unit)? = null) { protected open fun updateAccountsTransactionsAsync(accounts: List<TypedBankAccount>, abortIfTanIsRequired: Boolean = false, callback: ((GetTransactionsResponse) -> Unit)? = null) {
accounts.forEach { account -> accounts.forEach { account ->
@ -394,6 +400,15 @@ open class BankingPresenter(
updateAccountTransactionsAndBalances(retrievedData) 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) callRetrievedAccountTransactionsResponseListener(response)
@ -489,13 +504,30 @@ open class BankingPresenter(
callBanksChangedListeners() 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) persistBankAsync(bank)
callBanksChangedListeners() callBanksChangedListeners()
if (didCredentialsChange || didSelectedTanMethodChange) {
getBankingClientForBank(bank)?.dataChanged(bank) getBankingClientForBank(bank)?.dataChanged(bank)
} }
}
open fun accountUpdated(account: TypedBankAccount) { open fun accountUpdated(account: TypedBankAccount) {
persistBankAsync(account.bank) persistBankAsync(account.bank)
@ -541,6 +573,10 @@ open class BankingPresenter(
client.transferMoneyAsync(data) { response -> client.transferMoneyAsync(data) { response ->
if (response.successful) { if (response.successful) {
updateAccountTransactionsAsync(account, true) updateAccountTransactionsAsync(account, true)
handleSuccessfulResponse(account.bank, response)
}
else {
handleUnsuccessfulResponse(account.bank, response)
} }
callback(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) { open fun findUniqueBankForIbanAsync(iban: String, callback: (BankInfo?) -> Unit) {
asyncRunner.runAsync { asyncRunner.runAsync {
callback(findUniqueBankForIban(iban)) callback(findUniqueBankForIban(iban))

View File

@ -84,6 +84,7 @@
<attribute name="userId" attributeType="String"/> <attribute name="userId" attributeType="String"/>
<attribute name="userName" attributeType="String"/> <attribute name="userName" attributeType="String"/>
<attribute name="userSetDisplayName" optional="YES" attributeType="String"/> <attribute name="userSetDisplayName" optional="YES" attributeType="String"/>
<attribute name="wrongCredentialsEntered" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<relationship name="accounts" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="PersistedBankAccount" inverseName="bank" inverseEntity="PersistedBankAccount"/> <relationship name="accounts" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="PersistedBankAccount" inverseName="bank" inverseEntity="PersistedBankAccount"/>
<relationship name="supportedTanMethods" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="PersistedTanMethod"/> <relationship name="supportedTanMethods" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="PersistedTanMethod"/>
<relationship name="tanMedia" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="PersistedTanMedium"/> <relationship name="tanMedia" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="PersistedTanMedium"/>
@ -109,7 +110,7 @@
<element name="PersistedAccountTransaction" positionX="-36" positionY="45" width="128" height="553"/> <element name="PersistedAccountTransaction" positionX="-36" positionY="45" width="128" height="553"/>
<element name="PersistedAppSettings" positionX="-45" positionY="144" width="128" height="118"/> <element name="PersistedAppSettings" positionX="-45" positionY="144" width="128" height="118"/>
<element name="PersistedBankAccount" positionX="-54" positionY="63" width="128" height="418"/> <element name="PersistedBankAccount" positionX="-54" positionY="63" width="128" height="418"/>
<element name="PersistedBankData" positionX="-63" positionY="-18" width="128" height="283"/> <element name="PersistedBankData" positionX="-63" positionY="-18" width="128" height="298"/>
<element name="PersistedTanMedium" positionX="-45" positionY="144" width="128" height="28"/> <element name="PersistedTanMedium" positionX="-45" positionY="144" width="128" height="28"/>
<element name="PersistedTanMethod" positionX="-54" positionY="135" width="128" height="118"/> <element name="PersistedTanMethod" positionX="-54" positionY="135" width="128" height="118"/>
<element name="PersistedTanMethodSettings" positionX="-54" positionY="135" width="128" height="103"/> <element name="PersistedTanMethodSettings" positionX="-54" positionY="135" width="128" height="103"/>

View File

@ -8,6 +8,7 @@ class Mapper {
func map(_ bank: PersistedBankData) -> IBankData { 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: []) 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.savePassword = bank.savePassword
mapped.userSetDisplayName = bank.userSetDisplayName mapped.userSetDisplayName = bank.userSetDisplayName
mapped.displayIndex = bank.displayIndex mapped.displayIndex = bank.displayIndex
@ -37,6 +38,7 @@ class Mapper {
mapped.userId = bank.userId mapped.userId = bank.userId
mapped.iconUrl = bank.iconUrl mapped.iconUrl = bank.iconUrl
mapped.wrongCredentialsEntered = bank.wrongCredentialsEntered
mapped.savePassword = bank.savePassword mapped.savePassword = bank.savePassword
mapped.userSetDisplayName = bank.userSetDisplayName mapped.userSetDisplayName = bank.userSetDisplayName
mapped.displayIndex = bank.displayIndex mapped.displayIndex = bank.displayIndex

View File

@ -130,12 +130,7 @@ struct BankSettingsDialog: View {
if hasUnsavedData { if hasUnsavedData {
bank.userSetDisplayName = displayName bank.userSetDisplayName = displayName
bank.userName = userName presenter.bankUpdated(bank: bank, enteredUsername: userName, enteredPassword: password, selectedTanMethod: selectedTanMethod)
bank.password = password
bank.selectedTanMethod = selectedTanMethod
presenter.bankUpdated(bank: bank)
} }
closeDialog() closeDialog()