Update October 31, 2024 (#114)
This commit is contained in:
501
ozon/fbo.go
501
ozon/fbo.go
@@ -290,108 +290,38 @@ func (c FBO) GetShipmentDetails(ctx context.Context, params *GetShipmentDetailsP
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ListSupplyRequestsParams struct {
|
type ListSupplyRequestsParams struct {
|
||||||
// Number of the page returned in the request
|
// Filter
|
||||||
Page int32 `json:"page"`
|
Filter *ListSupplyRequestsFilter `json:"filter"`
|
||||||
|
|
||||||
// Number of elements on the page
|
// Customizing the display of the requests list
|
||||||
PageSize int32 `json:"page_size"`
|
Paging *ListSupplyRequestsPaging `json:"paging"`
|
||||||
|
}
|
||||||
|
|
||||||
// Filter on status of a supply by request
|
type ListSupplyRequestsFilter struct {
|
||||||
States []SupplyRequestState `json:"states"`
|
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 {
|
type ListSupplyRequestsResponse struct {
|
||||||
core.CommonResponse
|
core.CommonResponse
|
||||||
|
|
||||||
// Indicates that the response contains not the entire array of supply requests:
|
// Supply request identifier you last requested
|
||||||
// - true — make a new request with a different page and page_size values to get information on the remaining requests;
|
LastSupplyOrderId int64 `json:"last_supply_order_id"`
|
||||||
// - 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
|
// Supply request identifier
|
||||||
SupplyOrderId int64 `json:"supply_order_id"`
|
SupplyOrderId []string `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"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SupplyRequestSellerWarehouse struct {
|
// Requests with supply to a specific warehouse and through a virtual distribution center (vDC) are taken into account
|
||||||
// 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
|
|
||||||
func (c FBO) ListSupplyRequests(ctx context.Context, params *ListSupplyRequestsParams) (*ListSupplyRequestsResponse, error) {
|
func (c FBO) ListSupplyRequests(ctx context.Context, params *ListSupplyRequestsParams) (*ListSupplyRequestsResponse, error) {
|
||||||
url := "/v1/supply-order/list"
|
url := "/v2/supply-order/list"
|
||||||
|
|
||||||
resp := &ListSupplyRequestsResponse{}
|
resp := &ListSupplyRequestsResponse{}
|
||||||
|
|
||||||
@@ -405,17 +335,111 @@ func (c FBO) ListSupplyRequests(ctx context.Context, params *ListSupplyRequestsP
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GetSupplyRequestInfoParams struct {
|
type GetSupplyRequestInfoParams struct {
|
||||||
// Supply request identifier
|
// Supply request identifier in the Ozon system
|
||||||
SupplyOrderId int64 `json:"supply_order_id"`
|
OrderIds []string `json:"order_ids"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetSupplyRequestInfoResponse struct {
|
type GetSupplyRequestInfoResponse struct {
|
||||||
core.CommonResponse
|
core.CommonResponse
|
||||||
|
|
||||||
SupplyRequestCommonResponse
|
// Supply request details
|
||||||
|
Orders []SupplyOrder `json:"orders"`
|
||||||
|
|
||||||
// Driver and car information
|
// Warehouse details
|
||||||
VehicleInfo GetSupplyRequestInfoVehicle `json:"vehicle_info"`
|
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 {
|
type GetSupplyRequestInfoVehicle struct {
|
||||||
@@ -432,11 +456,22 @@ type GetSupplyRequestInfoVehicle struct {
|
|||||||
VehicleNumber string `json:"vehicle_number"`
|
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.
|
// Method for getting detailed information on a supply request.
|
||||||
// Requests with supply both to a specific warehouse and via a
|
// Requests with supply both to a specific warehouse and via a
|
||||||
// virtual distribution center (vDC) are taken into account
|
// virtual distribution center (vDC) are taken into account
|
||||||
func (c FBO) GetSupplyRequestInfo(ctx context.Context, params *GetSupplyRequestInfoParams) (*GetSupplyRequestInfoResponse, error) {
|
func (c FBO) GetSupplyRequestInfo(ctx context.Context, params *GetSupplyRequestInfoParams) (*GetSupplyRequestInfoResponse, error) {
|
||||||
url := "/v1/supply-order/get"
|
url := "/v2/supply-order/get"
|
||||||
|
|
||||||
resp := &GetSupplyRequestInfoResponse{}
|
resp := &GetSupplyRequestInfoResponse{}
|
||||||
|
|
||||||
@@ -563,3 +598,277 @@ func (c FBO) GetWarehouseWorkload(ctx context.Context) (*GetWarehouseWorkloadRes
|
|||||||
|
|
||||||
return resp, nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
542
ozon/fbo_test.go
542
ozon/fbo_test.go
@@ -301,36 +301,19 @@ func TestListSupplyRequests(t *testing.T) {
|
|||||||
http.StatusOK,
|
http.StatusOK,
|
||||||
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
|
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
|
||||||
&ListSupplyRequestsParams{
|
&ListSupplyRequestsParams{
|
||||||
Page: 0,
|
Filter: &ListSupplyRequestsFilter{
|
||||||
PageSize: 0,
|
States: []string{"ORDER_STATE_DATA_FILLING"},
|
||||||
States: []SupplyRequestState{AcceptanceAtStorageWarehouse},
|
},
|
||||||
|
Paging: &ListSupplyRequestsPaging{
|
||||||
|
FromOrderId: 0,
|
||||||
|
Limit: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
`{
|
`{
|
||||||
"has_next": true,
|
"last_supply_order_id": 0,
|
||||||
"supply_orders": [
|
"supply_order_id": [
|
||||||
{
|
"string"
|
||||||
"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
|
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
// Test No Client-Id or Api-Key
|
// Test No Client-Id or Api-Key
|
||||||
@@ -377,39 +360,74 @@ func TestGetSupplyRequestInfo(t *testing.T) {
|
|||||||
http.StatusOK,
|
http.StatusOK,
|
||||||
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
|
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
|
||||||
&GetSupplyRequestInfoParams{
|
&GetSupplyRequestInfoParams{
|
||||||
SupplyOrderId: 0,
|
OrderIds: []string{"string"},
|
||||||
},
|
},
|
||||||
`{
|
`{
|
||||||
"created_at": "string",
|
"orders": [
|
||||||
"local_timeslot": {
|
{
|
||||||
"from": "string",
|
"creation_date": "string",
|
||||||
"to": "string"
|
"creation_flow": "string",
|
||||||
},
|
"data_filling_deadline_utc": "2019-08-24T14:15:22Z",
|
||||||
"preferred_supply_date_from": "string",
|
"dropoff_warehouse_id": 0,
|
||||||
"preferred_supply_date_to": "string",
|
"state": "ORDER_STATE_UNSPECIFIED",
|
||||||
"seller_warehouse": {
|
"supplies": [
|
||||||
"address": "string",
|
{
|
||||||
"name": "string",
|
"bundle_id": "string",
|
||||||
"warehouse_id": 0
|
"storage_warehouse_id": 0,
|
||||||
},
|
"supply_id": 0
|
||||||
"state": "string",
|
}
|
||||||
"supply_order_id": 0,
|
],
|
||||||
"supply_order_number": "string",
|
"supply_order_id": 0,
|
||||||
"supply_warehouse": {
|
"supply_order_number": "string",
|
||||||
"address": "string",
|
"timeslot": [
|
||||||
"name": "string",
|
{
|
||||||
"warehouse_id": 0
|
"can_not_set_reasons": [
|
||||||
},
|
"string"
|
||||||
"time_left_to_prepare_supply": 0,
|
],
|
||||||
"time_left_to_select_supply_variant": 0,
|
"can_set": true,
|
||||||
"total_items_count": 0,
|
"is_required": true,
|
||||||
"total_quantity": 0,
|
"value": {
|
||||||
"vehicle_info": {
|
"timeslot": [
|
||||||
"driver_name": "string",
|
{
|
||||||
"driver_phone": "string",
|
"from": "2019-08-24T14:15:22Z",
|
||||||
"vehicle_model": "string",
|
"to": "2019-08-24T14:15:22Z"
|
||||||
"vehicle_number": "string"
|
}
|
||||||
}
|
],
|
||||||
|
"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
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
231
ozon/returns.go
231
ozon/returns.go
@@ -12,125 +12,6 @@ type Returns struct {
|
|||||||
client *core.Client
|
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 {
|
type GetFBSReturnsFilterTimeRange struct {
|
||||||
// The beginning of the period.
|
// The beginning of the period.
|
||||||
//
|
//
|
||||||
@@ -147,118 +28,6 @@ type GetFBSReturnsFilterTimeRange struct {
|
|||||||
TimeTo time.Time `json:"time_to"`
|
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 {
|
type GetRFBSReturnsParams struct {
|
||||||
// Filter
|
// Filter
|
||||||
Filter *GetRFBSReturnsFilter `json:"filter,omitempty"`
|
Filter *GetRFBSReturnsFilter `json:"filter,omitempty"`
|
||||||
|
|||||||
@@ -8,193 +8,6 @@ import (
|
|||||||
core "github.com/diphantxm/ozon-api-client"
|
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) {
|
func TestGetRFBSReturns(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user