Added ddAccountDialog and started AccountsView
This commit is contained in:
parent
fb70a4176d
commit
d7bdd1ae51
|
@ -2,13 +2,12 @@ package net.dankito.banking.javafx.dialogs.mainwindow
|
||||||
|
|
||||||
import net.dankito.banking.fints4javaBankingClientCreator
|
import net.dankito.banking.fints4javaBankingClientCreator
|
||||||
import net.dankito.banking.ui.javafx.RouterJavaFx
|
import net.dankito.banking.ui.javafx.RouterJavaFx
|
||||||
|
import net.dankito.banking.ui.javafx.controls.AccountsView
|
||||||
import net.dankito.banking.ui.javafx.dialogs.mainwindow.controls.MainMenuBar
|
import net.dankito.banking.ui.javafx.dialogs.mainwindow.controls.MainMenuBar
|
||||||
import net.dankito.banking.ui.javafx.util.Base64ServiceJava8
|
import net.dankito.banking.ui.javafx.util.Base64ServiceJava8
|
||||||
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
||||||
|
import tornadofx.*
|
||||||
import tornadofx.FX.Companion.messages
|
import tornadofx.FX.Companion.messages
|
||||||
import tornadofx.View
|
|
||||||
import tornadofx.borderpane
|
|
||||||
import tornadofx.get
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow : View(messages["main.window.title"]) {
|
class MainWindow : View(messages["main.window.title"]) {
|
||||||
|
@ -16,12 +15,23 @@ class MainWindow : View(messages["main.window.title"]) {
|
||||||
private val presenter = MainWindowPresenter(fints4javaBankingClientCreator(), Base64ServiceJava8(), RouterJavaFx())
|
private val presenter = MainWindowPresenter(fints4javaBankingClientCreator(), Base64ServiceJava8(), RouterJavaFx())
|
||||||
|
|
||||||
|
|
||||||
|
private var accountsView = AccountsView(presenter)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
prefHeight = 620.0
|
prefHeight = 620.0
|
||||||
prefWidth = 1150.0
|
prefWidth = 1150.0
|
||||||
|
|
||||||
top = MainMenuBar().root
|
top = MainMenuBar().root
|
||||||
|
|
||||||
|
center {
|
||||||
|
splitpane {
|
||||||
|
setDividerPosition(0, 0.2)
|
||||||
|
|
||||||
|
add(accountsView)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,26 @@
|
||||||
main.window.title=Banking
|
main.window.title=Banking
|
||||||
|
|
||||||
main.window.menu.file=File
|
main.window.menu.file=File
|
||||||
main.window.menu.file.quit=Quit
|
main.window.menu.file.quit=Quit
|
||||||
|
|
||||||
|
|
||||||
|
ok=OK
|
||||||
|
cancel=Cancel
|
||||||
|
close=Close
|
||||||
|
|
||||||
|
accounts=Accounts
|
||||||
|
check=Check
|
||||||
|
|
||||||
|
|
||||||
|
accounts.view.context.menu.info=Info
|
||||||
|
|
||||||
|
|
||||||
|
add.account.dialog.title=Add account
|
||||||
|
add.account.dialog.bank.code.label=Bank code
|
||||||
|
add.account.dialog.customer.id.and.password.hint=Enter the same values here as in your online banking portal
|
||||||
|
add.account.dialog.customer.id=Customer Id (Account number)
|
||||||
|
add.account.dialog.customer.id.hint=The user name you use for logging in into online banking
|
||||||
|
add.account.dialog.password=Online banking password
|
||||||
|
add.account.dialog.password.hint=The password you use for logging in into online banking
|
||||||
|
add.account.dialog.could.not.add.account=Could not add account for bank code '%s' and customer id '%s': %s
|
||||||
|
add.account.dialog.add.account.success=Successfully added accounterror.message.could.not.retrieve.accounting.entries=Could not get entries for account '%s': %s
|
|
@ -1,4 +1,26 @@
|
||||||
main.window.title=Banking
|
main.window.title=Banking
|
||||||
|
|
||||||
main.window.menu.file=Datei
|
main.window.menu.file=Datei
|
||||||
main.window.menu.file.quit=Beenden
|
main.window.menu.file.quit=Beenden
|
||||||
|
|
||||||
|
|
||||||
|
ok=OK
|
||||||
|
cancel=Abbrechen
|
||||||
|
close=Schließen
|
||||||
|
|
||||||
|
accounts=Konten
|
||||||
|
check=Überprüfen
|
||||||
|
|
||||||
|
|
||||||
|
accounts.view.context.menu.info=Info
|
||||||
|
|
||||||
|
|
||||||
|
add.account.dialog.title=Konto hinzufügen
|
||||||
|
add.account.dialog.bank.code.label=Bankleitzahl
|
||||||
|
add.account.dialog.customer.id.and.password.hint=Geben Sie hier die selben Werte ein wie auf Ihrer Online Banking Webseite
|
||||||
|
add.account.dialog.customer.id=Kundennummer (Kontonummer)
|
||||||
|
add.account.dialog.customer.id.hint=Der Nutzernamen den Sie fürs Online Banking verwenden
|
||||||
|
add.account.dialog.password=Online Banking Passwort
|
||||||
|
add.account.dialog.password.hint=Das Passwort das Sie fürs Online Banking verwenden
|
||||||
|
add.account.dialog.could.not.add.account=Konnte Kontoinformation zu Bankleitzahl '%s' und Nutzername '%s' nicht finden: %s
|
||||||
|
add.account.dialog.add.account.success=Hinzufügen des Kontos war erfolgreich.
|
|
@ -1,18 +1,21 @@
|
||||||
package net.dankito.banking.ui.javafx
|
package net.dankito.banking.ui.javafx
|
||||||
|
|
||||||
import net.dankito.banking.ui.IRouter
|
import net.dankito.banking.ui.IRouter
|
||||||
|
import net.dankito.banking.ui.javafx.dialogs.AddAccountDialog
|
||||||
import net.dankito.banking.ui.model.Account
|
import net.dankito.banking.ui.model.Account
|
||||||
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
|
import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
|
||||||
import net.dankito.banking.ui.model.tan.EnterTanResult
|
import net.dankito.banking.ui.model.tan.EnterTanResult
|
||||||
import net.dankito.banking.ui.model.tan.TanChallenge
|
import net.dankito.banking.ui.model.tan.TanChallenge
|
||||||
import net.dankito.banking.ui.model.tan.TanGeneratorTanMedium
|
import net.dankito.banking.ui.model.tan.TanGeneratorTanMedium
|
||||||
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
||||||
|
import tornadofx.FX.Companion.messages
|
||||||
|
import tornadofx.get
|
||||||
|
|
||||||
|
|
||||||
open class RouterJavaFx : IRouter {
|
open class RouterJavaFx : IRouter {
|
||||||
|
|
||||||
override fun showAddAccountDialog(presenter: MainWindowPresenter) {
|
override fun showAddAccountDialog(presenter: MainWindowPresenter) {
|
||||||
|
AddAccountDialog(presenter).show(messages["add.account.dialog.title"])
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTanFromUserFromNonUiThread(account: Account, tanChallenge: TanChallenge, presenter: MainWindowPresenter): EnterTanResult {
|
override fun getTanFromUserFromNonUiThread(account: Account, tanChallenge: TanChallenge, presenter: MainWindowPresenter): EnterTanResult {
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package net.dankito.banking.ui.javafx.controls
|
||||||
|
|
||||||
|
import javafx.geometry.Pos
|
||||||
|
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
||||||
|
import net.dankito.utils.javafx.ui.extensions.fixedHeight
|
||||||
|
import net.dankito.utils.javafx.ui.extensions.fixedWidth
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
|
||||||
|
open class AccountsView(protected val presenter: MainWindowPresenter) : View() {
|
||||||
|
|
||||||
|
|
||||||
|
override val root = vbox {
|
||||||
|
borderpane {
|
||||||
|
fixedHeight = 36.0
|
||||||
|
|
||||||
|
left = label(messages["accounts"]) {
|
||||||
|
borderpaneConstraints {
|
||||||
|
alignment = Pos.CENTER_LEFT
|
||||||
|
marginLeft = 4.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
right = button("+") {
|
||||||
|
fixedHeight = 32.0
|
||||||
|
fixedWidth = 32.0
|
||||||
|
|
||||||
|
action { showAddAccountDialog() }
|
||||||
|
|
||||||
|
borderpaneConstraints {
|
||||||
|
alignment = Pos.CENTER_RIGHT
|
||||||
|
marginTopBottom(2.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showAddAccountDialog() {
|
||||||
|
presenter.showAddAccountDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,231 @@
|
||||||
|
package net.dankito.banking.ui.javafx.dialogs
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty
|
||||||
|
import javafx.beans.property.SimpleStringProperty
|
||||||
|
import javafx.geometry.Insets
|
||||||
|
import javafx.geometry.Pos
|
||||||
|
import javafx.scene.control.Tooltip
|
||||||
|
import javafx.scene.paint.Color
|
||||||
|
import javafx.scene.text.Font
|
||||||
|
import javafx.scene.text.FontWeight
|
||||||
|
import net.dankito.banking.ui.model.responses.AddAccountResponse
|
||||||
|
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
||||||
|
import net.dankito.fints.model.BankInfo
|
||||||
|
import net.dankito.utils.javafx.ui.controls.UpdateButton
|
||||||
|
import net.dankito.utils.javafx.ui.dialogs.Window
|
||||||
|
import net.dankito.utils.javafx.ui.extensions.ensureOnlyUsesSpaceIfVisible
|
||||||
|
import net.dankito.utils.javafx.ui.extensions.setBackgroundToColor
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
|
||||||
|
open class AddAccountDialog(protected val presenter: MainWindowPresenter) : Window() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LabelMargins = Insets(6.0, 4.0, 6.0, 4.0)
|
||||||
|
|
||||||
|
private val TextFieldHeight = 36.0
|
||||||
|
private val TextFieldMargins = Insets(0.0, 4.0, 12.0, 4.0)
|
||||||
|
|
||||||
|
private val ButtonHeight = 40.0
|
||||||
|
private val ButtonWidth = 150.0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val bankCode = SimpleStringProperty("")
|
||||||
|
|
||||||
|
protected var selectedBank: BankInfo? = null
|
||||||
|
|
||||||
|
private val customerId = SimpleStringProperty("")
|
||||||
|
|
||||||
|
private val password = SimpleStringProperty("")
|
||||||
|
|
||||||
|
private val requiredDataHasBeenEntered = SimpleBooleanProperty(false)
|
||||||
|
|
||||||
|
|
||||||
|
private val checkEnteredCredentialsResult = SimpleStringProperty("")
|
||||||
|
|
||||||
|
private val isEnteredCredentialsResultVisible = SimpleBooleanProperty(false)
|
||||||
|
|
||||||
|
private val didEnteredCredentialsMatch = SimpleBooleanProperty(false)
|
||||||
|
|
||||||
|
|
||||||
|
private val checkCredentialsButton = UpdateButton(messages["check"])
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
bankCode.addListener { _, _, newValue -> checkIsEnteredBankCodeValid(newValue) }
|
||||||
|
|
||||||
|
customerId.addListener { _, _, _ -> checkIfRequiredDataHasBeenEntered() }
|
||||||
|
|
||||||
|
password.addListener { _, _, _ -> checkIfRequiredDataHasBeenEntered() }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override val root = vbox {
|
||||||
|
prefWidth = 350.0
|
||||||
|
|
||||||
|
label(messages["add.account.dialog.bank.code.label"]) {
|
||||||
|
vboxConstraints {
|
||||||
|
margin = LabelMargins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textfield(bankCode) {
|
||||||
|
prefHeight = TextFieldHeight
|
||||||
|
|
||||||
|
vboxConstraints {
|
||||||
|
margin = TextFieldMargins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label(messages["add.account.dialog.customer.id.and.password.hint"]) {
|
||||||
|
font = Font.font(this.font.name, FontWeight.BOLD, this.font.size + 1)
|
||||||
|
|
||||||
|
isWrapText = true
|
||||||
|
|
||||||
|
vboxConstraints {
|
||||||
|
marginTop = 12.0
|
||||||
|
marginBottom = 6.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label(messages["add.account.dialog.customer.id"]) {
|
||||||
|
vboxConstraints {
|
||||||
|
margin = LabelMargins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textfield(customerId) {
|
||||||
|
promptText = messages["add.account.dialog.customer.id.hint"]
|
||||||
|
prefHeight = TextFieldHeight
|
||||||
|
|
||||||
|
vboxConstraints {
|
||||||
|
margin = TextFieldMargins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label(messages["add.account.dialog.password"]) {
|
||||||
|
vboxConstraints {
|
||||||
|
margin = LabelMargins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordfield(password) {
|
||||||
|
promptText = messages["add.account.dialog.password.hint"]
|
||||||
|
prefHeight = TextFieldHeight
|
||||||
|
|
||||||
|
vboxConstraints {
|
||||||
|
margin = TextFieldMargins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label(checkEnteredCredentialsResult) {
|
||||||
|
visibleWhen(isEnteredCredentialsResultVisible)
|
||||||
|
ensureOnlyUsesSpaceIfVisible()
|
||||||
|
|
||||||
|
isWrapText = true
|
||||||
|
font = Font(font.size + 1)
|
||||||
|
|
||||||
|
paddingAll = 8.0
|
||||||
|
|
||||||
|
checkEnteredCredentialsResult.addListener { _, _, _ ->
|
||||||
|
if (didEnteredCredentialsMatch.value) {
|
||||||
|
setBackgroundToColor(Color.TRANSPARENT)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setBackgroundToColor(Color.RED)
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip = Tooltip(checkEnteredCredentialsResult.value)
|
||||||
|
|
||||||
|
currentWindow?.sizeToScene()
|
||||||
|
}
|
||||||
|
|
||||||
|
vboxConstraints {
|
||||||
|
marginTop = 12.0
|
||||||
|
marginBottom = 6.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hbox {
|
||||||
|
alignment = Pos.CENTER_RIGHT
|
||||||
|
|
||||||
|
button(messages["cancel"]) {
|
||||||
|
prefHeight = ButtonHeight
|
||||||
|
prefWidth = ButtonWidth
|
||||||
|
|
||||||
|
isCancelButton = true
|
||||||
|
|
||||||
|
action { close() }
|
||||||
|
|
||||||
|
hboxConstraints {
|
||||||
|
margin = Insets(6.0, 0.0, 4.0, 0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add(checkCredentialsButton.apply {
|
||||||
|
prefHeight = ButtonHeight
|
||||||
|
prefWidth = ButtonWidth
|
||||||
|
|
||||||
|
isDefaultButton = true
|
||||||
|
|
||||||
|
enableWhen(requiredDataHasBeenEntered)
|
||||||
|
|
||||||
|
action { checkEnteredCredentials() }
|
||||||
|
|
||||||
|
hboxConstraints {
|
||||||
|
margin = Insets(6.0, 4.0, 4.0, 12.0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun checkIsEnteredBankCodeValid(enteredBankCode: String?) {
|
||||||
|
enteredBankCode?.let {
|
||||||
|
val banksSearchResult = presenter.searchBanksByNameBankCodeOrCity(enteredBankCode)
|
||||||
|
|
||||||
|
// TODO: show banksSearchResult in AutoCompleteListView
|
||||||
|
|
||||||
|
val uniqueBankCodes = banksSearchResult.map { it.bankCode }.toSet()
|
||||||
|
selectedBank = if (uniqueBankCodes.size == 1) banksSearchResult.first() else null
|
||||||
|
|
||||||
|
checkIfRequiredDataHasBeenEntered()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun checkIfRequiredDataHasBeenEntered() {
|
||||||
|
requiredDataHasBeenEntered.value = selectedBank != null
|
||||||
|
&& selectedBank?.supportsFinTs3_0 == true
|
||||||
|
&& customerId.value.isNotEmpty() // TODO: check if it is of length 10?
|
||||||
|
&& password.value.isNotEmpty() // TODO: check if it is of length 5?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun checkEnteredCredentials() {
|
||||||
|
selectedBank?.let {
|
||||||
|
presenter.addAccountAsync(it, customerId.value, password.value) { response ->
|
||||||
|
runLater { handleAddAccountResultOnUiThread(response) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun handleAddAccountResultOnUiThread(response: AddAccountResponse) {
|
||||||
|
isEnteredCredentialsResultVisible.value = true
|
||||||
|
didEnteredCredentialsMatch.value = response.isSuccessful
|
||||||
|
val account = response.account
|
||||||
|
|
||||||
|
// TODO: in case of success show alert to ask if account transactions should get retrieved?
|
||||||
|
|
||||||
|
val message = if (response.isSuccessful) messages["add.account.dialog.add.account.success"]
|
||||||
|
else String.format(messages["add.account.dialog.could.not.add.account"],
|
||||||
|
account.bank.bankCode, account.customerId, response.errorToShowToUser)
|
||||||
|
|
||||||
|
checkEnteredCredentialsResult.value = message
|
||||||
|
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue