Implemented retrieving transactions of last 90 days when adding an account; switched from wasmJs to js as Ktor currently doesn't support wasmJs (due to CORS web sites cannot request banks servers directly anyway)
This commit is contained in:
parent
9ee82e9a5b
commit
2869544a1c
|
@ -15,8 +15,7 @@ plugins {
|
||||||
|
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
@OptIn(ExperimentalWasmDsl::class)
|
js {
|
||||||
wasmJs {
|
|
||||||
moduleName = "composeApp"
|
moduleName = "composeApp"
|
||||||
browser {
|
browser {
|
||||||
val projectDirPath = project.projectDir.path
|
val projectDirPath = project.projectDir.path
|
||||||
|
@ -58,6 +57,7 @@ kotlin {
|
||||||
|
|
||||||
commonMain.dependencies {
|
commonMain.dependencies {
|
||||||
implementation(libs.banking.client.model)
|
implementation(libs.banking.client.model)
|
||||||
|
implementation(libs.fints4k.banking.client)
|
||||||
|
|
||||||
implementation(libs.kcsv)
|
implementation(libs.kcsv)
|
||||||
implementation(libs.klf)
|
implementation(libs.klf)
|
||||||
|
|
|
@ -6,12 +6,16 @@ import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import net.codinux.banking.ui.forms.*
|
import net.codinux.banking.ui.forms.*
|
||||||
import net.codinux.banking.ui.model.BankInfo
|
import net.codinux.banking.ui.model.BankInfo
|
||||||
import net.codinux.banking.ui.service.Colors
|
import net.codinux.banking.ui.service.Colors
|
||||||
|
@ -32,6 +36,11 @@ fun AddAccountDialog(
|
||||||
derivedStateOf { selectedBank != null && loginName.length > 3 && password.length > 3 }
|
derivedStateOf { selectedBank != null && loginName.length > 3 && password.length > 3 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isAddingAccount by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
|
||||||
Dialog(onDismissRequest = onDismiss) {
|
Dialog(onDismissRequest = onDismiss) {
|
||||||
RoundedCornersCard {
|
RoundedCornersCard {
|
||||||
Column(Modifier.background(Color.White).padding(8.dp)) {
|
Column(Modifier.background(Color.White).padding(8.dp)) {
|
||||||
|
@ -93,10 +102,35 @@ fun AddAccountDialog(
|
||||||
Spacer(Modifier.width(8.dp))
|
Spacer(Modifier.width(8.dp))
|
||||||
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = onDismiss,
|
modifier = Modifier.width(150.dp),
|
||||||
enabled = isRequiredDataEntered
|
enabled = isRequiredDataEntered && isAddingAccount == false,
|
||||||
|
onClick = {
|
||||||
|
selectedBank?.let {
|
||||||
|
isAddingAccount = true
|
||||||
|
|
||||||
|
coroutineScope.launch { // TODO: launch on Dispatchers.IO where it is available
|
||||||
|
val errorMessage = DI.bankingService.addAccount(selectedBank!!, loginName, password)
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isAddingAccount = false
|
||||||
|
|
||||||
|
if (errorMessage == null) {
|
||||||
|
onDismiss()
|
||||||
|
} else {
|
||||||
|
// TODO: show error Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Text("Hinzufügen")
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
if (isAddingAccount) {
|
||||||
|
CircularProgressIndicator(Modifier.padding(end = 6.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
Text("Hinzufügen")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,12 @@ package net.codinux.banking.ui.service
|
||||||
|
|
||||||
import bankmeister.composeapp.generated.resources.Res
|
import bankmeister.composeapp.generated.resources.Res
|
||||||
import kotlinx.datetime.LocalDate
|
import kotlinx.datetime.LocalDate
|
||||||
|
import net.codinux.banking.client.SimpleBankingClientCallback
|
||||||
|
import net.codinux.banking.client.fints4k.FinTs4kBankingClientForCustomer
|
||||||
import net.codinux.banking.client.model.AccountTransaction
|
import net.codinux.banking.client.model.AccountTransaction
|
||||||
import net.codinux.banking.client.model.Amount
|
import net.codinux.banking.client.model.Amount
|
||||||
|
import net.codinux.banking.fints.config.FinTsClientConfiguration
|
||||||
|
import net.codinux.banking.fints.config.FinTsClientOptions
|
||||||
import net.codinux.banking.ui.model.BankInfo
|
import net.codinux.banking.ui.model.BankInfo
|
||||||
import net.codinux.csv.reader.CsvReader
|
import net.codinux.csv.reader.CsvReader
|
||||||
import net.codinux.log.logger
|
import net.codinux.log.logger
|
||||||
|
@ -33,6 +37,29 @@ class BankingService(
|
||||||
return transactions
|
return transactions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun addAccount(bank: BankInfo, loginName: String, password: String): String? {
|
||||||
|
try {
|
||||||
|
val config = FinTsClientConfiguration(FinTsClientOptions(true))
|
||||||
|
val client = FinTs4kBankingClientForCustomer(bank.bankCode, loginName, password, config, SimpleBankingClientCallback { tanChallenge, callback ->
|
||||||
|
// TODO: show EnterTanDialog
|
||||||
|
})
|
||||||
|
|
||||||
|
val response = client.getAccountDataAsync()
|
||||||
|
response.data?.let { accountData ->
|
||||||
|
if (cachedTransactions == null) {
|
||||||
|
cachedTransactions = accountData.bookedTransactions
|
||||||
|
} else {
|
||||||
|
cachedTransactions = (cachedTransactions!! + accountData.bookedTransactions).sortedByDescending { it.valueDate }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.error?.internalError ?: response.error?.errorMessagesFromBank?.joinToString("\n")
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
log.error(e) { "Could not add account for ${bank.name} $loginName" }
|
||||||
|
return e.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun readTransactionsFromCsv(): List<AccountTransaction> {
|
private suspend fun readTransactionsFromCsv(): List<AccountTransaction> {
|
||||||
val csv = Res.readBytes("files/transactions.csv").decodeToString()
|
val csv = Res.readBytes("files/transactions.csv").decodeToString()
|
||||||
val csvReader = CsvReader(hasHeaderRow = true, reuseRowInstance = true, skipEmptyRows = true).read(csv)
|
val csvReader = CsvReader(hasHeaderRow = true, reuseRowInstance = true, skipEmptyRows = true).read(csv)
|
||||||
|
|
|
@ -9,3 +9,6 @@ android.useAndroidX=true
|
||||||
|
|
||||||
#Kotlin Multiplatform
|
#Kotlin Multiplatform
|
||||||
kotlin.mpp.enableCInteropCommonization=true
|
kotlin.mpp.enableCInteropCommonization=true
|
||||||
|
|
||||||
|
# Compose Multiplatform Web
|
||||||
|
org.jetbrains.compose.experimental.jscanvas.enabled=true
|
|
@ -26,6 +26,7 @@ junit = "4.13.2"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
banking-client-model = { group = "net.codinux.banking.client", name = "banking-client-model", version.ref = "banking-client" }
|
banking-client-model = { group = "net.codinux.banking.client", name = "banking-client-model", version.ref = "banking-client" }
|
||||||
|
fints4k-banking-client = { group = "net.codinux.banking.client", name = "fints4k-banking-client", version.ref = "banking-client" }
|
||||||
|
|
||||||
kcsv = { group = "net.codinux.csv", name = "kcsv", version.ref = "kcsv" }
|
kcsv = { group = "net.codinux.csv", name = "kcsv", version.ref = "kcsv" }
|
||||||
klf = { group = "net.codinux.log", name = "klf", version.ref = "klf" }
|
klf = { group = "net.codinux.log", name = "klf", version.ref = "klf" }
|
||||||
|
|
|
@ -25,6 +25,10 @@ dependencyResolutionManagement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
maven {
|
||||||
|
setUrl("https://maven.dankito.net/api/packages/codinux/maven")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue