forked from OpenBazaar/openbazaar-go
-
Notifications
You must be signed in to change notification settings - Fork 8
/
dispute_case_record.go
147 lines (132 loc) · 5.6 KB
/
dispute_case_record.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package repo
import (
"math/big"
"time"
"github.com/phoreproject/pm-go/pb"
)
var (
ModeratorDisputeExpiry_firstInterval = time.Duration(15*24) * time.Hour
ModeratorDisputeExpiry_secondInterval = time.Duration(30*24) * time.Hour
ModeratorDisputeExpiry_thirdInterval = time.Duration(44*24) * time.Hour
ModeratorDisputeExpiry_lastInterval = time.Duration(45*24) * time.Hour
)
// DisputeCaseRecord is a one-to-one relationship with records in the
// SQL datastore
type DisputeCaseRecord struct {
CaseID string
Claim string
OrderState pb.OrderState
Timestamp time.Time
LastDisputeExpiryNotifiedAt time.Time
BuyerContract *pb.RicardianContract
BuyerOutpoints []*pb.Outpoint
BuyerPayoutAddress string
VendorContract *pb.RicardianContract
VendorOutpoints []*pb.Outpoint
VendorPayoutAddress string
IsBuyerInitiated bool
CoinType string
PaymentCoin *CurrencyCode
}
// BuildModeratorDisputeExpiryFirstNotification returns a Notification with ExpiresIn set for the First Interval
func (r *DisputeCaseRecord) BuildModeratorDisputeExpiryFirstNotification(createdAt time.Time) *Notification {
return r.buildModeratorDisputeExpiry(ModeratorDisputeExpiry_firstInterval, createdAt)
}
// BuildModeratorDisputeExpirySecondNotification returns a Notification with ExpiresIn set for the Second Interval
func (r *DisputeCaseRecord) BuildModeratorDisputeExpirySecondNotification(createdAt time.Time) *Notification {
return r.buildModeratorDisputeExpiry(ModeratorDisputeExpiry_secondInterval, createdAt)
}
// BuildModeratorDisputeExpiryThirdNotification returns a Notification with ExpiresIn set for the Third Interval
func (r *DisputeCaseRecord) BuildModeratorDisputeExpiryThirdNotification(createdAt time.Time) *Notification {
return r.buildModeratorDisputeExpiry(ModeratorDisputeExpiry_thirdInterval, createdAt)
}
// BuildModeratorDisputeExpiryLastNotification returns a Notification with ExpiresIn set for the Last Interval
func (r *DisputeCaseRecord) BuildModeratorDisputeExpiryLastNotification(createdAt time.Time) *Notification {
return r.buildModeratorDisputeExpiry(ModeratorDisputeExpiry_lastInterval, createdAt)
}
func (r *DisputeCaseRecord) buildModeratorDisputeExpiry(interval time.Duration, createdAt time.Time) *Notification {
timeRemaining := ModeratorDisputeExpiry_lastInterval - interval
notification := ModeratorDisputeExpiry{
ID: NewNotificationID(),
Type: NotifierTypeModeratorDisputeExpiry,
CaseID: r.CaseID,
ExpiresIn: uint(timeRemaining.Seconds()),
Thumbnail: Thumbnail{},
}
if r.IsBuyerInitiated {
if len(r.BuyerContract.VendorListings) > 0 && len(r.BuyerContract.VendorListings[0].Item.Images) > 0 {
notification.Thumbnail = Thumbnail{
Tiny: r.BuyerContract.VendorListings[0].Item.Images[0].Tiny,
Small: r.BuyerContract.VendorListings[0].Item.Images[0].Small,
}
}
} else {
if len(r.VendorContract.VendorListings) > 0 && len(r.VendorContract.VendorListings[0].Item.Images) > 0 {
notification.Thumbnail = Thumbnail{
Tiny: r.VendorContract.VendorListings[0].Item.Images[0].Tiny,
Small: r.VendorContract.VendorListings[0].Item.Images[0].Small,
}
}
}
return NewNotification(notification, createdAt, false)
}
// IsExpired returns a bool indicating whether the case is still open right now
func (r *DisputeCaseRecord) IsExpiredNow() bool {
return r.IsExpired(time.Now())
}
// IsExpired returns a bool indicating whether the case is still open
func (r *DisputeCaseRecord) IsExpired(when time.Time) bool {
expiresAt := r.Timestamp.Add(ModeratorDisputeExpiry_lastInterval)
return when.Equal(expiresAt) || when.After(expiresAt)
}
// Contract returns the contract from the dispute if one has been supplied by
// either the buyer or vendor
func (r *DisputeCaseRecord) Contract() *pb.RicardianContract {
contract := r.BuyerContract
if contract == nil {
contract = r.VendorContract
}
return contract
}
// ResolutionPaymentFeePerByte returns the preferred outpoints to be used when resolving
// a pending DisputeCaseResolution based on the provided PayoutRatio
func (r *DisputeCaseRecord) ResolutionPaymentFeePerByte(ratio PayoutRatio, defaultFee big.Int) *big.Int {
n := new(big.Int)
switch {
case ratio.BuyerMajority(), ratio.EvenMajority():
v5order, _ := ToV5Order(r.BuyerContract.BuyerOrder, nil)
n, _ = n.SetString(v5order.BigRefundFee, 10)
return n
case ratio.VendorMajority():
if len(r.VendorContract.VendorOrderFulfillment) > 0 && r.VendorContract.VendorOrderFulfillment[0].Payout != nil {
fulfillment := ToV5OrderFulfillment(r.VendorContract.VendorOrderFulfillment[0])
n, _ = n.SetString(fulfillment.Payout.BigPayoutFeePerByte, 10)
return n
}
}
return n
}
// ResolutionPaymentOutpoints returns the preferred outpoints to be used when resolving
// a pending DisputeCaseResolution based on the provided PayoutRatio
func (r *DisputeCaseRecord) ResolutionPaymentOutpoints(ratio PayoutRatio) (outpoints []*pb.Outpoint) {
if ratio.VendorMajority() {
outpoints = r.VendorOutpoints
if outpoints == nil {
outpoints = r.BuyerOutpoints
}
} else {
outpoints = r.BuyerOutpoints
if outpoints == nil {
outpoints = r.VendorOutpoints
}
}
return outpoints
}
// ResolutionPaymentContract returns the preferred contract to be used when resolving
// a pending DisputeCaseRecord based on the provided PayoutRatio
func (r *DisputeCaseRecord) ResolutionPaymentContract(ratio PayoutRatio) (contract *pb.RicardianContract) {
if ratio.VendorMajority() {
return r.VendorContract
}
return r.BuyerContract
}