From f59174519f42303eb733ab8b0a6fa979446838c8 Mon Sep 17 00:00:00 2001 From: diPhantxm Date: Fri, 17 Mar 2023 21:57:28 +0300 Subject: [PATCH] add methods for generating returns and shipment reports --- ENDPOINTS.md | 8 +-- ozon/reports.go | 165 +++++++++++++++++++++++++++++++++++++++++++ ozon/reports_test.go | 151 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 320 insertions(+), 4 deletions(-) diff --git a/ENDPOINTS.md b/ENDPOINTS.md index 4995d2b..fa36dac 100644 --- a/ENDPOINTS.md +++ b/ENDPOINTS.md @@ -155,10 +155,10 @@ - [x] Report details - [x] Reports list - [x] Products report -- [ ] Stocks report -- [ ] Report on products movement -- [ ] Returns report -- [ ] Shipment report +- [x] Stocks report +- [x] Report on products movement +- [x] Returns report +- [x] Shipment report - [x] Financial report - [ ] Issue a report on discounted products - [ ] Report on discounted products diff --git a/ozon/reports.go b/ozon/reports.go index 2a0a753..b3dcdc3 100644 --- a/ozon/reports.go +++ b/ozon/reports.go @@ -304,3 +304,168 @@ func (c Reports) GetStocks(params *GetStocksReportParams) (*GetStocksReportRespo return resp, nil } + +type GetProductsMovementReportParams struct { + // Date from which the data will be in the report + DateFrom time.Time `json:"date_from"` + + // Date up to which the data will be in the report + DateTo time.Time `json:"date_to"` + + // Default: "DEFAULT" + // Response language: + // - RU — Russian + // - EN — English + Language string `json:"language" default:"DEFAULT"` +} + +type GetProductsMovementReportResponse struct { + core.CommonResponse + + // Method result + Result struct { + // Unique report identifier + Code string `json:"code"` + } `json:"result"` +} + +// Report with complete information on products, as well as the number of products with statuses: +// - products with defects or in inventory, +// - products in transit between the fulfillment centers, +// - products in delivery, +// - products to be sold +func (c Reports) GetProductsMovement(params *GetProductsMovementReportParams) (*GetProductsMovementReportResponse, error) { + url := "/v1/report/products/movement/create" + + resp := &GetProductsMovementReportResponse{} + + response, err := c.client.Request(http.MethodPost, url, params, resp) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} + +type GetReturnsReportParams struct { + // Filter + Filter GetReturnsReportsFilter `json:"filter"` + + // Default: "DEFAULT" + // Response language: + // - RU — Russian + // - EN — English + Language string `json:"language" default:"DEFAULT"` +} + +type GetReturnsReportsFilter struct { + // Order delivery scheme: fbs — delivery from seller's warehouse + DeliverySchema string `json:"delivery_schema"` + + // Order identifier + OrderId int64 `json:"order_id"` + + // Order status + Status string `json:"status"` +} + +type GetReturnsReportResponse struct { + core.CommonResponse + + // Method result + Result struct { + // Unique report identifier + Code string `json:"code"` + } `json:"result"` +} + +// The report contains information about returned products that were accepted from the customer, ready for pickup, or delivered to the seller. +// +// The method is only suitable for orders shipped from the seller's warehouse +func (c Reports) GetReturns(params *GetReturnsReportParams) (*GetReturnsReportResponse, error) { + url := "/v1/report/returns/create" + + resp := &GetReturnsReportResponse{} + + response, err := c.client.Request(http.MethodPost, url, params, resp) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} + +type GetShipmentReportParams struct { + // Filter + Filter GetShipmentReportFilter `json:"filter"` + + // Default: "DEFAULT" + // Response language: + // - RU — Russian + // - EN — English + Language string `json:"language"` +} + +type GetShipmentReportFilter struct { + // Cancellation reason identifier + CancelReasonId []int64 `json:"cancel_reason_id"` + + // Work scheme: FBO or FBS. + // + // To get an FBO scheme report, pass fbo in this parameter. For an FBS scheme report pass fbs + DeliverySchema []string `json:"delivery_schema"` + + // Product identifier + OfferId string `json:"offer_id"` + + // Order processing start date and time + ProcessedAtFrom time.Time `json:"processed_at_from"` + + // Time when the order appeared in your personal account + ProcessedAtTo time.Time `json:"processed_at_to"` + + // Product identifier in the Ozon system, SKU + SKU []int64 `json:"sku"` + + // Status text + StatusAlias []string `json:"status_alias"` + + // Numerical status + Statuses []int64 `json:"statused"` + + // Product name + Title string `json:"title"` +} + +type GetShipmentReportResponse struct { + core.CommonResponse + + // Method result + Result struct { + // Unique report identifier + Code string `json:"code"` + } `json:"result"` +} + +// Shipment report with orders details: +// - order statuses +// - processing start date +// - order numbers +// - shipment numbers +// - shipment costs +// - shipments contents +func (c Reports) GetShipment(params *GetShipmentReportParams) (*GetShipmentReportResponse, error) { + url := "/v1/report/postings/create" + + resp := &GetShipmentReportResponse{} + + response, err := c.client.Request(http.MethodPost, url, params, resp) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} diff --git a/ozon/reports_test.go b/ozon/reports_test.go index 46b34b9..a2100ea 100644 --- a/ozon/reports_test.go +++ b/ozon/reports_test.go @@ -291,3 +291,154 @@ func TestGetStocksReport(t *testing.T) { } } } + +func TestGetProductsMovementReport(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + params *GetProductsMovementReportParams + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + &GetProductsMovementReportParams{ + DateFrom: core.TimeFromString(t, "2006-01-02T15:04:05Z", "2020-08-01T14:15:22Z"), + DateTo: core.TimeFromString(t, "2006-01-02T15:04:05Z", "2020-08-01T14:15:22Z"), + }, + `{ + "result": { + "code": "h56f4917-1346-4e64-9d90-с6e736c1e07c" + } + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + &GetProductsMovementReportParams{}, + `{ + "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.Reports().GetProductsMovement(test.params) + if err != nil { + t.Error(err) + } + + if resp.StatusCode != test.statusCode { + t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode) + } + } +} + +func TestGetReturnsReport(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + params *GetReturnsReportParams + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + &GetReturnsReportParams{ + Filter: GetReturnsReportsFilter{ + DeliverySchema: "fbs", + }, + }, + `{ + "result": { + "code": "d55f4517-8347-4e24-9d93-d6e736c1c07c" + } + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + &GetReturnsReportParams{}, + `{ + "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.Reports().GetReturns(test.params) + if err != nil { + t.Error(err) + } + + if resp.StatusCode != test.statusCode { + t.Errorf("got wrong status code: got: %d, expected: %d", resp.StatusCode, test.statusCode) + } + } +} + +func TestGetShipmentReport(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + params *GetShipmentReportParams + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + &GetShipmentReportParams{ + Filter: GetShipmentReportFilter{ + DeliverySchema: []string{"fbs", "fbo", "crossborder"}, + ProcessedAtFrom: core.TimeFromString(t, "2006-01-02T15:04:05Z", "2021-09-02T17:10:54.861Z"), + ProcessedAtTo: core.TimeFromString(t, "2006-01-02T15:04:05Z", "2021-11-02T17:10:54.861Z"), + }, + }, + `{ + "result": { + "code": "d55f4517-8347-4e24-9d93-d6e736c1c07c" + } + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + &GetShipmentReportParams{}, + `{ + "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.Reports().GetShipment(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) + } + } +}