Renamed Customer to User which is the correct term ((many) users can access a customer account at a bank; the one, that accesses a customer account over FinTS is not necessary the customer that owns the account)

This commit is contained in:
dankito 2024-08-27 23:53:15 +02:00
parent a983df42b1
commit afade80bcb
15 changed files with 51 additions and 51 deletions

View File

@ -5,7 +5,7 @@ import net.codinux.banking.client.model.options.RetrieveTransactions
import net.codinux.banking.client.model.response.GetAccountDataResponse
import net.codinux.banking.client.model.response.Response
interface BankingClientForCustomer {
interface BankingClientForUser {
/**
* Retrieves account data like customer name, her bank accounts, their balance and account transactions.

View File

@ -4,10 +4,10 @@ import net.codinux.banking.client.model.AccountCredentials
import net.codinux.banking.client.model.options.GetAccountDataOptions
import net.codinux.banking.client.model.request.GetAccountDataRequest
abstract class BankingClientForCustomerBase(
abstract class BankingClientForUserBase(
protected val credentials: AccountCredentials,
protected val client: BankingClient
) : BankingClientForCustomer {
) : BankingClientForUser {
override suspend fun getAccountDataAsync(options: GetAccountDataOptions) =
client.getAccountDataAsync(GetAccountDataRequest(credentials, options))

View File

@ -4,7 +4,7 @@ import net.codinux.banking.client.model.options.GetAccountDataOptions
import net.codinux.banking.client.model.response.GetAccountDataResponse
import net.codinux.banking.client.model.response.Response
interface BlockingBankingClientForCustomer {
interface BlockingBankingClientForUser {
// for languages not supporting default parameters (Java, Swift, JS, ...)
fun getAccountData() = getAccountData(GetAccountDataOptions())

View File

@ -4,10 +4,10 @@ import net.codinux.banking.client.model.AccountCredentials
import net.codinux.banking.client.model.options.GetAccountDataOptions
import net.codinux.banking.client.model.request.GetAccountDataRequest
abstract class BlockingBankingClientForCustomerBase(
abstract class BlockingBankingClientForUserBase(
protected val credentials: AccountCredentials,
protected val client: BlockingBankingClient
) : BlockingBankingClientForCustomer {
) : BlockingBankingClientForUser {
override fun getAccountData(options: GetAccountDataOptions) =
client.getAccountData(GetAccountDataRequest(credentials, options))

View File

@ -12,10 +12,10 @@ fun BankingClient.getAccountData(request: GetAccountDataRequest) = runBlocking {
this@getAccountData.getAccountDataAsync(request)
}
fun BankingClientForCustomer.getAccountData() = runBlocking {
fun BankingClientForUser.getAccountData() = runBlocking {
this@getAccountData.getAccountDataAsync()
}
fun BankingClientForCustomer.getAccountData(options: GetAccountDataOptions) = runBlocking {
fun BankingClientForUser.getAccountData(options: GetAccountDataOptions) = runBlocking {
this@getAccountData.getAccountDataAsync(options)
}

View File

@ -12,10 +12,10 @@ fun BankingClient.getAccountData(request: GetAccountDataRequest) = runBlocking {
this@getAccountData.getAccountDataAsync(request)
}
fun BankingClientForCustomer.getAccountData() = runBlocking {
fun BankingClientForUser.getAccountData() = runBlocking {
this@getAccountData.getAccountDataAsync()
}
fun BankingClientForCustomer.getAccountData(options: GetAccountDataOptions) = runBlocking {
fun BankingClientForUser.getAccountData(options: GetAccountDataOptions) = runBlocking {
this@getAccountData.getAccountDataAsync(options)
}

View File

@ -7,7 +7,7 @@ import net.codinux.banking.client.model.tan.TanMethod
@Suppress("RUNTIME_ANNOTATION_NOT_SUPPORTED")
@NoArgConstructor
open class CustomerAccount( // TODO: is actually a UserAccount
open class UserAccount(
val bankCode: String,
var loginName: String,
/**

View File

@ -3,11 +3,11 @@ package net.codinux.banking.client.model
import net.codinux.banking.client.model.config.NoArgConstructor
/**
* Contains only the basic info of a [CustomerAccount], just enough that a client application can display it to the user
* and the user knows exactly which [CustomerAccount] is meant / referred.
* Contains only the basic info of a [UserAccount], just enough that a client application can display it to the user
* and the user knows exactly which [UserAccount] is meant / referred.
*/
@NoArgConstructor
open class CustomerAccountViewInfo(
open class UserAccountViewInfo(
val bankCode: String,
var loginName: String,
val bankName: String,

View File

@ -1,20 +1,20 @@
package net.codinux.banking.client.model.response
import net.codinux.banking.client.model.AccountTransaction
import net.codinux.banking.client.model.CustomerAccount
import net.codinux.banking.client.model.UserAccount
import net.codinux.banking.client.model.config.JsonIgnore
import net.codinux.banking.client.model.config.NoArgConstructor
@Suppress("RUNTIME_ANNOTATION_NOT_SUPPORTED")
@NoArgConstructor
open class GetAccountDataResponse(
val customer: CustomerAccount
val user: UserAccount
) {
@get:JsonIgnore
val bookedTransactions: List<AccountTransaction>
get() = customer.accounts.flatMap { it.bookedTransactions }.sortedByDescending { it.valueDate }
get() = user.accounts.flatMap { it.bookedTransactions }.sortedByDescending { it.valueDate }
override fun toString() = customer.toString()
override fun toString() = user.toString()
}

View File

@ -1,8 +1,8 @@
package net.codinux.banking.client.model.tan
import net.codinux.banking.client.model.BankAccountViewInfo
import net.codinux.banking.client.model.CustomerAccount
import net.codinux.banking.client.model.CustomerAccountViewInfo
import net.codinux.banking.client.model.UserAccount
import net.codinux.banking.client.model.UserAccountViewInfo
import net.codinux.banking.client.model.config.JsonIgnore
import net.codinux.banking.client.model.config.NoArgConstructor
@ -21,10 +21,10 @@ open class TanChallenge(
*/
val selectedTanMethodId: String,
/**
* When adding an account, frontend has no Customer object in BankingClientCallback to know which TanMethods are
* available for Customer.
* When adding an account, frontend has no UserAccount object in BankingClientCallback to know which TanMethods are
* available for User.
* Also on other calls to bank server, bank server may returned an updated list of available TanMethods, so that
* [CustomerAccount] may contains an outdated list of available TanMethods.
* [UserAccount] may contains an outdated list of available TanMethods.
*
* Therefore i added list with up to date TanMethods here to ensure EnterTanDialog can display user's up to date TanMethods.
*/
@ -41,7 +41,7 @@ open class TanChallenge(
val tanImage: TanImage? = null,
val flickerCode: FlickerCode? = null,
val customer: CustomerAccountViewInfo,
val user: UserAccountViewInfo,
val account: BankAccountViewInfo? = null
) {

View File

@ -1,12 +1,12 @@
package net.codinux.banking.client.fints4k
import net.codinux.banking.client.BankingClientCallback
import net.codinux.banking.client.BankingClientForCustomerBase
import net.codinux.banking.client.BankingClientForUserBase
import net.codinux.banking.client.model.AccountCredentials
import net.codinux.banking.fints.config.FinTsClientConfiguration
open class FinTs4kBankingClientForCustomer(credentials: AccountCredentials, config: FinTsClientConfiguration = FinTsClientConfiguration(), callback: BankingClientCallback)
: BankingClientForCustomerBase(credentials, FinTs4kBankingClient(config, callback)) {
open class FinTs4KBankingClientForUser(credentials: AccountCredentials, config: FinTsClientConfiguration = FinTsClientConfiguration(), callback: BankingClientCallback)
: BankingClientForUserBase(credentials, FinTs4kBankingClient(config, callback)) {
constructor(bankCode: String, loginName: String, password: String, callback: BankingClientCallback)
: this(bankCode, loginName, password, FinTsClientConfiguration(), callback)

View File

@ -47,14 +47,14 @@ open class FinTs4kMapper {
open fun map(response: net.dankito.banking.client.model.response.GetAccountDataResponse): Response<GetAccountDataResponse> {
return if (response.successful && response.customerAccount != null) {
Response.success(GetAccountDataResponse(mapCustomer(response.customerAccount!!)))
Response.success(GetAccountDataResponse(mapUser(response.customerAccount!!)))
} else {
mapError(response)
}
}
open fun mapToCustomerAccountViewInfo(bank: BankData): CustomerAccountViewInfo = CustomerAccountViewInfo(
open fun mapToUserAccountViewInfo(bank: BankData): UserAccountViewInfo = UserAccountViewInfo(
bank.bankCode, bank.customerId, bank.bankName, getBankingGroup(bank.bankName, bank.bic)
)
@ -65,22 +65,22 @@ open class FinTs4kMapper {
)
protected open fun mapCustomer(customer: net.dankito.banking.client.model.CustomerAccount): CustomerAccount = CustomerAccount(
customer.bankCode, customer.loginName, customer.password,
customer.bankName, customer.bic, customer.customerName, customer.userId,
customer.accounts.map { mapAccount(it) },
protected open fun mapUser(user: net.dankito.banking.client.model.CustomerAccount) = UserAccount(
user.bankCode, user.loginName, user.password,
user.bankName, user.bic, user.customerName, user.userId,
user.accounts.map { mapAccount(it) },
customer.selectedTanMethod?.securityFunction?.code, customer.tanMethods.map { mapTanMethod(it) },
customer.selectedTanMedium?.mediumName, customer.tanMedia.map { mapTanMedium(it) },
user.selectedTanMethod?.securityFunction?.code, user.tanMethods.map { mapTanMethod(it) },
user.selectedTanMedium?.mediumName, user.tanMedia.map { mapTanMedium(it) },
getBankingGroup(customer.bankName, customer.bic)
getBankingGroup(user.bankName, user.bic)
)
protected open fun getBankingGroup(bankName: String, bic: String): BankingGroup? =
bankingGroupMapper.getBankingGroup(bankName, bic)
protected open fun mapAccount(account: net.dankito.banking.client.model.BankAccount): BankAccount = BankAccount(
protected open fun mapAccount(account: net.dankito.banking.client.model.BankAccount) = BankAccount(
account.identifier, account.accountHolderName, mapAccountType(account.type), account.iban, account.subAccountNumber,
account.productName, account.currency, account.accountLimit, account.isAccountTypeSupportedByApplication,
mapFeatures(account),
@ -146,13 +146,13 @@ open class FinTs4kMapper {
val tanMedia = challenge.bank.tanMedia.map { mapTanMedium(it) }
val selectedTanMediumName = challenge.bank.selectedTanMedium?.mediumName
val customer = mapToCustomerAccountViewInfo(challenge.bank)
val user = mapToUserAccountViewInfo(challenge.bank)
val account = challenge.account?.let { mapToBankAccountViewInfo(it) }
val tanImage = if (challenge is ImageTanChallenge) mapTanImage(challenge.image) else null
val flickerCode = if (challenge is FlickerCodeTanChallenge) mapFlickerCode(challenge.flickerCode) else null
return TanChallenge(type, action, challenge.messageToShowToUser, selectedTanMethodId, tanMethods, selectedTanMediumName, tanMedia, tanImage, flickerCode, customer, account)
return TanChallenge(type, action, challenge.messageToShowToUser, selectedTanMethodId, tanMethods, selectedTanMediumName, tanMedia, tanImage, flickerCode, user, account)
}
protected open fun mapTanChallengeType(challenge: net.codinux.banking.fints.model.TanChallenge): TanChallengeType = when {

View File

@ -19,7 +19,7 @@ class FinTs4kBankingClientTest {
}
private val underTest = FinTs4kBankingClientForCustomer(bankCode, loginName, password, SimpleBankingClientCallback { customer, tanChallenge ->
private val underTest = FinTs4KBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
})

View File

@ -51,7 +51,7 @@ class ShowUsage {
fun getAccountData() {
val client = FinTs4kBankingClientForCustomer(bankCode, loginName, password, SimpleBankingClientCallback())
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback())
val response = client.getAccountData()
@ -61,12 +61,12 @@ class ShowUsage {
private fun printReceivedData(response: Response<GetAccountDataResponse>) {
response.data?.let { data ->
val customer = data.customer
println("Kunde: ${customer.customerName} ${customer.accounts.size} Konten @ ${customer.bic} ${customer.bankName}")
val user = data.user
println("Kunde: ${user.customerName} ${user.accounts.size} Konten @ ${user.bic} ${user.bankName}")
println()
println("Konten:")
customer.accounts.sortedBy { it.type }.forEach { account ->
user.accounts.sortedBy { it.type }.forEach { account ->
println("${account.identifier} ${account.productName} ${account.balance} ${account.currency}")
}
@ -85,7 +85,7 @@ This fetches the booked account transactions of the last 90 days. In most cases
In case there is, add TAN handling in Client Callback:
```kotlin
val client = FinTs4kBankingClientForCustomer(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
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
})

View File

@ -2,7 +2,7 @@ package net.codinux.banking.client.fints4k.example
import kotlinx.datetime.LocalDate
import net.codinux.banking.client.SimpleBankingClientCallback
import net.codinux.banking.client.fints4k.FinTs4kBankingClientForCustomer
import net.codinux.banking.client.fints4k.FinTs4kBankingClientForUser
import net.codinux.banking.client.getAccountData
import net.codinux.banking.client.model.options.GetAccountDataOptions
import net.codinux.banking.client.model.options.RetrieveTransactions
@ -27,7 +27,7 @@ class ShowUsage {
fun getAccountDataSimpleExample() {
val client = FinTs4kBankingClientForCustomer(bankCode, loginName, password, SimpleBankingClientCallback())
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback())
val response = client.getAccountData()
@ -35,7 +35,7 @@ class ShowUsage {
}
fun getAccountDataFullExample() {
val client = FinTs4kBankingClientForCustomer(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
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
})
@ -59,12 +59,12 @@ class ShowUsage {
private fun printReceivedData(response: Response<GetAccountDataResponse>) {
response.data?.let { data ->
val customer = data.customer
println("Kunde: ${customer.customerName} ${customer.accounts.size} Konten @ ${customer.bic} ${customer.bankName}")
val user = data.user
println("Kunde: ${user.customerName} ${user.accounts.size} Konten @ ${user.bic} ${user.bankName}")
println()
println("Konten:")
customer.accounts.sortedBy { it.type }.forEach { account ->
user.accounts.sortedBy { it.type }.forEach { account ->
println("${account.identifier} ${account.productName} ${account.balance} ${account.currency}")
}