Skip to content

Commit

Permalink
Merge pull request #1013 from stripe/remi-wip-credit-note-line
Browse files Browse the repository at this point in the history
Add support for `CreditNoteLineItem`
  • Loading branch information
remi-stripe authored Jan 14, 2020
2 parents cc43935 + 56cbcb0 commit 119b386
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ cache:
env:
global:
# If changing this number, please also change it in `testing/testing.go`.
- STRIPE_MOCK_VERSION=0.78.0
- STRIPE_MOCK_VERSION=0.79.0

go:
- "1.9.x"
Expand Down
115 changes: 99 additions & 16 deletions creditnote.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,28 @@ const (
CreditNoteTypePrePayment CreditNoteType = "pre_payment"
)

// CreditNoteLineItemType is the list of allowed values for the credit note line item's type.
type CreditNoteLineItemType string

// List of values that CreditNoteType can take.
const (
CreditNoteLineItemTypeCustomLineItem CreditNoteLineItemType = "custom_line_item"
CreditNoteLineItemTypeInvoiceLineItem CreditNoteLineItemType = "invoice_line_item"
)

// CreditNoteParams is the set of parameters that can be used when creating or updating a credit note.
// For more details see https://stripe.com/docs/api/credit_notes/create, https://stripe.com/docs/api/credit_notes/update.
type CreditNoteParams struct {
Params `form:"*"`
Amount *int64 `form:"amount"`
CreditAmount *int64 `form:"credit_amount"`
Invoice *string `form:"invoice"`
Memo *string `form:"memo"`
OutOfBandAmount *int64 `form:"out_of_band_amount"`
Reason *string `form:"reason"`
Refund *string `form:"refund"`
RefundAmount *int64 `form:"refund_amount"`
Amount *int64 `form:"amount"`
CreditAmount *int64 `form:"credit_amount"`
Invoice *string `form:"invoice"`
Lines []*CreditNoteLineParams `form:"lines"`
Memo *string `form:"memo"`
OutOfBandAmount *int64 `form:"out_of_band_amount"`
Reason *string `form:"reason"`
Refund *string `form:"refund"`
RefundAmount *int64 `form:"refund_amount"`
}

// CreditNoteListParams is the set of parameters that can be used when listing credit notes.
Expand All @@ -53,25 +63,68 @@ type CreditNoteListParams struct {
Invoice *string `form:"invoice"`
}

// CreditNoteLineItemListParams is the set of parameters that can be used when listing credit note line items.
type CreditNoteLineItemListParams struct {
ListParams `form:"*"`

// ID is the credit note ID to list line items for.
ID *string `form:"-"` // Goes in the URL
}

// CreditNoteLineItemListPreviewParams is the set of parameters that can be used when previewing a credit note's line items
type CreditNoteLineItemListPreviewParams struct {
ListParams `form:"*"`
Amount *int64 `form:"amount"`
CreditAmount *int64 `form:"credit_amount"`
Invoice *string `form:"invoice"`
Lines []*CreditNoteLineParams `form:"lines"`
Memo *string `form:"memo"`
OutOfBandAmount *int64 `form:"out_of_band_amount"`
Reason *string `form:"reason"`
Refund *string `form:"refund"`
RefundAmount *int64 `form:"refund_amount"`
}

// CreditNoteLineParams is the set of parameters that can be used for a line item when creating
// or previewing a credit note.
type CreditNoteLineParams struct {
Amount *int64 `form:"amount"`
Description *string `form:"description"`
InvoiceLineItem *string `form:"invoice_line_item"`
Quantity *int64 `form:"quantity"`
TaxRates []*string `form:"tax_rates"`
UnitAmount *int64 `form:"unit_amount"`
UnitAmountDecimal *float64 `form:"unit_amount_decimal,high_precision"`
Type *string `form:"type"`
}

// CreditNotePreviewParams is the set of parameters that can be used when previewing a credit note.
// For more details see https://stripe.com/docs/api/credit_notes/preview.
type CreditNotePreviewParams struct {
Params `form:"*"`
Amount *int64 `form:"amount"`
CreditAmount *int64 `form:"credit_amount"`
Invoice *string `form:"invoice"`
Memo *string `form:"memo"`
OutOfBandAmount *int64 `form:"out_of_band_amount"`
Reason *string `form:"reason"`
Refund *string `form:"refund"`
RefundAmount *int64 `form:"refund_amount"`
Amount *int64 `form:"amount"`
CreditAmount *int64 `form:"credit_amount"`
Invoice *string `form:"invoice"`
Lines []*CreditNoteLineParams `form:"lines"`
Memo *string `form:"memo"`
OutOfBandAmount *int64 `form:"out_of_band_amount"`
Reason *string `form:"reason"`
Refund *string `form:"refund"`
RefundAmount *int64 `form:"refund_amount"`
}

