Update October 31, 2024 (#114)

This commit is contained in:
Kirill
2024-12-12 00:53:56 +03:00
committed by GitHub
parent 23ca98fedd
commit f4a09903c7
4 changed files with 888 additions and 573 deletions

View File

@@ -290,108 +290,38 @@ func (c FBO) GetShipmentDetails(ctx context.Context, params *GetShipmentDetailsP
}
type ListSupplyRequestsParams struct {
// Number of the page returned in the request
Page int32 `json:"page"`
// Filter
Filter *ListSupplyRequestsFilter `json:"filter"`
// Number of elements on the page
PageSize int32 `json:"page_size"`
// Customizing the display of the requests list
Paging *ListSupplyRequestsPaging `json:"paging"`
}
// Filter on status of a supply by request
States []SupplyRequestState `json:"states"`
type ListSupplyRequestsFilter struct {
States []string `json:"states"`
}
type ListSupplyRequestsPaging struct {
// Supply number from which the list of requests will start
FromOrderId int64 `json:"from_supply_order_id"`
// Number of requests in the response
Limit int32 `json:"limit"`
}
type ListSupplyRequestsResponse struct {
core.CommonResponse
// Indicates that the response contains not the entire array of supply requests:
// - true — make a new request with a different page and page_size values to get information on the remaining requests;
// - false — the entire array of requests for the filter specified in the request was returned in the response
HasNext bool `json:"has_next"`
// Supply requests list
SupplyOrders []SupplyRequestCommonResponse `json:"supply_orders"`
// Total requests number
TotalSupplyOrdersCount int32 `json:"total_supply_orders_count"`
}
type SupplyRequestCommonResponse struct {
// Supply request creation date
CreatedAt string `json:"created_at"`
// Local time supply interval
LocalTimeslot SupplyRequestCommonResponseLocalTimeslot `json:"local_timeslot"`
// Date from which you want to bring the supply to the warehouse. Only for supplies via vDC
PreferredSupplyDateFrom string `json:"preferred_supply_date_from"`
// Date by which you want to bring the supply to the warehouse. Only for supplies via vDC
PreferredSupplyDateTo string `json:"preferred_supply_date_to"`
// Your own warehouse from which you'll take the products to the supply warehouse.
// Only for supplies via vDC
SellerWarehouse SupplyRequestSellerWarehouse `json:"seller_warehouse"`
// Status of a supply by request
State string `json:"state"`
// Supply request identifier you last requested
LastSupplyOrderId int64 `json:"last_supply_order_id"`
// Supply request identifier
SupplyOrderId int64 `json:"supply_order_id"`
// Supply request number
SupplyOrderNumber string `json:"supply_order_number"`
// Supply warehouse
SupplyWarehouse SupplyRequestCommonResponseSupplyWarehouse `json:"supply_warehouse"`
// time_left_to_prepare_supply
TimeLeftToPrepareSupply int64 `json:"time_left_to_prepare_supply"`
// Time in seconds left to select the supply option. Only for supplies via vDC
TimeLeftToSelectSupplyVariant int64 `json:"time_left_to_select_supply_variant"`
// total_items_count
TotalItemsCount int32 `json:"total_items_count"`
// Total number of items in the request
TotalQuantity int32 `json:"total_quantity"`
SupplyOrderId []string `json:"supply_order_id"`
}
type SupplyRequestSellerWarehouse struct {
// Warehouse address
Address string `json:"address"`
// Warehouse name
Name string `json:"name"`
// Warehouse identifier
WarehouseId int64 `json:"warehouse_id"`
}
type SupplyRequestCommonResponseLocalTimeslot struct {
// Interval start
From string `json:"from"`
// Interval end
To string `json:"to"`
}
type SupplyRequestCommonResponseSupplyWarehouse struct {
// Warehouse address
Address string `json:"address"`
// Warehouse name
Name string `json:"name"`
// Warehouse identifier
WarehouseId int64 `json:"warehouse_id"`
}
// Method for getting a list of supply requests to the Ozon warehouse.
// Requests with supply both to a specific warehouse and via a virtual
// distribution center (vDC) are taken into account
// Requests with supply to a specific warehouse and through a virtual distribution center (vDC) are taken into account
func (c FBO) ListSupplyRequests(ctx context.Context, params *ListSupplyRequestsParams) (*ListSupplyRequestsResponse, error) {
url := "/v1/supply-order/list"
url := "/v2/supply-order/list"
resp := &ListSupplyRequestsResponse{}
@@ -405,17 +335,111 @@ func (c FBO) ListSupplyRequests(ctx context.Context, params *ListSupplyRequestsP
}
type GetSupplyRequestInfoParams struct {
// Supply request identifier
SupplyOrderId int64 `json:"supply_order_id"`
// Supply request identifier in the Ozon system
OrderIds []string `json:"order_ids"`
}
type GetSupplyRequestInfoResponse struct {
core.CommonResponse
SupplyRequestCommonResponse
// Supply request details
Orders []SupplyOrder `json:"orders"`
// Driver and car information
VehicleInfo GetSupplyRequestInfoVehicle `json:"vehicle_info"`
// Warehouse details
Warehouses []SupplyWarehouse `json:"warehouses"`
}
type SupplyOrder struct {
// Date of supply request creation
CreationDate string `json:"creation_date"`
// Request source
CreationFlow string `json:"creation_flow"`
// Time remaining in seconds to fill in the supply details. Only for requests from the vDC
DataFillingDeadline time.Time `json:"data_filling_deadline_utc"`
// Supply warehouse identifier
DropoffWarehouseId int64 `json:"dropoff_warehouse_id"`
// Filter by supply status
State string `json:"state"`
// Supply request contents
Supplies []Supply `json:"supplies"`
// Supply request identifier
Id int64 `json:"supply_order_id"`
// Request number
OrderNumber string `json:"supply_order_number"`
// Supply time slot
Timeslot []SupplyTimeslot `json:"timeslot"`
// Driver and vehicle details
Vehicle []SupplyVehicle `json:"vehicle"`
}
type Supply struct {
// Supply contents identifier. Used in the /v1/supply-order/bundle method
BundleId string `json:"bundle_id"`
// Storage warehouse identifier
StorageWarehouseId int64 `json:"storage_warehouse_id"`
// Supply identifier
Id int64 `json:"supply_id"`
}
type SupplyTimeslot struct {
// Reason why you can't select the supply time slot
Reasons []string `json:"can_not_set_reasons"`
// true, if you can select or edit the supply time slot
CanSet bool `json:"can_set"`
// true, if the characteristic is required
IsRequired bool `json:"is_required"`
Value SupplyTimeslotValue `json:"value"`
}
type SupplyVehicle struct {
// Reason why you can't select the supply time slot
Reasons []string `json:"can_not_set_reasons"`
// true, if you can select or edit the supply time slot
CanSet bool `json:"can_set"`
// true, if the characteristic is required
IsRequired bool `json:"is_required"`
Value []GetSupplyRequestInfoVehicle `json:"value"`
}
type SupplyTimeslotValue struct {
// Supply time slot in local time
Timeslot []SupplyTimeslotValueTimeslot `json:"timeslot"`
// Time zone
Timezone []SupplyTimeslotValueTimezone `json:"timezone_info"`
}
type SupplyTimeslotValueTimeslot struct {
// Supply time slot start
From time.Time `json:"from"`
// Supply time slot end
To time.Time `json:"to"`
}
type SupplyTimeslotValueTimezone struct {
// Time zone name
Name string `json:"iana_name"`
// Time zone offset from UTC-0 in seconds
Offset string `json:"offset"`
}
type GetSupplyRequestInfoVehicle struct {
@@ -432,11 +456,22 @@ type GetSupplyRequestInfoVehicle struct {
VehicleNumber string `json:"vehicle_number"`
}
type SupplyWarehouse struct {
// Warehouse address
Address string `json:"address"`
// Warehouse name
Name string `json:"name"`
// Warehouse identifier
Id int64 `json:"warehouse_id"`
}
// Method for getting detailed information on a supply request.
// Requests with supply both to a specific warehouse and via a
// virtual distribution center (vDC) are taken into account
func (c FBO) GetSupplyRequestInfo(ctx context.Context, params *GetSupplyRequestInfoParams) (*GetSupplyRequestInfoResponse, error) {
url := "/v1/supply-order/get"
url := "/v2/supply-order/get"
resp := &GetSupplyRequestInfoResponse{}
@@ -563,3 +598,277 @@ func (c FBO) GetWarehouseWorkload(ctx context.Context) (*GetWarehouseWorkloadRes
return resp, nil
}
type GetSupplyOrdersByStatusParams struct {
}
type GetSupplyOrdersByStatusResponse struct {
core.CommonResponse
Items []SupplyOrdersByStatus `json:"items"`
}
type SupplyOrdersByStatus struct {
// Number of supply requests in this status
Count int32 `json:"count"`
// Supply status
OrderState string `json:"order_state"`
}
// Returns the number of supply requests in a specific status.
func (c FBO) GetSupplyOrdersByStatus(ctx context.Context) (*GetSupplyOrdersByStatusResponse, error) {
url := "/v1/supply-order/status/counter"
resp := &GetSupplyOrdersByStatusResponse{}
response, err := c.client.Request(ctx, http.MethodGet, url, &GetSupplyOrdersByStatusParams{}, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}
type GetSupplyTimeslotsParams struct {
// Supply request identifier
SupplyOrderId int64 `json:"supply_order_id"`
}
type GetSupplyTimeslotsResponse struct {
core.CommonResponse
// Supply time slot
Timeslots []SupplyTimeslotValueTimeslot `json:"timeslots"`
// Time zone
Timezones []SupplyTimeslotValueTimezone `json:"timezone"`
}
func (c FBO) GetSupplyTimeslots(ctx context.Context, params *GetSupplyTimeslotsParams) (*GetSupplyTimeslotsResponse, error) {
url := "/v1/supply-order/timeslot/get"
resp := &GetSupplyTimeslotsResponse{}
response, err := c.client.Request(ctx, http.MethodGet, url, params, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}
type UpdateSupplyTimeslotParams struct {
// Supply request identifier
SupplyOrderId int64 `json:"supply_order_id"`
// Supply time slot details
Timeslot SupplyTimeslotValueTimeslot `json:"timeslot"`
}
type UpdateSupplyTimeslotResponse struct {
core.CommonResponse
// Possible errors
Errors []string `json:"errors"`
// Operation identifier
OperationId string `json:"operation_id"`
}
func (c FBO) UpdateSupplyTimeslot(ctx context.Context, params *UpdateSupplyTimeslotParams) (*UpdateSupplyTimeslotResponse, error) {
url := "/v1/supply-order/timeslot/update"
resp := &UpdateSupplyTimeslotResponse{}
response, err := c.client.Request(ctx, http.MethodGet, url, params, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}
type GetSupplyTimeslotStatusParams struct {
// Operation identifier
OperationId string `json:"operation_id"`
}
type GetSupplyTimeslotStatusResponse struct {
core.CommonResponse
// Possible errors
Errors []string `json:"errors"`
// Data status
Status string `json:"status"`
}
func (c FBO) GetSupplyTimeslotStatus(ctx context.Context, params *GetSupplyTimeslotStatusParams) (*GetSupplyTimeslotStatusResponse, error) {
url := "/v1/supply-order/timeslot/status"
resp := &GetSupplyTimeslotStatusResponse{}
response, err := c.client.Request(ctx, http.MethodGet, url, params, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}
type CreatePassParams struct {
// Supply request identifier
SupplyOrderId int64 `json:"supply_order_id"`
// Driver and car information
Vehicle GetSupplyRequestInfoVehicle `json:"vehicle"`
}
type CreatePassResponse struct {
core.CommonResponse
// Possible errors
Errors []string `json:"error_reasons"`
// Operation identifier
OperationId string `json:"operation_id"`
}
func (c FBO) CreatePass(ctx context.Context, params *CreatePassParams) (*CreatePassResponse, error) {
url := "/v1/supply-order/pass/create"
resp := &CreatePassResponse{}
response, err := c.client.Request(ctx, http.MethodGet, url, params, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}
type GetPassParams struct {
// Operation identifier
OperationId string `json:"operation_id"`
}
type GetPassResponse struct {
core.CommonResponse
// Possible errors
Errors []string `json:"errors"`
// Status of driver and vehicle data entry
Result string `json:"result"`
}
func (c FBO) GetPass(ctx context.Context, params *GetPassParams) (*GetPassResponse, error) {
url := "/v1/supply-order/pass/status"
resp := &GetPassResponse{}
response, err := c.client.Request(ctx, http.MethodGet, url, params, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}
type GetSupplyContentParams struct {
// Identifiers of supply contents. Minimum is 1, maximum is 1000. You can get them using the /v2/supply-order/get method
BundleIds []string `json:"bundle_ids"`
// true, to sort in ascending order
IsAsc bool `json:"is_asc"`
// Identifier of the last value on the page
LastId string `json:"last_id"`
// Number of values on the page. Minimum is 1, maximum is 1000
Limit int32 `json:"limit"`
// Search query, for example: by name, article code, or SKU
Query string `json:"query"`
// Sorting by parameters
SortField string `json:"sort_field"`
}
type GetSupplyContentResponse struct {
core.CommonResponse
// List of products in the supply request
Items []SupplyContentItem `json:"items"`
// Quantity of products in the request
TotalCount int32 `json:"total_count"`
// Indication that the response hasn't returned all products
HasNext bool `json:"has_next"`
// Identifier of the last value on the page
LastId string `json:"last_id"`
}
type SupplyContentItem struct {
// Link to product image
IconPath string `json:"icon_path"`
// Product identifier in the Ozon system, SKU
SKU int64 `json:"sku"`
// Product name
Name string `json:"name"`
// Product items quantity
Quantity int32 `json:"quantity"`
// Barcode
Barcode string `json:"barcode"`
// Product identifier
ProductId int64 `json:"product_id"`
// Quantity of products in one package
Quant int32 `json:"quant"`
// true if the quantity of products in one package can be edited
IsQuantEditable bool `json:"is_quant_editable"`
// Volume of products in liters
VolumeInLiters float64 `json:"volume_in_litres"`
// Volume of all products in liters
TotalVolumeInLiters float64 `json:"total_volume_in_litres"`
// Product article code
ContractorItemCode string `json:"contractor_item_code"`
// Super product label
SFBOAttribute string `json:"sfbo_attribute"`
// Type of wrapper
ShipmentType string `json:"shipment_type"`
}
func (c FBO) GetSupplyContent(ctx context.Context, params *GetSupplyContentParams) (*GetSupplyContentResponse, error) {
url := "/v1/supply-order/bundle"
resp := &GetSupplyContentResponse{}
response, err := c.client.Request(ctx, http.MethodGet, url, params, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}

View File

@@ -301,36 +301,19 @@ func TestListSupplyRequests(t *testing.T) {
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&ListSupplyRequestsParams{
Page: 0,
PageSize: 0,
States: []SupplyRequestState{AcceptanceAtStorageWarehouse},
Filter: &ListSupplyRequestsFilter{
States: []string{"ORDER_STATE_DATA_FILLING"},
},
Paging: &ListSupplyRequestsPaging{
FromOrderId: 0,
Limit: 0,
},
},
`{
"has_next": true,
"supply_orders": [
{
"created_at": "string",
"local_timeslot": {
"from": "string",
"to": "string"
},
"preferred_supply_date_from": "string",
"preferred_supply_date_to": "string",
"state": "string",
"supply_order_id": 0,
"supply_order_number": "string",
"supply_warehouse": {
"address": "string",
"name": "string",
"warehouse_id": 0
},
"time_left_to_prepare_supply": 0,
"time_left_to_select_supply_variant": 0,
"total_items_count": 0,
"total_quantity": 0
}
],
"total_supply_orders_count": 0
"last_supply_order_id": 0,
"supply_order_id": [
"string"
]
}`,
},
// Test No Client-Id or Api-Key
@@ -377,39 +360,74 @@ func TestGetSupplyRequestInfo(t *testing.T) {
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&GetSupplyRequestInfoParams{
SupplyOrderId: 0,
OrderIds: []string{"string"},
},
`{
"created_at": "string",
"local_timeslot": {
"from": "string",
"to": "string"
},
"preferred_supply_date_from": "string",
"preferred_supply_date_to": "string",
"seller_warehouse": {
"address": "string",
"name": "string",
"warehouse_id": 0
},
"state": "string",
"supply_order_id": 0,
"supply_order_number": "string",
"supply_warehouse": {
"address": "string",
"name": "string",
"warehouse_id": 0
},
"time_left_to_prepare_supply": 0,
"time_left_to_select_supply_variant": 0,
"total_items_count": 0,
"total_quantity": 0,
"vehicle_info": {
"driver_name": "string",
"driver_phone": "string",
"vehicle_model": "string",
"vehicle_number": "string"
}
"orders": [
{
"creation_date": "string",
"creation_flow": "string",
"data_filling_deadline_utc": "2019-08-24T14:15:22Z",
"dropoff_warehouse_id": 0,
"state": "ORDER_STATE_UNSPECIFIED",
"supplies": [
{
"bundle_id": "string",
"storage_warehouse_id": 0,
"supply_id": 0
}
],
"supply_order_id": 0,
"supply_order_number": "string",
"timeslot": [
{
"can_not_set_reasons": [
"string"
],
"can_set": true,
"is_required": true,
"value": {
"timeslot": [
{
"from": "2019-08-24T14:15:22Z",
"to": "2019-08-24T14:15:22Z"
}
],
"timezone_info": [
{
"iana_name": "string",
"offset": "string"
}
]
}
}
],
"vehicle": [
{
"can_not_set_reasons": [
"string"
],
"can_set": true,
"is_required": true,
"value": [
{
"driver_name": "string",
"driver_phone": "string",
"vehicle_model": "string",
"vehicle_number": "string"
}
]
}
]
}
],
"warehouses": [
{
"address": "string",
"name": "string",
"warehouse_id": 0
}
]
}`,
},
// Test No Client-Id or Api-Key
@@ -565,3 +583,409 @@ func TestGetWarehouseWorkload(t *testing.T) {
}
}
}
func TestGetSupplyOrdersByStatus(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"},
`{
"items": [
{
"count": 0,
"order_state": "ORDER_STATE_UNSPECIFIED"
}
]
}`,
},
// 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.FBO().GetSupplyOrdersByStatus(ctx)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &GetSupplyOrdersByStatusResponse{})
if resp.StatusCode != test.statusCode {
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
}
}
}
func TestGetSupplyTimeslots(t *testing.T) {
t.Parallel()
tests := []struct {
statusCode int
headers map[string]string
params *GetSupplyTimeslotsParams
response string
}{
// Test Ok
{
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&GetSupplyTimeslotsParams{
SupplyOrderId: 0,
},
`{
"timeslots": [
{
"from": "2019-08-24T14:15:22Z",
"to": "2019-08-24T14:15:22Z"
}
],
"timezone": [
{
"iana_name": "string",
"offset": "string"
}
]
}`,
},
// Test No Client-Id or Api-Key
{
http.StatusUnauthorized,
map[string]string{},
&GetSupplyTimeslotsParams{},
`{
"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.FBO().GetSupplyTimeslots(ctx, test.params)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &GetSupplyTimeslotsResponse{})
if resp.StatusCode != test.statusCode {
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
}
}
}
func TestUpdateSupplyTimeslot(t *testing.T) {
t.Parallel()
tests := []struct {
statusCode int
headers map[string]string
params *UpdateSupplyTimeslotParams
response string
}{
// Test Ok
{
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&UpdateSupplyTimeslotParams{
SupplyOrderId: 0,
Timeslot: SupplyTimeslotValueTimeslot{
From: core.TimeFromString(t, "2006-01-02T15:04:05Z", "2019-08-24T14:15:22Z"),
To: core.TimeFromString(t, "2006-01-02T15:04:05Z", "2019-08-24T14:15:22Z"),
},
},
`{
"errors": [
"UPDATE_TIMESLOT_ERROR_UNSPECIFIED"
],
"operation_id": "string"
}`,
},
// Test No Client-Id or Api-Key
{
http.StatusUnauthorized,
map[string]string{},
&UpdateSupplyTimeslotParams{},
`{
"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.FBO().UpdateSupplyTimeslot(ctx, test.params)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &UpdateSupplyTimeslotResponse{})
if resp.StatusCode != test.statusCode {
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
}
}
}
func TestGetSupplyTimeslotStatus(t *testing.T) {
t.Parallel()
tests := []struct {
statusCode int
headers map[string]string
params *GetSupplyTimeslotStatusParams
response string
}{
// Test Ok
{
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&GetSupplyTimeslotStatusParams{
OperationId: "string",
},
`{
"errors": [
"UPDATE_TIMESLOT_ERROR_UNSPECIFIED"
],
"status": "STATUS_UNSPECIFIED"
}`,
},
// Test No Client-Id or Api-Key
{
http.StatusUnauthorized,
map[string]string{},
&GetSupplyTimeslotStatusParams{},
`{
"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.FBO().GetSupplyTimeslotStatus(ctx, test.params)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &GetSupplyTimeslotStatusResponse{})
if resp.StatusCode != test.statusCode {
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
}
}
}
func TestCreatePass(t *testing.T) {
t.Parallel()
tests := []struct {
statusCode int
headers map[string]string
params *CreatePassParams
response string
}{
// Test Ok
{
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&CreatePassParams{
SupplyOrderId: 123,
Vehicle: GetSupplyRequestInfoVehicle{
DriverName: "string",
DriverPhone: "string",
VehicleModel: "string",
VehicleNumber: "string",
},
},
`{
"error_reasons": [
"SET_VEHICLE_ERROR_UNSPECIFIED"
],
"operation_id": "string"
}`,
},
// Test No Client-Id or Api-Key
{
http.StatusUnauthorized,
map[string]string{},
&CreatePassParams{},
`{
"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.FBO().CreatePass(ctx, test.params)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &CreatePassResponse{})
if resp.StatusCode != test.statusCode {
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
}
}
}
func TestGetPass(t *testing.T) {
t.Parallel()
tests := []struct {
statusCode int
headers map[string]string
params *GetPassParams
response string
}{
// Test Ok
{
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&GetPassParams{
OperationId: "string",
},
`{
"errors": [
"SET_VEHICLE_ERROR_UNSPECIFIED"
],
"result": "Unknown"
}`,
},
// Test No Client-Id or Api-Key
{
http.StatusUnauthorized,
map[string]string{},
&GetPassParams{},
`{
"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.FBO().GetPass(ctx, test.params)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &GetPassResponse{})
if resp.StatusCode != test.statusCode {
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
}
}
}
func TestGetSupplyContent(t *testing.T) {
t.Parallel()
tests := []struct {
statusCode int
headers map[string]string
params *GetSupplyContentParams
response string
}{
// Test Ok
{
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&GetSupplyContentParams{
BundleIds: []string{"string"},
IsAsc: true,
Limit: 0,
Query: "string",
SortField: "UNSPECIFIED",
},
`{
"items": [
{
"icon_path": "string",
"sku": 0,
"name": "string",
"quantity": 0,
"barcode": "string",
"product_id": 0,
"quant": 0,
"is_quant_editable": true,
"volume_in_litres": 0,
"total_volume_in_litres": 0,
"contractor_item_code": "string",
"sfbo_attribute": "ITEM_SFBO_ATTRIBUTE_UNSPECIFIED",
"shipment_type": "BUNDLE_ITEM_SHIPMENT_TYPE_UNSPECIFIED"
}
],
"total_count": 0,
"has_next": true,
"last_id": "string"
}`,
},
// Test No Client-Id or Api-Key
{
http.StatusUnauthorized,
map[string]string{},
&GetSupplyContentParams{},
`{
"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.FBO().GetSupplyContent(ctx, test.params)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &GetSupplyContentResponse{})
if resp.StatusCode != test.statusCode {
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
}
}
}

View File

@@ -12,125 +12,6 @@ type Returns struct {
client *core.Client
}
type GetFBOReturnsParams struct {
// Filter
Filter *GetFBOReturnsFilter `json:"filter,omitempty"`
// Identifier of the last value on the page. Leave this field blank in the first request.
//
// To get the next values, specify the recieved value in the next request in the `last_id` parameter
LastId int64 `json:"last_id"`
// Number of values in the response
Limit int64 `json:"limit"`
}
type GetFBOReturnsFilter struct {
// Shipment number
PostingNumber string `json:"posting_number"`
// Return status
Status []GetFBOReturnsFilterStatus `json:"status"`
}
type GetFBOReturnsResponse struct {
core.CommonResponse
// Identifier of the last value on the page
LastId int64 `json:"last_id"`
// Returns information
Returns []GetFBOReturnsReturn `json:"returns"`
}
type GetFBOReturnsReturn struct {
// Time when a return was received from the customer
AcceptedFromCustomerMoment time.Time `json:"accepted_from_customer_moment"`
// Seller identifier
CompanyId int64 `json:"company_id"`
// Current return location
CurrentPlaceName string `json:"current_place_name"`
// Return destination
DestinationPlaceName string `json:"dst_place_name"`
// Return shipment identifier
Id int64 `json:"id"`
// Indication that the package has been opened. true, if it has been
IsOpened bool `json:"is_opened"`
// Shipment number
PostingNumber string `json:"posting_number"`
// Unique return record identifier
ReturnId int64 `json:"return_id"`
// Return reason
ReturnReasonName string `json:"return_reason_name"`
// Return delivery time to the Ozon warehouse
ReturnedToOzonMoment time.Time `json:"returned_to_ozon_moment"`
// Product identifier in the Ozon system, SKU
SKU int64 `json:"sku"`
// Return status
Status GetFBOReturnsReturnStatus `json:"status_name"`
}
// Method for getting information on returned products that are sold from the Ozon warehouse
func (c Returns) GetFBOReturns(ctx context.Context, params *GetFBOReturnsParams) (*GetFBOReturnsResponse, error) {
url := "/v3/returns/company/fbo"
resp := &GetFBOReturnsResponse{}
response, err := c.client.Request(ctx, http.MethodPost, url, params, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}
type GetFBSReturnsParams struct {
// Filter
Filter *GetFBSReturnsFilter `json:"filter,omitempty"`
// Number of values in the response:
// - maximum — 1000,
// - minimum — 1
Limit int64 `json:"limit"`
// Return identifier that was loaded the last time.
// Return identifiers with the higher value than `last_id`
// will be returned in the response.
LastId int64 `json:"offset"`
}
type GetFBSReturnsFilter struct {
// Last day of free storage
LastFreeWaitingDay GetFBSReturnsFilterTimeRange `json:"last_free_waiting_dat"`
// Order ID
OrderId int64 `json:"order_id"`
// Shipment ID
PostingNumber []string `json:"posting_number"`
// Product name
ProductName string `json:"product_name"`
// Product ID
ProductOfferId string `json:"product_offer_id"`
// Return status
Status GetFBSReturnsFilterStatus `json:"status"`
}
type GetFBSReturnsFilterTimeRange struct {
// The beginning of the period.
//
@@ -147,118 +28,6 @@ type GetFBSReturnsFilterTimeRange struct {
TimeTo time.Time `json:"time_to"`
}
type GetFBSReturnsResponse struct {
core.CommonResponse
// Return identifier that was loaded the last time.
// Return identifiers with the higher value than `last_id`
// will be returned in the response
LastId int64 `json:"last_id"`
// Returns information
Returns []GetFBSReturnResultReturn `json:"returns"`
}
type GetFBSReturnResultReturn struct {
// Bottom barcode on the product label
ClearingId int64 `json:"clearing_id"`
// Commission fee
Commission float64 `json:"commission"`
// Commission percentage
CommissionPercent float64 `json:"commission_percent"`
// Product item identifier in the Ozon logistics system
ExemplarId int64 `json:"exemplar_id"`
// Return identifier in the Ozon accounting system
Id int64 `json:"id"`
// If the product is in transit — true
IsMoving bool `json:"is_moving"`
// Indication that the package has been opened. true, if it has been
IsOpened bool `json:"is_opened"`
// Last day of free storage
LastFreeWaitingDay string `json:"last_free_waiting_day"`
// ID of the warehouse the product is being transported to
PlaceId int64 `json:"place_id"`
// Intermediate return point
MovingToPlaceName string `json:"moving_to_place_name"`
// Delivery cost
PickingAmount float64 `json:"picking_amount"`
// Shipment number
PostingNumber string `json:"posting_number"`
PickingTag string `json:"picking_tag"`
// Current product price without a discount
Price float64 `json:"price"`
// Product price without commission
PriceWithoutCommission float64 `json:"price_without_commission"`
// Product identifier — SKU
ProductId int64 `json:"product_id"`
// Product name
ProductName string `json:"product_name"`
// Product quantity
Quantity int64 `json:"quantity"`
// Barcode on the return label. Use this parameter value to work with the return label
ReturnBarcode string `json:"return_barcode"`
// Package unit identifier in the Ozon logistics system
ReturnClearingId int64 `json:"return_clearing_id"`
// Product return date
ReturnDate string `json:"return_date"`
// Return reason
ReturnReasonName string `json:"return_reason_name"`
// Date when the product is ready to be handed over to the seller
WaitingForSellerDate string `json:"waiting_for_seller_date_time"`
// Date of handing over the product to the seller
ReturnedToSellerDate string `json:"returned_to_seller_date_time"`
// Return storage period in days
WaitingForSellerDays int64 `json:"waiting_for_seller_days"`
// Return storage cost
ReturnsKeepingCost float64 `json:"returns_keeping_cost"`
// Product identifier in the Ozon system, SKU
SKU int64 `json:"sku"`
// Return status
Status string `json:"status"`
}
// Method for getting information on returned products that are sold from the seller's warehouse
func (c Returns) GetFBSReturns(ctx context.Context, params *GetFBSReturnsParams) (*GetFBSReturnsResponse, error) {
url := "/v3/returns/company/fbs"
resp := &GetFBSReturnsResponse{}
response, err := c.client.Request(ctx, http.MethodPost, url, params, resp, nil)
if err != nil {
return nil, err
}
response.CopyCommonResponse(&resp.CommonResponse)
return resp, nil
}
type GetRFBSReturnsParams struct {
// Filter
Filter *GetRFBSReturnsFilter `json:"filter,omitempty"`

View File

@@ -8,193 +8,6 @@ import (
core "github.com/diphantxm/ozon-api-client"
)
func TestGetFBOReturns(t *testing.T) {
t.Parallel()
tests := []struct {
statusCode int
headers map[string]string
params *GetFBOReturnsParams
response string
}{
// Test Ok
{
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&GetFBOReturnsParams{
Filter: &GetFBOReturnsFilter{
PostingNumber: "some number",
},
LastId: 123,
Limit: 100,
},
`{
"last_id": 0,
"returns": [
{
"accepted_from_customer_moment": "2019-08-24T14:15:22Z",
"company_id": 123456789,
"current_place_name": "my-place",
"dst_place_name": "that-place",
"id": 123456789,
"is_opened": true,
"posting_number": "some number",
"return_reason_name": "ripped",
"returned_to_ozon_moment": "2019-08-24T14:15:22Z",
"sku": 123456789,
"status_name": "delivering"
}
]
}`,
},
// Test No Client-Id or Api-Key
{
http.StatusUnauthorized,
map[string]string{},
&GetFBOReturnsParams{},
`{
"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().GetFBOReturns(ctx, test.params)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &GetFBOReturnsResponse{})
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.Returns) > 0 {
if resp.Returns[0].Id == 0 {
t.Errorf("Id cannot be 0")
}
if resp.Returns[0].CompanyId == 0 {
t.Errorf("Company id cannot be 0")
}
if resp.Returns[0].SKU == 0 {
t.Errorf("SKU cannot be 0")
}
}
}
}
}
func TestGetFBSReturns(t *testing.T) {
t.Parallel()
tests := []struct {
statusCode int
headers map[string]string
params *GetFBSReturnsParams
response string
}{
// Test Ok
{
http.StatusOK,
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
&GetFBSReturnsParams{
Filter: &GetFBSReturnsFilter{
PostingNumber: []string{"07402477-0022-2"},
Status: "returned_to_seller",
},
Limit: 1000,
LastId: 0,
},
`{
"last_id": 0,
"returns": [
{
"clearing_id": 23,
"commission": 21,
"commission_percent": 0,
"exemplar_id": 42,
"id": 123,
"is_moving": true,
"is_opened": true,
"last_free_waiting_day": "string",
"place_id": 122,
"moving_to_place_name": "string",
"picking_amount": 0,
"posting_number": "string",
"picking_tag": "string",
"price": 0,
"price_without_commission": 0,
"product_id": 2222,
"product_name": "string",
"quantity": 0,
"return_barcode": "string",
"return_clearing_id": 0,
"return_date": "string",
"return_reason_name": "string",
"waiting_for_seller_date_time": "string",
"returned_to_seller_date_time": "string",
"waiting_for_seller_days": 0,
"returns_keeping_cost": 0,
"sku": 33332,
"status": "string"
}
]
}`,
},
// Test No Client-Id or Api-Key
{
http.StatusUnauthorized,
map[string]string{},
&GetFBSReturnsParams{},
`{
"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().GetFBSReturns(ctx, test.params)
if err != nil {
t.Error(err)
continue
}
compareJsonResponse(t, test.response, &GetFBSReturnsResponse{})
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.Returns) > 0 {
if resp.Returns[0].Id == 0 {
t.Errorf("Id cannot be 0")
}
if resp.Returns[0].ProductId == 0 {
t.Errorf("Product id cannot be 0")
}
if resp.Returns[0].SKU == 0 {
t.Errorf("SKU cannot be 0")
}
if resp.Returns[0].Status == "" {
t.Errorf("Status cannot be empty")
}
}
}
}
}
func TestGetRFBSReturns(t *testing.T) {
t.Parallel()