Updated to new BankingClient model
This commit is contained in:
parent
cd8e0a53ad
commit
234084e627
|
@ -1,17 +1,17 @@
|
||||||
package net.codinux.banking.dataaccess
|
package net.codinux.banking.dataaccess
|
||||||
|
|
||||||
import net.codinux.banking.client.model.AccountTransaction
|
import net.codinux.banking.client.model.AccountTransaction
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.User
|
||||||
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
|
|
||||||
interface BankingRepository {
|
interface BankingRepository {
|
||||||
|
|
||||||
fun getAllUserAccounts(): List<UserAccountEntity>
|
fun getAllUsers(): List<UserEntity>
|
||||||
|
|
||||||
suspend fun persistUserAccount(userAccount: UserAccount): UserAccountEntity
|
suspend fun persistUser(user: User): UserEntity
|
||||||
|
|
||||||
suspend fun persistTransactions(bankAccount: BankAccountEntity, transactions: List<AccountTransaction>): List<AccountTransactionEntity>
|
suspend fun persistTransactions(bankAccount: BankAccountEntity, transactions: List<AccountTransaction>): List<AccountTransactionEntity>
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ interface BankingRepository {
|
||||||
|
|
||||||
fun getAllAccountTransactions(): List<AccountTransactionEntity>
|
fun getAllAccountTransactions(): List<AccountTransactionEntity>
|
||||||
|
|
||||||
fun getAllTransactionsOfUserAccount(userAccount: UserAccountEntity): List<AccountTransactionEntity>
|
fun getAllTransactionsOfUser(user: UserEntity): List<AccountTransactionEntity>
|
||||||
|
|
||||||
fun getTransactionById(transactionId: Long): AccountTransactionEntity?
|
fun getTransactionById(transactionId: Long): AccountTransactionEntity?
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
package net.codinux.banking.dataaccess
|
package net.codinux.banking.dataaccess
|
||||||
|
|
||||||
import net.codinux.banking.client.model.AccountTransaction
|
import net.codinux.banking.client.model.AccountTransaction
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.User
|
||||||
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
|
|
||||||
class InMemoryBankingRepository(
|
class InMemoryBankingRepository(
|
||||||
userAccounts: Collection<UserAccount> = emptyList(),
|
users: Collection<User> = emptyList(),
|
||||||
transactions: Collection<AccountTransaction> = emptyList()
|
transactions: Collection<AccountTransaction> = emptyList()
|
||||||
) : BankingRepository {
|
) : BankingRepository {
|
||||||
|
|
||||||
private var nextId = 0L // TODO: make thread-safe
|
private var nextId = 0L // TODO: make thread-safe
|
||||||
|
|
||||||
private val userAccounts = userAccounts.map { map(it) }.toMutableList()
|
private val users = users.map { map(it) }.toMutableList()
|
||||||
|
|
||||||
private val transactions = transactions.map { map(it) }.toMutableList()
|
private val transactions = transactions.map { map(it) }.toMutableList()
|
||||||
|
|
||||||
|
|
||||||
override fun getAllUserAccounts(): List<UserAccountEntity> = userAccounts.toList()
|
override fun getAllUsers(): List<UserEntity> = users.toList()
|
||||||
|
|
||||||
override suspend fun persistUserAccount(userAccount: UserAccount): UserAccountEntity {
|
override suspend fun persistUser(user: User): UserEntity {
|
||||||
val entity = map(userAccount) // TODO: may fix someday and add also BankAccounts and their id
|
val entity = map(user) // TODO: may fix someday and add also BankAccounts and their id
|
||||||
this.userAccounts.add(entity)
|
this.users.add(entity)
|
||||||
return entity
|
return entity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,29 +37,31 @@ class InMemoryBankingRepository(
|
||||||
|
|
||||||
override fun getAllAccountTransactions(): List<AccountTransactionEntity> = transactions.toList()
|
override fun getAllAccountTransactions(): List<AccountTransactionEntity> = transactions.toList()
|
||||||
|
|
||||||
override fun getAllTransactionsOfUserAccount(userAccount: UserAccountEntity): List<AccountTransactionEntity> =
|
override fun getAllTransactionsOfUser(user: UserEntity): List<AccountTransactionEntity> =
|
||||||
getAllAccountTransactions().filter { it.userAccountId == userAccount.id }
|
getAllAccountTransactions().filter { it.userId == user.id }
|
||||||
|
|
||||||
override fun getTransactionById(transactionId: Long): AccountTransactionEntity? =
|
override fun getTransactionById(transactionId: Long): AccountTransactionEntity? =
|
||||||
getAllAccountTransactions().firstOrNull { it.id == transactionId }
|
getAllAccountTransactions().firstOrNull { it.id == transactionId }
|
||||||
|
|
||||||
|
|
||||||
private fun map(account: UserAccount) = UserAccountEntity(
|
private fun map(account: User) = UserEntity(
|
||||||
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
|
// TODO: may fix someday and also add BankAccounts
|
||||||
emptyList(), account.selectedTanMethodId, emptyList(), account.selectedTanMediumName, emptyList(),
|
emptyList(), account.selectedTanMethodIdentifier, emptyList(), account.selectedTanMediumIdentifier, emptyList(),
|
||||||
account.bankingGroup, account.iconUrl, account.wrongCredentialsEntered, account.userSetDisplayName, account.displayIndex
|
account.bankingGroup, account.finTsServerAddress,
|
||||||
|
account.userSetDisplayName, account.displayIndex,
|
||||||
|
account.iconUrl, account.wrongCredentialsEntered,
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: someday may fix and get userAccountId and bankAccountId
|
// TODO: someday may fix and get userAccountId and bankAccountId
|
||||||
private fun map(transaction: AccountTransaction, userAccountId: Long = nextId++, bankAccountId: Long = nextId++) = AccountTransactionEntity(
|
private fun map(transaction: AccountTransaction, userId: Long = nextId++, bankAccountId: Long = nextId++) = AccountTransactionEntity(
|
||||||
nextId++,
|
nextId++,
|
||||||
userAccountId, bankAccountId,
|
userId, 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.otherPartyBankId, transaction.otherPartyAccountId,
|
||||||
transaction.bookingText
|
transaction.postingText
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ 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.dataaccess.entities.AccountTransactionEntity
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
import net.codinux.log.logger
|
import net.codinux.log.logger
|
||||||
import kotlin.enums.EnumEntries
|
import kotlin.enums.EnumEntries
|
||||||
|
@ -25,42 +25,46 @@ open class SqliteBankingRepository(
|
||||||
|
|
||||||
private val log by logger()
|
private val log by logger()
|
||||||
|
|
||||||
override fun getAllUserAccounts(): List<UserAccountEntity> {
|
|
||||||
val bankAccounts = getAllBankAccounts().groupBy { it.userAccountId }
|
|
||||||
|
|
||||||
return userAccountQueries.selectAllUserAccounts { id, bankCode, loginName, password, bankName, bic, customerName, userId, selectedTanMethodId, selectedTanMediumName, bankingGroup, iconUrl, wrongCredentialsEntered, userSetDisplayName, displayIndex ->
|
override fun getAllUsers(): List<UserEntity> {
|
||||||
UserAccountEntity(id, bankCode, loginName, password, bankName, bic, customerName, userId, bankAccounts[id] ?: emptyList(), selectedTanMethodId, emptyList(), selectedTanMediumName, emptyList(),
|
val bankAccounts = getAllBankAccounts().groupBy { it.userId }
|
||||||
bankingGroup?.let { BankingGroup.valueOf(it) }, iconUrl, wrongCredentialsEntered, userSetDisplayName, displayIndex.toInt())
|
|
||||||
|
return userAccountQueries.selectAllUsers { id, bankCode, loginName, password, bankName, bic, customerName, userId, selectedTanMethodId, selectedTanMediumName, bankingGroup, iconUrl, wrongCredentialsEntered, userSetDisplayName, displayIndex ->
|
||||||
|
UserEntity(id, bankCode, loginName, password, bankName, bic, customerName, userId, bankAccounts[id] ?: emptyList(), selectedTanMethodId, emptyList(), selectedTanMediumName, emptyList(),
|
||||||
|
bankingGroup?.let { BankingGroup.valueOf(it) }, "", userSetDisplayName, displayIndex.toInt(), iconUrl, wrongCredentialsEntered)
|
||||||
}.executeAsList()
|
}.executeAsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun persistUserAccount(userAccount: UserAccount): UserAccountEntity {
|
override suspend fun persistUser(user: User): UserEntity {
|
||||||
return userAccountQueries.transactionWithResult {
|
return userAccountQueries.transactionWithResult {
|
||||||
userAccountQueries.insertUserAccount(userAccount.bankCode, userAccount.loginName, userAccount.password, userAccount.bankName, userAccount.bic,
|
userAccountQueries.insertUser(user.bankCode, user.loginName, user.password, user.bankName, user.bic,
|
||||||
userAccount.customerName, userAccount.userId, userAccount.selectedTanMethodId, userAccount.selectedTanMediumName,
|
user.customerName, user.userId, user.selectedTanMethodIdentifier, user.selectedTanMediumIdentifier,
|
||||||
userAccount.bankingGroup?.name, userAccount.iconUrl, userAccount.wrongCredentialsEntered, userAccount.userSetDisplayName, userAccount.displayIndex.toLong()
|
user.bankingGroup?.name, user.iconUrl, user.wrongCredentialsEntered, user.userSetDisplayName, user.displayIndex.toLong()
|
||||||
)
|
)
|
||||||
|
|
||||||
val userAccountId = getLastInsertedId() // getLastInsertedId() / last_insert_rowid() has to be called in a transaction with the insert operation, otherwise it will not work
|
val userId = getLastInsertedId() // getLastInsertedId() / last_insert_rowid() has to be called in a transaction with the insert operation, otherwise it will not work
|
||||||
|
|
||||||
val bankAccounts = persistBankAccounts(userAccountId, userAccount.accounts)
|
val bankAccounts = persistBankAccounts(userId, user.accounts)
|
||||||
|
|
||||||
UserAccountEntity(userAccountId, userAccount, bankAccounts)
|
UserEntity(userId, user, bankAccounts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun getAllBankAccounts(): List<BankAccountEntity> = userAccountQueries.selectAllBankAccounts { id, userAccountId, identifier, accountHolderName, type, iban, subAccountNumber, productName, currency, accountLimit, balance, isAccountTypeSupportedByApplication, features, countDaysForWhichTransactionsAreKept, lastTransactionsRetrievalTime, retrievedTransactionsFrom, userSetDisplayName, displayIndex, hideAccount, includeInAutomaticAccountsUpdate ->
|
fun getAllBankAccounts(): List<BankAccountEntity> = userAccountQueries.selectAllBankAccounts { id, userId, identifier, accountHolderName, type, iban, subAccountNumber, productName, currency, accountLimit, balance, isAccountTypeSupportedByApplication, features, serverTransactionsRetentionDays, lastTransactionsRetrievalTime, retrievedTransactionsFrom, userSetDisplayName, displayIndex, hideAccount, includeInAutomaticAccountsUpdate ->
|
||||||
BankAccountEntity(
|
BankAccountEntity(
|
||||||
id, userAccountId,
|
id, userId,
|
||||||
identifier, accountHolderName, BankAccountType.valueOf(type),
|
|
||||||
iban, subAccountNumber, productName, currency, accountLimit,
|
identifier, subAccountNumber, iban, productName,
|
||||||
|
accountHolderName, BankAccountType.valueOf(type),
|
||||||
|
currency, accountLimit,
|
||||||
|
|
||||||
mapToAmount(balance),
|
|
||||||
isAccountTypeSupportedByApplication, mapEnumSet(features, BankAccountFeatures.entries),
|
isAccountTypeSupportedByApplication, mapEnumSet(features, BankAccountFeatures.entries),
|
||||||
|
|
||||||
mapToInt(countDaysForWhichTransactionsAreKept),
|
mapToAmount(balance),
|
||||||
|
|
||||||
|
mapToInt(serverTransactionsRetentionDays),
|
||||||
mapToInstant(lastTransactionsRetrievalTime), mapToDate(retrievedTransactionsFrom),
|
mapToInstant(lastTransactionsRetrievalTime), mapToDate(retrievedTransactionsFrom),
|
||||||
|
|
||||||
mutableListOf(), mutableListOf(),
|
mutableListOf(), mutableListOf(),
|
||||||
|
@ -70,22 +74,22 @@ open class SqliteBankingRepository(
|
||||||
)
|
)
|
||||||
}.executeAsList()
|
}.executeAsList()
|
||||||
|
|
||||||
private suspend fun persistBankAccounts(userAccountId: Long, bankAccounts: Collection<BankAccount>): List<BankAccountEntity> =
|
private suspend fun persistBankAccounts(userId: Long, bankAccounts: Collection<BankAccount>): List<BankAccountEntity> =
|
||||||
bankAccounts.map { persistBankAccount(userAccountId, it) }
|
bankAccounts.map { persistBankAccount(userId, 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): BankAccountEntity {
|
private suspend fun persistBankAccount(userId: Long, account: BankAccount): BankAccountEntity {
|
||||||
userAccountQueries.insertBankAccount(
|
userAccountQueries.insertBankAccount(
|
||||||
userAccountId,
|
userId,
|
||||||
account.identifier, account.accountHolderName, mapEnum(account.type),
|
account.identifier, account.accountHolderName, mapEnum(account.type),
|
||||||
account.iban, account.subAccountNumber, account.productName, account.currency, account.accountLimit,
|
account.iban, account.subAccountNumber, account.productName, account.currency, account.accountLimit,
|
||||||
|
|
||||||
mapAmount(account.balance),
|
mapAmount(account.balance),
|
||||||
account.isAccountTypeSupportedByApplication, mapEnumCollectionToString(account.features),
|
account.isAccountTypeSupportedByApplication, mapEnumCollectionToString(account.features),
|
||||||
|
|
||||||
mapInt(account.countDaysForWhichTransactionsAreKept),
|
mapInt(account.serverTransactionsRetentionDays),
|
||||||
mapInstant(account.lastTransactionsRetrievalTime), mapDate(account.retrievedTransactionsFrom),
|
mapInstant(account.lastTransactionsRetrievalTime), mapDate(account.retrievedTransactionsFrom),
|
||||||
|
|
||||||
account.userSetDisplayName, mapInt(account.displayIndex),
|
account.userSetDisplayName, mapInt(account.displayIndex),
|
||||||
|
@ -95,25 +99,24 @@ open class SqliteBankingRepository(
|
||||||
val accountId = getLastInsertedId()
|
val accountId = getLastInsertedId()
|
||||||
|
|
||||||
val accountTransactionEntities = account.bookedTransactions.map { transaction ->
|
val accountTransactionEntities = account.bookedTransactions.map { transaction ->
|
||||||
persistTransaction(userAccountId, accountId, transaction)
|
persistTransaction(userId, accountId, transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
return BankAccountEntity(accountId, userAccountId, account, accountTransactionEntities)
|
return BankAccountEntity(accountId, userId, account, accountTransactionEntities)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel> =
|
override fun getAllAccountTransactionsAsViewModel(): List<AccountTransactionViewModel> =
|
||||||
// TODO: find a better way to express the reference value to display, sepaReference or (unparsed)reference
|
accountTransactionQueries.selectAllTransactionsAsViewModel { id, userId, bankAccountId, amount, currency, reference, valueDate, otherPartyName, postingText, userSetDisplayName, category ->
|
||||||
accountTransactionQueries.selectAllTransactionsAsViewModel { id, userAccountId, bankAccountId, amount, currency, unparsedReference, valueDate, otherPartyName, bookingText, sepaReference, userSetDisplayName, category ->
|
AccountTransactionViewModel(id, userId, bankAccountId, mapToAmount(amount), currency, reference, mapToDate(valueDate), otherPartyName, postingText, userSetDisplayName, category)
|
||||||
AccountTransactionViewModel(id, userAccountId, bankAccountId, mapToAmount(amount), currency, sepaReference ?: unparsedReference, mapToDate(valueDate), otherPartyName, bookingText, userSetDisplayName, category)
|
|
||||||
}.executeAsList()
|
}.executeAsList()
|
||||||
|
|
||||||
override fun getAllAccountTransactions(): List<AccountTransactionEntity> {
|
override fun getAllAccountTransactions(): List<AccountTransactionEntity> {
|
||||||
return accountTransactionQueries.selectAllTransactions(::mapTransaction).executeAsList()
|
return accountTransactionQueries.selectAllTransactions(::mapTransaction).executeAsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAllTransactionsOfUserAccount(userAccount: UserAccountEntity): List<AccountTransactionEntity> {
|
override fun getAllTransactionsOfUser(user: UserEntity): List<AccountTransactionEntity> {
|
||||||
return accountTransactionQueries.selectAllTransactionsOfUserAccount(userAccount.id, ::mapTransaction).executeAsList()
|
return accountTransactionQueries.selectAllTransactionsOfUser(user.id, ::mapTransaction).executeAsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTransactionById(transactionId: Long): AccountTransactionEntity? =
|
override fun getTransactionById(transactionId: Long): AccountTransactionEntity? =
|
||||||
|
@ -123,7 +126,7 @@ open class SqliteBankingRepository(
|
||||||
override suspend fun persistTransactions(bankAccount: BankAccountEntity, transactions: List<AccountTransaction>): List<AccountTransactionEntity> {
|
override suspend fun persistTransactions(bankAccount: BankAccountEntity, transactions: List<AccountTransaction>): List<AccountTransactionEntity> {
|
||||||
return accountTransactionQueries.transactionWithResult {
|
return accountTransactionQueries.transactionWithResult {
|
||||||
transactions.map { transaction ->
|
transactions.map { transaction ->
|
||||||
persistTransaction(bankAccount.userAccountId, bankAccount.id, transaction)
|
persistTransaction(bankAccount.userId, bankAccount.id, transaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,36 +134,34 @@ open class SqliteBankingRepository(
|
||||||
/**
|
/**
|
||||||
* Has to be executed in a transaction in order that getting persisted AccountTransaction's id works~
|
* Has to be executed in a transaction in order that getting persisted AccountTransaction's id works~
|
||||||
*/
|
*/
|
||||||
protected open suspend fun persistTransaction(userAccountId: Long, bankAccountId: Long, transaction: AccountTransaction): AccountTransactionEntity {
|
protected open suspend fun persistTransaction(userId: Long, bankAccountId: Long, transaction: AccountTransaction): AccountTransactionEntity {
|
||||||
accountTransactionQueries.insertTransaction(
|
accountTransactionQueries.insertTransaction(
|
||||||
userAccountId, bankAccountId,
|
userId, bankAccountId,
|
||||||
|
|
||||||
mapAmount(transaction.amount), transaction.currency, transaction.unparsedReference,
|
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.bookingText,
|
|
||||||
|
|
||||||
transaction.userSetDisplayName, null, transaction.notes, // TODO: add category to AccountTransaction
|
transaction.otherPartyName, transaction.otherPartyBankId, transaction.otherPartyAccountId,
|
||||||
|
transaction.postingText,
|
||||||
|
|
||||||
transaction.information,
|
transaction.userSetDisplayName, transaction.category, transaction.notes,
|
||||||
transaction.statementNumber?.toLong(), transaction.sequenceNumber?.toLong(),
|
|
||||||
|
transaction.statementNumber?.toLong(), transaction.sheetNumber?.toLong(),
|
||||||
mapAmount(transaction.openingBalance), mapAmount(transaction.closingBalance),
|
mapAmount(transaction.openingBalance), mapAmount(transaction.closingBalance),
|
||||||
|
|
||||||
transaction.endToEndReference, transaction.customerReference, transaction.mandateReference,
|
transaction.endToEndReference, transaction.customerReference, transaction.mandateReference,
|
||||||
transaction.creditorIdentifier, transaction.originatorsIdentificationCode,
|
transaction.creditorIdentifier, transaction.originatorsIdentificationCode,
|
||||||
|
|
||||||
transaction.compensationAmount, transaction.originalAmount,
|
transaction.compensationAmount, transaction.originalAmount,
|
||||||
transaction.sepaReference,
|
|
||||||
transaction.deviantOriginator, transaction.deviantRecipient,
|
transaction.deviantOriginator, transaction.deviantRecipient,
|
||||||
transaction.referenceWithNoSpecialType, transaction.primaNotaNumber, transaction.textKeySupplement,
|
transaction.referenceWithNoSpecialType,
|
||||||
|
|
||||||
transaction.currencyType, transaction.bookingKey,
|
transaction.journalNumber, transaction.textKeyAddition,
|
||||||
transaction.referenceForTheAccountOwner, transaction.referenceOfTheAccountServicingInstitution,
|
|
||||||
transaction.supplementaryDetails,
|
|
||||||
|
|
||||||
transaction.transactionReferenceNumber, transaction.relatedReferenceNumber
|
transaction.orderReferenceNumber, transaction.referenceNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
return AccountTransactionEntity(getLastInsertedId(), userAccountId, bankAccountId, transaction)
|
return AccountTransactionEntity(getLastInsertedId(), userId, bankAccountId, transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,46 +170,59 @@ open class SqliteBankingRepository(
|
||||||
|
|
||||||
|
|
||||||
private fun mapTransaction(
|
private fun mapTransaction(
|
||||||
id: Long, userAccountId: Long, bankAccountId: Long,
|
id: Long, userId: Long, bankAccountId: Long,
|
||||||
amount: String, currency: String, reference: String, bookingDate: String, valueDate: String,
|
|
||||||
otherPartyName: String?, otherPartyBankCode: String?, otherPartyAccountId: String?, bookingText: String?,
|
amount: String, currency: String, reference: String?,
|
||||||
|
bookingDate: String, valueDate: String,
|
||||||
|
|
||||||
|
otherPartyName: String?, otherPartyBankId: String?, otherPartyAccountId: String?,
|
||||||
|
postingText: String?,
|
||||||
|
|
||||||
userSetDisplayName: String?, category: String?, notes: String?,
|
userSetDisplayName: String?, category: String?, notes: String?,
|
||||||
information: String?, statementNumber: Long?, sequenceNumber: Long?,
|
|
||||||
|
statementNumber: Long?, sheetNumber: Long?,
|
||||||
|
|
||||||
openingBalance: String?, closingBalance: String?,
|
openingBalance: String?, closingBalance: String?,
|
||||||
|
|
||||||
endToEndReference: String?, customerReference: String?, mandateReference: String?, creditorIdentifier: String?, originatorsIdentificationCode: String?,
|
endToEndReference: String?, customerReference: String?, mandateReference: String?, creditorIdentifier: String?, originatorsIdentificationCode: String?,
|
||||||
compensationAmount: String?, originalAmount: String?, sepaReference: String?, deviantOriginator: String?, deviantRecipient: String?, referenceWithNoSpecialType: String?,
|
|
||||||
primaNotaNumber: String?, textKeySupplement: String?, currencyType: String?, bookingKey: String?, referenceForTheAccountOwner: String?, referenceOfTheAccountServicingInstitution: String?,
|
|
||||||
supplementaryDetails: String?, transactionReferenceNumber: String?, relatedReferenceNumber: String?): AccountTransactionEntity =
|
|
||||||
AccountTransactionEntity(
|
|
||||||
id,
|
|
||||||
userAccountId, bankAccountId,
|
|
||||||
|
|
||||||
Amount(amount), currency, reference,
|
compensationAmount: String?, originalAmount: String?, deviantOriginator: String?, deviantRecipient: String?, referenceWithNoSpecialType: String?,
|
||||||
mapToDate(bookingDate), mapToDate(valueDate),
|
|
||||||
otherPartyName, otherPartyBankCode, otherPartyAccountId,
|
|
||||||
bookingText,
|
|
||||||
|
|
||||||
userSetDisplayName, category, notes,
|
journalNumber: String?, textKeyAddition: String?,
|
||||||
|
|
||||||
information,
|
referenceForTheAccountOwner: String?, referenceOfTheAccountServicingInstitution: String?, supplementaryDetails: String?,
|
||||||
statementNumber?.toInt(), sequenceNumber?.toInt(),
|
|
||||||
|
|
||||||
mapToAmount(openingBalance), mapToAmount(closingBalance),
|
transactionReferenceNumber: String?, relatedReferenceNumber: String?
|
||||||
|
): AccountTransactionEntity = AccountTransactionEntity(
|
||||||
|
id,
|
||||||
|
userId, bankAccountId,
|
||||||
|
|
||||||
endToEndReference, customerReference, mandateReference,
|
Amount(amount), currency, reference,
|
||||||
creditorIdentifier, originatorsIdentificationCode,
|
mapToDate(bookingDate), mapToDate(valueDate),
|
||||||
compensationAmount, originalAmount,
|
otherPartyName, otherPartyBankId, otherPartyAccountId,
|
||||||
sepaReference,
|
postingText,
|
||||||
deviantOriginator, deviantRecipient,
|
|
||||||
referenceWithNoSpecialType, primaNotaNumber,
|
|
||||||
textKeySupplement,
|
|
||||||
|
|
||||||
currencyType, bookingKey,
|
mapToAmount(openingBalance), mapToAmount(closingBalance),
|
||||||
referenceForTheAccountOwner, referenceOfTheAccountServicingInstitution,
|
|
||||||
supplementaryDetails,
|
|
||||||
|
|
||||||
transactionReferenceNumber, relatedReferenceNumber
|
userSetDisplayName, category, notes,
|
||||||
)
|
|
||||||
|
statementNumber?.toInt(), sheetNumber?.toInt(),
|
||||||
|
|
||||||
|
referenceForTheAccountOwner, referenceOfTheAccountServicingInstitution,
|
||||||
|
supplementaryDetails,
|
||||||
|
|
||||||
|
endToEndReference, mandateReference,
|
||||||
|
creditorIdentifier, originatorsIdentificationCode,
|
||||||
|
|
||||||
|
compensationAmount, originalAmount,
|
||||||
|
deviantOriginator, deviantRecipient,
|
||||||
|
referenceWithNoSpecialType,
|
||||||
|
|
||||||
|
journalNumber, textKeyAddition,
|
||||||
|
|
||||||
|
transactionReferenceNumber, relatedReferenceNumber
|
||||||
|
// TODO: add isReversal
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@JvmName("mapAmount")
|
@JvmName("mapAmount")
|
||||||
|
|
|
@ -6,108 +6,117 @@ import net.codinux.banking.client.model.Amount
|
||||||
|
|
||||||
class AccountTransactionEntity(
|
class AccountTransactionEntity(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val userAccountId: Long,
|
val userId: Long,
|
||||||
val bankAccountId: Long,
|
val bankAccountId: Long,
|
||||||
|
|
||||||
amount: Amount,
|
amount: Amount,
|
||||||
currency: String,
|
currency: String,
|
||||||
reference: String,
|
reference: String?,
|
||||||
|
|
||||||
bookingDate: LocalDate,
|
bookingDate: LocalDate,
|
||||||
valueDate: LocalDate,
|
valueDate: LocalDate,
|
||||||
|
|
||||||
otherPartyName: String? = null,
|
otherPartyName: String? = null,
|
||||||
otherPartyBankCode: String? = null,
|
otherPartyBankId: String? = null,
|
||||||
otherPartyAccountId: String? = null,
|
otherPartyAccountId: String? = null,
|
||||||
|
|
||||||
bookingText: String? = null,
|
postingText: String? = null,
|
||||||
|
|
||||||
userSetDisplayName: String? = null,
|
|
||||||
category: String? = null,
|
|
||||||
notes: String? = null,
|
|
||||||
information: String? = null,
|
|
||||||
|
|
||||||
statementNumber: Int? = null,
|
|
||||||
sequenceNumber: Int? = null,
|
|
||||||
|
|
||||||
openingBalance: Amount? = null,
|
openingBalance: Amount? = null,
|
||||||
closingBalance: Amount? = null,
|
closingBalance: Amount? = null,
|
||||||
|
|
||||||
endToEndReference: String? = null,
|
userSetDisplayName: String? = null,
|
||||||
|
category: String? = null,
|
||||||
|
notes: String? = null,
|
||||||
|
|
||||||
|
statementNumber: Int? = null,
|
||||||
|
sheetNumber: Int? = null,
|
||||||
|
|
||||||
customerReference: String? = null,
|
customerReference: String? = null,
|
||||||
|
bankReference: String? = null,
|
||||||
|
furtherInformation: String? = null,
|
||||||
|
|
||||||
|
|
||||||
|
endToEndReference: String? = null,
|
||||||
mandateReference: String? = null,
|
mandateReference: String? = null,
|
||||||
creditorIdentifier: String? = null,
|
creditorIdentifier: String? = null,
|
||||||
originatorsIdentificationCode: String? = null,
|
originatorsIdentificationCode: String? = null,
|
||||||
|
|
||||||
compensationAmount: String? = null,
|
compensationAmount: String? = null,
|
||||||
originalAmount: String? = null,
|
originalAmount: String? = null,
|
||||||
sepaReference: String? = null,
|
|
||||||
deviantOriginator: String? = null,
|
deviantOriginator: String? = null,
|
||||||
deviantRecipient: String? = null,
|
deviantRecipient: String? = null,
|
||||||
referenceWithNoSpecialType: String? = null,
|
referenceWithNoSpecialType: String? = null,
|
||||||
primaNotaNumber: String? = null,
|
|
||||||
textKeySupplement: String? = null,
|
|
||||||
|
|
||||||
currencyType: String? = null,
|
journalNumber: String? = null,
|
||||||
bookingKey: String? = null,
|
textKeyAddition: String? = null,
|
||||||
referenceForTheAccountOwner: String? = null,
|
|
||||||
referenceOfTheAccountServicingInstitution: String? = null,
|
|
||||||
supplementaryDetails: String? = null,
|
|
||||||
|
|
||||||
transactionReferenceNumber: String? = null,
|
orderReferenceNumber: String? = null,
|
||||||
relatedReferenceNumber: String? = null
|
referenceNumber: String? = null,
|
||||||
|
|
||||||
|
isReversal: Boolean = false,
|
||||||
) : AccountTransaction(
|
) : AccountTransaction(
|
||||||
amount, currency, reference,
|
amount, currency, reference,
|
||||||
bookingDate, valueDate,
|
bookingDate, valueDate,
|
||||||
otherPartyName, otherPartyBankCode, otherPartyAccountId,
|
otherPartyName, otherPartyBankId, otherPartyAccountId,
|
||||||
bookingText,
|
postingText,
|
||||||
|
|
||||||
information,
|
|
||||||
statementNumber, sequenceNumber,
|
|
||||||
openingBalance, closingBalance,
|
openingBalance, closingBalance,
|
||||||
|
|
||||||
endToEndReference, customerReference, mandateReference,
|
statementNumber, sheetNumber,
|
||||||
|
|
||||||
|
customerReference, bankReference, furtherInformation,
|
||||||
|
|
||||||
|
endToEndReference, mandateReference,
|
||||||
creditorIdentifier, originatorsIdentificationCode,
|
creditorIdentifier, originatorsIdentificationCode,
|
||||||
|
|
||||||
compensationAmount, originalAmount,
|
compensationAmount, originalAmount,
|
||||||
sepaReference,
|
|
||||||
deviantOriginator, deviantRecipient,
|
deviantOriginator, deviantRecipient,
|
||||||
referenceWithNoSpecialType, primaNotaNumber,
|
referenceWithNoSpecialType,
|
||||||
textKeySupplement,
|
|
||||||
|
|
||||||
currencyType, bookingKey,
|
journalNumber, textKeyAddition,
|
||||||
referenceForTheAccountOwner, referenceOfTheAccountServicingInstitution,
|
|
||||||
supplementaryDetails,
|
|
||||||
|
|
||||||
transactionReferenceNumber, relatedReferenceNumber,
|
orderReferenceNumber, referenceNumber,
|
||||||
|
|
||||||
|
isReversal,
|
||||||
|
|
||||||
userSetDisplayName, category, notes
|
userSetDisplayName, category, notes
|
||||||
) {
|
) {
|
||||||
constructor(id: Long, userAccountId: Long, bankAccountId: Long, transaction: AccountTransaction) : this(
|
constructor(id: Long, userId: Long, bankAccountId: Long, transaction: AccountTransaction) : this(
|
||||||
id, userAccountId, bankAccountId,
|
id, userId, bankAccountId,
|
||||||
transaction.amount, transaction.currency, transaction.unparsedReference, transaction.bookingDate, transaction.valueDate,
|
transaction.amount, transaction.currency, transaction.reference,
|
||||||
transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId, transaction.bookingText,
|
transaction.bookingDate, transaction.valueDate,
|
||||||
|
|
||||||
transaction.userSetDisplayName, transaction.category, transaction.notes, transaction.information,
|
transaction.otherPartyName, transaction.otherPartyBankId, transaction.otherPartyAccountId,
|
||||||
|
|
||||||
|
transaction.postingText,
|
||||||
|
|
||||||
transaction.statementNumber, transaction.sequenceNumber,
|
|
||||||
transaction.openingBalance, transaction.closingBalance,
|
transaction.openingBalance, transaction.closingBalance,
|
||||||
|
|
||||||
transaction.endToEndReference, transaction.customerReference, transaction.mandateReference,
|
transaction.userSetDisplayName, transaction.category, transaction.notes,
|
||||||
|
|
||||||
|
transaction.statementNumber, transaction.sheetNumber,
|
||||||
|
|
||||||
|
transaction.customerReference, transaction.bankReference,
|
||||||
|
transaction.furtherInformation,
|
||||||
|
|
||||||
|
transaction.endToEndReference, transaction.mandateReference,
|
||||||
transaction.creditorIdentifier, transaction.originatorsIdentificationCode,
|
transaction.creditorIdentifier, transaction.originatorsIdentificationCode,
|
||||||
|
|
||||||
transaction.compensationAmount, transaction.originalAmount,
|
transaction.compensationAmount, transaction.originalAmount,
|
||||||
transaction.sepaReference,
|
|
||||||
transaction.deviantOriginator, transaction.deviantRecipient,
|
transaction.deviantOriginator, transaction.deviantRecipient,
|
||||||
transaction.referenceWithNoSpecialType, transaction.primaNotaNumber, transaction.textKeySupplement,
|
transaction.referenceWithNoSpecialType,
|
||||||
|
|
||||||
transaction.currencyType, transaction.bookingKey,
|
transaction.journalNumber, transaction.textKeyAddition,
|
||||||
transaction.referenceForTheAccountOwner, transaction.referenceOfTheAccountServicingInstitution,
|
|
||||||
transaction.supplementaryDetails,
|
|
||||||
|
|
||||||
transaction.transactionReferenceNumber, transaction.relatedReferenceNumber
|
transaction.orderReferenceNumber, transaction.referenceNumber,
|
||||||
|
|
||||||
|
transaction.isReversal,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
override val identifier: String by lazy {
|
override val identifier: String by lazy {
|
||||||
"$userAccountId ${super.identifier}"
|
"$userId ${super.identifier}"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -6,28 +6,29 @@ import net.codinux.banking.client.model.*
|
||||||
|
|
||||||
class BankAccountEntity(
|
class BankAccountEntity(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val userAccountId: Long,
|
val userId: Long,
|
||||||
|
|
||||||
identifier: String,
|
identifier: String,
|
||||||
|
subAccountNumber: String? = null,
|
||||||
|
iban: String? = null,
|
||||||
|
productName: String? = null,
|
||||||
|
|
||||||
accountHolderName: String,
|
accountHolderName: String,
|
||||||
type: BankAccountType = BankAccountType.Other,
|
type: BankAccountType = BankAccountType.Other,
|
||||||
iban: String? = null,
|
|
||||||
subAccountNumber: String? = null,
|
|
||||||
productName: String? = null,
|
|
||||||
currency: String = "EUR",
|
currency: String = "EUR",
|
||||||
accountLimit: String? = null,
|
accountLimit: String? = null,
|
||||||
|
|
||||||
balance: Amount = Amount.Zero, // TODO: add a BigDecimal library
|
|
||||||
|
|
||||||
isAccountTypeSupportedByApplication: Boolean = true,
|
isAccountTypeSupportedByApplication: Boolean = true,
|
||||||
features: Set<BankAccountFeatures> = emptySet(),
|
features: Set<BankAccountFeatures> = emptySet(),
|
||||||
|
|
||||||
countDaysForWhichTransactionsAreKept: Int? = null,
|
balance: Amount = Amount.Zero, // TODO: add a BigDecimal library
|
||||||
|
|
||||||
|
serverTransactionsRetentionDays: Int? = null,
|
||||||
lastTransactionsRetrievalTime: Instant? = null,
|
lastTransactionsRetrievalTime: Instant? = null,
|
||||||
retrievedTransactionsFrom: LocalDate? = null,
|
retrievedTransactionsFrom: LocalDate? = null,
|
||||||
|
|
||||||
bookedTransactions: MutableList<AccountTransactionEntity> = mutableListOf(),
|
bookedTransactions: MutableList<AccountTransactionEntity> = mutableListOf(),
|
||||||
unbookedTransactions: MutableList<UnbookedAccountTransaction> = mutableListOf(),
|
prebookedTransactions: MutableList<PrebookedAccountTransaction> = mutableListOf(),
|
||||||
|
|
||||||
userSetDisplayName: String? = null,
|
userSetDisplayName: String? = null,
|
||||||
displayIndex: Int = 0,
|
displayIndex: Int = 0,
|
||||||
|
@ -35,21 +36,39 @@ class BankAccountEntity(
|
||||||
hideAccount: Boolean = false,
|
hideAccount: Boolean = false,
|
||||||
includeInAutomaticAccountsUpdate: Boolean = true
|
includeInAutomaticAccountsUpdate: Boolean = true
|
||||||
) : BankAccount(
|
) : BankAccount(
|
||||||
identifier, accountHolderName, type, iban, subAccountNumber, productName, currency, accountLimit,
|
identifier, subAccountNumber, iban, productName,
|
||||||
balance, isAccountTypeSupportedByApplication, features,
|
|
||||||
lastTransactionsRetrievalTime, retrievedTransactionsFrom, countDaysForWhichTransactionsAreKept,
|
accountHolderName, type, currency, accountLimit,
|
||||||
bookedTransactions as MutableList<AccountTransaction>, unbookedTransactions,
|
|
||||||
userSetDisplayName, displayIndex, hideAccount, includeInAutomaticAccountsUpdate
|
isAccountTypeSupportedByApplication, features,
|
||||||
|
|
||||||
|
balance,
|
||||||
|
|
||||||
|
serverTransactionsRetentionDays, lastTransactionsRetrievalTime, retrievedTransactionsFrom,
|
||||||
|
|
||||||
|
bookedTransactions as MutableList<AccountTransaction>, prebookedTransactions,
|
||||||
|
|
||||||
|
userSetDisplayName, displayIndex,
|
||||||
|
hideAccount, includeInAutomaticAccountsUpdate
|
||||||
) {
|
) {
|
||||||
constructor(id: Long, userAccountId: Long, account: BankAccount, transactions: List<AccountTransactionEntity> = emptyList()) : this(
|
constructor(id: Long, userId: Long, account: BankAccount, transactions: List<AccountTransactionEntity> = emptyList()) : this(
|
||||||
id, userAccountId,
|
id, userId,
|
||||||
account.identifier, account.accountHolderName, account.type, account.iban, account.subAccountNumber,
|
account.identifier, account.subAccountNumber, account.iban, account.productName,
|
||||||
account.productName, account.currency, account.accountLimit,
|
|
||||||
account.balance,
|
account.accountHolderName, account.type,
|
||||||
|
account.currency, account.accountLimit,
|
||||||
|
|
||||||
account.isAccountTypeSupportedByApplication, account.features,
|
account.isAccountTypeSupportedByApplication, account.features,
|
||||||
account.countDaysForWhichTransactionsAreKept, account.lastTransactionsRetrievalTime, account.retrievedTransactionsFrom,
|
|
||||||
|
account.balance,
|
||||||
|
|
||||||
|
account.serverTransactionsRetentionDays,
|
||||||
|
account.lastTransactionsRetrievalTime, account.retrievedTransactionsFrom,
|
||||||
|
|
||||||
transactions.toMutableList(), mutableListOf(),
|
transactions.toMutableList(), mutableListOf(),
|
||||||
account.userSetDisplayName, account.displayIndex, account.hideAccount, account.includeInAutomaticAccountsUpdate
|
|
||||||
|
account.userSetDisplayName, account.displayIndex,
|
||||||
|
account.hideAccount, account.includeInAutomaticAccountsUpdate
|
||||||
)
|
)
|
||||||
|
|
||||||
val bookedTransactionsEntities: MutableList<AccountTransactionEntity> = bookedTransactions
|
val bookedTransactionsEntities: MutableList<AccountTransactionEntity> = bookedTransactions
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package net.codinux.banking.dataaccess.entities
|
package net.codinux.banking.dataaccess.entities
|
||||||
|
|
||||||
import net.codinux.banking.client.model.BankingGroup
|
import net.codinux.banking.client.model.BankingGroup
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.User
|
||||||
import net.codinux.banking.client.model.tan.TanMedium
|
import net.codinux.banking.client.model.tan.TanMedium
|
||||||
import net.codinux.banking.client.model.tan.TanMethod
|
import net.codinux.banking.client.model.tan.TanMethod
|
||||||
|
|
||||||
class UserAccountEntity(
|
class UserEntity(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
|
|
||||||
bankCode: String,
|
bankCode: String,
|
||||||
loginName: String,
|
loginName: String,
|
||||||
password: String?,
|
password: String?,
|
||||||
|
@ -16,38 +16,43 @@ class UserAccountEntity(
|
||||||
bic: String,
|
bic: String,
|
||||||
|
|
||||||
customerName: String,
|
customerName: String,
|
||||||
userId: String = loginName,
|
userId: String? = null,
|
||||||
|
|
||||||
override val accounts: List<BankAccountEntity> = emptyList(),
|
override val accounts: List<BankAccountEntity> = emptyList(),
|
||||||
|
|
||||||
selectedTanMethodId: String? = null,
|
selectedTanMethodIdentifier: String? = null,
|
||||||
tanMethods: List<TanMethod> = listOf(),
|
tanMethods: List<TanMethod> = listOf(),
|
||||||
|
|
||||||
selectedTanMediumName: String? = null,
|
selectedTanMediumIdentifier: String? = null,
|
||||||
tanMedia: List<TanMedium> = listOf(),
|
tanMedia: List<TanMedium> = listOf(),
|
||||||
|
|
||||||
bankingGroup: BankingGroup? = null,
|
bankingGroup: BankingGroup? = null,
|
||||||
iconUrl: String? = null,
|
finTsServerAddress: String,
|
||||||
|
|
||||||
wrongCredentialsEntered: Boolean = false,
|
|
||||||
|
|
||||||
userSetDisplayName: String? = null,
|
userSetDisplayName: String? = null,
|
||||||
displayIndex: Int = 0
|
displayIndex: Int = 0,
|
||||||
) : UserAccount(bankCode, loginName, password, bankName, bic, customerName, userId, accounts, selectedTanMethodId, tanMethods, selectedTanMediumName, tanMedia, bankingGroup, iconUrl) {
|
|
||||||
|
iconUrl: String? = null,
|
||||||
|
wrongCredentialsEntered: Boolean = false
|
||||||
|
) : User(bankCode, loginName, password, bankName, bic, customerName, userId, accounts, selectedTanMethodIdentifier, tanMethods, selectedTanMediumIdentifier, tanMedia, bankingGroup, finTsServerAddress) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.wrongCredentialsEntered = wrongCredentialsEntered
|
|
||||||
this.userSetDisplayName = userSetDisplayName
|
this.userSetDisplayName = userSetDisplayName
|
||||||
this.displayIndex = displayIndex
|
this.displayIndex = displayIndex
|
||||||
|
|
||||||
|
this.iconUrl = iconUrl
|
||||||
|
this.wrongCredentialsEntered = wrongCredentialsEntered
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
constructor(id: Long, user: UserAccount, bankAccounts: List<BankAccountEntity>) : this(
|
constructor(id: Long, user: User, 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,
|
||||||
bankAccounts,
|
bankAccounts,
|
||||||
user.selectedTanMethodId, emptyList(), user.selectedTanMediumName, emptyList(),
|
user.selectedTanMethodIdentifier, user.tanMethods, user.selectedTanMediumIdentifier, user.tanMedia,
|
||||||
user.bankingGroup, user.iconUrl, user.wrongCredentialsEntered, user.userSetDisplayName, user.displayIndex
|
user.bankingGroup, user.finTsServerAddress,
|
||||||
|
user.userSetDisplayName, user.displayIndex,
|
||||||
|
user.iconUrl, user.wrongCredentialsEntered,
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package net.codinux.banking.ui.appskeleton
|
package net.codinux.banking.ui.appskeleton
|
||||||
|
|
||||||
import androidx.compose.animation.*
|
import androidx.compose.animation.*
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
@ -18,13 +17,9 @@ import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.key.*
|
import androidx.compose.ui.input.key.*
|
||||||
import androidx.compose.ui.layout.onGloballyPositioned
|
|
||||||
import androidx.compose.ui.platform.LocalViewConfiguration
|
|
||||||
import androidx.compose.ui.platform.LocalWindowInfo
|
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.toSize
|
|
||||||
import bankmeister.composeapp.generated.resources.Res
|
import bankmeister.composeapp.generated.resources.Res
|
||||||
import bankmeister.composeapp.generated.resources.filter_alt
|
import bankmeister.composeapp.generated.resources.filter_alt
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -39,7 +34,7 @@ private val IconWidth = 48.dp
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomBar(showMenuDrawer: Boolean = true) {
|
fun BottomBar(showMenuDrawer: Boolean = true) {
|
||||||
val userAccounts by uiState.userAccounts.collectAsState()
|
val users by uiState.users.collectAsState()
|
||||||
|
|
||||||
val transactionsFilter by uiState.transactionsFilter.collectAsState()
|
val transactionsFilter by uiState.transactionsFilter.collectAsState()
|
||||||
|
|
||||||
|
@ -75,7 +70,7 @@ fun BottomBar(showMenuDrawer: Boolean = true) {
|
||||||
} else if (selectedAccount.bankAccount != null) {
|
} else if (selectedAccount.bankAccount != null) {
|
||||||
selectedAccount.bankAccount.displayName
|
selectedAccount.bankAccount.displayName
|
||||||
} else {
|
} else {
|
||||||
selectedAccount.userAccount.displayName
|
selectedAccount.user.displayName
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(title, color = color, maxLines = 1, overflow = TextOverflow.Ellipsis)
|
Text(title, color = color, maxLines = 1, overflow = TextOverflow.Ellipsis)
|
||||||
|
@ -132,7 +127,7 @@ fun BottomBar(showMenuDrawer: Boolean = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (userAccounts.isNotEmpty()) {
|
if (users.isNotEmpty()) {
|
||||||
if (showSearchbar == false) {
|
if (showSearchbar == false) {
|
||||||
Row(Modifier.fillMaxHeight().widthIn(IconWidth, IconWidth), verticalAlignment = Alignment.CenterVertically) {
|
Row(Modifier.fillMaxHeight().widthIn(IconWidth, IconWidth), verticalAlignment = Alignment.CenterVertically) {
|
||||||
IconButton({ showSearchbar = true }, Modifier.width(IconWidth)) {
|
IconButton({ showSearchbar = true }, Modifier.width(IconWidth)) {
|
||||||
|
|
|
@ -54,7 +54,7 @@ private val VerticalSpacing = 8.dp
|
||||||
fun SideMenuContent() {
|
fun SideMenuContent() {
|
||||||
val drawerState = uiState.drawerState.collectAsState().value
|
val drawerState = uiState.drawerState.collectAsState().value
|
||||||
|
|
||||||
val accounts = uiState.userAccounts.collectAsState().value
|
val accounts = uiState.users.collectAsState().value
|
||||||
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.User
|
||||||
import net.codinux.banking.client.model.UserAccountViewInfo
|
import net.codinux.banking.client.model.BankViewInfo
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
import net.codinux.banking.ui.model.BankInfo
|
import net.codinux.banking.ui.model.BankInfo
|
||||||
import net.dankito.banking.banklistcreator.prettifier.BankingGroupMapper
|
import net.dankito.banking.banklistcreator.prettifier.BankingGroupMapper
|
||||||
|
@ -22,8 +22,8 @@ private val bankIconService = DI.bankIconService
|
||||||
private val DefaultIconModifier: Modifier = Modifier.size(16.dp)
|
private val DefaultIconModifier: Modifier = Modifier.size(16.dp)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BankIcon(userAccount: UserAccount?, modifier: Modifier = Modifier, iconModifier: Modifier = DefaultIconModifier, iconResource: DrawableResource? = null) {
|
fun BankIcon(user: User?, modifier: Modifier = Modifier, iconModifier: Modifier = DefaultIconModifier, iconResource: DrawableResource? = null) {
|
||||||
val iconUrl by remember(userAccount?.bic) { mutableStateOf(userAccount?.let { bankIconService.findIconForBank(it) }) }
|
val iconUrl by remember(user?.bic) { mutableStateOf(user?.let { bankIconService.findIconForBank(it) }) }
|
||||||
|
|
||||||
BankIcon(iconUrl, modifier, iconModifier, iconResource = iconResource)
|
BankIcon(iconUrl, modifier, iconModifier, iconResource = iconResource)
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,8 @@ fun BankIcon(bank: BankInfo, modifier: Modifier = Modifier, iconModifier: Modifi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BankIcon(userAccount: UserAccountViewInfo?, modifier: Modifier = Modifier, iconModifier: Modifier = DefaultIconModifier, iconResource: DrawableResource? = null) {
|
fun BankIcon(user: BankViewInfo?, modifier: Modifier = Modifier, iconModifier: Modifier = DefaultIconModifier, iconResource: DrawableResource? = null) {
|
||||||
val iconUrl = userAccount?.let { bankIconService.findIconForBank(it.bankName, it.bankingGroup) }
|
val iconUrl = user?.let { bankIconService.findIconForBank(it.bankName, it.bankingGroup) }
|
||||||
|
|
||||||
BankIcon(iconUrl, modifier, iconModifier, iconResource = iconResource)
|
BankIcon(iconUrl, modifier, iconModifier, iconResource = iconResource)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import bankmeister.composeapp.generated.resources.Res
|
import bankmeister.composeapp.generated.resources.Res
|
||||||
import bankmeister.composeapp.generated.resources.account
|
import bankmeister.composeapp.generated.resources.account
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
|
|
||||||
private val uiState = DI.uiState
|
private val uiState = DI.uiState
|
||||||
|
@ -24,9 +24,9 @@ fun BanksList(
|
||||||
textColor: Color = Color.White,
|
textColor: Color = Color.White,
|
||||||
itemModifier: Modifier = Modifier.height(48.dp).widthIn(min = 300.dp),
|
itemModifier: Modifier = Modifier.height(48.dp).widthIn(min = 300.dp),
|
||||||
itemHorizontalPadding: Dp = 8.dp,
|
itemHorizontalPadding: Dp = 8.dp,
|
||||||
accountSelected: ((UserAccountEntity?, BankAccountEntity?) -> Unit)? = null
|
accountSelected: ((UserEntity?, BankAccountEntity?) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
val userAccounts = uiState.userAccounts.collectAsState()
|
val users = uiState.users.collectAsState()
|
||||||
|
|
||||||
|
|
||||||
Column(modifier) {
|
Column(modifier) {
|
||||||
|
@ -34,16 +34,16 @@ fun BanksList(
|
||||||
accountSelected?.invoke(null, null)
|
accountSelected?.invoke(null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
userAccounts.value.sortedBy { it.displayIndex }.forEach { userAccount ->
|
users.value.sortedBy { it.displayIndex }.forEach { user ->
|
||||||
Spacer(Modifier.fillMaxWidth().height(12.dp))
|
Spacer(Modifier.fillMaxWidth().height(12.dp))
|
||||||
|
|
||||||
NavigationMenuItem(itemModifier, userAccount.displayName, textColor, iconSize, IconTextSpacing, itemHorizontalPadding, userAccount, iconResource = Res.drawable.account) {
|
NavigationMenuItem(itemModifier, user.displayName, textColor, iconSize, IconTextSpacing, itemHorizontalPadding, user, iconResource = Res.drawable.account) {
|
||||||
accountSelected?.invoke(userAccount, null)
|
accountSelected?.invoke(user, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
userAccount.accounts.sortedBy { it.displayIndex }.forEach { account ->
|
user.accounts.sortedBy { it.displayIndex }.forEach { account ->
|
||||||
NavigationMenuItem(itemModifier, account.displayName, textColor, iconSize, IconTextSpacing, itemHorizontalPadding, bankAccount = account) {
|
NavigationMenuItem(itemModifier, account.displayName, textColor, iconSize, IconTextSpacing, itemHorizontalPadding, bankAccount = account) {
|
||||||
accountSelected?.invoke(userAccount, account)
|
accountSelected?.invoke(user, account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.config.Colors
|
import net.codinux.banking.ui.config.Colors
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
import org.jetbrains.compose.resources.DrawableResource
|
import org.jetbrains.compose.resources.DrawableResource
|
||||||
|
@ -37,7 +37,7 @@ fun NavigationMenuItem(
|
||||||
iconSize: Dp = 24.dp,
|
iconSize: Dp = 24.dp,
|
||||||
iconTextSpacing: Dp = 24.dp,
|
iconTextSpacing: Dp = 24.dp,
|
||||||
horizontalPadding: Dp = 8.dp,
|
horizontalPadding: Dp = 8.dp,
|
||||||
userAccount: UserAccountEntity? = null,
|
user: UserEntity? = null,
|
||||||
bankAccount: BankAccountEntity? = null,
|
bankAccount: BankAccountEntity? = null,
|
||||||
iconResource: DrawableResource? = null,
|
iconResource: DrawableResource? = null,
|
||||||
icon: (@Composable () -> Unit)? = null,
|
icon: (@Composable () -> Unit)? = null,
|
||||||
|
@ -54,7 +54,7 @@ fun NavigationMenuItem(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.clickable { onClick?.invoke() }
|
.clickable { onClick?.invoke() }
|
||||||
.let {
|
.let {
|
||||||
if (userAccount != null && filterService.isSelected(userAccount, transactionsFilter)
|
if (user != null && filterService.isSelected(user, transactionsFilter)
|
||||||
|| bankAccount != null && filterService.isSelected(bankAccount, transactionsFilter)) {
|
|| bankAccount != null && filterService.isSelected(bankAccount, transactionsFilter)) {
|
||||||
it.background(Colors.AccentAsSelectionBackground, shape = RoundedCornerShape(4.dp))
|
it.background(Colors.AccentAsSelectionBackground, shape = RoundedCornerShape(4.dp))
|
||||||
} else {
|
} else {
|
||||||
|
@ -68,7 +68,7 @@ fun NavigationMenuItem(
|
||||||
icon()
|
icon()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BankIcon(userAccount, Modifier.padding(end = iconTextSpacing), Modifier.size(iconSize), iconResource = iconResource)
|
BankIcon(user, Modifier.padding(end = iconTextSpacing), Modifier.size(iconSize), iconResource = iconResource)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(text, color = textColor, modifier = Modifier.weight(1f), maxLines = 1, overflow = TextOverflow.Ellipsis)
|
Text(text, color = textColor, modifier = Modifier.weight(1f), maxLines = 1, overflow = TextOverflow.Ellipsis)
|
||||||
|
@ -77,8 +77,8 @@ fun NavigationMenuItem(
|
||||||
null
|
null
|
||||||
} else if (bankAccount != null) {
|
} else if (bankAccount != null) {
|
||||||
bankAccount.balance
|
bankAccount.balance
|
||||||
} else if (userAccount != null) {
|
} else if (user != null) {
|
||||||
calculator.calculateBalanceOfUserAccount(userAccount)
|
calculator.calculateBalanceOfUser(user)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import net.codinux.banking.client.model.Amount
|
import net.codinux.banking.client.model.Amount
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
import net.codinux.banking.ui.forms.RoundedCornersCard
|
import net.codinux.banking.ui.forms.RoundedCornersCard
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
|
@ -28,7 +28,7 @@ private val formatUtil = DI.formatUtil
|
||||||
fun GroupedTransactionsListItems(
|
fun GroupedTransactionsListItems(
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
transactionsToDisplay: List<AccountTransactionViewModel>,
|
transactionsToDisplay: List<AccountTransactionViewModel>,
|
||||||
userAccountsId: Map<Long, UserAccountEntity>,
|
userAccountsId: Map<Long, UserEntity>,
|
||||||
transactionsGrouping: TransactionsGrouping
|
transactionsGrouping: TransactionsGrouping
|
||||||
) {
|
) {
|
||||||
val groupingService = remember { TransactionsGroupingService() }
|
val groupingService = remember { TransactionsGroupingService() }
|
||||||
|
@ -57,7 +57,9 @@ fun GroupedTransactionsListItems(
|
||||||
RoundedCornersCard {
|
RoundedCornersCard {
|
||||||
Column(Modifier.background(Color.White)) { // LazyColumn inside LazyColumn is not allowed
|
Column(Modifier.background(Color.White)) { // LazyColumn inside LazyColumn is not allowed
|
||||||
monthTransactions.forEachIndexed { index, transaction ->
|
monthTransactions.forEachIndexed { index, transaction ->
|
||||||
TransactionListItem(userAccountsId[transaction.userAccountId], transaction, index, monthTransactions.size)
|
key(transaction.id) {
|
||||||
|
TransactionListItem(userAccountsId[transaction.userId], transaction, index, monthTransactions.size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.DpOffset
|
import androidx.compose.ui.unit.DpOffset
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.User
|
||||||
import net.codinux.banking.ui.composables.BankIcon
|
import net.codinux.banking.ui.composables.BankIcon
|
||||||
import net.codinux.banking.ui.config.Colors
|
import net.codinux.banking.ui.config.Colors
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
|
@ -25,7 +25,7 @@ private val uiSettings = DI.uiSettings
|
||||||
private val formatUtil = DI.formatUtil
|
private val formatUtil = DI.formatUtil
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TransactionListItem(userAccount: UserAccount?, transaction: AccountTransactionViewModel, itemIndex: Int, countItems: Int) {
|
fun TransactionListItem(user: User?, transaction: AccountTransactionViewModel, itemIndex: Int, countItems: Int) {
|
||||||
val zebraStripes by uiSettings.zebraStripes.collectAsState()
|
val zebraStripes by uiSettings.zebraStripes.collectAsState()
|
||||||
|
|
||||||
val showBankIcons by uiSettings.showBankIcons.collectAsState()
|
val showBankIcons by uiSettings.showBankIcons.collectAsState()
|
||||||
|
@ -48,9 +48,9 @@ fun TransactionListItem(userAccount: UserAccount?, transaction: AccountTransacti
|
||||||
val transactionEntity = DI.bankingService.getTransaction(transaction.id)
|
val transactionEntity = DI.bankingService.getTransaction(transaction.id)
|
||||||
|
|
||||||
DI.uiState.showTransferMoneyDialogData.value = ShowTransferMoneyDialogData(
|
DI.uiState.showTransferMoneyDialogData.value = ShowTransferMoneyDialogData(
|
||||||
DI.uiState.userAccounts.value.firstNotNullOf { it.accounts.firstOrNull { it.id == transaction.bankAccountId } },
|
DI.uiState.users.value.firstNotNullOf { it.accounts.firstOrNull { it.id == transaction.bankAccountId } },
|
||||||
transaction.otherPartyName,
|
transaction.otherPartyName,
|
||||||
transactionEntity?.otherPartyBankCode,
|
transactionEntity?.otherPartyBankId,
|
||||||
transactionEntity?.otherPartyAccountId,
|
transactionEntity?.otherPartyAccountId,
|
||||||
if (withSameData) transaction.amount else null,
|
if (withSameData) transaction.amount else null,
|
||||||
if (withSameData) transaction.reference else null
|
if (withSameData) transaction.reference else null
|
||||||
|
@ -76,7 +76,7 @@ fun TransactionListItem(userAccount: UserAccount?, transaction: AccountTransacti
|
||||||
Column(Modifier.weight(1f)) {
|
Column(Modifier.weight(1f)) {
|
||||||
Row {
|
Row {
|
||||||
if (showBankIcons) {
|
if (showBankIcons) {
|
||||||
BankIcon(userAccount, Modifier.padding(end = 6.dp))
|
BankIcon(user, Modifier.padding(end = 6.dp))
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
|
@ -90,7 +90,7 @@ fun TransactionListItem(userAccount: UserAccount?, transaction: AccountTransacti
|
||||||
Spacer(modifier = Modifier.height(6.dp))
|
Spacer(modifier = Modifier.height(6.dp))
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = transaction.reference,
|
text = transaction.reference ?: "",
|
||||||
Modifier.fillMaxWidth(),
|
Modifier.fillMaxWidth(),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
|
|
|
@ -25,9 +25,9 @@ private val formatUtil = DI.formatUtil
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TransactionsList(uiState: UiState, uiSettings: UiSettings, isMobile: Boolean = true) {
|
fun TransactionsList(uiState: UiState, uiSettings: UiSettings, isMobile: Boolean = true) {
|
||||||
val userAccounts by uiState.userAccounts.collectAsState()
|
val users by uiState.users.collectAsState()
|
||||||
val userAccountsId by remember(userAccounts) {
|
val usersById by remember(users) {
|
||||||
derivedStateOf { userAccounts.associateBy { it.id } }
|
derivedStateOf { users.associateBy { it.id } }
|
||||||
}
|
}
|
||||||
|
|
||||||
val transactionsFilter by uiState.transactionsFilter.collectAsState()
|
val transactionsFilter by uiState.transactionsFilter.collectAsState()
|
||||||
|
@ -53,17 +53,19 @@ fun TransactionsList(uiState: UiState, uiSettings: UiSettings, isMobile: Boolean
|
||||||
Spacer(Modifier.weight(1f))
|
Spacer(Modifier.weight(1f))
|
||||||
|
|
||||||
if (showBalance) {
|
if (showBalance) {
|
||||||
val balance = calculator.calculateBalanceOfDisplayedTransactions(transactionsToDisplay, userAccounts, transactionsFilter)
|
val balance = calculator.calculateBalanceOfDisplayedTransactions(transactionsToDisplay, users, transactionsFilter)
|
||||||
Text(formatUtil.formatAmount(balance, "EUR"), color = formatUtil.getColorForAmount(balance, showColoredAmounts))
|
Text(formatUtil.formatAmount(balance, "EUR"), color = formatUtil.getColorForAmount(balance, showColoredAmounts))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transactionsGrouping != TransactionsGrouping.None) {
|
if (transactionsGrouping != TransactionsGrouping.None) {
|
||||||
GroupedTransactionsListItems(transactionsListModifier, transactionsToDisplay, userAccountsId, transactionsGrouping)
|
GroupedTransactionsListItems(transactionsListModifier, transactionsToDisplay, usersById, transactionsGrouping)
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(transactionsListModifier, contentPadding = PaddingValues(top = 8.dp, bottom = 16.dp)) {
|
LazyColumn(transactionsListModifier, contentPadding = PaddingValues(top = 8.dp, bottom = 16.dp)) {
|
||||||
itemsIndexed(transactionsToDisplay) { index, transaction ->
|
itemsIndexed(transactionsToDisplay) { index, transaction ->
|
||||||
TransactionListItem(userAccountsId[transaction.userAccountId], transaction, index, transactionsToDisplay.size)
|
key(transaction.id) {
|
||||||
|
TransactionListItem(usersById[transaction.userId], transaction, index, transactionsToDisplay.size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,12 @@ fun TransferMoneyDialog(
|
||||||
data: ShowTransferMoneyDialogData,
|
data: ShowTransferMoneyDialogData,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val userAccounts = uiState.userAccounts.value
|
val userAccounts = uiState.users.value
|
||||||
val accountsToUserAccount = userAccounts.sortedBy { it.displayIndex }
|
val accountsToUserAccount = userAccounts.sortedBy { it.displayIndex }
|
||||||
.flatMap { user -> user.accounts.sortedBy { it.displayIndex }.map { it to user } }.toMap()
|
.flatMap { user -> user.accounts.sortedBy { it.displayIndex }.map { it to user } }.toMap()
|
||||||
|
|
||||||
val accountsSupportingTransferringMoney = userAccounts.flatMap { it.accounts }
|
val accountsSupportingTransferringMoney = userAccounts.flatMap { it.accounts }
|
||||||
.filter { it.supportsAnyFeature(BankAccountFeatures.TransferMoney, BankAccountFeatures.InstantPayment) }
|
.filter { it.supportsMoneyTransfer }
|
||||||
|
|
||||||
if (accountsSupportingTransferringMoney.isEmpty()) {
|
if (accountsSupportingTransferringMoney.isEmpty()) {
|
||||||
uiState.applicationErrorOccurred(ErroneousAction.TransferMoney, "Keines Ihrer Konten unterstützt das Überweisen von Geld")
|
uiState.applicationErrorOccurred(ErroneousAction.TransferMoney, "Keines Ihrer Konten unterstützt das Überweisen von Geld")
|
||||||
|
@ -59,7 +59,7 @@ fun TransferMoneyDialog(
|
||||||
var recipientAccountIdentifier by remember { mutableStateOf(data.recipientAccountIdentifier ?: "") }
|
var recipientAccountIdentifier by remember { mutableStateOf(data.recipientAccountIdentifier ?: "") }
|
||||||
var amount by remember { mutableStateOf(data.amount?.amount ?: "") }
|
var amount by remember { mutableStateOf(data.amount?.amount ?: "") }
|
||||||
var paymentReference by remember { mutableStateOf(data.reference ?: "") }
|
var paymentReference by remember { mutableStateOf(data.reference ?: "") }
|
||||||
val accountSupportsInstantTransfer by remember(senderAccount) { derivedStateOf { senderAccount.supportsAnyFeature(BankAccountFeatures.InstantPayment) } }
|
val accountSupportsInstantTransfer by remember(senderAccount) { derivedStateOf { senderAccount.supportsInstantTransfer } }
|
||||||
var instantTransfer by remember { mutableStateOf(false) }
|
var instantTransfer by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val isRequiredDataEntered by remember(recipientName, recipientAccountIdentifier, amount) {
|
val isRequiredDataEntered by remember(recipientName, recipientAccountIdentifier, amount) {
|
||||||
|
|
|
@ -7,12 +7,12 @@ import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
||||||
|
|
||||||
data class AccountTransactionViewModel(
|
data class AccountTransactionViewModel(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val userAccountId: Long,
|
val userId: Long,
|
||||||
val bankAccountId: Long,
|
val bankAccountId: Long,
|
||||||
|
|
||||||
val amount: Amount,
|
val amount: Amount,
|
||||||
val currency: String,
|
val currency: String,
|
||||||
val reference: String,
|
val reference: String?,
|
||||||
val valueDate: LocalDate,
|
val valueDate: LocalDate,
|
||||||
val otherPartyName: String? = null,
|
val otherPartyName: String? = null,
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ data class AccountTransactionViewModel(
|
||||||
val userSetDisplayName: String? = null,
|
val userSetDisplayName: String? = null,
|
||||||
val category: String? = null
|
val category: String? = null
|
||||||
) {
|
) {
|
||||||
constructor(entity: AccountTransactionEntity) : this(entity.id, entity.userAccountId, entity.bankAccountId, entity)
|
constructor(entity: AccountTransactionEntity) : this(entity.id, entity.userId, entity.bankAccountId, entity)
|
||||||
|
|
||||||
constructor(id: Long, userAccountId: Long, bankAccountId: Long, transaction: AccountTransaction)
|
constructor(id: Long, userId: Long, bankAccountId: Long, transaction: AccountTransaction)
|
||||||
: this(id, userAccountId, bankAccountId, transaction.amount, transaction.currency, transaction.reference, transaction.valueDate, transaction.otherPartyName, transaction.bookingText)
|
: this(id, userId, bankAccountId, transaction.amount, transaction.currency, transaction.reference, transaction.valueDate, transaction.otherPartyName, transaction.postingText)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package net.codinux.banking.ui.model
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
|
|
||||||
class AccountTransactionsFilter {
|
class AccountTransactionsFilter {
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ class AccountTransactionsFilter {
|
||||||
val selectedAccount: BankAccountFilter?
|
val selectedAccount: BankAccountFilter?
|
||||||
get() = selectedAccounts.value.firstOrNull()
|
get() = selectedAccounts.value.firstOrNull()
|
||||||
|
|
||||||
fun selectedAccountChanged(userAccount: UserAccountEntity?, bankAccount: BankAccountEntity?) {
|
fun selectedAccountChanged(user: UserEntity?, bankAccount: BankAccountEntity?) {
|
||||||
selectedAccounts.value = if (userAccount == null) {
|
selectedAccounts.value = if (user == null) {
|
||||||
emptyList()
|
emptyList()
|
||||||
} else {
|
} else {
|
||||||
listOf(BankAccountFilter(userAccount, bankAccount))
|
listOf(BankAccountFilter(user, bankAccount))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package net.codinux.banking.ui.model
|
package net.codinux.banking.ui.model
|
||||||
|
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
|
|
||||||
data class BankAccountFilter(
|
data class BankAccountFilter(
|
||||||
val userAccount: UserAccountEntity,
|
val user: UserEntity,
|
||||||
val bankAccount: BankAccountEntity? = null
|
val bankAccount: BankAccountEntity? = null
|
||||||
)
|
)
|
|
@ -1,11 +1,11 @@
|
||||||
package net.codinux.banking.ui.model.events
|
package net.codinux.banking.ui.model.events
|
||||||
|
|
||||||
import net.codinux.banking.client.model.BankAccount
|
import net.codinux.banking.client.model.BankAccount
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.User
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
|
|
||||||
data class AccountTransactionsRetrievedEvent(
|
data class AccountTransactionsRetrievedEvent(
|
||||||
val user: UserAccount,
|
val user: User,
|
||||||
val account: BankAccount,
|
val account: BankAccount,
|
||||||
val newTransactions: List<AccountTransactionViewModel>
|
val newTransactions: List<AccountTransactionViewModel>
|
||||||
)
|
)
|
|
@ -1,7 +1,7 @@
|
||||||
package net.codinux.banking.ui.service
|
package net.codinux.banking.ui.service
|
||||||
|
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
import net.codinux.banking.ui.model.AccountTransactionsFilter
|
import net.codinux.banking.ui.model.AccountTransactionsFilter
|
||||||
import net.codinux.banking.ui.model.BankAccountFilter
|
import net.codinux.banking.ui.model.BankAccountFilter
|
||||||
|
@ -30,27 +30,27 @@ class AccountTransactionsFilterService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun matchesFilter(transaction: AccountTransactionViewModel, accountsFilter: List<BankAccountFilter>): Boolean =
|
private fun matchesFilter(transaction: AccountTransactionViewModel, accountsFilter: List<BankAccountFilter>): Boolean =
|
||||||
accountsFilter.any { (userAccount, bankAccount) ->
|
accountsFilter.any { (user, bankAccount) ->
|
||||||
if (bankAccount != null) {
|
if (bankAccount != null) {
|
||||||
transaction.bankAccountId == bankAccount.id
|
transaction.bankAccountId == bankAccount.id
|
||||||
} else {
|
} else {
|
||||||
transaction.userAccountId == userAccount.id
|
transaction.userId == user.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun matchesSearchTerm(transaction: AccountTransactionViewModel, searchTerm: String): Boolean =
|
private fun matchesSearchTerm(transaction: AccountTransactionViewModel, searchTerm: String): Boolean =
|
||||||
transaction.reference.contains(searchTerm, true)
|
transaction.reference?.contains(searchTerm, true) == true
|
||||||
|| (transaction.otherPartyName != null && transaction.otherPartyName.contains(searchTerm, true))
|
|| (transaction.otherPartyName != null && transaction.otherPartyName.contains(searchTerm, true))
|
||||||
|
|
||||||
|
|
||||||
fun isSelected(userAccount: UserAccountEntity, transactionsFilter: AccountTransactionsFilter): Boolean {
|
fun isSelected(user: UserEntity, transactionsFilter: AccountTransactionsFilter): Boolean {
|
||||||
if (transactionsFilter.showAllAccounts) {
|
if (transactionsFilter.showAllAccounts) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val filter = transactionsFilter.selectedAccount
|
val filter = transactionsFilter.selectedAccount
|
||||||
|
|
||||||
return filter?.userAccount == userAccount && filter.bankAccount == null
|
return filter?.user == user && filter.bankAccount == null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isSelected(bankAccount: BankAccountEntity, transactionsFilter: AccountTransactionsFilter): Boolean {
|
fun isSelected(bankAccount: BankAccountEntity, transactionsFilter: AccountTransactionsFilter): Boolean {
|
||||||
|
|
|
@ -22,7 +22,7 @@ class BankDataImporterAndExporter {
|
||||||
formatAmount(transaction.amount, decimalSeparator), transaction.currency,
|
formatAmount(transaction.amount, decimalSeparator), transaction.currency,
|
||||||
transaction.valueDate.toString(), transaction.bookingDate.toString(),
|
transaction.valueDate.toString(), transaction.bookingDate.toString(),
|
||||||
transaction.reference,
|
transaction.reference,
|
||||||
transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId
|
transaction.otherPartyName, transaction.otherPartyBankId, transaction.otherPartyAccountId
|
||||||
// TODO: export all columns / transaction data
|
// TODO: export all columns / transaction data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package net.codinux.banking.ui.service
|
package net.codinux.banking.ui.service
|
||||||
|
|
||||||
import net.codinux.banking.client.model.BankingGroup
|
import net.codinux.banking.client.model.BankingGroup
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.User
|
||||||
|
|
||||||
class BankIconService { // TODO: extract to a common library
|
class BankIconService { // TODO: extract to a common library
|
||||||
|
|
||||||
fun findIconForBank(user: UserAccount) = findIconForBank(user.bankName, user.bankingGroup)
|
fun findIconForBank(user: User) = findIconForBank(user.bankName, user.bankingGroup)
|
||||||
|
|
||||||
fun findIconForBank(bankName: String, bankingGroup: BankingGroup? = null): String? = when (bankingGroup) {
|
fun findIconForBank(bankName: String, bankingGroup: BankingGroup? = null): String? = when (bankingGroup) {
|
||||||
BankingGroup.Sparkasse -> "https://sparkasse.de/favicon-32x32.png"
|
BankingGroup.Sparkasse -> "https://sparkasse.de/favicon-32x32.png"
|
||||||
|
|
|
@ -15,7 +15,7 @@ import net.codinux.banking.client.service.BankingModelService
|
||||||
import net.codinux.banking.dataaccess.BankingRepository
|
import net.codinux.banking.dataaccess.BankingRepository
|
||||||
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
import net.codinux.banking.dataaccess.entities.AccountTransactionEntity
|
||||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
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.IOorDefault
|
import net.codinux.banking.ui.IOorDefault
|
||||||
|
@ -57,11 +57,11 @@ class BankingService(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getAllUserAccounts() = bankingRepository.getAllUserAccounts()
|
fun getAllUsers() = bankingRepository.getAllUsers()
|
||||||
|
|
||||||
fun getAllAccountTransactions() = bankingRepository.getAllAccountTransactions()
|
fun getAllAccountTransactions() = bankingRepository.getAllAccountTransactions()
|
||||||
|
|
||||||
fun getAllTransactionsOfUserAccount(userAccount: UserAccountEntity) = bankingRepository.getAllTransactionsOfUserAccount(userAccount)
|
fun getAllTransactionsOfUser(user: UserEntity) = bankingRepository.getAllTransactionsOfUser(user)
|
||||||
|
|
||||||
fun getAllAccountTransactionsAsViewModel() = bankingRepository.getAllAccountTransactionsAsViewModel()
|
fun getAllAccountTransactionsAsViewModel() = bankingRepository.getAllAccountTransactionsAsViewModel()
|
||||||
|
|
||||||
|
@ -95,15 +95,15 @@ class BankingService(
|
||||||
private suspend fun handleSuccessfulGetAccountDataResponse(response: GetAccountDataResponse) {
|
private suspend fun handleSuccessfulGetAccountDataResponse(response: GetAccountDataResponse) {
|
||||||
try {
|
try {
|
||||||
val newUser = response.user
|
val newUser = response.user
|
||||||
newUser.displayIndex = uiState.userAccounts.value.size
|
newUser.displayIndex = uiState.users.value.size
|
||||||
|
|
||||||
val newUserEntity = bankingRepository.persistUserAccount(newUser)
|
val newUserEntity = bankingRepository.persistUser(newUser)
|
||||||
|
|
||||||
log.info { "Saved user account $newUserEntity with ${newUserEntity.accounts.flatMap { it.bookedTransactionsEntities }.size} transactions" }
|
log.info { "Saved user account $newUserEntity with ${newUserEntity.accounts.flatMap { it.bookedTransactionsEntities }.size} transactions" }
|
||||||
|
|
||||||
val userAccounts = uiState.userAccounts.value.toMutableList()
|
val users = uiState.users.value.toMutableList()
|
||||||
userAccounts.add(newUserEntity)
|
users.add(newUserEntity)
|
||||||
uiState.userAccounts.value = userAccounts
|
uiState.users.value = users
|
||||||
|
|
||||||
updateTransactionsInUi(newUserEntity.accounts.flatMap { it.bookedTransactionsEntities })
|
updateTransactionsInUi(newUserEntity.accounts.flatMap { it.bookedTransactionsEntities })
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
@ -115,15 +115,15 @@ class BankingService(
|
||||||
suspend fun updateAccountTransactions() {
|
suspend fun updateAccountTransactions() {
|
||||||
val selectedAccount = uiState.transactionsFilter.value.selectedAccount
|
val selectedAccount = uiState.transactionsFilter.value.selectedAccount
|
||||||
if (selectedAccount != null) {
|
if (selectedAccount != null) {
|
||||||
updateAccountTransactions(selectedAccount.userAccount, selectedAccount.bankAccount)
|
updateAccountTransactions(selectedAccount.user, selectedAccount.bankAccount)
|
||||||
} else {
|
} else {
|
||||||
uiState.userAccounts.value.forEach { user ->
|
uiState.users.value.forEach { user ->
|
||||||
updateAccountTransactions(user)
|
updateAccountTransactions(user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun updateAccountTransactions(user: UserAccountEntity, bankAccount: BankAccountEntity? = null) {
|
private suspend fun updateAccountTransactions(user: UserEntity, bankAccount: BankAccountEntity? = null) {
|
||||||
withContext(Dispatchers.IOorDefault) {
|
withContext(Dispatchers.IOorDefault) {
|
||||||
try {
|
try {
|
||||||
val response = client.updateAccountTransactionsAsync(user, bankAccount?.let { listOf(it) })
|
val response = client.updateAccountTransactionsAsync(user, bankAccount?.let { listOf(it) })
|
||||||
|
@ -138,22 +138,22 @@ class BankingService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun handleSuccessfulUpdateAccountTransactionsResponse(user: UserAccountEntity, responses: List<GetTransactionsResponse>) {
|
private suspend fun handleSuccessfulUpdateAccountTransactionsResponse(user: UserEntity, responses: List<GetTransactionsResponse>) {
|
||||||
try {
|
try {
|
||||||
// TODO: when user gets updated by BankingClient, also update user in database
|
// TODO: when user gets updated by BankingClient, also update user in database
|
||||||
// val newUser = response.user
|
// val newUser = response.user
|
||||||
// val newUserEntity = bankingRepository.persistUserAccount(newUser)
|
// val newUserEntity = bankingRepository.persistUser(newUser)
|
||||||
//
|
//
|
||||||
// log.info { "Saved user account $newUserEntity with ${newUserEntity.accounts.flatMap { it.bookedTransactionsEntities }.size} transactions" }
|
// log.info { "Saved user account $newUserEntity with ${newUserEntity.accounts.flatMap { it.bookedTransactionsEntities }.size} transactions" }
|
||||||
|
|
||||||
val userAccountTransactions = getAllTransactionsOfUserAccount(user)
|
val userTransactions = getAllTransactionsOfUser(user)
|
||||||
|
|
||||||
responses.forEach { response ->
|
responses.forEach { response ->
|
||||||
val account = (response.account as? BankAccountEntity) ?: user.accounts.first { it.identifier == response.account.identifier && it.subAccountNumber == response.account.subAccountNumber }
|
val account = (response.account as? BankAccountEntity) ?: user.accounts.first { it.identifier == response.account.identifier && it.subAccountNumber == response.account.subAccountNumber }
|
||||||
|
|
||||||
// TODO: update BankAccount and may updated Transactions in database
|
// TODO: update BankAccount and may updated Transactions in database
|
||||||
|
|
||||||
val existingAccountTransactions = userAccountTransactions.filter { it.bankAccountId == account.id }
|
val existingAccountTransactions = userTransactions.filter { it.bankAccountId == account.id }
|
||||||
|
|
||||||
val newTransactions = modelService.findNewTransactions(response.bookedTransactions, existingAccountTransactions)
|
val newTransactions = modelService.findNewTransactions(response.bookedTransactions, existingAccountTransactions)
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ class BankingService(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
suspend fun transferMoney(user: UserAccountEntity, account: BankAccountEntity,
|
suspend fun transferMoney(user: UserEntity, account: BankAccountEntity,
|
||||||
recipientName: String, recipientAccountIdentifier: String, amount: Amount, currency: String,
|
recipientName: String, recipientAccountIdentifier: String, amount: Amount, currency: String,
|
||||||
paymentReference: String? = null, instantTransfer: Boolean = false, recipientBankIdentifier: String? = null): Boolean {
|
paymentReference: String? = null, instantTransfer: Boolean = false, recipientBankIdentifier: String? = null): Boolean {
|
||||||
val response = client.transferMoneyAsync(TransferMoneyRequestForUser(
|
val response = client.transferMoneyAsync(TransferMoneyRequestForUser(
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package net.codinux.banking.ui.service
|
package net.codinux.banking.ui.service
|
||||||
|
|
||||||
import net.codinux.banking.client.model.Amount
|
import net.codinux.banking.client.model.Amount
|
||||||
import net.codinux.banking.client.model.UserAccount
|
import net.codinux.banking.client.model.User
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.extensions.toBigDecimal
|
import net.codinux.banking.ui.extensions.toBigDecimal
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
import net.codinux.banking.ui.model.AccountTransactionsFilter
|
import net.codinux.banking.ui.model.AccountTransactionsFilter
|
||||||
|
@ -13,8 +13,8 @@ class CalculatorService {
|
||||||
// TODO: find a better solution
|
// TODO: find a better solution
|
||||||
Amount(transactions.sumOf { it.amount.toBigDecimal() }.toString())
|
Amount(transactions.sumOf { it.amount.toBigDecimal() }.toString())
|
||||||
|
|
||||||
fun calculateBalanceOfUserAccount(userAccount: UserAccount): Amount =
|
fun calculateBalanceOfUser(user: User): Amount =
|
||||||
sumAmounts(userAccount.accounts.map { it.balance })
|
sumAmounts(user.accounts.map { it.balance })
|
||||||
|
|
||||||
fun sumAmounts(amounts: Collection<Amount>): Amount =
|
fun sumAmounts(amounts: Collection<Amount>): Amount =
|
||||||
// TODO: find a better solution
|
// TODO: find a better solution
|
||||||
|
@ -28,9 +28,9 @@ class CalculatorService {
|
||||||
// TODO: find a better solution
|
// TODO: find a better solution
|
||||||
Amount(transactions.map { it.amount.toBigDecimal() }.filter { it < 0 }.sum().toString())
|
Amount(transactions.map { it.amount.toBigDecimal() }.filter { it < 0 }.sum().toString())
|
||||||
|
|
||||||
fun calculateBalanceOfDisplayedTransactions(transactions: Collection<AccountTransactionViewModel>, userAccounts: Collection<UserAccountEntity>, filter: AccountTransactionsFilter): Amount {
|
fun calculateBalanceOfDisplayedTransactions(transactions: Collection<AccountTransactionViewModel>, users: Collection<UserEntity>, filter: AccountTransactionsFilter): Amount {
|
||||||
if (filter.noFiltersApplied) {
|
if (filter.noFiltersApplied) {
|
||||||
return sumAmounts(userAccounts.flatMap { it.accounts.map { it.balance } })
|
return sumAmounts(users.flatMap { it.accounts.map { it.balance } })
|
||||||
}
|
}
|
||||||
|
|
||||||
val selectedAccount = filter.selectedAccount
|
val selectedAccount = filter.selectedAccount
|
||||||
|
@ -39,7 +39,7 @@ class CalculatorService {
|
||||||
if (selectedAccount.bankAccount != null) {
|
if (selectedAccount.bankAccount != null) {
|
||||||
selectedAccount.bankAccount.balance
|
selectedAccount.bankAccount.balance
|
||||||
} else {
|
} else {
|
||||||
calculateBalanceOfUserAccount(selectedAccount.userAccount)
|
calculateBalanceOfUser(selectedAccount.user)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sumTransactions(transactions)
|
sumTransactions(transactions)
|
||||||
|
|
|
@ -33,7 +33,7 @@ class RecipientFinder(private val bankFinder: BankFinder) {
|
||||||
suspend fun updateData(transactions: List<AccountTransaction>) {
|
suspend fun updateData(transactions: List<AccountTransaction>) {
|
||||||
availableRecipients = transactions.mapNotNull {
|
availableRecipients = transactions.mapNotNull {
|
||||||
if (it.otherPartyName != null && it.otherPartyAccountId != null) {
|
if (it.otherPartyName != null && it.otherPartyAccountId != null) {
|
||||||
RecipientSuggestion(it.otherPartyName!!, it.otherPartyBankCode, it.otherPartyAccountId!!)
|
RecipientSuggestion(it.otherPartyName!!, it.otherPartyBankId, it.otherPartyAccountId!!)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class RecipientFinder(private val bankFinder: BankFinder) {
|
||||||
|
|
||||||
transactionsByIban = transactions.filter { it.otherPartyAccountId != null }.groupBy { it.otherPartyAccountId!! }
|
transactionsByIban = transactions.filter { it.otherPartyAccountId != null }.groupBy { it.otherPartyAccountId!! }
|
||||||
.mapValues { it.value.map {
|
.mapValues { it.value.map {
|
||||||
PaymentDataSuggestion(it.reference, Amount(it.amount.amount.replace("-", "")), it.currency, it.valueDate)
|
PaymentDataSuggestion(it.reference ?: "", Amount(it.amount.amount.replace("-", "")), it.currency, it.valueDate)
|
||||||
}.toSet().sortedByDescending { it.valueDate } }
|
}.toSet().sortedByDescending { it.valueDate } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import androidx.compose.material.DrawerValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserEntity
|
||||||
import net.codinux.banking.ui.model.*
|
import net.codinux.banking.ui.model.*
|
||||||
import net.codinux.banking.ui.model.error.ApplicationError
|
import net.codinux.banking.ui.model.error.ApplicationError
|
||||||
import net.codinux.banking.ui.model.error.BankingClientError
|
import net.codinux.banking.ui.model.error.BankingClientError
|
||||||
|
@ -15,7 +15,7 @@ import net.codinux.banking.ui.model.events.TransferredMoneyEvent
|
||||||
|
|
||||||
class UiState : ViewModel() {
|
class UiState : ViewModel() {
|
||||||
|
|
||||||
val userAccounts = MutableStateFlow<List<UserAccountEntity>>(emptyList())
|
val users = MutableStateFlow<List<UserEntity>>(emptyList())
|
||||||
|
|
||||||
val transactions = MutableStateFlow<List<AccountTransactionViewModel>>(emptyList())
|
val transactions = MutableStateFlow<List<AccountTransactionViewModel>>(emptyList())
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS AccountTransaction (
|
||||||
|
|
||||||
amount TEXT NOT NULL,
|
amount TEXT NOT NULL,
|
||||||
currency TEXT NOT NULL,
|
currency TEXT NOT NULL,
|
||||||
unparsedReference TEXT NOT NULL,
|
unparsedReference TEXT,
|
||||||
|
|
||||||
bookingDate TEXT NOT NULL,
|
bookingDate TEXT NOT NULL,
|
||||||
valueDate TEXT NOT NULL,
|
valueDate TEXT NOT NULL,
|
||||||
|
@ -21,8 +21,6 @@ CREATE TABLE IF NOT EXISTS AccountTransaction (
|
||||||
category TEXT,
|
category TEXT,
|
||||||
notes TEXT,
|
notes TEXT,
|
||||||
|
|
||||||
information TEXT,
|
|
||||||
|
|
||||||
statementNumber INTEGER,
|
statementNumber INTEGER,
|
||||||
sequenceNumber INTEGER,
|
sequenceNumber INTEGER,
|
||||||
|
|
||||||
|
@ -34,17 +32,16 @@ CREATE TABLE IF NOT EXISTS AccountTransaction (
|
||||||
mandateReference TEXT,
|
mandateReference TEXT,
|
||||||
creditorIdentifier TEXT,
|
creditorIdentifier TEXT,
|
||||||
originatorsIdentificationCode TEXT,
|
originatorsIdentificationCode TEXT,
|
||||||
|
|
||||||
compensationAmount TEXT,
|
compensationAmount TEXT,
|
||||||
originalAmount TEXT,
|
originalAmount TEXT,
|
||||||
sepaReference TEXT,
|
|
||||||
deviantOriginator TEXT,
|
deviantOriginator TEXT,
|
||||||
deviantRecipient TEXT,
|
deviantRecipient TEXT,
|
||||||
referenceWithNoSpecialType TEXT,
|
referenceWithNoSpecialType TEXT,
|
||||||
|
|
||||||
primaNotaNumber TEXT,
|
primaNotaNumber TEXT,
|
||||||
textKeySupplement TEXT,
|
textKeySupplement TEXT,
|
||||||
|
|
||||||
currencyType TEXT,
|
|
||||||
bookingKey TEXT,
|
|
||||||
referenceForTheAccountOwner TEXT,
|
referenceForTheAccountOwner TEXT,
|
||||||
referenceOfTheAccountServicingInstitution TEXT,
|
referenceOfTheAccountServicingInstitution TEXT,
|
||||||
supplementaryDetails TEXT,
|
supplementaryDetails TEXT,
|
||||||
|
@ -65,22 +62,16 @@ INSERT INTO AccountTransaction(
|
||||||
|
|
||||||
userSetDisplayName, category, notes,
|
userSetDisplayName, category, notes,
|
||||||
|
|
||||||
information,
|
|
||||||
statementNumber, sequenceNumber,
|
statementNumber, sequenceNumber,
|
||||||
openingBalance, closingBalance,
|
openingBalance, closingBalance,
|
||||||
|
|
||||||
endToEndReference, customerReference, mandateReference,
|
endToEndReference, customerReference, mandateReference,
|
||||||
creditorIdentifier, originatorsIdentificationCode,
|
creditorIdentifier, originatorsIdentificationCode,
|
||||||
compensationAmount, originalAmount,
|
compensationAmount, originalAmount,
|
||||||
sepaReference,
|
|
||||||
deviantOriginator, deviantRecipient,
|
deviantOriginator, deviantRecipient,
|
||||||
referenceWithNoSpecialType,
|
referenceWithNoSpecialType,
|
||||||
primaNotaNumber, textKeySupplement,
|
primaNotaNumber, textKeySupplement,
|
||||||
|
|
||||||
currencyType, bookingKey,
|
|
||||||
referenceForTheAccountOwner, referenceOfTheAccountServicingInstitution,
|
|
||||||
supplementaryDetails,
|
|
||||||
|
|
||||||
transactionReferenceNumber, relatedReferenceNumber
|
transactionReferenceNumber, relatedReferenceNumber
|
||||||
)
|
)
|
||||||
VALUES(
|
VALUES(
|
||||||
|
@ -93,22 +84,16 @@ VALUES(
|
||||||
|
|
||||||
?, ?, ?,
|
?, ?, ?,
|
||||||
|
|
||||||
?,
|
|
||||||
?, ?,
|
?, ?,
|
||||||
?, ?,
|
?, ?,
|
||||||
|
|
||||||
?, ?, ?,
|
?, ?, ?,
|
||||||
?, ?,
|
?, ?,
|
||||||
?, ?,
|
?, ?,
|
||||||
?,
|
|
||||||
?, ?,
|
?, ?,
|
||||||
?,
|
?,
|
||||||
?, ?,
|
?, ?,
|
||||||
|
|
||||||
?, ?,
|
|
||||||
?, ?,
|
|
||||||
?,
|
|
||||||
|
|
||||||
?, ?
|
?, ?
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -118,11 +103,11 @@ SELECT AccountTransaction.*
|
||||||
FROM AccountTransaction;
|
FROM AccountTransaction;
|
||||||
|
|
||||||
selectAllTransactionsAsViewModel:
|
selectAllTransactionsAsViewModel:
|
||||||
SELECT id, userAccountId, bankAccountId, amount, currency, unparsedReference, valueDate, otherPartyName, bookingText, sepaReference, userSetDisplayName, category
|
SELECT id, userAccountId, bankAccountId, amount, currency, unparsedReference, valueDate, otherPartyName, bookingText, userSetDisplayName, category
|
||||||
FROM AccountTransaction;
|
FROM AccountTransaction;
|
||||||
|
|
||||||
|
|
||||||
selectAllTransactionsOfUserAccount:
|
selectAllTransactionsOfUser:
|
||||||
SELECT AccountTransaction.*
|
SELECT AccountTransaction.*
|
||||||
FROM AccountTransaction WHERE userAccountId = ?;
|
FROM AccountTransaction WHERE userAccountId = ?;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ CREATE TABLE IF NOT EXISTS UserAccount (
|
||||||
bic TEXT NOT NULL,
|
bic TEXT NOT NULL,
|
||||||
|
|
||||||
customerName TEXT NOT NULL,
|
customerName TEXT NOT NULL,
|
||||||
userId TEXT NOT NULL,
|
userId TEXT,
|
||||||
|
|
||||||
selectedTanMethodId TEXT,
|
selectedTanMethodId TEXT,
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ CREATE TABLE IF NOT EXISTS UserAccount (
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
insertUserAccount:
|
insertUser:
|
||||||
INSERT INTO UserAccount(
|
INSERT INTO UserAccount(
|
||||||
bankCode, loginName, password,
|
bankCode, loginName, password,
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ VALUES(
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
selectAllUserAccounts:
|
selectAllUsers:
|
||||||
SELECT UserAccount.*
|
SELECT UserAccount.*
|
||||||
FROM UserAccount;
|
FROM UserAccount;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import androidx.compose.runtime.Composable
|
||||||
import net.codinux.banking.client.model.BankAccountType
|
import net.codinux.banking.client.model.BankAccountType
|
||||||
import net.codinux.banking.client.model.BankAccountViewInfo
|
import net.codinux.banking.client.model.BankAccountViewInfo
|
||||||
import net.codinux.banking.client.model.BankingGroup
|
import net.codinux.banking.client.model.BankingGroup
|
||||||
import net.codinux.banking.client.model.UserAccountViewInfo
|
import net.codinux.banking.client.model.BankViewInfo
|
||||||
import net.codinux.banking.client.model.tan.*
|
import net.codinux.banking.client.model.tan.*
|
||||||
import net.codinux.banking.ui.model.TanChallengeReceived
|
import net.codinux.banking.ui.model.TanChallengeReceived
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import net.codinux.banking.ui.model.TanChallengeReceived
|
||||||
@Composable
|
@Composable
|
||||||
fun EnterTanDialogPreview_EnterTan() {
|
fun EnterTanDialogPreview_EnterTan() {
|
||||||
val tanMethods = listOf(TanMethod("Zeig mich an", TanMethodType.AppTan, "902"))
|
val tanMethods = listOf(TanMethod("Zeig mich an", TanMethodType.AppTan, "902"))
|
||||||
val user = UserAccountViewInfo("12345678", "SupiDupiNutzer", "Abzockbank", BankingGroup.Postbank)
|
val user = BankViewInfo("12345678", "SupiDupiNutzer", "Abzockbank", BankingGroup.Postbank)
|
||||||
val tanChallenge = TanChallenge(TanChallengeType.EnterTan, ActionRequiringTan.GetAccountInfo, "Geben Sie die TAN ein", tanMethods.first().identifier, tanMethods, user = user)
|
val tanChallenge = TanChallenge(TanChallengeType.EnterTan, ActionRequiringTan.GetAccountInfo, "Geben Sie die TAN ein", tanMethods.first().identifier, tanMethods, user = user)
|
||||||
|
|
||||||
EnterTanDialog(TanChallengeReceived(tanChallenge) { }) { }
|
EnterTanDialog(TanChallengeReceived(tanChallenge) { }) { }
|
||||||
|
@ -27,7 +27,7 @@ fun EnterTanDialogPreview_TanImage() {
|
||||||
val tanMethod = TanMethod("photoTAN-Verfahren", TanMethodType.photoTan, "902", 6, AllowedTanFormat.Numeric)
|
val tanMethod = TanMethod("photoTAN-Verfahren", TanMethodType.photoTan, "902", 6, AllowedTanFormat.Numeric)
|
||||||
val tanImage = TanImage("image/png", tanImageBytes)
|
val tanImage = TanImage("image/png", tanImageBytes)
|
||||||
|
|
||||||
val user = UserAccountViewInfo("10010010", "Ihr krasser Login Name", "Phantasie Bank", BankingGroup.Comdirect)
|
val user = BankViewInfo("10010010", "Ihr krasser Login Name", "Phantasie Bank", BankingGroup.Comdirect)
|
||||||
|
|
||||||
val tanChallenge = TanChallenge(TanChallengeType.Image, ActionRequiringTan.GetAccountInfo, "Geben Sie die TAN ein", tanMethod.identifier, listOf(tanMethod), null, emptyList(), tanImage, null, user)
|
val tanChallenge = TanChallenge(TanChallengeType.Image, ActionRequiringTan.GetAccountInfo, "Geben Sie die TAN ein", tanMethod.identifier, listOf(tanMethod), null, emptyList(), tanImage, null, user)
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ fun EnterTanDialogPreview_WithMultipleTanMedia() { // shows that dialog is reall
|
||||||
TanMedium(TanMediumType.TanGenerator, "SparkassenCard (Debitkarte)", TanMediumStatus.Used, TanGeneratorTanMedium("5432109876"))
|
TanMedium(TanMediumType.TanGenerator, "SparkassenCard (Debitkarte)", TanMediumStatus.Used, TanGeneratorTanMedium("5432109876"))
|
||||||
)
|
)
|
||||||
|
|
||||||
val user = UserAccountViewInfo("10010010", "Ihr krasser Login Name", "Eine ganz gewöhnliche Sparkasse", BankingGroup.Sparkasse)
|
val user = BankViewInfo("10010010", "Ihr krasser Login Name", "Eine ganz gewöhnliche Sparkasse", BankingGroup.Sparkasse)
|
||||||
val account = BankAccountViewInfo("12345678", null, BankAccountType.CheckingAccount, null, "Giro Konto")
|
val account = BankAccountViewInfo("12345678", null, BankAccountType.CheckingAccount, null, "Giro Konto")
|
||||||
|
|
||||||
val tanChallenge = TanChallenge(TanChallengeType.Image, ActionRequiringTan.GetTransactions, "Sie möchten eine \"Umsatzabfrage\" freigeben: Bitte bestätigen Sie den \"Startcode 80061030\" mit der Taste \"OK\".", "913", tanMethods, "SparkassenCard (Debitkarte)", tanMedia, tanImage, null, user, account)
|
val tanChallenge = TanChallenge(TanChallengeType.Image, ActionRequiringTan.GetTransactions, "Sie möchten eine \"Umsatzabfrage\" freigeben: Bitte bestätigen Sie den \"Startcode 80061030\" mit der Taste \"OK\".", "913", tanMethods, "SparkassenCard (Debitkarte)", tanMedia, tanImage, null, user, account)
|
||||||
|
|
|
@ -25,14 +25,14 @@ class SqliteBankingRepositoryTest {
|
||||||
@Test
|
@Test
|
||||||
fun saveUserAccount() = runTest {
|
fun saveUserAccount() = runTest {
|
||||||
val bankAccounts = listOf(
|
val bankAccounts = listOf(
|
||||||
BankAccount("12345", "Monika Tester", BankAccountType.CheckingAccount, balance = Amount("12.34"), retrievedTransactionsFrom = LocalDate(2024, 5, 7), features = setOf(BankAccountFeatures.RetrieveBalance, BankAccountFeatures.InstantPayment), countDaysForWhichTransactionsAreKept = 320)
|
BankAccount("12345", null, null, null, "Monika Tester", BankAccountType.CheckingAccount, balance = Amount("12.34"), retrievedTransactionsFrom = LocalDate(2024, 5, 7), features = setOf(BankAccountFeatures.RetrieveBalance, BankAccountFeatures.InstantTransfer), serverTransactionsRetentionDays = 320)
|
||||||
)
|
)
|
||||||
val userAccount = UserAccount("12345678", "SupiDupiUser", "geheim", "Abzock-Bank", "ABCDDEBBXXX", "Monika Tester", accounts = bankAccounts, bankingGroup = BankingGroup.DKB).apply {
|
val userAccount = User("12345678", "SupiDupiUser", "geheim", "Abzock-Bank", "ABCDDEBBXXX", "Monika Tester", accounts = bankAccounts, bankingGroup = BankingGroup.DKB, finTsServerAddress = "").apply {
|
||||||
wrongCredentialsEntered = true
|
wrongCredentialsEntered = true
|
||||||
displayIndex = 99
|
displayIndex = 99
|
||||||
}
|
}
|
||||||
|
|
||||||
val persisted = underTest.persistUserAccount(userAccount)
|
val persisted = underTest.persistUser(userAccount)
|
||||||
|
|
||||||
assertNotNull(persisted.id)
|
assertNotNull(persisted.id)
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class SqliteBankingRepositoryTest {
|
||||||
|
|
||||||
val persistedBankAccount = persisted.accounts.first()
|
val persistedBankAccount = persisted.accounts.first()
|
||||||
assertNotNull(persistedBankAccount.id)
|
assertNotNull(persistedBankAccount.id)
|
||||||
assertEquals(persisted.id, persistedBankAccount.userAccountId)
|
assertEquals(persisted.id, persistedBankAccount.userId)
|
||||||
|
|
||||||
assertEquals(bankAccounts.first().identifier, persistedBankAccount.identifier)
|
assertEquals(bankAccounts.first().identifier, persistedBankAccount.identifier)
|
||||||
assertEquals(bankAccounts.first().accountHolderName, persistedBankAccount.accountHolderName)
|
assertEquals(bankAccounts.first().accountHolderName, persistedBankAccount.accountHolderName)
|
||||||
|
@ -67,7 +67,7 @@ class SqliteBankingRepositoryTest {
|
||||||
|
|
||||||
assertEquals(bankAccounts.first().features, persistedBankAccount.features)
|
assertEquals(bankAccounts.first().features, persistedBankAccount.features)
|
||||||
|
|
||||||
assertEquals(bankAccounts.first().countDaysForWhichTransactionsAreKept, persistedBankAccount.countDaysForWhichTransactionsAreKept)
|
assertEquals(bankAccounts.first().serverTransactionsRetentionDays, persistedBankAccount.serverTransactionsRetentionDays)
|
||||||
assertEquals(bankAccounts.first().hideAccount, persistedBankAccount.hideAccount)
|
assertEquals(bankAccounts.first().hideAccount, persistedBankAccount.hideAccount)
|
||||||
assertEquals(bankAccounts.first().includeInAutomaticAccountsUpdate, persistedBankAccount.includeInAutomaticAccountsUpdate)
|
assertEquals(bankAccounts.first().includeInAutomaticAccountsUpdate, persistedBankAccount.includeInAutomaticAccountsUpdate)
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ class SqliteBankingRepositoryTest {
|
||||||
|
|
||||||
assertEquals(transaction.amount, persisted.amount)
|
assertEquals(transaction.amount, persisted.amount)
|
||||||
assertEquals(transaction.currency, persisted.currency)
|
assertEquals(transaction.currency, persisted.currency)
|
||||||
assertEquals(transaction.unparsedReference, persisted.unparsedReference)
|
assertEquals(transaction.reference, persisted.reference)
|
||||||
assertEquals(transaction.bookingDate, persisted.bookingDate)
|
assertEquals(transaction.bookingDate, persisted.bookingDate)
|
||||||
assertEquals(transaction.valueDate, persisted.valueDate)
|
assertEquals(transaction.valueDate, persisted.valueDate)
|
||||||
assertEquals(transaction.otherPartyName, persisted.otherPartyName)
|
assertEquals(transaction.otherPartyName, persisted.otherPartyName)
|
||||||
|
@ -109,7 +109,7 @@ class SqliteBankingRepositoryTest {
|
||||||
|
|
||||||
assertEquals(transaction.amount, persisted.amount)
|
assertEquals(transaction.amount, persisted.amount)
|
||||||
assertEquals(transaction.currency, persisted.currency)
|
assertEquals(transaction.currency, persisted.currency)
|
||||||
assertEquals(transaction.unparsedReference, persisted.reference)
|
assertEquals(transaction.reference, persisted.reference)
|
||||||
assertEquals(transaction.valueDate, persisted.valueDate)
|
assertEquals(transaction.valueDate, persisted.valueDate)
|
||||||
assertEquals(transaction.otherPartyName, persisted.otherPartyName)
|
assertEquals(transaction.otherPartyName, persisted.otherPartyName)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue