diff --git a/ozon/common.go b/ozon/common.go index 515315b..6cb1bcd 100644 --- a/ozon/common.go +++ b/ozon/common.go @@ -634,3 +634,35 @@ const ( // Yuan GetRFBSReturnsCurrencyCNY GetRFBSReturnsCurrency = "CNY" ) + +type GiveoutStatus string + +const ( + // Undefined, contact support team + GiveoutStatusUnspecified GiveoutStatus = "GIVEOUT_STATUS_UNSPECIFIED" + + // Created + GiveoutStatusCreated GiveoutStatus = "GIVEOUT_STATUS_CREATED" + + // Approved + GiveoutStatusApproved GiveoutStatus = "GIVEOUT_STATUS_APPROVED" + + // Completed + GiveoutStatusCompleted GiveoutStatus = "GIVEOUT_STATUS_COMPLETED" + + // Cancelled + GiveoutStatusCancelled GiveoutStatus = "GIVEOUT_STATUS_CANCELLED" +) + +type GiveoutDeliverySchema string + +const ( + // Undefined, contact support team + GiveoutDeliverySchemaUnspecified GiveoutDeliverySchema = "GIVEOUT_DELIVERY_SCHEMA_UNSPECIFIED" + + // FBO + GiveoutDeliverySchemaFBO GiveoutDeliverySchema = "GIVEOUT_DELIVERY_SCHEMA_FBO" + + // FBS + GiveoutDeliverySchemaFBS GiveoutDeliverySchema = "GIVEOUT_DELIVERY_SCHEMA_FBS" +) diff --git a/ozon/returns.go b/ozon/returns.go index 7dc3345..33b6b3b 100644 --- a/ozon/returns.go +++ b/ozon/returns.go @@ -647,3 +647,227 @@ func (c Returns) RefundRFBS(ctx context.Context, params *RefundRFBSParams) (*Ref return resp, nil } + +type IsGiveoutEnabledResponse struct { + core.CommonResponse + + // `true` if you can pick up a return shipment by barcode. + Enabled bool `json:"enabled"` +} + +// Check the ability to receive return shipments by barcode +// +// The `enabled` parameter is true if you can pick up return shipments by barcode. +func (c Returns) IsGiveoutEnabled(ctx context.Context) (*IsGiveoutEnabledResponse, error) { + url := "/v1/return/giveout/is-enabled" + + resp := &IsGiveoutEnabledResponse{} + + response, err := c.client.Request(ctx, http.MethodPost, url, struct{}{}, resp, nil) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} + +type GetGiveoutResponse struct { + core.CommonResponse + + // PDF file with barcode in binary format + FileContent string `json:"file_content"` + + // File name + FileName string `json:"file_name"` + + // File type + ContentType string `json:"content_type"` +} + +// Barcode for return shipment in PDF format +// +// Returns a PDF file with a barcode +func (c Returns) GetGiveoutPDF(ctx context.Context) (*GetGiveoutResponse, error) { + url := "/v1/return/giveout/get-pdf" + + resp := &GetGiveoutResponse{} + + response, err := c.client.Request(ctx, http.MethodPost, url, struct{}{}, resp, nil) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} + +// Barcode for return shipment in PNG format +// +// Returns a PNG file with a barcode +func (c Returns) GetGiveoutPNG(ctx context.Context) (*GetGiveoutResponse, error) { + url := "/v1/return/giveout/get-png" + + resp := &GetGiveoutResponse{} + + response, err := c.client.Request(ctx, http.MethodPost, url, struct{}{}, resp, nil) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} + +type GetGiveoutBarcodeResponse struct { + core.CommonResponse + + // Barcode value in text format + Barcode string `json:"barcode"` +} + +// Value of barcode for return shipments +// +// Use this method to get the barcode from the response of the +// `/v1/return/giveout/get-png` and `/v1/return/giveout/get-pdf` methods in text format +func (c Returns) GetGiveoutBarcode(ctx context.Context) (*GetGiveoutBarcodeResponse, error) { + url := "/v1/return/giveout/barcode" + + resp := &GetGiveoutBarcodeResponse{} + + response, err := c.client.Request(ctx, http.MethodPost, url, struct{}{}, resp, nil) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} + +// Use this method if an unauthorized person has gained access to your barcode. +// +// The method returns a PNG file with the new barcode. Once the method is used, +// you won't be able to get a return shipment using the old barcodes. +// To get a new barcode in PDF format, use the /v1/return/giveout/get-pdf method +func (c Returns) ResetGiveoutBarcode(ctx context.Context) (*GetGiveoutBarcodeResponse, error) { + url := "/v1/return/giveout/barcode-reset" + + resp := &GetGiveoutBarcodeResponse{} + + response, err := c.client.Request(ctx, http.MethodPost, url, struct{}{}, resp, nil) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} + +type GetGiveoutListParams struct { + // Identifier of the last value on the page + LastId int64 `json:"last_id"` + + // Number of values in the response + Limit int64 `json:"limit"` +} + +type GetGiveoutListResponse struct { + core.CommonResponse + + // Shipment identifier + Giveouts []GetGiveoutListGiveout `json:"giveouts"` +} + +type GetGiveoutListGiveout struct { + // Number of products in shipment + ApprovedArticlesCount int32 `json:"approved_articles_count"` + + // Creation date and time + CreatedAt time.Time `json:"created_at"` + + // Shipment identifier + GiveoutId int64 `json:"giveout_id"` + + // Return shipment status + GiveoutStatus GiveoutStatus `json:"giveout_status"` + + // Total number of products to be picked up from the warehouse + TotalArticlesCount int32 `json:"total_articles_count"` + + // Warehouse address + WarehouseAddress string `json:"warehouse_address"` + + // Warehouse identifier + WarehouseId int64 `json:"warehouse_id"` + + // Warehouse name + WarehouseName string `json:"warehouse_name"` +} + +// Return shipments list +func (c Returns) GetGiveoutList(ctx context.Context, params *GetGiveoutListParams) (*GetGiveoutListResponse, error) { + url := "/v1/return/giveout/list" + + resp := &GetGiveoutListResponse{} + + response, err := c.client.Request(ctx, http.MethodPost, url, struct{}{}, resp, nil) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} + +type GetGiveoutInfoParams struct { + // Shipment identifier + GiveoutId int64 `json:"giveout_id"` +} + +type GetGiveoutInfoResponse struct { + core.CommonResponse + + // Product IDs + Articles []GetGiveoutInfoArticle `json:"articles"` + + // Shipment identifier + GiveoutId int64 `json:"giveout_id"` + + // Return shipment status + GiveoutStatus GiveoutStatus `json:"giveout_status"` + + // Warehouse address + WarehouseAddress string `json:"warehouse_address"` + + // Warehouse name + WarehouseName string `json:"warehouse_name"` +} + +type GetGiveoutInfoArticle struct { + // `true` if the shipment is confirmed + Approved bool `json:"approved"` + + // Delivery schema + DeliverySchema GiveoutDeliverySchema `json:"delivery_schema"` + + // Product name + Name string `json:"name"` + + // Seller identifier + SellerId int64 `json:"seller_id"` +} + +// Information on return shipment +func (c Returns) GetGiveoutInfo(ctx context.Context, params *GetGiveoutInfoParams) (*GetGiveoutInfoResponse, error) { + url := "/v1/return/giveout/info" + + resp := &GetGiveoutInfoResponse{} + + response, err := c.client.Request(ctx, http.MethodPost, url, struct{}{}, resp, nil) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} diff --git a/ozon/returns_test.go b/ozon/returns_test.go index 9b9c496..c3ad555 100644 --- a/ozon/returns_test.go +++ b/ozon/returns_test.go @@ -603,3 +603,339 @@ func TestRefundRFBS(t *testing.T) { } } } + +func TestIsGiveoutEnabled(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + `{ + "enabled": true + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + `{ + "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.Returns().IsGiveoutEnabled(ctx) + 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) + } + } +} + +func TestGetGiveoutPDF(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + `{ + "content_type": "application/pdf", + "file_name": "string", + "file_content": "string" + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + `{ + "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.Returns().GetGiveoutPDF(ctx) + 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) + } + } +} + +func TestGetGiveoutPNG(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + `{ + "content_type": "image/png", + "file_name": "string", + "file_content": "string" + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + `{ + "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.Returns().GetGiveoutPNG(ctx) + 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) + } + } +} + +func TestGetGiveoutBarcode(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + `{ + "barcode": "string" + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + `{ + "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.Returns().GetGiveoutBarcode(ctx) + 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) + } + } +} + +func TestResetGiveoutBarcode(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + `{ + "content_type": "image/png", + "file_name": "string", + "file_content": "string" + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + `{ + "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.Returns().ResetGiveoutBarcode(ctx) + 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) + } + } +} + +func TestGetGiveoutList(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + params *GetGiveoutListParams + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + &GetGiveoutListParams{ + LastId: 0, + Limit: 0, + }, + `{ + "giveouts": [ + { + "approved_articles_count": 0, + "created_at": "2019-08-24T14:15:22Z", + "giveout_id": 0, + "giveout_status": "string", + "total_articles_count": 0, + "warehouse_address": "string", + "warehouse_id": 0, + "warehouse_name": "string" + } + ] + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + &GetGiveoutListParams{}, + `{ + "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.Returns().GetGiveoutList(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) + } + } +} + +func TestGetGiveoutInfo(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + params *GetGiveoutInfoParams + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + &GetGiveoutInfoParams{ + GiveoutId: 11, + }, + `{ + "articles": [ + { + "approved": true, + "delivery_schema": "string", + "name": "string", + "seller_id": 0 + } + ], + "giveout_id": 11, + "giveout_status": "string", + "warehouse_address": "string", + "warehouse_name": "string" + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + &GetGiveoutInfoParams{}, + `{ + "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.Returns().GetGiveoutInfo(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.GiveoutId != test.params.GiveoutId { + t.Errorf("expected giveout id to be equal: got: %d, expected: %d", resp.GiveoutId, test.params.GiveoutId) + } + } +}