diff --git a/fints4k/build.gradle b/fints4k/build.gradle index f7d262ae..075b7c9c 100644 --- a/fints4k/build.gradle +++ b/fints4k/build.gradle @@ -45,9 +45,9 @@ kotlin { def hostOs = System.getProperty("os.name") def isMingwX64 = hostOs.startsWith("Windows") def nativeTarget - if (hostOs == "Mac OS X") nativeTarget = macosX64('native') - else if (hostOs == "Linux") nativeTarget = linuxX64("native") - else if (isMingwX64) nativeTarget = mingwX64("native") + if (hostOs == "Mac OS X") nativeTarget = macosX64('native') { binaries.executable() } + else if (hostOs == "Linux") nativeTarget = linuxX64("native") { binaries.executable() } + else if (isMingwX64) nativeTarget = mingwX64("native") { binaries.executable() } else throw new GradleException("Host OS is not supported in Kotlin/Native.") diff --git a/fints4k/src/nativeMain/kotlin/Application.kt b/fints4k/src/nativeMain/kotlin/Application.kt new file mode 100644 index 00000000..1b147f53 --- /dev/null +++ b/fints4k/src/nativeMain/kotlin/Application.kt @@ -0,0 +1,77 @@ +import kotlinx.coroutines.runBlocking +import kotlinx.datetime.LocalDate +import net.dankito.banking.fints.FinTsClient +import net.dankito.banking.fints.FinTsJobExecutor +import net.dankito.banking.fints.RequestExecutor +import net.dankito.banking.fints.callback.SimpleFinTsClientCallback +import net.dankito.banking.fints.model.AddAccountParameter +import net.dankito.banking.fints.model.RetrievedAccountData +import net.dankito.banking.fints.response.client.AddAccountResponse +import net.dankito.banking.fints.webclient.BlockingKtorWebClient +import net.dankito.utils.multiplatform.extensions.* +import platform.posix.exit + +fun main(args: Array) { + if (args.size < 4) { + println("Bitte geben Sie Ihre Bankzugangsdaten ein in der Reihenfolge: \r\n" + + "Z. B.: ./fints4k.kexe 10050000 \"Mein Loginname\" GeheimesPasswort \"https://banking-be3.s-fints-pt-be.de/fints30\"") + exit(0) + } + + Application().retrieveAccountData(args[0], args[1], args[2], args[3]) +} + +class Application { + + fun retrieveAccountData(bankCode: String, customerId: String, pin: String, finTs3ServerAddress: String) { + runBlocking { + val client = FinTsClient(SimpleFinTsClientCallback(), FinTsJobExecutor(RequestExecutor(webClient = BlockingKtorWebClient()))) + + client.addAccountAsync(AddAccountParameter(bankCode, customerId, pin, finTs3ServerAddress)) { response -> + println("Retrieved response from ${response.bank.bankName} for ${response.bank.customerName}") + + displayRetrievedAccountData(response) + } + } + } + + private fun displayRetrievedAccountData(response: AddAccountResponse) { + if (response.retrievedData.isEmpty()) { + println() + + if (response.bank.accounts.isEmpty()) { + println("No data retrieved") + } else { + println("No transactions retrieved for accounts:") + response.bank.accounts.forEach { account -> println("- $account") } + } + } + + response.retrievedData.forEach { data -> + println() + println("${data.account}:") + println() + + if (data.bookedTransactions.isEmpty()) { + println("No transactions retrieved for this account") + } else { + displayTransactions(data) + } + } + } + + private fun displayTransactions(data: RetrievedAccountData) { + val countTransactionsDigits = data.bookedTransactions.size.numberOfDigits + val largestAmountDigits = data.bookedTransactions.maxByOrNull { it.amount.displayString.length }?.amount?.displayString?.length ?: 0 + + data.bookedTransactions.sortedByDescending { it.valueDate }.forEachIndexed { transactionIndex, transaction -> + println("${(transactionIndex + 1).toStringWithMinDigits(countTransactionsDigits, " ")}. ${formatDate(transaction.valueDate)} " + + "${transaction.amount.displayString.ensureMinStringLength(largestAmountDigits, " ")} ${transaction.otherPartyName ?: ""} - ${transaction.reference}") + } + } + + private fun formatDate(date: LocalDate): String { + return date.dayOfMonth.toStringWithTwoDigits() + "." + date.monthNumber.toStringWithTwoDigits() + "." + date.year + } + +} \ No newline at end of file diff --git a/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/extensions/NumberExtensions.kt b/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/extensions/NumberExtensions.kt index afb5360b..a7482695 100644 --- a/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/extensions/NumberExtensions.kt +++ b/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/extensions/NumberExtensions.kt @@ -6,10 +6,18 @@ fun Int.toStringWithTwoDigits(): String { } fun Int.toStringWithMinDigits(minimumCountDigits: Int): String { - val countDigitsToAdd = minimumCountDigits - this.numberOfDigits - val prefix = if (countDigitsToAdd > 0) "0".repeat(countDigitsToAdd) else "" + return toStringWithMinDigits(minimumCountDigits, "0") +} - return prefix + this.toString() +fun Int.toStringWithMinDigits(minimumCountDigits: Int, fillerString: String): String { + return this.toString().ensureMinStringLength(minimumCountDigits, fillerString) +} + +fun String.ensureMinStringLength(minimumStringLength: Int, fillerString: String): String { + val countDigitsToAdd = minimumStringLength - this.length + val prefix = if (countDigitsToAdd > 0) fillerString.repeat(countDigitsToAdd) else "" + + return prefix + this } val Int.numberOfDigits: Int diff --git a/multiplatform-utils/src/commonTest/kotlin/net.dankito.utils.multiplatform.extensions/NumberExtensionsTest.kt b/multiplatform-utils/src/commonTest/kotlin/net.dankito.utils.multiplatform.extensions/NumberExtensionsTest.kt index cc659368..9abd6e1e 100644 --- a/multiplatform-utils/src/commonTest/kotlin/net.dankito.utils.multiplatform.extensions/NumberExtensionsTest.kt +++ b/multiplatform-utils/src/commonTest/kotlin/net.dankito.utils.multiplatform.extensions/NumberExtensionsTest.kt @@ -1,3 +1,4 @@ +import net.dankito.utils.multiplatform.extensions.ensureMinStringLength import net.dankito.utils.multiplatform.extensions.numberOfDigits import net.dankito.utils.multiplatform.extensions.toStringWithMinDigits import kotlin.test.Test @@ -83,4 +84,12 @@ class NumberExtensionsTest { assertEquals(10, result) } + + @Test + fun ensureMinStringLength() { + val result = "123,45 EUR".ensureMinStringLength(12, " ") + + assertEquals(" 123,45 EUR", result) + } + } \ No newline at end of file