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
|
package lulu
import (
"encoding/json"
"fmt"
)
//go:generate go run github.com/yawnak/string-enumer -t ShippingLevel -t Title --text -o ./ship_gen.go .
// ShippingLevel is the quality/speed with which a package is shipped.
type ShippingLevel string
const (
Mail ShippingLevel = "MAIL" // Slowest ship method. Depending on the destination, tracking might not be available.
PriorityMail ShippingLevel = "PRIORITY_MAIL" // Priority mail shipping
Ground ShippingLevel = "GROUND" // Courier based shipping using ground transportation in the US.
Expedited ShippingLevel = "EXPEDITED" // Expedited (2nd day) delivery via air mail or equivalent.
Express ShippingLevel = "EXPRESS" // Overnight delivery. Fastest shipping available.
)
type ShippingAddress struct {
Country string // ISO 3166-2 country code
State string // 2 or 3 letter state codes (officially called ISO-3166-2 subdivision codes). They are required for some countries (e.g. US, MX, CA, AU)
City string
Street1 string // First address line
Street2 string // Second address line
PostCode string // Required for most countries
IsBusiness bool // Only relevant for US addresses. Some US carriers don't deliver to business-addresses on Saturday.
Name string // Full name of the person, including first and last name.
Title Title
Organization string // Name of an organization. Required if no person name is given.
Email string // Shipping carriers require an email address for notifications or handling delivery issues. If no email is given, the default email in the user profile will be used.
Phone string // Shipping carriers require a phone number for handling delivery issues. If no phone number is given, the default in the API user profile will be used.
TaxId string // The recipient’s tax identification number. Required for shipping addresses to Brazil, Chile, and Mexico.
}
// They use "country" in some places, "country_code" in others, etc.
// This is the union of all of them.
type shippingAddress struct {
Country string `json:"country"`
CountryCode string `json:"country_code"`
State string `json:"state"`
StateCode string `json:"state_code"`
City string `json:"city"`
Street1 string `json:"street1"`
Street2 string `json:"street2"`
PostCode string `json:"postcode"`
IsBusiness bool `json:"is_business"`
Name string `json:"name"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Title Title `json:"title"`
Organization string `json:"organization"`
Email string `json:"email"`
Phone string `json:"phone_number"`
TaxId string `json:"recipient_tax_id"`
}
func (a *ShippingAddress) UnmarshalJSON(data []byte) error {
s := string(data)
var alias shippingAddress
if err := json.Unmarshal(data, &alias); err != nil {
return err
}
if country, both := either(alias.Country, alias.CountryCode); !both {
a.Country = country
} else {
return fmt.Errorf(`address contains both "country" and "country_code": %q`, s)
}
if state, both := either(alias.State, alias.StateCode); !both {
a.State = state
} else {
return fmt.Errorf(`address contains both "state" and "state_code": %q`, s)
}
a.City = alias.City
a.Street1 = alias.Street1
a.Street2 = alias.Street2
a.PostCode = alias.PostCode
a.IsBusiness = alias.IsBusiness
hasName := alias.Name != ""
hasFirst := alias.FirstName != ""
hasLast := alias.LastName != ""
if hasName && (hasFirst || hasLast) {
return fmt.Errorf(`address contains both "name" and {"first_name", "last_name"}: %q`, s)
} else if hasName {
a.Name = alias.Name
} else if hasFirst && hasLast {
a.Name = fmt.Sprintf("%s %s", alias.FirstName, alias.LastName)
} else if hasLast {
a.Name = alias.LastName
} else if hasFirst {
a.Name = alias.FirstName
}
a.Title = alias.Title
a.Organization = alias.Organization
a.Email = alias.Email
a.Phone = alias.Phone
a.TaxId = alias.TaxId
return nil
}
func either(a, b string) (string, bool) {
if a != "" && b != "" {
return a, true
} else if a != "" {
return a, false
}
return b, false
}
type Title string
const (
Mr Title = "MR"
Miss Title = "MISS"
Mrs Title = "MRS"
Ms Title = "MS"
Dr Title = "DR"
)
|