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  }