io.bitsquare.gui.components.paymentmethods.SepaForm.java Source code

Java tutorial

Introduction

Here is the source code for io.bitsquare.gui.components.paymentmethods.SepaForm.java

Source

/*
 * This file is part of Bitsquare.
 *
 * Bitsquare is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * Bitsquare is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
 */

package io.bitsquare.gui.components.paymentmethods;

import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.BICValidator;
import io.bitsquare.gui.util.validation.IBANValidator;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.*;
import io.bitsquare.payment.*;
import javafx.collections.FXCollections;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.control.*;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.TextAlignment;
import javafx.util.StringConverter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

import static io.bitsquare.gui.util.FormBuilder.*;

public class SepaForm extends PaymentMethodForm {
    private static final Logger log = LoggerFactory.getLogger(SepaForm.class);

    private final SepaAccount sepaAccount;
    private final IBANValidator ibanValidator;
    private final BICValidator bicValidator;
    private InputTextField ibanInputTextField;
    private InputTextField bicInputTextField;
    private TextField currencyTextField;
    private final List<CheckBox> euroCountryCheckBoxes = new ArrayList<>();
    private final List<CheckBox> nonEuroCountryCheckBoxes = new ArrayList<>();
    private ComboBox<TradeCurrency> currencyComboBox;

    public static int addFormForBuyer(GridPane gridPane, int gridRow,
            PaymentAccountContractData paymentAccountContractData) {
        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:", sepaAccountContractData.getBic());
        return gridRow;
    }

    public SepaForm(PaymentAccount paymentAccount, IBANValidator ibanValidator, BICValidator bicValidator,
            InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) {
        super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
        this.sepaAccount = (SepaAccount) paymentAccount;
        this.ibanValidator = ibanValidator;
        this.bicValidator = bicValidator;
    }

