Implemented adding errors of ResponseParser, Mt940Parser and Mt940AccountTransactionsParser to MessageLog
This commit is contained in:
parent
55f5603cb9
commit
06ef511892
|
@ -3,6 +3,7 @@ package net.dankito.banking.fints
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.dankito.banking.fints.callback.FinTsClientCallback
|
import net.dankito.banking.fints.callback.FinTsClientCallback
|
||||||
|
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||||
import net.dankito.banking.fints.log.MessageLogCollector
|
import net.dankito.banking.fints.log.MessageLogCollector
|
||||||
import net.dankito.banking.fints.messages.MessageBuilder
|
import net.dankito.banking.fints.messages.MessageBuilder
|
||||||
import net.dankito.banking.fints.messages.MessageBuilderResult
|
import net.dankito.banking.fints.messages.MessageBuilderResult
|
||||||
|
@ -68,6 +69,12 @@ open class FinTsClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
responseParser.logAppender = messageLogAppender
|
||||||
|
mt940Parser.logAppender = messageLogAppender
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves information about bank (e.g. supported HBCI versions, FinTS server address,
|
* Retrieves information about bank (e.g. supported HBCI versions, FinTS server address,
|
||||||
* supported jobs, ...).
|
* supported jobs, ...).
|
||||||
|
@ -394,7 +401,8 @@ 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, parameter.account)
|
val (chunkTransaction, remainder) = mt940Parser.parseTransactionsChunk(remainingMt940String + transactionsSegment.bookedTransactionsString,
|
||||||
|
dialogContext.bank, parameter.account)
|
||||||
|
|
||||||
bookedTransactions.addAll(chunkTransaction)
|
bookedTransactions.addAll(chunkTransaction)
|
||||||
remainingMt940String = remainder
|
remainingMt940String = remainder
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package net.dankito.banking.fints.log
|
||||||
|
|
||||||
|
import net.dankito.banking.fints.model.BankData
|
||||||
|
import net.dankito.utils.multiplatform.log.Logger
|
||||||
|
|
||||||
|
|
||||||
|
interface IMessageLogAppender {
|
||||||
|
|
||||||
|
fun logError(message: String, e: Exception? = null, logger: Logger? = null, bank: BankData? = null)
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package net.dankito.banking.fints.response
|
package net.dankito.banking.fints.response
|
||||||
|
|
||||||
|
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||||
import net.dankito.banking.fints.messages.Separators
|
import net.dankito.banking.fints.messages.Separators
|
||||||
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Datum
|
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Datum
|
||||||
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Uhrzeit
|
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Uhrzeit
|
||||||
|
@ -25,7 +26,8 @@ import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||||
|
|
||||||
|
|
||||||
open class ResponseParser(
|
open class ResponseParser(
|
||||||
protected val messageUtils: MessageUtils = MessageUtils()
|
protected open val messageUtils: MessageUtils = MessageUtils(),
|
||||||
|
open var logAppender: IMessageLogAppender? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -52,7 +54,7 @@ open class ResponseParser(
|
||||||
|
|
||||||
return BankResponse(true, response, parsedSegments)
|
return BankResponse(true, response, parsedSegments)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error(e) { "Could not parse response '$response'" }
|
logError("Could not parse response '$response'", e)
|
||||||
|
|
||||||
return BankResponse(true, response, errorMessage = e.getInnerExceptionMessage())
|
return BankResponse(true, response, errorMessage = e.getInnerExceptionMessage())
|
||||||
}
|
}
|
||||||
|
@ -84,7 +86,7 @@ open class ResponseParser(
|
||||||
return parseSegment(segment, segmentId, dataElementGroups)
|
return parseSegment(segment, segmentId, dataElementGroups)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error(e) { "Could not parse segment '$segment'" } // TODO: what to do here, how to inform user?
|
logError("Could not parse segment '$segment'", e) // TODO: what to do here, how to inform user?
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
@ -463,7 +465,7 @@ open class ResponseParser(
|
||||||
return parseCodeEnum(smsAbbuchungskontoErforderlichString, SmsAbbuchungskontoErforderlich.values())
|
return parseCodeEnum(smsAbbuchungskontoErforderlichString, SmsAbbuchungskontoErforderlich.values())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (isEncodedBooleanValue(smsAbbuchungskontoErforderlichString) == false) {
|
if (isEncodedBooleanValue(smsAbbuchungskontoErforderlichString) == false) {
|
||||||
log.error(e) { "Could not parse '$smsAbbuchungskontoErforderlichString' to SmsAbbuchungskontoErforderlich" }
|
logError("Could not parse '$smsAbbuchungskontoErforderlichString' to SmsAbbuchungskontoErforderlich", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,7 +480,7 @@ open class ResponseParser(
|
||||||
return parseCodeEnum(auftraggeberkontoErforderlichString, AuftraggeberkontoErforderlich.values())
|
return parseCodeEnum(auftraggeberkontoErforderlichString, AuftraggeberkontoErforderlich.values())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (isEncodedBooleanValue(auftraggeberkontoErforderlichString) == false) {
|
if (isEncodedBooleanValue(auftraggeberkontoErforderlichString) == false) {
|
||||||
log.error(e) { "Could not parse '$auftraggeberkontoErforderlichString' to AuftraggeberkontoErforderlich" }
|
logError("Could not parse '$auftraggeberkontoErforderlichString' to AuftraggeberkontoErforderlich", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,7 +710,7 @@ open class ResponseParser(
|
||||||
|
|
||||||
return CreditCardTransaction(amount, transactionDescriptionBase, transactionDescriptionSupplement, bookingDate, valueDate, isCleared)
|
return CreditCardTransaction(amount, transactionDescriptionBase, transactionDescriptionSupplement, bookingDate, valueDate, isCleared)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error("Could not parse Credit card transaction '$transactionDataElementGroup'", e)
|
logError("Could not parse Credit card transaction '$transactionDataElementGroup'", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
@ -978,4 +980,14 @@ open class ResponseParser(
|
||||||
return binaryData
|
return binaryData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun logError(message: String, e: Exception?) {
|
||||||
|
logAppender?.let { logAppender ->
|
||||||
|
logAppender.logError(message, e, log)
|
||||||
|
}
|
||||||
|
?: run {
|
||||||
|
log.error(e) { message }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,13 +1,18 @@
|
||||||
package net.dankito.banking.fints.transactions
|
package net.dankito.banking.fints.transactions
|
||||||
|
|
||||||
|
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||||
import net.dankito.banking.fints.model.AccountData
|
import net.dankito.banking.fints.model.AccountData
|
||||||
import net.dankito.banking.fints.model.AccountTransaction
|
import net.dankito.banking.fints.model.AccountTransaction
|
||||||
|
import net.dankito.banking.fints.model.BankData
|
||||||
|
|
||||||
|
|
||||||
interface IAccountTransactionsParser {
|
interface IAccountTransactionsParser {
|
||||||
|
|
||||||
fun parseTransactions(transactionsString: String, account: AccountData): List<AccountTransaction>
|
var logAppender: IMessageLogAppender?
|
||||||
|
|
||||||
fun parseTransactionsChunk(transactionsChunk: String, account: AccountData): Pair<List<AccountTransaction>, String>
|
|
||||||
|
fun parseTransactions(transactionsString: String, bank: BankData, account: AccountData): List<AccountTransaction>
|
||||||
|
|
||||||
|
fun parseTransactionsChunk(transactionsChunk: String, bank: BankData, account: AccountData): Pair<List<AccountTransaction>, String>
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
package net.dankito.banking.fints.transactions
|
package net.dankito.banking.fints.transactions
|
||||||
|
|
||||||
import net.dankito.banking.fints.model.AccountData
|
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||||
import net.dankito.banking.fints.model.AccountTransaction
|
import net.dankito.banking.fints.model.*
|
||||||
import net.dankito.banking.fints.model.Amount
|
|
||||||
import net.dankito.banking.fints.model.Money
|
|
||||||
import net.dankito.banking.fints.transactions.mt940.IMt940Parser
|
import net.dankito.banking.fints.transactions.mt940.IMt940Parser
|
||||||
import net.dankito.banking.fints.transactions.mt940.Mt940Parser
|
import net.dankito.banking.fints.transactions.mt940.Mt940Parser
|
||||||
import net.dankito.banking.fints.transactions.mt940.model.AccountStatement
|
import net.dankito.banking.fints.transactions.mt940.model.AccountStatement
|
||||||
|
@ -11,10 +9,12 @@ import net.dankito.banking.fints.transactions.mt940.model.Balance
|
||||||
import net.dankito.banking.fints.transactions.mt940.model.Transaction
|
import net.dankito.banking.fints.transactions.mt940.model.Transaction
|
||||||
import net.dankito.banking.fints.transactions.mt940.model.StatementLine
|
import net.dankito.banking.fints.transactions.mt940.model.StatementLine
|
||||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||||
|
import net.dankito.utils.multiplatform.log.Logger
|
||||||
|
|
||||||
|
|
||||||
open class Mt940AccountTransactionsParser(
|
open class Mt940AccountTransactionsParser(
|
||||||
protected val mt940Parser: IMt940Parser = Mt940Parser()
|
protected val mt940Parser: IMt940Parser = Mt940Parser(),
|
||||||
|
override var logAppender: IMessageLogAppender? = null
|
||||||
) : IAccountTransactionsParser {
|
) : IAccountTransactionsParser {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -22,23 +22,25 @@ open class Mt940AccountTransactionsParser(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun parseTransactions(transactionsString: String, account: AccountData): List<AccountTransaction> {
|
override fun parseTransactions(transactionsString: String, bank: BankData, account: AccountData): List<AccountTransaction> {
|
||||||
|
setLogAppender(bank)
|
||||||
|
|
||||||
val accountStatements = mt940Parser.parseMt940String(transactionsString)
|
val accountStatements = mt940Parser.parseMt940String(transactionsString)
|
||||||
|
|
||||||
return accountStatements.flatMap { mapToAccountTransactions(it, account) }
|
return accountStatements.flatMap { mapToAccountTransactions(it, bank, account) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parseTransactionsChunk(transactionsChunk: String, account: AccountData): Pair<List<AccountTransaction>, String> {
|
override fun parseTransactionsChunk(transactionsChunk: String, bank: BankData, account: AccountData): Pair<List<AccountTransaction>, String> {
|
||||||
val (accountStatements, remainder) = mt940Parser.parseMt940Chunk(transactionsChunk)
|
val (accountStatements, remainder) = mt940Parser.parseMt940Chunk(transactionsChunk)
|
||||||
|
|
||||||
return Pair(accountStatements.flatMap { mapToAccountTransactions(it, account) }, remainder)
|
return Pair(accountStatements.flatMap { mapToAccountTransactions(it, bank, account) }, remainder)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun mapToAccountTransactions(statement: AccountStatement, account: AccountData): List<AccountTransaction> {
|
protected open fun mapToAccountTransactions(statement: AccountStatement, bank: BankData, account: AccountData): List<AccountTransaction> {
|
||||||
try {
|
try {
|
||||||
return statement.transactions.map { mapToAccountTransaction(statement, it, account) }
|
return statement.transactions.map { mapToAccountTransaction(statement, it, account) }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error(e) { "Could not map AccountStatement '$statement' to AccountTransactions" }
|
logError("Could not map AccountStatement '$statement' to AccountTransactions", e, bank)
|
||||||
}
|
}
|
||||||
|
|
||||||
return listOf()
|
return listOf()
|
||||||
|
@ -113,4 +115,27 @@ open class Mt940AccountTransactionsParser(
|
||||||
return positiveAmount
|
return positiveAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun setLogAppender(bankDataOfCall: BankData) {
|
||||||
|
// TODO: this does not perfectly work as in parallel calls to Mt940AccountTransactionsParser for different account logAppender gets overwritten by the later call
|
||||||
|
mt940Parser.logAppender = logAppender?.let { logAppender ->
|
||||||
|
object : IMessageLogAppender {
|
||||||
|
|
||||||
|
override fun logError(message: String, e: Exception?, logger: Logger?, bank: BankData?) {
|
||||||
|
logAppender.logError(message, e, logger, bank ?: bankDataOfCall)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun logError(message: String, e: Exception?, bank: BankData) {
|
||||||
|
logAppender?.let { logAppender ->
|
||||||
|
logAppender.logError(message, e, log, bank)
|
||||||
|
}
|
||||||
|
?: run {
|
||||||
|
log.error(e) { message }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,10 +1,14 @@
|
||||||
package net.dankito.banking.fints.transactions.mt940
|
package net.dankito.banking.fints.transactions.mt940
|
||||||
|
|
||||||
|
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||||
import net.dankito.banking.fints.transactions.mt940.model.AccountStatement
|
import net.dankito.banking.fints.transactions.mt940.model.AccountStatement
|
||||||
|
|
||||||
|
|
||||||
interface IMt940Parser {
|
interface IMt940Parser {
|
||||||
|
|
||||||
|
var logAppender: IMessageLogAppender?
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a whole MT 940 statements string, that is one that ends with a "-" line.
|
* Parses a whole MT 940 statements string, that is one that ends with a "-" line.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.dankito.banking.fints.transactions.mt940
|
package net.dankito.banking.fints.transactions.mt940
|
||||||
|
|
||||||
|
import net.dankito.banking.fints.log.IMessageLogAppender
|
||||||
import net.dankito.banking.fints.model.Amount
|
import net.dankito.banking.fints.model.Amount
|
||||||
import net.dankito.banking.fints.transactions.mt940.model.*
|
import net.dankito.banking.fints.transactions.mt940.model.*
|
||||||
import net.dankito.utils.multiplatform.Date
|
import net.dankito.utils.multiplatform.Date
|
||||||
|
@ -77,6 +78,9 @@ open class Mt940Parser : IMt940Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override var logAppender: IMessageLogAppender? = null
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a whole MT 940 statements string, that is one that ends with a "-" line.
|
* Parses a whole MT 940 statements string, that is one that ends with a "-" line.
|
||||||
*/
|
*/
|
||||||
|
@ -108,7 +112,7 @@ open class Mt940Parser : IMt940Parser {
|
||||||
|
|
||||||
return Pair(transactions, remainder)
|
return Pair(transactions, remainder)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error(e) { "Could not parse account statements from MT940 string:\n$mt940Chunk" }
|
logError("Could not parse account statements from MT940 string:\n$mt940Chunk", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Pair(listOf(), "")
|
return Pair(listOf(), "")
|
||||||
|
@ -131,7 +135,7 @@ open class Mt940Parser : IMt940Parser {
|
||||||
|
|
||||||
return parseAccountStatement(fieldsByCode)
|
return parseAccountStatement(fieldsByCode)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error(e) { "Could not parse account statement:\n$accountStatementString" }
|
logError("Could not parse account statement:\n$accountStatementString", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
@ -301,7 +305,7 @@ open class Mt940Parser : IMt940Parser {
|
||||||
|
|
||||||
return information
|
return information
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error(e) { "Could not parse InformationToAccountOwner from field value '$informationToAccountOwnerString'" }
|
logError("Could not parse InformationToAccountOwner from field value '$informationToAccountOwnerString'", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
@ -463,7 +467,7 @@ open class Mt940Parser : IMt940Parser {
|
||||||
|
|
||||||
return Date(year + 2000, month, day) // java.util.Date years start at 1900 at month at 0 not at 1
|
return Date(year + 2000, month, day) // java.util.Date years start at 1900 at month at 0 not at 1
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error(e) { "Could not parse dateString '$dateString'" }
|
logError("Could not parse dateString '$dateString'", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,4 +493,14 @@ open class Mt940Parser : IMt940Parser {
|
||||||
return Amount(amountString)
|
return Amount(amountString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun logError(message: String, e: Exception?) {
|
||||||
|
logAppender?.let { logAppender ->
|
||||||
|
logAppender.logError(message, e, log)
|
||||||
|
}
|
||||||
|
?: run {
|
||||||
|
log.error(e) { message }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ package net.dankito.banking.fints.transactions
|
||||||
|
|
||||||
import net.dankito.banking.fints.FinTsTestBaseJvm
|
import net.dankito.banking.fints.FinTsTestBaseJvm
|
||||||
import net.dankito.banking.fints.model.AccountData
|
import net.dankito.banking.fints.model.AccountData
|
||||||
|
import net.dankito.banking.fints.model.BankData
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ class Mt940AccountTransactionsParserTest : FinTsTestBaseJvm() {
|
||||||
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
val result = underTest.parseTransactions(transactionsString, AccountData())
|
val result = underTest.parseTransactions(transactionsString, BankData(), AccountData())
|
||||||
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
|
Loading…
Reference in New Issue