Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1957,6 +1957,173 @@ func (c *Client) CorporateCustomerEdit(customer CorporateCustomer, by string, si
return resp, status, nil
}

// ClearCart clears the current customer's shopping cart
//
// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-customer-interaction-site-cart-clear
//
// Example:
//
// var client = retailcrm.New("https://demo.url", "09jIJ")
//
// data, status, err := client.ClearCart("site_id", SiteFilter{SiteBy: "id"},
// ClearCartRequest{
// CreatedAt: time.Now().String(),
// Customer: CartCustomer{
// ID: 1,
// ExternalID: "ext_id",
// Site: "site",
// BrowserID: "browser_id",
// GaClientID: "ga_client_id",
// },
// Order: ClearCartOrder{
// ID: 1,
// ExternalID: "ext_id",
// Number: "abc123",
// },
// },
// )
//
// if err != nil {
// if apiErr, ok := retailcrm.AsAPIError(err); ok {
// log.Fatalf("http status: %d, %s", status, apiErr.String())
// }
//
// log.Fatalf("http status: %d, error: %s", status, err)
// }
func (c *Client) ClearCart(site string, filter SiteFilter, req ClearCartRequest) (
SuccessfulResponse, int, error,
) {
var resp SuccessfulResponse

updateJSON, err := json.Marshal(&req)
if err != nil {
return SuccessfulResponse{}, 0, err
}

p := url.Values{
"cart": {string(updateJSON)},
}

params, _ := query.Values(filter)

data, status, err := c.PostRequest(fmt.Sprintf("/customer-interaction/%s/cart/clear?%s", site, params.Encode()), p)
if err != nil {
return resp, status, err
}

err = json.Unmarshal(data, &resp)
if err != nil {
return resp, status, err
}

return resp, status, nil
}

// SetCart creates or overwrites shopping cart data
//
// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#post--api-v5-customer-interaction-site-cart-set
//
// Example:
//
// var client = retailcrm.New("https://demo.url", "09jIJ")
//
// data, status, err := client.SetCart("site_id", SiteFilter{SiteBy: "id"},
// SetCartRequest{
// ExternalID: "ext_id",
// DroppedAt: time.Now().String(),
// Link: "link",
// Customer: CartCustomer{
// ID: 1,
// ExternalID: "ext_id",
// Site: "site",
// BrowserID: "browser_id",
// GaClientID: "ga_client_id",
// },
// Items: []SetCartItem{
// {
// Quantity: 1,
// Price: 1.0,
// Offer: SetCartOffer{
// ID: 1,
// ExternalID: "ext_id",
// XMLID: "xml_id",
// },
// },
// },
// },
// )
//
// if err != nil {
// if apiErr, ok := retailcrm.AsAPIError(err); ok {
// log.Fatalf("http status: %d, %s", status, apiErr.String())
// }
//
// log.Fatalf("http status: %d, error: %s", status, err)
// }
func (c *Client) SetCart(site string, filter SiteFilter, req SetCartRequest) (
SuccessfulResponse, int, error,
) {
var resp SuccessfulResponse

updateJSON, err := json.Marshal(&req)
if err != nil {
return SuccessfulResponse{}, 0, err
}

p := url.Values{
"cart": {string(updateJSON)},
}

params, _ := query.Values(filter)

data, status, err := c.PostRequest(fmt.Sprintf("/customer-interaction/%s/cart/set?%s", site, params.Encode()), p)
if err != nil {
return resp, status, err
}

err = json.Unmarshal(data, &resp)
if err != nil {
return resp, status, err
}

return resp, status, nil
}

// GetCart returns the current customer's shopping cart
//
// For more information see https://docs.retailcrm.ru/Developers/API/APIVersions/APIv5#get--api-v5-customer-interaction-site-cart-customerId
//
// Example:
//
// var client = retailcrm.New("https://demo.url", "09jIJ")
//
// data, status, err := client.GetCart("site_id","customer_id", GetCartFilter{ SiteBy: "code", By: "externalId"})
//
// if err != nil {
// if apiErr, ok := retailcrm.AsAPIError(err); ok {
// log.Fatalf("http status: %d, %s", status, apiErr.String())
// }
//
// log.Fatalf("http status: %d, error: %s", status, err)
// }
func (c *Client) GetCart(site, customer string, filter GetCartFilter) (CartResponse, int, error) {
var resp CartResponse

params, _ := query.Values(filter)

data, status, err := c.GetRequest(fmt.Sprintf("/customer-interaction/%s/cart/%s?%s", site, customer, 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
}

// DeliveryTracking updates tracking data
//
// For more information see http://www.simla.com/docs/Developers/API/APIVersions/APIv5#post--api-v5-delivery-generic-subcode-tracking
Expand Down
165 changes: 165 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,171 @@ func TestClient_CorporateCustomerEdit(t *testing.T) {
}
}

func TestClient_ClearCart(t *testing.T) {
c := client()

site := "site_id"
filter := SiteFilter{SiteBy: "id"}
request := ClearCartRequest{
CreatedAt: time.Now().String(),
Customer: CartCustomer{
ID: 1,
ExternalID: "ext_id",
Site: "site",
BrowserID: "browser_id",
GaClientID: "ga_client_id",
},
Order: ClearCartOrder{
ID: 1,
ExternalID: "ext_id",
Number: "abc123",
},
}

defer gock.Off()
gock.New(crmURL).
Post(fmt.Sprintf("/customer-interaction/%s/cart/clear", site)).
MatchParam("siteBy", filter.SiteBy).
Reply(200).
BodyString(`{"success":true}`)

data, status, err := c.ClearCart(site, filter, request)
if err != nil {
t.Errorf("%v", err)
}

if status >= http.StatusBadRequest {
t.Errorf("(%d) %v", status, err)
}

if data.Success != true {
t.Errorf("%v", err)
}
}

func TestClient_SetCart(t *testing.T) {
c := client()

site := "site_id"
filter := SiteFilter{SiteBy: "id"}
request := SetCartRequest{
ExternalID: "ext_id",
DroppedAt: time.Now().String(),
Link: "link",
Customer: CartCustomer{
ID: 1,
ExternalID: "ext_id",
Site: "site",
BrowserID: "browser_id",
GaClientID: "ga_client_id",
},
Items: []SetCartItem{
{
Quantity: 1,
Price: 1.0,
Offer: SetCartOffer{
ID: 1,
ExternalID: "ext_id",
XMLID: "xml_id",
},
},
},
}

defer gock.Off()
gock.New(crmURL).
Post(fmt.Sprintf("/customer-interaction/%s/cart/set", site)).
MatchParam("siteBy", filter.SiteBy).
Reply(200).
BodyString(`{"success":true}`)

data, status, err := c.SetCart(site, filter, request)
if err != nil {
t.Errorf("%v", err)
}

if status >= http.StatusBadRequest {
t.Errorf("(%d) %v", status, err)
}

if data.Success != true {
t.Errorf("%v", err)
}
}

func TestClient_GetCart(t *testing.T) {
c := client()

site := "site_id"
customer := "customer_id"
filter := GetCartFilter{
SiteBy: "code",
By: "externalId",
}

expCart := Cart{
Currency: "currency",
ExternalID: "ext_id",
DroppedAt: time.Now().String(),
ClearedAt: time.Now().String(),
Link: "link",
Items: []CartItem{
{
ID: 1,
Quantity: 2,
Price: 3.0,
Offer: CartOffer{
DisplayName: "name",
ID: 1,
ExternalID: "ext_id",
XMLID: "xml_id",
Name: "name",
Article: "article",
VatRate: "vat_rate",
Properties: StringMap{
"a": "b",
"c": "d",
},
Barcode: "barcode",
},
},
},
}

cartResp := CartResponse{
SuccessfulResponse: SuccessfulResponse{Success: true},
Cart: expCart,
}

defer gock.Off()
gock.New(crmURL).
Get(fmt.Sprintf("/customer-interaction/%s/cart/%s", site, customer)).
MatchParams(map[string]string{
"siteBy": filter.SiteBy,
"by": filter.By,
}).
Reply(200).
JSON(cartResp)

data, status, err := c.GetCart(site, customer, filter)
if err != nil {
t.Errorf("%v", err)
}

if status >= http.StatusBadRequest {
t.Errorf("(%d) %v", status, err)
}

if data.Success != true {
t.Errorf("%v", err)
}

if !reflect.DeepEqual(expCart, data.Cart) {
t.Errorf("%v", err)
}

}

func TestClient_NotesNotes(t *testing.T) {
c := client()

Expand Down
15 changes: 15 additions & 0 deletions filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,3 +480,18 @@ 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"`
}
16 changes: 16 additions & 0 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,22 @@ type DeliveryShipmentsRequest struct {
Page int `url:"page,omitempty"`
}

// ClearCartRequest type.
type ClearCartRequest struct {
CreatedAt string `url:"createdAt,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"`
Expand Down
Loading