Compare commits
No commits in common. "5e7d8804992f671c4d7232970874739bfe9fd96b" and "16a73aa055ec7d5d6bfdfac0752d4c030d724b1a" have entirely different histories.
5e7d880499
...
16a73aa055
|
@ -1,6 +1,6 @@
|
||||||
// TODO: move to versions.gradle
|
// TODO: move to versions.gradle
|
||||||
ext {
|
ext {
|
||||||
appVersionName = '1.0.0-Alpha-12-SNAPSHOT'
|
appVersionName = '1.0.0-Alpha-11-SNAPSHOT'
|
||||||
|
|
||||||
|
|
||||||
/* Test */
|
/* Test */
|
||||||
|
@ -16,7 +16,6 @@ ext {
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url = "https://maven.dankito.net/api/packages/codinux/maven" }
|
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +47,4 @@ task publishAllToMavenLocal {
|
||||||
dependsOn = [
|
dependsOn = [
|
||||||
"fints4k:publishToMavenLocal",
|
"fints4k:publishToMavenLocal",
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
|
||||||
task publishAll {
|
|
||||||
dependsOn = [
|
|
||||||
"fints4k:publish",
|
|
||||||
]
|
|
||||||
}
|
}
|
|
@ -64,13 +64,13 @@ kotlin {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.jetbrains.kotlinx:kotlinx-datetime:$kotlinxDateTimeVersion")
|
api("org.jetbrains.kotlinx:kotlinx-datetime:$kotlinxDateTimeVersion")
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
|
implementation("net.codinux.log:kmp-log:$klfVersion")
|
||||||
|
|
||||||
implementation("io.ktor:ktor-client-core:$ktorVersion")
|
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinxSerializationVersion")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinxSerializationVersion")
|
||||||
|
|
||||||
implementation("net.codinux.log:kmp-log:$klfVersion")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
|
||||||
|
|
||||||
|
implementation("io.ktor:ktor-client-core:$ktorVersion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,19 +135,4 @@ kotlin {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
name = "codinux"
|
|
||||||
url = uri("https://maven.dankito.net/api/packages/codinux/maven")
|
|
||||||
|
|
||||||
credentials(PasswordCredentials) {
|
|
||||||
username = project.property("codinuxRegistryWriterUsername")
|
|
||||||
password = project.property("codinuxRegistryWriterPassword")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -9,13 +9,11 @@ import net.dankito.banking.fints.model.MessageLogEntryType
|
||||||
import net.dankito.banking.fints.extensions.getInnerException
|
import net.dankito.banking.fints.extensions.getInnerException
|
||||||
import net.dankito.banking.fints.extensions.nthIndexOf
|
import net.dankito.banking.fints.extensions.nthIndexOf
|
||||||
import net.dankito.banking.fints.extensions.toStringWithMinDigits
|
import net.dankito.banking.fints.extensions.toStringWithMinDigits
|
||||||
import net.dankito.banking.fints.util.FinTsUtils
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
open class MessageLogCollector(
|
open class MessageLogCollector(
|
||||||
private val options: FinTsClientOptions = FinTsClientOptions(),
|
private val options: FinTsClientOptions = FinTsClientOptions()
|
||||||
private val finTsUtils: FinTsUtils = FinTsUtils()
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -24,7 +22,7 @@ open class MessageLogCollector(
|
||||||
|
|
||||||
const val MaxCountStackTraceElements = 15
|
const val MaxCountStackTraceElements = 15
|
||||||
|
|
||||||
internal const val NewLine = "\r\n"
|
private const val NewLine = "\r\n"
|
||||||
|
|
||||||
private val log by logger()
|
private val log by logger()
|
||||||
}
|
}
|
||||||
|
@ -41,7 +39,7 @@ open class MessageLogCollector(
|
||||||
val message = if (logEntry.type == MessageLogEntryType.Error) {
|
val message = if (logEntry.type == MessageLogEntryType.Error) {
|
||||||
logEntry.messageTrace + logEntry.message + (if (logEntry.error != null) NewLine + getStackTrace(logEntry.error!!) else "")
|
logEntry.messageTrace + logEntry.message + (if (logEntry.error != null) NewLine + getStackTrace(logEntry.error!!) else "")
|
||||||
} else {
|
} else {
|
||||||
logEntry.messageTrace + "\n" + prettyPrintFinTsMessage(logEntry.message)
|
logEntry.messageTrace + "\n" + prettyPrintHbciMessage(logEntry.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (options.removeSensitiveDataFromMessageLog) {
|
return if (options.removeSensitiveDataFromMessageLog) {
|
||||||
|
@ -57,7 +55,7 @@ open class MessageLogCollector(
|
||||||
|
|
||||||
addMessageLogEntry(type, context, messageTrace, message)
|
addMessageLogEntry(type, context, messageTrace, message)
|
||||||
|
|
||||||
log.debug { "$messageTrace\n${prettyPrintFinTsMessage(message)}" }
|
log.debug { "$messageTrace\n${prettyPrintHbciMessage(message)}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun logError(loggingClass: KClass<*>, message: String, context: MessageContext, e: Exception? = null) {
|
open fun logError(loggingClass: KClass<*>, message: String, context: MessageContext, e: Exception? = null) {
|
||||||
|
@ -94,8 +92,9 @@ open class MessageLogCollector(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun prettyPrintFinTsMessage(message: String): String =
|
protected open fun prettyPrintHbciMessage(message: String): String {
|
||||||
finTsUtils.prettyPrintFinTsMessage(message)
|
return message.replace("'", "'$NewLine")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected open fun safelyRemoveSensitiveDataFromMessage(message: String, bank: BankData?): String {
|
protected open fun safelyRemoveSensitiveDataFromMessage(message: String, bank: BankData?): String {
|
||||||
|
|
|
@ -230,10 +230,9 @@ open class MessageBuilder(protected val utils: FinTsUtils = FinTsUtils()) {
|
||||||
if (result.isJobVersionSupported) {
|
if (result.isJobVersionSupported) {
|
||||||
val segmentNumber = SignedMessagePayloadFirstSegmentNumber
|
val segmentNumber = SignedMessagePayloadFirstSegmentNumber
|
||||||
|
|
||||||
val balanceJob = if (result.isAllowed(6)) SaldenabfrageVersion6(segmentNumber, account)
|
val balanceJob = if (result.isAllowed(5)) SaldenabfrageVersion5(segmentNumber, account)
|
||||||
else if (result.isAllowed(7)) SaldenabfrageVersion7(segmentNumber, account, context.bank)
|
// TODO: what about HKSAL6?
|
||||||
else if (result.isAllowed(8)) SaldenabfrageVersion8(segmentNumber, account, context.bank)
|
else SaldenabfrageVersion7(segmentNumber, account, context.bank)
|
||||||
else SaldenabfrageVersion5(segmentNumber, account)
|
|
||||||
|
|
||||||
val segments = mutableListOf<Segment>(balanceJob)
|
val segments = mutableListOf<Segment>(balanceJob)
|
||||||
|
|
||||||
|
@ -250,7 +249,7 @@ open class MessageBuilder(protected val utils: FinTsUtils = FinTsUtils()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun supportsGetBalanceMessage(account: AccountData): MessageBuilderResult {
|
protected open fun supportsGetBalanceMessage(account: AccountData): MessageBuilderResult {
|
||||||
return getSupportedVersionsOfJobForAccount(CustomerSegmentId.Balance, account, listOf(5, 6, 7, 8))
|
return getSupportedVersionsOfJobForAccount(CustomerSegmentId.Balance, account, listOf(5, 7))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ import net.dankito.banking.fints.messages.segmente.id.ISegmentId
|
||||||
|
|
||||||
|
|
||||||
open class Segmentkopf(
|
open class Segmentkopf(
|
||||||
val identifier: String,
|
identifier: String,
|
||||||
val segmentVersion: Int,
|
segmentVersion: Int,
|
||||||
val segmentNumber: Int = 0,
|
segmentNumber: Int = 0,
|
||||||
bezugssegment: Int? = null
|
bezugssegment: Int? = null
|
||||||
|
|
||||||
) : Datenelementgruppe(listOf(
|
) : Datenelementgruppe(listOf(
|
||||||
|
@ -22,6 +22,4 @@ open class Segmentkopf(
|
||||||
|
|
||||||
constructor(id: ISegmentId, segmentVersion: Int, segmentNumber: Int) : this(id.id, segmentVersion, segmentNumber)
|
constructor(id: ISegmentId, segmentVersion: Int, segmentNumber: Int) : this(id.id, segmentVersion, segmentNumber)
|
||||||
|
|
||||||
override fun toString() = "$identifier:$segmentNumber:$segmentVersion"
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@ import net.dankito.banking.fints.messages.Nachrichtenteil
|
||||||
import net.dankito.banking.fints.messages.Separators
|
import net.dankito.banking.fints.messages.Separators
|
||||||
import net.dankito.banking.fints.messages.datenelemente.DatenelementBase
|
import net.dankito.banking.fints.messages.datenelemente.DatenelementBase
|
||||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.DoNotPrintDatenelement
|
import net.dankito.banking.fints.messages.datenelemente.implementierte.DoNotPrintDatenelement
|
||||||
import net.dankito.banking.fints.messages.datenelementgruppen.implementierte.Segmentkopf
|
|
||||||
|
|
||||||
|
|
||||||
abstract class Segment(val dataElementsAndGroups: List<DatenelementBase>) : Nachrichtenteil() {
|
abstract class Segment(val dataElementsAndGroups: List<DatenelementBase>) : Nachrichtenteil() {
|
||||||
|
@ -29,6 +28,4 @@ abstract class Segment(val dataElementsAndGroups: List<DatenelementBase>) : Nach
|
||||||
return ReplaceEmptyDataElementGroupSeparatorsAtEndPattern.replaceFirst(formattedSegment, "")
|
return ReplaceEmptyDataElementGroupSeparatorsAtEndPattern.replaceFirst(formattedSegment, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() = "${dataElementsAndGroups.firstOrNull { it is Segmentkopf }}"
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
package net.dankito.banking.fints.messages.segmente.implementierte.umsaetze
|
|
||||||
|
|
||||||
import net.dankito.banking.fints.messages.datenelementgruppen.implementierte.account.Kontoverbindung
|
|
||||||
import net.dankito.banking.fints.model.AccountData
|
|
||||||
|
|
||||||
|
|
||||||
open class SaldenabfrageVersion6(
|
|
||||||
segmentNumber: Int,
|
|
||||||
account: AccountData,
|
|
||||||
allAccounts: Boolean = false,
|
|
||||||
maxAmountEntries: Int? = null,
|
|
||||||
continuationId: String? = null
|
|
||||||
)
|
|
||||||
: SaldenabfrageBase(segmentNumber, 6, Kontoverbindung(account), allAccounts, maxAmountEntries, continuationId)
|
|
|
@ -1,16 +0,0 @@
|
||||||
package net.dankito.banking.fints.messages.segmente.implementierte.umsaetze
|
|
||||||
|
|
||||||
import net.dankito.banking.fints.messages.datenelementgruppen.implementierte.account.KontoverbindungInternational
|
|
||||||
import net.dankito.banking.fints.model.AccountData
|
|
||||||
import net.dankito.banking.fints.model.BankData
|
|
||||||
|
|
||||||
|
|
||||||
open class SaldenabfrageVersion8(
|
|
||||||
segmentNumber: Int,
|
|
||||||
account: AccountData,
|
|
||||||
bank: BankData,
|
|
||||||
allAccounts: Boolean = false,
|
|
||||||
maxAmountEntries: Int? = null,
|
|
||||||
continuationId: String? = null
|
|
||||||
)
|
|
||||||
: SaldenabfrageBase(segmentNumber, 8, KontoverbindungInternational(account, bank), allAccounts, maxAmountEntries, continuationId)
|
|
|
@ -248,9 +248,6 @@ open class ResponseParser(
|
||||||
// yes, by standard the Kontoinformation can be missing:
|
// yes, by standard the Kontoinformation can be missing:
|
||||||
// N: bei Geschäftsvorfällen ohne Kontenbezug
|
// N: bei Geschäftsvorfällen ohne Kontenbezug
|
||||||
// M: sonst
|
// M: sonst
|
||||||
// ("Darüber hinaus kann auch ein Eintrag für nicht kontogebundene Geschäftsvorfälle (z. B. Informationsbestellung) eingestellt werden.
|
|
||||||
// Hierbei handelt es sich im Regelfall um Geschäftsvorfälle, die auch über den anonymen Zugang genutzt werden können. In diesem Fall
|
|
||||||
// sind die Felder für die Kontoverbindung und die übrigen kontobezogenen Angaben nicht zu belegen.")
|
|
||||||
// But in my eyes Deutsche Bank uses it wrong and adds a second HIUPD for the same account but with most information missing:
|
// But in my eyes Deutsche Bank uses it wrong and adds a second HIUPD for the same account but with most information missing:
|
||||||
// HIUPD:7:6:4+++2200672485+++Christian+Dankl, Christian+++HKTAN:1+HKPRO:1+HKVVB:1+HKFRD:1+DKPSP:1+HKPSP:1'
|
// HIUPD:7:6:4+++2200672485+++Christian+Dankl, Christian+++HKTAN:1+HKPRO:1+HKVVB:1+HKFRD:1+DKPSP:1+HKPSP:1'
|
||||||
return null
|
return null
|
||||||
|
@ -265,15 +262,8 @@ open class ResponseParser(
|
||||||
val customerId = parseString(dataElementGroups[3])
|
val customerId = parseString(dataElementGroups[3])
|
||||||
val accountType = parseNullableCodeEnum(dataElementGroups[4], AccountTypeCode.values())?.type
|
val accountType = parseNullableCodeEnum(dataElementGroups[4], AccountTypeCode.values())?.type
|
||||||
val currency = parseStringToNullIfEmpty(dataElementGroups[5])
|
val currency = parseStringToNullIfEmpty(dataElementGroups[5])
|
||||||
|
|
||||||
// Name Kontoinhaber 1 und 2
|
|
||||||
// Die Felder "Name des Kontoinhabers 1" und "Name des Kontoinhabers 2" sind in FinTS V3.0 mit ..27 Stellen definiert.
|
|
||||||
// Da diese Felder in anderem Kontext maximal 35 Stellen lang sein können, wird auch für diese beiden UPD-Felder eine
|
|
||||||
// Maximallänge von 35 Stellen zugelassen. Bestehende Implementierungen sollten damit keine Probleme bekommen und
|
|
||||||
// evtl. überzählige Stellen (>27) ggf. abschneiden.
|
|
||||||
val accountHolderName1 = parseString(dataElementGroups[6])
|
val accountHolderName1 = parseString(dataElementGroups[6])
|
||||||
val accountHolderName2 = if (dataElementGroups.size > 7) parseStringToNullIfEmpty(dataElementGroups[7]) else null
|
val accountHolderName2 = if (dataElementGroups.size > 7) parseStringToNullIfEmpty(dataElementGroups[7]) else null
|
||||||
|
|
||||||
val productName = if (dataElementGroups.size > 8) parseStringToNullIfEmpty(dataElementGroups[8]) else null
|
val productName = if (dataElementGroups.size > 8) parseStringToNullIfEmpty(dataElementGroups[8]) else null
|
||||||
val limit = if (dataElementGroups.size > 9) parseStringToNullIfEmpty(dataElementGroups[9]) else null // TODO: parse limit
|
val limit = if (dataElementGroups.size > 9) parseStringToNullIfEmpty(dataElementGroups[9]) else null // TODO: parse limit
|
||||||
|
|
||||||
|
@ -450,18 +440,11 @@ open class ResponseParser(
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun mapToSingleTanMethodParameters(methodDataElements: List<String>): TanMethodParameters {
|
protected open fun mapToSingleTanMethodParameters(methodDataElements: List<String>): TanMethodParameters {
|
||||||
val sicherheitsfunktion = try {
|
|
||||||
parseCodeEnum(methodDataElements[0], Sicherheitsfunktion.values())
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
log.error { "Could not map Sicherheitsfuntion from value '${methodDataElements[0]}'" }
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
|
|
||||||
val dkTanMethod = tryToParseDkTanMethod(methodDataElements[3])
|
val dkTanMethod = tryToParseDkTanMethod(methodDataElements[3])
|
||||||
val isDecoupledTanMethod = dkTanMethod == DkTanMethod.Decoupled || dkTanMethod == DkTanMethod.DecoupledPush
|
val isDecoupledTanMethod = dkTanMethod == DkTanMethod.Decoupled || dkTanMethod == DkTanMethod.DecoupledPush
|
||||||
|
|
||||||
return TanMethodParameters(
|
return TanMethodParameters(
|
||||||
sicherheitsfunktion,
|
parseCodeEnum(methodDataElements[0], Sicherheitsfunktion.values()),
|
||||||
parseCodeEnum(methodDataElements[1], TanProcess.values()),
|
parseCodeEnum(methodDataElements[1], TanProcess.values()),
|
||||||
parseString(methodDataElements[2]),
|
parseString(methodDataElements[2]),
|
||||||
dkTanMethod,
|
dkTanMethod,
|
||||||
|
@ -666,28 +649,17 @@ open class ResponseParser(
|
||||||
|
|
||||||
|
|
||||||
protected open fun parseBalanceSegment(segment: String, dataElementGroups: List<String>): BalanceSegment {
|
protected open fun parseBalanceSegment(segment: String, dataElementGroups: List<String>): BalanceSegment {
|
||||||
// 2: Kontoverbindung Auftraggeber (ktv, M), ab Version 7: Kontoverbindung international (kti, M)
|
// dataElementGroups[1] is account details
|
||||||
// 3: Kontoproduktbezeichnung (an ..30, M)
|
|
||||||
// 4: Kontowährung (cur, M)
|
|
||||||
// 5: Gebuchter Saldo (btg, M)
|
|
||||||
// 6: Saldo der vorgemerkten Umsätze (btg, O)
|
|
||||||
// 7: Kreditlinie (btg, O)
|
|
||||||
// 8: Verfügbarer Betrag (btg, O)
|
|
||||||
// 9: Bereits verfügter Betrag (btg, O)
|
|
||||||
// 10: Überziehung (btg, O)
|
|
||||||
// 11: Buchungszeitpunkt (tsp, O)
|
|
||||||
// ab Version 7: 12: Fälligkeit (dat, O: bei Kreditkartenkonten, N: sonst)
|
|
||||||
// ab Version 8: 13: Ab Monatswechsel pfändbar (btg, O)
|
|
||||||
|
|
||||||
val balance = parseBalance(dataElementGroups[4])
|
val balance = parseBalance(dataElementGroups[4])
|
||||||
val balanceOfPreBookedTransactions = if (dataElementGroups.size > 5) parseBalanceToNullIfZeroOrNotSet(dataElementGroups[5]) else null
|
val balanceOfPreBookedTransactions = if (dataElementGroups.size > 5) parseBalanceToNullIfZeroOrNotSet(dataElementGroups[5]) else null
|
||||||
|
|
||||||
return BalanceSegment(
|
return BalanceSegment(
|
||||||
balance = balance.amount,
|
balance.amount,
|
||||||
currency = parseString(dataElementGroups[3]),
|
parseString(dataElementGroups[3]),
|
||||||
date = balance.date,
|
balance.date,
|
||||||
accountProductName = parseString(dataElementGroups[2]),
|
parseString(dataElementGroups[2]),
|
||||||
balanceOfPreBookedTransactions = balanceOfPreBookedTransactions?.amount,
|
balanceOfPreBookedTransactions?.amount,
|
||||||
segment
|
segment
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,4 @@ open class AddAccountResponse(
|
||||||
open val retrievedData: List<RetrievedAccountData>
|
open val retrievedData: List<RetrievedAccountData>
|
||||||
get() = retrievedTransactionsResponses.mapNotNull { it.retrievedData }
|
get() = retrievedTransactionsResponses.mapNotNull { it.retrievedData }
|
||||||
|
|
||||||
override val messageLog: List<MessageLogEntry>
|
|
||||||
get() = buildList {
|
|
||||||
addAll(super.messageLog)
|
|
||||||
retrievedTransactionsResponses.forEach {
|
|
||||||
addAll(it.messageLog)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,19 +5,12 @@ import kotlinx.datetime.LocalDateTime
|
||||||
import kotlinx.datetime.LocalTime
|
import kotlinx.datetime.LocalTime
|
||||||
import net.dankito.banking.fints.extensions.nowAtEuropeBerlin
|
import net.dankito.banking.fints.extensions.nowAtEuropeBerlin
|
||||||
import net.dankito.banking.fints.extensions.todayAtEuropeBerlin
|
import net.dankito.banking.fints.extensions.todayAtEuropeBerlin
|
||||||
import net.dankito.banking.fints.log.MessageLogCollector
|
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
open class FinTsUtils {
|
open class FinTsUtils {
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val NewLine = MessageLogCollector.NewLine
|
|
||||||
|
|
||||||
private val BreakableSegmentSeparatorsRegex = Regex("""'([A-Z])""")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
open fun formatDateToday(): String {
|
open fun formatDateToday(): String {
|
||||||
return formatDate(LocalDate.todayAtEuropeBerlin())
|
return formatDate(LocalDate.todayAtEuropeBerlin())
|
||||||
|
@ -53,13 +46,6 @@ open class FinTsUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun prettyPrintFinTsMessage(finTsMessage: String): String {
|
|
||||||
return finTsMessage
|
|
||||||
.replace(BreakableSegmentSeparatorsRegex, "'$NewLine$1")
|
|
||||||
.replace("@HNSHK:", "@${NewLine}HNSHK:")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected open fun convertToInt(string: String): Int {
|
protected open fun convertToInt(string: String): Int {
|
||||||
return string.toInt()
|
return string.toInt()
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,23 +89,4 @@ class FinTsUtilsTest {
|
||||||
assertEquals(182251, result)
|
assertEquals(182251, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun prettyPrint() {
|
|
||||||
val result = underTest.prettyPrintFinTsMessage("""HNHBK:1:3+000000000392+300+0+1'HNVSK:998:3+PIN:1+998+1+1::0+1:20240821:022352+2:2:13:@8@ :5:1+280:10010010:UserName:V:0:0+0'HNVSD:999:1+@230@HNSHK:2:4+PIN:1+999+1265303553+1+1+1::0+1+1:20240821:022352+1:999:1+6:10:16+280:10010010:UserName:S:0:0'HKIDN:3:2+280:10010010+UserName+0+0'HKVVB:4:3+0+0+0+15E53C26816138699C7B6A3E8+1.0.0'HKSYN:5:3+0'HNSHA:6:2+1265303553++MyPassword''HNHBS:7:1+1'""")
|
|
||||||
|
|
||||||
assertEquals(result.replace("\r\n", "\n"), """
|
|
||||||
HNHBK:1:3+000000000392+300+0+1'
|
|
||||||
HNVSK:998:3+PIN:1+998+1+1::0+1:20240821:022352+2:2:13:@8@ :5:1+280:10010010:UserName:V:0:0+0'
|
|
||||||
HNVSD:999:1+@230@
|
|
||||||
HNSHK:2:4+PIN:1+999+1265303553+1+1+1::0+1+1:20240821:022352+1:999:1+6:10:16+280:10010010:UserName:S:0:0'
|
|
||||||
HKIDN:3:2+280:10010010+UserName+0+0'
|
|
||||||
HKVVB:4:3+0+0+0+15E53C26816138699C7B6A3E8+1.0.0'
|
|
||||||
HKSYN:5:3+0'
|
|
||||||
HNSHA:6:2+1265303553++MyPassword''
|
|
||||||
HNHBS:7:1+1'
|
|
||||||
""".trimIndent().replace("\r\n", "\n")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue