From d442c02964eee37d73c8e751638183afde9ac602 Mon Sep 17 00:00:00 2001 From: dankito Date: Thu, 24 Feb 2022 00:00:07 +0100 Subject: [PATCH] Implemented transferring money via command line --- .../model/response/FinTsClientResponse.kt | 2 +- fints4k/src/nativeMain/kotlin/NativeApp.kt | 6 ++-- .../kotlin/commands/CommonConfig.kt | 16 +++++++++ .../nativeMain/kotlin/commands/ConfigNames.kt | 11 ++++++ .../kotlin/commands/TransferMoneyCommand.kt | 36 +++++++++++++++++++ .../fints4kCommandLineInterface.kt | 34 +++++++++++++++--- fints4k/src/nativeMain/kotlin/main.kt | 5 ++- 7 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 fints4k/src/nativeMain/kotlin/commands/CommonConfig.kt create mode 100644 fints4k/src/nativeMain/kotlin/commands/ConfigNames.kt create mode 100644 fints4k/src/nativeMain/kotlin/commands/TransferMoneyCommand.kt rename fints4k/src/nativeMain/kotlin/{ => commands}/fints4kCommandLineInterface.kt (74%) diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/FinTsClientResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/FinTsClientResponse.kt index 68b8acca..a781ab3c 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/FinTsClientResponse.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/FinTsClientResponse.kt @@ -16,6 +16,6 @@ open class FinTsClientResponse( get() = error == null open val errorCodeAndMessage: String - get() = "$error${errorMessage?.let { " $it" }}}" + get() = "$error${errorMessage?.let { " $it" }}" } \ No newline at end of file diff --git a/fints4k/src/nativeMain/kotlin/NativeApp.kt b/fints4k/src/nativeMain/kotlin/NativeApp.kt index ed63685b..afeb9ef3 100644 --- a/fints4k/src/nativeMain/kotlin/NativeApp.kt +++ b/fints4k/src/nativeMain/kotlin/NativeApp.kt @@ -16,11 +16,11 @@ class NativeApp { private val client = FinTsClient(SimpleFinTsClientCallback { tanChallenge -> enterTan(tanChallenge) }) - fun retrieveAccountData(bankCode: String, loginName: String, password: String) { - retrieveAccountData(GetAccountDataParameter(bankCode, loginName, password)) + fun getAccountData(bankCode: String, loginName: String, password: String) { + getAccountData(GetAccountDataParameter(bankCode, loginName, password)) } - fun retrieveAccountData(param: GetAccountDataParameter) { + fun getAccountData(param: GetAccountDataParameter) { val response = client.getAccountData(param) if (response.error != null) { diff --git a/fints4k/src/nativeMain/kotlin/commands/CommonConfig.kt b/fints4k/src/nativeMain/kotlin/commands/CommonConfig.kt new file mode 100644 index 00000000..5eaf7798 --- /dev/null +++ b/fints4k/src/nativeMain/kotlin/commands/CommonConfig.kt @@ -0,0 +1,16 @@ +package commands + +import NativeApp +import net.dankito.banking.fints.model.TanMethodType + + +data class CommonConfig( + val app: NativeApp, + + val bankCode: String, + val loginName: String, + val password: String, + + val preferredTanMethods: List?, + val abortIfRequiresTan: Boolean +) \ No newline at end of file diff --git a/fints4k/src/nativeMain/kotlin/commands/ConfigNames.kt b/fints4k/src/nativeMain/kotlin/commands/ConfigNames.kt new file mode 100644 index 00000000..1dabad1d --- /dev/null +++ b/fints4k/src/nativeMain/kotlin/commands/ConfigNames.kt @@ -0,0 +1,11 @@ +package commands + +class ConfigNames { + + companion object { + + const val CommonConfig = "CommonConfig" + + } + +} \ No newline at end of file diff --git a/fints4k/src/nativeMain/kotlin/commands/TransferMoneyCommand.kt b/fints4k/src/nativeMain/kotlin/commands/TransferMoneyCommand.kt new file mode 100644 index 00000000..f9d42e27 --- /dev/null +++ b/fints4k/src/nativeMain/kotlin/commands/TransferMoneyCommand.kt @@ -0,0 +1,36 @@ +package commands + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.requireObject +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.options.option +import net.dankito.banking.client.model.parameter.TransferMoneyParameter +import net.dankito.banking.fints.model.Amount +import net.dankito.banking.fints.model.Currency +import net.dankito.banking.fints.model.Money + + +class TransferMoneyCommand : CliktCommand("Transfers money from your account to a recipient", name = "transfer", printHelpOnEmptyArgs = true) { + + val recipientName by argument("Recipient name", "Der Name des Empfängers") + val recipientAccountIdentifier by argument("Recipient account identifier", "In den meisten Fällen die IBAN des Empfängers") + val amount by argument("Amount", "The amount to transfer to recipient") + + val reference by argument("Reference", "Verwendungszweck. Max. 160 Zeichen, keine Sonderzeichen wie Umlaute etc.") + val recipientBankIdentifier by option("-b", "--bic", help = "Recipient's Bank Identifier, in most cases the BIC. Muss nur für Auslands-Überweisungen angegeben werden. Für deutsche Banken kann die BIC aus der IBAN abgeleitet werden.") + + + val config by requireObject>() + + + override fun run() { + val commonConfig = config[ConfigNames.CommonConfig] as CommonConfig + val (app, bankCode, loginName, password, preferredTanMethods, abortIfRequiresTan) = commonConfig + + + + app.transferMoney(TransferMoneyParameter(bankCode, loginName, password, null, recipientName, recipientAccountIdentifier, recipientBankIdentifier, + Money(Amount(amount), Currency.DefaultCurrencyCode), reference, false, preferredTanMethods, abortIfTanIsRequired = abortIfRequiresTan)) + } + +} \ No newline at end of file diff --git a/fints4k/src/nativeMain/kotlin/fints4kCommandLineInterface.kt b/fints4k/src/nativeMain/kotlin/commands/fints4kCommandLineInterface.kt similarity index 74% rename from fints4k/src/nativeMain/kotlin/fints4kCommandLineInterface.kt rename to fints4k/src/nativeMain/kotlin/commands/fints4kCommandLineInterface.kt index 8f203625..ba02780d 100644 --- a/fints4k/src/nativeMain/kotlin/fints4kCommandLineInterface.kt +++ b/fints4k/src/nativeMain/kotlin/commands/fints4kCommandLineInterface.kt @@ -1,4 +1,8 @@ +package commands + +import NativeApp import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.findOrSetObject import com.github.ajalt.clikt.parameters.arguments.argument import com.github.ajalt.clikt.parameters.options.* import com.github.ajalt.clikt.parameters.types.enum @@ -11,7 +15,8 @@ import net.dankito.banking.client.model.parameter.RetrieveTransactions import net.dankito.banking.fints.model.TanMethodType import net.dankito.utils.multiplatform.extensions.todayAtEuropeBerlin -class fints4kCommandLineInterface : CliktCommand(name = "fints", printHelpOnEmptyArgs = true) { + +class fints4kCommandLineInterface : CliktCommand(name = "fints", printHelpOnEmptyArgs = true, invokeWithoutSubcommand = true) { init { versionOption("1.0.0 Alpha-10", names = setOf("-v", "--version")) } @@ -21,6 +26,7 @@ class fints4kCommandLineInterface : CliktCommand(name = "fints", printHelpOnEmpt val password by argument("Passwort", "Dein Onlinebanking Passwort") // val password by option("-p", "--password", help = "Dein Onlinebanking Passwort").prompt("Passwort", hideInput = true) + val retrieveBalance by option("-b", "--balance", help = "Den Kontostand abrufen. Defaults to true").flag(default = true) val retrieveTransactions by option("-t", "--transactions", help = "Die Kontoumsätze abrufen. Default: OfLast90Days. As most banks don't afford a TAN to get transactions of last 90 days") .enum().default(RetrieveTransactions.OfLast90Days) @@ -31,12 +37,28 @@ class fints4kCommandLineInterface : CliktCommand(name = "fints", printHelpOnEmpt .validate { it.isNullOrBlank() || LocalDate.parse(it) != null } val retrieveTransactionsForLastNDays by option("-l", "--last-n-days", help = "Retrieve transactions for last n days. If set 'retrieveTransactions' gets set to '${RetrieveTransactions.AccordingToRetrieveFromAndTo}' and 'retrieveTransactionsFrom' will be ignored.").int() - val preferredTanMethod by option("-m", "--tan-method", help = "Your preferred TAN methods to use if action affords a TAN. Can be repeated like '-m AppTan -m SmsTan'").enum().multiple() + + val preferredTanMethods by option("-m", "--tan-method", help = "Your preferred TAN methods to use if action affords a TAN. Can be repeated like '-m AppTan -m SmsTan'").enum().multiple() val abortIfRequiresTan by option("-a", "--abort-if-requires-tan", help = "If actions should be aborted if it affords a TAN. Defaults to false").flag(default = false) + val config by findOrSetObject { mutableMapOf() } + + override fun run() { + config[ConfigNames.CommonConfig] = CommonConfig(NativeApp(), bankCode, loginName, password, preferredTanMethods, abortIfRequiresTan) + + if (currentContext.invokedSubcommand == null) { // if no subcommand is selected execute default command = getAccountData() + getAccountData() + } + } + + private fun getAccountData() { + val commonConfig = config[ConfigNames.CommonConfig] as CommonConfig + val (app, bankCode, loginName, password, preferredTanMethods, abortIfRequiresTan) = commonConfig + + val retrieveTransactionsFromDate = when { // retrieveTransactionsForLastNDays takes precedence over retrieveTransactionsFrom retrieveTransactionsForLastNDays != null -> LocalDate.todayAtEuropeBerlin().minus(retrieveTransactionsForLastNDays!!, DateTimeUnit.DAY) retrieveTransactionsFrom.isNullOrBlank() -> null @@ -45,9 +67,11 @@ class fints4kCommandLineInterface : CliktCommand(name = "fints", printHelpOnEmpt val retrieveTransactionsToDate = if (retrieveTransactionsTo.isNullOrBlank()) null else LocalDate.parse(retrieveTransactionsTo!!) val effectiveRetrieveTransactions = if (retrieveTransactionsFromDate != null || retrieveTransactionsToDate != null) RetrieveTransactions.AccordingToRetrieveFromAndTo - else retrieveTransactions + else retrieveTransactions - NativeApp().retrieveAccountData(GetAccountDataParameter(bankCode, loginName, password, null, retrieveBalance, effectiveRetrieveTransactions, - retrieveTransactionsFromDate, retrieveTransactionsToDate, preferredTanMethod, abortIfTanIsRequired = abortIfRequiresTan)) + + app.getAccountData(GetAccountDataParameter(bankCode, loginName, password, null, retrieveBalance, effectiveRetrieveTransactions, + retrieveTransactionsFromDate, retrieveTransactionsToDate, preferredTanMethods, abortIfTanIsRequired = abortIfRequiresTan)) } + } \ No newline at end of file diff --git a/fints4k/src/nativeMain/kotlin/main.kt b/fints4k/src/nativeMain/kotlin/main.kt index 0bd29b05..2cea82c3 100644 --- a/fints4k/src/nativeMain/kotlin/main.kt +++ b/fints4k/src/nativeMain/kotlin/main.kt @@ -1,4 +1,7 @@ +import com.github.ajalt.clikt.core.subcommands +import commands.TransferMoneyCommand +import commands.fints4kCommandLineInterface fun main(args: Array) { - fints4kCommandLineInterface().main(args) + fints4kCommandLineInterface().subcommands(TransferMoneyCommand()).main(args) } \ No newline at end of file