Renamed Account to Customer
This commit is contained in:
parent
9a5e0a1098
commit
b5cb401636
|
@ -13,7 +13,7 @@ import net.dankito.banking.LuceneConfig.Companion.OtherPartyAccountIdFieldName
|
|||
import net.dankito.banking.LuceneConfig.Companion.OtherPartyBankCodeFieldName
|
||||
import net.dankito.banking.LuceneConfig.Companion.OtherPartyNameFieldName
|
||||
import net.dankito.banking.LuceneConfig.Companion.UsageFieldName
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.AccountTransaction
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import net.dankito.utils.lucene.index.DocumentsWriter
|
||||
|
@ -79,14 +79,14 @@ open class LuceneBankingPersistence(
|
|||
}
|
||||
|
||||
|
||||
override fun deleteAccount(account: Account, allAccounts: List<Account>) {
|
||||
override fun deleteAccount(customer: Customer, allCustomers: List<Customer>) {
|
||||
try {
|
||||
deleteAccountTransactions(account.bankAccounts)
|
||||
deleteAccountTransactions(customer.bankAccounts)
|
||||
} catch (e: Exception) {
|
||||
log.error("Could not delete account transactions of account $account", e)
|
||||
log.error("Could not delete account transactions of account $customer", e)
|
||||
}
|
||||
|
||||
super.deleteAccount(account, allAccounts)
|
||||
super.deleteAccount(customer, allCustomers)
|
||||
}
|
||||
|
||||
protected open fun deleteAccountTransactions(bankAccounts: List<BankAccount>) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package net.dankito.banking.search
|
||||
|
||||
import net.dankito.banking.persistence.LuceneBankingPersistence
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.AccountTransaction
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import net.dankito.utils.io.FileUtils
|
||||
|
@ -35,7 +35,7 @@ class LuceneRemitteeSearcherTest {
|
|||
private val Amount = BigDecimal.valueOf(123.45)
|
||||
|
||||
|
||||
private val bankAccountMock = BankAccount(mock(Account::class.java), "", "", null, null)
|
||||
private val bankAccountMock = BankAccount(mock(Customer::class.java), "", "", null, null)
|
||||
|
||||
|
||||
private val dateFormat = SimpleDateFormat("dd.MM.yyyy")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package net.dankito.banking.persistence
|
||||
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.AccountTransaction
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import net.dankito.utils.serialization.ISerializer
|
||||
|
@ -19,16 +19,16 @@ open class BankingPersistenceJson(
|
|||
}
|
||||
|
||||
|
||||
override fun saveOrUpdateAccount(account: Account, allAccounts: List<Account>) {
|
||||
serializer.serializeObject(allAccounts, jsonFile)
|
||||
override fun saveOrUpdateAccount(customer: Customer, allCustomers: List<Customer>) {
|
||||
serializer.serializeObject(allCustomers, jsonFile)
|
||||
}
|
||||
|
||||
override fun deleteAccount(account: Account, allAccounts: List<Account>) {
|
||||
serializer.serializeObject(allAccounts, jsonFile)
|
||||
override fun deleteAccount(customer: Customer, allCustomers: List<Customer>) {
|
||||
serializer.serializeObject(allCustomers, jsonFile)
|
||||
}
|
||||
|
||||
override fun readPersistedAccounts(): List<Account> {
|
||||
return serializer.deserializeListOr(jsonFile, Account::class.java, listOf())
|
||||
override fun readPersistedAccounts(): List<Customer> {
|
||||
return serializer.deserializeListOr(jsonFile, Customer::class.java, listOf())
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package net.dankito.banking.ui.android
|
|||
import net.dankito.banking.ui.android.util.CurrentActivityTracker
|
||||
import net.dankito.banking.ui.IRouter
|
||||
import net.dankito.banking.ui.android.dialogs.*
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import net.dankito.banking.ui.model.parameters.TransferMoneyData
|
||||
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
|
||||
|
@ -23,13 +23,13 @@ open class RouterAndroid(protected val activityTracker: CurrentActivityTracker)
|
|||
}
|
||||
}
|
||||
|
||||
override fun getTanFromUserFromNonUiThread(account: Account, tanChallenge: TanChallenge, presenter: BankingPresenter): EnterTanResult {
|
||||
override fun getTanFromUserFromNonUiThread(customer: Customer, tanChallenge: TanChallenge, presenter: BankingPresenter): EnterTanResult {
|
||||
val enteredTan = AtomicReference<EnterTanResult>(null)
|
||||
val tanEnteredLatch = CountDownLatch(1)
|
||||
|
||||
activityTracker.currentOrNextActivity { activity ->
|
||||
activity.runOnUiThread {
|
||||
EnterTanDialog().show(account, tanChallenge, activity, false) {
|
||||
EnterTanDialog().show(customer, tanChallenge, activity, false) {
|
||||
enteredTan.set(it)
|
||||
tanEnteredLatch.countDown()
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ open class AccountTransactionAdapter(protected val presenter: BankingPresenter)
|
|||
viewHolder.txtvwAmount.text = presenter.formatAmount(item.amount)
|
||||
viewHolder.txtvwAmount.setTextColorToColorResource(if (item.amount >= BigDecimal.ZERO) R.color.positiveAmount else R.color.negativeAmount)
|
||||
|
||||
val iconUrl = item.bankAccount.account.bank.iconUrl
|
||||
val iconUrl = item.bankAccount.customer.bank.iconUrl
|
||||
if (iconUrl != null && presenter.areAllAccountSelected) {
|
||||
viewHolder.imgvwBankIcon.visibility = View.VISIBLE
|
||||
viewHolder.imgvwBankIcon.setImageURI(Uri.parse(iconUrl))
|
||||
|
|
|
@ -32,7 +32,7 @@ open class BankAccountsAdapter(bankAccounts: List<BankAccount>) : ListAdapter<Ba
|
|||
|
||||
protected open fun setIcon(bankAccount: BankAccount, imgBankIcon: ImageView) {
|
||||
try {
|
||||
val iconUrl = bankAccount.account.bank.iconUrl
|
||||
val iconUrl = bankAccount.customer.bank.iconUrl
|
||||
imgBankIcon.visibility = if (iconUrl == null) View.GONE else View.VISIBLE
|
||||
imgBankIcon.setImageURI(Uri.parse(iconUrl))
|
||||
} catch (e: Exception) {
|
||||
|
|
|
@ -169,7 +169,7 @@ open class AddAccountDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
protected open fun retrieveAccountTransactionsAndDismiss(response: AddAccountResponse, messageDialog: DialogInterface) {
|
||||
presenter.fetchAccountTransactionsAsync(response.account) { }
|
||||
presenter.fetchAccountTransactionsAsync(response.customer) { }
|
||||
|
||||
messageDialog.dismiss()
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import net.dankito.banking.ui.android.di.BankingComponent
|
|||
import net.dankito.banking.ui.android.adapter.TanMediumAdapter
|
||||
import net.dankito.banking.ui.android.adapter.TanProceduresAdapter
|
||||
import net.dankito.banking.ui.android.listener.ListItemSelectedListener
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.responses.BankingClientResponse
|
||||
import net.dankito.banking.ui.model.tan.*
|
||||
import net.dankito.banking.ui.presenter.BankingPresenter
|
||||
|
@ -40,7 +40,7 @@ open class EnterTanDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
|
||||
protected lateinit var account: Account
|
||||
protected lateinit var customer: Customer
|
||||
|
||||
protected lateinit var tanChallenge: TanChallenge
|
||||
|
||||
|
@ -58,10 +58,10 @@ open class EnterTanDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
|
||||
open fun show(account: Account, tanChallenge: TanChallenge, activity: AppCompatActivity,
|
||||
open fun show(customer: Customer, tanChallenge: TanChallenge, activity: AppCompatActivity,
|
||||
fullscreen: Boolean = false, tanEnteredCallback: (EnterTanResult) -> Unit) {
|
||||
|
||||
this.account = account
|
||||
this.customer = customer
|
||||
this.tanChallenge = tanChallenge
|
||||
this.tanEnteredCallback = tanEnteredCallback
|
||||
|
||||
|
@ -95,13 +95,13 @@ open class EnterTanDialog : DialogFragment() {
|
|||
|
||||
protected open fun setupSelectTanProcedureView(rootView: View) {
|
||||
val adapter = TanProceduresAdapter()
|
||||
val tanProceduresWithoutUnsupported = account.supportedTanProcedures.filterNot { it.type == TanProcedureType.ChipTanUsb } // USB tan generators are not supported on Android
|
||||
val tanProceduresWithoutUnsupported = customer.supportedTanProcedures.filterNot { it.type == TanProcedureType.ChipTanUsb } // USB tan generators are not supported on Android
|
||||
adapter.setItems(tanProceduresWithoutUnsupported)
|
||||
|
||||
rootView.findViewById<Spinner>(R.id.spnTanProcedures)?.let { spinner ->
|
||||
spinner.adapter = adapter
|
||||
|
||||
val selectedTanProcedure = account.selectedTanProcedure
|
||||
val selectedTanProcedure = customer.selectedTanProcedure
|
||||
?: tanProceduresWithoutUnsupported.firstOrNull { it.type != TanProcedureType.ChipTanManuell && it.type != TanProcedureType.ChipTanUsb }
|
||||
?: tanProceduresWithoutUnsupported.firstOrNull()
|
||||
selectedTanProcedure?.let { spinner.setSelection(adapter.getItems().indexOf(selectedTanProcedure)) }
|
||||
|
@ -120,7 +120,7 @@ open class EnterTanDialog : DialogFragment() {
|
|||
protected open fun setupSelectTanMediumView(rootView: View) {
|
||||
rootView.lytTanMedium.visibility = View.VISIBLE
|
||||
|
||||
tanMediumAdapter.setItems(account.tanMediaSorted)
|
||||
tanMediumAdapter.setItems(customer.tanMediaSorted)
|
||||
|
||||
rootView.spnTanMedium.adapter = tanMediumAdapter
|
||||
rootView.spnTanMedium.onItemSelectedListener = ListItemSelectedListener(tanMediumAdapter) { selectedTanMedium ->
|
||||
|
@ -140,7 +140,7 @@ open class EnterTanDialog : DialogFragment() {
|
|||
|
||||
protected open fun setupTanView(rootView: View) {
|
||||
if (OpticalTanProcedures.contains(tanChallenge.tanProcedure.type)) {
|
||||
if (account.tanMedia.isNotEmpty()) {
|
||||
if (customer.tanMedia.isNotEmpty()) {
|
||||
setupSelectTanMediumView(rootView)
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ open class SendMessageLogDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
protected open fun setupUI(rootView: View) {
|
||||
val messageLog = presenter.getMessageLogForAccounts(presenter.accounts).joinToString("\r\n\r\n")
|
||||
val messageLog = presenter.getMessageLogForAccounts(presenter.customers).joinToString("\r\n\r\n")
|
||||
|
||||
if (messageLog.isBlank()) {
|
||||
rootView.txtvwInfoNoMessageLogEntriesYet.visibility = View.VISIBLE
|
||||
|
|
|
@ -20,7 +20,7 @@ import com.mikepenz.materialdrawer.util.removeItemByPosition
|
|||
import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
|
||||
import net.dankito.banking.ui.android.R
|
||||
import net.dankito.banking.ui.android.extensions.withIcon
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.presenter.BankingPresenter
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
|
@ -129,7 +129,7 @@ open class DrawerView(
|
|||
}
|
||||
|
||||
private fun createAccountsDrawerItems(): List<IDrawerItem<*>> {
|
||||
return presenter.accounts.map { account ->
|
||||
return presenter.customers.map { account ->
|
||||
val accountItem = createAccountDrawerItem(account)
|
||||
|
||||
val bankAccountsItems = createBankAccountsDrawerItems(account).toMutableList()
|
||||
|
@ -139,20 +139,20 @@ open class DrawerView(
|
|||
}.flatten()
|
||||
}
|
||||
|
||||
private fun createAccountDrawerItem(account: Account): IDrawerItem<*> {
|
||||
private fun createAccountDrawerItem(customer: Customer): IDrawerItem<*> {
|
||||
|
||||
val accountItem = AccountDrawerItem()
|
||||
.withName(account.displayName)
|
||||
.withName(customer.displayName)
|
||||
.withLevel(AccountLevel)
|
||||
// .withSecondaryIcon(GoogleMaterial.Icon.gmd_settings) // used when editing account is implemented
|
||||
.withSecondaryIcon(GoogleMaterial.Icon.gmd_delete)
|
||||
.withSecondaryIconColor(activity, R.color.primaryTextColor_Dark)
|
||||
.withOnSecondaryIconClickedListener { closeDrawerAndEditAccount(account) }
|
||||
.withIcon(account.bank.iconUrl ?: "")
|
||||
.withSelected(presenter.isSingleSelectedAccount(account))
|
||||
.withOnDrawerItemClickListener { _, _, _ -> itemClicked { presenter.selectedAccount(account) } }
|
||||
.withOnSecondaryIconClickedListener { closeDrawerAndEditAccount(customer) }
|
||||
.withIcon(customer.bank.iconUrl ?: "")
|
||||
.withSelected(presenter.isSingleSelectedAccount(customer))
|
||||
.withOnDrawerItemClickListener { _, _, _ -> itemClicked { presenter.selectedAccount(customer) } }
|
||||
|
||||
if (account.bank.iconUrl == null) {
|
||||
if (customer.bank.iconUrl == null) {
|
||||
accountItem.withIcon(activity, FontAwesome.Icon.faw_piggy_bank, R.color.primaryTextColor_Dark)
|
||||
}
|
||||
|
||||
|
@ -160,8 +160,8 @@ open class DrawerView(
|
|||
return accountItem
|
||||
}
|
||||
|
||||
private fun createBankAccountsDrawerItems(account: Account): List<IDrawerItem<*>> {
|
||||
return account.bankAccounts.map { bankAccount ->
|
||||
private fun createBankAccountsDrawerItems(customer: Customer): List<IDrawerItem<*>> {
|
||||
return customer.bankAccounts.map { bankAccount ->
|
||||
SecondaryDrawerItem()
|
||||
.withName(bankAccount.displayName)
|
||||
.withLevel(BankAccountLevel)
|
||||
|
@ -176,20 +176,20 @@ open class DrawerView(
|
|||
return false
|
||||
}
|
||||
|
||||
private fun closeDrawerAndEditAccount(account: Account) {
|
||||
private fun closeDrawerAndEditAccount(customer: Customer) {
|
||||
closeDrawer()
|
||||
|
||||
editAccount(account)
|
||||
editAccount(customer)
|
||||
}
|
||||
|
||||
private fun editAccount(account: Account) {
|
||||
private fun editAccount(customer: Customer) {
|
||||
// TODO: implement editing account (e.g. displayed name etc.)
|
||||
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(activity.getString(R.string.dialog_edit_account_ask_should_account_be_deleted, account.displayName))
|
||||
.setMessage(activity.getString(R.string.dialog_edit_account_ask_should_account_be_deleted, customer.displayName))
|
||||
.setPositiveButton(R.string.delete) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
presenter.deleteAccount(account)
|
||||
presenter.deleteAccount(customer)
|
||||
}
|
||||
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
|
||||
.show()
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.dankito.banking.ui.IRouter
|
|||
import net.dankito.banking.ui.javafx.dialogs.AddAccountDialog
|
||||
import net.dankito.banking.ui.javafx.dialogs.cashtransfer.TransferMoneyDialog
|
||||
import net.dankito.banking.ui.javafx.dialogs.tan.EnterTanDialog
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import net.dankito.banking.ui.model.parameters.TransferMoneyData
|
||||
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
|
||||
|
@ -25,12 +25,12 @@ open class RouterJavaFx : IRouter {
|
|||
AddAccountDialog(presenter).show(messages["add.account.dialog.title"])
|
||||
}
|
||||
|
||||
override fun getTanFromUserFromNonUiThread(account: Account, tanChallenge: TanChallenge, presenter: BankingPresenter): EnterTanResult {
|
||||
override fun getTanFromUserFromNonUiThread(customer: Customer, tanChallenge: TanChallenge, presenter: BankingPresenter): EnterTanResult {
|
||||
val enteredTan = AtomicReference<EnterTanResult>(null)
|
||||
val tanEnteredLatch = CountDownLatch(1)
|
||||
|
||||
FX.runAndWait {
|
||||
EnterTanDialog(account, tanChallenge, presenter) {
|
||||
EnterTanDialog(customer, tanChallenge, presenter) {
|
||||
enteredTan.set(it)
|
||||
tanEnteredLatch.countDown()
|
||||
}.show(messages["enter.tan.dialog.title"])
|
||||
|
|
|
@ -10,14 +10,14 @@ import javafx.scene.input.KeyCode
|
|||
import net.dankito.banking.ui.javafx.dialogs.JavaFxDialogService
|
||||
import net.dankito.banking.ui.javafx.model.AccountsAccountTreeItem
|
||||
import net.dankito.banking.ui.javafx.model.AccountsRootTreeItem
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.presenter.BankingPresenter
|
||||
import tornadofx.*
|
||||
import tornadofx.FX.Companion.messages
|
||||
|
||||
|
||||
open class AccountsTreeView(accounts: ObservableList<Account>, protected val presenter: BankingPresenter)
|
||||
: TreeView<String>(AccountsRootTreeItem(accounts)) {
|
||||
open class AccountsTreeView(customers: ObservableList<Customer>, protected val presenter: BankingPresenter)
|
||||
: TreeView<String>(AccountsRootTreeItem(customers)) {
|
||||
|
||||
protected var currentMenu: ContextMenu? = null
|
||||
|
||||
|
@ -64,7 +64,7 @@ open class AccountsTreeView(accounts: ObservableList<Account>, protected val pre
|
|||
}
|
||||
|
||||
protected open fun askIfAccountShouldBeDeleted(treeItem: AccountsAccountTreeItem) {
|
||||
val account = treeItem.account
|
||||
val account = treeItem.customer
|
||||
|
||||
val selectedButton = JavaFxDialogService().showDialog(
|
||||
Alert.AlertType.WARNING,
|
||||
|
|
|
@ -15,7 +15,7 @@ import tornadofx.*
|
|||
|
||||
open class AccountsView(protected val presenter: BankingPresenter) : View() {
|
||||
|
||||
protected val accounts = FXCollections.observableArrayList(presenter.accounts)
|
||||
protected val accounts = FXCollections.observableArrayList(presenter.customers)
|
||||
|
||||
|
||||
init {
|
||||
|
@ -70,7 +70,7 @@ open class AccountsView(protected val presenter: BankingPresenter) : View() {
|
|||
accountTreeItem?.let {
|
||||
when (accountTreeItem) {
|
||||
is AccountsBankAccountTreeItem -> presenter.selectedBankAccount(accountTreeItem.bankAccount)
|
||||
is AccountsAccountTreeItem -> presenter.selectedAccount(accountTreeItem.account)
|
||||
is AccountsAccountTreeItem -> presenter.selectedAccount(accountTreeItem.customer)
|
||||
else -> presenter.selectedAllBankAccounts()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ open class AddAccountDialog(protected val presenter: BankingPresenter) : Window(
|
|||
handleSuccessfullyAddedAccountResultOnUiThread(response)
|
||||
}
|
||||
else {
|
||||
val account = response.account
|
||||
val account = response.customer
|
||||
|
||||
checkEnteredCredentialsResult.value = String.format(messages["add.account.dialog.error.could.not.add.account"],
|
||||
account.bank.bankCode, account.customerId, response.errorToShowToUser)
|
||||
|
@ -270,7 +270,7 @@ open class AddAccountDialog(protected val presenter: BankingPresenter) : Window(
|
|||
val userSelection = dialogService.showDialog(Alert.AlertType.CONFIRMATION, message, null, currentStage, ButtonType.YES, ButtonType.NO)
|
||||
|
||||
when (userSelection) {
|
||||
ButtonType.YES -> presenter.fetchAccountTransactionsAsync(response.account) { }
|
||||
ButtonType.YES -> presenter.fetchAccountTransactionsAsync(response.customer) { }
|
||||
else -> { } // nothing to do then, simply close dialog
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ open class TransferMoneyDialog @JvmOverloads constructor(
|
|||
cellFormat {
|
||||
text = it.displayNameIncludingBankName
|
||||
|
||||
it.account.bank.iconUrl?.let { iconUrl ->
|
||||
it.customer.bank.iconUrl?.let { iconUrl ->
|
||||
graphic = ImageView(iconUrl)?.apply {
|
||||
this.fitHeight = BankIconSize
|
||||
this.fitWidth = BankIconSize
|
||||
|
|
|
@ -10,7 +10,7 @@ import javafx.scene.text.FontWeight
|
|||
import net.dankito.banking.ui.javafx.dialogs.tan.controls.ChipTanFlickerCodeView
|
||||
import net.dankito.banking.ui.javafx.dialogs.JavaFxDialogService
|
||||
import net.dankito.banking.ui.javafx.dialogs.tan.controls.TanImageView
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.responses.BankingClientResponse
|
||||
import net.dankito.banking.ui.model.tan.*
|
||||
import net.dankito.banking.ui.presenter.BankingPresenter
|
||||
|
@ -20,7 +20,7 @@ import tornadofx.*
|
|||
|
||||
|
||||
open class EnterTanDialog(
|
||||
protected val account: Account,
|
||||
protected val customer: Customer,
|
||||
protected val challenge: TanChallenge,
|
||||
protected val presenter: BankingPresenter,
|
||||
protected val tanEnteredCallback: (EnterTanResult) -> Unit
|
||||
|
@ -41,11 +41,11 @@ open class EnterTanDialog(
|
|||
protected var tanImageView: TanImageView? = null
|
||||
|
||||
|
||||
protected val tanProceduresWithoutUnsupported = account.supportedTanProcedures.filterNot { it.type == TanProcedureType.ChipTanUsb } // USB tan generators are not supported
|
||||
protected val tanProceduresWithoutUnsupported = customer.supportedTanProcedures.filterNot { it.type == TanProcedureType.ChipTanUsb } // USB tan generators are not supported
|
||||
|
||||
protected val selectedTanProcedure = SimpleObjectProperty<TanProcedure>(account.selectedTanProcedure ?: tanProceduresWithoutUnsupported.firstOrNull { it.displayName.contains("manuell", true) == false } ?: tanProceduresWithoutUnsupported.firstOrNull())
|
||||
protected val selectedTanProcedure = SimpleObjectProperty<TanProcedure>(customer.selectedTanProcedure ?: tanProceduresWithoutUnsupported.firstOrNull { it.displayName.contains("manuell", true) == false } ?: tanProceduresWithoutUnsupported.firstOrNull())
|
||||
|
||||
protected val selectedTanMedium = SimpleObjectProperty<TanMedium>(account.tanMediaSorted.firstOrNull())
|
||||
protected val selectedTanMedium = SimpleObjectProperty<TanMedium>(customer.tanMediaSorted.firstOrNull())
|
||||
|
||||
protected val enteredTan = SimpleStringProperty("")
|
||||
|
||||
|
@ -84,13 +84,13 @@ open class EnterTanDialog(
|
|||
}
|
||||
}
|
||||
|
||||
if (account.tanMediaSorted.isNotEmpty()) {
|
||||
if (customer.tanMediaSorted.isNotEmpty()) {
|
||||
field(messages["enter.tan.dialog.select.tan.medium"]) {
|
||||
label.apply {
|
||||
font = Font.font(font.family, FontWeight.BLACK, font.size)
|
||||
}
|
||||
|
||||
combobox(selectedTanMedium, account.tanMediaSorted) {
|
||||
combobox(selectedTanMedium, customer.tanMediaSorted) {
|
||||
cellFormat {
|
||||
text = it.displayName
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@ package net.dankito.banking.ui.javafx.model
|
|||
|
||||
import javafx.scene.Node
|
||||
import javafx.scene.image.ImageView
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
|
||||
|
||||
open class AccountsAccountTreeItem(val account: Account) : AccountsTreeItemBase(account.displayName) {
|
||||
open class AccountsAccountTreeItem(val customer: Customer) : AccountsTreeItemBase(customer.displayName) {
|
||||
|
||||
companion object {
|
||||
private const val IconSize = 16.0
|
||||
|
@ -17,13 +17,13 @@ open class AccountsAccountTreeItem(val account: Account) : AccountsTreeItemBase(
|
|||
|
||||
graphic = createIconImageView()
|
||||
|
||||
account.bankAccounts.forEach { bankAccount ->
|
||||
customer.bankAccounts.forEach { bankAccount ->
|
||||
children.add(AccountsBankAccountTreeItem(bankAccount))
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun createIconImageView(): Node? {
|
||||
account.bank.iconUrl?.let {
|
||||
customer.bank.iconUrl?.let {
|
||||
val iconImageView = ImageView(it)
|
||||
|
||||
iconImageView.fitHeight = IconSize
|
||||
|
|
|
@ -2,26 +2,26 @@ package net.dankito.banking.ui.javafx.model
|
|||
|
||||
import javafx.collections.ListChangeListener
|
||||
import javafx.collections.ObservableList
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import tornadofx.FX.Companion.messages
|
||||
import tornadofx.get
|
||||
import tornadofx.runLater
|
||||
|
||||
|
||||
open class AccountsRootTreeItem(accounts: ObservableList<Account>) : AccountsTreeItemBase(messages["accounts.view.all.accounts"]) {
|
||||
open class AccountsRootTreeItem(customers: ObservableList<Customer>) : AccountsTreeItemBase(messages["accounts.view.all.accounts"]) {
|
||||
|
||||
init {
|
||||
setAccounts(accounts)
|
||||
setAccounts(customers)
|
||||
|
||||
accounts.addListener(ListChangeListener {
|
||||
runLater { setAccounts(accounts) }
|
||||
customers.addListener(ListChangeListener {
|
||||
runLater { setAccounts(customers) }
|
||||
})
|
||||
}
|
||||
|
||||
protected open fun setAccounts(accounts: List<Account>) {
|
||||
isExpanded = accounts.isNotEmpty()
|
||||
protected open fun setAccounts(customers: List<Customer>) {
|
||||
isExpanded = customers.isNotEmpty()
|
||||
|
||||
children.setAll(accounts.map { AccountsAccountTreeItem(it) })
|
||||
children.setAll(customers.map { AccountsAccountTreeItem(it) })
|
||||
}
|
||||
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
package net.dankito.banking.persistence
|
||||
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.AccountTransaction
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
|
||||
|
||||
interface IBankingPersistence {
|
||||
|
||||
fun saveOrUpdateAccount(account: Account, allAccounts: List<Account>)
|
||||
fun saveOrUpdateAccount(customer: Customer, allCustomers: List<Customer>)
|
||||
|
||||
fun deleteAccount(account: Account, allAccounts: List<Account>)
|
||||
fun deleteAccount(customer: Customer, allCustomers: List<Customer>)
|
||||
|
||||
fun readPersistedAccounts(): List<Account>
|
||||
fun readPersistedAccounts(): List<Customer>
|
||||
|
||||
|
||||
fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List<AccountTransaction>)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package net.dankito.banking.ui
|
||||
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
|
||||
import net.dankito.banking.ui.model.tan.EnterTanResult
|
||||
import net.dankito.banking.ui.model.tan.TanChallenge
|
||||
|
@ -9,7 +9,7 @@ import net.dankito.banking.ui.model.tan.TanGeneratorTanMedium
|
|||
|
||||
interface BankingClientCallback {
|
||||
|
||||
fun enterTan(account: Account, tanChallenge: TanChallenge): EnterTanResult
|
||||
fun enterTan(customer: Customer, tanChallenge: TanChallenge): EnterTanResult
|
||||
|
||||
/**
|
||||
* This method gets called for chipTan TAN generators when the bank asks the customer to synchronize her/his TAN generator.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package net.dankito.banking.ui
|
||||
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import net.dankito.banking.ui.model.parameters.TransferMoneyData
|
||||
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
|
||||
|
@ -14,7 +14,7 @@ interface IRouter {
|
|||
|
||||
fun showAddAccountDialog(presenter: BankingPresenter)
|
||||
|
||||
fun getTanFromUserFromNonUiThread(account: Account, tanChallenge: TanChallenge, presenter: BankingPresenter): EnterTanResult
|
||||
fun getTanFromUserFromNonUiThread(customer: Customer, tanChallenge: TanChallenge, presenter: BankingPresenter): EnterTanResult
|
||||
|
||||
fun getAtcFromUserFromNonUiThread(tanMedium: TanGeneratorTanMedium): EnterTanGeneratorAtcResult
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.util.*
|
|||
|
||||
@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
|
||||
open class BankAccount @JvmOverloads constructor(
|
||||
val account: Account,
|
||||
val customer: Customer,
|
||||
val identifier: String,
|
||||
var accountHolderName: String,
|
||||
var iban: String?,
|
||||
|
@ -27,7 +27,7 @@ open class BankAccount @JvmOverloads constructor(
|
|||
bookedAccountTransactions: List<AccountTransaction> = listOf()
|
||||
) {
|
||||
|
||||
internal constructor() : this(Account(), "", "", null, null, "") // for object deserializers
|
||||
internal constructor() : this(Customer(), "", "", null, null, "") // for object deserializers
|
||||
|
||||
|
||||
var id: String = UUID.randomUUID().toString()
|
||||
|
@ -47,7 +47,7 @@ open class BankAccount @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
val displayNameIncludingBankName: String
|
||||
get() = "${account.bank.name} ${displayName}"
|
||||
get() = "${customer.bank.name} ${displayName}"
|
||||
|
||||
|
||||
var bookedTransactions: List<AccountTransaction> = bookedAccountTransactions
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.util.*
|
|||
|
||||
|
||||
@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
|
||||
open class Account(
|
||||
open class Customer(
|
||||
val bank: Bank,
|
||||
val customerId: String,
|
||||
var password: String,
|
|
@ -6,7 +6,7 @@ import java.util.*
|
|||
open class MessageLogEntry(
|
||||
val message: String,
|
||||
val time: Date,
|
||||
val account: Account
|
||||
val customer: Customer
|
||||
) {
|
||||
|
||||
override fun toString(): String {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package net.dankito.banking.ui.model.responses
|
||||
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.AccountTransaction
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import java.math.BigDecimal
|
||||
|
@ -9,7 +9,7 @@ import java.math.BigDecimal
|
|||
open class AddAccountResponse(
|
||||
isSuccessful: Boolean,
|
||||
errorToShowToUser: String?,
|
||||
val account: Account,
|
||||
val customer: Customer,
|
||||
val supportsRetrievingTransactionsOfLast90DaysWithoutTan: Boolean = false,
|
||||
val bookedTransactionsOfLast90Days: Map<BankAccount, List<AccountTransaction>> = mapOf(),
|
||||
val unbookedTransactionsOfLast90Days: Map<BankAccount, List<Any>> = mapOf(),
|
||||
|
@ -20,7 +20,7 @@ open class AddAccountResponse(
|
|||
: BankingClientResponse(isSuccessful, errorToShowToUser, error, userCancelledAction) {
|
||||
|
||||
override fun toString(): String {
|
||||
return account.toString() + " " + super.toString()
|
||||
return customer.toString() + " " + super.toString()
|
||||
}
|
||||
|
||||
}
|
|
@ -66,7 +66,7 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
protected val clientsForAccounts = mutableMapOf<Account, IBankingClient>()
|
||||
protected val bankingClientsForAccounts = mutableMapOf<Customer, IBankingClient>()
|
||||
|
||||
protected var selectedBankAccountsField = mutableListOf<BankAccount>()
|
||||
|
||||
|
@ -75,7 +75,7 @@ open class BankingPresenter(
|
|||
protected var saveAccountOnNextEnterTanInvocation = false
|
||||
|
||||
|
||||
protected val accountsChangedListeners = mutableListOf<(List<Account>) -> Unit>()
|
||||
protected val accountsChangedListeners = mutableListOf<(List<Customer>) -> Unit>()
|
||||
|
||||
protected val retrievedAccountTransactionsResponseListeners = mutableListOf<(GetTransactionsResponse) -> Unit>()
|
||||
|
||||
|
@ -84,13 +84,13 @@ open class BankingPresenter(
|
|||
|
||||
protected val callback: BankingClientCallback = object : BankingClientCallback {
|
||||
|
||||
override fun enterTan(account: Account, tanChallenge: TanChallenge): EnterTanResult {
|
||||
override fun enterTan(customer: Customer, tanChallenge: TanChallenge): EnterTanResult {
|
||||
if (saveAccountOnNextEnterTanInvocation) {
|
||||
persistAccount(account)
|
||||
persistAccount(customer)
|
||||
saveAccountOnNextEnterTanInvocation = false
|
||||
}
|
||||
|
||||
val result = router.getTanFromUserFromNonUiThread(account, tanChallenge, this@BankingPresenter)
|
||||
val result = router.getTanFromUserFromNonUiThread(customer, tanChallenge, this@BankingPresenter)
|
||||
|
||||
if (result.changeTanProcedureTo != null || result.changeTanMediumTo != null) { // then either selected TAN medium or procedure will change -> save account on next call to enterTan() as then changes will be visible
|
||||
saveAccountOnNextEnterTanInvocation = true
|
||||
|
@ -125,21 +125,21 @@ open class BankingPresenter(
|
|||
try {
|
||||
val deserializedAccounts = persister.readPersistedAccounts()
|
||||
|
||||
deserializedAccounts.forEach { account ->
|
||||
val bank = account.bank
|
||||
deserializedAccounts.forEach { customer ->
|
||||
val bank = customer.bank
|
||||
val bankInfo = BankInfo(bank.name, bank.bankCode, bank.bic, "", "", "", bank.finTsServerAddress, "FinTS V3.0", null)
|
||||
|
||||
val newClient = bankingClientCreator.createClient(bankInfo, account.customerId, account.password,
|
||||
val newClient = bankingClientCreator.createClient(bankInfo, customer.customerId, customer.password,
|
||||
dataFolder, threadPool, callback)
|
||||
|
||||
try {
|
||||
newClient.restoreData()
|
||||
} catch (e: Exception) {
|
||||
log.error("Could not deserialize account data of $account", e)
|
||||
log.error("Could not deserialize customer data of $customer", e)
|
||||
// TODO: show error message to user
|
||||
}
|
||||
|
||||
addClientForAccount(account, newClient)
|
||||
addClientForAccount(customer, newClient)
|
||||
}
|
||||
|
||||
callAccountsChangedListeners()
|
||||
|
@ -150,8 +150,8 @@ open class BankingPresenter(
|
|||
}
|
||||
}
|
||||
|
||||
protected open fun addClientForAccount(account: Account, client: IBankingClient) {
|
||||
clientsForAccounts.put(account, client)
|
||||
protected open fun addClientForAccount(customer: Customer, client: IBankingClient) {
|
||||
bankingClientsForAccounts.put(customer, client)
|
||||
}
|
||||
|
||||
|
||||
|
@ -163,7 +163,7 @@ open class BankingPresenter(
|
|||
val startDate = Date()
|
||||
|
||||
newClient.addAccountAsync { response ->
|
||||
val account = response.account
|
||||
val account = response.customer
|
||||
|
||||
if (response.isSuccessful) {
|
||||
addClientForAccount(account, newClient)
|
||||
|
@ -191,14 +191,14 @@ open class BankingPresenter(
|
|||
}
|
||||
}
|
||||
|
||||
protected open fun findIconForBankAsync(account: Account) {
|
||||
protected open fun findIconForBankAsync(customer: Customer) {
|
||||
threadPool.runAsync {
|
||||
findIconForBank(account)
|
||||
findIconForBank(customer)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun findIconForBank(account: Account) {
|
||||
val bank = account.bank
|
||||
protected open fun findIconForBank(customer: Customer) {
|
||||
val bank = customer.bank
|
||||
|
||||
try {
|
||||
bankIconFinder.findIconForBank(bank.name)?.let { bankIconUrl ->
|
||||
|
@ -206,7 +206,7 @@ open class BankingPresenter(
|
|||
|
||||
bank.iconUrl = "file://" + bankIconFile.absolutePath // without 'file://' Android will not find it
|
||||
|
||||
persistAccount(account)
|
||||
persistAccount(customer)
|
||||
|
||||
callAccountsChangedListeners()
|
||||
}
|
||||
|
@ -250,13 +250,13 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
open fun deleteAccount(account: Account) {
|
||||
val wasSelected = isSingleSelectedAccount(account) or // either account or one of its bank accounts is currently selected
|
||||
(account.bankAccounts.firstOrNull { isSingleSelectedBankAccount(it) } != null)
|
||||
open fun deleteAccount(customer: Customer) {
|
||||
val wasSelected = isSingleSelectedAccount(customer) or // either account or one of its bank accounts is currently selected
|
||||
(customer.bankAccounts.firstOrNull { isSingleSelectedBankAccount(it) } != null)
|
||||
|
||||
clientsForAccounts.remove(account)
|
||||
bankingClientsForAccounts.remove(customer)
|
||||
|
||||
persister.deleteAccount(account, accounts)
|
||||
persister.deleteAccount(customer, customers)
|
||||
|
||||
callAccountsChangedListeners()
|
||||
|
||||
|
@ -266,10 +266,10 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
open fun fetchAccountTransactionsAsync(account: Account,
|
||||
open fun fetchAccountTransactionsAsync(customer: Customer,
|
||||
callback: (GetTransactionsResponse) -> Unit) {
|
||||
|
||||
account.bankAccounts.forEach { bankAccount ->
|
||||
customer.bankAccounts.forEach { bankAccount ->
|
||||
if (bankAccount.supportsRetrievingAccountTransactions) {
|
||||
fetchAccountTransactionsAsync(bankAccount, callback) // TODO: use a synchronous version of fetchAccountTransactions() so that all bank accounts get handled serially
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ open class BankingPresenter(
|
|||
open fun fetchAccountTransactionsAsync(bankAccount: BankAccount, fromDate: Date?, abortIfTanIsRequired: Boolean = false,
|
||||
callback: (GetTransactionsResponse) -> Unit) {
|
||||
|
||||
getClientForAccount(bankAccount.account)?.let { client ->
|
||||
getBankingClientForAccount(bankAccount.customer)?.let { client ->
|
||||
val startDate = Date()
|
||||
|
||||
client.getTransactionsAsync(bankAccount, GetTransactionsParameter(true, fromDate, null, abortIfTanIsRequired, { receivedAccountsTransactionChunk(bankAccount, it) } )) { response ->
|
||||
|
@ -308,7 +308,7 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
protected open fun updateAccountsTransactionsAsync(abortIfTanIsRequired: Boolean = false, callback: (GetTransactionsResponse) -> Unit) {
|
||||
clientsForAccounts.keys.forEach { account ->
|
||||
bankingClientsForAccounts.keys.forEach { account ->
|
||||
account.bankAccounts.forEach { bankAccount ->
|
||||
if (bankAccount.supportsRetrievingAccountTransactions) {
|
||||
updateBankAccountTransactionsAsync(bankAccount, abortIfTanIsRequired, callback)
|
||||
|
@ -353,7 +353,7 @@ open class BankingPresenter(
|
|||
bankAccount.balance = it
|
||||
}
|
||||
|
||||
persistAccount(bankAccount.account) // only needed because of balance
|
||||
persistAccount(bankAccount.customer) // only needed because of balance
|
||||
persistAccountTransactions(bankAccount, response.bookedTransactions, response.unbookedTransactions)
|
||||
}
|
||||
|
||||
|
@ -362,8 +362,8 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
protected open fun persistAccount(account: Account) {
|
||||
persister.saveOrUpdateAccount(account, accounts)
|
||||
protected open fun persistAccount(customer: Customer) {
|
||||
persister.saveOrUpdateAccount(customer, customers)
|
||||
}
|
||||
|
||||
protected open fun persistAccountTransactions(bankAccount: BankAccount, bookedTransactions: List<AccountTransaction>, unbookedTransactions: List<Any>) {
|
||||
|
@ -374,7 +374,7 @@ open class BankingPresenter(
|
|||
|
||||
|
||||
open fun transferMoneyAsync(bankAccount: BankAccount, data: TransferMoneyData, callback: (BankingClientResponse) -> Unit) {
|
||||
getClientForAccount(bankAccount.account)?.let { client ->
|
||||
getBankingClientForAccount(bankAccount.customer)?.let { client ->
|
||||
client.transferMoneyAsync(data, bankAccount) { response ->
|
||||
if (response.isSuccessful) {
|
||||
updateBankAccountTransactionsAsync(bankAccount, true) { }
|
||||
|
@ -485,13 +485,13 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
open fun getMessageLogForAccounts(accounts: List<Account>): List<String> {
|
||||
val logEntries = accounts.flatMap {
|
||||
getClientForAccount(it)?.messageLogWithoutSensitiveData ?: listOf()
|
||||
open fun getMessageLogForAccounts(customers: List<Customer>): List<String> {
|
||||
val logEntries = customers.flatMap {
|
||||
getBankingClientForAccount(it)?.messageLogWithoutSensitiveData ?: listOf()
|
||||
}
|
||||
|
||||
return logEntries.map { entry ->
|
||||
MessageLogEntryDateFormat.format(entry.time) + " " + entry.account.bank.bankCode + " " + entry.message
|
||||
MessageLogEntryDateFormat.format(entry.time) + " " + entry.customer.bank.bankCode + " " + entry.message
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -509,8 +509,8 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
protected open fun getClientForAccount(account: Account): IBankingClient? {
|
||||
return clientsForAccounts.get(account)
|
||||
protected open fun getBankingClientForAccount(customer: Customer): IBankingClient? {
|
||||
return bankingClientsForAccounts.get(customer)
|
||||
}
|
||||
|
||||
|
||||
|
@ -527,9 +527,9 @@ open class BankingPresenter(
|
|||
open val areAllAccountSelected: Boolean
|
||||
get() = selectedAccountType == SelectedAccountType.AllAccounts
|
||||
|
||||
open fun isSingleSelectedAccount(account: Account): Boolean {
|
||||
open fun isSingleSelectedAccount(customer: Customer): Boolean {
|
||||
return selectedAccountType == SelectedAccountType.SingleAccount
|
||||
&& selectedBankAccountsField.map { it.account }.toSet().containsExactly(account)
|
||||
&& selectedBankAccountsField.map { it.customer }.toSet().containsExactly(customer)
|
||||
}
|
||||
|
||||
open fun isSingleSelectedBankAccount(bankAccount: BankAccount): Boolean {
|
||||
|
@ -543,10 +543,10 @@ open class BankingPresenter(
|
|||
setSelectedBankAccounts(bankAccounts)
|
||||
}
|
||||
|
||||
open fun selectedAccount(account: Account) {
|
||||
open fun selectedAccount(customer: Customer) {
|
||||
selectedAccountType = SelectedAccountType.SingleAccount
|
||||
|
||||
setSelectedBankAccounts(account.bankAccounts)
|
||||
setSelectedBankAccounts(customer.bankAccounts)
|
||||
}
|
||||
|
||||
open fun selectedBankAccount(bankAccount: BankAccount) {
|
||||
|
@ -562,17 +562,17 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
open val accounts: List<Account>
|
||||
get() = clientsForAccounts.keys.toList()
|
||||
open val customers: List<Customer>
|
||||
get() = bankingClientsForAccounts.keys.toList()
|
||||
|
||||
open val bankAccounts: List<BankAccount>
|
||||
get() = accounts.flatMap { it.bankAccounts }
|
||||
get() = customers.flatMap { it.bankAccounts }
|
||||
|
||||
open val allTransactions: List<AccountTransaction>
|
||||
get() = getAccountTransactionsForBankAccounts(bankAccounts)
|
||||
|
||||
open val balanceOfAllAccounts: BigDecimal
|
||||
get() = getBalanceForAccounts(accounts)
|
||||
get() = getBalanceForAccounts(customers)
|
||||
|
||||
|
||||
open val bankAccountsSupportingRetrievingAccountTransactions: List<BankAccount>
|
||||
|
@ -621,8 +621,8 @@ open class BankingPresenter(
|
|||
return bankAccounts.flatMap { it.bookedTransactions }.sortedByDescending { it.valueDate } // TODO: someday add unbooked transactions
|
||||
}
|
||||
|
||||
protected open fun getBalanceForAccounts(accounts: Collection<Account>): BigDecimal {
|
||||
return accounts.map { it.balance }.fold(BigDecimal.ZERO) { acc, e -> acc + e }
|
||||
protected open fun getBalanceForAccounts(customers: Collection<Customer>): BigDecimal {
|
||||
return customers.map { it.balance }.fold(BigDecimal.ZERO) { acc, e -> acc + e }
|
||||
}
|
||||
|
||||
protected open fun sumBalance(singleBalances: Collection<BigDecimal>): BigDecimal {
|
||||
|
@ -660,16 +660,16 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
open fun addAccountsChangedListener(listener: (List<Account>) -> Unit): Boolean {
|
||||
open fun addAccountsChangedListener(listener: (List<Customer>) -> Unit): Boolean {
|
||||
return accountsChangedListeners.add(listener)
|
||||
}
|
||||
|
||||
open fun removeAccountsChangedListener(listener: (List<Account>) -> Unit): Boolean {
|
||||
open fun removeAccountsChangedListener(listener: (List<Customer>) -> Unit): Boolean {
|
||||
return accountsChangedListeners.add(listener)
|
||||
}
|
||||
|
||||
protected open fun callAccountsChangedListeners() {
|
||||
val accounts = this.accounts
|
||||
val accounts = this.customers
|
||||
|
||||
ArrayList(accountsChangedListeners).forEach {
|
||||
it(accounts) // TODO: use RxJava for this
|
||||
|
|
|
@ -6,7 +6,7 @@ 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.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import net.dankito.banking.ui.model.MessageLogEntry
|
||||
import net.dankito.banking.ui.model.parameters.GetTransactionsParameter
|
||||
|
@ -61,12 +61,12 @@ open class fints4kBankingClient(
|
|||
|
||||
protected val bank = bankDataMapper.mapFromBankInfo(bankInfo)
|
||||
|
||||
protected val customer = CustomerData(customerId, pin)
|
||||
protected val fints4kCustomer = CustomerData(customerId, pin)
|
||||
|
||||
protected var account: Account = mapper.mapAccount(customer, bank) // temporary save temp account, we update with data from server response like BankAccounts later
|
||||
protected var customer: Customer = mapper.mapCustomer(fints4kCustomer, bank) // temporary save temp customer, we update with data from server response like BankAccounts later
|
||||
|
||||
|
||||
protected val client = FinTsClientForCustomer(bank, customer, object : FinTsClientCallback {
|
||||
protected val client = FinTsClientForCustomer(bank, fints4kCustomer, object : FinTsClientCallback {
|
||||
|
||||
override fun askUserForTanProcedure(supportedTanProcedures: List<TanProcedure>, suggestedTanProcedure: TanProcedure?): TanProcedure? {
|
||||
// we simply return suggestedTanProcedure as even so it's not user's preferred TAN procedure she still can select it in EnterTanDialog
|
||||
|
@ -74,15 +74,15 @@ open class fints4kBankingClient(
|
|||
}
|
||||
|
||||
override fun enterTan(customer: CustomerData, tanChallenge: TanChallenge): EnterTanResult {
|
||||
mapper.updateTanMediaAndProcedures(account, customer)
|
||||
mapper.updateTanMediaAndProcedures(this@fints4kBankingClient.customer, customer)
|
||||
|
||||
val result = callback.enterTan(account, mapper.mapTanChallenge(tanChallenge))
|
||||
val result = callback.enterTan(this@fints4kBankingClient.customer, mapper.mapTanChallenge(tanChallenge))
|
||||
|
||||
return mapper.mapEnterTanResult(result, customer)
|
||||
}
|
||||
|
||||
override fun enterTanGeneratorAtc(customer: CustomerData, tanMedium: TanGeneratorTanMedium): EnterTanGeneratorAtcResult {
|
||||
mapper.updateTanMediaAndProcedures(account, customer)
|
||||
mapper.updateTanMediaAndProcedures(this@fints4kBankingClient.customer, customer)
|
||||
|
||||
val result = callback.enterTanGeneratorAtc(mapper.mapTanMedium(tanMedium))
|
||||
|
||||
|
@ -93,13 +93,13 @@ open class fints4kBankingClient(
|
|||
|
||||
|
||||
override val messageLogWithoutSensitiveData: List<MessageLogEntry>
|
||||
get() = client.messageLogWithoutSensitiveData.map { MessageLogEntry(it.message, it.time.toDate(), account) }
|
||||
get() = client.messageLogWithoutSensitiveData.map { MessageLogEntry(it.message, it.time.toDate(), customer) }
|
||||
|
||||
|
||||
override fun addAccountAsync(callback: (AddAccountResponse) -> Unit) {
|
||||
client.addAccountAsync { response ->
|
||||
this.account = mapper.mapAccount(customer, bank)
|
||||
val mappedResponse = mapper.mapResponse(account, response)
|
||||
this.customer = mapper.mapCustomer(fints4kCustomer, bank)
|
||||
val mappedResponse = mapper.mapResponse(customer, response)
|
||||
|
||||
saveData()
|
||||
|
||||
|
@ -108,7 +108,7 @@ open class fints4kBankingClient(
|
|||
}
|
||||
|
||||
override fun getTransactionsAsync(bankAccount: BankAccount, parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
|
||||
val account = mapper.findAccountForBankAccount(customer, bankAccount)
|
||||
val account = mapper.findAccountForBankAccount(fints4kCustomer, bankAccount)
|
||||
|
||||
if (account == null) { // TODO: in this case retrieve data from bank, all data should be re-creatable
|
||||
callback(GetTransactionsResponse(bankAccount, false, "Cannot find account for ${bankAccount.identifier}")) // TODO: translate
|
||||
|
@ -127,7 +127,7 @@ open class fints4kBankingClient(
|
|||
}
|
||||
|
||||
override fun transferMoneyAsync(data: TransferMoneyData, bankAccount: BankAccount, callback: (BankingClientResponse) -> Unit) {
|
||||
val account = mapper.findAccountForBankAccount(customer, bankAccount)
|
||||
val account = mapper.findAccountForBankAccount(fints4kCustomer, bankAccount)
|
||||
|
||||
if (account == null) {
|
||||
callback(BankingClientResponse(false, "Cannot find account for ${bankAccount.identifier}")) // TODO: translate
|
||||
|
@ -148,9 +148,9 @@ open class fints4kBankingClient(
|
|||
val deserializedCustomer = serializer.deserializeObject(getFints4kClientDataFile(), CustomerData::class.java)
|
||||
|
||||
deserializedCustomer?.let {
|
||||
mapper.updateCustomer(customer, deserializedCustomer)
|
||||
mapper.updateCustomer(fints4kCustomer, deserializedCustomer)
|
||||
|
||||
account = mapper.mapAccount(customer, bank)
|
||||
customer = mapper.mapCustomer(fints4kCustomer, bank)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,14 +160,14 @@ open class fints4kBankingClient(
|
|||
|
||||
clientDataFile.parentFile.mkdirs()
|
||||
|
||||
serializer.serializeObject(customer, clientDataFile)
|
||||
serializer.serializeObject(fints4kCustomer, clientDataFile)
|
||||
} catch (e: Exception) {
|
||||
log.error("Could not save customer data for $customer", e)
|
||||
log.error("Could not save customer data for $fints4kCustomer", e)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun getFints4kClientDataFile(): File {
|
||||
return File(File(dataFolder, "fints4k-client"), "${bank.bankCode}_${customer.customerId}_$fints4kClientDataFilename")
|
||||
return File(File(dataFolder, "fints4k-client"), "${bank.bankCode}_${fints4kCustomer.customerId}_$fints4kClientDataFilename")
|
||||
}
|
||||
|
||||
}
|
|
@ -29,21 +29,21 @@ open class fints4kModelMapper {
|
|||
return BankingClientResponse(response.isSuccessful, mapErrorToShowToUser(response), response.exception, response.userCancelledAction)
|
||||
}
|
||||
|
||||
open fun mapResponse(account: Account, response: net.dankito.banking.fints.response.client.AddAccountResponse): AddAccountResponse {
|
||||
val balances = response.balances.mapKeys { findMatchingBankAccount(account, it.key) }.filter { it.key != null }
|
||||
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>
|
||||
|
||||
val bookedTransactions = response.bookedTransactions.associateBy { it.account }
|
||||
val mappedBookedTransactions = mutableMapOf<BankAccount, List<AccountTransaction>>()
|
||||
|
||||
bookedTransactions.keys.forEach { accountData ->
|
||||
findMatchingBankAccount(account, accountData)?.let { bankAccount ->
|
||||
findMatchingBankAccount(customer, accountData)?.let { bankAccount ->
|
||||
mappedBookedTransactions.put(bankAccount, mapTransactions(bankAccount, response.bookedTransactions))
|
||||
}
|
||||
}
|
||||
|
||||
return AddAccountResponse(response.isSuccessful, mapErrorToShowToUser(response),
|
||||
account, response.supportsRetrievingTransactionsOfLast90DaysWithoutTan,
|
||||
customer, response.supportsRetrievingTransactionsOfLast90DaysWithoutTan,
|
||||
mappedBookedTransactions,
|
||||
mapOf(), // TODO: map unbooked transactions
|
||||
balances,
|
||||
|
@ -71,16 +71,16 @@ open class fints4kModelMapper {
|
|||
return Bank(bank.name, bank.bankCode, bank.bic, bank.finTs3ServerAddress)
|
||||
}
|
||||
|
||||
open fun mapAccount(customer: CustomerData, bank: BankData): Account {
|
||||
open fun mapCustomer(customer: CustomerData, bank: BankData): Customer {
|
||||
val mappedBank = mapBank(bank)
|
||||
|
||||
val account = Account(mappedBank, customer.customerId, customer.pin, customer.name, customer.userId)
|
||||
val mappedCustomer = Customer(mappedBank, customer.customerId, customer.pin, customer.name, customer.userId)
|
||||
|
||||
account.bankAccounts = mapBankAccounts(account, customer.accounts)
|
||||
mappedCustomer.bankAccounts = mapBankAccounts(mappedCustomer, customer.accounts)
|
||||
|
||||
updateTanMediaAndProcedures(account, customer)
|
||||
updateTanMediaAndProcedures(mappedCustomer, customer)
|
||||
|
||||
return account
|
||||
return mappedCustomer
|
||||
}
|
||||
|
||||
// TODO: move to a fints4k internal mapper
|
||||
|
@ -101,12 +101,12 @@ open class fints4kModelMapper {
|
|||
}
|
||||
|
||||
|
||||
open fun mapBankAccounts(account: Account, accountData: List<AccountData>): List<BankAccount> {
|
||||
return accountData.map { mapBankAccount(account, it) }
|
||||
open fun mapBankAccounts(customer: Customer, accountData: List<AccountData>): List<BankAccount> {
|
||||
return accountData.map { mapBankAccount(customer, it) }
|
||||
}
|
||||
|
||||
open fun mapBankAccount(account: Account, accountData: AccountData): BankAccount {
|
||||
return BankAccount(account, accountData.accountIdentifier, accountData.accountHolderName, accountData.iban,
|
||||
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",
|
||||
mapBankAccountType(accountData.accountType), accountData.productName, accountData.accountLimit,
|
||||
null, accountData.supportsFeature(AccountFeature.RetrieveAccountTransactions),
|
||||
|
@ -165,8 +165,8 @@ open class fints4kModelMapper {
|
|||
return customer.accounts.firstOrNull { bankAccount.identifier == it.accountIdentifier }
|
||||
}
|
||||
|
||||
open fun findMatchingBankAccount(account: Account, accountData: AccountData): BankAccount? {
|
||||
return account.bankAccounts.firstOrNull { it.identifier == accountData.accountIdentifier }
|
||||
open fun findMatchingBankAccount(customer: Customer, accountData: AccountData): BankAccount? {
|
||||
return customer.bankAccounts.firstOrNull { it.identifier == accountData.accountIdentifier }
|
||||
}
|
||||
|
||||
open fun findMatchingBankAccount(accounts: List<AccountData>, accountData: AccountData): AccountData? {
|
||||
|
@ -221,7 +221,7 @@ open class fints4kModelMapper {
|
|||
}
|
||||
|
||||
|
||||
open fun updateTanMediaAndProcedures(account: Account, customer: CustomerData) {
|
||||
open fun updateTanMediaAndProcedures(account: Customer, customer: CustomerData) {
|
||||
account.supportedTanProcedures = mapTanProcedures(customer.supportedTanProcedures)
|
||||
|
||||
if (customer.isTanProcedureSelected) {
|
||||
|
@ -262,8 +262,8 @@ open class fints4kModelMapper {
|
|||
}
|
||||
}
|
||||
|
||||
protected open fun findMappedTanProcedure(account: Account, tanProcedure: net.dankito.banking.fints.model.TanProcedure): TanProcedure? {
|
||||
return account.supportedTanProcedures.firstOrNull { it.bankInternalProcedureCode == tanProcedure.securityFunction.code }
|
||||
protected open fun findMappedTanProcedure(customer: Customer, tanProcedure: net.dankito.banking.fints.model.TanProcedure): TanProcedure? {
|
||||
return customer.supportedTanProcedures.firstOrNull { it.bankInternalProcedureCode == tanProcedure.securityFunction.code }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package net.dankito.banking
|
|||
|
||||
import net.dankito.banking.model.AccountCredentials
|
||||
import net.dankito.banking.ui.BankingClientCallback
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.tan.FlickerCodeTanChallenge
|
||||
import net.dankito.banking.ui.model.tan.ImageTanChallenge
|
||||
import net.dankito.banking.ui.model.tan.TanChallenge
|
||||
|
@ -24,7 +24,7 @@ import java.util.*
|
|||
*/
|
||||
open class HbciCallback(
|
||||
protected val credentials: AccountCredentials,
|
||||
protected val account: Account,
|
||||
protected val customer: Customer,
|
||||
protected val mapper: hbci4jModelMapper,
|
||||
protected val callback: BankingClientCallback
|
||||
) : AbstractHBCICallback() {
|
||||
|
@ -85,13 +85,13 @@ open class HbciCallback(
|
|||
|
||||
// ADDED: Auswaehlen welches PinTan Verfahren verwendet werden soll
|
||||
HBCICallback.NEED_PT_SECMECH -> selectTanProcedure(retData.toString())?.let { selectedTanProcedure ->
|
||||
account.selectedTanProcedure = selectedTanProcedure
|
||||
customer.selectedTanProcedure = selectedTanProcedure
|
||||
retData.replace(0, retData.length, selectedTanProcedure.bankInternalProcedureCode)
|
||||
}
|
||||
|
||||
// chipTan or simple TAN request (iTAN, smsTAN, ...)
|
||||
HBCICallback.NEED_PT_TAN -> {
|
||||
getTanFromUser(account, msg, retData.toString())?.let { enteredTan ->
|
||||
getTanFromUser(customer, msg, retData.toString())?.let { enteredTan ->
|
||||
retData.replace(0, retData.length, enteredTan)
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ open class HbciCallback(
|
|||
HBCICallback.NEED_PT_QRTAN -> { // use class QRCode to display QR code
|
||||
val qrData = retData.toString()
|
||||
val qrCode = QRCode(qrData, msg)
|
||||
val enterTanResult = callback.enterTan(account, ImageTanChallenge(TanImage(qrCode.mimetype, qrCode.image), msg, account.selectedTanProcedure!!))
|
||||
val enterTanResult = callback.enterTan(customer, ImageTanChallenge(TanImage(qrCode.mimetype, qrCode.image), msg, customer.selectedTanProcedure!!))
|
||||
enterTanResult.enteredTan?.let { enteredTan ->
|
||||
retData.replace(0, retData.length, enteredTan)
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ open class HbciCallback(
|
|||
// photoTan
|
||||
HBCICallback.NEED_PT_PHOTOTAN -> { // use class MatrixCode to display photo
|
||||
val matrixCode = MatrixCode(retData.toString())
|
||||
val enterTanResult = callback.enterTan(account, ImageTanChallenge(TanImage(matrixCode.mimetype, matrixCode.image), msg, account.selectedTanProcedure!!))
|
||||
val enterTanResult = callback.enterTan(customer, ImageTanChallenge(TanImage(matrixCode.mimetype, matrixCode.image), msg, customer.selectedTanProcedure!!))
|
||||
enterTanResult.enteredTan?.let { enteredTan ->
|
||||
retData.replace(0, retData.length, enteredTan)
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ open class HbciCallback(
|
|||
}
|
||||
|
||||
|
||||
open fun getTanFromUser(account: Account, messageToShowToUser: String, challengeHHD_UC: String): String? {
|
||||
open fun getTanFromUser(customer: Customer, messageToShowToUser: String, challengeHHD_UC: String): String? {
|
||||
// Wenn per "retData" Daten uebergeben wurden, dann enthalten diese
|
||||
// den fuer chipTAN optisch zu verwendenden Flickercode.
|
||||
// Falls nicht, ist es eine TAN-Abfrage, fuer die keine weiteren
|
||||
|
@ -184,14 +184,14 @@ open class HbciCallback(
|
|||
// werden.
|
||||
|
||||
val enterTanResult = if (challengeHHD_UC.isNullOrEmpty()) {
|
||||
callback.enterTan(account, TanChallenge(messageToShowToUser, account.selectedTanProcedure!!))
|
||||
callback.enterTan(customer, TanChallenge(messageToShowToUser, customer.selectedTanProcedure!!))
|
||||
}
|
||||
else {
|
||||
// for Sparkasse messageToShowToUser started with "chipTAN optisch\nTAN-Nummer\n\n"
|
||||
val usefulMessage = messageToShowToUser.split("\n").last().trim()
|
||||
|
||||
// val parsedDataSet = FlickerCode(challengeHHD_UC).render()
|
||||
callback.enterTan(account, FlickerCodeTanChallenge(net.dankito.banking.ui.model.tan.FlickerCode("", challengeHHD_UC), usefulMessage, account.selectedTanProcedure!!))
|
||||
callback.enterTan(customer, FlickerCodeTanChallenge(net.dankito.banking.ui.model.tan.FlickerCode("", challengeHHD_UC), usefulMessage, customer.selectedTanProcedure!!))
|
||||
}
|
||||
|
||||
return enterTanResult.enteredTan
|
||||
|
@ -202,7 +202,7 @@ open class HbciCallback(
|
|||
open fun selectTanProcedure(supportedTanProceduresString: String): net.dankito.banking.ui.model.tan.TanProcedure? {
|
||||
val supportedTanProcedures = mapper.mapTanProcedures(supportedTanProceduresString)
|
||||
|
||||
account.supportedTanProcedures = supportedTanProcedures
|
||||
customer.supportedTanProcedures = supportedTanProcedures
|
||||
|
||||
if (supportedTanProcedures.isNotEmpty()) {
|
||||
// select any procedure, user then can select her preferred one in EnterTanDialog; try not to select 'chipTAN manuell'
|
||||
|
|
|
@ -55,7 +55,7 @@ open class hbci4jBankingClient(
|
|||
|
||||
protected var bank = Bank(bankInfo.name, bankInfo.bankCode, bankInfo.bic, bankInfo.pinTanAddress ?: "")
|
||||
|
||||
protected var account = Account(bank, customerId, pin, "")
|
||||
protected var account = Customer(bank, customerId, pin, "")
|
||||
|
||||
|
||||
protected val mapper = hbci4jModelMapper()
|
||||
|
@ -93,13 +93,13 @@ open class hbci4jBankingClient(
|
|||
return AddAccountResponse(false, null, account, error = connection.error)
|
||||
}
|
||||
|
||||
protected open fun tryToRetrieveAccountTransactionsForAddedAccounts(account: Account): AddAccountResponse {
|
||||
protected open fun tryToRetrieveAccountTransactionsForAddedAccounts(customer: Customer): AddAccountResponse {
|
||||
val transactionsOfLast90DaysResponses = mutableListOf<GetTransactionsResponse>()
|
||||
val balances = mutableMapOf<BankAccount, BigDecimal>()
|
||||
val bookedTransactions = mutableMapOf<BankAccount, List<AccountTransaction>>()
|
||||
val unbookedTransactions = mutableMapOf<BankAccount, List<Any>>()
|
||||
|
||||
account.bankAccounts.forEach { bankAccount ->
|
||||
customer.bankAccounts.forEach { bankAccount ->
|
||||
if (bankAccount.supportsRetrievingAccountTransactions) {
|
||||
val response = getTransactionsOfLast90Days(bankAccount)
|
||||
transactionsOfLast90DaysResponses.add(response)
|
||||
|
@ -112,7 +112,7 @@ open class hbci4jBankingClient(
|
|||
|
||||
val supportsRetrievingTransactionsOfLast90DaysWithoutTan = transactionsOfLast90DaysResponses.firstOrNull { it.isSuccessful } != null
|
||||
|
||||
return AddAccountResponse(true, null, account, supportsRetrievingTransactionsOfLast90DaysWithoutTan,
|
||||
return AddAccountResponse(true, null, customer, supportsRetrievingTransactionsOfLast90DaysWithoutTan,
|
||||
bookedTransactions, unbookedTransactions, balances)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package net.dankito.banking.util
|
||||
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.Customer
|
||||
import net.dankito.banking.ui.model.Bank
|
||||
import net.dankito.banking.ui.model.BankAccount
|
||||
import net.dankito.banking.ui.model.BankAccountType
|
||||
|
@ -39,11 +39,11 @@ open class hbci4jModelMapper {
|
|||
}
|
||||
|
||||
|
||||
open fun mapBankAccounts(account: Account, bankAccounts: Array<out Konto>, passport: HBCIPassport): List<BankAccount> {
|
||||
open fun mapBankAccounts(customer: Customer, bankAccounts: Array<out Konto>, passport: HBCIPassport): List<BankAccount> {
|
||||
return bankAccounts.map { bankAccount ->
|
||||
val iban = if (bankAccount.iban.isNullOrBlank() == false) bankAccount.iban else passport.upd.getProperty("KInfo.iban") ?: ""
|
||||
|
||||
BankAccount(account, bankAccount.number,
|
||||
BankAccount(customer, bankAccount.number,
|
||||
if (bankAccount.name2.isNullOrBlank() == false) bankAccount.name + " " + bankAccount.name2 else bankAccount.name,
|
||||
iban, bankAccount.subnumber, bankAccount.customerid, BigDecimal.ZERO, bankAccount.curr, mapBankAccountType(bankAccount),
|
||||
null, bankAccount.limit?.value?.let { mapValue(it).toString() }, null,
|
||||
|
|
Loading…
Reference in New Issue