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

Round fiat volume #1623

Merged
merged 2 commits into from
Aug 15, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
42 changes: 25 additions & 17 deletions src/main/java/bisq/desktop/main/offer/MutableOfferDataModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,32 +114,34 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
private final BalanceListener btcBalanceListener;
private final SetChangeListener<PaymentAccount> paymentAccountsChangeListener;

private OfferPayload.Direction direction;
private TradeCurrency tradeCurrency;
private final StringProperty tradeCurrencyCode = new SimpleStringProperty();
private final BooleanProperty useMarketBasedPrice = new SimpleBooleanProperty();
private final Coin sellerSecurityDeposit;

protected OfferPayload.Direction direction;
protected TradeCurrency tradeCurrency;
protected final StringProperty tradeCurrencyCode = new SimpleStringProperty();
protected final BooleanProperty useMarketBasedPrice = new SimpleBooleanProperty();
//final BooleanProperty isMainNet = new SimpleBooleanProperty();
//final BooleanProperty isFeeFromFundingTxSufficient = new SimpleBooleanProperty();

// final ObjectProperty<Coin> feeFromFundingTxProperty = new SimpleObjectProperty(Coin.NEGATIVE_SATOSHI);
private final ObjectProperty<Coin> amount = new SimpleObjectProperty<>();
private final ObjectProperty<Coin> minAmount = new SimpleObjectProperty<>();
private final ObjectProperty<Price> price = new SimpleObjectProperty<>();
private final ObjectProperty<Volume> volume = new SimpleObjectProperty<>();
private final ObjectProperty<Coin> buyerSecurityDeposit = new SimpleObjectProperty<>();
private final Coin sellerSecurityDeposit;
protected final ObjectProperty<Coin> amount = new SimpleObjectProperty<>();
protected final ObjectProperty<Coin> minAmount = new SimpleObjectProperty<>();
protected final ObjectProperty<Price> price = new SimpleObjectProperty<>();
protected final ObjectProperty<Volume> volume = new SimpleObjectProperty<>();
protected final ObjectProperty<Coin> buyerSecurityDeposit = new SimpleObjectProperty<>();

private final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
protected final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();

protected PaymentAccount paymentAccount;
boolean isTabSelected;
private double marketPriceMargin = 0;
private Coin txFeeFromFeeService;
private boolean marketPriceAvailable;
private int feeTxSize = 260; // size of typical tx with 1 input
private int feeTxSizeEstimationRecursionCounter;
protected boolean isTabSelected;
protected double marketPriceMargin = 0;
protected Coin txFeeFromFeeService;
protected boolean marketPriceAvailable;
protected int feeTxSize = 260; // size of typical tx with 1 input
protected int feeTxSizeEstimationRecursionCounter;
protected boolean allowAmountUpdate = true;


///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -668,6 +670,8 @@ void calculateVolume() {
// For HalCash we want multiple of 10 EUR
if (isHalCashAccount())
volumeByAmount = OfferUtil.getAdjustedVolumeForHalCash(volumeByAmount);
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
volumeByAmount = OfferUtil.getRoundedFiatVolume(volumeByAmount, tradeCurrencyCode.get());

