mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-20 10:22:18 +01:00
Add adjustment fro multiple ofg 10 EUR for HalCash
With ATMs one can withdraw only multiples of 10 EUR. We adjust the input values the way that the EUR amount leads to multiple of 10. MinAmount and amount will be adjusted. Please note that a similar approach like implemented here for HalCash can be used for removing the decimal places from fiat amounts to improve privacy. We keep that for a follow up PR to not mix 2 different use cases.
This commit is contained in:
parent
e7b3629a71
commit
3bce2b828b
@ -40,6 +40,7 @@ import bisq.core.payment.AccountAgeWitnessService;
|
|||||||
import bisq.core.payment.BankAccount;
|
import bisq.core.payment.BankAccount;
|
||||||
import bisq.core.payment.CountryBasedPaymentAccount;
|
import bisq.core.payment.CountryBasedPaymentAccount;
|
||||||
import bisq.core.payment.F2FAccount;
|
import bisq.core.payment.F2FAccount;
|
||||||
|
import bisq.core.payment.HalCashAccount;
|
||||||
import bisq.core.payment.PaymentAccount;
|
import bisq.core.payment.PaymentAccount;
|
||||||
import bisq.core.payment.SameBankAccount;
|
import bisq.core.payment.SameBankAccount;
|
||||||
import bisq.core.payment.SepaAccount;
|
import bisq.core.payment.SepaAccount;
|
||||||
@ -307,7 +308,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
|||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
Offer createAndGetOffer() {
|
Offer createAndGetOffer() {
|
||||||
final boolean useMarketBasedPriceValue = isUseMarketBasedPriceValue();
|
boolean useMarketBasedPriceValue = isUseMarketBasedPriceValue();
|
||||||
long priceAsLong = price.get() != null && !useMarketBasedPriceValue ? price.get().getValue() : 0L;
|
long priceAsLong = price.get() != null && !useMarketBasedPriceValue ? price.get().getValue() : 0L;
|
||||||
String currencyCode = tradeCurrencyCode.get();
|
String currencyCode = tradeCurrencyCode.get();
|
||||||
boolean isCryptoCurrency = CurrencyUtil.isCryptoCurrency(currencyCode);
|
boolean isCryptoCurrency = CurrencyUtil.isCryptoCurrency(currencyCode);
|
||||||
@ -662,7 +663,13 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
|||||||
!amount.get().isZero() &&
|
!amount.get().isZero() &&
|
||||||
!price.get().isZero()) {
|
!price.get().isZero()) {
|
||||||
try {
|
try {
|
||||||
volume.set(price.get().getVolumeByAmount(amount.get()));
|
Volume volumeByAmount = price.get().getVolumeByAmount(amount.get());
|
||||||
|
|
||||||
|
// For HalCash we want multiple of 10 EUR
|
||||||
|
if (isHalCashAccount())
|
||||||
|
volumeByAmount = OfferUtil.getAdjustedVolumeForHalCash(volumeByAmount);
|
||||||
|
|
||||||
|
volume.set(volumeByAmount);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.error(t.toString());
|
log.error(t.toString());
|
||||||
}
|
}
|
||||||
@ -743,7 +750,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isUseMarketBasedPriceValue() {
|
protected boolean isUseMarketBasedPriceValue() {
|
||||||
return marketPriceAvailable && useMarketBasedPrice.get();
|
return marketPriceAvailable && useMarketBasedPrice.get() && !isHalCashAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -813,4 +820,8 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
|||||||
public boolean isBsqForFeeAvailable() {
|
public boolean isBsqForFeeAvailable() {
|
||||||
return OfferUtil.isBsqForFeeAvailable(bsqWalletService, amount.get(), marketPriceAvailable, marketPriceMargin);
|
return OfferUtil.isBsqForFeeAvailable(bsqWalletService, amount.get(), marketPriceAvailable, marketPriceMargin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isHalCashAccount() {
|
||||||
|
return paymentAccount instanceof HalCashAccount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
|
|||||||
onPaymentAccountsComboBoxSelected();
|
onPaymentAccountsComboBoxSelected();
|
||||||
|
|
||||||
balanceTextField.setTargetAmount(model.getDataModel().totalToPayAsCoinProperty().get());
|
balanceTextField.setTargetAmount(model.getDataModel().totalToPayAsCoinProperty().get());
|
||||||
updateMarketPriceAvailable();
|
updatePriceToggle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +297,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
|
|||||||
percentagePriceDescription.setText(Res.get("shared.aboveInPercent"));
|
percentagePriceDescription.setText(Res.get("shared.aboveInPercent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMarketPriceAvailable();
|
updatePriceToggle();
|
||||||
|
|
||||||
if (!model.getDataModel().isMakerFeeValid() && model.getDataModel().getMakerFee() != null)
|
if (!model.getDataModel().isMakerFeeValid() && model.getDataModel().getMakerFee() != null)
|
||||||
showInsufficientBsqFundsForBtcFeePaymentPopup();
|
showInsufficientBsqFundsForBtcFeePaymentPopup();
|
||||||
@ -502,6 +502,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
currencyComboBox.setOnAction(currencyComboBoxSelectionHandler);
|
currencyComboBox.setOnAction(currencyComboBoxSelectionHandler);
|
||||||
|
|
||||||
|
updatePriceToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onCurrencyComboBoxSelected() {
|
private void onCurrencyComboBoxSelected() {
|
||||||
@ -703,7 +705,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
marketPriceAvailableListener = (observable, oldValue, newValue) -> updateMarketPriceAvailable();
|
marketPriceAvailableListener = (observable, oldValue, newValue) -> updatePriceToggle();
|
||||||
|
|
||||||
getShowWalletFundedNotificationListener = (observable, oldValue, newValue) -> {
|
getShowWalletFundedNotificationListener = (observable, oldValue, newValue) -> {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
@ -756,15 +758,16 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
|
|||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateMarketPriceAvailable() {
|
protected void updatePriceToggle() {
|
||||||
int marketPriceAvailableValue = model.marketPriceAvailableProperty.get();
|
int marketPriceAvailableValue = model.marketPriceAvailableProperty.get();
|
||||||
if (marketPriceAvailableValue > -1) {
|
if (marketPriceAvailableValue > -1) {
|
||||||
boolean isMarketPriceAvailable = marketPriceAvailableValue == 1;
|
boolean showPriceToggle = marketPriceAvailableValue == 1 &&
|
||||||
percentagePriceBox.setVisible(isMarketPriceAvailable);
|
!model.getDataModel().isHalCashAccount();
|
||||||
percentagePriceBox.setManaged(isMarketPriceAvailable);
|
percentagePriceBox.setVisible(showPriceToggle);
|
||||||
priceTypeToggleButton.setVisible(isMarketPriceAvailable);
|
percentagePriceBox.setManaged(showPriceToggle);
|
||||||
priceTypeToggleButton.setManaged(isMarketPriceAvailable);
|
priceTypeToggleButton.setVisible(showPriceToggle);
|
||||||
boolean fixedPriceSelected = !model.getDataModel().getUseMarketBasedPrice().get() || !isMarketPriceAvailable;
|
priceTypeToggleButton.setManaged(showPriceToggle);
|
||||||
|
boolean fixedPriceSelected = !model.getDataModel().getUseMarketBasedPrice().get() || !showPriceToggle;
|
||||||
updatePriceToggleButtons(fixedPriceSelected);
|
updatePriceToggleButtons(fixedPriceSelected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import bisq.core.monetary.Price;
|
|||||||
import bisq.core.monetary.Volume;
|
import bisq.core.monetary.Volume;
|
||||||
import bisq.core.offer.Offer;
|
import bisq.core.offer.Offer;
|
||||||
import bisq.core.offer.OfferPayload;
|
import bisq.core.offer.OfferPayload;
|
||||||
|
import bisq.core.offer.OfferUtil;
|
||||||
import bisq.core.payment.PaymentAccount;
|
import bisq.core.payment.PaymentAccount;
|
||||||
import bisq.core.provider.price.MarketPrice;
|
import bisq.core.provider.price.MarketPrice;
|
||||||
import bisq.core.provider.price.PriceFeedService;
|
import bisq.core.provider.price.PriceFeedService;
|
||||||
@ -683,6 +684,9 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
if (minAmount.get() != null)
|
if (minAmount.get() != null)
|
||||||
minAmountValidationResult.set(isBtcInputValid(minAmount.get()));
|
minAmountValidationResult.set(isBtcInputValid(minAmount.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We want to trigger a recalculation of the volume
|
||||||
|
UserThread.execute(() -> onFocusOutVolumeTextField(true, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,6 +727,13 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
dataModel.calculateAmount();
|
dataModel.calculateAmount();
|
||||||
applyMakerFee();
|
applyMakerFee();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We want to trigger a recalculation of the volume and minAmount
|
||||||
|
UserThread.execute(() -> {
|
||||||
|
onFocusOutVolumeTextField(true, false);
|
||||||
|
// We also need to update minAmount
|
||||||
|
onFocusOutMinAmountTextField(true, false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,8 +754,16 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
if (result.isValid) {
|
if (result.isValid) {
|
||||||
setVolumeToModel();
|
setVolumeToModel();
|
||||||
ignoreVolumeStringListener = true;
|
ignoreVolumeStringListener = true;
|
||||||
if (dataModel.getVolume().get() != null)
|
|
||||||
volume.set(btcFormatter.formatVolume(dataModel.getVolume().get()));
|
Volume volume = dataModel.getVolume().get();
|
||||||
|
if (volume != null) {
|
||||||
|
// For HalCash we want multiple of 10 EUR
|
||||||
|
if (dataModel.isHalCashAccount())
|
||||||
|
volume = OfferUtil.getAdjustedVolumeForHalCash(volume);
|
||||||
|
|
||||||
|
this.volume.set(btcFormatter.formatVolume(volume));
|
||||||
|
}
|
||||||
|
|
||||||
ignoreVolumeStringListener = false;
|
ignoreVolumeStringListener = false;
|
||||||
|
|
||||||
dataModel.calculateAmount();
|
dataModel.calculateAmount();
|
||||||
@ -958,10 +977,16 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setMinAmountToModel() {
|
private void setMinAmountToModel() {
|
||||||
if (minAmount.get() != null && !minAmount.get().isEmpty())
|
if (minAmount.get() != null && !minAmount.get().isEmpty()) {
|
||||||
dataModel.setMinAmount(btcFormatter.parseToCoinWith4Decimals(minAmount.get()));
|
Coin minAmount = btcFormatter.parseToCoinWith4Decimals(this.minAmount.get());
|
||||||
else
|
|
||||||
|
if (dataModel.isHalCashAccount() && dataModel.getPrice().get() != null)
|
||||||
|
minAmount = OfferUtil.getAdjustedMinAmountForHalCash(minAmount, dataModel.getPrice().get());
|
||||||
|
|
||||||
|
dataModel.setMinAmount(minAmount);
|
||||||
|
} else {
|
||||||
dataModel.setMinAmount(null);
|
dataModel.setMinAmount(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPriceToModel() {
|
private void setPriceToModel() {
|
||||||
|
@ -35,6 +35,7 @@ import bisq.core.monetary.Price;
|
|||||||
import bisq.core.monetary.Volume;
|
import bisq.core.monetary.Volume;
|
||||||
import bisq.core.offer.Offer;
|
import bisq.core.offer.Offer;
|
||||||
import bisq.core.offer.OfferPayload;
|
import bisq.core.offer.OfferPayload;
|
||||||
|
import bisq.core.offer.OfferUtil;
|
||||||
import bisq.core.payment.AccountAgeWitnessService;
|
import bisq.core.payment.AccountAgeWitnessService;
|
||||||
import bisq.core.payment.PaymentAccount;
|
import bisq.core.payment.PaymentAccount;
|
||||||
import bisq.core.payment.PaymentAccountUtil;
|
import bisq.core.payment.PaymentAccountUtil;
|
||||||
@ -490,8 +491,11 @@ class TakeOfferDataModel extends OfferDataModel {
|
|||||||
if (tradePrice != null && offer != null &&
|
if (tradePrice != null && offer != null &&
|
||||||
amount.get() != null &&
|
amount.get() != null &&
|
||||||
!amount.get().isZero()) {
|
!amount.get().isZero()) {
|
||||||
volume.set(tradePrice.getVolumeByAmount(amount.get()));
|
Volume volumeByAmount = tradePrice.getVolumeByAmount(amount.get());
|
||||||
//volume.set(new ExchangeRate(tradePrice).coinToFiat(amountAsCoin.get()));
|
if (offer.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID))
|
||||||
|
volumeByAmount = OfferUtil.getAdjustedVolumeForHalCash(volumeByAmount);
|
||||||
|
|
||||||
|
volume.set(volumeByAmount);
|
||||||
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import bisq.core.btc.wallet.WalletsSetup;
|
|||||||
import bisq.core.locale.Res;
|
import bisq.core.locale.Res;
|
||||||
import bisq.core.offer.Offer;
|
import bisq.core.offer.Offer;
|
||||||
import bisq.core.offer.OfferPayload;
|
import bisq.core.offer.OfferPayload;
|
||||||
|
import bisq.core.offer.OfferUtil;
|
||||||
import bisq.core.payment.PaymentAccount;
|
import bisq.core.payment.PaymentAccount;
|
||||||
import bisq.core.payment.payload.PaymentMethod;
|
import bisq.core.payment.payload.PaymentMethod;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
@ -280,6 +281,11 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||||||
|
|
||||||
calculateVolume();
|
calculateVolume();
|
||||||
|
|
||||||
|
if (dataModel.getPaymentMethod().getId().equals(PaymentMethod.HAL_CASH_ID)) {
|
||||||
|
dataModel.applyAmount(OfferUtil.getAdjustedMinAmountForHalCash(dataModel.getAmount().get(), dataModel.tradePrice));
|
||||||
|
amount.set(btcFormatter.formatCoin(dataModel.getAmount().get()));
|
||||||
|
}
|
||||||
|
|
||||||
if (!dataModel.isMinAmountLessOrEqualAmount())
|
if (!dataModel.isMinAmountLessOrEqualAmount())
|
||||||
amountValidationResult.set(new InputValidator.ValidationResult(false,
|
amountValidationResult.set(new InputValidator.ValidationResult(false,
|
||||||
Res.get("takeOffer.validation.amountSmallerThanMinAmount")));
|
Res.get("takeOffer.validation.amountSmallerThanMinAmount")));
|
||||||
|
@ -97,7 +97,7 @@ public class EditOfferView extends MutableOfferView<EditOfferViewModel> {
|
|||||||
// Workaround to fix margin on top of amount group
|
// Workaround to fix margin on top of amount group
|
||||||
gridPane.setPadding(new Insets(-20, 25, -1, 25));
|
gridPane.setPadding(new Insets(-20, 25, -1, 25));
|
||||||
|
|
||||||
updateMarketPriceAvailable();
|
updatePriceToggle();
|
||||||
updateElementsWithDirection();
|
updateElementsWithDirection();
|
||||||
|
|
||||||
model.isNextButtonDisabled.setValue(false);
|
model.isNextButtonDisabled.setValue(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user