Implemented checking if allowed jobs are supported
This commit is contained in:
parent
7e729cb503
commit
7fcc8db798
|
@ -1,6 +1,7 @@
|
||||||
package net.dankito.fints
|
package net.dankito.fints
|
||||||
|
|
||||||
import net.dankito.fints.messages.MessageBuilder
|
import net.dankito.fints.messages.MessageBuilder
|
||||||
|
import net.dankito.fints.messages.MessageBuilderResult
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
|
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemID
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemID
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
|
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
|
||||||
|
@ -157,7 +158,7 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
if (parameter.alsoRetrieveBalance) {
|
if (parameter.alsoRetrieveBalance) {
|
||||||
val balanceResponse = getBalanceAfterDialogInit(bank, customer, dialogData)
|
val balanceResponse = getBalanceAfterDialogInit(bank, customer, dialogData)
|
||||||
|
|
||||||
if (balanceResponse.successful == false) {
|
if (balanceResponse.successful == false && balanceResponse.couldCreateMessage == true) { // don't break here if required HKSAL message is not implemented
|
||||||
return GetTransactionsResponse(balanceResponse)
|
return GetTransactionsResponse(balanceResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,9 +170,9 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
|
|
||||||
dialogData.increaseMessageNumber()
|
dialogData.increaseMessageNumber()
|
||||||
|
|
||||||
val requestBody = messageBuilder.createGetTransactionsMessage(parameter, bank, customer, product, dialogData)
|
val message = messageBuilder.createGetTransactionsMessage(parameter, bank, customer, product, dialogData)
|
||||||
|
|
||||||
val response = getAndHandleResponseForMessage(requestBody, bank)
|
val response = getAndHandleResponseForMessage(message, bank)
|
||||||
|
|
||||||
closeDialog(bank, customer, dialogData)
|
closeDialog(bank, customer, dialogData)
|
||||||
|
|
||||||
|
@ -302,6 +303,14 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun getAndHandleResponseForMessage(message: MessageBuilderResult, bank: BankData): Response {
|
||||||
|
message.createdMessage?.let { requestBody ->
|
||||||
|
return getAndHandleResponseForMessage(requestBody, bank)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response(false, messageCreationError = message)
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun getAndHandleResponseForMessage(requestBody: String, bank: BankData): Response {
|
protected open fun getAndHandleResponseForMessage(requestBody: String, bank: BankData): Response {
|
||||||
val webResponse = getResponseForMessage(requestBody, bank)
|
val webResponse = getResponseForMessage(requestBody, bank)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.dankito.fints.extensions
|
||||||
|
|
||||||
|
|
||||||
|
fun <T> Collection<T>.containsAny(otherCollection: Collection<T>): Boolean {
|
||||||
|
for (otherItem in otherCollection) {
|
||||||
|
if (this.contains(otherItem)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package net.dankito.fints.messages
|
package net.dankito.fints.messages
|
||||||
|
|
||||||
|
import net.dankito.fints.extensions.containsAny
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.Synchronisierungsmodus
|
import net.dankito.fints.messages.datenelemente.implementierte.Synchronisierungsmodus
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanProcess
|
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanProcess
|
||||||
import net.dankito.fints.messages.segmente.ISegmentNumberGenerator
|
import net.dankito.fints.messages.segmente.ISegmentNumberGenerator
|
||||||
|
@ -10,6 +11,8 @@ import net.dankito.fints.messages.segmente.id.CustomerSegmentId
|
||||||
import net.dankito.fints.messages.segmente.implementierte.*
|
import net.dankito.fints.messages.segmente.implementierte.*
|
||||||
import net.dankito.fints.messages.segmente.implementierte.sepa.SepaEinzelueberweisung
|
import net.dankito.fints.messages.segmente.implementierte.sepa.SepaEinzelueberweisung
|
||||||
import net.dankito.fints.messages.segmente.implementierte.umsaetze.KontoumsaetzeZeitraumMt940Version5
|
import net.dankito.fints.messages.segmente.implementierte.umsaetze.KontoumsaetzeZeitraumMt940Version5
|
||||||
|
import net.dankito.fints.messages.segmente.implementierte.umsaetze.KontoumsaetzeZeitraumMt940Version6
|
||||||
|
import net.dankito.fints.messages.segmente.implementierte.umsaetze.KontoumsaetzeZeitraumMt940Version7
|
||||||
import net.dankito.fints.messages.segmente.implementierte.umsaetze.Saldenabfrage
|
import net.dankito.fints.messages.segmente.implementierte.umsaetze.Saldenabfrage
|
||||||
import net.dankito.fints.model.*
|
import net.dankito.fints.model.*
|
||||||
import net.dankito.fints.util.FinTsUtils
|
import net.dankito.fints.util.FinTsUtils
|
||||||
|
@ -86,29 +89,53 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
|
||||||
|
|
||||||
|
|
||||||
open fun createGetTransactionsMessage(parameter: GetTransactionsParameter, bank: BankData, customer: CustomerData,
|
open fun createGetTransactionsMessage(parameter: GetTransactionsParameter, bank: BankData, customer: CustomerData,
|
||||||
product: ProductData, dialogData: DialogData): String {
|
product: ProductData, dialogData: DialogData): MessageBuilderResult {
|
||||||
|
|
||||||
return createSignedMessage(bank, customer, dialogData, listOf(
|
val result = getSupportedVersionOfJob(CustomerSegmentId.AccountTransactionsMt940, customer, listOf(5, 6, 7))
|
||||||
KontoumsaetzeZeitraumMt940Version5(generator.resetSegmentNumber(2), parameter, bank, customer),
|
|
||||||
ZweiSchrittTanEinreichung(generator.getNextSegmentNumber(), TanProcess.TanProcess4, CustomerSegmentId.AccountTransactionsMt940)
|
if (result.isJobVersionSupported) {
|
||||||
))
|
val transactionsJob = if (result.isAllowed(7)) KontoumsaetzeZeitraumMt940Version7(generator.resetSegmentNumber(2), parameter, bank, customer)
|
||||||
|
else if (result.isAllowed(6)) KontoumsaetzeZeitraumMt940Version6(generator.resetSegmentNumber(2), parameter, bank, customer)
|
||||||
|
else KontoumsaetzeZeitraumMt940Version5(generator.resetSegmentNumber(2), parameter, bank, customer)
|
||||||
|
|
||||||
|
|
||||||
|
return MessageBuilderResult(createSignedMessage(bank, customer, dialogData, listOf(
|
||||||
|
transactionsJob,
|
||||||
|
ZweiSchrittTanEinreichung(generator.getNextSegmentNumber(), TanProcess.TanProcess4, CustomerSegmentId.AccountTransactionsMt940)
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun createGetBalanceMessage(bank: BankData, customer: CustomerData, product: ProductData, dialogData: DialogData): String {
|
open fun createGetBalanceMessage(bank: BankData, customer: CustomerData, product: ProductData, dialogData: DialogData): MessageBuilderResult {
|
||||||
|
|
||||||
return createSignedMessage(bank, customer, dialogData, listOf(
|
val result = getSupportedVersionOfJob(CustomerSegmentId.Balance, customer, listOf(5))
|
||||||
Saldenabfrage(generator.resetSegmentNumber(2), bank, customer),
|
|
||||||
ZweiSchrittTanEinreichung(generator.getNextSegmentNumber(), TanProcess.TanProcess4, CustomerSegmentId.Balance)
|
if (result.isJobVersionSupported) {
|
||||||
))
|
return MessageBuilderResult(createSignedMessage(bank, customer, dialogData, listOf(
|
||||||
|
Saldenabfrage(generator.resetSegmentNumber(2), bank, customer),
|
||||||
|
ZweiSchrittTanEinreichung(generator.getNextSegmentNumber(), TanProcess.TanProcess4, CustomerSegmentId.Balance)
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun createBankTransferMessage(bankTransferData: BankTransferData, bank: BankData, customer: CustomerData, dialogData: DialogData): String {
|
open fun createBankTransferMessage(bankTransferData: BankTransferData, bank: BankData, customer: CustomerData, dialogData: DialogData): MessageBuilderResult {
|
||||||
|
|
||||||
return createSignedMessage(bank, customer, dialogData, listOf(
|
val result = getSupportedVersionOfJob(CustomerSegmentId.SepaBankTransfer, customer, listOf(1))
|
||||||
SepaEinzelueberweisung(generator.resetSegmentNumber(2), customer, bank.bic!!, bankTransferData),
|
|
||||||
ZweiSchrittTanEinreichung(generator.getNextSegmentNumber(), TanProcess.TanProcess4, CustomerSegmentId.SepaBankTransfer)
|
if (result.isJobVersionSupported) {
|
||||||
))
|
|
||||||
|
return MessageBuilderResult(createSignedMessage(bank, customer, dialogData, listOf(
|
||||||
|
SepaEinzelueberweisung(generator.resetSegmentNumber(2), customer, bank.bic!!, bankTransferData),
|
||||||
|
ZweiSchrittTanEinreichung(generator.getNextSegmentNumber(), TanProcess.TanProcess4, CustomerSegmentId.SepaBankTransfer)
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,4 +210,20 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
|
||||||
return payload.joinToString(Separators.SegmentSeparator) { it.format() }
|
return payload.joinToString(Separators.SegmentSeparator) { it.format() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun getSupportedVersionOfJob(segmentId: CustomerSegmentId, customer: CustomerData,
|
||||||
|
supportedVersions: List<Int>): MessageBuilderResult {
|
||||||
|
|
||||||
|
customer.accounts.firstOrNull()?.let { account -> // TODO: find a better solution / make more generic
|
||||||
|
val allowedVersions = account.allowedJobs.filter { it.jobName == segmentId.id }
|
||||||
|
.map { it.segmentVersion }
|
||||||
|
.sortedDescending()
|
||||||
|
|
||||||
|
return MessageBuilderResult(allowedVersions.isNotEmpty(), allowedVersions.containsAny(supportedVersions),
|
||||||
|
allowedVersions, supportedVersions, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
return MessageBuilderResult(false)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package net.dankito.fints.messages
|
||||||
|
|
||||||
|
|
||||||
|
open class MessageBuilderResult(
|
||||||
|
val isJobAllowed: Boolean,
|
||||||
|
val isJobVersionSupported: Boolean,
|
||||||
|
val allowedVersions: List<Int>,
|
||||||
|
val supportedVersions: List<Int>,
|
||||||
|
val createdMessage: String?
|
||||||
|
) {
|
||||||
|
|
||||||
|
constructor(isJobAllowed: Boolean) : this(isJobAllowed, false, listOf(), listOf(), null)
|
||||||
|
|
||||||
|
constructor(createdMessage: String) : this(true, true, listOf(), listOf(), createdMessage)
|
||||||
|
|
||||||
|
|
||||||
|
open fun isAllowed(version: Int): Boolean {
|
||||||
|
return allowedVersions.contains(version)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package net.dankito.fints.messages.segmente.implementierte.umsaetze
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.datenelementgruppen.implementierte.account.Kontoverbindung
|
||||||
|
import net.dankito.fints.model.BankData
|
||||||
|
import net.dankito.fints.model.CustomerData
|
||||||
|
import net.dankito.fints.model.GetTransactionsParameter
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Lösung bietet dem Kunden die Möglichkeit, auf seinem System verlorengegangene Buchungen erneut zu erhalten.
|
||||||
|
*
|
||||||
|
* Die maximale Anzahl der rückzumeldenden Buchungspositionen kann begrenzt werden. Eine Buchungsposition besteht
|
||||||
|
* aus einem :61:/:86:-Block eines MT 940-Formats. Es muss davon unabhängig immer ein gültiges MT 940-Format
|
||||||
|
* zurückgemeldet werden, d.h. die Felder :20: bis :60: und :62: bis :86: sind obligatorischer Bestandteil der Rückmeldung.
|
||||||
|
*
|
||||||
|
* Der maximale Zeitraum, für den rückwirkend Buchungen beim Kreditinstitut gespeichert sind, wird in den
|
||||||
|
* Bankparameterdaten übermittelt.
|
||||||
|
*/
|
||||||
|
open class KontoumsaetzeZeitraumMt940Version6(
|
||||||
|
segmentNumber: Int,
|
||||||
|
parameter: GetTransactionsParameter,
|
||||||
|
bank: BankData,
|
||||||
|
customer: CustomerData,
|
||||||
|
subAccountAttribute: String? = null
|
||||||
|
|
||||||
|
)
|
||||||
|
: KontoumsaetzeZeitraumMt940Base(
|
||||||
|
6,
|
||||||
|
segmentNumber,
|
||||||
|
Kontoverbindung(bank.countryCode, bank.bankCode, customer.customerId, subAccountAttribute),
|
||||||
|
parameter
|
||||||
|
)
|
|
@ -1,5 +1,6 @@
|
||||||
package net.dankito.fints.response
|
package net.dankito.fints.response
|
||||||
|
|
||||||
|
import net.dankito.fints.messages.MessageBuilderResult
|
||||||
import net.dankito.fints.messages.Separators
|
import net.dankito.fints.messages.Separators
|
||||||
import net.dankito.fints.messages.segmente.id.ISegmentId
|
import net.dankito.fints.messages.segmente.id.ISegmentId
|
||||||
import net.dankito.fints.messages.segmente.id.MessageSegmentId
|
import net.dankito.fints.messages.segmente.id.MessageSegmentId
|
||||||
|
@ -14,14 +15,18 @@ open class Response constructor(
|
||||||
/**
|
/**
|
||||||
* When a serious error occurred during web request or response parsing.
|
* When a serious error occurred during web request or response parsing.
|
||||||
*/
|
*/
|
||||||
val exception: Exception? = null
|
val exception: Exception? = null,
|
||||||
|
val messageCreationError: MessageBuilderResult? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
open val couldCreateMessage: Boolean
|
||||||
|
get() = messageCreationError == null
|
||||||
|
|
||||||
open val responseContainsErrors: Boolean
|
open val responseContainsErrors: Boolean
|
||||||
get() = exception == null && messageFeedback?.isError == true
|
get() = exception == null && messageFeedback?.isError == true
|
||||||
|
|
||||||
open val successful: Boolean
|
open val successful: Boolean
|
||||||
get() = didReceiveResponse && responseContainsErrors == false
|
get() = couldCreateMessage && didReceiveResponse && responseContainsErrors == false
|
||||||
|
|
||||||
open val isStrongAuthenticationRequired: Boolean
|
open val isStrongAuthenticationRequired: Boolean
|
||||||
get() = tanResponse?.isStrongAuthenticationRequired == true
|
get() = tanResponse?.isStrongAuthenticationRequired == true
|
||||||
|
|
|
@ -16,11 +16,20 @@ open class FinTsClientResponse(
|
||||||
/**
|
/**
|
||||||
* When a serious error occurred during web request or response parsing.
|
* When a serious error occurred during web request or response parsing.
|
||||||
*/
|
*/
|
||||||
val exception: Exception? = null
|
val exception: Exception? = null,
|
||||||
|
|
||||||
|
val isJobAllowed: Boolean = true,
|
||||||
|
val isJobVersionSupported: Boolean = true,
|
||||||
|
val allowedVersions: List<Int> = listOf(),
|
||||||
|
val supportedVersions: List<Int> = listOf()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
constructor(response: Response) : this(response.successful, response.isStrongAuthenticationRequired,
|
constructor(response: Response) : this(response.successful, response.isStrongAuthenticationRequired,
|
||||||
response.tanResponse, response.errorsToShowToUser, response.exception)
|
response.tanResponse, response.errorsToShowToUser, response.exception,
|
||||||
|
response.messageCreationError?.isJobAllowed ?: true,
|
||||||
|
response.messageCreationError?.isJobVersionSupported ?: true,
|
||||||
|
response.messageCreationError?.allowedVersions ?: listOf(),
|
||||||
|
response.messageCreationError?.supportedVersions ?: listOf())
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue