diff --git a/client.go b/client.go index 321af9a..3df354d 100644 --- a/client.go +++ b/client.go @@ -5545,3 +5545,97 @@ func (c *Client) CustomFieldEdit(customFields CustomFields) (CustomResponse, int return resp, status, nil } + +// BonusOperations returns history of the bonus account for all participations +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#get--api-v5-loyalty-bonus-operations +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// data, status, err := client.BonusOperations(retailcrm.BonusOperationsRequest{ +// Filter: BonusOperationsFilter{ +// LoyaltyId: []int{123, 456}, +// }, +// Limit: 10, +// Cursor: "123456", +// }) +// +// 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) +// } +// +// for _, value := range data.Customers { +// log.Printf("%v\n", value) +// } +func (c *Client) BonusOperations(parameters BonusOperationsRequest) (BonusOperationsResponse, int, error) { + var resp BonusOperationsResponse + + params, _ := query.Values(parameters) + data, status, err := c.GetRequest(fmt.Sprintf("/loyalty/bonus/operations?%s", params.Encode())) + + if err != nil { + return resp, status, err + } + + err = json.Unmarshal(data, &resp) + if err != nil { + return resp, status, err + } + + return resp, status, nil +} + +// AccountBonusOperations returns history of the bonus account for a specific participation +// +// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#get--api-v5-loyalty-account-id-bonus-operations +// +// Example: +// +// var client = retailcrm.New("https://demo.url", "09jIJ") +// +// data, status, err := client.AccountBonusOperations(retailcrm.AccountBonusOperationsRequest{ +// Filter: AccountBonusOperationsFilter{ +// CreatedAtFrom: "2012-12-12", +// CreatedAtTo: "2012-12-13", +// }, +// Limit: 10, +// Page: 3, +// }) +// +// 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) +// } +// +// for _, value := range data.Customers { +// log.Printf("%v\n", value) +// } +func (c *Client) AccountBonusOperations(id int, parameters AccountBonusOperationsRequest) (BonusOperationsResponse, int, error) { + var resp BonusOperationsResponse + + params, _ := query.Values(parameters) + data, status, err := c.GetRequest(fmt.Sprintf( + "/loyalty/account/%v/bonus/operations?%s", + id, params.Encode(), + )) + + if err != nil { + return resp, status, err + } + + err = json.Unmarshal(data, &resp) + if err != nil { + return resp, status, err + } + + return resp, status, nil +} diff --git a/client_test.go b/client_test.go index 771acc9..1097f62 100644 --- a/client_test.go +++ b/client_test.go @@ -6659,3 +6659,137 @@ func TestClient_UpdateScopes_Fail(t *testing.T) { t.Error(successFail) } } + +func TestClient_BonusOperations(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Get("/api/v5/loyalty/bonus/operations"). + MatchParam("filter[loyalties][]", "1"). + MatchParam("filter[loyalties][]", "3"). + MatchParam("cursor", "qwe"). + MatchParam("limit", "3"). + Reply(200). + BodyString(`{"success": true}`) + + c := client() + + data, status, err := c.BonusOperations(BonusOperationsRequest{ + Filter: BonusOperationsFilter{ + Loyalties: []int{1, 3}, + }, + Cursor: "qwe", + Limit: 3, + }) + + if err != nil { + t.Errorf("%v", err) + } + + if status >= http.StatusBadRequest { + t.Logf("%v", err) + } + + if data.Success != true { + t.Logf("%v", err) + } +} + +func TestClient_BonusOperations_Fail(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Get("/api/v5/loyalty/bonus/operations"). + MatchParam("filter[loyalties][]", "1"). + MatchParam("filter[loyalties][]", "3"). + MatchParam("cursor", "qwe"). + MatchParam("limit", "3"). + Reply(400). + BodyString(`{"success": false,"errorMsg": "Internal Server Error"}`) + + c := client() + + data, _, err := c.BonusOperations(BonusOperationsRequest{ + Filter: BonusOperationsFilter{ + Loyalties: []int{1, 3}, + }, + Cursor: "qwe", + Limit: 3, + }) + + if err == nil { + t.Error("Error must be return") + } + + if data.Success != false { + t.Error(successFail) + } +} + +func TestClient_AccountBonusOperations(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Get("/api/v5/loyalty/account/123/bonus/operations"). + MatchParam("filter[createdAtFrom]", "2012-12-12"). + MatchParam("filter[createdAtTo]", "2012-12-13"). + MatchParam("page", "3"). + MatchParam("limit", "10"). + Reply(200). + BodyString(`{"success": true}`) + + c := client() + + data, status, err := c.AccountBonusOperations(123, AccountBonusOperationsRequest{ + Filter: AccountBonusOperationsFilter{ + CreatedAtFrom: "2012-12-12", + CreatedAtTo: "2012-12-13", + }, + Page: 3, + Limit: 10, + }) + + if err != nil { + t.Errorf("%v", err) + } + + if status >= http.StatusBadRequest { + t.Logf("%v", err) + } + + if data.Success != true { + t.Logf("%v", err) + } +} + +func TestClient_AccountBonusOperations_Fail(t *testing.T) { + defer gock.Off() + + gock.New(crmURL). + Get("/api/v5/loyalty/account/123/bonus/operations"). + MatchParam("filter[createdAtFrom]", "2012-12-12"). + MatchParam("filter[createdAtTo]", "2012-12-13"). + MatchParam("page", "3"). + MatchParam("limit", "10"). + Reply(400). + BodyString(`{"success": false,"errorMsg": "Internal Server Error"}`) + + c := client() + + data, _, err := c.AccountBonusOperations(123, AccountBonusOperationsRequest{ + Filter: AccountBonusOperationsFilter{ + CreatedAtFrom: "2012-12-12", + CreatedAtTo: "2012-12-13", + }, + Page: 3, + Limit: 10, + }) + + if err == nil { + t.Error("Error must be return") + } + + if data.Success != false { + t.Error(successFail) + } +} diff --git a/filters.go b/filters.go index b393f9f..d312b99 100644 --- a/filters.go +++ b/filters.go @@ -427,3 +427,13 @@ 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"` +} diff --git a/request.go b/request.go index 4d49c23..21df512 100644 --- a/request.go +++ b/request.go @@ -232,6 +232,20 @@ type ConnectRequest struct { 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"` +} + // SystemURL returns system URL from the connection request without trailing slash. func (r ConnectRequest) SystemURL() string { if r.URL == "" { diff --git a/response.go b/response.go index 4599896..beb50dd 100644 --- a/response.go +++ b/response.go @@ -550,3 +550,10 @@ func NewConnectResponse(accountURL string) ConnectResponse { AccountURL: accountURL, } } + +// BonusOperationsResponse type. +type BonusOperationsResponse struct { + Success bool `json:"success"` + Pagination *Pagination `json:"pagination,omitempty"` + BonusOperations []BonusOperation `json:"bonusOperations,omitempty"` +} diff --git a/types.go b/types.go index 8d3d793..1961dd2 100644 --- a/types.go +++ b/types.go @@ -1186,3 +1186,42 @@ type Tag struct { Color string `json:"color,omitempty"` Attached bool `json:"attached,omitempty"` } + +// BonusOperation struct. +type BonusOperation struct { + Type string `json:"type,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + Amount float32 `json:"amount,omitempty"` + Order OperationOrder `json:"order"` + Bonus OperationBonus `json:"bonus"` + Event OperationEvent `json:"event"` + LoyaltyAccount OperationLoyaltyAccount `json:"loyaltyAccount"` + Loyalty OperationLoyalty `json:"loyalty"` +} + +// OperationOrder struct. +type OperationOrder struct { + ID int `json:"id,omitempty"` + ExternalID string `json:"externalId,omitempty"` +} + +// OperationBonus struct. +type OperationBonus struct { + ActivationDate string `json:"activationDate,omitempty"` +} + +// OperationEvent struct. +type OperationEvent struct { + ID int `json:"id,omitempty"` + Type string `json:"type,omitempty"` +} + +// OperationLoyaltyAccount struct. +type OperationLoyaltyAccount struct { + ID int `json:"id,omitempty"` +} + +// OperationLoyalty struct. +type OperationLoyalty struct { + ID int `json:"id,omitempty"` +}