Implemented parsing credit card transactions parameters

This commit is contained in:
dankito 2020-09-29 23:56:33 +02:00
parent b39c3f700a
commit 6d41b89f1d
6 changed files with 47 additions and 11 deletions

View File

@ -182,7 +182,7 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
} }
protected open fun determineIsSettingMaxCountEntriesAllowed(bank: BankData, segmentId: ISegmentId, supportedJobVersions: List<Int>): Boolean { protected open fun determineIsSettingMaxCountEntriesAllowed(bank: BankData, segmentId: ISegmentId, supportedJobVersions: List<Int>): Boolean {
return bank.supportedJobs.filterIsInstance<RetrieveAccountTransactionsInMt940Parameters>() return bank.supportedJobs.filterIsInstance<RetrieveAccountTransactionsParameters>()
.filter { it.segmentId == segmentId.id && supportedJobVersions.contains(it.segmentVersion) } .filter { it.segmentId == segmentId.id && supportedJobVersions.contains(it.segmentVersion) }
.firstOrNull { it.settingCountEntriesAllowed } != null .firstOrNull { it.settingCountEntriesAllowed } != null
} }

View File

@ -41,6 +41,8 @@ enum class InstituteSegmentId(override val id: String) : ISegmentId {
AccountTransactionsMt940Parameters(AccountTransactionsMt940.id + "S"), AccountTransactionsMt940Parameters(AccountTransactionsMt940.id + "S"),
CreditCardTransactions("DIKKU") CreditCardTransactions("DIKKU"),
CreditCardTransactionsParameters(CreditCardTransactions.id + "S")
} }

View File

