-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathboxes.go
151 lines (138 loc) · 4.39 KB
/
boxes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package postmaster
import (
"errors"
"fmt"
"strconv"
)
// Box (other name: Package; used Box here in order not to confuse with Shipment's Package)
// is a container that we try to fit Items into.
type Box struct {
p *Postmaster `json:"-"`
Id int `json:"-"`
Name string `json:"name"`
Width float32 `json:"width"`
Height float32 `json:"height"`
Length float32 `json:"length"`
Weight float32 `json:"weight"`
SizeUnits string `json:"size_units,omitempty"`
WeightUnits string `json:"weight_units,omitempty"`
// These are returned by server
ImageUrl string `json:"image_url,omitempty"`
}
// Item is an object we try to fit into Boxes.
type Item struct {
SKU string `json:"sku"`
Name string `json:"name,omitempty"`
Width float32 `json:"width"`
Height float32 `json:"height"`
Length float32 `json:"length"`
Weight float32 `json:"weight"`
Count int `json:"count"`
SizeUnits string `json:"size_units,omitempty"`
WeightUnits string `json:"weight_units,omitempty"`
// These are returned by server
ImageUrl string `json:"image_url,omitempty"`
}
// BoxList is API response for List() function.
type BoxList struct {
Results []Box `json:"results"`
Cursor string `json:"cursor"`
PreviousCursor string `json:"previous_cursor"`
}
// FitMessage is being sent to API in order to check whether given items fit given boxes.
type FitMessage struct {
Boxes []Box `json:"boxes"`
Items []Item `json:"items"`
PackageLimit int `json:"package_limit"`
}
// FitResponse is API response for trying to fit items into boxes.
type FitResponse struct {
Boxes []struct {
Box Box `json:"box"`
Items []Item `json:"items"`
}
Leftovers []Item `json:"leftovers"`
AllFit bool `json:"all_fit"`
}
// Box() creates new Box and assigns all important variables. Use this instead
// of new(postmaster.Box).
func (p *Postmaster) Box() (b *Box) {
b = new(Box)
b.p = p
b.Id = -1
return
}
// Create creates new Box. Existing *Box receiver's fields will be overwritten.
// You musn't invoke this function from an existing Box (i.e. Box with ID > -1).
func (b *Box) Create() (*Box, error) {
if b.Id != -1 {
return nil, errors.New("You can't create an existing box.")
}
res := map[string]int{}
_, err := post(b.p, "v1", "packages", b, &res)
if err == nil {
b.Id = res["id"]
}
return b, err
}
// Get fetches Box from API and stores it in *Box receiver.
// You musn't invoke this function from an "empty" box (i.e. Box with ID == -1).
func (b *Box) Get() (*Box, error) {
if b.Id == -1 {
return nil, errors.New("You must provide a box ID.")
}
endpoint := fmt.Sprintf("packages/%d", b.Id)
_, err := get(b.p, "v1", endpoint, nil, b)
return b, err
}
// Delete deletes Box, and replaces *Box receiver with an empty one.
// You musn't invoke this function from an "empty" box (i.e. Box with ID == -1).
func (b *Box) Delete() (*Box, error) {
if b.Id == -1 {
return nil, errors.New("You must provide a box ID.")
}
endpoint := fmt.Sprintf("packages/%d", b.Id)
res := map[string]string{}
_, err := del(b.p, "v1", endpoint, nil, &res)
b = b.p.Box()
return b, err
}
// Update updates Box.
// You musn't invoke this function from an "empty" box (i.e. Box with ID == -1).
func (b *Box) Update() (*Box, error) {
if b.Id == -1 {
return nil, errors.New("You must provide a box ID.")
}
endpoint := fmt.Sprintf("packages/%d", b.Id)
res := map[string]string{}
_, err := put(b.p, "v1", endpoint, b, &res)
return b, err
}
// ListBoxes returns a list of boxes, with limit and cursor (e.g. for pagination).
func (p *Postmaster) ListBoxes(limit int, cursor string) (*BoxList, error) {
params := make(map[string]string)
if limit > 0 {
params["limit"] = strconv.Itoa(limit)
}
if cursor != "" {
params["cursor"] = cursor
}
res := new(BoxList)
_, err := get(p, "v1", "packages", params, &res)
// Set Postmaster "base" object for each package, so we can use API with them
for k, _ := range res.Results {
res.Results[k].p = p
}
return res, err
}
// Fit checks if given items can be packed into given boxes.
func (p *Postmaster) Fit(boxes []Box, items []Item, limit int) (*FitResponse, error) {
params := FitMessage{
Boxes: boxes,
Items: items,
PackageLimit: limit,
}
res := new(FitResponse)
_, err := post(p, "v1", "packages/fit", params, &res)
return res, err
}