Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HalCash #1619

Merged
merged 5 commits into from
Aug 14, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions src/main/java/bisq/desktop/components/paymentmethods/HalCashForm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* 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.Layout;
import bisq.desktop.util.validation.HalCashValidator;

import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.HalCashAccountPayload;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.util.BSFormatter;
import bisq.core.util.validation.InputValidator;

import org.apache.commons.lang3.StringUtils;

import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;

import static bisq.desktop.util.FormBuilder.addLabelInputTextField;
import static bisq.desktop.util.FormBuilder.addLabelTextField;

public class HalCashForm extends PaymentMethodForm {
private final HalCashAccount halCashAccount;
private final HalCashValidator halCashValidator;
private InputTextField mobileNrInputTextField;

public static int addFormForBuyer(GridPane gridPane, int gridRow,
PaymentAccountPayload paymentAccountPayload) {
addLabelTextField(gridPane, ++gridRow, Res.get("payment.mobile"),
((HalCashAccountPayload) paymentAccountPayload).getMobileNr());
return gridRow;
}

public HalCashForm(PaymentAccount paymentAccount, AccountAgeWitnessService accountAgeWitnessService, HalCashValidator halCashValidator,
InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
this.halCashAccount = (HalCashAccount) paymentAccount;
this.halCashValidator = halCashValidator;
}

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

mobileNrInputTextField = addLabelInputTextField(gridPane, ++gridRow,
Res.get("payment.mobile")).second;
mobileNrInputTextField.setValidator(halCashValidator);
mobileNrInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
halCashAccount.setMobileNr(newValue);
updateFromInputs();
});

TradeCurrency singleTradeCurrency = halCashAccount.getSingleTradeCurrency();
String nameAndCode = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : "null";
addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.currency"), nameAndCode);
addLimitations();
addAccountNameTextFieldWithAutoFillCheckBox();
}

@Override
protected void autoFillNameTextField() {
if (useCustomAccountNameCheckBox != null && !useCustomAccountNameCheckBox.isSelected()) {
String mobileNr = mobileNrInputTextField.getText();
mobileNr = StringUtils.abbreviate(mobileNr, 9);
String method = Res.get(paymentAccount.getPaymentMethod().getId());
accountNameTextField.setText(method.concat(": ").concat(mobileNr));
}
}

@Override
public void addFormForDisplayAccount() {
gridRowFrom = gridRow;
addLabelTextField(gridPane, gridRow, Res.get("payment.account.name"),
halCashAccount.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.paymentMethod"),
Res.get(halCashAccount.getPaymentMethod().getId()));
TextField field = addLabelTextField(gridPane, ++gridRow, Res.get("payment.mobile"),
halCashAccount.getMobileNr()).second;
field.setMouseTransparent(false);
TradeCurrency singleTradeCurrency = halCashAccount.getSingleTradeCurrency();
String nameAndCode = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : "null";
addLabelTextField(gridPane, ++gridRow, Res.getWithCol("shared.currency"), nameAndCode);
addLimitations();
}

