Implemented parsing User parameters and most of account info
This commit is contained in:
parent
89fc324cb4
commit
5fc2c2ef5b
|
@ -1,6 +1,8 @@
|
|||
package net.dankito.fints
|
||||
|
||||
import net.dankito.fints.messages.MessageBuilder
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
|
||||
import net.dankito.fints.model.BankData
|
||||
import net.dankito.fints.model.CustomerData
|
||||
import net.dankito.fints.model.DialogData
|
||||
|
@ -8,7 +10,10 @@ import net.dankito.fints.model.ProductData
|
|||
import net.dankito.fints.response.InstituteSegmentId
|
||||
import net.dankito.fints.response.Response
|
||||
import net.dankito.fints.response.ResponseParser
|
||||
import net.dankito.fints.response.segments.AccountInfo
|
||||
import net.dankito.fints.response.segments.BankParameters
|
||||
import net.dankito.fints.response.segments.ReceivedSynchronization
|
||||
import net.dankito.fints.response.segments.UserParameters
|
||||
import net.dankito.fints.util.IBase64Service
|
||||
import net.dankito.utils.web.client.IWebClient
|
||||
import net.dankito.utils.web.client.OkHttpWebClient
|
||||
|
@ -37,6 +42,8 @@ open class FinTsClient(
|
|||
val response = getAndHandleResponseForMessage(requestBody, bank)
|
||||
|
||||
if (response.successful) {
|
||||
updateBankData(bank, response)
|
||||
|
||||
dialogData.increaseMessageNumber()
|
||||
response.messageHeader?.let { header -> dialogData.dialogId = header.dialogId }
|
||||
|
||||
|
@ -49,6 +56,23 @@ open class FinTsClient(
|
|||
}
|
||||
|
||||
|
||||
open fun initDialog(bank: BankData, customer: CustomerData, product: ProductData,
|
||||
dialogData: DialogData): Response {
|
||||
|
||||
val requestBody = messageBuilder.createInitDialogMessage(bank, customer, product, dialogData)
|
||||
|
||||
val response = getAndHandleResponseForMessage(requestBody, bank)
|
||||
|
||||
if (response.successful) {
|
||||
updateBankData(bank, response)
|
||||
updateCustomerData(customer, response)
|
||||
|
||||
response.messageHeader?.let { header -> dialogData.dialogId = header.dialogId }
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
open fun synchronizeCustomerSystemId(bank: BankData, customer: CustomerData, product: ProductData,
|
||||
dialogData: DialogData = DialogData()): Response {
|
||||
|
||||
|
@ -57,11 +81,10 @@ open class FinTsClient(
|
|||
val response = getAndHandleResponseForMessage(requestBody, bank)
|
||||
|
||||
if (response.successful) {
|
||||
response.messageHeader?.let { header -> dialogData.dialogId = header.dialogId }
|
||||
updateBankData(bank, response)
|
||||
updateCustomerData(customer, response)
|
||||
|
||||
response.getFirstSegmentById<ReceivedSynchronization>(InstituteSegmentId.Synchronization)?.customerSystemId?.let { customerSystemId ->
|
||||
customer.customerSystemId = customerSystemId
|
||||
}
|
||||
response.messageHeader?.let { header -> dialogData.dialogId = header.dialogId }
|
||||
|
||||
closeDialog(bank, customer, dialogData)
|
||||
}
|
||||
|
@ -113,4 +136,46 @@ open class FinTsClient(
|
|||
return base64Service.decode(responseBody.replace("\r", "").replace("\n", ""))
|
||||
}
|
||||
|
||||
|
||||
protected open fun updateBankData(bank: BankData, response: Response) {
|
||||
response.getFirstSegmentById<BankParameters>(InstituteSegmentId.BankParameters)?.let { bankParameters ->
|
||||
bank.bpdVersion = bankParameters.bpdVersion
|
||||
bank.name = bankParameters.bankName
|
||||
// bank.bic = bankParameters. // TODO: where's the BIC?
|
||||
// bank.finTs3ServerAddress = // TODO: parse HIKOM
|
||||
// TODO: save supported languages and security profiles
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun updateCustomerData(customer: CustomerData, response: Response) {
|
||||
response.getFirstSegmentById<BankParameters>(InstituteSegmentId.BankParameters)?.let { bankParameters ->
|
||||
if (customer.selectedLanguage == Dialogsprache.Default && bankParameters.supportedLanguages.isNotEmpty()) {
|
||||
customer.selectedLanguage = bankParameters.supportedLanguages.first()
|
||||
}
|
||||
}
|
||||
|
||||
response.getFirstSegmentById<ReceivedSynchronization>(InstituteSegmentId.Synchronization)?.let { synchronization ->
|
||||
synchronization.customerSystemId?.let {
|
||||
customer.customerSystemId = it
|
||||
|
||||
customer.customerSystemStatus = KundensystemStatusWerte.Benoetigt // TODO: didn't find out for sure yet, but i think i read somewhere, that this has to be set when customerSystemId is set
|
||||
}
|
||||
|
||||
// TODO: may also save securityReferenceNumbers
|
||||
}
|
||||
|
||||
response.getFirstSegmentById<AccountInfo>(InstituteSegmentId.AccountInfo)?.let { accountInfo ->
|
||||
customer.iban = accountInfo.iban
|
||||
customer.name = accountInfo.accountHolderName1
|
||||
|
||||
// TODO: may also make use of other info
|
||||
}
|
||||
|
||||
response.getFirstSegmentById<UserParameters>(InstituteSegmentId.UserParameters)?.let { userParameters ->
|
||||
customer.updVersion = userParameters.updVersion
|
||||
|
||||
// TODO: may also make use of other info
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -58,6 +58,15 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg
|
|||
}
|
||||
|
||||
|
||||
open fun createInitDialogMessage(bank: BankData, customer: CustomerData, product: ProductData, dialogData: DialogData): String {
|
||||
|
||||
return createMessage(true, true, bank, customer, dialogData, listOf(
|
||||
IdentifikationsSegment(generator.resetSegmentNumber(2), bank, customer),
|
||||
Verarbeitungsvorbereitung(generator.getNextSegmentNumber(), bank, customer, product),
|
||||
ZweiSchrittTanEinreichung(generator.getNextSegmentNumber(), TanProcess.TanProcess4, CustomerSegmentId.Identification.id)
|
||||
))
|
||||
}
|
||||
|
||||
open fun createSynchronizeCustomerSystemIdMessage(bank: BankData, customer: CustomerData, product: ProductData, dialogData: DialogData): String {
|
||||
|
||||
return createMessage(true, true, bank, customer, dialogData, listOf(
|
||||
|
|
|
@ -9,6 +9,7 @@ open class BankData(
|
|||
val countryCode: Int,
|
||||
var finTs3ServerAddress: String,
|
||||
var bpdVersion: Int = BPDVersion.VersionNotReceivedYet,
|
||||
var name: String = "",
|
||||
var bic: String? = null,
|
||||
var supportedLanguages: List<Dialogsprache> = listOf()
|
||||
) {
|
||||
|
|
|
@ -9,6 +9,7 @@ open class CustomerData(
|
|||
val customerId: String,
|
||||
var pin: String,
|
||||
val userId: String = customerId,
|
||||
var name: String = "",
|
||||
var iban: String? = null,
|
||||
var updVersion: Int = UPDVersion.VersionNotReceivedYet,
|
||||
var availableTanProcedures: List<TanProcedure> = listOf(),
|
||||
|
|
|
@ -9,6 +9,10 @@ enum class InstituteSegmentId(override val id: String) : ISegmentId {
|
|||
|
||||
BankParameters("HIBPA"),
|
||||
|
||||
SecurityMethods("HISHV")
|
||||
SecurityMethods("HISHV"),
|
||||
|
||||
UserParameters("HIUPA"),
|
||||
|
||||
AccountInfo("HIUPD")
|
||||
|
||||
}
|
|
@ -58,9 +58,14 @@ open class ResponseParser {
|
|||
protected open fun parseSegment(segment: String, segmentId: String, dataElementGroups: List<String>): ReceivedSegment? {
|
||||
return when (segmentId) {
|
||||
MessageSegmentId.MessageHeader.id -> parseMessageHeaderSegment(segment, dataElementGroups)
|
||||
|
||||
InstituteSegmentId.Synchronization.id -> parseSynchronization(segment, dataElementGroups)
|
||||
InstituteSegmentId.BankParameters.id -> parseBankParameters(segment, dataElementGroups)
|
||||
InstituteSegmentId.SecurityMethods.id -> parseSecurityMethods(segment, dataElementGroups)
|
||||
|
||||
InstituteSegmentId.UserParameters.id -> parseUserParameters(segment, dataElementGroups)
|
||||
InstituteSegmentId.AccountInfo.id -> parseAccountInfo(segment, dataElementGroups)
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +115,41 @@ open class ResponseParser {
|
|||
}
|
||||
|
||||
|
||||
protected open fun parseUserParameters(segment: String, dataElementGroups: List<String>): UserParameters {
|
||||
val customerId = dataElementGroups[1]
|
||||
val updVersion = dataElementGroups[2].toInt()
|
||||
val areListedJobsBlocked = dataElementGroups[3] == "0"
|
||||
val username = if (dataElementGroups.size > 4) returnNullIfEmpty(dataElementGroups[4]) else null
|
||||
val extension = if (dataElementGroups.size > 5) returnNullIfEmpty(dataElementGroups[5]) else null
|
||||
|
||||
return UserParameters(customerId, updVersion, areListedJobsBlocked, username, extension, segment)
|
||||
}
|
||||
|
||||
protected open fun parseAccountInfo(segment: String, dataElementGroups: List<String>): AccountInfo {
|
||||
// this is parsing a Kontoverbindung. May extract a method for it.
|
||||
val accountDetails = getDataElements(dataElementGroups[1])
|
||||
val accountNumber = accountDetails[0]
|
||||
val subAccountAttribute = returnNullIfEmpty(accountDetails[1])
|
||||
val bankCountryCode = accountDetails[2].toInt()
|
||||
val bankCode = accountDetails[3]
|
||||
|
||||
val iban = returnNullIfEmpty(dataElementGroups[2])
|
||||
val customerId = dataElementGroups[3]
|
||||
val accountType = parseCodeEnum(listOf(dataElementGroups[4]), AccountTypeCode.values()).first().type
|
||||
val currency = dataElementGroups[5]
|
||||
val accountHolderName1 = dataElementGroups[6]
|
||||
val accountHolderName2 = returnNullIfEmpty(dataElementGroups[7])
|
||||
val productName = returnNullIfEmpty(dataElementGroups[8])
|
||||
val limit = returnNullIfEmpty(dataElementGroups[9]) // TODO: parse limit
|
||||
|
||||
// TODO: parse allowed jobs
|
||||
// TODO: parse extension
|
||||
|
||||
return AccountInfo(accountNumber, subAccountAttribute, bankCountryCode, bankCode, iban, customerId, accountType,
|
||||
currency, accountHolderName1, accountHolderName2, productName, limit, null, segment)
|
||||
}
|
||||
|
||||
|
||||
protected open fun parseBankDetails(dataElementsGroup: String): Kreditinstitutskennung {
|
||||
val detailsStrings = getDataElements(dataElementsGroup)
|
||||
|
||||
|
@ -119,13 +159,13 @@ open class ResponseParser {
|
|||
protected open fun parseLanguages(dataElementsGroup: String): List<Dialogsprache> {
|
||||
val languageStrings = getDataElements(dataElementsGroup)
|
||||
|
||||
return parseFromCode(languageStrings, Dialogsprache.values())
|
||||
return parseCodeEnum(languageStrings, Dialogsprache.values())
|
||||
}
|
||||
|
||||
protected open fun parseHbciVersions(dataElementsGroup: String): List<HbciVersion> {
|
||||
val versionStrings = getDataElements(dataElementsGroup)
|
||||
|
||||
return parseFromCode(versionStrings, HbciVersion.values())
|
||||
return parseCodeEnum(versionStrings, HbciVersion.values())
|
||||
}
|
||||
|
||||
protected open fun parseSecurityProfiles(dataElementsGroups: List<String>): List<Sicherheitsprofil> {
|
||||
|
@ -141,7 +181,7 @@ open class ResponseParser {
|
|||
}
|
||||
|
||||
protected open fun parseSecurityMethod(methodString: String): Sicherheitsverfahren {
|
||||
return parseFromCode(listOf(methodString), Sicherheitsverfahren.values()).first()
|
||||
return parseCodeEnum(listOf(methodString), Sicherheitsverfahren.values()).first()
|
||||
}
|
||||
|
||||
protected open fun parseSecurityMethodVersion(versionString: String): VersionDesSicherheitsverfahrens {
|
||||
|
@ -150,7 +190,7 @@ open class ResponseParser {
|
|||
return VersionDesSicherheitsverfahrens.values().first { it.methodNumber == versionInt }
|
||||
}
|
||||
|
||||
protected open fun <T : ICodeEnum> parseFromCode(codeValues: List<String>, allValues: Array<T>): List<T> {
|
||||
protected open fun <T : ICodeEnum> parseCodeEnum(codeValues: List<String>, allValues: Array<T>): List<T> {
|
||||
// mapNotNull: don't crash if new, at time of implementation unknown values get introduced / returned by bank
|
||||
return codeValues.mapNotNull { code -> allValues.first { it.code == code } }
|
||||
}
|
||||
|
@ -168,4 +208,8 @@ open class ResponseParser {
|
|||
return false
|
||||
}
|
||||
|
||||
protected open fun returnNullIfEmpty(string: String): String? {
|
||||
return if (string.isEmpty()) null else string
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package net.dankito.fints.response.segments
|
||||
|
||||
|
||||
open class AccountInfo(
|
||||
val accountNumber: String,
|
||||
val subAccountAttribute: String?,
|
||||
val bankCountryCode: Int,
|
||||
val bankCode: String,
|
||||
val iban: String?,
|
||||
val customerId: String,
|
||||
val accountType: AccountType,
|
||||
val currency: String, // TODO: may parse to a value object
|
||||
val accountHolderName1: String,
|
||||
val accountHolderName2: String?,
|
||||
val productName: String?,
|
||||
val accountLimit: String?, // TODO: parse
|
||||
val extension: String?, // TODO: parse
|
||||
|
||||
segmentString: String
|
||||
|
||||
)
|
||||
: ReceivedSegment(segmentString)
|
|
@ -0,0 +1,26 @@
|
|||
package net.dankito.fints.response.segments
|
||||
|
||||
|
||||
enum class AccountType {
|
||||
|
||||
Girokonto,
|
||||
|
||||
Sparkonto,
|
||||
|
||||
Festgeldkonto,
|
||||
|
||||
Wertpapierdepot,
|
||||
|
||||
Darlehenskonto,
|
||||
|
||||
Kreditkartenkonto,
|
||||
|
||||
FondsDepot,
|
||||
|
||||
Bausparvertrag,
|
||||
|
||||
Versicherungsvertrag,
|
||||
|
||||
Sonstige
|
||||
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
package net.dankito.fints.response.segments
|
||||
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||
|
||||
|
||||
/**
|
||||
* Klassifizierung der Konten. Innerhalb der vorgegebenen Codebereiche sind kreditinstitutsindividuell bei Bedarf
|
||||
* weitere Kontoarten möglich.
|
||||
*
|
||||
* Codierung:
|
||||
* - 1 – 9: Kontokorrent-/Girokonto
|
||||
* - 10 – 19: Sparkonto
|
||||
* - 20 –29: Festgeldkonto (Termineinlagen)
|
||||
* - 30 – 39: Wertpapierdepot
|
||||
* - 40 –49: Kredit-/Darlehenskonto
|
||||
* - 50 – 59: Kreditkartenkonto
|
||||
* - 60 – 69: Fonds-Depot bei einer Kapitalanlagegesellschaft
|
||||
* - 70 – 79: Bausparvertrag
|
||||
* - 80 – 89: Versicherungsvertrag
|
||||
* - 90 – 99: Sonstige (nicht zuordenbar)
|
||||
*/
|
||||
enum class AccountTypeCode(override val code: String, val type: AccountType) : ICodeEnum {
|
||||
|
||||
Girokonto_1("1", AccountType.Girokonto),
|
||||
|
||||
Girokonto_2("2", AccountType.Girokonto),
|
||||
|
||||
Girokonto_3("3", AccountType.Girokonto),
|
||||
|
||||
Girokonto_4("4", AccountType.Girokonto),
|
||||
|
||||
Girokonto_5("5", AccountType.Girokonto),
|
||||
|
||||
Girokonto_6("6", AccountType.Girokonto),
|
||||
|
||||
Girokonto_7("7", AccountType.Girokonto),
|
||||
|
||||
Girokonto_8("8", AccountType.Girokonto),
|
||||
|
||||
Girokonto_9("9", AccountType.Girokonto),
|
||||
|
||||
Sparkonto_1("10", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_2("11", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_3("12", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_4("13", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_5("14", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_6("15", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_7("16", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_8("17", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_9("18", AccountType.Sparkonto),
|
||||
|
||||
Sparkonto_10("19", AccountType.Sparkonto),
|
||||
|
||||
Festgeldkonto_1("20", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_2("21", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_3("22", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_4("23", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_5("24", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_6("25", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_7("26", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_8("27", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_9("28", AccountType.Festgeldkonto),
|
||||
|
||||
Festgeldkonto_10("29", AccountType.Festgeldkonto),
|
||||
|
||||
Wertpapierdepot_1("30", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_2("31", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_3("32", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_4("33", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_5("34", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_6("35", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_7("36", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_8("37", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_9("38", AccountType.Wertpapierdepot),
|
||||
|
||||
Wertpapierdepot_10("39", AccountType.Wertpapierdepot),
|
||||
|
||||
Darlehenskonto_1("40", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_2("41", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_3("42", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_4("43", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_5("44", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_6("45", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_7("46", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_8("47", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_9("48", AccountType.Darlehenskonto),
|
||||
|
||||
Darlehenskonto_10("49", AccountType.Darlehenskonto),
|
||||
|
||||
Kreditkartenkonto_1("50", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_2("51", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_3("52", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_4("53", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_5("54", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_6("55", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_7("56", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_8("57", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_9("58", AccountType.Kreditkartenkonto),
|
||||
|
||||
Kreditkartenkonto_10("59", AccountType.Kreditkartenkonto),
|
||||
|
||||
FondsDepot_1("60", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_2("61", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_3("62", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_4("63", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_5("64", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_6("65", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_7("66", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_8("67", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_9("68", AccountType.FondsDepot),
|
||||
|
||||
FondsDepot_10("69", AccountType.FondsDepot),
|
||||
|
||||
Bausparvertrag_1("70", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_2("71", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_3("72", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_4("73", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_5("74", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_6("75", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_7("76", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_8("77", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_9("78", AccountType.Bausparvertrag),
|
||||
|
||||
Bausparvertrag_10("79", AccountType.Bausparvertrag),
|
||||
|
||||
Versicherungsvertrag_1("80", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_2("81", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_3("82", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_4("83", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_5("84", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_6("85", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_7("86", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_8("87", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_9("88", AccountType.Versicherungsvertrag),
|
||||
|
||||
Versicherungsvertrag_10("89", AccountType.Versicherungsvertrag),
|
||||
|
||||
Sonstige_1("90", AccountType.Sonstige),
|
||||
|
||||
Sonstige_2("91", AccountType.Sonstige),
|
||||
|
||||
Sonstige_3("92", AccountType.Sonstige),
|
||||
|
||||
Sonstige_4("93", AccountType.Sonstige),
|
||||
|
||||
Sonstige_5("94", AccountType.Sonstige),
|
||||
|
||||
Sonstige_6("95", AccountType.Sonstige),
|
||||
|
||||
Sonstige_7("96", AccountType.Sonstige),
|
||||
|
||||
Sonstige_8("97", AccountType.Sonstige),
|
||||
|
||||
Sonstige_9("98", AccountType.Sonstige),
|
||||
|
||||
Sonstige_10("99", AccountType.Sonstige)
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package net.dankito.fints.response.segments
|
||||
|
||||
|
||||
open class UserParameters(
|
||||
val userIdentifier: String,
|
||||
|
||||
/**
|
||||
* Antwortet ein Kreditinstitut auf das Kundensegment HKVVB und der UPD-Version=0 im Segment HIUPA ebenfalls mit
|
||||
* einer UPD-Version=0, so müssen im aktuellen Dialog diese übermittelten UPD verwendet werden; die UPD sind dann
|
||||
* nur für diesen Dialog gültig.
|
||||
*/
|
||||
val updVersion: Int,
|
||||
val areListedJobsBlocked: Boolean,
|
||||
val username: String? = null,
|
||||
|
||||
/**
|
||||
* Die innere Struktur dieses Parameterfeldes ist nicht weiter spezifiziert und kann von den Partnern bilateral
|
||||
* verwendet werden. Zur Selektion dieses neuen Datenelementes muss HKVVB (Verarbeitungsvorbereitung) mindestens
|
||||
* in der Segmentversion 3 gesendet werden.
|
||||
*/
|
||||
val extension: String? = null,
|
||||
segmentString: String
|
||||
|
||||
)
|
||||
: ReceivedSegment(segmentString)
|
|
@ -7,10 +7,7 @@ import net.dankito.fints.messages.datenelemente.implementierte.signatur.VersionD
|
|||
import net.dankito.fints.messages.datenelementgruppen.implementierte.signatur.Sicherheitsprofil
|
||||
import net.dankito.fints.messages.segmente.id.ISegmentId
|
||||
import net.dankito.fints.messages.segmente.id.MessageSegmentId
|
||||
import net.dankito.fints.response.segments.BankParameters
|
||||
import net.dankito.fints.response.segments.ReceivedMessageHeader
|
||||
import net.dankito.fints.response.segments.ReceivedSynchronization
|
||||
import net.dankito.fints.response.segments.SecurityMethods
|
||||
import net.dankito.fints.response.segments.*
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
@ -82,7 +79,6 @@ class ResponseParserTest {
|
|||
?: run { Assert.fail("No segment of type BankParameters found in ${result.receivedSegments}") }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun parseSecurityMethods() {
|
||||
|
||||
|
@ -107,6 +103,53 @@ class ResponseParserTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun parseUserParameters() {
|
||||
|
||||
// when
|
||||
val result = underTest.parse("HIUPA:6:4:4+3498443795+34+0++PERSNR0010789316542'")
|
||||
|
||||
// then
|
||||
assertSuccessfullyParsedSegment(result, InstituteSegmentId.UserParameters, 6, 4, 4)
|
||||
|
||||
result.getFirstSegmentById<UserParameters>(InstituteSegmentId.UserParameters)?.let { segment ->
|
||||
assertThat(segment.userIdentifier).isEqualTo("3498443795")
|
||||
assertThat(segment.updVersion).isEqualTo(34)
|
||||
assertThat(segment.areListedJobsBlocked).isTrue()
|
||||
assertThat(segment.username).isNull()
|
||||
assertThat(segment.extension).isEqualTo("PERSNR0010789316542")
|
||||
}
|
||||
?: run { Assert.fail("No segment of type UserParameters found in ${result.receivedSegments}") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parseAccountInfo() {
|
||||
|
||||
// when
|
||||
val result = underTest.parse("HIUPD:7:6:4+0987654321::280:12345678+DE11123456780987654321+2197654321+1+EUR+Hans Dampf++Sichteinlagen++HKSAK:1+HKISA:1+HKSSP:1+HKPAE:1+HKTSY:1+HKTAB:1+HKTAU:1+HKTAZ:1+HKSPA:1+HKPKA:1+HKPKB:1+HKPWE:1+HKPWA:1+HKPWB:1+HKPWL:1+HKCAZ:1+HKCCM:1+HKCCS:1+HKCDB:1+HKCDE:1+HKCDL:1+HKCDN:1+HKCDU:1+HKCMB:1+HKCME:1+HKCML:1+HKCSA:1+HKCSB:1+HKCSE:1+HKCSL:1+HKCUB:1+HKCUM:1+HKDSB:1+HKDSW:1+HKIPS:1+HKIPZ:1+HKPCR:1+HKPPD:1+DKPSA:1+DKPSP:1+HKTAN:1+DKANA:1+DKANL:1+DKKBA:1+DKDKL:1+DKBDK:1+DKBAZ:1+DKTCK:1+DKZDF:1+DKZDL:1+HKFRD:1+HKKDM:1+HKKAZ:1+HKKIF:1+HKSAL:1+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++{\n" +
|
||||
"umsltzt\n" +
|
||||
"?:'")
|
||||
|
||||
// then
|
||||
assertSuccessfullyParsedSegment(result, InstituteSegmentId.AccountInfo, 7, 6, 4)
|
||||
|
||||
result.getFirstSegmentById<AccountInfo>(InstituteSegmentId.AccountInfo)?.let { segment ->
|
||||
assertThat(segment.accountNumber).isEqualTo("0987654321")
|
||||
assertThat(segment.subAccountAttribute).isNull()
|
||||
assertThat(segment.bankCountryCode).isEqualTo(280)
|
||||
assertThat(segment.bankCode).isEqualTo("12345678")
|
||||
assertThat(segment.iban).isEqualTo("DE11123456780987654321")
|
||||
assertThat(segment.customerId).isEqualTo("2197654321")
|
||||
assertThat(segment.accountType).isEqualTo(AccountType.Girokonto)
|
||||
assertThat(segment.currency).isEqualTo("EUR")
|
||||
assertThat(segment.accountHolderName1).isEqualTo("Hans Dampf")
|
||||
assertThat(segment.accountHolderName2).isNull()
|
||||
assertThat(segment.productName).isEqualTo("Sichteinlagen")
|
||||
}
|
||||
?: run { Assert.fail("No segment of type AccountInfo found in ${result.receivedSegments}") }
|
||||
}
|
||||
|
||||
|
||||
private fun assertSuccessfullyParsedSegment(result: Response, segmentId: ISegmentId, segmentNumber: Int,
|
||||
segmentVersion: Int, referenceSegmentNumber: Int? = null) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue