Implemented checking if bank supports setting count max entries. Had to adjust Jackson serialization so that and not just JobParameters gets saved and restored and to implement a lot of default constructors for this
This commit is contained in:
parent
4ed3d44b9e
commit
b403557f2d
|
@ -12,15 +12,15 @@ import net.dankito.banking.fints.messages.segmente.Segment
|
|||
import net.dankito.banking.fints.messages.segmente.SegmentNumberGenerator
|
||||
import net.dankito.banking.fints.messages.segmente.Synchronisierung
|
||||
import net.dankito.banking.fints.messages.segmente.id.CustomerSegmentId
|
||||
import net.dankito.banking.fints.messages.segmente.id.ISegmentId
|
||||
import net.dankito.banking.fints.messages.segmente.implementierte.*
|
||||
import net.dankito.banking.fints.messages.segmente.implementierte.sepa.SepaBankTransferBase
|
||||
import net.dankito.banking.fints.messages.segmente.implementierte.tan.TanGeneratorListeAnzeigen
|
||||
import net.dankito.banking.fints.messages.segmente.implementierte.tan.TanGeneratorTanMediumAnOderUmmelden
|
||||
import net.dankito.banking.fints.messages.segmente.implementierte.umsaetze.*
|
||||
import net.dankito.banking.fints.model.*
|
||||
import net.dankito.banking.fints.response.segments.JobParameters
|
||||
import net.dankito.banking.fints.response.segments.SepaAccountInfoParameters
|
||||
import net.dankito.banking.fints.response.segments.TanResponse
|
||||
import net.dankito.banking.fints.response.InstituteSegmentId
|
||||
import net.dankito.banking.fints.response.segments.*
|
||||
import net.dankito.banking.fints.util.FinTsUtils
|
||||
import net.dankito.utils.multiplatform.Date
|
||||
import kotlin.math.absoluteValue
|
||||
|
@ -152,20 +152,36 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
|
|||
val result = supportsGetTransactionsMt940(account)
|
||||
|
||||
if (result.isJobVersionSupported) {
|
||||
val transactionsJob = if (result.isAllowed(7)) KontoumsaetzeZeitraumMt940Version7(generator.resetSegmentNumber(2), parameter, dialogContext.bank, account)
|
||||
else if (result.isAllowed(6)) KontoumsaetzeZeitraumMt940Version6(generator.resetSegmentNumber(2), parameter, account)
|
||||
else KontoumsaetzeZeitraumMt940Version5(generator.resetSegmentNumber(2), parameter, account)
|
||||
|
||||
val segments = mutableListOf<Segment>(transactionsJob)
|
||||
|
||||
addTanSegmentIfRequired(CustomerSegmentId.AccountTransactionsMt940, dialogContext, segments)
|
||||
|
||||
return createSignedMessageBuilderResult(dialogContext, segments)
|
||||
return createGetTransactionsMessageMt940(result, parameter, dialogContext, account)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
protected open fun createGetTransactionsMessageMt940(result: MessageBuilderResult, parameter: GetTransactionsParameter,
|
||||
dialogContext: DialogContext, account: AccountData): MessageBuilderResult {
|
||||
|
||||
if (parameter.maxCountEntries != null) {
|
||||
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)
|
||||
else if (result.isAllowed(6)) KontoumsaetzeZeitraumMt940Version6(generator.resetSegmentNumber(2), parameter, account)
|
||||
else KontoumsaetzeZeitraumMt940Version5(generator.resetSegmentNumber(2), parameter, account)
|
||||
|
||||
val segments = mutableListOf<Segment>(transactionsJob)
|
||||
|
||||
addTanSegmentIfRequired(CustomerSegmentId.AccountTransactionsMt940, dialogContext, segments)
|
||||
|
||||
return createSignedMessageBuilderResult(dialogContext, segments)
|
||||
}
|
||||
|
||||
protected open fun determineIsSettingMaxCountEntriesAllowed(bank: BankData, segmentId: ISegmentId, supportedJobVersions: List<Int>): Boolean {
|
||||
return bank.supportedJobs.filterIsInstance<RetrieveAccountTransactionsInMt940Parameters>()
|
||||
.filter { it.segmentId == segmentId.id && supportedJobVersions.contains(it.segmentVersion) }
|
||||
.firstOrNull { it.settingCountEntriesAllowed } != null
|
||||
}
|
||||
|
||||
open fun supportsGetTransactions(account: AccountData): Boolean {
|
||||
return supportsGetTransactionsMt940(account).isJobVersionSupported
|
||||
}
|
||||
|
@ -255,9 +271,7 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
|
|||
|
||||
val segmentId = if (data.instantPayment) CustomerSegmentId.SepaInstantPaymentBankTransfer else CustomerSegmentId.SepaBankTransfer
|
||||
|
||||
val messageBuilderResultAndNullableUrn = supportsBankTransferAndSepaVersion(dialogContext.bank, account, segmentId)
|
||||
val result = messageBuilderResultAndNullableUrn.first
|
||||
val urn = messageBuilderResultAndNullableUrn.second
|
||||
val (result, urn) = supportsBankTransferAndSepaVersion(dialogContext.bank, account, segmentId)
|
||||
|
||||
if (result.isJobVersionSupported && urn != null) {
|
||||
val segments = mutableListOf<Segment>(SepaBankTransferBase(segmentId, generator.resetSegmentNumber(2),
|
||||
|
|
|
@ -34,6 +34,6 @@ abstract class KontoumsaetzeZeitraumMt940Base(
|
|||
AlleKonten(false, Existenzstatus.Mandatory), // currently no supported, we retrieve account transactions account by account (most banks don't support AlleKonten anyway)
|
||||
Datum(parameter.fromDate, Existenzstatus.Optional),
|
||||
Datum(parameter.toDate, Existenzstatus.Optional),
|
||||
MaximaleAnzahlEintraege(parameter.maxCountEntries, Existenzstatus.Optional), // > 0. O: „Eingabe Anzahl Einträge erlaubt“ (BPD) = „J“. N: sonst
|
||||
MaximaleAnzahlEintraege(parameter.maxCountEntriesIfSettingItIsAllowed, if (parameter.isSettingMaxCountEntriesAllowedByBank) Existenzstatus.Optional else Existenzstatus.NotAllowed), // > 0. O: „Eingabe Anzahl Einträge erlaubt“ (BPD) = „J“. N: sonst
|
||||
Aufsetzpunkt(null, Existenzstatus.Optional) // will be set dynamically, see MessageBuilder.rebuildMessageWithContinuationId(); M: vom Institut wurde ein Aufsetzpunkt rückgemeldet. N: sonst
|
||||
))
|
|
@ -7,7 +7,22 @@ open class GetTransactionsParameter(
|
|||
val alsoRetrieveBalance: Boolean = true,
|
||||
val fromDate: Date? = null,
|
||||
val toDate: Date? = null,
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* // TODO: set a parameter in response if maxCountEntries is set but bank doesn't support it.
|
||||
*/
|
||||
val maxCountEntries: Int? = null,
|
||||
val abortIfTanIsRequired: Boolean = false,
|
||||
val retrievedChunkListener: ((Collection<AccountTransaction>) -> Unit)? = null
|
||||
)
|
||||
) {
|
||||
|
||||
internal var isSettingMaxCountEntriesAllowedByBank = false
|
||||
|
||||
internal val maxCountEntriesIfSettingItIsAllowed: Int?
|
||||
get() = if (isSettingMaxCountEntriesAllowedByBank) maxCountEntries else null
|
||||
|
||||
}
|
|
@ -63,8 +63,10 @@ open class SepaAccountInfoParameters(
|
|||
* zugelassenen SEPA pain messages.
|
||||
*/
|
||||
val supportedSepaFormats: List<String>
|
||||
)
|
||||
: JobParameters(parameters) {
|
||||
) : JobParameters(parameters) {
|
||||
|
||||
internal constructor() : this(JobParameters(), false, false, false, false, -1, listOf()) // for object deserializers
|
||||
|
||||
|
||||
companion object {
|
||||
const val CountReservedUsageLengthNotSet = 0
|
||||
|
|
|
@ -4,5 +4,8 @@ package net.dankito.banking.fints.response.segments
|
|||
open class TanInfo(
|
||||
parameters: JobParameters,
|
||||
val tanProcedureParameters: TwoStepTanProcedureParameters
|
||||
)
|
||||
: JobParameters(parameters)
|
||||
) : JobParameters(parameters) {
|
||||
|
||||
internal constructor() : this(JobParameters(), TwoStepTanProcedureParameters()) // for object deserializers
|
||||
|
||||
}
|
|
@ -28,6 +28,12 @@ open class TanProcedureParameters(
|
|||
val countSupportedActiveTanMedia: Int?
|
||||
) {
|
||||
|
||||
|
||||
internal constructor() : this(Sicherheitsfunktion.Klartext, TanProcess.TanProcess1, "", null, null, "", -1,
|
||||
AllowedTanFormat.Alphanumeric, "", -1, false, TanZeitUndDialogbezug.NotSupported, false, SmsAbbuchungskontoErforderlich.SmsAbbuchungskontoDarfNichtAngegebenWerden, AuftraggeberkontoErforderlich.AuftraggeberkontoDarfNichtAngegebenWerden,
|
||||
false, false, Initialisierungsmodus.InitialisierungsverfahrenMitKlartextPinOhneTan, BezeichnungDesTanMediumsErforderlich.BezeichnungDesTanMediumsDarfNichtAngegebenWerden, false, null) // for object deserializers
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return "$procedureName $technicalTanProcedureIdentification"
|
||||
}
|
||||
|
|
|
@ -6,4 +6,8 @@ open class TwoStepTanProcedureParameters(
|
|||
val moreThanOneTanDependentJobPerMessageAllowed: Boolean,
|
||||
val jobHashValue: String, // not evaluated for PIN/TAN
|
||||
val procedureParameters: List<TanProcedureParameters>
|
||||
)
|
||||
) {
|
||||
|
||||
internal constructor() : this(false, false, "", listOf()) // for object deserializers
|
||||
|
||||
}
|
|
@ -1,11 +1,20 @@
|
|||
package net.dankito.banking.util
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import net.dankito.banking.util.persistence.JacksonClassNameIdResolver
|
||||
import net.dankito.utils.multiplatform.File
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
open class JacksonJsonSerializer(
|
||||
protected val serializer: net.dankito.utils.serialization.ISerializer = net.dankito.utils.serialization.JacksonJsonSerializer()
|
||||
protected val serializer: net.dankito.utils.serialization.ISerializer = net.dankito.utils.serialization.JacksonJsonSerializer { objectMapper ->
|
||||
val typeResolver = ObjectMapper.DefaultTypeResolverBuilder(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE)
|
||||
typeResolver.init(JsonTypeInfo.Id.CLASS, JacksonClassNameIdResolver())
|
||||
typeResolver.inclusion(JsonTypeInfo.As.PROPERTY)
|
||||
typeResolver.typeProperty("@CLASS")
|
||||
objectMapper.setDefaultTyping(typeResolver)
|
||||
}
|
||||
) : ISerializer {
|
||||
|
||||
override fun serializeObject(obj: Any, outputFile: File) {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package net.dankito.banking.util.persistence
|
||||
|
||||
import com.fasterxml.jackson.databind.DatabindContext
|
||||
import com.fasterxml.jackson.databind.JavaType
|
||||
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.SepaAccountInfoParameters
|
||||
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
|
||||
}
|
||||
else if (value is SepaAccountInfoParameters) {
|
||||
return SepaAccountInfoParameters::class.jvmName
|
||||
}
|
||||
|
||||
return super.idFromValue(value)
|
||||
}
|
||||
|
||||
override fun typeFromId(context: DatabindContext?, id: String?): JavaType {
|
||||
return when (id) {
|
||||
RetrieveAccountTransactionsInMt940Parameters::class.jvmName -> _typeFactory.constructSpecializedType(_baseType, RetrieveAccountTransactionsInMt940Parameters::class.java)
|
||||
SepaAccountInfoParameters::class.jvmName -> _typeFactory.constructSpecializedType(_baseType, SepaAccountInfoParameters::class.java)
|
||||
else -> super.typeFromId(context, id)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue