Implemented displaying auto retrieved BIC and bank name in an info label; extracted InfoLabel from ValidationLabel
This commit is contained in:
parent
5d88e51ab9
commit
f3d7afc376
|
@ -59,6 +59,9 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
protected val inputValidator = InputValidator() // TODO: move to presenter
|
||||
|
||||
|
||||
protected var remitteeBic: String? = null
|
||||
|
||||
|
||||
protected var validRemitteeNameEntered = false
|
||||
|
||||
protected var validRemitteeIbanEntered = false
|
||||
|
@ -133,7 +136,6 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
tryToGetBicFromIban(it)
|
||||
})
|
||||
|
||||
rootView.edtxtRemitteeBic.addTextChangedListener(checkRequiredDataWatcher())
|
||||
rootView.edtxtAmount.addTextChangedListener(checkRequiredDataWatcher())
|
||||
rootView.edtxtUsage.addTextChangedListener(checkRequiredDataWatcher {
|
||||
checkIfEnteredUsageTextIsValid()
|
||||
|
@ -141,13 +143,11 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
|
||||
rootView.edtxtRemitteeName.setOnFocusChangeListener { _, hasFocus -> if (hasFocus == false) checkIfEnteredRemitteeNameIsValidAfterFocusLost() }
|
||||
rootView.edtxtRemitteeIban.setOnFocusChangeListener { _, hasFocus -> if (hasFocus == false) checkIfEnteredRemitteeIbanIsValidAfterFocusLost() }
|
||||
rootView.edtxtRemitteeBic.setOnFocusChangeListener { _, hasFocus -> if (hasFocus == false) checkIfEnteredRemitteeBicIsValid() }
|
||||
rootView.edtxtAmount.setOnFocusChangeListener { _, hasFocus -> if (hasFocus == false) checkIfEnteredAmountIsValid() }
|
||||
rootView.edtxtUsage.setOnFocusChangeListener { _, hasFocus -> if (hasFocus == false) checkIfEnteredUsageTextIsValid() }
|
||||
|
||||
transferMoneyIfEnterPressed(rootView.edtxtRemitteeName)
|
||||
transferMoneyIfEnterPressed(rootView.edtxtRemitteeIban)
|
||||
transferMoneyIfEnterPressed(rootView.edtxtRemitteeBic)
|
||||
transferMoneyIfEnterPressed(rootView.edtxtAmount)
|
||||
transferMoneyIfEnterPressed(rootView.edtxtUsage)
|
||||
|
||||
|
@ -218,7 +218,7 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
// a little bit inconsistent as if IBAN is not set bank's name won't be displayed even though it can be retrieved by BIC
|
||||
rootView.edtxtRemitteeBic.setText(data.creditorBic)
|
||||
remitteeBic = data.creditorBic
|
||||
|
||||
if (data.amount > BigDecimal.ZERO) {
|
||||
rootView.edtxtAmount.setText(AmountFormat.format(data.amount))
|
||||
|
@ -231,12 +231,7 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
protected open fun focusEditTextAccordingToPreselectedValues(rootView: View, data: TransferMoneyData) {
|
||||
if (data.creditorName.trim().isNotEmpty()) {
|
||||
if (data.creditorIban.trim().isNotEmpty()) {
|
||||
if (data.creditorBic.trim().isNotEmpty()) {
|
||||
rootView.edtxtAmount.requestFocus()
|
||||
}
|
||||
else {
|
||||
rootView.edtxtRemitteeBic.requestFocus()
|
||||
}
|
||||
rootView.edtxtAmount.requestFocus()
|
||||
}
|
||||
else {
|
||||
rootView.edtxtRemitteeIban.requestFocus()
|
||||
|
@ -247,8 +242,8 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
|
||||
protected open fun remitteeSelected(item: Remittee) {
|
||||
edtxtRemitteeName.setText(item.name)
|
||||
edtxtRemitteeBic.setText(item.bic)
|
||||
edtxtRemitteeIban.setText(item.iban)
|
||||
remitteeBic = item.bic
|
||||
}
|
||||
|
||||
protected open fun transferMoney() {
|
||||
|
@ -256,7 +251,7 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
val data = TransferMoneyData(
|
||||
inputValidator.convertToAllowedSepaCharacters(edtxtRemitteeName.text.toString()),
|
||||
edtxtRemitteeIban.text.toString().replace(" ", ""),
|
||||
edtxtRemitteeBic.text.toString().replace(" ", ""),
|
||||
remitteeBic?.replace(" ", "") ?: "", // should always be != null at this point
|
||||
amount.toBigDecimal(),
|
||||
inputValidator.convertToAllowedSepaCharacters(edtxtUsage.text.toString()),
|
||||
chkbxInstantPayment.isChecked
|
||||
|
@ -308,18 +303,26 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
protected open fun tryToGetBicFromIban(enteredIban: CharSequence) {
|
||||
presenter.findUniqueBankForIbanAsync(enteredIban.toString()) { foundBank ->
|
||||
context?.asActivity()?.runOnUiThread {
|
||||
showValuesForFoundBankOnUiThread(foundBank)
|
||||
showValuesForFoundBankOnUiThread(enteredIban, foundBank)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showValuesForFoundBankOnUiThread(foundBank: BankInfo?) {
|
||||
private fun showValuesForFoundBankOnUiThread(enteredIban: CharSequence, foundBank: BankInfo?) {
|
||||
validRemitteeBicEntered = foundBank != null
|
||||
remitteeBic = foundBank?.bic
|
||||
|
||||
edtxtRemitteeBank.setText(if (foundBank != null) (foundBank.name + " " + foundBank.city) else "")
|
||||
|
||||
edtxtRemitteeBic.setText(foundBank?.bic ?: "") // TODO: check if user entered BIC to not overwrite self entered BIC
|
||||
lytRemitteeBic.error = null // TODO: show information here if BIC hasn't been found
|
||||
if (foundBank != null) {
|
||||
txtRemitteeBankInfo.text = getString(R.string.dialog_transfer_money_bic_detected_from_iban, foundBank.bic, foundBank.name)
|
||||
txtRemitteeBankInfo.visibility = View.VISIBLE
|
||||
}
|
||||
else if (enteredIban.length >= InputValidator.MinimumLengthToDetermineBicFromIban) {
|
||||
txtRemitteeBankInfo.text = getString(R.string.dialog_transfer_money_could_not_determine_bic_from_iban, enteredIban.substring(4, InputValidator.MinimumLengthToDetermineBicFromIban))
|
||||
txtRemitteeBankInfo.visibility = View.VISIBLE
|
||||
}
|
||||
else {
|
||||
txtRemitteeBankInfo.visibility = View.GONE
|
||||
}
|
||||
|
||||
checkIfRequiredDataEnteredOnUiThread()
|
||||
}
|
||||
|
@ -357,13 +360,6 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
this.validRemitteeIbanEntered = validationResult.validationSuccessfulOrCouldCorrectString
|
||||
|
||||
showValidationResult(lytRemitteeIban, validationResult)
|
||||
|
||||
if (validRemitteeBicEntered || enteredIban.isBlank()) {
|
||||
lytRemitteeBic.error = null
|
||||
}
|
||||
else {
|
||||
lytRemitteeBic.error = context?.getString(R.string.error_no_bank_found_for_entered_iban)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun checkIfEnteredRemitteeIbanIsValidAfterFocusLost() {
|
||||
|
@ -376,15 +372,6 @@ open class TransferMoneyDialog : DialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
protected open fun checkIfEnteredRemitteeBicIsValid() {
|
||||
val enteredBic = edtxtRemitteeBic.text.toString()
|
||||
val validationResult = inputValidator.validateBic(enteredBic)
|
||||
|
||||
this.validRemitteeBicEntered = validationResult.validationSuccessfulOrCouldCorrectString
|
||||
|
||||
showValidationResult(lytRemitteeBic, validationResult)
|
||||
}
|
||||
|
||||
protected open fun checkIfEnteredAmountIsValid() {
|
||||
val validationResult = inputValidator.validateAmount(edtxtAmount.text.toString())
|
||||
|
||||
|
|
|
@ -79,41 +79,14 @@
|
|||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/lytRemitteeBank"
|
||||
<TextView
|
||||
android:id="@+id/txtRemitteeBankInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/dialog_transfer_money_remittee_bank"
|
||||
>
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/edtxtRemitteeBank"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dialog_transfer_money_input_fields_height"
|
||||
android:inputType="text"
|
||||
android:enabled="false"
|
||||
style="@style/TextAppearance.AppCompat.Small"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/lytRemitteeBic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/dialog_transfer_money_remittee_bic"
|
||||
>
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/edtxtRemitteeBic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dialog_transfer_money_input_fields_height"
|
||||
android:inputType="text"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/lytAmount"
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
<string name="dialog_transfer_money_account">Konto:</string>
|
||||
<string name="dialog_transfer_money_remittee_name">Name:</string>
|
||||
<string name="dialog_transfer_money_remittee_iban">IBAN:</string>
|
||||
<string name="dialog_transfer_money_remittee_bank">Bank (wird automatisch eingetragen):</string>
|
||||
<string name="dialog_transfer_money_remittee_bic">BIC (wird automatisch eingetragen):</string>
|
||||
<string name="dialog_transfer_money_bic_detected_from_iban">BIC: %1$s, %2$s</string>
|
||||
<string name="dialog_transfer_money_could_not_determine_bic_from_iban">Keine BIC gefunden für BLZ %1$s</string>
|
||||
<string name="dialog_transfer_money_amount">Betrag:</string>
|
||||
<string name="dialog_transfer_money_usage">Verwendungszweck:</string>
|
||||
<string name="dialog_transfer_money_instant_payment">Echtzeitüberweisung</string>
|
||||
|
@ -103,8 +103,6 @@
|
|||
<string name="error_no_iban_entered">Bitte geben Sie die IBAN des Empfängers ein</string>
|
||||
<string name="error_invalid_iban_characters_entered">Unzulässige(s) Zeichen eingegeben: %s</string>
|
||||
<string name="error_invalid_iban_pattern_entered">IBANs bestehen aus folgendem Muster: DE12 1234 5678 9012 3456 78</string>
|
||||
<string name="error_no_bank_found_for_entered_iban">Es wurde keine Bank zur eingegebenen IBAN gefunden.</string>
|
||||
<string name="error_no_bic_entered">Bitte geben Sie die BIC des Empfängers ein</string>
|
||||
<string name="error_invalid_bic_characters_entered">Unzulässige(s) Zeichen eingegeben: %s</string>
|
||||
<string name="error_invalid_bic_pattern_entered">Eine BIC besteht aus 8 oder 11 Zeichen und folgt dem Muster: ABCDED12(XYZ)</string>
|
||||
<string name="error_no_amount_entered">Bitte geben Sie den zu überweisenden Betrag ein</string>
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
<string name="dialog_transfer_money_account">Account:</string>
|
||||
<string name="dialog_transfer_money_remittee_name">Name:</string>
|
||||
<string name="dialog_transfer_money_remittee_iban">IBAN:</string>
|
||||
<string name="dialog_transfer_money_remittee_bank">Bank (will be entered automatically):</string>
|
||||
<string name="dialog_transfer_money_remittee_bic">BIC (will be entered automatically):</string>
|
||||
<string name="dialog_transfer_money_bic_detected_from_iban">BIC: %1$s, %2$s</string>
|
||||
<string name="dialog_transfer_money_could_not_determine_bic_from_iban">No BIC found for bank code %1$s</string>
|
||||
<string name="dialog_transfer_money_amount">Amount:</string>
|
||||
<string name="dialog_transfer_money_usage">Usage:</string>
|
||||
<string name="dialog_transfer_money_instant_payment">Instant payment</string>
|
||||
|
@ -103,8 +103,6 @@
|
|||
<string name="error_no_iban_entered">Please enter remittee\'s IBAN</string>
|
||||
<string name="error_invalid_iban_characters_entered">Invalid character(s) entered: %s</string>
|
||||
<string name="error_invalid_iban_pattern_entered">IBAN has to have pattern: EN12 1234 5678 9012 3456 78</string>
|
||||
<string name="error_no_bank_found_for_entered_iban">No bank found for entered IBAN.</string>
|
||||
<string name="error_no_bic_entered">Please enter remittee\'s BIC</string>
|
||||
<string name="error_invalid_bic_characters_entered">Invalid character(s) entered: %s</string>
|
||||
<string name="error_invalid_bic_pattern_entered">A BIC consists of 8 or 11 characters and has the pattern: ABCDED12(XYZ)</string>
|
||||
<string name="error_no_amount_entered">Please enter the amount to be transferred</string>
|
||||
|
|
|
@ -17,6 +17,8 @@ open class InputValidator {
|
|||
|
||||
const val UsageMaxLength = 140
|
||||
|
||||
const val MinimumLengthToDetermineBicFromIban = 12 // TODO: this is only true for German (and may some other) IBANs
|
||||
|
||||
|
||||
/**
|
||||
* The IBAN consists of up to 34 alphanumeric characters, as follows:
|
||||
|
|
|
@ -72,6 +72,8 @@
|
|||
"Transfer Money Dialog Title" = "Bank transfer";
|
||||
"Remittee Name" = "Name";
|
||||
"Remittee IBAN" = "IBAN";
|
||||
"BIC: %@, %@" = "BIC: %@, %@";
|
||||
"No BIC found for bank code %@" = "No BIC found for bank code %@";
|
||||
"Amount" = "Amount";
|
||||
"Usage" = "Usage";
|
||||
"Instant Payment" = "Instant Payment";
|
||||
|
|
|
@ -72,6 +72,8 @@
|
|||
"Transfer Money Dialog Title" = "Überweisung";
|
||||
"Remittee Name" = "Name";
|
||||
"Remittee IBAN" = "IBAN";
|
||||
"BIC: %@, %@" = "BIC: %@, %@";
|
||||
"No BIC found for bank code %@" = "Keine BIC gefunden für BLZ %@";
|
||||
"Amount" = "Betrag";
|
||||
"Usage" = "Verwendungszweck";
|
||||
"Instant Payment" = "Echtzeitüberweisung";
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import SwiftUI
|
||||
|
||||
|
||||
struct InfoLabel: View {
|
||||
|
||||
private let information: LocalizedStringKey
|
||||
|
||||
|
||||
init(_ information: String) {
|
||||
self.init(LocalizedStringKey(information))
|
||||
}
|
||||
|
||||
init(_ information: LocalizedStringKey) {
|
||||
self.information = information
|
||||
}
|
||||
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Spacer()
|
||||
.frame(height: 6)
|
||||
|
||||
HStack {
|
||||
Text(information)
|
||||
.padding(.leading, 16)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
Spacer()
|
||||
.frame(height: 18)
|
||||
}
|
||||
.font(.callout)
|
||||
.systemGroupedBackground()
|
||||
.listRowInsets(EdgeInsets())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct InfoLabel_Previews: PreviewProvider {
|
||||
|
||||
static var previews: some View {
|
||||
InfoLabel("A nice info")
|
||||
}
|
||||
|
||||
}
|
|
@ -20,6 +20,25 @@ extension String {
|
|||
return NSLocalizedString(self, comment: "")
|
||||
}
|
||||
|
||||
|
||||
subscript(_ i: Int) -> String {
|
||||
let idx1 = index(startIndex, offsetBy: i)
|
||||
let idx2 = index(idx1, offsetBy: 1)
|
||||
return String(self[idx1..<idx2])
|
||||
}
|
||||
|
||||
subscript (r: Range<Int>) -> String {
|
||||
let start = index(startIndex, offsetBy: r.lowerBound)
|
||||
let end = index(startIndex, offsetBy: r.upperBound)
|
||||
return String(self[start ..< end])
|
||||
}
|
||||
|
||||
subscript (r: CountableClosedRange<Int>) -> String {
|
||||
let startIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
|
||||
let endIndex = self.index(startIndex, offsetBy: r.upperBound - r.lowerBound)
|
||||
return String(self[startIndex...endIndex])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Optional where Wrapped == String {
|
||||
|
|
|
@ -25,24 +25,8 @@ struct ValidationLabel: View {
|
|||
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Spacer()
|
||||
.frame(height: 6)
|
||||
|
||||
HStack {
|
||||
Text(validationErrorOrHint)
|
||||
.padding(.leading, 16)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
Spacer()
|
||||
.frame(height: 18)
|
||||
}
|
||||
.font(.callout)
|
||||
InfoLabel(validationErrorOrHint)
|
||||
.foregroundColor(isHint ? Color.yellow : Color.red)
|
||||
.systemGroupedBackground()
|
||||
.listRowInsets(EdgeInsets())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ struct TransferMoneyDialog: View {
|
|||
@State private var isValidRemitteeBicEntered = false
|
||||
@State private var remitteeBicValidationResult: ValidationResult? = nil
|
||||
|
||||
@State private var remitteeBankInfo: String? = nil
|
||||
|
||||
@State private var amount = ""
|
||||
@State private var isValidAmountEntered = false
|
||||
@State private var amountValidationResult: ValidationResult? = nil
|
||||
|
@ -127,6 +129,11 @@ struct TransferMoneyDialog: View {
|
|||
remitteeIbanValidationResult.map { validationError in
|
||||
ValidationLabel(validationError)
|
||||
}
|
||||
|
||||
remitteeBankInfo.map {
|
||||
InfoLabel($0)
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
|
@ -215,9 +222,17 @@ struct TransferMoneyDialog: View {
|
|||
|
||||
if let foundBank = foundBank {
|
||||
self.remitteeBic = foundBank.bic
|
||||
self.remitteeBankInfo = "BIC: \(foundBank.bic), \(foundBank.name)"
|
||||
}
|
||||
else {
|
||||
self.remitteeBic = ""
|
||||
|
||||
if enteredIban.count >= InputValidator.Companion().MinimumLengthToDetermineBicFromIban {
|
||||
self.remitteeBankInfo = "No BIC found for bank code \(enteredIban[4..<Int(InputValidator.Companion().MinimumLengthToDetermineBicFromIban)])"
|
||||
}
|
||||
else {
|
||||
self.remitteeBankInfo = nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement a better check if entered BIC is valid (e.g. if format is ABCDDEXX123)
|
||||
|
|
Loading…
Reference in New Issue