Add check for payment accounts in use when trying to delete

This commit is contained in:
Manfred Karrer 2016-03-10 22:51:05 +01:00
parent 56008caef3
commit bab70abf9e
12 changed files with 90 additions and 28 deletions

View file

@ -47,6 +47,8 @@ import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.TextAlignment;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.monadic.MonadicBinding;
import javax.inject.Inject;
import javax.inject.Named;
@ -59,6 +61,7 @@ import static javafx.scene.layout.AnchorPane.*;
public class MainView extends InitializableView<StackPane, MainViewModel> {
public static final String TITLE_KEY = "view.title";
private MonadicBinding<String> marketPriceBinding;
public static StackPane getRootContainer() {
return MainView.rootContainer;
@ -138,14 +141,19 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
Tuple3<TextField, Label, VBox> marketPriceBox = getMarketPriceBox("Market price");
final BooleanProperty priceInverted = new SimpleBooleanProperty(false);
marketPriceBox.first.setOnMouseClicked(e -> priceInverted.setValue(!priceInverted.get()));
marketPriceBox.first.textProperty().bind(createStringBinding(
() -> (priceInverted.get() ?
model.marketPriceInverted.get() :
model.marketPrice.get()) +
marketPriceBinding = EasyBind.combine(
model.marketPriceCurrency, model.marketPrice, model.marketPriceInverted, priceInverted,
(marketPriceCurrency, marketPrice, marketPriceInverted, inverted) ->
(priceInverted.get() ?
" BTC/" + model.marketPriceCurrency.get() :
" " + model.marketPriceCurrency.get() + "/BTC"),
model.marketPriceCurrency, model.marketPrice, priceInverted));
marketPriceInverted :
marketPrice) +
(priceInverted.get() ?
" BTC/" + marketPriceCurrency :
" " + marketPriceCurrency + "/BTC"));
marketPriceBinding.subscribe((observable, oldValue, newValue) -> {
marketPriceBox.first.setText(newValue);
});
marketPriceBox.second.textProperty().bind(createStringBinding(
() -> {

View file

@ -21,6 +21,8 @@ import com.google.inject.Inject;
import io.bitsquare.gui.common.model.ActivatableDataModel;
import io.bitsquare.payment.PaymentAccount;
import io.bitsquare.payment.PaymentMethod;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.offer.OpenOfferManager;
import io.bitsquare.user.User;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@ -31,12 +33,16 @@ import java.util.stream.Collectors;
class AltCoinAccountsDataModel extends ActivatableDataModel {
private final User user;
private final OpenOfferManager openOfferManager;
private final TradeManager tradeManager;
final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
private final SetChangeListener<PaymentAccount> setChangeListener;
@Inject
public AltCoinAccountsDataModel(User user) {
public AltCoinAccountsDataModel(User user, OpenOfferManager openOfferManager, TradeManager tradeManager) {
this.user = user;
this.openOfferManager = openOfferManager;
this.tradeManager = tradeManager;
setChangeListener = change -> fillAndSortPaymentAccounts();
}
@ -67,8 +73,20 @@ class AltCoinAccountsDataModel extends ActivatableDataModel {
user.addPaymentAccount(paymentAccount);
}
public void onDeleteAccount(PaymentAccount paymentAccount) {
user.removePaymentAccount(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);
return isPaymentAccountUsed;
}
public void onSelectAccount(PaymentAccount paymentAccount) {

View file

@ -17,6 +17,7 @@
package io.bitsquare.gui.main.account.content.altcoinaccounts;
import io.bitsquare.common.UserThread;
import io.bitsquare.common.util.Tuple2;
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
import io.bitsquare.gui.common.view.FxmlView;
@ -44,6 +45,7 @@ import javafx.scene.layout.GridPane;
import javafx.util.Callback;
import javax.inject.Inject;
import java.util.concurrent.TimeUnit;
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?")
.actionButtonText("Yes")
.onAction(() -> {
model.onDeleteAccount(paymentAccount);
removeSelectAccountForm();
boolean isPaymentAccountUsed = model.onDeleteAccount(paymentAccount);
if (!isPaymentAccountUsed)
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")
.show();

View file

@ -72,8 +72,8 @@ class AltCoinAccountsViewModel extends ActivatableWithDataModel<AltCoinAccountsD
}
}
public void onDeleteAccount(PaymentAccount paymentAccount) {
dataModel.onDeleteAccount(paymentAccount);
public boolean onDeleteAccount(PaymentAccount paymentAccount) {
return dataModel.onDeleteAccount(paymentAccount);
}
public void onSelectAccount(PaymentAccount paymentAccount) {

View file

@ -24,6 +24,8 @@ import io.bitsquare.locale.FiatCurrency;
import io.bitsquare.locale.TradeCurrency;
import io.bitsquare.payment.PaymentAccount;
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.User;
import javafx.collections.FXCollections;
@ -37,13 +39,17 @@ class FiatAccountsDataModel extends ActivatableDataModel {
private final User user;
private Preferences preferences;
private final OpenOfferManager openOfferManager;
private final TradeManager tradeManager;
final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
private final SetChangeListener<PaymentAccount> setChangeListener;
@Inject
public FiatAccountsDataModel(User user, Preferences preferences) {
public FiatAccountsDataModel(User user, Preferences preferences, OpenOfferManager openOfferManager, TradeManager tradeManager) {
this.user = user;
this.preferences = preferences;
this.openOfferManager = openOfferManager;
this.tradeManager = tradeManager;
setChangeListener = change -> fillAndSortPaymentAccounts();
}
@ -90,8 +96,19 @@ class FiatAccountsDataModel extends ActivatableDataModel {
}
}
public void onDeleteAccount(PaymentAccount paymentAccount) {
user.removePaymentAccount(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);
return isPaymentAccountUsed;
}
public void onSelectAccount(PaymentAccount paymentAccount) {

View file

@ -17,6 +17,7 @@
package io.bitsquare.gui.main.account.content.fiataccounts;
import io.bitsquare.common.UserThread;
import io.bitsquare.common.util.Tuple2;
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
import io.bitsquare.gui.common.view.FxmlView;
@ -45,6 +46,7 @@ import javafx.util.StringConverter;
import javax.inject.Inject;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
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?")
.actionButtonText("Yes")
.onAction(() -> {
model.onDeleteAccount(paymentAccount);
removeSelectAccountForm();
boolean isPaymentAccountUsed = model.onDeleteAccount(paymentAccount);
if (!isPaymentAccountUsed)
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")
.show();

View file

@ -48,8 +48,8 @@ class FiatAccountsViewModel extends ActivatableWithDataModel<FiatAccountsDataMod
dataModel.onSaveNewAccount(paymentAccount);
}
public void onDeleteAccount(PaymentAccount paymentAccount) {
dataModel.onDeleteAccount(paymentAccount);
public boolean onDeleteAccount(PaymentAccount paymentAccount) {
return dataModel.onDeleteAccount(paymentAccount);
}
public void onSelectAccount(PaymentAccount paymentAccount) {

View file

@ -90,7 +90,7 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
new Popup().backgroundInfo("Bitsquare does not use a single application wallet, but dedicated wallets for every trade.\n\n" +
"Funding of the wallet will be done when needed, for instance when you create or take an offer.\n" +
"Withdrawing funds can be done after a trade is completed.\n\n" +
"Dedicated wallets help protect user privacy and prevent leaking information of previous trades to other" +
"Dedicated wallets help protect user privacy and prevent leaking information of previous trades to other " +
"traders.")
.actionButtonText("Visit FAQ web page")
.onAction(() -> Utilities.openWebPage("https://bitsquare.io/faq"))

View file

@ -550,7 +550,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
button.setOnAction(e -> onTakeOffer(offer));
}
if (!isTradable)
if (!myOffer && !isTradable)
button.setOnAction(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator, hasSameProtocolVersion));
button.setText(title);

View file

@ -149,9 +149,11 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
addTitledGroupBg(gridPane, ++rowIndex, rows, "Offer");
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
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()) {
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(tradeAmount));

View file

@ -230,7 +230,8 @@ public class SellerStep3View extends TradeStepView {
if (preferences.showAgain(key)) {
new Popup()
.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 " +
"to the bitcoin buyer and the security deposit will be refunded.")
.width(700)

View file

@ -409,12 +409,12 @@ public class BSFormatter {
"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)" :
"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" :
"You are creating an offer for selling bitcoin";
}