Compare commits

..

No commits in common. "master" and "v1.1.2" have entirely different histories.

37 changed files with 11049 additions and 20904 deletions

View file

@ -1,79 +0,0 @@
name: ci
on:
push:
branches:
- '**'
tags-ignore:
- '*.*'
pull_request:
env:
RETAILCRM_URL: https://test.retailcrm.pro
RETAILCRM_KEY: key
jobs:
golangci:
name: lint
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Set up Go 1.23
uses: actions/setup-go@v3
with:
go-version: '1.23'
- name: Get dependencies
run: |
go mod tidy
cp .env.dist .env
- name: Lint code with golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.62.2
only-new-issues: true
skip-pkg-cache: true
args: --build-tags=testutils
tests:
name: Tests
runs-on: ubuntu-latest
strategy:
matrix:
go-version: ['1.19', '1.20', '1.21', '1.22', '1.23', 'stable']
include:
- go-version: '1.23'
coverage: 1
steps:
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Get dependencies
run: |
go mod tidy
cp .env.dist .env
- name: Tests
env:
COVERAGE: ${{ matrix.coverage }}
if: env.COVERAGE != 1
run: |
go install gotest.tools/gotestsum@latest
gotestsum --format testdox ./... -tags=testutils -v -cpu 2 -timeout 60s -race
- name: Tests with coverage
env:
COVERAGE: ${{ matrix.coverage }}
if: env.COVERAGE == 1
run: |
go install gotest.tools/gotestsum@latest
gotestsum --format testdox ./... -tags=testutils -v -cpu 2 -timeout 60s -race -cover -coverprofile=coverage.txt -covermode=atomic "$d"
- name: Coverage
env:
COVERAGE: ${{ matrix.coverage }}
if: env.COVERAGE == 1
run: |
go install github.com/axw/gocov/gocov@latest
gocov convert ./coverage.txt | gocov report
bash <(curl -s https://codecov.io/bash)

3
.gitignore vendored
View file

@ -5,7 +5,6 @@
# Folders
_obj
vendor
# Architecture specific extensions/prefixes
*.[568vq]
@ -22,12 +21,10 @@ _testmain.go
*.exe
*.test
*.prof
coverage.txt
# IDE's files
.idea
*.iml
.env
.swp
# Project ignores

View file

@ -1,213 +0,0 @@
run:
skip-dirs-use-default: true
allow-parallel-runners: true
issues:
exclude-files:
- testutils.go
exclude-rules:
- path: _test\.go
linters:
- lll
- errcheck
- misspell
- ineffassign
- whitespace
- makezero
- errcheck
- funlen
- goconst
- gocognit
- gocyclo
- godot
- unused
- errchkjson
- varnamelen
exclude-use-default: true
exclude-case-sensitive: false
max-issues-per-linter: 0
max-same-issues: 0
fix: true
output:
formats:
- format: colored-line-number
sort-results: true
# Linters below do not support go1.18 yet because of generics.
# See https://github.com/golangci/golangci-lint/issues/2649
# - bodyclose
# - sqlclosecheck
linters:
disable-all: true
enable:
- asciicheck
- asasalint
- varnamelen
- reassign
- nilnil
- nilerr
- nakedret
- goprintffuncname
- typecheck
- errchkjson
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused
- unparam
- dogsled
- dupl
- errorlint
- exhaustive
- exportloopref
- copyloopvar
- funlen
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- goimports
- revive
- gosec
- lll
- makezero
- misspell
- nestif
- prealloc
- predeclared
- unconvert
- whitespace
linters-settings:
govet:
check-shadowing: false
disable-all: true
enable:
- assign
- atomic
- atomicalign
- bools
- buildtag
- copylocks
- httpresponse
- loopclosure
- lostcancel
- printf
- shift
- stdmethods
- structtag
- tests
- unmarshal
- unreachable
- unsafeptr
settings:
printf:
funcs:
- (*log.Logger).Fatal
- (*log.Logger).Fatalf
- (*log.Logger).Fatalln
- (*log.Logger).Panic
- (*log.Logger).Panicf
- (*log.Logger).Panicln
- (*log.Logger).Print
- (*log.Logger).Printf
- (*log.Logger).Println
- (*testing.common).Error
- (*testing.common).Errorf
- (*testing.common).Fatal
- (*testing.common).Fatalf
- (*testing.common).Log
- (*testing.common).Logf
- (*testing.common).Skip
- (*testing.common).Skipf
- (testing.TB).Error
- (testing.TB).Errorf
- (testing.TB).Fatal
- (testing.TB).Fatalf
- (testing.TB).Log
- (testing.TB).Logf
- (testing.TB).Skip
- (testing.TB).Skipf
- fmt.Errorf
- fmt.Fprint
- fmt.Fprintf
- fmt.Fprintln
- fmt.Print
- fmt.Printf
- fmt.Println
- fmt.Sprint
- fmt.Sprintf
- fmt.Sprintln
- log.Fatal
- log.Fatalf
- log.Fatalln
- log.Panic
- log.Panicf
- log.Panicln
- log.Print
- log.Printf
- log.Println
- runtime/trace.Logf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Fatalf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Panicf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Panicf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Criticalf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Errorf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Warningf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Noticef
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Infof
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Debugf
unused:
check-exported: false
unparam:
check-exported: false
dogsled:
max-blank-identifiers: 3
dupl:
threshold: 200
errorlint:
errorf: true
asserts: false
comparison: false
exhaustive:
check-generated: false
default-signifies-exhaustive: false
funlen:
lines: 90
statements: 40
gocognit:
min-complexity: 25
gocyclo:
min-complexity: 25
goimports:
local-prefixes: github.com/retailcrm/api-client-go/v2
lll:
line-length: 160
misspell:
locale: US
nestif:
min-complexity: 4
whitespace:
multi-if: false
multi-func: false
varnamelen:
max-distance: 10
ignore-map-index-ok: true
ignore-type-assert-ok: true
ignore-chan-recv-ok: true
ignore-decls:
- t *testing.T
- e error
- i int
severity:
default-severity: error
case-sensitive: false
service:
golangci-lint-version: 1.62.x

11
.travis.yml Normal file
View file

@ -0,0 +1,11 @@
language: go
go:
- '1.8'
- '1.9'
- '1.10'
- '1.11'
before_install:
- go get -v github.com/google/go-querystring/query
- go get -v github.com/h2non/gock
- cp .env.dist .env
script: go test -v ./...

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015-2020 RetailDriver LLC
Copyright (c) 2015-2018 RetailDriver LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

128
README.md
View file

@ -1,60 +1,58 @@
[![Build Status](https://github.com/retailcrm/api-client-go/workflows/ci/badge.svg)](https://github.com/retailcrm/api-client-go/actions)
[![Covarage](https://img.shields.io/codecov/c/gh/retailcrm/api-client-go/master.svg?logo=codecov&logoColor=white)](https://codecov.io/gh/retailcrm/api-client-go)
[![GitHub release](https://img.shields.io/github/release/retailcrm/api-client-go.svg?logo=github&logoColor=white)](https://github.com/retailcrm/api-client-go/releases)
[![Go Report Card](https://goreportcard.com/badge/github.com/retailcrm/api-client-go)](https://goreportcard.com/report/github.com/retailcrm/api-client-go)
[![GoLang version](https://img.shields.io/badge/go->=1.8-blue)](https://golang.org/dl/)
[![pkg.go.dev](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/retailcrm/api-client-go)
[![Build Status](https://img.shields.io/travis/retailcrm/api-client-go/master.svg?logo=travis&style=flat-square)](https://travis-ci.org/retailcrm/api-client-go)
[![GitHub release](https://img.shields.io/github/release/retailcrm/api-client-go.svg?style=flat-square)](https://github.com/retailcrm/api-client-go/releases)
[![GoLang version](https://img.shields.io/badge/go-1.8%2C%201.9%2C%201.10-blue.svg?style=flat-square)](https://golang.org/dl/)
[![Godoc reference](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/retailcrm/api-client-go)
# RetailCRM API Go client
# retailCRM API Go client
This is golang RetailCRM API client.
This is golang retailCRM API client.
## Installation
## Install
```bash
go get -u github.com/retailcrm/api-client-go/v2
go get -x github.com/retailcrm/api-client-go
```
## Usage
Example:
```go
```golang
package main
import (
"log"
"fmt"
"net/http"
"github.com/retailcrm/api-client-go/v2"
"github.com/retailcrm/api-client-go/v5"
)
func main() {
var client = retailcrm.New("https://demo.retailcrm.pro", "09jIJ09j0JKhgyfvyuUIKhiugF")
var client = v5.New("https://demo.retailcrm.pro", "09jIJ09j0JKhgyfvyuUIKhiugF")
data, status, err := client.Orders(retailcrm.OrdersRequest{
Filter: retailcrm.OrdersFilter{},
data, status, err := client.Orders(v5.OrdersRequest{
Filter: v5.OrdersFilter{},
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.RuntimeErr != nil {
fmt.Printf("%v", err.Error())
}
log.Fatalf("http status: %d, error: %s", status, err)
if status >= http.StatusBadRequest {
fmt.Printf("%v", err.ApiError())
}
for _, value := range data.Orders {
log.Printf("%v\n", value.Email)
fmt.Printf("%v\n", value.Email)
}
log.Println(data.Orders[1].FirstName)
fmt.Println(data.Orders[1].FirstName)
inventories, status, err := client.InventoriesUpload([]retailcrm.InventoryUpload{
idata, status, err := c.InventoriesUpload(
[]InventoryUpload{
{
XMLID: "pTKIKAeghYzX21HTdzFCe1",
Stores: []retailcrm.InventoryUploadStore{
Stores: []InventoryUploadStore{
{
Code: "test-store-v5",
Available: 10,
@ -74,7 +72,7 @@ func main() {
},
{
XMLID: "JQIvcrCtiSpOV3AAfMiQB3",
Stores: []retailcrm.InventoryUploadStore{
Stores: []InventoryUploadStore{
{
Code: "test-store-v5",
Available: 45,
@ -94,71 +92,19 @@ func main() {
},
},
)
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.RuntimeErr != nil {
fmt.Printf("%v", err.Error())
}
log.Println(inventories.ProcessedOffersCount)
if status >= http.StatusBadRequest {
fmt.Printf("%v", err.ApiError())
}
fmt.Println(idata.processedOffersCount)
}
```
You can use different error types and `retailcrm.AsAPIError` to process client errors. Example:
## Documentation
```go
package retailcrm
import (
"errors"
"log"
"os"
"strings"
"github.com/retailcrm/api-client-go/v2"
)
func main() {
var client = retailcrm.New("https://demo.retailcrm.pro", "09jIJ09j0JKhgyfvyuUIKhiugF")
resp, status, err := client.APICredentials()
if err != nil {
apiErr, ok := retailcrm.AsAPIError(err)
if !ok {
log.Fatalf("http status: %d, error: %s", status, err)
}
switch {
case errors.Is(apiErr, retailcrm.ErrMissingCredentials):
log.Fatalln("No API key provided.")
case errors.Is(apiErr, retailcrm.ErrInvalidCredentials):
log.Fatalln("Invalid API key.")
case errors.Is(apiErr, retailcrm.ErrAccessDenied):
log.Fatalln("Access denied. Please check that the provided key has access to the credentials info.")
case errors.Is(apiErr, retailcrm.ErrAccountDoesNotExist):
log.Fatalln("There is no RetailCRM at the provided URL.")
case errors.Is(apiErr, retailcrm.ErrMissingParameter):
// retailcrm.APIError in this case will always contain "Name" key in the errors list with the parameter name.
log.Fatalln("This parameter should be present:", apiErr.Errors()["Name"])
case errors.Is(apiErr, retailcrm.ErrValidation):
log.Println("Validation errors from the API:")
for name, value := range apiErr.Errors() {
log.Printf(" - %s: %s\n", name, value)
}
os.Exit(1)
case errors.Is(apiErr, retailcrm.ErrGeneric):
log.Fatalf("failure from the API. %s", apiErr.String())
}
}
log.Println("Available scopes:", strings.Join(resp.Scopes, ", "))
}
```
## Upgrading
Please check the [UPGRADING.md](UPGRADING.md) to learn how to upgrade to the new version.
* [English](http://www.retailcrm.pro/docs/Developers/Index)
* [Russian](http://www.retailcrm.ru/docs/Developers/Index)

View file

@ -1,70 +0,0 @@
# Upgrading to the v2
### Install the new version
```bash
go get -u github.com/retailcrm/api-client-go/v2
```
### Update all imports
Before:
```go
package main
import v5 "github.com/retailcrm/api-client-go/v5"
```
After:
```go
package main
import "github.com/retailcrm/api-client-go/v2"
```
You can use package alias `v5` to skip the second step.
### Replace package name for all imported symbols
Before:
```go
package main
import v5 "github.com/retailcrm/api-client-go/v5"
func main() {
client := v5.New("https://test.retailcrm.pro", "key")
data, status, err := client.Orders(v5.OrdersRequest{
Filter: v5.OrdersFilter{
City: "Moscow",
},
Page: 1,
})
...
}
```
After:
```go
package main
import "github.com/retailcrm/api-client-go/v2"
func main() {
client := retailcrm.New("https://test.retailcrm.pro", "key")
data, status, err := client.Orders(retailcrm.OrdersRequest{
Filter: retailcrm.OrdersFilter{
City: "Moscow",
},
Page: 1,
})
...
}
```
### Upgrade client usages
This major release contains some breaking changes regarding field names and fully redesigned error handling. Use the second example from
the readme to learn how to process errors correctly.

7224
client.go

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,8 +0,0 @@
package retailcrm
var UserGroupSuperadmins UserGroupType = "superadmins"
var (
NotificationTypeError NotificationType = "api.error"
NotificationTypeInfo NotificationType = "api.info"
)

194
error.go
View file

@ -1,194 +0,0 @@
package retailcrm
import (
"encoding/json"
"fmt"
"regexp"
"strings"
)
var missingParameterMatcher = regexp.MustCompile(`^Parameter \'([\w\]\[\_\-]+)\' is missing$`)
var (
// ErrRateLimited will be returned if request was rate limited.
ErrRateLimited = NewAPIError("rate limit exceeded")
// ErrMissingCredentials will be returned if no API key was provided to the API.
ErrMissingCredentials = NewAPIError(`apiKey is missing`)
// ErrInvalidCredentials will be returned if provided API key is invalid.
ErrInvalidCredentials = NewAPIError(`wrong "apiKey" value`)
// ErrAccessDenied will be returned in case of "Access denied" error.
ErrAccessDenied = NewAPIError("access denied")
// ErrAccountDoesNotExist will be returned if target system does not exist.
ErrAccountDoesNotExist = NewAPIError("account does not exist")
// ErrValidation will be returned in case of validation errors.
ErrValidation = NewAPIError("validation error")
// ErrMissingParameter will be returned if parameter is missing.
// Underlying error messages list will contain parameter name in the "Name" key.
ErrMissingParameter = NewAPIError("missing parameter")
// ErrGeneric will be returned if error cannot be classified as one of the errors above.
ErrGeneric = NewAPIError("API error")
)
// APIErrorsList struct.
type APIErrorsList map[string]string
// APIError returns when an API error was occurred.
type APIError interface {
error
fmt.Stringer
withWrapped(error) APIError
withErrors(APIErrorsList) APIError
Unwrap() error
Errors() APIErrorsList
}
type apiError struct {
ErrorMsg string `json:"errorMsg,omitempty"`
ErrorsList APIErrorsList `json:"errors,omitempty"`
wrapped error
}
// CreateAPIError from the provided response data. Different error types will be returned depending on the response,
// all of them can be matched using errors.Is. APi errors will always implement APIError interface.
func CreateAPIError(dataResponse []byte) error {
a := &apiError{}
if len(dataResponse) > 0 && dataResponse[0] == '<' {
return ErrAccountDoesNotExist
}
if err := json.Unmarshal(dataResponse, &a); err != nil {
return err
}
var found APIError
switch a.ErrorMsg {
case `"apiKey" is missing.`:
found = ErrMissingCredentials
case `Wrong "apiKey" value.`:
found = ErrInvalidCredentials
case "Access denied.":
found = ErrAccessDenied
case "Account does not exist.":
found = ErrAccountDoesNotExist
case "Errors in the entity format":
fallthrough
case "Validation error":
found = ErrValidation
default:
if param, ok := asMissingParameterErr(a.ErrorMsg); ok {
return a.withWrapped(ErrMissingParameter).withErrors(APIErrorsList{"Name": param})
}
found = ErrGeneric
}
result := NewAPIError(a.ErrorMsg).withWrapped(found)
if len(a.ErrorsList) > 0 {
return result.withErrors(a.ErrorsList)
}
return result
}
// CreateGenericAPIError for the situations when API response cannot be processed, but response was actually received.
func CreateGenericAPIError(message string) APIError {
return NewAPIError(message).withWrapped(ErrGeneric)
}
// NewAPIError returns API error with the provided message.
func NewAPIError(message string) APIError {
return &apiError{ErrorMsg: message}
}
// AsAPIError returns APIError and true if provided error is an APIError or contains wrapped APIError.
// Returns (nil, false) otherwise.
func AsAPIError(err error) (APIError, bool) {
apiErr := unwrapAPIError(err)
return apiErr, apiErr != nil
}
func unwrapAPIError(err error) APIError {
if err == nil {
return nil
}
if apiErr, ok := err.(APIError); ok { // nolint:errorlint
return apiErr
}
wrapper, ok := err.(interface { // nolint:errorlint
Unwrap() error
})
if ok {
return unwrapAPIError(wrapper.Unwrap())
}
return nil
}
// asMissingParameterErr returns true if "Parameter 'name' is missing" error message is provided.
func asMissingParameterErr(message string) (string, bool) {
matches := missingParameterMatcher.FindAllStringSubmatch(message, -1)
if len(matches) == 1 && len(matches[0]) == 2 {
return matches[0][1], true
}
return "", false
}
// Error returns errorMsg field from the response.
func (e *apiError) Error() string {
return e.ErrorMsg
}
// Unwrap returns wrapped error. It is usually one of the predefined types like ErrGeneric or ErrValidation.
// It can be used directly, but it's main purpose is to make errors matchable via errors.Is call.
func (e *apiError) Unwrap() error {
return e.wrapped
}
// Errors returns errors field from the response.
func (e *apiError) Errors() APIErrorsList {
return e.ErrorsList
}
// String returns string representation of an APIError.
func (e *apiError) String() string {
var sb strings.Builder
sb.Grow(256) // nolint:gomnd
sb.WriteString(fmt.Sprintf(`errorMsg: "%s"`, e.Error()))
if len(e.Errors()) > 0 {
i := 0
useIndex := true
errorList := make([]string, len(e.Errors()))
for index, errText := range e.Errors() {
if i == 0 && index == "0" {
useIndex = false
}
if useIndex {
errorList[i] = fmt.Sprintf(`%s: "%s"`, index, errText)
} else {
errorList[i] = errText
}
i++
}
sb.WriteString(", errors: [" + strings.Join(errorList, ", ") + "]")
}
return sb.String()
}
// withWrapped is a wrapped setter.
func (e *apiError) withWrapped(err error) APIError {
e.wrapped = err
return e
}
// withErrors is an ErrorsList setter.
func (e *apiError) withErrors(m APIErrorsList) APIError {
e.ErrorsList = m
return e
}

View file

@ -1,171 +0,0 @@
package retailcrm
import (
"testing"
"github.com/stretchr/testify/suite"
)
type ErrorTest struct {
suite.Suite
}
func TestError(t *testing.T) {
suite.Run(t, new(ErrorTest))
}
func (t *ErrorTest) TestFailure_ApiErrorsSlice() {
b := []byte(`{"success": false,
"errorMsg": "Failed to activate module",
"errors": [
"Your account has insufficient funds to activate integration module",
"Test error"
]}`)
expected := APIErrorsList{
"0": "Your account has insufficient funds to activate integration module",
"1": "Test error",
}
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().ErrorIs(e, ErrGeneric)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Assert().Equal(expected, apiErr.Errors())
}
func (t *ErrorTest) TestFailure_ApiErrorsMap() {
b := []byte(`{"success": false,
"errorMsg": "Failed to activate module",
"errors": {"id": "ID must be an integer", "test": "Test error"}}`,
)
expected := APIErrorsList{
"id": "ID must be an integer",
"test": "Test error",
}
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().ErrorIs(e, ErrGeneric)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Assert().Equal(expected, apiErr.Errors())
}
func (t *ErrorTest) TestFailure_APIKeyMissing() {
b := []byte(`{"success": false,
"errorMsg": "\"apiKey\" is missing."}`,
)
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Require().ErrorIs(e, ErrMissingCredentials)
}
func (t *ErrorTest) TestFailure_APIKeyWrong() {
b := []byte(`{"success": false,
"errorMsg": "Wrong \"apiKey\" value."}`,
)
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Require().ErrorIs(e, ErrInvalidCredentials)
}
func (t *ErrorTest) TestFailure_AccessDenied() {
b := []byte(`{"success": false,
"errorMsg": "Access denied."}`,
)
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Require().ErrorIs(e, ErrAccessDenied)
}
func (t *ErrorTest) TestFailure_AccountDoesNotExist() {
b := []byte(`{"success": false,
"errorMsg": "Account does not exist."}`,
)
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Require().ErrorIs(e, ErrAccountDoesNotExist)
}
func (t *ErrorTest) TestFailure_Validation() {
b := []byte(`{"success": false,
"errorMsg": "Errors in the entity format",
"errors": {"name": "name must be provided"}}`,
)
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Require().ErrorIs(e, ErrValidation)
t.Assert().Equal("name must be provided", apiErr.Errors()["name"])
}
func (t *ErrorTest) TestFailure_Validation2() {
b := []byte(`{"success": false,
"errorMsg": "Validation error",
"errors": {"name": "name must be provided"}}`,
)
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Require().ErrorIs(e, ErrValidation)
t.Assert().Equal("name must be provided", apiErr.Errors()["name"])
t.Assert().Equal("errorMsg: \"Validation error\", errors: [name: \"name must be provided\"]", apiErr.String())
}
func (t *ErrorTest) TestFailure_MissingParameter() {
b := []byte(`{"success": false,
"errorMsg": "Parameter 'item' is missing"}`,
)
e := CreateAPIError(b)
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Require().ErrorIs(e, ErrMissingParameter)
t.Assert().Equal("item", apiErr.Errors()["Name"])
}
func (t *ErrorTest) Test_CreateGenericAPIError() {
e := CreateGenericAPIError("generic error message")
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Assert().ErrorIs(apiErr, ErrGeneric)
t.Assert().Equal("generic error message", e.Error())
}
func (t *ErrorTest) TestFailure_HTML() {
e := CreateAPIError([]byte{'<'})
apiErr, ok := AsAPIError(e)
t.Require().NotNil(apiErr)
t.Require().True(ok)
t.Assert().ErrorIs(apiErr, ErrAccountDoesNotExist)
}

29
errs/error.go Normal file
View file

@ -0,0 +1,29 @@
package errs
import (
"encoding/json"
"fmt"
)
// Error returns the string representation of the error and satisfies the error interface.
func (f *Failure) Error() string {
return f.RuntimeErr.Error()
}
// ApiError returns formatted string representation of the API error
func (f *Failure) ApiError() string {
return fmt.Sprintf("%+v", f.ApiErr)
}
// ApiErrors returns array of formatted strings that represents API errors
func (f *Failure) ApiErrors() interface{} {
return f.ApiErrs
}
// ErrorResponse method
func ErrorResponse(data []byte) (FailureResponse, error) {
var resp FailureResponse
err := json.Unmarshal(data, &resp)
return resp, err
}

45
errs/error_test.go Normal file
View file

@ -0,0 +1,45 @@
package errs
import (
"testing"
)
func TestFailure_ApiErrorsSlice(t *testing.T) {
var err = Failure{}
b := []byte(`{"success": false, "errorMsg": "Failed to activate module", "errors": ["Your account has insufficient funds to activate integration module"]}`)
resp, e := ErrorResponse(b)
err.RuntimeErr = e
err.ApiErr = resp.ErrorMsg
if resp.Errors != nil {
err.ApiErrs = resp.Errors
}
f, ok := resp.Errors.([]interface{})
if !ok {
t.Errorf("%+v", f)
}
}
func TestFailure_ApiErrorsMap(t *testing.T) {
var err = Failure{}
b := []byte(`{"success": false, "errorMsg": "Failed to activate module", "errors": {"id": "ID must be an integer"}}`)
resp, e := ErrorResponse(b)
err.RuntimeErr = e
err.ApiErr = resp.ErrorMsg
if resp.Errors != nil {
err.ApiErrs = resp.Errors
}
f, ok := resp.Errors.(map[string]interface{})
if !ok {
t.Errorf("%+v", f)
}
}

8
errs/interfaces.go Normal file
View file

@ -0,0 +1,8 @@
package errs
// Error implements generic error interface
type Error interface {
error
ApiError() string
ApiErrors() interface{}
}

14
errs/types.go Normal file
View file

@ -0,0 +1,14 @@
package errs
// Failure struct implode runtime & api errors
type Failure struct {
RuntimeErr error
ApiErr string
ApiErrs interface{}
}
// FailureResponse convert json error response into object
type FailureResponse struct {
ErrorMsg string `json:"errorMsg,omitempty"`
Errors interface{} `json:"errors,omitempty"`
}

10
go.mod
View file

@ -1,10 +0,0 @@
module github.com/retailcrm/api-client-go/v2
go 1.13
require (
github.com/google/go-querystring v1.1.0
github.com/joho/godotenv v1.3.0
github.com/stretchr/testify v1.7.0
gopkg.in/h2non/gock.v1 v1.1.2
)

25
go.sum
View file

@ -1,25 +0,0 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

25
log.go
View file

@ -1,25 +0,0 @@
package retailcrm
// BasicLogger provides basic functionality for logging.
type BasicLogger interface {
Printf(string, ...interface{})
}
// DebugLogger can be used to easily wrap any logger with Debugf method into the BasicLogger instance.
type DebugLogger interface {
Debugf(string, ...interface{})
}
type debugLoggerAdapter struct {
logger DebugLogger
}
// DebugLoggerAdapter returns BasicLogger that calls underlying DebugLogger.Debugf.
func DebugLoggerAdapter(logger DebugLogger) BasicLogger {
return &debugLoggerAdapter{logger: logger}
}
// Printf data in the log using DebugLogger.Debugf.
func (l *debugLoggerAdapter) Printf(format string, v ...interface{}) {
l.logger.Debugf(format, v...)
}

View file

@ -1,24 +0,0 @@
package retailcrm
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
type wrappedLogger struct {
lastMessage string
}
func (w *wrappedLogger) Debugf(msg string, v ...interface{}) {
w.lastMessage = fmt.Sprintf(msg, v...)
}
func TestDebugLoggerAdapter_Printf(t *testing.T) {
wrapped := &wrappedLogger{}
logger := DebugLoggerAdapter(wrapped)
logger.Printf("Test message #%d", 1)
assert.Equal(t, "Test message #1", wrapped.lastMessage)
}

View file

@ -1,160 +0,0 @@
package retailcrm
import (
"encoding/json"
"fmt"
"strconv"
)
func (t Tag) MarshalJSON() ([]byte, error) {
return json.Marshal(t.Name)
}
func (a *APIErrorsList) UnmarshalJSON(data []byte) error {
var i interface{}
var m APIErrorsList
if err := json.Unmarshal(data, &i); err != nil {
return err
}
switch e := i.(type) {
case map[string]interface{}:
m = make(APIErrorsList, len(e))
for idx, val := range e {
m[idx] = fmt.Sprint(val)
}
case []interface{}:
m = make(APIErrorsList, len(e))
for idx, val := range e {
m[strconv.Itoa(idx)] = fmt.Sprint(val)
}
}
*a = m
return nil
}
func (l *StringMap) UnmarshalJSON(data []byte) error {
var i interface{}
var m StringMap
if err := json.Unmarshal(data, &i); err != nil {
return err
}
switch e := i.(type) {
case map[string]interface{}:
m = make(StringMap, len(e))
for idx, val := range e {
m[idx] = fmt.Sprint(val)
}
case []interface{}:
m = make(StringMap, len(e))
for idx, val := range e {
m[strconv.Itoa(idx)] = fmt.Sprint(val)
}
}
*l = m
return nil
}
func (l *CustomFieldMap) UnmarshalJSON(data []byte) error {
var i interface{}
var items CustomFieldMap
if err := json.Unmarshal(data, &i); err != nil {
return err
}
switch e := i.(type) {
case map[string]interface{}:
items = make(CustomFieldMap, len(e))
for idx, val := range e {
items[idx] = val
}
case []interface{}:
items = make(CustomFieldMap, len(e))
for idx, val := range e {
items[strconv.Itoa(idx)] = val
}
}
*l = items
return nil
}
func (p *OrderPayments) UnmarshalJSON(data []byte) error {
var i interface{}
var m OrderPayments
if err := json.Unmarshal(data, &i); err != nil {
return err
}
switch e := i.(type) {
case map[string]interface{}:
m = make(OrderPayments, len(e))
for idx, val := range e {
var res OrderPayment
err := unmarshalMap(val.(map[string]interface{}), &res)
if err != nil {
return err
}
m[idx] = res
}
case []interface{}:
m = make(OrderPayments, len(e))
for idx, val := range e {
var res OrderPayment
err := unmarshalMap(val.(map[string]interface{}), &res)
if err != nil {
return err
}
m[strconv.Itoa(idx)] = res
}
}
*p = m
return nil
}
func (p *Properties) UnmarshalJSON(data []byte) error {
var i interface{}
var m Properties
if err := json.Unmarshal(data, &i); err != nil {
return err
}
switch e := i.(type) {
case map[string]interface{}:
m = make(Properties, len(e))
for idx, val := range e {
var res Property
err := unmarshalMap(val.(map[string]interface{}), &res)
if err != nil {
return err
}
m[idx] = res
}
case []interface{}:
m = make(Properties, len(e))
for idx, val := range e {
var res Property
err := unmarshalMap(val.(map[string]interface{}), &res)
if err != nil {
return err
}
m[strconv.Itoa(idx)] = res
}
}
*p = m
return nil
}
func unmarshalMap(m map[string]interface{}, v interface{}) (err error) {
var data []byte
data, err = json.Marshal(m)
if err != nil {
return err
}
return json.Unmarshal(data, v)
}

View file

@ -1,102 +0,0 @@
package retailcrm
import (
"encoding/json"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestTag_MarshalJSON(t *testing.T) {
tags := []Tag{
{"first", "#3e89b6", false},
{"second", "#ffa654", false},
}
names := []byte(`["first","second"]`)
str, err := json.Marshal(tags)
if err != nil {
t.Errorf("%v", err.Error())
}
if !reflect.DeepEqual(str, names) {
t.Errorf("Marshaled: %#v\nExpected: %#v\n", str, names)
}
}
func TestAPIErrorsList_UnmarshalJSON(t *testing.T) {
var list APIErrorsList
require.NoError(t, json.Unmarshal([]byte(`["first", "second"]`), &list))
assert.Len(t, list, 2)
assert.Equal(t, list["0"], "first")
assert.Equal(t, list["1"], "second")
require.NoError(t, json.Unmarshal([]byte(`{"a": "first", "b": "second"}`), &list))
assert.Len(t, list, 2)
assert.Equal(t, list["a"], "first")
assert.Equal(t, list["b"], "second")
require.NoError(t, json.Unmarshal([]byte(`[]`), &list))
assert.Len(t, list, 0)
}
func TestCustomFieldsList_UnmarshalJSON(t *testing.T) {
var list CustomFieldMap
require.NoError(t, json.Unmarshal([]byte(`["first", "second"]`), &list))
assert.Len(t, list, 2)
assert.Equal(t, list["0"], "first")
assert.Equal(t, list["1"], "second")
require.NoError(t, json.Unmarshal([]byte(`{"a": "first", "b": "second"}`), &list))
assert.Len(t, list, 2)
assert.Equal(t, list["a"], "first")
assert.Equal(t, list["b"], "second")
require.NoError(t, json.Unmarshal([]byte(`{"a": ["first", "second"], "b": "second"}`), &list))
assert.Len(t, list, 2)
assert.Len(t, list["a"].([]interface{}), 2)
assert.Equal(t, list["a"].([]interface{})[0], "first")
assert.Equal(t, list["a"].([]interface{})[1], "second")
assert.Equal(t, list["b"], "second")
require.NoError(t, json.Unmarshal([]byte(`[]`), &list))
assert.Len(t, list, 0)
}
func TestOrderPayments_UnmarshalJSON(t *testing.T) {
var list OrderPayments
require.NoError(t, json.Unmarshal([]byte(`[{"id": 1}, {"id": 2}]`), &list))
assert.Len(t, list, 2)
assert.Equal(t, list["0"], OrderPayment{ID: 1})
assert.Equal(t, list["1"], OrderPayment{ID: 2})
require.NoError(t, json.Unmarshal([]byte(`{"a": {"id": 1}, "b": {"id": 2}}`), &list))
assert.Len(t, list, 2)
assert.Equal(t, list["a"], OrderPayment{ID: 1})
assert.Equal(t, list["b"], OrderPayment{ID: 2})
require.NoError(t, json.Unmarshal([]byte(`[]`), &list))
assert.Len(t, list, 0)
}
func TestProperties_UnmarshalJSON(t *testing.T) {
var list Properties
require.NoError(t, json.Unmarshal([]byte(`[{"code": "first"}, {"code": "second"}]`), &list))
assert.Len(t, list, 2)
assert.Equal(t, list["0"], Property{Code: "first"})
assert.Equal(t, list["1"], Property{Code: "second"})
require.NoError(t, json.Unmarshal([]byte(`{"a": {"code": "first"}, "b": {"code": "second"}}`), &list))
assert.Len(t, list, 2)
assert.Equal(t, list["a"], Property{Code: "first"})
assert.Equal(t, list["b"], Property{Code: "second"})
require.NoError(t, json.Unmarshal([]byte(`[]`), &list))
assert.Len(t, list, 0)
}

View file

@ -1,332 +0,0 @@
package retailcrm
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)
// CustomerRequest type.
type CustomerRequest struct {
By string `url:"by,omitempty"`
Site string `url:"site,omitempty"`
}
// CustomersRequest type.
type CustomersRequest struct {
Filter CustomersFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CorporateCustomersRequest type.
type CorporateCustomersRequest struct {
Filter CorporateCustomersFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CorporateCustomersNotesRequest type.
type CorporateCustomersNotesRequest struct {
Filter CorporateCustomersNotesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CorporateCustomerAddressesRequest type.
type CorporateCustomerAddressesRequest struct {
Filter CorporateCustomerAddressesFilter `url:"filter,omitempty"`
By string `url:"by,omitempty"`
Site string `url:"site,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// IdentifiersPairRequest type.
type IdentifiersPairRequest struct {
Filter IdentifiersPairFilter `url:"filter,omitempty"`
By string `url:"by,omitempty"`
Site string `url:"site,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CustomersUploadRequest type.
type CustomersUploadRequest struct {
Customers []Customer `url:"customers,omitempty,brackets"`
Site string `url:"site,omitempty"`
}
// CustomersHistoryRequest type.
type CustomersHistoryRequest struct {
Filter CustomersHistoryFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CorporateCustomersHistoryRequest type.
type CorporateCustomersHistoryRequest struct {
Filter CorporateCustomersHistoryFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// OrderRequest type.
type OrderRequest struct {
By string `url:"by,omitempty"`
Site string `url:"site,omitempty"`
}
// OrdersRequest type.
type OrdersRequest struct {
Filter OrdersFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// OrdersStatusesRequest type.
type OrdersStatusesRequest struct {
IDs []int `url:"ids,omitempty,brackets"`
ExternalIDs []string `url:"externalIds,omitempty,brackets"`
}
// OrdersUploadRequest type.
type OrdersUploadRequest struct {
Orders []Order `url:"orders,omitempty,brackets"`
Site string `url:"site,omitempty"`
}
// OrdersHistoryRequest type.
type OrdersHistoryRequest struct {
Filter OrdersHistoryFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// PacksRequest type.
type PacksRequest struct {
Filter PacksFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// PacksHistoryRequest type.
type PacksHistoryRequest struct {
Filter OrdersHistoryFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// UsersRequest type.
type UsersRequest struct {
Filter UsersFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// UserGroupsRequest type.
type UserGroupsRequest struct {
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// TasksRequest type.
type TasksRequest struct {
Filter TasksFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// NotesRequest type.
type NotesRequest struct {
Filter NotesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// SegmentsRequest type.
type SegmentsRequest struct {
Filter SegmentsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// InventoriesRequest type.
type InventoriesRequest struct {
Filter InventoriesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// ProductsGroupsRequest type.
type ProductsGroupsRequest struct {
Filter ProductsGroupsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// ProductsRequest type.
type ProductsRequest struct {
Filter ProductsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// ProductsPropertiesRequest type.
type ProductsPropertiesRequest struct {
Filter ProductsPropertiesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// DeliveryTrackingRequest type.
type DeliveryTrackingRequest struct {
DeliveryID string `json:"deliveryId,omitempty"`
TrackNumber string `json:"trackNumber,omitempty"`
History []DeliveryHistoryRecord `json:"history,omitempty"`
ExtraData map[string]string `json:"extraData,omitempty"`
}
// DeliveryShipmentsRequest type.
type DeliveryShipmentsRequest struct {
Filter ShipmentFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// ClearCartRequest type.
type ClearCartRequest struct {
ClearedAt string `url:"clearedAt,omitempty"`
Customer CartCustomer `url:"customer,omitempty"`
Order ClearCartOrder `url:"order,omitempty"`
}
// SetCartRequest type.
type SetCartRequest struct {
ExternalID string `url:"externalId,omitempty"`
DroppedAt string `url:"droppedAt,omitempty"`
Link string `url:"link,omitempty"`
Customer CartCustomer `url:"customer,omitempty"`
Items []SetCartItem `url:"items,omitempty"`
}
// CostsRequest type.
type CostsRequest struct {
Filter CostsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// FilesRequest type.
type FilesRequest struct {
Filter FilesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CustomFieldsRequest type.
type CustomFieldsRequest struct {
Filter CustomFieldsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CustomDictionariesRequest type.
type CustomDictionariesRequest struct {
Filter CustomDictionariesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// ConnectRequest contains information about the system connection that is requested to be created.
type ConnectRequest struct {
// Token is used to verify the request. Do not use directly; use Verify instead.
Token string `json:"token"`
// APIKey that was generated for the module.
APIKey string `json:"apiKey"`
// URL of the system. Do not use directly; use SystemURL instead.
URL string `json:"systemUrl"`
}
// BonusOperationsRequest type.
type BonusOperationsRequest struct {
Filter BonusOperationsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Cursor string `url:"cursor,omitempty"`
}
// AccountBonusOperationsRequest type.
type AccountBonusOperationsRequest struct {
Filter AccountBonusOperationsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
type LoyaltyBonusCreditRequest struct {
Amount float64 `url:"amount"`
ActivationDate string `url:"activationDate,omitempty"`
ExpiredDate string `url:"expireDate,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:"page,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"`
}
type NotificationsSendRequest struct {
UserGroups []UserGroupType `json:"userGroups,omitempty"`
Type NotificationType `json:"type"`
Message string `json:"message"`
UserIDs []string `json:"userIds,omitempty"`
}
type EditMGChannelTemplateRequest struct {
Templates []MGChannelTemplate `json:"templates"`
Removed []int `json:"removed"`
}
// SystemURL returns system URL from the connection request without trailing slash.
func (r ConnectRequest) SystemURL() string {
if r.URL == "" {
return ""
}
if r.URL[len(r.URL)-1:] == "/" {
return r.URL[:len(r.URL)-1]
}
return r.URL
}
// Verify returns true if connection request is legitimate. Application secret should be provided to this method.
func (r ConnectRequest) Verify(secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
if _, err := mac.Write([]byte(r.APIKey)); err != nil {
panic(err)
}
return hmac.Equal([]byte(r.Token), []byte(hex.EncodeToString(mac.Sum(nil))))
}
type OffersRequest struct {
OffersFilter `url:"filter,omitempty"`
}

View file

@ -1,43 +0,0 @@
package retailcrm
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"testing"
"github.com/stretchr/testify/suite"
)
type ConnectRequestTest struct {
suite.Suite
}
func TestConnectRequest(t *testing.T) {
suite.Run(t, new(ConnectRequestTest))
}
func (t *ConnectRequestTest) Test_SystemURL() {
t.Assert().Equal("", ConnectRequest{}.SystemURL())
t.Assert().Equal("https://test.retailcrm.pro", ConnectRequest{URL: "https://test.retailcrm.pro"}.SystemURL())
t.Assert().Equal("https://test.retailcrm.pro", ConnectRequest{URL: "https://test.retailcrm.pro/"}.SystemURL())
}
func (t *ConnectRequestTest) Test_Verify() {
t.Assert().True(ConnectRequest{
APIKey: "key",
Token: createConnectToken("key", "secret"),
}.Verify("secret"))
t.Assert().False(ConnectRequest{
APIKey: "key",
Token: createConnectToken("key", "secret2"),
}.Verify("secret"))
}
func createConnectToken(apiKey, secret string) string {
mac := hmac.New(sha256.New, []byte(secret))
if _, err := mac.Write([]byte(apiKey)); err != nil {
panic(err)
}
return hex.EncodeToString(mac.Sum(nil))
}

View file

@ -1,699 +0,0 @@
package retailcrm
// SuccessfulResponse type.
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"`
ID int `json:"id,omitempty"`
}
// OrderCreateResponse type.
type OrderCreateResponse struct {
CreateResponse
Order Order `json:"order,omitempty"`
}
// OperationResponse type.
type OperationResponse struct {
Success bool `json:"success"`
Errors map[string]string `json:"ErrorsList,omitempty"`
}
// VersionResponse return available API versions.
type VersionResponse struct {
Success bool `json:"success,omitempty"`
Versions []string `json:"versions,omitempty"`
}
// CredentialResponse return available API methods.
type CredentialResponse struct {
Success bool `json:"success,omitempty"`
// deprecated
Credentials []string `json:"credentials,omitempty"`
Scopes []string `json:"scopes,omitempty"`
SiteAccess string `json:"siteAccess,omitempty"`
SitesAvailable []string `json:"sitesAvailable,omitempty"`
}
// SystemInfoResponse return system info.
type SystemInfoResponse struct {
Success bool `json:"success,omitempty"`
SystemVersion string `json:"systemVersion,omitempty"`
PublicURL string `json:"publicUrl,omitempty"`
TechnicalURL string `json:"technicalUrl,omitempty"`
}
// CustomerResponse type.
type CustomerResponse struct {
Success bool `json:"success"`
Customer *Customer `json:"customer,omitempty"`
}
// CorporateCustomerResponse type.
type CorporateCustomerResponse struct {
Success bool `json:"success"`
CorporateCustomer *CorporateCustomer `json:"customerCorporate,omitempty"`
}
// CustomersResponse type.
type CustomersResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Customers []Customer `json:"customers,omitempty"`
}
// CorporateCustomersResponse type.
type CorporateCustomersResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
CustomersCorporate []CorporateCustomer `json:"customersCorporate,omitempty"`
}
// CorporateCustomersNotesResponse type.
type CorporateCustomersNotesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Notes []Note `json:"notes,omitempty"`
}
// CorporateCustomersAddressesResponse type.
type CorporateCustomersAddressesResponse struct {
Success bool `json:"success"`
Addresses []CorporateCustomerAddress `json:"addresses"`
}
// CorporateCustomerCompaniesResponse type.
type CorporateCustomerCompaniesResponse struct {
Success bool `json:"success"`
Companies []Company `json:"companies"`
}
// CorporateCustomerContactsResponse type.
type CorporateCustomerContactsResponse struct {
Success bool `json:"success"`
Contacts []CorporateCustomerContact `json:"contacts"`
}
// CustomerChangeResponse type.
type CustomerChangeResponse struct {
Success bool `json:"success"`
ID int `json:"id,omitempty"`
State string `json:"state,omitempty"`
}
// CorporateCustomerChangeResponse type.
type CorporateCustomerChangeResponse CustomerChangeResponse
// CustomersUploadResponse type.
type CustomersUploadResponse struct {
Success bool `json:"success"`
UploadedCustomers []IdentifiersPair `json:"uploadedCustomers,omitempty"`
FailedCustomers []ExternalID `json:"failedCustomers,omitempty"`
}
// CorporateCustomersUploadResponse type.
type CorporateCustomersUploadResponse CustomersUploadResponse
// CustomersHistoryResponse type.
type CustomersHistoryResponse struct {
Success bool `json:"success,omitempty"`
GeneratedAt string `json:"generatedAt,omitempty"`
History []CustomerHistoryRecord `json:"history,omitempty"`
Pagination *Pagination `json:"pagination,omitempty"`
}
// CorporateCustomersHistoryResponse type.
type CorporateCustomersHistoryResponse struct {
Success bool `json:"success,omitempty"`
GeneratedAt string `json:"generatedAt,omitempty"`
History []CorporateCustomerHistoryRecord `json:"history,omitempty"`
Pagination *Pagination `json:"pagination,omitempty"`
}
// OrderResponse type.
type OrderResponse struct {
Success bool `json:"success"`
Order *Order `json:"order,omitempty"`
}
// OrdersResponse type.
type OrdersResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Orders []Order `json:"orders,omitempty"`
}
// OrdersStatusesResponse type.
type OrdersStatusesResponse struct {
Success bool `json:"success"`
Orders []OrdersStatus `json:"orders"`
}
// OrdersUploadResponse type.
type OrdersUploadResponse struct {
Success bool `json:"success"`
UploadedOrders []IdentifiersPair `json:"uploadedOrders,omitempty"`
FailedOrders []ExternalID `json:"failedOrders,omitempty"`
}
// OrdersHistoryResponse type.
type OrdersHistoryResponse struct {
Success bool `json:"success,omitempty"`
GeneratedAt string `json:"generatedAt,omitempty"`
History []OrdersHistoryRecord `json:"history,omitempty"`
Pagination *Pagination `json:"pagination,omitempty"`
}
// PackResponse type.
type PackResponse struct {
Success bool `json:"success"`
Pack *Pack `json:"pack,omitempty"`
}
// PacksResponse type.
type PacksResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Packs []Pack `json:"packs,omitempty"`
}
// PacksHistoryResponse type.
type PacksHistoryResponse struct {
Success bool `json:"success,omitempty"`
GeneratedAt string `json:"generatedAt,omitempty"`
History []PacksHistoryRecord `json:"history,omitempty"`
Pagination *Pagination `json:"pagination,omitempty"`
}
// UserResponse type.
type UserResponse struct {
Success bool `json:"success"`
User *User `json:"user,omitempty"`
}
// UsersResponse type.
type UsersResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Users []User `json:"users,omitempty"`
}
// UserGroupsResponse type.
type UserGroupsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Groups []UserGroup `json:"groups,omitempty"`
}
// TaskResponse type.
type TaskResponse struct {
Success bool `json:"success"`
Task *Task `json:"task,omitempty"`
}
// TasksResponse type.
type TasksResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Tasks []Task `json:"tasks,omitempty"`
}
// NotesResponse type.
type NotesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Notes []Note `json:"notes,omitempty"`
}
// SegmentsResponse type.
type SegmentsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Segments []Segment `json:"segments,omitempty"`
}
// SettingsResponse type.
type SettingsResponse struct {
Success bool `json:"success"`
Settings Settings `json:"settings,omitempty"`
}
// CountriesResponse type.
type CountriesResponse struct {
Success bool `json:"success"`
CountriesIso []string `json:"countriesIso,omitempty"`
}
// CostGroupsResponse type.
type CostGroupsResponse struct {
Success bool `json:"success"`
CostGroups []CostGroup `json:"costGroups,omitempty"`
}
// CostItemsResponse type.
type CostItemsResponse struct {
Success bool `json:"success"`
CostItems []CostItem `json:"costItems,omitempty"`
}
// CouriersResponse type.
type CouriersResponse struct {
Success bool `json:"success"`
Couriers []Courier `json:"couriers,omitempty"`
}
// DeliveryServiceResponse type.
type DeliveryServiceResponse struct {
Success bool `json:"success"`
DeliveryServices map[string]DeliveryService `json:"deliveryServices,omitempty"`
}
// DeliveryTypesResponse type.
type DeliveryTypesResponse struct {
Success bool `json:"success"`
DeliveryTypes map[string]DeliveryType `json:"deliveryTypes,omitempty"`
}
// LegalEntitiesResponse type.
type LegalEntitiesResponse struct {
Success bool `json:"success"`
LegalEntities []LegalEntity `json:"legalEntities,omitempty"`
}
// OrderMethodsResponse type.
type OrderMethodsResponse struct {
Success bool `json:"success"`
OrderMethods map[string]OrderMethod `json:"orderMethods,omitempty"`
}
// OrderTypesResponse type.
type OrderTypesResponse struct {
Success bool `json:"success"`
OrderTypes map[string]OrderType `json:"orderTypes,omitempty"`
}
// PaymentStatusesResponse type.
type PaymentStatusesResponse struct {
Success bool `json:"success"`
PaymentStatuses map[string]PaymentStatus `json:"paymentStatuses,omitempty"`
}
// PaymentTypesResponse type.
type PaymentTypesResponse struct {
Success bool `json:"success"`
PaymentTypes map[string]PaymentType `json:"paymentTypes,omitempty"`
}
// PriceTypesResponse type.
type PriceTypesResponse struct {
Success bool `json:"success"`
PriceTypes []PriceType `json:"priceTypes,omitempty"`
}
// ProductStatusesResponse type.
type ProductStatusesResponse struct {
Success bool `json:"success"`
ProductStatuses map[string]ProductStatus `json:"productStatuses,omitempty"`
}
// StatusesResponse type.
type StatusesResponse struct {
Success bool `json:"success"`
Statuses map[string]Status `json:"statuses,omitempty"`
}
// StatusGroupsResponse type.
type StatusGroupsResponse struct {
Success bool `json:"success"`
StatusGroups map[string]StatusGroup `json:"statusGroups,omitempty"`
}
// SitesResponse type.
type SitesResponse struct {
Success bool `json:"success"`
Sites map[string]Site `json:"sites,omitempty"`
}
// StoresResponse type.
type StoresResponse struct {
Success bool `json:"success"`
Stores []Store `json:"stores,omitempty"`
}
// InventoriesResponse type.
type InventoriesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Offers []Offer `json:"offers,omitempty"`
}
// StoreUploadResponse type.
type StoreUploadResponse struct {
Success bool `json:"success"`
ProcessedOffersCount int `json:"processedOffersCount,omitempty"`
NotFoundOffers []Offer `json:"notFoundOffers,omitempty"`
}
// ProductsGroupsResponse type.
type ProductsGroupsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
ProductGroup []ProductGroup `json:"productGroup,omitempty"`
}
// ProductsResponse type.
type ProductsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
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"`
Pagination *Pagination `json:"pagination,omitempty"`
Properties []Property `json:"properties,omitempty"`
}
// CartResponse type.
type CartResponse struct {
SuccessfulResponse
Cart Cart `json:"cart"`
}
// DeliveryShipmentsResponse type.
type DeliveryShipmentsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
DeliveryShipments []DeliveryShipment `json:"deliveryShipments,omitempty"`
}
// DeliveryShipmentResponse type.
type DeliveryShipmentResponse struct {
Success bool `json:"success"`
DeliveryShipment *DeliveryShipment `json:"deliveryShipment,omitempty"`
}
// DeliveryShipmentUpdateResponse type.
type DeliveryShipmentUpdateResponse struct {
Success bool `json:"success"`
ID int `json:"id,omitempty"`
Status string `json:"status,omitempty"`
}
// IntegrationModuleResponse type.
type IntegrationModuleResponse struct {
Success bool `json:"success"`
IntegrationModule *IntegrationModule `json:"integrationModule,omitempty"`
}
// UpdateScopesResponse update scopes response.
type UpdateScopesResponse struct {
ErrorResponse
APIKey string `json:"apiKey"`
}
// IntegrationModuleEditResponse type.
type IntegrationModuleEditResponse struct {
Success bool `json:"success"`
Info ResponseInfo `json:"info,omitempty"`
}
// ResponseInfo type.
type ResponseInfo struct {
MgTransportInfo MgInfo `json:"mgTransport,omitempty"`
MgBotInfo MgInfo `json:"mgBot,omitempty"`
BillingInfo *BillingInfo `json:"billingInfo,omitempty"`
DeliveryTypeInfo DeliveryTypeInfo `json:"deliveryType,omitempty"`
}
type BillingInfo struct {
Price float64 `json:"price,omitempty"`
PriceWithDiscount float64 `json:"priceWithDiscount,omitempty"`
BillingType string `json:"billingType,omitempty"`
Currency *BillingInfoCurrency `json:"currency,omitempty"`
}
type BillingInfoCurrency struct {
Name string `json:"name,omitempty"`
ShortName string `json:"shortName,omitempty"`
Code string `json:"code,omitempty"`
}
// MgInfo type.
type MgInfo struct {
EndpointURL string `json:"endpointUrl"`
Token string `json:"token"`
}
// CostsResponse type.
type CostsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Costs []Cost `json:"costs,omitempty"`
}
// CostsUploadResponse type.
type CostsUploadResponse struct {
Success bool `json:"success"`
UploadedCosts []int `json:"uploadedCosts,omitempty"`
}
// CostsDeleteResponse type.
type CostsDeleteResponse struct {
Success bool `json:"success"`
Count int `json:"count,omitempty"`
NotRemovedIds []int `json:"notRemovedIds,omitempty"`
}
// CostResponse type.
type CostResponse struct {
Success bool `json:"success"`
Cost *Cost `json:"cost,omitempty"`
}
// FilesResponse type.
type FilesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Files []File `json:"files,omitempty"`
}
// FileUpload response.
type FileUploadResponse struct {
Success bool `json:"success"`
File *File `json:"file,omitempty"`
}
// FileResponse type.
type FileResponse struct {
Success bool `json:"success"`
File *File `json:"file,omitempty"`
}
// CustomFieldsResponse type.
type CustomFieldsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
CustomFields []CustomFields `json:"customFields,omitempty"`
}
// CustomDictionariesResponse type.
type CustomDictionariesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
CustomDictionaries *[]CustomDictionary `json:"customDictionaries,omitempty"`
}
// CustomResponse type.
type CustomResponse struct {
Success bool `json:"success"`
Code string `json:"code,omitempty"`
}
// CustomDictionaryResponse type.
type CustomDictionaryResponse struct {
Success bool `json:"success"`
CustomDictionary *CustomDictionary `json:"CustomDictionary,omitempty"`
}
// CustomFieldResponse type.
type CustomFieldResponse struct {
Success bool `json:"success"`
CustomField CustomFields `json:"customField,omitempty"`
}
// UnitsResponse type.
type UnitsResponse struct {
Success bool `json:"success"`
Units *[]Unit `json:"units,omitempty"`
}
// ErrorResponse should be returned to the one-step connection request in case of failure.
type ErrorResponse struct {
SuccessfulResponse
ErrorMessage string `json:"errorMsg"`
}
// ConnectResponse should be returned to the one-step connection request in case of successful connection.
type ConnectResponse struct {
SuccessfulResponse
AccountURL string `json:"accountUrl"`
}
// ConnectionConfigResponse contains connection configuration for one-step connection.
type ConnectionConfigResponse struct {
SuccessfulResponse
Scopes []string `json:"scopes"`
RegisterURL string `json:"registerUrl"`
}
// NewConnectResponse returns ConnectResponse with the provided account URL.
func NewConnectResponse(accountURL string) ConnectResponse {
return ConnectResponse{
SuccessfulResponse: SuccessfulResponse{Success: true},
AccountURL: accountURL,
}
}
// BonusOperationsResponse type.
type BonusOperationsResponse struct {
Success bool `json:"success"`
Pagination *CursorPagination `json:"pagination,omitempty"`
BonusOperations []BonusOperation `json:"bonusOperations,omitempty"`
}
// AccountBonusOperationsResponse type.
type AccountBonusOperationsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
BonusOperations []BonusOperation `json:"bonusOperations,omitempty"`
}
// ClientIDResponse type.
type ClientIDResponse struct {
ErrorMsg string `json:"errorMsg,omitempty"`
Errors map[string]string `json:"errors,omitempty"`
FailedClientIds []ClientID `json:"failed_client_ids,omitempty"`
Success bool `json:"success"`
}
// SourcesResponse type.
type SourcesResponse struct {
ErrorMsg string `json:"errorMsg,omitempty"`
Errors map[string]string `json:"errors,omitempty"`
FailedSources []Source `json:"failed_sources,omitempty"`
Success bool `json:"success"`
}
// CurrencyResponse type.
type CurrencyResponse struct {
Currencies []Currency `json:"currencies,omitempty"`
Success bool `json:"success"`
}
// CurrencyCreateResponse type.
type CurrencyCreateResponse struct {
Success bool `json:"success"`
ID int `json:"id,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"`
}
type MGChannelTemplatesResponse struct {
Pagination *Pagination `json:"pagination"`
Templates []MGChannelTemplate `json:"templates"`
SuccessfulResponse
}
type StoreOffersResponse struct {
Pagination *Pagination `json:"pagination"`
SuccessfulResponse
Offers []Offer `json:"offers,omitempty"`
}

View file

@ -1,16 +0,0 @@
package retailcrm
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewConnectResponse(t *testing.T) {
assert.Equal(t, ConnectResponse{
SuccessfulResponse: SuccessfulResponse{
Success: true,
},
AccountURL: "https://example.com",
}, NewConnectResponse("https://example.com"))
}

View file

@ -1,30 +0,0 @@
package retailcrm
import (
"fmt"
"strings"
"time"
)
type SystemTime time.Time
const systemTimeLayout = "2006-01-02 15:04:05"
// UnmarshalJSON parses time.Time from system format.
func (st *SystemTime) UnmarshalJSON(b []byte) (err error) {
s := strings.Trim(string(b), `"`)
nt, err := time.Parse(systemTimeLayout, s)
*st = SystemTime(nt)
return
}
// MarshalJSON will marshal time.Time to system format.
func (st SystemTime) MarshalJSON() ([]byte, error) {
return []byte(st.String()), nil
}
// String returns the time in the custom format.
func (st *SystemTime) String() string {
t := time.Time(*st)
return fmt.Sprintf("%q", t.Format(systemTimeLayout))
}

View file

@ -1,122 +0,0 @@
package retailcrm
import (
"encoding/json"
"errors"
"fmt"
)
const (
// TemplateItemTypeText is a type for text chunk in template.
TemplateItemTypeText uint8 = iota
// TemplateItemTypeVar is a type for variable in template.
TemplateItemTypeVar
QuickReply ButtonType = "QUICK_REPLY"
PhoneNumber ButtonType = "PHONE_NUMBER"
URL ButtonType = "URL"
)
const (
// TemplateVarCustom is a custom variable type.
TemplateVarCustom = "custom"
// TemplateVarName is a name variable type.
TemplateVarName = "name"
// TemplateVarFirstName is a first name variable type.
TemplateVarFirstName = "first_name"
// TemplateVarLastName is a last name variable type.
TemplateVarLastName = "last_name"
)
// templateVarAssoc for checking variable validity, only for internal use.
var templateVarAssoc = map[string]interface{}{
TemplateVarCustom: nil,
TemplateVarName: nil,
TemplateVarFirstName: nil,
TemplateVarLastName: nil,
}
type Text struct {
Parts []TextTemplateItem `json:"parts"`
Example []string `json:"example,omitempty"`
}
type Media struct {
Example string `json:"example,omitempty"`
}
type Header struct {
Text *Text `json:"text,omitempty"`
Document *Media `json:"document,omitempty"`
Image *Media `json:"image,omitempty"`
Video *Media `json:"video,omitempty"`
}
type TemplateItemList []TextTemplateItem
// TextTemplateItem is a part of template.
type TextTemplateItem struct {
Text string
VarType string
Type uint8
}
// MarshalJSON controls how TextTemplateItem will be marshaled into JSON.
func (t TextTemplateItem) MarshalJSON() ([]byte, error) {
switch t.Type {
case TemplateItemTypeText:
return json.Marshal(t.Text)
case TemplateItemTypeVar:
return json.Marshal(map[string]interface{}{
"var": t.VarType,
})
}
return nil, errors.New("unknown TextTemplateItem type")
}
// UnmarshalJSON will correctly unmarshal TextTemplateItem.
func (t *TextTemplateItem) UnmarshalJSON(b []byte) error {
var obj interface{}
err := json.Unmarshal(b, &obj)
if err != nil {
return err
}
switch bodyPart := obj.(type) {
case string:
t.Type = TemplateItemTypeText
t.Text = bodyPart
case map[string]interface{}:
// {} case
if len(bodyPart) == 0 {
t.Type = TemplateItemTypeText
t.Text = "{}"
return nil
}
if varTypeCurr, ok := bodyPart["var"].(string); ok {
if _, ok := templateVarAssoc[varTypeCurr]; !ok {
return fmt.Errorf("invalid placeholder var '%s'", varTypeCurr)
}
t.Type = TemplateItemTypeVar
t.VarType = varTypeCurr
} else {
return errors.New("invalid TextTemplateItem")
}
default:
return errors.New("invalid TextTemplateItem")
}
return nil
}
type ButtonType string
type Button struct {
Type ButtonType `json:"type"`
URL string `json:"url,omitempty"`
Text string `json:"text,omitempty"`
PhoneNumber string `json:"phoneNumber,omitempty"`
Example []string `json:"example,omitempty"`
}

View file

@ -1,565 +0,0 @@
//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: []interface{}{"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: map[string]interface{}{
"animal": "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: map[string]interface{}{
"animal": "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": {
"custom_multiselect": ["test1", "test3"],
"custom_select": "test2",
"custom_integer": 456,
"custom_float": 8.43
}
}
}`
}
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"
}
}`
}
func getMGTemplatesResponse() string {
return `{
"success": true,
"pagination": {
"limit": 10,
"totalCount": 100,
"currentPage": 5,
"totalPageCount": 10
},
"templates": [
{
"id": 1,
"externalId": 0,
"channel": {
"allowedSendByPhone": false,
"id": 1,
"externalId": 1,
"type": "fbmessenger",
"active": true,
"name": "fbmessenger"
},
"code": "namespace#NAMEAAA#ru",
"name": "NAMEAAA",
"active": true,
"template": [
"Text_0",
{
"var": "custom"
}
],
"templateExample": ["Text_1"],
"namespace": "namespace_0",
"lang": "en",
"category": "test_0",
"header": {
"text": {
"parts": [
"JABAAA",
{
"var": "custom"
}
],
"example": [
"AAAAAA"
]
},
"image": {
"example": "https://example.com/file/123.png"
},
"document": {
"example": "https://example.com/file/123.pdf"
},
"video": {
"example": "https://example.com/file/123.mp4"
}
},
"footer": "footer_0",
"buttons": [
{
"type": "PHONE_NUMBER",
"text": "your-phone-button-text",
"phoneNumber": "+79895553535"
},
{
"type": "QUICK_REPLY",
"text": "Yes"
},
{
"type": "URL",
"url": "https://example.com/file/{{1}}",
"text": "button",
"example": [
"https://www.website.com/dynamic-url-example"
]
}
],
"verificationStatus": "APPROVED"
}
]
}`
}
func getMGTemplatesForEdit() string {
return `[{"header":{"text":{"parts":["Hello,",{"var":"custom"}],"example":["Henry"]},"document":{"example":"https://example.com/file/123.pdf"},"image":{"example":"https://example.com/file/123.png"},"video":{"example":"https://example.com/file/123.mp4"}},"lang":"en","category":"test_0","code":"namespace#name_0#ru","name":"name_0","namespace":"namespace","footer":"footer_0","verificationStatus":"REJECTED","template":["Text_0",{"var":"custom"}],"buttons":[{"type":"PHONE_NUMBER","text":"your-phone-button-text","phoneNumber":"+79895553535"},{"type":"QUICK_REPLY","text":"Yes"},{"type":"URL","url":"https://example.com/file/{{1}}","text":"button","example":["https://www.website.com/dynamic-url-example"]}],"templateExample":["WIU"],"id":1,"externalId":10,"mgChannelId":110,"active":true}]`
}
func getStoreOfferResponse() string {
return `{
"success": true,
"pagination": {
"limit": 20,
"totalCount": 1,
"currentPage": 1,
"totalPageCount": 1
},
"offers": [
{
"images": [
"https://s3-s1.retailcrm.tech/ru-central1/retailcrm/dev-vega-d32aea7f9a5bc26eba6ad986077cea03/product/65a92fa0bb737-test.jpeg"
],
"id": 76,
"site": "main",
"name": "Название\nПеревод строки",
"article": "Артикул",
"product": {
"type": "product",
"catalogId": 2,
"id": 222
},
"prices": [
{
"priceType": "base",
"price": 10000,
"ordering": 991,
"currency": "RUB"
}
],
"purchasePrice": 10,
"quantity": 5,
"active": true,
"unit": {
"code": "pc",
"name": "Штука",
"sym": "шт."
}
}
]
}`
}

1719
types.go

File diff suppressed because it is too large Load diff

View file

@ -1,55 +0,0 @@
package retailcrm
import (
"encoding/json"
"reflect"
"testing"
)
func TestClient_OrderDeliveryData(t *testing.T) {
d := OrderDeliveryData{
OrderDeliveryDataBasic: OrderDeliveryDataBasic{
"track",
"status",
"address",
"type",
},
}
data, _ := json.Marshal(d)
expectedStr := `{"payerType":"type","pickuppointAddress":"address","status":"status","trackNumber":"track"}`
if string(data) != expectedStr {
t.Errorf("Marshaled: %s\nExpected: %s\n", data, expectedStr)
}
d.AdditionalFields = map[string]interface{}{
"customFirst": "one",
"customSecond": "two",
}
data, _ = json.Marshal(d)
expectedStr = `{"customFirst":"one","customSecond":"two","payerType":"type","pickuppointAddress":"address","status":"status","trackNumber":"track"}`
if string(data) != expectedStr {
t.Errorf("Marshaled: %s\nExpected: %s\n", data, expectedStr)
}
d = OrderDeliveryData{}
json.Unmarshal(data, &d)
expected := OrderDeliveryData{
OrderDeliveryDataBasic: OrderDeliveryDataBasic{
"track",
"status",
"address",
"type",
},
AdditionalFields: map[string]interface{}{
"customFirst": "one",
"customSecond": "two",
},
}
eq := reflect.DeepEqual(expected, d)
if eq != true {
t.Errorf("Unmarshaled: %#v\nExpected: %#v\n", d, expected)
}
}

4173
v5/client.go Normal file

File diff suppressed because it is too large Load diff

5171
v5/client_test.go Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
package retailcrm
package v5
// CustomersFilter type.
// CustomersFilter type
type CustomersFilter struct {
Ids []string `url:"ids,omitempty,brackets"`
ExternalIds []string `url:"externalIds,omitempty,brackets"`
@ -57,74 +57,7 @@ type CustomersFilter struct {
CustomFields map[string]string `url:"customFields,omitempty,brackets"`
}
// CorporateCustomersFilter type.
type CorporateCustomersFilter struct {
ContragentName string `url:"contragentName,omitempty"`
ContragentInn string `url:"contragentInn,omitempty"`
ContragentKpp string `url:"contragentKpp,omitempty"`
ContragentBik string `url:"contragentBik,omitempty"`
ContragentCorrAccount string `url:"contragentCorrAccount,omitempty"`
ContragentBankAccount string `url:"contragentBankAccount,omitempty"`
ContragentTypes []string `url:"contragentTypes,omitempty,brackets"`
ExternalIds []string `url:"externalIds,omitempty,brackets"`
Name string `url:"name,omitempty"`
City string `url:"city,omitempty"`
Region string `url:"region,omitempty"`
Email string `url:"email,omitempty"`
Notes string `url:"notes,omitempty"`
MinOrdersCount int `url:"minOrdersCount,omitempty"`
MaxOrdersCount int `url:"maxOrdersCount,omitempty"`
MinAverageSumm float32 `url:"minAverageSumm,omitempty"`
MaxAverageSumm float32 `url:"maxAverageSumm,omitempty"`
MinTotalSumm float32 `url:"minTotalSumm,omitempty"`
MaxTotalSumm float32 `url:"maxTotalSumm,omitempty"`
ClassSegment string `url:"classSegment,omitempty"`
DiscountCardNumber string `url:"discountCardNumber,omitempty"`
Attachments int `url:"attachments,omitempty"`
MinCostSumm float32 `url:"minCostSumm,omitempty"`
MaxCostSumm float32 `url:"maxCostSumm,omitempty"`
Vip int `url:"vip,omitempty"`
Bad int `url:"bad,omitempty"`
TasksCount int `url:"tasksCounts,omitempty"`
Ids []string `url:"ids,omitempty,brackets"`
Sites []string `url:"sites,omitempty,brackets"`
Managers []string `url:"managers,omitempty,brackets"`
ManagerGroups []string `url:"managerGroups,omitempty,brackets"`
DateFrom string `url:"dateFrom,omitempty"`
DateTo string `url:"dateTo,omitempty"`
FirstOrderFrom string `url:"firstOrderFrom,omitempty"`
FirstOrderTo string `url:"firstOrderTo,omitempty"`
LastOrderFrom string `url:"lastOrderFrom,omitempty"`
LastOrderTo string `url:"lastOrderTo,omitempty"`
CustomFields map[string]string `url:"customFields,omitempty,brackets"`
}
// CorporateCustomersNotesFilter type.
type CorporateCustomersNotesFilter struct {
Ids []string `url:"ids,omitempty,brackets"`
CustomerIds []string `url:"ids,omitempty,brackets"`
CustomerExternalIds []string `url:"customerExternalIds,omitempty,brackets"`
ManagerIds []string `url:"managerIds,omitempty,brackets"`
Text string `url:"text,omitempty"`
CreatedAtFrom string `url:"createdAtFrom,omitempty"`
CreatedAtTo string `url:"createdAtTo,omitempty"`
}
// CorporateCustomerAddressesFilter type.
type CorporateCustomerAddressesFilter struct {
Ids []string `url:"ids,omitempty,brackets"`
Name string `url:"name,omitempty"`
City string `url:"city,omitempty"`
Region string `url:"region,omitempty"`
}
// IdentifiersPairFilter type.
type IdentifiersPairFilter struct {
Ids []string `url:"ids,omitempty,brackets"`
ExternalIds []string `url:"externalIds,omitempty,brackets"`
}
// CustomersHistoryFilter type.
// CustomersHistoryFilter type
type CustomersHistoryFilter struct {
CustomerID int `url:"customerId,omitempty"`
SinceID int `url:"sinceId,omitempty"`
@ -133,17 +66,7 @@ type CustomersHistoryFilter struct {
EndDate string `url:"endDate,omitempty"`
}
// CorporateCustomersHistoryFilter type.
type CorporateCustomersHistoryFilter struct {
CustomerID int `url:"customerId,omitempty"`
SinceID int `url:"sinceId,omitempty"`
CustomerExternalID string `url:"customerExternalId,omitempty"`
ContactIds []string `url:"contactIds,omitempty,brackets"`
StartDate string `url:"startDate,omitempty"`
EndDate string `url:"endDate,omitempty"`
}
// OrdersFilter type.
// OrdersFilter type
type OrdersFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
ExternalIds []string `url:"externalIds,omitempty,brackets"`
@ -199,7 +122,6 @@ type OrdersFilter struct {
PaymentStatuses []string `url:"paymentStatuses,omitempty,brackets"`
PaymentTypes []string `url:"paymentTypes,omitempty,brackets"`
DeliveryTypes []string `url:"deliveryTypes,omitempty,brackets"`
DeliveryServices []string `url:"deliveryServices,omitempty,brackets"`
OrderMethods []string `url:"orderMethods,omitempty,brackets"`
ShipmentStores []string `url:"shipmentStores,omitempty,brackets"`
Couriers []string `url:"couriers,omitempty,brackets"`
@ -208,8 +130,6 @@ type OrdersFilter struct {
Sites []string `url:"sites,omitempty,brackets"`
CreatedAtFrom string `url:"createdAtFrom,omitempty"`
CreatedAtTo string `url:"createdAtTo,omitempty"`
PaidAtFrom string `url:"paidAtFrom,omitempty"`
PaidAtTo string `url:"paidAtTo,omitempty"`
FullPaidAtFrom string `url:"fullPaidAtFrom,omitempty"`
FullPaidAtTo string `url:"fullPaidAtTo,omitempty"`
DeliveryDateFrom string `url:"deliveryDateFrom,omitempty"`
@ -237,7 +157,7 @@ type OrdersFilter struct {
CustomFields map[string]string `url:"customFields,omitempty,brackets"`
}
// OrdersHistoryFilter type.
// OrdersHistoryFilter type
type OrdersHistoryFilter struct {
OrderID int `url:"orderId,omitempty"`
SinceID int `url:"sinceId,omitempty"`
@ -246,7 +166,7 @@ type OrdersHistoryFilter struct {
EndDate string `url:"endDate,omitempty"`
}
// UsersFilter type.
// UsersFilter type
type UsersFilter struct {
Email string `url:"email,omitempty"`
Status string `url:"status,omitempty"`
@ -259,7 +179,7 @@ type UsersFilter struct {
Groups []string `url:"groups,omitempty,brackets"`
}
// TasksFilter type.
// TasksFilter type
type TasksFilter struct {
OrderNumber string `url:"orderNumber,omitempty"`
Status string `url:"status,omitempty"`
@ -271,7 +191,7 @@ type TasksFilter struct {
Performers []int `url:"performers,omitempty,brackets"`
}
// NotesFilter type.
// NotesFilter type
type NotesFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
CustomerIds []int `url:"customerIds,omitempty,brackets"`
@ -282,7 +202,7 @@ type NotesFilter struct {
CreatedAtTo string `url:"createdAtTo,omitempty"`
}
// SegmentsFilter type.
// SegmentsFilter type
type SegmentsFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
Active int `url:"active,omitempty"`
@ -294,7 +214,7 @@ type SegmentsFilter struct {
DateTo string `url:"dateTo,omitempty"`
}
// PacksFilter type.
// PacksFilter type
type PacksFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
Stores []string `url:"stores,omitempty"`
@ -309,7 +229,7 @@ type PacksFilter struct {
DeliveryNoteNumber string `url:"deliveryNoteNumber,omitempty"`
}
// InventoriesFilter type.
// InventoriesFilter type
type InventoriesFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
ProductExternalID string `url:"productExternalId,omitempty"`
@ -322,7 +242,7 @@ type InventoriesFilter struct {
Sites []string `url:"sites,omitempty,brackets"`
}
// ProductsGroupsFilter type.
// ProductsGroupsFilter type
type ProductsGroupsFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
Sites []string `url:"sites,omitempty,brackets"`
@ -330,7 +250,7 @@ type ProductsGroupsFilter struct {
ParentGroupID string `url:"parentGroupId,omitempty"`
}
// ProductsFilter type.
// ProductsFilter type
type ProductsFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
OfferIds []int `url:"offerIds,omitempty,brackets"`
@ -352,21 +272,20 @@ type ProductsFilter struct {
ExternalID string `url:"externalId,omitempty"`
Manufacturer string `url:"manufacturer,omitempty"`
URL string `url:"url,omitempty"`
URLLike string `url:"urlLike,omitempty"`
PriceType string `url:"priceType,omitempty"`
OfferExternalID string `url:"offerExternalId,omitempty"`
Sites []string `url:"sites,omitempty,brackets"`
Properties map[string]string `url:"properties,omitempty,brackets"`
}
// ProductsPropertiesFilter type.
// ProductsPropertiesFilter type
type ProductsPropertiesFilter struct {
Code string `url:"code,omitempty"`
Name string `url:"name,omitempty"`
Sites []string `url:"sites,omitempty,brackets"`
}
// ShipmentFilter type.
// ShipmentFilter type
type ShipmentFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
ExternalID string `url:"externalId,omitempty"`
@ -379,44 +298,27 @@ type ShipmentFilter struct {
Statuses []string `url:"statuses,omitempty,brackets"`
}
// CostsFilter type.
// CostsFilter type
type CostsFilter struct {
MinSumm int `url:"minSumm,omitempty"`
MaxSumm int `url:"maxSumm,omitempty"`
MinSumm string `url:"minSumm,omitempty"`
MaxSumm string `url:"maxSumm,omitempty"`
OrderNumber string `url:"orderNumber,omitempty"`
Comment string `url:"orderNumber,omitempty"`
IDs []int `url:"ids,omitempty,brackets"`
Ids []string `url:"ids,omitempty,brackets"`
Sites []string `url:"sites,omitempty,brackets"`
CreatedBy []int `url:"createdBy,omitempty,brackets"`
CreatedBy []string `url:"createdBy,omitempty,brackets"`
CostGroups []string `url:"costGroups,omitempty,brackets"`
CostItems []string `url:"costItems,omitempty,brackets"`
Users []int `url:"users,omitempty,brackets"`
Users []string `url:"users,omitempty,brackets"`
DateFrom string `url:"dateFrom,omitempty"`
DateTo string `url:"dateTo,omitempty"`
CreatedAtFrom string `url:"createdAtFrom,omitempty"`
CreatedAtTo string `url:"createdAtTo,omitempty"`
OrderIDs []int `url:"orderIds,omitempty,brackets"`
OrderExternalIDs []string `url:"orderExternalIds,omitempty,brackets"`
OrderIds []string `url:"orderIds,omitempty,brackets"`
OrderExternalIds []string `url:"orderIds,omitempty,brackets"`
}
// FilesFilter type.
type FilesFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
OrderIds []int `url:"orderIds,omitempty,brackets"`
OrderExternalIds []string `url:"orderExternalIds,omitempty,brackets"`
CustomerIds []int `url:"customerIds,omitempty,brackets"`
CustomerExternalIds []string `url:"customerExternalIds,omitempty,brackets"`
CreatedAtFrom string `url:"createdAtFrom,omitempty"`
CreatedAtTo string `url:"createdAtTo,omitempty"`
SizeFrom int `url:"sizeFrom,omitempty"`
SizeTo int `url:"sizeTo,omitempty"`
Type []string `url:"type,omitempty,brackets"`
Filename string `url:"filename,omitempty"`
IsAttached string `url:"isAttached,omitempty"`
Sites []string `url:"sites,omitempty,brackets"`
}
// CustomFieldsFilter type.
// CustomFieldsFilter type
type CustomFieldsFilter struct {
Name string `url:"name,omitempty"`
Code string `url:"code,omitempty"`
@ -426,72 +328,8 @@ type CustomFieldsFilter struct {
DisplayArea string `url:"displayArea,omitempty"`
}
// CustomDictionariesFilter type.
// CustomDictionariesFilter type
type CustomDictionariesFilter struct {
Name string `url:"name,omitempty"`
Code string `url:"code,omitempty"`
}
// BonusOperationsFilter type.
type BonusOperationsFilter struct {
Loyalties []int `url:"loyalties,omitempty,brackets"`
}
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:"minOrdersSum,omitempty"`
MaxOrderSum string `url:"maxOrdersSum,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"`
}
type OffersFilter struct {
Ids []int `url:"ids,omitempty,brackets"`
Active *int `url:"active,omitempty"`
}
type SiteFilter struct {
// SiteBy contains information about what is betrayed site id or site code.
// id|code, default is code.
SiteBy string `url:"siteBy,omitempty"`
}
type GetCartFilter struct {
// SiteBy contains information about what is betrayed site id or site code.
// id|code, default is code.
SiteBy string `url:"siteBy,omitempty"`
// By contains information about what is betrayed: customer id or customer externalId.
// id|externalId, default is externalId.
By string `url:"by,omitempty"`
}

165
v5/request.go Normal file
View file

@ -0,0 +1,165 @@
package v5
// CustomerRequest type
type CustomerRequest struct {
By string `url:"by,omitempty"`
Site string `url:"site,omitempty"`
}
// CustomersRequest type
type CustomersRequest struct {
Filter CustomersFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CustomersUploadRequest type
type CustomersUploadRequest struct {
Customers []Customer `url:"customers,omitempty,brackets"`
Site string `url:"site,omitempty"`
}
// CustomersHistoryRequest type
type CustomersHistoryRequest struct {
Filter CustomersHistoryFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// OrderRequest type
type OrderRequest struct {
By string `url:"by,omitempty"`
Site string `url:"site,omitempty"`
}
// OrdersRequest type
type OrdersRequest struct {
Filter OrdersFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// OrdersUploadRequest type
type OrdersUploadRequest struct {
Orders []Order `url:"orders,omitempty,brackets"`
Site string `url:"site,omitempty"`
}
// OrdersHistoryRequest type
type OrdersHistoryRequest struct {
Filter OrdersHistoryFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// PacksRequest type
type PacksRequest struct {
Filter PacksFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// PacksHistoryRequest type
type PacksHistoryRequest struct {
Filter OrdersHistoryFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// UsersRequest type
type UsersRequest struct {
Filter UsersFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// UserGroupsRequest type
type UserGroupsRequest struct {
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// TasksRequest type
type TasksRequest struct {
Filter TasksFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// NotesRequest type
type NotesRequest struct {
Filter NotesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// SegmentsRequest type
type SegmentsRequest struct {
Filter SegmentsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// InventoriesRequest type
type InventoriesRequest struct {
Filter InventoriesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// ProductsGroupsRequest type
type ProductsGroupsRequest struct {
Filter ProductsGroupsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// ProductsRequest type
type ProductsRequest struct {
Filter ProductsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// ProductsPropertiesRequest type
type ProductsPropertiesRequest struct {
Filter ProductsPropertiesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// DeliveryTrackingRequest type
type DeliveryTrackingRequest struct {
DeliveryID string `url:"deliveryId,omitempty"`
TrackNumber string `url:"trackNumber,omitempty"`
History []DeliveryHistoryRecord `url:"history,omitempty,brackets"`
ExtraData map[string]string `url:"extraData,omitempty,brackets"`
}
// DeliveryShipmentsRequest type
type DeliveryShipmentsRequest struct {
Filter ShipmentFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CostsRequest type
type CostsRequest struct {
Filter CostsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CustomFieldsRequest type
type CustomFieldsRequest struct {
Filter CustomFieldsFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}
// CustomDictionariesRequest type
type CustomDictionariesRequest struct {
Filter CustomDictionariesFilter `url:"filter,omitempty"`
Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"`
}

406
v5/response.go Normal file
View file

@ -0,0 +1,406 @@
package v5
// SuccessfulResponse type
type SuccessfulResponse struct {
Success bool `json:"success,omitempty"`
}
// CreateResponse type
type CreateResponse struct {
Success bool `json:"success"`
ID int `json:"id,omitempty"`
}
// OperationResponse type
type OperationResponse struct {
Success bool `json:"success"`
Errors map[string]string `json:"errors,omitempty,brackets"`
}
// VersionResponse return available API versions
type VersionResponse struct {
Success bool `json:"success,omitempty"`
Versions []string `json:"versions,brackets,omitempty"`
}
// CredentialResponse return available API methods
type CredentialResponse struct {
Success bool `json:"success,omitempty"`
Credentials []string `json:"credentials,brackets,omitempty"`
SiteAccess string `json:"siteAccess,omitempty"`
SitesAvailable []string `json:"sitesAvailable,brackets,omitempty"`
}
// CustomerResponse type
type CustomerResponse struct {
Success bool `json:"success"`
Customer *Customer `json:"customer,omitempty,brackets"`
}
// CustomersResponse type
type CustomersResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Customers []Customer `json:"customers,omitempty,brackets"`
}
// CustomerChangeResponse type
type CustomerChangeResponse struct {
Success bool `json:"success"`
ID int `json:"id,omitempty"`
State string `json:"state,omitempty"`
}
// CustomersUploadResponse type
type CustomersUploadResponse struct {
Success bool `json:"success"`
UploadedCustomers []IdentifiersPair `json:"uploadedCustomers,omitempty,brackets"`
}
// CustomersHistoryResponse type
type CustomersHistoryResponse struct {
Success bool `json:"success,omitempty"`
GeneratedAt string `json:"generatedAt,omitempty"`
History []CustomerHistoryRecord `json:"history,omitempty,brackets"`
Pagination *Pagination `json:"pagination,omitempty"`
}
// OrderResponse type
type OrderResponse struct {
Success bool `json:"success"`
Order *Order `json:"order,omitempty,brackets"`
}
// OrdersResponse type
type OrdersResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Orders []Order `json:"orders,omitempty,brackets"`
}
// OrdersUploadResponse type
type OrdersUploadResponse struct {
Success bool `json:"success"`
UploadedOrders []IdentifiersPair `json:"uploadedOrders,omitempty,brackets"`
}
// OrdersHistoryResponse type
type OrdersHistoryResponse struct {
Success bool `json:"success,omitempty"`
GeneratedAt string `json:"generatedAt,omitempty"`
History []OrdersHistoryRecord `json:"history,omitempty,brackets"`
Pagination *Pagination `json:"pagination,omitempty"`
}
// PackResponse type
type PackResponse struct {
Success bool `json:"success"`
Pack *Pack `json:"pack,omitempty,brackets"`
}
// PacksResponse type
type PacksResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Packs []Pack `json:"packs,omitempty,brackets"`
}
// PacksHistoryResponse type
type PacksHistoryResponse struct {
Success bool `json:"success,omitempty"`
GeneratedAt string `json:"generatedAt,omitempty"`
History []PacksHistoryRecord `json:"history,omitempty,brackets"`
Pagination *Pagination `json:"pagination,omitempty"`
}
// UserResponse type
type UserResponse struct {
Success bool `json:"success"`
User *User `json:"user,omitempty,brackets"`
}
// UsersResponse type
type UsersResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Users []User `json:"users,omitempty,brackets"`
}
// UserGroupsResponse type
type UserGroupsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Groups []UserGroup `json:"groups,omitempty,brackets"`
}
// TaskResponse type
type TaskResponse struct {
Success bool `json:"success"`
Task *Task `json:"task,omitempty,brackets"`
}
// TasksResponse type
type TasksResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Tasks []Task `json:"tasks,omitempty,brackets"`
}
// NotesResponse type
type NotesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Notes []Note `json:"notes,omitempty,brackets"`
}
// SegmentsResponse type
type SegmentsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Segments []Segment `json:"segments,omitempty,brackets"`
}
// CountriesResponse type
type CountriesResponse struct {
Success bool `json:"success"`
CountriesIso []string `json:"countriesIso,omitempty,brackets"`
}
// CostGroupsResponse type
type CostGroupsResponse struct {
Success bool `json:"success"`
CostGroups []CostGroup `json:"costGroups,omitempty,brackets"`
}
// CostItemsResponse type
type CostItemsResponse struct {
Success bool `json:"success"`
CostItems []CostItem `json:"costItems,omitempty,brackets"`
}
// CouriersResponse type
type CouriersResponse struct {
Success bool `json:"success"`
Couriers []Courier `json:"couriers,omitempty,brackets"`
}
// DeliveryServiceResponse type
type DeliveryServiceResponse struct {
Success bool `json:"success"`
DeliveryServices map[string]DeliveryService `json:"deliveryServices,omitempty,brackets"`
}
// DeliveryTypesResponse type
type DeliveryTypesResponse struct {
Success bool `json:"success"`
DeliveryTypes map[string]DeliveryType `json:"deliveryTypes,omitempty,brackets"`
}
// LegalEntitiesResponse type
type LegalEntitiesResponse struct {
Success bool `json:"success"`
LegalEntities []LegalEntity `json:"legalEntities,omitempty,brackets"`
}
// OrderMethodsResponse type
type OrderMethodsResponse struct {
Success bool `json:"success"`
OrderMethods map[string]OrderMethod `json:"orderMethods,omitempty,brackets"`
}
// OrderTypesResponse type
type OrderTypesResponse struct {
Success bool `json:"success"`
OrderTypes map[string]OrderType `json:"orderTypes,omitempty,brackets"`
}
// PaymentStatusesResponse type
type PaymentStatusesResponse struct {
Success bool `json:"success"`
PaymentStatuses map[string]PaymentStatus `json:"paymentStatuses,omitempty,brackets"`
}
// PaymentTypesResponse type
type PaymentTypesResponse struct {
Success bool `json:"success"`
PaymentTypes map[string]PaymentType `json:"paymentTypes,omitempty,brackets"`
}
// PriceTypesResponse type
type PriceTypesResponse struct {
Success bool `json:"success"`
PriceTypes []PriceType `json:"priceTypes,omitempty,brackets"`
}
// ProductStatusesResponse type
type ProductStatusesResponse struct {
Success bool `json:"success"`
ProductStatuses map[string]ProductStatus `json:"productStatuses,omitempty,brackets"`
}
// StatusesResponse type
type StatusesResponse struct {
Success bool `json:"success"`
Statuses map[string]Status `json:"statuses,omitempty,brackets"`
}
// StatusGroupsResponse type
type StatusGroupsResponse struct {
Success bool `json:"success"`
StatusGroups map[string]StatusGroup `json:"statusGroups,omitempty,brackets"`
}
// SitesResponse type
type SitesResponse struct {
Success bool `json:"success"`
Sites map[string]Site `json:"sites,omitempty,brackets"`
}
// StoresResponse type
type StoresResponse struct {
Success bool `json:"success"`
Stores []Store `json:"stores,omitempty,brackets"`
}
// InventoriesResponse type
type InventoriesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Offers []Offer `json:"offers,omitempty"`
}
// StoreUploadResponse type
type StoreUploadResponse struct {
Success bool `json:"success"`
ProcessedOffersCount int `json:"processedOffersCount,omitempty"`
NotFoundOffers []Offer `json:"notFoundOffers,omitempty"`
}
// ProductsGroupsResponse type
type ProductsGroupsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
ProductGroup []ProductGroup `json:"productGroup,omitempty,brackets"`
}
// ProductsResponse type
type ProductsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Products []Product `json:"products,omitempty,brackets"`
}
// ProductsPropertiesResponse type
type ProductsPropertiesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Properties []Property `json:"properties,omitempty,brackets"`
}
// DeliveryShipmentsResponse type
type DeliveryShipmentsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
DeliveryShipments []DeliveryShipment `json:"deliveryShipments,omitempty,brackets"`
}
// DeliveryShipmentResponse type
type DeliveryShipmentResponse struct {
Success bool `json:"success"`
DeliveryShipment *DeliveryShipment `json:"deliveryShipment,omitempty,brackets"`
}
// DeliveryShipmentUpdateResponse type
type DeliveryShipmentUpdateResponse struct {
Success bool `json:"success"`
ID int `json:"id,omitempty"`
Status string `json:"status,omitempty"`
}
// IntegrationModuleResponse type
type IntegrationModuleResponse struct {
Success bool `json:"success"`
IntegrationModule *IntegrationModule `json:"integrationModule,omitempty"`
}
// IntegrationModuleEditResponse type
type IntegrationModuleEditResponse struct {
Success bool `json:"success"`
Info ResponseInfo `json:"info,omitempty,brackets"`
}
// ResponseInfo type
type ResponseInfo struct {
MgTransportInfo MgInfo `json:"mgTransport,omitempty,brackets"`
MgBotInfo MgInfo `json:"mgBot,omitempty,brackets"`
}
// MgInfo type
type MgInfo struct {
EndpointUrl string `json:"endpointUrl"`
Token string `json:"token"`
}
// CostsResponse type
type CostsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
Costs []Cost `json:"costs,omitempty,brackets"`
}
// CostsUploadResponse type
type CostsUploadResponse struct {
Success bool `json:"success"`
UploadedCosts []int `json:"uploadedCosts,omitempty,brackets"`
}
// CostsDeleteResponse type
type CostsDeleteResponse struct {
Success bool `json:"success"`
Count int `json:"count,omitempty,brackets"`
NotRemovedIds []int `json:"notRemovedIds,omitempty,brackets"`
}
// CostResponse type
type CostResponse struct {
Success bool `json:"success"`
Cost *Cost `json:"cost,omitempty,brackets"`
}
// CustomFieldsResponse type
type CustomFieldsResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
CustomFields []CustomFields `json:"customFields,omitempty,brackets"`
}
// CustomDictionariesResponse type
type CustomDictionariesResponse struct {
Success bool `json:"success"`
Pagination *Pagination `json:"pagination,omitempty"`
CustomDictionaries *[]CustomDictionary `json:"customDictionaries,omitempty,brackets"`
}
// CustomResponse type
type CustomResponse struct {
Success bool `json:"success"`
Code string `json:"code,omitempty"`
}
// CustomDictionaryResponse type
type CustomDictionaryResponse struct {
Success bool `json:"success"`
CustomDictionary *CustomDictionary `json:"CustomDictionary,omitempty,brackets"`
}
// CustomFieldResponse type
type CustomFieldResponse struct {
Success bool `json:"success"`
CustomField CustomFields `json:"customField,omitempty,brackets"`
}
// UnitsResponse type
type UnitsResponse struct {
Success bool `json:"success"`
Units *[]Unit `json:"units,omitempty,brackets"`
}

964
v5/types.go Normal file
View file

@ -0,0 +1,964 @@
package v5
import "net/http"
// Client type
type Client struct {
URL string
Key string
Debug bool
httpClient *http.Client
}
// Pagination type
type Pagination struct {
Limit int `json:"limit,omitempty"`
TotalCount int `json:"totalCount,omitempty"`
CurrentPage int `json:"currentPage,omitempty"`
TotalPageCount int `json:"totalPageCount,omitempty"`
}
// Address type
type Address struct {
Index string `json:"index,omitempty"`
CountryIso string `json:"countryIso,omitempty"`
Region string `json:"region,omitempty"`
RegionID int `json:"regionId,omitempty"`
City string `json:"city,omitempty"`
CityID int `json:"cityId,omitempty"`
CityType string `json:"cityType,omitempty"`
Street string `json:"street,omitempty"`
StreetID int `json:"streetId,omitempty"`
StreetType string `json:"streetType,omitempty"`
Building string `json:"building,omitempty"`
Flat string `json:"flat,omitempty"`
IntercomCode string `json:"intercomCode,omitempty"`
Floor int `json:"floor,omitempty"`
Block int `json:"block,omitempty"`
House string `json:"house,omitempty"`
Metro string `json:"metro,omitempty"`
Notes string `json:"notes,omitempty"`
Text string `json:"text,omitempty"`
}
// GeoHierarchyRow type
type GeoHierarchyRow struct {
Country string `json:"country,omitempty"`
Region string `json:"region,omitempty"`
RegionID int `json:"regionId,omitempty"`
City string `json:"city,omitempty"`
CityID int `json:"cityId,omitempty"`
}
// Source type
type Source struct {
Source string `json:"source,omitempty"`
Medium string `json:"medium,omitempty"`
Campaign string `json:"campaign,omitempty"`
Keyword string `json:"keyword,omitempty"`
Content string `json:"content,omitempty"`
}
// Contragent type
type Contragent struct {
ContragentType string `json:"contragentType,omitempty"`
LegalName string `json:"legalName,omitempty"`
LegalAddress string `json:"legalAddress,omitempty"`
INN string `json:"INN,omitempty"`
OKPO string `json:"OKPO,omitempty"`
KPP string `json:"KPP,omitempty"`
OGRN string `json:"OGRN,omitempty"`
OGRNIP string `json:"OGRNIP,omitempty"`
CertificateNumber string `json:"certificateNumber,omitempty"`
CertificateDate string `json:"certificateDate,omitempty"`
BIK string `json:"BIK,omitempty"`
Bank string `json:"bank,omitempty"`
BankAddress string `json:"bankAddress,omitempty"`
CorrAccount string `json:"corrAccount,omitempty"`
BankAccount string `json:"bankAccount,omitempty"`
}
// APIKey type
type APIKey struct {
Current bool `json:"current,omitempty"`
}
// Property type
type Property struct {
Code string `json:"code,omitempty"`
Name string `json:"name,omitempty"`
Value string `json:"value,omitempty"`
Sites []string `json:"Sites,omitempty,brackets"`
}
// IdentifiersPair type
type IdentifiersPair struct {
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
}
// DeliveryTime type
type DeliveryTime struct {
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
Custom string `json:"custom,omitempty"`
}
/**
Customer related types
*/
// Customer type
type Customer struct {
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
Patronymic string `json:"patronymic,omitempty"`
Sex string `json:"sex,omitempty"`
Email string `json:"email,omitempty"`
Phones []Phone `json:"phones,brackets,omitempty"`
Address *Address `json:"address,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
Birthday string `json:"birthday,omitempty"`
ManagerID int `json:"managerId,omitempty"`
Vip bool `json:"vip,omitempty"`
Bad bool `json:"bad,omitempty"`
Site string `json:"site,omitempty"`
Source *Source `json:"source,omitempty"`
Contragent *Contragent `json:"contragent,omitempty"`
PersonalDiscount float32 `json:"personalDiscount,omitempty"`
CumulativeDiscount float32 `json:"cumulativeDiscount,omitempty"`
DiscountCardNumber string `json:"discountCardNumber,omitempty"`
EmailMarketingUnsubscribedAt string `json:"emailMarketingUnsubscribedAt,omitempty"`
AvgMarginSumm float32 `json:"avgMarginSumm,omitempty"`
MarginSumm float32 `json:"marginSumm,omitempty"`
TotalSumm float32 `json:"totalSumm,omitempty"`
AverageSumm float32 `json:"averageSumm,omitempty"`
OrdersCount int `json:"ordersCount,omitempty"`
CostSumm float32 `json:"costSumm,omitempty"`
MaturationTime int `json:"maturationTime,omitempty"`
FirstClientID string `json:"firstClientId,omitempty"`
LastClientID string `json:"lastClientId,omitempty"`
BrowserID string `json:"browserId,omitempty"`
MgCustomerID string `json:"mgCustomerId,omitempty"`
PhotoURL string `json:"photoUrl,omitempty"`
CustomFields []map[string]string `json:"customFields,omitempty,brackets"`
}
// Phone type
type Phone struct {
Number string `json:"number,omitempty"`
}
// CustomerHistoryRecord type
type CustomerHistoryRecord struct {
ID int `json:"id,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
Created bool `json:"created,omitempty"`
Deleted bool `json:"deleted,omitempty"`
Source string `json:"source,omitempty"`
Field string `json:"field,omitempty"`
User *User `json:"user,omitempty,brackets"`
APIKey *APIKey `json:"apiKey,omitempty,brackets"`
Customer *Customer `json:"customer,omitempty,brackets"`
}
/**
Order related types
*/
// Order type
type Order struct {
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
Number string `json:"number,omitempty"`
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
Patronymic string `json:"patronymic,omitempty"`
Email string `json:"email,omitempty"`
Phone string `json:"phone,omitempty"`
AdditionalPhone string `json:"additionalPhone,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
StatusUpdatedAt string `json:"statusUpdatedAt,omitempty"`
ManagerID int `json:"managerId,omitempty"`
Mark int `json:"mark,omitempty"`
Call bool `json:"call,omitempty"`
Expired bool `json:"expired,omitempty"`
FromAPI bool `json:"fromApi,omitempty"`
MarkDatetime string `json:"markDatetime,omitempty"`
CustomerComment string `json:"customerComment,omitempty"`
ManagerComment string `json:"managerComment,omitempty"`
Status string `json:"status,omitempty"`
StatusComment string `json:"statusComment,omitempty"`
FullPaidAt string `json:"fullPaidAt,omitempty"`
Site string `json:"site,omitempty"`
OrderType string `json:"orderType,omitempty"`
OrderMethod string `json:"orderMethod,omitempty"`
CountryIso string `json:"countryIso,omitempty"`
Summ float32 `json:"summ,omitempty"`
TotalSumm float32 `json:"totalSumm,omitempty"`
PrepaySum float32 `json:"prepaySum,omitempty"`
PurchaseSumm float32 `json:"purchaseSumm,omitempty"`
DiscountManualAmount float32 `json:"discountManualAmount,omitempty"`
DiscountManualPercent float32 `json:"discountManualPercent,omitempty"`
Weight float32 `json:"weight,omitempty"`
Length int `json:"length,omitempty"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
ShipmentStore string `json:"shipmentStore,omitempty"`
ShipmentDate string `json:"shipmentDate,omitempty"`
ClientID string `json:"clientId,omitempty"`
Shipped bool `json:"shipped,omitempty"`
UploadedToExternalStoreSystem bool `json:"uploadedToExternalStoreSystem,omitempty"`
Source *Source `json:"source,omitempty"`
Contragent *Contragent `json:"contragent,omitempty"`
Customer *Customer `json:"customer,omitempty"`
Delivery *OrderDelivery `json:"delivery,omitempty"`
Marketplace *OrderMarketplace `json:"marketplace,omitempty"`
Items []OrderItem `json:"items,omitempty,brackets"`
CustomFields []map[string]string `json:"customFields,omitempty,brackets"`
Payments []OrderPayment `json:"payments,omitempty,brackets"`
}
// OrderDelivery type
type OrderDelivery struct {
Code string `json:"code,omitempty"`
IntegrationCode string `json:"integrationCode,omitempty"`
Cost float32 `json:"cost,omitempty"`
NetCost float32 `json:"netCost,omitempty"`
VatRate string `json:"vatRate,omitempty"`
Date string `json:"date,omitempty"`
Time *OrderDeliveryTime `json:"time,omitempty"`
Address *Address `json:"address,omitempty"`
Service *OrderDeliveryService `json:"service,omitempty"`
Data *OrderDeliveryData `json:"data,omitempty"`
}
// OrderDeliveryTime type
type OrderDeliveryTime struct {
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
Custom string `json:"custom,omitempty"`
}
// OrderDeliveryService type
type OrderDeliveryService struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
}
// OrderDeliveryData type
type OrderDeliveryData struct {
TrackNumber string `json:"trackNumber,omitempty"`
Status string `json:"status,omitempty"`
PickuppointAddress string `json:"pickuppointAddress,omitempty"`
PayerType string `json:"payerType,omitempty"`
}
// OrderMarketplace type
type OrderMarketplace struct {
Code string `json:"code,omitempty"`
OrderID string `json:"orderId,omitempty"`
}
// OrderPayment type
type OrderPayment struct {
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
Type string `json:"type,omitempty"`
Status string `json:"status,omitempty"`
PaidAt string `json:"paidAt,omitempty"`
Amount float32 `json:"amount,omitempty"`
Comment string `json:"comment,omitempty"`
}
// OrderItem type
type OrderItem struct {
ID int `json:"id,omitempty"`
InitialPrice float32 `json:"initialPrice,omitempty"`
PurchasePrice float32 `json:"purchasePrice,omitempty"`
DiscountTotal float32 `json:"discountTotal,omitempty"`
DiscountManualAmount float32 `json:"discountManualAmount,omitempty"`
DiscountManualPercent float32 `json:"discountManualPercent,omitempty"`
ProductName string `json:"productName,omitempty"`
VatRate string `json:"vatRate,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
Quantity float32 `json:"quantity,omitempty"`
Status string `json:"status,omitempty"`
Comment string `json:"comment,omitempty"`
IsCanceled bool `json:"isCanceled,omitempty"`
Offer Offer `json:"offer,omitempty"`
Properties []Property `json:"properties,omitempty,brackets"`
PriceType *PriceType `json:"priceType,omitempty"`
}
// OrdersHistoryRecord type
type OrdersHistoryRecord struct {
ID int `json:"id,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
Created bool `json:"created,omitempty"`
Deleted bool `json:"deleted,omitempty"`
Source string `json:"source,omitempty"`
Field string `json:"field,omitempty"`
User *User `json:"user,omitempty,brackets"`
APIKey *APIKey `json:"apiKey,omitempty,brackets"`
Order *Order `json:"order,omitempty,brackets"`
}
// Pack type
type Pack struct {
ID int `json:"id,omitempty"`
PurchasePrice float32 `json:"purchasePrice,omitempty"`
Quantity float32 `json:"quantity,omitempty"`
Store string `json:"store,omitempty"`
ShipmentDate string `json:"shipmentDate,omitempty"`
InvoiceNumber string `json:"invoiceNumber,omitempty"`
DeliveryNoteNumber string `json:"deliveryNoteNumber,omitempty"`
Item *PackItem `json:"item,omitempty"`
ItemID int `json:"itemId,omitempty"`
Unit *Unit `json:"unit,omitempty"`
}
// PackItem type
type PackItem struct {
ID int `json:"id,omitempty"`
Order *Order `json:"order,omitempty"`
Offer *Offer `json:"offer,omitempty"`
}
// PacksHistoryRecord type
type PacksHistoryRecord struct {
ID int `json:"id,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
Created bool `json:"created,omitempty"`
Deleted bool `json:"deleted,omitempty"`
Source string `json:"source,omitempty"`
Field string `json:"field,omitempty"`
User *User `json:"user,omitempty,brackets"`
Pack *Pack `json:"pack,omitempty,brackets"`
}
// Offer type
type Offer struct {
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
Name string `json:"name,omitempty"`
XMLID string `json:"xmlId,omitempty"`
Article string `json:"article,omitempty"`
VatRate string `json:"vatRate,omitempty"`
Price float32 `json:"price,omitempty"`
PurchasePrice float32 `json:"purchasePrice,omitempty"`
Quantity float32 `json:"quantity,omitempty"`
Height float32 `json:"height,omitempty"`
Width float32 `json:"width,omitempty"`
Length float32 `json:"length,omitempty"`
Weight float32 `json:"weight,omitempty"`
Stores []Inventory `json:"stores,omitempty,brackets"`
Properties map[string]string `json:"properties,omitempty,brackets"`
Prices []OfferPrice `json:"prices,omitempty,brackets"`
Images []string `json:"images,omitempty,brackets"`
Unit *Unit `json:"unit,omitempty,brackets"`
}
// Inventory type
type Inventory struct {
PurchasePrice float32 `json:"purchasePrice,omitempty"`
Quantity float32 `json:"quantity,omitempty"`
Store string `json:"store,omitempty"`
}
// InventoryUpload type
type InventoryUpload struct {
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
XMLID string `json:"xmlId,omitempty"`
Stores []InventoryUploadStore `json:"stores,omitempty"`
}
// InventoryUploadStore type
type InventoryUploadStore struct {
PurchasePrice float32 `json:"purchasePrice,omitempty"`
Available float32 `json:"available,omitempty"`
Code string `json:"code,omitempty"`
}
// OfferPrice type
type OfferPrice struct {
Price float32 `json:"price,omitempty"`
Ordering int `json:"ordering,omitempty"`
PriceType string `json:"priceType,omitempty"`
}
// OfferPriceUpload type
type OfferPriceUpload struct {
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
XMLID string `json:"xmlId,omitempty"`
Site string `json:"site,omitempty"`
Prices []PriceUpload `json:"prices,omitempty"`
}
// PriceUpload type
type PriceUpload struct {
Code string `json:"code,omitempty"`
Price float32 `json:"price,omitempty"`
}
// Unit type
type Unit struct {
Code string `json:"code"`
Name string `json:"name"`
Sym string `json:"sym"`
Default bool `json:"default,omitempty"`
Active bool `json:"active,omitempty"`
}
/**
User related types
*/
// User type
type User struct {
ID int `json:"id,omitempty"`
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
Patronymic string `json:"patronymic,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
Active bool `json:"active,omitempty"`
Online bool `json:"online,omitempty"`
IsAdmin bool `json:"isAdmin,omitempty"`
IsManager bool `json:"isManager,omitempty"`
Email string `json:"email,omitempty"`
Phone string `json:"phone,omitempty"`
Status string `json:"status,omitempty"`
Groups []UserGroup `json:"groups,omitempty,brackets"`
}
// UserGroup type
type UserGroup struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
SignatureTemplate string `json:"signatureTemplate,omitempty"`
IsManager bool `json:"isManager,omitempty"`
IsDeliveryMen bool `json:"isDeliveryMen,omitempty"`
DeliveryTypes []string `json:"deliveryTypes,omitempty,brackets"`
BreakdownOrderTypes []string `json:"breakdownOrderTypes,omitempty,brackets"`
BreakdownSites []string `json:"breakdownSites,omitempty,brackets"`
BreakdownOrderMethods []string `json:"breakdownOrderMethods,omitempty,brackets"`
GrantedOrderTypes []string `json:"grantedOrderTypes,omitempty,brackets"`
GrantedSites []string `json:"grantedSites,omitempty,brackets"`
}
/**
Task related types
*/
// Task type
type Task struct {
ID int `json:"id,omitempty"`
PerformerID int `json:"performerId,omitempty"`
Text string `json:"text,omitempty"`
Commentary string `json:"commentary,omitempty"`
Datetime string `json:"datetime,omitempty"`
Complete bool `json:"complete,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
Creator int `json:"creator,omitempty"`
Performer int `json:"performer,omitempty"`
Phone string `json:"phone,omitempty"`
PhoneSite string `json:"phoneSite,omitempty"`
Customer *Customer `json:"customer,omitempty"`
Order *Order `json:"order,omitempty"`
}
/*
Notes related types
*/
// Note type
type Note struct {
ID int `json:"id,omitempty"`
ManagerID int `json:"managerId,omitempty"`
Text string `json:"text,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
Customer *Customer `json:"customer,omitempty"`
}
/*
Payments related types
*/
// Payment type
type Payment struct {
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
PaidAt string `json:"paidAt,omitempty"`
Amount float32 `json:"amount,omitempty"`
Comment string `json:"comment,omitempty"`
Status string `json:"status,omitempty"`
Type string `json:"type,omitempty"`
Order *Order `json:"order,omitempty"`
}
/*
Segment related types
*/
// Segment type
type Segment struct {
ID int `json:"id,omitempty"`
Code string `json:"code,omitempty"`
Name string `json:"name,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
CustomersCount int `json:"customersCount,omitempty"`
IsDynamic bool `json:"isDynamic,omitempty"`
Active bool `json:"active,omitempty"`
}
/**
Reference related types
*/
// CostGroup type
type CostGroup struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Color string `json:"color,omitempty"`
Active bool `json:"active,omitempty"`
Ordering int `json:"ordering,omitempty"`
}
// CostItem type
type CostItem struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Group string `json:"group,omitempty"`
Type string `json:"type,omitempty"`
Active bool `json:"active,omitempty"`
AppliesToOrders bool `json:"appliesToOrders,omitempty"`
AppliesToUsers bool `json:"appliesToUsers,omitempty"`
Ordering int `json:"ordering,omitempty"`
Source *Source `json:"source,omitempty"`
}
// Courier type
type Courier struct {
ID int `json:"id,omitempty"`
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
Patronymic string `json:"patronymic,omitempty"`
Email string `json:"email,omitempty"`
Description string `json:"description,omitempty"`
Active bool `json:"active,omitempty"`
Phone *Phone `json:"phone,omitempty"`
}
// DeliveryService type
type DeliveryService struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
}
// 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"`
}
// LegalEntity type
type LegalEntity struct {
Code string `json:"code,omitempty"`
VatRate string `json:"vatRate,omitempty"`
CountryIso string `json:"countryIso,omitempty"`
ContragentType string `json:"contragentType,omitempty"`
LegalName string `json:"legalName,omitempty"`
LegalAddress string `json:"legalAddress,omitempty"`
INN string `json:"INN,omitempty"`
OKPO string `json:"OKPO,omitempty"`
KPP string `json:"KPP,omitempty"`
OGRN string `json:"OGRN,omitempty"`
OGRNIP string `json:"OGRNIP,omitempty"`
CertificateNumber string `json:"certificateNumber,omitempty"`
CertificateDate string `json:"certificateDate,omitempty"`
BIK string `json:"BIK,omitempty"`
Bank string `json:"bank,omitempty"`
BankAddress string `json:"bankAddress,omitempty"`
CorrAccount string `json:"corrAccount,omitempty"`
BankAccount string `json:"bankAccount,omitempty"`
}
// OrderMethod type
type OrderMethod struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
DefaultForCRM bool `json:"defaultForCrm,omitempty"`
DefaultForAPI bool `json:"defaultForApi,omitempty"`
}
// OrderType type
type OrderType struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
DefaultForCRM bool `json:"defaultForCrm,omitempty"`
DefaultForAPI bool `json:"defaultForApi,omitempty"`
}
// PaymentStatus type
type PaymentStatus struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
DefaultForCRM bool `json:"defaultForCrm,omitempty"`
DefaultForAPI bool `json:"defaultForApi,omitempty"`
PaymentComplete bool `json:"paymentComplete,omitempty"`
Description string `json:"description,omitempty"`
Ordering int `json:"ordering,omitempty"`
PaymentTypes []string `json:"paymentTypes,omitempty,brackets"`
}
// PaymentType type
type PaymentType struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
DefaultForCRM bool `json:"defaultForCrm,omitempty"`
DefaultForAPI bool `json:"defaultForApi,omitempty"`
Description string `json:"description,omitempty"`
DeliveryTypes []string `json:"deliveryTypes,omitempty,brackets"`
PaymentStatuses []string `json:"PaymentStatuses,omitempty,brackets"`
}
// PriceType type
type PriceType struct {
ID int `json:"id,omitempty"`
Code string `json:"code,omitempty"`
Name string `json:"name,omitempty"`
Active bool `json:"active,omitempty"`
Default bool `json:"default,omitempty"`
Description string `json:"description,omitempty"`
FilterExpression string `json:"filterExpression,omitempty"`
Ordering int `json:"ordering,omitempty"`
Groups []string `json:"groups,omitempty,brackets"`
Geo []GeoHierarchyRow `json:"geo,omitempty,brackets"`
}
// ProductStatus type
type ProductStatus struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
Ordering int `json:"ordering,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
CancelStatus bool `json:"cancelStatus,omitempty"`
OrderStatusByProductStatus string `json:"orderStatusByProductStatus,omitempty"`
OrderStatusForProductStatus string `json:"orderStatusForProductStatus,omitempty"`
}
// Status type
type Status struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
Ordering int `json:"ordering,omitempty"`
Group string `json:"group,omitempty"`
}
// StatusGroup type
type StatusGroup struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Active bool `json:"active,omitempty"`
Ordering int `json:"ordering,omitempty"`
Process bool `json:"process,omitempty"`
Statuses []string `json:"statuses,omitempty,brackets"`
}
// 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"`
}
// Store type
type Store struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
ExternalID string `json:"externalId,omitempty"`
Description string `json:"description,omitempty"`
XMLID string `json:"xmlId,omitempty"`
Email string `json:"email,omitempty"`
Type string `json:"type,omitempty"`
InventoryType string `json:"inventoryType,omitempty"`
Active bool `json:"active,omitempty"`
Phone *Phone `json:"phone,omitempty"`
Address *Address `json:"address,omitempty"`
}
// 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"`
}
// 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,brackets"`
Groups []ProductGroup `json:"groups,omitempty,brackets"`
Properties map[string]string `json:"properties,omitempty,brackets"`
}
// DeliveryHistoryRecord type
type DeliveryHistoryRecord struct {
Code string `json:"code,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
Comment string `json:"comment,omitempty"`
}
// DeliveryShipment type
type DeliveryShipment struct {
IntegrationCode string `json:"integrationCode,omitempty"`
ID int `json:"id,omitempty"`
ExternalID string `json:"externalId,omitempty"`
DeliveryType string `json:"deliveryType,omitempty"`
Store string `json:"store,omitempty"`
ManagerID int `json:"managerId,omitempty"`
Status string `json:"status,omitempty"`
Date string `json:"date,omitempty"`
Time *DeliveryTime `json:"time,omitempty"`
LunchTime string `json:"lunchTime,omitempty"`
Comment string `json:"comment,omitempty"`
Orders []Order `json:"orders,omitempty,brackets"`
ExtraData map[string]string `json:"extraData,omitempty,brackets"`
}
// IntegrationModule type
type IntegrationModule struct {
Code string `json:"code,omitempty"`
IntegrationCode string `json:"integrationCode,omitempty"`
Active bool `json:"active,omitempty"`
Freeze bool `json:"freeze,omitempty"`
Native bool `json:"native,omitempty"`
Name string `json:"name,omitempty"`
Logo string `json:"logo,omitempty"`
ClientID string `json:"clientId,omitempty"`
BaseURL string `json:"baseUrl,omitempty"`
AccountURL string `json:"accountUrl,omitempty"`
AvailableCountries []string `json:"availableCountries,omitempty"`
Actions map[string]string `json:"actions,omitempty"`
Integrations *Integrations `json:"integrations,omitempty"`
}
// Integrations type
type Integrations struct {
Telephony *Telephony `json:"telephony,omitempty"`
Delivery *Delivery `json:"delivery,omitempty"`
Store *Warehouse `json:"store,omitempty"`
MgTransport *MgTransport `json:"mgTransport,omitempty"`
MgBot *MgBot `json:"mgBot,omitempty"`
}
// Delivery type
type Delivery struct {
Description string `json:"description,omitempty"`
Actions map[string]string `json:"actions,omitempty,brackets"`
PayerType []string `json:"payerType,omitempty,brackets"`
PlatePrintLimit int `json:"platePrintLimit,omitempty"`
RateDeliveryCost bool `json:"rateDeliveryCost,omitempty"`
AllowPackages bool `json:"allowPackages,omitempty"`
CodAvailable bool `json:"codAvailable,omitempty"`
SelfShipmentAvailable bool `json:"selfShipmentAvailable,omitempty"`
AllowTrackNumber bool `json:"allowTrackNumber,omitempty"`
AvailableCountries []string `json:"availableCountries,omitempty"`
RequiredFields []string `json:"requiredFields,omitempty"`
StatusList []DeliveryStatus `json:"statusList,omitempty"`
PlateList []Plate `json:"plateList,omitempty"`
DeliveryDataFieldList []DeliveryDataField `json:"deliveryDataFieldList,omitempty"`
ShipmentDataFieldList []DeliveryDataField `json:"shipmentDataFieldList,omitempty"`
}
// DeliveryStatus type
type DeliveryStatus struct {
Code string `json:"code,omitempty"`
Name string `json:"name,omitempty"`
IsEditable bool `json:"isEditable,omitempty"`
}
// Plate type
type Plate struct {
Code string `json:"code,omitempty"`
Label string `json:"label,omitempty"`
}
// DeliveryDataField type
type DeliveryDataField struct {
Code string `json:"code,omitempty"`
Label string `json:"label,omitempty"`
Hint string `json:"hint,omitempty"`
Type string `json:"type,omitempty"`
AutocompleteURL string `json:"autocompleteUrl,omitempty"`
Multiple bool `json:"multiple,omitempty"`
Required bool `json:"required,omitempty"`
AffectsCost bool `json:"affectsCost,omitempty"`
Editable bool `json:"editable,omitempty"`
}
// Telephony type
type Telephony struct {
MakeCallURL string `json:"makeCallUrl,omitempty"`
AllowEdit bool `json:"allowEdit,omitempty"`
InputEventSupported bool `json:"inputEventSupported,omitempty"`
OutputEventSupported bool `json:"outputEventSupported,omitempty"`
HangupEventSupported bool `json:"hangupEventSupported,omitempty"`
ChangeUserStatusURL string `json:"changeUserStatusUrl,omitempty"`
AdditionalCodes []AdditionalCode `json:"additionalCodes,omitempty,brackets"`
ExternalPhones []ExternalPhone `json:"externalPhones,omitempty,brackets"`
}
// AdditionalCode type
type AdditionalCode struct {
Code string `json:"code,omitempty"`
UserID string `json:"userId,omitempty"`
}
// ExternalPhone type
type ExternalPhone struct {
SiteCode string `json:"siteCode,omitempty"`
ExternalPhone string `json:"externalPhone,omitempty"`
}
// Warehouse type
type Warehouse struct {
Actions []Action `json:"actions,omitempty,brackets"`
}
// Action type
type Action struct {
Code string `json:"code,omitempty"`
URL string `json:"url,omitempty"`
CallPoints []string `json:"callPoints,omitempty"`
}
// MgTransport type
type MgTransport struct {
WebhookUrl string `json:"webhookUrl,omitempty"`
}
// MgBot type
type MgBot struct{}
/**
Cost related types
*/
// CostRecord type
type CostRecord struct {
Source *Source `json:"source,omitempty"`
Comment string `json:"comment,omitempty"`
DateFrom string `json:"dateFrom,omitempty"`
DateTo string `json:"dateTo,omitempty"`
Summ float32 `json:"summ,omitempty"`
CostItem string `json:"costItem,omitempty"`
UserId int `json:"userId,omitempty"`
Order *Order `json:"order,omitempty"`
Sites []string `json:"sites,omitempty,brackets"`
}
// Cost type
type Cost struct {
Source *Source `json:"source,omitempty"`
ID int `json:"id,omitempty"`
DateFrom string `json:"dateFrom,omitempty"`
DateTo string `json:"dateTo,omitempty"`
Summ float32 `json:"summ,omitempty"`
CostItem string `json:"costItem,omitempty"`
Comment string `json:"comment,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
CreatedBy string `json:"createdBy,omitempty"`
Order *Order `json:"order,omitempty"`
UserId int `json:"userId,omitempty"`
Sites []string `json:"sites,omitempty,brackets"`
}
// CustomFields type
type CustomFields struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Required bool `json:"required,omitempty"`
InFilter bool `json:"inFilter,omitempty"`
InList bool `json:"inList,omitempty"`
InGroupActions bool `json:"inGroupActions,omitempty"`
Type string `json:"type,omitempty"`
Entity string `json:"entity,omitempty"`
Default string `json:"default,omitempty"`
Ordering int `json:"ordering,omitempty"`
DisplayArea string `json:"displayArea,omitempty"`
ViewMode string `json:"viewMode,omitempty"`
Dictionary string `json:"dictionary,omitempty"`
}
/**
CustomDictionaries related types
*/
// CustomDictionary type
type CustomDictionary struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Elements []Element `json:"elements,omitempty,brackets"`
}
// Element type
type Element struct {
Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"`
Ordering int `json:"ordering,omitempty"`
}
// Activity struct
type Activity struct {
Active bool `json:"active"`
Freeze bool `json:"freeze"`
}