diff --git a/core/src/main/java/haveno/core/notifications/alerts/TradeEvents.java b/core/src/main/java/haveno/core/notifications/alerts/TradeEvents.java index aa9d8eeb69..8de1faf729 100644 --- a/core/src/main/java/haveno/core/notifications/alerts/TradeEvents.java +++ b/core/src/main/java/haveno/core/notifications/alerts/TradeEvents.java @@ -84,8 +84,6 @@ public class TradeEvents { if (trade.getContract() != null && pubKeyRingProvider.get().equals(trade.getContract().getBuyerPubKeyRing())) msg = Res.get("account.notifications.trade.message.msg.completed", shortId); break; - case COMPLETED: - break; } if (msg != null) { MobileMessage message = new MobileMessage(Res.get("account.notifications.trade.message.title"), diff --git a/core/src/main/java/haveno/core/support/traderchat/TradeChatSession.java b/core/src/main/java/haveno/core/support/traderchat/TradeChatSession.java index 17fb238ded..b59e3834cb 100644 --- a/core/src/main/java/haveno/core/support/traderchat/TradeChatSession.java +++ b/core/src/main/java/haveno/core/support/traderchat/TradeChatSession.java @@ -62,7 +62,7 @@ public class TradeChatSession extends SupportSession { @Override public boolean chatIsOpen() { - return trade != null && trade.getState() != Trade.State.TRADE_COMPLETED; + return trade != null && !trade.isCompleted(); } @Override diff --git a/core/src/main/java/haveno/core/trade/Trade.java b/core/src/main/java/haveno/core/trade/Trade.java index 1632180a70..02235fdba0 100644 --- a/core/src/main/java/haveno/core/trade/Trade.java +++ b/core/src/main/java/haveno/core/trade/Trade.java @@ -163,10 +163,7 @@ public abstract class Trade implements Tradable, Model { SELLER_SENT_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED), SELLER_SEND_FAILED_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED), SELLER_STORED_IN_MAILBOX_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED), - SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED), - - // trade completed - TRADE_COMPLETED(Phase.COMPLETED); + SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED); @NotNull public Phase getPhase() { @@ -205,8 +202,7 @@ public abstract class Trade implements Tradable, Model { DEPOSITS_CONFIRMED, DEPOSITS_UNLOCKED, PAYMENT_SENT, - PAYMENT_RECEIVED, - COMPLETED; + PAYMENT_RECEIVED; public static Trade.Phase fromProto(protobuf.Trade.Phase phase) { return ProtoUtil.enumFromProto(Trade.Phase.class, phase.name()); @@ -456,6 +452,10 @@ public abstract class Trade implements Tradable, Model { private Long payoutHeight; private IdlePayoutSyncer idlePayoutSyncer; + @Getter + @Setter + private boolean isCompleted; + /////////////////////////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////////////////////////// @@ -622,7 +622,7 @@ public abstract class Trade implements Tradable, Model { // handle trade phase events tradePhaseSubscription = EasyBind.subscribe(phaseProperty, newValue -> { if (isDepositsPublished() && !isPayoutUnlocked()) updateWalletRefreshPeriod(); - if (isCompleted()) { + if (isPaymentReceived()) { UserThread.execute(() -> { if (tradePhaseSubscription != null) { tradePhaseSubscription.unsubscribe(); @@ -650,7 +650,7 @@ public abstract class Trade implements Tradable, Model { // complete disputed trade if (getDisputeState().isArbitrated() && !getDisputeState().isClosed()) processModel.getTradeManager().closeDisputedTrade(getId(), Trade.DisputeState.DISPUTE_CLOSED); - // complete arbitrator trade + // auto complete arbitrator trade if (isArbitrator() && !isCompleted()) processModel.getTradeManager().onTradeCompleted(this); // reset address entries @@ -1334,15 +1334,19 @@ public abstract class Trade implements Tradable, Model { } public void setPayoutTx(MoneroTxWallet payoutTx) { + + // set payout tx fields this.payoutTx = payoutTx; - payoutTxId = payoutTx.getHash(); - if ("".equals(payoutTxId)) payoutTxId = null; // tx id is empty until signed payoutTxKey = payoutTx.getKey(); payoutTxFee = payoutTx.getFee().longValueExact(); + payoutTxId = payoutTx.getHash(); + if ("".equals(payoutTxId)) payoutTxId = null; // tx id is empty until signed + + // set payout tx id in dispute(s) for (Dispute dispute : getDisputes()) dispute.setDisputePayoutTxId(payoutTxId); // set final payout amounts - if (hasPaymentReceivedMessage()) { // TODO: replace with isPaymentReceived() but only if correct when trade completes with dispute + if (isPaymentReceived()) { BigInteger splitTxFee = payoutTx.getFee().divide(BigInteger.valueOf(2)); getBuyer().setPayoutTxFee(splitTxFee); getSeller().setPayoutTxFee(splitTxFee); @@ -1622,10 +1626,6 @@ public abstract class Trade implements Tradable, Model { return getState().getPhase().ordinal() >= Phase.PAYMENT_RECEIVED.ordinal(); } - public boolean isCompleted() { - return getState().getPhase().ordinal() >= Phase.COMPLETED.ordinal(); - } - public boolean isPayoutPublished() { return getPayoutState().ordinal() >= PayoutState.PAYOUT_PUBLISHED.ordinal(); } @@ -2110,7 +2110,8 @@ public abstract class Trade implements Tradable, Model { .collect(Collectors.toList())) .setLockTime(lockTime) .setStartTime(startTime) - .setUid(uid); + .setUid(uid) + .setIsCompleted(isCompleted); Optional.ofNullable(payoutTxId).ifPresent(builder::setPayoutTxId); Optional.ofNullable(contract).ifPresent(e -> builder.setContract(contract.toProtoMessage())); @@ -2145,6 +2146,7 @@ public abstract class Trade implements Tradable, Model { trade.setLockTime(proto.getLockTime()); trade.setStartTime(proto.getStartTime()); trade.setCounterCurrencyExtraData(ProtoUtil.stringOrNullFromProto(proto.getCounterCurrencyExtraData())); + trade.setCompleted(proto.getIsCompleted()); trade.chatMessages.addAll(proto.getChatMessageList().stream() .map(ChatMessage::fromPayloadProto) @@ -2192,6 +2194,7 @@ public abstract class Trade implements Tradable, Model { ",\n startTime=" + startTime + ",\n refundResultState=" + refundResultState + ",\n refundResultStateProperty=" + refundResultStateProperty + + ",\n isCompleted=" + isCompleted + "\n}"; } } diff --git a/core/src/main/java/haveno/core/trade/TradeManager.java b/core/src/main/java/haveno/core/trade/TradeManager.java index b4f55dc0a7..f8acdcaacf 100644 --- a/core/src/main/java/haveno/core/trade/TradeManager.java +++ b/core/src/main/java/haveno/core/trade/TradeManager.java @@ -938,7 +938,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi public void onTradeCompleted(Trade trade) { if (trade.isCompleted()) throw new RuntimeException("Trade " + trade.getId() + " was already completed"); closedTradableManager.add(trade); - trade.setState(Trade.State.TRADE_COMPLETED); + trade.setCompleted(true); removeTrade(trade); // TODO The address entry should have been removed already. Check and if its the case remove that. diff --git a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java index 465c10e5e7..d21f543b67 100644 --- a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java +++ b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java @@ -402,23 +402,23 @@ class TakeOfferViewModel extends ActivatableWithDataModel im if (errorMessage != null) { String appendMsg = ""; if (trade != null) { - switch (trade.getState().getPhase()) { - case INIT: - appendMsg = Res.get("takeOffer.error.noFundsLost"); - break; - case DEPOSIT_REQUESTED: - appendMsg = Res.get("takeOffer.error.feePaid"); - break; - case DEPOSITS_PUBLISHED: - case PAYMENT_SENT: - case PAYMENT_RECEIVED: - appendMsg = Res.get("takeOffer.error.depositPublished"); - break; - case COMPLETED: - appendMsg = Res.get("takeOffer.error.payoutPublished"); - break; - default: - break; + if (trade.isPayoutPublished()) appendMsg = Res.get("takeOffer.error.payoutPublished"); + else { + switch (trade.getState().getPhase()) { + case INIT: + appendMsg = Res.get("takeOffer.error.noFundsLost"); + break; + case DEPOSIT_REQUESTED: + appendMsg = Res.get("takeOffer.error.feePaid"); + break; + case DEPOSITS_PUBLISHED: + case PAYMENT_SENT: + case PAYMENT_RECEIVED: + appendMsg = Res.get("takeOffer.error.depositPublished"); + break; + default: + break; + } } } this.errorMessage.set(errorMessage + appendMsg); diff --git a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java index 87208d6d26..050018c5ed 100644 --- a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java +++ b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java @@ -363,6 +363,12 @@ public class PendingTradesViewModel extends ActivatableWithDataModel