mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-24 06:49:31 -05:00
support cash by atm payment method #626
This commit is contained in:
parent
92fb41fffa
commit
655583477a
@ -81,6 +81,12 @@ public class CurrencyUtil {
|
|||||||
|
|
||||||
public static List<TradeCurrency> getAllFiatCurrencies() {
|
public static List<TradeCurrency> getAllFiatCurrencies() {
|
||||||
return getAllTraditionalCurrencies().stream()
|
return getAllTraditionalCurrencies().stream()
|
||||||
|
.filter(currency -> CurrencyUtil.isFiatCurrency(currency.getCode()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<TradeCurrency> getAllSortedFiatCurrencies() {
|
||||||
|
return getAllSortedTraditionalCurrencies().stream()
|
||||||
.filter(currency -> CurrencyUtil.isFiatCurrency(currency.getCode()))
|
.filter(currency -> CurrencyUtil.isFiatCurrency(currency.getCode()))
|
||||||
.collect(Collectors.toList()); // sorted by currency name
|
.collect(Collectors.toList()); // sorted by currency name
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import haveno.core.locale.Res;
|
|||||||
import haveno.core.monetary.Price;
|
import haveno.core.monetary.Price;
|
||||||
import haveno.core.payment.PaymentAccount;
|
import haveno.core.payment.PaymentAccount;
|
||||||
import haveno.core.payment.PaymentAccountUtil;
|
import haveno.core.payment.PaymentAccountUtil;
|
||||||
|
import haveno.core.payment.payload.PaymentMethod;
|
||||||
import haveno.core.provider.price.MarketPrice;
|
import haveno.core.provider.price.MarketPrice;
|
||||||
import haveno.core.provider.price.PriceFeedService;
|
import haveno.core.provider.price.PriceFeedService;
|
||||||
import haveno.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
|
import haveno.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
|
||||||
@ -47,8 +48,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static haveno.core.payment.payload.PaymentMethod.HAL_CASH_ID;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CreateOfferService {
|
public class CreateOfferService {
|
||||||
@ -137,7 +136,7 @@ public class CreateOfferService {
|
|||||||
boolean useMarketBasedPriceValue = price == null &&
|
boolean useMarketBasedPriceValue = price == null &&
|
||||||
useMarketBasedPrice &&
|
useMarketBasedPrice &&
|
||||||
isMarketPriceAvailable(currencyCode) &&
|
isMarketPriceAvailable(currencyCode) &&
|
||||||
!paymentAccount.hasPaymentMethodWithId(HAL_CASH_ID);
|
!PaymentMethod.isFixedPriceOnly(paymentAccount.getPaymentMethod().getId());
|
||||||
|
|
||||||
// verify price
|
// verify price
|
||||||
if (price == null && !useMarketBasedPriceValue) {
|
if (price == null && !useMarketBasedPriceValue) {
|
||||||
|
@ -246,10 +246,7 @@ public class Offer implements NetworkPayload, PersistablePayload {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Volume volumeByAmount = price.getVolumeByAmount(amount);
|
Volume volumeByAmount = price.getVolumeByAmount(amount);
|
||||||
if (offerPayload.getPaymentMethodId().equals(PaymentMethod.HAL_CASH_ID))
|
volumeByAmount = VolumeUtil.getAdjustedVolume(volumeByAmount, getPaymentMethod().getId());
|
||||||
volumeByAmount = VolumeUtil.getAdjustedVolumeForHalCash(volumeByAmount);
|
|
||||||
else if (isFiatOffer())
|
|
||||||
volumeByAmount = VolumeUtil.getRoundedFiatVolume(volumeByAmount);
|
|
||||||
|
|
||||||
return volumeByAmount;
|
return volumeByAmount;
|
||||||
}
|
}
|
||||||
|
@ -19,15 +19,14 @@ package haveno.core.offer.takeoffer;
|
|||||||
|
|
||||||
import haveno.common.taskrunner.Model;
|
import haveno.common.taskrunner.Model;
|
||||||
import haveno.core.account.witness.AccountAgeWitnessService;
|
import haveno.core.account.witness.AccountAgeWitnessService;
|
||||||
import haveno.core.locale.CurrencyUtil;
|
|
||||||
import haveno.core.monetary.Price;
|
import haveno.core.monetary.Price;
|
||||||
import haveno.core.monetary.Volume;
|
import haveno.core.monetary.Volume;
|
||||||
import haveno.core.offer.Offer;
|
import haveno.core.offer.Offer;
|
||||||
import haveno.core.offer.OfferUtil;
|
import haveno.core.offer.OfferUtil;
|
||||||
import haveno.core.payment.PaymentAccount;
|
import haveno.core.payment.PaymentAccount;
|
||||||
import haveno.core.payment.payload.PaymentMethod;
|
|
||||||
import haveno.core.provider.price.PriceFeedService;
|
import haveno.core.provider.price.PriceFeedService;
|
||||||
import haveno.core.trade.HavenoUtils;
|
import haveno.core.trade.HavenoUtils;
|
||||||
|
import haveno.core.util.VolumeUtil;
|
||||||
import haveno.core.xmr.model.XmrAddressEntry;
|
import haveno.core.xmr.model.XmrAddressEntry;
|
||||||
import haveno.core.xmr.wallet.XmrWalletService;
|
import haveno.core.xmr.wallet.XmrWalletService;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -41,8 +40,6 @@ import java.util.Objects;
|
|||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static haveno.core.offer.OfferDirection.SELL;
|
import static haveno.core.offer.OfferDirection.SELL;
|
||||||
import static haveno.core.util.VolumeUtil.getAdjustedVolumeForHalCash;
|
|
||||||
import static haveno.core.util.VolumeUtil.getRoundedFiatVolume;
|
|
||||||
import static haveno.core.xmr.model.XmrAddressEntry.Context.OFFER_FUNDING;
|
import static haveno.core.xmr.model.XmrAddressEntry.Context.OFFER_FUNDING;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -136,11 +133,7 @@ public class TakeOfferModel implements Model {
|
|||||||
private void calculateVolume() {
|
private void calculateVolume() {
|
||||||
Price tradePrice = offer.getPrice();
|
Price tradePrice = offer.getPrice();
|
||||||
Volume volumeByAmount = Objects.requireNonNull(tradePrice).getVolumeByAmount(amount);
|
Volume volumeByAmount = Objects.requireNonNull(tradePrice).getVolumeByAmount(amount);
|
||||||
|
volumeByAmount = VolumeUtil.getAdjustedVolume(volumeByAmount, offer.getPaymentMethod().getId());
|
||||||
if (offer.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID))
|
|
||||||
volumeByAmount = getAdjustedVolumeForHalCash(volumeByAmount);
|
|
||||||
else if (CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()))
|
|
||||||
volumeByAmount = getRoundedFiatVolume(volumeByAmount);
|
|
||||||
|
|
||||||
volume = volumeByAmount;
|
volume = volumeByAmount;
|
||||||
|
|
||||||
|
64
core/src/main/java/haveno/core/payment/CashByAtmAccount.java
Normal file
64
core/src/main/java/haveno/core/payment/CashByAtmAccount.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Haveno.
|
||||||
|
*
|
||||||
|
* Haveno is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Haveno is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package haveno.core.payment;
|
||||||
|
|
||||||
|
import haveno.core.api.model.PaymentAccountFormField;
|
||||||
|
import haveno.core.locale.CurrencyUtil;
|
||||||
|
import haveno.core.locale.TradeCurrency;
|
||||||
|
import haveno.core.payment.payload.CashByAtmAccountPayload;
|
||||||
|
import haveno.core.payment.payload.PaymentAccountPayload;
|
||||||
|
import haveno.core.payment.payload.PaymentMethod;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class CashByAtmAccount extends PaymentAccount {
|
||||||
|
|
||||||
|
public static final List<TradeCurrency> SUPPORTED_CURRENCIES = CurrencyUtil.getAllFiatCurrencies();
|
||||||
|
|
||||||
|
private static final List<PaymentAccountFormField.FieldId> INPUT_FIELD_IDS = List.of(
|
||||||
|
PaymentAccountFormField.FieldId.EXTRA_INFO
|
||||||
|
);
|
||||||
|
|
||||||
|
public CashByAtmAccount() {
|
||||||
|
super(PaymentMethod.CASH_BY_ATM);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PaymentAccountPayload createPayload() {
|
||||||
|
return new CashByAtmAccountPayload(paymentMethod.getId(), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull List<TradeCurrency> getSupportedCurrencies() {
|
||||||
|
return SUPPORTED_CURRENCIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull List<PaymentAccountFormField.FieldId> getInputFieldIds() {
|
||||||
|
return INPUT_FIELD_IDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtraInfo(String extraInfo) {
|
||||||
|
((CashByAtmAccountPayload) paymentAccountPayload).setExtraInfo(extraInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExtraInfo() {
|
||||||
|
return ((CashByAtmAccountPayload) paymentAccountPayload).getExtraInfo();
|
||||||
|
}
|
||||||
|
}
|
@ -76,6 +76,8 @@ public class PaymentAccountFactory {
|
|||||||
return new F2FAccount();
|
return new F2FAccount();
|
||||||
case PaymentMethod.PAY_BY_MAIL_ID:
|
case PaymentMethod.PAY_BY_MAIL_ID:
|
||||||
return new PayByMailAccount();
|
return new PayByMailAccount();
|
||||||
|
case PaymentMethod.CASH_BY_ATM_ID:
|
||||||
|
return new CashByAtmAccount();
|
||||||
case PaymentMethod.PROMPT_PAY_ID:
|
case PaymentMethod.PROMPT_PAY_ID:
|
||||||
return new PromptPayAccount();
|
return new PromptPayAccount();
|
||||||
case PaymentMethod.ADVANCED_CASH_ID:
|
case PaymentMethod.ADVANCED_CASH_ID:
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Haveno.
|
||||||
|
*
|
||||||
|
* Haveno is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Haveno is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package haveno.core.payment.payload;
|
||||||
|
|
||||||
|
import com.google.protobuf.Message;
|
||||||
|
import haveno.core.locale.Res;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Slf4j
|
||||||
|
public final class CashByAtmAccountPayload extends PaymentAccountPayload {
|
||||||
|
private String extraInfo = "";
|
||||||
|
|
||||||
|
public CashByAtmAccountPayload(String paymentMethod, String id) {
|
||||||
|
super(paymentMethod, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PROTO BUFFER
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private CashByAtmAccountPayload(String paymentMethod, String id,
|
||||||
|
String extraInfo,
|
||||||
|
long maxTradePeriod,
|
||||||
|
Map<String, String> excludeFromJsonDataMap) {
|
||||||
|
super(paymentMethod,
|
||||||
|
id,
|
||||||
|
maxTradePeriod,
|
||||||
|
excludeFromJsonDataMap);
|
||||||
|
this.extraInfo = extraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message toProtoMessage() {
|
||||||
|
return getPaymentAccountPayloadBuilder()
|
||||||
|
.setCashByAtmAccountPayload(protobuf.CashByAtmAccountPayload.newBuilder()
|
||||||
|
.setExtraInfo(extraInfo))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CashByAtmAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
|
||||||
|
return new CashByAtmAccountPayload(proto.getPaymentMethodId(),
|
||||||
|
proto.getId(),
|
||||||
|
proto.getCashByAtmAccountPayload().getExtraInfo(),
|
||||||
|
proto.getMaxTradePeriod(),
|
||||||
|
new HashMap<>(proto.getExcludeFromJsonDataMap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// API
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPaymentDetails() {
|
||||||
|
return Res.getWithCol("payment.shared.extraInfo") + " " + extraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPaymentDetailsForTradePopup() {
|
||||||
|
return Res.getWithCol("payment.shared.extraInfo") + " " + extraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getAgeWitnessInputData() {
|
||||||
|
return super.getAgeWitnessInputData(ArrayUtils.addAll(id.getBytes(StandardCharsets.UTF_8)));
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,7 @@ import haveno.core.payment.AmazonGiftCardAccount;
|
|||||||
import haveno.core.payment.AustraliaPayidAccount;
|
import haveno.core.payment.AustraliaPayidAccount;
|
||||||
import haveno.core.payment.BizumAccount;
|
import haveno.core.payment.BizumAccount;
|
||||||
import haveno.core.payment.CapitualAccount;
|
import haveno.core.payment.CapitualAccount;
|
||||||
|
import haveno.core.payment.CashByAtmAccount;
|
||||||
import haveno.core.payment.PayByMailAccount;
|
import haveno.core.payment.PayByMailAccount;
|
||||||
import haveno.core.payment.CashDepositAccount;
|
import haveno.core.payment.CashDepositAccount;
|
||||||
import haveno.core.payment.CelPayAccount;
|
import haveno.core.payment.CelPayAccount;
|
||||||
@ -162,6 +163,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
|||||||
public static final String AMAZON_GIFT_CARD_ID = "AMAZON_GIFT_CARD";
|
public static final String AMAZON_GIFT_CARD_ID = "AMAZON_GIFT_CARD";
|
||||||
public static final String BLOCK_CHAINS_INSTANT_ID = "BLOCK_CHAINS_INSTANT";
|
public static final String BLOCK_CHAINS_INSTANT_ID = "BLOCK_CHAINS_INSTANT";
|
||||||
public static final String PAY_BY_MAIL_ID = "PAY_BY_MAIL";
|
public static final String PAY_BY_MAIL_ID = "PAY_BY_MAIL";
|
||||||
|
public static final String CASH_BY_ATM_ID = "CASH_BY_ATM";
|
||||||
public static final String CAPITUAL_ID = "CAPITUAL";
|
public static final String CAPITUAL_ID = "CAPITUAL";
|
||||||
public static final String CELPAY_ID = "CELPAY";
|
public static final String CELPAY_ID = "CELPAY";
|
||||||
public static final String MONESE_ID = "MONESE";
|
public static final String MONESE_ID = "MONESE";
|
||||||
@ -224,6 +226,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
|||||||
public static PaymentMethod AMAZON_GIFT_CARD;
|
public static PaymentMethod AMAZON_GIFT_CARD;
|
||||||
public static PaymentMethod BLOCK_CHAINS_INSTANT;
|
public static PaymentMethod BLOCK_CHAINS_INSTANT;
|
||||||
public static PaymentMethod PAY_BY_MAIL;
|
public static PaymentMethod PAY_BY_MAIL;
|
||||||
|
public static PaymentMethod CASH_BY_ATM;
|
||||||
public static PaymentMethod CAPITUAL;
|
public static PaymentMethod CAPITUAL;
|
||||||
public static PaymentMethod CELPAY;
|
public static PaymentMethod CELPAY;
|
||||||
public static PaymentMethod MONESE;
|
public static PaymentMethod MONESE;
|
||||||
@ -271,6 +274,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
|||||||
// Global
|
// Global
|
||||||
CASH_DEPOSIT = new PaymentMethod(CASH_DEPOSIT_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK, getAssetCodes(CashDepositAccount.SUPPORTED_CURRENCIES)),
|
CASH_DEPOSIT = new PaymentMethod(CASH_DEPOSIT_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK, getAssetCodes(CashDepositAccount.SUPPORTED_CURRENCIES)),
|
||||||
PAY_BY_MAIL = new PaymentMethod(PAY_BY_MAIL_ID, 8 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK, getAssetCodes(PayByMailAccount.SUPPORTED_CURRENCIES)),
|
PAY_BY_MAIL = new PaymentMethod(PAY_BY_MAIL_ID, 8 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK, getAssetCodes(PayByMailAccount.SUPPORTED_CURRENCIES)),
|
||||||
|
CASH_BY_ATM = new PaymentMethod(CASH_BY_ATM_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK, getAssetCodes(CashByAtmAccount.SUPPORTED_CURRENCIES)),
|
||||||
MONEY_GRAM = new PaymentMethod(MONEY_GRAM_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_MID_RISK, getAssetCodes(MoneyGramAccount.SUPPORTED_CURRENCIES)),
|
MONEY_GRAM = new PaymentMethod(MONEY_GRAM_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_MID_RISK, getAssetCodes(MoneyGramAccount.SUPPORTED_CURRENCIES)),
|
||||||
WESTERN_UNION = new PaymentMethod(WESTERN_UNION_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_MID_RISK, getAssetCodes(WesternUnionAccount.SUPPORTED_CURRENCIES)),
|
WESTERN_UNION = new PaymentMethod(WESTERN_UNION_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_MID_RISK, getAssetCodes(WesternUnionAccount.SUPPORTED_CURRENCIES)),
|
||||||
NATIONAL_BANK = new PaymentMethod(NATIONAL_BANK_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK, getAssetCodes(NationalBankAccount.SUPPORTED_CURRENCIES)),
|
NATIONAL_BANK = new PaymentMethod(NATIONAL_BANK_ID, 4 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK, getAssetCodes(NationalBankAccount.SUPPORTED_CURRENCIES)),
|
||||||
@ -560,4 +564,14 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
|||||||
id.equals(PaymentMethod.MONEY_BEAM_ID) ||
|
id.equals(PaymentMethod.MONEY_BEAM_ID) ||
|
||||||
id.equals(PaymentMethod.UPHOLD_ID);
|
id.equals(PaymentMethod.UPHOLD_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isRoundedForAtmCash(String id) {
|
||||||
|
return id.equals(PaymentMethod.CASH_BY_ATM_ID) ||
|
||||||
|
id.equals(PaymentMethod.HAL_CASH_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isFixedPriceOnly(String id) {
|
||||||
|
return id.equals(PaymentMethod.CASH_BY_ATM_ID) ||
|
||||||
|
id.equals(PaymentMethod.HAL_CASH_ID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import haveno.core.payment.payload.AustraliaPayidAccountPayload;
|
|||||||
import haveno.core.payment.payload.BizumAccountPayload;
|
import haveno.core.payment.payload.BizumAccountPayload;
|
||||||
import haveno.core.payment.payload.CapitualAccountPayload;
|
import haveno.core.payment.payload.CapitualAccountPayload;
|
||||||
import haveno.core.payment.payload.CashAppAccountPayload;
|
import haveno.core.payment.payload.CashAppAccountPayload;
|
||||||
|
import haveno.core.payment.payload.CashByAtmAccountPayload;
|
||||||
import haveno.core.payment.payload.PayByMailAccountPayload;
|
import haveno.core.payment.payload.PayByMailAccountPayload;
|
||||||
import haveno.core.payment.payload.CashDepositAccountPayload;
|
import haveno.core.payment.payload.CashDepositAccountPayload;
|
||||||
import haveno.core.payment.payload.CelPayAccountPayload;
|
import haveno.core.payment.payload.CelPayAccountPayload;
|
||||||
@ -201,6 +202,8 @@ public class CoreProtoResolver implements ProtoResolver {
|
|||||||
return USPostalMoneyOrderAccountPayload.fromProto(proto);
|
return USPostalMoneyOrderAccountPayload.fromProto(proto);
|
||||||
case PAY_BY_MAIL_ACCOUNT_PAYLOAD:
|
case PAY_BY_MAIL_ACCOUNT_PAYLOAD:
|
||||||
return PayByMailAccountPayload.fromProto(proto);
|
return PayByMailAccountPayload.fromProto(proto);
|
||||||
|
case CASH_BY_ATM_ACCOUNT_PAYLOAD:
|
||||||
|
return CashByAtmAccountPayload.fromProto(proto);
|
||||||
case PROMPT_PAY_ACCOUNT_PAYLOAD:
|
case PROMPT_PAY_ACCOUNT_PAYLOAD:
|
||||||
return PromptPayAccountPayload.fromProto(proto);
|
return PromptPayAccountPayload.fromProto(proto);
|
||||||
case ADVANCED_CASH_ACCOUNT_PAYLOAD:
|
case ADVANCED_CASH_ACCOUNT_PAYLOAD:
|
||||||
|
@ -22,7 +22,6 @@ import haveno.common.crypto.PubKeyRing;
|
|||||||
import haveno.common.proto.network.NetworkPayload;
|
import haveno.common.proto.network.NetworkPayload;
|
||||||
import haveno.common.util.JsonExclude;
|
import haveno.common.util.JsonExclude;
|
||||||
import haveno.common.util.Utilities;
|
import haveno.common.util.Utilities;
|
||||||
import haveno.core.locale.CurrencyUtil;
|
|
||||||
import haveno.core.monetary.Price;
|
import haveno.core.monetary.Price;
|
||||||
import haveno.core.monetary.Volume;
|
import haveno.core.monetary.Volume;
|
||||||
import haveno.core.offer.OfferPayload;
|
import haveno.core.offer.OfferPayload;
|
||||||
@ -204,12 +203,7 @@ public final class Contract implements NetworkPayload {
|
|||||||
|
|
||||||
public Volume getTradeVolume() {
|
public Volume getTradeVolume() {
|
||||||
Volume volumeByAmount = getPrice().getVolumeByAmount(getTradeAmount());
|
Volume volumeByAmount = getPrice().getVolumeByAmount(getTradeAmount());
|
||||||
|
volumeByAmount = VolumeUtil.getAdjustedVolume(volumeByAmount, getPaymentMethodId());
|
||||||
if (getPaymentMethodId().equals(PaymentMethod.HAL_CASH_ID))
|
|
||||||
volumeByAmount = VolumeUtil.getAdjustedVolumeForHalCash(volumeByAmount);
|
|
||||||
else if (CurrencyUtil.isFiatCurrency(getOfferPayload().getCurrencyCode()))
|
|
||||||
volumeByAmount = VolumeUtil.getRoundedFiatVolume(volumeByAmount);
|
|
||||||
|
|
||||||
return volumeByAmount;
|
return volumeByAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,13 +28,11 @@ import haveno.common.proto.ProtoUtil;
|
|||||||
import haveno.common.taskrunner.Model;
|
import haveno.common.taskrunner.Model;
|
||||||
import haveno.common.util.Utilities;
|
import haveno.common.util.Utilities;
|
||||||
import haveno.core.api.CoreMoneroConnectionsService;
|
import haveno.core.api.CoreMoneroConnectionsService;
|
||||||
import haveno.core.locale.CurrencyUtil;
|
|
||||||
import haveno.core.monetary.Price;
|
import haveno.core.monetary.Price;
|
||||||
import haveno.core.monetary.Volume;
|
import haveno.core.monetary.Volume;
|
||||||
import haveno.core.offer.Offer;
|
import haveno.core.offer.Offer;
|
||||||
import haveno.core.offer.OfferDirection;
|
import haveno.core.offer.OfferDirection;
|
||||||
import haveno.core.payment.payload.PaymentAccountPayload;
|
import haveno.core.payment.payload.PaymentAccountPayload;
|
||||||
import haveno.core.payment.payload.PaymentMethod;
|
|
||||||
import haveno.core.proto.CoreProtoResolver;
|
import haveno.core.proto.CoreProtoResolver;
|
||||||
import haveno.core.proto.network.CoreNetworkProtoResolver;
|
import haveno.core.proto.network.CoreNetworkProtoResolver;
|
||||||
import haveno.core.support.dispute.Dispute;
|
import haveno.core.support.dispute.Dispute;
|
||||||
@ -1438,14 +1436,7 @@ public abstract class Trade implements Tradable, Model {
|
|||||||
try {
|
try {
|
||||||
if (getAmount() != null && getPrice() != null) {
|
if (getAmount() != null && getPrice() != null) {
|
||||||
Volume volumeByAmount = getPrice().getVolumeByAmount(getAmount());
|
Volume volumeByAmount = getPrice().getVolumeByAmount(getAmount());
|
||||||
if (offer != null) {
|
if (offer != null) volumeByAmount = VolumeUtil.getAdjustedVolume(volumeByAmount, offer.getPaymentMethod().getId());
|
||||||
if (offer.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID))
|
|
||||||
volumeByAmount = VolumeUtil.getAdjustedVolumeForHalCash(volumeByAmount);
|
|
||||||
else if (CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()))
|
|
||||||
volumeByAmount = VolumeUtil.getRoundedFiatVolume(volumeByAmount);
|
|
||||||
else if (CurrencyUtil.isTraditionalCurrency(offer.getCurrencyCode()))
|
|
||||||
volumeByAmount = VolumeUtil.getRoundedTraditionalVolume(volumeByAmount);
|
|
||||||
}
|
|
||||||
return volumeByAmount;
|
return volumeByAmount;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -26,6 +26,7 @@ import haveno.core.monetary.TraditionalMoney;
|
|||||||
import haveno.core.monetary.TraditionalExchangeRate;
|
import haveno.core.monetary.TraditionalExchangeRate;
|
||||||
import haveno.core.monetary.Volume;
|
import haveno.core.monetary.Volume;
|
||||||
import haveno.core.offer.Offer;
|
import haveno.core.offer.Offer;
|
||||||
|
import haveno.core.payment.payload.PaymentMethod;
|
||||||
import haveno.core.trade.HavenoUtils;
|
import haveno.core.trade.HavenoUtils;
|
||||||
import org.bitcoinj.core.Monetary;
|
import org.bitcoinj.core.Monetary;
|
||||||
import org.bitcoinj.utils.MonetaryFormat;
|
import org.bitcoinj.utils.MonetaryFormat;
|
||||||
@ -42,23 +43,33 @@ public class VolumeUtil {
|
|||||||
|
|
||||||
private static double EXPONENT = Math.pow(10, TraditionalMoney.SMALLEST_UNIT_EXPONENT); // 1000000000000 with precision 8
|
private static double EXPONENT = Math.pow(10, TraditionalMoney.SMALLEST_UNIT_EXPONENT); // 1000000000000 with precision 8
|
||||||
|
|
||||||
|
public static Volume getAdjustedVolume(Volume volumeByAmount, String paymentMethodId) {
|
||||||
|
if (PaymentMethod.isRoundedForAtmCash(paymentMethodId))
|
||||||
|
return VolumeUtil.getRoundedAtmCashVolume(volumeByAmount);
|
||||||
|
else if (CurrencyUtil.isFiatCurrency(volumeByAmount.getCurrencyCode()))
|
||||||
|
return VolumeUtil.getRoundedFiatVolume(volumeByAmount);
|
||||||
|
else if (CurrencyUtil.isTraditionalCurrency(volumeByAmount.getCurrencyCode()))
|
||||||
|
return VolumeUtil.getRoundedTraditionalVolume(volumeByAmount);
|
||||||
|
return volumeByAmount;
|
||||||
|
}
|
||||||
|
|
||||||
public static Volume getRoundedFiatVolume(Volume volumeByAmount) {
|
public static Volume getRoundedFiatVolume(Volume volumeByAmount) {
|
||||||
// We want to get rounded to 1 unit of the fiat currency, e.g. 1 EUR.
|
// We want to get rounded to 1 unit of the fiat currency, e.g. 1 EUR.
|
||||||
return getAdjustedFiatVolume(volumeByAmount, 1);
|
return getAdjustedFiatVolume(volumeByAmount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Volume getRoundedAtmCashVolume(Volume volumeByAmount) {
|
||||||
|
// EUR has precision TraditionalMoney.SMALLEST_UNIT_EXPONENT and we want multiple of 10 so we divide by EXPONENT then
|
||||||
|
// round and multiply with 10
|
||||||
|
return getAdjustedFiatVolume(volumeByAmount, 10);
|
||||||
|
}
|
||||||
|
|
||||||
public static Volume getRoundedTraditionalVolume(Volume volumeByAmount) {
|
public static Volume getRoundedTraditionalVolume(Volume volumeByAmount) {
|
||||||
DecimalFormat decimalFormat = new DecimalFormat("#.####");
|
DecimalFormat decimalFormat = new DecimalFormat("#.####");
|
||||||
double roundedVolume = Double.parseDouble(decimalFormat.format(Double.parseDouble(volumeByAmount.toString())));
|
double roundedVolume = Double.parseDouble(decimalFormat.format(Double.parseDouble(volumeByAmount.toString())));
|
||||||
return Volume.parse(String.valueOf(roundedVolume), volumeByAmount.getCurrencyCode());
|
return Volume.parse(String.valueOf(roundedVolume), volumeByAmount.getCurrencyCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Volume getAdjustedVolumeForHalCash(Volume volumeByAmount) {
|
|
||||||
// EUR has precision TraditionalMoney.SMALLEST_UNIT_EXPONENT and we want multiple of 10 so we divide by EXPONENT then
|
|
||||||
// round and multiply with 10
|
|
||||||
return getAdjustedFiatVolume(volumeByAmount, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param volumeByAmount The volume generated from an amount
|
* @param volumeByAmount The volume generated from an amount
|
||||||
|
@ -19,14 +19,17 @@ package haveno.core.util.coin;
|
|||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import haveno.common.util.MathUtils;
|
import haveno.common.util.MathUtils;
|
||||||
|
import haveno.core.locale.CurrencyUtil;
|
||||||
import haveno.core.monetary.Price;
|
import haveno.core.monetary.Price;
|
||||||
import haveno.core.monetary.Volume;
|
import haveno.core.monetary.Volume;
|
||||||
|
import haveno.core.payment.payload.PaymentMethod;
|
||||||
import haveno.core.trade.HavenoUtils;
|
import haveno.core.trade.HavenoUtils;
|
||||||
import haveno.core.xmr.wallet.Restrictions;
|
import haveno.core.xmr.wallet.Restrictions;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static haveno.core.util.VolumeUtil.getAdjustedFiatVolume;
|
import static haveno.core.util.VolumeUtil.getAdjustedFiatVolume;
|
||||||
@ -76,6 +79,21 @@ public class CoinUtil {
|
|||||||
return BigDecimal.valueOf(percent).multiply(new BigDecimal(amount)).toBigInteger();
|
return BigDecimal.valueOf(percent).multiply(new BigDecimal(amount)).toBigInteger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BigInteger getRoundedAmount(BigInteger amount, Price price, long maxTradeLimit, String currencyCode, String paymentMethodId) {
|
||||||
|
if (PaymentMethod.isRoundedForAtmCash(paymentMethodId)) {
|
||||||
|
return getRoundedAtmCashAmount(amount, price, maxTradeLimit);
|
||||||
|
} else if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||||
|
return getRoundedFiatAmount(amount, price, maxTradeLimit);
|
||||||
|
} else if (CurrencyUtil.isTraditionalCurrency(currencyCode)) {
|
||||||
|
return getRoundedTraditionalAmount(amount, price, maxTradeLimit);
|
||||||
|
}
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BigInteger getRoundedAtmCashAmount(BigInteger amount, Price price, long maxTradeLimit) {
|
||||||
|
return getAdjustedAmount(amount, price, maxTradeLimit, 10);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the possibly adjusted amount for {@code amount}, taking into account the
|
* Calculate the possibly adjusted amount for {@code amount}, taking into account the
|
||||||
* {@code price} and {@code maxTradeLimit} and {@code factor}.
|
* {@code price} and {@code maxTradeLimit} and {@code factor}.
|
||||||
@ -88,9 +106,11 @@ public class CoinUtil {
|
|||||||
public static BigInteger getRoundedFiatAmount(BigInteger amount, Price price, long maxTradeLimit) {
|
public static BigInteger getRoundedFiatAmount(BigInteger amount, Price price, long maxTradeLimit) {
|
||||||
return getAdjustedAmount(amount, price, maxTradeLimit, 1);
|
return getAdjustedAmount(amount, price, maxTradeLimit, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BigInteger getAdjustedAmountForHalCash(BigInteger amount, Price price, long maxTradeLimit) {
|
public static BigInteger getRoundedTraditionalAmount(BigInteger amount, Price price, long maxTradeLimit) {
|
||||||
return getAdjustedAmount(amount, price, maxTradeLimit, 10);
|
DecimalFormat decimalFormat = new DecimalFormat("#.####");
|
||||||
|
double roundedXmrAmount = Double.parseDouble(decimalFormat.format(HavenoUtils.atomicUnitsToXmr(amount)));
|
||||||
|
return HavenoUtils.xmrToAtomicUnits(roundedXmrAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2943,13 +2943,6 @@ payment.payByMail.info=Trading using pay-by-mail (PBM) on Haveno requires that y
|
|||||||
|
|
||||||
payment.payByMail.contact=Contact info
|
payment.payByMail.contact=Contact info
|
||||||
payment.payByMail.contact.prompt=Name or nym envelope should be addressed to
|
payment.payByMail.contact.prompt=Name or nym envelope should be addressed to
|
||||||
payment.f2f.contact=Contact info
|
|
||||||
payment.f2f.contact.prompt=How would you like to be contacted by the trading peer? (email address, phone number,...)
|
|
||||||
payment.f2f.city=City for 'Face to face' meeting
|
|
||||||
payment.f2f.city.prompt=The city will be displayed with the offer
|
|
||||||
payment.shared.optionalExtra=Optional additional information
|
|
||||||
payment.shared.extraInfo=Additional information
|
|
||||||
payment.shared.extraInfo.prompt=Define any special terms, conditions, or details you would like to be displayed with your offers for this payment account (users will see this info before accepting offers).
|
|
||||||
payment.payByMail.extraInfo.prompt=Please state on your offers: \n\n\
|
payment.payByMail.extraInfo.prompt=Please state on your offers: \n\n\
|
||||||
Country you are located (eg France); \n\
|
Country you are located (eg France); \n\
|
||||||
Countries / regions you would accept trades from (eg France, EU, or any European country); \n\
|
Countries / regions you would accept trades from (eg France, EU, or any European country); \n\
|
||||||
@ -2957,6 +2950,23 @@ Any special terms/conditions; \n\
|
|||||||
Any other details.
|
Any other details.
|
||||||
payment.payByMail.tradingRestrictions=Please review the maker's terms and conditions.\n\
|
payment.payByMail.tradingRestrictions=Please review the maker's terms and conditions.\n\
|
||||||
If you do not meet the requirements do not take this trade.
|
If you do not meet the requirements do not take this trade.
|
||||||
|
payment.cashByAtm.info=Cash at ATM: Cardless withdraw at ATM using code\n\n\
|
||||||
|
1. List your accepted banks, regions, or other terms.\n\n\
|
||||||
|
2. Chat with your peer trader to coordinate a time and share the withdraw code.\n\n\
|
||||||
|
If you cannot complete the transaction as specified in your trade contract, you may lose some (or all) of your security deposit.
|
||||||
|
payment.cashByAtm.extraInfo.prompt=Please state on your offers: \n\n\
|
||||||
|
Your accepted banks / locations; \n\
|
||||||
|
Any special terms/conditions; \n\
|
||||||
|
Any other details.
|
||||||
|
payment.payByMail.tradingRestrictions=Please review the maker's terms and conditions.\n\
|
||||||
|
If you do not meet the requirements do not take this trade.
|
||||||
|
payment.f2f.contact=Contact info
|
||||||
|
payment.f2f.contact.prompt=How would you like to be contacted by the trading peer? (email address, phone number,...)
|
||||||
|
payment.f2f.city=City for 'Face to face' meeting
|
||||||
|
payment.f2f.city.prompt=The city will be displayed with the offer
|
||||||
|
payment.shared.optionalExtra=Optional additional information
|
||||||
|
payment.shared.extraInfo=Additional information
|
||||||
|
payment.shared.extraInfo.prompt=Define any special terms, conditions, or details you would like to be displayed with your offers for this payment account (users will see this info before accepting offers).
|
||||||
payment.f2f.info='Face to Face' trades have different rules and come with different risks than online transactions.\n\n\
|
payment.f2f.info='Face to Face' trades have different rules and come with different risks than online transactions.\n\n\
|
||||||
The main differences are:\n\
|
The main differences are:\n\
|
||||||
● The trading peers need to exchange information about the meeting location and time by using their provided contact details.\n\
|
● The trading peers need to exchange information about the meeting location and time by using their provided contact details.\n\
|
||||||
@ -3001,6 +3011,7 @@ SPECIFIC_BANKS=Transfers with specific banks
|
|||||||
US_POSTAL_MONEY_ORDER=US Postal Money Order
|
US_POSTAL_MONEY_ORDER=US Postal Money Order
|
||||||
CASH_DEPOSIT=Cash Deposit
|
CASH_DEPOSIT=Cash Deposit
|
||||||
PAY_BY_MAIL=Pay By Mail
|
PAY_BY_MAIL=Pay By Mail
|
||||||
|
CASH_BY_ATM=Cash by ATM
|
||||||
MONEY_GRAM=MoneyGram
|
MONEY_GRAM=MoneyGram
|
||||||
WESTERN_UNION=Western Union
|
WESTERN_UNION=Western Union
|
||||||
F2F=Face to face (in person)
|
F2F=Face to face (in person)
|
||||||
@ -3018,7 +3029,9 @@ US_POSTAL_MONEY_ORDER_SHORT=US Money Order
|
|||||||
# suppress inspection "UnusedProperty"
|
# suppress inspection "UnusedProperty"
|
||||||
CASH_DEPOSIT_SHORT=Cash Deposit
|
CASH_DEPOSIT_SHORT=Cash Deposit
|
||||||
# suppress inspection "UnusedProperty"
|
# suppress inspection "UnusedProperty"
|
||||||
PAY_BY_MAIL_SHORT=PayByMail
|
PAY_BY_MAIL_SHORT=Pay By Mail
|
||||||
|
# suppress inspection "UnusedProperty"
|
||||||
|
CASH_BY_ATM_SHORT=Cash By ATM
|
||||||
# suppress inspection "UnusedProperty"
|
# suppress inspection "UnusedProperty"
|
||||||
MONEY_GRAM_SHORT=MoneyGram
|
MONEY_GRAM_SHORT=MoneyGram
|
||||||
# suppress inspection "UnusedProperty"
|
# suppress inspection "UnusedProperty"
|
||||||
|
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Haveno.
|
||||||
|
*
|
||||||
|
* Haveno is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Haveno is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package haveno.desktop.components.paymentmethods;
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXTextArea;
|
||||||
|
import haveno.core.account.witness.AccountAgeWitnessService;
|
||||||
|
import haveno.core.locale.CurrencyUtil;
|
||||||
|
import haveno.core.locale.Res;
|
||||||
|
import haveno.core.locale.TradeCurrency;
|
||||||
|
import haveno.core.payment.CashByAtmAccount;
|
||||||
|
import haveno.core.payment.PaymentAccount;
|
||||||
|
import haveno.core.payment.payload.CashByAtmAccountPayload;
|
||||||
|
import haveno.core.payment.payload.PaymentAccountPayload;
|
||||||
|
import haveno.core.util.coin.CoinFormatter;
|
||||||
|
import haveno.core.util.validation.InputValidator;
|
||||||
|
import haveno.desktop.util.Layout;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.scene.control.TextArea;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
|
||||||
|
import static haveno.desktop.util.FormBuilder.addCompactTopLabelTextArea;
|
||||||
|
import static haveno.desktop.util.FormBuilder.addCompactTopLabelTextField;
|
||||||
|
import static haveno.desktop.util.FormBuilder.addTopLabelTextArea;
|
||||||
|
import static haveno.desktop.util.FormBuilder.addTopLabelTextFieldWithCopyIcon;
|
||||||
|
|
||||||
|
public class CashByAtmForm extends PaymentMethodForm {
|
||||||
|
private final CashByAtmAccount cashByAtmAccount;
|
||||||
|
|
||||||
|
public static int addFormForBuyer(GridPane gridPane, int gridRow,
|
||||||
|
PaymentAccountPayload paymentAccountPayload) {
|
||||||
|
CashByAtmAccountPayload cbm = (CashByAtmAccountPayload) paymentAccountPayload;
|
||||||
|
addTopLabelTextFieldWithCopyIcon(gridPane, gridRow, 1,
|
||||||
|
Res.get("payment.shared.extraInfo"),
|
||||||
|
cbm.getExtraInfo(),
|
||||||
|
Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||||
|
|
||||||
|
TextArea textExtraInfo = addCompactTopLabelTextArea(gridPane, gridRow, 1, Res.get("payment.shared.extraInfo"), "").second;
|
||||||
|
textExtraInfo.setMinHeight(70);
|
||||||
|
textExtraInfo.setEditable(false);
|
||||||
|
textExtraInfo.setText(cbm.getExtraInfo());
|
||||||
|
return gridRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CashByAtmForm(PaymentAccount paymentAccount,
|
||||||
|
AccountAgeWitnessService accountAgeWitnessService,
|
||||||
|
InputValidator inputValidator, GridPane gridPane, int gridRow, CoinFormatter formatter) {
|
||||||
|
super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
|
||||||
|
this.cashByAtmAccount = (CashByAtmAccount) paymentAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFormForAddAccount() {
|
||||||
|
gridRowFrom = gridRow + 1;
|
||||||
|
|
||||||
|
addTradeCurrencyComboBox();
|
||||||
|
currencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getAllSortedFiatCurrencies()));
|
||||||
|
|
||||||
|
TextArea extraTextArea = addTopLabelTextArea(gridPane, ++gridRow,
|
||||||
|
Res.get("payment.shared.optionalExtra"), Res.get("payment.cashByAtm.extraInfo.prompt")).second;
|
||||||
|
extraTextArea.setMinHeight(70);
|
||||||
|
((JFXTextArea) extraTextArea).setLabelFloat(false);
|
||||||
|
extraTextArea.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
|
cashByAtmAccount.setExtraInfo(newValue);
|
||||||
|
updateFromInputs();
|
||||||
|
});
|
||||||
|
|
||||||
|
addLimitations(false);
|
||||||
|
addAccountNameTextFieldWithAutoFillToggleButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void autoFillNameTextField() {
|
||||||
|
setAccountNameWithString(cashByAtmAccount.getExtraInfo().substring(0, Math.min(50, cashByAtmAccount.getExtraInfo().length())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFormForEditAccount() {
|
||||||
|
gridRowFrom = gridRow;
|
||||||
|
addAccountNameTextFieldWithAutoFillToggleButton();
|
||||||
|
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.paymentMethod"),
|
||||||
|
Res.get(cashByAtmAccount.getPaymentMethod().getId()));
|
||||||
|
|
||||||
|
TradeCurrency tradeCurrency = paymentAccount.getSingleTradeCurrency();
|
||||||
|
String nameAndCode = tradeCurrency != null ? tradeCurrency.getNameAndCode() : "";
|
||||||
|
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.currency"), nameAndCode);
|
||||||
|
|
||||||
|
TextArea textAreaExtra = addCompactTopLabelTextArea(gridPane, ++gridRow, Res.get("payment.shared.extraInfo"), "").second;
|
||||||
|
textAreaExtra.setText(cashByAtmAccount.getExtraInfo());
|
||||||
|
textAreaExtra.setMinHeight(70);
|
||||||
|
textAreaExtra.setEditable(false);
|
||||||
|
|
||||||
|
addLimitations(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAllInputsValid() {
|
||||||
|
allInputsValid.set(isAccountNameValid()
|
||||||
|
&& !cashByAtmAccount.getExtraInfo().isEmpty()
|
||||||
|
&& paymentAccount.getSingleTradeCurrency() != null);
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ import haveno.core.locale.Res;
|
|||||||
import haveno.core.offer.OfferRestrictions;
|
import haveno.core.offer.OfferRestrictions;
|
||||||
import haveno.core.payment.AmazonGiftCardAccount;
|
import haveno.core.payment.AmazonGiftCardAccount;
|
||||||
import haveno.core.payment.AustraliaPayidAccount;
|
import haveno.core.payment.AustraliaPayidAccount;
|
||||||
|
import haveno.core.payment.CashByAtmAccount;
|
||||||
import haveno.core.payment.PayByMailAccount;
|
import haveno.core.payment.PayByMailAccount;
|
||||||
import haveno.core.payment.CashDepositAccount;
|
import haveno.core.payment.CashDepositAccount;
|
||||||
import haveno.core.payment.ZelleAccount;
|
import haveno.core.payment.ZelleAccount;
|
||||||
@ -72,6 +73,7 @@ import haveno.desktop.components.paymentmethods.AmazonGiftCardForm;
|
|||||||
import haveno.desktop.components.paymentmethods.AustraliaPayidForm;
|
import haveno.desktop.components.paymentmethods.AustraliaPayidForm;
|
||||||
import haveno.desktop.components.paymentmethods.BizumForm;
|
import haveno.desktop.components.paymentmethods.BizumForm;
|
||||||
import haveno.desktop.components.paymentmethods.CapitualForm;
|
import haveno.desktop.components.paymentmethods.CapitualForm;
|
||||||
|
import haveno.desktop.components.paymentmethods.CashByAtmForm;
|
||||||
import haveno.desktop.components.paymentmethods.PayByMailForm;
|
import haveno.desktop.components.paymentmethods.PayByMailForm;
|
||||||
import haveno.desktop.components.paymentmethods.CashDepositForm;
|
import haveno.desktop.components.paymentmethods.CashDepositForm;
|
||||||
import haveno.desktop.components.paymentmethods.CelPayForm;
|
import haveno.desktop.components.paymentmethods.CelPayForm;
|
||||||
@ -270,6 +272,14 @@ public class TraditionalAccountsView extends PaymentAccountsView<GridPane, Tradi
|
|||||||
.actionButtonText(Res.get("shared.iUnderstand"))
|
.actionButtonText(Res.get("shared.iUnderstand"))
|
||||||
.onAction(() -> doSaveNewAccount(paymentAccount))
|
.onAction(() -> doSaveNewAccount(paymentAccount))
|
||||||
.show();
|
.show();
|
||||||
|
} else if (paymentAccount instanceof CashByAtmAccount) {
|
||||||
|
// CashByAtm has no chargeback risk so we don't show the text from payment.limits.info.
|
||||||
|
new Popup().information(Res.get("payment.cashByAtm.info"))
|
||||||
|
.width(850)
|
||||||
|
.closeButtonText(Res.get("shared.cancel"))
|
||||||
|
.actionButtonText(Res.get("shared.iUnderstand"))
|
||||||
|
.onAction(() -> doSaveNewAccount(paymentAccount))
|
||||||
|
.show();
|
||||||
} else if (paymentAccount instanceof HalCashAccount) {
|
} else if (paymentAccount instanceof HalCashAccount) {
|
||||||
// HalCash has no chargeback risk so we don't show the text from payment.limits.info.
|
// HalCash has no chargeback risk so we don't show the text from payment.limits.info.
|
||||||
new Popup().information(Res.get("payment.halCash.info"))
|
new Popup().information(Res.get("payment.halCash.info"))
|
||||||
@ -559,6 +569,8 @@ public class TraditionalAccountsView extends PaymentAccountsView<GridPane, Tradi
|
|||||||
return new CashDepositForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
return new CashDepositForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
||||||
case PaymentMethod.PAY_BY_MAIL_ID:
|
case PaymentMethod.PAY_BY_MAIL_ID:
|
||||||
return new PayByMailForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
return new PayByMailForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
||||||
|
case PaymentMethod.CASH_BY_ATM_ID:
|
||||||
|
return new CashByAtmForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
||||||
case PaymentMethod.HAL_CASH_ID:
|
case PaymentMethod.HAL_CASH_ID:
|
||||||
return new HalCashForm(paymentAccount, accountAgeWitnessService, halCashValidator, inputValidator, root, gridRow, formatter);
|
return new HalCashForm(paymentAccount, accountAgeWitnessService, halCashValidator, inputValidator, root, gridRow, formatter);
|
||||||
case PaymentMethod.F2F_ID:
|
case PaymentMethod.F2F_ID:
|
||||||
|
@ -32,6 +32,7 @@ import haveno.core.offer.OfferDirection;
|
|||||||
import haveno.core.offer.OfferUtil;
|
import haveno.core.offer.OfferUtil;
|
||||||
import haveno.core.offer.OpenOfferManager;
|
import haveno.core.offer.OpenOfferManager;
|
||||||
import haveno.core.payment.PaymentAccount;
|
import haveno.core.payment.PaymentAccount;
|
||||||
|
import haveno.core.payment.payload.PaymentMethod;
|
||||||
import haveno.core.provider.price.PriceFeedService;
|
import haveno.core.provider.price.PriceFeedService;
|
||||||
import haveno.core.trade.HavenoUtils;
|
import haveno.core.trade.HavenoUtils;
|
||||||
import haveno.core.trade.handlers.TransactionResultHandler;
|
import haveno.core.trade.handlers.TransactionResultHandler;
|
||||||
@ -81,7 +82,6 @@ import java.util.function.Predicate;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static haveno.core.payment.payload.PaymentMethod.HAL_CASH_ID;
|
|
||||||
import static java.util.Comparator.comparing;
|
import static java.util.Comparator.comparing;
|
||||||
|
|
||||||
public abstract class MutableOfferDataModel extends OfferDataModel {
|
public abstract class MutableOfferDataModel extends OfferDataModel {
|
||||||
@ -503,12 +503,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
|
|||||||
|
|
||||||
private Volume calculateVolumeForAmount(ObjectProperty<BigInteger> minAmount) {
|
private Volume calculateVolumeForAmount(ObjectProperty<BigInteger> minAmount) {
|
||||||
Volume volumeByAmount = price.get().getVolumeByAmount(minAmount.get());
|
Volume volumeByAmount = price.get().getVolumeByAmount(minAmount.get());
|
||||||
|
volumeByAmount = VolumeUtil.getAdjustedVolume(volumeByAmount, paymentAccount.getPaymentMethod().getId());
|
||||||
// For HalCash we want multiple of 10 EUR
|
|
||||||
if (isUsingHalCashAccount())
|
|
||||||
volumeByAmount = VolumeUtil.getAdjustedVolumeForHalCash(volumeByAmount);
|
|
||||||
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
|
|
||||||
volumeByAmount = VolumeUtil.getRoundedFiatVolume(volumeByAmount);
|
|
||||||
return volumeByAmount;
|
return volumeByAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,10 +511,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
|
|||||||
if (isNonZeroPrice.test(price) && isNonZeroVolume.test(volume) && allowAmountUpdate) {
|
if (isNonZeroPrice.test(price) && isNonZeroVolume.test(volume) && allowAmountUpdate) {
|
||||||
try {
|
try {
|
||||||
BigInteger value = HavenoUtils.coinToAtomicUnits(DisplayUtils.reduceTo4Decimals(HavenoUtils.atomicUnitsToCoin(price.get().getAmountByVolume(volume.get())), btcFormatter));
|
BigInteger value = HavenoUtils.coinToAtomicUnits(DisplayUtils.reduceTo4Decimals(HavenoUtils.atomicUnitsToCoin(price.get().getAmountByVolume(volume.get())), btcFormatter));
|
||||||
if (isUsingHalCashAccount())
|
value = CoinUtil.getRoundedAmount(value, price.get(), getMaxTradeLimit(), tradeCurrencyCode.get(), paymentAccount.getPaymentMethod().getId());
|
||||||
value = CoinUtil.getAdjustedAmountForHalCash(value, price.get(), getMaxTradeLimit());
|
|
||||||
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
|
|
||||||
value = CoinUtil.getRoundedFiatAmount(value, price.get(), getMaxTradeLimit());
|
|
||||||
|
|
||||||
calculateVolume();
|
calculateVolume();
|
||||||
|
|
||||||
@ -680,7 +672,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel {
|
|||||||
this.triggerPrice = triggerPrice;
|
this.triggerPrice = triggerPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUsingHalCashAccount() {
|
public boolean isUsingRoundedAtmCashAccount() {
|
||||||
return paymentAccount.hasPaymentMethodWithId(HAL_CASH_ID);
|
return PaymentMethod.isRoundedForAtmCash(paymentAccount.getPaymentMethod().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,6 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static haveno.core.payment.payload.PaymentMethod.HAL_CASH_ID;
|
|
||||||
import static haveno.desktop.main.offer.OfferViewUtil.addPayInfoEntry;
|
import static haveno.desktop.main.offer.OfferViewUtil.addPayInfoEntry;
|
||||||
import static haveno.desktop.util.FormBuilder.add2ButtonsAfterGroup;
|
import static haveno.desktop.util.FormBuilder.add2ButtonsAfterGroup;
|
||||||
import static haveno.desktop.util.FormBuilder.addAddressTextField;
|
import static haveno.desktop.util.FormBuilder.addAddressTextField;
|
||||||
@ -828,7 +827,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||||||
int marketPriceAvailableValue = model.marketPriceAvailableProperty.get();
|
int marketPriceAvailableValue = model.marketPriceAvailableProperty.get();
|
||||||
if (marketPriceAvailableValue > -1) {
|
if (marketPriceAvailableValue > -1) {
|
||||||
boolean showPriceToggle = marketPriceAvailableValue == 1 &&
|
boolean showPriceToggle = marketPriceAvailableValue == 1 &&
|
||||||
!model.getDataModel().paymentAccount.hasPaymentMethodWithId(HAL_CASH_ID);
|
!PaymentMethod.isFixedPriceOnly(model.getDataModel().paymentAccount.getPaymentMethod().getId());
|
||||||
percentagePriceBox.setVisible(showPriceToggle);
|
percentagePriceBox.setVisible(showPriceToggle);
|
||||||
priceTypeToggleButton.setVisible(showPriceToggle);
|
priceTypeToggleButton.setVisible(showPriceToggle);
|
||||||
boolean fixedPriceSelected = !model.getDataModel().getUseMarketBasedPrice().get() || !showPriceToggle;
|
boolean fixedPriceSelected = !model.getDataModel().getUseMarketBasedPrice().get() || !showPriceToggle;
|
||||||
|
@ -841,12 +841,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
|
|
||||||
Volume volume = dataModel.getVolume().get();
|
Volume volume = dataModel.getVolume().get();
|
||||||
if (volume != null) {
|
if (volume != null) {
|
||||||
// For HalCash we want multiple of 10 EUR
|
volume = VolumeUtil.getAdjustedVolume(volume, dataModel.getPaymentAccount().getPaymentMethod().getId());
|
||||||
if (dataModel.isUsingHalCashAccount())
|
|
||||||
volume = VolumeUtil.getAdjustedVolumeForHalCash(volume);
|
|
||||||
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
|
|
||||||
volume = VolumeUtil.getRoundedFiatVolume(volume);
|
|
||||||
|
|
||||||
this.volume.set(VolumeUtil.formatVolume(volume));
|
this.volume.set(VolumeUtil.formatVolume(volume));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1082,10 +1077,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
||||||
Price price = dataModel.getPrice().get();
|
Price price = dataModel.getPrice().get();
|
||||||
if (price != null && price.isPositive()) {
|
if (price != null && price.isPositive()) {
|
||||||
if (dataModel.isUsingHalCashAccount())
|
amount = CoinUtil.getRoundedAmount(amount, price, maxTradeLimit, tradeCurrencyCode.get(), dataModel.getPaymentAccount().getPaymentMethod().getId());
|
||||||
amount = CoinUtil.getAdjustedAmountForHalCash(amount, price, maxTradeLimit);
|
|
||||||
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
|
|
||||||
amount = CoinUtil.getRoundedFiatAmount(amount, price, maxTradeLimit);
|
|
||||||
}
|
}
|
||||||
dataModel.setAmount(amount);
|
dataModel.setAmount(amount);
|
||||||
if (syncMinAmountWithAmount ||
|
if (syncMinAmountWithAmount ||
|
||||||
@ -1106,10 +1098,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
Price price = dataModel.getPrice().get();
|
Price price = dataModel.getPrice().get();
|
||||||
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
||||||
if (price != null && price.isPositive()) {
|
if (price != null && price.isPositive()) {
|
||||||
if (dataModel.isUsingHalCashAccount())
|
minAmount = CoinUtil.getRoundedAmount(minAmount, price, maxTradeLimit, tradeCurrencyCode.get(), dataModel.getPaymentAccount().getPaymentMethod().getId());
|
||||||
minAmount = CoinUtil.getAdjustedAmountForHalCash(minAmount, price, maxTradeLimit);
|
|
||||||
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
|
|
||||||
minAmount = CoinUtil.getRoundedFiatAmount(minAmount, price, maxTradeLimit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dataModel.setMinAmount(minAmount);
|
dataModel.setMinAmount(minAmount);
|
||||||
|
@ -63,7 +63,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static haveno.core.payment.payload.PaymentMethod.HAL_CASH_ID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain for that UI element.
|
* Domain for that UI element.
|
||||||
@ -376,10 +375,7 @@ class TakeOfferDataModel extends OfferDataModel {
|
|||||||
amount.get() != null &&
|
amount.get() != null &&
|
||||||
amount.get().compareTo(BigInteger.valueOf(0)) != 0) {
|
amount.get().compareTo(BigInteger.valueOf(0)) != 0) {
|
||||||
Volume volumeByAmount = tradePrice.getVolumeByAmount(amount.get());
|
Volume volumeByAmount = tradePrice.getVolumeByAmount(amount.get());
|
||||||
if (offer.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID))
|
volumeByAmount = VolumeUtil.getAdjustedVolume(volumeByAmount, offer.getPaymentMethod().getId());
|
||||||
volumeByAmount = VolumeUtil.getAdjustedVolumeForHalCash(volumeByAmount);
|
|
||||||
else if (offer.isFiatOffer())
|
|
||||||
volumeByAmount = VolumeUtil.getRoundedFiatVolume(volumeByAmount);
|
|
||||||
|
|
||||||
volume.set(volumeByAmount);
|
volume.set(volumeByAmount);
|
||||||
|
|
||||||
@ -491,7 +487,7 @@ class TakeOfferDataModel extends OfferDataModel {
|
|||||||
return offer.getSellerSecurityDeposit();
|
return offer.getSellerSecurityDeposit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUsingHalCashAccount() {
|
public boolean isRoundedForAtmCash() {
|
||||||
return paymentAccount.hasPaymentMethodWithId(HAL_CASH_ID);
|
return PaymentMethod.isRoundedForAtmCash(paymentAccount.getPaymentMethod().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,18 +302,19 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
|
|
||||||
Price tradePrice = dataModel.tradePrice;
|
Price tradePrice = dataModel.tradePrice;
|
||||||
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
||||||
if (dataModel.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID)) {
|
if (PaymentMethod.isRoundedForAtmCash(dataModel.getPaymentMethod().getId())) {
|
||||||
BigInteger adjustedAmountForHalCash = CoinUtil.getAdjustedAmountForHalCash(dataModel.getAmount().get(),
|
BigInteger adjustedAmountForHalCash = CoinUtil.getRoundedAtmCashAmount(dataModel.getAmount().get(),
|
||||||
tradePrice,
|
tradePrice,
|
||||||
maxTradeLimit);
|
maxTradeLimit);
|
||||||
dataModel.applyAmount(adjustedAmountForHalCash);
|
dataModel.applyAmount(adjustedAmountForHalCash);
|
||||||
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
|
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
|
||||||
} else if (dataModel.getOffer().isFiatOffer()) {
|
} else if (dataModel.getOffer().isTraditionalOffer()) {
|
||||||
if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) {
|
if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) {
|
||||||
// We only apply the rounding if the amount is variable (minAmount is lower as 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
|
// Otherwise we could get an amount lower then the minAmount set by rounding
|
||||||
BigInteger roundedAmount = CoinUtil.getRoundedFiatAmount(dataModel.getAmount().get(), tradePrice,
|
BigInteger roundedAmount = dataModel.getOffer().isFiatOffer() ?
|
||||||
maxTradeLimit);
|
CoinUtil.getRoundedFiatAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit) :
|
||||||
|
CoinUtil.getRoundedTraditionalAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit);
|
||||||
dataModel.applyAmount(roundedAmount);
|
dataModel.applyAmount(roundedAmount);
|
||||||
}
|
}
|
||||||
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
|
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
|
||||||
@ -585,13 +586,15 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
||||||
Price price = dataModel.tradePrice;
|
Price price = dataModel.tradePrice;
|
||||||
if (price != null) {
|
if (price != null) {
|
||||||
if (dataModel.isUsingHalCashAccount()) {
|
if (dataModel.isRoundedForAtmCash()) {
|
||||||
amount = CoinUtil.getAdjustedAmountForHalCash(amount, price, maxTradeLimit);
|
amount = CoinUtil.getRoundedAtmCashAmount(amount, price, maxTradeLimit);
|
||||||
} else if (dataModel.getOffer().isFiatOffer()
|
} else if (dataModel.getOffer().isTraditionalOffer()
|
||||||
&& !isAmountEqualMinAmount(amount) && !isAmountEqualMaxAmount(amount)) {
|
&& !isAmountEqualMinAmount(amount) && !isAmountEqualMaxAmount(amount)) {
|
||||||
// We only apply the rounding if the amount is variable (minAmount is lower as 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
|
// Otherwise we could get an amount lower then the minAmount set by rounding
|
||||||
amount = CoinUtil.getRoundedFiatAmount(amount, price, maxTradeLimit);
|
amount = dataModel.getOffer().isFiatOffer() ?
|
||||||
|
CoinUtil.getRoundedFiatAmount(amount, price, maxTradeLimit) :
|
||||||
|
CoinUtil.getRoundedTraditionalAmount(amount, price, maxTradeLimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataModel.applyAmount(amount);
|
dataModel.applyAmount(amount);
|
||||||
|
@ -856,6 +856,7 @@ message PaymentAccountPayload {
|
|||||||
CelPayAccountPayload cel_pay_account_payload = 37;
|
CelPayAccountPayload cel_pay_account_payload = 37;
|
||||||
MoneseAccountPayload monese_account_payload = 38;
|
MoneseAccountPayload monese_account_payload = 38;
|
||||||
VerseAccountPayload verse_account_payload = 39;
|
VerseAccountPayload verse_account_payload = 39;
|
||||||
|
CashByAtmAccountPayload cash_by_atm_account_payload = 40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,6 +1113,10 @@ message PayByMailAccountPayload {
|
|||||||
string extra_info = 3;
|
string extra_info = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message CashByAtmAccountPayload {
|
||||||
|
string extra_info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message PromptPayAccountPayload {
|
message PromptPayAccountPayload {
|
||||||
string prompt_pay_id = 1;
|
string prompt_pay_id = 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user