Implemented changing TAN procedure and TAN medium
This commit is contained in:
parent
ce58ef60ca
commit
b0ee9bb0d5
|
@ -28,6 +28,11 @@ add.account.dialog.successfully.added.account.bank.supports.retrieving.transacti
|
|||
|
||||
|
||||
enter.tan.dialog.title=TAN required
|
||||
enter.tan.dialog.select.tan.procedure=TAN procedure:
|
||||
enter.tan.dialog.select.tan.medium=TAN medium:
|
||||
enter.tan.dialog.size.label=Size:
|
||||
enter.tan.dialog.frequency.label=Speed:
|
||||
enter.tan.dialog.enter.tan.label=TAN:
|
||||
enter.tan.dialog.error.could.not.decode.tan.image=Could not decode flicker code or QR code / PhotoTan. Most likely an internal error:\n%s.
|
||||
enter.tan.dialog.tan.medium.successfully.changed=TAN medium successfully changed to \'%s\'.
|
||||
enter.tan.dialog.tan.error.changing.tan.medium=Could not change TAN medium to \'%s\':\n%s.
|
|
@ -28,6 +28,11 @@ add.account.dialog.successfully.added.account.bank.supports.retrieving.transacti
|
|||
|
||||
|
||||
enter.tan.dialog.title=TAN wird benötigt
|
||||
enter.tan.dialog.select.tan.procedure=TAN Verfahren:
|
||||
enter.tan.dialog.select.tan.medium=TAN Medium:
|
||||
enter.tan.dialog.size.label=Größe:
|
||||
enter.tan.dialog.frequency.label=Geschwindigkeit:
|
||||
enter.tan.dialog.enter.tan.label=TAN:
|
||||
enter.tan.dialog.error.could.not.decode.tan.image=Flickercode bzw. QR-Code / PhotoTan konnte nicht dekodiert werden. Höchst wahrscheinlich ein interner Fehler:\n%s.
|
||||
enter.tan.dialog.tan.medium.successfully.changed=TAN Medium erfolgreich geändert zu \'%s\'.
|
||||
enter.tan.dialog.tan.error.changing.tan.medium=TAN Medium konnte nicht geändert werden zu \'%s\':\n%s.
|
|
@ -21,40 +21,32 @@ import java.io.StringWriter
|
|||
|
||||
open class JavaFxDialogService {
|
||||
|
||||
open fun showInfoMessage(infoMessage: CharSequence, alertTitle: CharSequence?) {
|
||||
showInfoMessage(infoMessage, alertTitle, FX.primaryStage)
|
||||
}
|
||||
|
||||
open fun showInfoMessage(infoMessage: CharSequence, alertTitle: CharSequence?, owner: Stage?) {
|
||||
open fun showInfoMessage(infoMessage: CharSequence, alertTitle: CharSequence? = null, owner: Stage? = FX.primaryStage) {
|
||||
Platform.runLater { showInfoMessageOnUiThread(infoMessage, alertTitle, owner) }
|
||||
}
|
||||
|
||||
open fun showInfoMessageOnUiThread(infoMessage: CharSequence, alertTitle: CharSequence?, owner: Stage?) {
|
||||
val alert = createDialog(Alert.AlertType.INFORMATION, infoMessage, alertTitle, owner, ButtonType.OK)
|
||||
open fun showInfoMessageOnUiThread(infoMessage: CharSequence, alertTitle: CharSequence? = null, owner: Stage? = FX.primaryStage): ButtonType? {
|
||||
val dialog = createDialog(Alert.AlertType.INFORMATION, infoMessage, alertTitle, owner, ButtonType.OK)
|
||||
|
||||
alert.showAndWait()
|
||||
return showAndWaitForResult(dialog)
|
||||
}
|
||||
|
||||
|
||||
open fun showErrorMessage(errorMessage: CharSequence, alertTitle: CharSequence?, exception: Exception?) {
|
||||
showErrorMessage(errorMessage, alertTitle, exception, null)
|
||||
}
|
||||
|
||||
open fun showErrorMessage(errorMessage: CharSequence, alertTitle: CharSequence?, exception: Exception?, owner: Stage?) {
|
||||
open fun showErrorMessage(errorMessage: CharSequence, alertTitle: CharSequence? = null, exception: Exception? = null, owner: Stage? = FX.primaryStage) {
|
||||
Platform.runLater { showErrorMessageOnUiThread(errorMessage, alertTitle, exception, owner) }
|
||||
}
|
||||
|
||||
open fun showErrorMessageOnUiThread(errorMessage: CharSequence, alertTitle: CharSequence?, exception: Exception?, owner: Stage?) {
|
||||
val alert = createDialog(Alert.AlertType.ERROR, errorMessage, alertTitle, owner, ButtonType.OK)
|
||||
open fun showErrorMessageOnUiThread(errorMessage: CharSequence, alertTitle: CharSequence? = null, exception: Exception? = null, owner: Stage? = FX.primaryStage): ButtonType? {
|
||||
val dialog = createDialog(Alert.AlertType.ERROR, errorMessage, alertTitle, owner, ButtonType.OK)
|
||||
|
||||
if (exception != null) {
|
||||
createExpandableException(alert, exception)
|
||||
createExpandableException(dialog, exception)
|
||||
}
|
||||
|
||||
alert.showAndWait()
|
||||
return showAndWaitForResult(dialog)
|
||||
}
|
||||
|
||||
protected open fun createExpandableException(alert: Alert, exception: Exception) {
|
||||
protected open fun createExpandableException(dialog: Alert, exception: Exception) {
|
||||
val sw = StringWriter()
|
||||
val pw = PrintWriter(sw)
|
||||
exception.printStackTrace(pw)
|
||||
|
@ -77,13 +69,17 @@ open class JavaFxDialogService {
|
|||
expContent.add(textArea, 0, 1)
|
||||
|
||||
// Set expandable Exception into the dialog pane.
|
||||
alert.dialogPane.expandableContent = expContent
|
||||
dialog.dialogPane.expandableContent = expContent
|
||||
}
|
||||
|
||||
|
||||
open fun showDialog(alertType: Alert.AlertType, message: CharSequence, alertTitle: CharSequence? = null, owner: Stage? = FX.primaryStage, vararg buttons: ButtonType): ButtonType? {
|
||||
val dialog = createDialog(alertType, message, alertTitle, owner, *buttons)
|
||||
|
||||
return showAndWaitForResult(dialog)
|
||||
}
|
||||
|
||||
protected open fun showAndWaitForResult(dialog: Alert): ButtonType? {
|
||||
val result = dialog.showAndWait()
|
||||
|
||||
return result.map { it }.orElse(null)
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package net.dankito.banking.ui.javafx.dialogs.tan
|
||||
|
||||
import javafx.beans.property.SimpleObjectProperty
|
||||
import javafx.beans.property.SimpleStringProperty
|
||||
import javafx.geometry.Insets
|
||||
import javafx.geometry.Pos
|
||||
import net.dankito.banking.javafx.dialogs.tan.controls.ChipTanFlickerCodeView
|
||||
import net.dankito.banking.ui.javafx.dialogs.JavaFxDialogService
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.tan.EnterTanResult
|
||||
import net.dankito.banking.ui.model.tan.FlickerCodeTanChallenge
|
||||
import net.dankito.banking.ui.model.tan.TanChallenge
|
||||
import net.dankito.banking.ui.model.responses.BankingClientResponse
|
||||
import net.dankito.banking.ui.model.tan.*
|
||||
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
||||
import net.dankito.utils.javafx.ui.dialogs.Window
|
||||
import tornadofx.*
|
||||
|
@ -26,22 +27,74 @@ open class EnterTanDialog(
|
|||
}
|
||||
|
||||
|
||||
protected val dialogService = JavaFxDialogService()
|
||||
|
||||
|
||||
protected val selectedTanProcedure = SimpleObjectProperty<TanProcedure>(account.selectedTanProcedure ?: account.supportedTanProcedures.firstOrNull())
|
||||
|
||||
protected val selectedTanMedium = SimpleObjectProperty<TanMedium>(account.tanMediaSorted.firstOrNull())
|
||||
|
||||
protected val enteredTan = SimpleStringProperty("")
|
||||
|
||||
|
||||
init {
|
||||
selectedTanProcedure.addListener { _, _, newValue ->
|
||||
tanEnteredCallback(EnterTanResult.userAsksToChangeTanProcedure(newValue))
|
||||
|
||||
close()
|
||||
}
|
||||
|
||||
selectedTanMedium.addListener { _, _, newValue ->
|
||||
if (newValue.status != TanMediumStatus.Used) {
|
||||
tanEnteredCallback(EnterTanResult.userAsksToChangeTanMedium(newValue) { response ->
|
||||
runLater { handleChangeTanMediumResponseOnUiThread(newValue, response) }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override val root = vbox {
|
||||
paddingAll = 4.0
|
||||
|
||||
(challenge as? FlickerCodeTanChallenge)?.let { flickerCodeTanChallenge ->
|
||||
hbox {
|
||||
alignment = Pos.CENTER
|
||||
|
||||
vboxConstraints {
|
||||
marginLeftRight(30.0)
|
||||
marginBottom = 12.0
|
||||
form {
|
||||
fieldset {
|
||||
field(messages["enter.tan.dialog.select.tan.procedure"]) {
|
||||
combobox(selectedTanProcedure, account.supportedTanProcedures) {
|
||||
cellFormat {
|
||||
text = it.displayName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add(ChipTanFlickerCodeView(flickerCodeTanChallenge.flickerCode))
|
||||
if (account.tanMediaSorted.isNotEmpty()) {
|
||||
field(messages["enter.tan.dialog.select.tan.medium"]) {
|
||||
combobox(selectedTanMedium, account.tanMediaSorted) {
|
||||
cellFormat {
|
||||
text = it.displayName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(challenge as? FlickerCodeTanChallenge)?.let { flickerCodeTanChallenge ->
|
||||
val flickerCode = flickerCodeTanChallenge.flickerCode
|
||||
if (flickerCode.decodingSuccessful) {
|
||||
hbox {
|
||||
alignment = Pos.CENTER
|
||||
|
||||
vboxConstraints {
|
||||
marginLeftRight(30.0)
|
||||
marginBottom = 12.0
|
||||
}
|
||||
|
||||
add(ChipTanFlickerCodeView(flickerCode))
|
||||
}
|
||||
}
|
||||
else {
|
||||
showDecodingTanChallengeFailedError(flickerCode.decodingError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +163,26 @@ open class EnterTanDialog(
|
|||
}
|
||||
|
||||
|
||||
private fun finishedEnteringTan() {
|
||||
protected open fun showDecodingTanChallengeFailedError(error: Exception?) {
|
||||
dialogService.showErrorMessage(String.format(messages["enter.tan.dialog.error.could.not.decode.tan.image"], error?.localizedMessage),
|
||||
null, error, currentStage)
|
||||
}
|
||||
|
||||
protected open fun handleChangeTanMediumResponseOnUiThread(newUsedTanMedium: TanMedium, response: BankingClientResponse) {
|
||||
if (response.isSuccessful) {
|
||||
dialogService.showInfoMessageOnUiThread(String.format(messages["enter.tan.dialog.tan.medium.successfully.changed"],
|
||||
newUsedTanMedium.displayName), null, currentStage)
|
||||
|
||||
close()
|
||||
}
|
||||
else {
|
||||
dialogService.showErrorMessageOnUiThread(String.format(messages["enter.tan.dialog.tan.error.changing.tan.medium"],
|
||||
newUsedTanMedium.displayName, response.errorToShowToUser), null, response.error, currentStage)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected open fun finishedEnteringTan() {
|
||||
if (enteredTan.value.isNullOrEmpty()) {
|
||||
cancelledEnteringTan()
|
||||
}
|
||||
|
@ -121,7 +193,7 @@ open class EnterTanDialog(
|
|||
}
|
||||
}
|
||||
|
||||
private fun cancelledEnteringTan() {
|
||||
protected open fun cancelledEnteringTan() {
|
||||
tanEnteredCallback(EnterTanResult.userDidNotEnterTan())
|
||||
|
||||
close()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.dankito.banking.ui.model
|
||||
|
||||
import net.dankito.banking.ui.model.tan.TanMedium
|
||||
import net.dankito.banking.ui.model.tan.TanMediumStatus
|
||||
import net.dankito.banking.ui.model.tan.TanProcedure
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
@ -23,6 +24,9 @@ open class Account(
|
|||
|
||||
var tanMedia: List<TanMedium> = listOf()
|
||||
|
||||
val tanMediaSorted: List<TanMedium>
|
||||
get() = tanMedia.sortedByDescending { it.status == TanMediumStatus.Used }
|
||||
|
||||
|
||||
val displayName: String
|
||||
get() = bank.name
|
||||
|
|
|
@ -15,13 +15,13 @@ import android.widget.Spinner
|
|||
import kotlinx.android.synthetic.main.dialog_enter_tan.view.*
|
||||
import kotlinx.android.synthetic.main.view_tan_image.view.*
|
||||
import net.dankito.banking.fints4java.android.R
|
||||
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
||||
import net.dankito.banking.fints4java.android.ui.adapter.TanMediumAdapter
|
||||
import net.dankito.banking.fints4java.android.ui.adapter.TanProceduresAdapter
|
||||
import net.dankito.banking.fints4java.android.ui.listener.ListItemSelectedListener
|
||||
import net.dankito.banking.ui.model.Account
|
||||
import net.dankito.banking.ui.model.responses.BankingClientResponse
|
||||
import net.dankito.banking.ui.model.tan.*
|
||||
import net.dankito.banking.ui.presenter.MainWindowPresenter
|
||||
|
||||
|
||||
open class EnterTanDialog : DialogFragment() {
|
||||
|
@ -104,7 +104,7 @@ open class EnterTanDialog : DialogFragment() {
|
|||
protected open fun setupSelectTanMediumView(rootView: View) {
|
||||
rootView.lytTanMedium.visibility = View.VISIBLE
|
||||
|
||||
tanMediumAdapter.setItems(account.tanMedia.sortedByDescending { it.status == TanMediumStatus.Used })
|
||||
tanMediumAdapter.setItems(account.tanMediaSorted)
|
||||
|
||||
rootView.spnTanMedium.adapter = tanMediumAdapter
|
||||
rootView.spnTanMedium.onItemSelectedListener = ListItemSelectedListener(tanMediumAdapter) { selectedTanMedium ->
|
||||
|
@ -131,12 +131,12 @@ open class EnterTanDialog : DialogFragment() {
|
|||
val flickerCodeView = rootView.flickerCodeView
|
||||
flickerCodeView.visibility = View.VISIBLE
|
||||
|
||||
val flickercode = (tanChallenge as FlickerCodeTanChallenge).flickerCode
|
||||
if (flickercode.decodingSuccessful) {
|
||||
flickerCodeView.setCode(flickercode)
|
||||
val flickerCode = (tanChallenge as FlickerCodeTanChallenge).flickerCode
|
||||
if (flickerCode.decodingSuccessful) {
|
||||
flickerCodeView.setCode(flickerCode)
|
||||
}
|
||||
else {
|
||||
showDecodingTanChallengeFailedErrorDelayed(flickercode.decodingError)
|
||||
showDecodingTanChallengeFailedErrorDelayed(flickerCode.decodingError)
|
||||
}
|
||||
}
|
||||
else if (tanChallenge is ImageTanChallenge) {
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<string name="dialog_enter_tan_select_tan_procedure">TAN procedure</string>
|
||||
<string name="dialog_enter_tan_select_tan_medium">TAN medium</string>
|
||||
<string name="dialog_enter_tan_enter_tan">Enter TAN:</string>
|
||||
<string name="dialog_enter_tan_error_could_not_decode_tan_image">Could not decode QR code / PhotoTan. Most likely an internal error:\n%s.</string>
|
||||
<string name="dialog_enter_tan_error_could_not_decode_tan_image">Could not decode flicker code or QR code / PhotoTan. Most likely an internal error:\n%s.</string>
|
||||
<string name="dialog_enter_tan_tan_medium_successfully_changed">TAN medium successfully changed to \'%s\'.</string>
|
||||
<string name="dialog_enter_tan_error_changing_tan_medium">Could not change TAN medium to \'%s\':\n%s.</string>
|
||||
|
||||
|
|
Loading…
Reference in New Issue