From 6d41b89f1d78cc0ba47b5421bf41212a024bb6e1 Mon Sep 17 00:00:00 2001 From: dankito Date: Tue, 29 Sep 2020 23:56:33 +0200 Subject: [PATCH] Implemented parsing credit card transactions parameters --- .../banking/fints/messages/MessageBuilder.kt | 2 +- .../fints/response/InstituteSegmentId.kt | 4 +++- .../banking/fints/response/ResponseParser.kt | 18 ++++++++++++-- ... RetrieveAccountTransactionsParameters.kt} | 2 +- .../fints/response/ResponseParserTest.kt | 24 +++++++++++++++++-- .../persistence/JacksonClassNameIdResolver.kt | 8 +++---- 6 files changed, 47 insertions(+), 11 deletions(-) rename fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/{RetrieveAccountTransactionsInMt940Parameters.kt => RetrieveAccountTransactionsParameters.kt} (86%) diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/MessageBuilder.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/MessageBuilder.kt index 7c22b1d6..ef595d1b 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/MessageBuilder.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/MessageBuilder.kt @@ -182,7 +182,7 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg } protected open fun determineIsSettingMaxCountEntriesAllowed(bank: BankData, segmentId: ISegmentId, supportedJobVersions: List): Boolean { - return bank.supportedJobs.filterIsInstance() + return bank.supportedJobs.filterIsInstance() .filter { it.segmentId == segmentId.id && supportedJobVersions.contains(it.segmentVersion) } .firstOrNull { it.settingCountEntriesAllowed } != null } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/InstituteSegmentId.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/InstituteSegmentId.kt index db0a5f2b..2534779b 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/InstituteSegmentId.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/InstituteSegmentId.kt @@ -41,6 +41,8 @@ enum class InstituteSegmentId(override val id: String) : ISegmentId { AccountTransactionsMt940Parameters(AccountTransactionsMt940.id + "S"), - CreditCardTransactions("DIKKU") + CreditCardTransactions("DIKKU"), + + CreditCardTransactionsParameters(CreditCardTransactions.id + "S") } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/ResponseParser.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/ResponseParser.kt index 6d8ea3dc..8b5a04ad 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/ResponseParser.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/ResponseParser.kt @@ -119,6 +119,7 @@ open class ResponseParser( InstituteSegmentId.AccountTransactionsMt940Parameters.id -> parseMt940AccountTransactionsParameters(segment, segmentId, dataElementGroups) InstituteSegmentId.CreditCardTransactions.id -> parseCreditCardTransactions(segment, dataElementGroups) + InstituteSegmentId.CreditCardTransactionsParameters.id -> parseCreditCardTransactionsParameters(segment, segmentId, dataElementGroups) else -> { if (JobParametersSegmentRegex.matches(segmentId)) { @@ -668,7 +669,7 @@ open class ResponseParser( return ReceivedAccountTransactions(bookedTransactionsString, unbookedTransactionsString, segment) } - protected open fun parseMt940AccountTransactionsParameters(segment: String, segmentId: String, dataElementGroups: List): RetrieveAccountTransactionsInMt940Parameters { + protected open fun parseMt940AccountTransactionsParameters(segment: String, segmentId: String, dataElementGroups: List): RetrieveAccountTransactionsParameters { val jobParameters = parseJobParameters(segment, segmentId, dataElementGroups) val transactionsParameterIndex = if (jobParameters.segmentVersion >= 6) 4 else 3 @@ -678,7 +679,7 @@ open class ResponseParser( val settingCountEntriesAllowed = parseBoolean(dataElements[1]) val settingAllAccountAllowed = if (dataElements.size > 2) parseBoolean(dataElements[2]) else false - return RetrieveAccountTransactionsInMt940Parameters(jobParameters, countDaysForWhichTransactionsAreKept, settingCountEntriesAllowed, settingAllAccountAllowed) + return RetrieveAccountTransactionsParameters(jobParameters, countDaysForWhichTransactionsAreKept, settingCountEntriesAllowed, settingAllAccountAllowed) } @@ -718,6 +719,19 @@ open class ResponseParser( return Money(Amount(amountString), currency) } + protected open fun parseCreditCardTransactionsParameters(segment: String, segmentId: String, dataElementGroups: List): RetrieveAccountTransactionsParameters { + val jobParameters = parseJobParameters(segment, segmentId, dataElementGroups) + + val transactionsParameterIndex = if (jobParameters.segmentVersion >= 2) 4 else 3 // TODO: check if at segment version 1 the transactions parameter are the third data elements group + val dataElements = getDataElements(dataElementGroups[transactionsParameterIndex]) + + val countDaysForWhichTransactionsAreKept = parseInt(dataElements[0]) + val settingCountEntriesAllowed = parseBoolean(dataElements[1]) + val settingAllAccountAllowed = if (dataElements.size > 2) parseBoolean(dataElements[2]) else false + + return RetrieveAccountTransactionsParameters(jobParameters, countDaysForWhichTransactionsAreKept, settingCountEntriesAllowed, settingAllAccountAllowed) + } + protected open fun parseBankDetails(dataElementsGroup: String): Kreditinstitutskennung { val detailsStrings = getDataElements(dataElementsGroup) diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/RetrieveAccountTransactionsInMt940Parameters.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/RetrieveAccountTransactionsParameters.kt similarity index 86% rename from fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/RetrieveAccountTransactionsInMt940Parameters.kt rename to fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/RetrieveAccountTransactionsParameters.kt index 2af9bc70..efac30c3 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/RetrieveAccountTransactionsInMt940Parameters.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/RetrieveAccountTransactionsParameters.kt @@ -1,7 +1,7 @@ package net.dankito.banking.fints.response.segments -open class RetrieveAccountTransactionsInMt940Parameters( +open class RetrieveAccountTransactionsParameters( parameters: JobParameters, open val countDaysForWhichTransactionsAreKept: Int, open val settingCountEntriesAllowed: Boolean, diff --git a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/response/ResponseParserTest.kt b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/response/ResponseParserTest.kt index 08719ea7..4273db27 100644 --- a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/response/ResponseParserTest.kt +++ b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/response/ResponseParserTest.kt @@ -1055,7 +1055,7 @@ class ResponseParserTest : FinTsTestBase() { // then assertSuccessfullyParsedSegment(result, InstituteSegmentId.AccountTransactionsMt940Parameters, 21, 4, 4) - result.getFirstSegmentById(InstituteSegmentId.AccountTransactionsMt940Parameters)?.let { segment -> + result.getFirstSegmentById(InstituteSegmentId.AccountTransactionsMt940Parameters)?.let { segment -> expect(segment.countDaysForWhichTransactionsAreKept).toBe(countDaysForWhichTransactionsAreKept) expect(segment.settingCountEntriesAllowed).isFalse() expect(segment.settingAllAccountAllowed).isFalse() @@ -1075,7 +1075,7 @@ class ResponseParserTest : FinTsTestBase() { // then assertSuccessfullyParsedSegment(result, InstituteSegmentId.AccountTransactionsMt940Parameters, 23, 6, 4) - result.getFirstSegmentById(InstituteSegmentId.AccountTransactionsMt940Parameters)?.let { segment -> + result.getFirstSegmentById(InstituteSegmentId.AccountTransactionsMt940Parameters)?.let { segment -> expect(segment.countDaysForWhichTransactionsAreKept).toBe(countDaysForWhichTransactionsAreKept) expect(segment.settingCountEntriesAllowed).isFalse() expect(segment.settingAllAccountAllowed).isFalse() @@ -1119,6 +1119,26 @@ class ResponseParserTest : FinTsTestBase() { ?: run { fail("No segment of type ReceivedCreditCardTransactionsAndBalance found in ${result.receivedSegments}") } } + @Test + fun parseCreditCardAccountTransactionsParameters() { + + // given + val countDaysForWhichTransactionsAreKept = 9999 + + // when + val result = underTest.parse("DIKKUS:15:2:4+999+1+0+$countDaysForWhichTransactionsAreKept:J:J'") + + // then + assertSuccessfullyParsedSegment(result, InstituteSegmentId.CreditCardTransactionsParameters, 15, 2, 4) + + result.getFirstSegmentById(InstituteSegmentId.CreditCardTransactionsParameters)?.let { segment -> + expect(segment.countDaysForWhichTransactionsAreKept).toBe(countDaysForWhichTransactionsAreKept) + expect(segment.settingCountEntriesAllowed).isTrue() + expect(segment.settingAllAccountAllowed).isTrue() + } + ?: run { fail("No segment of type CreditCardTransactionsParameters found in ${result.receivedSegments}") } + } + private fun assertSuccessfullyParsedSegment(result: BankResponse, segmentId: ISegmentId, segmentNumber: Int, segmentVersion: Int, referenceSegmentNumber: Int? = null) { diff --git a/ui/BankingUiCommon/src/jvmMain/kotlin/net/dankito/banking/util/persistence/JacksonClassNameIdResolver.kt b/ui/BankingUiCommon/src/jvmMain/kotlin/net/dankito/banking/util/persistence/JacksonClassNameIdResolver.kt index 29402029..91e5fe29 100644 --- a/ui/BankingUiCommon/src/jvmMain/kotlin/net/dankito/banking/util/persistence/JacksonClassNameIdResolver.kt +++ b/ui/BankingUiCommon/src/jvmMain/kotlin/net/dankito/banking/util/persistence/JacksonClassNameIdResolver.kt @@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver import com.fasterxml.jackson.databind.type.SimpleType import com.fasterxml.jackson.databind.type.TypeFactory import net.dankito.banking.fints.response.segments.JobParameters -import net.dankito.banking.fints.response.segments.RetrieveAccountTransactionsInMt940Parameters +import net.dankito.banking.fints.response.segments.RetrieveAccountTransactionsParameters import net.dankito.banking.fints.response.segments.SepaAccountInfoParameters import kotlin.reflect.jvm.jvmName @@ -14,8 +14,8 @@ import kotlin.reflect.jvm.jvmName open class JacksonClassNameIdResolver : ClassNameIdResolver(SimpleType.construct(JobParameters::class.java), TypeFactory.defaultInstance()) { override fun idFromValue(value: Any?): String { - if (value is RetrieveAccountTransactionsInMt940Parameters) { - return RetrieveAccountTransactionsInMt940Parameters::class.jvmName + if (value is RetrieveAccountTransactionsParameters) { + return RetrieveAccountTransactionsParameters::class.jvmName } else if (value is SepaAccountInfoParameters) { return SepaAccountInfoParameters::class.jvmName @@ -26,7 +26,7 @@ open class JacksonClassNameIdResolver : ClassNameIdResolver(SimpleType.construct override fun typeFromId(context: DatabindContext, id: String): JavaType { return when (id) { - RetrieveAccountTransactionsInMt940Parameters::class.jvmName -> _typeFactory.constructSpecializedType(_baseType, RetrieveAccountTransactionsInMt940Parameters::class.java) + RetrieveAccountTransactionsParameters::class.jvmName -> _typeFactory.constructSpecializedType(_baseType, RetrieveAccountTransactionsParameters::class.java) SepaAccountInfoParameters::class.jvmName -> _typeFactory.constructSpecializedType(_baseType, SepaAccountInfoParameters::class.java) else -> _typeFactory.constructFromCanonical(id) // don't know why classes of Lists and Sets also get written as id to output, but for deserialization call to type factory is needed, super.typeFromId() does not work }