update posting methods status/substatus, changed price index to multiple indexes in products responses
This commit is contained in:
138
ozon/common.go
138
ozon/common.go
@@ -175,3 +175,141 @@ const (
|
|||||||
// overdue
|
// overdue
|
||||||
Overdue SupplyRequestState = "OVERDUE"
|
Overdue SupplyRequestState = "OVERDUE"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ShipmentStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// acceptance is in progress
|
||||||
|
AcceptanceInProgress ShipmentStatus = "acceptance_in_progress"
|
||||||
|
|
||||||
|
// arbitration
|
||||||
|
Arbitration ShipmentStatus = "arbitration"
|
||||||
|
|
||||||
|
// awaiting confirmation
|
||||||
|
AwaitingApprove ShipmentStatus = "awaiting_approve"
|
||||||
|
|
||||||
|
// awaiting shipping
|
||||||
|
AwaitingDeliver ShipmentStatus = "awaiting_deliver"
|
||||||
|
|
||||||
|
// awaiting packaging
|
||||||
|
AwaitingPackaging ShipmentStatus = "awaiting_packaging"
|
||||||
|
|
||||||
|
// created
|
||||||
|
AwaitingVerification ShipmentStatus = "awaiting_verification"
|
||||||
|
|
||||||
|
// cancelled
|
||||||
|
CancelledSubstatus ShipmentStatus = "cancelled"
|
||||||
|
|
||||||
|
// delivered
|
||||||
|
Delivered ShipmentStatus = "delivered"
|
||||||
|
|
||||||
|
// delivery is in progress
|
||||||
|
Delivering ShipmentStatus = "delivering"
|
||||||
|
|
||||||
|
// picked up by driver
|
||||||
|
DriverPickup ShipmentStatus = "driver_pickup"
|
||||||
|
|
||||||
|
// not accepted at the sorting center
|
||||||
|
NotAccepted ShipmentStatus = "not_accepted"
|
||||||
|
|
||||||
|
// sent by the seller
|
||||||
|
SentBySeller ShipmentStatus = "sent_by_seller"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ShipmentSubstatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// acceptance in progress
|
||||||
|
PostingAcceptanceInProgress ShipmentStatus = "posting_acceptance_in_progress"
|
||||||
|
|
||||||
|
// arbitrage
|
||||||
|
PostingInArbitration ShipmentStatus = "posting_in_arbitration"
|
||||||
|
|
||||||
|
// created
|
||||||
|
PostingCreated ShipmentStatus = "posting_created"
|
||||||
|
|
||||||
|
// in the freight
|
||||||
|
PostingInCarriage ShipmentStatus = "posting_in_carriage"
|
||||||
|
|
||||||
|
// not added to the freight
|
||||||
|
PostingNotInCarriage ShipmentStatus = "posting_not_in_carriage"
|
||||||
|
|
||||||
|
// registered
|
||||||
|
PostingRegistered ShipmentStatus = "posting_registered"
|
||||||
|
|
||||||
|
// is handed over to the delivery service
|
||||||
|
PostingTransferringToDelivery ShipmentStatus = "posting_transferring_to_delivery"
|
||||||
|
|
||||||
|
// waiting for passport data
|
||||||
|
PostingAwaitingPassportData ShipmentStatus = "posting_awaiting_passport_data"
|
||||||
|
|
||||||
|
// created
|
||||||
|
PostingCreatedSubstatus ShipmentStatus = "posting_created"
|
||||||
|
|
||||||
|
// awaiting registration
|
||||||
|
PostingAwaitingRegistration ShipmentStatus = "posting_awaiting_registration"
|
||||||
|
|
||||||
|
// registration error
|
||||||
|
PostingRegistrationError ShipmentStatus = "posting_registration_error"
|
||||||
|
|
||||||
|
// created
|
||||||
|
PostingSplitPending ShipmentStatus = "posting_split_pending"
|
||||||
|
|
||||||
|
// canceled
|
||||||
|
PostingCancelled ShipmentStatus = "posting_canceled"
|
||||||
|
|
||||||
|
// customer delivery arbitrage
|
||||||
|
PostingInClientArbitration ShipmentStatus = "posting_in_client_arbitration"
|
||||||
|
|
||||||
|
// delivered
|
||||||
|
PostingDelivered ShipmentStatus = "posting_delivered"
|
||||||
|
|
||||||
|
// recieved
|
||||||
|
PostingReceived ShipmentStatus = "posting_received"
|
||||||
|
|
||||||
|
// presumably delivered
|
||||||
|
PostingConditionallyDelivered ShipmentStatus = "posting_conditionally_delivered"
|
||||||
|
|
||||||
|
// courier on the way
|
||||||
|
PostingInCourierService ShipmentStatus = "posting_in_courier_service"
|
||||||
|
|
||||||
|
// at the pick-up point
|
||||||
|
PostingInPickupPoint ShipmentStatus = "posting_in_pickup_point"
|
||||||
|
|
||||||
|
// on the way to the city
|
||||||
|
PostingOnWayToCity ShipmentStatus = "posting_on_way_to_city"
|
||||||
|
|
||||||
|
// on the way to the pick-up point
|
||||||
|
PostingOnWayToPickupPoint ShipmentStatus = "posting_on_way_to_pickup_point"
|
||||||
|
|
||||||
|
// returned to the warehouse
|
||||||
|
PostingReturnedToWarehouse ShipmentStatus = "posting_returned_to_warehouse"
|
||||||
|
|
||||||
|
// is handed over to the courier
|
||||||
|
PostingTransferredToCourierService ShipmentStatus = "posting_transferred_to_courier_service"
|
||||||
|
|
||||||
|
// handed over to the driver
|
||||||
|
PostingDriverPickup ShipmentStatus = "posting_driver_pick_up"
|
||||||
|
|
||||||
|
// not accepted at the sorting center
|
||||||
|
PostingNotInSortCenter ShipmentStatus = "posting_not_in_sort_center"
|
||||||
|
|
||||||
|
// sent by the seller
|
||||||
|
SentBySellerSubstatus ShipmentStatus = "sent_by_seller"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TPLIntegrationType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// delivery by the Ozon logistics
|
||||||
|
OzonTPLType TPLIntegrationType = "ozon"
|
||||||
|
|
||||||
|
// delivery by a third-party service, Ozon registers the order
|
||||||
|
AggregatorTPLType TPLIntegrationType = "aggregator"
|
||||||
|
|
||||||
|
// delivery by a third-party service, the seller registers the order
|
||||||
|
TrackingTPLType TPLIntegrationType = "3pl_tracking"
|
||||||
|
|
||||||
|
// delivery by the seller
|
||||||
|
NonIntegratedTPLType TPLIntegrationType = "non_integrated"
|
||||||
|
)
|
||||||
|
|||||||
17
ozon/fbs.go
17
ozon/fbs.go
@@ -754,14 +754,13 @@ type GetShipmentDataByIdentifierResponse struct {
|
|||||||
ShipmentDate time.Time `json:"shipment_date"`
|
ShipmentDate time.Time `json:"shipment_date"`
|
||||||
|
|
||||||
// Shipment status
|
// Shipment status
|
||||||
Status string `json:"status"`
|
Status ShipmentStatus `json:"status"`
|
||||||
|
|
||||||
// Type of integration with the delivery service:
|
// Shipment substatus
|
||||||
// - ozon — delivery by the Ozon logistics.
|
Substatus ShipmentSubstatus `json:"substatus"`
|
||||||
// - aggregator — delivery by a third-party service, Ozon registers the order.
|
|
||||||
// - 3pl_tracking — delivery by a third-party service, the seller registers the order.
|
// Type of integration with the delivery service
|
||||||
// - non_integrated — delivery by the seller
|
TPLIntegrationType TPLIntegrationType `json:"tpl_integration_type"`
|
||||||
TPLIntegrationType string `json:"tpl_integration_type"`
|
|
||||||
|
|
||||||
// Shipment tracking number
|
// Shipment tracking number
|
||||||
TrackingNumber string `json:"tracking_number"`
|
TrackingNumber string `json:"tracking_number"`
|
||||||
@@ -1132,6 +1131,7 @@ type CancelShipmentResponse struct {
|
|||||||
// - 665 — the customer did not pick the order;
|
// - 665 — the customer did not pick the order;
|
||||||
// - 666 — delivery is not available in the region;
|
// - 666 — delivery is not available in the region;
|
||||||
// - 667 — order was lost by the delivery service.
|
// - 667 — order was lost by the delivery service.
|
||||||
|
//
|
||||||
// For presumably delivered orders only the last 3 reasons are available.
|
// For presumably delivered orders only the last 3 reasons are available.
|
||||||
//
|
//
|
||||||
// If cancel_reason_id parameter value is 402, fill the cancel_reason_message field
|
// If cancel_reason_id parameter value is 402, fill the cancel_reason_message field
|
||||||
@@ -1381,13 +1381,14 @@ type CheckProductItemsDataResponse struct {
|
|||||||
// Asynchronous method:
|
// Asynchronous method:
|
||||||
// - for checking the availability of product items in the “Chestny ZNAK” labeling system
|
// - for checking the availability of product items in the “Chestny ZNAK” labeling system
|
||||||
// - for saving product items data
|
// - for saving product items data
|
||||||
|
//
|
||||||
// To get the checks results, use the `/v4/fbs/posting/product/exemplar/status method`
|
// To get the checks results, use the `/v4/fbs/posting/product/exemplar/status method`
|
||||||
//
|
//
|
||||||
// If necessary, specify the number of the cargo customs declaration in the gtd parameter. If it is missing, pass the value `is_gtd_absent` = true
|
// If necessary, specify the number of the cargo customs declaration in the gtd parameter. If it is missing, pass the value `is_gtd_absent` = true
|
||||||
//
|
//
|
||||||
// If you have multiple identical products in a shipment, specify one `product_id` and `exemplars` array for each product in the shipment
|
// If you have multiple identical products in a shipment, specify one `product_id` and `exemplars` array for each product in the shipment
|
||||||
//
|
//
|
||||||
// Always pass a complete set of product items data
|
// # Always pass a complete set of product items data
|
||||||
//
|
//
|
||||||
// For example, you have 10 product items in your system.
|
// For example, you have 10 product items in your system.
|
||||||
// You have passed them for checking and saving. Then they added another 60 product items to your system.
|
// You have passed them for checking and saving. Then they added another 60 product items to your system.
|
||||||
|
|||||||
@@ -223,7 +223,51 @@ type ProductDetails struct {
|
|||||||
// Product price including discounts. This value is shown on the product description page
|
// Product price including discounts. This value is shown on the product description page
|
||||||
Price string `json:"price"`
|
Price string `json:"price"`
|
||||||
|
|
||||||
// Price index. Learn more in Help Center
|
// Product price indexes
|
||||||
|
PriceIndexes struct {
|
||||||
|
// Competitors' product price on other marketplaces
|
||||||
|
ExternalIndexData struct {
|
||||||
|
// Minimum competitors' product price on other marketplaces
|
||||||
|
MinimalPrice string `json:"minimal_price"`
|
||||||
|
|
||||||
|
// Price currency
|
||||||
|
MinimalPriceCurrency string `json:"minimal_price_currency"`
|
||||||
|
|
||||||
|
// Price index value
|
||||||
|
PriceIndexValue float64 `json:"price_index_value"`
|
||||||
|
} `json:"external_index_data"`
|
||||||
|
|
||||||
|
// Competitors' product price on Ozon
|
||||||
|
OzonIndexData struct {
|
||||||
|
// Minimum competitors' product price on Ozon
|
||||||
|
MinimalPrice string `json:"minimal_price"`
|
||||||
|
|
||||||
|
// Price currency
|
||||||
|
MinimalPriceCurrency string `json:"minimal_price_currency"`
|
||||||
|
|
||||||
|
// Price index value
|
||||||
|
PriceIndexValue float64 `json:"price_index_value"`
|
||||||
|
} `json:"ozon_index_data"`
|
||||||
|
|
||||||
|
// Resulting price index of the product
|
||||||
|
PriceIndex string `json:"price_index"`
|
||||||
|
|
||||||
|
// Price of your product on other marketplaces
|
||||||
|
SelfMarketplaceIndexData struct {
|
||||||
|
// Minimum price of your product on other marketplaces
|
||||||
|
MinimalPrice string `json:"minimal_price"`
|
||||||
|
|
||||||
|
// Price currency
|
||||||
|
MinimalPriceCurrency string `json:"minimal_price_currency"`
|
||||||
|
|
||||||
|
// Price index value
|
||||||
|
PriceIndexValue float64 `json:"price_index_value"`
|
||||||
|
} `json:"self_marketplace_index_data"`
|
||||||
|
} `json:"prices_indexes"`
|
||||||
|
|
||||||
|
// Deprecated: Price index. Learn more in Help Center
|
||||||
|
//
|
||||||
|
// Use PriceIndexes instead
|
||||||
PriceIndex string `json:"price_idnex"`
|
PriceIndex string `json:"price_idnex"`
|
||||||
|
|
||||||
// Product price suggested by the system based on similar offers
|
// Product price suggested by the system based on similar offers
|
||||||
@@ -1445,6 +1489,7 @@ type GetProductRangeLimitUploadQuota struct {
|
|||||||
// - Product range limit: how many products you can create in your personal account.
|
// - Product range limit: how many products you can create in your personal account.
|
||||||
// - Products creation limit: how many products you can create per day.
|
// - Products creation limit: how many products you can create per day.
|
||||||
// - Products update limit: how many products you can update per day.
|
// - Products update limit: how many products you can update per day.
|
||||||
|
//
|
||||||
// If you have a product range limit and you exceed it, you won't be able to create new products
|
// If you have a product range limit and you exceed it, you won't be able to create new products
|
||||||
func (c Products) GetProductRangeLimit() (*GetProductRangeLimitResponse, error) {
|
func (c Products) GetProductRangeLimit() (*GetProductRangeLimitResponse, error) {
|
||||||
url := "/v4/product/info/limit"
|
url := "/v4/product/info/limit"
|
||||||
@@ -1910,7 +1955,7 @@ type GetMarkdownInfoResponse struct {
|
|||||||
core.CommonResponse
|
core.CommonResponse
|
||||||
|
|
||||||
// Information about the markdown and the main product
|
// Information about the markdown and the main product
|
||||||
Items []struct{
|
Items []struct {
|
||||||
// Comment on the damage reason
|
// Comment on the damage reason
|
||||||
CommentReasonDamaged string `json:"comment_reason_damaged"`
|
CommentReasonDamaged string `json:"comment_reason_damaged"`
|
||||||
|
|
||||||
@@ -1975,7 +2020,7 @@ func (c Products) GetMarkdownInfo(params *GetMarkdownInfoParams) (*GetMarkdownIn
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SetDiscountOnMarkdownProductParams struct{
|
type SetDiscountOnMarkdownProductParams struct {
|
||||||
// Discount amount: from 3 to 99 percents
|
// Discount amount: from 3 to 99 percents
|
||||||
Discount int32 `json:"discount"`
|
Discount int32 `json:"discount"`
|
||||||
|
|
||||||
@@ -1983,7 +2028,7 @@ type SetDiscountOnMarkdownProductParams struct{
|
|||||||
ProductId int64 `json:"product_id"`
|
ProductId int64 `json:"product_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SetDiscountOnMarkdownProductResponse struct{
|
type SetDiscountOnMarkdownProductResponse struct {
|
||||||
core.CommonResponse
|
core.CommonResponse
|
||||||
|
|
||||||
// Method result. true if the query was executed without errors
|
// Method result. true if the query was executed without errors
|
||||||
@@ -2004,3 +2049,36 @@ func (c Products) SetDiscountOnMarkdownProduct(params *SetDiscountOnMarkdownProd
|
|||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NumberOfSubsToProductAvailabilityParams struct {
|
||||||
|
// List of SKUs, product identifiers in the Ozon system
|
||||||
|
SKUS []int64 `json:"skus"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NumberOfSubsToProductAvailabilityResponse struct {
|
||||||
|
core.CommonResponse
|
||||||
|
|
||||||
|
// Method result
|
||||||
|
Result []struct {
|
||||||
|
// Number of subscribed users
|
||||||
|
Count int64 `json:"count"`
|
||||||
|
|
||||||
|
// Product identifier in the Ozon system, SKU
|
||||||
|
SKU int64 `json:"sku"`
|
||||||
|
} `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can pass multiple products in a request
|
||||||
|
func (c Products) NumberOfSubsToProductAvailability(params *NumberOfSubsToProductAvailabilityParams) (*NumberOfSubsToProductAvailabilityResponse, error) {
|
||||||
|
url := "/v1/product/info/subscription"
|
||||||
|
|
||||||
|
resp := &NumberOfSubsToProductAvailabilityResponse{}
|
||||||
|
|
||||||
|
response, err := c.client.Request(http.MethodPost, url, params, resp, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
response.CopyCommonResponse(&resp.CommonResponse)
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -168,7 +168,24 @@ func TestGetProductDetails(t *testing.T) {
|
|||||||
"has_stock": false,
|
"has_stock": false,
|
||||||
"active_product": false
|
"active_product": false
|
||||||
},
|
},
|
||||||
"price_index": "0.00",
|
"price_indexes": {
|
||||||
|
"external_index_data": {
|
||||||
|
"minimal_price": "string",
|
||||||
|
"minimal_price_currency": "string",
|
||||||
|
"price_index_value": 0
|
||||||
|
},
|
||||||
|
"ozon_index_data": {
|
||||||
|
"minimal_price": "string",
|
||||||
|
"minimal_price_currency": "string",
|
||||||
|
"price_index_value": 0
|
||||||
|
},
|
||||||
|
"price_index": "WITHOUT_INDEX",
|
||||||
|
"self_marketplaces_index_data": {
|
||||||
|
"minimal_price": "string",
|
||||||
|
"minimal_price_currency": "string",
|
||||||
|
"price_index_value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
"commissions": [],
|
"commissions": [],
|
||||||
"volume_weight": 0.1,
|
"volume_weight": 0.1,
|
||||||
"is_prepayment": false,
|
"is_prepayment": false,
|
||||||
@@ -233,7 +250,7 @@ func TestGetProductDetails(t *testing.T) {
|
|||||||
"state_updated_at": "2021-10-21T15:48:03.927309Z"
|
"state_updated_at": "2021-10-21T15:48:03.927309Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
// Test No Client-Id or Api-Key
|
// Test No Client-Id or Api-Key
|
||||||
{
|
{
|
||||||
@@ -2407,3 +2424,66 @@ func TestSetDiscountOnMarkdownProduct(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNumberOfSubsToProductAvailability(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
statusCode int
|
||||||
|
headers map[string]string
|
||||||
|
params *NumberOfSubsToProductAvailabilityParams
|
||||||
|
response string
|
||||||
|
}{
|
||||||
|
// Test Ok
|
||||||
|
{
|
||||||
|
http.StatusOK,
|
||||||
|
map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"},
|
||||||
|
&NumberOfSubsToProductAvailabilityParams{
|
||||||
|
SKUS: []int64{1234},
|
||||||
|
},
|
||||||
|
`{
|
||||||
|
"result": [
|
||||||
|
{
|
||||||
|
"count": 2,
|
||||||
|
"sku": 1234
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
// Test No Client-Id or Api-Key
|
||||||
|
{
|
||||||
|
http.StatusUnauthorized,
|
||||||
|
map[string]string{},
|
||||||
|
&NumberOfSubsToProductAvailabilityParams{},
|
||||||
|
`{
|
||||||
|
"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))
|
||||||
|
|
||||||
|
resp, err := c.Products().NumberOfSubsToProductAvailability(test.params)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != test.statusCode {
|
||||||
|
t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusOK {
|
||||||
|
if len(resp.Result) != len(test.params.SKUS) {
|
||||||
|
t.Errorf("Length of SKUS in request and response are not equal")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.Result) > 0 {
|
||||||
|
if resp.Result[0].SKU != test.params.SKUS[0] {
|
||||||
|
t.Errorf("SKU in request and response are not equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user