Add payment method: moneygram

This commit is contained in:
Bernard Labno 2018-04-27 15:38:31 +02:00
parent 0b283767fa
commit edd421654a
No known key found for this signature in database
GPG Key ID: FB792CBD872450F0
4 changed files with 315 additions and 0 deletions

View File

@ -0,0 +1,269 @@
/*
* This file is part of Bisq.
*
* Bisq 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.
*
* Bisq 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 Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.components.paymentmethods;
import bisq.desktop.components.InputTextField;
import bisq.desktop.util.BSFormatter;
import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.desktop.util.validation.EmailValidator;
import bisq.core.locale.BankUtil;
import bisq.core.locale.Country;
import bisq.core.locale.CountryUtil;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Region;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.MoneyGramAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.MoneyGramAccountPayload;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.util.validation.InputValidator;
import bisq.common.util.Tuple2;
import bisq.common.util.Tuple3;
import org.apache.commons.lang3.StringUtils;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.collections.FXCollections;
import javafx.util.StringConverter;
import lombok.extern.slf4j.Slf4j;
import static bisq.desktop.util.FormBuilder.addLabel;
import static bisq.desktop.util.FormBuilder.addLabelTextFieldWithCopyIcon;
@Slf4j
public class MoneyGramForm extends PaymentMethodForm {
public static int addFormForBuyer(GridPane gridPane, int gridRow,
PaymentAccountPayload paymentAccountPayload) {
final MoneyGramAccountPayload payload = (MoneyGramAccountPayload) paymentAccountPayload;
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.getWithCol("payment.account.fullName"),
payload.getHolderName());
FormBuilder.addLabelTextFieldWithCopyIcon(gridPane, ++gridRow,
Res.getWithCol("payment.bank.country"),
CountryUtil.getNameAndCode(((MoneyGramAccountPayload) paymentAccountPayload).getCountryCode()));
if (BankUtil.isStateRequired(payload.getCountryCode()))
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.account.state"),
payload.getState());
addLabelTextFieldWithCopyIcon(gridPane, ++gridRow, Res.get("payment.email"),
payload.getEmail());
return gridRow;
}
protected final MoneyGramAccountPayload moneyGramAccountPayload;
protected InputTextField holderNameInputTextField, emailInputTextField, stateInputTextField;
private Label stateLabel;
private final EmailValidator emailValidator;
public MoneyGramForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, InputValidator inputValidator,
GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
this.moneyGramAccountPayload = (MoneyGramAccountPayload) paymentAccount.paymentAccountPayload;
emailValidator = new EmailValidator();
}
@Override
public void addFormForDisplayAccount() {
gridRowFrom = gridRow;
final Country country = getMoneyGramPaymentAccount().getCountry();
FormBuilder.addLabelTextField(gridPane, gridRow, Res.get("payment.account.name"), paymentAccount.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.paymentMethod"),
Res.get(paymentAccount.getPaymentMethod().getId()));
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.get("payment.country"), country != null ? country.name : "");
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.getWithCol("payment.account.fullName"),
moneyGramAccountPayload.getHolderName());
if (BankUtil.isStateRequired(moneyGramAccountPayload.getCountryCode()))
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.get("payment.account.state"),
moneyGramAccountPayload.getState()).second.setMouseTransparent(false);
FormBuilder.addLabelTextField(gridPane, ++gridRow, Res.get("payment.email"),
moneyGramAccountPayload.getEmail());
addLimitations();
addCurrenciesGrid(false);
}
@Override
public void addFormForAddAccount() {
gridRowFrom = gridRow + 1;
Tuple3<Label, ComboBox, ComboBox> tuple3 = FormBuilder.addLabelComboBoxComboBox(gridPane, ++gridRow, Res.get("payment.country"));
//noinspection unchecked,unchecked,unchecked
ComboBox<Region> regionComboBox = tuple3.second;
regionComboBox.setPromptText(Res.get("payment.select.region"));
regionComboBox.setConverter(new StringConverter<Region>() {
@Override
public String toString(Region region) {
return region.name;
}
@Override
public Region fromString(String s) {
return null;
}
});
regionComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllRegions()));
//noinspection unchecked,unchecked,unchecked
ComboBox<Country> countryComboBox = tuple3.third;
countryComboBox.setVisibleRowCount(15);
countryComboBox.setDisable(true);
countryComboBox.setPromptText(Res.get("payment.select.country"));
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();
if (selectedItem != null) {
getMoneyGramPaymentAccount().setCountry(selectedItem);
updateFromInputs();
applyIsStateRequired();
stateInputTextField.setText("");
}
});
regionComboBox.setOnAction(e -> {
Region selectedItem = regionComboBox.getSelectionModel().getSelectedItem();
if (selectedItem != null) {
countryComboBox.setDisable(false);
countryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllCountriesForRegion(selectedItem)));
}
});
holderNameInputTextField = FormBuilder.addLabelInputTextField(gridPane,
++gridRow, Res.getWithCol("payment.account.fullName")).second;
holderNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
moneyGramAccountPayload.setHolderName(newValue);
updateFromInputs();
});
holderNameInputTextField.setValidator(inputValidator);
final Tuple2<Label, InputTextField> tuple2 = FormBuilder.addLabelInputTextField(gridPane, ++gridRow, Res.get("payment.account.state"));
stateLabel = tuple2.first;
stateInputTextField = tuple2.second;
stateInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
moneyGramAccountPayload.setState(newValue);
updateFromInputs();
});
applyIsStateRequired();
emailInputTextField = FormBuilder.addLabelInputTextField(gridPane, ++gridRow, Res.get("payment.email")).second;
emailInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
moneyGramAccountPayload.setEmail(newValue);
updateFromInputs();
});
emailInputTextField.setValidator(emailValidator);
addCurrenciesGrid(true);
addLimitations();
addAccountNameTextFieldWithAutoFillCheckBox();
updateFromInputs();
}
private void addCurrenciesGrid(boolean isEditable) {
Label label = addLabel(gridPane, ++gridRow, Res.get("payment.supportedCurrencies"), 0);
GridPane.setValignment(label, VPos.TOP);
FlowPane flowPane = new FlowPane();
flowPane.setPadding(new Insets(10, 10, 10, 10));
flowPane.setVgap(10);
flowPane.setHgap(10);
if (isEditable)
flowPane.setId("flow-pane-checkboxes-bg");
else
flowPane.setId("flow-pane-checkboxes-non-editable-bg");
CurrencyUtil.getAllMoneyGramCurrencies().forEach(e -> {
CheckBox checkBox = new CheckBox(e.getCode());
checkBox.setMouseTransparent(!isEditable);
checkBox.setSelected(paymentAccount.getTradeCurrencies().contains(e));
checkBox.setMinWidth(60);
checkBox.setMaxWidth(checkBox.getMinWidth());
checkBox.setTooltip(new Tooltip(e.getName()));
checkBox.setOnAction(event -> {
if (checkBox.isSelected())
paymentAccount.addCurrency(e);
else
paymentAccount.removeCurrency(e);
updateAllInputsValid();
});
flowPane.getChildren().add(checkBox);
});
GridPane.setRowIndex(flowPane, gridRow);
GridPane.setColumnIndex(flowPane, 1);
gridPane.getChildren().add(flowPane);
}
private void applyIsStateRequired() {
final boolean stateRequired = BankUtil.isStateRequired(moneyGramAccountPayload.getCountryCode());
stateLabel.setManaged(stateRequired);
stateLabel.setVisible(stateRequired);
stateInputTextField.setManaged(stateRequired);
stateInputTextField.setVisible(stateRequired);
}
private MoneyGramAccount getMoneyGramPaymentAccount() {
return (MoneyGramAccount) this.paymentAccount;
}
@Override
protected void autoFillNameTextField() {
if (useCustomAccountNameCheckBox != null && !useCustomAccountNameCheckBox.isSelected()) {
accountNameTextField.setText(Res.get(paymentAccount.getPaymentMethod().getId())
.concat(": ")
.concat(StringUtils.abbreviate(holderNameInputTextField.getText(), 9)));
}
}
@Override
public void updateAllInputsValid() {
boolean result = isAccountNameValid()
&& getMoneyGramPaymentAccount().getCountry() != null
&& inputValidator.validate(moneyGramAccountPayload.getHolderName()).isValid
&& emailValidator.validate(moneyGramAccountPayload.getEmail()).isValid
&& paymentAccount.getTradeCurrencies().size() > 0;
allInputsValid.set(result);
}
}

View File

@ -30,6 +30,7 @@ import bisq.desktop.components.paymentmethods.ClearXchangeForm;
import bisq.desktop.components.paymentmethods.FasterPaymentsForm;
import bisq.desktop.components.paymentmethods.InteracETransferForm;
import bisq.desktop.components.paymentmethods.MoneyBeamForm;
import bisq.desktop.components.paymentmethods.MoneyGramForm;
import bisq.desktop.components.paymentmethods.NationalBankForm;
import bisq.desktop.components.paymentmethods.OKPayForm;
import bisq.desktop.components.paymentmethods.PaymentMethodForm;
@ -73,6 +74,7 @@ import bisq.core.app.BisqEnvironment;
import bisq.core.locale.Res;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.ClearXchangeAccount;
import bisq.core.payment.MoneyGramAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountFactory;
import bisq.core.payment.WesternUnionAccount;
@ -252,6 +254,13 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
.actionButtonText(Res.get("shared.iUnderstand"))
.onAction(() -> doSaveNewAccount(paymentAccount))
.show();
} else if (paymentAccount instanceof MoneyGramAccount) {
new Popup<>().information(Res.get("payment.moneyGram.info"))
.width(700)
.closeButtonText(Res.get("shared.cancel"))
.actionButtonText(Res.get("shared.iUnderstand"))
.onAction(() -> doSaveNewAccount(paymentAccount))
.show();
} else {
doSaveNewAccount(paymentAccount);
}
@ -467,6 +476,8 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
return new InteracETransferForm(paymentAccount, accountAgeWitnessService, interacETransferValidator, inputValidator, root, gridRow, formatter);
case PaymentMethod.US_POSTAL_MONEY_ORDER_ID:
return new USPostalMoneyOrderForm(paymentAccount, accountAgeWitnessService, usPostalMoneyOrderValidator, inputValidator, root, gridRow, formatter);
case PaymentMethod.MONEY_GRAM_ID:
return new MoneyGramForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
case PaymentMethod.WESTERN_UNION_ID:
return new WesternUnionForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
case PaymentMethod.CASH_DEPOSIT_ID:

View File

@ -29,6 +29,7 @@ import bisq.desktop.components.paymentmethods.CryptoCurrencyForm;
import bisq.desktop.components.paymentmethods.FasterPaymentsForm;
import bisq.desktop.components.paymentmethods.InteracETransferForm;
import bisq.desktop.components.paymentmethods.MoneyBeamForm;
import bisq.desktop.components.paymentmethods.MoneyGramForm;
import bisq.desktop.components.paymentmethods.NationalBankForm;
import bisq.desktop.components.paymentmethods.OKPayForm;
import bisq.desktop.components.paymentmethods.PerfectMoneyForm;
@ -53,6 +54,7 @@ import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.payment.payload.CashDepositAccountPayload;
import bisq.core.payment.payload.CryptoCurrencyAccountPayload;
import bisq.core.payment.payload.MoneyGramAccountPayload;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.payment.payload.USPostalMoneyOrderAccountPayload;
@ -245,6 +247,9 @@ public class BuyerStep2View extends TradeStepView {
case PaymentMethod.CASH_DEPOSIT_ID:
gridRow = CashDepositForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
break;
case PaymentMethod.MONEY_GRAM_ID:
gridRow = MoneyGramForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
break;
case PaymentMethod.WESTERN_UNION_ID:
gridRow = WesternUnionForm.addFormForBuyer(gridPane, gridRow, paymentAccountPayload);
break;
@ -338,6 +343,24 @@ public class BuyerStep2View extends TradeStepView {
} else {
showConfirmPaymentStartedPopup();
}
} else if (model.dataModel.getSellersPaymentAccountPayload() instanceof MoneyGramAccountPayload) {
//noinspection UnusedAssignment
//noinspection ConstantConditions
String key = "moneyGramMTCNSent";
if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) {
String email = ((MoneyGramAccountPayload) model.dataModel.getSellersPaymentAccountPayload()).getEmail();
Popup popup = new Popup<>();
popup.headLine(Res.get("portfolio.pending.step2_buyer.moneyGramMTCNInfo.headline"))
.feedback(Res.get("portfolio.pending.step2_buyer.moneyGramMTCNInfo.msg", email))
.onAction(this::showConfirmPaymentStartedPopup)
.actionButtonText(Res.get("shared.yes"))
.closeButtonText(Res.get("shared.no"))
.onClose(popup::hide)
.dontShowAgainId(key)
.show();
} else {
showConfirmPaymentStartedPopup();
}
} else {
showConfirmPaymentStartedPopup();
}
@ -432,6 +455,15 @@ public class BuyerStep2View extends TradeStepView {
paymentDetailsForTradePopup + ".\n" +
copyPaste + "\n\n" +
extra;
} else if (paymentAccountPayload instanceof MoneyGramAccountPayload) {
final String email = ((MoneyGramAccountPayload) paymentAccountPayload).getEmail();
final String extra = Res.get("portfolio.pending.step2_buyer.moneyGram.extra", email);
message += Res.get("portfolio.pending.step2_buyer.moneyGram",
amount) +
accountDetails +
paymentDetailsForTradePopup + ".\n" +
copyPaste + "\n\n" +
extra;
} else if (paymentAccountPayload instanceof USPostalMoneyOrderAccountPayload) {
//noinspection UnusedAssignment
message += Res.get("portfolio.pending.step2_buyer.postal", amount) +

View File

@ -30,6 +30,7 @@ import bisq.core.locale.Res;
import bisq.core.payment.payload.BankAccountPayload;
import bisq.core.payment.payload.CashDepositAccountPayload;
import bisq.core.payment.payload.CryptoCurrencyAccountPayload;
import bisq.core.payment.payload.MoneyGramAccountPayload;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.SepaAccountPayload;
import bisq.core.payment.payload.SepaInstantAccountPayload;
@ -315,6 +316,8 @@ public class SellerStep3View extends TradeStepView {
message = message + Res.get("portfolio.pending.step3_seller.cash", part);
else if (paymentAccountPayload instanceof WesternUnionAccountPayload)
message = message + Res.get("portfolio.pending.step3_seller.westernUnion", part);
else if (paymentAccountPayload instanceof MoneyGramAccountPayload)
message = message + Res.get("portfolio.pending.step3_seller.moneyGram", part);
Optional<String> optionalHolderName = getOptionalHolderName();
if (optionalHolderName.isPresent()) {