@Override
public void updateAllInputsValid() {
allInputsValid.set(isAccountNameValid()
&& halCashValidator.validate(halCashAccount.getMobileNr()).isValid
&& halCashAccount.getTradeCurrencies().size() > 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import bisq.desktop.components.paymentmethods.ClearXchangeForm;
import bisq.desktop.components.paymentmethods.F2FForm;
import bisq.desktop.components.paymentmethods.FasterPaymentsForm;
import bisq.desktop.components.paymentmethods.HalCashForm;
import bisq.desktop.components.paymentmethods.InteracETransferForm;
import bisq.desktop.components.paymentmethods.MoneyBeamForm;
import bisq.desktop.components.paymentmethods.MoneyGramForm;
Expand Down Expand Up @@ -59,6 +60,7 @@
import bisq.desktop.util.validation.ChaseQuickPayValidator;
import bisq.desktop.util.validation.ClearXchangeValidator;
import bisq.desktop.util.validation.F2FValidator;
import bisq.desktop.util.validation.HalCashValidator;
import bisq.desktop.util.validation.IBANValidator;
import bisq.desktop.util.validation.InteracETransferValidator;
import bisq.desktop.util.validation.MoneyBeamValidator;
Expand All @@ -77,6 +79,7 @@
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.ClearXchangeAccount;
import bisq.core.payment.F2FAccount;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.MoneyGramAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountFactory;
Expand Down Expand Up @@ -143,6 +146,7 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
private final InteracETransferValidator interacETransferValidator;
private final USPostalMoneyOrderValidator usPostalMoneyOrderValidator;
private final WeChatPayValidator weChatPayValidator;
private final HalCashValidator halCashValidator;
private final F2FValidator f2FValidator;
private final AccountAgeWitnessService accountAgeWitnessService;
private final BSFormatter formatter;
Expand Down Expand Up @@ -174,6 +178,7 @@ public FiatAccountsView(FiatAccountsViewModel model,
InteracETransferValidator interacETransferValidator,
USPostalMoneyOrderValidator usPostalMoneyOrderValidator,
WeChatPayValidator weChatPayValidator,
HalCashValidator halCashValidator,
F2FValidator f2FValidator,
AccountAgeWitnessService accountAgeWitnessService,
BSFormatter formatter) {
Expand All @@ -197,6 +202,7 @@ public FiatAccountsView(FiatAccountsViewModel model,
this.interacETransferValidator = interacETransferValidator;
this.usPostalMoneyOrderValidator = usPostalMoneyOrderValidator;
this.weChatPayValidator = weChatPayValidator;
this.halCashValidator = halCashValidator;
this.f2FValidator = f2FValidator;
this.accountAgeWitnessService = accountAgeWitnessService;
this.formatter = formatter;
Expand Down Expand Up @@ -248,6 +254,14 @@ private void onSaveNewAccount(PaymentAccount paymentAccount) {
.actionButtonText(Res.get("shared.iUnderstand"))
.onAction(() -> doSaveNewAccount(paymentAccount))
.show();
} else if (paymentAccount instanceof HalCashAccount) {
// HalCash has no chargeback risk so we don't show the text from payment.limits.info.
new Popup<>().information(Res.get("payment.halCash.info"))
.width(700)
.closeButtonText(Res.get("shared.cancel"))
.actionButtonText(Res.get("shared.iUnderstand"))
.onAction(() -> doSaveNewAccount(paymentAccount))
.show();
} else {
new Popup<>().information(Res.get("payment.limits.info",
formatter.formatCoinWithCode(maxTradeLimitFirstMonth),
Expand Down Expand Up @@ -499,6 +513,8 @@ private PaymentMethodForm getPaymentMethodForm(PaymentMethod paymentMethod, Paym
return new WesternUnionForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
case PaymentMethod.CASH_DEPOSIT_ID:
return new CashDepositForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
case PaymentMethod.HAL_CASH_ID:
return new HalCashForm(paymentAccount, accountAgeWitnessService, halCashValidator, inputValidator, root, gridRow, formatter);
case PaymentMethod.F2F_ID:
return new F2FForm(paymentAccount, accountAgeWitnessService, f2FValidator, inputValidator, root, gridRow, formatter);
default:
Expand Down
17 changes: 14 additions & 3 deletions src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import bisq.core.payment.BankAccount;
import bisq.core.payment.CountryBasedPaymentAccount;
import bisq.core.payment.F2FAccount;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.SameBankAccount;
import bisq.core.payment.SepaAccount;
Expand Down Expand Up @@ -307,7 +308,7 @@ void onTabSelected(boolean isSelected) {

@SuppressWarnings("ConstantConditions")
Offer createAndGetOffer() {
final boolean useMarketBasedPriceValue = isUseMarketBasedPriceValue();
boolean useMarketBasedPriceValue = isUseMarketBasedPriceValue();
long priceAsLong = price.get() != null && !useMarketBasedPriceValue ? price.get().getValue() : 0L;
String currencyCode = tradeCurrencyCode.get();
boolean isCryptoCurrency = CurrencyUtil.isCryptoCurrency(currencyCode);
Expand Down Expand Up @@ -662,7 +663,13 @@ void calculateVolume() {
!amount.get().isZero() &&
!price.get().isZero()) {
try {
volume.set(price.get().getVolumeByAmount(amount.get()));
Volume volumeByAmount = price.get().getVolumeByAmount(amount.get());

// For HalCash we want multiple of 10 EUR
if (isHalCashAccount())
volumeByAmount = OfferUtil.getAdjustedVolumeForHalCash(volumeByAmount);

volume.set(volumeByAmount);
} catch (Throwable t) {
log.error(t.toString());
}
Expand Down Expand Up @@ -743,7 +750,7 @@ void setBuyerSecurityDeposit(Coin buyerSecurityDeposit) {
}

protected boolean isUseMarketBasedPriceValue() {
return marketPriceAvailable && useMarketBasedPrice.get();
return marketPriceAvailable && useMarketBasedPrice.get() && !isHalCashAccount();
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -813,4 +820,8 @@ public boolean isCurrencyForMakerFeeBtc() {
public boolean isBsqForFeeAvailable() {
return OfferUtil.isBsqForFeeAvailable(bsqWalletService, amount.get(), marketPriceAvailable, marketPriceMargin);
}

public boolean isHalCashAccount() {
return paymentAccount instanceof HalCashAccount;
}
}
23 changes: 13 additions & 10 deletions src/main/java/bisq/desktop/main/offer/MutableOfferView.java
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ protected void doActivate() {
onPaymentAccountsComboBoxSelected();

balanceTextField.setTargetAmount(model.getDataModel().totalToPayAsCoinProperty().get());
updateMarketPriceAvailable();
updatePriceToggle();
}
}

Expand Down Expand Up @@ -297,7 +297,7 @@ public void initWithData(OfferPayload.Direction direction, TradeCurrency tradeCu
percentagePriceDescription.setText(Res.get("shared.aboveInPercent"));
}

updateMarketPriceAvailable();
updatePriceToggle();

if (!model.getDataModel().isMakerFeeValid() && model.getDataModel().getMakerFee() != null)
showInsufficientBsqFundsForBtcFeePaymentPopup();
Expand Down Expand Up @@ -502,6 +502,8 @@ else if (tradeCurrencies.contains(model.getTradeCurrency()))
}

currencyComboBox.setOnAction(currencyComboBoxSelectionHandler);

updatePriceToggle();
}

private void onCurrencyComboBoxSelected() {
Expand Down Expand Up @@ -703,7 +705,7 @@ private void createListeners() {
}
};

marketPriceAvailableListener = (observable, oldValue, newValue) -> updateMarketPriceAvailable();
marketPriceAvailableListener = (observable, oldValue, newValue) -> updatePriceToggle();

getShowWalletFundedNotificationListener = (observable, oldValue, newValue) -> {
if (newValue) {
Expand Down Expand Up @@ -756,15 +758,16 @@ private Label createPopoverLabel(String text) {
return label;
}

protected void updateMarketPriceAvailable() {
protected void updatePriceToggle() {
int marketPriceAvailableValue = model.marketPriceAvailableProperty.get();
if (marketPriceAvailableValue > -1) {
boolean isMarketPriceAvailable = marketPriceAvailableValue == 1;
percentagePriceBox.setVisible(isMarketPriceAvailable);
percentagePriceBox.setManaged(isMarketPriceAvailable);
priceTypeToggleButton.setVisible(isMarketPriceAvailable);
priceTypeToggleButton.setManaged(isMarketPriceAvailable);
boolean fixedPriceSelected = !model.getDataModel().getUseMarketBasedPrice().get() || !isMarketPriceAvailable;
boolean showPriceToggle = marketPriceAvailableValue == 1 &&
!model.getDataModel().isHalCashAccount();
percentagePriceBox.setVisible(showPriceToggle);
percentagePriceBox.setManaged(showPriceToggle);
priceTypeToggleButton.setVisible(showPriceToggle);
priceTypeToggleButton.setManaged(showPriceToggle);
boolean fixedPriceSelected = !model.getDataModel().getUseMarketBasedPrice().get() || !showPriceToggle;
updatePriceToggleButtons(fixedPriceSelected);
}
}
Expand Down
35 changes: 30 additions & 5 deletions src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.payment.PaymentAccount;
import bisq.core.provider.price.MarketPrice;
import bisq.core.provider.price.PriceFeedService;
Expand Down Expand Up @@ -683,6 +684,9 @@ void onFocusOutAmountTextField(boolean oldValue, boolean newValue) {
if (minAmount.get() != null)
minAmountValidationResult.set(isBtcInputValid(minAmount.get()));
}

// We want to trigger a recalculation of the volume
UserThread.execute(() -> onFocusOutVolumeTextField(true, false));
}
}

Expand Down Expand Up @@ -723,6 +727,13 @@ void onFocusOutPriceTextField(boolean oldValue, boolean newValue) {
dataModel.calculateAmount();
applyMakerFee();
}

// We want to trigger a recalculation of the volume and minAmount
UserThread.execute(() -> {
onFocusOutVolumeTextField(true, false);
// We also need to update minAmount
onFocusOutMinAmountTextField(true, false);
});
}
}

Expand All @@ -743,8 +754,16 @@ void onFocusOutVolumeTextField(boolean oldValue, boolean newValue) {
if (result.isValid) {
setVolumeToModel();
ignoreVolumeStringListener = true;
if (dataModel.getVolume().get() != null)
volume.set(btcFormatter.formatVolume(dataModel.getVolume().get()));

Volume volume = dataModel.getVolume().get();
if (volume != null) {
// For HalCash we want multiple of 10 EUR
if (dataModel.isHalCashAccount())
volume = OfferUtil.getAdjustedVolumeForHalCash(volume);

this.volume.set(btcFormatter.formatVolume(volume));
}

ignoreVolumeStringListener = false;

dataModel.calculateAmount();
Expand Down Expand Up @@ -958,10 +977,16 @@ private void setAmountToModel() {
}

private void setMinAmountToModel() {
if (minAmount.get() != null && !minAmount.get().isEmpty())
dataModel.setMinAmount(btcFormatter.parseToCoinWith4Decimals(minAmount.get()));
else
if (minAmount.get() != null && !minAmount.get().isEmpty()) {
Coin minAmount = btcFormatter.parseToCoinWith4Decimals(this.minAmount.get());

if (dataModel.isHalCashAccount() && dataModel.getPrice().get() != null)
minAmount = OfferUtil.getAdjustedMinAmountForHalCash(minAmount, dataModel.getPrice().get());

dataModel.setMinAmount(minAmount);
} else {
dataModel.setMinAmount(null);
}
}

private void setPriceToModel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountUtil;
Expand Down Expand Up @@ -490,8 +491,11 @@ void calculateVolume() {
if (tradePrice != null && offer != null &&
amount.get() != null &&
!amount.get().isZero()) {
volume.set(tradePrice.getVolumeByAmount(amount.get()));
//volume.set(new ExchangeRate(tradePrice).coinToFiat(amountAsCoin.get()));
Volume volumeByAmount = tradePrice.getVolumeByAmount(amount.get());
if (offer.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID))
volumeByAmount = OfferUtil.getAdjustedVolumeForHalCash(volumeByAmount);

volume.set(volumeByAmount);

updateBalance();
}
Expand Down
Loading