Added basic BankingClient model

This commit is contained in:
dankito 2024-08-14 21:01:35 +02:00
parent 4a38369cc0
commit 0baa3b670e
15 changed files with 3431 additions and 1 deletions

1
.gitignore vendored
View File

@ -6,6 +6,7 @@
**/target
.gradle
.kotlin
/local.properties

View File

@ -0,0 +1,101 @@
@file:OptIn(ExperimentalWasmDsl::class)
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
plugins {
kotlin("multiplatform")
}
kotlin {
jvmToolchain(8)
jvm {
withJava()
testRuns["test"].executionTask.configure {
useJUnitPlatform()
testLogging {
showExceptions = true
showStandardStreams = true
events("passed", "skipped", "failed")
// exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}
}
js {
moduleName = "banking-client-model"
binaries.executable()
browser {
testTask {
useKarma {
useChromeHeadless()
useFirefoxHeadless()
}
}
}
nodejs {
testTask {
useMocha {
timeout = "20s" // Mocha times out after 2 s, which is too short for bufferExceeded() test
}
}
}
}
wasmJs()
linuxX64()
mingwX64()
iosArm64()
iosSimulatorArm64()
macosX64()
macosArm64()
watchosArm64()
watchosSimulatorArm64()
tvosArm64()
tvosSimulatorArm64()
applyDefaultHierarchyTemplate()
val kotlinxDateTimeVersion: String by project
val jsJodaTimeZoneVersion: String by project
sourceSets {
commonMain {
dependencies {
api("org.jetbrains.kotlinx:kotlinx-datetime:$kotlinxDateTimeVersion")
}
}
commonTest {
dependencies {
implementation(kotlin("test"))
}
}
jvmMain {
dependencies {
}
}
jvmTest { }
jsMain {
dependencies {
api(npm("@js-joda/timezone", jsJodaTimeZoneVersion))
}
}
jsTest { }
nativeMain { }
nativeTest { }
}
}

View File

@ -0,0 +1,7 @@
package net.codinux.banking.client.model
class AccountCredentials(
var bankCode: String,
var loginName: String,
var password: String
)

View File

@ -0,0 +1,63 @@
package net.codinux.banking.client.model
import kotlinx.datetime.LocalDate
class AccountTransaction(
val amount: Amount = Amount.Zero,
val currency: String,
val reference: String, // Alternative: purpose (or Remittance information)
/**
* Transaction date (Buchungstag) - der Tag, an dem ein Zahlungsvorgang in das System einer Bank eingegangen ist.
* Das bedeutet aber nicht automatisch, dass das Geld schon verfügbar ist. Dafür ist die Wertstellung entscheidend.
*/
val bookingDate: LocalDate,
/**
* Effective date (Wertstellung / Valutadatum) - der Tag an dem das Geld verfügbar ist. An diesem Tag wird die
* Kontobewegung wirksam.
*
* Buchung und Wertstellung erfolgen häufig am gleichen Tag, das muss aber nicht immer der Fall sein.
*/
val valueDate: LocalDate,
val otherPartyName: String? = null, // Alternatives: Parties involved, Transaction parties.single names: Beneficiary, Payee respectively Payer, Debtor
val otherPartyBankCode: String? = null,
val otherPartyAccountId: String? = null,
val bookingText: String? = null,
val information: String? = null,
val statementNumber: Int? = null,
val sequenceNumber: Int? = null,
val openingBalance: Amount? = null,
val closingBalance: Amount? = null,
val endToEndReference: String? = null,
val customerReference: String? = null,
val mandateReference: String? = null,
val creditorIdentifier: String? = null,
val originatorsIdentificationCode: String? = null,
val compensationAmount: String? = null,
val originalAmount: String? = null,
val sepaReference: String? = null,
val deviantOriginator: String? = null,
val deviantRecipient: String? = null,
val referenceWithNoSpecialType: String? = null,
val primaNotaNumber: String? = null,
val textKeySupplement: String? = null,
val currencyType: String? = null,
val bookingKey: String? = null,
val referenceForTheAccountOwner: String? = null,
val referenceOfTheAccountServicingInstitution: String? = null,
val supplementaryDetails: String? = null,
val transactionReferenceNumber: String? = null,
val relatedReferenceNumber: String? = null,
var userSetDisplayName: String? = null,
var notes: String? = null,
) {
override fun toString() = "${valueDate.dayOfMonth}.${valueDate.monthNumber}.${valueDate.year} ${amount.toString().padStart(4, ' ')} ${if (currency == "EUR") "€" else currency} ${otherPartyName ?: ""} - $reference"
}

View File

@ -0,0 +1,16 @@
package net.codinux.banking.client.model
import kotlin.jvm.JvmInline
@JvmInline
value class Amount(val amount: String = "0") {
companion object {
val Zero = Amount("0")
fun fromString(amount: String): Amount = Amount(amount)
}
override fun toString() = amount
}

View File

@ -0,0 +1,36 @@
package net.codinux.banking.client.model
import kotlinx.datetime.LocalDate
class BankAccount(
val identifier: String,
var accountHolderName: String,
val type: BankAccountType = BankAccountType.CheckingAccount,
val iban: String? = null,
val subAccountNumber: String? = null,
val productName: String? = null,
val currency: String = "EUR",
var accountLimit: String? = null,
val isAccountTypeSupportedByApplication: Boolean = true,
val features: Set<BankAccountFeatures> = emptySet(),
// var balance: BigDecimal = BigDecimal.ZERO,
var balance: Amount = Amount.Zero, // TODO: add a BigDecimal library
var retrievedTransactionsFromOn: LocalDate? = null,
var retrievedTransactionsUpTo: LocalDate? = null,
var haveAllTransactionsBeenRetrieved: Boolean = false,
val countDaysForWhichTransactionsAreKept: Int? = null,
val bookedTransactions: MutableList<AccountTransaction> = mutableListOf(),
val unbookedTransactions: MutableList<UnbookedAccountTransaction> = mutableListOf(),
var userSetDisplayName: String? = null,
var displayIndex: Int = 0,
var hideAccount: Boolean = false,
var includeInAutomaticAccountsUpdate: Boolean = true
) {
override fun toString() = "$type $identifier $productName (IBAN: $iban)"
}

View File

@ -0,0 +1,8 @@
package net.codinux.banking.client.model
enum class BankAccountFeatures {
RetrieveTransactions,
RetrieveBalance,
TransferMoney,
InstantPayment
}

View File

@ -0,0 +1,23 @@
package net.codinux.banking.client.model
enum class BankAccountType {
CheckingAccount,
SavingsAccount,
FixedTermDepositAccount,
SecuritiesAccount,
LoanAccount,
CreditCardAccount,
FundDeposit,
BuildingLoanContract,
InsuranceContract,
Other
}

View File

@ -0,0 +1,31 @@
package net.codinux.banking.client.model
enum class BankingGroup {
Sparkasse,
DKB,
OldenburgischeLandesbank,
VolksUndRaiffeisenbanken,
Sparda,
PSD,
GLS,
SonstigeGenossenschaftsbank,
DeutscheBank,
Postbank,
Commerzbank,
Comdirect,
Unicredit,
Targobank,
ING,
Santander,
Norisbank,
Degussa,
Oberbank,
Bundesbank,
KfW,
N26,
Consors
}

View File

@ -0,0 +1,31 @@
package net.codinux.banking.client.model
class CustomerAccount(
val bankCode: String,
var loginName: String,
/**
* User may decides to not save password .
*/
var password: String?,
val bankName: String,
val bic: String,
val customerName: String,
val userId: String = loginName,
val accounts: List<BankAccount> = emptyList(),
var bankingGroup: BankingGroup? = null,
var iconUrl: String? = null,
) {
var wrongCredentialsEntered: Boolean = false
var userSetDisplayName: String? = null
var displayIndex: Int = 0
override fun toString() = "$bankName $loginName, ${accounts.size} accounts"
}

View File

@ -0,0 +1,4 @@
package net.codinux.banking.client.model
class UnbookedAccountTransaction {
}

View File

@ -0,0 +1,7 @@
package net.codinux.banking.client.model
@JsModule("@js-joda/timezone")
@JsNonModule
external object JsJodaTimeZoneModule
private val jsJodaTz = JsJodaTimeZoneModule

View File

@ -2,3 +2,6 @@ kotlin.code.style=official
kotlinVersion=2.0.10
kotlinxDateTimeVersion=0.6.0
jsJodaTimeZoneVersion=2.3.0

3097
kotlin-js-store/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@ pluginManagement {
kotlin("multiplatform") version kotlinVersion
kotlin("jvm") version kotlinVersion
// kotlin("plugin.serialization") version kotlinVersion
kotlin("plugin.allopen") version kotlinVersion
kotlin("plugin.noarg") version kotlinVersion
}
@ -22,3 +22,5 @@ plugins {
rootProject.name = "BankingClient"
include("BankingClientModel")