diff --git a/ozon/common.go b/ozon/common.go index ace9bff..b3478ff 100644 --- a/ozon/common.go +++ b/ozon/common.go @@ -479,3 +479,16 @@ const ( GetFBOReturnsReturnStatusAcceptedFromCustomer GetFBOReturnsReturnStatus = "Принят от покупателя" GetFBOReturnsReturnStatusReceivedAtOzon GetFBOReturnsReturnStatus = "Получен в Ozon" ) + +type DigitalActType string + +const ( + // acceptance certificate + DigitalActTypeOfAcceptance DigitalActType = "act_of_acceptance" + + // discrepancy certificate + DigitalActTypeOfMismatch DigitalActType = "act_of_mismatch" + + // surplus certificate + DigitalActTypeOfExcess DigitalActType = "act_of_excess" +) diff --git a/ozon/fbs.go b/ozon/fbs.go index fb34e43..276b848 100644 --- a/ozon/fbs.go +++ b/ozon/fbs.go @@ -1594,7 +1594,13 @@ type PrintLabelingResponse struct { core.CommonResponse // Order content - Content string `json:"content"` + Content string `json:"file_content"` + + // File name + FileName string `json:"file_name"` + + // File type + ContentType string `json:"content_type"` } // Generates a PDF file with a labeling for the specified shipments. You can pass a maximum of 20 identifiers in one request. @@ -2139,7 +2145,7 @@ type GetDigitalActParams struct { // - act_of_acceptance — acceptance certificate, // - act_of_mismatch — discrepancy certificate, // - act_of_excess — surplus certificate - DocType string `json:"doc_type"` + DocType DigitalActType `json:"doc_type"` } type GetDigitalActResponse struct { @@ -2161,7 +2167,9 @@ func (c FBS) GetDigitalAct(params *GetDigitalActParams) (*GetDigitalActResponse, resp := &GetDigitalActResponse{} - response, err := c.client.Request(http.MethodPost, url, params, resp, nil) + response, err := c.client.Request(http.MethodPost, url, params, resp, map[string]string{ + "Content-Type": "application/json", + }) if err != nil { return nil, err } @@ -2194,7 +2202,9 @@ func (c FBS) PackageUnitLabel(params *PackageUnitLabelsParams) (*PackageUnitLabe resp := &PackageUnitLabelsResponse{} - response, err := c.client.Request(http.MethodPost, url, params, resp, nil) + response, err := c.client.Request(http.MethodPost, url, params, resp, map[string]string{ + "Content-Type": "application/json", + }) if err != nil { return nil, err } @@ -2655,13 +2665,13 @@ type BarcodeFromProductShipmentResponse struct { core.CommonResponse // Link to barcode image - Content string `json:"content"` + Content string `json:"file_content"` // File name - Name string `json:"name"` + Name string `json:"file_name"` // File type - Type string `json:"type"` + Type string `json:"content_type"` } // Method for getting a barcode to show at a pick-up point or sorting center during the shipment @@ -2670,7 +2680,9 @@ func (c FBS) BarcodeFromProductShipment(params *BarcodeFromProductShipmentParams resp := &BarcodeFromProductShipmentResponse{} - response, err := c.client.Request(http.MethodPost, url, params, resp, nil) + response, err := c.client.Request(http.MethodPost, url, params, resp, map[string]string{ + "Content-Type": "image/png", + }) if err != nil { return nil, err } @@ -2705,3 +2717,43 @@ func (c FBS) BarcodeValueFromProductShipment(params *BarcodeValueFromProductShip return resp, nil } + +type GetActPDFParams struct { + // Document generation task number (freight identifier) received from + // the POST `/v2/posting/fbs/act/create` method + Id int64 `json:"id"` +} + +type GetActPDFResponse struct { + core.CommonResponse + + // File content in binary format + FileContent string `json:"file_content"` + + // File name + FileName string `json:"file_name"` + + // File type + ContentType string `json:"content_type"` +} + +// Get the generated transfer documents in PDF format: an acceptance and transfer certificate and a waybill. +// +// If you are not connected to electronic document circulation (EDC), the method returns an acceptance and transfer certificate and a waybill. +// +// If you are connected to EDC, the method returns a waybill only. +func (c FBS) GetActPDF(params *GetActPDFParams) (*GetActPDFResponse, error) { + url := "/v2/posting/fbs/act/get-pdf" + + resp := &GetActPDFResponse{} + + response, err := c.client.Request(http.MethodPost, url, params, resp, map[string]string{ + "Content-Type": "application/pdf", + }) + if err != nil { + return nil, err + } + response.CopyCommonResponse(&resp.CommonResponse) + + return resp, nil +} diff --git a/ozon/fbs_test.go b/ozon/fbs_test.go index 7c1bdc6..7fa7b86 100644 --- a/ozon/fbs_test.go +++ b/ozon/fbs_test.go @@ -1186,7 +1186,9 @@ func TestPrintLabeling(t *testing.T) { PostingNumber: []string{"48173252-0034-4"}, }, `{ - "content": "https://cdn1.ozone.ru/s3/ozon-disk-api/c4a11c8b748033daf6cdd44aca7ed4c492e55d6f4810f13feae4792afa7934191647255705" + "content_type": "application/pdf", + "file_name": "ticket-170660-2023-07-13T13:17:06Z.pdf", + "file_content": "%PDF-1.7\n%âãÏÓ\n53 0 obj\n<>/Pages 9 0 R/StructTreeRoot 10 0 R/Type/Catalog>>\nendobj\n8 0 obj\n<>\nstream\nxœå[[ݶ\u0011~?¿BÏ\u0005Bs†\u001c^\u0000Àwí5ú\u0010 m\u0016Èsà¦)\n;hÒ\u0014èÏïG‰\u0014)‰<{äµ] ]?¬¬oIÎ}†¤F±‰óϤñï\u001bÕü×X­´OÏï?^~¹$<ø¨È9q\u0013Y\u0012åñì§_¼|ÿ‡égü\t+\u0012\u001bxžª}Æxšҿ¿¼›–‡_º¼xg¦Ÿþ5Oku˜œÌ3ýíògüûå\"Ni\u0016C\u0001°\u000fA9g‰'r¢\"\u0013YóĪ\u0018NÑ{\u001d–ÕóZ¬\\Ô\"" }`, }, // Test No Client-Id or Api-Key @@ -1212,6 +1214,12 @@ func TestPrintLabeling(t *testing.T) { 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 resp.Content == "" { + t.Error("content cannot be empty") + } + } } } @@ -1888,9 +1896,9 @@ func TestGetDigitalAct(t *testing.T) { DocType: "act_of_acceptance", }, `{ - "content": "string", - "name": "string", - "type": "string" + "content_type": "application/pdf", + "file_name": "20816409_act_of_mismatch.pdf", + "file_content": "%PDF-1.4\n%ÓôÌá\n1 0 obj\n<<\n/Creator(Chromium)\n/Producer(PDFsharp 1.50.5147 \\([www.pdfsharp.com|http://www.pdfsharp.com/]\\) \\(Original: Skia/PDF m103\\))\n/CreationDate(D:20230625092529+00'00')\n/ModDate(D:20230625092529+00'00')\n>>\nendobj\n2 0 obj\n<<\n/Type/Page\n/Resources\n<<\n/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]\n/ExtGState\n<<\n/G3 3 0 R\n/G8 8 0 R\n>>\n/XObject\n<<\n/X6 6 0 R\n/X7 7 0 R\n>>\n/Font\n<<\n/F4 4 0 R\n/F5 5 0 R\n>>\n>>\n/MediaBox[0 0 594.96 841.92]\n/Contents 9 0 R\n/StructParents 0\n/Parent 13 0 R\n/Group\n<<\n/CS/DeviceRGB\n/S/Transparency\n>>\n>>\nendobj\n3 0 obj\n<<\n/ca 1\n/BM/Normal\n>>\nendobj\n4 0 obj\n<<\n/Type/Font\n/Subtype/Type0\n/BaseFont/AAAAAA+LiberationSans\n/Encoding/Identity-H\n/DescendantFonts[160 0 R]\n/ToUnicode 161 0 R\n>>\nendobj\n5 0 obj\n<<\n/Type/Font\n/Subtype/Type0\n/BaseFont/BAAAAA+LiberationSans-Bold\n/Encoding/Identity-H\n/DescendantFonts[164 0" }`, }, // Test No Client-Id or Api-Key @@ -2544,9 +2552,9 @@ func TestBarcodeFromProductShipment(t *testing.T) { Id: 295662811, }, `{ - "content": "https://cdn.ozone.ru/s3/ozon-disk-api/techdoc/seller-api/barcode_1684849346.png", - "name": "barcode-test", - "type": "PNG" + "content_type": "image/png", + "file_name": "20913984_barcode.png", + "file_content": "‰PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0003\u0010\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000íZ\u000e'\u0000\u0000\u0002pIDATxœìÕÁJ\u00031\u0014@Q+þÿ/×E\u0017\u000e¼›\u0010u¡-ç¬$£Éˌp?î÷·§t» }ýü¸ÃcåzŸ¹2w˜OWû\\Ϛ뫧×Ùö;œì|rÇýßîç¼úî{˜§¬N?™í7oì•v¸®Ÿµ¹Ãù„û•¹¾ÿÏ9ÿî?›až¸ºéê7O&߿É9çÉ\u000eÏáý¯\u0007\u0000à\u0012\b\u0000’@\u0000\u0004\u0002€$\u0010\u0000$\u0000 \t\u0004\u0000I \u0000H\u0002\u0001@\u0012\b\u0000’@\u0000\u0004\u0002€$\u0010\u0000$\u0000 \t\u0004\u0000I \u0000H\u0002\u0001@\u0012\b\u0000’@\u0000\u0004\u0002€$\u0010\u0000$\u0000 \t\u0004\u0000I \u0000H\u0002\u0001@\u0012\b\u0000’@\u0000\u0004\u0002€$\u0010\u0000$\u0000 \t\u0004\u0000I \u0000H\u0002\u0001@\u0012\b\u0000’@\u0000\u0004\u0002€$\u0010\u0000" }`, }, // Test No Client-Id or Api-Key @@ -2638,3 +2646,57 @@ func TestBarcodeValueFromProductShipment(t *testing.T) { } } } + +func TestGetActPDF(t *testing.T) { + t.Parallel() + + tests := []struct { + statusCode int + headers map[string]string + params *GetActPDFParams + response string + }{ + // Test Ok + { + http.StatusOK, + map[string]string{"Client-Id": "my-client-id", "Api-Key": "my-api-key"}, + &GetActPDFParams{ + Id: 22435521842000, + }, + `{ + "content_type": "application/pdf", + "file_name": "20928233.pdf", + "file_content": "binarystring" + }`, + }, + // Test No Client-Id or Api-Key + { + http.StatusUnauthorized, + map[string]string{}, + &GetActPDFParams{}, + `{ + "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.FBS().GetActPDF(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 resp.FileContent == "" { + t.Errorf("result cannot be empty") + } + } + } +}