Separate fees in trade complete screen. Show withdrawal btc address only after button click

This commit is contained in:
Manfred Karrer 2017-11-26 20:06:11 -05:00
parent 2137522e1f
commit 2b248c5426
No known key found for this signature in database
GPG key ID: 401250966A6B2C46
4 changed files with 103 additions and 54 deletions

View file

@ -560,7 +560,9 @@ portfolio.pending.step3_seller.onPaymentReceived.confirm.headline=Confirm that y
portfolio.pending.step3_seller.onPaymentReceived.confirm.yes=Yes, I have received the payment
portfolio.pending.step5_buyer.groupTitle=Summary of completed trade
portfolio.pending.step5_buyer.totalPaid=Total fees paid:
portfolio.pending.step5_buyer.tradeFee=Trade fee:
portfolio.pending.step5_buyer.makersMiningFee=Mining fee:
portfolio.pending.step5_buyer.takersMiningFee=Total mining fees:
portfolio.pending.step5_buyer.refunded=Refunded security deposit:
portfolio.pending.step5_buyer.withdrawBTC=Withdraw your bitcoin
portfolio.pending.step5_buyer.amount=Amount to withdraw:

View file

@ -223,24 +223,45 @@ public class PendingTradesDataModel extends ActivatableDataModel {
return tradeManager.isMyOffer(offer);
}
private boolean isMaker() {
public boolean isMaker() {
return isMaker;
}
Coin getTotalFees() {
Coin getTradeFeeInBTC() {
Trade trade = getTrade();
if (trade != null) {
Offer offer = trade.getOffer();
if (isMaker()) {
if (offer.isCurrencyForMakerFeeBtc())
return offer.getMakerFee();
else
return Coin.ZERO;// getTradeFeeAsBsq is used for BSQ
} else {
if (trade.isCurrencyForTakerFeeBtc())
return trade.getTakerFee();
else
return Coin.ZERO; // getTradeFeeAsBsq is used for BSQ
}
} else {
log.error("Trade is null at getTotalFees");
return Coin.ZERO;
}
}
Coin getTxFee() {
Trade trade = getTrade();
if (trade != null) {
if (isMaker()) {
Offer offer = trade.getOffer();
if (offer.isCurrencyForMakerFeeBtc())
return offer.getMakerFee().add(offer.getTxFee());
return offer.getTxFee();
else
return offer.getTxFee().subtract(offer.getMakerFee());
return offer.getTxFee().subtract(offer.getMakerFee()); // BSQ will be used as part of the miner fee
} else {
if (trade.isCurrencyForTakerFeeBtc())
return trade.getTakerFee().add(trade.getTxFee().multiply(3));
return trade.getTxFee().multiply(3);
else
return trade.getTxFee().multiply(3).subtract(trade.getTakerFee());
return trade.getTxFee().multiply(3).subtract(trade.getTakerFee()); // BSQ will be used as part of the miner fee
}
} else {
log.error("Trade is null at getTotalFees");
@ -254,12 +275,12 @@ public class PendingTradesDataModel extends ActivatableDataModel {
if (isMaker()) {
Offer offer = trade.getOffer();
if (offer.isCurrencyForMakerFeeBtc())
return Coin.ZERO;
return Coin.ZERO; // getTradeFeeInBTC is used for BTC
else
return offer.getMakerFee();
} else {
if (trade.isCurrencyForTakerFeeBtc())
return Coin.ZERO;
return Coin.ZERO; // getTradeFeeInBTC is used for BTC
else
return trade.getTakerFee();
}

View file

@ -35,7 +35,9 @@ import io.bisq.gui.util.BsqFormatter;
import io.bisq.gui.util.GUIUtil;
import io.bisq.gui.util.validation.BtcAddressValidator;
import io.bisq.network.p2p.P2PService;
import javafx.beans.property.*;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.bitcoinj.core.Coin;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
@ -242,15 +244,24 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
return dataModel.getTrade() != null ? btcFormatter.formatVolumeWithCode(dataModel.getTrade().getTradeVolume()) : "";
}
public String getTotalFees() {
Coin totalFees = dataModel.getTotalFees();
if (trade != null && totalFees.isPositive()) {
Coin tradeFeeAsBsq = dataModel.getTradeFeeAsBsq();
String percentage = GUIUtil.getPercentageOfTradeAmount(totalFees, trade.getTradeAmount(), btcFormatter);
if (tradeFeeAsBsq.isPositive()) {
return btcFormatter.formatCoinWithCode(totalFees) + percentage + " + " + bsqFormatter.formatCoinWithCode(tradeFeeAsBsq);
public String getTxFee() {
if (trade != null) {
Coin txFee = dataModel.getTxFee();
String percentage = GUIUtil.getPercentageOfTradeAmount(txFee, trade.getTradeAmount(), btcFormatter);
return btcFormatter.formatCoinWithCode(txFee) + percentage;
} else {
return "";
}
}
public String getTradeFee() {
if (trade != null && dataModel.getOffer() != null) {
if (dataModel.getOffer().isCurrencyForMakerFeeBtc()) {
Coin tradeFeeInBTC = dataModel.getTradeFeeInBTC();
String percentage = GUIUtil.getPercentageOfTradeAmount(tradeFeeInBTC, trade.getTradeAmount(), btcFormatter);
return btcFormatter.formatCoinWithCode(tradeFeeInBTC) + percentage;
} else {
return btcFormatter.formatCoinWithCode(totalFees) + percentage;
return bsqFormatter.formatCoinWithCode(dataModel.getTradeFeeAsBsq());
}
} else {
return "";

View file

@ -23,6 +23,7 @@ import io.bisq.common.app.Log;
import io.bisq.common.handlers.FaultHandler;
import io.bisq.common.handlers.ResultHandler;
import io.bisq.common.locale.Res;
import io.bisq.common.util.Tuple2;
import io.bisq.core.btc.AddressEntry;
import io.bisq.core.btc.AddressEntryException;
import io.bisq.core.btc.InsufficientFundsException;
@ -31,6 +32,7 @@ import io.bisq.core.btc.wallet.BtcWalletService;
import io.bisq.core.user.DontShowAgainLookup;
import io.bisq.core.util.CoinUtil;
import io.bisq.gui.components.InputTextField;
import io.bisq.gui.components.TitledGroupBg;
import io.bisq.gui.main.MainView;
import io.bisq.gui.main.funds.FundsView;
import io.bisq.gui.main.funds.transactions.TransactionsView;
@ -60,6 +62,8 @@ public class BuyerStep4View extends TradeStepView {
private InputTextField withdrawAddressTextField;
private Button withdrawToExternalWalletButton, useSavingsWalletButton;
private TitledGroupBg withdrawTitledGroupBg;
private Label withdrawAddressLabel;
///////////////////////////////////////////////////////////////////////////////////////////
@ -114,15 +118,25 @@ public class BuyerStep4View extends TradeStepView {
@SuppressWarnings("PointlessBooleanExpression")
@Override
protected void addContent() {
addTitledGroupBg(gridPane, gridRow, 4, Res.get("portfolio.pending.step5_buyer.groupTitle"), 0);
addTitledGroupBg(gridPane, gridRow, 5, Res.get("portfolio.pending.step5_buyer.groupTitle"), 0);
addLabelTextField(gridPane, gridRow, getBtcTradeAmountLabel(), model.getTradeVolume(), Layout.FIRST_ROW_DISTANCE);
addLabelTextField(gridPane, ++gridRow, getFiatTradeAmountLabel(), model.getFiatVolume());
addLabelTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.totalPaid"), model.getTotalFees());
addLabelTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.refunded"), model.getSecurityDeposit());
addTitledGroupBg(gridPane, ++gridRow, 2, Res.get("portfolio.pending.step5_buyer.withdrawBTC"), Layout.GROUP_DISTANCE);
addLabelTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.tradeFee"), model.getTradeFee());
final String miningFee = model.dataModel.isMaker() ?
Res.get("portfolio.pending.step5_buyer.makersMiningFee") :
Res.get("portfolio.pending.step5_buyer.takersMiningFee");
addLabelTextField(gridPane, ++gridRow, miningFee, model.getTxFee());
withdrawTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, Res.get("portfolio.pending.step5_buyer.withdrawBTC"), Layout.GROUP_DISTANCE);
addLabelTextField(gridPane, gridRow, Res.get("portfolio.pending.step5_buyer.amount"), model.getPayoutAmount(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
withdrawAddressTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.withdrawToAddress")).second;
final Tuple2<Label, InputTextField> tuple2 = addLabelInputTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.withdrawToAddress"));
withdrawAddressLabel = tuple2.first;
withdrawAddressLabel.setManaged(false);
withdrawAddressLabel.setVisible(false);
withdrawAddressTextField = tuple2.second;
withdrawAddressTextField.setManaged(false);
withdrawAddressTextField.setVisible(false);
HBox hBox = new HBox();
hBox.setSpacing(10);
@ -142,7 +156,7 @@ public class BuyerStep4View extends TradeStepView {
handleTradeCompleted();
model.dataModel.tradeManager.addTradeToClosedTrades(trade);
});
withdrawToExternalWalletButton.setOnAction(e -> reviewWithdrawal());
withdrawToExternalWalletButton.setOnAction(e -> onWithdrawal());
String key = "tradeCompleted" + trade.getId();
//noinspection ConstantConditions
@ -155,6 +169,16 @@ public class BuyerStep4View extends TradeStepView {
}
}
private void onWithdrawal() {
withdrawAddressLabel.setManaged(true);
withdrawAddressLabel.setVisible(true);
withdrawAddressTextField.setManaged(true);
withdrawAddressTextField.setVisible(true);
GridPane.setRowSpan(withdrawTitledGroupBg, 2);
withdrawToExternalWalletButton.setDefaultButton(true);
withdrawToExternalWalletButton.setOnAction(e -> reviewWithdrawal());
}
@SuppressWarnings("PointlessBooleanExpression")
private void reviewWithdrawal() {
Coin amount = trade.getPayoutAmount();
@ -177,37 +201,28 @@ public class BuyerStep4View extends TradeStepView {
if (toAddresses.isEmpty()) {
validateWithdrawAddress();
} else if (Restrictions.isAboveDust(amount, fee)) {
if (DevEnv.DEV_MODE) {
doWithdrawal(amount, fee);
} else {
BSFormatter formatter = model.btcFormatter;
//noinspection ConstantConditions
if (!DevEnv.DEV_MODE) {
int txSize = feeEstimationTransaction.bitcoinSerialize().length;
double feePerByte = CoinUtil.getFeePerByte(fee, txSize);
double kb = txSize / 1000d;
String recAmount = formatter.formatCoinWithCode(receiverAmount);
new Popup<>().headLine(Res.get("portfolio.pending.step5_buyer.confirmWithdrawal"))
.confirmation(Res.get("shared.sendFundsDetailsWithFee",
formatter.formatCoinWithCode(amount),
fromAddresses,
toAddresses,
formatter.formatCoinWithCode(fee),
feePerByte,
kb,
recAmount))
.actionButtonText(Res.get("shared.yes"))
.onAction(() -> doWithdrawal(amount, fee))
.closeButtonText(Res.get("shared.cancel"))
.onClose(() -> {
useSavingsWalletButton.setDisable(false);
withdrawToExternalWalletButton.setDisable(false);
})
.show();
} else {
doWithdrawal(amount, fee);
}
}
BSFormatter formatter = model.btcFormatter;
int txSize = feeEstimationTransaction.bitcoinSerialize().length;
double feePerByte = CoinUtil.getFeePerByte(fee, txSize);
double kb = txSize / 1000d;
String recAmount = formatter.formatCoinWithCode(receiverAmount);
new Popup<>().headLine(Res.get("portfolio.pending.step5_buyer.confirmWithdrawal"))
.confirmation(Res.get("shared.sendFundsDetailsWithFee",
formatter.formatCoinWithCode(amount),
fromAddresses,
toAddresses,
formatter.formatCoinWithCode(fee),
feePerByte,
kb,
recAmount))
.actionButtonText(Res.get("shared.yes"))
.onAction(() -> doWithdrawal(amount, fee))
.closeButtonText(Res.get("shared.cancel"))
.onClose(() -> {
useSavingsWalletButton.setDisable(false);
withdrawToExternalWalletButton.setDisable(false);
})
.show();
} else {
new Popup<>().warning(Res.get("portfolio.pending.step5_buyer.amountTooLow")).show();
}