Added account to GetTransactionsParameter

This commit is contained in:
dankito 2020-09-19 04:05:34 +02:00
parent d8739cf193
commit 129b4f64fa
13 changed files with 63 additions and 70 deletions

View File

@ -333,36 +333,35 @@ open class FinTsClient(
val now = Date() val now = Date()
val ninetyDaysAgo = Date(now.millisSinceEpoch - NinetyDaysMillis) val ninetyDaysAgo = Date(now.millisSinceEpoch - NinetyDaysMillis)
getTransactionsAsync(GetTransactionsParameter(account.supportsFeature(AccountFeature.RetrieveBalance), ninetyDaysAgo, abortIfTanIsRequired = true), bank, account) { response -> getTransactionsAsync(GetTransactionsParameter(account, account.supportsFeature(AccountFeature.RetrieveBalance), ninetyDaysAgo, abortIfTanIsRequired = true), bank) { response ->
callback(response) callback(response)
} }
} }
open fun getTransactionsAsync(parameter: GetTransactionsParameter, bank: BankData, open fun getTransactionsAsync(parameter: GetTransactionsParameter, bank: BankData, callback: (GetTransactionsResponse) -> Unit) {
account: AccountData, callback: (GetTransactionsResponse) -> Unit) {
val dialogContext = DialogContext(bank, product) val dialogContext = DialogContext(bank, product)
initDialog(dialogContext) { initDialogResponse -> initDialog(dialogContext) { initDialogResponse ->
if (initDialogResponse.successful == false) { if (initDialogResponse.successful == false) {
callback(GetTransactionsResponse(initDialogResponse, RetrievedAccountData.unsuccessfulList(account))) callback(GetTransactionsResponse(initDialogResponse, RetrievedAccountData.unsuccessfulList(parameter.account)))
} }
else { else {
mayGetBalance(parameter, account, dialogContext) { balanceResponse -> mayGetBalance(parameter, dialogContext) { balanceResponse ->
if (balanceResponse.successful == false && balanceResponse.couldCreateMessage == true) { // don't break here if required HKSAL message is not implemented if (balanceResponse.successful == false && balanceResponse.couldCreateMessage == true) { // don't break here if required HKSAL message is not implemented
closeDialog(dialogContext) closeDialog(dialogContext)
callback(GetTransactionsResponse(balanceResponse, RetrievedAccountData.unsuccessfulList(account))) callback(GetTransactionsResponse(balanceResponse, RetrievedAccountData.unsuccessfulList(parameter.account)))
} }
else { else {
getTransactionsAfterInitAndGetBalance(parameter, account, dialogContext, balanceResponse, callback) getTransactionsAfterInitAndGetBalance(parameter, dialogContext, balanceResponse, callback)
} }
} }
} }
} }
} }
protected open fun getTransactionsAfterInitAndGetBalance(parameter: GetTransactionsParameter, account: AccountData, dialogContext: DialogContext, protected open fun getTransactionsAfterInitAndGetBalance(parameter: GetTransactionsParameter, dialogContext: DialogContext,
balanceResponse: Response, callback: (GetTransactionsResponse) -> Unit) { balanceResponse: Response, callback: (GetTransactionsResponse) -> Unit) {
val balance: Money? = balanceResponse.getFirstSegmentById<BalanceSegment>(InstituteSegmentId.Balance)?.let { val balance: Money? = balanceResponse.getFirstSegmentById<BalanceSegment>(InstituteSegmentId.Balance)?.let {
Money(it.balance, it.currency) Money(it.balance, it.currency)
@ -370,7 +369,7 @@ open class FinTsClient(
val bookedTransactions = mutableSetOf<AccountTransaction>() val bookedTransactions = mutableSetOf<AccountTransaction>()
val unbookedTransactions = mutableSetOf<Any>() val unbookedTransactions = mutableSetOf<Any>()
val message = messageBuilder.createGetTransactionsMessage(parameter, account, dialogContext) val message = messageBuilder.createGetTransactionsMessage(parameter, dialogContext)
var remainingMt940String = "" var remainingMt940String = ""
@ -378,7 +377,7 @@ open class FinTsClient(
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, parameter.account)
bookedTransactions.addAll(chunkTransaction) bookedTransactions.addAll(chunkTransaction)
remainingMt940String = remainder remainingMt940String = remainder
@ -392,15 +391,15 @@ open class FinTsClient(
val successful = response.successful && (parameter.alsoRetrieveBalance == false || balance != null) val successful = response.successful && (parameter.alsoRetrieveBalance == false || balance != null)
callback(GetTransactionsResponse(response, listOf(RetrievedAccountData(account, successful, balance, bookedTransactions, unbookedTransactions)), callback(GetTransactionsResponse(response, listOf(RetrievedAccountData(parameter.account, successful, balance, bookedTransactions, unbookedTransactions)),
if (parameter.maxCountEntries != null) parameter.isSettingMaxCountEntriesAllowedByBank else null if (parameter.maxCountEntries != null) parameter.isSettingMaxCountEntriesAllowedByBank else null
)) ))
} }
} }
protected open fun mayGetBalance(parameter: GetTransactionsParameter, account: AccountData, dialogContext: DialogContext, callback: (Response) -> Unit) { protected open fun mayGetBalance(parameter: GetTransactionsParameter, dialogContext: DialogContext, callback: (Response) -> Unit) {
if (parameter.alsoRetrieveBalance && account.supportsFeature(AccountFeature.RetrieveBalance)) { if (parameter.alsoRetrieveBalance && parameter.account.supportsFeature(AccountFeature.RetrieveBalance)) {
val message = messageBuilder.createGetBalanceMessage(account, dialogContext) val message = messageBuilder.createGetBalanceMessage(parameter.account, dialogContext)
getAndHandleResponseForMessage(message, dialogContext) { response -> getAndHandleResponseForMessage(message, dialogContext) { response ->
callback(response) callback(response)

View File

@ -38,8 +38,8 @@ open class FinTsClientForCustomer(
} }
open fun getTransactionsAsync(parameter: GetTransactionsParameter, account: AccountData, callback: (GetTransactionsResponse) -> Unit) { open fun getTransactionsAsync(parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
client.getTransactionsAsync(parameter, bank, account, callback) client.getTransactionsAsync(parameter, bank, callback)
} }

View File

@ -146,28 +146,27 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
} }
open fun createGetTransactionsMessage(parameter: GetTransactionsParameter, account: AccountData, open fun createGetTransactionsMessage(parameter: GetTransactionsParameter, dialogContext: DialogContext): MessageBuilderResult {
dialogContext: DialogContext): MessageBuilderResult {
val result = supportsGetTransactionsMt940(account) val result = supportsGetTransactionsMt940(parameter.account)
if (result.isJobVersionSupported) { if (result.isJobVersionSupported) {
return createGetTransactionsMessageMt940(result, parameter, dialogContext, account) return createGetTransactionsMessageMt940(result, parameter, dialogContext)
} }
return result return result
} }
protected open fun createGetTransactionsMessageMt940(result: MessageBuilderResult, parameter: GetTransactionsParameter, protected open fun createGetTransactionsMessageMt940(result: MessageBuilderResult, parameter: GetTransactionsParameter,
dialogContext: DialogContext, account: AccountData): MessageBuilderResult { dialogContext: DialogContext): MessageBuilderResult {
if (parameter.maxCountEntries != null) { if (parameter.maxCountEntries != null) {
parameter.isSettingMaxCountEntriesAllowedByBank = determineIsSettingMaxCountEntriesAllowed(dialogContext.bank, InstituteSegmentId.AccountTransactionsMt940Parameters, listOf(5, 6, 7)) parameter.isSettingMaxCountEntriesAllowedByBank = determineIsSettingMaxCountEntriesAllowed(dialogContext.bank, InstituteSegmentId.AccountTransactionsMt940Parameters, listOf(5, 6, 7))
} }
val transactionsJob = if (result.isAllowed(7)) KontoumsaetzeZeitraumMt940Version7(generator.resetSegmentNumber(2), parameter, dialogContext.bank, account) val transactionsJob = if (result.isAllowed(7)) KontoumsaetzeZeitraumMt940Version7(generator.resetSegmentNumber(2), parameter, dialogContext.bank)
else if (result.isAllowed(6)) KontoumsaetzeZeitraumMt940Version6(generator.resetSegmentNumber(2), parameter, account) else if (result.isAllowed(6)) KontoumsaetzeZeitraumMt940Version6(generator.resetSegmentNumber(2), parameter)
else KontoumsaetzeZeitraumMt940Version5(generator.resetSegmentNumber(2), parameter, account) else KontoumsaetzeZeitraumMt940Version5(generator.resetSegmentNumber(2), parameter)
val segments = mutableListOf<Segment>(transactionsJob) val segments = mutableListOf<Segment>(transactionsJob)

View File

@ -17,7 +17,5 @@ import net.dankito.banking.fints.model.GetTransactionsParameter
*/ */
open class KontoumsaetzeZeitraumMt940Version5( open class KontoumsaetzeZeitraumMt940Version5(
segmentNumber: Int, segmentNumber: Int,
parameter: GetTransactionsParameter, parameter: GetTransactionsParameter
account: AccountData ) : KontoumsaetzeZeitraumMt940Base(5, segmentNumber, Kontoverbindung(parameter.account), parameter)
)
: KontoumsaetzeZeitraumMt940Base(5, segmentNumber, Kontoverbindung(account), parameter)

View File

@ -17,8 +17,6 @@ import net.dankito.banking.fints.model.GetTransactionsParameter
*/ */
open class KontoumsaetzeZeitraumMt940Version6( open class KontoumsaetzeZeitraumMt940Version6(
segmentNumber: Int, segmentNumber: Int,
parameter: GetTransactionsParameter, parameter: GetTransactionsParameter
account: AccountData
) ) : KontoumsaetzeZeitraumMt940Base(6, segmentNumber, Kontoverbindung(parameter.account), parameter)
: KontoumsaetzeZeitraumMt940Base(6, segmentNumber, Kontoverbindung(account), parameter)

View File

@ -19,7 +19,5 @@ import net.dankito.banking.fints.model.GetTransactionsParameter
open class KontoumsaetzeZeitraumMt940Version7( open class KontoumsaetzeZeitraumMt940Version7(
segmentNumber: Int, segmentNumber: Int,
parameter: GetTransactionsParameter, parameter: GetTransactionsParameter,
bank: BankData, bank: BankData
account: AccountData ) : KontoumsaetzeZeitraumMt940Base(7, segmentNumber, KontoverbindungInternational(parameter.account, bank), parameter)
)
: KontoumsaetzeZeitraumMt940Base(7, segmentNumber, KontoverbindungInternational(account, bank), parameter)

View File

@ -1,9 +1,11 @@
package net.dankito.banking.fints.model package net.dankito.banking.fints.model
import net.dankito.utils.multiplatform.Date import net.dankito.utils.multiplatform.Date
import kotlin.jvm.JvmOverloads
open class GetTransactionsParameter( open class GetTransactionsParameter @JvmOverloads constructor(
open val account: AccountData,
open val alsoRetrieveBalance: Boolean = true, open val alsoRetrieveBalance: Boolean = true,
open val fromDate: Date? = null, open val fromDate: Date? = null,
open val toDate: Date? = null, open val toDate: Date? = null,
@ -12,8 +14,6 @@ open class GetTransactionsParameter(
* Be aware this is by far not supported by all banks. * Be aware this is by far not supported by all banks.
* *
* And it depends on the actual job if setting maxCountEntries is supported or not. * And it depends on the actual job if setting maxCountEntries is supported or not.
*
* // TODO: set a parameter in response if maxCountEntries is set but bank doesn't support it.
*/ */
open val maxCountEntries: Int? = null, open val maxCountEntries: Int? = null,
open val abortIfTanIsRequired: Boolean = false, open val abortIfTanIsRequired: Boolean = false,

View File

@ -128,7 +128,7 @@ class MessageBuilderTest : FinTsTestBase() {
val dialogContext = DialogContext(Bank, Product) val dialogContext = DialogContext(Bank, Product)
// when // when
val result = underTest.createGetTransactionsMessage(GetTransactionsParameter(), Account, dialogContext) val result = underTest.createGetTransactionsMessage(GetTransactionsParameter(Account), dialogContext)
// then // then
expect(result.isJobAllowed).toBe(false) expect(result.isJobAllowed).toBe(false)
@ -146,7 +146,7 @@ class MessageBuilderTest : FinTsTestBase() {
val dialogContext = DialogContext(Bank, Product) val dialogContext = DialogContext(Bank, Product)
// when // when
val result = underTest.createGetTransactionsMessage(GetTransactionsParameter(), account, dialogContext) val result = underTest.createGetTransactionsMessage(GetTransactionsParameter(account), dialogContext)
// then // then
expect(result.isJobAllowed).toBe(true) expect(result.isJobAllowed).toBe(true)
@ -168,7 +168,7 @@ class MessageBuilderTest : FinTsTestBase() {
val maxCountEntries = 99 val maxCountEntries = 99
// when // when
val result = underTest.createGetTransactionsMessage(GetTransactionsParameter(false, fromDate, toDate, maxCountEntries), account, dialogContext) val result = underTest.createGetTransactionsMessage(GetTransactionsParameter(account, false, fromDate, toDate, maxCountEntries), dialogContext)
// then // then
expect(result.createdMessage).notToBeNull() expect(result.createdMessage).notToBeNull()
@ -200,7 +200,7 @@ class MessageBuilderTest : FinTsTestBase() {
val continuationId = "9345-10-26-11.52.15.693455" val continuationId = "9345-10-26-11.52.15.693455"
// when // when
val result = underTest.createGetTransactionsMessage(GetTransactionsParameter(false, fromDate, toDate, maxCountEntries, false), account, dialogContext) // TODO: test Aufsetzpunkt / continuationId val result = underTest.createGetTransactionsMessage(GetTransactionsParameter(account, false, fromDate, toDate, maxCountEntries, false), dialogContext) // TODO: test Aufsetzpunkt / continuationId
// then // then
expect(result.createdMessage).notToBeNull() expect(result.createdMessage).notToBeNull()

View File

@ -16,7 +16,6 @@ interface IBankingClient {
fun addAccountAsync(callback: (AddAccountResponse) -> Unit) fun addAccountAsync(callback: (AddAccountResponse) -> Unit)
fun getTransactionsAsync( fun getTransactionsAsync(
bankAccount: TypedBankAccount,
parameter: GetTransactionsParameter, parameter: GetTransactionsParameter,
callback: (GetTransactionsResponse) -> Unit callback: (GetTransactionsResponse) -> Unit
) )

View File

@ -2,16 +2,15 @@ package net.dankito.banking.ui.model.parameters
import net.dankito.utils.multiplatform.Date import net.dankito.utils.multiplatform.Date
import net.dankito.banking.ui.model.IAccountTransaction import net.dankito.banking.ui.model.IAccountTransaction
import net.dankito.banking.ui.model.TypedBankAccount
import kotlin.jvm.JvmOverloads
open class GetTransactionsParameter( open class GetTransactionsParameter @JvmOverloads constructor(
val alsoRetrieveBalance: Boolean = true, open val account: TypedBankAccount,
val fromDate: Date? = null, open val alsoRetrieveBalance: Boolean = true,
val toDate: Date? = null, open val fromDate: Date? = null,
val abortIfTanIsRequired: Boolean = false, open val toDate: Date? = null,
val retrievedChunkListener: ((List<IAccountTransaction>) -> Unit)? = null open val abortIfTanIsRequired: Boolean = false,
) { open val retrievedChunkListener: ((List<IAccountTransaction>) -> Unit)? = null
)
constructor() : this(true, null, null) // for Java
}

View File

@ -279,13 +279,13 @@ open class BankingPresenter(
fetchAccountTransactionsAsync(bankAccount, null, false, callback) fetchAccountTransactionsAsync(bankAccount, null, false, callback)
} }
open fun fetchAccountTransactionsAsync(bankAccount: TypedBankAccount, fromDate: Date?, abortIfTanIsRequired: Boolean = false, open fun fetchAccountTransactionsAsync(account: TypedBankAccount, fromDate: Date?, abortIfTanIsRequired: Boolean = false,
callback: ((GetTransactionsResponse) -> Unit)? = null) { callback: ((GetTransactionsResponse) -> Unit)? = null) {
getBankingClientForAccount(bankAccount.customer)?.let { client -> getBankingClientForAccount(account.customer)?.let { client ->
val startDate = Date() val startDate = Date()
client.getTransactionsAsync(bankAccount, GetTransactionsParameter(true, fromDate, null, abortIfTanIsRequired, { receivedAccountsTransactionChunk(bankAccount, it) } )) { response -> client.getTransactionsAsync(GetTransactionsParameter(account,true, fromDate, null, abortIfTanIsRequired, { receivedAccountsTransactionChunk(account, it) } )) { response ->
if (response.tanRequiredButWeWereToldToAbortIfSo == false) { // don't call retrievedAccountTransactions() if aborted due to TAN required but we told client to abort if so if (response.tanRequiredButWeWereToldToAbortIfSo == false) { // don't call retrievedAccountTransactions() if aborted due to TAN required but we told client to abort if so
retrievedAccountTransactions(response, startDate, fromDate == null) retrievedAccountTransactions(response, startDate, fromDate == null)

View File

@ -75,25 +75,27 @@ open class fints4kBankingClient(
} }
override fun getTransactionsAsync(bankAccount: TypedBankAccount, parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) { override fun getTransactionsAsync(parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
val bankAccount = parameter.account
findAccountForBankAccount(bankAccount) { account, errorMessage -> findAccountForBankAccount(bankAccount) { account, errorMessage ->
if (account == null) { if (account == null) {
callback(GetTransactionsResponse(bankAccount, errorMessage ?: "")) callback(GetTransactionsResponse(bankAccount, errorMessage ?: ""))
} }
else { else {
val mappedParameter = GetTransactionsParameter(parameter.alsoRetrieveBalance, parameter.fromDate, val mappedParameter = GetTransactionsParameter(account, parameter.alsoRetrieveBalance, parameter.fromDate,
parameter.toDate, null, parameter.abortIfTanIsRequired) { parameter.toDate, null, parameter.abortIfTanIsRequired) {
parameter.retrievedChunkListener?.invoke(mapper.mapTransactions(bankAccount, it)) parameter.retrievedChunkListener?.invoke(mapper.mapTransactions(bankAccount, it))
} }
doGetTransactionsAsync(mappedParameter, account, bankAccount, callback) doGetTransactionsAsync(mappedParameter, bankAccount, callback)
} }
} }
} }
protected open fun doGetTransactionsAsync(parameter: net.dankito.banking.fints.model.GetTransactionsParameter, protected open fun doGetTransactionsAsync(parameter: net.dankito.banking.fints.model.GetTransactionsParameter,
account: AccountData, bankAccount: TypedBankAccount, callback: (GetTransactionsResponse) -> Unit) { bankAccount: TypedBankAccount, callback: (GetTransactionsResponse) -> Unit) {
client.getTransactionsAsync(parameter, account) { response -> client.getTransactionsAsync(parameter) { response ->
handleGetTransactionsResponse(bankAccount, response, callback) handleGetTransactionsResponse(bankAccount, response, callback)
} }
} }

View File

@ -133,21 +133,22 @@ open class hbci4jBankingClient(
open fun getTransactionsOfLast90Days(bankAccount: TypedBankAccount): GetTransactionsResponse { open fun getTransactionsOfLast90Days(bankAccount: TypedBankAccount): GetTransactionsResponse {
val ninetyDaysAgo = Date(Date().time - NinetyDaysInMilliseconds) val ninetyDaysAgo = Date(Date().time - NinetyDaysInMilliseconds)
return getTransactions(bankAccount, GetTransactionsParameter(bankAccount.supportsRetrievingBalance, ninetyDaysAgo)) // TODO: implement abortIfTanIsRequired return getTransactions(GetTransactionsParameter(bankAccount, bankAccount.supportsRetrievingBalance, ninetyDaysAgo)) // TODO: implement abortIfTanIsRequired
} }
override fun getTransactionsAsync(bankAccount: TypedBankAccount, parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) { override fun getTransactionsAsync(parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
asyncRunner.runAsync { asyncRunner.runAsync {
callback(getTransactions(bankAccount, parameter)) callback(getTransactions(parameter))
} }
} }
protected open fun getTransactions(account: TypedBankAccount, parameter: GetTransactionsParameter): GetTransactionsResponse { protected open fun getTransactions(parameter: GetTransactionsParameter): GetTransactionsResponse {
val connection = connect() val connection = connect()
val account = parameter.account
connection.handle?.let { handle -> connection.handle?.let { handle ->
try { try {
val (nullableBalanceJob, accountTransactionsJob, status) = executeJobsForGetAccountingEntries(handle, account, parameter) val (nullableBalanceJob, accountTransactionsJob, status) = executeJobsForGetAccountingEntries(handle, parameter)
// Pruefen, ob die Kommunikation mit der Bank grundsaetzlich geklappt hat // Pruefen, ob die Kommunikation mit der Bank grundsaetzlich geklappt hat
if (!status.isOK) { if (!status.isOK) {
@ -195,8 +196,8 @@ open class hbci4jBankingClient(
return GetTransactionsResponse(account, connection.error?.getInnerExceptionMessage() ?: "Could not connect") return GetTransactionsResponse(account, connection.error?.getInnerExceptionMessage() ?: "Could not connect")
} }
protected open fun executeJobsForGetAccountingEntries(handle: HBCIHandler, bankAccount: TypedBankAccount, parameter: GetTransactionsParameter): Triple<HBCIJob?, HBCIJob, HBCIExecStatus> { protected open fun executeJobsForGetAccountingEntries(handle: HBCIHandler, parameter: GetTransactionsParameter): Triple<HBCIJob?, HBCIJob, HBCIExecStatus> {
val konto = mapper.mapToKonto(bankAccount) val konto = mapper.mapToKonto(parameter.account)
// 1. Auftrag fuer das Abrufen des Saldos erzeugen // 1. Auftrag fuer das Abrufen des Saldos erzeugen
var balanceJob: HBCIJob? = null var balanceJob: HBCIJob? = null