update/4-october-2023 - Barcodes (#42)
This commit is contained in:
111
ozon/barcodes.go
Normal file
111
ozon/barcodes.go
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
package ozon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
core "github.com/diphantxm/ozon-api-client"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Barcodes struct {
|
||||||
|
client *core.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenerateBarcodesParams struct {
|
||||||
|
// List of products for which you want to generate barcodes
|
||||||
|
ProductIds []int64 `json:"product_ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenerateBarcodesResponse struct {
|
||||||
|
core.CommonResponse
|
||||||
|
|
||||||
|
Errors []GenerateBarcodesError `json:"errors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenerateBarcodesError struct {
|
||||||
|
// Error code
|
||||||
|
Code string `json:"code"`
|
||||||
|
|
||||||
|
// Error details
|
||||||
|
Error string `json:"error"`
|
||||||
|
|
||||||
|
// Barcode that is failed to generate
|
||||||
|
Barcode string `json:"barcode"`
|
||||||
|
|
||||||
|
// Product identifier for which the barcode generation failed
|
||||||
|
ProductId int64 `json:"product_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a product doesn't have a barcode, you can create it using this method. If a barcode already exists,
|
||||||
|
// but it isn't specified in your account, you can bind it using the `/v1/barcode/add` method.
|
||||||
|
//
|
||||||
|
// You can't generate barcodes for more than 100 products per request.
|
||||||
|
// You can use the method no more than 20 times per minute.
|
||||||
|
func (b *Barcodes) Generate(ctx context.Context, params *GenerateBarcodesParams) (*GenerateBarcodesResponse, error) {
|
||||||
|
url := "/v1/barcode/generate"
|
||||||
|
|
||||||
|
resp := &GenerateBarcodesResponse{}
|
||||||
|
|
||||||
|
response, err := b.client.Request(ctx, http.MethodPost, url, params, resp, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
response.CopyCommonResponse(&resp.CommonResponse)
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type BindBarcodesParams struct {
|
||||||
|
// List of barcodes and products
|
||||||
|
Barcodes []BindBarcode `json:"barcodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BindBarcode struct {
|
||||||
|
// Barcode. Maximum 100 characters
|
||||||
|
Barcode string `json:"barcode"`
|
||||||
|
|
||||||
|
// Product identifier in the Ozon system, SKU
|
||||||
|
SKU int64 `json:"sku"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BindBarcodesResponse struct {
|
||||||
|
core.CommonResponse
|
||||||
|
|
||||||
|
// Errors while binding barcodes
|
||||||
|
Errors []BindBarcodesError `json:"errors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BindBarcodesError struct {
|
||||||
|
// Error code
|
||||||
|
Code string `json:"code"`
|
||||||
|
|
||||||
|
// Error details
|
||||||
|
Error string `json:"error"`
|
||||||
|
|
||||||
|
// Barcode that is failed to generate
|
||||||
|
Barcode string `json:"barcode"`
|
||||||
|
|
||||||
|
// SKU of the product for which the barcode binding failed
|
||||||
|
SKU int64 `json:"sku"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a product has a barcode that isn't specified in your account,
|
||||||
|
// bind it using this method. If a product doesn't have a barcode,
|
||||||
|
// you can create it using the `/v1/barcode/generate` method.
|
||||||
|
//
|
||||||
|
// You can't bind barcodes to more than 100 products per request.
|
||||||
|
// Each product can have up to 100 barcodes.
|
||||||
|
// You can use the method no more than 20 times per minute.
|
||||||
|
func (b *Barcodes) Bind(ctx context.Context, params *BindBarcodesParams) (*BindBarcodesResponse, error) {
|
||||||
|
url := "/v1/barcode/add"
|
||||||
|
|
||||||
|
resp := &BindBarcodesResponse{}
|
||||||
|
|
||||||
|
response, err := b.client.Request(ctx, http.MethodPost, url, params, resp, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
response.CopyCommonResponse(&resp.CommonResponse)
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
141
ozon/barcodes_test.go
Normal file
141
ozon/barcodes_test.go
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
package ozon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
core "github.com/diphantxm/ozon-api-client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateBarcodes(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
statusCode int
|
||||||
|
headers map[string]string
|
||||||
|
params *GenerateBarcodesParams
|
||||||
|
response string
|
||||||
|
}{
|
||||||
|
// Test Ok
|
||||||
|
{
|
||||||
|
http.StatusOK,
|
||||||
|
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
|
||||||
|
&GenerateBarcodesParams{
|
||||||
|
ProductIds: []int64{123456789},
|
||||||
|
},
|
||||||
|
`{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "code 200",
|
||||||
|
"error": "no error",
|
||||||
|
"barcode": "456",
|
||||||
|
"product_id": 123456789
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
// Test No Client-Id or Api-Key
|
||||||
|
{
|
||||||
|
http.StatusUnauthorized,
|
||||||
|
map[string]string{},
|
||||||
|
&GenerateBarcodesParams{},
|
||||||
|
`{
|
||||||
|
"code": 16,
|
||||||
|
"message": "Client-Id and Api-Key headers are required"
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
c := NewMockClient(core.NewMockHttpHandler(test.statusCode, test.response, test.headers))
|
||||||
|
|
||||||
|
ctx, _ := context.WithTimeout(context.Background(), testTimeout)
|
||||||
|
resp, err := c.Barcodes().Generate(ctx, test.params)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != test.statusCode {
|
||||||
|
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusOK {
|
||||||
|
if len(resp.Errors) != 0 {
|
||||||
|
if resp.Errors[0].ProductId != test.params.ProductIds[0] {
|
||||||
|
t.Errorf("Product ids are not equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBindBarcodes(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
statusCode int
|
||||||
|
headers map[string]string
|
||||||
|
params *BindBarcodesParams
|
||||||
|
response string
|
||||||
|
}{
|
||||||
|
// Test Ok
|
||||||
|
{
|
||||||
|
http.StatusOK,
|
||||||
|
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
|
||||||
|
&BindBarcodesParams{
|
||||||
|
Barcodes: []BindBarcode{
|
||||||
|
{
|
||||||
|
Barcode: "some barcode",
|
||||||
|
SKU: 123456789,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
`{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "code 200",
|
||||||
|
"error": "no error",
|
||||||
|
"barcode": "some barcode",
|
||||||
|
"sku": 123456789
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
// Test No Client-Id or Api-Key
|
||||||
|
{
|
||||||
|
http.StatusUnauthorized,
|
||||||
|
map[string]string{},
|
||||||
|
&BindBarcodesParams{},
|
||||||
|
`{
|
||||||
|
"code": 16,
|
||||||
|
"message": "Client-Id and Api-Key headers are required"
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
c := NewMockClient(core.NewMockHttpHandler(test.statusCode, test.response, test.headers))
|
||||||
|
|
||||||
|
ctx, _ := context.WithTimeout(context.Background(), testTimeout)
|
||||||
|
resp, err := c.Barcodes().Bind(ctx, test.params)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != test.statusCode {
|
||||||
|
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusOK {
|
||||||
|
if len(resp.Errors) != 0 {
|
||||||
|
if resp.Errors[0].Barcode != test.params.Barcodes[0].Barcode {
|
||||||
|
t.Errorf("Barcodes are not equal")
|
||||||
|
}
|
||||||
|
if resp.Errors[0].SKU != test.params.Barcodes[0].SKU {
|
||||||
|
t.Errorf("Barcodes are not equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ type Client struct {
|
|||||||
chats *Chats
|
chats *Chats
|
||||||
certificates *Certificates
|
certificates *Certificates
|
||||||
strategies *Strategies
|
strategies *Strategies
|
||||||
|
barcodes *Barcodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Client) Analytics() *Analytics {
|
func (c Client) Analytics() *Analytics {
|
||||||
@@ -105,6 +106,10 @@ func (c Client) Strategies() *Strategies {
|
|||||||
return c.strategies
|
return c.strategies
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Client) Barcodes() *Barcodes {
|
||||||
|
return c.barcodes
|
||||||
|
}
|
||||||
|
|
||||||
func NewClient(httpClient core.HttpClient, clientId, apiKey string) *Client {
|
func NewClient(httpClient core.HttpClient, clientId, apiKey string) *Client {
|
||||||
coreClient := core.NewClient(httpClient, DefaultAPIBaseUrl, map[string]string{
|
coreClient := core.NewClient(httpClient, DefaultAPIBaseUrl, map[string]string{
|
||||||
"Client-Id": clientId,
|
"Client-Id": clientId,
|
||||||
@@ -131,6 +136,7 @@ func NewClient(httpClient core.HttpClient, clientId, apiKey string) *Client {
|
|||||||
chats: &Chats{client: coreClient},
|
chats: &Chats{client: coreClient},
|
||||||
certificates: &Certificates{client: coreClient},
|
certificates: &Certificates{client: coreClient},
|
||||||
strategies: &Strategies{client: coreClient},
|
strategies: &Strategies{client: coreClient},
|
||||||
|
barcodes: &Barcodes{client: coreClient},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,5 +163,6 @@ func NewMockClient(handler http.HandlerFunc) *Client {
|
|||||||
chats: &Chats{client: coreClient},
|
chats: &Chats{client: coreClient},
|
||||||
certificates: &Certificates{client: coreClient},
|
certificates: &Certificates{client: coreClient},
|
||||||
strategies: &Strategies{client: coreClient},
|
strategies: &Strategies{client: coreClient},
|
||||||
|
barcodes: &Barcodes{client: coreClient},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user