Converted fints4kBankingClient to a multi platform project
This commit is contained in:
parent
42f9e5f018
commit
82628d8a6b
|
@ -1,22 +1,127 @@
|
|||
apply plugin: 'java-library'
|
||||
apply plugin: 'kotlin'
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "com.android.library"
|
||||
id "maven-publish"
|
||||
}
|
||||
|
||||
|
||||
ext.artifactName = "fints4k-banking-client"
|
||||
|
||||
|
||||
sourceCompatibility = "1.7"
|
||||
targetCompatibility = "1.7"
|
||||
kotlin {
|
||||
jvm {
|
||||
compilations.main.kotlinOptions {
|
||||
jvmTarget = "1.6"
|
||||
}
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions.jvmTarget = "1.6"
|
||||
}
|
||||
compileTestKotlin {
|
||||
kotlinOptions.jvmTarget = "1.6"
|
||||
targets {
|
||||
// Select iOS target for real device or emulator.
|
||||
final def iOSIsRealDevice = System.getenv('SDK_NAME')?.startsWith("iphoneos")
|
||||
final def iOSTarget = iOSIsRealDevice ? presets.iosArm64 : presets.iosX64
|
||||
|
||||
// iOS target.
|
||||
fromPreset(iOSTarget, 'ios') {
|
||||
binaries {
|
||||
framework {
|
||||
baseName = "fints4kBankingClient"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation kotlin("stdlib-common")
|
||||
|
||||
implementation project(":BankingUiCommon")
|
||||
implementation project(":fints4k")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jvmMain {
|
||||
dependencies {
|
||||
api kotlin("stdlib-jdk7")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
iosMain {
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
api project(':BankingUiCommon')
|
||||
api project(':fints4k')
|
||||
// Task to generate iOS framework for xcode projects.
|
||||
task packForXCode(type: Sync) {
|
||||
|
||||
final File frameworkDir = new File(buildDir, "xcode-frameworks")
|
||||
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
|
||||
|
||||
final def framework = kotlin.targets.ios.binaries.getFramework("", mode)
|
||||
|
||||
inputs.property "mode", mode
|
||||
dependsOn framework.linkTask
|
||||
|
||||
from { framework.outputFile.parentFile }
|
||||
into frameworkDir
|
||||
|
||||
doLast {
|
||||
new File(frameworkDir, 'gradlew').with {
|
||||
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
|
||||
setExecutable(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run packForXCode when building.
|
||||
tasks.build.dependsOn packForXCode
|
||||
|
||||
|
||||
android {
|
||||
compileSdkVersion androidCompileSdkVersion
|
||||
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion androidMinSdkVersion
|
||||
targetSdkVersion androidTargetSdkVersion
|
||||
|
||||
versionName version
|
||||
versionCode appVersionCode
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
pickFirst 'META-INF/ktor-http.kotlin_module'
|
||||
pickFirst 'META-INF/kotlinx-io.kotlin_module'
|
||||
pickFirst 'META-INF/atomicfu.kotlin_module'
|
||||
pickFirst 'META-INF/ktor-utils.kotlin_module'
|
||||
pickFirst 'META-INF/kotlinx-coroutines-io.kotlin_module'
|
||||
pickFirst 'META-INF/ktor-client-core.kotlin_module'
|
||||
pickFirst 'META-INF/DEPENDENCIES'
|
||||
pickFirst 'META-INF/NOTICE'
|
||||
pickFirst 'META-INF/LICENSE'
|
||||
pickFirst 'META-INF/LICENSE.txt'
|
||||
pickFirst 'META-INF/NOTICE.txt'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package net.dankito.banking
|
||||
|
||||
import com.soywiz.klock.jvm.toDate
|
||||
import net.dankito.banking.extensions.toKlockDate
|
||||
import net.dankito.banking.ui.BankingClientCallback
|
||||
import net.dankito.banking.ui.IBankingClient
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
|
@ -19,17 +17,14 @@ import net.dankito.banking.fints.model.*
|
|||
import net.dankito.banking.mapper.BankDataMapper
|
||||
import net.dankito.banking.fints.util.IBase64Service
|
||||
import net.dankito.banking.fints.util.PureKotlinBase64Service
|
||||
import net.dankito.utils.serialization.JacksonJsonSerializer
|
||||
import net.dankito.banking.fints.webclient.IWebClient
|
||||
import net.dankito.banking.fints.webclient.KtorWebClient
|
||||
import net.dankito.banking.bankfinder.BankInfo
|
||||
import net.dankito.banking.extensions.toAmount
|
||||
import net.dankito.banking.extensions.toMoney
|
||||
import net.dankito.utils.multiplatform.log.Slf4jLoggerFactory
|
||||
import net.dankito.utils.multiplatform.toDate
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.math.BigDecimal
|
||||
import net.dankito.banking.util.ISerializer
|
||||
import net.dankito.utils.multiplatform.Date
|
||||
import net.dankito.utils.multiplatform.File
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
||||
|
||||
open class fints4kBankingClient(
|
||||
|
@ -37,6 +32,7 @@ open class fints4kBankingClient(
|
|||
customerId: String,
|
||||
pin: String,
|
||||
protected val dataFolder: File,
|
||||
protected val serializer: ISerializer,
|
||||
webClient: IWebClient = KtorWebClient(),
|
||||
base64Service: IBase64Service = PureKotlinBase64Service(),
|
||||
callback: BankingClientCallback
|
||||
|
@ -46,12 +42,7 @@ open class fints4kBankingClient(
|
|||
companion object {
|
||||
val fints4kClientDataFilename = "fints4kClientData.json"
|
||||
|
||||
private val log = LoggerFactory.getLogger(fints4kBankingClient::class.java)
|
||||
|
||||
|
||||
init {
|
||||
net.dankito.banking.fints.util.log.LoggerFactory.loggerFactory = net.dankito.banking.fints.util.log.Slf4jLoggerFactory()
|
||||
}
|
||||
private val log = LoggerFactory.getLogger(fints4kBankingClient::class)
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,8 +50,6 @@ open class fints4kBankingClient(
|
|||
|
||||
protected val bankDataMapper = BankDataMapper()
|
||||
|
||||
protected val serializer = JacksonJsonSerializer()
|
||||
|
||||
|
||||
protected val bank = bankDataMapper.mapFromBankInfo(bankInfo)
|
||||
|
||||
|
@ -96,7 +85,7 @@ open class fints4kBankingClient(
|
|||
|
||||
|
||||
override val messageLogWithoutSensitiveData: List<MessageLogEntry>
|
||||
get() = client.messageLogWithoutSensitiveData.map { MessageLogEntry(it.message, it.time.toDate(), customer) }
|
||||
get() = client.messageLogWithoutSensitiveData.map { MessageLogEntry(it.message, it.time, customer) }
|
||||
|
||||
|
||||
override fun addAccountAsync(callback: (AddAccountResponse) -> Unit) {
|
||||
|
@ -117,7 +106,8 @@ open class fints4kBankingClient(
|
|||
callback(GetTransactionsResponse(bankAccount, false, "Cannot find account for ${bankAccount.identifier}")) // TODO: translate
|
||||
}
|
||||
else {
|
||||
client.getTransactionsAsync(GetTransactionsParameter(parameter.alsoRetrieveBalance, parameter.fromDate?.toKlockDate(), parameter.toDate?.toKlockDate(), null, parameter.abortIfTanIsRequired,
|
||||
client.getTransactionsAsync(GetTransactionsParameter(parameter.alsoRetrieveBalance, parameter.fromDate,
|
||||
parameter.toDate, null, parameter.abortIfTanIsRequired,
|
||||
{ parameter.retrievedChunkListener?.invoke(mapper.mapTransactions(bankAccount, it)) } ), account) { response ->
|
||||
|
||||
val mappedResponse = mapper.mapResponse(bankAccount, response)
|
||||
|
@ -148,7 +138,7 @@ open class fints4kBankingClient(
|
|||
|
||||
|
||||
override fun restoreData() {
|
||||
val deserializedCustomer = serializer.deserializeObject(getFints4kClientDataFile(), CustomerData::class.java)
|
||||
val deserializedCustomer = serializer.deserializeObject(getFints4kClientDataFile(), CustomerData::class)
|
||||
|
||||
deserializedCustomer?.let {
|
||||
mapper.updateCustomer(fints4kCustomer, deserializedCustomer)
|
||||
|
@ -161,7 +151,7 @@ open class fints4kBankingClient(
|
|||
try {
|
||||
val clientDataFile = getFints4kClientDataFile()
|
||||
|
||||
clientDataFile.parentFile.mkdirs()
|
||||
clientDataFile.parent?.mkdirs()
|
||||
|
||||
serializer.serializeObject(fints4kCustomer, clientDataFile)
|
||||
} catch (e: Exception) {
|
|
@ -5,10 +5,11 @@ import net.dankito.banking.ui.IBankingClient
|
|||
import net.dankito.banking.ui.IBankingClientCreator
|
||||
import net.dankito.banking.bankfinder.BankInfo
|
||||
import net.dankito.banking.util.IAsyncRunner
|
||||
import java.io.File
|
||||
import net.dankito.banking.util.ISerializer
|
||||
import net.dankito.utils.multiplatform.File
|
||||
|
||||
|
||||
open class fints4kBankingClientCreator : IBankingClientCreator {
|
||||
open class fints4kBankingClientCreator(protected val serializer: ISerializer) : IBankingClientCreator {
|
||||
|
||||
override fun createClient(
|
||||
bankInfo: BankInfo,
|
||||
|
@ -19,7 +20,7 @@ open class fints4kBankingClientCreator : IBankingClientCreator {
|
|||
callback: BankingClientCallback
|
||||
): IBankingClient {
|
||||
|
||||
return fints4kBankingClient(bankInfo, customerId, pin, dataFolder, callback = callback)
|
||||
return fints4kBankingClient(bankInfo, customerId, pin, dataFolder, serializer, callback = callback)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package net.dankito.banking.mapper
|
||||
|
||||
import net.dankito.banking.extensions.toJavaBigDecimal
|
||||
import net.dankito.banking.extensions.toJavaUtilDate
|
||||
import net.dankito.utils.multiplatform.BigDecimal
|
||||
import net.dankito.banking.extensions.toBigDecimal
|
||||
import net.dankito.banking.ui.model.*
|
||||
import net.dankito.banking.ui.model.responses.AddAccountResponse
|
||||
import net.dankito.banking.ui.model.responses.BankingClientResponse
|
||||
|
@ -15,14 +15,13 @@ import net.dankito.banking.fints.model.CustomerData
|
|||
import net.dankito.banking.fints.model.Money
|
||||
import net.dankito.banking.fints.response.client.FinTsClientResponse
|
||||
import net.dankito.banking.fints.response.segments.AccountType
|
||||
import net.dankito.utils.exception.ExceptionHelper
|
||||
import java.math.BigDecimal
|
||||
//import net.dankito.utils.exception.ExceptionHelper
|
||||
|
||||
|
||||
open class fints4kModelMapper {
|
||||
|
||||
|
||||
private val exceptionHelper = ExceptionHelper()
|
||||
// private val exceptionHelper = ExceptionHelper()
|
||||
|
||||
|
||||
open fun mapResponse(response: FinTsClientResponse): BankingClientResponse {
|
||||
|
@ -31,7 +30,7 @@ open class fints4kModelMapper {
|
|||
|
||||
open fun mapResponse(customer: Customer, response: net.dankito.banking.fints.response.client.AddAccountResponse): AddAccountResponse {
|
||||
val balances = response.balances.mapKeys { findMatchingBankAccount(customer, it.key) }.filter { it.key != null }
|
||||
.mapValues { (it.value as Money).toJavaBigDecimal() } as Map<BankAccount, BigDecimal>
|
||||
.mapValues { (it.value as Money).toBigDecimal() } as Map<BankAccount, BigDecimal>
|
||||
|
||||
val bookedTransactions = response.bookedTransactions.associateBy { it.account }
|
||||
val mappedBookedTransactions = mutableMapOf<BankAccount, List<AccountTransaction>>()
|
||||
|
@ -56,14 +55,15 @@ open class fints4kModelMapper {
|
|||
return GetTransactionsResponse(bankAccount, response.isSuccessful, mapErrorToShowToUser(response),
|
||||
mapTransactions(bankAccount, response.bookedTransactions),
|
||||
listOf(), // TODO: map unbooked transactions
|
||||
response.balance?.toJavaBigDecimal(),
|
||||
response.balance?.toBigDecimal(),
|
||||
response.exception, response.userCancelledAction, response.tanRequiredButWeWereToldToAbortIfSo)
|
||||
}
|
||||
|
||||
open fun mapErrorToShowToUser(response: FinTsClientResponse): String? {
|
||||
val innerException = response.exception?.let { exception -> exceptionHelper.getInnerException(exception) }
|
||||
// val innerException = response.exception?.let { exception -> exceptionHelper.getInnerException(exception) }
|
||||
val innerException = response.exception // TODO
|
||||
|
||||
return innerException?.localizedMessage ?: response.errorsToShowToUser.joinToString("\n")
|
||||
return innerException?.message ?: response.errorsToShowToUser.joinToString("\n")
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,7 +102,7 @@ open class fints4kModelMapper {
|
|||
|
||||
open fun mapBankAccount(customer: Customer, accountData: AccountData): BankAccount {
|
||||
return BankAccount(customer, accountData.accountIdentifier, accountData.accountHolderName, accountData.iban,
|
||||
accountData.subAccountAttribute, accountData.customerId, BigDecimal.ZERO, accountData.currency ?: "EUR",
|
||||
accountData.subAccountAttribute, accountData.customerId, BigDecimal.Zero, accountData.currency ?: "EUR",
|
||||
mapBankAccountType(accountData.accountType), accountData.productName, accountData.accountLimit,
|
||||
null, accountData.supportsFeature(AccountFeature.RetrieveAccountTransactions),
|
||||
accountData.supportsFeature(AccountFeature.RetrieveBalance), accountData.supportsFeature(AccountFeature.TransferMoney),
|
||||
|
@ -176,19 +176,19 @@ open class fints4kModelMapper {
|
|||
open fun mapTransaction(bankAccount: BankAccount, transaction: net.dankito.banking.fints.model.AccountTransaction): AccountTransaction {
|
||||
return AccountTransaction(
|
||||
bankAccount,
|
||||
transaction.amount.toJavaBigDecimal(),
|
||||
transaction.amount.toBigDecimal(),
|
||||
transaction.amount.currency.code,
|
||||
transaction.unparsedUsage,
|
||||
transaction.bookingDate.toJavaUtilDate(),
|
||||
transaction.bookingDate,
|
||||
transaction.otherPartyName,
|
||||
transaction.otherPartyBankCode,
|
||||
transaction.otherPartyAccountId,
|
||||
transaction.bookingText,
|
||||
transaction.valueDate.toJavaUtilDate(),
|
||||
transaction.valueDate,
|
||||
transaction.statementNumber,
|
||||
transaction.sequenceNumber,
|
||||
transaction.openingBalance?.toJavaBigDecimal(),
|
||||
transaction.closingBalance?.toJavaBigDecimal(),
|
||||
transaction.openingBalance?.toBigDecimal(),
|
||||
transaction.closingBalance?.toBigDecimal(),
|
||||
|
||||
transaction.endToEndReference,
|
||||
transaction.customerReference,
|
Loading…
Reference in New Issue