3pl/partnerapi/onpoint/onpoint.go

251 lines
6.5 KiB
Go
Raw Normal View History

2022-09-16 10:43:13 +00:00
package onpoint
import (
"errors"
"fmt"
2024-04-16 04:24:28 +00:00
"log"
2022-09-16 10:43:13 +00:00
"net/http"
2024-04-16 05:04:34 +00:00
"net/url"
2022-09-16 10:43:13 +00:00
"strconv"
"strings"
"time"
2022-10-13 09:45:04 +00:00
"git.selly.red/Selly-Modules/natsio"
"git.selly.red/Selly-Modules/natsio/model"
"git.selly.red/Selly-Modules/natsio/subject"
2022-09-16 10:43:13 +00:00
2022-10-13 09:45:04 +00:00
"git.selly.red/Selly-Modules/3pl/util/httputil"
"git.selly.red/Selly-Modules/3pl/util/pjson"
2022-09-16 10:43:13 +00:00
)
// Client ...
type Client struct {
env ENV
apiKey string
secretKey string
natsClient natsio.Server
}
// NewClient generate OnPoint client
func NewClient(env ENV, apiKey, secretKey string, nc natsio.Server) (*Client, error) {
if apiKey == "" {
return nil, errors.New("onpoint: cannot init with empty api key")
}
return &Client{
env: env,
apiKey: apiKey,
secretKey: secretKey,
natsClient: nc,
}, nil
}
// CreateOrder ...
func (c *Client) CreateOrder(p CreateOrderRequest) (*CreateOrderResponse, error) {
url := c.getBaseURL() + apiPathCreateOrder
natsPayload := model.CommunicationRequestHttp{
ResponseImmediately: true,
Payload: model.HttpRequest{
URL: url,
Method: http.MethodPost,
Data: pjson.ToJSONString(p),
},
}
var (
r model.CommunicationHttpResponse
errRes Error
dataRes struct {
2022-10-04 08:45:29 +00:00
Code string `json:"code"`
2022-09-16 10:43:13 +00:00
Data CreateOrderResponse `json:"data"`
}
)
if err := c.requestHttpViaNats(natsPayload, &r); err != nil {
return nil, err
}
res := r.Response
if res == nil {
return nil, fmt.Errorf("onpoint.Client.CreateOrder: empty_response")
}
if res.StatusCode >= http.StatusBadRequest {
if err := r.ParseResponseData(&errRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.CreateOrder: parse_response_err: %v", err)
}
return nil, errRes
}
if err := r.ParseResponseData(&dataRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.CreateOrder: parse_response_data: %v", err)
}
return &dataRes.Data, nil
}
// UpdateDelivery ...
func (c *Client) UpdateDelivery(p UpdateOrderDeliveryRequest) (*UpdateOrderDeliveryResponse, error) {
url := c.getBaseURL() + apiPathUpdateDelivery
natsPayload := model.CommunicationRequestHttp{
ResponseImmediately: true,
Payload: model.HttpRequest{
URL: url,
Method: http.MethodPost,
Data: pjson.ToJSONString(p),
},
}
var (
r model.CommunicationHttpResponse
errRes Error
dataRes struct {
Data UpdateOrderDeliveryResponse `json:"data"`
}
)
if err := c.requestHttpViaNats(natsPayload, &r); err != nil {
return nil, err
}
res := r.Response
if res == nil {
return nil, fmt.Errorf("onpoint.Client.UpdateDelivery: empty_response")
}
if res.StatusCode >= http.StatusBadRequest {
if err := r.ParseResponseData(&errRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.UpdateDelivery: parse_response_err: %v", err)
}
return nil, errRes
}
if err := r.ParseResponseData(&dataRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.UpdateDelivery: parse_response_data: %v", err)
}
return &dataRes.Data, nil
}
// CancelOrder ...
func (c *Client) CancelOrder(p CancelOrderRequest) (*CancelOrderResponse, error) {
url := c.getBaseURL() + apiPathCancelOrder
natsPayload := model.CommunicationRequestHttp{
ResponseImmediately: true,
Payload: model.HttpRequest{
URL: url,
Method: http.MethodPost,
Data: pjson.ToJSONString(p),
},
}
var (
r model.CommunicationHttpResponse
errRes Error
dataRes struct {
Data CancelOrderResponse `json:"data"`
}
)
if err := c.requestHttpViaNats(natsPayload, &r); err != nil {
return nil, err
}
res := r.Response
if res == nil {
return nil, fmt.Errorf("onpoint.Client.CancelOrder: empty_response")
}
if res.StatusCode >= http.StatusBadRequest {
if err := r.ParseResponseData(&errRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.CancelOrder: parse_response_err: %v", err)
}
return nil, errRes
}
if err := r.ParseResponseData(&dataRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.CancelOrder: parse_response_data: %v", err)
}
return &dataRes.Data, nil
}
2024-04-08 08:38:20 +00:00
// GetInventories ...
func (c *Client) GetInventories(req ListInventoriesReq) (*ListInventoriesRes, error) {
url := c.getBaseURL() + apiPathGetInventories
q := map[string]string{}
if !req.UpdatedFrom.IsZero() {
q["updated_from"] = req.UpdatedFrom.Format(TimeLayout)
}
if !req.UpdatedTo.IsZero() {
q["updated_to"] = req.UpdatedTo.Format(TimeLayout)
}
if len(req.SKUList) > 0 {
q["sku_list"] = strings.Join(req.SKUList, ",")
}
if req.Page > 0 {
q["page"] = strconv.Itoa(req.Page)
}
if req.Size > 0 {
q["size"] = strconv.Itoa(req.Size)
}
natsPayload := model.CommunicationRequestHttp{
ResponseImmediately: true,
Payload: model.HttpRequest{
URL: url,
Method: http.MethodGet,
2024-04-08 08:38:20 +00:00
Query: q,
},
}
var (
r model.CommunicationHttpResponse
errRes Error
dataRes ListInventoriesRes
)
if err := c.requestHttpViaNats(natsPayload, &r); err != nil {
return nil, err
}
res := r.Response
if res == nil {
return nil, fmt.Errorf("onpoint.Client.GetInventories: empty_response")
}
if res.StatusCode >= http.StatusBadRequest {
if err := r.ParseResponseData(&errRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.GetInventories: parse_response_err: %v", err)
}
return nil, errRes
}
if err := r.ParseResponseData(&dataRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.GetInventories: parse_response_data: %v", err)
}
return &dataRes, nil
}
2022-09-16 10:43:13 +00:00
func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp, res interface{}) error {
ec, err := c.natsClient.NewJSONEncodedConn()
if err != nil {
return fmt.Errorf("onpoint: request via nats %v", err)
}
2024-04-16 05:04:34 +00:00
u, err := url.ParseRequestURI(data.Payload.URL)
if err != nil {
return fmt.Errorf("onpoint: request via nats %v", err)
}
q := u.Query()
2022-09-16 10:43:13 +00:00
for k, v := range data.Payload.Query {
2024-04-16 05:04:34 +00:00
q.Set(k, v)
2022-09-16 10:43:13 +00:00
}
2024-04-16 05:04:34 +00:00
u.RawQuery = q.Encode()
2022-09-16 10:43:13 +00:00
now := time.Now().Unix()
ts := strconv.FormatInt(now, 10)
arr := []string{
2024-04-16 05:04:34 +00:00
u.RawQuery,
2022-09-16 10:43:13 +00:00
data.Payload.Data,
ts,
}
s := strings.Join(arr, ".")
2024-04-16 04:24:28 +00:00
log.Println("DEBUG: onpoint. secret_message:", s)
log.Println("DEBUG: onpoint. secret_key:", c.secretKey)
2022-09-16 10:43:13 +00:00
// sign data
sign := hashSHA256AndUppercase(s, c.secretKey)
data.Payload.Header = map[string]string{
2022-10-04 09:29:34 +00:00
headerXAPIKey: c.apiKey,
headerXSignature: sign,
headerXTimestamp: ts,
httputil.HeaderKeyContentType: httputil.HeaderValueApplicationJSON,
2022-09-16 10:43:13 +00:00
}
2024-04-16 05:04:34 +00:00
data.Payload.Query = map[string]string{}
2024-04-16 05:10:56 +00:00
data.Payload.URL = u.String()
2022-09-16 10:43:13 +00:00
return ec.Request(subject.Communication.RequestHTTP, data, res)
}
func (c *Client) getBaseURL() string {
return baseURLENVMapping[c.env]
}