github.com/s7techlab/cckit@v0.10.5/examples/cpaper_asservice/cpaper.go (about) 1 package cpaper_asservice 2 3 import ( 4 "fmt" 5 6 "github.com/golang/protobuf/ptypes/empty" 7 "github.com/pkg/errors" 8 9 "github.com/s7techlab/cckit/router" 10 ) 11 12 type CPaperService struct { 13 } 14 15 func NewService() *CPaperService { 16 return &CPaperService{} 17 } 18 19 func (cc *CPaperService) List(ctx router.Context, in *empty.Empty) (*CommercialPaperList, error) { 20 // List method retrieves all entries from the ledger using GetStateByPartialCompositeKey method and passing it the 21 // namespace of our contract type, in this example that's "CommercialPaper", then it unmarshals received bytes via 22 // proto.Ummarshal method and creates a []CommercialPaperList as defined in the 23 // "StateMappings" variable at the top of the file 24 if res, err := State(ctx).List(&CommercialPaper{}); err != nil { 25 return nil, err 26 } else { 27 return res.(*CommercialPaperList), nil 28 } 29 } 30 31 func (cc *CPaperService) Get(ctx router.Context, id *CommercialPaperId) (*CommercialPaper, error) { 32 if res, err := State(ctx).Get(id, &CommercialPaper{}); err != nil { 33 return nil, err 34 } else { 35 return res.(*CommercialPaper), nil 36 } 37 } 38 39 func (cc *CPaperService) GetByExternalId(ctx router.Context, id *ExternalId) (*CommercialPaper, error) { 40 if res, err := State(ctx).GetByKey( 41 &CommercialPaper{}, "ExternalId", []string{id.Id}, &CommercialPaper{}); err != nil { 42 return nil, err 43 } else { 44 return res.(*CommercialPaper), nil 45 } 46 } 47 48 func (cc *CPaperService) Issue(ctx router.Context, issue *IssueCommercialPaper) (*CommercialPaper, error) { 49 // Validate input message using the rules defined in schema 50 if err := issue.Validate(); err != nil { 51 return nil, errors.Wrap(err, "payload validation") 52 } 53 54 // Create state entry 55 cpaper := &CommercialPaper{ 56 Issuer: issue.Issuer, 57 PaperNumber: issue.PaperNumber, 58 Owner: issue.Issuer, 59 IssueDate: issue.IssueDate, 60 MaturityDate: issue.MaturityDate, 61 FaceValue: issue.FaceValue, 62 State: CommercialPaper_STATE_ISSUED, // Initial state 63 ExternalId: issue.ExternalId, 64 } 65 66 if err := Event(ctx).Set(issue); err != nil { 67 return nil, err 68 } 69 70 if err := State(ctx).Insert(cpaper); err != nil { 71 return nil, err 72 } 73 return cpaper, nil 74 } 75 76 func (cc *CPaperService) Buy(ctx router.Context, buy *BuyCommercialPaper) (*CommercialPaper, error) { 77 // Get the current commercial paper state 78 cpaper, err := cc.Get(ctx, &CommercialPaperId{Issuer: buy.Issuer, PaperNumber: buy.PaperNumber}) 79 if err != nil { 80 return nil, errors.Wrap(err, "get cpaper") 81 } 82 83 // Validate current owner 84 if cpaper.Owner != buy.CurrentOwner { 85 return nil, fmt.Errorf( 86 "paper %s %s is not owned by %s", 87 cpaper.Issuer, cpaper.PaperNumber, buy.CurrentOwner) 88 } 89 90 // First buyData moves state from ISSUED to TRADING 91 if cpaper.State == CommercialPaper_STATE_ISSUED { 92 cpaper.State = CommercialPaper_STATE_TRADING 93 } 94 95 // Check paper is not already REDEEMED 96 if cpaper.State == CommercialPaper_STATE_TRADING { 97 cpaper.Owner = buy.NewOwner 98 } else { 99 return nil, fmt.Errorf( 100 "paper %s %s is not trading.current state = %s", 101 cpaper.Issuer, cpaper.PaperNumber, cpaper.State) 102 } 103 104 if err = Event(ctx).Set(buy); err != nil { 105 return nil, err 106 } 107 108 if err = State(ctx).Put(cpaper); err != nil { 109 return nil, err 110 } 111 112 return cpaper, nil 113 } 114 115 func (cc *CPaperService) Redeem(ctx router.Context, redeem *RedeemCommercialPaper) (*CommercialPaper, error) { 116 // Get the current commercial paper state 117 cpaper, err := cc.Get(ctx, &CommercialPaperId{Issuer: redeem.Issuer, PaperNumber: redeem.PaperNumber}) 118 if err != nil { 119 return nil, errors.Wrap(err, "get cpaper") 120 } 121 if err != nil { 122 return nil, errors.Wrap(err, "paper not found") 123 } 124 125 // Check paper is not REDEEMED 126 if cpaper.State == CommercialPaper_STATE_REDEEMED { 127 return nil, fmt.Errorf("paper %s %s is already redeemed", cpaper.Issuer, cpaper.PaperNumber) 128 } 129 130 // Verify that the redeemer owns the commercial paper before redeeming it 131 if cpaper.Owner == redeem.RedeemingOwner { 132 cpaper.Owner = redeem.Issuer 133 cpaper.State = CommercialPaper_STATE_REDEEMED 134 } else { 135 return nil, fmt.Errorf("redeeming owner does not own paper %s %s", cpaper.Issuer, cpaper.PaperNumber) 136 } 137 138 if err = Event(ctx).Set(redeem); err != nil { 139 return nil, err 140 } 141 142 if err = State(ctx).Put(cpaper); err != nil { 143 return nil, err 144 } 145 146 return cpaper, nil 147 } 148 149 func (cc *CPaperService) Delete(ctx router.Context, id *CommercialPaperId) (*CommercialPaper, error) { 150 cpaper, err := cc.Get(ctx, id) 151 if err != nil { 152 return nil, errors.Wrap(err, "get cpaper") 153 } 154 155 if err = State(ctx).Delete(id); err != nil { 156 return nil, err 157 } 158 159 return cpaper, nil 160 }