enable floating price offers for cardless cash

This commit is contained in:
woodser 2025-01-29 09:24:20 -05:00
parent 97569bad37
commit 88c3f04be0
4 changed files with 24 additions and 36 deletions

View File

@ -597,7 +597,6 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
}
public static boolean isFixedPriceOnly(String id) {
return id.equals(PaymentMethod.CASH_AT_ATM_ID) ||
id.equals(PaymentMethod.HAL_CASH_ID);
return id.equals(PaymentMethod.HAL_CASH_ID);
}
}

View File

@ -3014,9 +3014,11 @@ payment.tradingRestrictions=Please review the maker's terms and conditions.\n\
If you do not meet the requirements do not take this trade.
payment.cashAtAtm.info=Cardless Cash: Cardless withdraw at ATM using code\n\n\
To use this payment method:\n\n\
1. Create a Cardless Cash payment account, lising your accepted banks, regions, or other terms to be shown with the offer.\n\n\
1. Create a Cardless Cash payment account, listing your accepted banks, regions, or other terms to be shown with the offer.\n\n\
2. Create or take an offer with the payment account.\n\n\
3. When the offer is taken, chat with your peer to coordinate a time to complete the payment and share the payment details.\n\n\
If the trade amount is above the cash withdrawal limit, traders should split it into multiple transactions.\n\n\
ATM cash trades must be in multiples of 10. Using range offers is recommended so the XMR amount can adjust to match the exact price.\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.cashAtAtm.extraInfo.prompt=Please state on your offers: \n\n\
Your accepted banks / locations; \n\

View File

@ -183,7 +183,7 @@ class TakeOfferDataModel extends OfferDataModel {
checkArgument(!possiblePaymentAccounts.isEmpty(), "possiblePaymentAccounts.isEmpty()");
paymentAccount = getLastSelectedPaymentAccount();
this.amount.set(offer.getAmount().min(BigInteger.valueOf(getMaxTradeLimit())));
this.amount.set(BigInteger.valueOf(getMaxTradeLimit()));
updateSecurityDeposit();
@ -292,8 +292,7 @@ class TakeOfferDataModel extends OfferDataModel {
if (paymentAccount != null) {
this.paymentAccount = paymentAccount;
long myLimit = getMaxTradeLimit();
this.amount.set(offer.getMinAmount().max(amount.get().min(BigInteger.valueOf(myLimit))));
this.amount.set(BigInteger.valueOf(getMaxTradeLimit()));
preferences.setTakeOfferSelectedPaymentAccountId(paymentAccount.getId());
}
@ -338,7 +337,7 @@ class TakeOfferDataModel extends OfferDataModel {
.orElse(firstItem);
}
long getMaxTradeLimit() {
long getMyMaxTradeLimit() {
if (paymentAccount != null) {
return accountAgeWitnessService.getMyTradeLimit(paymentAccount, getCurrencyCode(),
offer.getMirroredDirection(), offer.hasBuyerAsTakerWithoutDeposit());
@ -347,6 +346,10 @@ class TakeOfferDataModel extends OfferDataModel {
}
}
long getMaxTradeLimit() {
return Math.min(offer.getAmount().longValueExact(), getMyMaxTradeLimit());
}
boolean canTakeOffer() {
return GUIUtil.canCreateOrTakeOfferOrShowPopup(user, navigation) &&
GUIUtil.isBootstrappedOrShowPopup(p2PService);
@ -383,8 +386,10 @@ class TakeOfferDataModel extends OfferDataModel {
}
}
void applyAmount(BigInteger amount) {
this.amount.set(amount.min(BigInteger.valueOf(getMaxTradeLimit())));
void maybeApplyAmount(BigInteger amount) {
if (amount.compareTo(offer.getMinAmount()) >= 0 && amount.compareTo(BigInteger.valueOf(getMaxTradeLimit())) <= 0) {
this.amount.set(amount);
}
calculateTotalToPay();
}

View File

@ -208,7 +208,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
errorMessage.set(offer.getErrorMessage());
xmrValidator.setMaxValue(offer.getAmount());
xmrValidator.setMaxTradeLimit(BigInteger.valueOf(dataModel.getMaxTradeLimit()).min(offer.getAmount()));
xmrValidator.setMaxTradeLimit(BigInteger.valueOf(dataModel.getMaxTradeLimit()));
xmrValidator.setMinValue(offer.getMinAmount());
}
@ -237,7 +237,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
public void onPaymentAccountSelected(PaymentAccount paymentAccount) {
dataModel.onPaymentAccountSelected(paymentAccount);
xmrValidator.setMaxTradeLimit(BigInteger.valueOf(dataModel.getMaxTradeLimit()).min(offer.getAmount()));
xmrValidator.setMaxTradeLimit(BigInteger.valueOf(dataModel.getMaxTradeLimit()));
updateButtonDisableState();
}
@ -299,20 +299,13 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
Price tradePrice = dataModel.tradePrice;
long maxTradeLimit = dataModel.getMaxTradeLimit();
if (PaymentMethod.isRoundedForAtmCash(dataModel.getPaymentMethod().getId())) {
BigInteger adjustedAmountForAtm = CoinUtil.getRoundedAtmCashAmount(dataModel.getAmount().get(),
tradePrice,
maxTradeLimit);
dataModel.applyAmount(adjustedAmountForAtm);
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
BigInteger adjustedAmountForAtm = CoinUtil.getRoundedAtmCashAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit);
dataModel.maybeApplyAmount(adjustedAmountForAtm);
} else if (dataModel.getOffer().isTraditionalOffer()) {
if (!isAmountEqualMinAmount(dataModel.getAmount().get()) && (!isAmountEqualMaxAmount(dataModel.getAmount().get()))) {
// 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
BigInteger roundedAmount = CoinUtil.getRoundedAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit, dataModel.getOffer().getCurrencyCode(), dataModel.getOffer().getPaymentMethodId());
dataModel.applyAmount(roundedAmount);
}
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
BigInteger roundedAmount = CoinUtil.getRoundedAmount(dataModel.getAmount().get(), tradePrice, maxTradeLimit, dataModel.getOffer().getCurrencyCode(), dataModel.getOffer().getPaymentMethodId());
dataModel.maybeApplyAmount(roundedAmount);
}
amount.set(HavenoUtils.formatXmr(dataModel.getAmount().get()));
if (!dataModel.isMinAmountLessOrEqualAmount())
amountValidationResult.set(new InputValidator.ValidationResult(false,
@ -580,25 +573,14 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
if (price != null) {
if (dataModel.isRoundedForAtmCash()) {
amount = CoinUtil.getRoundedAtmCashAmount(amount, price, maxTradeLimit);
} else if (dataModel.getOffer().isTraditionalOffer()
&& !isAmountEqualMinAmount(amount) && !isAmountEqualMaxAmount(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
} else if (dataModel.getOffer().isTraditionalOffer()) {
amount = CoinUtil.getRoundedAmount(amount, price, maxTradeLimit, dataModel.getOffer().getCurrencyCode(), dataModel.getOffer().getPaymentMethodId());
}
}
dataModel.applyAmount(amount);
dataModel.maybeApplyAmount(amount);
}
}
private boolean isAmountEqualMinAmount(BigInteger amount) {
return offer.getMinAmount().equals(amount);
}
private boolean isAmountEqualMaxAmount(BigInteger amount) {
return offer.getAmount().equals(amount);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////