diff --git a/core/src/main/java/io/bitsquare/locale/BankUtil.java b/core/src/main/java/io/bitsquare/locale/BankUtil.java index 148dbb684f..20152e769b 100644 --- a/core/src/main/java/io/bitsquare/locale/BankUtil.java +++ b/core/src/main/java/io/bitsquare/locale/BankUtil.java @@ -20,32 +20,64 @@ package io.bitsquare.locale; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class BankUtil { private static final Logger log = LoggerFactory.getLogger(BankUtil.class); - - //TODO set country specific labels - public static String getBankIdLabel(String countryCode) { - if (countryCode == null) - countryCode = ""; + // BankName + public static boolean isBankNameRequired(String countryCode) { switch (countryCode) { case "GB": - return "Bank nr. or BIC/SWIFT:"; + case "US": + return false; + default: + return true; + } + } + + + // BankId + public static boolean isBankIdRequired(String countryCode) { + switch (countryCode) { + case "GB": + case "US": + return false; + default: + return true; + } + } + + public static String getBankIdLabel(String countryCode) { + switch (countryCode) { + case "GB": + case "US": + log.warn("BankId must not be used for country " + countryCode); default: return "Bank nr. or BIC/SWIFT:"; } } - //TODO set country specific labels - public static String getBranchIdLabel(String countryCode) { - if (countryCode == null) - countryCode = ""; + // BranchId + public static boolean isBranchIdRequired(String countryCode) { switch (countryCode) { + case "GB": case "US": - return "Routing Number:"; + return true; + default: + return true; + } + } + + public static String getBranchIdLabel(String countryCode) { + switch (countryCode) { case "GB": return "UK Sort code:"; + case "US": + return "Routing Number:"; case "CA": return "Transit Number:"; default: @@ -53,21 +85,66 @@ public class BankUtil { } } - //TODO set country specific labels + + // AccountNr + public static boolean isAccountNrRequired(String countryCode) { + switch (countryCode) { + default: + return true; + } + } + public static String getAccountNrLabel(String countryCode) { - if (countryCode == null) - countryCode = ""; switch (countryCode) { case "GB": - return "Account number"; + case "US": + return "Account number:"; default: return "Account nr. or IBAN:"; } } + // AccountType + public static boolean isAccountTypeRequired(String countryCode) { + switch (countryCode) { + case "US": + return true; + default: + return false; + } + } + + public static String getAccountTypeLabel(String countryCode) { + switch (countryCode) { + case "US": + return "Account type:"; + default: + return ""; + } + } + + public static List getAccountTypeValues(String countryCode) { + switch (countryCode) { + case "US": + return Arrays.asList("Checking", "Savings"); + default: + return new ArrayList<>(); + } + } + + + // HolderId + public static boolean isHolderIdRequired(String countryCode) { + switch (countryCode) { + case "BR": + case "CL": + return true; + default: + return false; + } + } + public static String getHolderIdLabel(String countryCode) { - if (countryCode == null) - countryCode = ""; switch (countryCode) { case "BR": return "CPF Number:"; @@ -77,58 +154,4 @@ public class BankUtil { return "Personal ID:"; } } - - public static boolean isBankNameRequired(String countryCode) { - if (countryCode == null) - countryCode = ""; - switch (countryCode) { - case "GB": - return false; - default: - return true; - } - } - - public static boolean isBankIdRequired(String countryCode) { - if (countryCode == null) - countryCode = ""; - switch (countryCode) { - case "GB": - return false; - default: - return true; - } - } - - public static boolean isBranchIdRequired(String countryCode) { - if (countryCode == null) - countryCode = ""; - switch (countryCode) { - case "GB": - return true; - default: - return true; - } - } - - public static boolean isAccountNrRequired(String countryCode) { - if (countryCode == null) - countryCode = ""; - switch (countryCode) { - default: - return true; - } - } - - public static boolean isHolderIdRequired(String countryCode) { - if (countryCode == null) - countryCode = ""; - switch (countryCode) { - case "BR": - case "CL": - return true; - default: - return false; - } - } } diff --git a/core/src/main/java/io/bitsquare/payment/BankAccountContractData.java b/core/src/main/java/io/bitsquare/payment/BankAccountContractData.java index ad61b037b4..1649e0ddf3 100644 --- a/core/src/main/java/io/bitsquare/payment/BankAccountContractData.java +++ b/core/src/main/java/io/bitsquare/payment/BankAccountContractData.java @@ -36,6 +36,7 @@ public abstract class BankAccountContractData extends CountryBasedPaymentAccount protected String bankId; protected String branchId; protected String accountNr; + protected String accountType; @Nullable protected String holderTaxId; @@ -51,17 +52,29 @@ public abstract class BankAccountContractData extends CountryBasedPaymentAccount @Override public String getPaymentDetailsForTradePopup() { - String holderIdString = BankUtil.isHolderIdRequired(countryCode) ? (getHolderIdLabel() + ": " + holderTaxId + "\n") : ""; + String holderIdString = BankUtil.isHolderIdRequired(countryCode) ? (BankUtil.getHolderIdLabel(countryCode) + ": " + holderTaxId + "\n") : ""; + + String bankName = BankUtil.isBankNameRequired(countryCode) ? "Bank name: " + this.bankName + "\n" : ""; + String bankId = BankUtil.isBankIdRequired(countryCode) ? BankUtil.getBankIdLabel(countryCode) + this.bankId + "\n" : ""; + String branchId = BankUtil.isBranchIdRequired(countryCode) ? BankUtil.getBranchIdLabel(countryCode) + this.branchId + "\n" : ""; + String accountNr = BankUtil.isAccountNrRequired(countryCode) ? BankUtil.getAccountNrLabel(countryCode) + this.accountNr + "\n" : ""; + String accountType = BankUtil.isAccountTypeRequired(countryCode) ? BankUtil.getAccountTypeLabel(countryCode) + this.accountType + "\n" : ""; + return "Holder name: " + holderName + "\n" + - "Bank name: " + bankName + "\n" + - "Bank Nr.: " + bankId + "\n" + - "Branch Nr.: " + branchId + "\n" + - "Account Nr.: " + accountNr + "\n" + + bankName + + bankId + + branchId + + accountNr + + accountType + holderIdString + "Country of bank: " + CountryUtil.getNameAndCode(getCountryCode()); } + protected String getHolderIdLabel() { + return BankUtil.getHolderIdLabel(countryCode); + } + public void setHolderName(String holderName) { this.holderName = holderName; } @@ -74,6 +87,7 @@ public abstract class BankAccountContractData extends CountryBasedPaymentAccount this.bankName = bankName; } + @Nullable public String getBankName() { return bankName; } @@ -82,20 +96,18 @@ public abstract class BankAccountContractData extends CountryBasedPaymentAccount this.bankId = bankId; } + @Nullable public String getBankId() { return bankId; } - public String getBranchId() { - return branchId; - } - public void setBranchId(String branchId) { this.branchId = branchId; } - public String getAccountNr() { - return accountNr; + @Nullable + public String getBranchId() { + return branchId; } public void setAccountNr(String accountNr) { @@ -103,15 +115,25 @@ public abstract class BankAccountContractData extends CountryBasedPaymentAccount } @Nullable - public String getHolderTaxId() { - return holderTaxId; + public String getAccountNr() { + return accountNr; } public void setHolderTaxId(String holderTaxId) { this.holderTaxId = holderTaxId; } - public String getHolderIdLabel() { - return BankUtil.getHolderIdLabel(countryCode); + @Nullable + public String getHolderTaxId() { + return holderTaxId; + } + + public void setAccountType(String accountType) { + this.accountType = accountType; + } + + @Nullable + public String getAccountType() { + return accountType; } } diff --git a/core/src/main/java/io/bitsquare/payment/CountryBasedPaymentAccountContractData.java b/core/src/main/java/io/bitsquare/payment/CountryBasedPaymentAccountContractData.java index 360d726a72..f7b06cb4ac 100644 --- a/core/src/main/java/io/bitsquare/payment/CountryBasedPaymentAccountContractData.java +++ b/core/src/main/java/io/bitsquare/payment/CountryBasedPaymentAccountContractData.java @@ -18,16 +18,12 @@ package io.bitsquare.payment; import io.bitsquare.app.Version; -import org.jetbrains.annotations.NotNull; - -import javax.annotation.Nullable; public abstract class CountryBasedPaymentAccountContractData extends PaymentAccountContractData { // That object is sent over the wire, so we need to take care of version compatibility. private static final long serialVersionUID = Version.P2P_NETWORK_VERSION; - @Nullable - protected String countryCode; + protected String countryCode = ""; /////////////////////////////////////////////////////////////////////////////////////////// @@ -42,11 +38,10 @@ public abstract class CountryBasedPaymentAccountContractData extends PaymentAcco // Getter, Setter /////////////////////////////////////////////////////////////////////////////////////////// - public void setCountryCode(@NotNull String countryCode) { + public void setCountryCode(String countryCode) { this.countryCode = countryCode; } - @Nullable public String getCountryCode() { return countryCode; } diff --git a/core/src/main/java/io/bitsquare/payment/SpecificBanksAccountContractData.java b/core/src/main/java/io/bitsquare/payment/SpecificBanksAccountContractData.java index c83d26819c..cea262abdf 100644 --- a/core/src/main/java/io/bitsquare/payment/SpecificBanksAccountContractData.java +++ b/core/src/main/java/io/bitsquare/payment/SpecificBanksAccountContractData.java @@ -19,8 +19,6 @@ package io.bitsquare.payment; import com.google.common.base.Joiner; import io.bitsquare.app.Version; -import io.bitsquare.locale.BankUtil; -import io.bitsquare.locale.CountryUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,14 +60,7 @@ public final class SpecificBanksAccountContractData extends BankAccountContractD @Override public String getPaymentDetailsForTradePopup() { - String holderIdString = BankUtil.isHolderIdRequired(countryCode) ? (getHolderIdLabel() + ": " + holderTaxId + "\n") : ""; - return "Holder name: " + holderName + "\n" + - holderIdString + - "Bank name: " + bankName + "\n" + - "Bank Nr.: " + bankId + "\n" + - "Branch Nr.: " + branchId + "\n" + - "Account Nr.: " + accountNr + "\n" + - "Accepted banks: " + Joiner.on(", ").join(acceptedBanks) + "\n" + - "Country of bank: " + CountryUtil.getNameAndCode(getCountryCode()); + return getPaymentDetailsForTradePopup() + "\n" + + "Accepted banks: " + Joiner.on(", ").join(acceptedBanks) + "\n"; } } diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/AliPayForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/AliPayForm.java index f64e56cdc4..af74729703 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/AliPayForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/AliPayForm.java @@ -27,6 +27,7 @@ import io.bitsquare.payment.AliPayAccount; import io.bitsquare.payment.AliPayAccountContractData; import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentAccountContractData; +import javafx.beans.value.WeakChangeListener; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import org.apache.commons.lang3.StringUtils; @@ -59,10 +60,10 @@ public class AliPayForm extends PaymentMethodForm { accountNrInputTextField = addLabelInputTextField(gridPane, ++gridRow, "Account nr.:").second; accountNrInputTextField.setValidator(aliPayValidator); - accountNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + accountNrInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { aliPayAccount.setAccountNr(newValue); updateFromInputs(); - }); + })); addLabelTextField(gridPane, ++gridRow, "Currency:", aliPayAccount.getSingleTradeCurrency().getNameAndCode()); addAllowedPeriod(); diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/BankForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/BankForm.java index d623585a71..6584026399 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/BankForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/BankForm.java @@ -32,6 +32,7 @@ import io.bitsquare.payment.BankAccountContractData; import io.bitsquare.payment.CountryBasedPaymentAccount; import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentAccountContractData; +import javafx.beans.value.WeakChangeListener; import javafx.collections.FXCollections; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; @@ -59,17 +60,21 @@ abstract class BankForm extends PaymentMethodForm { private Tuple2 accountNrTuple; private Tuple2 branchIdTuple; private Tuple2 bankNameTuple; + private Tuple2 accountTypeTuple; + private Label accountTypeLabel; + private ComboBox accountTypeComboBox; static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountContractData paymentAccountContractData) { BankAccountContractData bankAccountContractData = (BankAccountContractData) paymentAccountContractData; + String countryCode = ((BankAccountContractData) paymentAccountContractData).getCountryCode(); + if (bankAccountContractData.getHolderTaxId() != null) - addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account holder name / " + bankAccountContractData.getHolderIdLabel(), + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account holder name / " + BankUtil.getHolderIdLabel(countryCode), bankAccountContractData.getHolderName() + " / " + bankAccountContractData.getHolderTaxId()); else addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account holder name:", bankAccountContractData.getHolderName()); - addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Country of bank:", CountryUtil.getNameAndCode(bankAccountContractData.getCountryCode())); - String countryCode = ((BankAccountContractData) paymentAccountContractData).getCountryCode(); + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Country of bank:", CountryUtil.getNameAndCode(countryCode)); String bankCodeLabel = BankUtil.getBankIdLabel(countryCode); if (BankUtil.isBankNameRequired(countryCode) && BankUtil.isBankIdRequired(countryCode)) @@ -82,13 +87,21 @@ abstract class BankForm extends PaymentMethodForm { String accountNrLabel = BankUtil.getAccountNrLabel(countryCode); String branchCodeLabel = BankUtil.getBranchIdLabel(countryCode); - if (BankUtil.isBranchIdRequired(countryCode) && BankUtil.isAccountNrRequired(countryCode)) - addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, branchCodeLabel + " / " + accountNrLabel, - bankAccountContractData.getBranchId() + " / " + bankAccountContractData.getAccountNr()); - else if (BankUtil.isBranchIdRequired(countryCode)) + String accountTypeLabel = BankUtil.getAccountTypeLabel(countryCode); + + String accountTypeString = ""; + String accountTypeLabelString = ""; + + if (BankUtil.isAccountTypeRequired(countryCode)) { + accountTypeString = " (" + bankAccountContractData.getAccountType() + ")"; + accountTypeLabelString = " (" + accountTypeLabel + ")"; + } + + if (BankUtil.isBranchIdRequired(countryCode)) addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, branchCodeLabel, bankAccountContractData.getBranchId()); - else if (BankUtil.isAccountNrRequired(countryCode)) - addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, accountNrLabel, bankAccountContractData.getAccountNr()); + if (BankUtil.isAccountNrRequired(countryCode)) + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, accountNrLabel + accountTypeLabelString, bankAccountContractData.getAccountNr() + accountTypeString); + return gridRow; } @@ -122,6 +135,9 @@ abstract class BankForm extends PaymentMethodForm { if (BankUtil.isAccountNrRequired(countryCode)) addLabelTextField(gridPane, ++gridRow, BankUtil.getAccountNrLabel(countryCode), bankAccountContractData.getAccountNr()).second.setMouseTransparent(false); + if (BankUtil.isAccountTypeRequired(countryCode)) + addLabelTextField(gridPane, ++gridRow, BankUtil.getAccountTypeLabel(countryCode), bankAccountContractData.getAccountType()).second.setMouseTransparent(false); + addAllowedPeriod(); } @@ -175,6 +191,19 @@ abstract class BankForm extends PaymentMethodForm { bankIdLabel.setText(BankUtil.getBankIdLabel(countryCode)); branchIdLabel.setText(BankUtil.getBranchIdLabel(countryCode)); accountNrLabel.setText(BankUtil.getAccountNrLabel(countryCode)); + accountTypeLabel.setText(BankUtil.getAccountTypeLabel(countryCode)); + + bankNameInputTextField.setText(""); + bankIdInputTextField.setText(""); + branchIdInputTextField.setText(""); + accountNrInputTextField.setText(""); + accountTypeComboBox.getSelectionModel().clearSelection(); + accountTypeComboBox.setItems(FXCollections.observableArrayList(BankUtil.getAccountTypeValues(countryCode))); + + bankNameInputTextField.resetValidation(); + bankIdInputTextField.resetValidation(); + branchIdInputTextField.resetValidation(); + accountNrInputTextField.resetValidation(); if (holderIdInputTextField != null) { holderIdInputTextField.resetValidation(); @@ -224,6 +253,12 @@ abstract class BankForm extends PaymentMethodForm { accountNrTuple.second.setManaged(accountNrRequired); ((BankValidator) accountNrTuple.second.getValidator()).setCountryCode(bankAccountContractData.getCountryCode()); + boolean accountTypeRequired = BankUtil.isAccountTypeRequired(countryCode); + accountTypeTuple.first.setVisible(accountTypeRequired); + accountTypeTuple.first.setManaged(accountTypeRequired); + accountTypeTuple.second.setVisible(accountTypeRequired); + accountTypeTuple.second.setManaged(accountTypeRequired); + updateFromInputs(); onCountryChanged(); @@ -245,40 +280,52 @@ abstract class BankForm extends PaymentMethodForm { bankNameTuple = addLabelInputTextField(gridPane, ++gridRow, "Bank name:"); bankNameInputTextField = bankNameTuple.second; bankNameInputTextField.setValidator(inputValidator); - bankNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + bankNameInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { bankAccountContractData.setBankName(newValue); updateFromInputs(); - }); + })); bankIdTuple = addLabelInputTextField(gridPane, ++gridRow, BankUtil.getBankIdLabel("")); bankIdLabel = bankIdTuple.first; bankIdInputTextField = bankIdTuple.second; bankIdInputTextField.setValidator(inputValidator); - bankIdInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + bankIdInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { bankAccountContractData.setBankId(newValue); updateFromInputs(); - }); + })); branchIdTuple = addLabelInputTextField(gridPane, ++gridRow, BankUtil.getBranchIdLabel("")); branchIdLabel = branchIdTuple.first; branchIdInputTextField = branchIdTuple.second; branchIdInputTextField.setValidator(new BranchIdValidator()); - branchIdInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + branchIdInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { bankAccountContractData.setBranchId(newValue); updateFromInputs(); - }); + })); accountNrTuple = addLabelInputTextField(gridPane, ++gridRow, BankUtil.getAccountNrLabel("")); accountNrLabel = accountNrTuple.first; accountNrInputTextField = accountNrTuple.second; accountNrInputTextField.setValidator(new AccountNrValidator()); - accountNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + accountNrInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { bankAccountContractData.setAccountNr(newValue); updateFromInputs(); + })); + + + accountTypeTuple = addLabelComboBox(gridPane, ++gridRow, ""); + accountTypeLabel = accountTypeTuple.first; + accountTypeComboBox = accountTypeTuple.second; + accountTypeComboBox.setPromptText("Select account type"); + accountTypeComboBox.setOnAction(e -> { + if (BankUtil.isAccountTypeRequired(bankAccountContractData.getCountryCode())) { + bankAccountContractData.setAccountType(accountTypeComboBox.getSelectionModel().getSelectedItem()); + updateFromInputs(); + } }); addAllowedPeriod(); @@ -299,10 +346,10 @@ abstract class BankForm extends PaymentMethodForm { holderNameInputTextField = tuple.second; holderNameInputTextField.setMinWidth(300); holderNameInputTextField.setValidator(inputValidator); - holderNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + holderNameInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { bankAccountContractData.setHolderName(newValue); updateFromInputs(); - }); + })); holderNameInputTextField.minWidthProperty().bind(currencyTextField.widthProperty()); holderIdLabel = tuple.third; @@ -313,29 +360,28 @@ abstract class BankForm extends PaymentMethodForm { holderIdInputTextField.setVisible(false); holderIdInputTextField.setManaged(false); holderIdInputTextField.setValidator(inputValidator); - holderIdInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + holderIdInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { bankAccountContractData.setHolderTaxId(newValue); updateFromInputs(); - }); + })); } - protected void addAcceptedBanksForAddAccount() { - } - - @Override protected void autoFillNameTextField() { if (useCustomAccountNameCheckBox != null && !useCustomAccountNameCheckBox.isSelected()) { String bankId = null; - if (BankUtil.isBankIdRequired(bankAccountContractData.getCountryCode())) { + String countryCode = bankAccountContractData.getCountryCode(); + if (countryCode == null) + countryCode = ""; + if (BankUtil.isBankIdRequired(countryCode)) { bankId = bankIdInputTextField.getText(); if (bankId.length() > 6) bankId = StringUtils.abbreviate(bankId, 9); - } else if (BankUtil.isBranchIdRequired(bankAccountContractData.getCountryCode())) { + } else if (BankUtil.isBranchIdRequired(countryCode)) { bankId = branchIdInputTextField.getText(); if (bankId.length() > 6) bankId = StringUtils.abbreviate(bankId, 9); - } else if (BankUtil.isBankNameRequired(bankAccountContractData.getCountryCode())) { + } else if (BankUtil.isBankNameRequired(countryCode)) { bankId = bankNameInputTextField.getText(); if (bankId.length() > 6) bankId = StringUtils.abbreviate(bankId, 9); @@ -360,18 +406,22 @@ abstract class BankForm extends PaymentMethodForm { && paymentAccount.getSingleTradeCurrency() != null && getCountryBasedPaymentAccount().getCountry() != null; - if (BankUtil.isBankNameRequired(bankAccountContractData.getCountryCode())) + String countryCode = bankAccountContractData.getCountryCode(); + if (BankUtil.isBankNameRequired(countryCode)) result &= bankNameInputTextField.getValidator().validate(bankAccountContractData.getBankName()).isValid; - if (BankUtil.isBankIdRequired(bankAccountContractData.getCountryCode())) + if (BankUtil.isBankIdRequired(countryCode)) result &= bankIdInputTextField.getValidator().validate(bankAccountContractData.getBankId()).isValid; - if (BankUtil.isBranchIdRequired(bankAccountContractData.getCountryCode())) + if (BankUtil.isBranchIdRequired(countryCode)) result &= branchIdInputTextField.getValidator().validate(bankAccountContractData.getBranchId()).isValid; - if (BankUtil.isAccountNrRequired(bankAccountContractData.getCountryCode())) + if (BankUtil.isAccountNrRequired(countryCode)) result &= accountNrInputTextField.getValidator().validate(bankAccountContractData.getAccountNr()).isValid; + if (BankUtil.isAccountTypeRequired(countryCode)) + result &= bankAccountContractData.getAccountType() != null; + if (getCountryBasedPaymentAccount().getCountry() != null && BankUtil.isHolderIdRequired(getCountryBasedPaymentAccount().getCountry().code)) result &= holderIdInputTextField.getValidator().validate(bankAccountContractData.getHolderTaxId()).isValid; @@ -392,6 +442,9 @@ abstract class BankForm extends PaymentMethodForm { } } + protected void addAcceptedBanksForAddAccount() { + } + public void addAcceptedBanksForDisplayAccount() { } } diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/BlockChainForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/BlockChainForm.java index 840560ad20..d3a6b25499 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/BlockChainForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/BlockChainForm.java @@ -30,6 +30,7 @@ import io.bitsquare.payment.CryptoCurrencyAccount; import io.bitsquare.payment.CryptoCurrencyAccountContractData; import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentAccountContractData; +import javafx.beans.value.WeakChangeListener; import javafx.collections.FXCollections; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; @@ -80,10 +81,10 @@ public class BlockChainForm extends PaymentMethodForm { addressInputTextField = tuple2.second; addressInputTextField.setValidator(altCoinAddressValidator); - addressInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + addressInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { cryptoCurrencyAccount.setAddress(newValue); updateFromInputs(); - }); + })); addAllowedPeriod(); addAccountNameTextFieldWithAutoFillCheckBox(); diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/OKPayForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/OKPayForm.java index b58d815bf2..6b4a0c83fe 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/OKPayForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/OKPayForm.java @@ -28,6 +28,7 @@ import io.bitsquare.payment.OKPayAccount; import io.bitsquare.payment.OKPayAccountContractData; import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentAccountContractData; +import javafx.beans.value.WeakChangeListener; import javafx.geometry.Insets; import javafx.geometry.VPos; import javafx.scene.control.CheckBox; @@ -66,10 +67,10 @@ public class OKPayForm extends PaymentMethodForm { accountNrInputTextField = addLabelInputTextField(gridPane, ++gridRow, "Wallet ID:").second; accountNrInputTextField.setValidator(okPayValidator); - accountNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + accountNrInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { okPayAccount.setAccountNr(newValue); updateFromInputs(); - }); + })); addCurrenciesGrid(true); addAllowedPeriod(); diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PaymentMethodForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PaymentMethodForm.java index 292b18ecf8..f687e73cd2 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PaymentMethodForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PaymentMethodForm.java @@ -27,6 +27,7 @@ import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentAccountContractData; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.value.WeakChangeListener; import javafx.collections.FXCollections; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; @@ -91,10 +92,10 @@ public abstract class PaymentMethodForm { accountNameTextField.setEditable(false); accountNameTextField.setValidator(inputValidator); accountNameTextField.setFocusTraversable(false); - accountNameTextField.textProperty().addListener((ov, oldValue, newValue) -> { + accountNameTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { paymentAccount.setAccountName(newValue); updateAllInputsValid(); - }); + })); useCustomAccountNameCheckBox = tuple.third; useCustomAccountNameCheckBox.setSelected(false); useCustomAccountNameCheckBox.setOnAction(e -> { diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PerfectMoneyForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PerfectMoneyForm.java index 99a5d73ba2..5b150c1326 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PerfectMoneyForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/PerfectMoneyForm.java @@ -27,6 +27,7 @@ import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentAccountContractData; import io.bitsquare.payment.PerfectMoneyAccount; import io.bitsquare.payment.PerfectMoneyAccountContractData; +import javafx.beans.value.WeakChangeListener; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import org.apache.commons.lang3.StringUtils; @@ -60,10 +61,10 @@ public class PerfectMoneyForm extends PaymentMethodForm { accountNrInputTextField = addLabelInputTextField(gridPane, ++gridRow, "Account nr.:").second; accountNrInputTextField.setValidator(perfectMoneyValidator); - accountNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + accountNrInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { perfectMoneyAccount.setAccountNr(newValue); updateFromInputs(); - }); + })); addLabelTextField(gridPane, ++gridRow, "Currency:", perfectMoneyAccount.getSingleTradeCurrency().getNameAndCode()); addAllowedPeriod(); diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SameBankForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SameBankForm.java index 3dd753321f..575f46034c 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SameBankForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SameBankForm.java @@ -25,6 +25,7 @@ import io.bitsquare.locale.BankUtil; import io.bitsquare.payment.CountryBasedPaymentAccount; import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentAccountContractData; +import javafx.beans.value.WeakChangeListener; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; @@ -51,10 +52,10 @@ public class SameBankForm extends BankForm { Tuple2 tuple = addLabelInputTextField(gridPane, ++gridRow, "Account holder name:"); InputTextField holderNameInputTextField = tuple.second; holderNameInputTextField.setValidator(inputValidator); - holderNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + holderNameInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { bankAccountContractData.setHolderName(newValue); updateFromInputs(); - }); + })); } @Override diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SepaForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SepaForm.java index 96f2221cc2..7b7a419ecc 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SepaForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SepaForm.java @@ -25,6 +25,7 @@ import io.bitsquare.gui.util.validation.IBANValidator; import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.locale.*; import io.bitsquare.payment.*; +import javafx.beans.value.WeakChangeListener; import javafx.collections.FXCollections; import javafx.geometry.HPos; import javafx.geometry.Insets; @@ -58,10 +59,11 @@ public class SepaForm extends PaymentMethodForm { private ComboBox currencyComboBox; public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountContractData paymentAccountContractData) { - addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account holder name:", ((SepaAccountContractData) paymentAccountContractData).getHolderName()); - addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Country of bank:", CountryUtil.getNameAndCode(((CountryBasedPaymentAccountContractData) paymentAccountContractData).getCountryCode())); - addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "IBAN:", ((SepaAccountContractData) paymentAccountContractData).getIban()); - addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "BIC/SWIFT:", ((SepaAccountContractData) paymentAccountContractData).getBic()); + SepaAccountContractData sepaAccountContractData = (SepaAccountContractData) paymentAccountContractData; + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Account holder name:", sepaAccountContractData.getHolderName()); + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "Country of bank:", CountryUtil.getNameAndCode(sepaAccountContractData.getCountryCode())); + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "IBAN:", sepaAccountContractData.getIban()); + addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, "BIC/SWIFT:", sepaAccountContractData.getBic()); return gridRow; } @@ -79,25 +81,25 @@ public class SepaForm extends PaymentMethodForm { InputTextField holderNameInputTextField = addLabelInputTextField(gridPane, ++gridRow, "Account holder name:").second; holderNameInputTextField.setValidator(inputValidator); - holderNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + holderNameInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { sepaAccount.setHolderName(newValue); updateFromInputs(); - }); + })); ibanInputTextField = addLabelInputTextField(gridPane, ++gridRow, "IBAN:").second; ibanInputTextField.setValidator(ibanValidator); - ibanInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + ibanInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { sepaAccount.setIban(newValue); updateFromInputs(); - }); + })); bicInputTextField = addLabelInputTextField(gridPane, ++gridRow, "BIC/SWIFT:").second; bicInputTextField.setValidator(bicValidator); - bicInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + bicInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { sepaAccount.setBic(newValue); updateFromInputs(); - }); + })); addLabel(gridPane, ++gridRow, "Country of your Bank:"); diff --git a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SwishForm.java b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SwishForm.java index f868287763..f4881eb750 100644 --- a/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SwishForm.java +++ b/gui/src/main/java/io/bitsquare/gui/components/paymentmethods/SwishForm.java @@ -27,6 +27,7 @@ import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentAccountContractData; import io.bitsquare.payment.SwishAccount; import io.bitsquare.payment.SwishAccountContractData; +import javafx.beans.value.WeakChangeListener; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import org.apache.commons.lang3.StringUtils; @@ -61,17 +62,17 @@ public class SwishForm extends PaymentMethodForm { InputTextField holderNameInputTextField = addLabelInputTextField(gridPane, ++gridRow, "Account holder name:").second; holderNameInputTextField.setValidator(inputValidator); - holderNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + holderNameInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { swishAccount.setHolderName(newValue); updateFromInputs(); - }); + })); mobileNrInputTextField = addLabelInputTextField(gridPane, ++gridRow, "Mobile nr.:").second; mobileNrInputTextField.setValidator(swishValidator); - mobileNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> { + mobileNrInputTextField.textProperty().addListener(new WeakChangeListener<>((ov, oldValue, newValue) -> { swishAccount.setMobileNr(newValue); updateFromInputs(); - }); + })); addLabelTextField(gridPane, ++gridRow, "Currency:", swishAccount.getSingleTradeCurrency().getNameAndCode()); addAllowedPeriod(); diff --git a/gui/src/main/java/io/bitsquare/gui/util/FormBuilder.java b/gui/src/main/java/io/bitsquare/gui/util/FormBuilder.java index 2e7cadd122..390fac2f88 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/FormBuilder.java +++ b/gui/src/main/java/io/bitsquare/gui/util/FormBuilder.java @@ -508,7 +508,7 @@ public class FormBuilder { /////////////////////////////////////////////////////////////////////////////////////////// - // Label + CheckBox + // Label + CheckBox /////////////////////////////////////////////////////////////////////////////////////////// public static Tuple2 addLabelCheckBox(GridPane gridPane, int rowIndex, String title) { diff --git a/gui/src/main/java/io/bitsquare/gui/util/validation/AccountNrValidator.java b/gui/src/main/java/io/bitsquare/gui/util/validation/AccountNrValidator.java index c9e6434ece..e3473eaa07 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/validation/AccountNrValidator.java +++ b/gui/src/main/java/io/bitsquare/gui/util/validation/AccountNrValidator.java @@ -24,18 +24,18 @@ public final class AccountNrValidator extends BankValidator { @Override public ValidationResult validate(String input) { + String message; switch (countryCode) { case "GB": - try { - Integer.parseInt(input); - if (input.length() != 8) { - return new ValidationResult(false, BSResources.get("validation.ukAccountNr")); - } else { - return super.validate(input); - } - } catch (Throwable t) { - return new ValidationResult(false, BSResources.get("validation.ukAccountNr")); - } + if (isNumberWithFixedLength(input, 8)) + return super.validate(input); + else + return new ValidationResult(false, BSResources.get("validation.accountNr", 8)); + case "US": + if (isNumberInRange(input, 4, 17)) + return super.validate(input); + else + return new ValidationResult(false, BSResources.get("validation.accountNr", "4 - 17")); default: return super.validate(input); } diff --git a/gui/src/main/java/io/bitsquare/gui/util/validation/BranchIdValidator.java b/gui/src/main/java/io/bitsquare/gui/util/validation/BranchIdValidator.java index e8562e7681..95e7ab5d79 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/validation/BranchIdValidator.java +++ b/gui/src/main/java/io/bitsquare/gui/util/validation/BranchIdValidator.java @@ -25,19 +25,20 @@ public final class BranchIdValidator extends BankValidator { public ValidationResult validate(String input) { switch (countryCode) { case "GB": - try { - Integer.parseInt(input); - if (input.length() != 6) { - return new ValidationResult(false, BSResources.get("Sort code must consist of 6 numbers")); - } else { - return super.validate(input); - } - } catch (Throwable t) { - return new ValidationResult(false, BSResources.get("validation.ukSortCode")); - } + if (isNumberWithFixedLength(input, 6)) + return super.validate(input); + else + return new ValidationResult(false, BSResources.get("validation.sortCode", "Sort code", 6)); + case "US": + if (isNumberWithFixedLength(input, 9)) + return super.validate(input); + else + return new ValidationResult(false, BSResources.get("validation.sortCode", "Routing number", 9)); default: return super.validate(input); } } + + } diff --git a/gui/src/main/java/io/bitsquare/gui/util/validation/InputValidator.java b/gui/src/main/java/io/bitsquare/gui/util/validation/InputValidator.java index b4d528f2f3..5fb43471d6 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/validation/InputValidator.java +++ b/gui/src/main/java/io/bitsquare/gui/util/validation/InputValidator.java @@ -18,6 +18,7 @@ package io.bitsquare.gui.util.validation; import io.bitsquare.locale.BSResources; +import org.apache.commons.lang3.math.NumberUtils; public class InputValidator { @@ -60,4 +61,20 @@ public class InputValidator { '}'; } } + + protected boolean isPositiveNumber(String input) { + try { + return input != null && NumberUtils.isNumber(input) && Long.parseLong(input) >= 0; + } catch (Throwable t) { + return false; + } + } + + protected boolean isNumberWithFixedLength(String input, int length) { + return isPositiveNumber(input) && input.length() == length; + } + + protected boolean isNumberInRange(String input, int minLength, int maxLength) { + return isPositiveNumber(input) && input.length() >= minLength && input.length() <= maxLength; + } } diff --git a/gui/src/main/resources/i18n/displayStrings.properties b/gui/src/main/resources/i18n/displayStrings.properties index 782dd5d03f..e46b85b80b 100644 --- a/gui/src/main/resources/i18n/displayStrings.properties +++ b/gui/src/main/resources/i18n/displayStrings.properties @@ -27,8 +27,8 @@ validation.btc.toSmall=Input results in a bitcoin value with a fraction of the s validation.btc.toLarge=Input larger as maximum trading amount of {0} is not allowed. validation.passwordTooShort=The password you entered is too short. It needs to have min. 8 characters. validation.passwordTooLong=The password you entered is too long. It cannot be longer as 50 characters. -validation.ukSortCode=Sort code must consist of 6 numbers -validation.ukAccountNr=Account number must consist of 8 numbers +validation.sortCode={0} must consist of {1} numbers +validation.accountNr=Account number must consist of {0} numbers # Create offer createOffer.amount.prompt=Enter amount in BTC