Implemented parsing received transactions string as a whole as sometimes banks breaks MT940 data sets in the middle when sending transactions in multiple messages so that this data set cannot be parsed if received messages get parsed immediately

This commit is contained in:
dankl 2019-12-31 17:27:17 +01:00 committed by dankito
parent 2951445390
commit 9798b39807
4 changed files with 30 additions and 21 deletions

View File

@ -18,6 +18,8 @@ import net.dankito.fints.response.client.FinTsClientResponse
import net.dankito.fints.response.client.GetTanMediaListResponse
import net.dankito.fints.response.client.GetTransactionsResponse
import net.dankito.fints.response.segments.*
import net.dankito.fints.transactions.IAccountTransactionsParser
import net.dankito.fints.transactions.Mt940AccountTransactionsParser
import net.dankito.fints.util.IBase64Service
import net.dankito.utils.IThreadPool
import net.dankito.utils.ThreadPool
@ -36,6 +38,7 @@ open class FinTsClient @JvmOverloads constructor(
protected val webClient: IWebClient = OkHttpWebClient(),
protected val messageBuilder: MessageBuilder = MessageBuilder(),
protected val responseParser: ResponseParser = ResponseParser(),
protected val mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(),
protected val threadPool: IThreadPool = ThreadPool(),
protected val product: ProductData = ProductData("15E53C26816138699C7B6A3E8", "0.1") // TODO: get version dynamically
) {
@ -261,7 +264,7 @@ open class FinTsClient @JvmOverloads constructor(
// TODO: that should not work. Find out in which method transactions are retrieved after entering TAN
// just retrieved all transactions -> check if retrieving that ones of last 90 days is possible without entering TAN
if (customer.supportsRetrievingTransactionsOfLast90DaysWithoutTan == null &&
response.successful && transactions.bookedTransactions.isNotEmpty() && parameter.fromDate == null) {
response.successful && transactions.bookedTransactionsString.isNotEmpty() && parameter.fromDate == null) {
tryGetTransactionsOfLast90DaysWithoutTan(bank, customer)
}
@ -277,22 +280,31 @@ open class FinTsClient @JvmOverloads constructor(
}
protected open fun getTransactionsFromResponse(response: Response, transactions: ReceivedAccountTransactions): Pair<List<AccountTransaction>, List<Any>> {
val bookedTransactions = mutableListOf<AccountTransaction>()
val unbookedTransactions = mutableListOf<Any>()
val bookedTransactionsString = StringBuilder()
val unbookedTransactionsString = StringBuilder()
bookedTransactions.addAll(transactions.bookedTransactions)
unbookedTransactions.addAll(transactions.unbookedTransactions)
getTransactionsFromResponse(response, transactions, bookedTransactionsString, unbookedTransactionsString)
val bookedTransactions = mt940Parser.parseTransactions(bookedTransactionsString.toString())
val unbookedTransactions = listOf<Any>() // TODO: implement parsing MT942
return Pair(bookedTransactions, unbookedTransactions)
}
protected open fun getTransactionsFromResponse(response: Response, transactions: ReceivedAccountTransactions,
bookedTransactionsString: StringBuilder, unbookedTransactionsString: StringBuilder) {
bookedTransactionsString.append(transactions.bookedTransactionsString)
transactions.unbookedTransactionsString?.let {
unbookedTransactionsString.append(transactions.unbookedTransactionsString)
}
response.followUpResponse?.let { followUpResponse ->
followUpResponse.getFirstSegmentById<ReceivedAccountTransactions>(InstituteSegmentId.AccountTransactionsMt940)?.let { followUpTransactions ->
val followUpBookedAndUnbookedTransactions = getTransactionsFromResponse(followUpResponse, followUpTransactions)
bookedTransactions.addAll(followUpBookedAndUnbookedTransactions.first)
unbookedTransactions.addAll(followUpBookedAndUnbookedTransactions.second)
getTransactionsFromResponse(followUpResponse, followUpTransactions, bookedTransactionsString, unbookedTransactionsString)
}
}
return Pair(bookedTransactions, unbookedTransactions)
}
protected open fun getBalanceAfterDialogInit(bank: BankData, customer: CustomerData,

View File

@ -7,6 +7,8 @@ import net.dankito.fints.response.ResponseParser
import net.dankito.fints.response.client.AddAccountResponse
import net.dankito.fints.response.client.FinTsClientResponse
import net.dankito.fints.response.client.GetTransactionsResponse
import net.dankito.fints.transactions.IAccountTransactionsParser
import net.dankito.fints.transactions.Mt940AccountTransactionsParser
import net.dankito.fints.util.IBase64Service
import net.dankito.utils.IThreadPool
import net.dankito.utils.ThreadPool
@ -22,11 +24,12 @@ open class FinTsClientForCustomer(
webClient: IWebClient = OkHttpWebClient(),
messageBuilder: MessageBuilder = MessageBuilder(),
responseParser: ResponseParser = ResponseParser(),
mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(),
threadPool: IThreadPool = ThreadPool(),
product: ProductData = ProductData("15E53C26816138699C7B6A3E8", "0.1") // TODO: get version dynamically
) {
protected val client = FinTsClient(callback, base64Service, webClient, messageBuilder, responseParser, threadPool, product)
protected val client = FinTsClient(callback, base64Service, webClient, messageBuilder, responseParser, mt940Parser, threadPool, product)
open fun addAccountAsync(callback: (AddAccountResponse) -> Unit) {

View File

@ -14,8 +14,6 @@ import net.dankito.fints.messages.datenelementgruppen.implementierte.Kreditinsti
import net.dankito.fints.messages.datenelementgruppen.implementierte.signatur.Sicherheitsprofil
import net.dankito.fints.messages.segmente.id.MessageSegmentId
import net.dankito.fints.response.segments.*
import net.dankito.fints.transactions.IAccountTransactionsParser
import net.dankito.fints.transactions.Mt940AccountTransactionsParser
import net.dankito.fints.util.MessageUtils
import org.slf4j.LoggerFactory
import java.math.BigDecimal
@ -24,7 +22,6 @@ import java.util.regex.Pattern
open class ResponseParser @JvmOverloads constructor(
protected val mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(),
protected val messageUtils: MessageUtils = MessageUtils()
) {
@ -504,10 +501,9 @@ open class ResponseParser @JvmOverloads constructor(
protected open fun parseMt940AccountTransactions(segment: String, dataElementGroups: List<String>): ReceivedAccountTransactions {
val bookedTransactionsString = extractBinaryData(dataElementGroups[1])
// TODO: implement parsing MT942
val unbookedTransactionsString = if (dataElementGroups.size > 2) extractBinaryData(dataElementGroups[2]) else null
return ReceivedAccountTransactions(mt940Parser.parseTransactions(bookedTransactionsString), listOf(), segment)
return ReceivedAccountTransactions(bookedTransactionsString, unbookedTransactionsString, segment)
}

View File

@ -1,11 +1,9 @@
package net.dankito.fints.response.segments
import net.dankito.fints.model.AccountTransaction
open class ReceivedAccountTransactions(
val bookedTransactions: List<AccountTransaction>,
val unbookedTransactions: List<Any>, // TODO
val bookedTransactionsString: String,
val unbookedTransactionsString: String?, // TODO
segmentString: String
)