// CreditNoteVoidParams is the set of parameters that can be used when voiding invoices.
type CreditNoteVoidParams struct {
Params `form:"*"`
}

// CreditNoteTaxAmount represent the tax amount applied to a credit note.
type CreditNoteTaxAmount struct {
Amount int64 `json:"amount"`
Inclusive bool `json:"inclusive"`
TaxRate *TaxRate `json:"tax_rate"`
}

// CreditNote is the resource representing a Stripe credit note.
// For more details see https://stripe.com/docs/api/credit_notes/object.
type CreditNote struct {
Expand All @@ -80,27 +133,57 @@ type CreditNote struct {
Currency Currency `json:"currency"`
Customer *Customer `json:"customer"`
CustomerBalanceTransaction *CustomerBalanceTransaction `json:"customer_balance_transaction"`
DiscountAmount int64 `json:"discount_amount"`
Invoice *Invoice `json:"invoice"`
ID string `json:"id"`
Lines *CreditNoteLineItemList `json:"lines"`
Livemode bool `json:"livemode"`
Memo string `json:"memo"`
Metadata map[string]string `json:"metadata"`
Number string `json:"number"`
Object string `json:"object"`
OutOfBandAmount int64 `json:"out_of_band_amount"`
PDF string `json:"pdf"`
Reason CreditNoteReason `json:"reason"`
Refund *Refund `json:"refund"`
Status CreditNoteStatus `json:"status"`
Subtotal int64 `json:"subtotal"`
TaxAmounts []*CreditNoteTaxAmount `json:"tax_amounts"`
Total int64 `json:"total"`
Type CreditNoteType `json:"type"`
VoidedAt int64 `json:"voided_at"`
}

// CreditNoteLineItem is the resource representing a Stripe credit note line item.
// For more details see https://stripe.com/docs/api/credit_notes/line_item
type CreditNoteLineItem struct {
Amount int64 `json:"amount"`
Description string `json:"description"`
DiscountAmount int64 `json:"discount_amount"`
ID string `json:"id"`
InvoiceLineItem string `json:"invoice_line_item"`
Livemode bool `json:"livemode"`
Object string `json:"object"`
Quantity int64 `json:"quantity"`
TaxAmounts []*CreditNoteTaxAmount `json:"tax_amounts"`
TaxRates []*TaxRate `json:"tax_rates"`
Type CreditNoteLineItemType `json:"type"`
UnitAmount int64 `json:"unit_amount"`
UnitAmountDecimal float64 `json:"unit_amount_decimal,string"`
}

// CreditNoteList is a list of credit notes as retrieved from a list endpoint.
type CreditNoteList struct {
ListMeta
Data []*CreditNote `json:"data"`
}

// CreditNoteLineItemList is a list of credit note line items as retrieved from a list endpoint.
type CreditNoteLineItemList struct {
ListMeta
Data []*CreditNoteLineItem `json:"data"`
}

// UnmarshalJSON handles deserialization of a CreditNote.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
Expand Down
51 changes: 51 additions & 0 deletions creditnote/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,47 @@ func (c Client) List(listParams *stripe.CreditNoteListParams) *Iter {
})}
}

// ListLines returns a list of credit note line items on a credit note.
func ListLines(params *stripe.CreditNoteLineItemListParams) *LineItemIter {
return getC().ListLines(params)
}

// ListLines returns a list of credit note line items on a credit note.
func (c Client) ListLines(listParams *stripe.CreditNoteLineItemListParams) *LineItemIter {
path := stripe.FormatURLPath("/v1/credit_notes/%s/lines", stripe.StringValue(listParams.ID))
return &LineItemIter{stripe.GetIter(listParams, func(p *stripe.Params, b *form.Values) ([]interface{}, stripe.ListMeta, error) {
list := &stripe.CreditNoteLineItemList{}
err := c.B.CallRaw(http.MethodGet, path, c.Key, b, p, list)

ret := make([]interface{}, len(list.Data))
for i, v := range list.Data {
ret[i] = v
}

return ret, list.ListMeta, err
})}
}

// ListPreviewLines returns a list of lines on a previewed credit note.
func ListPreviewLines(params *stripe.CreditNoteLineItemListPreviewParams) *LineItemIter {
return getC().ListPreviewLines(params)
}

