Implemented persisting TanMethods
This commit is contained in:
parent
a2dbe912d4
commit
0fff3f2c97
|
@ -4,10 +4,12 @@ import app.cash.sqldelight.db.SqlDriver
|
||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
import kotlinx.datetime.LocalDate
|
import kotlinx.datetime.LocalDate
|
||||||
import net.codinux.banking.client.model.*
|
import net.codinux.banking.client.model.*
|
||||||
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
import net.codinux.banking.client.model.tan.AllowedTanFormat
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.client.model.tan.TanMethod
|
||||||
import net.codinux.banking.dataaccess.entities.UserEntity
|
import net.codinux.banking.client.model.tan.TanMethodType
|
||||||
|
import net.codinux.banking.dataaccess.entities.*
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
|
import net.codinux.log.Log
|
||||||
import net.codinux.log.logger
|
import net.codinux.log.logger
|
||||||
import kotlin.enums.EnumEntries
|
import kotlin.enums.EnumEntries
|
||||||
import kotlin.js.JsName
|
import kotlin.js.JsName
|
||||||
|
@ -28,9 +30,10 @@ open class SqliteBankingRepository(
|
||||||
|
|
||||||
override fun getAllUsers(): List<UserEntity> {
|
override fun getAllUsers(): List<UserEntity> {
|
||||||
val bankAccounts = getAllBankAccounts().groupBy { it.userId }
|
val bankAccounts = getAllBankAccounts().groupBy { it.userId }
|
||||||
|
val tanMethods = getAllTanMethods().groupBy { it.userId }
|
||||||
|
|
||||||
return userQueries.selectAllUsers { id, bankCode, loginName, password, bankName, bic, customerName, userId, selectedTanMethodIdentifier, selectedTanMediumIdentifier, bankingGroup, serverAddress, userSetDisplayName, displayIndex, iconUrl, wrongCredentialsEntered ->
|
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, emptyList(), selectedTanMediumIdentifier, emptyList(),
|
UserEntity(id, bankCode, loginName, password, bankName, bic, customerName, userId, bankAccounts[id] ?: emptyList(), selectedTanMethodIdentifier, tanMethods[id] ?: emptyList(), selectedTanMediumIdentifier, emptyList(),
|
||||||
bankingGroup?.let { BankingGroup.valueOf(it) }, serverAddress, userSetDisplayName, displayIndex.toInt(), iconUrl, wrongCredentialsEntered)
|
bankingGroup?.let { BankingGroup.valueOf(it) }, serverAddress, userSetDisplayName, displayIndex.toInt(), iconUrl, wrongCredentialsEntered)
|
||||||
}.executeAsList()
|
}.executeAsList()
|
||||||
}
|
}
|
||||||
|
@ -46,12 +49,13 @@ open class SqliteBankingRepository(
|
||||||
|
|
||||||
val bankAccounts = persistBankAccounts(userId, user.accounts)
|
val bankAccounts = persistBankAccounts(userId, user.accounts)
|
||||||
|
|
||||||
UserEntity(userId, user, bankAccounts)
|
val tanMethods = persistTanMethods(userId, user.tanMethods)
|
||||||
|
|
||||||
|
UserEntity(userId, user, bankAccounts, tanMethods)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun getAllBankAccounts(): List<BankAccountEntity> = userQueries.selectAllBankAccounts { id, userId, identifier, subAccountNumber, iban, productName, accountHolderName, type, currency, accountLimit, isAccountTypeSupportedByApplication, features, balance, serverTransactionsRetentionDays, lastTransactionsRetrievalTime, retrievedTransactionsFrom, userSetDisplayName, displayIndex, hideAccount, includeInAutomaticAccountsUpdate ->
|
fun getAllBankAccounts(): List<BankAccountEntity> = userQueries.selectAllBankAccounts { id, userId, identifier, subAccountNumber, iban, productName, accountHolderName, type, currency, accountLimit, isAccountTypeSupportedByApplication, features, balance, serverTransactionsRetentionDays, lastTransactionsRetrievalTime, retrievedTransactionsFrom, userSetDisplayName, displayIndex, hideAccount, includeInAutomaticAccountsUpdate ->
|
||||||
BankAccountEntity(
|
BankAccountEntity(
|
||||||
id, userId,
|
id, userId,
|
||||||
|
@ -107,6 +111,39 @@ open class SqliteBankingRepository(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getAllTanMethods(): List<TanMethodEntity> = userQueries.selectAllTanMethods { id, userId, displayName, type, identifier, maxTanInputLength, allowedTanFormat ->
|
||||||
|
TanMethodEntity(
|
||||||
|
id,
|
||||||
|
userId,
|
||||||
|
|
||||||
|
displayName,
|
||||||
|
mapToEnum(type, TanMethodType.entries),
|
||||||
|
identifier,
|
||||||
|
mapToInt(maxTanInputLength),
|
||||||
|
mapToEnum(allowedTanFormat, AllowedTanFormat.entries)
|
||||||
|
)
|
||||||
|
}.executeAsList()
|
||||||
|
|
||||||
|
private suspend fun persistTanMethods(userId: Long, tanMethods: List<TanMethod>): List<TanMethodEntity> =
|
||||||
|
tanMethods.map { persistTanMethod(userId, it) }
|
||||||
|
|
||||||
|
private suspend fun persistTanMethod(userId: Long, tanMethod: TanMethod): TanMethodEntity {
|
||||||
|
userQueries.insertTanMethod(
|
||||||
|
userId,
|
||||||
|
|
||||||
|
tanMethod.displayName,
|
||||||
|
mapEnum(tanMethod.type),
|
||||||
|
tanMethod.identifier,
|
||||||
|
mapInt(tanMethod.maxTanInputLength),
|
||||||
|
mapEnum(tanMethod.allowedTanFormat)
|
||||||
|
)
|
||||||
|
|
||||||
|
val tanMethodId = getLastInsertedId()
|
||||||
|
|
||||||
|
return TanMethodEntity(tanMethodId, userId, tanMethod)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel> =
|
override fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel> =
|
||||||
accountTransactionQueries.selectAllTransactionsAsViewModel { id, userId, bankAccountId, amount, currency, reference, valueDate, otherPartyName, postingText, userSetDisplayName, category ->
|
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)
|
AccountTransactionViewModel(id, userId, bankAccountId, mapToAmount(amount), currency, reference, mapToDate(valueDate), otherPartyName, postingText, userSetDisplayName, category)
|
||||||
|
@ -284,7 +321,10 @@ open class SqliteBankingRepository(
|
||||||
|
|
||||||
private fun <E : Enum<E>> mapEnum(enum: Enum<E>): String = enum.name
|
private fun <E : Enum<E>> mapEnum(enum: Enum<E>): String = enum.name
|
||||||
|
|
||||||
private fun <E : Enum<E>> mapToEnum(enumName: String, values: EnumEntries<E>): E? {
|
private fun <E : Enum<E>> mapToEnum(enumName: String, values: EnumEntries<E>): E =
|
||||||
|
values.first { it.name == enumName }
|
||||||
|
|
||||||
|
private fun <E : Enum<E>> mapToEnumNullable(enumName: String, values: EnumEntries<E>): E? {
|
||||||
val mapped = values.firstOrNull { it.name == enumName }
|
val mapped = values.firstOrNull { it.name == enumName }
|
||||||
|
|
||||||
if (mapped == null) {
|
if (mapped == null) {
|
||||||
|
@ -298,7 +338,7 @@ open class SqliteBankingRepository(
|
||||||
enums.joinToString(",") { it.name }
|
enums.joinToString(",") { it.name }
|
||||||
|
|
||||||
private fun <E : Enum<E>> mapEnumSet(enumsString: String, values: EnumEntries<E>): Set<E> =
|
private fun <E : Enum<E>> mapEnumSet(enumsString: String, values: EnumEntries<E>): Set<E> =
|
||||||
enumsString.split(',').filterNot { it.isBlank() }.mapNotNull { mapToEnum(it, values) }.toSet()
|
enumsString.split(',').filterNot { it.isBlank() }.mapNotNull { mapToEnumNullable(it, values) }.toSet()
|
||||||
|
|
||||||
@JvmName("mapIntNullable")
|
@JvmName("mapIntNullable")
|
||||||
@JsName("mapIntNullable")
|
@JsName("mapIntNullable")
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package net.codinux.banking.dataaccess.entities
|
||||||
|
|
||||||
|
import net.codinux.banking.client.model.tan.AllowedTanFormat
|
||||||
|
import net.codinux.banking.client.model.tan.TanMethod
|
||||||
|
import net.codinux.banking.client.model.tan.TanMethodType
|
||||||
|
|
||||||
|
class TanMethodEntity(
|
||||||
|
val id: Long,
|
||||||
|
val userId: Long,
|
||||||
|
|
||||||
|
displayName: String,
|
||||||
|
type: TanMethodType,
|
||||||
|
identifier: String,
|
||||||
|
maxTanInputLength: Int? = null,
|
||||||
|
allowedTanFormat: AllowedTanFormat = AllowedTanFormat.Alphanumeric
|
||||||
|
) : TanMethod(displayName, type, identifier, maxTanInputLength, allowedTanFormat) {
|
||||||
|
|
||||||
|
constructor(id: Long, userId: Long, tanMethod: TanMethod)
|
||||||
|
: this(id, userId, tanMethod.displayName, tanMethod.type, tanMethod.identifier, tanMethod.maxTanInputLength, tanMethod.allowedTanFormat)
|
||||||
|
|
||||||
|
}
|
|
@ -21,7 +21,7 @@ class UserEntity(
|
||||||
override val accounts: List<BankAccountEntity> = emptyList(),
|
override val accounts: List<BankAccountEntity> = emptyList(),
|
||||||
|
|
||||||
selectedTanMethodIdentifier: String? = null,
|
selectedTanMethodIdentifier: String? = null,
|
||||||
tanMethods: List<TanMethod> = listOf(),
|
override val tanMethods: List<TanMethodEntity> = listOf(),
|
||||||
|
|
||||||
selectedTanMediumIdentifier: String? = null,
|
selectedTanMediumIdentifier: String? = null,
|
||||||
tanMedia: List<TanMedium> = listOf(),
|
tanMedia: List<TanMedium> = listOf(),
|
||||||
|
@ -45,11 +45,11 @@ class UserEntity(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
constructor(id: Long, user: User, bankAccounts: List<BankAccountEntity>) : this(
|
constructor(id: Long, user: User, bankAccounts: List<BankAccountEntity>, tanMethods: List<TanMethodEntity>) : this(
|
||||||
id,
|
id,
|
||||||
user.bankCode, user.loginName, user.password, user.bankName, user.bic, user.customerName, user.userId,
|
user.bankCode, user.loginName, user.password, user.bankName, user.bic, user.customerName, user.userId,
|
||||||
bankAccounts,
|
bankAccounts,
|
||||||
user.selectedTanMethodIdentifier, user.tanMethods, user.selectedTanMediumIdentifier, user.tanMedia,
|
user.selectedTanMethodIdentifier, tanMethods, user.selectedTanMediumIdentifier, user.tanMedia,
|
||||||
user.bankingGroup, user.serverAddress,
|
user.bankingGroup, user.serverAddress,
|
||||||
user.userSetDisplayName, user.displayIndex,
|
user.userSetDisplayName, user.displayIndex,
|
||||||
user.iconUrl, user.wrongCredentialsEntered,
|
user.iconUrl, user.wrongCredentialsEntered,
|
||||||
|
|
|
@ -141,6 +141,46 @@ SELECT BankAccount.*
|
||||||
FROM BankAccount;
|
FROM BankAccount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS TanMethod (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
|
||||||
|
userId INTEGER NOT NULL,
|
||||||
|
|
||||||
|
displayName TEXT NOT NULL,
|
||||||
|
type TEXT NOT NULL,
|
||||||
|
identifier TEXT NOT NULL,
|
||||||
|
maxTanInputLength INTEGER ,
|
||||||
|
allowedTanFormat TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
insertTanMethod:
|
||||||
|
INSERT INTO TanMethod(
|
||||||
|
userId,
|
||||||
|
|
||||||
|
displayName,
|
||||||
|
type,
|
||||||
|
identifier,
|
||||||
|
maxTanInputLength,
|
||||||
|
allowedTanFormat
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
?,
|
||||||
|
|
||||||
|
?,
|
||||||
|
?,
|
||||||
|
?,
|
||||||
|
?,
|
||||||
|
?
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
selectAllTanMethods:
|
||||||
|
SELECT TanMethod.*
|
||||||
|
FROM TanMethod;
|
||||||
|
|
||||||
|
|
||||||
-- TODO: find a better place for this cross-cutting concern:
|
-- TODO: find a better place for this cross-cutting concern:
|
||||||
getLastInsertedId:
|
getLastInsertedId:
|
||||||
SELECT last_insert_rowid();
|
SELECT last_insert_rowid();
|
||||||
|
|
Loading…
Reference in New Issue