Compare commits

..

No commits in common. "c5647508328ad11609873f63bb8cd5f7498a37b2" and "88c64f1ff1df164d5a3c05bddcde2d10c1a46396" have entirely different histories.

373 changed files with 1689 additions and 1797 deletions

View File

@ -7,9 +7,9 @@ import kotlinx.coroutines.withContext
import kotlinx.datetime.LocalDate
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
import net.dankito.banking.client.model.response.GetAccountDataResponse
import net.codinux.banking.fints.FinTsClient
import net.codinux.banking.fints.callback.SimpleFinTsClientCallback
import net.codinux.banking.fints.model.TanChallenge
import net.dankito.banking.fints.FinTsClient
import net.dankito.banking.fints.callback.SimpleFinTsClientCallback
import net.dankito.banking.fints.model.TanChallenge
import net.dankito.utils.multiplatform.extensions.millisSinceEpochAtSystemDefaultTimeZone
import org.slf4j.LoggerFactory
import java.math.BigDecimal

View File

@ -5,7 +5,7 @@ import net.codinux.banking.fints4k.android.Presenter
import net.codinux.banking.fints4k.android.R
import net.codinux.banking.fints4k.android.adapter.viewholder.AccountTransactionsViewHolder
import net.dankito.banking.client.model.AccountTransaction
import net.codinux.banking.fints.util.toBigDecimal
import net.dankito.banking.fints.util.toBigDecimal
import net.dankito.utils.android.extensions.setTextColorToColorResource
import net.dankito.utils.android.ui.adapter.ListRecyclerAdapter
import org.slf4j.LoggerFactory

View File

@ -15,9 +15,9 @@ import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import net.codinux.banking.fints4k.android.Presenter
import net.codinux.banking.fints4k.android.R
import net.codinux.banking.fints.model.FlickerCodeTanChallenge
import net.codinux.banking.fints.model.ImageTanChallenge
import net.codinux.banking.fints.model.TanChallenge
import net.dankito.banking.fints.model.FlickerCodeTanChallenge
import net.dankito.banking.fints.model.ImageTanChallenge
import net.dankito.banking.fints.model.TanChallenge
import net.dankito.utils.android.extensions.getSpannedFromHtml
import net.dankito.utils.android.extensions.show

View File

@ -13,12 +13,12 @@ import net.dankito.banking.client.model.CustomerAccount
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
import net.dankito.banking.client.model.parameter.RetrieveTransactions
import net.dankito.banking.client.model.parameter.TransferMoneyParameter
import net.codinux.banking.fints.FinTsClient
import net.codinux.banking.fints.callback.SimpleFinTsClientCallback
import net.codinux.banking.fints.extensions.toStringWithMinDigits
import net.codinux.banking.fints.getAccountData
import net.codinux.banking.fints.model.TanChallenge
import net.codinux.banking.fints.transferMoney
import net.dankito.banking.fints.FinTsClient
import net.dankito.banking.fints.callback.SimpleFinTsClientCallback
import net.dankito.banking.fints.extensions.toStringWithMinDigits
import net.dankito.banking.fints.getAccountData
import net.dankito.banking.fints.model.TanChallenge
import net.dankito.banking.fints.transferMoney
import util.CsvWriter
import util.OutputFormat

View File

