Added example how to update account transactions

This commit is contained in:
dankito 2024-09-03 22:53:26 +02:00
parent 36391c8f20
commit bd052587c5
2 changed files with 78 additions and 15 deletions

View File

@ -51,11 +51,11 @@ class ShowUsage {
fun getAccountData() { fun getAccountData() {
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback()) val client = FinTs4kBankingClient(SimpleBankingClientCallback())
val response = client.getAccountData() val response = client.getAccountData(bankCode, loginName, password) // that's all
printReceivedData(response) printReceivedData(response) // now print retrieved data (save it to database, display it in UI, ...)
} }
@ -82,15 +82,6 @@ class ShowUsage {
This fetches the booked account transactions of the last 90 days. In most cases no TAN is required for this. This fetches the booked account transactions of the last 90 days. In most cases no TAN is required for this.
In case there is, add TAN handling in Client Callback:
```kotlin
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
val tan: String? = null // if a TAN is required, add a UI or ...
callback.invoke(EnterTanResult(tan)) // ... set a break point here, get TAN e.g. from your TAN app, set tan variable in debugger view and resume debugger
})
```
You can also specify options e.g. which transactions should be retrieved: You can also specify options e.g. which transactions should be retrieved:
```kotlin ```kotlin
@ -104,6 +95,15 @@ val options = GetAccountDataOptions(
val response = client.getAccountData(options) val response = client.getAccountData(options)
``` ```
Retrieving transactions older than 90 days requires a TAN, so add TAN handling in Client Callback:
```kotlin
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
val tan: String? = null // if a TAN is required, add a UI or ...
callback.invoke(EnterTanResult(tan)) // ... set a break point here, get TAN e.g. from your TAN app, set tan variable in debugger view and resume debugger
})
```
Add some error handling by checking `response.error`: Add some error handling by checking `response.error`:
```kotlin ```kotlin
@ -111,3 +111,37 @@ response.error?.let{ error ->
println("Could not fetch account data: ${error.internalError ?: error.errorMessagesFromBank.joinToString()}") println("Could not fetch account data: ${error.internalError ?: error.errorMessagesFromBank.joinToString()}")
} }
``` ```
### Update Account Transactions
The data model saves when it retrieved account transactions the last time (in `BankAccount.lastTransactionsRetrievalTime`).
So you only need to call `FinTs4kBankingClient.updateAccountTransactions()` to retrieve all transactions starting from
`BankAccount.lastTransactionsRetrievalTime`.
But as we can only specify from which day on account transactions should be retrieved, response may contain some transactions
from the day of `lastTransactionsRetrievalTime` that we already have locally. To filter out these you can use
`BankingModelService().findNewTransactions(retrieveTransactions, existingTransactions)`:
```kotlin
fun updateAccountTransactions() {
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback())
// simulate account transactions we retrieved last time
val today = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date
val lastCallToBankServer = client.getAccountData(GetAccountDataOptions(RetrieveTransactions.AccordingToRetrieveFromAndTo, retrieveTransactionsFrom = today.minusDays(90), retrieveTransactionsTo = today.minusDays(30)))
if (lastCallToBankServer.data != null) { // now update account transactions
val existingTransactions = lastCallToBankServer.data!!.bookedTransactions
val updateTransactionsResponse = client.updateAccountTransactions()
if (updateTransactionsResponse.data != null) {
val retrievedTransactions = updateTransactionsResponse.data!!.flatMap { it.bookedTransactions }
val newTransactions = BankingModelService().findNewTransactions(retrievedTransactions, existingTransactions)
// `retrievedTransactions` may contain transactions we already have locally, `newTransactions` only
// transactions that are not in `existingTransactions`
}
}
}
```

View File

@ -1,7 +1,11 @@
package net.codinux.banking.client.fints4k.example package net.codinux.banking.client.fints4k.example
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import net.codinux.banking.client.SimpleBankingClientCallback import net.codinux.banking.client.SimpleBankingClientCallback
import net.codinux.banking.client.fints4k.FinTs4kBankingClient
import net.codinux.banking.client.fints4k.FinTs4kBankingClientForUser import net.codinux.banking.client.fints4k.FinTs4kBankingClientForUser
import net.codinux.banking.client.getAccountData import net.codinux.banking.client.getAccountData
import net.codinux.banking.client.model.options.GetAccountDataOptions import net.codinux.banking.client.model.options.GetAccountDataOptions
@ -9,6 +13,9 @@ import net.codinux.banking.client.model.options.RetrieveTransactions
import net.codinux.banking.client.model.response.GetAccountDataResponse import net.codinux.banking.client.model.response.GetAccountDataResponse
import net.codinux.banking.client.model.response.Response import net.codinux.banking.client.model.response.Response
import net.codinux.banking.client.model.tan.EnterTanResult import net.codinux.banking.client.model.tan.EnterTanResult
import net.codinux.banking.client.service.BankingModelService
import net.codinux.banking.client.updateAccountTransactions
import net.codinux.banking.fints.extensions.minusDays
fun main() { fun main() {
val showUsage = ShowUsage() val showUsage = ShowUsage()
@ -27,11 +34,11 @@ class ShowUsage {
fun getAccountDataSimpleExample() { fun getAccountDataSimpleExample() {
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback()) val client = FinTs4kBankingClient(SimpleBankingClientCallback())
val response = client.getAccountData() val response = client.getAccountData(bankCode, loginName, password) // that's all
printReceivedData(response) printReceivedData(response) // now print retrieved data (save it to database, display it in UI, ...)
} }
fun getAccountDataFullExample() { fun getAccountDataFullExample() {
@ -57,6 +64,28 @@ class ShowUsage {
} }
fun updateAccountTransactions() {
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback())
// simulate account transactions we retrieved last time
val today = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date
val lastCallToBankServer = client.getAccountData(GetAccountDataOptions(RetrieveTransactions.AccordingToRetrieveFromAndTo, retrieveTransactionsFrom = today.minusDays(90), retrieveTransactionsTo = today.minusDays(30)))
if (lastCallToBankServer.data != null) { // now update account transactions
val existingTransactions = lastCallToBankServer.data!!.bookedTransactions
val updateTransactionsResponse = client.updateAccountTransactions()
if (updateTransactionsResponse.data != null) {
val retrievedTransactions = updateTransactionsResponse.data!!.flatMap { it.bookedTransactions }
val newTransactions = BankingModelService().findNewTransactions(retrievedTransactions, existingTransactions)
// `retrievedTransactions` may contain transactions we already have locally, `newTransactions` only
// transactions that are not in `existingTransactions`
}
}
}
private fun printReceivedData(response: Response<GetAccountDataResponse>) { private fun printReceivedData(response: Response<GetAccountDataResponse>) {
response.data?.let { data -> response.data?.let { data ->
val user = data.user val user = data.user