// ListPreviewLines returns a list of lines on a previewed credit note.
func (c Client) ListPreviewLines(listParams *stripe.CreditNoteLineItemListPreviewParams) *LineItemIter {
return &LineItemIter{stripe.GetIter(listParams, func(p *stripe.Params, b *form.Values) ([]interface{}, stripe.ListMeta, error) {
list := &stripe.CreditNoteLineItemList{}
err := c.B.CallRaw(http.MethodGet, "/v1/credit_notes/preview/lines", c.Key, b, p, list)

ret := make([]interface{}, len(list.Data))
for i, v := range list.Data {
ret[i] = v
}

return ret, list.ListMeta, err
})}
}

// Preview previews a credit note.
func Preview(params *stripe.CreditNotePreviewParams) (*stripe.CreditNote, error) {
return getC().Preview(params)
Expand Down Expand Up @@ -107,6 +148,16 @@ func (i *Iter) CreditNote() *stripe.CreditNote {
return i.Current().(*stripe.CreditNote)
}

// LineItemIter is an iterator for credit note line items on a credit note.
type LineItemIter struct {
*stripe.Iter
}

// CreditNoteLineItem returns the credit note line item which the iterator is currently pointing to.
func (i *LineItemIter) CreditNoteLineItem() *stripe.CreditNoteLineItem {
return i.Current().(*stripe.CreditNoteLineItem)
}

func getC() Client {
return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key}
}
53 changes: 53 additions & 0 deletions creditnote/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,54 @@ func TestCreditNoteList(t *testing.T) {
assert.NotNil(t, i.CreditNote())
}

func TestCreditNoteListLines(t *testing.T) {
i := ListLines(&stripe.CreditNoteLineItemListParams{
ID: stripe.String("cn_123"),
})

// Verify that we can get at least one invoice
assert.True(t, i.Next())
assert.Nil(t, i.Err())
assert.NotNil(t, i.CreditNoteLineItem())
}

func TestCreditNoteListPreviewLines(t *testing.T) {
params := &stripe.CreditNoteLineItemListPreviewParams{
Invoice: stripe.String("in_123"),
Lines: []*stripe.CreditNoteLineParams{
{
Type: stripe.String(string(stripe.CreditNoteLineItemTypeInvoiceLineItem)),
Amount: stripe.Int64(100),
InvoiceLineItem: stripe.String("ili_123"),
TaxRates: stripe.StringSlice([]string{
"txr_123",
}),
},
},
}
i := ListPreviewLines(params)

// Verify that we can get at least one invoice
assert.True(t, i.Next())
assert.Nil(t, i.Err())
assert.NotNil(t, i.CreditNoteLineItem())
}

func TestCreditNoteNew(t *testing.T) {
params := &stripe.CreditNoteParams{
Amount: stripe.Int64(100),
Invoice: stripe.String("in_123"),
Reason: stripe.String(string(stripe.CreditNoteReasonDuplicate)),
Lines: []*stripe.CreditNoteLineParams{
{
Type: stripe.String(string(stripe.CreditNoteLineItemTypeInvoiceLineItem)),
Amount: stripe.Int64(100),
InvoiceLineItem: stripe.String("ili_123"),
TaxRates: stripe.StringSlice([]string{
"txr_123",
}),
},
},
}
cn, err := New(params)
assert.Nil(t, err)
Expand All @@ -54,6 +97,16 @@ func TestCreditNotePreview(t *testing.T) {
params := &stripe.CreditNotePreviewParams{
Amount: stripe.Int64(100),
Invoice: stripe.String("in_123"),
Lines: []*stripe.CreditNoteLineParams{
{
Type: stripe.String(string(stripe.CreditNoteLineItemTypeInvoiceLineItem)),
Amount: stripe.Int64(100),
InvoiceLineItem: stripe.String("ili_123"),
TaxRates: stripe.StringSlice([]string{
"txr_123",
}),
},
},
}
cn, err := Preview(params)
assert.Nil(t, err)
Expand Down
2 changes: 1 addition & 1 deletion testing/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const (
// added in a more recent version of stripe-mock, we can show people a
// better error message instead of the test suite crashing with a bunch of
// confusing 404 errors or the like.
MockMinimumVersion = "0.78.0"
MockMinimumVersion = "0.79.0"

// TestMerchantID is a token that can be used to represent a merchant ID in
// simple tests.
Expand Down

0 comments on commit 119b386

Please sign in to comment.