Fixed that bookedTransactions just got associated with first available bank account, which is just not true; Fixed grouping balances by BankAccount
This commit is contained in:
parent
438772a6a2
commit
be479edc11
|
@ -26,17 +26,20 @@ open class fints4javaModelMapper {
|
|||
}
|
||||
|
||||
open fun mapResponse(account: Account, response: net.dankito.fints.response.client.AddAccountResponse): AddAccountResponse {
|
||||
var bookedTransactions = mapOf<BankAccount, List<AccountTransaction>>()
|
||||
var balances = mapOf<BankAccount, BigDecimal>()
|
||||
val balances = response.balances.mapKeys { findMatchingBankAccount(account, it.key) }.filter { it.key != null } as Map<BankAccount, BigDecimal>
|
||||
|
||||
account.bankAccounts.firstOrNull()?.let { bankAccount -> // TODO: set bank account also on net.dankito.fints.response.client.GetTransactionsResponse
|
||||
bookedTransactions = mapOf(bankAccount to mapTransactions(bankAccount, response.bookedTransactions))
|
||||
response.balance?.let { balances = mapOf(bankAccount to it) }
|
||||
val bookedTransactions = response.bookedTransactions.associateBy { it.account }
|
||||
val mappedBookedTransactions = mutableMapOf<BankAccount, List<AccountTransaction>>()
|
||||
|
||||
bookedTransactions.keys.forEach { accountData ->
|
||||
findMatchingBankAccount(account, accountData)?.let { bankAccount ->
|
||||
mappedBookedTransactions.put(bankAccount, mapTransactions(bankAccount, response.bookedTransactions))
|
||||
}
|
||||
}
|
||||
|
||||
return AddAccountResponse(response.isSuccessful, mapErrorToShowToUser(response),
|
||||
account, response.supportsRetrievingTransactionsOfLast90DaysWithoutTan,
|
||||
bookedTransactions,
|
||||
mappedBookedTransactions,
|
||||
mapOf(), // TODO: map unbooked transactions
|
||||
balances,
|
||||
response.exception)
|
||||
|
@ -96,6 +99,10 @@ open class fints4javaModelMapper {
|
|||
return customer.accounts.firstOrNull { bankAccount.identifier == it.accountIdentifier }
|
||||
}
|
||||
|
||||
open fun findMatchingBankAccount(account: Account, accountData: AccountData): BankAccount? {
|
||||
return account.bankAccounts.firstOrNull { it.identifier == accountData.accountIdentifier }
|
||||
}
|
||||
|
||||
|
||||
open fun mapTransactions(bankAccount: BankAccount, transactions: List<net.dankito.fints.model.AccountTransaction>): List<AccountTransaction> {
|
||||
return transactions.map { mapTransaction(bankAccount, it) }
|
||||
|
|
|
@ -154,23 +154,25 @@ open class FinTsClient @JvmOverloads constructor(
|
|||
|
||||
// also check if retrieving account transactions of last 90 days without tan is supported (and thereby may retrieve first account transactions)
|
||||
val transactionsOfLast90DaysResponses = mutableListOf<GetTransactionsResponse>()
|
||||
val balances = mutableMapOf<AccountData, BigDecimal>()
|
||||
customer.accounts.forEach { account ->
|
||||
if (account.supportsRetrievingAccountTransactions) {
|
||||
transactionsOfLast90DaysResponses.add(
|
||||
tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, account, false))
|
||||
val response = tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, account, false)
|
||||
transactionsOfLast90DaysResponses.add(response)
|
||||
response.balance?.let { balances.put(account, it) }
|
||||
}
|
||||
}
|
||||
val transactionsOfLast90DaysResponse = transactionsOfLast90DaysResponses.firstOrNull { it.isSuccessful } ?: GetTransactionsResponse(Response(false))
|
||||
|
||||
if (didOverwriteUserUnselectedTanProcedure) {
|
||||
customer.resetSelectedTanProcedure()
|
||||
}
|
||||
|
||||
val supportsRetrievingTransactionsOfLast90DaysWithoutTan = transactionsOfLast90DaysResponses.firstOrNull { it.isSuccessful } != null
|
||||
val unbookedTransactions = transactionsOfLast90DaysResponses.flatMap { it.unbookedTransactions }
|
||||
val bookedTransactions = transactionsOfLast90DaysResponses.flatMap { it.bookedTransactions }
|
||||
|
||||
return AddAccountResponse(synchronizeCustomerResponse.toResponse(), bank, customer,
|
||||
transactionsOfLast90DaysResponse.isSuccessful,
|
||||
transactionsOfLast90DaysResponse.bookedTransactions,
|
||||
transactionsOfLast90DaysResponse.unbookedTransactions,
|
||||
transactionsOfLast90DaysResponse.balance)
|
||||
supportsRetrievingTransactionsOfLast90DaysWithoutTan, bookedTransactions, unbookedTransactions, balances)
|
||||
}
|
||||
|
||||
|
||||
|
@ -253,7 +255,7 @@ open class FinTsClient @JvmOverloads constructor(
|
|||
tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, account, true)
|
||||
}
|
||||
|
||||
val bookedAndUnbookedTransactions = getTransactionsFromResponse(response, transactions)
|
||||
val bookedAndUnbookedTransactions = getTransactionsFromResponse(response, transactions, account)
|
||||
|
||||
return GetTransactionsResponse(response,
|
||||
bookedAndUnbookedTransactions.first.sortedByDescending { it.bookingDate },
|
||||
|
@ -264,13 +266,13 @@ open class FinTsClient @JvmOverloads constructor(
|
|||
return GetTransactionsResponse(response)
|
||||
}
|
||||
|
||||
protected open fun getTransactionsFromResponse(response: Response, transactions: ReceivedAccountTransactions): Pair<List<AccountTransaction>, List<Any>> {
|
||||
protected open fun getTransactionsFromResponse(response: Response, transactions: ReceivedAccountTransactions, account: AccountData): Pair<List<AccountTransaction>, List<Any>> {
|
||||
val bookedTransactionsString = StringBuilder()
|
||||
val unbookedTransactionsString = StringBuilder()
|
||||
|
||||
getTransactionsFromResponse(response, transactions, bookedTransactionsString, unbookedTransactionsString)
|
||||
|
||||
val bookedTransactions = mt940Parser.parseTransactions(bookedTransactionsString.toString())
|
||||
val bookedTransactions = mt940Parser.parseTransactions(bookedTransactionsString.toString(), account)
|
||||
val unbookedTransactions = listOf<Any>() // TODO: implement parsing MT942
|
||||
|
||||
return Pair(bookedTransactions, unbookedTransactions)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.dankito.fints.model
|
||||
|
||||
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Laenderkennzeichen
|
||||
import net.dankito.fints.response.segments.AccountType
|
||||
import net.dankito.fints.response.segments.JobParameters
|
||||
|
||||
|
@ -25,6 +26,8 @@ open class AccountData(
|
|||
var triedToRetrieveTransactionsOfLast90DaysWithoutTan: Boolean = false
|
||||
) {
|
||||
|
||||
internal constructor() : this("", null, Laenderkennzeichen.Germany, "", null, "", null, null, "", null, null, listOf())
|
||||
|
||||
override fun toString(): String {
|
||||
return "$productName $accountIdentifier $accountHolderName"
|
||||
}
|
||||
|
|
|
@ -16,12 +16,13 @@ open class AccountTransaction(
|
|||
val bookingText: String?,
|
||||
val valueDate: Date?,
|
||||
val openingBalance: BigDecimal?,
|
||||
val closingBalance: BigDecimal?
|
||||
val closingBalance: BigDecimal?,
|
||||
val account: AccountData
|
||||
// TODO: may also add other values from parsed usage lines
|
||||
) {
|
||||
|
||||
// for object deserializers
|
||||
private constructor() : this(0.toBigDecimal(),"", "", Date(), null, null, null, null, null, null, null)
|
||||
internal constructor() : this(0.toBigDecimal(),"", "", Date(), null, null, null, null, null, null, null, AccountData())
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.dankito.fints.response.client
|
||||
|
||||
import net.dankito.fints.model.AccountData
|
||||
import net.dankito.fints.model.AccountTransaction
|
||||
import net.dankito.fints.model.BankData
|
||||
import net.dankito.fints.model.CustomerData
|
||||
|
@ -14,6 +15,6 @@ open class AddAccountResponse(
|
|||
val supportsRetrievingTransactionsOfLast90DaysWithoutTan: Boolean = false,
|
||||
bookedTransactionsOfLast90Days: List<AccountTransaction> = listOf(),
|
||||
unbookedTransactionsOfLast90Days: List<Any> = listOf(),
|
||||
balance: BigDecimal? = null
|
||||
val balances: Map<AccountData, BigDecimal> = mapOf()
|
||||
)
|
||||
: GetTransactionsResponse(response, bookedTransactionsOfLast90Days, unbookedTransactionsOfLast90Days, balance)
|
||||
: GetTransactionsResponse(response, bookedTransactionsOfLast90Days, unbookedTransactionsOfLast90Days, balances.values.fold(BigDecimal.ZERO) { acc, e -> acc + e })
|
|
@ -1,10 +1,11 @@
|
|||
package net.dankito.fints.transactions
|
||||
|
||||
import net.dankito.fints.model.AccountData
|
||||
import net.dankito.fints.model.AccountTransaction
|
||||
|
||||
|
||||
interface IAccountTransactionsParser {
|
||||
|
||||
fun parseTransactions(transactionsString: String): List<AccountTransaction>
|
||||
fun parseTransactions(transactionsString: String, account: AccountData): List<AccountTransaction>
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package net.dankito.fints.transactions
|
||||
|
||||
import net.dankito.fints.model.AccountData
|
||||
import net.dankito.fints.model.AccountTransaction
|
||||
import net.dankito.fints.transactions.mt940.IMt940Parser
|
||||
import net.dankito.fints.transactions.mt940.Mt940Parser
|
||||
|
@ -20,15 +21,15 @@ open class Mt940AccountTransactionsParser @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
|
||||
override fun parseTransactions(transactionsString: String): List<AccountTransaction> {
|
||||
override fun parseTransactions(transactionsString: String, account: AccountData): List<AccountTransaction> {
|
||||
val accountStatements = mt940Parser.parseMt940String(transactionsString)
|
||||
|
||||
return accountStatements.flatMap { mapToAccountTransactions(it) }
|
||||
return accountStatements.flatMap { mapToAccountTransactions(it, account) }
|
||||
}
|
||||
|
||||
protected open fun mapToAccountTransactions(statement: AccountStatement): List<AccountTransaction> {
|
||||
protected open fun mapToAccountTransactions(statement: AccountStatement, account: AccountData): List<AccountTransaction> {
|
||||
try {
|
||||
return statement.transactions.map { mapToAccountTransaction(statement, it) }
|
||||
return statement.transactions.map { mapToAccountTransaction(statement, it, account) }
|
||||
} catch (e: Exception) {
|
||||
log.error("Could not map AccountStatement '$statement' to AccountTransactions", e)
|
||||
}
|
||||
|
@ -36,7 +37,7 @@ open class Mt940AccountTransactionsParser @JvmOverloads constructor(
|
|||
return listOf()
|
||||
}
|
||||
|
||||
protected open fun mapToAccountTransaction(statement: AccountStatement, transaction: Transaction): AccountTransaction {
|
||||
protected open fun mapToAccountTransaction(statement: AccountStatement, transaction: Transaction, account: AccountData): AccountTransaction {
|
||||
return AccountTransaction(
|
||||
mapAmount(transaction.turnover),
|
||||
statement.closingBalance.currency,
|
||||
|
@ -48,7 +49,8 @@ open class Mt940AccountTransactionsParser @JvmOverloads constructor(
|
|||
transaction.details?.bookingText,
|
||||
transaction.turnover.valueDate,
|
||||
mapAmount(statement.openingBalance), // TODO: that's not true, these are the opening and closing balance of
|
||||
mapAmount(statement.closingBalance) // all transactions of this day, not this specific transaction's ones
|
||||
mapAmount(statement.closingBalance), // all transactions of this day, not this specific transaction's ones
|
||||
account
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.dankito.fints.transactions
|
||||
|
||||
import net.dankito.fints.model.AccountData
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
|
@ -24,7 +25,7 @@ class Mt940AccountTransactionsParserTest {
|
|||
|
||||
|
||||
// when
|
||||
val result = underTest.parseTransactions(transactionsString)
|
||||
val result = underTest.parseTransactions(transactionsString, AccountData())
|
||||
|
||||
|
||||
// then
|
||||
|
|
Loading…
Reference in New Issue