@ -119,6 +119,7 @@ open class ResponseParser(
InstituteSegmentId.AccountTransactionsMt940Parameters.id -> parseMt940AccountTransactionsParameters(segment, segmentId, dataElementGroups) InstituteSegmentId.AccountTransactionsMt940Parameters.id -> parseMt940AccountTransactionsParameters(segment, segmentId, dataElementGroups)
InstituteSegmentId.CreditCardTransactions.id -> parseCreditCardTransactions(segment, dataElementGroups) InstituteSegmentId.CreditCardTransactions.id -> parseCreditCardTransactions(segment, dataElementGroups)
InstituteSegmentId.CreditCardTransactionsParameters.id -> parseCreditCardTransactionsParameters(segment, segmentId, dataElementGroups)
else -> { else -> {
if (JobParametersSegmentRegex.matches(segmentId)) { if (JobParametersSegmentRegex.matches(segmentId)) {
@ -668,7 +669,7 @@ open class ResponseParser(
return ReceivedAccountTransactions(bookedTransactionsString, unbookedTransactionsString, segment) return ReceivedAccountTransactions(bookedTransactionsString, unbookedTransactionsString, segment)
} }
protected open fun parseMt940AccountTransactionsParameters(segment: String, segmentId: String, dataElementGroups: List<String>): RetrieveAccountTransactionsInMt940Parameters { protected open fun parseMt940AccountTransactionsParameters(segment: String, segmentId: String, dataElementGroups: List<String>): RetrieveAccountTransactionsParameters {
val jobParameters = parseJobParameters(segment, segmentId, dataElementGroups) val jobParameters = parseJobParameters(segment, segmentId, dataElementGroups)
val transactionsParameterIndex = if (jobParameters.segmentVersion >= 6) 4 else 3 val transactionsParameterIndex = if (jobParameters.segmentVersion >= 6) 4 else 3
@ -678,7 +679,7 @@ open class ResponseParser(
val settingCountEntriesAllowed = parseBoolean(dataElements[1]) val settingCountEntriesAllowed = parseBoolean(dataElements[1])
val settingAllAccountAllowed = if (dataElements.size > 2) parseBoolean(dataElements[2]) else false 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) return Money(Amount(amountString), currency)
} }
protected open fun parseCreditCardTransactionsParameters(segment: String, segmentId: String, dataElementGroups: List<String>): 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 { protected open fun parseBankDetails(dataElementsGroup: String): Kreditinstitutskennung {
val detailsStrings = getDataElements(dataElementsGroup) val detailsStrings = getDataElements(dataElementsGroup)

View File

@ -1,7 +1,7 @@
package net.dankito.banking.fints.response.segments package net.dankito.banking.fints.response.segments
open class RetrieveAccountTransactionsInMt940Parameters( open class RetrieveAccountTransactionsParameters(
parameters: JobParameters, parameters: JobParameters,
open val countDaysForWhichTransactionsAreKept: Int, open val countDaysForWhichTransactionsAreKept: Int,
open val settingCountEntriesAllowed: Boolean, open val settingCountEntriesAllowed: Boolean,

View File

@ -1055,7 +1055,7 @@ class ResponseParserTest : FinTsTestBase() {
// then // then
assertSuccessfullyParsedSegment(result, InstituteSegmentId.AccountTransactionsMt940Parameters, 21, 4, 4) assertSuccessfullyParsedSegment(result, InstituteSegmentId.AccountTransactionsMt940Parameters, 21, 4, 4)
result.getFirstSegmentById<RetrieveAccountTransactionsInMt940Parameters>(InstituteSegmentId.AccountTransactionsMt940Parameters)?.let { segment -> result.getFirstSegmentById<RetrieveAccountTransactionsParameters>(InstituteSegmentId.AccountTransactionsMt940Parameters)?.let { segment ->
expect(segment.countDaysForWhichTransactionsAreKept).toBe(countDaysForWhichTransactionsAreKept) expect(segment.countDaysForWhichTransactionsAreKept).toBe(countDaysForWhichTransactionsAreKept)
expect(segment.settingCountEntriesAllowed).isFalse() expect(segment.settingCountEntriesAllowed).isFalse()
expect(segment.settingAllAccountAllowed).isFalse() expect(segment.settingAllAccountAllowed).isFalse()
@ -1075,7 +1075,7 @@ class ResponseParserTest : FinTsTestBase() {
// then // then
assertSuccessfullyParsedSegment(result, InstituteSegmentId.AccountTransactionsMt940Parameters, 23, 6, 4) assertSuccessfullyParsedSegment(result, InstituteSegmentId.AccountTransactionsMt940Parameters, 23, 6, 4)
result.getFirstSegmentById<RetrieveAccountTransactionsInMt940Parameters>(InstituteSegmentId.AccountTransactionsMt940Parameters)?.let { segment -> result.getFirstSegmentById<RetrieveAccountTransactionsParameters>(InstituteSegmentId.AccountTransactionsMt940Parameters)?.let { segment ->
expect(segment.countDaysForWhichTransactionsAreKept).toBe(countDaysForWhichTransactionsAreKept) expect(segment.countDaysForWhichTransactionsAreKept).toBe(countDaysForWhichTransactionsAreKept)
expect(segment.settingCountEntriesAllowed).isFalse() expect(segment.settingCountEntriesAllowed).isFalse()
expect(segment.settingAllAccountAllowed).isFalse() expect(segment.settingAllAccountAllowed).isFalse()
@ -1119,6 +1119,26 @@ class ResponseParserTest : FinTsTestBase() {
?: run { fail("No segment of type ReceivedCreditCardTransactionsAndBalance found in ${result.receivedSegments}") } ?: 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<RetrieveAccountTransactionsParameters>(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, private fun assertSuccessfullyParsedSegment(result: BankResponse, segmentId: ISegmentId, segmentNumber: Int,
segmentVersion: Int, referenceSegmentNumber: Int? = null) { segmentVersion: Int, referenceSegmentNumber: Int? = null) {

View File

@ -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.SimpleType
import com.fasterxml.jackson.databind.type.TypeFactory import com.fasterxml.jackson.databind.type.TypeFactory
import net.dankito.banking.fints.response.segments.JobParameters 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 net.dankito.banking.fints.response.segments.SepaAccountInfoParameters
import kotlin.reflect.jvm.jvmName 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()) { open class JacksonClassNameIdResolver : ClassNameIdResolver(SimpleType.construct(JobParameters::class.java), TypeFactory.defaultInstance()) {
override fun idFromValue(value: Any?): String { override fun idFromValue(value: Any?): String {
if (value is RetrieveAccountTransactionsInMt940Parameters) { if (value is RetrieveAccountTransactionsParameters) {
return RetrieveAccountTransactionsInMt940Parameters::class.jvmName return RetrieveAccountTransactionsParameters::class.jvmName
} }
else if (value is SepaAccountInfoParameters) { else if (value is SepaAccountInfoParameters) {
return SepaAccountInfoParameters::class.jvmName return SepaAccountInfoParameters::class.jvmName
@ -26,7 +26,7 @@ open class JacksonClassNameIdResolver : ClassNameIdResolver(SimpleType.construct
override fun typeFromId(context: DatabindContext, id: String): JavaType { override fun typeFromId(context: DatabindContext, id: String): JavaType {
return when (id) { 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) 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 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
} }