Fix bug with not correctly resolved payment account

This commit is contained in:
Manfred Karrer 2016-07-26 22:27:57 +02:00
parent 281c9f5fa7
commit b239c8692a
7 changed files with 129 additions and 111 deletions

View file

@ -97,7 +97,7 @@ public abstract class BankAccountContractData extends CountryBasedPaymentAccount
@Nullable
public String getBankId() {
return bankId;
return BankUtil.isBankIdRequired(countryCode) ? bankId : bankName;
}
public void setBranchId(String branchId) {

View file

@ -0,0 +1,91 @@
package io.bitsquare.payment;
import io.bitsquare.locale.TradeCurrency;
import io.bitsquare.trade.offer.Offer;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
public class PaymentAccountUtil {
private static final Logger log = LoggerFactory.getLogger(PaymentAccountUtil.class);
public static boolean isAnyPaymentAccountValidForOffer(Offer offer, Collection<PaymentAccount> paymentAccounts) {
for (PaymentAccount paymentAccount : paymentAccounts) {
if (isPaymentAccountValidForOffer(offer, paymentAccount))
return true;
}
return false;
}
public static ObservableList<PaymentAccount> getPossiblePaymentAccounts(Offer offer, Set<PaymentAccount> paymentAccounts) {
ObservableList<PaymentAccount> result = FXCollections.observableArrayList();
for (PaymentAccount paymentAccount : paymentAccounts) {
if (isPaymentAccountValidForOffer(offer, paymentAccount))
result.add(paymentAccount);
}
return result;
}
//TODO not tested with all combinations yet....
public static boolean isPaymentAccountValidForOffer(Offer offer, PaymentAccount paymentAccount) {
// check if we have a matching currency
Set<String> paymentAccountCurrencyCodes = paymentAccount.getTradeCurrencies().stream().map(TradeCurrency::getCode).collect(Collectors.toSet());
boolean matchesCurrencyCode = paymentAccountCurrencyCodes.contains(offer.getCurrencyCode());
if (!matchesCurrencyCode)
return false;
// check if we have a matching payment method or if its a bank account payment method which is treated special
if (paymentAccount instanceof CountryBasedPaymentAccount) {
CountryBasedPaymentAccount countryBasedPaymentAccount = (CountryBasedPaymentAccount) paymentAccount;
// check if we have a matching country
boolean matchesCountryCodes = offer.getAcceptedCountryCodes() != null && countryBasedPaymentAccount.getCountry() != null &&
offer.getAcceptedCountryCodes().contains(countryBasedPaymentAccount.getCountry().code);
if (!matchesCountryCodes)
return false;
if (paymentAccount instanceof SepaAccount || offer.getPaymentMethod().equals(PaymentMethod.SEPA)) {
boolean samePaymentMethod = paymentAccount.getPaymentMethod().equals(offer.getPaymentMethod());
return samePaymentMethod;
} else if (offer.getPaymentMethod().equals(PaymentMethod.SAME_BANK) ||
offer.getPaymentMethod().equals(PaymentMethod.SPECIFIC_BANKS)) {
checkNotNull(offer.getAcceptedBankIds(), "offer.getAcceptedBankIds() must not be null");
if (paymentAccount instanceof SpecificBanksAccount) {
// check if we have a matching bank
boolean offerSideMatchesBank = offer.getAcceptedBankIds().contains(((BankAccount) paymentAccount).getBankId());
boolean paymentAccountSideMatchesBank = ((SpecificBanksAccount) paymentAccount).getAcceptedBanks().contains(offer.getBankId());
return offerSideMatchesBank && paymentAccountSideMatchesBank;
} else {
// national or same bank
boolean matchesBank = offer.getAcceptedBankIds().contains(((BankAccount) paymentAccount).getBankId());
return matchesBank;
}
} else {
if (paymentAccount instanceof SpecificBanksAccount) {
// check if we have a matching bank
boolean paymentAccountSideMatchesBank = ((SpecificBanksAccount) paymentAccount).getAcceptedBanks().contains(offer.getBankId());
return paymentAccountSideMatchesBank;
} else if (paymentAccount instanceof SameBankAccount) {
// check if we have a matching bank
boolean paymentAccountSideMatchesBank = ((SameBankAccount) paymentAccount).getBankId().equals(offer.getBankId());
return paymentAccountSideMatchesBank;
} else {
// national
return true;
}
}
} else {
return paymentAccount.getPaymentMethod().equals(offer.getPaymentMethod());
}
}
}

View file

@ -33,7 +33,8 @@ import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.*;
import io.bitsquare.p2p.NodeAddress;
import io.bitsquare.p2p.P2PService;
import io.bitsquare.payment.*;
import io.bitsquare.payment.PaymentAccountUtil;
import io.bitsquare.payment.PaymentMethod;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.closed.ClosedTradableManager;
import io.bitsquare.trade.offer.Offer;
@ -53,13 +54,9 @@ import org.bitcoinj.utils.Fiat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
class OfferBookViewModel extends ActivatableViewModel {
protected final static Logger log = LoggerFactory.getLogger(OfferBookViewModel.class);
@ -358,70 +355,7 @@ class OfferBookViewModel extends ActivatableViewModel {
}
boolean isAnyPaymentAccountValidForOffer(Offer offer) {
return isAnyPaymentAccountValidForOffer(offer, user.getPaymentAccounts());
}
static boolean isAnyPaymentAccountValidForOffer(Offer offer, Collection<PaymentAccount> paymentAccounts) {
for (PaymentAccount paymentAccount : paymentAccounts) {
if (isPaymentAccountValidForOffer(offer, paymentAccount))
return true;
}
return false;
}
//TODO not tested with all combinations yet....
static boolean isPaymentAccountValidForOffer(Offer offer, PaymentAccount paymentAccount) {
// check if we have a matching currency
Set<String> paymentAccountCurrencyCodes = paymentAccount.getTradeCurrencies().stream().map(TradeCurrency::getCode).collect(Collectors.toSet());
boolean matchesCurrencyCode = paymentAccountCurrencyCodes.contains(offer.getCurrencyCode());
if (!matchesCurrencyCode)
return false;
// check if we have a matching payment method or if its a bank account payment method which is treated special
if (paymentAccount instanceof CountryBasedPaymentAccount) {
CountryBasedPaymentAccount countryBasedPaymentAccount = (CountryBasedPaymentAccount) paymentAccount;
// check if we have a matching country
boolean matchesCountryCodes = offer.getAcceptedCountryCodes() != null && countryBasedPaymentAccount.getCountry() != null &&
offer.getAcceptedCountryCodes().contains(countryBasedPaymentAccount.getCountry().code);
if (!matchesCountryCodes)
return false;
if (paymentAccount instanceof SepaAccount || offer.getPaymentMethod().equals(PaymentMethod.SEPA)) {
boolean samePaymentMethod = paymentAccount.getPaymentMethod().equals(offer.getPaymentMethod());
return samePaymentMethod;
} else if (offer.getPaymentMethod().equals(PaymentMethod.SAME_BANK) ||
offer.getPaymentMethod().equals(PaymentMethod.SPECIFIC_BANKS)) {
checkNotNull(offer.getAcceptedBankIds(), "offer.getAcceptedBankIds() must not be null");
if (paymentAccount instanceof SpecificBanksAccount) {
// check if we have a matching bank
boolean offerSideMatchesBank = offer.getAcceptedBankIds().contains(((BankAccount) paymentAccount).getBankId());
boolean paymentAccountSideMatchesBank = ((SpecificBanksAccount) paymentAccount).getAcceptedBanks().contains(offer.getBankId());
return offerSideMatchesBank && paymentAccountSideMatchesBank;
} else {
// national or same bank
boolean matchesBank = offer.getAcceptedBankIds().contains(((BankAccount) paymentAccount).getBankId());
return matchesBank;
}
} else {
if (paymentAccount instanceof SpecificBanksAccount) {
// check if we have a matching bank
boolean paymentAccountSideMatchesBank = ((SpecificBanksAccount) paymentAccount).getAcceptedBanks().contains(offer.getBankId());
return paymentAccountSideMatchesBank;
} else if (paymentAccount instanceof SameBankAccount) {
// check if we have a matching bank
boolean paymentAccountSideMatchesBank = ((SameBankAccount) paymentAccount).getBankId().equals(offer.getBankId());
return paymentAccountSideMatchesBank;
} else {
// national
return true;
}
}
} else {
return paymentAccount.getPaymentMethod().equals(offer.getPaymentMethod());
}
return PaymentAccountUtil.isAnyPaymentAccountValidForOffer(offer, user.getPaymentAccounts());
}
public boolean hasPaymentAccountForCurrency() {

View file

@ -32,8 +32,8 @@ import io.bitsquare.gui.main.overlays.notifications.Notification;
import io.bitsquare.gui.main.overlays.popups.Popup;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.locale.TradeCurrency;
import io.bitsquare.payment.PaymentAccount;
import io.bitsquare.payment.PaymentAccountUtil;
import io.bitsquare.payment.PaymentMethod;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.handlers.TradeResultHandler;
@ -41,14 +41,12 @@ import io.bitsquare.trade.offer.Offer;
import io.bitsquare.user.Preferences;
import io.bitsquare.user.User;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.utils.ExchangeRate;
import org.bitcoinj.utils.Fiat;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
@ -271,17 +269,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
}
ObservableList<PaymentAccount> getPossiblePaymentAccounts() {
ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList(new ArrayList<>());
for (PaymentAccount paymentAccount : user.getPaymentAccounts()) {
if (paymentAccount.getPaymentMethod().equals(offer.getPaymentMethod())) {
for (TradeCurrency tradeCurrency : paymentAccount.getTradeCurrencies()) {
if (tradeCurrency.getCode().equals(offer.getCurrencyCode())) {
paymentAccounts.add(paymentAccount);
}
}
}
}
return paymentAccounts;
return PaymentAccountUtil.getPossiblePaymentAccounts(offer, user.getPaymentAccounts());
}
boolean hasAcceptedArbitrators() {

View file

@ -192,8 +192,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
balanceTextField.setTargetAmount(model.dataModel.totalToPayAsCoin.get());
if (DevFlags.DEV_MODE)
UserThread.runAfter(() -> onShowPayFundsScreen(), 200, TimeUnit.MILLISECONDS);
/* if (DevFlags.DEV_MODE)
UserThread.runAfter(() -> onShowPayFundsScreen(), 200, TimeUnit.MILLISECONDS);*/
}
@Override

View file

@ -32,6 +32,7 @@ import io.bitsquare.gui.main.overlays.popups.Popup;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.locale.BSResources;
import io.bitsquare.locale.BankUtil;
import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.payment.PaymentAccount;
@ -205,11 +206,15 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
addLabelTextField(gridPane, ++rowIndex, "Payment account:", paymentAccount.getAccountName());
} else {
final String method = BSResources.get(paymentMethod.getId());
if (isNationalBanks || isSpecificBanks)
if (isNationalBanks || isSpecificBanks) {
if (BankUtil.isBankIdRequired(offer.getCountryCode()))
addLabelTextField(gridPane, ++rowIndex, "Payment method (offerers bank ID):", method + " (" + bankId + ")");
else
else if (BankUtil.isBankNameRequired(offer.getCountryCode()))
addLabelTextField(gridPane, ++rowIndex, "Payment method (offerers bank name):", method + " (" + bankId + ")");
} else {
addLabelTextField(gridPane, ++rowIndex, "Payment method:", method);
}
}
if (showAcceptedBanks) {
if (paymentMethod.equals(PaymentMethod.SAME_BANK)) {
addLabelTextField(gridPane, ++rowIndex, "Bank ID (e.g. BIC or SWIFT):", acceptedBanks.get(0));

View file

@ -25,44 +25,44 @@ public class OfferBookViewModelTest {
Collection<PaymentAccount> paymentAccounts;
paymentAccounts = new ArrayList<>(Arrays.asList(getSepaAccount("EUR", "DE", "1212324", new ArrayList<>(Arrays.asList("AT", "DE")))));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// empty paymentAccounts
paymentAccounts = new ArrayList<>();
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// simple cases: same payment methods
// offer: okpay paymentAccount: okpay - same country, same currency
paymentAccounts = new ArrayList<>(Arrays.asList(getOKPayAccount("EUR")));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getOKPayPaymentMethod("EUR"), paymentAccounts));
// offer: ether paymentAccount: ether - same country, same currency
paymentAccounts = new ArrayList<>(Arrays.asList(getCryptoAccount("ETH")));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getBlockChainsPaymentMethod("ETH"), paymentAccounts));
// offer: sepa paymentAccount: sepa - same country, same currency
paymentAccounts = new ArrayList<>(Arrays.asList(getSepaAccount("EUR", "AT", "1212324", new ArrayList<>(Arrays.asList("AT", "DE")))));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// offer: nationalBank paymentAccount: nationalBank - same country, same currency
paymentAccounts = new ArrayList<>(Arrays.asList(getNationalBankAccount("EUR", "AT", "PSK")));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// offer: SameBank paymentAccount: SameBank - same country, same currency
paymentAccounts = new ArrayList<>(Arrays.asList(getSameBankAccount("EUR", "AT", "PSK")));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSameBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// offer: sepa paymentAccount: sepa - diff. country, same currency
paymentAccounts = new ArrayList<>(Arrays.asList(getSepaAccount("EUR", "DE", "1212324", new ArrayList<>(Arrays.asList("AT", "DE")))));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
@ -70,79 +70,79 @@ public class OfferBookViewModelTest {
// offer: sepa paymentAccount: sepa - same country, same currency
paymentAccounts = new ArrayList<>(Arrays.asList(getSepaAccount("EUR", "AT", "1212324", new ArrayList<>(Arrays.asList("AT", "DE")))));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// offer: sepa paymentAccount: nationalBank - same country, same currency
// wrong method
paymentAccounts = new ArrayList<>(Arrays.asList(getNationalBankAccount("EUR", "AT", "PSK")));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// wrong currency
paymentAccounts = new ArrayList<>(Arrays.asList(getNationalBankAccount("USD", "US", "XXX")));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// wrong country
paymentAccounts = new ArrayList<>(Arrays.asList(getNationalBankAccount("EUR", "FR", "PSK")));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// sepa wrong country
paymentAccounts = new ArrayList<>(Arrays.asList(getNationalBankAccount("EUR", "CH", "PSK")));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// sepa wrong currency
paymentAccounts = new ArrayList<>(Arrays.asList(getNationalBankAccount("CHF", "DE", "PSK")));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// same bank
paymentAccounts = new ArrayList<>(Arrays.asList(getSameBankAccount("EUR", "AT", "PSK")));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// not same bank
paymentAccounts = new ArrayList<>(Arrays.asList(getSameBankAccount("EUR", "AT", "Raika")));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// same bank, wrong country
paymentAccounts = new ArrayList<>(Arrays.asList(getSameBankAccount("EUR", "DE", "PSK")));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// same bank, wrong currency
paymentAccounts = new ArrayList<>(Arrays.asList(getSameBankAccount("USD", "AT", "PSK")));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// spec. bank
paymentAccounts = new ArrayList<>(Arrays.asList(getSpecificBanksAccount("EUR", "AT", "PSK",
new ArrayList<>(Arrays.asList("PSK", "Raika")))));
assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// spec. bank, missing bank
paymentAccounts = new ArrayList<>(Arrays.asList(getSpecificBanksAccount("EUR", "AT", "PSK",
new ArrayList<>(Arrays.asList("Raika")))));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// spec. bank, wrong country
paymentAccounts = new ArrayList<>(Arrays.asList(getSpecificBanksAccount("EUR", "FR", "PSK",
new ArrayList<>(Arrays.asList("PSK", "Raika")))));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// spec. bank, wrong currency
paymentAccounts = new ArrayList<>(Arrays.asList(getSpecificBanksAccount("USD", "AT", "PSK",
new ArrayList<>(Arrays.asList("PSK", "Raika")))));
assertFalse(OfferBookViewModel.isAnyPaymentAccountValidForOffer(
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
//TODO add more tests