1package linodego 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "time" 8 9 "github.com/linode/linodego/internal/parseabletime" 10) 11 12// Invoice structs reflect an invoice for billable activity on the account. 13type Invoice struct { 14 ID int `json:"id"` 15 Label string `json:"label"` 16 Total float32 `json:"total"` 17 Date *time.Time `json:"-"` 18} 19 20// InvoiceItem structs reflect an single billable activity associate with an Invoice 21type InvoiceItem struct { 22 Label string `json:"label"` 23 Type string `json:"type"` 24 UnitPrice int `json:"unitprice"` 25 Quantity int `json:"quantity"` 26 Amount float32 `json:"amount"` 27 From *time.Time `json:"-"` 28 To *time.Time `json:"-"` 29} 30 31// InvoicesPagedResponse represents a paginated Invoice API response 32type InvoicesPagedResponse struct { 33 *PageOptions 34 Data []Invoice `json:"data"` 35} 36 37// endpoint gets the endpoint URL for Invoice 38func (InvoicesPagedResponse) endpoint(c *Client) string { 39 endpoint, err := c.Invoices.Endpoint() 40 if err != nil { 41 panic(err) 42 } 43 44 return endpoint 45} 46 47// appendData appends Invoices when processing paginated Invoice responses 48func (resp *InvoicesPagedResponse) appendData(r *InvoicesPagedResponse) { 49 resp.Data = append(resp.Data, r.Data...) 50} 51 52// ListInvoices gets a paginated list of Invoices against the Account 53func (c *Client) ListInvoices(ctx context.Context, opts *ListOptions) ([]Invoice, error) { 54 response := InvoicesPagedResponse{} 55 err := c.listHelper(ctx, &response, opts) 56 if err != nil { 57 return nil, err 58 } 59 60 return response.Data, nil 61} 62 63// UnmarshalJSON implements the json.Unmarshaler interface 64func (i *Invoice) UnmarshalJSON(b []byte) error { 65 type Mask Invoice 66 67 p := struct { 68 *Mask 69 Date *parseabletime.ParseableTime `json:"date"` 70 }{ 71 Mask: (*Mask)(i), 72 } 73 74 if err := json.Unmarshal(b, &p); err != nil { 75 return err 76 } 77 78 i.Date = (*time.Time)(p.Date) 79 80 return nil 81} 82 83// UnmarshalJSON implements the json.Unmarshaler interface 84func (i *InvoiceItem) UnmarshalJSON(b []byte) error { 85 type Mask InvoiceItem 86 87 p := struct { 88 *Mask 89 From *parseabletime.ParseableTime `json:"from"` 90 To *parseabletime.ParseableTime `json:"to"` 91 }{ 92 Mask: (*Mask)(i), 93 } 94 95 if err := json.Unmarshal(b, &p); err != nil { 96 return err 97 } 98 99 i.From = (*time.Time)(p.From) 100 i.To = (*time.Time)(p.To) 101 102 return nil 103} 104 105// GetInvoice gets the a single Invoice matching the provided ID 106func (c *Client) GetInvoice(ctx context.Context, id int) (*Invoice, error) { 107 e, err := c.Invoices.Endpoint() 108 if err != nil { 109 return nil, err 110 } 111 112 e = fmt.Sprintf("%s/%d", e, id) 113 r, err := coupleAPIErrors(c.R(ctx).SetResult(&Invoice{}).Get(e)) 114 if err != nil { 115 return nil, err 116 } 117 118 return r.Result().(*Invoice), nil 119} 120 121// InvoiceItemsPagedResponse represents a paginated Invoice Item API response 122type InvoiceItemsPagedResponse struct { 123 *PageOptions 124 Data []InvoiceItem `json:"data"` 125} 126 127// endpointWithID gets the endpoint URL for InvoiceItems associated with a specific Invoice 128func (InvoiceItemsPagedResponse) endpointWithID(c *Client, id int) string { 129 endpoint, err := c.InvoiceItems.endpointWithParams(id) 130 if err != nil { 131 panic(err) 132 } 133 134 return endpoint 135} 136 137// appendData appends InvoiceItems when processing paginated Invoice Item responses 138func (resp *InvoiceItemsPagedResponse) appendData(r *InvoiceItemsPagedResponse) { 139 resp.Data = append(resp.Data, r.Data...) 140} 141 142// ListInvoiceItems gets the invoice items associated with a specific Invoice 143func (c *Client) ListInvoiceItems(ctx context.Context, id int, opts *ListOptions) ([]InvoiceItem, error) { 144 response := InvoiceItemsPagedResponse{} 145 err := c.listHelperWithID(ctx, &response, id, opts) 146 if err != nil { 147 return nil, err 148 } 149 150 return response.Data, nil 151} 152