Compare commits
13 Commits
fd7a3bc747
...
4fbb0425e6
Author | SHA1 | Date |
---|---|---|
dankito | 4fbb0425e6 | |
dankito | 9af8d0eb1d | |
dankito | 045774ff3f | |
dankito | 400c13d6a2 | |
dankito | 62482fb5a3 | |
dankito | 68317f3b1c | |
dankito | 72608a444d | |
dankito | 89e21dc38a | |
dankito | 8f822e9469 | |
dankito | a6b2ed8729 | |
dankito | 83dfd41784 | |
dankito | 52af60077a | |
dankito | bf211e238f |
|
@ -41,7 +41,7 @@ interface BankingClient {
|
||||||
*
|
*
|
||||||
* Optionally specify which [accounts] should be updated. If not specified all accounts will be updated.
|
* Optionally specify which [accounts] should be updated. If not specified all accounts will be updated.
|
||||||
*/
|
*/
|
||||||
suspend fun updateAccountTransactionsAsync(user: User, accounts: List<BankAccount>? = null): Response<List<GetTransactionsResponse>>
|
suspend fun updateAccountTransactionsAsync(bank: BankAccess, accounts: List<BankAccount>? = null): Response<List<GetTransactionsResponse>>
|
||||||
|
|
||||||
|
|
||||||
suspend fun transferMoneyAsync(bankCode: String, loginName: String, password: String, recipientName: String,
|
suspend fun transferMoneyAsync(bankCode: String, loginName: String, password: String, recipientName: String,
|
||||||
|
|
|
@ -3,7 +3,7 @@ package net.codinux.banking.client
|
||||||
import net.codinux.banking.client.model.AccountCredentials
|
import net.codinux.banking.client.model.AccountCredentials
|
||||||
import net.codinux.banking.client.model.Amount
|
import net.codinux.banking.client.model.Amount
|
||||||
import net.codinux.banking.client.model.BankAccount
|
import net.codinux.banking.client.model.BankAccount
|
||||||
import net.codinux.banking.client.model.User
|
import net.codinux.banking.client.model.BankAccess
|
||||||
import net.codinux.banking.client.model.options.GetAccountDataOptions
|
import net.codinux.banking.client.model.options.GetAccountDataOptions
|
||||||
import net.codinux.banking.client.model.request.GetAccountDataRequest
|
import net.codinux.banking.client.model.request.GetAccountDataRequest
|
||||||
import net.codinux.banking.client.model.request.TransferMoneyRequest
|
import net.codinux.banking.client.model.request.TransferMoneyRequest
|
||||||
|
@ -16,23 +16,23 @@ abstract class BankingClientForUserBase(
|
||||||
protected val client: BankingClient
|
protected val client: BankingClient
|
||||||
) : BankingClientForUser {
|
) : BankingClientForUser {
|
||||||
|
|
||||||
private lateinit var user: User
|
private lateinit var bank: BankAccess
|
||||||
|
|
||||||
override suspend fun getAccountDataAsync(options: GetAccountDataOptions) =
|
override suspend fun getAccountDataAsync(options: GetAccountDataOptions) =
|
||||||
client.getAccountDataAsync(GetAccountDataRequest(credentials, options)).also {
|
client.getAccountDataAsync(GetAccountDataRequest(credentials, options)).also {
|
||||||
it.data?.user?.let { retrievedUser ->
|
it.data?.bank?.let { retrievedBank ->
|
||||||
this.user = retrievedUser
|
this.bank = retrievedBank
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateAccountTransactionsAsync(accounts: List<BankAccount>?): Response<List<GetTransactionsResponse>> =
|
override suspend fun updateAccountTransactionsAsync(accounts: List<BankAccount>?): Response<List<GetTransactionsResponse>> =
|
||||||
client.updateAccountTransactionsAsync(user, accounts)
|
client.updateAccountTransactionsAsync(bank, accounts)
|
||||||
|
|
||||||
|
|
||||||
override suspend fun transferMoneyAsync(recipientName: String, recipientAccountIdentifier: String, amount: Amount, paymentReference: String?) =
|
override suspend fun transferMoneyAsync(recipientName: String, recipientAccountIdentifier: String, amount: Amount, paymentReference: String?) =
|
||||||
transferMoneyAsync(TransferMoneyRequest(null, recipientName, recipientAccountIdentifier, null, amount, paymentReference = paymentReference))
|
transferMoneyAsync(TransferMoneyRequest(null, recipientName, recipientAccountIdentifier, null, amount, paymentReference = paymentReference))
|
||||||
|
|
||||||
override suspend fun transferMoneyAsync(request: TransferMoneyRequest) =
|
override suspend fun transferMoneyAsync(request: TransferMoneyRequest) =
|
||||||
client.transferMoneyAsync(TransferMoneyRequestForUser(user.bankCode, user.loginName, user.password!!, request))
|
client.transferMoneyAsync(TransferMoneyRequestForUser(bank.domesticBankCode, bank.loginName, bank.password!!, request))
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package net.codinux.banking.client
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import net.codinux.banking.client.model.Amount
|
import net.codinux.banking.client.model.Amount
|
||||||
import net.codinux.banking.client.model.BankAccount
|
import net.codinux.banking.client.model.BankAccount
|
||||||
import net.codinux.banking.client.model.User
|
import net.codinux.banking.client.model.BankAccess
|
||||||
import net.codinux.banking.client.model.options.GetAccountDataOptions
|
import net.codinux.banking.client.model.options.GetAccountDataOptions
|
||||||
import net.codinux.banking.client.model.request.GetAccountDataRequest
|
import net.codinux.banking.client.model.request.GetAccountDataRequest
|
||||||
import net.codinux.banking.client.model.request.TransferMoneyRequest
|
import net.codinux.banking.client.model.request.TransferMoneyRequest
|
||||||
|
@ -19,8 +19,8 @@ fun BankingClient.getAccountData(request: GetAccountDataRequest) = runBlocking {
|
||||||
getAccountDataAsync(request)
|
getAccountDataAsync(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BankingClient.updateAccountTransactions(user: User, accounts: List<BankAccount>? = null) = runBlocking {
|
fun BankingClient.updateAccountTransactions(bank: BankAccess, accounts: List<BankAccount>? = null) = runBlocking {
|
||||||
updateAccountTransactionsAsync(user, accounts)
|
updateAccountTransactionsAsync(bank, accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,28 +2,42 @@ package net.codinux.banking.client.model
|
||||||
|
|
||||||
import platform.Foundation.NSDecimalNumber
|
import platform.Foundation.NSDecimalNumber
|
||||||
import net.codinux.banking.client.model.config.NoArgConstructor
|
import net.codinux.banking.client.model.config.NoArgConstructor
|
||||||
|
import platform.Foundation.NSDecimalNumberHandler
|
||||||
|
import platform.Foundation.NSRoundingMode
|
||||||
|
|
||||||
@NoArgConstructor
|
@NoArgConstructor
|
||||||
actual class Amount actual constructor(amount: String) : NSDecimalNumber(string = amount) {
|
actual class Amount actual constructor(amount: String) {
|
||||||
|
|
||||||
actual companion object {
|
actual companion object {
|
||||||
actual val Zero = Amount("0.00")
|
actual val Zero = Amount("0.00")
|
||||||
|
|
||||||
|
private val handler = NSDecimalNumberHandler.decimalNumberHandlerWithRoundingMode(roundingMode = NSRoundingMode.NSRoundBankers, scale = DecimalPrecision.toShort(), false, false, false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal val amount = NSDecimalNumber(string = amount)
|
||||||
|
|
||||||
|
|
||||||
actual operator fun plus(other: Amount): Amount =
|
actual operator fun plus(other: Amount): Amount =
|
||||||
Amount(this.decimalNumberByAdding(other).stringValue)
|
Amount(amount.decimalNumberByAdding(other.amount).stringValue)
|
||||||
|
|
||||||
actual operator fun minus(other: Amount): Amount =
|
actual operator fun minus(other: Amount): Amount =
|
||||||
Amount(this.decimalNumberBySubtracting(other).stringValue)
|
Amount(amount.decimalNumberBySubtracting(other.amount).stringValue)
|
||||||
|
|
||||||
actual operator fun times(other: Amount): Amount =
|
actual operator fun times(other: Amount): Amount =
|
||||||
Amount(this.decimalNumberByMultiplyingBy(other).stringValue)
|
Amount(amount.decimalNumberByMultiplyingBy(other.amount).stringValue)
|
||||||
|
|
||||||
actual operator fun div(other: Amount): Amount =
|
actual operator fun div(other: Amount): Amount =
|
||||||
Amount(this.decimalNumberByDividingBy(other).stringValue)
|
Amount(amount.decimalNumberByDividingBy(other.amount, handler).stringValue)
|
||||||
|
|
||||||
|
|
||||||
actual override fun toString(): String = this.stringValue
|
override fun equals(other: Any?): Boolean {
|
||||||
|
return other is Amount && this.amount == other.amount
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode() =
|
||||||
|
amount.hashCode()
|
||||||
|
|
||||||
|
actual override fun toString(): String = amount.stringValue
|
||||||
|
|
||||||
}
|
}
|
|
@ -124,7 +124,8 @@ open class AccountTransaction(
|
||||||
*/
|
*/
|
||||||
val isReversal: Boolean = false,
|
val isReversal: Boolean = false,
|
||||||
|
|
||||||
var userSetDisplayName: String? = null,
|
var userSetReference: String? = null,
|
||||||
|
var userSetOtherPartyName: String? = null,
|
||||||
var category: String? = null,
|
var category: String? = null,
|
||||||
var notes: String? = null,
|
var notes: String? = null,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -12,6 +12,19 @@ fun Amount.toFloat() =
|
||||||
fun Amount.toDouble() =
|
fun Amount.toDouble() =
|
||||||
this.toString().toDouble()
|
this.toString().toDouble()
|
||||||
|
|
||||||
|
val Amount.isNegative: Boolean
|
||||||
|
get() = this.toString().startsWith("-")
|
||||||
|
|
||||||
|
fun Collection<Amount>.sum(): Amount {
|
||||||
|
var sum: Amount = Amount.Zero
|
||||||
|
|
||||||
|
for (element in this) {
|
||||||
|
sum += element
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@NoArgConstructor
|
@NoArgConstructor
|
||||||
expect class Amount(amount: String = "0") {
|
expect class Amount(amount: String = "0") {
|
||||||
|
|
|
@ -7,16 +7,20 @@ import net.codinux.banking.client.model.tan.TanMethod
|
||||||
|
|
||||||
@Suppress("RUNTIME_ANNOTATION_NOT_SUPPORTED")
|
@Suppress("RUNTIME_ANNOTATION_NOT_SUPPORTED")
|
||||||
@NoArgConstructor
|
@NoArgConstructor
|
||||||
open class User(
|
open class BankAccess(
|
||||||
val bankCode: String,
|
/**
|
||||||
|
* The country specific bank code, like in Germany the Bankleitzahl, in USA the Routing Number, in Great Britain
|
||||||
|
* the Sort Code, in India the FSC Code, ...
|
||||||
|
*/
|
||||||
|
val domesticBankCode: String,
|
||||||
var loginName: String,
|
var loginName: String,
|
||||||
/**
|
/**
|
||||||
* User may decides to not save password .
|
* User may decides to not save password.
|
||||||
*/
|
*/
|
||||||
var password: String?,
|
var password: String?,
|
||||||
|
|
||||||
val bankName: String,
|
val bankName: String,
|
||||||
val bic: String,
|
val bic: String?, // not all banks (in the world) have a BIC
|
||||||
|
|
||||||
val customerName: String,
|
val customerName: String,
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +33,7 @@ open class User(
|
||||||
* So in most cases the userId is identical with the customerId = loginName in our speech, but there are rare cases
|
* So in most cases the userId is identical with the customerId = loginName in our speech, but there are rare cases
|
||||||
* where the userId differs from customerId.
|
* where the userId differs from customerId.
|
||||||
*/
|
*/
|
||||||
val userId: String? = null,
|
var userId: String? = null,
|
||||||
|
|
||||||
open val accounts: List<BankAccount> = emptyList(),
|
open val accounts: List<BankAccount> = emptyList(),
|
||||||
|
|
||||||
|
@ -39,8 +43,8 @@ open class User(
|
||||||
* As [tanMethods] also contains selected TanMethod, we didn't want to duplicate this object. Use
|
* As [tanMethods] also contains selected TanMethod, we didn't want to duplicate this object. Use
|
||||||
* [selectedTanMethod] to get selected TanMethod or iterate over [tanMethods] and filter selected one by this id.
|
* [selectedTanMethod] to get selected TanMethod or iterate over [tanMethods] and filter selected one by this id.
|
||||||
*/
|
*/
|
||||||
val selectedTanMethodIdentifier: String? = null,
|
var selectedTanMethodIdentifier: String? = null,
|
||||||
open val tanMethods: List<TanMethod> = listOf(),
|
open val tanMethods: MutableList<out TanMethod> = mutableListOf(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifier of selected TanMedium.
|
* Identifier of selected TanMedium.
|
||||||
|
@ -48,11 +52,15 @@ open class User(
|
||||||
* As [tanMedia] also contains selected TanMedium, we didn't want to duplicate this object. Use [selectedTanMedium]
|
* As [tanMedia] also contains selected TanMedium, we didn't want to duplicate this object. Use [selectedTanMedium]
|
||||||
* to get selected TanMedium or iterate over [tanMedia] and filter selected one by this medium name.
|
* to get selected TanMedium or iterate over [tanMedia] and filter selected one by this medium name.
|
||||||
*/
|
*/
|
||||||
val selectedTanMediumIdentifier: String? = null,
|
var selectedTanMediumIdentifier: String? = null,
|
||||||
open val tanMedia: List<TanMedium> = listOf(),
|
open val tanMedia: MutableList<out TanMedium> = mutableListOf(),
|
||||||
|
|
||||||
var bankingGroup: BankingGroup? = null,
|
var bankingGroup: BankingGroup? = null,
|
||||||
open var serverAddress: String? = null
|
open var serverAddress: String? = null,
|
||||||
|
/**
|
||||||
|
* The ISO code of the country where the bank resides and to know the system of [domesticBankCode].
|
||||||
|
*/
|
||||||
|
val countryCode: String = "de"
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var userSetDisplayName: String? = null
|
var userSetDisplayName: String? = null
|
|
@ -20,16 +20,15 @@ open class BankAccount(
|
||||||
val isAccountTypeSupportedByApplication: Boolean = false,
|
val isAccountTypeSupportedByApplication: Boolean = false,
|
||||||
val features: Set<BankAccountFeatures> = emptySet(),
|
val features: Set<BankAccountFeatures> = emptySet(),
|
||||||
|
|
||||||
// var balance: BigDecimal = BigDecimal.ZERO,
|
var balance: Amount = Amount.Zero,
|
||||||
var balance: Amount = Amount.Zero, // TODO: add a BigDecimal library
|
|
||||||
|
|
||||||
val serverTransactionsRetentionDays: Int? = null,
|
val serverTransactionsRetentionDays: Int? = null,
|
||||||
open var lastAccountUpdateTime: Instant? = null,
|
open var lastAccountUpdateTime: Instant? = null,
|
||||||
var retrievedTransactionsFrom: LocalDate? = null,
|
var retrievedTransactionsFrom: LocalDate? = null,
|
||||||
|
|
||||||
open val bookedTransactions: MutableList<AccountTransaction> = mutableListOf(),
|
open val bookedTransactions: MutableList<out AccountTransaction> = mutableListOf(),
|
||||||
open val prebookedTransactions: MutableList<PrebookedAccountTransaction> = mutableListOf(),
|
open val prebookedTransactions: MutableList<out PrebookedAccountTransaction> = mutableListOf(),
|
||||||
open val holdings: List<Holding> = emptyList(),
|
open val holdings: MutableList<out Holding> = mutableListOf(),
|
||||||
|
|
||||||
var userSetDisplayName: String? = null,
|
var userSetDisplayName: String? = null,
|
||||||
var displayIndex: Int = 0,
|
var displayIndex: Int = 0,
|
||||||
|
@ -41,6 +40,18 @@ open class BankAccount(
|
||||||
open val displayName: String
|
open val displayName: String
|
||||||
get() = userSetDisplayName ?: productName ?: identifier
|
get() = userSetDisplayName ?: productName ?: identifier
|
||||||
|
|
||||||
|
open fun addTransactions(transactions: List<out AccountTransaction>) {
|
||||||
|
(this.bookedTransactions as MutableList<AccountTransaction>).addAll(transactions)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun addPrebookedTransactions(transactions: List<out PrebookedAccountTransaction>) {
|
||||||
|
(this.prebookedTransactions as MutableList<PrebookedAccountTransaction>).addAll(transactions)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun addHoldings(holdings: List<out Holding>) {
|
||||||
|
(this.holdings as MutableList<Holding>).addAll(holdings)
|
||||||
|
}
|
||||||
|
|
||||||
@get:JsonIgnore
|
@get:JsonIgnore
|
||||||
open val supportsTransactionRetrieval: Boolean
|
open val supportsTransactionRetrieval: Boolean
|
||||||
get() = supportsAnyFeature(BankAccountFeatures.RetrieveBalance)
|
get() = supportsAnyFeature(BankAccountFeatures.RetrieveBalance)
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
package net.codinux.banking.client.model.response
|
package net.codinux.banking.client.model.response
|
||||||
|
|
||||||
import net.codinux.banking.client.model.AccountTransaction
|
import net.codinux.banking.client.model.AccountTransaction
|
||||||
import net.codinux.banking.client.model.User
|
import net.codinux.banking.client.model.BankAccess
|
||||||
import net.codinux.banking.client.model.config.JsonIgnore
|
import net.codinux.banking.client.model.config.JsonIgnore
|
||||||
import net.codinux.banking.client.model.config.NoArgConstructor
|
import net.codinux.banking.client.model.config.NoArgConstructor
|
||||||
|
|
||||||
@Suppress("RUNTIME_ANNOTATION_NOT_SUPPORTED")
|
@Suppress("RUNTIME_ANNOTATION_NOT_SUPPORTED")
|
||||||
@NoArgConstructor
|
@NoArgConstructor
|
||||||
open class GetAccountDataResponse(
|
open class GetAccountDataResponse(
|
||||||
val user: User
|
val bank: BankAccess
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@get:JsonIgnore
|
@get:JsonIgnore
|
||||||
val bookedTransactions: List<AccountTransaction>
|
val bookedTransactions: List<AccountTransaction>
|
||||||
get() = user.accounts.flatMap { it.bookedTransactions }.sortedByDescending { it.valueDate }
|
get() = bank.accounts.flatMap { it.bookedTransactions }.sortedByDescending { it.valueDate }
|
||||||
|
|
||||||
|
|
||||||
override fun toString() = user.toString()
|
override fun toString() = bank.toString()
|
||||||
}
|
}
|
|
@ -7,43 +7,47 @@ import net.codinux.banking.client.model.config.NoArgConstructor
|
||||||
|
|
||||||
@NoArgConstructor
|
@NoArgConstructor
|
||||||
open class Holding(
|
open class Holding(
|
||||||
val name: String,
|
open var name: String,
|
||||||
|
|
||||||
val isin: String? = null,
|
open var isin: String? = null,
|
||||||
val wkn: String? = null,
|
open var wkn: String? = null,
|
||||||
|
|
||||||
val quantity: Int? = null,
|
open var quantity: Int? = null,
|
||||||
val currency: String? = null,
|
open var currency: String? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gesamter Kurswert aller Einheiten des Wertpapiers
|
* Gesamter Kurswert aller Einheiten des Wertpapiers
|
||||||
*/
|
*/
|
||||||
val totalBalance: Amount? = null,
|
open var totalBalance: Amount? = null,
|
||||||
/**
|
/**
|
||||||
* Aktueller Kurswert einer einzelnen Einheit des Wertpapiers
|
* Aktueller Kurswert einer einzelnen Einheit des Wertpapiers
|
||||||
*/
|
*/
|
||||||
val marketValue: Amount? = null,
|
open var marketValue: Amount? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Änderung in Prozent Aktueller Kurswert gegenüber Einstandspreis.
|
* Änderung in Prozent Aktueller Kurswert gegenüber Einstandspreis.
|
||||||
*/
|
*/
|
||||||
val performancePercentage: Float? = null,
|
open var performancePercentage: Float? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gesamter Einstandspreis (Kaufpreis)
|
* Gesamter Einstandspreis (Kaufpreis)
|
||||||
*/
|
*/
|
||||||
val totalCostPrice: Amount? = null,
|
open var totalCostPrice: Amount? = null,
|
||||||
/**
|
/**
|
||||||
* (Durchschnittlicher) Einstandspreis/-kurs einer Einheit des Wertpapiers
|
* (Durchschnittlicher) Einstandspreis/-kurs einer Einheit des Wertpapiers
|
||||||
*/
|
*/
|
||||||
val averageCostPrice: Amount? = null,
|
open var averageCostPrice: Amount? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zeitpunkt zu dem der Kurswert bestimmt wurde
|
* Zeitpunkt zu dem der Kurswert bestimmt wurde
|
||||||
*/
|
*/
|
||||||
val pricingTime: Instant? = null,
|
open var pricingTime: Instant? = null,
|
||||||
|
|
||||||
val buyingDate: LocalDate? = null,
|
open var buyingDate: LocalDate? = null,
|
||||||
|
|
||||||
|
var userSetDisplayName: String? = null,
|
||||||
) {
|
) {
|
||||||
|
open val identifier: String by lazy { "${isin}_$wkn" }
|
||||||
|
|
||||||
override fun toString() = "$name $totalBalance $currency"
|
override fun toString() = "$name $totalBalance $currency"
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package net.codinux.banking.client.model.tan
|
||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
import net.codinux.banking.client.model.BankAccountViewInfo
|
import net.codinux.banking.client.model.BankAccountViewInfo
|
||||||
import net.codinux.banking.client.model.User
|
import net.codinux.banking.client.model.BankAccess
|
||||||
import net.codinux.banking.client.model.BankViewInfo
|
import net.codinux.banking.client.model.BankViewInfo
|
||||||
import net.codinux.banking.client.model.config.JsonIgnore
|
import net.codinux.banking.client.model.config.JsonIgnore
|
||||||
import net.codinux.banking.client.model.config.NoArgConstructor
|
import net.codinux.banking.client.model.config.NoArgConstructor
|
||||||
|
@ -24,9 +24,9 @@ open class TanChallenge(
|
||||||
open val selectedTanMethodId: String,
|
open val selectedTanMethodId: String,
|
||||||
/**
|
/**
|
||||||
* When adding an account, frontend has no UserAccount object in BankingClientCallback to know which TanMethods are
|
* When adding an account, frontend has no UserAccount object in BankingClientCallback to know which TanMethods are
|
||||||
* available for User.
|
* available for user.
|
||||||
* Also on other calls to bank server, bank server may returned an updated list of available TanMethods, so that
|
* Also on other calls to bank server, bank server may returned an updated list of available TanMethods, so that
|
||||||
* [User] may contains an outdated list of available TanMethods.
|
* [BankAccess] 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.
|
* Therefore i added list with up to date TanMethods here to ensure EnterTanDialog can display user's up to date TanMethods.
|
||||||
*/
|
*/
|
||||||
|
@ -43,7 +43,7 @@ open class TanChallenge(
|
||||||
|
|
||||||
open val tanImage: TanImage? = null,
|
open val tanImage: TanImage? = null,
|
||||||
open val flickerCode: FlickerCode? = null,
|
open val flickerCode: FlickerCode? = null,
|
||||||
open val user: BankViewInfo,
|
open val bank: BankViewInfo,
|
||||||
open val account: BankAccountViewInfo? = null,
|
open val account: BankAccountViewInfo? = null,
|
||||||
/**
|
/**
|
||||||
* Datum und Uhrzeit, bis zu welchem Zeitpunkt eine TAN auf Basis der gesendeten Challenge gültig ist. Nach Ablauf der Gültigkeitsdauer wird die entsprechende TAN entwertet.
|
* Datum und Uhrzeit, bis zu welchem Zeitpunkt eine TAN auf Basis der gesendeten Challenge gültig ist. Nach Ablauf der Gültigkeitsdauer wird die entsprechende TAN entwertet.
|
||||||
|
|
|
@ -14,7 +14,9 @@ open class TanMedium(
|
||||||
/**
|
/**
|
||||||
* Only set if [type] is [TanMediumType.MobilePhone].
|
* Only set if [type] is [TanMediumType.MobilePhone].
|
||||||
*/
|
*/
|
||||||
val mobilePhone: MobilePhoneTanMedium? = null
|
val mobilePhone: MobilePhoneTanMedium? = null,
|
||||||
|
|
||||||
|
var userSetDisplayName: String? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,12 +54,13 @@ open class TanMedium(
|
||||||
}
|
}
|
||||||
|
|
||||||
val displayName: String by lazy {
|
val displayName: String by lazy {
|
||||||
identifier + " " + when (status) {
|
userSetDisplayName
|
||||||
TanMediumStatus.Used -> "Aktiv"
|
?: (identifier + " " + when (status) {
|
||||||
TanMediumStatus.Available -> "Verfügbar"
|
TanMediumStatus.Used -> "Aktiv"
|
||||||
TanMediumStatus.ActiveFollowUpCard -> " Folgekarte, aktiv bei erster Nutzung"
|
TanMediumStatus.Available -> "Verfügbar"
|
||||||
TanMediumStatus.AvailableFollowUpCard -> " Folgekarte, die erst aktiviert werden muss"
|
TanMediumStatus.ActiveFollowUpCard -> " Folgekarte, aktiv bei erster Nutzung"
|
||||||
}
|
TanMediumStatus.AvailableFollowUpCard -> " Folgekarte, die erst aktiviert werden muss"
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() = "$mediumName $status"
|
override fun toString() = "$mediumName $status"
|
||||||
|
|
|
@ -10,7 +10,8 @@ open class TanMethod(
|
||||||
open val type: TanMethodType,
|
open val type: TanMethodType,
|
||||||
open val identifier: String,
|
open val identifier: String,
|
||||||
open val maxTanInputLength: Int? = null,
|
open val maxTanInputLength: Int? = null,
|
||||||
open val allowedTanFormat: AllowedTanFormat = AllowedTanFormat.Alphanumeric
|
open val allowedTanFormat: AllowedTanFormat = AllowedTanFormat.Alphanumeric,
|
||||||
|
open var userSetDisplayName: String? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@get:JsonIgnore
|
@get:JsonIgnore
|
||||||
|
|
|
@ -3,7 +3,6 @@ package net.codinux.banking.client.model
|
||||||
import net.codinux.banking.client.model.config.NoArgConstructor
|
import net.codinux.banking.client.model.config.NoArgConstructor
|
||||||
|
|
||||||
@JsModule("big.js")
|
@JsModule("big.js")
|
||||||
@kotlin.js.JsNonModule
|
|
||||||
open external class Big(value: String) {
|
open external class Big(value: String) {
|
||||||
fun plus(other: Big): Big
|
fun plus(other: Big): Big
|
||||||
fun minus(other: Big): Big
|
fun minus(other: Big): Big
|
||||||
|
@ -14,38 +13,41 @@ open external class Big(value: String) {
|
||||||
|
|
||||||
|
|
||||||
@NoArgConstructor
|
@NoArgConstructor
|
||||||
actual class Amount actual constructor(amount: String): Big(amount) {
|
actual class Amount actual constructor(amount: String) {
|
||||||
|
|
||||||
actual companion object {
|
actual companion object {
|
||||||
actual val Zero = Amount("0.00")
|
actual val Zero = Amount("0.00")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal val amount = Big(amount)
|
||||||
|
|
||||||
|
|
||||||
actual operator fun plus(other: Amount): Amount {
|
actual operator fun plus(other: Amount): Amount {
|
||||||
return Amount(super.plus(other).toString())
|
return Amount(amount.plus(other.amount).toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual operator fun minus(other: Amount): Amount {
|
actual operator fun minus(other: Amount): Amount {
|
||||||
return Amount(super.minus(other).toString())
|
return Amount(amount.minus(other.amount).toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual operator fun times(other: Amount): Amount {
|
actual operator fun times(other: Amount): Amount {
|
||||||
return Amount(super.times(other).toString())
|
return Amount(amount.times(other.amount).toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual operator fun div(other: Amount): Amount {
|
actual operator fun div(other: Amount): Amount {
|
||||||
return Amount(super.div(other).toString())
|
return Amount(amount.div(other.amount).toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
return other is Amount && this.toString() == other.toString()
|
return other is Amount && amount.toString() == other.amount.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
return super.hashCode()
|
return super.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual override fun toString(): String = super.toString()
|
actual override fun toString(): String = amount.toString()
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@ import net.codinux.banking.client.BankingClient
|
||||||
import net.codinux.banking.client.BankingClientCallback
|
import net.codinux.banking.client.BankingClientCallback
|
||||||
import net.codinux.banking.client.model.BankAccount
|
import net.codinux.banking.client.model.BankAccount
|
||||||
import net.codinux.banking.client.model.BankAccountFeatures
|
import net.codinux.banking.client.model.BankAccountFeatures
|
||||||
import net.codinux.banking.client.model.User
|
import net.codinux.banking.client.model.BankAccess
|
||||||
import net.codinux.banking.client.model.options.GetAccountDataOptions
|
import net.codinux.banking.client.model.options.GetAccountDataOptions
|
||||||
import net.codinux.banking.client.model.request.GetAccountDataRequest
|
import net.codinux.banking.client.model.request.GetAccountDataRequest
|
||||||
import net.codinux.banking.client.model.request.TransferMoneyRequestForUser
|
import net.codinux.banking.client.model.request.TransferMoneyRequestForUser
|
||||||
|
@ -35,14 +35,14 @@ open class FinTs4kBankingClient(
|
||||||
return mapper.map(response, request.bankInfo)
|
return mapper.map(response, request.bankInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateAccountTransactionsAsync(user: User, accounts: List<BankAccount>?): Response<List<GetTransactionsResponse>> {
|
override suspend fun updateAccountTransactionsAsync(bank: BankAccess, accounts: List<BankAccount>?): Response<List<GetTransactionsResponse>> {
|
||||||
val accountsToRequest = (accounts ?: user.accounts).filter { it.supportsAnyFeature(BankAccountFeatures.RetrieveBalance, BankAccountFeatures.RetrieveBalance) }
|
val accountsToRequest = (accounts ?: bank.accounts).filter { it.supportsAnyFeature(BankAccountFeatures.RetrieveBalance, BankAccountFeatures.RetrieveBalance) }
|
||||||
|
|
||||||
if (accountsToRequest.isNotEmpty()) {
|
if (accountsToRequest.isNotEmpty()) {
|
||||||
var finTsModel: BankData? = null
|
var finTsModel: BankData? = null
|
||||||
|
|
||||||
val responses = accountsToRequest.map { account ->
|
val responses = accountsToRequest.map { account ->
|
||||||
val parameter = mapper.mapToUpdateAccountTransactionsParameter(user, account, finTsModel)
|
val parameter = mapper.mapToUpdateAccountTransactionsParameter(bank, account, finTsModel)
|
||||||
|
|
||||||
val response = client.getAccountDataAsync(parameter)
|
val response = client.getAccountDataAsync(parameter)
|
||||||
|
|
||||||
|
|
|
@ -58,19 +58,19 @@ open class FinTs4kMapper {
|
||||||
bank.serverAddress, bank.bic, bank.name
|
bank.serverAddress, bank.bic, bank.name
|
||||||
)
|
)
|
||||||
|
|
||||||
open fun mapToUpdateAccountTransactionsParameter(user: User, account: BankAccount, finTsModel: BankData?): GetAccountDataParameter {
|
open fun mapToUpdateAccountTransactionsParameter(bank: BankAccess, account: BankAccount, finTsModel: BankData?): GetAccountDataParameter {
|
||||||
val defaults = GetAccountDataOptions()
|
val defaults = GetAccountDataOptions()
|
||||||
|
|
||||||
val accountIdentifier = BankAccountIdentifierImpl(account.identifier, account.subAccountNumber, account.iban)
|
val accountIdentifier = BankAccountIdentifierImpl(account.identifier, account.subAccountNumber, account.iban)
|
||||||
val from = account.lastAccountUpdateTime?.toLocalDateTime(TimeZone.EuropeBerlin)?.date // TODO: in case lastTransactionsUpdateTime is not set, this would retrieve all transactions (and require a TAN im most cases)
|
val from = account.lastAccountUpdateTime?.toLocalDateTime(TimeZone.EuropeBerlin)?.date // TODO: in case lastTransactionsUpdateTime is not set, this would retrieve all transactions (and require a TAN im most cases)
|
||||||
val retrieveTransactions = if (from != null) RetrieveTransactions.AccordingToRetrieveFromAndTo else RetrieveTransactions.valueOf(defaults.retrieveTransactions.name)
|
val retrieveTransactions = if (from != null) RetrieveTransactions.AccordingToRetrieveFromAndTo else RetrieveTransactions.valueOf(defaults.retrieveTransactions.name)
|
||||||
// val preferredTanMethods = listOf(mapTanMethodType(user.selectedTanMethod.type)) // TODO: currently we aren't saving TanMethods in database, re-enable as soon as TanMethods get saved
|
// val preferredTanMethods = listOf(mapTanMethodType(bank.selectedTanMethod.type)) // TODO: currently we aren't saving TanMethods in database, re-enable as soon as TanMethods get saved
|
||||||
val preferredTanMethods = defaults.preferredTanMethods?.map { mapTanMethodType(it) }
|
val preferredTanMethods = defaults.preferredTanMethods?.map { mapTanMethodType(it) }
|
||||||
|
|
||||||
return GetAccountDataParameter(user.bankCode, user.loginName, user.password!!, listOf(accountIdentifier), true,
|
return GetAccountDataParameter(bank.domesticBankCode, bank.loginName, bank.password!!, listOf(accountIdentifier), true,
|
||||||
retrieveTransactions, from,
|
retrieveTransactions, from,
|
||||||
preferredTanMethods = preferredTanMethods,
|
preferredTanMethods = preferredTanMethods,
|
||||||
preferredTanMedium = user.selectedTanMediumIdentifier,
|
preferredTanMedium = bank.selectedTanMediumIdentifier,
|
||||||
finTsModel = finTsModel
|
finTsModel = finTsModel
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ open class FinTs4kMapper {
|
||||||
|
|
||||||
open fun map(response: net.dankito.banking.client.model.response.GetAccountDataResponse, bank: BankInfo? = null): Response<GetAccountDataResponse> =
|
open fun map(response: net.dankito.banking.client.model.response.GetAccountDataResponse, bank: BankInfo? = null): Response<GetAccountDataResponse> =
|
||||||
if (response.successful && response.customerAccount != null) {
|
if (response.successful && response.customerAccount != null) {
|
||||||
Response.success(GetAccountDataResponse(mapUser(response.customerAccount!!, bank)))
|
Response.success(GetAccountDataResponse(mapBank(response.customerAccount!!, bank)))
|
||||||
} else {
|
} else {
|
||||||
mapError(response)
|
mapError(response)
|
||||||
}
|
}
|
||||||
|
@ -99,12 +99,12 @@ open class FinTs4kMapper {
|
||||||
open fun map(responses: List<Triple<BankAccount, GetAccountDataParameter, net.dankito.banking.client.model.response.GetAccountDataResponse>>): Response<List<GetTransactionsResponse>> {
|
open fun map(responses: List<Triple<BankAccount, GetAccountDataParameter, net.dankito.banking.client.model.response.GetAccountDataResponse>>): Response<List<GetTransactionsResponse>> {
|
||||||
val type = if (responses.all { it.third.successful }) ResponseType.Success else ResponseType.Error
|
val type = if (responses.all { it.third.successful }) ResponseType.Success else ResponseType.Error
|
||||||
|
|
||||||
// TODO: update UserAccount and BankAccount objects according to retrieved data
|
// TODO: update BankAccess and BankAccount objects according to retrieved data
|
||||||
val mappedResponses = responses.map { (account, param, getAccountDataResponse) ->
|
val mappedResponses = responses.map { (account, param, getAccountDataResponse) ->
|
||||||
val user = getAccountDataResponse.customerAccount
|
val bank = getAccountDataResponse.customerAccount
|
||||||
val finTsBankAccount = user?.accounts?.firstOrNull { it.identifier == account.identifier && it.subAccountNumber == account.subAccountNumber }
|
val finTsBankAccount = bank?.accounts?.firstOrNull { it.identifier == account.identifier && it.subAccountNumber == account.subAccountNumber }
|
||||||
|
|
||||||
if (getAccountDataResponse.successful && user != null && finTsBankAccount != null) {
|
if (getAccountDataResponse.successful && bank != null && finTsBankAccount != null) {
|
||||||
if (finTsBankAccount.lastAccountUpdateTime != null) {
|
if (finTsBankAccount.lastAccountUpdateTime != null) {
|
||||||
account.lastAccountUpdateTime = finTsBankAccount.lastAccountUpdateTime
|
account.lastAccountUpdateTime = finTsBankAccount.lastAccountUpdateTime
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ open class FinTs4kMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun mapToUserAccountViewInfo(bank: BankData): BankViewInfo = BankViewInfo(
|
open fun mapToBankViewInfo(bank: BankData): BankViewInfo = BankViewInfo(
|
||||||
bank.bankCode, bank.customerId, bank.bankName, getBankingGroup(bank.bankName, bank.bic)
|
bank.bankCode, bank.customerId, bank.bankName, getBankingGroup(bank.bankName, bank.bic)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -138,17 +138,18 @@ open class FinTs4kMapper {
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
protected open fun mapUser(user: net.dankito.banking.client.model.CustomerAccount, bank: BankInfo? = null) = User(
|
protected open fun mapBank(bank: net.dankito.banking.client.model.CustomerAccount, info: BankInfo? = null) = BankAccess(
|
||||||
user.bankCode, user.loginName, user.password,
|
bank.bankCode, bank.loginName, bank.password,
|
||||||
bank?.name ?: user.bankName, user.bic, user.customerName, user.userId,
|
info?.name ?: bank.bankName, bank.bic, bank.customerName, bank.userId,
|
||||||
user.accounts.map { mapAccount(it) }.sortedBy { it.type }
|
bank.accounts.map { mapAccount(it) }.sortedBy { it.type }
|
||||||
.onEachIndexed { index, bankAccount -> bankAccount.displayIndex = index },
|
.onEachIndexed { index, bankAccount -> bankAccount.displayIndex = index },
|
||||||
|
|
||||||
user.selectedTanMethod?.securityFunction?.code, user.tanMethods.map { mapTanMethod(it) },
|
bank.selectedTanMethod?.securityFunction?.code, bank.tanMethods.map { mapTanMethod(it) }.toMutableList(),
|
||||||
user.selectedTanMedium?.mediumName, user.tanMedia.map { mapTanMedium(it) },
|
bank.selectedTanMedium?.mediumName, bank.tanMedia.map { mapTanMedium(it) }.toMutableList(),
|
||||||
|
|
||||||
bank?.bankingGroup ?: getBankingGroup(user.bankName, user.bic),
|
info?.bankingGroup ?: getBankingGroup(bank.bankName, bank.bic),
|
||||||
user.finTsServerAddress
|
bank.finTsServerAddress,
|
||||||
|
"de"
|
||||||
)
|
)
|
||||||
|
|
||||||
protected open fun getBankingGroup(bankName: String, bic: String): BankingGroup? =
|
protected open fun getBankingGroup(bankName: String, bic: String): BankingGroup? =
|
||||||
|
@ -163,7 +164,7 @@ open class FinTs4kMapper {
|
||||||
account.serverTransactionsRetentionDays,
|
account.serverTransactionsRetentionDays,
|
||||||
account.lastAccountUpdateTime, account.retrievedTransactionsFrom,
|
account.lastAccountUpdateTime, account.retrievedTransactionsFrom,
|
||||||
bookedTransactions = mapBookedTransactions(account).toMutableList(),
|
bookedTransactions = mapBookedTransactions(account).toMutableList(),
|
||||||
holdings = mapHoldings(account.statementOfHoldings, account.currency, account.lastAccountUpdateTime)
|
holdings = mapHoldings(account.statementOfHoldings, account.currency, account.lastAccountUpdateTime).toMutableList()
|
||||||
)
|
)
|
||||||
|
|
||||||
protected open fun mapAccountType(type: net.dankito.banking.client.model.BankAccountType): BankAccountType =
|
protected open fun mapAccountType(type: net.dankito.banking.client.model.BankAccountType): BankAccountType =
|
||||||
|
@ -297,13 +298,13 @@ open class FinTs4kMapper {
|
||||||
// TanMedium has not natural id in FinTS model so we have to create our own one
|
// TanMedium has not natural id in FinTS model so we have to create our own one
|
||||||
val selectedTanMediumName = challenge.bank.selectedTanMedium?.let { selected -> tanMedia.firstOrNull { it == selected } }?.identifier
|
val selectedTanMediumName = challenge.bank.selectedTanMedium?.let { selected -> tanMedia.firstOrNull { it == selected } }?.identifier
|
||||||
|
|
||||||
val user = mapToUserAccountViewInfo(challenge.bank)
|
val bank = mapToBankViewInfo(challenge.bank)
|
||||||
val account = challenge.account?.let { mapToBankAccountViewInfo(it) }
|
val account = challenge.account?.let { mapToBankAccountViewInfo(it) }
|
||||||
|
|
||||||
val tanImage = if (challenge is ImageTanChallenge) mapTanImage(challenge.image) else null
|
val tanImage = if (challenge is ImageTanChallenge) mapTanImage(challenge.image) else null
|
||||||
val flickerCode = if (challenge is FlickerCodeTanChallenge) mapFlickerCode(challenge.flickerCode) else null
|
val flickerCode = if (challenge is FlickerCodeTanChallenge) mapFlickerCode(challenge.flickerCode) else null
|
||||||
|
|
||||||
return object : TanChallenge(type, action, challenge.messageToShowToUser, selectedTanMethodId, tanMethods, selectedTanMediumName, tanMedia, tanImage, flickerCode, user, account, challenge.tanExpirationTime, challenge.challengeCreationTimestamp) {
|
return object : TanChallenge(type, action, challenge.messageToShowToUser, selectedTanMethodId, tanMethods, selectedTanMediumName, tanMedia, tanImage, flickerCode, bank, account, challenge.tanExpirationTime, challenge.challengeCreationTimestamp) {
|
||||||
override fun addTanExpiredCallback(callback: () -> Unit) {
|
override fun addTanExpiredCallback(callback: () -> Unit) {
|
||||||
challenge.addTanExpiredCallback(callback)
|
challenge.addTanExpiredCallback(callback)
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,12 +88,12 @@ class ShowUsage {
|
||||||
|
|
||||||
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 bank = data.bank
|
||||||
println("Kunde: ${user.customerName} ${user.accounts.size} Konten @ ${user.bic} ${user.bankName}")
|
println("Kunde: ${bank.customerName} ${bank.accounts.size} Konten @ ${bank.bic} ${bank.bankName}")
|
||||||
|
|
||||||
println()
|
println()
|
||||||
println("Konten:")
|
println("Konten:")
|
||||||
user.accounts.sortedBy { it.type }.forEach { account ->
|
bank.accounts.sortedBy { it.type }.forEach { account ->
|
||||||
println("${account.identifier} ${account.productName} ${account.balance} ${account.currency}")
|
println("${account.identifier} ${account.productName} ${account.balance} ${account.currency}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
Für den deutschen Begriff "Bankzugang" gibt es im Englischen verschiedene mögliche Übersetzungen, abhängig vom Kontext. Hier sind einige Alternativen:
|
||||||
|
|
||||||
|
1. **Bank access** – Diese Übersetzung ist direkt und wird verwendet, wenn es um den allgemeinen Zugang zu einem Bankkonto oder einer Bank geht.
|
||||||
|
|
||||||
|
2. **Online banking access** – Diese Option wird oft genutzt, wenn es sich spezifisch um den Zugang zu einem Online-Banking-Konto handelt.
|
||||||
|
|
||||||
|
3. **Bank account access** – Dies wird verwendet, wenn man den Zugang zu einem spezifischen Bankkonto meint.
|
||||||
|
|
||||||
|
4. **Bank login** – Eine übliche Formulierung für den Zugang zu einem Online-Banking-Portal durch Einloggen mit Anmeldedaten.
|
||||||
|
|
||||||
|
5. **Bank credentials** – Dies bezieht sich auf die Anmeldeinformationen (Benutzername, Passwort, etc.) für den Zugang zu einem Bankkonto, speziell im digitalen Bereich.
|
||||||
|
|
||||||
|
6. **Access to banking services** – Diese Variante beschreibt eher den allgemeinen Zugang zu Bankdienstleistungen, sowohl digital als auch in Filialen.
|
||||||
|
|
||||||
|
Die beste Wahl hängt vom genauen Kontext ab, z.B. ob es sich um physischen Zugang zu einer Bank, Online-Zugang oder Zugang zu bestimmten Bankdiensten handelt.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Hier sind einige Namensvorschläge für deine Klasse mit entsprechenden Übersetzungen ins Englische:
|
||||||
|
|
||||||
|
1. **BankVerbindung**
|
||||||
|
_BankConnection_
|
||||||
|
|
||||||
|
2. **BankZugangsdaten**
|
||||||
|
_BankAccessData_
|
||||||
|
|
||||||
|
3. **OnlineBankProfil**
|
||||||
|
_OnlineBankProfile_
|
||||||
|
|
||||||
|
4. **BankKontoDetails**
|
||||||
|
_BankAccountDetails_
|
||||||
|
|
||||||
|
5. **BankNutzerProfil**
|
||||||
|
_BankUserProfile_
|
||||||
|
|
||||||
|
6. **BankNutzerDaten**
|
||||||
|
_BankUserData_
|
||||||
|
|
||||||
|
7. **BankZugangsprofil**
|
||||||
|
_BankAccessProfile_
|
||||||
|
|
||||||
|
8. **BankKontoverbindung**
|
||||||
|
_BankAccountConnection_
|
||||||
|
|
||||||
|
9. **BankServiceInfo**
|
||||||
|
_BankServiceInfo_
|
||||||
|
|
||||||
|
10. **BankNutzerVerwaltung**
|
||||||
|
_BankUserManagement_
|
||||||
|
|
||||||
|
Diese Namen umfassen sowohl den Zugang zur Bank als auch Daten über die Bank und den Nutzer.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Hier sind einige Namensvorschläge für die Klasse auf Deutsch und Englisch:
|
||||||
|
|
||||||
|
1. **BankZugangsdaten**
|
||||||
|
- **Englisch**: BankAccessData
|
||||||
|
|
||||||
|
2. **OnlineBankingZugang**
|
||||||
|
- **Englisch**: OnlineBankingAccess
|
||||||
|
|
||||||
|
3. **BankVerbindung**
|
||||||
|
- **Englisch**: BankConnection
|
||||||
|
|
||||||
|
4. **BankZugang**
|
||||||
|
- **Englisch**: BankAccess
|
||||||
|
|
||||||
|
5. **NutzerBankDetails**
|
||||||
|
- **Englisch**: UserBankDetails
|
||||||
|
|
||||||
|
6. **BankingAuthentifizierung**
|
||||||
|
- **Englisch**: BankingAuthentication
|
||||||
|
|
||||||
|
7. **BankLoginDaten**
|
||||||
|
- **Englisch**: BankLoginData
|
||||||
|
|
||||||
|
8. **BankZugangsInfo**
|
||||||
|
- **Englisch**: BankAccessInfo
|
||||||
|
|
||||||
|
9. **KontoZugangsdaten**
|
||||||
|
- **Englisch**: AccountAccessData
|
||||||
|
|
||||||
|
10. **OnlineBankingVerbindung**
|
||||||
|
- **Englisch**: OnlineBankingConnection
|
||||||
|
|
||||||
|
Diese Namen sollen die wesentlichen Informationen der Klasse widerspiegeln und die verschiedenen Attribute gut abdecken.
|
|
@ -0,0 +1,18 @@
|
||||||
|
In vielen Ländern gibt es eigene Systeme zur eindeutigen Identifizierung von Banken, die ähnlich wie die **Bankleitzahl** (BLZ) in Deutschland funktionieren. Hier sind einige Beispiele:
|
||||||
|
|
||||||
|
1. **USA** – **Routing Number**: In den USA wird die **Routing Transit Number (RTN)** oder **ABA-Routing-Nummer** verwendet, um Banken zu identifizieren.
|
||||||
|
2. **Großbritannien** – **Sort Code**: In Großbritannien wird der **Sort Code** verwendet, um eine Bank und ihre Filiale zu identifizieren.
|
||||||
|
3. **International** – **SWIFT/BIC**: Das **SWIFT/BIC**-System (Society for Worldwide Interbank Financial Telecommunication / Bank Identifier Code) wird weltweit verwendet, um Banken international eindeutig zu identifizieren.
|
||||||
|
4. **Kanada** – **Institution Number**: In Kanada gibt es eine **Institution Number** (in Kombination mit einer Transitnummer).
|
||||||
|
5. **Australien** – **BSB Number**: In Australien ist es die **BSB Number** (Bank-State-Branch Number).
|
||||||
|
6. **Indien** – **IFSC Code**: In Indien wird der **Indian Financial System Code (IFSC)** verwendet.
|
||||||
|
7. **Schweiz** – **SIC Number**: In der Schweiz gibt es das **SIC (Swiss Interbank Clearing)**-System, um Banken zu identifizieren.
|
||||||
|
|
||||||
|
### Guter englischer Name für eine landesweite eindeutige Bankidentifikation
|
||||||
|
Ein passender englischer Begriff für einen solchen eindeutigen Identifikationswert wäre:
|
||||||
|
|
||||||
|
- **National Bank Identifier (NBI)**: Dies beschreibt eine eindeutige Kennung, die eine Bank auf nationaler Ebene identifiziert.
|
||||||
|
- **Domestic Bank Code (DBC)**: Dies weist ebenfalls auf die Verwendung im nationalen Kontext hin.
|
||||||
|
- **Bank Identifier Code (BIC)**: Obwohl dieser Begriff oft international verwendet wird, kann er auch auf eine landesweite eindeutige Identifikation hinweisen, wenn er im nationalen Kontext benutzt wird.
|
||||||
|
|
||||||
|
Ein allgemeiner Begriff wie **"National Bank Code"** wäre ebenfalls leicht verständlich und eindeutig in seiner Funktion.
|
Loading…
Reference in New Issue