diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/FinTsClient.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/FinTsClient.kt index a92f22aa..90249ff3 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/FinTsClient.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/FinTsClient.kt @@ -20,6 +20,7 @@ import net.dankito.utils.web.client.RequestParameters import net.dankito.utils.web.client.WebClientResponse import org.slf4j.LoggerFactory import java.math.BigDecimal +import java.util.* open class FinTsClient @JvmOverloads constructor( @@ -82,8 +83,48 @@ open class FinTsClient @JvmOverloads constructor( } + /** + * Some banks support that according to PSD2 account transactions may be retrieved without + * a TAN (= no strong customer authorization needed). + */ + open fun tryGetTransactionsOfLast90DaysWithoutTanAsync(bank: BankData, customer: CustomerData, + callback: (GetTransactionsResponse) -> Unit) { + + callback(tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, false)) + } + + /** + * Some banks support that according to PSD2 account transactions may be retrieved without + * a TAN (= no strong customer authorization needed). + */ + open fun tryGetTransactionsOfLast90DaysWithoutTan(bank: BankData, customer: CustomerData): GetTransactionsResponse { + + return tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, false) + } + + protected open fun tryGetTransactionsOfLast90DaysWithoutTan(bank: BankData, customer: CustomerData, + skipSettingCustomerFlag: Boolean): GetTransactionsResponse { + + val ninetyDaysAgoMilliseconds = 90 * 24 * 60 * 60 * 1000L + val ninetyDaysAgo = Date(Date().time - ninetyDaysAgoMilliseconds) + + val response = getTransactions( + GetTransactionsParameter(false, ninetyDaysAgo), bank, customer) + + customer.triedToRetrieveTransactionsOfLast90DaysWithoutTan = true + + if (response.isSuccessful) { + if (skipSettingCustomerFlag == false) { + customer.supportsRetrievingTransactionsOfLast90DaysWithoutTan = + response.isStrongAuthenticationRequired + } + } + + return response + } + open fun getTransactionsAsync(parameter: GetTransactionsParameter, bank: BankData, - customer: CustomerData, callback: (GetTransactionsResponse) -> Unit) { + customer: CustomerData, callback: (GetTransactionsResponse) -> Unit) { threadPool.runAsync { callback(getTransactions(parameter, bank, customer)) @@ -95,6 +136,12 @@ open class FinTsClient @JvmOverloads constructor( // synchronizeCustomerSystemIdIfNotDoneYet(bank, customer) // even though specification says this is required it can be omitted + if (customer.supportsRetrievingTransactionsOfLast90DaysWithoutTan == null && + customer.triedToRetrieveTransactionsOfLast90DaysWithoutTan == false && + parameter.fromDate == null) { + tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, true) + } + val dialogData = DialogData() @@ -130,6 +177,13 @@ open class FinTsClient @JvmOverloads constructor( response.getFirstSegmentById(InstituteSegmentId.AccountTransactionsMt940)?.let { transactions -> + // TODO: that should not work. Find out in which method transactions are retrieved after entering TAN + // just retrieved all transactions -> check if retrieving that ones of last 90 days is possible without entering TAN + if (customer.supportsRetrievingTransactionsOfLast90DaysWithoutTan == null && + response.successful && transactions.bookedTransactions.isNotEmpty() && parameter.fromDate == null) { + tryGetTransactionsOfLast90DaysWithoutTan(bank, customer) + } + return GetTransactionsResponse(response, transactions.bookedTransactions.sortedByDescending { it.bookingDate }, transactions.unbookedTransactions, diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/model/CustomerData.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/model/CustomerData.kt index 5ddb424f..fba2d251 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/model/CustomerData.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/model/CustomerData.kt @@ -19,7 +19,9 @@ open class CustomerData( var version: VersionDesSicherheitsverfahrens = VersionDesSicherheitsverfahrens.PIN_Zwei_Schritt, var selectedLanguage: Dialogsprache = Dialogsprache.Default, var customerSystemId: String = KundensystemID.Anonymous, - var customerSystemStatus: KundensystemStatusWerte = KundensystemStatus.SynchronizingCustomerSystemId + var customerSystemStatus: KundensystemStatusWerte = KundensystemStatus.SynchronizingCustomerSystemId, + var supportsRetrievingTransactionsOfLast90DaysWithoutTan: Boolean? = null, + var triedToRetrieveTransactionsOfLast90DaysWithoutTan: Boolean = false ) { companion object { diff --git a/fints4javaLib/src/test/kotlin/net/dankito/fints/FinTsClientTest.kt b/fints4javaLib/src/test/kotlin/net/dankito/fints/FinTsClientTest.kt index 81390d53..f323dbdf 100644 --- a/fints4javaLib/src/test/kotlin/net/dankito/fints/FinTsClientTest.kt +++ b/fints4javaLib/src/test/kotlin/net/dankito/fints/FinTsClientTest.kt @@ -11,7 +11,6 @@ import net.dankito.fints.util.Java8Base64Service import org.assertj.core.api.Assertions.assertThat import org.junit.Ignore import org.junit.Test -import java.util.* @Ignore // not an automatic test, supply your settings below @@ -66,13 +65,11 @@ class FinTsClientTest { @Test fun getTransactions() { - // given - // some banks support retrieving account transactions of last 90 days without TAN - val ninetyDaysAgoMilliseconds = 90 * 24 * 60 * 60 * 1000L - val ninetyDaysAgo = Date(Date().time - ninetyDaysAgoMilliseconds) - // when - val result = underTest.getTransactions(GetTransactionsParameter(fromDate = ninetyDaysAgo), Bank, Customer) + + // some banks support retrieving account transactions of last 90 days without TAN + val result = underTest.tryGetTransactionsOfLast90DaysWithoutTan(Bank, Customer) + // then assertThat(result.isSuccessful).isTrue()