diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c36b28..aaa8081 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,7 @@ jobs: version: v1.45.2 only-new-issues: true skip-pkg-cache: true + args: --build-tags=testutils tests: name: Tests runs-on: ubuntu-latest @@ -58,13 +59,13 @@ jobs: env: COVERAGE: ${{ matrix.coverage }} if: env.COVERAGE != 1 - run: go test ./... + run: go test -tags=testutils ./... - name: Tests with coverage env: COVERAGE: ${{ matrix.coverage }} if: env.COVERAGE == 1 run: | - go test ./... -race -coverprofile=coverage.txt -covermode=atomic "$d" + go test -tags=testutils ./... -race -coverprofile=coverage.txt -covermode=atomic "$d" - name: Coverage env: COVERAGE: ${{ matrix.coverage }} diff --git a/.golangci.yml b/.golangci.yml index f1e7ff7..16dd100 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,6 +1,8 @@ run: skip-dirs-use-default: true allow-parallel-runners: true + skip-files: + - testutils.go output: format: colored-line-number diff --git a/client.go b/client.go index cc60476..6583b82 100644 --- a/client.go +++ b/client.go @@ -17,6 +17,10 @@ import ( "github.com/google/go-querystring/query" ) +// HTTPStatusUnknown can return for the method `/api/v5/customers/upload`, `/api/v5/customers-corporate/upload`, +// `/api/v5/orders/upload`. +const HTTPStatusUnknown = 460 + // New initialize client. func New(url string, key string) *Client { return &Client{ @@ -209,21 +213,21 @@ func fillSite(p *url.Values, site []string) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.APIVersions() +// data, status, err := client.APIVersions() // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.versions { -// log.Printf("%v\n", value) -// } +// for _, value := range data.versions { +// log.Printf("%v\n", value) +// } func (c *Client) APIVersions() (VersionResponse, int, error) { var resp VersionResponse @@ -246,21 +250,21 @@ func (c *Client) APIVersions() (VersionResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.APICredentials() +// data, status, err := client.APICredentials() // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.Scopes { -// log.Printf("%v\n", value) -// } +// for _, value := range data.Scopes { +// log.Printf("%v\n", value) +// } func (c *Client) APICredentials() (CredentialResponse, int, error) { var resp CredentialResponse @@ -283,19 +287,19 @@ func (c *Client) APICredentials() (CredentialResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.APISystemInfo() +// data, status, err := client.APISystemInfo() // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// log.Printf("%v\n", data) +// log.Printf("%v\n", data) func (c *Client) APISystemInfo() (SystemInfoResponse, int, error) { var resp SystemInfoResponse @@ -318,26 +322,26 @@ func (c *Client) APISystemInfo() (SystemInfoResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Customers(retailcrm.CustomersRequest{ +// data, status, err := client.Customers(retailcrm.CustomersRequest{ // Filter: CustomersFilter{ // City: "Moscow", // }, // Page: 3, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.Customers { -// log.Printf("%v\n", value) -// } +// for _, value := range data.Customers { +// log.Printf("%v\n", value) +// } func (c *Client) Customers(parameters CustomersRequest) (CustomersResponse, int, error) { var resp CustomersResponse @@ -362,17 +366,17 @@ func (c *Client) Customers(parameters CustomersRequest) (CustomersResponse, int, // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CustomersCombine([]retailcrm.Customer{{ID: 1}, {ID: 2}}, Customer{ID: 3}) +// data, status, err := client.CustomersCombine([]retailcrm.Customer{{ID: 1}, {ID: 2}}, Customer{ID: 3}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CustomersCombine(customers []Customer, resultCustomer Customer) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -403,9 +407,9 @@ func (c *Client) CustomersCombine(customers []Customer, resultCustomer Customer) // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CustomersCombine(retailcrm.Customer{ +// data, status, err := client.CustomersCombine(retailcrm.Customer{ // FirstName: "Ivan", // LastName: "Ivanov", // Patronymic: "Ivanovich", @@ -417,13 +421,13 @@ func (c *Client) CustomersCombine(customers []Customer, resultCustomer Customer) // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { // fmt.Printf("%v", data.ID) @@ -458,20 +462,20 @@ func (c *Client) CustomerCreate(customer Customer, site ...string) (CustomerChan // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CustomersFixExternalIds([]retailcrm.IdentifiersPair{{ +// data, status, err := client.CustomersFixExternalIds([]retailcrm.IdentifiersPair{{ // ID: 1, // ExternalID: 12, // }}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CustomersFixExternalIds(customers []IdentifiersPair) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -500,25 +504,25 @@ func (c *Client) CustomersFixExternalIds(customers []IdentifiersPair) (Successfu // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CustomersHistory(retailcrm.CustomersHistoryRequest{ +// data, status, err := client.CustomersHistory(retailcrm.CustomersHistoryRequest{ // Filter: retailcrm.CustomersHistoryFilter{ // SinceID: 20, // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.History { -// log.Printf("%v\n", value) -// } +// for _, value := range data.History { +// log.Printf("%v\n", value) +// } func (c *Client) CustomersHistory(parameters CustomersHistoryRequest) (CustomersHistoryResponse, int, error) { var resp CustomersHistoryResponse @@ -543,26 +547,26 @@ func (c *Client) CustomersHistory(parameters CustomersHistoryRequest) (Customers // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CustomerNotes(retailcrm.NotesRequest{ +// data, status, err := client.CustomerNotes(retailcrm.NotesRequest{ // Filter: retailcrm.NotesFilter{ // CustomerIds: []int{1,2,3} -// }, +// }, // Page: 1, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.Notes { -// log.Printf("%v\n", value) -// } +// for _, value := range data.Notes { +// log.Printf("%v\n", value) +// } func (c *Client) CustomerNotes(parameters NotesRequest) (NotesResponse, int, error) { var resp NotesResponse @@ -587,9 +591,9 @@ func (c *Client) CustomerNotes(parameters NotesRequest) (NotesResponse, int, err // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CustomerNoteCreate(retailcrm.Note{ +// data, status, err := client.CustomerNoteCreate(retailcrm.Note{ // Text: "some text", // ManagerID: 12, // Customer: &retailcrm.Customer{ @@ -597,17 +601,17 @@ func (c *Client) CustomerNotes(parameters NotesRequest) (NotesResponse, int, err // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.ID) -// } +// if data.Success == true { +// log.Printf("%v\n", data.ID) +// } func (c *Client) CustomerNoteCreate(note Note, site ...string) (CreateResponse, int, error) { var resp CreateResponse @@ -638,16 +642,16 @@ func (c *Client) CustomerNoteCreate(note Note, site ...string) (CreateResponse, // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CustomerNoteDelete(12) -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// data, status, err := client.CustomerNoteDelete(12) +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CustomerNoteDelete(id int) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -670,13 +674,15 @@ func (c *Client) CustomerNoteDelete(id int) (SuccessfulResponse, int, error) { // CustomersUpload customers batch upload // +// # This method can return response together with error if http status is equal 460 +// // For more information see http://www.simla.com/docs/Developers/API/APIVersions/APIv5#post--api-v5-customers-upload // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CustomersUpload([]retailcrm.Customer{ +// data, status, err := client.CustomersUpload([]retailcrm.Customer{ // { // FirstName: "Ivan", // LastName: "Ivanov", @@ -693,17 +699,17 @@ func (c *Client) CustomerNoteDelete(id int) (SuccessfulResponse, int, error) { // }, // }} // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.UploadedCustomers) -// } +// if data.Success == true { +// log.Printf("%v\n", data.UploadedCustomers) +// } func (c *Client) CustomersUpload(customers []Customer, site ...string) (CustomersUploadResponse, int, error) { var resp CustomersUploadResponse @@ -716,12 +722,16 @@ func (c *Client) CustomersUpload(customers []Customer, site ...string) (Customer fillSite(&p, site) data, status, err := c.PostRequest("/customers/upload", p) - if err != nil { + if err != nil && status != HTTPStatusUnknown { return resp, status, err } - err = json.Unmarshal(data, &resp) - if err != nil { + errJSON := json.Unmarshal(data, &resp) + if errJSON != nil { + return resp, status, errJSON + } + + if status == HTTPStatusUnknown { return resp, status, err } @@ -734,21 +744,21 @@ func (c *Client) CustomersUpload(customers []Customer, site ...string) (Customer // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Customer(12, retailcrm.ByExternalID, "") +// data, status, err := client.Customer(12, retailcrm.ByExternalID, "") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.Customer) -// } +// if data.Success == true { +// log.Printf("%v\n", data.Customer) +// } func (c *Client) Customer(id, by, site string) (CustomerResponse, int, error) { var resp CustomerResponse var context = checkBy(by) @@ -788,17 +798,17 @@ func (c *Client) Customer(id, by, site string) (CustomerResponse, int, error) { // retailcrm.ByID, // ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.Customer) -// } +// if data.Success == true { +// log.Printf("%v\n", data.Customer) +// } func (c *Client) CustomerEdit(customer Customer, by string, site ...string) (CustomerChangeResponse, int, error) { var resp CustomerChangeResponse var uid = strconv.Itoa(customer.ID) @@ -836,26 +846,26 @@ func (c *Client) CustomerEdit(customer Customer, by string, site ...string) (Cus // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomers(retailcrm.CorporateCustomersRequest{ +// data, status, err := client.CorporateCustomers(retailcrm.CorporateCustomersRequest{ // Filter: CorporateCustomersFilter{ // City: "Moscow", // }, // Page: 3, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.CustomersCorporate { -// log.Printf("%v\n", value) -// } +// for _, value := range data.CustomersCorporate { +// log.Printf("%v\n", value) +// } func (c *Client) CorporateCustomers(parameters CorporateCustomersRequest) (CorporateCustomersResponse, int, error) { var resp CorporateCustomersResponse @@ -880,19 +890,19 @@ func (c *Client) CorporateCustomers(parameters CorporateCustomersRequest) (Corpo // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomerCreate(retailcrm.CorporateCustomer{ +// data, status, err := client.CorporateCustomerCreate(retailcrm.CorporateCustomer{ // Nickname: "Company", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { // fmt.Printf("%v", data.ID) @@ -929,20 +939,20 @@ func (c *Client) CorporateCustomerCreate(customer CorporateCustomer, site ...str // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomersFixExternalIds([]retailcrm.IdentifiersPair{{ +// data, status, err := client.CorporateCustomersFixExternalIds([]retailcrm.IdentifiersPair{{ // ID: 1, // ExternalID: 12, // }}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CorporateCustomersFixExternalIds(customers []IdentifiersPair) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -971,25 +981,25 @@ func (c *Client) CorporateCustomersFixExternalIds(customers []IdentifiersPair) ( // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomersHistory(retailcrm.CorporateCustomersHistoryRequest{ +// data, status, err := client.CorporateCustomersHistory(retailcrm.CorporateCustomersHistoryRequest{ // Filter: retailcrm.CorporateCustomersHistoryFilter{ // SinceID: 20, // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.History { -// log.Printf("%v\n", value) -// } +// for _, value := range data.History { +// log.Printf("%v\n", value) +// } func (c *Client) CorporateCustomersHistory(parameters CorporateCustomersHistoryRequest) ( CorporateCustomersHistoryResponse, int, error, ) { @@ -1016,26 +1026,26 @@ func (c *Client) CorporateCustomersHistory(parameters CorporateCustomersHistoryR // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomersNotes(retailcrm.CorporateCustomersNotesRequest{ +// data, status, err := client.CorporateCustomersNotes(retailcrm.CorporateCustomersNotesRequest{ // Filter: CorporateCustomersNotesFilter{ // Text: "text", // }, // Page: 3, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.Notes { -// log.Printf("%v\n", value) -// } +// for _, value := range data.Notes { +// log.Printf("%v\n", value) +// } func (c *Client) CorporateCustomersNotes(parameters CorporateCustomersNotesRequest) ( CorporateCustomersNotesResponse, int, error, ) { @@ -1062,26 +1072,26 @@ func (c *Client) CorporateCustomersNotes(parameters CorporateCustomersNotesReque // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomerNoteCreate(retailcrm.CorporateCustomerNote{ -// Text: "text", -// Customer: &retailcrm.IdentifiersPair{ -// ID: 1, +// data, status, err := client.CorporateCustomerNoteCreate(retailcrm.CorporateCustomerNote{ +// Text: "text", +// Customer: &retailcrm.IdentifiersPair{ +// ID: 1, +// } +// }) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) // } -// }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } -// -// log.Fatalf("http status: %d, error: %s", status, err) -// } -// -// if data.Success == true { -// fmt.Printf("%v", data.ID) -// } +// if data.Success == true { +// fmt.Printf("%v", data.ID) +// } func (c *Client) CorporateCustomerNoteCreate(note CorporateCustomerNote, site ...string) (CreateResponse, int, error) { var resp CreateResponse @@ -1112,17 +1122,17 @@ func (c *Client) CorporateCustomerNoteCreate(note CorporateCustomerNote, site .. // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomerNoteDelete(12) +// data, status, err := client.CorporateCustomerNoteDelete(12) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CorporateCustomerNoteDelete(id int) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -1145,13 +1155,15 @@ func (c *Client) CorporateCustomerNoteDelete(id int) (SuccessfulResponse, int, e // CorporateCustomersUpload corporate customers batch upload // +// # This method can return response together with error if http status is equal 460 +// // For more information see http://help.retailcrm.pro/Developers/ApiVersion5#post--api-v5-customers-corporate-upload // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomersUpload([]retailcrm.CorporateCustomer{ +// data, status, err := client.CorporateCustomersUpload([]retailcrm.CorporateCustomer{ // { // Nickname: "Company", // ExternalID: 1, @@ -1162,17 +1174,17 @@ func (c *Client) CorporateCustomerNoteDelete(id int) (SuccessfulResponse, int, e // }, // }} // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.UploadedCustomers) -// } +// if data.Success == true { +// log.Printf("%v\n", data.UploadedCustomers) +// } func (c *Client) CorporateCustomersUpload( customers []CorporateCustomer, site ...string, ) (CorporateCustomersUploadResponse, int, error) { @@ -1187,12 +1199,16 @@ func (c *Client) CorporateCustomersUpload( fillSite(&p, site) data, status, err := c.PostRequest("/customers-corporate/upload", p) - if err != nil { + if err != nil && status != HTTPStatusUnknown { return resp, status, err } - err = json.Unmarshal(data, &resp) - if err != nil { + errJSON := json.Unmarshal(data, &resp) + if errJSON != nil { + return resp, status, err + } + + if status == HTTPStatusUnknown { return resp, status, err } @@ -1205,21 +1221,21 @@ func (c *Client) CorporateCustomersUpload( // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomer(12, retailcrm.ByExternalID, "") +// data, status, err := client.CorporateCustomer(12, retailcrm.ByExternalID, "") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.CorporateCustomer) -// } +// if data.Success == true { +// log.Printf("%v\n", data.CorporateCustomer) +// } func (c *Client) CorporateCustomer(id, by, site string) (CorporateCustomerResponse, int, error) { var resp CorporateCustomerResponse var context = checkBy(by) @@ -1246,29 +1262,29 @@ func (c *Client) CorporateCustomer(id, by, site string) (CorporateCustomerRespon // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomerAddresses("ext-id", retailcrm.CorporateCustomerAddressesRequest{ -// Filter: v5,CorporateCustomerAddressesFilter{ -// Name: "Main Address", -// }, -// By: retailcrm.ByExternalID, -// Site: "site", -// Limit: 20, -// Page: 1, -// }) +// data, status, err := client.CorporateCustomerAddresses("ext-id", retailcrm.CorporateCustomerAddressesRequest{ +// Filter: v5,CorporateCustomerAddressesFilter{ +// Name: "Main Address", +// }, +// By: retailcrm.ByExternalID, +// Site: "site", +// Limit: 20, +// Page: 1, +// }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.Addresses) -// } +// if data.Success == true { +// log.Printf("%v\n", data.Addresses) +// } func (c *Client) CorporateCustomerAddresses( id string, parameters CorporateCustomerAddressesRequest, ) (CorporateCustomersAddressesResponse, int, error) { @@ -1296,20 +1312,20 @@ func (c *Client) CorporateCustomerAddresses( // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := c.CorporateCustomerAddressesCreate("ext-id", retailcrm.ByExternalID, retailcrm.CorporateCustomerAddress{ -// Text: "this is new address", -// Name: "New Address", -// }) +// data, status, err := c.CorporateCustomerAddressesCreate("ext-id", retailcrm.ByExternalID, retailcrm.CorporateCustomerAddress{ +// Text: "this is new address", +// Name: "New Address", +// }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { // fmt.Printf("%v", data.ID) @@ -1349,27 +1365,27 @@ func (c *Client) CorporateCustomerAddressesCreate( // // var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := c.CorporateCustomerAddressesEdit( -// "customer-ext-id", -// retailcrm.ByExternalID, -// retailcrm.ByExternalID, -// CorporateCustomerAddress{ -// ExternalID: "addr-ext-id", -// Name: "Main Address 2", -// }, -// ) +// data, status, err := c.CorporateCustomerAddressesEdit( +// "customer-ext-id", +// retailcrm.ByExternalID, +// retailcrm.ByExternalID, +// CorporateCustomerAddress{ +// ExternalID: "addr-ext-id", +// Name: "Main Address 2", +// }, +// ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.Customer) -// } +// if data.Success == true { +// log.Printf("%v\n", data.Customer) +// } func (c *Client) CorporateCustomerAddressesEdit( customerID, customerBy, entityBy string, address CorporateCustomerAddress, site ...string, ) (CreateResponse, int, error) { @@ -1417,29 +1433,29 @@ func (c *Client) CorporateCustomerAddressesEdit( // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomerCompanies("ext-id", retailcrm.IdentifiersPairRequest{ -// Filter: v5,IdentifiersPairFilter{ -// Ids: []string{"1"}, -// }, -// By: retailcrm.ByExternalID, -// Site: "site", -// Limit: 20, -// Page: 1, -// }) +// data, status, err := client.CorporateCustomerCompanies("ext-id", retailcrm.IdentifiersPairRequest{ +// Filter: v5,IdentifiersPairFilter{ +// Ids: []string{"1"}, +// }, +// By: retailcrm.ByExternalID, +// Site: "site", +// Limit: 20, +// Page: 1, +// }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.Companies) -// } +// if data.Success == true { +// log.Printf("%v\n", data.Companies) +// } func (c *Client) CorporateCustomerCompanies( id string, parameters IdentifiersPairRequest, ) (CorporateCustomerCompaniesResponse, int, error) { @@ -1467,19 +1483,19 @@ func (c *Client) CorporateCustomerCompanies( // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := c.CorporateCustomerCompaniesCreate("ext-id", retailcrm.ByExternalID, retailcrm.Company{ -// Name: "Company name", -// }) +// data, status, err := c.CorporateCustomerCompaniesCreate("ext-id", retailcrm.ByExternalID, retailcrm.Company{ +// Name: "Company name", +// }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { // fmt.Printf("%v", data.ID) @@ -1519,27 +1535,27 @@ func (c *Client) CorporateCustomerCompaniesCreate( // // var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := c.CorporateCustomerCompaniesEdit( -// "customer-ext-id", -// retailcrm.ByExternalID, -// retailcrm.ByExternalID, -// Company{ -// ExternalID: "company-ext-id", -// Name: "New Company Name", -// }, -// ) +// data, status, err := c.CorporateCustomerCompaniesEdit( +// "customer-ext-id", +// retailcrm.ByExternalID, +// retailcrm.ByExternalID, +// Company{ +// ExternalID: "company-ext-id", +// Name: "New Company Name", +// }, +// ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.ID) -// } +// if data.Success == true { +// log.Printf("%v\n", data.ID) +// } func (c *Client) CorporateCustomerCompaniesEdit( customerID, customerBy, entityBy string, company Company, site ...string, ) (CreateResponse, int, error) { @@ -1587,29 +1603,29 @@ func (c *Client) CorporateCustomerCompaniesEdit( // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CorporateCustomerContacts("ext-id", retailcrm.IdentifiersPairRequest{ -// Filter: retailcrm.IdentifiersPairFilter{ -// Ids: []string{"1"}, -// }, -// By: retailcrm.ByExternalID, -// Site: "site", -// Limit: 20, -// Page: 1, -// }) +// data, status, err := client.CorporateCustomerContacts("ext-id", retailcrm.IdentifiersPairRequest{ +// Filter: retailcrm.IdentifiersPairFilter{ +// Ids: []string{"1"}, +// }, +// By: retailcrm.ByExternalID, +// Site: "site", +// Limit: 20, +// Page: 1, +// }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.Contacts) -// } +// if data.Success == true { +// log.Printf("%v\n", data.Contacts) +// } func (c *Client) CorporateCustomerContacts( id string, parameters IdentifiersPairRequest, ) (CorporateCustomerContactsResponse, int, error) { @@ -1637,24 +1653,24 @@ func (c *Client) CorporateCustomerContacts( // // Example (customer with specified id or externalId should exist in specified site): // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := c.CorporateCustomerContactsCreate("ext-id", retailcrm.ByExternalID, retailcrm.CorporateCustomerContact{ -// IsMain: false, -// Customer: retailcrm.CorporateCustomerContactCustomer{ -// ExternalID: "external_id", -// Site: "site", -// }, -// Companies: []IdentifiersPair{}, -// }, "site") +// data, status, err := c.CorporateCustomerContactsCreate("ext-id", retailcrm.ByExternalID, retailcrm.CorporateCustomerContact{ +// IsMain: false, +// Customer: retailcrm.CorporateCustomerContactCustomer{ +// ExternalID: "external_id", +// Site: "site", +// }, +// Companies: []IdentifiersPair{}, +// }, "site") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { // fmt.Printf("%v", data.ID) @@ -1694,24 +1710,24 @@ func (c *Client) CorporateCustomerContactsCreate( // // var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := c.CorporateCustomerContactsEdit("ext-id", retailcrm.ByExternalID, retailcrm.ByID, retailcrm.CorporateCustomerContact{ -// IsMain: false, -// Customer: retailcrm.CorporateCustomerContactCustomer{ -// ID: 2350, -// }, -// }, "site") +// data, status, err := c.CorporateCustomerContactsEdit("ext-id", retailcrm.ByExternalID, retailcrm.ByID, retailcrm.CorporateCustomerContact{ +// IsMain: false, +// Customer: retailcrm.CorporateCustomerContactCustomer{ +// ID: 2350, +// }, +// }, "site") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.ID) -// } +// if data.Success == true { +// log.Printf("%v\n", data.ID) +// } func (c *Client) CorporateCustomerContactsEdit( customerID, customerBy, entityBy string, contact CorporateCustomerContact, site ...string, ) (CreateResponse, int, error) { @@ -1772,17 +1788,17 @@ func (c *Client) CorporateCustomerContactsEdit( // retailcrm.ByID, // ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.Customer) -// } +// if data.Success == true { +// log.Printf("%v\n", data.Customer) +// } func (c *Client) CorporateCustomerEdit(customer CorporateCustomer, by string, site ...string) ( CustomerChangeResponse, int, error, ) { @@ -1822,31 +1838,30 @@ func (c *Client) CorporateCustomerEdit(customer CorporateCustomer, by string, si // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") -// t, _ := time.Parse("2006-01-02 15:04:05", "2012-12-12 12:12:12") +// var client = retailcrm.New("https://demo.url", "09jIJ") +// t, _ := time.Parse("2006-01-02 15:04:05", "2012-12-12 12:12:12") // -// data, status, err := client.DeliveryTracking( -// []retailcrm.DeliveryTrackingRequest{{ -// DeliveryID: "1", -// TrackNumber: "123", -// History: []retailcrm.DeliveryHistoryRecord{ -// { -// Code: "cancel", -// UpdatedAt: t.Format(time.RFC3339), +// data, status, err := client.DeliveryTracking( +// []retailcrm.DeliveryTrackingRequest{{ +// DeliveryID: "1", +// TrackNumber: "123", +// History: []retailcrm.DeliveryHistoryRecord{ +// { +// Code: "cancel", +// UpdatedAt: t.Format(time.RFC3339), +// }, // }, -// }, -// }}, -// "delivery-1", -// ) +// }}, +// "delivery-1", +// ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } -// -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) DeliveryTracking(parameters []DeliveryTrackingRequest, subcode string) ( SuccessfulResponse, int, error, ) { @@ -1877,26 +1892,26 @@ func (c *Client) DeliveryTracking(parameters []DeliveryTrackingRequest, subcode // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.DeliveryShipments(retailcrm.DeliveryShipmentsRequest{ +// data, status, err := client.DeliveryShipments(retailcrm.DeliveryShipmentsRequest{ // Limit: 12, // Filter: retailcrm.ShipmentFilter{ // DateFrom: "2012-12-12", // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.DeliveryShipments { -// log.Printf("%v\n", value) -// } +// for _, value := range data.DeliveryShipments { +// log.Printf("%v\n", value) +// } func (c *Client) DeliveryShipments(parameters DeliveryShipmentsRequest) (DeliveryShipmentsResponse, int, error) { var resp DeliveryShipmentsResponse @@ -1921,7 +1936,7 @@ func (c *Client) DeliveryShipments(parameters DeliveryShipmentsRequest) (Deliver // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.DeliveryShipmentCreate( // retailcrm.DeliveryShipment{ @@ -1935,17 +1950,17 @@ func (c *Client) DeliveryShipments(parameters DeliveryShipmentsRequest) (Deliver // "sdek", // ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.ID) -// } +// if data.Success == true { +// log.Printf("%v\n", data.ID) +// } func (c *Client) DeliveryShipmentCreate( shipment DeliveryShipment, deliveryType string, site ...string, ) (DeliveryShipmentUpdateResponse, int, error) { @@ -1978,21 +1993,21 @@ func (c *Client) DeliveryShipmentCreate( // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.DeliveryShipment(12) +// data, status, err := client.DeliveryShipment(12) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.DeliveryShipment) -// } +// if data.Success == true { +// log.Printf("%v\n", data.DeliveryShipment) +// } func (c *Client) DeliveryShipment(id int) (DeliveryShipmentResponse, int, error) { var resp DeliveryShipmentResponse @@ -2015,23 +2030,23 @@ func (c *Client) DeliveryShipment(id int) (DeliveryShipmentResponse, int, error) // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.DeliveryShipmentEdit(retailcrm.DeliveryShipment{ +// data, status, err := client.DeliveryShipmentEdit(retailcrm.DeliveryShipment{ // ID: "12", // Time: retailcrm.DeliveryTime{ // From: "14:00", // To: "18:00", // }, -// }) +// }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) DeliveryShipmentEdit(shipment DeliveryShipment, site ...string) ( DeliveryShipmentUpdateResponse, int, error, ) { @@ -2063,21 +2078,21 @@ func (c *Client) DeliveryShipmentEdit(shipment DeliveryShipment, site ...string) // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.IntegrationModule("moysklad3") +// data, status, err := client.IntegrationModule("moysklad3") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.IntegrationModule) -// } +// if data.Success == true { +// log.Printf("%v\n", data.IntegrationModule) +// } func (c *Client) IntegrationModule(code string) (IntegrationModuleResponse, int, error) { var resp IntegrationModuleResponse @@ -2198,21 +2213,21 @@ func (c *Client) UpdateScopes(code string, request ScopesRequired) (UpdateScopes // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Orders(retailcrm.OrdersRequest{Filter: retailcrm.OrdersFilter{City: "Moscow"}, Page: 1}) +// data, status, err := client.Orders(retailcrm.OrdersRequest{Filter: retailcrm.OrdersFilter{City: "Moscow"}, Page: 1}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.Orders { -// log.Printf("%v\n", value) -// } +// for _, value := range data.Orders { +// log.Printf("%v\n", value) +// } func (c *Client) Orders(parameters OrdersRequest) (OrdersResponse, int, error) { var resp OrdersResponse @@ -2237,17 +2252,17 @@ func (c *Client) Orders(parameters OrdersRequest) (OrdersResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrdersCombine("ours", retailcrm.Order{ID: 1}, retailcrm.Order{ID: 1}) +// data, status, err := client.OrdersCombine("ours", retailcrm.Order{ID: 1}, retailcrm.Order{ID: 1}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) OrdersCombine(technique string, order, resultOrder Order) (OperationResponse, int, error) { var resp OperationResponse @@ -2279,9 +2294,9 @@ func (c *Client) OrdersCombine(technique string, order, resultOrder Order) (Oper // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrderCreate(retailcrm.Order{ +// data, status, err := client.OrderCreate(retailcrm.Order{ // FirstName: "Ivan", // LastName: "Ivanov", // Patronymic: "Ivanovich", @@ -2289,17 +2304,17 @@ func (c *Client) OrdersCombine(technique string, order, resultOrder Order) (Oper // Items: []retailcrm.OrderItem{{Offer: retailcrm.Offer{ID: 12}, Quantity: 5}}, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v\n", data.ID) -// } +// if data.Success == true { +// log.Printf("%v\n", data.ID) +// } func (c *Client) OrderCreate(order Order, site ...string) (OrderCreateResponse, int, error) { var resp OrderCreateResponse orderJSON, _ := json.Marshal(&order) @@ -2375,21 +2390,21 @@ func (c *Client) OrdersFixExternalIds(orders []IdentifiersPair) (SuccessfulRespo // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrdersHistory(retailcrm.OrdersHistoryRequest{Filter: retailcrm.OrdersHistoryFilter{SinceID: 20}}) +// data, status, err := client.OrdersHistory(retailcrm.OrdersHistoryRequest{Filter: retailcrm.OrdersHistoryFilter{SinceID: 20}}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.History { -// log.Printf("%v\n", value) -// } +// for _, value := range data.History { +// log.Printf("%v\n", value) +// } func (c *Client) OrdersHistory(parameters OrdersHistoryRequest) (OrdersHistoryResponse, int, error) { var resp OrdersHistoryResponse @@ -2414,9 +2429,9 @@ func (c *Client) OrdersHistory(parameters OrdersHistoryRequest) (OrdersHistoryRe // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrderPaymentCreate(retailcrm.Payment{ +// data, status, err := client.OrderPaymentCreate(retailcrm.Payment{ // Order: &retailcrm.Order{ // ID: 12, // }, @@ -2424,17 +2439,17 @@ func (c *Client) OrdersHistory(parameters OrdersHistoryRequest) (OrdersHistoryRe // Type: "cash", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.ID) -// } +// log.Printf("%v\n", data.ID) +// } func (c *Client) OrderPaymentCreate(payment Payment, site ...string) (CreateResponse, int, error) { var resp CreateResponse @@ -2465,17 +2480,17 @@ func (c *Client) OrderPaymentCreate(payment Payment, site ...string) (CreateResp // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrderPaymentDelete(12) +// data, status, err := client.OrderPaymentDelete(12) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) OrderPaymentDelete(id int) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -2502,23 +2517,23 @@ func (c *Client) OrderPaymentDelete(id int) (SuccessfulResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrderPaymentEdit( -// retailcrm.Payment{ +// data, status, err := client.OrderPaymentEdit( +// retailcrm.Payment{ // ID: 12, // Amount: 500, // }, // retailcrm.ByID, // ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) OrderPaymentEdit(payment Payment, by string, site ...string) (SuccessfulResponse, int, error) { var resp SuccessfulResponse var uid = strconv.Itoa(payment.ID) @@ -2556,20 +2571,20 @@ func (c *Client) OrderPaymentEdit(payment Payment, by string, site ...string) (S // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrdersStatuses(retailcrm.OrdersStatusesRequest{ +// data, status, err := client.OrdersStatuses(retailcrm.OrdersStatusesRequest{ // IDs: []int{1}, // ExternalIDs: []string{"2"}, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) OrdersStatuses(request OrdersStatusesRequest) (OrdersStatusesResponse, int, error) { var resp OrdersStatusesResponse @@ -2590,13 +2605,15 @@ func (c *Client) OrdersStatuses(request OrdersStatusesRequest) (OrdersStatusesRe // OrdersUpload batch orders uploading // +// # This method can return response together with error if http status is equal 460 +// // For more information see http://www.simla.com/docs/Developers/API/APIVersions/APIv5#post--api-v5-orders-upload // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrdersUpload([]retailcrm.Order{ +// data, status, err := client.OrdersUpload([]retailcrm.Order{ // { // FirstName: "Ivan", // LastName: "Ivanov", @@ -2613,17 +2630,17 @@ func (c *Client) OrdersStatuses(request OrdersStatusesRequest) (OrdersStatusesRe // } // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.UploadedOrders) -// } +// log.Printf("%v\n", data.UploadedOrders) +// } func (c *Client) OrdersUpload(orders []Order, site ...string) (OrdersUploadResponse, int, error) { var resp OrdersUploadResponse @@ -2636,12 +2653,16 @@ func (c *Client) OrdersUpload(orders []Order, site ...string) (OrdersUploadRespo fillSite(&p, site) data, status, err := c.PostRequest("/orders/upload", p) - if err != nil { + if err != nil && status != HTTPStatusUnknown { return resp, status, err } - err = json.Unmarshal(data, &resp) - if err != nil { + errJSON := json.Unmarshal(data, &resp) + if errJSON != nil { + return resp, status, err + } + + if status == HTTPStatusUnknown { return resp, status, err } @@ -2654,21 +2675,21 @@ func (c *Client) OrdersUpload(orders []Order, site ...string) (OrdersUploadRespo // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Order(12, retailcrm.ByExternalID, "") +// data, status, err := client.Order(12, retailcrm.ByExternalID, "") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.Order) -// } +// log.Printf("%v\n", data.Order) +// } func (c *Client) Order(id, by, site string) (OrderResponse, int, error) { var resp OrderResponse var context = checkBy(by) @@ -2695,23 +2716,23 @@ func (c *Client) Order(id, by, site string) (OrderResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrderEdit( -// retailcrm.Order{ +// data, status, err := client.OrderEdit( +// retailcrm.Order{ // ID: 12, // Items: []retailcrm.OrderItem{{Offer: retailcrm.Offer{ID: 13}, Quantity: 6}}, // }, -// retailcrm.ByID, -// ) +// retailcrm.ByID, +// ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) OrderEdit(order Order, by string, site ...string) (CreateResponse, int, error) { var resp CreateResponse var uid = strconv.Itoa(order.ID) @@ -2749,21 +2770,21 @@ func (c *Client) OrderEdit(order Order, by string, site ...string) (CreateRespon // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Packs(retailcrm.PacksRequest{Filter: retailcrm.PacksFilter{OrderID: 12}}) +// data, status, err := client.Packs(retailcrm.PacksRequest{Filter: retailcrm.PacksFilter{OrderID: 12}}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.Packs { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) Packs(parameters PacksRequest) (PacksResponse, int, error) { var resp PacksResponse @@ -2788,25 +2809,25 @@ func (c *Client) Packs(parameters PacksRequest) (PacksResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.PackCreate(Pack{ +// data, status, err := client.PackCreate(Pack{ // Store: "store-1", // ItemID: 12, // Quantity: 1, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.ID) -// } +// log.Printf("%v\n", data.ID) +// } func (c *Client) PackCreate(pack Pack) (CreateResponse, int, error) { var resp CreateResponse packJSON, _ := json.Marshal(&pack) @@ -2834,21 +2855,21 @@ func (c *Client) PackCreate(pack Pack) (CreateResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.PacksHistory(retailcrm.PacksHistoryRequest{Filter: retailcrm.OrdersHistoryFilter{SinceID: 5}}) +// data, status, err := client.PacksHistory(retailcrm.PacksHistoryRequest{Filter: retailcrm.OrdersHistoryFilter{SinceID: 5}}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.History { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) PacksHistory(parameters PacksHistoryRequest) (PacksHistoryResponse, int, error) { var resp PacksHistoryResponse @@ -2873,21 +2894,21 @@ func (c *Client) PacksHistory(parameters PacksHistoryRequest) (PacksHistoryRespo // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Pack(112) +// data, status, err := client.Pack(112) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.Pack) -// } +// log.Printf("%v\n", data.Pack) +// } func (c *Client) Pack(id int) (PackResponse, int, error) { var resp PackResponse @@ -2910,17 +2931,17 @@ func (c *Client) Pack(id int) (PackResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.PackDelete(112) +// data, status, err := client.PackDelete(112) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) PackDelete(id int) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -2943,17 +2964,17 @@ func (c *Client) PackDelete(id int) (SuccessfulResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.PackEdit(Pack{ID: 12, Quantity: 2}) +// data, status, err := client.PackEdit(Pack{ID: 12, Quantity: 2}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) PackEdit(pack Pack) (CreateResponse, int, error) { var resp CreateResponse @@ -3020,20 +3041,20 @@ func (c *Client) CostGroups() (CostGroupsResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CostGroupEdit(retailcrm.CostGroup{ +// data, status, err := client.CostGroupEdit(retailcrm.CostGroup{ // Code: "group-1", // Color: "#da5c98", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CostGroupEdit(costGroup CostGroup) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -3081,20 +3102,20 @@ func (c *Client) CostItems() (CostItemsResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CostItemEdit(retailcrm.CostItem{ +// data, status, err := client.CostItemEdit(retailcrm.CostItem{ // Code: "seo", // Active: false, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CostItemEdit(costItem CostItem) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -3142,26 +3163,26 @@ func (c *Client) Couriers() (CouriersResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CostItemEdit(retailcrm.Courier{ +// data, status, err := client.CostItemEdit(retailcrm.Courier{ // Active: true, // Email: "courier1@example.com", // FirstName: "Ivan", // LastName: "Ivanov", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// if data.Success == true { -// log.Printf("%v", data.ID) -// } +// if data.Success == true { +// log.Printf("%v", data.ID) +// } func (c *Client) CourierCreate(courier Courier) (CreateResponse, int, error) { var resp CreateResponse @@ -3190,20 +3211,20 @@ func (c *Client) CourierCreate(courier Courier) (CreateResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.CostItemEdit(retailcrm.Courier{ +// data, status, err := client.CostItemEdit(retailcrm.Courier{ // ID: 1, // Patronymic: "Ivanovich", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CourierEdit(courier Courier) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -3251,20 +3272,20 @@ func (c *Client) DeliveryServices() (DeliveryServiceResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.DeliveryServiceEdit(retailcrm.DeliveryService{ +// data, status, err := client.DeliveryServiceEdit(retailcrm.DeliveryService{ // Active: false, // Code: "delivery-1", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) DeliveryServiceEdit(deliveryService DeliveryService) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -3312,22 +3333,22 @@ func (c *Client) DeliveryTypes() (DeliveryTypesResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.DeliveryTypeEdit(retailcrm.DeliveryType{ +// data, status, err := client.DeliveryTypeEdit(retailcrm.DeliveryType{ // Active: false, // Code: "type-1", // DefaultCost: 300, // DefaultForCrm: false, // } // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) DeliveryTypeEdit(deliveryType DeliveryType) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -3375,20 +3396,20 @@ func (c *Client) LegalEntities() (LegalEntitiesResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.LegalEntityEdit(retailcrm.LegalEntity{ +// data, status, err := client.LegalEntityEdit(retailcrm.LegalEntity{ // Code: "legal-entity-1", // CertificateDate: "2012-12-12", // } // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) LegalEntityEdit(legalEntity LegalEntity) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -3436,21 +3457,21 @@ func (c *Client) OrderMethods() (OrderMethodsResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrderMethodEdit(retailcrm.OrderMethod{ +// data, status, err := client.OrderMethodEdit(retailcrm.OrderMethod{ // Code: "method-1", // Active: false, // DefaultForCRM: false, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) OrderMethodEdit(orderMethod OrderMethod) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -3498,21 +3519,21 @@ func (c *Client) OrderTypes() (OrderTypesResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.OrderTypeEdit(retailcrm.OrderType{ +// data, status, err := client.OrderTypeEdit(retailcrm.OrderType{ // Code: "order-type-1", // Active: false, // DefaultForCRM: false, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) OrderTypeEdit(orderType OrderType) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -3990,21 +4011,21 @@ func (c *Client) Settings() (SettingsResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Inventories(retailcrm.InventoriesRequest{Filter: retailcrm.InventoriesFilter{Details: 1, ProductActive: 1}, Page: 1}) +// data, status, err := client.Inventories(retailcrm.InventoriesRequest{Filter: retailcrm.InventoriesFilter{Details: 1, ProductActive: 1}, Page: 1}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.Offers { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) Inventories(parameters InventoriesRequest) (InventoriesResponse, int, error) { var resp InventoriesResponse @@ -4143,25 +4164,25 @@ func (c *Client) PricesUpload(prices []OfferPriceUpload) (StoreUploadResponse, i // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.ProductsGroup(retailcrm.ProductsGroupsRequest{ +// data, status, err := client.ProductsGroup(retailcrm.ProductsGroupsRequest{ // Filter: retailcrm.ProductsGroupsFilter{ // Active: 1, // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.ProductGroup { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) ProductsGroup(parameters ProductsGroupsRequest) (ProductsGroupsResponse, int, error) { var resp ProductsGroupsResponse @@ -4186,26 +4207,26 @@ func (c *Client) ProductsGroup(parameters ProductsGroupsRequest) (ProductsGroups // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Products(retailcrm.ProductsRequest{ +// data, status, err := client.Products(retailcrm.ProductsRequest{ // Filter: retailcrm.ProductsFilter{ // Active: 1, // MinPrice: 1000, // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.Products { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) Products(parameters ProductsRequest) (ProductsResponse, int, error) { var resp ProductsResponse @@ -4230,25 +4251,25 @@ func (c *Client) Products(parameters ProductsRequest) (ProductsResponse, int, er // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.ProductsProperties(retailcrm.ProductsPropertiesRequest{ +// data, status, err := client.ProductsProperties(retailcrm.ProductsPropertiesRequest{ // Filter: retailcrm.ProductsPropertiesFilter{ // Sites: []string["store"], // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.Properties { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) ProductsProperties(parameters ProductsPropertiesRequest) (ProductsPropertiesResponse, int, error) { var resp ProductsPropertiesResponse @@ -4273,25 +4294,25 @@ func (c *Client) ProductsProperties(parameters ProductsPropertiesRequest) (Produ // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Tasks(retailcrm.TasksRequest{ +// data, status, err := client.Tasks(retailcrm.TasksRequest{ // Filter: TasksFilter{ // DateFrom: "2012-12-12", // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.Tasks { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) Tasks(parameters TasksRequest) (TasksResponse, int, error) { var resp TasksResponse @@ -4316,24 +4337,24 @@ func (c *Client) Tasks(parameters TasksRequest) (TasksResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Tasks(retailcrm.Task{ +// data, status, err := client.Tasks(retailcrm.Task{ // Text: "task №1", // PerformerID: 12, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.ID) -// } +// log.Printf("%v\n", data.ID) +// } func (c *Client) TaskCreate(task Task, site ...string) (CreateResponse, int, error) { var resp CreateResponse taskJSON, _ := json.Marshal(&task) @@ -4363,21 +4384,21 @@ func (c *Client) TaskCreate(task Task, site ...string) (CreateResponse, int, err // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Task(12) +// data, status, err := client.Task(12) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.Task) -// } +// log.Printf("%v\n", data.Task) +// } func (c *Client) Task(id int) (TaskResponse, int, error) { var resp TaskResponse @@ -4400,20 +4421,20 @@ func (c *Client) Task(id int) (TaskResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Task(retailcrm.Task{ +// data, status, err := client.Task(retailcrm.Task{ // ID: 12 // Text: "task №2", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) TaskEdit(task Task, site ...string) (SuccessfulResponse, int, error) { var resp SuccessfulResponse var uid = strconv.Itoa(task.ID) @@ -4450,21 +4471,21 @@ func (c *Client) TaskEdit(task Task, site ...string) (SuccessfulResponse, int, e // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.UserGroups(retailcrm.UserGroupsRequest{Page: 1}) +// data, status, err := client.UserGroups(retailcrm.UserGroupsRequest{Page: 1}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.Groups { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) UserGroups(parameters UserGroupsRequest) (UserGroupsResponse, int, error) { var resp UserGroupsResponse @@ -4489,21 +4510,21 @@ func (c *Client) UserGroups(parameters UserGroupsRequest) (UserGroupsResponse, i // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.Users(retailcrm.UsersRequest{Filter: retailcrm.UsersFilter{Active: 1}, Page: 1}) +// data, status, err := client.Users(retailcrm.UsersRequest{Filter: retailcrm.UsersFilter{Active: 1}, Page: 1}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // for _, value := range data.Users { -// log.Printf("%v\n", value) -// } +// log.Printf("%v\n", value) +// } func (c *Client) Users(parameters UsersRequest) (UsersResponse, int, error) { var resp UsersResponse @@ -4528,21 +4549,21 @@ func (c *Client) Users(parameters UsersRequest) (UsersResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.User(12) +// data, status, err := client.User(12) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.User) -// } +// log.Printf("%v\n", data.User) +// } func (c *Client) User(id int) (UserResponse, int, error) { var resp UserResponse @@ -4565,17 +4586,17 @@ func (c *Client) User(id int) (UserResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.UserStatus(12, "busy") +// data, status, err := client.UserStatus(12, "busy") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) UserStatus(id int, status string) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -4625,7 +4646,7 @@ func (c *Client) StaticticsUpdate() (SuccessfulResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.Costs(CostsRequest{ // Filter: CostsFilter{ @@ -4634,17 +4655,17 @@ func (c *Client) StaticticsUpdate() (SuccessfulResponse, int, error) { // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.Costs { -// log.Printf("%v\n", value.Summ) -// } +// for _, value := range data.Costs { +// log.Printf("%v\n", value.Summ) +// } func (c *Client) Costs(costs CostsRequest) (CostsResponse, int, error) { var resp CostsResponse @@ -4670,33 +4691,33 @@ func (c *Client) Costs(costs CostsRequest) (CostsResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CostCreate( -// retailcrm.CostRecord{ +// retailcrm.CostRecord{ // DateFrom: "2012-12-12", // DateTo: "2012-12-12", // Summ: 12, // CostItem: "calculation-of-costs", // Order: Order{ -// Number: "1" -// }, -// Sites: []string{"store"}, +// Number: "1" +// }, +// Sites: []string{"store"}, // }, // "store" -// ) +// ) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("%v", data.ID) -// } +// If data.Success == true { +// log.Printf("%v", data.ID) +// } func (c *Client) CostCreate(cost CostRecord, site ...string) (CreateResponse, int, error) { var resp CreateResponse @@ -4727,21 +4748,21 @@ func (c *Client) CostCreate(cost CostRecord, site ...string) (CreateResponse, in // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.client.CostsDelete([]int{1, 2, 3, 48, 49, 50}) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("Not removed costs: %v", data.NotRemovedIds) -// } +// If data.Success == true { +// log.Printf("Not removed costs: %v", data.NotRemovedIds) +// } func (c *Client) CostsDelete(ids []int) (CostsDeleteResponse, int, error) { var resp CostsDeleteResponse @@ -4770,7 +4791,7 @@ func (c *Client) CostsDelete(ids []int) (CostsDeleteResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CostCreate([]retailcrm.CostRecord{ // { @@ -4779,9 +4800,9 @@ func (c *Client) CostsDelete(ids []int) (CostsDeleteResponse, int, error) { // Summ: 12, // CostItem: "calculation-of-costs", // Order: Order{ -// Number: "1" -// }, -// Sites: []string{"store"}, +// Number: "1" +// }, +// Sites: []string{"store"}, // }, // { // DateFrom: "2012-12-13", @@ -4789,19 +4810,19 @@ func (c *Client) CostsDelete(ids []int) (CostsDeleteResponse, int, error) { // Summ: 13, // CostItem: "seo", // } -// }) +// }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("Uploaded costs: %v", data.UploadedCosts) -// } +// If data.Success == true { +// log.Printf("Uploaded costs: %v", data.UploadedCosts) +// } func (c *Client) CostsUpload(cost []CostRecord) (CostsUploadResponse, int, error) { var resp CostsUploadResponse @@ -4830,21 +4851,21 @@ func (c *Client) CostsUpload(cost []CostRecord) (CostsUploadResponse, int, error // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.Cost(1) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("%v", data.Cost) -// } +// If data.Success == true { +// log.Printf("%v", data.Cost) +// } func (c *Client) Cost(id int) (CostResponse, int, error) { var resp CostResponse @@ -4868,17 +4889,17 @@ func (c *Client) Cost(id int) (CostResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CostDelete(1) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) CostDelete(id int) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -4908,7 +4929,7 @@ func (c *Client) CostDelete(id int) (SuccessfulResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CostEdit(1, retailcrm.Cost{ // DateFrom: "2012-12-12", @@ -4917,17 +4938,17 @@ func (c *Client) CostDelete(id int) (SuccessfulResponse, int, error) { // CostItem: "seo", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("%v", data.ID) -// } +// If data.Success == true { +// log.Printf("%v", data.ID) +// } func (c *Client) CostEdit(id int, cost CostRecord, site ...string) (CreateResponse, int, error) { var resp CreateResponse @@ -4958,7 +4979,7 @@ func (c *Client) CostEdit(id int, cost CostRecord, site ...string) (CreateRespon // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.Files(FilesRequest{ // Filter: FilesFilter{ @@ -4966,13 +4987,13 @@ func (c *Client) CostEdit(id int, cost CostRecord, site ...string) (CreateRespon // }, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } func (c *Client) Files(files FilesRequest) (FilesResponse, int, error) { var resp FilesResponse @@ -4998,22 +5019,22 @@ func (c *Client) Files(files FilesRequest) (FilesResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// file, err := os.Open("file.jpg") -// if err != nil { -// fmt.Print(err) -// } +// file, err := os.Open("file.jpg") +// if err != nil { +// fmt.Print(err) +// } // -// data, status, err := client.FileUpload(file) +// data, status, err := client.FileUpload(file) // -// if err.Error() != "" { -// fmt.Printf("%v", err.Error()) -// } +// if err.Error() != "" { +// fmt.Printf("%v", err.Error()) +// } // -// if status >= http.StatusBadRequest { -// fmt.Printf("%v", err.Error()) -// } +// if status >= http.StatusBadRequest { +// fmt.Printf("%v", err.Error()) +// } func (c *Client) FileUpload(reader io.Reader) (FileUploadResponse, int, error) { var resp FileUploadResponse @@ -5037,21 +5058,21 @@ func (c *Client) FileUpload(reader io.Reader) (FileUploadResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.File(112) +// data, status, err := client.File(112) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // // if data.Success == true { -// log.Printf("%v\n", data.File) -// } +// log.Printf("%v\n", data.File) +// } func (c *Client) File(id int) (FileResponse, int, error) { var resp FileResponse @@ -5074,17 +5095,17 @@ func (c *Client) File(id int) (FileResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.FileDelete(123) +// data, status, err := client.FileDelete(123) // -// if err.Error() != "" { -// fmt.Printf("%v", err.Error()) -// } +// if err.Error() != "" { +// fmt.Printf("%v", err.Error()) +// } // -// if status >= http.StatusBadRequest { -// fmt.Printf("%v", err.Error()) -// } +// if status >= http.StatusBadRequest { +// fmt.Printf("%v", err.Error()) +// } func (c *Client) FileDelete(id int) (SuccessfulResponse, int, error) { var resp SuccessfulResponse @@ -5108,17 +5129,17 @@ func (c *Client) FileDelete(id int) (SuccessfulResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// fileData, status, err := client.FileDownload(123) +// fileData, status, err := client.FileDownload(123) // -// if err.Error() != "" { -// fmt.Printf("%v", err.Error()) -// } +// if err.Error() != "" { +// fmt.Printf("%v", err.Error()) +// } // -// if status >= http.StatusBadRequest { -// fmt.Printf("%v", err.Error()) -// } +// if status >= http.StatusBadRequest { +// fmt.Printf("%v", err.Error()) +// } func (c *Client) FileDownload(id int) (io.ReadCloser, int, error) { data, status, err := c.GetRequest(fmt.Sprintf("/files/%d/download", id)) if status != http.StatusOK { @@ -5135,17 +5156,17 @@ func (c *Client) FileDownload(id int) (io.ReadCloser, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.FileEdit(123, File{Filename: "image2.jpg"}) +// data, status, err := client.FileEdit(123, File{Filename: "image2.jpg"}) // -// if err.Error() != "" { -// fmt.Printf("%v", err.Error()) -// } +// if err.Error() != "" { +// fmt.Printf("%v", err.Error()) +// } // -// if status >= http.StatusBadRequest { -// fmt.Printf("%v", err.Error()) -// } +// if status >= http.StatusBadRequest { +// fmt.Printf("%v", err.Error()) +// } func (c *Client) FileEdit(id int, file File) (FileResponse, int, error) { var resp FileResponse @@ -5174,22 +5195,22 @@ func (c *Client) FileEdit(id int, file File) (FileResponse, int, error) { // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CustomFields(retailcrm.CustomFieldsRequest{ // Type: "string", -// Entity: "customer", +// Entity: "customer", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.CustomFields { +// for _, value := range data.CustomFields { // fmt.Printf("%v\n", value) // } func (c *Client) CustomFields(customFields CustomFieldsRequest) (CustomFieldsResponse, int, error) { @@ -5320,21 +5341,21 @@ func (c *Client) CustomDictionariesCreate(customDictionary CustomDictionary) (Cu // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CustomDictionary("courier-profiles") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("%v", data.CustomDictionary.Name) -// } +// If data.Success == true { +// log.Printf("%v", data.CustomDictionary.Name) +// } func (c *Client) CustomDictionary(code string) (CustomDictionaryResponse, int, error) { var resp CustomDictionaryResponse @@ -5414,7 +5435,7 @@ func (c *Client) CustomDictionaryEdit(customDictionary CustomDictionary) (Custom // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CustomFieldsCreate(CustomFields{ // Name: "First order", @@ -5424,17 +5445,17 @@ func (c *Client) CustomDictionaryEdit(customDictionary CustomDictionary) (Custom // DisplayArea: "customer", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("%v", data.Code) -// } +// If data.Success == true { +// log.Printf("%v", data.Code) +// } func (c *Client) CustomFieldsCreate(customFields CustomFields) (CustomResponse, int, error) { var resp CustomResponse @@ -5464,21 +5485,21 @@ func (c *Client) CustomFieldsCreate(customFields CustomFields) (CustomResponse, // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CustomField("order", "first-order") // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("%v", data.CustomField) -// } +// If data.Success == true { +// log.Printf("%v", data.CustomField) +// } func (c *Client) CustomField(entity, code string) (CustomFieldResponse, int, error) { var resp CustomFieldResponse @@ -5502,7 +5523,7 @@ func (c *Client) CustomField(entity, code string) (CustomFieldResponse, int, err // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // // data, status, err := client.CustomFieldEdit(CustomFields{ // Code: "first-order", @@ -5510,17 +5531,17 @@ func (c *Client) CustomField(entity, code string) (CustomFieldResponse, int, err // DisplayArea: "delivery", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// If data.Success == true { -// log.Printf("%v", data.Code) -// } +// If data.Success == true { +// log.Printf("%v", data.Code) +// } func (c *Client) CustomFieldEdit(customFields CustomFields) (CustomResponse, int, error) { var resp CustomResponse @@ -5552,9 +5573,9 @@ func (c *Client) CustomFieldEdit(customFields CustomFields) (CustomResponse, int // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.BonusOperations(retailcrm.BonusOperationsRequest{ +// data, status, err := client.BonusOperations(retailcrm.BonusOperationsRequest{ // Filter: BonusOperationsFilter{ // LoyaltyId: []int{123, 456}, // }, @@ -5562,17 +5583,17 @@ func (c *Client) CustomFieldEdit(customFields CustomFields) (CustomResponse, int // Cursor: "123456", // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.BonusOperations { -// log.Printf("%v\n", value) -// } +// for _, value := range data.BonusOperations { +// log.Printf("%v\n", value) +// } func (c *Client) BonusOperations(parameters BonusOperationsRequest) (BonusOperationsResponse, int, error) { var resp BonusOperationsResponse @@ -5597,9 +5618,9 @@ func (c *Client) BonusOperations(parameters BonusOperationsRequest) (BonusOperat // // Example: // -// var client = retailcrm.New("https://demo.url", "09jIJ") +// var client = retailcrm.New("https://demo.url", "09jIJ") // -// data, status, err := client.AccountBonusOperations(retailcrm.AccountBonusOperationsRequest{ +// data, status, err := client.AccountBonusOperations(retailcrm.AccountBonusOperationsRequest{ // Filter: AccountBonusOperationsFilter{ // CreatedAtFrom: "2012-12-12", // CreatedAtTo: "2012-12-13", @@ -5608,17 +5629,17 @@ func (c *Client) BonusOperations(parameters BonusOperationsRequest) (BonusOperat // Page: 3, // }) // -// if err != nil { -// if apiErr, ok := retailcrm.AsAPIError(err); ok { -// log.Fatalf("http status: %d, %s", status, apiErr.String()) -// } +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } // -// log.Fatalf("http status: %d, error: %s", status, err) -// } +// log.Fatalf("http status: %d, error: %s", status, err) +// } // -// for _, value := range data.BonusOperations { -// log.Printf("%v\n", value) -// } +// for _, value := range data.BonusOperations { +// log.Printf("%v\n", value) +// } func (c *Client) AccountBonusOperations(id int, parameters AccountBonusOperationsRequest) (BonusOperationsResponse, int, error) { var resp BonusOperationsResponse @@ -5643,3 +5664,832 @@ func (c *Client) AccountBonusOperations(id int, parameters AccountBonusOperation return resp, status, nil } + +// ProductsBatchEdit perform editing products batch +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-store-products-batch-edit +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// products := []ProductEdit{{ +// CatalogID: 3, +// BaseProduct: BaseProduct{ +// Name: "Product 1", +// URL: "https://example.com/p/1", +// Article: "p1", +// ExternalID: "ext1", +// }, +// ID: 194, +// Site: "second", +// Groups: []ProductEditGroupInput{{ID: 19}}, +// }} +// +// data, status, err := client.ProductsBatchEdit(products) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", data.ProcessedProductsCount) +// } +func (c *Client) ProductsBatchEdit(products []ProductEdit) (ProductsBatchEditResponse, int, error) { + var resp ProductsBatchEditResponse + + productsEditJSON, _ := json.Marshal(products) + p := url.Values{ + "products": {string(productsEditJSON)}, + } + + data, status, err := c.PostRequest("/store/products/batch/edit", p) + + if err != nil { + return resp, status, err + } + + err = json.Unmarshal(data, &resp) + if err != nil { + return resp, status, err + } + + return resp, status, nil +} + +// ProductsBatchCreate perform adding products batch +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-store-products-batch-create +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// products := []ProductCreate{{ +// CatalogID: 3, +// BaseProduct: BaseProduct{ +// Name: "Product 1", +// URL: "https://example.com/p/1", +// Article: "p1", +// ExternalID: "ext1", +// }, +// Groups: []ProductEditGroupInput{{ID: 19}}, +// }} +// +// data, status, err := client.ProductsBatchCreate(products) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", data.AddedProducts) +// } +func (c *Client) ProductsBatchCreate(products []ProductCreate) (ProductsBatchEditResponse, int, error) { + var resp ProductsBatchEditResponse + + productsEditJSON, _ := json.Marshal(products) + p := url.Values{ + "products": {string(productsEditJSON)}, + } + + data, status, err := c.PostRequest("/store/products/batch/create", p) + + if err != nil { + return resp, status, err + } + + err = json.Unmarshal(data, &resp) + if err != nil { + return resp, status, err + } + + return resp, status, nil +} + +// LoyaltyAccountCreate аdd a client to the loyalty program +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-loyalty-account-create +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// acc := SerializedCreateLoyaltyAccount{ +// SerializedBaseLoyaltyAccount: SerializedBaseLoyaltyAccount{ +// PhoneNumber: "89151005004", +// CustomFields: []string{"dog"}, +// }, +// Customer: SerializedEntityCustomer{ +// ID: 123, +// }, +// } +// +// data, status, err := client.LoyaltyAccountCreate("site", acc) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", data.LoyaltyAccount.ID) +// } +func (c *Client) LoyaltyAccountCreate(site string, loyaltyAccount SerializedCreateLoyaltyAccount) (CreateLoyaltyAccountResponse, int, error) { + var result CreateLoyaltyAccountResponse + + loyaltyAccountJSON, _ := json.Marshal(loyaltyAccount) + p := url.Values{ + "site": {site}, + "loyaltyAccount": {string(loyaltyAccountJSON)}, + } + + resp, status, err := c.PostRequest("/loyalty/account/create", p) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// LoyaltyAccountEdit edit a client in the loyalty program +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-loyalty-account-id-edit +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// acc := SerializedEditLoyaltyAccount{ +// SerializedBaseLoyaltyAccount: SerializedBaseLoyaltyAccount{ +// PhoneNumber: "89151005004", +// CustomFields: []string{"dog"}, +// }, +// } +// +// data, status, err := client.LoyaltyAccountEdit(13, acc) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", data.LoyaltyAccount.PhoneNumber) +// } +func (c *Client) LoyaltyAccountEdit(id int, loyaltyAccount SerializedEditLoyaltyAccount) (EditLoyaltyAccountResponse, int, error) { + var result EditLoyaltyAccountResponse + + loyaltyAccountJSON, _ := json.Marshal(loyaltyAccount) + p := url.Values{ + "loyaltyAccount": {string(loyaltyAccountJSON)}, + } + + resp, status, err := c.PostRequest(fmt.Sprintf("/loyalty/account/%d/edit", id), p) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// LoyaltyAccount return information about client in the loyalty program +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#get--api-v5-loyalty-account-id +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// data, status, err := client.LoyaltyAccount(13) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", data.LoyaltyAccount.PhoneNumber) +// } +func (c *Client) LoyaltyAccount(id int) (LoyaltyAccountResponse, int, error) { + var result LoyaltyAccountResponse + + resp, status, err := c.GetRequest(fmt.Sprintf("/loyalty/account/%d", id)) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// LoyaltyAccountActivate activate participation in the loyalty program for client +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-loyalty-account-id-activate +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// data, status, err := client.LoyaltyAccountActivate(13) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", data.LoyaltyAccount.Active) +// } +func (c *Client) LoyaltyAccountActivate(id int) (LoyaltyAccountActivateResponse, int, error) { + var result LoyaltyAccountActivateResponse + + resp, status, err := c.PostRequest(fmt.Sprintf("/loyalty/account/%d/activate", id), strings.NewReader("")) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// LoyaltyBonusCredit accrue bonus participation in the program of loyalty +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-loyalty-account-id-bonus-credit +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// req := LoyaltyBonusCreditRequest{ +// Amount: 120, +// ExpiredDate: "2023-11-24 12:39:37", +// Comment: "Test", +// } +// +// data, status, err := client.LoyaltyBonusCredit(13, req) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", data.LoyaltyBonus.ActivationDate) +// } +func (c *Client) LoyaltyBonusCredit(id int, req LoyaltyBonusCreditRequest) (LoyaltyBonusCreditResponse, int, error) { + var result LoyaltyBonusCreditResponse + p, _ := query.Values(req) + + resp, status, err := c.PostRequest(fmt.Sprintf("/loyalty/account/%d/bonus/credit", id), p) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// LoyaltyBonusStatusDetails get details on the bonus account +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#get--api-v5-loyalty-account-id-bonus-status-details +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// req := LoyaltyBonusStatusDetailsRequest{ +// Limit: 20, +// Page: 3, +// } +// +// data, status, err := client.LoyaltyBonusStatusDetails(13, "waiting_activation", req) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// for _, bonus := range data.Bonuses { +// log.Printf("%v", bonus.Amount) +// } +// } +func (c *Client) LoyaltyBonusStatusDetails( + id int, statusType string, request LoyaltyBonusStatusDetailsRequest, +) (LoyaltyBonusDetailsResponse, int, error) { + var result LoyaltyBonusDetailsResponse + + p, _ := query.Values(request) + + resp, status, err := c.GetRequest(fmt.Sprintf("/loyalty/account/%d/bonus/%s/details?%s", id, statusType, p.Encode())) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// LoyaltyAccounts return list of participations in the loyalty program +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#get--api-v5-loyalty-accounts +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// req := LoyaltyAccountsRequest{ +// Filter: LoyaltyAccountAPIFilter{ +// Status: "activated", +// PhoneNumber: "89185556363", +// Ids: []int{14}, +// Level: 5, +// Loyalties: []int{2}, +// CustomerID: "109", +// }, +// } +// +// data, status, err := client.LoyaltyAccounts(req) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// for _, account := range data.LoyaltyAccounts { +// log.Printf("%v", account.Status) +// } +// } +func (c *Client) LoyaltyAccounts(req LoyaltyAccountsRequest) (LoyaltyAccountsResponse, int, error) { + var result LoyaltyAccountsResponse + + p, _ := query.Values(req) + + resp, status, err := c.GetRequest(fmt.Sprintf("/loyalty/accounts?%s", p.Encode())) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// LoyaltyCalculate calculations of the maximum discount +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-loyalty-calculate +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// req := LoyaltyCalculateRequest{ +// Site: "main", +// Order: Order{ +// PrivilegeType: "loyalty_level", +// Customer: &Customer{ +// ID: 123, +// }, +// Items: []OrderItem{ +// { +// InitialPrice: 10000, +// Quantity: 1, +// Offer: Offer{ID: 214}, +// PriceType: &PriceType{Code: "base"}, +// }, +// }, +// }, +// Bonuses: 10, +// } +// +// data, status, err := client.LoyaltyCalculate(req) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", data.Order.PrivilegeType) +// log.Printf("%v", data.Order.BonusesCreditTotal) +// } +func (c *Client) LoyaltyCalculate(req LoyaltyCalculateRequest) (LoyaltyCalculateResponse, int, error) { + var result LoyaltyCalculateResponse + + orderJSON, _ := json.Marshal(req.Order) + + p := url.Values{ + "site": {req.Site}, + "order": {string(orderJSON)}, + "bonuses": {fmt.Sprintf("%f", req.Bonuses)}, + } + + resp, status, err := c.PostRequest("/loyalty/calculate", p) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// GetLoyalties returns list of loyalty programs +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#get--api-v5-loyalty-loyalties +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// req := LoyaltiesRequest{ +// Filter: LoyaltyAPIFilter{ +// Active: active, +// Ids: []int{2}, +// Sites: []string{"main"}, +// }, +// } +// +// data, status, err := client.GetLoyalties(req) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// for _, l := range data.Loyalties { +// log.Printf("%v", l.ID) +// log.Printf("%v", l.Active) +// } +// } +func (c *Client) GetLoyalties(req LoyaltiesRequest) (LoyaltiesResponse, int, error) { + var result LoyaltiesResponse + + p, _ := query.Values(req) + + resp, status, err := c.GetRequest(fmt.Sprintf("/loyalty/loyalties?%s", p.Encode())) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// GetLoyaltyByID return program of loyalty by id +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#get--api-v5-loyalty-loyalties-id +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// data, status, err := client.GetLoyaltyByID(2) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", res.Loyalty.ID) +// log.Printf("%v", res.Loyalty.Active) +// } +func (c *Client) GetLoyaltyByID(id int) (LoyaltyResponse, int, error) { + var result LoyaltyResponse + + resp, status, err := c.GetRequest(fmt.Sprintf("/loyalty/loyalties/%d", id)) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// OrderIntegrationDeliveryCancel cancels of integration delivery +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-orders-externalId-delivery-cancel +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// data, status, err := client.OrderIntegrationDeliveryCancel("externalId", false, "1001C") +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", res.Success) +// } +func (c *Client) OrderIntegrationDeliveryCancel(by string, force bool, id string) (SuccessfulResponse, int, error) { + var result SuccessfulResponse + + p := url.Values{ + "by": {checkBy(by)}, + "force": {fmt.Sprintf("%t", force)}, + } + + resp, status, err := c.PostRequest(fmt.Sprintf("/orders/%s/delivery/cancel?%s", id, p.Encode()), strings.NewReader("")) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// CreateProductsGroup adds a product group +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-store-product-groups-create +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// group := ProductGroup{ +// ParentID: 125, +// Name: "Фрукты", +// Site: "main", +// Active: true, +// ExternalID: "abc22", +// } +// +// data, status, err := client.CreateProductsGroup(group) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", res.ID) +// } +func (c *Client) CreateProductsGroup(group ProductGroup) (ActionProductsGroupResponse, int, error) { + var result ActionProductsGroupResponse + + groupJSON, _ := json.Marshal(group) + + p := url.Values{ + "productGroup": {string(groupJSON)}, + } + + resp, status, err := c.PostRequest("/store/product-groups/create", p) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// EditProductsGroup edits a product group +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-store-product-groups-externalId-edit +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// group := ProductGroup{ +// Name: "Овощи", +// Active: true, +// ExternalID: "abc22", +// } +// +// data, status, err := client.EditProductsGroup("id", "125", "main", group) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data.Success == true { +// log.Printf("%v", res.ID) +// } +func (c *Client) EditProductsGroup(by, id, site string, group ProductGroup) (ActionProductsGroupResponse, int, error) { + var result ActionProductsGroupResponse + + groupJSON, _ := json.Marshal(group) + + p := url.Values{ + "by": {checkBy(by)}, + "site": {site}, + "productGroup": {string(groupJSON)}, + } + + resp, status, err := c.PostRequest(fmt.Sprintf("/store/product-groups/%s/edit", id), p) + + if err != nil { + return result, status, err + } + + err = json.Unmarshal(resp, &result) + + if err != nil { + return result, status, err + } + + return result, status, nil +} + +// GetOrderPlate receives a print form file for the order +// +// # Body of response is already closed +// +// For more information see https://help.retailcrm.ru/api_v5_ru.html#get--api-v5-orders-externalId-plates-plateId-print +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// data, status, err := client.GetOrderPlate("id", "107", "main", 1) +// +// if err != nil { +// if apiErr, ok := retailcrm.AsAPIError(err); ok { +// log.Fatalf("http status: %d, %s", status, apiErr.String()) +// } +// +// log.Fatalf("http status: %d, error: %s", status, err) +// } +// +// if data != nil { +// fileData, err := io.ReadAll(data) +// if err != nil { +// return +// } +// +// log.Printf("%s", fileData) +// } +func (c *Client) GetOrderPlate(by, orderID, site string, plateID int) (io.ReadCloser, int, error) { + p := url.Values{ + "by": {checkBy(by)}, + "site": {site}, + } + + requestURL := fmt.Sprintf("%s/api/v5/orders/%s/plates/%d/print?%s", c.URL, orderID, plateID, p.Encode()) + req, err := http.NewRequest("GET", requestURL, nil) + + if err != nil { + return nil, 0, err + } + + req.Header.Set("X-API-KEY", c.Key) + + if c.Debug { + c.writeLog("API Request: %s %s", requestURL, c.Key) + } + + resp, err := c.httpClient.Do(req) + + if err != nil { + return nil, 0, err + } + + if resp.StatusCode >= http.StatusInternalServerError { + return nil, resp.StatusCode, CreateGenericAPIError( + fmt.Sprintf("HTTP request error. Status code: %d.", resp.StatusCode)) + } + + if resp.StatusCode >= http.StatusBadRequest && resp.StatusCode < http.StatusInternalServerError { + res, err := buildRawResponse(resp) + + if err != nil { + return nil, 0, err + } + + return nil, resp.StatusCode, CreateAPIError(res) + } + + reader := resp.Body + err = reader.Close() + + if err != nil { + return nil, 0, err + } + + return reader, resp.StatusCode, nil +} diff --git a/client_test.go b/client_test.go index 317c30a..db426fa 100644 --- a/client_test.go +++ b/client_test.go @@ -3,6 +3,7 @@ package retailcrm import ( "encoding/json" "fmt" + "github.com/google/go-querystring/query" "io/ioutil" "log" "math/rand" @@ -21,6 +22,8 @@ import ( gock "gopkg.in/h2non/gock.v1" ) +const prefix = "/api/v5" + func TestMain(m *testing.M) { err := godotenv.Load(".env") if err != nil { @@ -501,7 +504,15 @@ func TestClient_CustomersUpload(t *testing.T) { MatchType("url"). BodyString(p.Encode()). Reply(200). - BodyString(`{"success": true}`) + BodyString(`{ + "success": true, + "uploadedCustomers": [ + { + "id": 136 + } + ], + "failedCustomers": [] + }`) data, status, err := c.CustomersUpload(customers) if err != nil { @@ -515,12 +526,14 @@ func TestClient_CustomersUpload(t *testing.T) { if data.Success != true { t.Errorf("%v", err) } + + assert.Equal(t, 136, data.UploadedCustomers[0].ID) } func TestClient_CustomersUpload_Fail(t *testing.T) { c := client() - customers := []Customer{{ExternalID: strconv.Itoa(iCodeFail)}} + customers := []Customer{{ExternalID: strconv.Itoa(iCodeFail)}, {FirstName: "John"}} defer gock.Off() @@ -534,9 +547,25 @@ func TestClient_CustomersUpload_Fail(t *testing.T) { MatchType("url"). BodyString(p.Encode()). Reply(460). - BodyString(`{"success": false, "errorMsg": "Customers are loaded with ErrorsList"}`) + BodyString(fmt.Sprintf(`{ + "success": false, + "uploadedCustomers": [ + { + "id": 132 + } + ], + "failedCustomers": [ + { + "externalId": "%d" + } + ], + "errorMsg": "Customers are loaded with errors", + "errors": { + "managerId": "Something went wrong" + } + }`, iCodeFail)) - data, _, err := c.CustomersUpload(customers) + data, status, err := c.CustomersUpload(customers) if err == nil { t.Error("Error must be return") } @@ -544,6 +573,12 @@ func TestClient_CustomersUpload_Fail(t *testing.T) { if data.Success != false { t.Error(successFail) } + + assert.Equal(t, 132, data.UploadedCustomers[0].ID) + assert.Equal(t, HTTPStatusUnknown, status) + assert.Equal(t, fmt.Sprintf("%d", iCodeFail), data.FailedCustomers[0].ExternalID) + assert.Equal(t, "Customers are loaded with errors", err.Error()) + assert.Equal(t, "Something went wrong", err.(APIError).Errors()["managerId"]) //nolint:errorlint } func TestClient_CustomersCombine(t *testing.T) { @@ -1156,7 +1191,7 @@ func TestClient_CorporateCustomersUpload(t *testing.T) { func TestClient_CorporateCustomersUpload_Fail(t *testing.T) { c := client() - customers := []CorporateCustomer{{ExternalID: strconv.Itoa(iCodeFail)}} + customers := []CorporateCustomer{{ExternalID: strconv.Itoa(iCodeFail), ManagerID: 100001}} defer gock.Off() @@ -1170,9 +1205,19 @@ func TestClient_CorporateCustomersUpload_Fail(t *testing.T) { MatchType("url"). BodyString(p.Encode()). Reply(460). - BodyString(`{"success": false, "errorMsg": "Customers are loaded with ErrorsList"}`) + BodyString(fmt.Sprintf(`{ + "success": false, + "uploadedCustomers": [], + "failedCustomers": [{ + "externalId": "%d" + }], + "errorMsg": "Customers are loaded with errors", + "errors": { + "managerId": "Something went wrong" + } + }`, iCodeFail)) - data, _, err := c.CorporateCustomersUpload(customers) + data, status, err := c.CorporateCustomersUpload(customers) if err == nil { t.Error("Error must be return") } @@ -1180,6 +1225,12 @@ func TestClient_CorporateCustomersUpload_Fail(t *testing.T) { if data.Success != false { t.Error(successFail) } + + assert.Empty(t, data.UploadedCustomers) + assert.Equal(t, HTTPStatusUnknown, status) + assert.Equal(t, fmt.Sprintf("%d", iCodeFail), data.FailedCustomers[0].ExternalID) + assert.Equal(t, "Customers are loaded with errors", err.Error()) + assert.Equal(t, "Something went wrong", err.(APIError).Errors()["managerId"]) //nolint:errorlint } func TestClient_CorporateCustomer(t *testing.T) { @@ -2190,6 +2241,9 @@ func TestClient_OrdersUpload_Fail(t *testing.T) { LastName: fmt.Sprintf("Test_%s", RandomString(8)), ExternalID: strconv.Itoa(iCodeFail), Email: fmt.Sprintf("%s@example.com", RandomString(8)), + Items: []OrderItem{ + {Offer: Offer{ID: iCodeFail}}, + }, }, } @@ -2206,9 +2260,21 @@ func TestClient_OrdersUpload_Fail(t *testing.T) { MatchType("url"). BodyString(p.Encode()). Reply(460). - BodyString(`{"success": false, "errorMsg": "Orders are loaded with ErrorsList"}`) + BodyString(fmt.Sprintf(`{ + "success": false, + "uploadedOrders": [], + "failedOrders": [ + { + "externalId": "%d" + } + ], + "errorMsg": "Orders are loaded with errors", + "errors": [ + "items[0].offer.id: Offer with id %d not found." + ] + }`, iCodeFail, iCodeFail)) - data, _, err := c.OrdersUpload(orders) + data, status, err := c.OrdersUpload(orders) if err == nil { t.Error("Error must be return") } @@ -2216,6 +2282,11 @@ func TestClient_OrdersUpload_Fail(t *testing.T) { if data.Success != false { t.Error(successFail) } + + assert.Equal(t, HTTPStatusUnknown, status) + assert.Equal(t, fmt.Sprintf("%d", iCodeFail), data.FailedOrders[0].ExternalID) + assert.Equal(t, "Orders are loaded with errors", err.Error()) + assert.Equal(t, "items[0].offer.id: Offer with id 123123 not found.", err.(APIError).Errors()["0"]) //nolint:errorlint } func TestClient_OrdersCombine(t *testing.T) { @@ -3122,7 +3193,26 @@ func TestClient_DeliveryTypes(t *testing.T) { gock.New(crmURL). Get("/reference/delivery-types"). Reply(200). - BodyString(`{"success": true}`) + BodyString(`{ + "success": true, + "deliveryTypes": { + "courier": { + "name": "Доставка курьером", + "code": "courier", + "active": true, + "deliveryPaymentTypes": [ + { + "code": "cash", + "cod": false + }, + { + "code": "bank-card", + "cod": false + } + ] + } + } + }`) data, st, err := c.DeliveryTypes() if err != nil { @@ -3136,6 +3226,14 @@ func TestClient_DeliveryTypes(t *testing.T) { if data.Success != true { t.Errorf("%v", err) } + + assert.Equal(t, "Доставка курьером", data.DeliveryTypes["courier"].Name) + assert.Equal(t, "courier", data.DeliveryTypes["courier"].Code) + assert.True(t, data.DeliveryTypes["courier"].Active) + assert.Equal(t, "cash", data.DeliveryTypes["courier"].DeliveryPaymentTypes[0].Code) + assert.Equal(t, "bank-card", data.DeliveryTypes["courier"].DeliveryPaymentTypes[1].Code) + assert.False(t, data.DeliveryTypes["courier"].DeliveryPaymentTypes[0].Cod) + assert.False(t, data.DeliveryTypes["courier"].DeliveryPaymentTypes[1].Cod) } func TestClient_LegalEntities(t *testing.T) { @@ -5124,11 +5222,41 @@ func TestClient_IntegrationModule(t *testing.T) { BaseURL: fmt.Sprintf("http://example.com/%s", name), ClientID: RandomString(10), Logo: "https://cdn.worldvectorlogo.com/logos/github-icon.svg", + Integrations: &Integrations{ + Delivery: &Delivery{ + StatusList: []DeliveryStatus{ + { + Code: "st1", + Name: "st1", + IsEditable: true, + IsError: true, + IsPreprocessing: false, + }, + { + Code: "st2", + Name: "st2", + IsEditable: false, + IsError: false, + IsPreprocessing: false, + }, + }, + }, + }, } + integrations, err := json.Marshal(integrationModule.Integrations) + assert.NoError(t, err) + jsonData := fmt.Sprintf( - `{"code":"%s","integrationCode":"%s","active":false,"name":"%s","logo":"%s","clientId":"%s","baseUrl":"%s","accountUrl":"%s"}`, - code, code, integrationModule.Name, integrationModule.Logo, integrationModule.ClientID, integrationModule.BaseURL, integrationModule.AccountURL, + `{"code":"%s","integrationCode":"%s","active":false,"name":"%s","logo":"%s","clientId":"%s","baseUrl":"%s","accountUrl":"%s","integrations":%s}`, + code, + code, + integrationModule.Name, + integrationModule.Logo, + integrationModule.ClientID, + integrationModule.BaseURL, + integrationModule.AccountURL, + integrations, ) pr := url.Values{ @@ -5140,7 +5268,24 @@ func TestClient_IntegrationModule(t *testing.T) { MatchType("url"). BodyString(pr.Encode()). Reply(201). - BodyString(`{"success": true}`) + BodyString(`{ + "success": true, + "info": { + "deliveryType": { + "id": 38, + "code": "sdek-v-2-podkliuchenie-1" + }, + "billingInfo": { + "price": 0, + "currency": { + "name": "Рубль", + "shortName": "руб.", + "code": "RUB" + }, + "billingType": "fixed" + } + } + }`) m, status, err := c.IntegrationModuleEdit(integrationModule) if err != nil { @@ -6802,3 +6947,779 @@ func TestClient_AccountBonusOperations_Fail(t *testing.T) { t.Error(successFail) } } + +func TestClient_ProductsBatchCreate(t *testing.T) { + defer gock.Off() + + products := getProductsCreate() + productsJSON, err := json.Marshal(products) + assert.NoError(t, err) + + p := url.Values{"products": {string(productsJSON)}} + + gock.New(crmURL). + Post(prefix + "/store/products/batch/create"). + BodyString(p.Encode()). + Reply(http.StatusOK). + JSON(getProductsCreateResponse()) + + resp, status, err := client().ProductsBatchCreate(products) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if resp.Success != true || resp.ProcessedProductsCount == 0 { + t.Errorf("%v", err) + } +} + +func TestClient_ProductsBatchCreateFail(t *testing.T) { + defer gock.Off() + + products := getProductsCreate() + productsJSON, err := json.Marshal(products) + assert.NoError(t, err) + + p := url.Values{"products": {string(productsJSON)}} + + gock.New(crmURL). + Post(prefix + "/store/products/batch/create"). + BodyString(p.Encode()). + Reply(http.StatusBadRequest). + JSON(`{"success":false,"errorMsg":"Something went wrong"}`) + + resp, status, err := client().ProductsBatchCreate(products) + + if err == nil { + t.Error("Expected error") + } + + if status < http.StatusBadRequest { + t.Errorf("%v", err) + } + + if resp.Success != false { + t.Error(successFail) + } +} + +func TestClient_ProductsBatchEdit(t *testing.T) { + defer gock.Off() + + products := getProductsEdit() + productsJSON, err := json.Marshal(products) + assert.NoError(t, err) + + p := url.Values{"products": {string(productsJSON)}} + + gock.New(crmURL). + Post(prefix + "/store/products/batch/edit"). + BodyString(p.Encode()). + Reply(http.StatusOK). + JSON(getProductsEditResponse()) + + resp, status, err := client().ProductsBatchEdit(products) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if resp.Success != true || resp.ProcessedProductsCount == 0 { + t.Errorf("%v", err) + } +} + +func TestClient_ProductsBatchEditFail(t *testing.T) { + defer gock.Off() + + products := getProductsEdit() + productsJSON, err := json.Marshal(products) + assert.NoError(t, err) + + p := url.Values{"products": {string(productsJSON)}} + + gock.New(crmURL). + Post(prefix + "/store/products/batch/edit"). + BodyString(p.Encode()). + Reply(http.StatusInternalServerError). + JSON(`{"success":false,"errorMsg":"Something went wrong"}`) + + resp, status, err := client().ProductsBatchEdit(products) + + if err == nil { + t.Error("Expected error") + } + + if status != http.StatusInternalServerError { + t.Errorf("%v", err) + } + + if resp.Success != false { + t.Error(successFail) + } +} + +func TestClient_LoyaltyAccountCreate(t *testing.T) { + defer gock.Off() + + acc := getLoyaltyAccountCreate() + accJSON, _ := json.Marshal(acc) + p := url.Values{ + "site": {"second"}, + "loyaltyAccount": {string(accJSON)}, + } + + gock.New(crmURL). + Post(prefix + "/loyalty/account/create"). + BodyString(p.Encode()). + Reply(http.StatusOK). + JSON(getLoyaltyAccountCreateResponse()) + + resp, status, err := client().LoyaltyAccountCreate("second", acc) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if resp.Success != true { + t.Errorf("%v", err) + } +} + +func TestClient_LoyaltyAccountCreateFail(t *testing.T) { + defer gock.Off() + + acc := getLoyaltyAccountCreate() + accJSON, _ := json.Marshal(acc) + p := url.Values{ + "site": {"second"}, + "loyaltyAccount": {string(accJSON)}, + } + + gock.New(crmURL). + Post("/loyalty/account/create"). + BodyString(p.Encode()). + Reply(http.StatusInternalServerError). + JSON(`{"success":false,"errorMsg":"Something went wrong"}`) + + resp, status, err := client().LoyaltyAccountCreate("second", acc) + + if err == nil { + t.Error("Expected error") + } + + if status != http.StatusInternalServerError { + t.Errorf("%v", err) + } + + if resp.Success != false { + t.Error(successFail) + } +} + +func TestClient_LoyaltyAccountEdit(t *testing.T) { + defer gock.Off() + + acc := getLoyaltyAccountCreate() + acc.PhoneNumber = "89142221020" + req := SerializedEditLoyaltyAccount{acc.SerializedBaseLoyaltyAccount} + reqJSON, _ := json.Marshal(req) + p := url.Values{ + "loyaltyAccount": {string(reqJSON)}, + } + + gock.New(crmURL). + Post(fmt.Sprintf("/loyalty/account/%d/edit", 13)). + BodyString(p.Encode()). + Reply(http.StatusOK). + JSON(getLoyaltyAccountEditResponse()) + + res, status, err := client().LoyaltyAccountEdit(13, req) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } +} + +func TestClient_LoyaltyAccountEditFail(t *testing.T) { + defer gock.Off() + + acc := getLoyaltyAccountCreate() + acc.PhoneNumber = "89142221020" + req := SerializedEditLoyaltyAccount{acc.SerializedBaseLoyaltyAccount} + reqJSON, _ := json.Marshal(req) + p := url.Values{ + "loyaltyAccount": {string(reqJSON)}, + } + + gock.New(crmURL). + Post(fmt.Sprintf("/loyalty/account/%d/edit", 13)). + BodyString(p.Encode()). + Reply(http.StatusInternalServerError). + JSON(`{"success":false,"errorMsg":"Something went wrong"}`) + + res, status, err := client().LoyaltyAccountEdit(13, req) + + if err == nil { + t.Error("Expected error") + } + + if status != http.StatusInternalServerError { + t.Errorf("%v", err) + } + + if res.Success != false { + t.Error(successFail) + } +} + +func TestClient_LoyaltyAccount(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Get(prefix + fmt.Sprintf("/loyalty/account/%d", 13)). + Reply(http.StatusOK). + JSON(getLoyaltyAccountResponse()) + + res, status, err := client().LoyaltyAccount(13) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.NotEmpty(t, res.LoyaltyAccount.ID) + assert.NotEmpty(t, res.LoyaltyAccount.Loyalty) + assert.NotEmpty(t, res.LoyaltyAccount.Customer) + assert.NotEmpty(t, res.LoyaltyAccount.PhoneNumber) + assert.NotEmpty(t, res.LoyaltyAccount.NextLevelSum) + assert.NotEmpty(t, res.LoyaltyAccount.LoyaltyLevel) + assert.NotEmpty(t, res.LoyaltyAccount.CreatedAt) + assert.NotEmpty(t, res.LoyaltyAccount.ActivatedAt) + assert.NotEmpty(t, res.LoyaltyAccount.Status) +} + +func TestClient_LoyaltyAccountActivate(t *testing.T) { + defer gock.Off() + + var resp LoyaltyAccountActivateResponse + err := json.Unmarshal([]byte(getLoyaltyAccountResponse()), &resp) + assert.NoError(t, err) + resp.Verification = SmsVerification{ + CreatedAt: "2022-11-24 12:39:37", + ExpiredAt: "2022-11-24 12:39:37", + VerifiedAt: "2022-11-24 13:39:37", + CheckID: "test", + ActionType: "test", + } + gock.New(crmURL). + Post(prefix + fmt.Sprintf("/loyalty/account/%d/activate", 13)). + Body(strings.NewReader("")). + Reply(http.StatusOK). + JSON(resp) + + res, status, err := client().LoyaltyAccountActivate(13) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.NotEmpty(t, res.LoyaltyAccount.ID) + assert.NotEmpty(t, res.LoyaltyAccount.Loyalty) + assert.NotEmpty(t, res.LoyaltyAccount.Customer) + assert.NotEmpty(t, res.LoyaltyAccount.PhoneNumber) + assert.NotEmpty(t, res.LoyaltyAccount.NextLevelSum) + assert.NotEmpty(t, res.LoyaltyAccount.LoyaltyLevel) + assert.NotEmpty(t, res.LoyaltyAccount.CreatedAt) + assert.NotEmpty(t, res.LoyaltyAccount.ActivatedAt) + assert.NotEmpty(t, res.LoyaltyAccount.Status) + assert.NotEmpty(t, res.Verification) +} + +func TestClient_LoyaltyBonusCredit(t *testing.T) { + defer gock.Off() + + req := LoyaltyBonusCreditRequest{ + Amount: 120, + ExpiredDate: "2023-11-24 12:39:37", + Comment: "Test", + } + body, err := query.Values(req) + assert.NoError(t, err) + + gock.New(crmURL). + Post(prefix + fmt.Sprintf("/loyalty/account/%d/bonus/credit", 13)). + BodyString(body.Encode()). + Reply(http.StatusOK). + JSON(`{ + "success":true, + "loyaltyBonus": { + "amount":120, + "expiredDate":"2023-11-24 12:39:37" + } + }`) + + res, status, err := client().LoyaltyBonusCredit(13, req) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } +} + +func TestClient_LoyaltyBonusCreditFail(t *testing.T) { + defer gock.Off() + + req := LoyaltyBonusCreditRequest{ + Amount: 120, + ExpiredDate: "2023-11-24 12:39:37", + Comment: "Test", + } + body, err := query.Values(req) + assert.NoError(t, err) + + gock.New(crmURL). + Post(prefix + fmt.Sprintf("/loyalty/account/%d/bonus/credit", 13)). + BodyString(body.Encode()). + Reply(http.StatusInternalServerError). + JSON(`{"success":false,"errorMsg":"Something went wrong"}`) + + res, status, err := client().LoyaltyBonusCredit(13, req) + + if err == nil { + t.Error("Expected error") + } + + if status != http.StatusInternalServerError { + t.Errorf("%v", err) + } + + if res.Success != false { + t.Error(successFail) + } +} + +func TestClient_LoyaltyBonusStatusDetails(t *testing.T) { + defer gock.Off() + + req := LoyaltyBonusStatusDetailsRequest{ + Limit: 20, + Page: 3, + } + + gock.New(crmURL). + Get(prefix+fmt.Sprintf("/loyalty/account/%d/bonus/%s/details", 13, "waiting_activation")). + MatchParam("limit", strconv.Itoa(20)). + MatchParam("page", strconv.Itoa(3)). + Reply(http.StatusOK). + JSON(getBonusDetailsResponse()) + + res, status, err := client().LoyaltyBonusStatusDetails(13, "waiting_activation", req) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.NotEmpty(t, res.Pagination.TotalCount) + assert.NotEmpty(t, res.Bonuses) + assert.NotEmpty(t, res.Statistic.TotalAmount) +} + +func TestClient_LoyaltyAccounts(t *testing.T) { + defer gock.Off() + + req := LoyaltyAccountsRequest{ + Filter: LoyaltyAccountAPIFilter{ + Status: "activated", + PhoneNumber: "89185556363", + Ids: []int{14}, + Level: 5, + Loyalties: []int{2}, + CustomerID: "109", + }, + } + + gock.New(crmURL). + Get(prefix + "/loyalty/accounts"). + MatchParams(map[string]string{ + "filter[phoneNumber]": "89185556363", + "filter[status]": "activated", + "filter[level]": "5", + "filter[customerId]": "109", + }). + Reply(http.StatusOK). + JSON(getLoyaltyAccountsResponse()) + + res, status, err := client().LoyaltyAccounts(req) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.Equal(t, req.Filter.Ids[0], res.LoyaltyAccounts[0].ID) + assert.Equal(t, req.Filter.Loyalties[0], res.LoyaltyAccounts[0].Loyalty.ID) + assert.True(t, res.LoyaltyAccounts[0].Active) + assert.Equal(t, req.Filter.PhoneNumber, res.LoyaltyAccounts[0].PhoneNumber) + assert.Equal(t, req.Filter.Status, res.LoyaltyAccounts[0].Status) +} + +func TestClient_LoyaltyCalculate(t *testing.T) { + defer gock.Off() + + req := getLoyaltyCalculateReq() + orderJSON, err := json.Marshal(req.Order) + assert.NoError(t, err) + + p := url.Values{ + "site": {req.Site}, + "bonuses": {fmt.Sprintf("%f", req.Bonuses)}, + "order": {string(orderJSON)}, + } + + gock.New(crmURL). + Post(prefix + "/loyalty/calculate"). + BodyString(p.Encode()). + Reply(http.StatusOK). + JSON(getLoyaltyCalculateResponse()) + + res, status, err := client().LoyaltyCalculate(req) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.Equal(t, float32(999), res.Order.BonusesCreditTotal) + assert.Equal(t, float32(10), res.Order.BonusesChargeTotal) + assert.Equal(t, req.Order.PrivilegeType, res.Order.PrivilegeType) + assert.Equal(t, float64(9990), res.Order.TotalSumm) + assert.Equal(t, 13, res.Order.LoyaltyAccount.ID) + assert.Equal(t, float64(240), res.Order.LoyaltyAccount.Amount) + assert.Equal(t, req.Order.Customer.ID, res.Order.Customer.ID) + + assert.Equal(t, float32(999), res.Order.Items[0].BonusesCreditTotal) + assert.Equal(t, float32(10), res.Order.Items[0].BonusesChargeTotal) + assert.Equal(t, req.Order.Items[0].PriceType.Code, res.Order.Items[0].PriceType.Code) + assert.Equal(t, req.Order.Items[0].InitialPrice, res.Order.Items[0].InitialPrice) + assert.Equal(t, "bonus_charge", res.Order.Items[0].Discounts[0].Type) + assert.Equal(t, float32(10), res.Order.Items[0].Discounts[0].Amount) + assert.Equal(t, float64(9990), res.Order.Items[0].Prices[0].Price) + assert.Equal(t, float32(1), res.Order.Items[0].Prices[0].Quantity) + assert.Equal(t, float32(1), res.Order.Items[0].Quantity) + assert.Equal(t, "696999ed-bc8d-4d0f-9627-527acf7b1d57", res.Order.Items[0].Offer.XMLID) + + assert.Equal(t, req.Order.PrivilegeType, res.Calculations[0].PrivilegeType) + assert.Equal(t, req.Bonuses, res.Calculations[0].Discount) + assert.Equal(t, float32(999), res.Calculations[0].CreditBonuses) + assert.Equal(t, float32(240), res.Calculations[0].MaxChargeBonuses) + + assert.Equal(t, float32(240), res.Calculations[0].MaxChargeBonuses) + assert.Equal(t, "Бонусная программа", res.Loyalty.Name) + assert.Equal(t, float32(1), res.Loyalty.ChargeRate) +} + +func TestClient_GetLoyalties(t *testing.T) { + defer gock.Off() + + active := new(int) + *active = 1 + + req := LoyaltiesRequest{ + Filter: LoyaltyAPIFilter{ + Active: active, + Ids: []int{2}, + Sites: []string{"main"}, + }, + } + + gock.New(crmURL). + Get(prefix + "/loyalty/loyalties"). + MatchParams(map[string]string{ + "filter[active]": "1", + "filter[sites][]": "main", + "filter[ids][]": "2", + }). + Reply(http.StatusOK). + JSON(getLoyaltiesResponse()) + + res, status, err := client().GetLoyalties(req) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.NotEmpty(t, res.Pagination) + assert.True(t, res.Loyalties[0].Active) + assert.False(t, res.Loyalties[0].Blocked) + assert.Equal(t, 2, res.Loyalties[0].ID) + assert.Equal(t, "Бонусная программа", res.Loyalties[0].Name) + assert.False(t, res.Loyalties[0].ConfirmSmsCharge) + assert.False(t, res.Loyalties[0].ConfirmSmsCharge) + assert.NotEmpty(t, res.Loyalties[0].CreatedAt) + assert.NotEmpty(t, res.Loyalties[0].ActivatedAt) +} + +func TestClient_GetLoyaltyById(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Get(prefix + "/loyalty/loyalties/2"). + Reply(http.StatusOK). + JSON(getLoyaltyResponse()) + + res, status, err := client().GetLoyaltyByID(2) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.True(t, res.Loyalty.Active) + assert.False(t, res.Loyalty.Blocked) + assert.Equal(t, 2, res.Loyalty.ID) + assert.Equal(t, 4, len(res.Loyalty.LoyaltyLevels)) + assert.Equal(t, "Бонусная программа", res.Loyalty.Name) + assert.False(t, res.Loyalty.ConfirmSmsCharge) + assert.False(t, res.Loyalty.ConfirmSmsCharge) + assert.NotEmpty(t, res.Loyalty.CreatedAt) + assert.NotEmpty(t, res.Loyalty.ActivatedAt) +} + +func TestClient_OrderIntegrationDeliveryCancel(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Post(prefix + "/orders/123/delivery/cancel"). + MatchParams(map[string]string{ + "by": "id", + "force": "true", + }). + Reply(http.StatusOK). + JSON(`{"success":true}`) + + res, status, err := client().OrderIntegrationDeliveryCancel("id", true, "123") + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } +} + +func TestClient_CreateProductsGroup(t *testing.T) { + defer gock.Off() + + group := ProductGroup{ + ParentID: 19, + Name: "Подкатегория хлама", + Site: "main", + Active: true, + Description: "Ну и хлам!", + ExternalID: "ti22", + } + + body, err := json.Marshal(group) + assert.NoError(t, err) + + p := url.Values{ + "productGroup": {string(body)}, + } + + gock.New(crmURL). + Post(prefix + "/store/product-groups/create"). + BodyString(p.Encode()). + Reply(http.StatusCreated). + JSON(`{"success":true,"id":32}`) + + res, status, err := client().CreateProductsGroup(group) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.Equal(t, 32, res.ID) +} + +func TestClient_EditProductsGroup(t *testing.T) { + defer gock.Off() + + group := ProductGroup{ + Name: "Ценнейший хлам из хламов", + Active: true, + ExternalID: "ti22", + } + + body, err := json.Marshal(group) + assert.NoError(t, err) + + p := url.Values{ + "by": {"id"}, + "site": {"main"}, + "productGroup": {string(body)}, + } + + gock.New(crmURL). + Post(prefix + "/store/product-groups/32/edit"). + BodyString(p.Encode()). + Reply(http.StatusOK). + JSON(`{"success":true,"id":32}`) + + res, status, err := client().EditProductsGroup("id", "32", "main", group) + + if err != nil { + t.Errorf("%v", err) + } + + if !statuses[status] { + t.Errorf("%v", err) + } + + if res.Success != true { + t.Errorf("%v", err) + } + + assert.Equal(t, 32, res.ID) +} + +func TestClient_GetOrderPlate(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Get(prefix + "/orders/124/plates/1/print"). + MatchParams(map[string]string{ + "by": "id", + "site": "main", + }). + Reply(200). + Body(ioutil.NopCloser(strings.NewReader("PDF"))) + + data, status, err := client().GetOrderPlate("id", "124", "main", 1) + + if err != nil { + t.Errorf("%v", err) + } + + assert.NotNil(t, data) + assert.Equal(t, status, http.StatusOK) +} + +func TestClient_GetOrderPlateFail(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Get(prefix + "/orders/124/plates/1/print"). + MatchParams(map[string]string{ + "by": "id", + "site": "main", + }). + Reply(404). + JSON(`{ + "success": false, + "errorMsg": "Not found" + }`) + + data, status, err := client().GetOrderPlate("id", "124", "main", 1) + + if err == nil { + t.Error("Expected error") + } + + assert.Nil(t, data) + assert.Equal(t, status, http.StatusNotFound) + assert.Equal(t, "Not found", err.(APIError).Error()) //nolint:errorlint +} diff --git a/filters.go b/filters.go index 03f7e76..762ae4f 100644 --- a/filters.go +++ b/filters.go @@ -439,3 +439,37 @@ type AccountBonusOperationsFilter struct { CreatedAtFrom string `url:"createdAtFrom,omitempty"` CreatedAtTo string `url:"createdAtTo,omitempty"` } + +type LoyaltyBonusAPIFilterType struct { + Date string `url:"date,omitempty"` +} + +type LoyaltyAccountAPIFilter struct { + ID string `url:"id,omitempty"` + Status string `url:"status,,omitempty"` + Customer string `url:"customer,omitempty"` + MinOrderSum string `url:"minOrderSum,omitempty"` + MaxOrderSum string `url:"maxOrderSum,omitempty"` + MinAmount string `url:"minAmount,omitempty"` + MaxAmount string `url:"maxAmount,omitempty"` + PhoneNumber string `url:"phoneNumber,omitempty"` + CardNumber string `url:"cardNumber,omitempty"` + Ids []int `url:"ids,omitempty,brackets"` + Loyalties []int `url:"loyalties,omitempty,brackets"` + Sites []string `url:"sites,omitempty,brackets"` + Level int `url:"level,omitempty"` + CreatedAtFrom string `url:"createdAtFrom,omitempty"` + CreatedAtTo string `url:"createdAtTo,omitempty"` + BurnDateFrom string `url:"burnDateFrom,omitempty"` + BurnDateTo string `url:"burnDateTo,omitempty"` + CustomFields []string `url:"customFields,omitempty,brackets"` + CustomerID string `url:"customerId,omitempty"` + CustomerExternalID string `url:"customerExternalId,omitempty"` +} + +type LoyaltyAPIFilter struct { + Active *int `url:"active,omitempty"` + Blocked *int `url:"blocked,omitempty"` + Ids []int `url:"ids,omitempty,brackets"` + Sites []string `url:"sites,omitempty,brackets"` +} diff --git a/request.go b/request.go index 21df512..543a115 100644 --- a/request.go +++ b/request.go @@ -246,6 +246,37 @@ type AccountBonusOperationsRequest struct { Page int `url:"page,omitempty"` } +type LoyaltyBonusCreditRequest struct { + Amount float64 `url:"amount"` + ActivationDate string `url:"activationDate,omitempty"` + ExpiredDate string `url:"expiredDate,omitempty"` + Comment string `url:"comment,omitempty"` +} + +type LoyaltyBonusStatusDetailsRequest struct { + Limit int `url:"limit,omitempty"` + Page int `url:"page,omitempty"` + Filter LoyaltyBonusAPIFilterType `url:"filter,omitempty"` +} + +type LoyaltyAccountsRequest struct { + Limit int `url:"limit,omitempty"` + Page int `url:"limit,omitempty"` + Filter LoyaltyAccountAPIFilter `url:"filter,omitempty"` +} + +type LoyaltyCalculateRequest struct { + Site string + Order Order + Bonuses float32 +} + +type LoyaltiesRequest struct { + Limit int `url:"limit,omitempty"` + Page int `url:"page,omitempty"` + Filter LoyaltyAPIFilter `url:"filter,omitempty"` +} + // SystemURL returns system URL from the connection request without trailing slash. func (r ConnectRequest) SystemURL() string { if r.URL == "" { diff --git a/response.go b/response.go index d81b82f..501d01a 100644 --- a/response.go +++ b/response.go @@ -5,6 +5,17 @@ type SuccessfulResponse struct { Success bool `json:"success"` } +type CreateLoyaltyAccountResponse struct { + SuccessfulResponse + LoyaltyAccount LoyaltyAccount `json:"loyaltyAccount,omitempty"` + Warnings []string `json:"warnings,omitempty"` +} + +type EditLoyaltyAccountResponse struct { + SuccessfulResponse + LoyaltyAccount LoyaltyAccount `json:"loyaltyAccount,omitempty"` +} + // CreateResponse type. type CreateResponse struct { Success bool `json:"success"` @@ -112,6 +123,7 @@ type CorporateCustomerChangeResponse CustomerChangeResponse type CustomersUploadResponse struct { Success bool `json:"success"` UploadedCustomers []IdentifiersPair `json:"uploadedCustomers,omitempty"` + FailedCustomers []ExternalID `json:"failedCustomers,omitempty"` } // CorporateCustomersUploadResponse type. @@ -156,6 +168,7 @@ type OrdersStatusesResponse struct { type OrdersUploadResponse struct { Success bool `json:"success"` UploadedOrders []IdentifiersPair `json:"uploadedOrders,omitempty"` + FailedOrders []ExternalID `json:"failedOrders,omitempty"` } // OrdersHistoryResponse type. @@ -370,6 +383,23 @@ type ProductsResponse struct { Products []Product `json:"products,omitempty"` } +type ProductEditNotFoundResponse struct { + ID string `json:"id"` + ExternalID string `json:"externalId,omitempty"` +} + +type ProductsBatchEditResponse struct { + SuccessfulResponse + ProcessedProductsCount int `json:"processedProductsCount,omitempty"` + NotFoundProducts []ProductEditNotFoundResponse `json:"notFoundProducts,omitempty"` +} + +type ProductsBatchCreateResponse struct { + SuccessfulResponse + ProcessedProductsCount int `json:"processedProductsCount,omitempty"` + AddedProducts []int `json:"addedProducts,omitempty"` +} + // ProductsPropertiesResponse type. type ProductsPropertiesResponse struct { Success bool `json:"success"` @@ -417,9 +447,10 @@ type IntegrationModuleEditResponse struct { // ResponseInfo type. type ResponseInfo struct { - MgTransportInfo MgInfo `json:"mgTransport,omitempty"` - MgBotInfo MgInfo `json:"mgBot,omitempty"` - BillingInfo *BillingInfo `json:"billingInfo,omitempty"` + MgTransportInfo MgInfo `json:"mgTransport,omitempty"` + MgBotInfo MgInfo `json:"mgBot,omitempty"` + BillingInfo *BillingInfo `json:"billingInfo,omitempty"` + DeliveryTypeInfo DeliveryTypeInfo `json:"deliveryType,omitempty"` } type BillingInfo struct { @@ -564,3 +595,59 @@ type AccountBonusOperationsResponse struct { Pagination *Pagination `json:"pagination,omitempty"` BonusOperations []BonusOperation `json:"bonusOperations,omitempty"` } + +type LoyaltyAccountResponse struct { + SuccessfulResponse + LoyaltyAccount `json:"loyaltyAccount"` +} + +type LoyaltyAccountActivateResponse struct { + SuccessfulResponse + LoyaltyAccount `json:"loyaltyAccount"` + Verification SmsVerification `json:"verification,omitempty"` +} + +type LoyaltyBonusCreditResponse struct { + SuccessfulResponse + LoyaltyBonus LoyaltyBonus `json:"loyaltyBonus"` +} + +type LoyaltyBonusDetailsResponse struct { + SuccessfulResponse + Pagination `json:"pagination"` + Statistic LoyaltyBonusStatisticResponse `json:"statistic"` + Bonuses []BonusDetail `json:"bonuses,omitempty"` +} + +type LoyaltyBonusStatisticResponse struct { + TotalAmount float64 `json:"totalAmount"` +} + +type LoyaltyAccountsResponse struct { + SuccessfulResponse + Pagination *Pagination `json:"pagination"` + LoyaltyAccounts []LoyaltyAccount `json:"loyaltyAccounts,omitempty"` +} + +type LoyaltyCalculateResponse struct { + SuccessfulResponse + Order SerializedLoyaltyOrder `json:"order,omitempty"` + Calculations []LoyaltyCalculation `json:"calculations,omitempty"` + Loyalty SerializedLoyalty `json:"loyalty,omitempty"` +} + +type LoyaltiesResponse struct { + SuccessfulResponse + Pagination *Pagination `json:"pagination"` + Loyalties []Loyalty `json:"loyalties,omitempty"` +} + +type LoyaltyResponse struct { + SuccessfulResponse + Loyalty Loyalty `json:"loyalty"` +} + +type ActionProductsGroupResponse struct { + SuccessfulResponse + ID int `json:"id"` +} diff --git a/testutils.go b/testutils.go new file mode 100644 index 0000000..eec7d68 --- /dev/null +++ b/testutils.go @@ -0,0 +1,426 @@ +//go:build testutils +// +build testutils + +package retailcrm + +func getProductsCreate() []ProductCreate { + products := []ProductCreate{ + { + CatalogID: 3, + BaseProduct: BaseProduct{ + Name: "Product 1", + URL: "https://example.com/p/1", + Article: "p1", + ExternalID: "ext1", + Manufacturer: "man1", + Description: "Description 1", + Popular: true, + Stock: true, + Novelty: true, + Recommended: true, + Active: true, + Markable: true, + }, + Groups: []ProductEditGroupInput{{ID: 19}}, + }, + { + CatalogID: 3, + BaseProduct: BaseProduct{ + Name: "Product 2", + URL: "https://example.com/p/2", + Article: "p2", + ExternalID: "ext2", + Manufacturer: "man2", + Description: "Description 2", + Popular: true, + Stock: true, + Novelty: true, + Recommended: true, + Active: true, + Markable: true, + }, + Groups: []ProductEditGroupInput{{ID: 19}}, + }, + } + + return products +} + +func getProductsCreateResponse() ProductsBatchCreateResponse { + return ProductsBatchCreateResponse{ + SuccessfulResponse: SuccessfulResponse{Success: true}, + ProcessedProductsCount: 2, + AddedProducts: []int{1, 2}, + } +} + +func getProductsEdit() []ProductEdit { + products := []ProductEdit{ + { + BaseProduct: getProductsCreate()[0].BaseProduct, + ID: 194, + CatalogID: 3, + Site: "second", + }, + { + BaseProduct: getProductsCreate()[1].BaseProduct, + ID: 195, + CatalogID: 3, + Site: "second", + }, + } + + return products +} + +func getProductsEditResponse() ProductsBatchEditResponse { + return ProductsBatchEditResponse{ + SuccessfulResponse: SuccessfulResponse{Success: true}, + ProcessedProductsCount: 2, + NotFoundProducts: nil, + } +} + +func getLoyaltyAccountCreate() SerializedCreateLoyaltyAccount { + return SerializedCreateLoyaltyAccount{ + SerializedBaseLoyaltyAccount: SerializedBaseLoyaltyAccount{ + PhoneNumber: "89151005004", + CustomFields: []string{"dog"}, + }, + Customer: SerializedEntityCustomer{ + ID: 123, + }, + } +} + +func getLoyaltyAccountCreateResponse() CreateLoyaltyAccountResponse { + return CreateLoyaltyAccountResponse{ + SuccessfulResponse: SuccessfulResponse{Success: true}, + LoyaltyAccount: LoyaltyAccount{ + Active: true, + ID: 13, + PhoneNumber: "89151005004", + LoyaltyLevel: LoyaltyLevel{}, + CreatedAt: "2022-11-24 12:39:37", + ActivatedAt: "2022-11-24 12:39:37", + CustomFields: []string{"dog"}, + }, + } +} + +func getLoyaltyAccountEditResponse() EditLoyaltyAccountResponse { + return EditLoyaltyAccountResponse{ + SuccessfulResponse: SuccessfulResponse{Success: true}, + LoyaltyAccount: LoyaltyAccount{ + Active: true, + ID: 13, + PhoneNumber: "89142221020", + LoyaltyLevel: LoyaltyLevel{}, + CreatedAt: "2022-11-24 12:39:37", + ActivatedAt: "2022-11-24 12:39:37", + CustomFields: []string{"dog"}, + }, + } +} + +func getLoyaltyAccountResponse() string { + return `{ + "success": true, + "loyaltyAccount": { + "active": true, + "id": 13, + "loyalty": { + "id": 2 + }, + "customer": { + "id": 123, + "customFields": [], + "firstName": "Руслан1", + "lastName": "Ефанов", + "patronymic": "" + }, + "phoneNumber": "89142221020", + "amount": 0, + "ordersSum": 0, + "nextLevelSum": 10000, + "level": { + "type": "bonus_percent", + "id": 5, + "name": "Новичок", + "sum": 0, + "privilegeSize": 5, + "privilegeSizePromo": 3 + }, + "createdAt": "2022-11-24 12:39:37", + "activatedAt": "2022-11-24 12:39:37", + "status": "activated", + "customFields": [] + } + }` +} + +func getBonusDetailsResponse() string { + return `{ + "success": true, + "pagination": { + "limit": 20, + "totalCount": 41, + "currentPage": 3, + "totalPageCount": 3 + }, + "statistic": { + "totalAmount": 240 + }, + "bonuses": [ + { + "date": "2022-12-08", + "amount": 240 + } + ] + }` +} + +func getLoyaltyAccountsResponse() string { + return `{ + "success": true, + "pagination": { + "limit": 20, + "totalCount": 1, + "currentPage": 1, + "totalPageCount": 1 + }, + "loyaltyAccounts": [ + { + "active": true, + "id": 14, + "loyalty": { + "id": 2 + }, + "customer": { + "id": 109, + "firstName": "Казимир", + "lastName": "Эльбрусов" + }, + "phoneNumber": "89185556363", + "amount": 0, + "ordersSum": 0, + "nextLevelSum": 10000, + "level": { + "type": "bonus_percent", + "id": 5, + "name": "Новичок", + "sum": 0, + "privilegeSize": 5, + "privilegeSizePromo": 3 + }, + "createdAt": "2022-12-07 15:27:04", + "activatedAt": "2022-12-07 15:27:04", + "status": "activated" + } + ] + }` +} + +func getLoyaltyCalculateReq() LoyaltyCalculateRequest { + return LoyaltyCalculateRequest{ + Site: "main", + Order: Order{ + PrivilegeType: "loyalty_level", + Customer: &Customer{ + ID: 123, + }, + Items: []OrderItem{ + { + InitialPrice: 10000, + Quantity: 1, + Offer: Offer{ID: 214}, + PriceType: &PriceType{Code: "base"}, + }, + }, + }, + Bonuses: 10, + } +} + +func getLoyaltyCalculateResponse() string { + return `{ + "success": true, + "order": { + "bonusesCreditTotal": 999, + "bonusesChargeTotal": 10, + "privilegeType": "loyalty_level", + "totalSumm": 9990, + "loyaltyAccount": { + "id": 13, + "amount": 240 + }, + "loyaltyLevel": { + "id": 6, + "name": "Любитель" + }, + "customer": { + "id": 123, + "personalDiscount": 0 + }, + "delivery": { + "cost": 0 + }, + "site": "main", + "items": [ + { + "bonusesChargeTotal": 10, + "bonusesCreditTotal": 999, + "priceType": { + "code": "base" + }, + "initialPrice": 10000, + "discounts": [ + { + "type": "bonus_charge", + "amount": 10 + } + ], + "discountTotal": 10, + "prices": [ + { + "price": 9990, + "quantity": 1 + } + ], + "quantity": 1, + "offer": { + "xmlId": "696999ed-bc8d-4d0f-9627-527acf7b1d57" + } + } + ] + }, + "calculations": [ + { + "privilegeType": "loyalty_level", + "discount": 10, + "creditBonuses": 999, + "maxChargeBonuses": 240, + "maximum": true + }, + { + "privilegeType": "none", + "discount": 10, + "creditBonuses": 0, + "maxChargeBonuses": 240, + "maximum": false + } + ], + "loyalty": { + "name": "Бонусная программа", + "chargeRate": 1 + } + }` +} + +func getLoyaltiesResponse() string { + return `{ + "success": true, + "pagination": { + "limit": 20, + "totalCount": 1, + "currentPage": 1, + "totalPageCount": 1 + }, + "loyalties": [ + { + "levels": [ + { + "type": "bonus_percent", + "id": 5, + "name": "Новичок", + "sum": 0, + "privilegeSize": 5, + "privilegeSizePromo": 3 + }, + { + "type": "bonus_percent", + "id": 6, + "name": "Любитель", + "sum": 10000, + "privilegeSize": 10, + "privilegeSizePromo": 5 + }, + { + "type": "bonus_percent", + "id": 7, + "name": "Продвинутый покупатель", + "sum": 25000, + "privilegeSize": 15, + "privilegeSizePromo": 7 + }, + { + "type": "bonus_percent", + "id": 8, + "name": "Мастер шоппинга", + "sum": 50000, + "privilegeSize": 20, + "privilegeSizePromo": 10 + } + ], + "active": true, + "blocked": false, + "id": 2, + "name": "Бонусная программа", + "confirmSmsCharge": false, + "confirmSmsRegistration": false, + "createdAt": "2022-01-18 15:40:22", + "activatedAt": "2022-12-08 12:05:45" + } + ] + }` +} + +func getLoyaltyResponse() string { + return `{ + "success": true, + "loyalty": { + "levels": [ + { + "type": "bonus_percent", + "id": 5, + "name": "Новичок", + "sum": 0, + "privilegeSize": 5, + "privilegeSizePromo": 3 + }, + { + "type": "bonus_percent", + "id": 6, + "name": "Любитель", + "sum": 10000, + "privilegeSize": 10, + "privilegeSizePromo": 5 + }, + { + "type": "bonus_percent", + "id": 7, + "name": "Продвинутый покупатель", + "sum": 25000, + "privilegeSize": 15, + "privilegeSizePromo": 7 + }, + { + "type": "bonus_percent", + "id": 8, + "name": "Мастер шоппинга", + "sum": 50000, + "privilegeSize": 20, + "privilegeSizePromo": 10 + } + ], + "active": true, + "blocked": false, + "id": 2, + "name": "Бонусная программа", + "confirmSmsCharge": false, + "confirmSmsRegistration": false, + "createdAt": "2022-01-18 15:40:22", + "activatedAt": "2022-12-08 12:05:45" + } +}` +} diff --git a/types.go b/types.go index 4263439..1144f38 100644 --- a/types.go +++ b/types.go @@ -328,6 +328,8 @@ type Order struct { Items []OrderItem `json:"items,omitempty"` CustomFields StringMap `json:"customFields,omitempty"` Payments OrderPayments `json:"payments,omitempty"` + ApplyRound *bool `json:"applyRound,omitempty"` + PrivilegeType string `json:"privilegeType,omitempty"` } // OrdersStatus type. @@ -703,6 +705,21 @@ type WorkTime struct { LunchEndTime string `json:"lunch_end_time"` } +type SerializedBaseLoyaltyAccount struct { + PhoneNumber string `json:"phoneNumber,omitempty"` + CardNumber string `json:"cardNumber,omitempty"` + CustomFields []string `json:"customFields,omitempty"` +} + +type SerializedCreateLoyaltyAccount struct { + SerializedBaseLoyaltyAccount + Customer SerializedEntityCustomer `json:"customer"` +} + +type SerializedEditLoyaltyAccount struct { + SerializedBaseLoyaltyAccount +} + // Settings type. Contains retailCRM configuration. type Settings struct { DefaultCurrency SettingsNode `json:"default_currency"` @@ -758,17 +775,23 @@ type DeliveryService struct { // DeliveryType type. type DeliveryType struct { - Name string `json:"name,omitempty"` - Code string `json:"code,omitempty"` - Active bool `json:"active,omitempty"` - DefaultCost float32 `json:"defaultCost,omitempty"` - DefaultNetCost float32 `json:"defaultNetCost,omitempty"` - Description string `json:"description,omitempty"` - IntegrationCode string `json:"integrationCode,omitempty"` - VatRate string `json:"vatRate,omitempty"` - DefaultForCrm bool `json:"defaultForCrm,omitempty"` - DeliveryServices []string `json:"deliveryServices,omitempty"` - PaymentTypes []string `json:"paymentTypes,omitempty"` + Name string `json:"name,omitempty"` + Code string `json:"code,omitempty"` + Active bool `json:"active,omitempty"` + DefaultCost float32 `json:"defaultCost,omitempty"` + DefaultNetCost float32 `json:"defaultNetCost,omitempty"` + Description string `json:"description,omitempty"` + IntegrationCode string `json:"integrationCode,omitempty"` + VatRate string `json:"vatRate,omitempty"` + DefaultForCrm bool `json:"defaultForCrm,omitempty"` + DeliveryServices []string `json:"deliveryServices,omitempty"` + PaymentTypes []string `json:"paymentTypes,omitempty"` // Deprecated, use DeliveryPaymentTypes + DeliveryPaymentTypes []DeliveryPaymentType `json:"deliveryPaymentTypes,omitempty"` +} + +type DeliveryPaymentType struct { + Code string `json:"code"` + Cod bool `json:"cod,omitempty"` } // LegalEntity type. @@ -793,6 +816,11 @@ type LegalEntity struct { BankAccount string `json:"bankAccount,omitempty"` } +type SerializedEntityCustomer struct { + ID int `json:"id,omitempty"` + ExternalID int `json:"externalId,omitempty"` +} + // OrderMethod type. type OrderMethod struct { Name string `json:"name,omitempty"` @@ -883,21 +911,24 @@ type StatusGroup struct { // Site type. type Site struct { - Name string `json:"name,omitempty"` - Code string `json:"code,omitempty"` - URL string `json:"url,omitempty"` - Description string `json:"description,omitempty"` - Phones string `json:"phones,omitempty"` - Zip string `json:"zip,omitempty"` - Address string `json:"address,omitempty"` - CountryIso string `json:"countryIso,omitempty"` - YmlURL string `json:"ymlUrl,omitempty"` - LoadFromYml bool `json:"loadFromYml,omitempty"` - CatalogUpdatedAt string `json:"catalogUpdatedAt,omitempty"` - CatalogLoadingAt string `json:"catalogLoadingAt,omitempty"` - Contragent *LegalEntity `json:"contragent,omitempty"` - DefaultForCRM bool `json:"defaultForCrm,omitempty"` - Ordering int `json:"ordering,omitempty"` + Name string `json:"name,omitempty"` + Code string `json:"code,omitempty"` + URL string `json:"url,omitempty"` + Description string `json:"description,omitempty"` + Phones string `json:"phones,omitempty"` + Zip string `json:"zip,omitempty"` + Address string `json:"address,omitempty"` + CountryIso string `json:"countryIso,omitempty"` + YmlURL string `json:"ymlUrl,omitempty"` + LoadFromYml bool `json:"loadFromYml,omitempty"` + CatalogUpdatedAt string `json:"catalogUpdatedAt,omitempty"` + CatalogLoadingAt string `json:"catalogLoadingAt,omitempty"` + Contragent *LegalEntity `json:"contragent,omitempty"` + DefaultForCRM bool `json:"defaultForCrm,omitempty"` + Ordering int `json:"ordering,omitempty"` + IsDemo bool `json:"isDemo,omitempty"` + CatalogID string `json:"catalogId,omitempty"` + IsCatalogMainSite bool `json:"isCatalogMainSite,omitempty"` } // Store type. @@ -917,34 +948,65 @@ type Store struct { // ProductGroup type. type ProductGroup struct { - ID int `json:"id,omitempty"` - ParentID int `json:"parentId,omitempty"` - Name string `json:"name,omitempty"` - Site string `json:"site,omitempty"` - Active bool `json:"active,omitempty"` + ID int `json:"id,omitempty"` + ParentID int `json:"parentId,omitempty"` + Name string `json:"name,omitempty"` + Site string `json:"site,omitempty"` + Active bool `json:"active,omitempty"` + Description string `json:"description,omitempty"` + ExternalID string `json:"externalId,omitempty"` + ParentExternalID string `json:"parentExternalId,omitempty"` +} + +// BaseProduct type. +type BaseProduct struct { + Name string `json:"name,omitempty"` + URL string `json:"url,omitempty"` + Article string `json:"article,omitempty"` + ExternalID string `json:"externalId,omitempty"` + Manufacturer string `json:"manufacturer,omitempty"` + Description string `json:"description,omitempty"` + Popular bool `json:"popular,omitempty"` + Stock bool `json:"stock,omitempty"` + Novelty bool `json:"novelty,omitempty"` + Recommended bool `json:"recommended,omitempty"` + Active bool `json:"active,omitempty"` + Markable bool `json:"markable,omitempty"` } // Product type. type Product struct { - ID int `json:"id,omitempty"` - MaxPrice float32 `json:"maxPrice,omitempty"` - MinPrice float32 `json:"minPrice,omitempty"` - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` - Article string `json:"article,omitempty"` - ExternalID string `json:"externalId,omitempty"` - Manufacturer string `json:"manufacturer,omitempty"` - ImageURL string `json:"imageUrl,omitempty"` - Description string `json:"description,omitempty"` - Popular bool `json:"popular,omitempty"` - Stock bool `json:"stock,omitempty"` - Novelty bool `json:"novelty,omitempty"` - Recommended bool `json:"recommended,omitempty"` - Active bool `json:"active,omitempty"` - Quantity float32 `json:"quantity,omitempty"` - Offers []Offer `json:"offers,omitempty"` - Groups []ProductGroup `json:"groups,omitempty"` - Properties StringMap `json:"properties,omitempty"` + BaseProduct + ID int `json:"id,omitempty"` + MaxPrice float32 `json:"maxPrice,omitempty"` + MinPrice float32 `json:"minPrice,omitempty"` + ImageURL string `json:"imageUrl,omitempty"` + Quantity float32 `json:"quantity,omitempty"` + Offers []Offer `json:"offers,omitempty"` + Properties StringMap `json:"properties,omitempty"` + Groups []ProductGroup `json:"groups,omitempty"` +} + +// ProductEditGroupInput type. +type ProductEditGroupInput struct { + ID int `json:"id"` + ExternalID int `json:"externalId,omitempty"` +} + +// ProductCreate type. +type ProductCreate struct { + BaseProduct + Groups []ProductEditGroupInput `json:"groups,omitempty"` + CatalogID int `json:"catalogId,omitempty"` +} + +// ProductEdit type. +type ProductEdit struct { + BaseProduct + ID int `json:"id,omitempty"` + CatalogID int `json:"catalogId,omitempty"` + Site string `json:"site,omitempty"` + Groups []ProductEditGroupInput `json:"groups,omitempty"` } // DeliveryHistoryRecord type. @@ -1022,9 +1084,11 @@ type Delivery struct { // DeliveryStatus type. type DeliveryStatus struct { - Code string `json:"code,omitempty"` - Name string `json:"name,omitempty"` - IsEditable bool `json:"isEditable,omitempty"` + Code string `json:"code,omitempty"` + Name string `json:"name,omitempty"` + IsEditable bool `json:"isEditable,omitempty"` + IsError bool `json:"isError,omitempty"` + IsPreprocessing bool `json:"isPreprocessing,omitempty"` } // Plate type. @@ -1230,3 +1294,140 @@ type OperationLoyalty struct { type CursorPagination struct { NextCursor string `json:"nextCursor,omitempty"` } + +// DeliveryTypeInfo type. +type DeliveryTypeInfo struct { + ID int `json:"id"` + Code string `json:"code"` +} + +// LoyaltyAccount type. +type LoyaltyAccount struct { + Active bool `json:"active"` + ID int `json:"id"` + PhoneNumber string `json:"phoneNumber,omitempty"` + CardNumber string `json:"cardNumber,omitempty"` + Amount float64 `json:"amount,omitempty"` + LoyaltyLevel LoyaltyLevel `json:"level,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + ActivatedAt string `json:"activatedAt,omitempty"` + ConfirmedPhoneAt string `json:"confirmedPhoneAt,omitempty"` + LastCheckID int `json:"lastCheckId,omitempty"` + CustomFields []string `json:"customFields,omitempty"` + Loyalty Loyalty `json:"loyalty,omitempty"` + Customer Customer `json:"customer,omitempty"` + Status string `json:"status,omitempty"` + OrderSum float64 `json:"orderSum,omitempty"` + NextLevelSum float64 `json:"nextLevelSum,omitempty"` +} + +// Loyalty type. +type Loyalty struct { + ID int `json:"id"` + LoyaltyLevels []LoyaltyLevel `json:"levels,omitempty"` + Active bool `json:"active,omitempty"` + Blocked bool `json:"blocked,omitempty"` + Name string `json:"name,omitempty"` + ConfirmSmsCharge bool `json:"confirmSmsCharge,omitempty"` + ConfirmSmsRegistration bool `json:"confirmSmsRegistration,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + ActivatedAt string `json:"activatedAt,omitempty"` + DeactivatedAt string `json:"deactivatedAt,omitempty"` + BlockedAt string `json:"blockedAt,omitempty"` +} + +// LoyaltyLevel type. +type LoyaltyLevel struct { + ID int `json:"id"` + Name string `json:"name"` + Type string `json:"type,omitempty"` + Sum float64 `json:"sum,omitempty"` + PrivilegeSize float64 `json:"privilegeSize,omitempty"` + PrivilegeSizePromo float64 `json:"privilegeSizePromo,omitempty"` +} + +type SmsVerification struct { + CreatedAt string `json:"createdAt"` + ExpiredAt string `json:"expiredAt"` + VerifiedAt string `json:"verifiedAt"` + CheckID string `json:"checkId"` + ActionType string `json:"actionType"` +} + +type LoyaltyBonus struct { + Amount float32 `json:"amount"` + ActivationDate string `json:"activationDate"` + ExpiredDate string `json:"expiredDate,omitempty"` +} + +type BonusDetail struct { + Date string `json:"date"` + Amount float32 `json:"amount"` +} + +type SerializedLoyaltyOrder struct { + BonusesCreditTotal float32 `json:"bonusesCreditTotal,omitempty"` + BonusesChargeTotal float32 `json:"bonusesChargeTotal,omitempty"` + PrivilegeType string `json:"privilegeType,omitempty"` + TotalSumm float64 `json:"totalSumm,omitempty"` + PersonalDiscountPercent float32 `json:"personalDiscountPercent,omitempty"` + LoyaltyAccount LoyaltyAccount `json:"loyaltyAccount"` + LoyaltyEventDiscount LoyaltyEventDiscount `json:"loyaltyEventDiscount,omitempty"` + Customer Customer `json:"customer"` + Delivery Delivery `json:"delivery,omitempty"` + Site string `json:"site,omitempty"` + Items []LoyaltyItems `json:"items,omitempty"` +} + +type LoyaltyEventDiscount struct { + ID int `json:"id"` +} + +type LoyaltyItems struct { + BonusesChargeTotal float32 `json:"bonusesChargeTotal,omitempty"` + BonusesCreditTotal float32 `json:"bonusesCreditTotal,omitempty"` + ID int `json:"id,omitempty"` + ExternalIds []CodeValueModel `json:"externalIds,omitempty"` + PriceType PriceType `json:"priceType,omitempty"` + InitialPrice float32 `json:"initialPrice,omitempty"` + Discounts []AbstractDiscount `json:"discounts,omitempty"` + Prices []OrderProductPriceItem `json:"prices,omitempty"` + VatRate string `json:"vatRate,omitempty"` + CreatedAt string `json:"createdAt"` + Quantity float32 `json:"quantity"` + Offer Offer `json:"offer,omitempty"` +} + +type CodeValueModel struct { + Code string `json:"code"` + Value string `json:"value,omitempty"` +} + +type AbstractDiscount struct { + Type string `json:"type"` + Amount float32 `json:"amount"` +} + +type OrderProductPriceItem struct { + Price float64 `json:"price"` + Quantity float32 `json:"quantity"` +} + +type LoyaltyCalculation struct { + PrivilegeType string `json:"privilegeType"` + Discount float32 `json:"discount"` + CreditBonuses float32 `json:"creditBonuses"` + LoyaltyEventDiscount LoyaltyEventDiscount `json:"loyaltyEventDiscount,omitempty"` + MaxChargeBonuses float32 `json:"maxChargeBonuses,omitempty"` + Maximum *bool `json:"maximum,omitempty"` + Loyalty SerializedLoyalty `json:"loyalty,omitempty"` +} + +type SerializedLoyalty struct { + Name string `json:"name"` + ChargeRate float32 `json:"chargeRate"` +} + +type ExternalID struct { + ExternalID string `json:"externalId,omitempty"` +}