From 0e0a7b5207b558f2ca92057ed64ab9c25ac2916c Mon Sep 17 00:00:00 2001 From: dankito Date: Wed, 16 Sep 2020 15:07:21 +0200 Subject: [PATCH] Implemented filtering out duplicate transactions as some banks return some transactions multiple times in MT940 response --- .../net/dankito/banking/fints/FinTsClient.kt | 4 +-- .../banking/fints/model/AccountTransaction.kt | 31 +++++++++++++++++++ .../dankito/banking/fints/model/Currency.kt | 14 +++++++++ .../fints/model/GetTransactionsParameter.kt | 2 +- .../net/dankito/banking/fints/model/Money.kt | 18 +++++++++++ .../dankito/banking/fints4kBankingClient.kt | 5 +-- .../banking/mapper/fints4kModelMapper.kt | 2 +- 7 files changed, 70 insertions(+), 6 deletions(-) diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt index fb0b5ce4..8afecbb1 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt @@ -377,7 +377,7 @@ open class FinTsClient( val message = messageBuilder.createGetTransactionsMessage(parameter, account, dialogContext) - val bookedTransactions = mutableListOf() + val bookedTransactions = mutableSetOf() // some banks like Postbank return some transactions multiple times -> remove these var remainingMt940String = "" dialogContext.abortIfTanIsRequired = parameter.abortIfTanIsRequired @@ -398,7 +398,7 @@ open class FinTsClient( callback(GetTransactionsResponse( response, - bookedTransactions, + bookedTransactions.toList(), listOf(), // TODO: implement parsing MT942 balance ) diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/AccountTransaction.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/AccountTransaction.kt index d88c32be..ede6dc59 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/AccountTransaction.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/AccountTransaction.kt @@ -49,6 +49,37 @@ open class AccountTransaction( null, "", "", null, null, "", null) + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is AccountTransaction) return false + + if (account != other.account) return false + if (amount != other.amount) return false + if (unparsedUsage != other.unparsedUsage) return false + if (bookingDate != other.bookingDate) return false + if (otherPartyName != other.otherPartyName) return false + if (otherPartyBankCode != other.otherPartyBankCode) return false + if (otherPartyAccountId != other.otherPartyAccountId) return false + if (bookingText != other.bookingText) return false + if (valueDate != other.valueDate) return false + + return true + } + + override fun hashCode(): Int { + var result = account.hashCode() + result = 31 * result + amount.hashCode() + result = 31 * result + unparsedUsage.hashCode() + result = 31 * result + bookingDate.hashCode() + result = 31 * result + (otherPartyName?.hashCode() ?: 0) + result = 31 * result + (otherPartyBankCode?.hashCode() ?: 0) + result = 31 * result + (otherPartyAccountId?.hashCode() ?: 0) + result = 31 * result + (bookingText?.hashCode() ?: 0) + result = 31 * result + valueDate.hashCode() + return result + } + + override fun toString(): String { return "$valueDate $amount $otherPartyName: $unparsedUsage" } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/Currency.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/Currency.kt index 963b2f65..2d7e0db6 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/Currency.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/Currency.kt @@ -8,6 +8,20 @@ open class Currency( internal constructor() : this("") // for object deserializers + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is Currency) return false + + if (code != other.code) return false + + return true + } + + override fun hashCode(): Int { + return code.hashCode() + } + + override fun toString(): String { return code } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/GetTransactionsParameter.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/GetTransactionsParameter.kt index a560bca8..5ed8ca79 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/GetTransactionsParameter.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/GetTransactionsParameter.kt @@ -9,5 +9,5 @@ open class GetTransactionsParameter( val toDate: Date? = null, val maxCountEntries: Int? = null, val abortIfTanIsRequired: Boolean = false, - val retrievedChunkListener: ((List) -> Unit)? = null + val retrievedChunkListener: ((Collection) -> Unit)? = null ) \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/Money.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/Money.kt index f9ed5e53..76232e3e 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/Money.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/Money.kt @@ -16,6 +16,24 @@ open class Money( get() = "$amount $currency" + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is Money) return false + + if (amount != other.amount) return false + if (currency != other.currency) return false + + return true + } + + override fun hashCode(): Int { + var result = amount.hashCode() + result = 31 * result + currency.hashCode() + return result + } + + override fun toString(): String { return displayString } diff --git a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt index c0b7236f..422d591b 100644 --- a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt +++ b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt @@ -82,8 +82,9 @@ open class fints4kBankingClient( } else { val mappedParameter = GetTransactionsParameter(parameter.alsoRetrieveBalance, parameter.fromDate, - parameter.toDate, null, parameter.abortIfTanIsRequired, - { parameter.retrievedChunkListener?.invoke(mapper.mapTransactions(bankAccount, it)) } ) + parameter.toDate, null, parameter.abortIfTanIsRequired) { + parameter.retrievedChunkListener?.invoke(mapper.mapTransactions(bankAccount, it)) + } doGetTransactionsAsync(mappedParameter, account, bankAccount, callback) } diff --git a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt index 8f8cd3bd..69c8a2e9 100644 --- a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt +++ b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt @@ -180,7 +180,7 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { } - open fun mapTransactions(bankAccount: TypedBankAccount, transactions: List): List { + open fun mapTransactions(bankAccount: TypedBankAccount, transactions: Collection): List { return transactions.map { mapTransaction(bankAccount, it) } }