receipts.gno
2.43 Kb · 81 lines
1package bolo
2
3import "gno.land/p/nt/seqid/v0"
4
5// ReceiptView is one gift, as the receipt page and the campaign page show it (API
6// §2.4): a copy, holding nothing of the realm's state.
7type ReceiptView struct {
8 ID, CampaignID string
9 Seq int64
10 Donor address // empty when Anonymous
11 Anonymous bool
12 Amount, Tip int64
13 Message string // empty when MessageHidden
14 MessageHidden bool // hidden by moderation; the receipt and amount stay
15 At int64
16 RaisedAfter int64 // the campaign's gross total right after this gift
17 DonorRefunded int64 // what this donor was refunded on this campaign after this gift (INV-12)
18}
19
20// GetReceipt returns gift seq of campaign id (API §4): an unknown campaign or
21// sequence number is ErrNotFound.
22func GetReceipt(id string, seq int64) ReceiptView {
23 c := campaignOf(id)
24 return receiptView(c, receiptOf(c, seq))
25}
26
27// receiptOf returns gift seq of c, or panics with ErrNotFound.
28func receiptOf(c *campaign, seq int64) *receipt {
29 if seq <= 0 {
30 panic(ErrNotFound)
31 }
32 v := c.receipts.Get(seqid.ID(seq).Binary())
33 if v == nil {
34 panic(ErrNotFound)
35 }
36 return v.(*receipt)
37}
38
39// ListRecent returns the campaign's last gifts, newest first, at most recentSize
40// (API §4): read through the ring of sequence numbers in its hot state.
41func ListRecent(id string) []ReceiptView {
42 c := campaignOf(id)
43 s := c.state
44 n := s.donationCount
45 if n > recentSize {
46 n = recentSize
47 }
48 views := make([]ReceiptView, 0, n)
49 for i := 1; i <= n; i++ {
50 seq := s.recent[(s.recentNext-i+recentSize)%recentSize]
51 views = append(views, receiptView(c, c.receipts.Get(seqid.ID(seq).Binary()).(*receipt)))
52 }
53 return views
54}
55
56// receiptView builds r's view (API §2.4): the donor blanked when the gift was
57// anonymous, the message when moderation hid it, and what this donor was refunded
58// since, so a receipt can't vouch for money taken back (INV-12).
59func receiptView(c *campaign, r *receipt) ReceiptView {
60 v := ReceiptView{
61 ID: receiptID(c.id, seqid.ID(r.seq)),
62 CampaignID: idString(c.id),
63 Seq: int64(r.seq),
64 Anonymous: r.anonymous,
65 Amount: r.amount,
66 Tip: r.tip,
67 MessageHidden: r.messageHidden,
68 At: r.at,
69 RaisedAfter: r.raisedAfter,
70 }
71 if !r.anonymous {
72 v.Donor = r.donor
73 }
74 if !r.messageHidden {
75 v.Message = r.message
76 }
77 if k := contributionOf(c, r.donor); k != nil {
78 v.DonorRefunded = k.refunded - r.refundedBefore
79 }
80 return v
81}