@ -1,7 +1,7 @@
package commands
import NativeApp
import net.codinux.banking.fints.model.TanMethodType
import net.dankito.banking.fints.model.TanMethodType
data class CommonConfig(

View File

@ -5,10 +5,10 @@ import com.github.ajalt.clikt.core.requireObject
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.options.option
import net.dankito.banking.client.model.parameter.TransferMoneyParameter
import net.codinux.banking.fints.model.AccountData
import net.codinux.banking.fints.model.Amount
import net.codinux.banking.fints.model.Currency
import net.codinux.banking.fints.model.Money
import net.dankito.banking.fints.model.AccountData
import net.dankito.banking.fints.model.Amount
import net.dankito.banking.fints.model.Currency
import net.dankito.banking.fints.model.Money
class TransferMoneyCommand : CliktCommand("Transfers money from your account to a recipient", name = "transfer", printHelpOnEmptyArgs = true) {

View File

@ -12,8 +12,8 @@ import kotlinx.datetime.LocalDate
import kotlinx.datetime.minus
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
import net.dankito.banking.client.model.parameter.RetrieveTransactions
import net.codinux.banking.fints.model.TanMethodType
import net.codinux.banking.fints.extensions.todayAtEuropeBerlin
import net.dankito.banking.fints.model.TanMethodType
import net.dankito.banking.fints.extensions.todayAtEuropeBerlin
import util.OutputFormat

View File

@ -1,11 +1,11 @@
package net.codinux.banking.fints
package net.dankito.banking.fints
import kotlinx.coroutines.runBlocking
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
import net.dankito.banking.client.model.parameter.TransferMoneyParameter
import net.dankito.banking.client.model.response.GetAccountDataResponse
import net.dankito.banking.client.model.response.TransferMoneyResponse
import net.codinux.banking.fints.model.Money
import net.dankito.banking.fints.model.Money
fun FinTsClient.getAccountData(bankCode: String, loginName: String, password: String): GetAccountDataResponse {

View File

@ -1,7 +1,7 @@
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import net.dankito.banking.client.model.AccountTransaction
import net.codinux.banking.fints.model.TanChallenge
import net.dankito.banking.fints.model.TanChallenge
import react.*
import react.dom.*
import styled.styledDiv

View File

@ -2,8 +2,8 @@ import io.ktor.util.encodeBase64
import kotlinx.html.InputType
import kotlinx.html.js.onChangeFunction
import kotlinx.html.style
import net.codinux.banking.fints.model.ImageTanChallenge
import net.codinux.banking.fints.model.TanChallenge
import net.dankito.banking.fints.model.ImageTanChallenge
import net.dankito.banking.fints.model.TanChallenge
import org.w3c.dom.HTMLInputElement
import react.Props
import react.RBuilder

View File

@ -6,11 +6,11 @@ import net.dankito.banking.client.model.parameter.GetAccountDataParameter
import net.dankito.banking.client.model.parameter.TransferMoneyParameter
import net.dankito.banking.client.model.response.GetAccountDataResponse
import net.dankito.banking.client.model.response.TransferMoneyResponse
import net.codinux.banking.fints.FinTsClient
import net.codinux.banking.fints.callback.SimpleFinTsClientCallback
import net.codinux.banking.fints.model.*
import net.codinux.banking.fints.webclient.KtorWebClient
import net.codinux.banking.fints.webclient.ProxyingWebClient
import net.dankito.banking.fints.FinTsClient
import net.dankito.banking.fints.callback.SimpleFinTsClientCallback
import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.webclient.KtorWebClient
import net.dankito.banking.fints.webclient.ProxyingWebClient
import net.dankito.utils.multiplatform.log.LoggerFactory
open class Presenter {

View File

@ -34,7 +34,7 @@ kotlin {
browser {
testTask {
useKarma {
useChromeHeadless()
// useChromeHeadless()
useFirefoxHeadless()
}
}
@ -43,13 +43,10 @@ kotlin {
nodejs()
}
// wasmJs() // ktor is not available for wasmJs yet
linuxX64()
mingwX64()
iosX64()
iosArm64()
iosSimulatorArm64()
macosX64()

View File

@ -1,35 +0,0 @@
package net.codinux.banking.fints.config
import net.codinux.banking.fints.model.ProductData
data class FinTsClientOptions(
/**
* If FinTS messages sent to and received from bank servers and errors should be collected. They are then accessible
* via [net.codinux.banking.fints.response.client.FinTsClientResponse.messageLog].
*
* Set to false by default.
*/
val collectMessageLog: Boolean = false,
/**
* If set to true then [net.codinux.banking.fints.callback.FinTsClientCallback.messageLogAdded] get fired when a
* FinTS message get sent to bank server, a FinTS message is received from bank server or an error occurred.
*
* Defaults to false.
*/
val fireCallbackOnMessageLogs: Boolean = false,
/**
* If sensitive data like user name, password, login name should be removed from FinTS messages before being logged.
*
* Defaults to true.
*/
val removeSensitiveDataFromMessageLog: Boolean = true,
val version: String = "1.0.0", // TODO: get version dynamically
val productName: String = "15E53C26816138699C7B6A3E8"
) {
val product: ProductData by lazy { ProductData(productName, version) }
}

View File

@ -1,17 +0,0 @@
package net.codinux.banking.fints.log
import net.codinux.banking.fints.model.AccountData
import net.codinux.banking.fints.model.BankData
import net.codinux.banking.fints.model.MessageType
import net.codinux.banking.fints.model.JobContextType
class MessageContext(
val jobType: JobContextType,
val dialogType: MessageType,
val jobNumber: Int,
val dialogNumber: Int,
val messageNumber: Int,
val bank: BankData,
val account: AccountData?
)

View File

@ -1,7 +0,0 @@
package net.codinux.banking.fints.messages.datenelemente
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.Nachrichtenteil
abstract class DatenelementBase(val existenzstatus: Existenzstatus) : Nachrichtenteil()

View File

@ -1,6 +0,0 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
open class BezugssegmentInKreditinstitutsnachricht(segmentNumber: Int) : Bezugssegment(segmentNumber, Existenzstatus.Optional)

View File

@ -1,6 +0,0 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
open class BezugssegmentInKundennachricht(segmentNumber: Int) : Bezugssegment(segmentNumber, Existenzstatus.NotAllowed)

View File

@ -1,21 +0,0 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
enum class Dialogsprache(override val code: String) : ICodeEnum {
/**
* Der Kunde darf lediglich ein Sprachkennzeichen einstellen, das im Rahmen
* der BPD vom Kreditinstitut an das Kundensystem übermittelt wurde.
* Wenn noch keine BPD vorliegen, sollte das Kundenprodukt mit Hilfe eines
* anonymen Dialogs die aktuelle BPD des Instituts ermitteln und die Standardsprache des Instituts einstellen, die in den Bankparameterdaten mitgeteilt
* wird. Falls die BPD nicht abgerufen werden kann, ist der Wert 0 einzustellen. Das Kreditinstitut antwortet in diesem Fall in seiner Standardsprache.
*/
Default("0"),
German("1"),
English("2"),
French("3")
}

View File

@ -1,21 +0,0 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
/**
* Information darüber, ob die Kundensystem-ID erforderlich ist.
*/
enum class KundensystemStatusWerte(override val code: String) : ICodeEnum {
/**
* Kundensystem-ID wird nicht benötigt (HBCI DDV-Verfahren und
* chipkartenbasierte Verfahren ab Sicherheitsprofil-Version 3)
* und PinTan bis über HKSYN eine Kundensystem-ID vom Bankserver abgerufen wurde.
*/
NichtBenoetigt("0"),
/**
* Kundensystem-ID wird benötigt (sonstige HBCI RAH- /
* RDH- und PIN/TAN-Verfahren)
*/
Benoetigt("1")
}

View File

@ -1,7 +0,0 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.TextDatenelement
open class NotAllowedDatenelement : TextDatenelement("", Existenzstatus.NotAllowed)

View File

@ -1,7 +0,0 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte.account
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
open class BIC(bic: String, existenzstatus: Existenzstatus) : AlphanumerischesDatenelement(bic, existenzstatus, 11)

View File

@ -1,7 +0,0 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte.account
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
open class IBAN(iban: String, existenzstatus: Existenzstatus) : AlphanumerischesDatenelement(iban, existenzstatus, 34)

View File

@ -1,8 +0,0 @@
package net.codinux.banking.fints.messages.segmente.id
interface ISegmentId {
val id: String
}

View File

@ -1,17 +0,0 @@
package net.codinux.banking.fints.messages.segmente.implementierte
import net.codinux.banking.fints.messages.datenelemente.implementierte.DialogId
import net.codinux.banking.fints.messages.datenelementgruppen.implementierte.Segmentkopf
import net.codinux.banking.fints.messages.segmente.Segment
import net.codinux.banking.fints.messages.segmente.id.CustomerSegmentId
import net.codinux.banking.fints.model.DialogContext
class Dialogende(
segmentNumber: Int,
dialogContext: DialogContext
) : Segment(listOf(
Segmentkopf(CustomerSegmentId.DialogEnd, 1, segmentNumber),
DialogId(dialogContext.dialogId)
))

View File

@ -1,28 +0,0 @@
package net.codinux.banking.fints.messages.segmente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.implementierte.KundenID
import net.codinux.banking.fints.messages.datenelemente.implementierte.KundensystemID
import net.codinux.banking.fints.messages.datenelemente.implementierte.KundensystemStatus
import net.codinux.banking.fints.messages.datenelementgruppen.implementierte.Kreditinstitutskennung
import net.codinux.banking.fints.messages.datenelementgruppen.implementierte.Segmentkopf
import net.codinux.banking.fints.messages.segmente.Segment
import net.codinux.banking.fints.messages.segmente.id.CustomerSegmentId
import net.codinux.banking.fints.model.BankData
import net.codinux.banking.fints.model.MessageBaseData
open class IdentifikationsSegment(
segmentNumber: Int,
bank: BankData
) : Segment(listOf(
Segmentkopf(CustomerSegmentId.Identification, 2, segmentNumber),
Kreditinstitutskennung(bank.countryCode, bank.bankCodeForOnlineBanking),
KundenID(bank.customerId),
KundensystemID(bank.customerSystemId),
KundensystemStatus(bank.customerSystemStatus, Existenzstatus.Mandatory)
)) {
constructor(segmentNumber: Int, baseData: MessageBaseData) : this(segmentNumber, baseData.bank)
}

View File

@ -1,31 +0,0 @@
package net.codinux.banking.fints.model
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import net.codinux.banking.fints.log.MessageContext
import net.codinux.banking.fints.response.segments.ReceivedSegment
open class MessageLogEntry(
open val type: MessageLogEntryType,
open val context: MessageContext,
open val messageTrace: String,
open val message: String,
open val error: Throwable? = null,
/**
* Parsed received segments.
*
* Is only set if [type] is set to [MessageLogEntryType.Received] and response parsing was successful.
*/
open val parsedSegments: List<ReceivedSegment> = emptyList(),
open val time: Instant = Clock.System.now()
) {
val messageIncludingMessageTrace: String
get() = messageTrace + "\n" + message
override fun toString(): String {
return "$type $message"
}
}

View File

@ -1,13 +0,0 @@
package net.codinux.banking.fints.response.client
import net.codinux.banking.fints.model.JobContext
import net.codinux.banking.fints.response.BankResponse
import net.codinux.banking.fints.response.segments.TanMediaList
open class GetTanMediaListResponse(
context: JobContext,
response: BankResponse,
val tanMediaList: TanMediaList?
)
: FinTsClientResponse(context, response)

View File

@ -1,44 +0,0 @@
package net.codinux.banking.fints.response.segments
open class JobParameters(
open val jobName: String,
/**
* Höchstens zulässige Anzahl an Segmenten der jeweiligen Auftragsart je
* Kundennachricht. Übersteigt die Anzahl der vom Kunden übermittelten Segmente pro Auftragsart die zugelassene Maximalanzahl, so wird die gesamte
* Nachricht abgelehnt.
*/
open val maxCountJobs: Int,
/**
* Anzahl der Signaturen, die zur Ausführung eines Geschäftsvorfalls als erforderlich definiert ist.
* Falls 0 angegeben ist, handelt es sich um einen nicht signierungspflichtigen
* Geschäftsvorfall, der auch über einen anonymen Zugang ohne Signierungsmöglichkeit ausgeführt werden kann.
* Falls die Anzahl der benötigten Signaturen größer als 1 ist, bedeutet dies,
* dass dieser Geschäftsvorfall zusätzlich von mindestens einem anderen berechtigten Benutzer signiert werden muss, über dessen Identität in den UPD
* jedoch nichts ausgesagt wird.
* In bestimmten Fällen ist die Anzahl der Signaturen durch die Art des Geschäftsvorfalls vorgegeben (z. B. sind bei Keymanagement-Aufträgen nicht
* mehrere Signaturen möglich).
*
* (Ist meistens 1, da PinTan Nachrichten außer im Anonymen Dialog immer eigene Signatur brauchen.)
*/
open val minimumCountSignatures: Int,
open val securityClass: Int?,
segmentString: String
)
: ReceivedSegment(segmentString) {
internal constructor() : this("", 0, 0, null, "0:0:0") // for object deserializers
constructor(parameters: JobParameters)
: this(parameters.jobName, parameters.maxCountJobs, parameters.minimumCountSignatures,
parameters.securityClass, parameters.segmentString)
override fun toString(): String {
return "$jobName $segmentVersion"
}
}

View File

@ -1,12 +0,0 @@
package net.codinux.banking.fints.response.segments
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanEinsatzOption
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanMedium
open class TanMediaList(
val usageOption: TanEinsatzOption,
val tanMedia: List<TanMedium>,
segmentString: String
)
: ReceivedSegment(segmentString)

View File

@ -1,4 +0,0 @@
package net.codinux.banking.fints.response.segments
open class UnparsedSegment(segmentString: String) : ReceivedSegment(segmentString)

View File

@ -2,15 +2,15 @@ package net.dankito.banking.client.model
import kotlinx.datetime.LocalDate
import kotlinx.serialization.Serializable
import net.codinux.banking.fints.model.Amount
import net.codinux.banking.fints.model.Money
import net.codinux.banking.fints.extensions.UnixEpochStart
import net.dankito.banking.fints.model.Amount
import net.dankito.banking.fints.model.Money
import net.dankito.banking.fints.extensions.UnixEpochStart
@Serializable
open class AccountTransaction(
val amount: Money, // TODO: if we decide to stick with Money, create own type, don't use that one from fints.model (or move over from)
val unparsedReference: String, // alternative names: purpose, reason
val unparsedReference: String,
val bookingDate: LocalDate,
val otherPartyName: String?,
val otherPartyBankCode: String?,

View File

@ -2,8 +2,8 @@ package net.dankito.banking.client.model
import kotlinx.datetime.LocalDate
import kotlinx.serialization.Serializable
import net.codinux.banking.fints.model.Currency
import net.codinux.banking.fints.model.Money
import net.dankito.banking.fints.model.Currency
import net.dankito.banking.fints.model.Money
@Serializable

View File

@ -1,8 +1,8 @@
package net.dankito.banking.client.model
import kotlinx.serialization.Serializable
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanMedium
import net.codinux.banking.fints.model.TanMethod
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanMedium
import net.dankito.banking.fints.model.TanMethod
//import net.dankito.banking.client.model.tan.TanMedium
//import net.dankito.banking.client.model.tan.TanMethod

View File

@ -1,7 +1,7 @@
package net.dankito.banking.client.model.parameter
import net.codinux.banking.fints.model.BankData
import net.codinux.banking.fints.model.TanMethodType
import net.dankito.banking.fints.model.BankData
import net.dankito.banking.fints.model.TanMethodType
import net.dankito.banking.client.model.CustomerCredentials

View File

@ -1,8 +1,8 @@
package net.dankito.banking.client.model.parameter
import kotlinx.datetime.LocalDate
import net.codinux.banking.fints.model.BankData
import net.codinux.banking.fints.model.TanMethodType
import net.dankito.banking.fints.model.BankData
import net.dankito.banking.fints.model.TanMethodType
import net.dankito.banking.client.model.BankAccountIdentifier

View File

@ -1,10 +1,10 @@
package net.dankito.banking.client.model.parameter
import net.dankito.banking.client.model.BankAccountIdentifier
import net.codinux.banking.fints.model.AccountData
import net.codinux.banking.fints.model.BankData
import net.codinux.banking.fints.model.Money
import net.codinux.banking.fints.model.TanMethodType
import net.dankito.banking.fints.model.AccountData
import net.dankito.banking.fints.model.BankData
import net.dankito.banking.fints.model.Money
import net.dankito.banking.fints.model.TanMethodType
open class TransferMoneyParameter(

View File

@ -1,15 +1,15 @@
package net.dankito.banking.client.model.response
import net.codinux.banking.fints.model.BankData
import net.codinux.banking.fints.model.MessageLogEntry
import net.dankito.banking.fints.model.BankData
import net.dankito.banking.fints.model.MessageLogEntry
// TODO: rename to BankingClientResponse?
open class FinTsClientResponse(
open val error: ErrorCode?,
open val errorMessage: String?,
open val messageLogWithoutSensitiveData: List<MessageLogEntry>,
open val finTsModel: BankData? = null
open val error: ErrorCode?,
open val errorMessage: String?,
open val messageLogWithoutSensitiveData: List<MessageLogEntry>,
open val finTsModel: BankData? = null
) {
internal constructor() : this(null, null, listOf()) // for object deserializers

View File

@ -2,7 +2,7 @@ package net.dankito.banking.client.model.response
import net.dankito.banking.client.model.AccountTransaction
import net.dankito.banking.client.model.CustomerAccount
import net.codinux.banking.fints.model.*
import net.dankito.banking.fints.model.*
open class GetAccountDataResponse(

View File

@ -1,12 +1,12 @@
package net.dankito.banking.client.model.response
import net.codinux.banking.fints.model.BankData
import net.codinux.banking.fints.model.MessageLogEntry
import net.dankito.banking.fints.model.BankData
import net.dankito.banking.fints.model.MessageLogEntry
open class TransferMoneyResponse(
error: ErrorCode?,
errorMessage: String?,
messageLogWithoutSensitiveData: List<MessageLogEntry>,
finTsModel: BankData? = null
error: ErrorCode?,
errorMessage: String?,
messageLogWithoutSensitiveData: List<MessageLogEntry>,
finTsModel: BankData? = null
) : FinTsClientResponse(error, errorMessage, messageLogWithoutSensitiveData, finTsModel)

View File

@ -6,7 +6,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import net.codinux.banking.fints.model.Amount
import net.dankito.banking.fints.model.Amount
class AmountSerializer : KSerializer<Amount> {

View File

@ -6,7 +6,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import net.codinux.banking.fints.model.Currency
import net.dankito.banking.fints.model.Currency
class CurrencySerializer : KSerializer<Currency> {

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints
package net.dankito.banking.fints
import net.dankito.banking.client.model.parameter.FinTsClientParameter
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
@ -6,15 +6,15 @@ import net.dankito.banking.client.model.parameter.TransferMoneyParameter
import net.dankito.banking.client.model.response.ErrorCode
import net.dankito.banking.client.model.response.GetAccountDataResponse
import net.dankito.banking.client.model.response.TransferMoneyResponse
import net.codinux.banking.fints.callback.FinTsClientCallback
import net.codinux.banking.fints.config.FinTsClientConfiguration
import net.codinux.banking.fints.mapper.FinTsModelMapper
import net.codinux.banking.fints.model.*
import net.codinux.banking.fints.response.client.FinTsClientResponse
import net.codinux.banking.fints.response.client.GetAccountInfoResponse
import net.codinux.banking.fints.response.client.GetAccountTransactionsResponse
import net.codinux.banking.fints.response.segments.AccountType
import net.codinux.banking.fints.util.BicFinder
import net.dankito.banking.fints.callback.FinTsClientCallback
import net.dankito.banking.fints.config.FinTsClientConfiguration
import net.dankito.banking.fints.mapper.FinTsModelMapper
import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.response.client.FinTsClientResponse
import net.dankito.banking.fints.response.client.GetAccountInfoResponse
import net.dankito.banking.fints.response.client.GetAccountTransactionsResponse
import net.dankito.banking.fints.response.segments.AccountType
import net.dankito.banking.fints.util.BicFinder
open class FinTsClient(
@ -175,13 +175,13 @@ open class FinTsClient(
val newUserInfoResponse = config.jobExecutor.retrieveBasicDataLikeUsersTanMethods(context, param.preferredTanMethods, param.preferredTanMedium)
/* Second dialog, executed in retrieveBasicDataLikeUsersTanMethods() if required: some banks require that in order to initialize a dialog with
strong customer authorization TAN media is required */
if (newUserInfoResponse.successful == false) { // bank parameter (FinTS server address, ...) already seem to be wrong
return GetAccountInfoResponse(context, newUserInfoResponse)
}
/* Second dialog, executed in retrieveBasicDataLikeUsersTanMethods() if required: some banks require that in order to initialize a dialog with
strong customer authorization TAN media is required */
val getAccountsResponse = config.jobExecutor.getAccounts(context)
return GetAccountInfoResponse(context, getAccountsResponse)

View File

@ -1,16 +1,17 @@
package net.codinux.banking.fints
package net.dankito.banking.fints
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.datetime.*
import net.codinux.banking.fints.callback.FinTsClientCallback
import net.codinux.banking.fints.config.FinTsClientConfiguration
import net.codinux.banking.fints.extensions.minusDays
import net.codinux.banking.fints.extensions.todayAtEuropeBerlin
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.*
import net.codinux.banking.fints.model.*
import net.codinux.banking.fints.response.BankResponse
import net.codinux.banking.fints.response.client.*
import net.dankito.banking.fints.callback.FinTsClientCallback
import net.dankito.banking.fints.config.FinTsClientConfiguration
import net.dankito.banking.fints.extensions.minusDays
import net.dankito.banking.fints.extensions.todayAtEuropeBerlin
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.*
import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.response.BankResponse
import net.dankito.banking.fints.response.client.*
import net.dankito.banking.fints.webclient.IWebClient
/**
@ -25,6 +26,19 @@ open class FinTsClientDeprecated(
constructor(callback: FinTsClientCallback) : this(FinTsClientConfiguration(), callback)
/**
* Retrieves information about bank (e.g. supported HBCI versions, FinTS server address,
* supported jobs, ...).
*
* On success [bank] parameter is updated afterwards.
*/
open fun getAnonymousBankInfoAsync(bank: BankData, callback: (FinTsClientResponse) -> Unit) {
GlobalScope.launch {
callback(getAnonymousBankInfo(bank))
}
}
/**
* Retrieves information about bank (e.g. supported HBCI versions, FinTS server address,
* supported jobs, ...).

View File

@ -1,11 +1,11 @@
package net.codinux.banking.fints
package net.dankito.banking.fints
import net.codinux.banking.fints.callback.FinTsClientCallback
import net.codinux.banking.fints.config.FinTsClientConfiguration
import net.codinux.banking.fints.model.*
import net.codinux.banking.fints.response.client.AddAccountResponse
import net.codinux.banking.fints.response.client.FinTsClientResponse
import net.codinux.banking.fints.response.client.GetAccountTransactionsResponse
import net.dankito.banking.fints.callback.FinTsClientCallback
import net.dankito.banking.fints.config.FinTsClientConfiguration
import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.response.client.AddAccountResponse
import net.dankito.banking.fints.response.client.FinTsClientResponse
import net.dankito.banking.fints.response.client.GetAccountTransactionsResponse
open class FinTsClientForCustomer(

View File

@ -1,26 +1,26 @@
package net.codinux.banking.fints
package net.dankito.banking.fints
import kotlinx.coroutines.delay
import kotlinx.datetime.LocalDate
import net.codinux.log.logger
import net.codinux.banking.fints.messages.MessageBuilder
import net.codinux.banking.fints.messages.MessageBuilderResult
import net.codinux.banking.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.*
import net.codinux.banking.fints.messages.segmente.id.CustomerSegmentId
import net.codinux.banking.fints.messages.segmente.id.ISegmentId
import net.codinux.banking.fints.model.*
import net.codinux.banking.fints.model.mapper.ModelMapper
import net.codinux.banking.fints.response.BankResponse
import net.codinux.banking.fints.response.InstituteSegmentId
import net.codinux.banking.fints.response.client.*
import net.codinux.banking.fints.response.segments.*
import net.codinux.banking.fints.tan.FlickerCodeDecoder
import net.codinux.banking.fints.tan.TanImageDecoder
import net.codinux.banking.fints.util.TanMethodSelector
import net.codinux.banking.fints.extensions.minusDays
import net.codinux.banking.fints.extensions.todayAtEuropeBerlin
import net.codinux.banking.fints.extensions.todayAtSystemDefaultTimeZone
import net.dankito.banking.fints.messages.MessageBuilder
import net.dankito.banking.fints.messages.MessageBuilderResult
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.*
import net.dankito.banking.fints.messages.segmente.id.CustomerSegmentId
import net.dankito.banking.fints.messages.segmente.id.ISegmentId
import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.model.mapper.ModelMapper
import net.dankito.banking.fints.response.BankResponse
import net.dankito.banking.fints.response.InstituteSegmentId
import net.dankito.banking.fints.response.client.*
import net.dankito.banking.fints.response.segments.*
import net.dankito.banking.fints.tan.FlickerCodeDecoder
import net.dankito.banking.fints.tan.TanImageDecoder
import net.dankito.banking.fints.util.TanMethodSelector
import net.dankito.banking.fints.extensions.minusDays
import net.dankito.banking.fints.extensions.todayAtEuropeBerlin
import net.dankito.banking.fints.extensions.todayAtSystemDefaultTimeZone
/**

View File

@ -1,18 +1,17 @@
package net.codinux.banking.fints
package net.dankito.banking.fints
import net.codinux.log.logger
import net.codinux.banking.fints.messages.MessageBuilder
import net.codinux.banking.fints.messages.MessageBuilderResult
import net.codinux.banking.fints.model.*
import net.codinux.banking.fints.response.BankResponse
import net.codinux.banking.fints.response.segments.TanResponse
import net.codinux.banking.fints.util.IBase64Service
import net.codinux.banking.fints.util.PureKotlinBase64Service
import net.codinux.banking.fints.webclient.IWebClient
import net.codinux.banking.fints.webclient.KtorWebClient
import net.codinux.banking.fints.webclient.WebClientResponse
import net.codinux.banking.fints.extensions.getAllExceptionMessagesJoined
import net.codinux.banking.fints.response.segments.ReceivedSegment
import net.dankito.banking.fints.messages.MessageBuilder
import net.dankito.banking.fints.messages.MessageBuilderResult
import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.response.BankResponse
import net.dankito.banking.fints.response.segments.TanResponse
import net.dankito.banking.fints.util.IBase64Service
import net.dankito.banking.fints.util.PureKotlinBase64Service
import net.dankito.banking.fints.webclient.IWebClient
import net.dankito.banking.fints.webclient.KtorWebClient
import net.dankito.banking.fints.webclient.WebClientResponse
import net.dankito.banking.fints.extensions.getAllExceptionMessagesJoined
open class RequestExecutor(
@ -105,11 +104,9 @@ open class RequestExecutor(
try {
val decodedResponse = decodeBase64Response(responseBody)
val parsedResponse = context.responseParser.parse(decodedResponse)
addMessageLog(context, MessageLogEntryType.Received, decodedResponse)
addMessageLog(context, MessageLogEntryType.Received, decodedResponse, parsedResponse.receivedSegments)
return parsedResponse
return context.responseParser.parse(decodedResponse)
} catch (e: Exception) {
logError(context, "Could not decode responseBody:\r\n'$responseBody'", e)
@ -167,8 +164,8 @@ open class RequestExecutor(
}
protected open fun addMessageLog(context: JobContext, type: MessageLogEntryType, message: String, parsedSegments: List<ReceivedSegment> = emptyList()) {
context.addMessageLog(type, message, parsedSegments)
protected open fun addMessageLog(context: JobContext, type: MessageLogEntryType, message: String) {
context.addMessageLog(type, message)
}
protected open fun logError(context: JobContext, message: String, e: Exception?) {

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.callback
package net.dankito.banking.fints.callback
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
import net.codinux.banking.fints.model.*
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
import net.dankito.banking.fints.model.*
interface FinTsClientCallback {
@ -27,11 +27,4 @@ interface FinTsClientCallback {
*/
suspend fun enterTanGeneratorAtc(bank: BankData, tanMedium: TanGeneratorTanMedium): EnterTanGeneratorAtcResult
/**
* Gets fired when a FinTS message get sent to bank server, a FinTS message is received from bank server or an error occurred.
*
* Be aware, in order that this message gets fired [net.codinux.banking.fints.config.FinTsClientOptions.fireCallbackOnMessageLogs] has to be set to true.
*/
fun messageLogAdded(messageLogEntry: MessageLogEntry)
}

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.callback
package net.dankito.banking.fints.callback
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
import net.codinux.banking.fints.model.*
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
import net.dankito.banking.fints.model.*
open class NoOpFinTsClientCallback : FinTsClientCallback {
@ -18,8 +18,4 @@ open class NoOpFinTsClientCallback : FinTsClientCallback {
return EnterTanGeneratorAtcResult.userDidNotEnterAtc()
}
override fun messageLogAdded(messageLogEntry: MessageLogEntry) {
}
}

View File

@ -1,19 +1,18 @@
package net.codinux.banking.fints.callback
package net.dankito.banking.fints.callback
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
import net.codinux.banking.fints.model.*
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
import net.dankito.banking.fints.model.*
open class SimpleFinTsClientCallback(
protected open val askUserForTanMethod: ((supportedTanMethods: List<TanMethod>, suggestedTanMethod: TanMethod?) -> TanMethod?)? = null,
protected open val messageLogAdded: ((MessageLogEntry) -> Unit)? = null,
protected open val enterTan: ((tanChallenge: TanChallenge) -> Unit)? = null,
protected open val enterTanGeneratorAtc: ((bank: BankData, tanMedium: TanGeneratorTanMedium) -> EnterTanGeneratorAtcResult)? = null,
protected open val enterTan: ((tanChallenge: TanChallenge) -> Unit)? = null
protected open val askUserForTanMethod: ((supportedTanMethods: List<TanMethod>, suggestedTanMethod: TanMethod?) -> TanMethod?)? = null
) : FinTsClientCallback {
constructor() : this(null as ((tanChallenge: TanChallenge) -> Unit)?) // Swift does not support default parameter values -> create constructor overloads
constructor() : this(null) // Swift does not support default parameter values -> create constructor overloads
constructor(enterTan: ((tanChallenge: TanChallenge) -> Unit)?) : this(null, null, null, enterTan)
constructor(enterTan: ((tanChallenge: TanChallenge) -> Unit)?) : this(enterTan, null)
override suspend fun askUserForTanMethod(supportedTanMethods: List<TanMethod>, suggestedTanMethod: TanMethod?): TanMethod? {
@ -29,8 +28,4 @@ open class SimpleFinTsClientCallback(
return enterTanGeneratorAtc?.invoke(bank, tanMedium) ?: EnterTanGeneratorAtcResult.userDidNotEnterAtc()
}
override fun messageLogAdded(messageLogEntry: MessageLogEntry) {
messageLogAdded?.invoke(messageLogEntry)
}
}

View File

@ -1,15 +1,15 @@
package net.codinux.banking.fints.config
package net.dankito.banking.fints.config
import net.codinux.banking.fints.FinTsJobExecutor
import net.codinux.banking.fints.RequestExecutor
import net.codinux.banking.fints.messages.MessageBuilder
import net.codinux.banking.fints.model.mapper.ModelMapper
import net.codinux.banking.fints.util.FinTsServerAddressFinder
import net.codinux.banking.fints.util.IBase64Service
import net.codinux.banking.fints.util.PureKotlinBase64Service
import net.codinux.banking.fints.util.TanMethodSelector
import net.codinux.banking.fints.webclient.IWebClient
import net.codinux.banking.fints.webclient.KtorWebClient
import net.dankito.banking.fints.FinTsJobExecutor
import net.dankito.banking.fints.RequestExecutor
import net.dankito.banking.fints.messages.MessageBuilder
import net.dankito.banking.fints.model.mapper.ModelMapper
import net.dankito.banking.fints.util.FinTsServerAddressFinder
import net.dankito.banking.fints.util.IBase64Service
import net.dankito.banking.fints.util.PureKotlinBase64Service
import net.dankito.banking.fints.util.TanMethodSelector
import net.dankito.banking.fints.webclient.IWebClient
import net.dankito.banking.fints.webclient.KtorWebClient
class FinTsClientConfiguration(
var options: FinTsClientOptions = FinTsClientOptions(),

View File

@ -0,0 +1,13 @@
package net.dankito.banking.fints.config
import net.dankito.banking.fints.model.ProductData
data class FinTsClientOptions(
val removeSensitiveDataFromMessageLog: Boolean = true,
val version: String = "1.0.0", // TODO: get version dynamically
val productName: String = "15E53C26816138699C7B6A3E8"
) {
val product: ProductData by lazy { ProductData(productName, version) }
}

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.extensions
package net.dankito.banking.fints.extensions
import kotlinx.datetime.*
import kotlin.js.JsName

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.extensions
package net.dankito.banking.fints.extensions
import kotlinx.datetime.*

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.extensions
package net.dankito.banking.fints.extensions
fun Int.toStringWithMinDigits(minimumCountDigits: Int, fillerString: Char = '0'): String {

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.extensions
package net.dankito.banking.fints.extensions
import kotlinx.datetime.Clock
import kotlin.random.Random

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.extensions
package net.dankito.banking.fints.extensions
/**

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.extensions
package net.dankito.banking.fints.extensions
fun Throwable.getAllExceptionMessagesJoined(maxDepth: Int = 5): String {

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.extensions
package net.dankito.banking.fints.extensions
import kotlinx.datetime.TimeZone

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.log
package net.dankito.banking.fints.log
import kotlin.reflect.KClass

View File

@ -0,0 +1,17 @@
package net.dankito.banking.fints.log
import net.dankito.banking.fints.model.AccountData
import net.dankito.banking.fints.model.BankData
import net.dankito.banking.fints.model.MessageType
import net.dankito.banking.fints.model.JobContextType
class MessageContext(
val jobType: JobContextType,
val dialogType: MessageType,
val jobNumber: Int,
val dialogNumber: Int,
val messageNumber: Int,
val bank: BankData,
val account: AccountData?
)

View File

@ -1,22 +1,19 @@
package net.codinux.banking.fints.log
package net.dankito.banking.fints.log
import net.codinux.log.LoggerFactory
import net.codinux.log.logger
import net.codinux.banking.fints.callback.FinTsClientCallback
import net.codinux.banking.fints.config.FinTsClientOptions
import net.codinux.banking.fints.model.BankData
import net.codinux.banking.fints.model.MessageLogEntry
import net.codinux.banking.fints.model.MessageLogEntryType
import net.codinux.banking.fints.extensions.getInnerException
import net.codinux.banking.fints.extensions.nthIndexOf
import net.codinux.banking.fints.extensions.toStringWithMinDigits
import net.codinux.banking.fints.response.segments.ReceivedSegment
import net.codinux.banking.fints.util.FinTsUtils
import net.dankito.banking.fints.config.FinTsClientOptions
import net.dankito.banking.fints.model.BankData
import net.dankito.banking.fints.model.MessageLogEntry
import net.dankito.banking.fints.model.MessageLogEntryType
import net.dankito.banking.fints.extensions.getInnerException
import net.dankito.banking.fints.extensions.nthIndexOf
import net.dankito.banking.fints.extensions.toStringWithMinDigits
import net.dankito.banking.fints.util.FinTsUtils
import kotlin.reflect.KClass
open class MessageLogCollector(
private val callback: FinTsClientCallback,
private val options: FinTsClientOptions = FinTsClientOptions(),
private val finTsUtils: FinTsUtils = FinTsUtils()
) {
@ -38,13 +35,13 @@ open class MessageLogCollector(
// in either case remove sensitive data after response is parsed as otherwise some information like account holder name and accounts may is not set yet on BankData
open val messageLog: List<MessageLogEntry>
// safe CPU cycles by only formatting and removing sensitive data if messageLog is really requested
get() = _messageLog.map { MessageLogEntry(it.type, it.context, it.messageTrace, createMessageForLog(it), it.error, it.parsedSegments, it.time) }
get() = _messageLog.map { MessageLogEntry(it.type, it.context, it.messageTrace, createMessageForLog(it), it.error, it.time) }
private fun createMessageForLog(logEntry: MessageLogEntry): String {
val message = if (logEntry.type == MessageLogEntryType.Error) {
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 {
logEntry.message
logEntry.messageTrace + "\n" + prettyPrintFinTsMessage(logEntry.message)
}
return if (options.removeSensitiveDataFromMessageLog) {
@ -55,41 +52,25 @@ open class MessageLogCollector(
}
open fun addMessageLog(type: MessageLogEntryType, message: String, context: MessageContext, parsedSegments: List<ReceivedSegment> = emptyList()) {
open fun addMessageLog(type: MessageLogEntryType, message: String, context: MessageContext) {
val messageTrace = createMessageTraceString(type, context)
val prettyPrintMessage = if (options.collectMessageLog || options.fireCallbackOnMessageLogs || log.isDebugEnabled) { // only use CPU cycles if message will ever be used / displayed
prettyPrintFinTsMessage(message)
} else {
message
}
addMessageLogEntry(type, context, messageTrace, message)
log.debug { "$messageTrace\n$prettyPrintMessage" }
addMessageLogEntry(type, context, messageTrace, prettyPrintMessage, null, parsedSegments)
log.debug { "$messageTrace\n${prettyPrintFinTsMessage(message)}" }
}
open fun logError(loggingClass: KClass<*>, message: String, context: MessageContext, e: Exception? = null) {
val type = MessageLogEntryType.Error
val messageTrace = createMessageTraceString(type, context)
LoggerFactory.getLogger(loggingClass).error(e) { messageTrace + message }
LoggerFactory.getLogger(loggingClass).error(e) { messageTrace + messageTrace }
addMessageLogEntry(type, context, messageTrace, message, e)
}
protected open fun addMessageLogEntry(type: MessageLogEntryType, context: MessageContext, messageTrace: String, message: String, error: Throwable? = null, parsedSegments: List<ReceivedSegment> = emptyList()) {
if (options.collectMessageLog || options.fireCallbackOnMessageLogs) {
val newEntry = MessageLogEntry(type, context, messageTrace, message, error, parsedSegments)
if (options.collectMessageLog) {
_messageLog.add(newEntry)
}
if (options.fireCallbackOnMessageLogs) {
callback.messageLogAdded(newEntry)
}
}
protected open fun addMessageLogEntry(type: MessageLogEntryType, context: MessageContext, messageTrace: String, message: String, error: Throwable? = null) {
_messageLog.add(MessageLogEntry(type, context, messageTrace, message, error))
}
@ -107,9 +88,9 @@ open class MessageLogCollector(
protected open fun getMessageTypeString(type: MessageLogEntryType): String {
return when (type) {
MessageLogEntryType.Sent -> "01 Sending message"
MessageLogEntryType.Received -> "02 Received message"
MessageLogEntryType.Error -> "03 Error"
MessageLogEntryType.Sent -> "Sending message"
MessageLogEntryType.Received -> "Received message"
MessageLogEntryType.Error -> "Error"
}
}

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.mapper
package net.dankito.banking.fints.mapper
import kotlinx.datetime.LocalDate

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.mapper
package net.dankito.banking.fints.mapper
import kotlinx.datetime.LocalDate
import net.dankito.banking.client.model.*
@ -7,14 +7,14 @@ import net.dankito.banking.client.model.parameter.FinTsClientParameter
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
import net.dankito.banking.client.model.parameter.RetrieveTransactions
import net.dankito.banking.client.model.response.ErrorCode
import net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate.Laenderkennzeichen
import net.codinux.banking.fints.model.*
import net.codinux.banking.fints.response.client.FinTsClientResponse
import net.codinux.banking.fints.response.client.GetAccountTransactionsResponse
import net.codinux.banking.fints.response.segments.AccountType
import net.codinux.banking.fints.util.BicFinder
import net.codinux.banking.fints.extensions.minusDays
import net.codinux.banking.fints.extensions.todayAtEuropeBerlin
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Laenderkennzeichen
import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.response.client.FinTsClientResponse
import net.dankito.banking.fints.response.client.GetAccountTransactionsResponse
import net.dankito.banking.fints.response.segments.AccountType
import net.dankito.banking.fints.util.BicFinder
import net.dankito.banking.fints.extensions.minusDays
import net.dankito.banking.fints.extensions.todayAtEuropeBerlin
open class FinTsModelMapper {
@ -90,7 +90,7 @@ open class FinTsModelMapper {
return data.bookedTransactions.map { map(it) }
}
open fun map(transaction: net.codinux.banking.fints.model.AccountTransaction): AccountTransaction {
open fun map(transaction: net.dankito.banking.fints.model.AccountTransaction): AccountTransaction {
return AccountTransaction(transaction.amount, transaction.unparsedReference, transaction.bookingDate,
transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId, transaction.bookingText, transaction.valueDate,
transaction.statementNumber, transaction.sequenceNumber, transaction.openingBalance, transaction.closingBalance,

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.messages
package net.dankito.banking.fints.messages
enum class Existenzstatus {

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.messages
package net.dankito.banking.fints.messages
import io.ktor.utils.io.charsets.Charsets

View File

@ -1,26 +1,26 @@
package net.codinux.banking.fints.messages
package net.dankito.banking.fints.messages
import net.codinux.banking.fints.extensions.randomWithSeed
import net.codinux.banking.fints.messages.datenelemente.implementierte.Aufsetzpunkt
import net.codinux.banking.fints.messages.datenelemente.implementierte.KundensystemID
import net.codinux.banking.fints.messages.datenelemente.implementierte.Synchronisierungsmodus
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanMedienArtVersion
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanMediumKlasse
import net.codinux.banking.fints.messages.datenelemente.implementierte.tan.TanProcess
import net.codinux.banking.fints.messages.segmente.Segment
import net.codinux.banking.fints.messages.segmente.Synchronisierung
import net.codinux.banking.fints.messages.segmente.id.CustomerSegmentId
import net.codinux.banking.fints.messages.segmente.id.ISegmentId
import net.codinux.banking.fints.messages.segmente.implementierte.*
import net.codinux.banking.fints.messages.segmente.implementierte.sepa.SepaBankTransferBase
import net.codinux.banking.fints.messages.segmente.implementierte.tan.TanGeneratorListeAnzeigen
import net.codinux.banking.fints.messages.segmente.implementierte.tan.TanGeneratorTanMediumAnOderUmmelden
import net.codinux.banking.fints.messages.segmente.implementierte.umsaetze.*
import net.codinux.banking.fints.model.*
import net.codinux.banking.fints.response.InstituteSegmentId
import net.codinux.banking.fints.response.segments.*
import net.codinux.banking.fints.util.FinTsUtils
import net.dankito.banking.fints.extensions.randomWithSeed
import net.dankito.banking.fints.messages.datenelemente.implementierte.Aufsetzpunkt
import net.dankito.banking.fints.messages.datenelemente.implementierte.KundensystemID
import net.dankito.banking.fints.messages.datenelemente.implementierte.Synchronisierungsmodus
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanMedienArtVersion
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanMediumKlasse
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanProcess
import net.dankito.banking.fints.messages.segmente.Segment
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.InstituteSegmentId
import net.dankito.banking.fints.response.segments.*
import net.dankito.banking.fints.util.FinTsUtils
import kotlin.math.absoluteValue
@ -133,7 +133,7 @@ open class MessageBuilder(protected val utils: FinTsUtils = FinTsUtils()) {
}
if (context.bank.customerSystemId == KundensystemID.Anonymous) {
segments.add(Synchronisierung(SignedMessagePayloadFirstSegmentNumber + segments.size, Synchronisierungsmodus.NeueKundensystemIdZurueckmelden))
segments.add(Synchronisierung(segments.size + 3, Synchronisierungsmodus.NeueKundensystemIdZurueckmelden))
}
return createSignedMessageBuilderResult(context, MessageType.DialogInit, segments)
@ -394,7 +394,7 @@ open class MessageBuilder(protected val utils: FinTsUtils = FinTsUtils()) {
return createSignedMessage(context, null, payloadSegments)
}
protected open fun createSignedMessage(context: JobContext, tan: String? = null, payloadSegments: List<Segment>): String {
open fun createSignedMessage(context: JobContext, tan: String? = null, payloadSegments: List<Segment>): String {
val date = utils.formatDateTodayAsInt()
val time = utils.formatTimeNowAsInt()
@ -406,7 +406,7 @@ open class MessageBuilder(protected val utils: FinTsUtils = FinTsUtils()) {
return createMessage(context, encryptedPayload, payloadSegments.size)
}
protected open fun createMessage(context: JobContext, payloadSegments: List<Segment>, countWrappedSegments: Int = 0): String {
open fun createMessage(context: JobContext, payloadSegments: List<Segment>, countWrappedSegments: Int = 0): String {
val dialog = context.dialog
dialog.increaseMessageNumber()
@ -536,7 +536,8 @@ open class MessageBuilder(protected val utils: FinTsUtils = FinTsUtils()) {
}
protected open fun isTanRequiredForJob(context: JobContext, segmentId: CustomerSegmentId): Boolean {
return context.bank.doesJobRequireTan(segmentId)
return context.bank.pinInfo?.jobTanConfiguration?.first { it.segmentId == segmentId.id }?.tanRequired
?: false // TODO: actually in this case it's not allowed to execute job via PIN/TAN at all
}
protected open fun getSepaUrnFor(segmentId: CustomerSegmentId, bank: BankData, sepaDataFormat: String): String? {

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages
package net.dankito.banking.fints.messages
import net.codinux.banking.fints.messages.segmente.Segment
import net.codinux.banking.fints.messages.segmente.implementierte.ZweiSchrittTanEinreichung
import net.dankito.banking.fints.messages.segmente.Segment
import net.dankito.banking.fints.messages.segmente.implementierte.ZweiSchrittTanEinreichung
open class MessageBuilderResult(

View File

@ -1,6 +1,6 @@
package net.codinux.banking.fints.messages
package net.dankito.banking.fints.messages
import net.codinux.banking.fints.util.MessageUtils
import net.dankito.banking.fints.util.MessageUtils
abstract class Nachrichtenteil(protected val messageUtils: MessageUtils = MessageUtils()) {

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.messages
package net.dankito.banking.fints.messages
class Separators {

View File

@ -1,6 +1,6 @@
package net.codinux.banking.fints.messages.datenelemente
package net.dankito.banking.fints.messages.datenelemente
import net.codinux.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.Existenzstatus
abstract class Datenelement(existenzstatus: Existenzstatus): DatenelementBase(existenzstatus) {

View File

@ -0,0 +1,7 @@
package net.dankito.banking.fints.messages.datenelemente
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.Nachrichtenteil
abstract class DatenelementBase(val existenzstatus: Existenzstatus) : Nachrichtenteil()

View File

@ -1,8 +1,8 @@
package net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
import net.codinux.banking.fints.messages.datenelemente.implementierte.ICodeEnum
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
import net.dankito.banking.fints.messages.datenelemente.implementierte.ICodeEnum
/**

View File

@ -1,10 +1,10 @@
package net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
import kotlinx.datetime.LocalDate
import net.codinux.log.logger
import net.codinux.banking.fints.extensions.toStringWithMinDigits
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
import net.dankito.banking.fints.extensions.toStringWithMinDigits
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.ZiffernDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.ZiffernDatenelement
/**

View File

@ -1,10 +1,10 @@
package net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
import kotlinx.datetime.LocalTime
import net.codinux.log.logger
import net.codinux.banking.fints.extensions.toStringWithMinDigits
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.ZiffernDatenelement
import net.dankito.banking.fints.extensions.toStringWithMinDigits
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.ZiffernDatenelement
/**

View File

@ -1,6 +1,6 @@
package net.codinux.banking.fints.messages.datenelemente.basisformate
package net.dankito.banking.fints.messages.datenelemente.basisformate
import net.codinux.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.Existenzstatus
/**

View File

@ -1,6 +1,6 @@
package net.codinux.banking.fints.messages.datenelemente.basisformate
package net.dankito.banking.fints.messages.datenelemente.basisformate
import net.codinux.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.Existenzstatus
/**

View File

@ -1,6 +1,6 @@
package net.codinux.banking.fints.messages.datenelemente.basisformate
package net.dankito.banking.fints.messages.datenelemente.basisformate
import net.codinux.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.Existenzstatus
/**

View File

@ -1,11 +1,11 @@
package net.codinux.banking.fints.messages.datenelemente.basisformate
package net.dankito.banking.fints.messages.datenelemente.basisformate
import io.ktor.utils.io.charsets.encode
import io.ktor.utils.io.charsets.name
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.HbciCharset
import net.codinux.banking.fints.messages.Separators
import net.codinux.banking.fints.messages.datenelemente.Datenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.HbciCharset
import net.dankito.banking.fints.messages.Separators
import net.dankito.banking.fints.messages.datenelemente.Datenelement
/**

View File

@ -1,6 +1,6 @@
package net.codinux.banking.fints.messages.datenelemente.basisformate
package net.dankito.banking.fints.messages.datenelemente.basisformate
import net.codinux.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.Existenzstatus
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate.Identifikation
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Identifikation
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
/**

View File

@ -0,0 +1,6 @@
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.dankito.banking.fints.messages.Existenzstatus
open class BezugssegmentInKreditinstitutsnachricht(segmentNumber: Int) : Bezugssegment(segmentNumber, Existenzstatus.Optional)

View File

@ -0,0 +1,6 @@
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.dankito.banking.fints.messages.Existenzstatus
open class BezugssegmentInKundennachricht(segmentNumber: Int) : Bezugssegment(segmentNumber, Existenzstatus.NotAllowed)

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate.Identifikation
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Identifikation
/**

View File

@ -0,0 +1,14 @@
package net.dankito.banking.fints.messages.datenelemente.implementierte
enum class Dialogsprache(override val code: String) : ICodeEnum {
Default("0"),
German("1"),
English("2"),
French("3")
}

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate.Code
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Code
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.TextDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.TextDatenelement
/**

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
enum class HbciVersion(val versionNumber: Int, override val code: String) : ICodeEnum {

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.NumerischesDatenelement
/**

View File

@ -1,4 +1,4 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
inline fun <reified T : Enum<T>> allCodes(): List<String> {

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.AlphanumerischesDatenelement
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate.Identifikation
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Identifikation
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate.Identifikation
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Identifikation
/**

View File

@ -1,7 +1,7 @@
package net.codinux.banking.fints.messages.datenelemente.implementierte
package net.dankito.banking.fints.messages.datenelemente.implementierte
import net.codinux.banking.fints.messages.Existenzstatus
import net.codinux.banking.fints.messages.datenelemente.abgeleiteteformate.Code
import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Code
/**

View File

@ -0,0 +1,10 @@
package net.dankito.banking.fints.messages.datenelemente.implementierte
enum class KundensystemStatusWerte(override val code: String) : ICodeEnum {
NichtBenoetigt("0"),
Benoetigt("1")
}

Some files were not shown because too many files have changed in this diff Show More