Implemented abortIfTanIsRequired so that at app start we can try to get all accounts' transaction without that user is being asked to enter a TAN if retrieving transaction without TAN isn't supported
This commit is contained in:
parent
126eaafced
commit
614074b9b9
|
@ -255,13 +255,14 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
val now = Date()
|
val now = Date()
|
||||||
val ninetyDaysAgo = Date(now.time - NinetyDaysAgoMilliseconds - now.timezoneOffset * 60 * 1000) // map to UTC
|
val ninetyDaysAgo = Date(now.time - NinetyDaysAgoMilliseconds - now.timezoneOffset * 60 * 1000) // map to UTC
|
||||||
|
|
||||||
val response = getTransactions(GetTransactionsParameter(account.supportsFeature(AccountFeature.RetrieveBalance), ninetyDaysAgo), bank, customer, account)
|
val response = getTransactions(GetTransactionsParameter(account.supportsFeature(AccountFeature.RetrieveBalance), ninetyDaysAgo, abortIfTanIsRequired = true), bank, customer, account)
|
||||||
|
|
||||||
|
|
||||||
account.triedToRetrieveTransactionsOfLast90DaysWithoutTan = true
|
account.triedToRetrieveTransactionsOfLast90DaysWithoutTan = true
|
||||||
|
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
if (response.isStrongAuthenticationRequired == false || hasRetrievedTransactionsWithTanJustBefore) {
|
if (response.isStrongAuthenticationRequired == false || hasRetrievedTransactionsWithTanJustBefore) {
|
||||||
|
// TODO: make use of supportsRetrievingTransactionsOfLast90DaysWithoutTan in UI e.g. in updateAccountsTransactionsIfNoTanIsRequiredAsync()
|
||||||
account.supportsRetrievingTransactionsOfLast90DaysWithoutTan = !!! response.isStrongAuthenticationRequired
|
account.supportsRetrievingTransactionsOfLast90DaysWithoutTan = !!! response.isStrongAuthenticationRequired
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,6 +311,8 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
val bookedTransactions = mutableListOf<AccountTransaction>()
|
val bookedTransactions = mutableListOf<AccountTransaction>()
|
||||||
var remainingMt940String = ""
|
var remainingMt940String = ""
|
||||||
|
|
||||||
|
dialogContext.abortIfTanIsRequired = parameter.abortIfTanIsRequired
|
||||||
|
|
||||||
dialogContext.chunkedResponseHandler = { response ->
|
dialogContext.chunkedResponseHandler = { response ->
|
||||||
response.getFirstSegmentById<ReceivedAccountTransactions>(InstituteSegmentId.AccountTransactionsMt940)?.let { transactionsSegment ->
|
response.getFirstSegmentById<ReceivedAccountTransactions>(InstituteSegmentId.AccountTransactionsMt940)?.let { transactionsSegment ->
|
||||||
val (chunkTransaction, remainder) = mt940Parser.parseTransactionsChunk(remainingMt940String + transactionsSegment.bookedTransactionsString, account)
|
val (chunkTransaction, remainder) = mt940Parser.parseTransactionsChunk(remainingMt940String + transactionsSegment.bookedTransactionsString, account)
|
||||||
|
@ -699,6 +702,12 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
protected open fun handleMayRequiresTan(response: Response, dialogContext: DialogContext): Response { // TODO: use response from DialogContext
|
protected open fun handleMayRequiresTan(response: Response, dialogContext: DialogContext): Response { // TODO: use response from DialogContext
|
||||||
|
|
||||||
if (response.isStrongAuthenticationRequired) {
|
if (response.isStrongAuthenticationRequired) {
|
||||||
|
if (dialogContext.abortIfTanIsRequired) {
|
||||||
|
response.tanRequiredButWeWereToldToAbortIfSo = true
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
response.tanResponse?.let { tanResponse ->
|
response.tanResponse?.let { tanResponse ->
|
||||||
val customer = dialogContext.customer
|
val customer = dialogContext.customer
|
||||||
val enteredTanResult = callback.enterTan(customer, createTanChallenge(tanResponse, customer))
|
val enteredTanResult = callback.enterTan(customer, createTanChallenge(tanResponse, customer))
|
||||||
|
|
|
@ -8,6 +8,7 @@ open class DialogContext(
|
||||||
bank: BankData,
|
bank: BankData,
|
||||||
customer: CustomerData,
|
customer: CustomerData,
|
||||||
product: ProductData,
|
product: ProductData,
|
||||||
|
var abortIfTanIsRequired: Boolean = false,
|
||||||
var currentMessage: MessageBuilderResult? = null,
|
var currentMessage: MessageBuilderResult? = null,
|
||||||
var dialogId: String = InitialDialogId,
|
var dialogId: String = InitialDialogId,
|
||||||
var response: Response? = null,
|
var response: Response? = null,
|
||||||
|
|
|
@ -8,5 +8,6 @@ open class GetTransactionsParameter @JvmOverloads constructor(
|
||||||
val fromDate: Date? = null,
|
val fromDate: Date? = null,
|
||||||
val toDate: Date? = null,
|
val toDate: Date? = null,
|
||||||
val maxCountEntries: Int? = null,
|
val maxCountEntries: Int? = null,
|
||||||
|
val abortIfTanIsRequired: Boolean = false,
|
||||||
val retrievedChunkListener: ((List<AccountTransaction>) -> Unit)? = null
|
val retrievedChunkListener: ((List<AccountTransaction>) -> Unit)? = null
|
||||||
)
|
)
|
|
@ -29,9 +29,12 @@ open class Response(
|
||||||
|
|
||||||
open var tanRequiredButUserDidNotEnterOne = false
|
open var tanRequiredButUserDidNotEnterOne = false
|
||||||
|
|
||||||
|
open var tanRequiredButWeWereToldToAbortIfSo = false
|
||||||
|
|
||||||
open val successful: Boolean
|
open val successful: Boolean
|
||||||
get() = noTanProcedureSelected == false && couldCreateMessage && didReceiveResponse
|
get() = noTanProcedureSelected == false && couldCreateMessage && didReceiveResponse
|
||||||
&& responseContainsErrors == false && tanRequiredButUserDidNotEnterOne == false
|
&& responseContainsErrors == false && tanRequiredButUserDidNotEnterOne == false
|
||||||
|
&& tanRequiredButWeWereToldToAbortIfSo == false
|
||||||
|
|
||||||
open val isStrongAuthenticationRequired: Boolean
|
open val isStrongAuthenticationRequired: Boolean
|
||||||
get() = tanResponse?.isStrongAuthenticationRequired == true
|
get() = tanResponse?.isStrongAuthenticationRequired == true
|
||||||
|
|
|
@ -8,6 +8,7 @@ open class GetTransactionsParameter(
|
||||||
val alsoRetrieveBalance: Boolean = true,
|
val alsoRetrieveBalance: Boolean = true,
|
||||||
val fromDate: Date? = null,
|
val fromDate: Date? = null,
|
||||||
val toDate: Date? = null,
|
val toDate: Date? = null,
|
||||||
|
val abortIfTanIsRequired: Boolean = false,
|
||||||
val retrievedChunkListener: ((List<AccountTransaction>) -> Unit)? = null
|
val retrievedChunkListener: ((List<AccountTransaction>) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import net.dankito.banking.ui.model.tan.TanGeneratorTanMedium
|
||||||
import net.dankito.banking.util.IBankIconFinder
|
import net.dankito.banking.util.IBankIconFinder
|
||||||
import net.dankito.banking.fints.banks.IBankFinder
|
import net.dankito.banking.fints.banks.IBankFinder
|
||||||
import net.dankito.banking.fints.model.BankInfo
|
import net.dankito.banking.fints.model.BankInfo
|
||||||
|
import net.dankito.banking.ui.model.parameters.GetTransactionsParameter
|
||||||
import net.dankito.banking.ui.model.settings.AppSettings
|
import net.dankito.banking.ui.model.settings.AppSettings
|
||||||
import net.dankito.utils.IThreadPool
|
import net.dankito.utils.IThreadPool
|
||||||
import net.dankito.utils.ThreadPool
|
import net.dankito.utils.ThreadPool
|
||||||
|
@ -99,6 +100,8 @@ open class BankingPresenter(
|
||||||
threadPool.runAsync {
|
threadPool.runAsync {
|
||||||
readAppSettings()
|
readAppSettings()
|
||||||
readPersistedAccounts()
|
readPersistedAccounts()
|
||||||
|
|
||||||
|
updateAccountsTransactionsIfNoTanIsRequiredAsync()
|
||||||
}
|
}
|
||||||
|
|
||||||
// preloadBankList asynchronously; on Android it takes approximately 18 seconds till banks are indexed for first time -> do it as early as possible
|
// preloadBankList asynchronously; on Android it takes approximately 18 seconds till banks are indexed for first time -> do it as early as possible
|
||||||
|
@ -264,16 +267,16 @@ open class BankingPresenter(
|
||||||
open fun fetchAccountTransactionsAsync(bankAccount: BankAccount,
|
open fun fetchAccountTransactionsAsync(bankAccount: BankAccount,
|
||||||
callback: (GetTransactionsResponse) -> Unit) {
|
callback: (GetTransactionsResponse) -> Unit) {
|
||||||
|
|
||||||
fetchAccountTransactionsAsync(bankAccount, null, callback)
|
fetchAccountTransactionsAsync(bankAccount, null, false, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun fetchAccountTransactionsAsync(bankAccount: BankAccount, fromDate: Date?,
|
open fun fetchAccountTransactionsAsync(bankAccount: BankAccount, fromDate: Date?, abortIfTanIsRequired: Boolean = false,
|
||||||
callback: (GetTransactionsResponse) -> Unit) {
|
callback: (GetTransactionsResponse) -> Unit) {
|
||||||
|
|
||||||
getClientForAccount(bankAccount.account)?.let { client ->
|
getClientForAccount(bankAccount.account)?.let { client ->
|
||||||
val startDate = Date()
|
val startDate = Date()
|
||||||
|
|
||||||
client.getTransactionsAsync(bankAccount, net.dankito.banking.ui.model.parameters.GetTransactionsParameter(true, fromDate, null, { receivedAccountsTransactionChunk(bankAccount, it) } )) { response ->
|
client.getTransactionsAsync(bankAccount, GetTransactionsParameter(true, fromDate, null, abortIfTanIsRequired, { receivedAccountsTransactionChunk(bankAccount, it) } )) { response ->
|
||||||
|
|
||||||
retrievedAccountTransactions(bankAccount, startDate, response)
|
retrievedAccountTransactions(bankAccount, startDate, response)
|
||||||
|
|
||||||
|
@ -283,12 +286,20 @@ open class BankingPresenter(
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun updateAccountsTransactionsAsync(callback: (GetTransactionsResponse) -> Unit) {
|
open fun updateAccountsTransactionsAsync(callback: (GetTransactionsResponse) -> Unit) {
|
||||||
|
updateAccountsTransactionsAsync(false, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun updateAccountsTransactionsIfNoTanIsRequiredAsync() {
|
||||||
|
updateAccountsTransactionsAsync(true) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun updateAccountsTransactionsAsync(abortIfTanIsRequired: Boolean = false, callback: (GetTransactionsResponse) -> Unit) {
|
||||||
clientsForAccounts.keys.forEach { account ->
|
clientsForAccounts.keys.forEach { account ->
|
||||||
account.bankAccounts.forEach { bankAccount ->
|
account.bankAccounts.forEach { bankAccount ->
|
||||||
if (bankAccount.supportsRetrievingAccountTransactions) {
|
if (bankAccount.supportsRetrievingAccountTransactions) {
|
||||||
val fromDate = bankAccount.lastRetrievedTransactionsTimestamp?.let { Date(it.time - OneDayMillis) } // one day before last received transactions
|
val fromDate = bankAccount.lastRetrievedTransactionsTimestamp?.let { Date(it.time - OneDayMillis) } // one day before last received transactions
|
||||||
|
|
||||||
fetchAccountTransactionsAsync(bankAccount, fromDate, callback)
|
fetchAccountTransactionsAsync(bankAccount, fromDate, abortIfTanIsRequired, callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ open class fints4kBankingClient(
|
||||||
callback(GetTransactionsResponse(false, "Cannot find account for ${bankAccount.identifier}")) // TODO: translate
|
callback(GetTransactionsResponse(false, "Cannot find account for ${bankAccount.identifier}")) // TODO: translate
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
client.getTransactionsAsync(net.dankito.banking.fints.model.GetTransactionsParameter(parameter.alsoRetrieveBalance, parameter.fromDate, parameter.toDate, null,
|
client.getTransactionsAsync(GetTransactionsParameter(parameter.alsoRetrieveBalance, parameter.fromDate, parameter.toDate, null, parameter.abortIfTanIsRequired,
|
||||||
{ parameter.retrievedChunkListener?.invoke(mapper.mapTransactions(bankAccount, it)) } ), account) { response ->
|
{ parameter.retrievedChunkListener?.invoke(mapper.mapTransactions(bankAccount, it)) } ), account) { response ->
|
||||||
|
|
||||||
val mappedResponse = mapper.mapResponse(bankAccount, response)
|
val mappedResponse = mapper.mapResponse(bankAccount, response)
|
||||||
|
|
|
@ -143,7 +143,7 @@ open class hbci4jBankingClient(
|
||||||
open fun getTransactionsOfLast90Days(bankAccount: BankAccount): GetTransactionsResponse {
|
open fun getTransactionsOfLast90Days(bankAccount: BankAccount): GetTransactionsResponse {
|
||||||
val ninetyDaysAgo = Date(Date().time - NinetyDaysInMilliseconds)
|
val ninetyDaysAgo = Date(Date().time - NinetyDaysInMilliseconds)
|
||||||
|
|
||||||
return getTransactions(bankAccount, GetTransactionsParameter(bankAccount.supportsRetrievingBalance, ninetyDaysAgo))
|
return getTransactions(bankAccount, GetTransactionsParameter(bankAccount.supportsRetrievingBalance, ninetyDaysAgo)) // TODO: implement abortIfTanIsRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTransactionsAsync(bankAccount: BankAccount, parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
|
override fun getTransactionsAsync(bankAccount: BankAccount, parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
|
||||||
|
|
Loading…
Reference in New Issue