From a9ebad0793b64b19a79ea5434e64b0725c1bd562 Mon Sep 17 00:00:00 2001 From: dankito Date: Tue, 3 Sep 2024 22:21:42 +0200 Subject: [PATCH] Fixed identifying TAN media as e.g. Sparkasse named all their TanGenerator media "SparkassenCard (Debitkarte)" - so it was not possible to differentiate between them --- .../client/model/tan/TanGeneratorTanMedium.kt | 4 ++ .../banking/client/model/tan/TanMedium.kt | 44 +++++++++++++++++++ .../banking/client/fints4k/FinTs4kMapper.kt | 3 +- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/BankingClientModel/src/commonMain/kotlin/net/codinux/banking/client/model/tan/TanGeneratorTanMedium.kt b/BankingClientModel/src/commonMain/kotlin/net/codinux/banking/client/model/tan/TanGeneratorTanMedium.kt index 6fff2ccf..e69c71d8 100644 --- a/BankingClientModel/src/commonMain/kotlin/net/codinux/banking/client/model/tan/TanGeneratorTanMedium.kt +++ b/BankingClientModel/src/commonMain/kotlin/net/codinux/banking/client/model/tan/TanGeneratorTanMedium.kt @@ -4,6 +4,10 @@ import kotlinx.datetime.LocalDate import net.codinux.banking.client.model.config.NoArgConstructor @NoArgConstructor +/** + * 'TanGenerator' is in most cases a debit card, but can also be something like "BestSign" app (Postbank). + * In latter case [cardNumber] can also be, contrary to specification, be an empty string. + */ open class TanGeneratorTanMedium( val cardNumber: String, val cardSequenceNumber: String? = null, diff --git a/BankingClientModel/src/commonMain/kotlin/net/codinux/banking/client/model/tan/TanMedium.kt b/BankingClientModel/src/commonMain/kotlin/net/codinux/banking/client/model/tan/TanMedium.kt index 9d182ff9..c1d32e02 100644 --- a/BankingClientModel/src/commonMain/kotlin/net/codinux/banking/client/model/tan/TanMedium.kt +++ b/BankingClientModel/src/commonMain/kotlin/net/codinux/banking/client/model/tan/TanMedium.kt @@ -16,5 +16,49 @@ open class TanMedium( */ val mobilePhone: MobilePhoneTanMedium? = null ) { + + /** + * Using only [mediumName] as identifier does not work as e.g. Sparkasse names all their TanGenerator TAN media + * "SparkassenCard (Debitkarte)" - so it's not possible to differentiate between them solely by medium name. + */ + val identifier: String by lazy { + // TODO: translate + var id = mediumName ?: when (type) { + TanMediumType.MobilePhone -> "Mobiltelefon" + TanMediumType.TanGenerator -> "Tan Generator" + TanMediumType.Generic -> "Unbenanntes TAN Medium" + } + + if (mobilePhone != null) { + id += " " + (mobilePhone.concealedPhoneNumber ?: mobilePhone.phoneNumber) + } + if (tanGenerator != null) { + if (tanGenerator.cardNumber.isNotBlank()) { + id += " " + tanGenerator.cardNumber + } + if (tanGenerator.cardSequenceNumber.isNullOrBlank() == false) { + id += " " + tanGenerator.cardSequenceNumber + } + + if (tanGenerator.validFrom != null && tanGenerator.validTo != null) { + id += ", gültig von " + tanGenerator.validFrom.let { "${it.dayOfMonth}.${it.monthNumber}${it.year}" } + + " - " + tanGenerator.validTo.let { "${it.dayOfMonth}.${it.monthNumber}${it.year}" } + } else if (tanGenerator.validTo != null) { + id += ", gültig bis " + tanGenerator.validTo.let { "${it.dayOfMonth}.${it.monthNumber}${it.year}" } + } + } + + id + } + + val displayName: String by lazy { + identifier + " " + when (status) { + TanMediumStatus.Used -> "Aktive" + TanMediumStatus.Available -> "Verfügbar" + TanMediumStatus.ActiveFollowUpCard -> " Folgekarte, aktiv bei erster Nutzung" + TanMediumStatus.AvailableFollowUpCard -> " Folgekarte, die erst aktiviert werden muss" + } + } + override fun toString() = "$mediumName $status" } \ No newline at end of file diff --git a/FinTs4jBankingClient/src/commonMain/kotlin/net/codinux/banking/client/fints4k/FinTs4kMapper.kt b/FinTs4jBankingClient/src/commonMain/kotlin/net/codinux/banking/client/fints4k/FinTs4kMapper.kt index 1ff6e8d8..5bfa9e73 100644 --- a/FinTs4jBankingClient/src/commonMain/kotlin/net/codinux/banking/client/fints4k/FinTs4kMapper.kt +++ b/FinTs4jBankingClient/src/commonMain/kotlin/net/codinux/banking/client/fints4k/FinTs4kMapper.kt @@ -191,7 +191,8 @@ open class FinTs4kMapper { val selectedTanMethodId = challenge.tanMethod.securityFunction.code val tanMedia = challenge.bank.tanMedia.map { mapTanMedium(it) } - val selectedTanMediumName = challenge.bank.selectedTanMedium?.mediumName + // TanMedium has not natural id in FinTS model so we have to create our own one + val selectedTanMediumName = challenge.bank.selectedTanMedium?.let { selected -> tanMedia.firstOrNull { it == selected } }?.identifier val user = mapToUserAccountViewInfo(challenge.bank) val account = challenge.account?.let { mapToBankAccountViewInfo(it) }