Renamed Account to Customer

This commit is contained in:
dankito 2020-06-14 23:15:52 +02:00
parent 9a5e0a1098
commit b5cb401636
31 changed files with 194 additions and 194 deletions

View File

@ -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>) {

View File

@ -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")

View File

@ -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())
}

View File

@ -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()
}

View File

@ -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))

View File

@ -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) {

View File

@ -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()
}

View File

@ -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)
}

View File

@ -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

View File

@ -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()

View File

@ -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"])

View File

@ -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,

View File

@ -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()
}
}

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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) })
}
}

View File

@ -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>)

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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 {

View File

@ -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()
}
}

View File

@ -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

View File

@ -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")
}
}

View File

@ -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 }
}

View File

@ -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'

View File

@ -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)
}

View File

@ -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,