Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for CreditNoteLineItem #1013

Merged
merged 1 commit into from
Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
cjavilla-stripe marked this conversation as resolved.
Show resolved Hide resolved
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
cjavilla-stripe marked this conversation as resolved.
Show resolved Hide resolved
}

// CreditNoteLineItemListPreviewParams is the set of parameters that can be used when previewing a credit note's line items
type CreditNoteLineItemListPreviewParams struct {
ListParams `form:"*"`
cjavilla-stripe marked this conversation as resolved.
Show resolved Hide resolved
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"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not familiar with this string thing at the end so pointing it out. guessing that's how we specify the type of the json field and that'll be converted to float64.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's mostly cargo culted from other resources

}

// 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