forked from getconversio/go-shopify
-
Notifications
You must be signed in to change notification settings - Fork 256
/
product_listing.go
158 lines (133 loc) · 5.59 KB
/
product_listing.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
152
153
154
155
156
157
158
package goshopify
import (
"context"
"fmt"
"time"
)
const productListingBasePath = "product_listings"
// ProductListingService is an interface for interfacing with the product listing endpoints
// of the Shopify API.
// See: https://shopify.dev/docs/admin-api/rest/reference/sales-channels/productlisting
type ProductListingService interface {
List(context.Context, interface{}) ([]ProductListing, error)
ListAll(context.Context, interface{}) ([]ProductListing, error)
ListWithPagination(context.Context, interface{}) ([]ProductListing, *Pagination, error)
Count(context.Context, interface{}) (int, error)
Get(context.Context, uint64, interface{}) (*ProductListing, error)
GetProductIds(context.Context, interface{}) ([]uint64, error)
Publish(context.Context, uint64) (*ProductListing, error)
Delete(context.Context, uint64) error
}
// ProductListingServiceOp handles communication with the product related methods of
// the Shopify API.
type ProductListingServiceOp struct {
client *Client
}
// ProductListing represents a Shopify product published to your sales channel app
type ProductListing struct {
Id uint64 `json:"product_id,omitempty"`
Title string `json:"title,omitempty"`
BodyHTML string `json:"body_html,omitempty"`
Vendor string `json:"vendor,omitempty"`
ProductType string `json:"product_type,omitempty"`
Handle string `json:"handle,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
PublishedAt *time.Time `json:"published_at,omitempty"`
Tags string `json:"tags,omitempty"`
Options []ProductOption `json:"options,omitempty"`
Variants []Variant `json:"variants,omitempty"`
Images []Image `json:"images,omitempty"`
}
// Represents the result from the product_listings/X.json endpoint
type ProductListingResource struct {
ProductListing *ProductListing `json:"product_listing"`
}
// Represents the result from the product_listings.json endpoint
type ProductsListingsResource struct {
ProductListings []ProductListing `json:"product_listings"`
}
// Represents the result from the product_listings/product_ids.json endpoint
type ProductListingIdsResource struct {
ProductIds []uint64 `json:"product_ids"`
}
// Resource which create product_listing endpoint expects in request body
// e.g.
// PUT /admin/api/2020-07/product_listings/921728736.json
//
// {
// "product_listing": {
// "product_id": 921728736
// }
// }
type ProductListingPublishResource struct {
ProductListing struct {
ProductId uint64 `json:"product_id"`
} `json:"product_listing"`
}
// List products
func (s *ProductListingServiceOp) List(ctx context.Context, options interface{}) ([]ProductListing, error) {
products, _, err := s.ListWithPagination(ctx, options)
if err != nil {
return nil, err
}
return products, nil
}
// ListAll Lists all products, iterating over pages
func (s *ProductListingServiceOp) ListAll(ctx context.Context, options interface{}) ([]ProductListing, error) {
collector := []ProductListing{}
for {
entities, pagination, err := s.ListWithPagination(ctx, options)
if err != nil {
return collector, err
}
collector = append(collector, entities...)
if pagination.NextPageOptions == nil {
break
}
options = pagination.NextPageOptions
}
return collector, nil
}
// ListWithPagination lists products and return pagination to retrieve next/previous results.
func (s *ProductListingServiceOp) ListWithPagination(ctx context.Context, options interface{}) ([]ProductListing, *Pagination, error) {
path := fmt.Sprintf("%s.json", productListingBasePath)
resource := new(ProductsListingsResource)
pagination, err := s.client.ListWithPagination(ctx, path, resource, options)
if err != nil {
return nil, nil, err
}
return resource.ProductListings, pagination, nil
}
// Count products listings published to your sales channel app
func (s *ProductListingServiceOp) Count(ctx context.Context, options interface{}) (int, error) {
path := fmt.Sprintf("%s/count.json", productListingBasePath)
return s.client.Count(ctx, path, options)
}
// Get individual product_listing by product Id
func (s *ProductListingServiceOp) Get(ctx context.Context, productId uint64, options interface{}) (*ProductListing, error) {
path := fmt.Sprintf("%s/%d.json", productListingBasePath, productId)
resource := new(ProductListingResource)
err := s.client.Get(ctx, path, resource, options)
return resource.ProductListing, err
}
// GetProductIds lists all product Ids that are published to your sales channel
func (s *ProductListingServiceOp) GetProductIds(ctx context.Context, options interface{}) ([]uint64, error) {
path := fmt.Sprintf("%s/product_ids.json", productListingBasePath)
resource := new(ProductListingIdsResource)
err := s.client.Get(ctx, path, resource, options)
return resource.ProductIds, err
}
// Publish an existing product listing to your sales channel app
func (s *ProductListingServiceOp) Publish(ctx context.Context, productId uint64) (*ProductListing, error) {
path := fmt.Sprintf("%s/%v.json", productListingBasePath, productId)
wrappedData := new(ProductListingPublishResource)
wrappedData.ProductListing.ProductId = productId
resource := new(ProductListingResource)
err := s.client.Put(ctx, path, wrappedData, resource)
return resource.ProductListing, err
}
// Delete unpublishes an existing product from your sales channel app.
func (s *ProductListingServiceOp) Delete(ctx context.Context, productId uint64) error {
return s.client.Delete(ctx, fmt.Sprintf("%s/%d.json", productListingBasePath, productId))
}