volume.set(volumeByAmount);
} catch (Throwable t) {
Expand All @@ -688,6 +692,10 @@ void calculateAmount() {
Coin value = formatter.reduceTo4Decimals(price.get().getAmountByVolume(volume.get()));
if (isHalCashAccount())
value = OfferUtil.getAdjustedAmountForHalCash(value, price.get(), getMaxTradeLimit());
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
value = OfferUtil.getRoundedFiatAmount(value, price.get(), tradeCurrencyCode.get(), getMaxTradeLimit());

calculateVolume();

amount.set(value);
calculateTotalToPay();
Expand Down
27 changes: 17 additions & 10 deletions src/main/java/bisq/desktop/main/offer/MutableOfferViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
private MarketPrice marketPrice;
final IntegerProperty marketPriceAvailableProperty = new SimpleIntegerProperty(-1);
private ChangeListener<Number> currenciesUpdateListener;
private boolean syncMinAmountWithAmount = true;
protected boolean syncMinAmountWithAmount = true;

///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle
Expand Down Expand Up @@ -760,6 +760,8 @@ void onFocusOutVolumeTextField(boolean oldValue, boolean newValue) {
// For HalCash we want multiple of 10 EUR
if (dataModel.isHalCashAccount())
volume = OfferUtil.getAdjustedVolumeForHalCash(volume);
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
volume = OfferUtil.getRoundedFiatVolume(volume, tradeCurrencyCode.get());

this.volume.set(btcFormatter.formatVolume(volume));
}
Expand Down Expand Up @@ -968,12 +970,14 @@ private void setAmountToModel() {
if (amount.get() != null && !amount.get().isEmpty()) {
Coin amount = btcFormatter.parseToCoinWith4Decimals(this.amount.get());

if (dataModel.isHalCashAccount() && dataModel.getPrice().get() != null) {
amount = OfferUtil.getAdjustedAmountForHalCash(amount,
dataModel.getPrice().get(),
dataModel.getMaxTradeLimit());
long maxTradeLimit = dataModel.getMaxTradeLimit();
Price price = dataModel.getPrice().get();
if (price != null) {
if (dataModel.isHalCashAccount())
amount = OfferUtil.getAdjustedAmountForHalCash(amount, price, maxTradeLimit);
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
amount = OfferUtil.getRoundedFiatAmount(amount, price, tradeCurrencyCode.get(), maxTradeLimit);
}

dataModel.setAmount(amount);
if (syncMinAmountWithAmount ||
dataModel.getMinAmount().get() == null ||
Expand All @@ -990,10 +994,13 @@ private void setMinAmountToModel() {
if (minAmount.get() != null && !minAmount.get().isEmpty()) {
Coin minAmount = btcFormatter.parseToCoinWith4Decimals(this.minAmount.get());

if (dataModel.isHalCashAccount() && dataModel.getPrice().get() != null) {
minAmount = OfferUtil.getAdjustedAmountForHalCash(minAmount,
dataModel.getPrice().get(),
dataModel.getMaxTradeLimit());
Price price = dataModel.getPrice().get();
long maxTradeLimit = dataModel.getMaxTradeLimit();
if (price != null) {
if (dataModel.isHalCashAccount())
minAmount = OfferUtil.getAdjustedAmountForHalCash(minAmount, price, maxTradeLimit);
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
minAmount = OfferUtil.getRoundedFiatAmount(minAmount, price, tradeCurrencyCode.get(), maxTradeLimit);
}

dataModel.setMinAmount(minAmount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountUtil;
import bisq.core.payment.payload.PaymentMethod;
Expand Down Expand Up @@ -494,6 +495,8 @@ void calculateVolume() {
Volume volumeByAmount = tradePrice.getVolumeByAmount(amount.get());
if (offer.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID))
volumeByAmount = OfferUtil.getAdjustedVolumeForHalCash(volumeByAmount);
else if (CurrencyUtil.isFiatCurrency(getCurrencyCode()))
volumeByAmount = OfferUtil.getRoundedFiatVolume(volumeByAmount, getCurrencyCode());

volume.set(volumeByAmount);

Expand Down Expand Up @@ -642,4 +645,8 @@ public Coin getSellerSecurityDeposit() {
public Coin getBsqBalance() {
return bsqWalletService.getAvailableBalance();
}

public boolean isHalCashAccount() {
return paymentAccount instanceof HalCashAccount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import bisq.desktop.util.validation.BtcValidator;

import bisq.core.btc.wallet.WalletsSetup;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.monetary.Price;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
Expand Down Expand Up @@ -281,12 +283,23 @@ void onFocusOutAmountTextField(boolean oldValue, boolean newValue, String userIn

calculateVolume();

Price tradePrice = dataModel.tradePrice;
long maxTradeLimit = dataModel.getMaxTradeLimit();
if (dataModel.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID)) {
Coin adjustedAmountForHalCash = OfferUtil.getAdjustedAmountForHalCash(dataModel.getAmount().get(),
dataModel.tradePrice,
dataModel.getMaxTradeLimit());
tradePrice,
maxTradeLimit);
dataModel.applyAmount(adjustedAmountForHalCash);
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get()));
} else if (CurrencyUtil.isFiatCurrency(dataModel.getCurrencyCode())) {
if (!isAmountEqualMinAmount(dataModel.getAmount().get())) {
// We only apply the rounding if the amount is variable (minAmount is lower as amount).
// Otherwise we could get an amount lower then the minAmount set by rounding
Coin roundedAmount = OfferUtil.getRoundedFiatAmount(dataModel.getAmount().get(), tradePrice,
dataModel.getCurrencyCode(), maxTradeLimit);
dataModel.applyAmount(roundedAmount);
}
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get()));
}

if (!dataModel.isMinAmountLessOrEqualAmount())
Expand Down Expand Up @@ -543,7 +556,25 @@ private void calculateVolume() {
}

private void setAmountToModel() {
dataModel.applyAmount(btcFormatter.parseToCoinWith4Decimals(amount.get()));
if (amount.get() != null && !amount.get().isEmpty()) {
Coin amount = btcFormatter.parseToCoinWith4Decimals(this.amount.get());
long maxTradeLimit = dataModel.getMaxTradeLimit();
Price price = dataModel.tradePrice;
if (price != null) {
if (dataModel.isHalCashAccount()) {
amount = OfferUtil.getAdjustedAmountForHalCash(amount, price, maxTradeLimit);
} else if (CurrencyUtil.isFiatCurrency(dataModel.getCurrencyCode()) && !isAmountEqualMinAmount(amount)) {
// We only apply the rounding if the amount is variable (minAmount is lower as amount).
// Otherwise we could get an amount lower then the minAmount set by rounding
amount = OfferUtil.getRoundedFiatAmount(amount, price, dataModel.getCurrencyCode(), maxTradeLimit);
}
}
dataModel.applyAmount(amount);
}
}

private boolean isAmountEqualMinAmount(Coin amount) {
return amount.value == offer.getMinAmount().value;
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,34 @@ class EditOfferDataModel extends MutableOfferDataModel {
this.corePersistenceProtoResolver = corePersistenceProtoResolver;
}

public void reset() {
direction = null;
tradeCurrency = null;
tradeCurrencyCode.set(null);
useMarketBasedPrice.set(false);
amount.set(null);
minAmount.set(null);
price.set(null);
volume.set(null);
buyerSecurityDeposit.set(null);
paymentAccounts.clear();
paymentAccount = null;
marketPriceMargin = 0;
}

public void applyOpenOffer(OpenOffer openOffer) {
this.openOffer = openOffer;

Offer offer = openOffer.getOffer();
direction = offer.getDirection();
CurrencyUtil.getTradeCurrency(offer.getCurrencyCode())
.ifPresent(c -> this.tradeCurrency = c);
tradeCurrencyCode.set(offer.getCurrencyCode());
buyerSecurityDeposit.set(offer.getBuyerSecurityDeposit());

this.initialState = openOffer.getState();
final PaymentAccount tmpPaymentAccount = user.getPaymentAccount(openOffer.getOffer().getMakerPaymentAccountId());
final TradeCurrency selectedTradeCurrency = CurrencyUtil.getTradeCurrency(openOffer.getOffer().getCurrencyCode()).get();
PaymentAccount tmpPaymentAccount = user.getPaymentAccount(openOffer.getOffer().getMakerPaymentAccountId());
TradeCurrency selectedTradeCurrency = CurrencyUtil.getTradeCurrency(openOffer.getOffer().getCurrencyCode()).get();

this.paymentAccount = PaymentAccount.fromProto(tmpPaymentAccount.toProtoMessage(), corePersistenceProtoResolver);

Expand All @@ -73,7 +96,7 @@ public void applyOpenOffer(OpenOffer openOffer) {
else
paymentAccount.setSelectedTradeCurrency(selectedTradeCurrency);

this.allowAmountUpdate = false;
allowAmountUpdate = false;
}

@Override
Expand All @@ -83,9 +106,9 @@ protected PaymentAccount getPreselectedPaymentAccount() {

public void populateData() {
Offer offer = openOffer.getOffer();

setAmount(offer.getAmount());
// Min amount need to be set before amount as if minAmount is null it would be set by amount
setMinAmount(offer.getMinAmount());
setAmount(offer.getAmount());
setPrice(offer.getPrice());
setVolume(offer.getVolume());
setUseMarketBasedPrice(offer.isUseMarketBasedPrice());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class EditOfferViewModel extends MutableOfferViewModel<EditOfferDataModel> {
@Inject
public EditOfferViewModel(EditOfferDataModel dataModel, FiatVolumeValidator fiatVolumeValidator, FiatPriceValidator fiatPriceValidator, AltcoinValidator altcoinValidator, BtcValidator btcValidator, BsqValidator bsqValidator, SecurityDepositValidator securityDepositValidator, P2PService p2PService, WalletsSetup walletsSetup, PriceFeedService priceFeedService, Navigation navigation, Preferences preferences, BSFormatter btcFormatter, BsqFormatter bsqFormatter) {
super(dataModel, fiatVolumeValidator, fiatPriceValidator, altcoinValidator, btcValidator, bsqValidator, securityDepositValidator, p2PService, walletsSetup, priceFeedService, navigation, preferences, btcFormatter, bsqFormatter);
syncMinAmountWithAmount = false;
}

@Override
Expand All @@ -54,6 +55,7 @@ public void activate() {
}

public void applyOpenOffer(OpenOffer openOffer) {
dataModel.reset();
dataModel.applyOpenOffer(openOffer);
}

Expand Down