mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-28 17:34:11 -04:00
Add check for payment accounts in use when trying to delete
This commit is contained in:
parent
56008caef3
commit
bab70abf9e
12 changed files with 90 additions and 28 deletions
|
@ -47,6 +47,8 @@ import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.text.TextAlignment;
|
import javafx.scene.text.TextAlignment;
|
||||||
|
import org.fxmisc.easybind.EasyBind;
|
||||||
|
import org.fxmisc.easybind.monadic.MonadicBinding;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
@ -59,6 +61,7 @@ import static javafx.scene.layout.AnchorPane.*;
|
||||||
public class MainView extends InitializableView<StackPane, MainViewModel> {
|
public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||||
|
|
||||||
public static final String TITLE_KEY = "view.title";
|
public static final String TITLE_KEY = "view.title";
|
||||||
|
private MonadicBinding<String> marketPriceBinding;
|
||||||
|
|
||||||
public static StackPane getRootContainer() {
|
public static StackPane getRootContainer() {
|
||||||
return MainView.rootContainer;
|
return MainView.rootContainer;
|
||||||
|
@ -138,14 +141,19 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||||
Tuple3<TextField, Label, VBox> marketPriceBox = getMarketPriceBox("Market price");
|
Tuple3<TextField, Label, VBox> marketPriceBox = getMarketPriceBox("Market price");
|
||||||
final BooleanProperty priceInverted = new SimpleBooleanProperty(false);
|
final BooleanProperty priceInverted = new SimpleBooleanProperty(false);
|
||||||
marketPriceBox.first.setOnMouseClicked(e -> priceInverted.setValue(!priceInverted.get()));
|
marketPriceBox.first.setOnMouseClicked(e -> priceInverted.setValue(!priceInverted.get()));
|
||||||
marketPriceBox.first.textProperty().bind(createStringBinding(
|
marketPriceBinding = EasyBind.combine(
|
||||||
() -> (priceInverted.get() ?
|
model.marketPriceCurrency, model.marketPrice, model.marketPriceInverted, priceInverted,
|
||||||
model.marketPriceInverted.get() :
|
(marketPriceCurrency, marketPrice, marketPriceInverted, inverted) ->
|
||||||
model.marketPrice.get()) +
|
|
||||||
(priceInverted.get() ?
|
(priceInverted.get() ?
|
||||||
" BTC/" + model.marketPriceCurrency.get() :
|
marketPriceInverted :
|
||||||
" " + model.marketPriceCurrency.get() + "/BTC"),
|
marketPrice) +
|
||||||
model.marketPriceCurrency, model.marketPrice, priceInverted));
|
(priceInverted.get() ?
|
||||||
|
" BTC/" + marketPriceCurrency :
|
||||||
|
" " + marketPriceCurrency + "/BTC"));
|
||||||
|
|
||||||
|
marketPriceBinding.subscribe((observable, oldValue, newValue) -> {
|
||||||
|
marketPriceBox.first.setText(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
marketPriceBox.second.textProperty().bind(createStringBinding(
|
marketPriceBox.second.textProperty().bind(createStringBinding(
|
||||||
() -> {
|
() -> {
|
||||||
|
|
|
@ -21,6 +21,8 @@ import com.google.inject.Inject;
|
||||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||||
import io.bitsquare.payment.PaymentAccount;
|
import io.bitsquare.payment.PaymentAccount;
|
||||||
import io.bitsquare.payment.PaymentMethod;
|
import io.bitsquare.payment.PaymentMethod;
|
||||||
|
import io.bitsquare.trade.TradeManager;
|
||||||
|
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||||
import io.bitsquare.user.User;
|
import io.bitsquare.user.User;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
@ -31,12 +33,16 @@ import java.util.stream.Collectors;
|
||||||
class AltCoinAccountsDataModel extends ActivatableDataModel {
|
class AltCoinAccountsDataModel extends ActivatableDataModel {
|
||||||
|
|
||||||
private final User user;
|
private final User user;
|
||||||
|
private final OpenOfferManager openOfferManager;
|
||||||
|
private final TradeManager tradeManager;
|
||||||
final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
|
final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
|
||||||
private final SetChangeListener<PaymentAccount> setChangeListener;
|
private final SetChangeListener<PaymentAccount> setChangeListener;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AltCoinAccountsDataModel(User user) {
|
public AltCoinAccountsDataModel(User user, OpenOfferManager openOfferManager, TradeManager tradeManager) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
|
this.openOfferManager = openOfferManager;
|
||||||
|
this.tradeManager = tradeManager;
|
||||||
setChangeListener = change -> fillAndSortPaymentAccounts();
|
setChangeListener = change -> fillAndSortPaymentAccounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +73,20 @@ class AltCoinAccountsDataModel extends ActivatableDataModel {
|
||||||
user.addPaymentAccount(paymentAccount);
|
user.addPaymentAccount(paymentAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDeleteAccount(PaymentAccount paymentAccount) {
|
|
||||||
|
public boolean onDeleteAccount(PaymentAccount paymentAccount) {
|
||||||
|
boolean isPaymentAccountUsed = openOfferManager.getOpenOffers().stream()
|
||||||
|
.filter(o -> o.getOffer().getOffererPaymentAccountId().equals(paymentAccount.getId()))
|
||||||
|
.findAny()
|
||||||
|
.isPresent();
|
||||||
|
isPaymentAccountUsed = isPaymentAccountUsed || tradeManager.getTrades().stream()
|
||||||
|
.filter(t -> t.getOffer().getOffererPaymentAccountId().equals(paymentAccount.getId()) ||
|
||||||
|
t.getTakerPaymentAccountId().equals(paymentAccount.getId()))
|
||||||
|
.findAny()
|
||||||
|
.isPresent();
|
||||||
|
if (!isPaymentAccountUsed)
|
||||||
user.removePaymentAccount(paymentAccount);
|
user.removePaymentAccount(paymentAccount);
|
||||||
|
return isPaymentAccountUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSelectAccount(PaymentAccount paymentAccount) {
|
public void onSelectAccount(PaymentAccount paymentAccount) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.account.content.altcoinaccounts;
|
package io.bitsquare.gui.main.account.content.altcoinaccounts;
|
||||||
|
|
||||||
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
|
@ -44,6 +45,7 @@ import javafx.scene.layout.GridPane;
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||||
|
|
||||||
|
@ -143,8 +145,14 @@ public class AltCoinAccountsView extends ActivatableViewAndModel<GridPane, AltCo
|
||||||
new Popup().warning("Do you really want to delete the selected account?")
|
new Popup().warning("Do you really want to delete the selected account?")
|
||||||
.actionButtonText("Yes")
|
.actionButtonText("Yes")
|
||||||
.onAction(() -> {
|
.onAction(() -> {
|
||||||
model.onDeleteAccount(paymentAccount);
|
boolean isPaymentAccountUsed = model.onDeleteAccount(paymentAccount);
|
||||||
|
if (!isPaymentAccountUsed)
|
||||||
removeSelectAccountForm();
|
removeSelectAccountForm();
|
||||||
|
else
|
||||||
|
UserThread.runAfter(() -> {
|
||||||
|
new Popup().warning("You cannot delete that account because it is used in an " +
|
||||||
|
"open offer or in a trade.").show();
|
||||||
|
}, 100, TimeUnit.MILLISECONDS);
|
||||||
})
|
})
|
||||||
.closeButtonText("Cancel")
|
.closeButtonText("Cancel")
|
||||||
.show();
|
.show();
|
||||||
|
|
|
@ -72,8 +72,8 @@ class AltCoinAccountsViewModel extends ActivatableWithDataModel<AltCoinAccountsD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDeleteAccount(PaymentAccount paymentAccount) {
|
public boolean onDeleteAccount(PaymentAccount paymentAccount) {
|
||||||
dataModel.onDeleteAccount(paymentAccount);
|
return dataModel.onDeleteAccount(paymentAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSelectAccount(PaymentAccount paymentAccount) {
|
public void onSelectAccount(PaymentAccount paymentAccount) {
|
||||||
|
|
|
@ -24,6 +24,8 @@ import io.bitsquare.locale.FiatCurrency;
|
||||||
import io.bitsquare.locale.TradeCurrency;
|
import io.bitsquare.locale.TradeCurrency;
|
||||||
import io.bitsquare.payment.PaymentAccount;
|
import io.bitsquare.payment.PaymentAccount;
|
||||||
import io.bitsquare.payment.PaymentMethod;
|
import io.bitsquare.payment.PaymentMethod;
|
||||||
|
import io.bitsquare.trade.TradeManager;
|
||||||
|
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
import io.bitsquare.user.User;
|
import io.bitsquare.user.User;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
|
@ -37,13 +39,17 @@ class FiatAccountsDataModel extends ActivatableDataModel {
|
||||||
|
|
||||||
private final User user;
|
private final User user;
|
||||||
private Preferences preferences;
|
private Preferences preferences;
|
||||||
|
private final OpenOfferManager openOfferManager;
|
||||||
|
private final TradeManager tradeManager;
|
||||||
final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
|
final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
|
||||||
private final SetChangeListener<PaymentAccount> setChangeListener;
|
private final SetChangeListener<PaymentAccount> setChangeListener;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public FiatAccountsDataModel(User user, Preferences preferences) {
|
public FiatAccountsDataModel(User user, Preferences preferences, OpenOfferManager openOfferManager, TradeManager tradeManager) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
|
this.openOfferManager = openOfferManager;
|
||||||
|
this.tradeManager = tradeManager;
|
||||||
setChangeListener = change -> fillAndSortPaymentAccounts();
|
setChangeListener = change -> fillAndSortPaymentAccounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,8 +96,19 @@ class FiatAccountsDataModel extends ActivatableDataModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDeleteAccount(PaymentAccount paymentAccount) {
|
public boolean onDeleteAccount(PaymentAccount paymentAccount) {
|
||||||
|
boolean isPaymentAccountUsed = openOfferManager.getOpenOffers().stream()
|
||||||
|
.filter(o -> o.getOffer().getOffererPaymentAccountId().equals(paymentAccount.getId()))
|
||||||
|
.findAny()
|
||||||
|
.isPresent();
|
||||||
|
isPaymentAccountUsed = isPaymentAccountUsed || tradeManager.getTrades().stream()
|
||||||
|
.filter(t -> t.getOffer().getOffererPaymentAccountId().equals(paymentAccount.getId()) ||
|
||||||
|
t.getTakerPaymentAccountId().equals(paymentAccount.getId()))
|
||||||
|
.findAny()
|
||||||
|
.isPresent();
|
||||||
|
if (!isPaymentAccountUsed)
|
||||||
user.removePaymentAccount(paymentAccount);
|
user.removePaymentAccount(paymentAccount);
|
||||||
|
return isPaymentAccountUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSelectAccount(PaymentAccount paymentAccount) {
|
public void onSelectAccount(PaymentAccount paymentAccount) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.account.content.fiataccounts;
|
package io.bitsquare.gui.main.account.content.fiataccounts;
|
||||||
|
|
||||||
|
import io.bitsquare.common.UserThread;
|
||||||
import io.bitsquare.common.util.Tuple2;
|
import io.bitsquare.common.util.Tuple2;
|
||||||
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
|
||||||
import io.bitsquare.gui.common.view.FxmlView;
|
import io.bitsquare.gui.common.view.FxmlView;
|
||||||
|
@ -45,6 +46,7 @@ import javafx.util.StringConverter;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||||
|
@ -146,8 +148,14 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
|
||||||
new Popup().warning("Do you really want to delete the selected account?")
|
new Popup().warning("Do you really want to delete the selected account?")
|
||||||
.actionButtonText("Yes")
|
.actionButtonText("Yes")
|
||||||
.onAction(() -> {
|
.onAction(() -> {
|
||||||
model.onDeleteAccount(paymentAccount);
|
boolean isPaymentAccountUsed = model.onDeleteAccount(paymentAccount);
|
||||||
|
if (!isPaymentAccountUsed)
|
||||||
removeSelectAccountForm();
|
removeSelectAccountForm();
|
||||||
|
else
|
||||||
|
UserThread.runAfter(() -> {
|
||||||
|
new Popup().warning("You cannot delete that account because it is used in an " +
|
||||||
|
"open offer or in a trade.").show();
|
||||||
|
}, 100, TimeUnit.MILLISECONDS);
|
||||||
})
|
})
|
||||||
.closeButtonText("Cancel")
|
.closeButtonText("Cancel")
|
||||||
.show();
|
.show();
|
||||||
|
|
|
@ -48,8 +48,8 @@ class FiatAccountsViewModel extends ActivatableWithDataModel<FiatAccountsDataMod
|
||||||
dataModel.onSaveNewAccount(paymentAccount);
|
dataModel.onSaveNewAccount(paymentAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDeleteAccount(PaymentAccount paymentAccount) {
|
public boolean onDeleteAccount(PaymentAccount paymentAccount) {
|
||||||
dataModel.onDeleteAccount(paymentAccount);
|
return dataModel.onDeleteAccount(paymentAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSelectAccount(PaymentAccount paymentAccount) {
|
public void onSelectAccount(PaymentAccount paymentAccount) {
|
||||||
|
|
|
@ -550,7 +550,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||||
button.setOnAction(e -> onTakeOffer(offer));
|
button.setOnAction(e -> onTakeOffer(offer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isTradable)
|
if (!myOffer && !isTradable)
|
||||||
button.setOnAction(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator, hasSameProtocolVersion));
|
button.setOnAction(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator, hasSameProtocolVersion));
|
||||||
|
|
||||||
button.setText(title);
|
button.setText(title);
|
||||||
|
|
|
@ -149,9 +149,11 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
||||||
addTitledGroupBg(gridPane, ++rowIndex, rows, "Offer");
|
addTitledGroupBg(gridPane, ++rowIndex, rows, "Offer");
|
||||||
|
|
||||||
if (takeOfferHandlerOptional.isPresent())
|
if (takeOfferHandlerOptional.isPresent())
|
||||||
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getDirectionForTaker(offer.getDirection()), Layout.FIRST_ROW_DISTANCE);
|
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getDirectionForTakeOffer(offer.getDirection()), Layout.FIRST_ROW_DISTANCE);
|
||||||
|
else if (placeOfferHandlerOptional.isPresent())
|
||||||
|
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getOfferDirectionForCreateOffer(offer.getDirection()), Layout.FIRST_ROW_DISTANCE);
|
||||||
else
|
else
|
||||||
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getOfferDirectionForOfferer(offer.getDirection()), Layout.FIRST_ROW_DISTANCE);
|
addLabelTextField(gridPane, rowIndex, "Offer type:", formatter.getDirectionBothSides(offer.getDirection()), Layout.FIRST_ROW_DISTANCE);
|
||||||
|
|
||||||
if (takeOfferHandlerOptional.isPresent()) {
|
if (takeOfferHandlerOptional.isPresent()) {
|
||||||
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(tradeAmount));
|
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(tradeAmount));
|
||||||
|
|
|
@ -230,7 +230,8 @@ public class SellerStep3View extends TradeStepView {
|
||||||
if (preferences.showAgain(key)) {
|
if (preferences.showAgain(key)) {
|
||||||
new Popup()
|
new Popup()
|
||||||
.headLine("Confirm that you have received the payment")
|
.headLine("Confirm that you have received the payment")
|
||||||
.confirmation("Have you received the " + model.dataModel.getCurrencyCode() + " payment from your trading partner?\n\n" +
|
.confirmation("Have you received the " + CurrencyUtil.getNameByCode(model.dataModel.getCurrencyCode()) +
|
||||||
|
" payment from your trading partner?\n\n" +
|
||||||
"Please note that as soon you have confirmed the receipt, the locked trade amount will be released " +
|
"Please note that as soon you have confirmed the receipt, the locked trade amount will be released " +
|
||||||
"to the bitcoin buyer and the security deposit will be refunded.")
|
"to the bitcoin buyer and the security deposit will be refunded.")
|
||||||
.width(700)
|
.width(700)
|
||||||
|
|
|
@ -409,12 +409,12 @@ public class BSFormatter {
|
||||||
"You are selling bitcoin as taker / Offerer is buying bitcoin";
|
"You are selling bitcoin as taker / Offerer is buying bitcoin";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDirectionForTaker(Offer.Direction direction) {
|
public String getDirectionForTakeOffer(Offer.Direction direction) {
|
||||||
return direction == Offer.Direction.BUY ? "You are selling bitcoin (by taking an offer from someone who wants to buy bitcoin)" :
|
return direction == Offer.Direction.BUY ? "You are selling bitcoin (by taking an offer from someone who wants to buy bitcoin)" :
|
||||||
"You are buying bitcoin (by taking an offer from someone who wants to sell bitcoin)";
|
"You are buying bitcoin (by taking an offer from someone who wants to sell bitcoin)";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOfferDirectionForOfferer(Offer.Direction direction) {
|
public String getOfferDirectionForCreateOffer(Offer.Direction direction) {
|
||||||
return direction == Offer.Direction.BUY ? "You are creating an offer for buying bitcoin" :
|
return direction == Offer.Direction.BUY ? "You are creating an offer for buying bitcoin" :
|
||||||
"You are creating an offer for selling bitcoin";
|
"You are creating an offer for selling bitcoin";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue