Saving also userAccountId and bankAccountId on child entities
This commit is contained in:
parent
d356d45db7
commit
4856ced158
|
@ -1,6 +1,5 @@
|
||||||
package net.codinux.banking.dataaccess
|
package net.codinux.banking.dataaccess
|
||||||
|
|
||||||
import net.codinux.banking.client.model.AccountTransaction
|
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.UserAccount
|
||||||
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
||||||
|
@ -10,13 +9,11 @@ interface BankingRepository {
|
||||||
|
|
||||||
fun getAllUserAccounts(): List<UserAccountEntity>
|
fun getAllUserAccounts(): List<UserAccountEntity>
|
||||||
|
|
||||||
suspend fun persistUserAccount(userAccount: UserAccount): Long
|
suspend fun persistUserAccount(userAccount: UserAccount): UserAccountEntity
|
||||||
|
|
||||||
|
|
||||||
fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel>
|
fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel>
|
||||||
|
|
||||||
fun getAllAccountTransactions(): List<AccountTransactionEntity>
|
fun getAllAccountTransactions(): List<AccountTransactionEntity>
|
||||||
|
|
||||||
suspend fun persistAccountTransactions(transactions: Collection<AccountTransaction>): Map<Long, AccountTransaction>
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,36 +20,31 @@ class InMemoryBankingRepository(
|
||||||
|
|
||||||
override fun getAllUserAccounts(): List<UserAccountEntity> = userAccounts.toList()
|
override fun getAllUserAccounts(): List<UserAccountEntity> = userAccounts.toList()
|
||||||
|
|
||||||
override suspend fun persistUserAccount(userAccount: UserAccount): Long {
|
override suspend fun persistUserAccount(userAccount: UserAccount): UserAccountEntity {
|
||||||
val entity = map(userAccount)
|
val entity = map(userAccount) // TODO: may fix someday and add also BankAccounts and their id
|
||||||
this.userAccounts.add(entity)
|
this.userAccounts.add(entity)
|
||||||
return entity.id
|
return entity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel> =
|
override fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel> =
|
||||||
transactions.map { AccountTransactionViewModel(it.id, it) }
|
transactions.map { AccountTransactionViewModel(it) }
|
||||||
|
|
||||||
override fun getAllAccountTransactions(): List<AccountTransactionEntity> = transactions.toList()
|
override fun getAllAccountTransactions(): List<AccountTransactionEntity> = transactions.toList()
|
||||||
|
|
||||||
override suspend fun persistAccountTransactions(transactions: Collection<AccountTransaction>): Map<Long, AccountTransaction> {
|
|
||||||
val entities = transactions.map { map(it) }
|
|
||||||
|
|
||||||
this.transactions.addAll(entities)
|
|
||||||
|
|
||||||
return entities.associateBy { it.id }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun map(account: UserAccount) = UserAccountEntity(
|
private fun map(account: UserAccount) = UserAccountEntity(
|
||||||
nextId++,
|
nextId++,
|
||||||
account.bankCode, account.loginName, account.password, account.bankName, account.bic, account.customerName, account.userId,
|
account.bankCode, account.loginName, account.password, account.bankName, account.bic, account.customerName, account.userId,
|
||||||
|
// TODO: may fix someday and also add BankAccounts
|
||||||
emptyList(), account.selectedTanMethodId, emptyList(), account.selectedTanMediumName, emptyList(),
|
emptyList(), account.selectedTanMethodId, emptyList(), account.selectedTanMediumName, emptyList(),
|
||||||
account.bankingGroup, account.iconUrl, account.wrongCredentialsEntered, account.userSetDisplayName, account.displayIndex
|
account.bankingGroup, account.iconUrl, account.wrongCredentialsEntered, account.userSetDisplayName, account.displayIndex
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun map(transaction: AccountTransaction) = AccountTransactionEntity(
|
// TODO: someday may fix and get userAccountId and bankAccountId
|
||||||
|
private fun map(transaction: AccountTransaction, userAccountId: Long = nextId++, bankAccountId: Long = nextId++) = AccountTransactionEntity(
|
||||||
nextId++,
|
nextId++,
|
||||||
|
userAccountId, bankAccountId,
|
||||||
transaction.amount, transaction.currency, transaction.reference,
|
transaction.amount, transaction.currency, transaction.reference,
|
||||||
transaction.bookingDate, transaction.valueDate,
|
transaction.bookingDate, transaction.valueDate,
|
||||||
transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId,
|
transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId,
|
||||||
|
|
|
@ -11,7 +11,7 @@ import kotlin.enums.EnumEntries
|
||||||
import kotlin.js.JsName
|
import kotlin.js.JsName
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
class SqliteBankingRepository(
|
open class SqliteBankingRepository(
|
||||||
sqlDriver: SqlDriver
|
sqlDriver: SqlDriver
|
||||||
) : BankingRepository {
|
) : BankingRepository {
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class SqliteBankingRepository(
|
||||||
}.executeAsList()
|
}.executeAsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun persistUserAccount(userAccount: UserAccount): Long {
|
override suspend fun persistUserAccount(userAccount: UserAccount): UserAccountEntity {
|
||||||
return userAccountQueries.transactionWithResult {
|
return userAccountQueries.transactionWithResult {
|
||||||
userAccountQueries.insertUserAccount(userAccount.bankCode, userAccount.loginName, userAccount.password, userAccount.bankName, userAccount.bic,
|
userAccountQueries.insertUserAccount(userAccount.bankCode, userAccount.loginName, userAccount.password, userAccount.bankName, userAccount.bic,
|
||||||
userAccount.customerName, userAccount.userId, userAccount.selectedTanMethodId, userAccount.selectedTanMediumName,
|
userAccount.customerName, userAccount.userId, userAccount.selectedTanMethodId, userAccount.selectedTanMediumName,
|
||||||
|
@ -40,9 +40,9 @@ class SqliteBankingRepository(
|
||||||
|
|
||||||
val userAccountId = getLastInsertedId() // getLastInsertedId() / last_insert_rowid() has to be called in a transaction with the insert operation, otherwise it will not work
|
val userAccountId = getLastInsertedId() // getLastInsertedId() / last_insert_rowid() has to be called in a transaction with the insert operation, otherwise it will not work
|
||||||
|
|
||||||
persistBankAccounts(userAccountId, userAccount.accounts)
|
val bankAccounts = persistBankAccounts(userAccountId, userAccount.accounts)
|
||||||
|
|
||||||
userAccountId
|
UserAccountEntity(userAccountId, userAccount, bankAccounts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,18 +58,20 @@ class SqliteBankingRepository(
|
||||||
mapToAmount(balance), mapToDate(retrievedTransactionsFrom), mapToDate(retrievedTransactionsTo),
|
mapToAmount(balance), mapToDate(retrievedTransactionsFrom), mapToDate(retrievedTransactionsTo),
|
||||||
mapToInt(countDaysForWhichTransactionsAreKept),
|
mapToInt(countDaysForWhichTransactionsAreKept),
|
||||||
|
|
||||||
|
mutableListOf(), mutableListOf(),
|
||||||
|
|
||||||
userSetDisplayName, mapToInt(displayIndex),
|
userSetDisplayName, mapToInt(displayIndex),
|
||||||
hideAccount, includeInAutomaticAccountsUpdate
|
hideAccount, includeInAutomaticAccountsUpdate
|
||||||
)
|
)
|
||||||
}.executeAsList()
|
}.executeAsList()
|
||||||
|
|
||||||
private suspend fun persistBankAccounts(userAccountId: Long, bankAccounts: Collection<BankAccount>): Map<Long, BankAccount> =
|
private suspend fun persistBankAccounts(userAccountId: Long, bankAccounts: Collection<BankAccount>): List<BankAccountEntity> =
|
||||||
bankAccounts.associate { persistBankAccount(userAccountId, it) }
|
bankAccounts.map { persistBankAccount(userAccountId, it) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has to be executed in a transaction in order that getting persisted BankAccount's id works~
|
* Has to be executed in a transaction in order that getting persisted BankAccount's id works~
|
||||||
*/
|
*/
|
||||||
private suspend fun persistBankAccount(userAccountId: Long, account: BankAccount): Pair<Long, BankAccount> {
|
private suspend fun persistBankAccount(userAccountId: Long, account: BankAccount): BankAccountEntity {
|
||||||
userAccountQueries.insertBankAccount(
|
userAccountQueries.insertBankAccount(
|
||||||
userAccountId,
|
userAccountId,
|
||||||
account.identifier, account.accountHolderName, mapEnum(account.type),
|
account.identifier, account.accountHolderName, mapEnum(account.type),
|
||||||
|
@ -86,19 +88,27 @@ class SqliteBankingRepository(
|
||||||
account.hideAccount, account.includeInAutomaticAccountsUpdate
|
account.hideAccount, account.includeInAutomaticAccountsUpdate
|
||||||
)
|
)
|
||||||
|
|
||||||
return Pair(getLastInsertedId(), account)
|
val accountId = getLastInsertedId()
|
||||||
|
|
||||||
|
val accountTransactionEntities = account.bookedTransactions.map { transaction ->
|
||||||
|
persistTransaction(userAccountId, accountId, transaction)
|
||||||
|
}
|
||||||
|
|
||||||
|
return BankAccountEntity(accountId, userAccountId, account, accountTransactionEntities)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel> =
|
override fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel> =
|
||||||
accountTransactionQueries.selectAllTransactionsAsViewModel { id, amount, currency, reference, valueDate, otherPartyName, bookingText, sepaReference, userSetDisplayName, category ->
|
accountTransactionQueries.selectAllTransactionsAsViewModel { id, userAccountId, bankAccountId, amount, currency, reference, valueDate, otherPartyName, bookingText, sepaReference, userSetDisplayName, category ->
|
||||||
AccountTransactionViewModel(id, mapToAmount(amount), currency, sepaReference ?: reference, mapToDate(valueDate), otherPartyName, bookingText, userSetDisplayName, category)
|
AccountTransactionViewModel(id, userAccountId, bankAccountId, mapToAmount(amount), currency, sepaReference ?: reference, mapToDate(valueDate), otherPartyName, bookingText, userSetDisplayName, category)
|
||||||
}.executeAsList()
|
}.executeAsList()
|
||||||
|
|
||||||
override fun getAllAccountTransactions(): List<AccountTransactionEntity> {
|
override fun getAllAccountTransactions(): List<AccountTransactionEntity> {
|
||||||
return accountTransactionQueries.selectAllTransactions { id, amount, currency, reference, bookingDate, valueDate, otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, userSetDisplayName, category, notes, information, statementNumber, sequenceNumber, openingBalance, closingBalance, endToEndReference, customerReference, mandateReference, creditorIdentifier, originatorsIdentificationCode, compensationAmount, originalAmount, sepaReference, deviantOriginator, deviantRecipient, referenceWithNoSpecialType, primaNotaNumber, textKeySupplement, currencyType, bookingKey, referenceForTheAccountOwner, referenceOfTheAccountServicingInstitution, supplementaryDetails, transactionReferenceNumber, relatedReferenceNumber ->
|
return accountTransactionQueries.selectAllTransactions { id, userAccountId, bankAccountId, amount, currency, reference, bookingDate, valueDate, otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, userSetDisplayName, category, notes, information, statementNumber, sequenceNumber, openingBalance, closingBalance, endToEndReference, customerReference, mandateReference, creditorIdentifier, originatorsIdentificationCode, compensationAmount, originalAmount, sepaReference, deviantOriginator, deviantRecipient, referenceWithNoSpecialType, primaNotaNumber, textKeySupplement, currencyType, bookingKey, referenceForTheAccountOwner, referenceOfTheAccountServicingInstitution, supplementaryDetails, transactionReferenceNumber, relatedReferenceNumber ->
|
||||||
AccountTransactionEntity(
|
AccountTransactionEntity(
|
||||||
id,
|
id,
|
||||||
|
userAccountId, bankAccountId,
|
||||||
|
|
||||||
Amount(amount), currency, reference,
|
Amount(amount), currency, reference,
|
||||||
mapToDate(bookingDate), mapToDate(valueDate),
|
mapToDate(bookingDate), mapToDate(valueDate),
|
||||||
otherPartyName, otherPartyBankCode, otherPartyAccountId,
|
otherPartyName, otherPartyBankCode, otherPartyAccountId,
|
||||||
|
@ -128,18 +138,13 @@ class SqliteBankingRepository(
|
||||||
}.executeAsList()
|
}.executeAsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun persistAccountTransactions(transactions: Collection<AccountTransaction>): Map<Long, AccountTransaction> =
|
|
||||||
accountTransactionQueries.transactionWithResult {
|
|
||||||
transactions.associate {
|
|
||||||
saveAccountTransaction(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has to be executed in a transaction in order that getting persisted BankAccount's id works~
|
* Has to be executed in a transaction in order that getting persisted BankAccount's id works~
|
||||||
*/
|
*/
|
||||||
private suspend fun saveAccountTransaction(transaction: AccountTransaction): Pair<Long, AccountTransaction> {
|
protected open suspend fun persistTransaction(userAccountId: Long, bankAccountId: Long, transaction: AccountTransaction): AccountTransactionEntity {
|
||||||
accountTransactionQueries.insertTransaction(
|
accountTransactionQueries.insertTransaction(
|
||||||
|
userAccountId, bankAccountId,
|
||||||
|
|
||||||
mapAmount(transaction.amount), transaction.currency, transaction.reference,
|
mapAmount(transaction.amount), transaction.currency, transaction.reference,
|
||||||
mapDate(transaction.bookingDate), mapDate(transaction.valueDate),
|
mapDate(transaction.bookingDate), mapDate(transaction.valueDate),
|
||||||
transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId,
|
transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId,
|
||||||
|
@ -165,7 +170,7 @@ class SqliteBankingRepository(
|
||||||
transaction.transactionReferenceNumber, transaction.relatedReferenceNumber
|
transaction.transactionReferenceNumber, transaction.relatedReferenceNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
return Pair(getLastInsertedId(), transaction)
|
return AccountTransactionEntity(getLastInsertedId(), userAccountId, bankAccountId, transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import net.codinux.banking.client.model.Amount
|
||||||
|
|
||||||
class AccountTransactionEntity(
|
class AccountTransactionEntity(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
|
val userAccountId: Long,
|
||||||
|
val bankAccountId: Long,
|
||||||
|
|
||||||
amount: Amount,
|
amount: Amount,
|
||||||
currency: String,
|
currency: String,
|
||||||
|
@ -78,4 +80,28 @@ class AccountTransactionEntity(
|
||||||
transactionReferenceNumber, relatedReferenceNumber,
|
transactionReferenceNumber, relatedReferenceNumber,
|
||||||
|
|
||||||
userSetDisplayName, category, notes
|
userSetDisplayName, category, notes
|
||||||
)
|
) {
|
||||||
|
constructor(id: Long, userAccountId: Long, bankAccountId: Long, transaction: AccountTransaction) : this(
|
||||||
|
id, userAccountId, bankAccountId,
|
||||||
|
transaction.amount, transaction.currency, transaction.reference, transaction.bookingDate, transaction.valueDate,
|
||||||
|
transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId, transaction.bookingText,
|
||||||
|
|
||||||
|
transaction.userSetDisplayName, transaction.category, transaction.notes, transaction.information,
|
||||||
|
|
||||||
|
transaction.statementNumber, transaction.sequenceNumber,
|
||||||
|
transaction.openingBalance, transaction.closingBalance,
|
||||||
|
|
||||||
|
transaction.endToEndReference, transaction.customerReference, transaction.mandateReference,
|
||||||
|
transaction.creditorIdentifier, transaction.originatorsIdentificationCode,
|
||||||
|
transaction.compensationAmount, transaction.originalAmount,
|
||||||
|
transaction.sepaReference,
|
||||||
|
transaction.deviantOriginator, transaction.deviantRecipient,
|
||||||
|
transaction.referenceWithNoSpecialType, transaction.primaNotaNumber, transaction.textKeySupplement,
|
||||||
|
|
||||||
|
transaction.currencyType, transaction.bookingKey,
|
||||||
|
transaction.referenceForTheAccountOwner, transaction.referenceOfTheAccountServicingInstitution,
|
||||||
|
transaction.supplementaryDetails,
|
||||||
|
|
||||||
|
transaction.transactionReferenceNumber, transaction.relatedReferenceNumber
|
||||||
|
)
|
||||||
|
}
|
|
@ -25,8 +25,8 @@ class BankAccountEntity(
|
||||||
|
|
||||||
countDaysForWhichTransactionsAreKept: Int? = null,
|
countDaysForWhichTransactionsAreKept: Int? = null,
|
||||||
|
|
||||||
// bookedTransactions: MutableList<AccountTransaction> = mutableListOf(),
|
bookedTransactions: MutableList<AccountTransactionEntity> = mutableListOf(),
|
||||||
// unbookedTransactions: MutableList<UnbookedAccountTransaction> = mutableListOf(),
|
unbookedTransactions: MutableList<UnbookedAccountTransaction> = mutableListOf(),
|
||||||
|
|
||||||
userSetDisplayName: String? = null,
|
userSetDisplayName: String? = null,
|
||||||
displayIndex: Int = 0,
|
displayIndex: Int = 0,
|
||||||
|
@ -37,6 +37,19 @@ class BankAccountEntity(
|
||||||
identifier, accountHolderName, type, iban, subAccountNumber, productName, currency, accountLimit,
|
identifier, accountHolderName, type, iban, subAccountNumber, productName, currency, accountLimit,
|
||||||
isAccountTypeSupportedByApplication, features, balance,
|
isAccountTypeSupportedByApplication, features, balance,
|
||||||
retrievedTransactionsFrom, retrievedTransactionsTo, false, countDaysForWhichTransactionsAreKept,
|
retrievedTransactionsFrom, retrievedTransactionsTo, false, countDaysForWhichTransactionsAreKept,
|
||||||
mutableListOf(), mutableListOf(),
|
bookedTransactions as MutableList<AccountTransaction>, unbookedTransactions,
|
||||||
userSetDisplayName, displayIndex, hideAccount, includeInAutomaticAccountsUpdate
|
userSetDisplayName, displayIndex, hideAccount, includeInAutomaticAccountsUpdate
|
||||||
)
|
) {
|
||||||
|
constructor(id: Long, userAccountId: Long, account: BankAccount, transactions: List<AccountTransactionEntity> = emptyList()) : this(
|
||||||
|
id, userAccountId,
|
||||||
|
account.identifier, account.accountHolderName, account.type, account.iban, account.subAccountNumber,
|
||||||
|
account.productName, account.currency, account.accountLimit,
|
||||||
|
account.isAccountTypeSupportedByApplication, account.features, account.balance,
|
||||||
|
account.retrievedTransactionsFrom, account.retrievedTransactionsTo, account.countDaysForWhichTransactionsAreKept,
|
||||||
|
transactions.toMutableList(), mutableListOf(),
|
||||||
|
account.userSetDisplayName, account.displayIndex, account.hideAccount, account.includeInAutomaticAccountsUpdate
|
||||||
|
)
|
||||||
|
|
||||||
|
val bookedTransactionsEntities: MutableList<AccountTransactionEntity> = bookedTransactions
|
||||||
|
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ class UserAccountEntity(
|
||||||
customerName: String,
|
customerName: String,
|
||||||
userId: String = loginName,
|
userId: String = loginName,
|
||||||
|
|
||||||
accounts: List<BankAccountEntity> = emptyList(), // TODO: make accounts open
|
override val accounts: List<BankAccountEntity> = emptyList(),
|
||||||
|
|
||||||
selectedTanMethodId: String? = null,
|
selectedTanMethodId: String? = null,
|
||||||
tanMethods: List<TanMethod> = listOf(),
|
tanMethods: List<TanMethod> = listOf(),
|
||||||
|
@ -42,14 +42,12 @@ class UserAccountEntity(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
constructor(id: Long, user: UserAccount) : this(
|
constructor(id: Long, user: UserAccount, bankAccounts: List<BankAccountEntity>) : 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,
|
||||||
emptyList(), user.selectedTanMethodId, emptyList(), user.selectedTanMediumName, emptyList(),
|
bankAccounts,
|
||||||
|
user.selectedTanMethodId, emptyList(), user.selectedTanMediumName, emptyList(),
|
||||||
user.bankingGroup, user.iconUrl, user.wrongCredentialsEntered, user.userSetDisplayName, user.displayIndex
|
user.bankingGroup, user.iconUrl, user.wrongCredentialsEntered, user.userSetDisplayName, user.displayIndex
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
val accountEntities: List<BankAccountEntity> = accounts
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,9 +3,12 @@ package net.codinux.banking.ui.model
|
||||||
import kotlinx.datetime.LocalDate
|
import kotlinx.datetime.LocalDate
|
||||||
import net.codinux.banking.client.model.AccountTransaction
|
import net.codinux.banking.client.model.AccountTransaction
|
||||||
import net.codinux.banking.client.model.Amount
|
import net.codinux.banking.client.model.Amount
|
||||||
|
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
||||||
|
|
||||||
data class AccountTransactionViewModel(
|
data class AccountTransactionViewModel(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
|
val userAccountId: Long,
|
||||||
|
val bankAccountId: Long,
|
||||||
|
|
||||||
val amount: Amount,
|
val amount: Amount,
|
||||||
val currency: String,
|
val currency: String,
|
||||||
|
@ -17,6 +20,8 @@ data class AccountTransactionViewModel(
|
||||||
val userSetDisplayName: String? = null,
|
val userSetDisplayName: String? = null,
|
||||||
val category: String? = null
|
val category: String? = null
|
||||||
) {
|
) {
|
||||||
constructor(id: Long, transaction: AccountTransaction)
|
constructor(entity: AccountTransactionEntity) : this(entity.id, entity.userAccountId, entity.bankAccountId, entity)
|
||||||
: this(id, transaction.amount, transaction.currency, transaction.reference, transaction.valueDate, transaction.otherPartyName, transaction.bookingText)
|
|
||||||
|
constructor(id: Long, userAccountId: Long, bankAccountId: Long, transaction: AccountTransaction)
|
||||||
|
: this(id, userAccountId, bankAccountId, transaction.amount, transaction.currency, transaction.reference, transaction.valueDate, transaction.otherPartyName, transaction.bookingText)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,12 @@ import net.codinux.banking.client.fints4k.FinTs4kBankingClient
|
||||||
import net.codinux.banking.client.model.AccountTransaction
|
import net.codinux.banking.client.model.AccountTransaction
|
||||||
import net.codinux.banking.client.model.Amount
|
import net.codinux.banking.client.model.Amount
|
||||||
import net.codinux.banking.client.model.options.GetAccountDataOptions
|
import net.codinux.banking.client.model.options.GetAccountDataOptions
|
||||||
import net.codinux.banking.client.model.options.RetrieveTransactions
|
|
||||||
import net.codinux.banking.client.model.request.GetAccountDataRequest
|
import net.codinux.banking.client.model.request.GetAccountDataRequest
|
||||||
import net.codinux.banking.client.model.response.*
|
import net.codinux.banking.client.model.response.ErrorType
|
||||||
|
import net.codinux.banking.client.model.response.GetAccountDataResponse
|
||||||
|
import net.codinux.banking.client.model.response.Response
|
||||||
|
import net.codinux.banking.client.model.response.ResponseType
|
||||||
import net.codinux.banking.dataaccess.BankingRepository
|
import net.codinux.banking.dataaccess.BankingRepository
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
|
||||||
import net.codinux.banking.fints.config.FinTsClientConfiguration
|
import net.codinux.banking.fints.config.FinTsClientConfiguration
|
||||||
import net.codinux.banking.fints.config.FinTsClientOptions
|
import net.codinux.banking.fints.config.FinTsClientOptions
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
|
@ -73,28 +74,19 @@ class BankingService(
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun handleSuccessfulGetAccountDataResponse(response: GetAccountDataResponse) {
|
private suspend fun handleSuccessfulGetAccountDataResponse(response: GetAccountDataResponse) {
|
||||||
try {
|
|
||||||
val newTransactions = response.bookedTransactions
|
|
||||||
val createdIds = bankingRepository.persistAccountTransactions(newTransactions)
|
|
||||||
|
|
||||||
log.info { "Saved ${newTransactions.size} transactions" }
|
|
||||||
|
|
||||||
val transactions = uiState.transactions.value.toMutableList()
|
|
||||||
transactions.addAll(createdIds.map { AccountTransactionViewModel(it.key, it.value) })
|
|
||||||
uiState.transactions.value = transactions.sortedByDescending { it.valueDate }
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
log.error(e) { "Could not save account transactions ${response.bookedTransactions}" }
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val newUser = response.user
|
val newUser = response.user
|
||||||
val newUserAccountId = bankingRepository.persistUserAccount(newUser)
|
val newUserEntity = bankingRepository.persistUserAccount(newUser)
|
||||||
|
|
||||||
log.info { "Saved user account $newUser" }
|
log.info { "Saved user account $newUserEntity with ${newUserEntity.accounts.flatMap { it.bookedTransactionsEntities }.size} transactions" }
|
||||||
|
|
||||||
val userAccounts = uiState.userAccounts.value.toMutableList()
|
val userAccounts = uiState.userAccounts.value.toMutableList()
|
||||||
userAccounts.add(UserAccountEntity(newUserAccountId, newUser))
|
userAccounts.add(newUserEntity)
|
||||||
uiState.userAccounts.value = userAccounts
|
uiState.userAccounts.value = userAccounts
|
||||||
|
|
||||||
|
val transactions = uiState.transactions.value.toMutableList()
|
||||||
|
transactions.addAll(newUserEntity.accounts.flatMap { it.bookedTransactionsEntities }.map { AccountTransactionViewModel(it) })
|
||||||
|
uiState.transactions.value = transactions.sortedByDescending { it.valueDate }
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log.error(e) { "Could not save user account ${response.user}" }
|
log.error(e) { "Could not save user account ${response.user}" }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
CREATE TABLE IF NOT EXISTS AccountTransaction (
|
CREATE TABLE IF NOT EXISTS AccountTransaction (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
|
||||||
|
userAccountId INTEGER NOT NULL,
|
||||||
|
bankAccountId INTEGER NOT NULL,
|
||||||
|
|
||||||
amount TEXT NOT NULL,
|
amount TEXT NOT NULL,
|
||||||
currency TEXT NOT NULL,
|
currency TEXT NOT NULL,
|
||||||
reference TEXT NOT NULL,
|
reference TEXT NOT NULL,
|
||||||
|
@ -53,6 +56,8 @@ CREATE TABLE IF NOT EXISTS AccountTransaction (
|
||||||
|
|
||||||
insertTransaction:
|
insertTransaction:
|
||||||
INSERT INTO AccountTransaction(
|
INSERT INTO AccountTransaction(
|
||||||
|
userAccountId, bankAccountId,
|
||||||
|
|
||||||
amount, currency, reference,
|
amount, currency, reference,
|
||||||
bookingDate, valueDate,
|
bookingDate, valueDate,
|
||||||
otherPartyName, otherPartyBankCode, otherPartyAccountId,
|
otherPartyName, otherPartyBankCode, otherPartyAccountId,
|
||||||
|
@ -79,6 +84,8 @@ INSERT INTO AccountTransaction(
|
||||||
transactionReferenceNumber, relatedReferenceNumber
|
transactionReferenceNumber, relatedReferenceNumber
|
||||||
)
|
)
|
||||||
VALUES(
|
VALUES(
|
||||||
|
?, ?,
|
||||||
|
|
||||||
?, ?, ?,
|
?, ?, ?,
|
||||||
?, ?,
|
?, ?,
|
||||||
?, ?, ?,
|
?, ?, ?,
|
||||||
|
@ -111,5 +118,5 @@ SELECT AccountTransaction.*
|
||||||
FROM AccountTransaction;
|
FROM AccountTransaction;
|
||||||
|
|
||||||
selectAllTransactionsAsViewModel:
|
selectAllTransactionsAsViewModel:
|
||||||
SELECT id, amount, currency, reference, valueDate, otherPartyName, bookingText, sepaReference, userSetDisplayName, category
|
SELECT id, userAccountId, bankAccountId, amount, currency, reference, valueDate, otherPartyName, bookingText, sepaReference, userSetDisplayName, category
|
||||||
FROM AccountTransaction;
|
FROM AccountTransaction;
|
|
@ -5,6 +5,7 @@ import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
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 kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
|
@ -15,7 +16,10 @@ class SqliteBankingRepositoryTest {
|
||||||
BankmeisterDb.Schema.synchronous().create(this)
|
BankmeisterDb.Schema.synchronous().create(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val underTest = SqliteBankingRepository(sqlDriver)
|
private val underTest = object : SqliteBankingRepository(sqlDriver) {
|
||||||
|
override public suspend fun persistTransaction(userAccountId: Long, bankAccountId: Long, transaction: AccountTransaction): AccountTransactionEntity =
|
||||||
|
super.persistTransaction(userAccountId, bankAccountId, transaction)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -28,13 +32,8 @@ class SqliteBankingRepositoryTest {
|
||||||
displayIndex = 99
|
displayIndex = 99
|
||||||
}
|
}
|
||||||
|
|
||||||
underTest.persistUserAccount(userAccount)
|
val persisted = underTest.persistUserAccount(userAccount)
|
||||||
|
|
||||||
val result = underTest.getAllUserAccounts()
|
|
||||||
|
|
||||||
assertEquals(1, result.size)
|
|
||||||
|
|
||||||
val persisted = result.first()
|
|
||||||
assertNotNull(persisted.id)
|
assertNotNull(persisted.id)
|
||||||
|
|
||||||
assertEquals(userAccount.bankCode, persisted.bankCode)
|
assertEquals(userAccount.bankCode, persisted.bankCode)
|
||||||
|
@ -52,9 +51,9 @@ class SqliteBankingRepositoryTest {
|
||||||
assertEquals(userAccount.wrongCredentialsEntered, persisted.wrongCredentialsEntered)
|
assertEquals(userAccount.wrongCredentialsEntered, persisted.wrongCredentialsEntered)
|
||||||
assertEquals(userAccount.displayIndex, persisted.displayIndex)
|
assertEquals(userAccount.displayIndex, persisted.displayIndex)
|
||||||
|
|
||||||
assertEquals(1, persisted.accountEntities.size)
|
assertEquals(1, persisted.accounts.size)
|
||||||
|
|
||||||
val persistedBankAccount = persisted.accountEntities.first()
|
val persistedBankAccount = persisted.accounts.first()
|
||||||
assertNotNull(persistedBankAccount.id)
|
assertNotNull(persistedBankAccount.id)
|
||||||
assertEquals(persisted.id, persistedBankAccount.userAccountId)
|
assertEquals(persisted.id, persistedBankAccount.userAccountId)
|
||||||
|
|
||||||
|
@ -78,7 +77,7 @@ class SqliteBankingRepositoryTest {
|
||||||
fun saveTransaction() = runTest {
|
fun saveTransaction() = runTest {
|
||||||
val transaction = AccountTransaction(Amount("12.45"), "EUR", "Lohn", LocalDate(2024, 5, 7), LocalDate(2024, 6, 15), "Dein Boss")
|
val transaction = AccountTransaction(Amount("12.45"), "EUR", "Lohn", LocalDate(2024, 5, 7), LocalDate(2024, 6, 15), "Dein Boss")
|
||||||
|
|
||||||
underTest.persistAccountTransactions(listOf(transaction))
|
underTest.persistTransaction(1L, 1L, transaction)
|
||||||
|
|
||||||
val result = underTest.getAllAccountTransactions()
|
val result = underTest.getAllAccountTransactions()
|
||||||
|
|
||||||
|
@ -99,7 +98,7 @@ class SqliteBankingRepositoryTest {
|
||||||
fun saveTransaction_GetAsViewModel() = runTest {
|
fun saveTransaction_GetAsViewModel() = runTest {
|
||||||
val transaction = AccountTransaction(Amount("12.45"), "EUR", "Lohn", LocalDate(2024, 5, 7), LocalDate(2024, 6, 15), "Dein Boss")
|
val transaction = AccountTransaction(Amount("12.45"), "EUR", "Lohn", LocalDate(2024, 5, 7), LocalDate(2024, 6, 15), "Dein Boss")
|
||||||
|
|
||||||
underTest.persistAccountTransactions(listOf(transaction))
|
underTest.persistTransaction(1L, 1L, transaction)
|
||||||
|
|
||||||
val result = underTest.getAllAccountTransactionsAsViewModel()
|
val result = underTest.getAllAccountTransactionsAsViewModel()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue