diff --git a/BankingUiCommon/src/main/java/net/dankito/banking/ui/model/tan/MobilePhoneTanMedium.kt b/BankingUiCommon/src/main/java/net/dankito/banking/ui/model/tan/MobilePhoneTanMedium.kt new file mode 100644 index 00000000..73d4ed28 --- /dev/null +++ b/BankingUiCommon/src/main/java/net/dankito/banking/ui/model/tan/MobilePhoneTanMedium.kt @@ -0,0 +1,15 @@ +package net.dankito.banking.ui.model.tan + + +open class MobilePhoneTanMedium( + displayName: String, + status: TanMediumStatus, + val phoneNumber: String? + +) : TanMedium(displayName, status) { + + override fun toString(): String { + return "$displayName $status" + } + +} \ No newline at end of file diff --git a/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/dialogs/EnterTanDialog.kt b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/dialogs/EnterTanDialog.kt index ae2621c7..b09d63e8 100644 --- a/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/dialogs/EnterTanDialog.kt +++ b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/dialogs/EnterTanDialog.kt @@ -119,6 +119,7 @@ open class EnterTanDialog : DialogFragment() { rootView.spnTanMedium.adapter = tanMediumAdapter rootView.spnTanMedium.onItemSelectedListener = ListItemSelectedListener(tanMediumAdapter) { selectedTanMedium -> + // TODO: implement logic to change a mobile phone as TAN medium if (selectedTanMedium.status != TanMediumStatus.Used) { (selectedTanMedium as? TanGeneratorTanMedium)?.let { tanGeneratorTanMedium -> tanEnteredCallback(EnterTanResult.userAsksToChangeTanMedium(tanGeneratorTanMedium) { response -> diff --git a/fints4javaBankingClient/src/main/kotlin/net/dankito/banking/mapper/fints4javaModelMapper.kt b/fints4javaBankingClient/src/main/kotlin/net/dankito/banking/mapper/fints4javaModelMapper.kt index fcd37bd3..e1f14ce8 100644 --- a/fints4javaBankingClient/src/main/kotlin/net/dankito/banking/mapper/fints4javaModelMapper.kt +++ b/fints4javaBankingClient/src/main/kotlin/net/dankito/banking/mapper/fints4javaModelMapper.kt @@ -240,6 +240,10 @@ open class fints4javaModelMapper { return mapTanMedium(tanMedium) } + if (tanMedium is net.dankito.fints.messages.datenelemente.implementierte.tan.MobilePhoneTanMedium) { + return mapTanMedium(tanMedium) + } + return TanMedium( getDisplayNameForTanMedium(tanMedium), mapTanMediumStatus(tanMedium) @@ -254,6 +258,14 @@ open class fints4javaModelMapper { ) } + open fun mapTanMedium(tanMedium: net.dankito.fints.messages.datenelemente.implementierte.tan.MobilePhoneTanMedium): MobilePhoneTanMedium { + return MobilePhoneTanMedium( + getDisplayNameForTanMedium(tanMedium), + mapTanMediumStatus(tanMedium), + tanMedium.phoneNumber ?: tanMedium.concealedPhoneNumber + ) + } + protected open fun getDisplayNameForTanMedium(tanMedium: net.dankito.fints.messages.datenelemente.implementierte.tan.TanMedium): String { if (tanMedium is net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium) { var cardNumber = tanMedium.cardNumber @@ -261,12 +273,21 @@ open class fints4javaModelMapper { cardNumber += " (Kartenfolgenummer $it)" // TODO: translate } - tanMedium.mediaName?.let { mediaName -> + tanMedium.mediumName?.let { mediaName -> return "$mediaName $cardNumber" } return "Karte $cardNumber" // TODO: translate } + else if (tanMedium is net.dankito.fints.messages.datenelemente.implementierte.tan.MobilePhoneTanMedium) { + val mediumName = tanMedium.mediumName + + (tanMedium.phoneNumber ?: tanMedium.concealedPhoneNumber)?.let { phoneNumber -> + return "$mediumName ($phoneNumber)" + } + + return mediumName + } return tanMedium.mediumClass.name } diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/datenelemente/implementierte/tan/MobilePhoneTanMedium.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/datenelemente/implementierte/tan/MobilePhoneTanMedium.kt new file mode 100644 index 00000000..d9bf2941 --- /dev/null +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/datenelemente/implementierte/tan/MobilePhoneTanMedium.kt @@ -0,0 +1,43 @@ +package net.dankito.fints.messages.datenelemente.implementierte.tan + +import net.dankito.fints.messages.datenelementgruppen.implementierte.account.KontoverbindungInternational + + +open class MobilePhoneTanMedium( + mediumClass: TanMediumKlasse, + status: TanMediumStatus, + val mediumName: String, + val concealedPhoneNumber: String?, + val phoneNumber: String?, + val smsDebitAccount: KontoverbindungInternational? = null +) : TanMedium(mediumClass, status) { + + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is MobilePhoneTanMedium) return false + if (!super.equals(other)) return false + + if (mediumName != other.mediumName) return false + if (concealedPhoneNumber != other.concealedPhoneNumber) return false + if (phoneNumber != other.phoneNumber) return false + if (smsDebitAccount != other.smsDebitAccount) return false + + return true + } + + override fun hashCode(): Int { + var result = super.hashCode() + result = 31 * result + (mediumName.hashCode()) + result = 31 * result + (concealedPhoneNumber?.hashCode() ?: 0) + result = 31 * result + (phoneNumber?.hashCode() ?: 0) + result = 31 * result + (smsDebitAccount?.hashCode() ?: 0) + return result + } + + + override fun toString(): String { + return super.toString() + " $mediumName ${phoneNumber ?: concealedPhoneNumber ?: ""}" + } + +} \ No newline at end of file diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/datenelemente/implementierte/tan/TanGeneratorTanMedium.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/datenelemente/implementierte/tan/TanGeneratorTanMedium.kt index 1f3391b1..f0f2c138 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/datenelemente/implementierte/tan/TanGeneratorTanMedium.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/datenelemente/implementierte/tan/TanGeneratorTanMedium.kt @@ -11,7 +11,7 @@ open class TanGeneratorTanMedium( val cardType: Int?, val validFrom: Date?, val validTo: Date?, - val mediaName: String? + val mediumName: String? ) : TanMedium(mediumClass, status) { @@ -27,7 +27,7 @@ open class TanGeneratorTanMedium( if (cardType != other.cardType) return false if (validFrom != other.validFrom) return false if (validTo != other.validTo) return false - if (mediaName != other.mediaName) return false + if (mediumName != other.mediumName) return false return true } @@ -39,13 +39,13 @@ open class TanGeneratorTanMedium( result = 31 * result + (cardType?.hashCode() ?: 0) result = 31 * result + (validFrom?.hashCode() ?: 0) result = 31 * result + (validTo?.hashCode() ?: 0) - result = 31 * result + (mediaName?.hashCode() ?: 0) + result = 31 * result + (mediumName?.hashCode() ?: 0) return result } override fun toString(): String { - return super.toString() + " $mediaName $cardNumber (card sequence number: ${cardSequenceNumber ?: "-"})" + return super.toString() + " $mediumName $cardNumber (card sequence number: ${cardSequenceNumber ?: "-"})" } } \ No newline at end of file diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/response/ResponseParser.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/response/ResponseParser.kt index f1909988..f86fa3b6 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/response/ResponseParser.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/response/ResponseParser.kt @@ -11,6 +11,7 @@ import net.dankito.fints.messages.datenelemente.implementierte.signatur.Sicherhe import net.dankito.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens import net.dankito.fints.messages.datenelemente.implementierte.tan.* import net.dankito.fints.messages.datenelementgruppen.implementierte.Kreditinstitutskennung +import net.dankito.fints.messages.datenelementgruppen.implementierte.account.KontoverbindungInternational import net.dankito.fints.messages.datenelementgruppen.implementierte.signatur.Sicherheitsprofil import net.dankito.fints.messages.segmente.id.MessageSegmentId import net.dankito.fints.response.segments.* @@ -490,6 +491,7 @@ open class ResponseParser @JvmOverloads constructor( return when (mediumClass) { TanMediumKlasse.TanGenerator -> parseTanGeneratorTanMedium(mediumClass, status, hitabVersion, remainingDataElements) + TanMediumKlasse.MobiltelefonMitMobileTan -> parseMobilePhoneTanMedium(mediumClass, status, hitabVersion, remainingDataElements) else -> TanMedium(mediumClass, status) } } @@ -501,10 +503,21 @@ open class ResponseParser @JvmOverloads constructor( // TODO: may also parse account info val validFrom = if (hitabVersion < 2) null else parseNullableDate(dataElements[8]) val validTo = if (hitabVersion < 2) null else parseNullableDate(dataElements[9]) - val mediaName = if (hitabVersion < 2) null else parseStringToNullIfEmpty(dataElements[10]) + val mediumName = if (hitabVersion < 2) null else parseStringToNullIfEmpty(dataElements[10]) return TanGeneratorTanMedium(mediumClass, status, parseString(dataElements[0]), parseStringToNullIfEmpty(dataElements[1]), - cardType, validFrom, validTo, mediaName) + cardType, validFrom, validTo, mediumName) + } + + protected open fun parseMobilePhoneTanMedium(mediumClass: TanMediumKlasse, status: TanMediumStatus, + hitabVersion: Int, dataElements: List): MobilePhoneTanMedium { + + val mediumName = parseString(dataElements[10]) + val concealedPhoneNumber = if (hitabVersion < 2) null else parseStringToNullIfEmpty(dataElements[11]) + val phoneNumber = if (hitabVersion < 2) null else parseStringToNullIfEmpty(dataElements[12]) + val smsDebitAccount: KontoverbindungInternational? = null // TODO: may parse 13th data element to KontoverbindungInternational + + return MobilePhoneTanMedium(mediumClass, status, mediumName, concealedPhoneNumber, phoneNumber, smsDebitAccount) }