    @Override
    public void addFormForAddAccount() {
        gridRowFrom = gridRow + 1;

        InputTextField holderNameInputTextField = addLabelInputTextField(gridPane, ++gridRow,
                "Account holder name:").second;
        holderNameInputTextField.setValidator(inputValidator);
        holderNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
            sepaAccount.setHolderName(newValue);
            updateFromInputs();
        });

        ibanInputTextField = addLabelInputTextField(gridPane, ++gridRow, "IBAN:").second;
        ibanInputTextField.setValidator(ibanValidator);
        ibanInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
            sepaAccount.setIban(newValue);
            updateFromInputs();

        });
        bicInputTextField = addLabelInputTextField(gridPane, ++gridRow, "BIC:").second;
        bicInputTextField.setValidator(bicValidator);
        bicInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
            sepaAccount.setBic(newValue);
            updateFromInputs();

        });

        addLabel(gridPane, ++gridRow, "Country of bank:");
        HBox hBox = new HBox();
        hBox.setSpacing(10);
        ComboBox<Country> countryComboBox = new ComboBox<>();
        currencyComboBox = new ComboBox<>();
        currencyTextField = new TextField("");
        currencyTextField.setEditable(false);
        currencyTextField.setMouseTransparent(true);
        currencyTextField.setFocusTraversable(false);
        currencyTextField.setMinWidth(300);

        currencyTextField.setVisible(false);
        currencyTextField.setManaged(false);
        currencyComboBox.setVisible(false);
        currencyComboBox.setManaged(false);

        hBox.getChildren().addAll(countryComboBox, currencyTextField, currencyComboBox);
        GridPane.setRowIndex(hBox, gridRow);
        GridPane.setColumnIndex(hBox, 1);
        gridPane.getChildren().add(hBox);

        countryComboBox.setPromptText("Select country of bank");
        countryComboBox.setConverter(new StringConverter<Country>() {
            @Override
            public String toString(Country country) {
                return country.name + " (" + country.code + ")";
            }

            @Override
            public Country fromString(String s) {
                return null;
            }
        });
        countryComboBox.setOnAction(e -> {
            Country selectedItem = countryComboBox.getSelectionModel().getSelectedItem();
            sepaAccount.setCountry(selectedItem);
            TradeCurrency currency = CurrencyUtil.getCurrencyByCountryCode(selectedItem.code);
            setupCurrency(selectedItem, currency);

            updateCountriesSelection(true, euroCountryCheckBoxes);
            updateCountriesSelection(true, nonEuroCountryCheckBoxes);
            updateFromInputs();
        });

        addEuroCountriesGrid(true);
        addNonEuroCountriesGrid(true);
        addAllowedPeriod();
        addAccountNameTextFieldWithAutoFillCheckBox();

        countryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllSepaCountries()));
        Country country = CountryUtil.getDefaultCountry();
        if (CountryUtil.getAllSepaCountries().contains(country)) {
            countryComboBox.getSelectionModel().select(country);
            sepaAccount.setCountry(country);
            TradeCurrency currency = CurrencyUtil.getCurrencyByCountryCode(country.code);
            setupCurrency(country, currency);
        }

        updateFromInputs();
    }

    private void setupCurrency(Country country, TradeCurrency currency) {
        if (CountryUtil.getAllSepaEuroCountries().contains(country)) {
            currencyTextField.setVisible(true);
            currencyTextField.setManaged(true);
            currencyComboBox.setVisible(false);
            currencyComboBox.setManaged(false);
            sepaAccount.setSingleTradeCurrency(currency);
            currencyTextField.setText("Currency: " + currency.getNameAndCode());
        } else {
            currencyComboBox.setVisible(true);
            currencyComboBox.setManaged(true);
            currencyTextField.setVisible(false);
            currencyTextField.setManaged(false);
            currencyComboBox.setItems(
                    FXCollections.observableArrayList(currency, CurrencyUtil.getFiatCurrency("EUR").get()));
            currencyComboBox.setOnAction(e2 -> {
                sepaAccount.setSingleTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem());
                updateCountriesSelection(true, euroCountryCheckBoxes);
                autoFillNameTextField();
            });
            currencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
                @Override
                public String toString(TradeCurrency currency) {
                    return currency.getNameAndCode();
                }

                @Override
                public TradeCurrency fromString(String string) {
                    return null;
                }
            });
            currencyComboBox.getSelectionModel().select(0);
        }
    }

    private void addEuroCountriesGrid(boolean isEditable) {
        addCountriesGrid(isEditable, "Accept trades from these Euro countries:", euroCountryCheckBoxes,
                CountryUtil.getAllSepaEuroCountries());
    }

    private void addNonEuroCountriesGrid(boolean isEditable) {
        addCountriesGrid(isEditable, "Accept trades from these non-Euro countries:", nonEuroCountryCheckBoxes,
                CountryUtil.getAllSepaNonEuroCountries());
    }

    private void addCountriesGrid(boolean isEditable, String title, List<CheckBox> checkBoxList,
            List<Country> dataProvider) {
        Label label = addLabel(gridPane, ++gridRow, title, 0);
        label.setWrapText(true);
        label.setMaxWidth(180);
        label.setTextAlignment(TextAlignment.RIGHT);
        GridPane.setHalignment(label, HPos.RIGHT);
        GridPane.setValignment(label, VPos.TOP);
        FlowPane flowPane = new FlowPane();
        flowPane.setPadding(new Insets(10, 10, 10, 10));
        flowPane.setVgap(10);
        flowPane.setHgap(10);
        flowPane.setMinHeight(55);

        if (isEditable)
            flowPane.setId("flow-pane-checkboxes-bg");
        else
            flowPane.setId("flow-pane-checkboxes-non-editable-bg");

        dataProvider.stream().forEach(country -> {
            final String countryCode = country.code;
            CheckBox checkBox = new CheckBox(countryCode);
            checkBox.setUserData(countryCode);
            checkBoxList.add(checkBox);
            checkBox.setMouseTransparent(!isEditable);
            checkBox.setMinWidth(45);
            checkBox.setMaxWidth(45);
            checkBox.setTooltip(new Tooltip(country.name));
            checkBox.setOnAction(event -> {
                if (checkBox.isSelected())
                    sepaAccount.addAcceptedCountry(countryCode);
                else
                    sepaAccount.removeAcceptedCountry(countryCode);

                updateAllInputsValid();
            });
            flowPane.getChildren().add(checkBox);
        });
        updateCountriesSelection(isEditable, checkBoxList);

        GridPane.setRowIndex(flowPane, gridRow);
        GridPane.setColumnIndex(flowPane, 1);
        gridPane.getChildren().add(flowPane);
    }

    private void updateCountriesSelection(boolean isEditable, List<CheckBox> checkBoxList) {
        checkBoxList.stream().forEach(checkBox -> {
            String countryCode = (String) checkBox.getUserData();
            TradeCurrency selectedCurrency = sepaAccount.getSelectedTradeCurrency();
            if (selectedCurrency == null) {
                Country country = CountryUtil.getDefaultCountry();
                if (CountryUtil.getAllSepaCountries().contains(country))
                    selectedCurrency = CurrencyUtil.getCurrencyByCountryCode(country.code);
            }

            boolean selected;

            if (isEditable && selectedCurrency != null) {
                selected = CurrencyUtil.getCurrencyByCountryCode(countryCode).getCode()
                        .equals(selectedCurrency.getCode());

                if (selected)
                    sepaAccount.addAcceptedCountry(countryCode);
                else
                    sepaAccount.removeAcceptedCountry(countryCode);
            } else {
                selected = sepaAccount.getAcceptedCountryCodes().contains(countryCode);
            }
            checkBox.setSelected(selected);
        });
    }

    @Override
    protected void autoFillNameTextField() {
        if (useCustomAccountNameCheckBox != null && !useCustomAccountNameCheckBox.isSelected()) {
            String iban = ibanInputTextField.getText();
            if (iban.length() > 9)
                iban = StringUtils.abbreviate(iban, 9);
            String method = BSResources.get(paymentAccount.getPaymentMethod().getId());
            CountryBasedPaymentAccount countryBasedPaymentAccount = (CountryBasedPaymentAccount) this.paymentAccount;
            String country = countryBasedPaymentAccount.getCountry() != null
                    ? countryBasedPaymentAccount.getCountry().code
                    : "?";
            String currency = this.paymentAccount.getSingleTradeCurrency() != null
                    ? this.paymentAccount.getSingleTradeCurrency().getCode()
                    : "?";
            accountNameTextField.setText(
                    method.concat(" (").concat(currency).concat("/").concat(country).concat("): ").concat(iban));
        }
    }

    @Override
    public void updateAllInputsValid() {
        allInputsValid.set(isAccountNameValid() && bicValidator.validate(sepaAccount.getBic()).isValid
                && ibanValidator.validate(sepaAccount.getIban()).isValid
                && inputValidator.validate(sepaAccount.getHolderName()).isValid
                && sepaAccount.getAcceptedCountryCodes().size() > 0 && sepaAccount.getSingleTradeCurrency() != null
                && sepaAccount.getCountry() != null);
    }

    @Override
    public void addFormForDisplayAccount() {
        gridRowFrom = gridRow;
        addLabelTextField(gridPane, gridRow, "Account name:", sepaAccount.getAccountName(),
                Layout.FIRST_ROW_AND_GROUP_DISTANCE);
        addLabelTextField(gridPane, ++gridRow, "Payment method:",
                BSResources.get(sepaAccount.getPaymentMethod().getId()));
        addLabelTextField(gridPane, ++gridRow, "Account holder name:", sepaAccount.getHolderName());
        addLabelTextField(gridPane, ++gridRow, "IBAN:", sepaAccount.getIban()).second.setMouseTransparent(false);
        addLabelTextField(gridPane, ++gridRow, "BIC:", sepaAccount.getBic()).second.setMouseTransparent(false);
        addLabelTextField(gridPane, ++gridRow, "Country of Bank:",
                sepaAccount.getCountry() != null ? sepaAccount.getCountry().name : "");
        addLabelTextField(gridPane, ++gridRow, "Currency:", sepaAccount.getSingleTradeCurrency().getNameAndCode());
        String countries;
        Tooltip tooltip = null;
        if (CountryUtil.containsAllSepaEuroCountries(sepaAccount.getAcceptedCountryCodes())) {
            countries = "All Euro countries";
        } else {
            countries = CountryUtil.getCodesString(sepaAccount.getAcceptedCountryCodes());
            tooltip = new Tooltip(CountryUtil.getNamesByCodesString(sepaAccount.getAcceptedCountryCodes()));
        }
        TextField acceptedCountries = addLabelTextField(gridPane, ++gridRow, "Accepted countries:",
                countries).second;
        if (tooltip != null) {
            acceptedCountries.setMouseTransparent(false);
            acceptedCountries.setTooltip(tooltip);
        }
        addAllowedPeriod();
    }
}