From 414295adbc7e083d98bbaf970eda0334055d98ac Mon Sep 17 00:00:00 2001 From: dankito Date: Mon, 9 Sep 2024 02:05:04 +0200 Subject: [PATCH] Implemented persisting TanMedia --- .../dataaccess/SqliteBankingRepository.kt | 64 +++++++++++++++++-- .../dataaccess/entities/TanMediumEntity.kt | 20 ++++++ .../banking/dataaccess/entities/UserEntity.kt | 4 +- .../sqldelight/net/codinux/banking/ui/User.sq | 64 +++++++++++++++++++ 4 files changed, 144 insertions(+), 8 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/entities/TanMediumEntity.kt diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/SqliteBankingRepository.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/SqliteBankingRepository.kt index c82e514..1b580e8 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/SqliteBankingRepository.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/SqliteBankingRepository.kt @@ -4,12 +4,9 @@ import app.cash.sqldelight.db.SqlDriver import kotlinx.datetime.Instant import kotlinx.datetime.LocalDate import net.codinux.banking.client.model.* -import net.codinux.banking.client.model.tan.AllowedTanFormat -import net.codinux.banking.client.model.tan.TanMethod -import net.codinux.banking.client.model.tan.TanMethodType +import net.codinux.banking.client.model.tan.* import net.codinux.banking.dataaccess.entities.* import net.codinux.banking.ui.model.AccountTransactionViewModel -import net.codinux.log.Log import net.codinux.log.logger import kotlin.enums.EnumEntries import kotlin.js.JsName @@ -31,9 +28,10 @@ open class SqliteBankingRepository( override fun getAllUsers(): List { val bankAccounts = getAllBankAccounts().groupBy { it.userId } val tanMethods = getAllTanMethods().groupBy { it.userId } + val tanMedia = getAllTanMedia().groupBy { it.userId } return userQueries.selectAllUsers { id, bankCode, loginName, password, bankName, bic, customerName, userId, selectedTanMethodIdentifier, selectedTanMediumIdentifier, bankingGroup, serverAddress, userSetDisplayName, displayIndex, iconUrl, wrongCredentialsEntered -> - UserEntity(id, bankCode, loginName, password, bankName, bic, customerName, userId, bankAccounts[id] ?: emptyList(), selectedTanMethodIdentifier, tanMethods[id] ?: emptyList(), selectedTanMediumIdentifier, emptyList(), + UserEntity(id, bankCode, loginName, password, bankName, bic, customerName, userId, bankAccounts[id] ?: emptyList(), selectedTanMethodIdentifier, tanMethods[id] ?: emptyList(), selectedTanMediumIdentifier, tanMedia[id] ?: emptyList(), bankingGroup?.let { BankingGroup.valueOf(it) }, serverAddress, userSetDisplayName, displayIndex.toInt(), iconUrl, wrongCredentialsEntered) }.executeAsList() } @@ -50,8 +48,9 @@ open class SqliteBankingRepository( val bankAccounts = persistBankAccounts(userId, user.accounts) val tanMethods = persistTanMethods(userId, user.tanMethods) + val tanMedia = persistTanMedia(userId, user.tanMedia) - UserEntity(userId, user, bankAccounts, tanMethods) + UserEntity(userId, user, bankAccounts, tanMethods, tanMedia) } } @@ -144,6 +143,59 @@ open class SqliteBankingRepository( } + private fun getAllTanMedia(): List = userQueries.selectAllTanMedia { id, userId, type, mediumName, status, phoneNumber, concealedPhoneNumber, cardNumber, cardSequenceNumber, cardType, validFrom, validTo -> + val mobilePhone = if (phoneNumber != null || concealedPhoneNumber != null) { + MobilePhoneTanMedium(phoneNumber, concealedPhoneNumber) + } else { + null + } + + val tanGenerator = if (cardNumber != null) { + TanGeneratorTanMedium(cardNumber, cardSequenceNumber, mapToInt(cardType), mapToDate(validFrom), mapToDate(validTo)) + } else { + null + } + + TanMediumEntity( + id, + userId, + + mapToEnum(type, TanMediumType.entries), + mediumName, + mapToEnum(status, TanMediumStatus.entries), + + tanGenerator, + mobilePhone + ) + }.executeAsList() + + private suspend fun persistTanMedia(userId: Long, tanMedia: List): List = + tanMedia.map { persistTanMedium(userId, it) } + + private suspend fun persistTanMedium(userId: Long, medium: TanMedium): TanMediumEntity { + userQueries.insertTanMedium( + userId, + + mapEnum(medium.type), + medium.mediumName, + mapEnum(medium.status), + + medium.mobilePhone?.phoneNumber, + medium.mobilePhone?.concealedPhoneNumber, + + medium.tanGenerator?.cardNumber, + medium.tanGenerator?.cardSequenceNumber, + mapInt(medium.tanGenerator?.cardType), + mapDate(medium.tanGenerator?.validFrom), + mapDate(medium.tanGenerator?.validTo) + ) + + val tanMediumId = getLastInsertedId() + + return TanMediumEntity(tanMediumId, userId, medium) + } + + override fun getAllAccountTransactionsAsViewModel(): List = accountTransactionQueries.selectAllTransactionsAsViewModel { id, userId, bankAccountId, amount, currency, reference, valueDate, otherPartyName, postingText, userSetDisplayName, category -> AccountTransactionViewModel(id, userId, bankAccountId, mapToAmount(amount), currency, reference, mapToDate(valueDate), otherPartyName, postingText, userSetDisplayName, category) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/entities/TanMediumEntity.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/entities/TanMediumEntity.kt new file mode 100644 index 0000000..d6c01b8 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/entities/TanMediumEntity.kt @@ -0,0 +1,20 @@ +package net.codinux.banking.dataaccess.entities + +import net.codinux.banking.client.model.tan.* + +class TanMediumEntity( + val id: Long, + val userId: Long, + + type: TanMediumType, + mediumName: String?, + status: TanMediumStatus, + + tanGenerator: TanGeneratorTanMedium? = null, + mobilePhone: MobilePhoneTanMedium? = null +) : TanMedium(type, mediumName, status, tanGenerator, mobilePhone) { + + constructor(id: Long, userId: Long, medium: TanMedium) + : this(id, userId, medium.type, medium.mediumName, medium.status, medium.tanGenerator, medium.mobilePhone) + +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/entities/UserEntity.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/entities/UserEntity.kt index a254d6b..7a90944 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/entities/UserEntity.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/entities/UserEntity.kt @@ -45,11 +45,11 @@ class UserEntity( } - constructor(id: Long, user: User, bankAccounts: List, tanMethods: List) : this( + constructor(id: Long, user: User, bankAccounts: List, tanMethods: List, tanMedia: List) : this( id, user.bankCode, user.loginName, user.password, user.bankName, user.bic, user.customerName, user.userId, bankAccounts, - user.selectedTanMethodIdentifier, tanMethods, user.selectedTanMediumIdentifier, user.tanMedia, + user.selectedTanMethodIdentifier, tanMethods, user.selectedTanMediumIdentifier, tanMedia, user.bankingGroup, user.serverAddress, user.userSetDisplayName, user.displayIndex, user.iconUrl, user.wrongCredentialsEntered, diff --git a/composeApp/src/commonMain/sqldelight/net/codinux/banking/ui/User.sq b/composeApp/src/commonMain/sqldelight/net/codinux/banking/ui/User.sq index ddd519b..ef9b881 100644 --- a/composeApp/src/commonMain/sqldelight/net/codinux/banking/ui/User.sq +++ b/composeApp/src/commonMain/sqldelight/net/codinux/banking/ui/User.sq @@ -181,6 +181,70 @@ SELECT TanMethod.* FROM TanMethod; + +CREATE TABLE IF NOT EXISTS TanMedium ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + userId INTEGER NOT NULL, + + type TEXT NOT NULL, + mediumName TEXT, + status TEXT NOT NULL, + + -- MobilePhone TanMedium + phoneNumber TEXT, + concealedPhoneNumber TEXT, + + -- TanGenerator TanMedium + cardNumber TEXT, + cardSequenceNumber TEXT, + cardType INTEGER, + validFrom TEXT, + validTo TEXT +); + + +insertTanMedium: +INSERT INTO TanMedium( + userId, + + type, + mediumName, + status, + + phoneNumber, + concealedPhoneNumber, + + cardNumber, + cardSequenceNumber, + cardType, + validFrom, + validTo +) +VALUES ( + ?, + + ?, + ?, + ?, + + ?, + ?, + + ?, + ?, + ?, + ?, + ? +); + + +selectAllTanMedia: +SELECT TanMedium.* +FROM TanMedium; + + + -- TODO: find a better place for this cross-cutting concern: getLastInsertedId: SELECT last_insert_rowid();